ComparePdfSemantics vergelijkt eigenschappen van annotaties en AcroForm-widgets onafhankelijk van paginarendering; formuliervariabelen kunnen veranderen terwijl de appearance-pixels identiek blijven
Geef TPdfDiffPagePairs uit de pagina-uitlijning mee of een expliciete mapping; nil kiest positionele paren, en een expliciete mapping moet beide documenten precies één keer dekken, met -1 voor een ontbrekende kant
De identiteit van een annotatie is zijn /NM-naam, en die van een form widget de volledig gekwalificeerde veldnaam; de identiteit is begrensd tot de gemapte pagina en itemsoort
Ontbrekende namen en dubbele namen, inclusief meerdere widgets van één veld op dezelfde pagina, worden als psckAmbiguous gemeld met een expliciete reden; de volgorde in de annotatiearray bepaalt de identiteit niet
Het ondersteunde profiel vergelijkt strings, vlaggen, kleuren, dekking, randen, markup-, lijn-, hoekpunt- en inktgeometrie, URI-acties, veldwaarden, keuzelabels en geselecteerde opties, en de status van checkbox of radio
CompareAppearanceStreams vergelijkt optioneel de inhoud van appearance streams van annotaties; dit staat standaard uit
CompareAnnotations en CompareForms kiezen de bijbehorende itemsoorten; GeometryTolerance staat standaard op 0.001 PDF-user-space-punt
Toegevoegde, verwijderde en gewijzigde items bevatten before/after-eigenschappen en begrenzingen; BuildSemanticDiffOverlays geeft aparte before/after-rechthoeken met pagina- en wijzigingsindexen terug
Alle indexen zijn op 0 gebaseerd en begrenzingen blijven in PDF user space, in punten; pas de relevante paginarotatie, crop- en viewporttransformatie toe voordat je in een bitmap tekent
Pagina's worden met onafhankelijke native handles geladen, waarbij de huidige pagina en de formulierfocus van de aanroeper behouden blijven en formulieracties worden vermeden
Het profiel sluit niet-widget-velden, willekeurige custom dictionary's, ingesloten bestanden, scriptacties en niet-URI-bestemmingen uit; XFA-vergelijking wordt expliciet geweigerd
Standaardlimieten zijn 10,000 paginaparen, 4,096 gescande items, 4,096 wijzigingen, 1 MiB per string, 16 MiB aan strings totaal en 16,777,216 vergelijkingen; een uitgeput budget verwerpt onvolledige uitvoer
Complete onderscheidt een geslaagde volledige vergelijking van een geweigerde vergelijking; de wijzigingen kunnen expliciet dubbelzinnige identiteiten bevatten, dus bekijk AmbiguousCount voordat je de resultaten als definitieve itemmatch behandelt
Echte Delphi/FPC Win32/Win64-acceptatie omvat 92 asserties per doel, waaronder opgeslagen/heropende documenten, waardeveranderingen bij identieke pixels, Unicode-identiteit, paginaverplaatsing, dubbelzinnigheid en budgetten
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;