PdfEditor

class PdfEditor

Writer for edits to an existing PDF. Open one with PdfDocument.edit.

val editor = doc.edit()
editor.setInfo(title = "New Title")
editor.stampPage(doc.pages[0]) {
setFillRgb(0.8, 0.1, 0.1)
text(StandardFont.HelveticaBold, 48.0, 120.0, 400.0, "DRAFT")
}
val bytes = editor.saveIncremental()

Two save modes:

  • saveIncremental appends changes to the original bytes (ISO 32000-1 §7.5.6). The original content is preserved verbatim, only the new/changed objects, a fresh xref section and a trailer pointing back via /Prev are written at the end. This is the right mode for ordinary edits and the foundation for digital signing (which signs the appended byte range).

  • saveRewritten writes a fresh, garbage-collected file containing only objects reachable from the catalog, with edits applied and unreachable objects dropped. Required for redaction, since removed content is truly gone rather than retained in the original byte prefix.

Encrypted documents (V4 AES-128 and V5 AES-256) are supported when the password authenticated: every staged object is encrypted with the SAME parameters as the base document at saveIncremental time and the trailer keeps the original /Encrypt. Legacy RC4 documents are refused (read-only). Note saveRewritten instead emits a DECRYPTED file: the rewrite drops the /Encrypt dictionary and writes the resolved plain-text objects.

Properties

Link copied to clipboard

Number of objects staged for writing.

Functions

Link copied to clipboard
fun addFlateStream(data: ByteArray, extra: Map<String, PdfObject> = emptyMap()): PdfReference

Stage a new /FlateDecode-compressed stream from uncompressed data (see PdfStreams.flate); returns the reference to it.

Link copied to clipboard

Stage a brand-new indirect object; returns the reference to it.

Link copied to clipboard

Reserve the next free object number (generation 0).

Link copied to clipboard
fun appendPage(source: PdfDocument, sourceIndex: Int): PdfReference

Append a page deep-copied from source (see graftPage); returns its new ref.

Link copied to clipboard
fun editPageContent(page: PdfPage, transform: (List<Operation>) -> List<Operation>)

Rewrite page's content stream by transforming its parsed operations. The page's decoded content is parsed (see ContentStreamParser), passed to transform, re-serialized, written as a new compressed stream, and the page's /Contents is repointed at it. The original content objects are left in place (orphaned) per incremental-update semantics.

Link copied to clipboard
fun graftPage(source: PdfDocument, sourceIndex: Int): PdfReference

Deep-copy one page (and its full transitive object graph: resources, fonts, content streams, XObjects) from source into this editor under fresh object numbers, returning the new page reference. Inherited /MediaBox, /Resources, /Rotate are baked onto the copied page so it is self-contained, and /Parent is dropped (set later by applyPageOrder). Mirrors MuPDF's pdf_graft_page.

Link copied to clipboard
fun insertPageAt(position: Int, pageRef: PdfReference)

Insert a (grafted) page reference at zero-based position.

Link copied to clipboard

Append every page of source to this document (cross-document merge).

Link copied to clipboard
fun redactRegion(page: PdfPage, rectangle: Rectangle)

Redact a single rectangular region of page (see redactRegions).

Link copied to clipboard
fun redactRegions(page: PdfPage, rectangles: List<Rectangle>)

Redact rectangular regions of page (rectangles in page user space).

Link copied to clipboard

Remove all text-showing operations (Tj, TJ, ', ") from page.

Link copied to clipboard
fun removePage(page: PdfPage)

Remove page from the document.

Link copied to clipboard
fun rotatePage(page: PdfPage, degrees: Int)

Set the page /Rotate (clockwise, must be a multiple of 90). Normalised to 0/90/180/270.

Link copied to clipboard

Produce the updated document bytes: original + appended objects + new xref section + trailer. When nothing was staged or overridden this is a verbatim copy of the original.

Link copied to clipboard
fun saveRewritten(useObjectStreams: Boolean = false): ByteArray

Serialize a fresh, self-contained PDF containing only the objects reachable from the catalog (and /Info), with staged edits applied and objects renumbered densely. Unlike saveIncremental, the original bytes are NOT retained and unreachable objects (e.g. content streams replaced by an edit) are dropped, which is what makes it the correct method for redaction (the removed content is truly gone, not just superseded).

Link copied to clipboard
fun setButtonValue(field: PdfFormField, exportValue: String)

Set a button field (/Btn) to a named export value, the mechanism behind checkboxes and radio groups. The field's /V becomes the chosen on-state name; every widget's /AS is set to that name when the widget defines it as an appearance state, or to /Off otherwise (so sibling radios in the group are cleared). Pass "Off" to clear the field.

Link copied to clipboard
fun setCheckbox(field: PdfFormField, checked: Boolean)

Check or uncheck a checkbox field. The "on" state name is taken from the widget's /AP /N keys (the non-Off one, e.g. /Yes), so the value matches whatever the document author defined.

Link copied to clipboard
fun setChoiceValue(field: PdfFormField, value: String)

Set a choice field (/Ch: combo box or list box) to value. Sets /V, sets /I (selected index) when the value is found in /Opt, and regenerates the widget appearance so the selection is visible.

Link copied to clipboard
fun setInfo(title: String? = null, author: String? = null, subject: String? = null, keywords: String? = null, creator: String? = null, producer: String? = null): PdfReference

Set document metadata (/Info). Only non-null fields are changed; any existing /Info entries (standard or custom) are preserved. Updates the existing /Info object in place if the trailer references one, otherwise creates a new /Info object and points the trailer at it. Returns the reference to the (possibly newly created) /Info dictionary.

Link copied to clipboard
fun setPageOrder(orderedPageRefs: List<PdfReference>)

Replace the document's page order with exactly orderedPageRefs. Rebuilds a single flat /Pages node (kids + /Count), re-parents every page to it, and keeps the catalog pointing at it. This is the engine behind delete, reorder, insert and merge: omit a ref to delete, permute to reorder, append a grafted ref to insert. Pages no longer referenced are dropped by saveRewritten.

Link copied to clipboard

Fill a text form field: set its value (/V) and regenerate the widget's normal appearance (/AP /N) so the value is visible in any viewer. The appearance honours the field's /DA (font, size, colour) and is clipped to the field rectangle. Also clears the form's /NeedAppearances flag (if set) so viewers use the appearance we just generated.

Link copied to clipboard
fun setTrailerEntry(key: String, value: PdfObject)

Set or replace a trailer entry (e.g. /Root, /Info) in the new section.

Link copied to clipboard
fun stampPage(page: PdfPage, block: ContentStreamBuilder.() -> Unit)

Overlay content onto an existing page (a stamp/watermark) drawn by block. The existing content is preserved (wrapped in q/Q so its graphics state can't leak into the overlay), the overlay is appended in its own q/Q, and any standard fonts the overlay uses are merged into the page's /Resources under fresh, non-colliding names.

Link copied to clipboard

Stage a replacement for an existing object (keeps ref's generation).