use lopdf::{Document, Object, Result, dictionary};
mod utils;
fn page_with_mixed_annots(annots_indirect: bool) -> (Document, lopdf::ObjectId) {
let mut doc = Document::with_version("1.7");
let referenced = doc.add_object(dictionary! {
"Type" => "Annot",
"Subtype" => "Text",
"Contents" => Object::string_literal("referenced"),
});
let entries = vec![
Object::Reference(referenced),
Object::Dictionary(dictionary! {
"Type" => "Annot",
"Subtype" => "Text",
"Contents" => Object::string_literal("direct"),
}),
];
let annots = if annots_indirect {
Object::Reference(doc.add_object(Object::Array(entries)))
} else {
Object::Array(entries)
};
let page_id = doc.add_object(dictionary! {
"Type" => "Page",
"Annots" => annots,
});
(doc, page_id)
}
fn contents_of(doc: &Document, page_id: lopdf::ObjectId) -> Vec<String> {
doc.get_page_annotations(page_id)
.unwrap()
.iter()
.map(|a| String::from_utf8_lossy(a.get(b"Contents").unwrap().as_str().unwrap()).into_owned())
.collect()
}
#[test]
fn page_annotations_include_direct_dictionaries() {
let (doc, page_id) = page_with_mixed_annots(false);
assert_eq!(contents_of(&doc, page_id), vec!["referenced", "direct"]);
}
#[test]
fn page_annotations_include_direct_dictionaries_behind_an_indirect_annots() {
let (doc, page_id) = page_with_mixed_annots(true);
assert_eq!(contents_of(&doc, page_id), vec!["referenced", "direct"]);
}
#[test]
fn page_annotations_skip_a_dangling_reference() {
let mut doc = Document::with_version("1.7");
let good = doc.add_object(dictionary! {
"Type" => "Annot",
"Subtype" => "Text",
"Contents" => Object::string_literal("kept"),
});
let page_id = doc.add_object(dictionary! {
"Type" => "Page",
"Annots" => vec![
Object::Reference((9999, 0)),
Object::Reference(good),
Object::Null,
],
});
assert_eq!(contents_of(&doc, page_id), vec!["kept"]);
}
#[test]
fn page_annotations_without_annots_is_empty() {
let mut doc = Document::with_version("1.7");
let page_id = doc.add_object(dictionary! { "Type" => "Page" });
assert!(doc.get_page_annotations(page_id).unwrap().is_empty());
}
#[test]
fn annotation_count() -> Result<()> {
let doc = utils::load_document("assets/AnnotationDemo.pdf")?;
assert_eq!(doc.version, "1.7".to_string());
assert_eq!(doc.page_iter().count(), 1);
assert_eq!(doc.get_page_annotations(doc.page_iter().next().unwrap())?.len(), 33);
Ok(())
}