Skip to content

Replace

hs edited this page Oct 27, 2026 · 1 revision

Replace

replace removes every occurrence of a find string from the selected pages and draws the replacement with an embedded subset of the bundled vivo Sans. The original glyphs are surgically deleted from the content streams (page content and Form XObjects); the replacement preserves the original text transform, font size, spacings, rise, render mode and fill color, anchored at the visually topmost-left glyph of each occurrence.

pdfcpu2 replace -f "old text" -r "new text" in.pdf out.pdf
pdfcpu2 replace -f "DRAFT" in.pdf out.pdf          # deletion only
pdfcpu2 replace -f "old" -r "new" -p 1-10 in.pdf out.pdf

Flags must precede the positional arguments (see Passwords-and-Global-Flags).

How it works

  1. Scan — an offset-tracking scanner reuses the text extractor's font decoding and produces one record per glyph ({char, x/y, device matrix, owning op, owning object}), including text inside Form XObjects. It tracks the full graphics state (CTM, fill color) and text state.
  2. Match — glyphs are clustered into horizontal lines following content-stream order; matching is whitespace-insensitive (a find string ignores spaces, and gaps/real spaces between original glyphs don't break a match — 医院 matches 医 院). Whitespace glyphs carry no ink and are left alone. Overprinted duplicate draws (fake bold) are paired and deleted together with their primary.
  3. Delete — matched show ops are rewritten in place: fully matched ops disappear (the state side effects of ' and " are replayed), partially matched ops are rebuilt with TJ adjustments that compensate the removed advances so surviving glyphs keep their exact positions.
  4. Draw — the replacement text is drawn once per occurrence, anchored at the visually topmost-left matched glyph, replaying the original text matrix (position/rotation/skew/scale), Tf size, Tc/Tw/Tz/Ts, render mode and fill color. Bold originals are approximated with fill+stroke (2 Tr).

Replacement glyphs always come from a subset of the bundled vivo Sans (see Home license notes), embedded as a Type0/CIDFontType2 font with Identity-H encoding and a ToUnicode CMap — replaced text stays selectable, extractable and copy-pastable in any viewer. The subset is reused and extended across runs: one fixed font (pdfcpu2-replace) carries all replacement glyphs, existing codes stay stable and new runes are appended; font garbage is left to optimize.

API

n, err := api.ReplaceTextFile(ctx, "in.pdf", "out.pdf", "old", "new", nil, nil) // all pages

n is the number of replaced occurrences; the output file is only written when n > 0.

Limitations

  • Horizontal text lines only (rotated/vertical baselines are not matched).
  • Single-line find strings; no reflow — a longer replacement simply extends to the right of the anchor.
  • Original fonts that lose glyphs are not garbage collected yet (see Roadmap).

Clone this wiki locally