use crate::error::{GraphitePdfKitError, Result};
use std::fmt;
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct PageSize {
pub width: f64,
pub height: f64,
}
impl PageSize {
pub const A0: Self = Self::new(2383.937, 3370.394);
pub const A1: Self = Self::new(1683.780, 2383.937);
pub const A2: Self = Self::new(1190.551, 1683.780);
pub const A3: Self = Self::new(841.890, 1190.551);
pub const A4: Self = Self::new(595.276, 841.890);
pub const A5: Self = Self::new(420.472, 595.276);
pub const A6: Self = Self::new(297.638, 420.472);
pub const LETTER: Self = Self::new(612.0, 792.0);
pub const LEGAL: Self = Self::new(612.0, 1008.0);
pub const TABLOID: Self = Self::new(792.0, 1224.0);
pub const fn new(width: f64, height: f64) -> Self {
Self { width, height }
}
pub fn landscape(&self) -> Self {
Self::new(self.height, self.width)
}
pub fn from_inches(width_in: f64, height_in: f64) -> Result<Self> {
if width_in <= 0.0 || height_in <= 0.0 {
return Err(GraphitePdfKitError::InvalidPageSize(
"Page dimensions must be positive".to_string(),
));
}
Ok(Self::new(width_in * 72.0, height_in * 72.0))
}
pub fn from_mm(width_mm: f64, height_mm: f64) -> Result<Self> {
if width_mm <= 0.0 || height_mm <= 0.0 {
return Err(GraphitePdfKitError::InvalidPageSize(
"Page dimensions must be positive".to_string(),
));
}
const MM_PER_POINT: f64 = 25.4 / 72.0;
Ok(Self::new(width_mm / MM_PER_POINT, height_mm / MM_PER_POINT))
}
pub fn from_cm(width_cm: f64, height_cm: f64) -> Result<Self> {
Self::from_mm(width_cm * 10.0, height_cm * 10.0)
}
}
impl TryFrom<(f64, f64)> for PageSize {
type Error = GraphitePdfKitError;
fn try_from(value: (f64, f64)) -> Result<Self> {
if value.0 <= 0.0 || value.1 <= 0.0 {
return Err(GraphitePdfKitError::InvalidPageSize(
"Page width and height must be positive".to_string(),
));
}
Ok(Self::new(value.0, value.1))
}
}
impl Default for PageSize {
fn default() -> Self {
Self::A4
}
}
impl fmt::Display for PageSize {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{} × {} pt", self.width, self.height)
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct PageMargins {
pub left: f64,
pub right: f64,
pub top: f64,
pub bottom: f64,
}
impl PageMargins {
pub const fn new(left: f64, right: f64, top: f64, bottom: f64) -> Self {
Self {
left,
right,
top,
bottom,
}
}
pub const fn all(value: f64) -> Self {
Self::new(value, value, value, value)
}
pub const ZERO: Self = Self::all(0.0);
pub const ONE_INCH: Self = Self::all(72.0);
}
impl Default for PageMargins {
fn default() -> Self {
Self::ONE_INCH
}
}
impl fmt::Display for PageMargins {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"left: {} pt, right: {} pt, top: {} pt, bottom: {} pt",
self.left, self.right, self.top, self.bottom
)
}
}
impl From<f64> for PageMargins {
fn from(value: f64) -> Self {
Self::all(value)
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
pub enum PageOrientation {
#[default]
Portrait,
Landscape,
}