PDFium Delphi Component Docs

مقارنة دلالية للتعليقات التوضيحية والنماذج

تقارن ComparePdfSemantics خصائص التعليقات و widgets الخاصة بـ AcroForm مستقلة عن تصيير الصفحات؛ قد تتغير قيمة النموذج مع بقاء بكسلات مظهره متطابقة

مرر TPdfDiffPagePairs الناتجة عن المحاذاة أو خريطة صريحة؛ تختار nil الأزواج بحسب الموقع، ويجب أن تغطي الخريطة كل مستند مرة واحدة، مع -1 للجانب الغائب

تعتمد هوية التعليق على اسم /NM وهوية widget على اسم الحقل الكامل؛ تنحصر الهوية في الصفحة المطابقة ونوع العنصر

تُبلغ الأسماء المفقودة أو المكررة، بما فيها widgets متعددة لحقل واحد على الصفحة نفسها، بوصف psckAmbiguous مع سبب صريح؛ لا يحدد ترتيب مصفوفة التعليقات الهوية

يقارن النطاق المدعوم النصوص والأعلام والألوان والعتامة والحدود والعلامات وهندسة الخطوط والرؤوس والحبر وإجراءات URI وقيم الحقول وتسميات الخيارات وتحديدها وحالة checkbox أو radio

تقارن CompareAppearanceStreams محتوى تدفقات مظهر التعليقات اختياريًا؛ وهي معطلة افتراضيًا

تختار CompareAnnotations و CompareForms أنواع العناصر؛ القيمة الافتراضية لـ GeometryTolerance هي 0.001 نقطة في فضاء مستخدم PDF

تتضمن العناصر المضافة والمحذوفة والمعدلة الخصائص والحدود قبل وبعد؛ تعيد BuildSemanticDiffOverlays مستطيلات منفصلة للحالتين مع فهارس الصفحات والتغييرات

تبدأ كل الفهارس من الصفر، وتظل الحدود بنقاط فضاء مستخدم PDF؛ طبّق دوران الصفحة وقصها وتحويل viewport المناسب قبل الرسم في bitmap

تُحمل الصفحات بمقابض أصلية مستقلة، مع الحفاظ على الصفحة الحالية وتركيز النموذج وتجنب تشغيل إجراءاته

لا يشمل النطاق الحقول بلا widget أو القواميس المخصصة الاعتباطية أو الملفات المضمنة أو إجراءات السكربت أو الوجهات غير URI؛ تُرفض مقارنة XFA صراحة

الحدود الافتراضية 10,000 زوج صفحات و 4,096 عنصرًا مفحوصًا و 4,096 تغييرًا و 1 MiB لكل نص و 16 MiB للنصوص إجمالًا و 16,777,216 مقارنة؛ يرفض استنفاد الميزانية نتيجة غير مكتملة

تميز Complete المقارنة الكاملة الناجحة عن المرفوضة؛ قد تحتوي النتيجة هويات ملتبسة صريحة، لذا افحص AmbiguousCount قبل اعتبار المطابقة نهائية

يغطي القبول الفعلي بـ Delphi/FPC على Win32/Win64 ‏92 assertion لكل هدف، بما في ذلك الحفظ وإعادة الفتح وتغير القيم مع بكسلات متطابقة وهويات Unicode ونقل الصفحات والالتباس والميزانيات

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;