zng_layout/unit/
resolution.rs

1use std::fmt;
2
3use zng_var::{animation::Transitionable, impl_from_and_into_var};
4
5/// Pixels-per-inch resolution.
6#[derive(Debug, Clone, Copy, serde::Serialize, serde::Deserialize, Transitionable)]
7#[serde(transparent)]
8pub struct Ppi(pub f32);
9impl Ppi {
10    /// Returns the minimum of the two resolutions.
11    pub fn min(self, other: impl Into<Ppi>) -> Ppi {
12        Ppi(self.0.min(other.into().0))
13    }
14
15    /// Returns the maximum of the two resolutions.
16    pub fn max(self, other: impl Into<Ppi>) -> Ppi {
17        Ppi(self.0.max(other.into().0))
18    }
19}
20impl Default for Ppi {
21    /// 96ppi.
22    fn default() -> Self {
23        Ppi(96.0)
24    }
25}
26impl PartialEq for Ppi {
27    fn eq(&self, other: &Self) -> bool {
28        super::about_eq(self.0, other.0, 0.0001)
29    }
30}
31impl std::hash::Hash for Ppi {
32    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
33        super::about_eq_hash(self.0, 0.0001, state)
34    }
35}
36
37/// Pixels-per-meter resolution.
38#[derive(Debug, Clone, Copy, PartialEq, serde::Serialize, serde::Deserialize, Transitionable)]
39#[serde(transparent)]
40pub struct Ppm(pub f32);
41impl Ppm {
42    /// Returns the minimum of the two resolutions.
43    pub fn min(self, other: impl Into<Ppm>) -> Ppm {
44        Ppm(self.0.min(other.into().0))
45    }
46
47    /// Returns the maximum of the two resolutions.
48    pub fn max(self, other: impl Into<Ppm>) -> Ppm {
49        Ppm(self.0.max(other.into().0))
50    }
51}
52impl Default for Ppm {
53    /// 96ppi.
54    fn default() -> Self {
55        Ppi(96.0).into()
56    }
57}
58
59/// Extension methods for initializing resolution units.
60///
61/// # Examples
62///
63/// ```
64/// use zng_layout::unit::*;
65///
66/// let ppm: Ppm = 96.dpi().into();
67/// ```
68pub trait ResolutionUnits {
69    /// Pixels-per-inch.
70    fn ppi(self) -> Ppi;
71    /// Same as [`ppi`].
72    ///
73    /// [`ppi`]: ResolutionUnits::ppi
74    fn dpi(self) -> Ppi
75    where
76        Self: Sized,
77    {
78        self.ppi()
79    }
80
81    /// Pixels-per-meter.
82    fn ppm(self) -> Ppm;
83}
84impl ResolutionUnits for u32 {
85    fn ppi(self) -> Ppi {
86        Ppi(self as f32)
87    }
88
89    fn ppm(self) -> Ppm {
90        Ppm(self as f32)
91    }
92}
93impl ResolutionUnits for f32 {
94    fn ppi(self) -> Ppi {
95        Ppi(self)
96    }
97
98    fn ppm(self) -> Ppm {
99        Ppm(self)
100    }
101}
102
103impl fmt::Display for Ppi {
104    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
105        write!(f, "{}ppi", self.0)
106    }
107}
108impl fmt::Display for Ppm {
109    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
110        write!(f, "{}ppm", self.0)
111    }
112}
113impl_from_and_into_var! {
114    fn from(ppi: Ppi) -> Ppm {
115        Ppm(ppi.0 * 39.3701)
116    }
117
118    fn from(ppm: Ppm) -> Ppi {
119        Ppi(ppm.0 / 39.3701)
120    }
121}