1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
use super::{Document, Object, ObjectId};
impl Document {
pub fn new_object_id(&mut self) -> ObjectId {
self.max_id += 1;
(self.max_id, 0)
}
pub fn add_object<T: Into<Object>>(&mut self, object: T) -> ObjectId {
self.max_id += 1;
let id = (self.max_id, 0);
self.objects.insert(id, object.into());
id
}
}
#[test]
fn create_document() {
use super::{Dictionary, Stream, StringFormat};
use super::content::*;
use Object::Reference;
use std::iter::FromIterator;
use chrono::prelude::Local;
let mut doc = Document::new();
doc.version = "1.5".to_string();
let info_id = doc.add_object(
Dictionary::from_iter(vec![
("Title", Object::String(b"Create PDF document example".to_vec(), StringFormat::Literal)),
("Creator", Object::String(b"https://crates.io/crates/lopdf".to_vec(), StringFormat::Literal)),
("CreationDate", Local::now().into()),
])
);
let pages_id = doc.new_object_id();
let font_id = doc.add_object(
Dictionary::from_iter(vec![
("Type", "Font".into()),
("Subtype", "Type1".into()),
("BaseFont", "Courier".into()),
])
);
let resources_id = doc.add_object(
Dictionary::from_iter(vec![
("Font", Dictionary::from_iter(vec![
("F1", Reference(font_id)),
]).into()),
])
);
let content = Content{operations: vec![
Operation::new("BT", vec![]),
Operation::new("Tf", vec!["F1".into(), 48.into()]),
Operation::new("Td", vec![100.into(), 600.into()]),
Operation::new("Tj", vec![Object::String(b"Hello World!".to_vec(), StringFormat::Literal)]),
Operation::new("ET", vec![]),
]};
let content_id = doc.add_object(Stream::new(Dictionary::new(), content.encode().unwrap()));
let page_id = doc.add_object(
Dictionary::from_iter(vec![
("Type", "Page".into()),
("Parent", Reference(pages_id)),
("Contents", vec![Reference(content_id)].into()),
])
);
let pages = Dictionary::from_iter(vec![
("Type", "Pages".into()),
("Kids", vec![Reference(page_id)].into()),
("Count", 1.into()),
("Resources", Reference(resources_id)),
("MediaBox", vec![0.into(), 0.into(), 595.into(), 842.into()].into()),
]);
doc.objects.insert(pages_id, Object::Dictionary(pages));
let catalog_id = doc.add_object(
Dictionary::from_iter(vec![
("Type", "Catalog".into()),
("Pages", Reference(pages_id)),
])
);
doc.trailer.set("Root", Reference(catalog_id));
doc.trailer.set("Info", Reference(info_id));
doc.compress();
doc.save("test_1_create.pdf").unwrap();
use std::fs::File;
use std::io::Cursor;
let in_file = File::open("test_1_create.pdf").unwrap();
let mut in_doc = Document::load_from(in_file).unwrap();
let out_buf = Vec::<u8>::new();
let mut memory_cursor = Cursor::new(out_buf);
in_doc.save_to(&mut memory_cursor).unwrap();
assert!(!memory_cursor.get_ref().is_empty());
}