mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-11-10 21:11:52 +00:00
Do not send duplex to printers without two-sided support (#6673)
On Windows the printer list reports whether a driver supports two-sided printing, but the job still asked for it anyway, so duplex jobs printed single-sided or misaligned on printers such as the reported Brother model. Leave duplex unset for a printer reported as not two-sided, so that printer keeps its own setting, while printers that support two-sided or report no capability keep the chosen setting. Test: duplex_is_not_sent_to_a_printer_without_two_sided failed before the change and passes after. Co-authored-by: eliets2 <287273517+eliets2@users.noreply.github.com> Co-authored-by: FredApps <153173854+FredApps@users.noreply.github.com>
This commit is contained in:
2 files changed
+45
-2
No files matched your search
@@ -832,6 +832,38 @@ mod tests {
|
||||
assert!(cut.settings(4, &[]).is_err());
|
||||
}
|
||||
|
||||
/// #3208: long or short edge goes to a printer whose driver doesn't take two-sided settings
|
||||
/// as no duplex setting at all, so the driver keeps its own instead of refusing the job; Off
|
||||
/// still reaches it, a printer that can or whose support is unknown still gets the choice,
|
||||
/// and a stale long-edge choice doesn't block cut and stack. The printers are listed as the
|
||||
/// dialog lists them (#3554), drivers unasked, with each answer in `two_sided`.
|
||||
#[test]
|
||||
fn duplex_is_not_sent_to_a_printer_without_two_sided() {
|
||||
let draft = |name: &str, duplex| PrintDraft {
|
||||
printers: ["Office", "Duplexer", "Network"]
|
||||
.map(|n| spool::Printer { name: n.into(), default: n == "Office", two_sided: None, description: String::new() })
|
||||
.to_vec(),
|
||||
two_sided: [("Office".to_string(), Some(false)), ("Duplexer".to_string(), Some(true))].into_iter().collect(),
|
||||
printer: Some(name.into()),
|
||||
duplex,
|
||||
..PrintDraft::default()
|
||||
};
|
||||
for duplex in [spool::Duplex::LongEdge, spool::Duplex::ShortEdge] {
|
||||
assert_eq!(draft("Office", Some(duplex)).job("report.pdf").duplex, None, "{duplex:?} to a printer without two-sided");
|
||||
assert_eq!(draft("Duplexer", Some(duplex)).job("report.pdf").duplex, Some(duplex));
|
||||
assert_eq!(draft("Network", Some(duplex)).job("report.pdf").duplex, Some(duplex), "unknown support keeps the choice");
|
||||
}
|
||||
assert_eq!(draft("Office", Some(spool::Duplex::Off)).job("report.pdf").duplex, Some(spool::Duplex::Off), "Off still reaches it");
|
||||
assert_eq!(draft("Office", None).job("report.pdf").duplex, None);
|
||||
// A long-edge choice left from another printer doesn't block cut and stack on this one.
|
||||
let mut cut = draft("Office", Some(spool::Duplex::LongEdge));
|
||||
(cut.handling, cut.order) = (Handling::Multiple, PageOrder::CutStack);
|
||||
assert!(cut.settings(4, &[]).is_ok());
|
||||
assert_eq!(cut.job("report.pdf").duplex, Some(spool::Duplex::Off));
|
||||
cut.printer = Some("Duplexer".into());
|
||||
assert!(cut.settings(4, &[]).is_err(), "still refused where it would print two-sided");
|
||||
}
|
||||
|
||||
/// #5772: a booklet's both sides ask the printer for the short edge, unless its driver doesn't
|
||||
/// take two-sided settings: it would refuse the job, so its own setting (manual two-sided, say)
|
||||
/// prints it. One side on its own stays one-sided.
|
||||
|
||||
@@ -255,7 +255,7 @@ impl PrintDraft {
|
||||
area: Some(area),
|
||||
});
|
||||
}
|
||||
if self.cut_and_stack() && matches!(self.duplex, Some(spool::Duplex::LongEdge | spool::Duplex::ShortEdge)) {
|
||||
if self.cut_and_stack() && matches!(self.chosen_duplex(), Some(spool::Duplex::LongEdge | spool::Duplex::ShortEdge)) {
|
||||
return Err("Cut and stack needs Two-sided: Off. Print single-sided sheets.".into());
|
||||
}
|
||||
let range = match self.which {
|
||||
@@ -322,6 +322,17 @@ impl PrintDraft {
|
||||
p.two_sided.or_else(|| self.two_sided.get(&p.name).copied().flatten())
|
||||
}
|
||||
|
||||
/// The Two-sided choice as the chosen printer can take it: long or short edge is left out for
|
||||
/// a printer whose driver doesn't take two-sided settings from other programs, so its own
|
||||
/// setting applies instead of the job being refused (#3208). Off and the printer's default
|
||||
/// stay as chosen: one-sided is accepted by every driver.
|
||||
fn chosen_duplex(&self) -> Option<spool::Duplex> {
|
||||
match self.duplex {
|
||||
Some(spool::Duplex::LongEdge | spool::Duplex::ShortEdge) if self.printer_two_sided() == Some(false) => None,
|
||||
chosen => chosen,
|
||||
}
|
||||
}
|
||||
|
||||
/// The spooler job for this print: the dialog's copies, two-sided and colour settings, the
|
||||
/// driver options changed from the printer's defaults, and the chosen paper.
|
||||
pub fn job(&self, title: &str) -> spool::Job {
|
||||
@@ -337,7 +348,7 @@ impl PrintDraft {
|
||||
} else if self.handling == Handling::Booklet {
|
||||
print::booklet_job_duplex(self.booklet_subset, self.printer_two_sided())
|
||||
} else {
|
||||
self.duplex
|
||||
self.chosen_duplex()
|
||||
},
|
||||
scaling: spool::Scaling::Exact,
|
||||
grayscale: print::driver_needs_grayscale(self.grayscale, self.raster()),
|
||||
|
||||
Reference in new issue
Block a user