mirror of
https://github.com/storytold/craft-libs.git
synced 2026-11-14 22:42:46 +00:00
Merge pull request #147 from midasmatterhorn/fix/r4-print-shrink-zero-scale
print: shrink-to-fit refuses a sheet the written matrix cannot represent
This commit is contained in:
2 files changed
+54
No files matched your search
@@ -1136,6 +1136,21 @@ pub(crate) fn plan(sheets: &[Sheet], paper: (f64, f64), fit: Fit) -> Result<Vec<
|
||||
if scale >= 1.0 && close((w, h), paper) {
|
||||
None
|
||||
} else {
|
||||
// The matrix is written with at most four decimals and a PDF real has no
|
||||
// exponent, so a scale that rounds away prints nothing at all and one that
|
||||
// rounds up prints the wrong size. Refuse both, the way a nondefault
|
||||
// UserUnit is refused: an error, never a job that spools a blank page.
|
||||
let written = number(scale).parse::<f64>().unwrap_or(0.0);
|
||||
if written <= 0.0 || (written - scale).abs() > scale * 0.01 {
|
||||
return Err(Error::Spool(format!(
|
||||
"shrink to fit cannot place sheet {} ({:.2} x {:.2} in) on the {:.2} x {:.2} in paper; nothing was sent",
|
||||
i + 1,
|
||||
w / 72.0,
|
||||
h / 72.0,
|
||||
pw / 72.0,
|
||||
ph / 72.0
|
||||
)));
|
||||
}
|
||||
let [x0, y0, x1, y1] = sheet.bounds;
|
||||
let (cw, ch) = (x1 - x0, y1 - y0);
|
||||
// The paper in the page's unrotated space.
|
||||
|
||||
@@ -555,3 +555,42 @@ fn windows_jobs_reach_the_spooler() {
|
||||
let missing = spool::submit(&mixed, &Job { printer: Some(name.into()), ..Job::default() });
|
||||
assert!(matches!(missing, Err(Error::Spool(ref m)) if m.contains(name)), "{missing:?}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shrink_to_fit_refuses_a_sheet_the_output_cannot_represent() {
|
||||
use crate::sheets::{Fit, plan, read};
|
||||
// A runaway-zoom export: 16 000 000 pt wide. Written with four decimals the scale would be
|
||||
// "0" -- a singular matrix, a blank page, reported back as a spooled job.
|
||||
let huge = TestPage { media: Some([0.0, 0.0, 16_000_000.0, 792.0]), ..LETTER };
|
||||
let pdf = test_pdf(&[huge], false);
|
||||
let sheets = read(&pdf).unwrap();
|
||||
let refused = plan(&sheets.sheets, (612.0, 792.0), Fit::Shrink { margin: 18.0 });
|
||||
assert!(matches!(refused, Err(Error::Spool(ref m)) if m.contains("shrink")), "{refused:?}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shrink_to_fit_holds_the_one_percent_scale_boundary() {
|
||||
use crate::sheets::{Fit, plan, read};
|
||||
// The matrix carries the scale through the four-decimal formatter, so the plan refuses when
|
||||
// what would be written is more than 1% off the real scale. Letter with an 18 pt margin gives
|
||||
// 576 pt of printable width: a 118 700 pt wide, 120 000 pt tall sheet (no quarter turn) scales
|
||||
// by 576 / 118 700 = 0.00485257, written 0.0049 -- 0.98% short, inside the bound, so it
|
||||
// prints.
|
||||
let inside = TestPage { media: Some([0.0, 0.0, 118_700.0, 120_000.0]), ..LETTER };
|
||||
let pdf = test_pdf(&[inside], false);
|
||||
let sheets = read(&pdf).unwrap();
|
||||
let edits = plan(&sheets.sheets, (612.0, 792.0), Fit::Shrink { margin: 18.0 }).unwrap();
|
||||
let updated = sheets.update(&edits).unwrap();
|
||||
let frame = frame_of(&updated, pdf.len());
|
||||
let written: f64 = frame.split_whitespace().nth(1).unwrap().parse().unwrap();
|
||||
let real = edits[0].frame.as_ref().unwrap().matrix[0];
|
||||
assert!(written != real && (written - real).abs() < real * 0.01, "just inside the 1% bound the written scale is accepted: {frame}");
|
||||
|
||||
// A 118 750 pt wide sheet: 576 / 118 750 = 0.00485053, written 0.0049, 1.02% off -- refused as
|
||||
// an error before anything is sent, rather than printed a percent too small.
|
||||
let outside = TestPage { media: Some([0.0, 0.0, 118_750.0, 120_000.0]), ..LETTER };
|
||||
let pdf = test_pdf(&[outside], false);
|
||||
let sheets = read(&pdf).unwrap();
|
||||
let refused = plan(&sheets.sheets, (612.0, 792.0), Fit::Shrink { margin: 18.0 });
|
||||
assert!(matches!(refused, Err(Error::Spool(ref m)) if m.contains("shrink") && m.contains("nothing was sent")), "{refused:?}");
|
||||
}
|
||||
Reference in new issue
Block a user