PDFium Delphi Component Docs

事务式保留样式文本替换

添加 FPdfStyledEdit,并提供 IPdfRegexEngine,即可针对原生顶层文本对象规划和执行替换

PlanStyledPdfRegexReplacements 捕获可重现的源快照,按页面和对象顺序连接实际 Unicode 字形,再将匹配映射回稳定对象锚点;不计入提取时额外生成的空格和换行

ExecuteStyledPdfReplacements 修改独立加载的文档前,先验证快照 SHA-256、当前源身份、锚点和互不重叠的区间

源身份基于可重现的序列化,包含规范化时间戳和标识,不以原始文件字节为准;计划保存实际快照字节及其 SHA-256

尽可能复用原生字体、字号、颜色和矩阵;跨对象或跨页替换保留首对象样式,删除后续对象中被消耗的字符,同时保留剩余文本和页面顺序

原生 Unicode 无法重现时,FallbackFontName 明确指定标准 PostScript 后备字体;ForceFallbackFont 可直接请求此路径

后备处理保留绘制顺序、矩阵、渲染模式、填充和描边属性;裁剪、透明、带标记或 tagged 的对象会被拒绝,避免悄悄丢失图形语义

文本宽于源边界时,若矩阵正立且无剪切,可水平缩小;MinHorizontalScale 默认为 0.5,较窄的替换文本保留原矩阵

该工作流支持单行替换和受限水平适配,不遍历嵌套 Form XObjects,不重写 Tagged PDF 语义,也不进行段落重排

拒绝已签名或加密文档及 XFA;取消、过期计划、无效 UTF-16、不支持字体或预算耗尽均保留调用方文档

PreviewOnly 在 PreviewPdf 中返回独立重新打开的结果,不替换调用方文档;只有保存并重新打开后验证了字形提取和页数,成功提交才会替换文档

修改原生对象前,先将所有匹配组装为最终对象文本;只针对原始边界检查一次适配和最小缩放,防止重复匹配累计过度缩小

所有锚定编辑完成后,空替换文本会删除已完全消耗的文本对象;多项替换从后向前执行,保证较早的源偏移仍然有效

默认上限为 256 MiB 文档字节、10,000 页、100,000 个文本对象、16,777,216 个 UTF-16 单元和 100,000 次替换;文本扫描工作预算为 67,108,864 次原生字符访问及 UTF-16 规划复制单元

硬上限保持上述页面、对象、字符和替换限制,允许 512 MiB 文档字节和 1,073,741,824 次扫描访问,并将后备字体名称限制为 1,024 字节

报告包含源和输出 SHA-256、已应用替换/后备/缩放计数,以及每对象原始和最终文本及 PDF 用户空间点边界;页面和对象索引均为从零开始的源索引

替换操作不是安全擦除工作流;敏感内容及相关文档数据的移除应使用专门的擦除 API

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;