1use crate::error::Result;
2use crate::objects::{Object, ObjectId};
3use crate::page::Page;
4use crate::writer::PdfWriter;
5use std::collections::HashMap;
6
7pub struct Document {
24 pub(crate) pages: Vec<Page>,
25 #[allow(dead_code)]
26 pub(crate) objects: HashMap<ObjectId, Object>,
27 #[allow(dead_code)]
28 pub(crate) next_object_id: u32,
29 pub(crate) metadata: DocumentMetadata,
30}
31
32#[derive(Debug, Clone)]
34pub struct DocumentMetadata {
35 pub title: Option<String>,
37 pub author: Option<String>,
39 pub subject: Option<String>,
41 pub keywords: Option<String>,
43 pub creator: Option<String>,
45 pub producer: Option<String>,
47}
48
49impl Default for DocumentMetadata {
50 fn default() -> Self {
51 Self {
52 title: None,
53 author: None,
54 subject: None,
55 keywords: None,
56 creator: Some("oxidize_pdf".to_string()),
57 producer: Some("oxidize_pdf".to_string()),
58 }
59 }
60}
61
62impl Document {
63 pub fn new() -> Self {
65 Self {
66 pages: Vec::new(),
67 objects: HashMap::new(),
68 next_object_id: 1,
69 metadata: DocumentMetadata::default(),
70 }
71 }
72
73 pub fn add_page(&mut self, page: Page) {
75 self.pages.push(page);
76 }
77
78 pub fn set_title(&mut self, title: impl Into<String>) {
80 self.metadata.title = Some(title.into());
81 }
82
83 pub fn set_author(&mut self, author: impl Into<String>) {
85 self.metadata.author = Some(author.into());
86 }
87
88 pub fn set_subject(&mut self, subject: impl Into<String>) {
90 self.metadata.subject = Some(subject.into());
91 }
92
93 pub fn set_keywords(&mut self, keywords: impl Into<String>) {
95 self.metadata.keywords = Some(keywords.into());
96 }
97
98 pub fn save(&mut self, path: impl AsRef<std::path::Path>) -> Result<()> {
104 let mut writer = PdfWriter::new(path)?;
105 writer.write_document(self)?;
106 Ok(())
107 }
108
109 pub fn write(&mut self, buffer: &mut Vec<u8>) -> Result<()> {
115 let mut writer = PdfWriter::new_with_writer(buffer);
116 writer.write_document(self)?;
117 Ok(())
118 }
119
120 #[allow(dead_code)]
121 pub(crate) fn allocate_object_id(&mut self) -> ObjectId {
122 let id = ObjectId::new(self.next_object_id, 0);
123 self.next_object_id += 1;
124 id
125 }
126
127 #[allow(dead_code)]
128 pub(crate) fn add_object(&mut self, obj: Object) -> ObjectId {
129 let id = self.allocate_object_id();
130 self.objects.insert(id, obj);
131 id
132 }
133}
134
135impl Default for Document {
136 fn default() -> Self {
137 Self::new()
138 }
139}