PDFium Delphi Component Docs

Semantische vergelijking van annotaties en formulieren

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);

Public declarations

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;