From ee1b5454ee146c646fc4d125bc27a3cd39272adc Mon Sep 17 00:00:00 2001 From: mtlcl410 Date: Sun, 8 Nov 2026 12:02:11 +0800 Subject: [PATCH] M2: a page without its own /MediaBox inherits its parent's before the US Letter fallback, tested (view.render-pages) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tests only: the page model and the renderer size a page whose /Pages parent carries the /MediaBox (ISO 32000-2 §7.7.3.4) at that box, 300 x 400, not US Letter. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01Pq7HyCHD1R3rywQBPCHXZA --- crates/model/src/lib.rs | 14 ++++++++++++++ crates/render/src/raster/tests.rs | 21 +++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/crates/model/src/lib.rs b/crates/model/src/lib.rs index a96207ba21..5509f95e98 100644 --- a/crates/model/src/lib.rs +++ b/crates/model/src/lib.rs @@ -272,6 +272,20 @@ mod tests { assert_eq!(p.display_size(&d), (612.0, 792.0)); } + /// A page without a `/MediaBox` of its own inherits its `/Pages` parent's (ISO 32000-2 + /// §7.7.3.4): only a box neither has falls back to US Letter. + #[test] + fn a_page_inherits_its_parents_media_box_before_falling_back_to_letter() { + let d = doc_from(&[ + "<< /Type /Catalog /Pages 2 0 R >>".to_string(), + "<< /Type /Pages /Kids [3 0 R] /Count 1 /MediaBox [0 0 300 400] >>".to_string(), + "<< /Type /Page /Parent 2 0 R >>".to_string(), + ]); + let p = &pages(&d)[0]; + assert_eq!(p.crop(&d), [0.0, 0.0, 300.0, 400.0]); + assert_eq!(p.display_size(&d), (300.0, 400.0)); + } + /// A `/MediaBox` without area (`[0 0 0 0]`) is US Letter too, as the renderer draws it. #[test] fn a_page_whose_media_box_has_no_area_is_letter() { diff --git a/crates/render/src/raster/tests.rs b/crates/render/src/raster/tests.rs index 980b4bc4aa..c6a56c66f0 100644 --- a/crates/render/src/raster/tests.rs +++ b/crates/render/src/raster/tests.rs @@ -5538,6 +5538,27 @@ trailer << /Root 1 0 R >> } } +/// A page without a `/MediaBox` of its own inherits its `/Pages` parent's (ISO 32000-2 §7.7.3.4) +/// before any fallback: rendered and inspected at 300 × 400, not US Letter. +#[test] +fn a_page_inherits_its_parents_media_box_before_falling_back_to_letter() { + let pdf = b"%PDF-1.4 +1 0 obj << /Type /Catalog /Pages 2 0 R >> endobj +2 0 obj << /Type /Pages /Kids [3 0 R] /Count 1 /MediaBox [0 0 300 400] >> endobj +3 0 obj << /Type /Page /Parent 2 0 R /Contents 4 0 R >> endobj +4 0 obj << /Length 25 >> stream +0 0 1 rg 10 10 50 50 re f +endstream endobj +trailer << /Root 1 0 R >> +%%EOF" + .to_vec(); + let page = render_first_page(pdf.clone()); + assert_eq!((page.width, page.height), (300, 400), "rendered size"); + assert_eq!(rgb_at(&page.rgba, page.width as usize, 30, 400 - 30), [0, 0, 255]); + let info = crate::inspect(Arc::new(pdf), None).expect("inspect"); + assert_eq!((info.pages[0].width, info.pages[0].height), (300.0, 400.0), "inspected size"); +} + /// A page whose content expands far beyond its compressed stream stops at the expansion budget, /// which is 64 times the compressed size and at least `MAX_DECODED_STREAM`, and the page says so. #[test]