graphitepdf-kit 0.2.0

A core PDF generation library for Rust: document building, text, vector graphics, images, and more.
Documentation
use crate::backend_font::{Font, FontRegistry};
use crate::error::Result;
use crate::metadata::Metadata;
use crate::page::{PageMargins, PageSize};
use crate::writer::PdfWriter;

#[cfg(feature = "tracing")]
use tracing::instrument;

#[derive(Clone, Debug)]
pub struct Page {
    size: PageSize,
    margins: PageMargins,
    content: Vec<u8>,
}

impl Page {
    pub fn new(size: PageSize) -> Self {
        Self {
            size,
            margins: PageMargins::default(),
            content: Vec::new(),
        }
    }

    pub fn with_margins(mut self, margins: PageMargins) -> Self {
        self.margins = margins;
        self
    }

    pub fn with_content(mut self, content: Vec<u8>) -> Self {
        self.content = content;
        self
    }
}

#[derive(Clone, Debug)]
pub struct DocumentBuilder {
    metadata: Metadata,
    pages: Vec<Page>,
    fonts: FontRegistry,
}

impl DocumentBuilder {
    pub fn new() -> Self {
        Self {
            metadata: Metadata::new(),
            pages: Vec::new(),
            fonts: FontRegistry::with_default_font(),
        }
    }

    pub fn metadata(mut self, metadata: Metadata) -> Self {
        self.metadata = metadata;
        self
    }

    pub fn add_font(mut self, font: impl Into<Font>) -> (Self, String) {
        let name = self.fonts.register(font);
        (self, name)
    }

    pub fn add_page(mut self, page: Page) -> Self {
        self.pages.push(page);
        self
    }

    pub fn with_page(mut self, size: PageSize, content: impl Into<Vec<u8>>) -> Self {
        self.pages.push(Page {
            size,
            margins: PageMargins::default(),
            content: content.into(),
        });
        self
    }

    #[cfg_attr(feature = "tracing", instrument(skip(self, writer)))]
    pub fn write<W: std::io::Write>(self, mut writer: W) -> Result<()> {
        let mut pdf_writer = PdfWriter::with_metadata_and_fonts(self.metadata, self.fonts);
        for page in self.pages {
            pdf_writer.add_page(page.size, page.content);
        }
        let buffer = pdf_writer.write_all()?;
        writer.write_all(&buffer)?;
        Ok(())
    }

    #[cfg_attr(feature = "tracing", instrument(skip(self, path)))]
    pub fn save(self, path: impl AsRef<std::path::Path>) -> Result<()> {
        let mut file = std::fs::File::create(path)?;
        self.write(&mut file)?;
        Ok(())
    }
}

impl Default for DocumentBuilder {
    fn default() -> Self {
        Self::new()
    }
}