Ajoutez FPdfStyledEdit et fournissez un IPdfRegexEngine pour planifier et exécuter les remplacements dans les objets texte natifs de premier niveau
PlanStyledPdfRegexReplacements capture un instantané reproductible de la source, concatène les glyphes Unicode réels dans l’ordre des pages et des objets, puis rattache les correspondances à des ancrages d’objet stables ; les espaces et sauts de ligne générés par l’extraction sont exclus
ExecuteStyledPdfReplacements vérifie le SHA-256 de l’instantané, l’identité de la source actuelle, les ancrages et l’absence de chevauchement des intervalles avant de modifier un document chargé indépendamment
L’identité de la source repose sur une sérialisation reproductible, avec horodatages et identifiants normalisés, plutôt que sur les octets du fichier d’origine ; le plan conserve les octets réels de l’instantané et leur SHA-256
La police native, la taille du texte, sa couleur et sa matrice sont réutilisées lorsque possible ; les remplacements couvrant plusieurs objets ou pages gardent le style du premier objet et retirent les caractères consommés des suivants, en conservant le reste du texte et l’ordre des pages
FallbackFontName choisit explicitement une police PostScript standard lorsque l’Unicode natif ne peut pas être reproduit ; ForceFallbackFont demande directement ce traitement
La police de secours préserve l’ordre de dessin, la matrice, le mode de rendu et les attributs de remplissage et de contour ; les objets découpés, transparents, marqués ou balisés sont refusés pour éviter de perdre silencieusement leur sémantique graphique
Un texte plus large que ses limites source peut être réduit horizontalement si sa matrice est droite et sans cisaillement ; MinHorizontalScale vaut par défaut 0.5 et un remplacement plus étroit conserve la matrice d’origine
Ce traitement accepte un remplacement sur une seule ligne avec ajustement horizontal borné ; il ne parcourt pas les Form XObjects imbriqués, ne réécrit pas la sémantique Tagged PDF et ne réorganise pas les paragraphes
Les documents signés ou chiffrés et XFA sont refusés ; une annulation, un plan périmé, un UTF-16 invalide, une police non prise en charge ou un budget épuisé laisse le document appelant intact
PreviewOnly renvoie le résultat rouvert indépendamment dans PreviewPdf sans remplacer le document appelant ; la validation réussie ne remplace le document qu’après vérification de l’extraction des glyphes et du nombre de pages après enregistrement et réouverture
Toutes les correspondances sont assemblées en texte final avant de modifier les objets natifs ; l’ajustement et l’échelle minimale ne sont vérifiés qu’une fois par rapport aux limites originales, évitant une réduction excessive cumulée
Un remplacement vide supprime un objet texte entièrement consommé après toutes les modifications ancrées ; plusieurs remplacements sont appliqués en sens inverse pour maintenir les décalages source précédents
Les limites par défaut sont de 256 MiB de document, 10,000 pages, 100,000 objets texte, 16,777,216 unités UTF-16 et 100,000 remplacements ; le budget de parcours est de 67,108,864 visites de caractères natifs et unités UTF-16 copiées pour la planification
Les plafonds conservent ces limites de pages, objets, caractères et remplacements, autorisent 512 MiB de document et 1,073,741,824 visites, et limitent le nom de la police de secours à 1,024 octets
Le rapport comprend les SHA-256 source et sortie, les nombres de remplacements, recours à une police de secours et ajustements, ainsi que le texte original/final et les limites de chaque objet en points PDF ; les indices source de page et d’objet commencent à zéro
Un remplacement n’est pas une procédure de caviardage de sécurité ; utilisez les API de caviardage dédiées pour retirer les contenus sensibles et les données associées du document
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;