pdfium_render/pdf/document/page/
size.rs

1//! Defines the [PdfPagePaperSize] enum, a set of common ANSI and ISO paper sizes.
2
3use crate::pdf::points::PdfPoints;
4use crate::pdf::rect::PdfRect;
5
6#[cfg(doc)]
7use crate::pdf::document::page::PdfPage;
8
9/// A standardized paper size.
10#[derive(Debug, Copy, Clone, PartialEq)]
11pub enum PdfPagePaperStandardSize {
12    /// ANSI Standard Paper A size (US Letter), 216 x 279 mm / 8.5 x 11.0 in
13    USLetterAnsiA,
14
15    /// US Half Letter size, 140 x 216 mm / 5.5 x 8.5 in
16    USHalfLetter,
17
18    /// US Government Letter size, 203 x 254 mm / 8.0 x 10.0 in
19    USGovernmentLetter,
20
21    /// US Legal size, 216 x 356 mm / 8.5 x 14.0 in
22    USLegal,
23
24    /// US Junior Legal size, 127 x 203 mm / 5.0 x 8.0 in
25    USJuniorLegal,
26
27    /// US Government Legal size, 216 x 330 mm / 8.5 x 13.0 in
28    USGovernmentLegal,
29
30    /// ANSI Standard Paper B size (US Ledger / Tabloid), 279 x 432 mm / 11.0 x 17.0 in
31    USLedgerTabloidAnsiB,
32
33    /// ISO 216 4A0, quadruple the size of ISO 216 standard A0, 1682 x 2378 mm
34    A0x4,
35
36    /// ISO 216 2A0, double the size of ISO 216 standard A0, 1189 x 1682 mm
37    A0x2,
38
39    /// ISO 216 A0, 841 x 1189 mm
40    A0,
41
42    /// ISO 216 A1, 594 x 841 mm
43    A1,
44
45    /// ISO 216 A2, 420 x 594 mm
46    A2,
47
48    /// ISO 216 A3, 297 x 420 mm
49    A3,
50
51    /// ISO 216 A4, 210 x 297 mm
52    A4,
53
54    /// ISO 216 A4R, equivalent to A4 rotated 90 degrees, 297 x 210 mm
55    A4R,
56
57    /// ISO 216 A5, 148 x 210 mm
58    A5,
59
60    /// ISO 216 A6, 105 x 148 mm
61    A6,
62
63    /// ISO 216 A7, 74 x 105 mm
64    A7,
65
66    /// ISO 216 A8, 52 x 74 mm
67    A8,
68
69    /// ISO 216 A9, 37 x 52 mm
70    A9,
71
72    /// ISO 216 A10, 26 x 37 mm
73    A10,
74
75    /// ISO 216 B0, 1000 x 1414 mm
76    B0,
77
78    /// ISO 216 B1, 707 x 1000 mm
79    B1,
80
81    /// ISO 216 B2, 500 x 707 mm
82    B2,
83
84    /// ISO 216 B3, 353 x 500 mm
85    B3,
86
87    /// ISO 216 B4, 250 x 353 mm
88    B4,
89
90    /// ISO 216 B5, 176 x 250 mm
91    B5,
92
93    /// ISO 216 B6, 125 x 176 mm
94    B6,
95
96    /// ISO 216 B7, 88 x 125 mm
97    B7,
98
99    /// ISO 216 B8, 62 x 88 mm
100    B8,
101
102    /// ISO 216 B9, 44 x 62 mm
103    B9,
104
105    /// ISO 216 B10, 31 x 44 mm
106    B10,
107
108    /// ISO 216 C0, 917 x 1297 mm
109    C0,
110
111    /// ISO 216 C1, 648 x 917 mm
112    C1,
113
114    /// ISO 216 C2, 458 x 648 mm
115    C2,
116
117    /// ISO 216 C3, 324 x 458 mm
118    C3,
119
120    /// ISO 216 C4, 229 x 324 mm
121    C4,
122
123    /// ISO 216 C5, 162 x 229 mm
124    C5,
125
126    /// ISO 216 C6, 114 x 162 mm
127    C6,
128
129    /// ISO 216 C7, 81 x 114 mm
130    C7,
131
132    /// ISO 216 C8, 57 x 81 mm
133    C8,
134
135    /// ISO 216 C9, 40 x 57 mm
136    C9,
137
138    /// ISO 216 C10, 28 x 40 mm
139    C10,
140
141    /// ANSI Standard Paper B+ (Super B) size, equivalent to ANSI B with a 1 inch margin,
142    /// 330 x 483 mm / 13.0 x 19.0 in
143    AnsiBPlus,
144
145    /// ANSI Standard Paper C size, 432 x 559 mm / 17.0 x 22.0 in
146    AnsiC,
147
148    /// ANSI Standard Paper D size, 559 x 864 mm / 22.0 x 34.0 in
149    AnsiD,
150
151    /// ANSI Standard Paper E size, 864 x 1118 mm / 34.0 x 44.0 in
152    AnsiE,
153
154    /// North American architectural A size, 229 x 305 mm / 9.0 x 12.0 in
155    ArchA,
156
157    /// North American architectural B size, 305 x 457 mm / 12.0 x 18.0 in
158    ArchB,
159
160    /// North American architectural C size, 457 x 610 mm / 18.0 x 24.0 in
161    ArchC,
162
163    /// North American architectural D size, 610 x 914 mm / 24.0 x 36.0 in
164    ArchD,
165
166    /// North American architectural E size, 762 x 1067 mm / 30.0 x 42.0 in
167    ArchE,
168}
169
170impl PdfPagePaperStandardSize {
171    /// Returns the [PdfPagePaperStandardSize] variant, if any, that exactly matches the
172    /// given dimensions in millimeters.
173    pub fn from_mm_dimensions(width: u32, height: u32) -> Option<PdfPagePaperStandardSize> {
174        match (width, height) {
175            (216, 279) => Some(PdfPagePaperStandardSize::USLetterAnsiA),
176            (140, 216) => Some(PdfPagePaperStandardSize::USHalfLetter),
177            (203, 254) => Some(PdfPagePaperStandardSize::USGovernmentLetter),
178            (216, 356) => Some(PdfPagePaperStandardSize::USLegal),
179            (127, 203) => Some(PdfPagePaperStandardSize::USJuniorLegal),
180            (216, 330) => Some(PdfPagePaperStandardSize::USGovernmentLegal),
181            (279, 432) => Some(PdfPagePaperStandardSize::USLedgerTabloidAnsiB),
182            (1682, 2378) => Some(PdfPagePaperStandardSize::A0x4),
183            (1189, 1682) => Some(PdfPagePaperStandardSize::A0x2),
184            (841, 1189) => Some(PdfPagePaperStandardSize::A0),
185            (594, 841) => Some(PdfPagePaperStandardSize::A1),
186            (420, 594) => Some(PdfPagePaperStandardSize::A2),
187            (297, 420) => Some(PdfPagePaperStandardSize::A3),
188            (210, 297) => Some(PdfPagePaperStandardSize::A4),
189            (297, 210) => Some(PdfPagePaperStandardSize::A4R),
190            (148, 210) => Some(PdfPagePaperStandardSize::A5),
191            (105, 148) => Some(PdfPagePaperStandardSize::A6),
192            (74, 105) => Some(PdfPagePaperStandardSize::A7),
193            (52, 74) => Some(PdfPagePaperStandardSize::A8),
194            (37, 52) => Some(PdfPagePaperStandardSize::A9),
195            (26, 37) => Some(PdfPagePaperStandardSize::A10),
196            (1000, 1414) => Some(PdfPagePaperStandardSize::B0),
197            (707, 1000) => Some(PdfPagePaperStandardSize::B1),
198            (500, 707) => Some(PdfPagePaperStandardSize::B2),
199            (353, 500) => Some(PdfPagePaperStandardSize::B3),
200            (250, 353) => Some(PdfPagePaperStandardSize::B4),
201            (176, 250) => Some(PdfPagePaperStandardSize::B5),
202            (125, 176) => Some(PdfPagePaperStandardSize::B6),
203            (88, 125) => Some(PdfPagePaperStandardSize::B7),
204            (62, 88) => Some(PdfPagePaperStandardSize::B8),
205            (44, 62) => Some(PdfPagePaperStandardSize::B9),
206            (31, 44) => Some(PdfPagePaperStandardSize::B10),
207            (917, 1297) => Some(PdfPagePaperStandardSize::C0),
208            (648, 917) => Some(PdfPagePaperStandardSize::C1),
209            (458, 648) => Some(PdfPagePaperStandardSize::C2),
210            (324, 458) => Some(PdfPagePaperStandardSize::C3),
211            (229, 324) => Some(PdfPagePaperStandardSize::C4),
212            (162, 229) => Some(PdfPagePaperStandardSize::C5),
213            (114, 162) => Some(PdfPagePaperStandardSize::C6),
214            (81, 114) => Some(PdfPagePaperStandardSize::C7),
215            (57, 81) => Some(PdfPagePaperStandardSize::C8),
216            (40, 57) => Some(PdfPagePaperStandardSize::C9),
217            (28, 40) => Some(PdfPagePaperStandardSize::C10),
218            (330, 483) => Some(PdfPagePaperStandardSize::AnsiBPlus),
219            (432, 559) => Some(PdfPagePaperStandardSize::AnsiC),
220            (559, 864) => Some(PdfPagePaperStandardSize::AnsiD),
221            (864, 1118) => Some(PdfPagePaperStandardSize::AnsiE),
222            (229, 305) => Some(PdfPagePaperStandardSize::ArchA),
223            (305, 457) => Some(PdfPagePaperStandardSize::ArchB),
224            (457, 610) => Some(PdfPagePaperStandardSize::ArchC),
225            (610, 914) => Some(PdfPagePaperStandardSize::ArchD),
226            (762, 1067) => Some(PdfPagePaperStandardSize::ArchE),
227            _ => None,
228        }
229    }
230
231    /// Returns the width of this [PdfPagePaperStandardSize] in portrait orientation.
232    pub fn width(&self) -> PdfPoints {
233        PdfPoints::from_mm(match self {
234            PdfPagePaperStandardSize::USLetterAnsiA => 216.0,
235            PdfPagePaperStandardSize::USHalfLetter => 140.0,
236            PdfPagePaperStandardSize::USGovernmentLetter => 203.0,
237            PdfPagePaperStandardSize::USLegal => 216.0,
238            PdfPagePaperStandardSize::USJuniorLegal => 127.0,
239            PdfPagePaperStandardSize::USGovernmentLegal => 216.0,
240            PdfPagePaperStandardSize::USLedgerTabloidAnsiB => 279.0,
241            PdfPagePaperStandardSize::A0x4 => 1682.0,
242            PdfPagePaperStandardSize::A0x2 => 1189.0,
243            PdfPagePaperStandardSize::A0 => 841.0,
244            PdfPagePaperStandardSize::A1 => 594.0,
245            PdfPagePaperStandardSize::A2 => 420.0,
246            PdfPagePaperStandardSize::A3 => 297.0,
247            PdfPagePaperStandardSize::A4 => 210.0,
248            PdfPagePaperStandardSize::A4R => 297.0,
249            PdfPagePaperStandardSize::A5 => 148.0,
250            PdfPagePaperStandardSize::A6 => 105.0,
251            PdfPagePaperStandardSize::A7 => 74.0,
252            PdfPagePaperStandardSize::A8 => 52.0,
253            PdfPagePaperStandardSize::A9 => 37.0,
254            PdfPagePaperStandardSize::A10 => 26.0,
255            PdfPagePaperStandardSize::B0 => 1000.0,
256            PdfPagePaperStandardSize::B1 => 707.0,
257            PdfPagePaperStandardSize::B2 => 500.0,
258            PdfPagePaperStandardSize::B3 => 353.0,
259            PdfPagePaperStandardSize::B4 => 250.0,
260            PdfPagePaperStandardSize::B5 => 176.0,
261            PdfPagePaperStandardSize::B6 => 125.0,
262            PdfPagePaperStandardSize::B7 => 88.0,
263            PdfPagePaperStandardSize::B8 => 62.0,
264            PdfPagePaperStandardSize::B9 => 44.0,
265            PdfPagePaperStandardSize::B10 => 31.0,
266            PdfPagePaperStandardSize::C0 => 917.0,
267            PdfPagePaperStandardSize::C1 => 648.0,
268            PdfPagePaperStandardSize::C2 => 458.0,
269            PdfPagePaperStandardSize::C3 => 324.0,
270            PdfPagePaperStandardSize::C4 => 229.0,
271            PdfPagePaperStandardSize::C5 => 162.0,
272            PdfPagePaperStandardSize::C6 => 114.0,
273            PdfPagePaperStandardSize::C7 => 81.0,
274            PdfPagePaperStandardSize::C8 => 57.0,
275            PdfPagePaperStandardSize::C9 => 40.0,
276            PdfPagePaperStandardSize::C10 => 28.0,
277            PdfPagePaperStandardSize::AnsiBPlus => 330.0,
278            PdfPagePaperStandardSize::AnsiC => 432.0,
279            PdfPagePaperStandardSize::AnsiD => 559.0,
280            PdfPagePaperStandardSize::AnsiE => 864.0,
281            PdfPagePaperStandardSize::ArchA => 229.0,
282            PdfPagePaperStandardSize::ArchB => 305.0,
283            PdfPagePaperStandardSize::ArchC => 457.0,
284            PdfPagePaperStandardSize::ArchD => 610.0,
285            PdfPagePaperStandardSize::ArchE => 762.0,
286        })
287    }
288
289    /// Returns the height of this [PdfPagePaperStandardSize] in portrait orientation.
290    pub fn height(&self) -> PdfPoints {
291        PdfPoints::from_mm(match self {
292            PdfPagePaperStandardSize::USLetterAnsiA => 279.0,
293            PdfPagePaperStandardSize::USHalfLetter => 216.0,
294            PdfPagePaperStandardSize::USGovernmentLetter => 254.0,
295            PdfPagePaperStandardSize::USLegal => 356.0,
296            PdfPagePaperStandardSize::USJuniorLegal => 203.0,
297            PdfPagePaperStandardSize::USGovernmentLegal => 330.0,
298            PdfPagePaperStandardSize::USLedgerTabloidAnsiB => 432.0,
299            PdfPagePaperStandardSize::A0x4 => 2378.0,
300            PdfPagePaperStandardSize::A0x2 => 1682.0,
301            PdfPagePaperStandardSize::A0 => 1189.0,
302            PdfPagePaperStandardSize::A1 => 841.0,
303            PdfPagePaperStandardSize::A2 => 594.0,
304            PdfPagePaperStandardSize::A3 => 420.0,
305            PdfPagePaperStandardSize::A4 => 297.0,
306            PdfPagePaperStandardSize::A4R => 210.0,
307            PdfPagePaperStandardSize::A5 => 210.0,
308            PdfPagePaperStandardSize::A6 => 148.0,
309            PdfPagePaperStandardSize::A7 => 105.0,
310            PdfPagePaperStandardSize::A8 => 74.0,
311            PdfPagePaperStandardSize::A9 => 52.0,
312            PdfPagePaperStandardSize::A10 => 37.0,
313            PdfPagePaperStandardSize::B0 => 1414.0,
314            PdfPagePaperStandardSize::B1 => 1000.0,
315            PdfPagePaperStandardSize::B2 => 707.0,
316            PdfPagePaperStandardSize::B3 => 500.0,
317            PdfPagePaperStandardSize::B4 => 353.0,
318            PdfPagePaperStandardSize::B5 => 250.0,
319            PdfPagePaperStandardSize::B6 => 176.0,
320            PdfPagePaperStandardSize::B7 => 125.0,
321            PdfPagePaperStandardSize::B8 => 88.0,
322            PdfPagePaperStandardSize::B9 => 62.0,
323            PdfPagePaperStandardSize::B10 => 44.0,
324            PdfPagePaperStandardSize::C0 => 1297.0,
325            PdfPagePaperStandardSize::C1 => 917.0,
326            PdfPagePaperStandardSize::C2 => 648.0,
327            PdfPagePaperStandardSize::C3 => 458.0,
328            PdfPagePaperStandardSize::C4 => 324.0,
329            PdfPagePaperStandardSize::C5 => 229.0,
330            PdfPagePaperStandardSize::C6 => 162.0,
331            PdfPagePaperStandardSize::C7 => 114.0,
332            PdfPagePaperStandardSize::C8 => 81.0,
333            PdfPagePaperStandardSize::C9 => 57.0,
334            PdfPagePaperStandardSize::C10 => 40.0,
335            PdfPagePaperStandardSize::AnsiBPlus => 483.0,
336            PdfPagePaperStandardSize::AnsiC => 559.0,
337            PdfPagePaperStandardSize::AnsiD => 864.0,
338            PdfPagePaperStandardSize::AnsiE => 1118.0,
339            PdfPagePaperStandardSize::ArchA => 305.0,
340            PdfPagePaperStandardSize::ArchB => 457.0,
341            PdfPagePaperStandardSize::ArchC => 610.0,
342            PdfPagePaperStandardSize::ArchD => 914.0,
343            PdfPagePaperStandardSize::ArchE => 1067.0,
344        })
345    }
346}
347
348/// The paper size of a [PdfPage].
349#[derive(Debug, Copy, Clone, PartialEq)]
350pub enum PdfPagePaperSize {
351    /// A known paper size in portrait orientation.
352    Portrait(PdfPagePaperStandardSize),
353
354    /// A known paper size in landscape orientation.
355    Landscape(PdfPagePaperStandardSize),
356
357    /// A custom paper size, expressed as a (width, height) tuple in [PdfPoints].
358    Custom(PdfPoints, PdfPoints),
359}
360
361impl PdfPagePaperSize {
362    /// Returns the [PdfPagePaperSize] matching the given dimensions,
363    /// or [PdfPagePaperSize::Custom] if no match can be made.
364    #[inline]
365    pub fn from_points(width: PdfPoints, height: PdfPoints) -> Self {
366        let width_mm = width.to_mm().trunc() as u32;
367
368        let height_mm = height.to_mm().trunc() as u32;
369
370        match PdfPagePaperStandardSize::from_mm_dimensions(width_mm, height_mm) {
371            Some(size) => PdfPagePaperSize::Portrait(size),
372            None => {
373                // Try swapping the width and height. This will detect a rotated paper size.
374
375                match PdfPagePaperStandardSize::from_mm_dimensions(height_mm, width_mm) {
376                    Some(size) => PdfPagePaperSize::Landscape(size),
377                    None => {
378                        // Still no match. Return the original result.
379
380                        PdfPagePaperSize::Custom(width, height)
381                    }
382                }
383            }
384        }
385    }
386
387    /// Returns the [PdfPagePaperSize] matching the given dimensions,
388    /// or [PdfPagePaperSize::Custom] if no match can be made.
389    #[inline]
390    pub fn from_inches(width: f32, height: f32) -> Self {
391        Self::from_points(
392            PdfPoints::from_inches(width),
393            PdfPoints::from_inches(height),
394        )
395    }
396
397    /// Returns the [PdfPagePaperSize] matching the given dimensions,
398    /// or [PdfPagePaperSize::Custom] if no match can be made.
399    #[inline]
400    pub fn from_cm(width: f32, height: f32) -> Self {
401        Self::from_points(PdfPoints::from_cm(width), PdfPoints::from_cm(height))
402    }
403
404    /// Returns the [PdfPagePaperSize] matching the given dimensions,
405    /// or [PdfPagePaperSize::Custom] if no match can be made.
406    #[inline]
407    pub fn from_mm(width: f32, height: f32) -> Self {
408        Self::from_points(PdfPoints::from_mm(width), PdfPoints::from_mm(height))
409    }
410
411    /// Creates a new portrait [PdfPagePaperSize] from a standard [PdfPagePaperStandardSize].
412    #[inline]
413    pub fn new_portrait(size: PdfPagePaperStandardSize) -> Self {
414        PdfPagePaperSize::Portrait(size)
415    }
416
417    /// Creates a new landscape [PdfPagePaperSize] from a standard [PdfPagePaperStandardSize].
418    #[inline]
419    pub fn new_landscape(size: PdfPagePaperStandardSize) -> Self {
420        PdfPagePaperSize::Landscape(size)
421    }
422
423    /// Creates a new custom [PdfPagePaperSize] from the given dimensions.
424    #[inline]
425    pub fn new_custom(width: PdfPoints, height: PdfPoints) -> Self {
426        PdfPagePaperSize::Custom(width, height)
427    }
428
429    /// Creates a new portrait A4 [PdfPagePaperSize].
430    #[inline]
431    pub fn a4() -> Self {
432        Self::new_portrait(PdfPagePaperStandardSize::A4)
433    }
434
435    /// Creates a new portrait A4R [PdfPagePaperSize], equivalent to landscape A4. In terms of
436    /// paper size, this is equivalent to calling [PdfPagePaperSize::a4().to_landscape()]
437    #[inline]
438    pub fn a4r() -> Self {
439        Self::new_portrait(PdfPagePaperStandardSize::A4R)
440    }
441
442    /// Creates a new portrait A3 [PdfPagePaperSize].
443    #[inline]
444    pub fn a3() -> Self {
445        Self::new_portrait(PdfPagePaperStandardSize::A3)
446    }
447
448    /// Rotates a landscape [PdfPagePaperSize] into a portrait [PdfPagePaperSize] and vice versa,
449    /// consuming this [PdfPagePaperSize].
450    ///
451    /// Custom sizes have their height and width dimensions swapped.
452    pub fn rotate(self) -> Self {
453        match self {
454            PdfPagePaperSize::Portrait(size) => PdfPagePaperSize::Landscape(size),
455            PdfPagePaperSize::Landscape(size) => PdfPagePaperSize::Portrait(size),
456            PdfPagePaperSize::Custom(width, height) => PdfPagePaperSize::Custom(height, width),
457        }
458    }
459
460    /// Rotates a portrait [PdfPagePaperSize] into a landscape [PdfPagePaperSize] if necessary.
461    /// A new [PdfPagePaperSize] value is returned; this [PdfPagePaperSize] is not affected.
462    /// Sizes already in landscape are not changed. Custom sizes are changed only if the
463    /// current height is greater than the width, in which case the dimensions are swapped.
464    pub fn landscape(&self) -> Self {
465        match self {
466            PdfPagePaperSize::Portrait(size) => PdfPagePaperSize::Landscape(*size),
467            PdfPagePaperSize::Landscape(_) => *self,
468            PdfPagePaperSize::Custom(width, height) => {
469                if height > width {
470                    PdfPagePaperSize::Custom(*height, *width)
471                } else {
472                    *self
473                }
474            }
475        }
476    }
477
478    /// Rotates a landscape [PdfPagePaperSize] into a portrait [PdfPagePaperSize] if necessary.
479    /// A new [PdfPagePaperSize] value is returned; this [PdfPagePaperSize] is not affected.
480    /// Sizes already in portrait are not changed. Custom sizes are changed only if the
481    /// current width is greater than the height, in which case the dimensions are swapped.
482    pub fn portrait(&self) -> Self {
483        match self {
484            PdfPagePaperSize::Portrait(_) => *self,
485            PdfPagePaperSize::Landscape(size) => PdfPagePaperSize::Portrait(*size),
486            PdfPagePaperSize::Custom(width, height) => {
487                if width > height {
488                    PdfPagePaperSize::Custom(*height, *width)
489                } else {
490                    *self
491                }
492            }
493        }
494    }
495
496    /// Returns the width of this [PdfPagePaperSize].
497    #[inline]
498    pub fn width(&self) -> PdfPoints {
499        match self {
500            PdfPagePaperSize::Portrait(size) => size.width(),
501            PdfPagePaperSize::Landscape(size) => size.height(),
502            PdfPagePaperSize::Custom(width, _) => *width,
503        }
504    }
505
506    /// Returns the height of this [PdfPagePaperSize].
507    #[inline]
508    pub fn height(&self) -> PdfPoints {
509        match self {
510            PdfPagePaperSize::Portrait(size) => size.height(),
511            PdfPagePaperSize::Landscape(size) => size.width(),
512            PdfPagePaperSize::Custom(_, height) => *height,
513        }
514    }
515
516    /// Returns the dimensions of this [PdfPagePaperSize] as a [PdfRect].
517    #[inline]
518    pub fn as_rect(&self) -> PdfRect {
519        PdfRect::new(
520            PdfPoints::ZERO,
521            PdfPoints::ZERO,
522            self.height(),
523            self.width(),
524        )
525    }
526}