加入 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;