Skip to content

Commit 7307304

Browse files
committedFeb 24, 2025·
merge annot changes manually
(pr #243)
1 parent f87d3f5 commit 7307304

File tree

5 files changed

+124
-7
lines changed

5 files changed

+124
-7
lines changed
 

‎examples/src/bin/add_annot.rs

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
extern crate pdf;
2+
3+
4+
use std::env::args;
5+
use std::ops::Deref;
6+
7+
use pdf::content::{FormXObject, Op, serialize_ops};
8+
use pdf::error::PdfError;
9+
use pdf::file::{FileOptions, Log};
10+
use pdf::font::{Font, FontData, TFont};
11+
use pdf::object::*;
12+
use pdf::primitive::{Dictionary, Name, PdfString, Primitive};
13+
14+
fn run() -> Result<(), PdfError> {
15+
let path = args().nth(1).expect("no file given");
16+
println!("read: {}", path);
17+
18+
let mut old_file = FileOptions::cached().open(&path)?;
19+
let mut old_page: PageRc = old_file.get_page(0).unwrap();
20+
21+
let old_annots = old_page.annotations.load(&old_file.resolver()).expect("can't load annotations");
22+
let mut annots: Vec<_> = (*old_annots).clone();
23+
// let mut new_annots = annots.deref().clone();
24+
// for annot in &new_annots {
25+
// dbg!(&annot.subtype);
26+
// dbg!(&annot.rect);
27+
// dbg!(&annot.color);
28+
// dbg!(&annot.transparency);
29+
// dbg!(&annot.ink_list);
30+
// dbg!(&annot.line);
31+
// dbg!(&annot.creation_date);
32+
// dbg!(&annot.uuid);
33+
// dbg!(&annot.border_style);
34+
// dbg!(&annot.popup);
35+
// dbg!(&annot.other);
36+
// }
37+
38+
let mut bs = Dictionary::new();
39+
bs.insert(Name::from("S"), PdfString::from("/S"));
40+
bs.insert(Name::from("W"), PdfString::from("3"));
41+
let new_annot = Annot {
42+
subtype: Name::from("Line"),
43+
// rect: Some(Rectangle {
44+
// left: 89.774,
45+
// bottom: 726.55,
46+
// right: 300.961,
47+
// top: 742.55,
48+
// }),
49+
rect: Some(Rectangle { left: 10., bottom: 10., right: 200., top: 200. }),
50+
contents: None,
51+
page: Some(old_page.clone()),
52+
border: None,
53+
annotation_name: None,
54+
date: None,
55+
annot_flags: 4,
56+
appearance_streams: None,
57+
appearance_state: None,
58+
color: Some(Primitive::Array(
59+
vec![Primitive::Integer(1), Primitive::Integer(0), Primitive::Integer(0)]
60+
)),
61+
ink_list: None,
62+
line: Some(vec![10., 100., 20., 200.]),
63+
// creation_date: None,
64+
// uuid: None,
65+
// border_style: Some(bs),
66+
// border_style: None,
67+
// popup: None,
68+
other: Dictionary::new(),
69+
// transparency: Some(1.0),
70+
// transparency: None,
71+
};
72+
73+
let annot_ref = old_file.create(new_annot)?;
74+
annots.push(MaybeRef::Indirect(annot_ref));
75+
76+
77+
match old_annots {
78+
MaybeRef::Direct(_) => {
79+
// need to update the whole page
80+
let mut new_page: Page = (*old_page).clone();
81+
82+
let lazy_annots = Lazy::from(old_file.create(annots).unwrap());
83+
new_page.annotations = lazy_annots;
84+
PageRc::update(new_page, &old_page, &mut old_file).unwrap();
85+
}
86+
MaybeRef::Indirect(r) => {
87+
// can just update the annot reference
88+
old_file.update_ref(&r, annots).unwrap();
89+
}
90+
}
91+
old_file.save_to("out.pdf")?;
92+
93+
Ok(())
94+
}
95+
96+
fn main() {
97+
if let Err(e) = run() {
98+
println!("{e}");
99+
}
100+
}

‎pdf/src/object/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,9 @@ pub trait Updater {
111111
fn update<T: ObjectWrite>(&mut self, old: PlainRef, obj: T) -> Result<RcRef<T>>;
112112
fn promise<T: Object>(&mut self) -> PromisedRef<T>;
113113
fn fulfill<T: ObjectWrite>(&mut self, promise: PromisedRef<T>, obj: T) -> Result<RcRef<T>>;
114+
fn update_ref<T: ObjectWrite>(&mut self, old: &RcRef<T>, obj: T) -> Result<RcRef<T>> {
115+
self.update(old.get_ref().inner, obj)
116+
}
114117
}
115118

116119
pub struct NoUpdate;

‎pdf/src/object/stream.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,10 @@ impl<I: ObjectWrite> Stream<I> {
177177
}
178178
impl<I: ObjectWrite> ObjectWrite for Stream<I> {
179179
fn to_primitive(&self, update: &mut impl Updater) -> Result<Primitive> {
180-
self.to_pdf_stream(update).map(Primitive::Stream)
180+
match self.inner_data {
181+
StreamData::Original(_, id) => Ok(Primitive::Reference(id)),
182+
_ => self.to_pdf_stream(update).map(Primitive::Stream),
183+
}
181184
}
182185
}
183186
impl<I: DeepClone> DeepClone for Stream<I> {

‎pdf/src/object/types.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,11 @@ impl PageRc {
6868
pub fn create(page: Page, update: &mut impl Updater) -> Result<PageRc> {
6969
Ok(PageRc(update.create(PagesNode::Leaf(page))?))
7070
}
71-
pub fn get_ref(&self) -> Ref<PagesNode> {
72-
self.0.get_ref()
71+
pub fn update(page: Page, old_page: &PageRc, update: &mut impl Updater) -> Result<PageRc> {
72+
update.update(old_page.get_ref(), PagesNode::Leaf(page)).map(PageRc)
73+
}
74+
pub fn get_ref(&self) -> PlainRef {
75+
self.0.inner
7376
}
7477
}
7578
impl Object for PageRc {
@@ -979,6 +982,9 @@ pub struct Annot {
979982
#[pdf(key="InkList")]
980983
pub ink_list: Option<Primitive>,
981984

985+
#[pdf(key="L")]
986+
pub line: Option<Vec<f32>>,
987+
982988
#[pdf(other)]
983989
pub other: Dictionary,
984990
}

‎pdf/src/primitive.rs

+9-4
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,10 @@ impl Object for PdfStream {
268268
}
269269
impl ObjectWrite for PdfStream {
270270
fn to_primitive(&self, update: &mut impl Updater) -> Result<Primitive> {
271-
Ok(self.clone().into())
271+
match self.inner {
272+
StreamInner::InFile { id, .. } => Ok(Primitive::Reference(id)),
273+
StreamInner::Pending { .. } => Ok(self.clone().into()),
274+
}
272275
}
273276
}
274277
impl PdfStream {
@@ -277,14 +280,16 @@ impl PdfStream {
277280

278281
writeln!(out, "stream")?;
279282
match self.inner {
280-
StreamInner::InFile { .. } => {
281-
unimplemented!()
283+
StreamInner::InFile { id, .. } => {
284+
Primitive::Reference(id).serialize(out)?;
282285
}
283286
StreamInner::Pending { ref data } => {
287+
self.info.serialize(out)?;
288+
writeln!(out, "stream")?;
284289
out.write_all(data)?;
290+
writeln!(out, "\nendstream")?;
285291
}
286292
}
287-
writeln!(out, "\nendstream")?;
288293
Ok(())
289294
}
290295
pub fn raw_data(&self, resolve: &impl Resolve) -> Result<Arc<[u8]>> {

0 commit comments

Comments
 (0)
Please sign in to comment.