use std::fmt;
use zng_var::{animation::Transitionable, impl_from_and_into_var};
#[derive(Debug, Clone, Copy, serde::Serialize, serde::Deserialize, Transitionable)]
#[serde(transparent)]
pub struct Ppi(pub f32);
impl Ppi {
pub fn min(self, other: impl Into<Ppi>) -> Ppi {
Ppi(self.0.min(other.into().0))
}
pub fn max(self, other: impl Into<Ppi>) -> Ppi {
Ppi(self.0.max(other.into().0))
}
}
impl Default for Ppi {
fn default() -> Self {
Ppi(96.0)
}
}
impl PartialEq for Ppi {
fn eq(&self, other: &Self) -> bool {
super::about_eq(self.0, other.0, 0.0001)
}
}
impl std::hash::Hash for Ppi {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
super::about_eq_hash(self.0, 0.0001, state)
}
}
#[derive(Debug, Clone, Copy, PartialEq, serde::Serialize, serde::Deserialize, Transitionable)]
#[serde(transparent)]
pub struct Ppm(pub f32);
impl Ppm {
pub fn min(self, other: impl Into<Ppm>) -> Ppm {
Ppm(self.0.min(other.into().0))
}
pub fn max(self, other: impl Into<Ppm>) -> Ppm {
Ppm(self.0.max(other.into().0))
}
}
impl Default for Ppm {
fn default() -> Self {
Ppi(96.0).into()
}
}
pub trait ResolutionUnits {
fn ppi(self) -> Ppi;
fn dpi(self) -> Ppi
where
Self: Sized,
{
self.ppi()
}
fn ppm(self) -> Ppm;
}
impl ResolutionUnits for u32 {
fn ppi(self) -> Ppi {
Ppi(self as f32)
}
fn ppm(self) -> Ppm {
Ppm(self as f32)
}
}
impl ResolutionUnits for f32 {
fn ppi(self) -> Ppi {
Ppi(self)
}
fn ppm(self) -> Ppm {
Ppm(self)
}
}
impl fmt::Display for Ppi {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}ppi", self.0)
}
}
impl fmt::Display for Ppm {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}ppm", self.0)
}
}
impl_from_and_into_var! {
fn from(ppi: Ppi) -> Ppm {
Ppm(ppi.0 * 39.3701)
}
fn from(ppm: Ppm) -> Ppi {
Ppi(ppm.0 / 39.3701)
}
}