Skip to main content

graphitepdf_kit/
document.rs

1use crate::backend_font::{Font, FontRegistry};
2use crate::error::Result;
3use crate::metadata::Metadata;
4use crate::page::{PageMargins, PageSize};
5use crate::writer::PdfWriter;
6
7#[cfg(feature = "tracing")]
8use tracing::instrument;
9
10#[derive(Clone, Debug)]
11pub struct Page {
12    size: PageSize,
13    margins: PageMargins,
14    content: Vec<u8>,
15}
16
17impl Page {
18    pub fn new(size: PageSize) -> Self {
19        Self {
20            size,
21            margins: PageMargins::default(),
22            content: Vec::new(),
23        }
24    }
25
26    pub fn with_margins(mut self, margins: PageMargins) -> Self {
27        self.margins = margins;
28        self
29    }
30
31    pub fn with_content(mut self, content: Vec<u8>) -> Self {
32        self.content = content;
33        self
34    }
35}
36
37#[derive(Clone, Debug)]
38pub struct DocumentBuilder {
39    metadata: Metadata,
40    pages: Vec<Page>,
41    fonts: FontRegistry,
42}
43
44impl DocumentBuilder {
45    pub fn new() -> Self {
46        Self {
47            metadata: Metadata::new(),
48            pages: Vec::new(),
49            fonts: FontRegistry::with_default_font(),
50        }
51    }
52
53    pub fn metadata(mut self, metadata: Metadata) -> Self {
54        self.metadata = metadata;
55        self
56    }
57
58    pub fn add_font(mut self, font: impl Into<Font>) -> (Self, String) {
59        let name = self.fonts.register(font);
60        (self, name)
61    }
62
63    pub fn add_page(mut self, page: Page) -> Self {
64        self.pages.push(page);
65        self
66    }
67
68    pub fn with_page(mut self, size: PageSize, content: impl Into<Vec<u8>>) -> Self {
69        self.pages.push(Page {
70            size,
71            margins: PageMargins::default(),
72            content: content.into(),
73        });
74        self
75    }
76
77    #[cfg_attr(feature = "tracing", instrument(skip(self, writer)))]
78    pub fn write<W: std::io::Write>(self, mut writer: W) -> Result<()> {
79        let mut pdf_writer = PdfWriter::with_metadata_and_fonts(self.metadata, self.fonts);
80        for page in self.pages {
81            pdf_writer.add_page(page.size, page.content);
82        }
83        let buffer = pdf_writer.write_all()?;
84        writer.write_all(&buffer)?;
85        Ok(())
86    }
87
88    #[cfg_attr(feature = "tracing", instrument(skip(self, path)))]
89    pub fn save(self, path: impl AsRef<std::path::Path>) -> Result<()> {
90        let mut file = std::fs::File::create(path)?;
91        self.write(&mut file)?;
92        Ok(())
93    }
94}
95
96impl Default for DocumentBuilder {
97    fn default() -> Self {
98        Self::new()
99    }
100}