Export Data on an XFA form writes its data as Acrobat does: XML (the data alone, rooted at the form's root data node, its namespaces declared) or an XDP holding the whole datasets and a reference to the PDF (.xdp, a new format). Import Data takes an XDP, a datasets or data element, or a data document whose root is the form's root data node, and makes it the form's whole data, keeping data descriptions; a laid-out form is laid out again from it (rows added and removed) and its calculations run; XFDF, FDF and tables still go the AcroForm way. Undoable. Image fields are now buttons marked /PCXfaImage (no PDF action): the forms layer treats one as an image field, so clicking it (or form_set_image) picks a picture, which is kept in the data as base64 with its xfa:contentType, as Designer saves it, and the laid-out form shows it from there. xfa: replace_data, write_data_image (hostile content types cleaned, 32 MB cap), export_data, import_data (64 MB cap, the parser's node limit, self-closing data elements). engine: export routing by document kind, import routing by the file's root element, re-layout and calculation after the data changes outside the fields, the picture's content type from its bytes. UI: XML and XDP in the export dialog of an XFA form, .xdp in the import filter. Tool texts, README and parity (form.xfa-data) updated. Hardened after an adversarial review pass: the file's data is held as a tree and written with the packet's own namespace prefix (never its markup), every packet rewrite is parsed back before it is written, files capped at 16 MB and 64 levels (a tag scan before the recursive parser, also guarding the datasets parser), pictures at 8 MB and PNG/ JPEG/GIF only, the file's shape and root name checked, UTF-16 and ISO-8859-1 decoded, pictures into data groups refused, cleaned names for pictures, static forms empty the fields the file doesn't hold, more rows than the layout cap reported, one datasets stream per edit, and only image fields take pictures into the data. |
||
|---|---|---|
| .. | ||
| src | ||
| Cargo.toml | ||
| README.md | ||
README.md
pdfcraft-forms
Interactive forms (AcroForm, ISO 32000-2 §12.7). Layer L3; depends on pdfcraft-cos and
pdfcraft-fonts.
API
let all: Vec<Field> = fields(&doc); // terminal fields with widgets, options, flags, /DA
let snapshot = fields_with_adopted(&doc); // fields and page-only adoption count in one pass
let all = snapshot.items;
let adopted = snapshot.adopted_page_fields;
set_value(&mut doc, "name", &FieldValue::Text("Ada".into()))?;
set_value(&mut doc, "agree", &FieldValue::Check(true))?;
set_value(&mut doc, "size", &FieldValue::Radio(Some("L".into())))?;
set_value(&mut doc, "toppings", &FieldValue::Choice(vec!["Ham".into()]))?;
reset(&mut doc, None)?; // Clear form (back to /DV)
// Prepare a form
let name = add_field(&mut doc, 0, [72.0, 700.0, 216.0, 722.0], &NewField::Text { multiline: false }, None)?; // "Text1"
set_props(&mut doc, &name, &FieldProps { name: Some("email".into()), required: Some(true), ..Default::default() })?;
// A partial appearance edit keeps each widget's other styles and custom /DA font.
set_props(&mut doc, "email", &FieldProps {
appearance: Some(LookPatch { width: Some(3.0), fill: Some(None), ..Default::default() }),
..Default::default()
})?;
delete_field(&mut doc, "email")?;
Behaviour
- Inheritable attributes (
/FT,/Ff,/V,/DV,/DA,/Q,/MaxLen) are resolved down the field tree; the form's/DAand/Qare the last fallback. - Text and choice fields get new appearance streams (
/Tx BMC … EMC): auto-size (0 Tf), comb, multiline wrapping, password masking, quadding,/MKbackground and border, list-box selection. The/DAfont is used when/DRhas it as a simple font or a composite font with a predefined Unicode CMap; otherwise Helvetica (WinAnsi). A value or button caption the font can't hold (Chinese in a Helvetica field, a character beyond U+FFFF in a UCS-2 CMap) is kept, as Acrobat keeps it:/Vis stored as typed, the appearance draws?for those characters, the widget is marked with the first one (pdfcraft_fonts::UNDRAWN_MARK, cleared once all of it can be drawn) and the form sets/NeedAppearances, so other viewers draw the field from its value with fonts that have them. Not in a document that declares PDF/A, which forbids that flag (declares_pdfa).undrawn_fieldslists the marked fields; the engine reports each edit that draws one, and flattening refuses to make that?permanent. - Check boxes and radio buttons switch
/Vand each widget's/AS. Widgets with no appearances get PdfCraft's own (a drawn check mark or dot; no symbol font needed). - Values are validated (options,
MaxLen, single vs multi-select, NoToggleToOff, read-only) and a failed call changes nothing. FieldProps::appearanceapplies aLookPatchindependently to each widget.Nonekeeps a property;Some(None)removes a border/fill colour. Unchanged/DA, custom font resources, widget-specific/DAoverrides, indirect/MKand/BScontents, dash arrays and unknown dictionary keys are preserved. It is mutually exclusive with the completelookreplacement. Use the engine'sEdit::Batchto change several fields atomically in one undo step./RV(rich text) is removed when a value is set so it can't contradict/V.- New fields follow Acrobat: names Text1, Check Box1, Group1 (radio groups), Dropdown1, List Box1,
Button1, Date1, Signature1;
/Helvis added to/DR; appearances are drawn at once. Radio buttons joining a group become kid widgets with their own export state. Renaming changes only the last part of a dotted name.
Not yet
Rich-text values and exact appearance metrics/layout remain incomplete. JavaScript
execution and FDF/XFDF exchange are integrated through the engine; this crate provides
field actions and native AF rules. /MK /R rotation (0, 90, 180, 270) is drawn into the
appearance.