From be2cee9d2110f2ee5e93592584075f222bd75965 Mon Sep 17 00:00:00 2001 From: tingerrr Date: Thu, 26 Oct 2023 18:14:39 +0200 Subject: [PATCH 1/2] Make `/Annots` indirect --- examples/hello.rs | 20 ++++++++++---------- src/annotations.rs | 27 +++++++++++---------------- src/chunk.rs | 5 +++++ src/structure.rs | 7 ++++--- 4 files changed, 30 insertions(+), 29 deletions(-) diff --git a/examples/hello.rs b/examples/hello.rs index e9bec42..9952763 100644 --- a/examples/hello.rs +++ b/examples/hello.rs @@ -13,6 +13,7 @@ fn main() -> std::io::Result<()> { let page_id = Ref::new(3); let font_id = Ref::new(4); let content_id = Ref::new(5); + let annotation_id = Ref::new(6); let font_name = Name(b"F1"); // Write the document catalog with a reference to the page tree. @@ -29,11 +30,16 @@ fn main() -> std::io::Result<()> { page.media_box(Rect::new(0.0, 0.0, 595.0, 842.0)); page.parent(page_tree_id); page.contents(content_id); + page.annotations([annotation_id]); - // We also create the annotations list here that allows us to have things - // like links or comments on the page. - let mut annotations = page.annotations(); - let mut annotation = annotations.push(); + // We also need to specify which resources the page needs, which in our case + // is only a font that we name "F1" (the specific name doesn't matter). + page.resources().fonts().pair(font_name, font_id); + page.finish(); + + // We also create an annotation which allows us to have things like links or + // comments on the page. + let mut annotation = pdf.annotation(annotation_id); // Write the type, area, alt-text, and color for our link annotation. annotation.subtype(AnnotationType::Link); @@ -58,12 +64,6 @@ fn main() -> std::io::Result<()> { // you cannot accidentally forget it. The `finish()` method from the `Finish` // trait is just a postfix-style version of dropping. annotation.finish(); - annotations.finish(); - - // We also need to specify which resources the page needs, which in our case - // is only a font that we name "F1" (the specific name doesn't matter). - page.resources().fonts().pair(font_name, font_id); - page.finish(); // Specify the font we want to use. Because Helvetica is one of the 14 base // fonts shipped with every PDF reader, we don't have to embed any font diff --git a/src/annotations.rs b/src/annotations.rs index 67fd5ad..22f3d0c 100644 --- a/src/annotations.rs +++ b/src/annotations.rs @@ -2,7 +2,7 @@ use super::*; /// Writer for an _annotation dictionary_. /// -/// An array of this struct is created by [`Page::annotations`]. +/// An array of this struct is created by [`Chunk::annotation`]. pub struct Annotation<'a> { dict: Dict<'a>, } @@ -671,24 +671,19 @@ mod tests { fn test_annotations() { test!( crate::tests::slice(|w| { - let mut page = w.page(Ref::new(1)); - let mut annots = page.annotations(); - annots.push().rect(Rect::new(0.0, 0.0, 1.0, 1.0)); - annots.push().rect(Rect::new(1.0, 1.0, 0.0, 0.0)); - annots.finish(); - page.bleed_box(Rect::new(-100.0, -100.0, 100.0, 100.0)); + w.annotation(Ref::new(1)).rect(Rect::new(0.0, 0.0, 1.0, 1.0)); + w.annotation(Ref::new(2)).rect(Rect::new(1.0, 1.0, 0.0, 0.0)); }), b"1 0 obj", b"<<", - b" /Type /Page", - b" /Annots [<<", - b" /Type /Annot", - b" /Rect [0 0 1 1]", - b" >> <<", - b" /Type /Annot", - b" /Rect [1 1 0 0]", - b" >>]", - b" /BleedBox [-100 -100 100 100]", + b" /Type /Annot", + b" /Rect [0 0 1 1]", + b">>", + b"endobj\n", + b"2 0 obj", + b"<<", + b" /Type /Annot", + b" /Rect [1 1 0 0]", b">>", b"endobj\n\n", ); diff --git a/src/chunk.rs b/src/chunk.rs index 1dd9b6a..f3e496c 100644 --- a/src/chunk.rs +++ b/src/chunk.rs @@ -377,6 +377,11 @@ impl Chunk { /// Interactive features. impl Chunk { + /// Start writing an annotation dictionary. + pub fn annotation(&mut self, id: Ref) -> Annotation<'_> { + self.indirect(id).start() + } + /// Start writing a form field dictionary. pub fn form_field(&mut self, id: Ref) -> Field<'_> { self.indirect(id).start() diff --git a/src/structure.rs b/src/structure.rs index 7136bea..f124c58 100644 --- a/src/structure.rs +++ b/src/structure.rs @@ -1167,9 +1167,10 @@ impl<'a> Page<'a> { self.insert(Name(b"Trans")).start() } - /// Start writing the `/Annots` (annotations) array.' - pub fn annotations(&mut self) -> TypedArray<'_, Annotation> { - self.insert(Name(b"Annots")).array().typed() + /// Start writing the `/Annots` (annotations) array. + pub fn annotations(&mut self, ids: impl IntoIterator) -> &mut Self { + self.insert(Name(b"Annots")).array().items(ids); + self } /// Write the `/StructParents` attribute to indicate the [structure tree From a0b89844b8d70f6972a565a161e5da2cf55e51f1 Mon Sep 17 00:00:00 2001 From: tingerrr Date: Wed, 1 Nov 2023 17:50:22 +0100 Subject: [PATCH 2/2] Review --- src/structure.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/structure.rs b/src/structure.rs index f124c58..57e2fad 100644 --- a/src/structure.rs +++ b/src/structure.rs @@ -1167,7 +1167,7 @@ impl<'a> Page<'a> { self.insert(Name(b"Trans")).start() } - /// Start writing the `/Annots` (annotations) array. + /// Write the `/Annots` (annotations) array. pub fn annotations(&mut self, ids: impl IntoIterator) -> &mut Self { self.insert(Name(b"Annots")).array().items(ids); self