FPdfStyledEdit와 IPdfRegexEngine을 추가해 네이티브 최상위 텍스트 객체의 교체를 계획하고 실행합니다
PlanStyledPdfRegexReplacements는 재현 가능한 원본 스냅샷을 얻고 실제 Unicode glyph를 페이지와 객체 순서로 연결한 뒤 일치를 안정된 객체 앵커로 되돌려 연결합니다. 추출 과정에서 만든 공백과 줄바꿈은 제외합니다
ExecuteStyledPdfReplacements는 독립적으로 로드한 문서를 바꾸기 전에 스냅샷 SHA-256, 현재 원본 식별, 앵커, 겹치지 않는 구간을 검증합니다
원본 식별에는 실제 파일 바이트가 아니라 시각과 식별자를 정규화한 재현 가능한 직렬화를 사용합니다. 계획에는 실제 스냅샷 바이트와 SHA-256을 저장합니다
가능하면 네이티브 폰트, 글자 크기, 색상, 행렬을 재사용합니다. 여러 객체나 페이지에 걸친 교체는 첫 객체의 스타일을 쓰고 뒤 객체에서 소비한 문자만 제거해 남은 텍스트와 페이지 순서를 유지합니다
FallbackFontName은 네이티브 Unicode를 재현할 수 없을 때 쓸 표준 PostScript 폰트를 명시합니다. ForceFallbackFont는 이 경로를 직접 요청합니다
fallback은 그리기 순서, 행렬, 렌더링 모드, 채우기와 선 속성을 유지합니다. clip, 투명, marked, tagged 객체는 그래픽 의미를 조용히 잃지 않고 거부합니다
원본 경계보다 넓은 텍스트는 행렬이 똑바르고 shear가 없으면 수평 축소할 수 있습니다. MinHorizontalScale 기본값은 0.5이며 더 좁은 교체 텍스트는 원본 행렬을 유지합니다
단일 행 교체와 상한이 있는 수평 맞춤을 지원합니다. 중첩 Form XObject 탐색, Tagged PDF 의미 재작성, 문단 reflow는 수행하지 않습니다
서명 또는 암호화된 문서와 XFA를 거부합니다. 취소, 오래된 계획, 잘못된 UTF-16, 지원하지 않는 폰트, 상한 초과는 호출자의 문서를 그대로 둡니다
PreviewOnly는 호출자의 문서를 교체하지 않고 독립적으로 다시 연 결과를 PreviewPdf에 반환합니다. 성공한 commit도 저장/재열기 후 glyph 추출과 페이지 수를 검증한 뒤 문서를 교체합니다
네이티브 객체를 바꾸기 전에 모든 일치를 최종 객체 텍스트로 조립합니다. 맞춤과 최소 비율은 원본 경계에서 한 번만 검사해 반복된 일치가 지나친 축소를 누적하지 않게 합니다
빈 교체 텍스트로 완전히 소비된 객체는 모든 앵커 편집 뒤에 제거합니다. 여러 교체는 역순으로 실행해 앞쪽 원본 오프셋을 유지합니다
기본 상한은 문서 256 MiB, 10,000페이지, 텍스트 객체 100,000개, UTF-16단위 16,777,216개, 교체 100,000회입니다. 텍스트 스캔 작업은 네이티브 문자 방문과 UTF-16 계획 복사의 합계 67,108,864단위까지입니다
하드 상한도 페이지, 객체, 문자, 교체는 같으며 문서는 512 MiB, 스캔 방문은 1,073,741,824회까지입니다. fallback 폰트 이름은 1,024바이트로 제한합니다
보고는 원본/출력 SHA-256, 적용한 교체/fallback/축소 수, 객체별 원본/최종 텍스트와 PDF 사용자 공간 포인트 경계를 포함합니다. 페이지와 객체 번호는 0부터 시작하는 원본 번호입니다
텍스트 교체는 보안 영구 삭제 작업이 아닙니다. 민감한 콘텐츠와 관련 문서 데이터 제거에는 전용 영구 삭제 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;