From 1c170a25ab832b829e683f0f2e7da6c059d1cc0c Mon Sep 17 00:00:00 2001 From: chenjie Date: Sat, 14 Dec 2024 10:09:10 +0800 Subject: [PATCH] Change Page annotations to Lazy --- examples/src/bin/add_annot.rs | 108 ++++++++++++++++++++++++++++++++++ pdf/src/object/mod.rs | 7 +++ pdf/src/object/types.rs | 8 ++- 3 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 examples/src/bin/add_annot.rs diff --git a/examples/src/bin/add_annot.rs b/examples/src/bin/add_annot.rs new file mode 100644 index 0000000..4206d87 --- /dev/null +++ b/examples/src/bin/add_annot.rs @@ -0,0 +1,108 @@ +extern crate pdf; + + +use std::env::args; +use std::ops::Deref; + +use pdf::content::{FormXObject, Op, serialize_ops}; +use pdf::error::PdfError; +use pdf::file::{FileOptions, Log}; +use pdf::font::{Font, FontData, TFont}; +use pdf::object::*; +use pdf::primitive::{Dictionary, Name, PdfString, Primitive}; + +fn run() -> Result<(), PdfError> { + let path = args().nth(1).expect("no file given"); + println!("read: {}", path); + + let mut old_file = FileOptions::cached().open(&path)?; + let mut old_page: PageRc = old_file.get_page(0).unwrap(); + + let mut annots = old_page.annotations.load(&old_file.resolver()).expect("can't load annotations"); + // let mut new_annots = annots.deref().clone(); + // for annot in &new_annots { + // dbg!(&annot.subtype); + // dbg!(&annot.rect); + // dbg!(&annot.color); + // dbg!(&annot.transparency); + // dbg!(&annot.ink_list); + // dbg!(&annot.line); + // dbg!(&annot.creation_date); + // dbg!(&annot.uuid); + // dbg!(&annot.border_style); + // dbg!(&annot.popup); + // dbg!(&annot.other); + // } + + let mut bs = Dictionary::new(); + bs.insert(Name::from("S"), PdfString::from("/S")); + bs.insert(Name::from("W"), PdfString::from("3")); + let new_annot = Annot { + subtype: Name::from("Line"), + // rect: Some(Rectangle { + // left: 89.774, + // bottom: 726.55, + // right: 300.961, + // top: 742.55, + // }), + rect: None, + contents: None, + page: Some(old_page.clone()), + border: None, + annotation_name: None, + date: None, + annot_flags: 4, + appearance_streams: None, + appearance_state: None, + color: Some(Primitive::Array( + vec![Primitive::Integer(1), Primitive::Integer(0), Primitive::Integer(0)] + )), + ink_list: None, + line: Some(Primitive::Array( + vec![ + Primitive::Number(95.774), + Primitive::Number(734.237), + Primitive::Number(320.961), + Primitive::Number(734.863) + ] + )), + // creation_date: None, + // uuid: None, + // border_style: Some(bs), + // border_style: None, + // popup: None, + other: Dictionary::new(), + // transparency: Some(1.0), + // transparency: None, + }; + + let annot_ref = old_file.create(new_annot)?; + annots.push(MaybeRef::Indirect(annot_ref)); + + // let lazy_annots = Lazy::from_primitive( + // annots.to_primitive(&mut FileOptions::cached().storage()).unwrap(), + // &file.resolver() + // ); + + // old_page.update_annots(annots, &old_file.resolver(), &mut FileOptions::cached().storage()); + // let old_annots = old_page.annotations.to_primitive(&mut old_file).unwrap(); + + + // let layz_annots = Lazy::from(annots); + // match annots { + // MaybeRef::Indirect(annot) => { + // old_page.annotations = Lazy::from(annot); + // } + // } + + old_file.update(old_page.get_plain_ref(), old_page); + old_file.save_to("/Users/apple/Downloads/test_pdf/out.pdf")?; + + Ok(()) +} + +fn main() { + if let Err(e) = run() { + println!("{e}"); + } +} \ No newline at end of file diff --git a/pdf/src/object/mod.rs b/pdf/src/object/mod.rs index bbdfa60..f0c29e3 100644 --- a/pdf/src/object/mod.rs +++ b/pdf/src/object/mod.rs @@ -456,6 +456,13 @@ impl Default for Lazy { } } +impl From> for Lazy { + fn from(value: RcRef) -> Self { + Lazy { primitive: Primitive::Reference(value.inner), _marker: PhantomData } + } +} + + ////////////////////////////////////// // Object for Primitives & other types ////////////////////////////////////// diff --git a/pdf/src/object/types.rs b/pdf/src/object/types.rs index f04b7ea..1e11c63 100644 --- a/pdf/src/object/types.rs +++ b/pdf/src/object/types.rs @@ -71,6 +71,9 @@ impl PageRc { pub fn get_ref(&self) -> Ref { self.0.get_ref() } + pub fn get_plain_ref(&self) -> PlainRef { + self.0.inner + } } impl Object for PageRc { fn from_primitive(p: Primitive, resolve: &impl Resolve) -> Result { @@ -295,7 +298,7 @@ pub struct Page { pub vp: Option, #[pdf(key="Annots")] - pub annotations: Lazy>>, + pub annotations: Lazy>>>, #[pdf(other)] pub other: Dictionary, @@ -984,6 +987,9 @@ pub struct Annot { #[pdf(key="InkList")] pub ink_list: Option, + #[pdf(key="L")] + pub line: Option, + #[pdf(other)] pub other: Dictionary, }