diff --git a/crates/automation/src/tools.rs b/crates/automation/src/tools.rs index 59ecf0425..b0c5c8cb2 100644 --- a/crates/automation/src/tools.rs +++ b/crates/automation/src/tools.rs @@ -493,7 +493,7 @@ pub fn tools() -> Vec { t( "doc_print", "Print", - "Print with Acrobat's Print dialog options, or save the print-ready PDF. pages: a range such as \"1-3, 6, 9-\" (page labels allowed; default all); subset odd/even; reverse. layout: fit (default), actual, shrink, custom (scale %), multiple (per_sheet 2/4/6/9/16, order, border, auto_rotate; cut-stack order arranges single-sided sheets for cutting into piles and stacking left to right, top to bottom, keeping sheet order within each pile; duplex must be off), booklet (booklet_subset both/front/back, binding left/right), poster (scale %, overlap pt, cut_marks). orientation auto/portrait/landscape; comments_forms document / document-and-markups (default) / document-and-stamps / form-fields-only; paper Letter/Legal/Tabloid, ARCH A/B/C/D/E1/E, ANSI C/D/E, or A0/A1/A2/A3/A4/A5/A6 (short names or full preset labels); use layout actual for 100% in the print-ready PDF; printer drivers may still substitute paper or scale. Then path (save) or printer (a name or \"default\") with copies, collate, duplex off/long-edge/short-edge, grayscale, and options (driver options from printer_options, CUPS).", + "Print with Acrobat's Print dialog options, or save the print-ready PDF. pages: a range such as \"1-3, 6, 9-\" (page labels allowed; default all); subset odd/even; reverse. layout: fit (default), actual, shrink, custom (scale %), multiple (per_sheet 2/4/6/9/16, order, border, auto_rotate; cut-stack order arranges single-sided sheets for cutting into piles and stacking left to right, top to bottom, keeping sheet order within each pile; duplex must be off), booklet (booklet_subset both/front/back, binding left/right), poster (scale %, overlap pt, cut_marks). orientation auto/portrait/landscape; comments_forms document / document-and-markups (default) / document-and-stamps / form-fields-only; paper Letter/Legal/Tabloid, ARCH A/B/C/D/E1/E, ANSI C/D/E, A0/A1/A2/A3/A4/A5/A6, or US #10 Envelope (short names or full preset labels); use layout actual for 100% in the print-ready PDF; printer drivers may still substitute paper or scale. Then path (save) or printer (a name or \"default\") with copies, collate, duplex off/long-edge/short-edge, grayscale, and options (driver options from printer_options, CUPS).", ) .with(schema( json!({ diff --git a/crates/automation/tests/automation.rs b/crates/automation/tests/automation.rs index 2c87162d5..624187c5e 100644 --- a/crates/automation/tests/automation.rs +++ b/crates/automation/tests/automation.rs @@ -6552,6 +6552,7 @@ fn architectural_and_iso_papers_through_tools() { ("Letter", 612.0, 792.0), ("US Legal", 612.0, 1008.0), ("Tabloid", 792.0, 1224.0), + ("US #10 Envelope", 4.125 * 72.0, 9.5 * 72.0), ] { for orientation in ["portrait", "landscape"] { let out = ok( diff --git a/crates/print/src/lib.rs b/crates/print/src/lib.rs index 802d9595b..22d04b423 100644 --- a/crates/print/src/lib.rs +++ b/crates/print/src/lib.rs @@ -279,7 +279,7 @@ impl Default for Settings { } /// Common paper sizes (points, portrait). -pub const PAPERS: [(&str, (f64, f64)); 20] = [ +pub const PAPERS: [(&str, (f64, f64)); 21] = [ ("US Letter", (612.0, 792.0)), ("US Legal", (612.0, 1008.0)), ("Tabloid", (792.0, 1224.0)), @@ -300,13 +300,15 @@ pub const PAPERS: [(&str, (f64, f64)); 20] = [ ("A1", (1683.78, 2383.94)), ("A0", (2383.94, 3370.39)), ("4 x 6 in label (101.6 x 152.4 mm)", (288.0, 432.0)), + ("US #10 Envelope (4.125 x 9.5 in)", (297.0, 684.0)), ]; /// `PAPERS` index of the 4 × 6 in shipping label. pub const LABEL_PAPER: usize = 19; /// The CUPS media name for `PAPERS[index]`, so the spooler feeds the sheet the PDF was laid out -/// on rather than the queue's default (PPD keywords; `w288h432` is the usual 4×6 label). +/// on rather than the queue's default (PPD keywords; `w288h432` is the usual 4×6 label, `Env10` +/// the US #10 envelope). pub fn cups_media(index: usize) -> Option<&'static str> { match PAPERS.get(index)?.0 { "US Letter" => Some("Letter"), @@ -315,6 +317,7 @@ pub fn cups_media(index: usize) -> Option<&'static str> { "A3" => Some("A3"), "A4" => Some("A4"), "A5" => Some("A5"), + "US #10 Envelope (4.125 x 9.5 in)" => Some("Env10"), _ if index == LABEL_PAPER => Some("w288h432"), _ => None, } diff --git a/crates/print/src/tests.rs b/crates/print/src/tests.rs index 54cbbd4c7..b349f144a 100644 --- a/crates/print/src/tests.rs +++ b/crates/print/src/tests.rs @@ -645,6 +645,17 @@ fn paper_matching_accepts_rounded_metric_sizes_but_not_custom_or_invalid_sizes() } } +#[test] +fn us_number_10_envelope_is_offered_and_fed_by_name() { + // 4.125 × 9.5 in (#2734). + let index = matching_paper((684.0, 297.0)).unwrap(); + assert_eq!(PAPERS[index].0, "US #10 Envelope (4.125 x 9.5 in)"); + assert_eq!(PAPERS[index].1, (297.0, 684.0)); + assert_eq!(cups_media(index), Some("Env10")); + let s = Settings { pages: vec![0], paper: PAPERS[index].1, layout: Layout::Size(SizeMode::Actual), ..Settings::default() }; + assert_eq!(layout(&[(297.0, 684.0)], &s).unwrap()[0].size, (297.0, 684.0)); +} + #[test] fn label_is_cut_turned_upright_and_fitted_without_distortion() { let label = LABEL_PAPER; diff --git a/parity/acrobat-features.toml b/parity/acrobat-features.toml index ad00b0115..20a5a69e4 100644 --- a/parity/acrobat-features.toml +++ b/parity/acrobat-features.toml @@ -7996,8 +7996,8 @@ milestone = "M10" status = "shipped" commands = ["print.dialog"] tools = ["doc_print"] -evidence = ["crates/print/src/tests.rs::size_modes", "crates/print/src/tests.rs::architectural_sheets_preserve_full_scale", "crates/automation/tests/automation.rs::architectural_and_iso_papers_through_tools", "crates/ui-egui/tests/print.rs::architectural_page_can_be_matched_at_100_percent"] -notes = "fit, actual size, shrink oversized, custom %; ARCH A/B/C/D/E1/E, ANSI C/D/E, ISO A0/A1/A2 and A6 presets; Match page at 100% matches the current page to a standard sheet. PDF scale shows the previewed source-to-sheet transform, not calibrated physical output; driver substitution/scaling remains possible" +evidence = ["crates/print/src/tests.rs::size_modes", "crates/print/src/tests.rs::architectural_sheets_preserve_full_scale", "crates/print/src/tests.rs::us_number_10_envelope_is_offered_and_fed_by_name", "crates/automation/tests/automation.rs::architectural_and_iso_papers_through_tools", "crates/ui-egui/tests/print.rs::architectural_page_can_be_matched_at_100_percent"] +notes = "fit, actual size, shrink oversized, custom %; ARCH A/B/C/D/E1/E, ANSI C/D/E, ISO A0/A1/A2, A6 and US #10 envelope presets; Match page at 100% matches the current page to a standard sheet. PDF scale shows the previewed source-to-sheet transform, not calibrated physical output; driver substitution/scaling remains possible" [[feature]] id = "print.paper-source-by-size"