XFA: flatten a form into a plain PDF, or convert it to a static form (#1948)

Flattening the fields of a laid-out XFA form used to leave the XFA in
the file: Adobe's viewers then laid the form out again from the
template over the baked pages, so the "flattened" PDF was still a live
form there and a plain one everywhere else.

pdfcraft_xfa::strip takes the XFA out of a document: the packets
(template, data and all), /NeedsRendering on the catalog and the
AcroForm, the layout mark, the overrides, and the private keys on
every field down the tree. The engine calls it after Flatten form
fields on a document with XFA packets, so the result is a plain PDF
every viewer shows the same, and for the new Edit::XfaToStatic
("Convert to a static form"; tool xfa_to_static), which keeps the
laid-out pages and the fields with their values as an ordinary
AcroForm that no viewer lays out again and whose scripts no longer
run. Both undoable: the engine's post-edit refresh re-reads the
layout mark to drop or restore its XFA state and the cached template.

What the packets held beyond the fields is reported (packets by
name, data no field showed, buttons left inert, the layout's own
warnings, Reader usage rights) as document warnings, and a dynamic
form that was never laid out is refused rather than left with
nothing. Applying redactions shares the same strip. Closes the last
planned XFA parity entry (form.xfa-flatten shipped).
This commit is contained in:
ysrdevs
2026-10-15 02:32:04 -04:00
committed by GitHub
parent 9f0ed4ba86
commit e8d1980ded
13 changed files with 596 additions and 45 deletions
+5 -5
View File
@@ -5241,11 +5241,11 @@ title = "Flatten XFA forms"
area = "F"
tier = "P2"
milestone = "M12"
status = "planned"
commands = []
tools = []
evidence = []
notes = ""
status = "shipped"
commands = ["form.flatten"]
tools = ["doc_flatten", "xfa_to_static"]
evidence = ["crates/xfa/src/tests.rs::stripping_takes_the_xfa_out_and_leaves_an_ordinary_document", "crates/engine/src/tests.rs::flattening_an_xfa_form_bakes_its_pages_and_takes_the_xfa_out", "crates/engine/src/tests.rs::an_xfa_form_converts_to_a_static_form_that_keeps_its_fields", "crates/automation/tests/automation.rs::xfa_forms_flatten_and_convert_to_static_through_tools"]
notes = "Flatten form fields on a laid-out XFA form bakes the fields into the pages and takes the XFA out (packets, /NeedsRendering, PdfCraft's private keys), so every viewer, Adobe's included, shows the baked pages rather than laying the form out again from the template. xfa_to_static (tool and engine edit) keeps the laid-out pages and the fields with their values as an ordinary AcroForm whose scripts no longer run. Both undoable until saved. Missing: a menu entry for the conversion (the tool and the MCP server have it); flattening keeps the layout as PdfCraft laid it out, not as Acrobat would (form.xfa-dynamic)"
[[feature]]
id = "form.fill-sign-text"