mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-11-09 04:22:20 +00:00
Widgets are drawn in a second pass over /Annots, holding nothing per entry; comment order with a widget among them in the test
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Pq7HyDBXygTf7jcqdsjcfn
This commit is contained in:
1 parent
2bace2144f
commit
3dca7f3b01
2 files changed
+17
-4
No files matched your search
@@ -47,10 +47,15 @@ fn pdf(order: &str) -> Vec<u8> {
|
||||
|
||||
/// The colour at the page's centre.
|
||||
fn centre(order: &str) -> [u8; 3] {
|
||||
at(order, 100, 100)
|
||||
}
|
||||
|
||||
/// The colour at (`x`, `y`) px from the top left.
|
||||
fn at(order: &str, x: usize, y: usize) -> [u8; 3] {
|
||||
let mut renderer = PageRenderer::new(Arc::new(pdf(order)), RenderConfig::default());
|
||||
let out = renderer.render(RenderRequest { page: 0, scale: 1.0, ..Default::default() });
|
||||
assert!(out.error.is_none(), "{:?}", out.error);
|
||||
let at = (100 * out.width as usize + 100) * 4;
|
||||
let at = (y * out.width as usize + x) * 4;
|
||||
let px = out.rgba.get(at..at + 3).expect("the centre lies on the page");
|
||||
[px[0], px[1], px[2]]
|
||||
}
|
||||
@@ -62,4 +67,8 @@ fn a_widget_is_drawn_above_the_comments_on_its_page() {
|
||||
// Comments keep their `/Annots` order among themselves.
|
||||
assert_eq!(centre("RS"), [0, 0, 0], "the black square listed last is on top");
|
||||
assert_eq!(centre("SR"), [255, 0, 0], "the red square listed last is on top");
|
||||
// And with a widget among them: (45, 45) is inside both squares, outside the check box.
|
||||
assert_eq!(at("WRS", 45, 45), [0, 0, 0], "a widget first: the black square listed last is on top");
|
||||
assert_eq!(at("WSR", 45, 45), [255, 0, 0], "a widget first: the red square listed last is on top");
|
||||
assert_eq!(centre("WSR"), [0, 255, 0], "and the check box above both");
|
||||
}
|
||||
+7
-3
@@ -203,9 +203,12 @@ pub fn interpret_page<'a>(
|
||||
// PdfCraft patch (86): form fields' widgets are drawn after the page's other
|
||||
// annotations, each group in `/Annots` order, as other readers draw them: a filled
|
||||
// comment listed after a check box covered the box. ISO 32000-2 doesn't order the two.
|
||||
let mut annots: Vec<Dict<'_>> = annot_arr.iter::<Dict<'_>>().collect();
|
||||
annots.sort_by_key(|a| a.get::<hayro_syntax::object::Name<'_>>(SUBTYPE).as_deref() == Some(b"Widget"));
|
||||
for annot in annots {
|
||||
// Two passes over the array, so nothing is held for every entry of a long one.
|
||||
for widgets in [false, true] {
|
||||
for annot in annot_arr.iter::<Dict<'_>>() {
|
||||
if (annot.get::<hayro_syntax::object::Name<'_>>(SUBTYPE).as_deref() == Some(b"Widget")) != widgets {
|
||||
continue;
|
||||
}
|
||||
let flags = annot.get::<u32>(F).unwrap_or(0);
|
||||
|
||||
// Annotation should be hidden (Hidden = bit 2, NoView = bit 6).
|
||||
@@ -321,6 +324,7 @@ pub fn interpret_page<'a>(
|
||||
draw_highlight_without_appearance(&annot, context, device);
|
||||
}
|
||||
}
|
||||
}
|
||||
device.end_annotations();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user