PDFium Delphi Component Docs

Transactional styled text replacement

Add FPdfStyledEdit and provide an IPdfRegexEngine to plan and execute replacements against native top-level text objects

PlanStyledPdfRegexReplacements captures a reproducible source snapshot, concatenates actual Unicode glyphs in page and object order, and maps matches back to stable object anchors; generated extraction spaces and line breaks are excluded

ExecuteStyledPdfReplacements validates the snapshot SHA-256, current source identity, anchors and nonoverlapping intervals before changing an independently loaded document

The source identity uses reproducible serialization, including normalized timestamps and identifiers, rather than the original file bytes; the plan stores the actual snapshot bytes and their SHA-256

Native font, text size, color and matrix are reused where possible; replacements spanning objects or pages retain the first object's style and remove consumed characters from later objects while preserving remaining text and page order

FallbackFontName explicitly selects a standard PostScript font when native Unicode cannot be reproduced; ForceFallbackFont requests that path directly

Fallback preserves painter order, matrix, rendering mode, fill and stroke attributes; clipped, transparent, marked or tagged objects are rejected rather than silently losing their graphics semantics

Text wider than its source bounds may shrink horizontally when its matrix is upright and nonsheared; MinHorizontalScale defaults to 0.5, with narrower replacement text retaining the original matrix

This workflow supports single-line replacement text and bounded horizontal fitting; it does not traverse nested Form XObjects, rewrite Tagged PDF semantics or perform paragraph reflow

Signed or encrypted documents and XFA are rejected; cancellation, stale plans, invalid UTF-16, unsupported fonts and exhausted budgets leave the caller document unchanged

PreviewOnly returns the independently reopened result in PreviewPdf without replacing the caller; successful commit replaces the document only after glyph extraction and page count have been verified after saving and reopening

All matches are assembled into final object text before changing native objects; fitting and the minimum scale are checked once against original bounds, preventing repeated matches from accumulating excessive shrinkage

Empty replacement text removes a fully consumed text object after all anchored edits; multiple replacements run backward so earlier source offsets remain valid

Default limits are 256 MiB of document bytes, 10,000 pages, 100,000 text objects, 16,777,216 UTF-16 units and 100,000 replacements; the text-scan work budget is 67,108,864 native character visits and UTF-16 planning-copy units

Hard maxima retain those page, object, character and replacement limits, allow 512 MiB of document bytes and 1,073,741,824 scan visits, and bound a fallback font name to 1,024 bytes

The report includes source and output SHA-256 values, applied replacement, fallback and scaling counts, and per-object original/final text and bounds in PDF user-space points; page and object indexes are zero-based source indexes

A replacement operation is not a security redaction workflow; use the dedicated redaction APIs for removal of sensitive content and associated document data

Options := TPdfStyledEditOptions.Default;
Plan := PlanStyledPdfRegexReplacements(Pdf, Pattern, Replacement, Engine, Options);
Options.PreviewOnly := True;
if not ExecuteStyledPdfReplacements(Pdf, Plan, Options, PreviewPdf, Report) then
  raise EPdfProduction.Create(Report.ErrorMessage);

Public declarations

type
  TPdfStyledEditOptions= record
    MaxDocumentBytes: Integer;
    MaxPages, MaxTextObjects, MaxCharacters, MaxReplacements: Integer;
    MaxTextScanWork: Int64;
    MinHorizontalScale: Double;
    FallbackFontName: AnsiString;
    ForceFallbackFont: Boolean;
    PreviewOnly: Boolean;
    CancellationToken: IPdfCancellationToken;
    class function Default: TPdfStyledEditOptions; static;
  end;
  TPdfStyledEditPlan= record
    SourceSha256: string;
    SourceBytes: TBytes;
    Spans: TPdfStyledSpans;
    Replacements: TPdfStyledReplacements;
  end;
  TPdfStyledObjectChange= record
    PageIndex, ObjectIndex: Integer;
    BeforeText, AfterText: WideString;
    BeforeBounds, AfterBounds: TPdfRectangle;
    HorizontalScale: Double;
    FontFallback: Boolean;
  end;
  TPdfStyledObjectChanges= array of TPdfStyledObjectChange;
  TPdfStyledEditReport= record
    Succeeded, Cancelled, PreviewOnly: Boolean;
    AppliedReplacementCount, FontFallbackCount, ScaledObjectCount: Integer;
    SourceSha256, OutputSha256, ErrorMessage: string;
    Changes: TPdfStyledObjectChanges;
  end;

function PlanStyledPdfRegexReplacements(Pdf: TPdf;
  const Pattern, Replacement: WideString; Engine: IPdfRegexEngine;
  const Options: TPdfStyledEditOptions): TPdfStyledEditPlan;
function ExecuteStyledPdfReplacements(Pdf: TPdf;
  const Plan: TPdfStyledEditPlan; const Options: TPdfStyledEditOptions;
  out PreviewPdf: TBytes; out Report: TPdfStyledEditReport): Boolean;