|
רושם חבילת XFA (XML Forms Architecture) בעלת שם לצורך פליטה בתוך ערך AcroForm /XFA של המסמך. PDF 1.7 §12.7.6 + §12.7.8 מאפשר ל-AcroForm לשאת מערך /XFA לצד, או במקום, מערך /Fields סטטי, ובכך לאפשר תהליכי AcroForm + XFA היברידיים או טפסי XFA דינמיים טהורים
Delphi syntax:
procedure AddXFAPacket(const PacketName: AnsiString; const XMLBytes: TBytes);
procedure ClearXFAPackets;
function XFAPacketCount: Integer;
תיאור
כל קריאה ל-AddXFAPacket רושמת חבילה אחת בעלת שם. שמות טיפוסיים, לפי מפרט XFA 3.3 ו-PDF 1.7 §12.7.8 Table 234:
template - form layout + scripts (the largest packet in most XFA documents).
datasets - data binding (the XML payload the template renders against).
config - viewer configuration.
connectionSet - external data connections.
localeSet - locale-specific formatting rules.
stylesheet - XSLT or CSS styling.
xfdf - XFDF form data overlay.
xmpmeta - XMP metadata.
signature - signature-related XFA data.
sourceSet - source-side data definitions.
ב-EndDoc כל חבילה רשומה הופכת לאובייקט stream indirect דחוס FlateDecode, ומערך AcroForm /XFA מחליף לסירוגין מחרוזות PDF של packet-name והפניות stream לפי סדר הרישום, כך שה-layout דטרמיניסטי ברמת byte. ClearXFAPackets מסיר את כל החבילות הרשומות, שימושי לשימוש חוזר במופע THotPDF על פני כמה מסמכים. XFAPacketCount מחזיר את הספירה הנוכחית
Container-level support only
HotPDF אינה מנתחת את XFA XML, אינה מממשת את מנוע dynamic-layout של XFA, אינה מריצה FormCalc או JavaScript בתוך XFA template, ואינה מאמתת את מבנה ה-template. הקורא כותב את XFA XML בעצמו, בדרך כלל באמצעות Adobe LiveCycle Designer או כתיבה ידנית מול מפרט XFA 3.3, ו-HotPDF פולטת את ה-bytes כפי שהם
קוראי צריכה עם מנוע XFA, כמו Acrobat / Reader ישנים, FormsCentral ומוצרי kiosk מסוימים, מרנדרים את הטופס; קוראים ללא מנוע XFA, כמו Adobe Reader DC מ-2017 ואילך ורוב הקוראים בקוד פתוח, מציגים את שדות AcroForm fallback אם המסמך הוא תהליך AcroForm + XFA היברידי
PDF/A and PDF/X compliance gates
ISO 19005-1 §6.4.2 / ISO 19005-2 §6.4.2 / ISO 19005-3 §6.4.2 אוסרים במפורש טפסי XFA, משום שמנוע dynamic-layout אינו ניתן לארכוב דטרמיניסטי. תהליכי prepress של ISO 15930 דוחים טפסים אינטראקטיביים לחלוטין. AddXFAPacket מעלה חריגה מיד תחת כל PDFACompliance או PDFXCompliance שאינם ריקים, עם הפניית spec רלוונטית. שמות packet כפולים מעלים חריגה. PacketName ריק או XMLBytes ריק מעלים חריגה. RequirePDFVersion(pdf15) מעלה אוטומטית את גרסת המסמך
AcroForm dictionary emission
מילון AcroForm נפלט כאשר ל-/Fields יש לפחות entry אחד או כאשר לפחות חבילת XFA אחת נרשמה. קוראים לפני v2.119.51 שאינם רושמים חבילות שומרים על פלט /AcroForm זהה ברמת byte
Typical workflow (pure XFA dynamic form)
PDF.BeginDoc;
TemplateBytes := TFile.ReadAllBytes('form-template.xml');
DataBytes := TFile.ReadAllBytes('form-data.xml');
PDF.AddXFAPacket('xdp:xdp', BytesOf('<xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">'));
PDF.AddXFAPacket('template', TemplateBytes);
PDF.AddXFAPacket('datasets', DataBytes);
PDF.AddXFASignaturePacket(SigBytes); { caller-generated XAdES }
PDF.AddXFAPacket('/xdp:xdp', BytesOf('</xdp:xdp>'));
PDF.EndDoc;
XDP wrapper, single-stream, dynamic, and signed XFA
The array /XFA form must open and close with xdp:xdp wrapper packets, as the example now shows (ISO 32000-1 §12.7.8). Related XFA APIs: SetXFADocument writes the whole XFA/XDP document as a single /XFA stream, mutually exclusive with AddXFAPacket; XFANeedsRendering sets the Catalog /NeedsRendering flag (ISO 32000-1 §7.7.2) so a viewer regenerates a dynamic XFA form on first open; AddXFASignaturePacket embeds a caller-generated XAdES / XML-DSig signature as the signature packet. HotPDF never generates or parses the signature - the caller produces it with an XML cryptographic library over the XFA datasets.
XFA-to-AcroForm flattening
ApplyXFAAsAcroForm ממפה bytes של XDP/XFA שסופקו על ידי הקורא אל העמוד הנוכחי כ-native AcroForm widgets וגרפיקת עמוד פשוטה. FlattenLoadedXFA מבצע את אותה המרה עבור PDF טעון שכבר נושא חבילת /XFA מוטמעת. העבר Editable=False כדי להפוך widgets שנוצרו ל-read-only, ובדוק XFAFlattenWarnings עבור רכיבים שלא ניתן היה למפות
See also: AcroForm Support, THotPDF.RegisterAcroFormFont, THPDFPage.AddTextField
|