Adicione FPdfStyledEdit e forneça um IPdfRegexEngine para planejar e executar substituições sobre objetos de texto nativos de nível superior
PlanStyledPdfRegexReplacements captura um snapshot de origem reproduzível, concatena os glifos Unicode reais na ordem de página e de objeto e mapeia as correspondências de volta para âncoras de objeto estáveis; espaços e quebras de linha gerados pela extração são excluídos
ExecuteStyledPdfReplacements valida o SHA-256 do snapshot, a identidade atual da origem, as âncoras e os intervalos sem sobreposição antes de alterar um documento carregado de forma independente
A identidade da origem usa serialização reproduzível, incluindo timestamps e identificadores normalizados, em vez dos bytes originais do arquivo; o plano guarda os bytes reais do snapshot e seu SHA-256
Fonte nativa, tamanho do texto, cor e matriz são reutilizados sempre que possível; substituições que atravessam objetos ou páginas mantêm o estilo do primeiro objeto e removem os caracteres consumidos dos objetos seguintes, preservando o texto restante e a ordem das páginas
FallbackFontName seleciona explicitamente uma fonte PostScript padrão quando o Unicode nativo não pode ser reproduzido; ForceFallbackFont solicita esse caminho diretamente
O fallback preserva a ordem do painter, a matriz, o modo de renderização e os atributos de fill e stroke; objetos com clip, transparência, marked content ou tags são rejeitados em vez de perder silenciosamente sua semântica gráfica
Texto mais largo do que seus limites de origem pode encolher horizontalmente quando sua matriz é vertical e sem cisalhamento; MinHorizontalScale tem padrão 0.5, e texto de substituição mais estreito mantém a matriz original
Este fluxo de trabalho suporta texto de substituição de linha única e ajuste horizontal com limites; ele não atravessa Form XObjects aninhados, não reescreve a semântica de Tagged PDF nem faz reflow de parágrafos
Documentos assinados ou criptografados e XFA são rejeitados; cancelamento, planos desatualizados, UTF-16 inválido, fontes não suportadas e orçamentos esgotados deixam o documento de quem chama inalterado
PreviewOnly retorna o resultado reaberto de forma independente em PreviewPdf sem substituir o documento de quem chama; o commit bem-sucedido substitui o documento somente depois que a extração de glifos e a contagem de páginas forem verificadas após salvar e reabrir
Todas as correspondências são montadas no texto final dos objetos antes de alterar os objetos nativos; o ajuste e a escala mínima são verificados uma única vez contra os limites originais, impedindo que correspondências repetidas acumulem encolhimento excessivo
Texto de substituição vazio remove um objeto de texto totalmente consumido após todas as edições ancoradas; várias substituições rodam de trás para frente, de modo que os offsets anteriores da origem permaneçam válidos
Os limites padrão são 256 MiB de bytes do documento, 10,000 páginas, 100,000 objetos de texto, 16,777,216 unidades UTF-16 e 100,000 substituições; o orçamento de trabalho da varredura de texto é de 67,108,864 visitas nativas a caracteres e unidades de cópia de planejamento UTF-16
Os máximos rígidos mantêm os limites de página, objeto, caractere e substituição, permitem 512 MiB de bytes do documento e 1,073,741,824 visitas de varredura, e restringem o nome da fonte de fallback a 1,024 bytes
O relatório inclui os valores de SHA-256 de origem e de saída, contagens de substituições aplicadas, fallbacks e escalonamentos, além do texto e dos limites originais/finais por objeto em pontos do user space PDF; os índices de página e de objeto são índices de origem de base zero
Uma operação de substituição não é um fluxo de redação (redaction) de segurança; use as APIs de redaction dedicadas para remover conteúdo sensível e os dados de documento associados
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;