Merge #815: fix(pdf): leave form fields and media out of PDF/A-2b exports (#743)

This commit is contained in:
aiongg
2026-10-13 19:03:42 +00:00
3 changed files with 32 additions and 2 deletions
+5 -1
View File
@@ -244,12 +244,16 @@ pub fn export_pdf_with_report(doc: &Document, cache: &Cache, opts: &PdfOptions)
// group that got past it, with its page.
crate::pdfx::cmyk_group_spaces(&mut bytes);
}
// Form fields (Buttons and Forms) and, for interactive PDF, video and sound; not in PDF/X.
// Form fields (Buttons and Forms) and, for interactive PDF, video and sound; not in PDF/X
// or PDF/A: this update comes after krilla's validator ran, and its NeedAppearances fields and
// Screen annotations aren't allowed in PDF/A.
let fields = crate::forms::collect(doc, &sheets);
let media = if opts.media { crate::forms::collect_media(doc, &sheets) } else { Vec::new() };
if !fields.is_empty() || !media.is_empty() {
if opts.standard == Standard::PdfX4 {
warnings.push("PDF/X-4: form fields and media were left out".into());
} else if opts.standard == Standard::PdfA2b {
warnings.push("PDF/A-2b: form fields and media were left out".into());
} else {
match crate::forms::add_fields(&bytes, &fields, &media) {
Some(b) => bytes = b,
+26
View File
@@ -478,6 +478,32 @@ fn stroke_behind_fill_strokes_the_run_before_filling_it() {
assert_eq!(text.trim(), "I", "the text is not duplicated");
}
#[test]
fn pdfa_leaves_out_form_fields_added_after_validation() {
let mut d = doc_with_text("Archive me");
let lid = d.default_layer();
let id = ItemId(d.alloc());
let mut b = Item::new(id, lid, designcraft_doc::Shape::Rectangle, designcraft_geom::shapes::rectangle(Rect::new(36.0, 400.0, 200.0, 430.0)));
b.form_field = Some(designcraft_doc::FormField {
kind: designcraft_doc::FieldKind::TextField,
name: "name".into(),
value: String::new(),
options: Vec::new(),
multiline: false,
required: false,
font_size: 0.0,
});
d.insert_item(SpreadRef::Doc(0), b, None).unwrap();
let plain = export_pdf(&d, &Cache::new(), &PdfOptions::default()).unwrap();
assert!(String::from_utf8_lossy(&plain).contains("/AcroForm"), "control: a plain export has the field");
let opts = PdfOptions { standard: Standard::PdfA2b, created: Some(1_700_000_000), ..Default::default() };
let a = export_pdf_with_report(&d, &Cache::new(), &opts).unwrap();
let text = String::from_utf8_lossy(&a.bytes).to_string();
assert!(text.contains("pdfaid"));
assert!(!text.contains("/AcroForm") && !text.contains("NeedAppearances"), "PDF/A must not get the form update");
assert!(a.warnings.iter().any(|w| w.contains("PDF/A-2b") && w.contains("left out")), "{:?}", a.warnings);
}
#[test]
fn missing_glyphs_print_as_boxes() {
// Source Serif 4 lacks 語: its .notdef box is drawn as a path, not as a .notdef glyph
+1 -1
View File
@@ -365,7 +365,7 @@ It is evidence of breadth: each item exists. It is not a claim of InDesign-level
- Cell strokes: with cells selected (or the cursor in a cell) the Stroke panel edits the chosen cell edges, picked on a drawn edge proxy (top, bottom, left, right, inner horizontal, inner vertical); Table › Cell Options › Strokes and Fills… does the same with the cell fill. Weight, every stroke type, colour, tint, gap colour and gap tint draw on screen and in PDF and round-trip through IDML (`table.setCell` `stroke.edges`, `table.getCellStroke`).
- Distribute Rows Evenly (`table.distributeRows`, Table menu and panel): selected rows receive equal fixed heights preserving their composed total height, with undo/redo. Row-spanning merges and rows outside the composed frames are rejected; shrinking tall cells can overset their text.
- Object States (`states.create/show/rename/release/list`, Object States panel): multi-state objects show one state on screen and in PDF.
- Buttons (`button.set/clear/list`, Buttons and Forms panel): go to page / next / previous / first / last / URL as PDF link annotations. Form fields too (`form.set/clear/list`: text fields, check boxes, combo and list boxes, signature fields; required, multiline, defaults) exported as AcroForm widgets through an incremental update (not in PDF/X).
- Buttons (`button.set/clear/list`, Buttons and Forms panel): go to page / next / previous / first / last / URL as PDF link annotations. Form fields too (`form.set/clear/list`: text fields, check boxes, combo and list boxes, signature fields; required, multiline, defaults) exported as AcroForm widgets through an incremental update (not in PDF/X or PDF/A).
- Power Zoom (Hand tool: press and hold still for half a second, or Alt-press): zoom out to the spread, aim the red view rectangle, release to zoom back in there.
- Graphic cells (`table.placeGraphic`, `table.textCell`, Table › Convert Cell Type, Table panel): images in table cells, fitted or filled, clipped to the cell on screen and in PDF.
- Live Distribute (Space while dragging a selection handle; `transform.resize {distribute}`): objects keep their size and spread with the bounds.