mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-10-24 10:08:00 -06:00
M2: a /Rotate that isn't a quarter turn counts as 0, as the page is drawn (#1863)
Page::rotation rounded a /Rotate that isn't a multiple of 90 down to a quarter turn (135 became 90), while the renderer draws such a page upright. Display size and the display-to-user-space matrix (header and footer, watermarks, measuring, printing, image signatures) then disagreed with the page on screen. ISO 32000-2 §7.7.3.3 requires a multiple of 90; read any other value as 0, as the renderer does. Page import and image stamps, which read /Rotate themselves, already treat such a value as 0. Test: rotate_off_a_quarter_turn_counts_as_upright (/Rotate 135, 30, -45, 359).
This commit is contained in:
+19
-2
@@ -37,9 +37,11 @@ impl Page {
|
||||
}
|
||||
}
|
||||
|
||||
/// Clockwise rotation when displayed: 0, 90, 180 or 270.
|
||||
/// Clockwise rotation when displayed: 0, 90, 180 or 270. A `/Rotate` that isn't a multiple
|
||||
/// of 90 (ISO 32000-2 §7.7.3.3 requires one) counts as 0, as the renderer draws that page.
|
||||
pub fn rotation(&self, doc: &Document) -> i64 {
|
||||
self.dict.get(b"Rotate").and_then(|o| doc.resolve(o).as_int()).unwrap_or(0).rem_euclid(360) / 90 * 90
|
||||
let r = self.dict.get(b"Rotate").and_then(|o| doc.resolve(o).as_int()).unwrap_or(0).rem_euclid(360);
|
||||
if r % 90 == 0 { r } else { 0 }
|
||||
}
|
||||
|
||||
/// The size of the page's user-space unit in points (`/UserUnit`; it isn't inherited), read
|
||||
@@ -184,6 +186,21 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
/// A `/Rotate` that isn't a quarter turn counts as 0, as the renderer draws the page
|
||||
/// upright, so display space matches what's on screen.
|
||||
#[test]
|
||||
fn rotate_off_a_quarter_turn_counts_as_upright() {
|
||||
for rotate in [135, 30, -45, 359] {
|
||||
let d = doc(rotate);
|
||||
let p = &pages(&d)[0];
|
||||
assert_eq!(p.rotation(&d), 0, "{rotate}");
|
||||
assert_eq!(p.display_size(&d), (200.0, 300.0), "{rotate}");
|
||||
assert_eq!(p.view_matrix(&d), [1.0, 0.0, 0.0, 1.0, 10.0, 20.0], "{rotate}");
|
||||
}
|
||||
let d = doc(-90);
|
||||
assert_eq!(pages(&d)[0].rotation(&d), 270);
|
||||
}
|
||||
|
||||
/// Display space is in points: `/UserUnit 2` doubles it. As in Acrobat, the value isn't
|
||||
/// inherited, values below 1 or not numbers count as 1, and values over 75,000 as 75,000.
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user