PDFium Delphi Component Docs

Semantischer Vergleich von Annotationen und Formularen

ComparePdfSemantics vergleicht Annotationen und AcroForm-Widgets unabhängig vom Seitenrendering; Formularwerte können sich bei identischen Darstellungspixeln ändern

Übergeben Sie TPdfDiffPagePairs aus der Seitenausrichtung oder eine explizite Zuordnung; nil verwendet Positionspaare; explizite Zuordnungen müssen beide Dokumente genau einmal abdecken, mit -1 für eine fehlende Seite

Die Identität einer Annotation folgt ihrem /NM-Namen, die eines Widgets dem vollständig qualifizierten Feldnamen; sie gilt innerhalb der zugeordneten Seite und Elementart

Fehlende und wiederholte Namen, auch mehrere Widgets eines Felds auf derselben Seite, werden mit expliziter Begründung als psckAmbiguous gemeldet; die Reihenfolge im Annotationenarray bestimmt keine Identität

Das unterstützte Profil vergleicht Strings, Flags, Farben, Deckkraft, Rahmen, Markierungen, Linien-, Vertex- und Freihandgeometrie, URI-Aktionen, Feldwerte, Auswahllabels und Optionen sowie Checkbox- und Radiobuttonzustände

CompareAppearanceStreams vergleicht optional den Inhalt von Annotationsdarstellungsstreams; standardmäßig deaktiviert

CompareAnnotations und CompareForms wählen die Elementarten; GeometryTolerance beträgt standardmäßig 0.001 Punkte im PDF-Benutzerraum

Hinzugefügte, entfernte und geänderte Elemente enthalten Eigenschaften und Grenzen davor/danach; BuildSemanticDiffOverlays liefert separate Vorher-/Nachherrechtecke mit Seiten- und Änderungsindizes

Alle Indizes beginnen bei null, Grenzen bleiben in PDF-Benutzerraumpunkten; wenden Sie Seitenrotation, Beschnitt und Viewporttransformation an, bevor Sie in ein Bitmap zeichnen

Seiten werden mit unabhängigen nativen Handles geladen, erhalten aktuelle Seite und Formularfokus des Aufrufers und lösen keine Formularaktionen aus

Das Profil umfasst keine Felder ohne Widget, beliebigen eigenen Dictionaries, eingebetteten Dateien, Skriptaktionen oder Nicht-URI-Ziele; XFA-Vergleich wird explizit abgelehnt

Standardlimits sind 10,000 Seitenpaare, 4,096 untersuchte Elemente, 4,096 Änderungen, 1 MiB pro String, 16 MiB Strings insgesamt und 16,777,216 Vergleiche; ein erschöpftes Budget verwirft unvollständige Ergebnisse

Complete unterscheidet einen vollständigen erfolgreichen Vergleich von einem abgelehnten; Änderungen können explizit mehrdeutige Identitäten enthalten, prüfen Sie daher AmbiguousCount vor einer endgültigen Elementzuordnung

Die reale Delphi/FPC-Win32/Win64-Abnahme umfasst 92 Assertions pro Ziel, darunter gespeicherte/wiedergeöffnete Dokumente, Wertänderungen bei identischen Pixeln, Unicode-Identität, Seitenverschiebung, Mehrdeutigkeit und Budgets

Options := TPdfSemanticDiffOptions.Default;
if not ComparePdfSemantics(BeforePdf, AfterPdf, PagePairs, Options, Report) then
  raise EPdfError.Create(Report.ErrorMessage);
Overlays := BuildSemanticDiffOverlays(Report);

Öffentliche Deklarationen

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;