ComparePdfSemantics jämför egenskaper hos annoteringar och AcroForm-widgets oberoende av sidrendering; formulärvärden kan ändras även när utseendepixlar förblir identiska
Skicka TPdfDiffPagePairs från sidjustering eller en explicit mappning; nil väljer positionella par, och explicita mappningar måste täcka båda dokumenten exakt en gång, med -1 för en saknad sida
Annoteringsidentitet använder sitt /NM-namn, och formulärwidget-identitet använder det fullständigt kvalificerade fältnamnet; identiteten är avgränsad till den mappade sidan och elementtypen
Saknade namn och upprepade namn, inklusive flera widgets av ett fält på samma sida, rapporteras som psckAmbiguous med en explicit orsak; annoteringsmatrisens ordning avgör inte identiteten
Den stödda profilen jämför strängar, flaggor, färger, opacitet, kantlinjer, markering, linje-, hörn- och blekkgeometri, URI-åtgärder, fältvärden, etiketter för val och valda alternativ, samt kryssrute- eller radiotillstånd
CompareAppearanceStreams jämför valfritt annoteringarnas utseendeströmsinnehåll; den är avstängd som standard
CompareAnnotations och CompareForms väljer respektive elementtyp; GeometryTolerance har 0.001 PDF-användarrymdpunkter som standard
Tillagda, borttagna och ändrade objekt inkluderar egenskaper och gränser före/efter; BuildSemanticDiffOverlays returnerar separata rektanglar före/efter med sid- och ändringsindex
Alla index är nollbaserade och gränserna förblir i PDF-användarrymd, i punkter; tillämpa sidans rotation, beskärning och viewport-transformering innan du ritar in i en bitmap
Sidor läses in med oberoende nativa handles, vilket bevarar anroparens aktuella sida och formulärfokus och undviker formuläråtgärder
Profilen utesluter icke-widget-fält, godtyckliga anpassade ordböcker, inbäddade filer, skriptåtgärder och icke-URI-mål; XFA-jämförelse avvisas explicit
Standardgränserna är 10,000 sidpar, 4,096 skannade objekt, 4,096 ändringar, 1 MiB per sträng, 16 MiB totala strängar och 16,777,216 jämförelser; en förbrukad budget avvisar ofullständig utdata
Complete skiljer en lyckad fullständig jämförelse från en avvisad jämförelse; dess ändringar kan innehålla explicit tvetydiga identiteter, så undersök AmbiguousCount innan du behandlar resultaten som en definitiv objektmatchning
Verklig Delphi/FPC Win32/Win64-godkännande omfattar 92 påståenden per mål, inklusive sparade/återöppnade dokument, värdeändringar med identiska pixlar, Unicode-identitet, sidflytt, tvetydighet och budgetar
Options := TPdfSemanticDiffOptions.Default; if not ComparePdfSemantics(BeforePdf, AfterPdf, PagePairs, Options, Report) then raise EPdfError.Create(Report.ErrorMessage); Overlays := BuildSemanticDiffOverlays(Report);
type
TPdfSemanticItemKind = (psikAnnotation, psikFormWidget);
TPdfSemanticChangeKind = (psckAdded, psckRemoved, psckChanged, psckAmbiguous);
TPdfSemanticSide = (pssBefore, pssAfter);
TPdfSemanticProperty = record
Name: string;
Value: WideString;
end;
TPdfSemanticProperties = array of TPdfSemanticProperty;
TPdfSemanticItem = record
Kind: TPdfSemanticItemKind;
Identity: WideString;
PageIndex, AnnotationIndex: Integer;
HasBounds: Boolean;
Bounds: TPdfRectangle;
Properties: TPdfSemanticProperties;
end;
TPdfSemanticPropertyChange = record
Name: string;
HasBefore, HasAfter: Boolean;
BeforeValue, AfterValue: WideString;
end;
TPdfSemanticPropertyChanges = array of TPdfSemanticPropertyChange;
TPdfSemanticChange = record
Kind: TPdfSemanticChangeKind;
ItemKind: TPdfSemanticItemKind;
Identity: WideString;
HasBefore, HasAfter: Boolean;
BeforeItem, AfterItem: TPdfSemanticItem;
Properties: TPdfSemanticPropertyChanges;
AmbiguityReason: string;
end;
TPdfSemanticChanges = array of TPdfSemanticChange;
TPdfSemanticOverlay = record
Side: TPdfSemanticSide;
PageIndex, ChangeIndex: Integer;
Kind: TPdfSemanticChangeKind;
Bounds: TPdfRectangle;
end;
TPdfSemanticOverlays = array of TPdfSemanticOverlay;
TPdfSemanticDiffOptions = record
CompareAnnotations, CompareForms, CompareAppearanceStreams: Boolean;
GeometryTolerance: Double;
MaxPagePairs, MaxItems, MaxChanges, MaxStringBytes: Integer;
MaxTotalStringBytes, MaxComparisons: Int64;
class function Default: TPdfSemanticDiffOptions; static;
end;
TPdfSemanticDiffReport = record
Complete: Boolean;
Changes: TPdfSemanticChanges;
AddedCount, RemovedCount, ChangedCount, AmbiguousCount: Integer;
ComparedItemCount: Integer;
ErrorMessage: string;
end;
// Indices are zero based. Nil PagePairs selects positional pairing. Explicit
// pairs must cover both documents exactly once; -1 denotes an absent side
// Identity is scoped to a mapped page and item kind. Missing names and repeated
// names (including repeated widgets of one field) are reported as ambiguous
// No rendering, focus changes, form actions, or positional identity guessing
// are performed. Pages are opened independently of the caller's current page
// The supported profile covers strings, flags, colors, opacity, borders,
// markup/line/vertex/ink geometry, URI actions, field values/options/checks,
// and optionally appearance streams. Arbitrary dictionaries, embedded files,
// script actions, non-URI destinations, and non-widget fields are not compared
function ComparePdfSemantics(BeforePdf, AfterPdf: TPdf;
const PagePairs: TPdfDiffPagePairs; const Options: TPdfSemanticDiffOptions;
out Report: TPdfSemanticDiffReport): Boolean;
// Bounds remain in PDF user space, in points. Transform with the destination
// page's rotation/crop/viewport rather than treating them as bitmap pixels
function BuildSemanticDiffOverlays(const Report: TPdfSemanticDiffReport):
TPdfSemanticOverlays;