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 pub(crate) objects: HashMap<ObjectId, Object>,
26 pub(crate) next_object_id: u32,
27 pub(crate) metadata: DocumentMetadata,
28}
29
30#[derive(Debug, Clone)]
32pub struct DocumentMetadata {
33 pub title: Option<String>,
35 pub author: Option<String>,
37 pub subject: Option<String>,
39 pub keywords: Option<String>,
41 pub creator: Option<String>,
43 pub producer: Option<String>,
45}
46
47impl Default for DocumentMetadata {
48 fn default() -> Self {
49 Self {
50 title: None,
51 author: None,
52 subject: None,
53 keywords: None,
54 creator: Some("oxidize_pdf".to_string()),
55 producer: Some("oxidize_pdf".to_string()),
56 }
57 }
58}
59
60impl Document {
61 pub fn new() -> Self {
63 Self {
64 pages: Vec::new(),
65 objects: HashMap::new(),
66 next_object_id: 1,
67 metadata: DocumentMetadata::default(),
68 }
69 }
70
71 pub fn add_page(&mut self, page: Page) {
73 self.pages.push(page);
74 }
75
76 pub fn set_title(&mut self, title: impl Into<String>) {
78 self.metadata.title = Some(title.into());
79 }
80
81 pub fn set_author(&mut self, author: impl Into<String>) {
83 self.metadata.author = Some(author.into());
84 }
85
86 pub fn set_subject(&mut self, subject: impl Into<String>) {
88 self.metadata.subject = Some(subject.into());
89 }
90
91 pub fn set_keywords(&mut self, keywords: impl Into<String>) {
93 self.metadata.keywords = Some(keywords.into());
94 }
95
96 pub fn save(&mut self, path: impl AsRef<std::path::Path>) -> Result<()> {
102 let mut writer = PdfWriter::new(path)?;
103 writer.write_document(self)?;
104 Ok(())
105 }
106
107 pub fn write(&mut self, buffer: &mut Vec<u8>) -> Result<()> {
113 let mut writer = PdfWriter::new_with_writer(buffer);
114 writer.write_document(self)?;
115 Ok(())
116 }
117
118 pub(crate) fn allocate_object_id(&mut self) -> ObjectId {
119 let id = ObjectId::new(self.next_object_id, 0);
120 self.next_object_id += 1;
121 id
122 }
123
124 pub(crate) fn add_object(&mut self, obj: Object) -> ObjectId {
125 let id = self.allocate_object_id();
126 self.objects.insert(id, obj);
127 id
128 }
129}
130
131impl Default for Document {
132 fn default() -> Self {
133 Self::new()
134 }
135}