Include FPdfStyledEdit and supply an IPdfRegexEngine to plan and apply replacements to native top-level text objects
PlanStyledPdfRegexReplacements takes a reproducible source snapshot, joins actual Unicode glyphs in page/object order and maps matches back to stable object anchors; extraction-generated spaces and line breaks are omitted
Before altering a separately loaded document, ExecuteStyledPdfReplacements checks snapshot SHA-256, current source identity, anchors and nonoverlapping ranges
Identity is derived from reproducible serialisation with normalised timestamps and identifiers, rather than original file bytes; the plan keeps the actual snapshot bytes and their SHA-256
Where possible, native fonts, sizes, colours and matrices are reused; a match spanning objects or pages takes the first object's style and consumes matched characters in later objects without disturbing remaining text or page order
If native Unicode cannot be reproduced, FallbackFontName explicitly chooses a standard PostScript font; ForceFallbackFont selects that route directly
Fallback retains painter order, matrix, rendering mode and fill/stroke attributes; clipped, transparent, marked or tagged objects are refused instead of having their graphics semantics silently discarded
When replacement text exceeds its source width, an upright, nonsheared matrix may be scaled horizontally; MinHorizontalScale defaults to 0.5, whilst narrower text keeps the original matrix
This is a single-line replacement workflow with limited horizontal fitting; it neither walks nested Form XObjects nor rewrites Tagged PDF semantics or reflows paragraphs
Signed or encrypted input and XFA are refused; cancellation, obsolete plans, invalid UTF-16, unsupported fonts and exhausted allowances leave the caller's document intact
PreviewOnly returns separately reopened output in PreviewPdf without replacing the caller's document; committing replaces it only after saving and reopening have verified glyph extraction and page count
Matches are combined into each object's final text before native objects change; fitting and minimum scale are tested once against original bounds, avoiding excessive shrinkage from repeated matches
An empty replacement removes a fully consumed text object after all anchored edits; multiple replacements are applied backwards to keep earlier source offsets valid
Defaults allow 256 MiB of document data, 10,000 pages, 100,000 text objects, 16,777,216 UTF-16 units and 100,000 replacements; scanning allows 67,108,864 native-character visits and UTF-16 planning-copy units
Hard limits retain these page, object, character and replacement ceilings, permit 512 MiB of document data and 1,073,741,824 scan visits, and limit fallback font names to 1,024 bytes
Reporting includes source/output SHA-256, replacement, fallback and scaling totals, and each object's original/final text and PDF user-space bounds in points; page and object indexes are zero-based source indexes
Text replacement is not a security redaction process; sensitive content and associated document data must be removed through the dedicated redaction APIs
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);
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;