Skip to content

Commit

Permalink
some improvments on forms
Browse files Browse the repository at this point in the history
  • Loading branch information
s3bk committed Dec 11, 2023
1 parent cf0ed63 commit b4d21fc
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 68 deletions.
107 changes: 43 additions & 64 deletions examples/src/bin/form.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,32 +17,57 @@ fn main() -> Result<(), PdfError> {
let mut file = FileOptions::cached().open(&path).unwrap();
let mut to_update_field: Option<_> = None;

let page0 = file.get_page(0).unwrap();
let ops = page0
.contents.as_ref().unwrap()
.operations(&file.resolver()).unwrap();

for annot in &page0.annotations {
let font = Font {
data: FontData::TrueType(TFont{
base_font: Some(Name::from("Helvetica")),
first_char: None,
font_descriptor: None,
last_char: None,
widths: None,
}),
encoding: Some(pdf::encoding::Encoding::standard()),
name: None,
subtype: pdf::font::FontType::TrueType,
to_unicode: None,
_other: Default::default()
};
let font_name = Name::from("Helvetica");
let font = file.create(font)?;
let mut fonts = HashMap::new();
fonts.insert("Helvetica".into(), font.into());
let resources = Resources {
fonts,
.. Default::default()
};
let resources = file.create(resources)?;

let page0 = file.get_page(0).unwrap();
for &annot in &page0.annotations {
let annot = file.resolver().get(annot)?;
if let Some(ref a) = annot.appearance_streams {
let normal = file.resolver().get(a.normal);
if let Ok(normal) = normal {
match *normal {
AppearanceStreamEntry::Single(ref s) => {
//dbg!(&s.stream.resources);

let mut ops = s.operations(&file.resolver())?;
for op in ops.iter_mut() {
match op {
Op::TextDraw { text } => {
println!("{}", text.to_string_lossy());
*text = PdfString::from("helloo");
}
_ => {}
}
}
let stream = Stream::new(s.stream.info.info.clone(), serialize_ops(&ops)?);
let form_dict = FormDict {
resources: Some(resources.clone().into()),
.. (**s.stream).clone()
};

let ops = vec![
Op::Save,
Op::TextFont { name: font_name.clone(), size: 14.0 },
Op::TextDraw { text: PdfString::from("Hello World!") },
Op::EndText,
Op::Restore
];
let stream = Stream::new(form_dict, serialize_ops(&ops)?);

let normal2 = AppearanceStreamEntry::Single(FormXObject { stream });

file.update(a.normal.get_inner(), normal2)?;
}
_ => {}
Expand All @@ -68,63 +93,17 @@ fn main() -> Result<(), PdfError> {
}
}

/*
let font = Font {
data: FontData::TrueType(TFont{
base_font: Some(Name::from("Helvetica")),
first_char: None,
font_descriptor: None,
last_char: None,
widths: None,
}),
encoding: Some(pdf::encoding::Encoding::standard()),
name: None,
subtype: pdf::font::FontType::TrueType,
to_unicode: None,
_other: Default::default()
};
let font_name = Name::from("Helvetica");
let font = file.create(font)?;
let mut fonts = HashMap::new();
fonts.insert("Helvetica".into(), font.into());
let resources = Resources {
fonts,
.. Default::default()
};
let resources = file.create(resources)?;
*/

if let Some(to_update_field) = to_update_field {
println!("\nUpdating field:");
println!("{:?}\n", to_update_field);

let text = "helloo";
let text = "Hello World!";
let new_value: PdfString = PdfString::new(text.into());
let mut updated_field = (*to_update_field).clone();
updated_field.value = Primitive::String(new_value);

/*
let mut form_dict = FormDict {
bbox: updated_field.rect,
resources: Some(resources.into()),
.. Default::default()
};
let content = format!("q BT /Helvetica 14 Tf ({text}) ET Q");
let form = FormXObject {
stream: Stream::new(form_dict, content.into_bytes())
};
//dbg!(&form);
let normal = AppearanceStreamEntry::Single(form);
let apperance = AppearanceStreams {
normal: file.create(normal)?.into(),
down: None,
rollover: None
};
//updated_field.appearance_streams = Some(apperance.into());
//updated_field.appearance_state = Some("N".into());
//dbg!(&updated_field);
*/

let reference = file.update(

Check warning on line 107 in examples/src/bin/form.rs

View workflow job for this annotation

GitHub Actions / clippy

unused variable: `reference`

warning: unused variable: `reference` --> examples/src/bin/form.rs:107:13 | 107 | let reference = file.update( | ^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_reference` | = note: `#[warn(unused_variables)]` on by default
to_update_field.get_ref().get_inner(),
updated_field,
Expand Down
26 changes: 24 additions & 2 deletions pdf/src/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,15 @@ where
}
});
match res {
Ok(any) => Ok(RcRef::new(key, any.downcast()?)),
Ok(any) => {
match any.downcast() {
Ok(val) => Ok(RcRef::new(key, val)),
Err(_) => {
let p = self.resolve(key)?;
Ok(RcRef::new(key, T::from_primitive(p, self)?.into()))
}
}
}
Err(e) => Err(PdfError::Shared { source: e.clone()}),
}
}
Expand Down Expand Up @@ -359,6 +367,8 @@ where
Ok(RcRef::new(r, rc))
}
fn update<T: ObjectWrite>(&mut self, old: PlainRef, obj: T) -> Result<RcRef<T>> {
use std::collections::hash_map::Entry;

let r = match self.refs.get(old.id)? {
XRef::Free { .. } => panic!(),
XRef::Raw { gen_nr, .. } => PlainRef { id: old.id, gen: gen_nr },
Expand All @@ -367,7 +377,19 @@ where
XRef::Invalid => panic!()
};
let primitive = obj.to_primitive(self)?;
self.changes.insert(old.id, (primitive, r.gen));
match self.changes.entry(old.id) {
Entry::Vacant(e) => {
e.insert((primitive, r.gen));
}
Entry::Occupied(mut e) => match (e.get_mut(), primitive) {
((Primitive::Dictionary(ref mut dict), _), Primitive::Dictionary(new)) => {
dict.append(new);
}
(old, new) => {
*old = (new, r.gen);
}
}
}
let rc = Shared::new(obj);

Ok(RcRef::new(r, rc))
Expand Down
2 changes: 1 addition & 1 deletion pdf/src/object/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ pub struct Page {
pub vp: Option<Primitive>,

#[pdf(key="Annots", default="vec![]")]
pub annotations: Vec<Annot>,
pub annotations: Vec<Ref<Annot>>,

#[pdf(other)]
pub other: Dictionary,
Expand Down
4 changes: 3 additions & 1 deletion pdf/src/primitive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,9 @@ impl Dictionary {
None => Ok(())
}
}
pub fn append(&mut self, other: Dictionary) {
self.dict.extend(other.dict);
}
}
impl DataSize for Dictionary {
const IS_DYNAMIC: bool = true;
Expand Down Expand Up @@ -849,7 +852,6 @@ mod tests {
}

#[test]
#[should_panic]
fn utf16be_invalid_bytelen() {
let s = PdfString::new([0xfe, 0xff, 0xd8, 0x34, 0x20].as_slice().into());
let repl_ch = String::from(std::char::REPLACEMENT_CHARACTER);
Expand Down

0 comments on commit b4d21fc

Please sign in to comment.