PDFium Delphi Component Docs

Confronto semantico di annotazioni e form

ComparePdfSemantics confronta proprietà delle annotazioni e dei widget AcroForm indipendentemente dal rendering della pagina; i valori dei form possono cambiare anche a parità di pixel dell'aspetto

Passare TPdfDiffPagePairs dall'allineamento delle pagine o una mappatura esplicita; nil sceglie coppie per posizione e le mappature esplicite devono coprire entrambi i documenti esattamente una volta, usando -1 per il lato mancante

L'identità di un'annotazione usa il nome /NM e quella di un widget il nome completo del campo; l'identità è circoscritta alla pagina mappata e al tipo di elemento

Nomi mancanti o ripetuti, inclusi più widget dello stesso campo sulla stessa pagina, vengono segnalati come psckAmbiguous con un motivo esplicito; l'ordine dell'array delle annotazioni non determina l'identità

Il profilo supportato confronta stringhe, flag, colori, opacità, bordi, markup, geometria di linee, vertici e ink, azioni URI, valori dei campi, etichette di scelta, opzioni selezionate e stato di checkbox o radio

CompareAppearanceStreams confronta opzionalmente il contenuto degli stream di aspetto delle annotazioni; è disabilitato per impostazione predefinita

CompareAnnotations e CompareForms selezionano i rispettivi tipi di elementi; GeometryTolerance vale per impostazione predefinita 0.001 punti nello spazio utente PDF

Elementi aggiunti, rimossi e modificati includono proprietà e limiti prima e dopo; BuildSemanticDiffOverlays restituisce rettangoli prima e dopo separati con indici di pagina e modifica

Tutti gli indici sono a base zero e i limiti restano nello spazio utente PDF, in punti; prima di disegnare su un bitmap applicare rotazione, ritaglio e trasformazione del viewport della pagina interessata

Le pagine vengono caricate con handle nativi indipendenti, mantenendo pagina corrente e focus del form del chiamante ed evitando azioni dei form

Il profilo esclude campi senza widget, dizionari personalizzati arbitrari, file incorporati, azioni script e destinazioni non URI; il confronto XFA è rifiutato esplicitamente

I limiti predefiniti sono 10,000 coppie di pagine, 4,096 elementi esaminati, 4,096 modifiche, 1 MiB per stringa, 16 MiB di stringhe totali e 16,777,216 confronti; esaurire un limite fa rifiutare l'output incompleto

Complete distingue un confronto completo riuscito da uno rifiutato; le modifiche possono includere identità esplicitamente ambigue, quindi controllare AmbiguousCount prima di trattare il risultato come un abbinamento definitivo

L'accettazione reale Delphi/FPC Win32/Win64 copre 92 asserzioni per destinazione, inclusi documenti salvati e riaperti, valori modificati con pixel identici, identità Unicode, spostamenti di pagine, ambiguità e limiti

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

Dichiarazioni pubbliche

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;