Подключите FPdfStyledEdit и передайте IPdfRegexEngine, чтобы планировать и выполнять замены в нативных top-level текстовых объектах
PlanStyledPdfRegexReplacements захватывает воспроизводимый снимок источника, склеивает фактические глифы Unicode в порядке страниц и объектов и привязывает совпадения к стабильным якорям объектов; сгенерированные извлечением пробелы и разрывы строк исключаются
ExecuteStyledPdfReplacements проверяет SHA-256 снимка, текущую идентичность источника, якоря и неперекрывающиеся интервалы до изменения независимо загруженного документа
Идентичность источника строится на воспроизводимой сериализации, включая нормализованные метки времени и идентификаторы, а не на исходных байтах файла; план хранит фактические байты снимка и их SHA-256
Нативные шрифт, размер текста, цвет и матрица переиспользуются, где возможно; замены, охватывающие объекты или страницы, сохраняют стиль первого объекта и удаляют потреблённые символы из последующих, сохраняя остальной текст и порядок страниц
FallbackFontName явно выбирает стандартный шрифт PostScript, когда нативный Unicode воспроизвести нельзя; ForceFallbackFont запрашивает этот путь напрямую
Fallback сохраняет порядок отрисовки, матрицу, режим рендеринга, атрибуты заливки и обводки; обрезанные, прозрачные, маркированные или тегированные объекты отклоняются, а не молча теряют графическую семантику
Текст шире исходных границ может сжиматься по горизонтали, когда его матрица прямая и без сдвига; MinHorizontalScale по умолчанию 0.5, а более узкий замещающий текст сохраняет исходную матрицу
Этот рабочий процесс поддерживает однострочный замещающий текст и ограниченную горизонтальную подгонку; он не обходит вложенные Form XObject, не переписывает семантику Tagged PDF и не выполняет перевёрстку абзацев
Подписанные или зашифрованные документы и XFA отклоняются; отмена, устаревшие планы, недопустимый UTF-16, неподдерживаемые шрифты и исчерпанные бюджеты оставляют документ вызывающего без изменений
PreviewOnly возвращает независимо переоткрытый результат в PreviewPdf, не заменяя документ вызывающего; успешная фиксация заменяет документ только после проверки извлечения глифов и количества страниц после сохранения и повторного открытия
Все совпадения собираются в итоговый текст объекта до изменения нативных объектов; подгонка и минимальный масштаб проверяются один раз по исходным границам, поэтому повторные совпадения не накапливают чрезмерное сжатие
Пустой замещающий текст удаляет полностью потреблённый текстовый объект после всех привязанных правок; множественные замены выполняются в обратном порядке, поэтому ранние смещения источника остаются корректными
Лимиты по умолчанию: 256 МиБ байтов документа, 10 000 страниц, 100 000 текстовых объектов, 16 777 216 единиц UTF-16 и 100 000 замен; бюджет работы сканера текста — 67 108 864 нативных посещений символов и единиц копии планирования UTF-16
Жёсткие максимумы сохраняют лимиты страниц, объектов, символов и замен, допускают 512 МиБ байтов документа и 1 073 741 824 посещения сканирования и ограничивают имя fallback-шрифта 1 024 байтами
Отчёт включает SHA-256 источника и вывода, счётчики применённых замен, fallback-шрифтов и масштабирований, а также исходный/итоговый текст и границы каждого объекта в пунктах пользовательского пространства PDF; индексы страниц и объектов — нуль-базированные индексы источника
Операция замены — не рабочий процесс защитного редактирования (redaction); для удаления чувствительного содержимого и связанных данных документа используйте специализированные API redaction
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;