diff --git a/crates/automation/src/forms.rs b/crates/automation/src/forms.rs index 3e15c2f4e3..c9f758de31 100644 --- a/crates/automation/src/forms.rs +++ b/crates/automation/src/forms.rs @@ -299,13 +299,18 @@ impl Automation { // which one is ticked, and the names form_fill takes to tick each. One option // per distinct on state: kids sharing a state tick together (EXAMPLE 2), so // their `/Opt` exports are not separate choices. Exports name the options - // unless two states share one (Table 230 allows it); then the states do. + // unless two states share one (Table 230 allows it) or an export would tick + // another state (form_fill reads a name as an on state first); then the + // states do. FormFieldKind::CheckBox => { let mut seen = std::collections::HashSet::new(); let states: Vec<&str> = f.widgets.iter().filter_map(|w| w.on_state.as_deref()).filter(|s| seen.insert(*s)).collect(); if states.len() > 1 { let mut exports = std::collections::HashSet::new(); - let by_export = states.iter().all(|s| exports.insert(f.export_for_state(s))); + let by_export = states.iter().all(|s| { + let e = f.export_for_state(s); + exports.insert(e) && f.state_for(e) == Some(*s) + }); let name = |s: &str| if by_export { f.export_for_state(s).to_owned() } else { s.to_owned() }; // The ticked kid is the one whose `/AS` is its on state: ยง12.7.5.2.3 // makes `/AS` decide where it and `/V` differ. diff --git a/crates/automation/tests/it/automation.rs b/crates/automation/tests/it/automation.rs index 3f095e2f3b..34bcf7bc20 100644 --- a/crates/automation/tests/it/automation.rs +++ b/crates/automation/tests/it/automation.rs @@ -2699,7 +2699,11 @@ fn form_fields_lists_a_check_box_by_on_state_and_reports_the_kid_that_is_on() { // Two on states with one export: the states name the options. let same = listed("check-box-same-export", "<< /FT /Btn /T (pair) /V /B /Opt [(x) (x)] /Kids [6 0 R 7 0 R] >>", ("A", "Off"), ("B", "B")); assert_eq!(same, (json!(["A", "B"]), json!("B"))); + // B's export is A's on state, so naming it would tick A: the states name the options. + let crossed = listed("check-box-crossed-export", "<< /FT /Btn /T (pair) /V /B /Opt [(x) (A)] /Kids [6 0 R 7 0 R] >>", ("A", "Off"), ("B", "B")); + assert_eq!(crossed, (json!(["A", "B"]), json!("B"))); } + /// A form whose fields are only page widgets (the `/Fields` list is empty) still lists, fills and /// resets through the tools, and the leniency shows up as a repair note. #[test]