How editing text in a PDF actually works

A PDF does not store a document. It stores instructions for painting a page, and the text is one of the things being painted. Almost everything that is awkward about editing a PDF follows from that one fact.

By EasyEditPDF · Updated

What a page actually contains

Inside the file, a page is a content stream: a sequence of operators with operands, executed in order. Text arrives between BT and ET, positioned by a text matrix, and drawn by Tj for a single string or TJ for a string broken into pieces with numeric adjustments between them.

Two things follow immediately. There are no paragraphs — a visual line may be several operators, and one operator may cover several visual lines. And the bytes in the string are not necessarily the characters you see: they are indices into a font, and the file has to supply a separate map saying what each index means.

Why you cannot simply change the string

Replacing the text of an operator changes how wide the run is drawn. The rest of the line does not move with it, because nothing in the file says those pieces belong together — the producer positioned them once, when it wrote the file, and their positions are constants. Longer replacement text overlaps what follows; shorter text leaves a gap.

That is before the font. A PDF usually embeds only the glyphs the document happened to use, so a character you type may simply not exist in the file’s copy of the face. See font subsetting.

Grading every block before you type

Rather than let you edit and find out afterwards, the extractor grades each block of text and the editor shows that grade beside it. Four levels, worst reason wins:

The rules, in full

These are the tests the extractor applies. A block can collect several; the worst one decides its level.

ReasonLevelWhat produces it
scanned-pageUnsupportedThe page carries almost no text of its own and is mostly covered by images.
no-unicode-mappingUnsupportedA fifth or more of the block's glyphs have no declared character, so what the text says cannot be known.
inside-form-fieldUnsupportedThe text sits inside a fillable form field, whose contents belong to the field rather than the page.
vectorized-text-suspectedUnsupportedThe area looks drawn rather than typed — many small paths and no text-drawing instruction covering them. Reported as a suspicion, never as a certainty.
complex-backgroundOverlay onlyThe pixels immediately around the text vary, so no single colour would cover the old text invisibly. Also assumed when the page was not rasterised.
subset-fontLimitedThe font is embedded as a subset — it carries only the characters the file already used, so a character you type may have no glyph.
per-character-positioningLimitedEach glyph carries its own position adjustment, so replacing the run means recomputing spacing the file set by hand.
rotatedLimitedThe text is set at an angle.
unmapped-glyphsNo changeA few glyphs have no declared character — typically a ligature or a bullet drawn from a symbol face. The block stays editable and the confidence drops.

What happens when you export

The edited block is redrawn, in the document’s own embedded font where its character map can be recovered and the glyphs are present, and otherwise in a substitute chosen to match the widths the document already recorded. Anything newly embedded is subsetted.

The old text is removed where the exporter can prove which instructions drew it, and covered with a rectangle where it cannot — in the surrounding colour where that is unambiguous, in white where it is not. Which of the two happens depends on the file and is not known until the export runs, so the exported file may still contain the old words — this is not redaction.

Limits

Files must be smaller than 1 MiB and at most 100 pages. These are the sizes the engine has been tested at rather than a paywall, and they are the same on every plan today.

Related: why a PDF’s text will not edit, text-based vs scanned PDFs. Open the editor.