Skip to main content

pdfium_render/pdf/
points.rs

1//! Defines the [PdfPoints] struct, the basic unit of measurement within the internal
2//! coordinate system inside a [PdfDocument].
3
4use std::cmp::Ordering;
5use std::fmt::{Display, Formatter};
6use std::ops::{Add, AddAssign, Div, Mul, Neg, Sub, SubAssign};
7
8#[cfg(doc)]
9use {crate::pdf::bitmap::PdfBitmap, crate::pdf::document::PdfDocument, crate::pdf::document::page::PdfPage};
10
11/// The internal coordinate system inside a [PdfDocument] is measured in Points, a
12/// device-independent unit equal to 1/72 inches, roughly 0.358 mm. Points are converted to pixels
13/// when a [PdfPage] is rendered into a [PdfBitmap].
14#[derive(Debug, Copy, Clone, PartialOrd, PartialEq)]
15#[allow(clippy::derive_ord_xor_partial_ord)]
16pub struct PdfPoints {
17    pub value: f32,
18}
19
20impl PdfPoints {
21    /// A [PdfPoints] object with identity value 0.0.
22    pub const ZERO: PdfPoints = PdfPoints::zero();
23
24    /// A [PdfPoints] object with the largest addressable finite positive value.
25    pub const MAX: PdfPoints = PdfPoints::max();
26
27    /// A [PdfPoints] object with the smallest addressable finite negative value.
28    pub const MIN: PdfPoints = PdfPoints::min();
29
30    /// Creates a new [PdfPoints] object with the given value.
31    #[inline]
32    pub const fn new(value: f32) -> Self {
33        Self { value }
34    }
35
36    /// Creates a new [PdfPoints] object with the value 0.0.
37    ///
38    /// Consider using the compile-time constant value [PdfPoints::ZERO]
39    /// rather than calling this function directly.
40    #[inline]
41    pub const fn zero() -> Self {
42        Self::new(0.0)
43    }
44
45    /// A [PdfPoints] object with the largest addressable finite positive value.
46    ///
47    /// In theory, this should be [f32::MAX]; in practice, values approaching [f32::MAX]
48    /// are handled inconsistently by Pdfium, so this value is set to an arbitrarily large
49    /// positive value that does not approach [f32::MAX] but should more than suffice
50    /// for every use case.
51    #[inline]
52    pub const fn max() -> Self {
53        Self::new(2_000_000_000.0)
54    }
55
56    /// A [PdfPoints] object with the smallest addressable finite negative value.
57    ///
58    /// In theory, this should be [f32::MIN]; in practice, values approaching [f32::MIN]
59    /// are handled inconsistently by Pdfium, so this value is set to an arbitrarily large
60    /// negative value that does not approach [f32::MIN] but should more than suffice
61    /// for every use case.
62    #[inline]
63    pub const fn min() -> Self {
64        Self::new(-2_000_000_000.0)
65    }
66
67    /// Creates a new [PdfPoints] object from the given measurement in inches.
68    #[inline]
69    pub fn from_inches(inches: f32) -> Self {
70        Self::new(inches * 72.0)
71    }
72
73    /// Creates a new [PdfPoints] object from the given measurement in centimeters.
74    #[inline]
75    pub fn from_cm(cm: f32) -> Self {
76        Self::from_inches(cm / 2.54)
77    }
78
79    /// Creates a new [PdfPoints] object from the given measurement in millimeters.
80    #[inline]
81    pub fn from_mm(mm: f32) -> Self {
82        Self::from_cm(mm / 10.0)
83    }
84
85    /// Converts the value of this [PdfPoints] object to inches.
86    #[inline]
87    pub fn to_inches(&self) -> f32 {
88        self.value / 72.0
89    }
90
91    /// Converts the value of this [PdfPoints] object to centimeters.
92    #[inline]
93    pub fn to_cm(&self) -> f32 {
94        self.to_inches() * 2.54
95    }
96
97    /// Converts the value of this [PdfPoints] object to millimeters.
98    #[inline]
99    pub fn to_mm(&self) -> f32 {
100        self.to_cm() * 10.0
101    }
102
103    /// Creates a new [PdfPoints] object with the absolute value of this [PdfPoints] object.
104    #[inline]
105    pub fn abs(&self) -> PdfPoints {
106        PdfPoints::new(self.value.abs())
107    }
108}
109
110impl Add<PdfPoints> for PdfPoints {
111    type Output = PdfPoints;
112
113    #[inline]
114    fn add(self, rhs: Self) -> Self::Output {
115        PdfPoints::new(self.value + rhs.value)
116    }
117}
118
119impl AddAssign<PdfPoints> for PdfPoints {
120    #[inline]
121    fn add_assign(&mut self, rhs: PdfPoints) {
122        self.value += rhs.value;
123    }
124}
125
126impl Sub<PdfPoints> for PdfPoints {
127    type Output = PdfPoints;
128
129    #[inline]
130    fn sub(self, rhs: Self) -> Self::Output {
131        PdfPoints::new(self.value - rhs.value)
132    }
133}
134
135impl SubAssign<PdfPoints> for PdfPoints {
136    #[inline]
137    fn sub_assign(&mut self, rhs: PdfPoints) {
138        self.value -= rhs.value;
139    }
140}
141
142impl Mul<f32> for PdfPoints {
143    type Output = PdfPoints;
144
145    #[inline]
146    fn mul(self, rhs: f32) -> Self::Output {
147        PdfPoints::new(self.value * rhs)
148    }
149}
150
151impl Div<f32> for PdfPoints {
152    type Output = PdfPoints;
153
154    #[inline]
155    fn div(self, rhs: f32) -> Self::Output {
156        PdfPoints::new(self.value / rhs)
157    }
158}
159
160impl Neg for PdfPoints {
161    type Output = PdfPoints;
162
163    #[inline]
164    fn neg(self) -> Self::Output {
165        PdfPoints::new(-self.value)
166    }
167}
168
169impl Eq for PdfPoints {}
170
171#[allow(clippy::derive_ord_xor_partial_ord)]
172impl Ord for PdfPoints {
173    #[inline]
174    fn cmp(&self, other: &Self) -> Ordering {
175        self.value.total_cmp(&other.value)
176    }
177}
178
179impl Display for PdfPoints {
180    #[inline]
181    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
182        f.write_fmt(format_args!("PdfPoints({})", self.value))
183    }
184}
185
186#[cfg(test)]
187mod tests {
188    use crate::prelude::*;
189
190    #[test]
191    fn test_points_ordering() {
192        assert!(PdfPoints::new(1.0) > PdfPoints::ZERO);
193        assert_eq!(PdfPoints::ZERO, -PdfPoints::ZERO);
194        assert!(PdfPoints::ZERO > PdfPoints::new(-1.0));
195    }
196}