Skip to main content

pdfkit/
types.rs

1use std::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign};
2
3use serde::{Deserialize, Serialize};
4
5/// Wraps `CGRect` values used by PDFKit geometry APIs.
6#[derive(Debug, Clone, Copy, PartialEq, Deserialize, Serialize)]
7pub struct PdfRect {
8    /// Wraps the rectangle x-origin used by PDFKit geometry APIs.
9    pub x: f64,
10    /// Wraps the rectangle y-origin used by PDFKit geometry APIs.
11    pub y: f64,
12    /// Wraps the rectangle width used by PDFKit geometry APIs.
13    pub width: f64,
14    /// Wraps the rectangle height used by PDFKit geometry APIs.
15    pub height: f64,
16}
17
18/// Wraps `CGPoint` values used by PDFKit geometry APIs.
19#[derive(Debug, Clone, Copy, PartialEq, Deserialize)]
20pub struct PdfPoint {
21    /// Wraps the point x-coordinate used by PDFKit geometry APIs.
22    pub x: f64,
23    /// Wraps the point y-coordinate used by PDFKit geometry APIs.
24    pub y: f64,
25}
26
27/// Wraps `CGSize` values used by PDFKit geometry APIs.
28#[derive(Debug, Clone, Copy, PartialEq, Deserialize)]
29pub struct PdfSize {
30    /// Wraps the width used by PDFKit geometry APIs.
31    pub width: f64,
32    /// Wraps the height used by PDFKit geometry APIs.
33    pub height: f64,
34}
35
36/// Wraps `NSEdgeInsets` values used by `PDFView`.
37#[derive(Debug, Clone, Copy, PartialEq, Deserialize)]
38pub struct PdfEdgeInsets {
39    /// Wraps the top inset used by `PDFView` layout APIs.
40    pub top: f64,
41    /// Wraps the left inset used by `PDFView` layout APIs.
42    pub left: f64,
43    /// Wraps the bottom inset used by `PDFView` layout APIs.
44    pub bottom: f64,
45    /// Wraps the right inset used by `PDFView` layout APIs.
46    pub right: f64,
47}
48
49/// Wraps RGBA color values used by PDFKit.
50#[derive(Debug, Clone, Copy, PartialEq, Deserialize)]
51pub struct PdfColor {
52    /// Wraps the red component used by PDFKit color APIs.
53    pub red: f64,
54    /// Wraps the green component used by PDFKit color APIs.
55    pub green: f64,
56    /// Wraps the blue component used by PDFKit color APIs.
57    pub blue: f64,
58    /// Wraps the alpha component used by PDFKit color APIs.
59    pub alpha: f64,
60}
61
62/// Wraps text-range values returned by `PDFSelection`.
63#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize)]
64pub struct PdfTextRange {
65    /// Wraps the starting character index returned by `PDFSelection`.
66    pub location: usize,
67    /// Wraps the character count returned by `PDFSelection`.
68    pub length: usize,
69}
70
71/// Wraps `PDFDisplayBox` values.
72#[derive(Debug, Clone, Copy, PartialEq, Eq)]
73#[repr(i32)]
74pub enum DisplayBox {
75    /// Wraps the corresponding `PDFDisplayBox` value.
76    MediaBox = 0,
77    /// Wraps the corresponding `PDFDisplayBox` value.
78    CropBox = 1,
79    /// Wraps the corresponding `PDFDisplayBox` value.
80    BleedBox = 2,
81    /// Wraps the corresponding `PDFDisplayBox` value.
82    TrimBox = 3,
83    /// Wraps the corresponding `PDFDisplayBox` value.
84    ArtBox = 4,
85}
86
87impl DisplayBox {
88    /// Returns the raw `PDFDisplayBox` value used by PDFKit.
89    #[must_use]
90    pub const fn as_raw(self) -> i32 {
91        self as i32
92    }
93}
94
95/// Wraps `PDFBorderStyle` values.
96#[derive(Debug, Clone, Copy, PartialEq, Eq)]
97#[repr(i32)]
98pub enum PdfBorderStyle {
99    /// Wraps the corresponding `PDFBorderStyle` value.
100    Solid = 0,
101    /// Wraps the corresponding `PDFBorderStyle` value.
102    Dashed = 1,
103    /// Wraps the corresponding `PDFBorderStyle` value.
104    Beveled = 2,
105    /// Wraps the corresponding `PDFBorderStyle` value.
106    Inset = 3,
107    /// Wraps the corresponding `PDFBorderStyle` value.
108    Underline = 4,
109}
110
111impl PdfBorderStyle {
112    /// Converts a raw `PDFBorderStyle` value into this Rust enum.
113    #[must_use]
114    pub const fn from_raw(raw: i32) -> Option<Self> {
115        match raw {
116            0 => Some(Self::Solid),
117            1 => Some(Self::Dashed),
118            2 => Some(Self::Beveled),
119            3 => Some(Self::Inset),
120            4 => Some(Self::Underline),
121            _ => None,
122        }
123    }
124}
125
126/// Wraps `PDFActionNamedName` values.
127#[derive(Debug, Clone, Copy, PartialEq, Eq)]
128#[repr(i32)]
129pub enum PdfActionNamedName {
130    /// Wraps the corresponding `PDFActionNamedName` value.
131    None = 0,
132    /// Wraps the corresponding `PDFActionNamedName` value.
133    NextPage = 1,
134    /// Wraps the corresponding `PDFActionNamedName` value.
135    PreviousPage = 2,
136    /// Wraps the corresponding `PDFActionNamedName` value.
137    FirstPage = 3,
138    /// Wraps the corresponding `PDFActionNamedName` value.
139    LastPage = 4,
140    /// Wraps the corresponding `PDFActionNamedName` value.
141    GoBack = 5,
142    /// Wraps the corresponding `PDFActionNamedName` value.
143    GoForward = 6,
144    /// Wraps the corresponding `PDFActionNamedName` value.
145    GoToPage = 7,
146    /// Wraps the corresponding `PDFActionNamedName` value.
147    Find = 8,
148    /// Wraps the corresponding `PDFActionNamedName` value.
149    Print = 9,
150    /// Wraps the corresponding `PDFActionNamedName` value.
151    ZoomIn = 10,
152    /// Wraps the corresponding `PDFActionNamedName` value.
153    ZoomOut = 11,
154}
155
156impl PdfActionNamedName {
157    /// Returns the raw `PDFActionNamedName` value used by PDFKit.
158    #[must_use]
159    pub const fn as_raw(self) -> i32 {
160        self as i32
161    }
162
163    /// Converts a raw `PDFActionNamedName` value into this Rust enum.
164    #[must_use]
165    pub const fn from_raw(raw: i32) -> Option<Self> {
166        match raw {
167            0 => Some(Self::None),
168            1 => Some(Self::NextPage),
169            2 => Some(Self::PreviousPage),
170            3 => Some(Self::FirstPage),
171            4 => Some(Self::LastPage),
172            5 => Some(Self::GoBack),
173            6 => Some(Self::GoForward),
174            7 => Some(Self::GoToPage),
175            8 => Some(Self::Find),
176            9 => Some(Self::Print),
177            10 => Some(Self::ZoomIn),
178            11 => Some(Self::ZoomOut),
179            _ => None,
180        }
181    }
182}
183
184/// Wraps `PDFLineStyle` values.
185#[derive(Debug, Clone, Copy, PartialEq, Eq)]
186#[repr(i32)]
187pub enum PdfLineStyle {
188    /// Wraps the corresponding `PDFLineStyle` value.
189    None = 0,
190    /// Wraps the corresponding `PDFLineStyle` value.
191    Square = 1,
192    /// Wraps the corresponding `PDFLineStyle` value.
193    Circle = 2,
194    /// Wraps the corresponding `PDFLineStyle` value.
195    Diamond = 3,
196    /// Wraps the corresponding `PDFLineStyle` value.
197    OpenArrow = 4,
198    /// Wraps the corresponding `PDFLineStyle` value.
199    ClosedArrow = 5,
200}
201
202impl PdfLineStyle {
203    /// Converts a raw `PDFLineStyle` value into this Rust enum.
204    #[must_use]
205    pub const fn from_raw(raw: i32) -> Option<Self> {
206        match raw {
207            0 => Some(Self::None),
208            1 => Some(Self::Square),
209            2 => Some(Self::Circle),
210            3 => Some(Self::Diamond),
211            4 => Some(Self::OpenArrow),
212            5 => Some(Self::ClosedArrow),
213            _ => None,
214        }
215    }
216}
217
218/// Wraps `PDFTextAnnotationIconType` values.
219#[derive(Debug, Clone, Copy, PartialEq, Eq)]
220#[repr(i32)]
221pub enum PdfTextAnnotationIconType {
222    /// Wraps the corresponding `PDFTextAnnotationIconType` value.
223    Comment = 0,
224    /// Wraps the corresponding `PDFTextAnnotationIconType` value.
225    Key = 1,
226    /// Wraps the corresponding `PDFTextAnnotationIconType` value.
227    Note = 2,
228    /// Wraps the corresponding `PDFTextAnnotationIconType` value.
229    Help = 3,
230    /// Wraps the corresponding `PDFTextAnnotationIconType` value.
231    NewParagraph = 4,
232    /// Wraps the corresponding `PDFTextAnnotationIconType` value.
233    Paragraph = 5,
234    /// Wraps the corresponding `PDFTextAnnotationIconType` value.
235    Insert = 6,
236}
237
238impl PdfTextAnnotationIconType {
239    /// Returns the raw `PDFTextAnnotationIconType` value used by PDFKit.
240    #[must_use]
241    pub const fn as_raw(self) -> i32 {
242        self as i32
243    }
244
245    /// Converts a raw `PDFTextAnnotationIconType` value into this Rust enum.
246    #[must_use]
247    pub const fn from_raw(raw: i32) -> Option<Self> {
248        match raw {
249            0 => Some(Self::Comment),
250            1 => Some(Self::Key),
251            2 => Some(Self::Note),
252            3 => Some(Self::Help),
253            4 => Some(Self::NewParagraph),
254            5 => Some(Self::Paragraph),
255            6 => Some(Self::Insert),
256            _ => None,
257        }
258    }
259}
260
261/// Wraps `PDFMarkupType` values.
262#[derive(Debug, Clone, Copy, PartialEq, Eq)]
263#[repr(i32)]
264pub enum PdfMarkupType {
265    /// Wraps the corresponding `PDFMarkupType` value.
266    Highlight = 0,
267    /// Wraps the corresponding `PDFMarkupType` value.
268    StrikeOut = 1,
269    /// Wraps the corresponding `PDFMarkupType` value.
270    Underline = 2,
271    /// Wraps the corresponding `PDFMarkupType` value.
272    Redact = 3,
273}
274
275impl PdfMarkupType {
276    /// Converts a raw `PDFMarkupType` value into this Rust enum.
277    #[must_use]
278    pub const fn from_raw(raw: i32) -> Option<Self> {
279        match raw {
280            0 => Some(Self::Highlight),
281            1 => Some(Self::StrikeOut),
282            2 => Some(Self::Underline),
283            3 => Some(Self::Redact),
284            _ => None,
285        }
286    }
287}
288
289/// Wraps `PDFDisplayMode` values.
290#[derive(Debug, Clone, Copy, PartialEq, Eq)]
291#[repr(i32)]
292pub enum PdfDisplayMode {
293    /// Wraps the corresponding `PDFDisplayMode` value.
294    SinglePage = 0,
295    /// Wraps the corresponding `PDFDisplayMode` value.
296    SinglePageContinuous = 1,
297    /// Wraps the corresponding `PDFDisplayMode` value.
298    TwoUp = 2,
299    /// Wraps the corresponding `PDFDisplayMode` value.
300    TwoUpContinuous = 3,
301}
302
303impl PdfDisplayMode {
304    /// Converts a raw `PDFDisplayMode` value into this Rust enum.
305    #[must_use]
306    pub const fn from_raw(raw: i32) -> Option<Self> {
307        match raw {
308            0 => Some(Self::SinglePage),
309            1 => Some(Self::SinglePageContinuous),
310            2 => Some(Self::TwoUp),
311            3 => Some(Self::TwoUpContinuous),
312            _ => None,
313        }
314    }
315}
316
317/// Wraps `PDFDisplayDirection` values.
318#[derive(Debug, Clone, Copy, PartialEq, Eq)]
319#[repr(i32)]
320pub enum PdfDisplayDirection {
321    /// Wraps the corresponding `PDFDisplayDirection` value.
322    Vertical = 0,
323    /// Wraps the corresponding `PDFDisplayDirection` value.
324    Horizontal = 1,
325}
326
327impl PdfDisplayDirection {
328    /// Converts a raw `PDFDisplayDirection` value into this Rust enum.
329    #[must_use]
330    pub const fn from_raw(raw: i32) -> Option<Self> {
331        match raw {
332            0 => Some(Self::Vertical),
333            1 => Some(Self::Horizontal),
334            _ => None,
335        }
336    }
337}
338
339/// Wraps `PDFInterpolationQuality` values.
340#[derive(Debug, Clone, Copy, PartialEq, Eq)]
341#[repr(i32)]
342pub enum PdfInterpolationQuality {
343    /// Wraps the corresponding `PDFInterpolationQuality` value.
344    None = 0,
345    /// Wraps the corresponding `PDFInterpolationQuality` value.
346    Low = 1,
347    /// Wraps the corresponding `PDFInterpolationQuality` value.
348    High = 2,
349}
350
351impl PdfInterpolationQuality {
352    /// Converts a raw `PDFInterpolationQuality` value into this Rust enum.
353    #[must_use]
354    pub const fn from_raw(raw: i32) -> Option<Self> {
355        match raw {
356            0 => Some(Self::None),
357            1 => Some(Self::Low),
358            2 => Some(Self::High),
359            _ => None,
360        }
361    }
362}
363
364/// Wraps `PDFView area-of-interest`.
365#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
366pub struct PdfAreaOfInterest(u64);
367
368impl PdfAreaOfInterest {
369    /// Wraps the corresponding `PDFView` area-of-interest flag.
370    pub const NONE: Self = Self(0);
371    /// Wraps the corresponding `PDFView` area-of-interest flag.
372    pub const PAGE: Self = Self(1 << 0);
373    /// Wraps the corresponding `PDFView` area-of-interest flag.
374    pub const TEXT: Self = Self(1 << 1);
375    /// Wraps the corresponding `PDFView` area-of-interest flag.
376    pub const ANNOTATION: Self = Self(1 << 2);
377    /// Wraps the corresponding `PDFView` area-of-interest flag.
378    pub const LINK: Self = Self(1 << 3);
379    /// Wraps the corresponding `PDFView` area-of-interest flag.
380    pub const CONTROL: Self = Self(1 << 4);
381    /// Wraps the corresponding `PDFView` area-of-interest flag.
382    pub const TEXT_FIELD: Self = Self(1 << 5);
383    /// Wraps the corresponding `PDFView` area-of-interest flag.
384    pub const ICON: Self = Self(1 << 6);
385    /// Wraps the corresponding `PDFView` area-of-interest flag.
386    pub const POPUP: Self = Self(1 << 7);
387    /// Wraps the corresponding `PDFView` area-of-interest flag.
388    pub const IMAGE: Self = Self(1 << 8);
389    /// Wraps the corresponding `PDFView` area-of-interest flag.
390    pub const ANY: Self = Self(i64::MAX as u64);
391
392    /// Creates a flag set from raw PDFKit bits.
393    #[must_use]
394    pub const fn from_bits(bits: u64) -> Self {
395        Self(bits)
396    }
397
398    /// Returns the raw PDFKit bit pattern.
399    #[must_use]
400    pub const fn bits(self) -> u64 {
401        self.0
402    }
403
404    /// Reports whether no PDFKit flags are set.
405    #[must_use]
406    pub const fn is_empty(self) -> bool {
407        self.0 == 0
408    }
409
410    /// Checks PDFKit flag membership against another value.
411    #[must_use]
412    pub const fn contains(self, other: Self) -> bool {
413        (self.0 & other.0) == other.0
414    }
415
416    /// Checks PDFKit flag membership against another value.
417    #[must_use]
418    pub const fn intersects(self, other: Self) -> bool {
419        (self.0 & other.0) != 0
420    }
421}
422
423impl BitOr for PdfAreaOfInterest {
424    type Output = Self;
425
426    fn bitor(self, rhs: Self) -> Self::Output {
427        Self(self.0 | rhs.0)
428    }
429}
430
431impl BitOrAssign for PdfAreaOfInterest {
432    fn bitor_assign(&mut self, rhs: Self) {
433        self.0 |= rhs.0;
434    }
435}
436
437impl BitAnd for PdfAreaOfInterest {
438    type Output = Self;
439
440    fn bitand(self, rhs: Self) -> Self::Output {
441        Self(self.0 & rhs.0)
442    }
443}
444
445impl BitAndAssign for PdfAreaOfInterest {
446    fn bitand_assign(&mut self, rhs: Self) {
447        self.0 &= rhs.0;
448    }
449}
450
451/// Wraps `PDFWidgetControlType` values.
452#[derive(Debug, Clone, Copy, PartialEq, Eq)]
453#[repr(i32)]
454pub enum PdfWidgetControlType {
455    /// Wraps the corresponding `PDFWidgetControlType` value.
456    Unknown = -1,
457    /// Wraps the corresponding `PDFWidgetControlType` value.
458    PushButton = 0,
459    /// Wraps the corresponding `PDFWidgetControlType` value.
460    RadioButton = 1,
461    /// Wraps the corresponding `PDFWidgetControlType` value.
462    CheckBox = 2,
463}
464
465impl PdfWidgetControlType {
466    /// Converts a raw `PDFWidgetControlType` value into this Rust enum.
467    #[must_use]
468    pub const fn from_raw(raw: i32) -> Option<Self> {
469        match raw {
470            -1 => Some(Self::Unknown),
471            0 => Some(Self::PushButton),
472            1 => Some(Self::RadioButton),
473            2 => Some(Self::CheckBox),
474            _ => None,
475        }
476    }
477}
478
479/// Wraps `PDFWidgetCellState` values.
480#[derive(Debug, Clone, Copy, PartialEq, Eq)]
481#[repr(i32)]
482pub enum PdfWidgetCellState {
483    /// Wraps the corresponding `PDFWidgetCellState` value.
484    Mixed = -1,
485    /// Wraps the corresponding `PDFWidgetCellState` value.
486    Off = 0,
487    /// Wraps the corresponding `PDFWidgetCellState` value.
488    On = 1,
489}
490
491impl PdfWidgetCellState {
492    /// Returns the raw `PDFWidgetCellState` value used by PDFKit.
493    #[must_use]
494    pub const fn as_raw(self) -> i32 {
495        self as i32
496    }
497
498    /// Converts a raw `PDFWidgetCellState` value into this Rust enum.
499    #[must_use]
500    pub const fn from_raw(raw: i32) -> Option<Self> {
501        match raw {
502            -1 => Some(Self::Mixed),
503            0 => Some(Self::Off),
504            1 => Some(Self::On),
505            _ => None,
506        }
507    }
508}
509
510/// Wraps `PDFPrintScalingMode` values.
511#[derive(Debug, Clone, Copy, PartialEq, Eq)]
512#[repr(i32)]
513pub enum PdfPrintScalingMode {
514    /// Wraps the corresponding `PDFPrintScalingMode` value.
515    None = 0,
516    /// Wraps the corresponding `PDFPrintScalingMode` value.
517    ToFit = 1,
518    /// Wraps the corresponding `PDFPrintScalingMode` value.
519    DownToFit = 2,
520}
521
522impl PdfPrintScalingMode {
523    /// Returns the raw `PDFPrintScalingMode` value used by PDFKit.
524    #[must_use]
525    pub const fn as_raw(self) -> i32 {
526        self as i32
527    }
528
529    /// Converts a raw `PDFPrintScalingMode` value into this Rust enum.
530    #[must_use]
531    pub const fn from_raw(raw: i32) -> Option<Self> {
532        match raw {
533            0 => Some(Self::None),
534            1 => Some(Self::ToFit),
535            2 => Some(Self::DownToFit),
536            _ => None,
537        }
538    }
539}
540
541/// Wraps `PDFDocumentPermissions` values.
542#[derive(Debug, Clone, Copy, PartialEq, Eq)]
543#[repr(i32)]
544pub enum PdfDocumentPermissions {
545    /// Wraps the corresponding `PDFDocumentPermissions` value.
546    None = 0,
547    /// Wraps the corresponding `PDFDocumentPermissions` value.
548    User = 1,
549    /// Wraps the corresponding `PDFDocumentPermissions` value.
550    Owner = 2,
551}
552
553impl PdfDocumentPermissions {
554    /// Converts a raw `PDFDocumentPermissions` value into this Rust enum.
555    #[must_use]
556    pub const fn from_raw(raw: i32) -> Option<Self> {
557        match raw {
558            0 => Some(Self::None),
559            1 => Some(Self::User),
560            2 => Some(Self::Owner),
561            _ => None,
562        }
563    }
564}
565
566/// Wraps `PDFSelectionGranularity` values.
567#[derive(Debug, Clone, Copy, PartialEq, Eq)]
568#[repr(u64)]
569pub enum PdfSelectionGranularity {
570    /// Wraps the corresponding `PDFSelectionGranularity` value.
571    Character = 0,
572    /// Wraps the corresponding `PDFSelectionGranularity` value.
573    Word = 1,
574    /// Wraps the corresponding `PDFSelectionGranularity` value.
575    Line = 2,
576}
577
578impl PdfSelectionGranularity {
579    /// Returns the raw `PDFSelectionGranularity` value used by PDFKit.
580    #[must_use]
581    pub const fn as_raw(self) -> u64 {
582        self as u64
583    }
584
585    /// Converts a raw `PDFSelectionGranularity` value into this Rust enum.
586    #[must_use]
587    pub const fn from_raw(raw: u64) -> Option<Self> {
588        match raw {
589            0 => Some(Self::Character),
590            1 => Some(Self::Word),
591            2 => Some(Self::Line),
592            _ => None,
593        }
594    }
595}
596
597/// Snapshot of `PDFDocument` state.
598#[derive(Debug, Clone, Deserialize)]
599pub struct PdfDocumentInfo {
600    /// Mirrors the corresponding `PDFDocument` field.
601    pub document_url: Option<String>,
602    /// Mirrors the corresponding `PDFDocument` field.
603    pub major_version: i32,
604    /// Mirrors the corresponding `PDFDocument` field.
605    pub minor_version: i32,
606    /// Mirrors the corresponding `PDFDocument` field.
607    pub is_encrypted: bool,
608    /// Mirrors the corresponding `PDFDocument` field.
609    pub is_locked: bool,
610    /// Mirrors the corresponding `PDFDocument` field.
611    pub permissions_status: i32,
612    /// Mirrors the corresponding `PDFDocument` field.
613    pub access_permissions: u64,
614    /// Mirrors the corresponding `PDFDocument` field.
615    pub allows_printing: bool,
616    /// Mirrors the corresponding `PDFDocument` field.
617    pub allows_copying: bool,
618    /// Mirrors the corresponding `PDFDocument` field.
619    pub allows_document_changes: bool,
620    /// Mirrors the corresponding `PDFDocument` field.
621    pub allows_document_assembly: bool,
622    /// Mirrors the corresponding `PDFDocument` field.
623    pub allows_content_accessibility: bool,
624    /// Mirrors the corresponding `PDFDocument` field.
625    pub allows_commenting: bool,
626    /// Mirrors the corresponding `PDFDocument` field.
627    pub allows_form_field_entry: bool,
628    /// Mirrors the corresponding `PDFDocument` field.
629    pub page_class: String,
630}
631
632impl PdfDocumentInfo {
633    /// Converts the stored raw PDFKit value into a typed enum.
634    #[must_use]
635    pub fn permissions_status_enum(&self) -> Option<PdfDocumentPermissions> {
636        PdfDocumentPermissions::from_raw(self.permissions_status)
637    }
638}
639
640/// Wraps `PDFDocumentAttributes`.
641#[derive(Debug, Clone, Deserialize)]
642pub struct PdfDocumentAttributes {
643    /// Mirrors the corresponding `PDFDocument` field.
644    pub title: Option<String>,
645    /// Mirrors the corresponding `PDFDocument` field.
646    pub author: Option<String>,
647    /// Mirrors the corresponding `PDFDocument` field.
648    pub subject: Option<String>,
649    /// Mirrors the corresponding `PDFDocument` field.
650    pub creator: Option<String>,
651    /// Mirrors the corresponding `PDFDocument` field.
652    pub producer: Option<String>,
653    /// Mirrors the corresponding `PDFDocument` field.
654    pub creation_date: Option<String>,
655    /// Mirrors the corresponding `PDFDocument` field.
656    pub modification_date: Option<String>,
657    /// Mirrors the corresponding `PDFDocument` field.
658    pub keywords: Option<Vec<String>>,
659}
660
661/// Builder-style options for the corresponding `PDFPageImageInitialization` API.
662#[derive(Debug, Clone, Default, PartialEq, Serialize)]
663pub struct PdfPageImageInitializationOptions {
664    /// Mirrors the corresponding `PDFPage` field.
665    pub media_box: Option<PdfRect>,
666    /// Mirrors the corresponding `PDFPage` field.
667    pub rotation: Option<i32>,
668    /// Mirrors the corresponding `PDFPage` field.
669    pub upscale_if_smaller: bool,
670    /// Mirrors the corresponding `PDFPage` field.
671    pub compression_quality: Option<f64>,
672}
673
674impl PdfPageImageInitializationOptions {
675    /// Sets the corresponding `PDFPageImageInitialization` option and returns the builder.
676    pub fn with_media_box(mut self, value: PdfRect) -> Self {
677        self.media_box = Some(value);
678        self
679    }
680
681    /// Sets the corresponding `PDFPageImageInitialization` option and returns the builder.
682    pub fn with_rotation(mut self, value: i32) -> Self {
683        self.rotation = Some(value);
684        self
685    }
686
687    /// Sets the corresponding `PDFPageImageInitialization` option and returns the builder.
688    pub fn with_upscale_if_smaller(mut self, value: bool) -> Self {
689        self.upscale_if_smaller = value;
690        self
691    }
692
693    /// Sets the corresponding `PDFPageImageInitialization` option and returns the builder.
694    pub fn with_compression_quality(mut self, value: f64) -> Self {
695        self.compression_quality = Some(value);
696        self
697    }
698}
699
700/// Builder-style options for the corresponding `PDFDocumentWrite` API.
701#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize)]
702pub struct PdfDocumentWriteOptions {
703    /// Mirrors the corresponding `PDFDocument` field.
704    pub owner_password: Option<String>,
705    /// Mirrors the corresponding `PDFDocument` field.
706    pub user_password: Option<String>,
707    /// Mirrors the corresponding `PDFDocument` field.
708    pub access_permissions: Option<u64>,
709    /// Mirrors the corresponding `PDFDocument` field.
710    pub burn_in_annotations: bool,
711    /// Mirrors the corresponding `PDFDocument` field.
712    pub save_text_from_ocr: bool,
713    /// Mirrors the corresponding `PDFDocument` field.
714    pub save_images_as_jpeg: bool,
715    /// Mirrors the corresponding `PDFDocument` field.
716    pub optimize_images_for_screen: bool,
717}
718
719impl PdfDocumentWriteOptions {
720    /// Sets the corresponding `PDFDocumentWrite` option and returns the builder.
721    pub fn with_owner_password(mut self, value: impl Into<String>) -> Self {
722        self.owner_password = Some(value.into());
723        self
724    }
725
726    /// Sets the corresponding `PDFDocumentWrite` option and returns the builder.
727    pub fn with_user_password(mut self, value: impl Into<String>) -> Self {
728        self.user_password = Some(value.into());
729        self
730    }
731
732    /// Sets the corresponding `PDFDocumentWrite` option and returns the builder.
733    pub fn with_access_permissions(mut self, value: u64) -> Self {
734        self.access_permissions = Some(value);
735        self
736    }
737
738    /// Sets the corresponding `PDFDocumentWrite` option and returns the builder.
739    pub fn with_burn_in_annotations(mut self, value: bool) -> Self {
740        self.burn_in_annotations = value;
741        self
742    }
743
744    /// Sets the corresponding `PDFDocumentWrite` option and returns the builder.
745    pub fn with_save_text_from_ocr(mut self, value: bool) -> Self {
746        self.save_text_from_ocr = value;
747        self
748    }
749
750    /// Sets the corresponding `PDFDocumentWrite` option and returns the builder.
751    pub fn with_save_images_as_jpeg(mut self, value: bool) -> Self {
752        self.save_images_as_jpeg = value;
753        self
754    }
755
756    /// Sets the corresponding `PDFDocumentWrite` option and returns the builder.
757    pub fn with_optimize_images_for_screen(mut self, value: bool) -> Self {
758        self.optimize_images_for_screen = value;
759        self
760    }
761}
762
763/// Snapshot of `PDFBorder` state.
764#[derive(Debug, Clone, Deserialize)]
765pub struct PdfBorderInfo {
766    /// Mirrors the corresponding `PDFBorder` field.
767    pub style: i32,
768    /// Mirrors the corresponding `PDFBorder` field.
769    pub line_width: f64,
770    /// Mirrors the corresponding `PDFBorder` field.
771    pub dash_pattern: Option<Vec<f64>>,
772}
773
774impl PdfBorderInfo {
775    /// Converts the stored raw PDFKit value into a typed enum.
776    #[must_use]
777    pub fn style_enum(&self) -> Option<PdfBorderStyle> {
778        PdfBorderStyle::from_raw(self.style)
779    }
780}
781
782/// Snapshot of `PDFAnnotation` state.
783#[derive(Debug, Clone, Deserialize)]
784pub struct PdfAnnotationInfo {
785    /// Mirrors the corresponding `PDFAnnotation` field.
786    pub annotation_type: Option<String>,
787    /// Mirrors the corresponding `PDFAnnotation` field.
788    pub bounds: PdfRect,
789    /// Mirrors the corresponding `PDFAnnotation` field.
790    pub contents: Option<String>,
791    /// Mirrors the corresponding `PDFAnnotation` field.
792    pub should_display: bool,
793    /// Mirrors the corresponding `PDFAnnotation` field.
794    pub should_print: bool,
795    /// Mirrors the corresponding `PDFAnnotation` field.
796    pub has_appearance_stream: bool,
797    /// Mirrors the corresponding `PDFAnnotation` field.
798    pub user_name: Option<String>,
799    /// Mirrors the corresponding `PDFAnnotation` field.
800    pub modification_date: Option<String>,
801    /// Mirrors the corresponding `PDFAnnotation` field.
802    pub color: Option<PdfColor>,
803    /// Mirrors the corresponding `PDFAnnotation` field.
804    pub highlighted: bool,
805    /// Mirrors the corresponding `PDFAnnotation` field.
806    pub action_type: Option<String>,
807    /// Mirrors the corresponding `PDFAnnotation` field.
808    pub border: Option<PdfBorderInfo>,
809}
810
811/// Snapshot of `PDFDestination` state.
812#[derive(Debug, Clone, Deserialize)]
813pub struct PdfDestinationInfo {
814    /// Mirrors the corresponding `PDFDestination` field.
815    pub page_label: Option<String>,
816    /// Mirrors the corresponding `PDFDestination` field.
817    pub page_index: Option<usize>,
818    /// Mirrors the corresponding `PDFDestination` field.
819    pub point: PdfPoint,
820    /// Mirrors the corresponding `PDFDestination` field.
821    pub zoom: f64,
822}
823
824/// Snapshot of `PDFAppearanceCharacteristics` state.
825#[derive(Debug, Clone, Deserialize)]
826pub struct PdfAppearanceCharacteristicsInfo {
827    /// Mirrors the corresponding `PDFAppearanceCharacteristics` field.
828    pub control_type: i32,
829    /// Mirrors the corresponding `PDFAppearanceCharacteristics` field.
830    pub background_color: Option<PdfColor>,
831    /// Mirrors the corresponding `PDFAppearanceCharacteristics` field.
832    pub border_color: Option<PdfColor>,
833    /// Mirrors the corresponding `PDFAppearanceCharacteristics` field.
834    pub rotation: i32,
835    /// Mirrors the corresponding `PDFAppearanceCharacteristics` field.
836    pub caption: Option<String>,
837    /// Mirrors the corresponding `PDFAppearanceCharacteristics` field.
838    pub rollover_caption: Option<String>,
839    /// Mirrors the corresponding `PDFAppearanceCharacteristics` field.
840    pub down_caption: Option<String>,
841}
842
843impl PdfAppearanceCharacteristicsInfo {
844    /// Converts the stored raw PDFKit value into a typed enum.
845    #[must_use]
846    pub fn control_type_enum(&self) -> Option<PdfWidgetControlType> {
847        PdfWidgetControlType::from_raw(self.control_type)
848    }
849}
850
851/// Snapshot of `PDFView` state.
852#[derive(Debug, Clone, Deserialize)]
853pub struct PdfViewInfo {
854    /// Mirrors the corresponding `PDFView` field.
855    pub display_mode: i32,
856    /// Mirrors the corresponding `PDFView` field.
857    pub display_direction: i32,
858    /// Mirrors the corresponding `PDFView` field.
859    pub displays_page_breaks: bool,
860    /// Mirrors the corresponding `PDFView` field.
861    pub page_break_margins: PdfEdgeInsets,
862    /// Mirrors the corresponding `PDFView` field.
863    pub display_box: i32,
864    /// Mirrors the corresponding `PDFView` field.
865    pub displays_as_book: bool,
866    /// Mirrors the corresponding `PDFView` field.
867    pub displays_rtl: bool,
868    /// Mirrors the corresponding `PDFView` field.
869    pub background_color: Option<PdfColor>,
870    /// Mirrors the corresponding `PDFView` field.
871    pub interpolation_quality: i32,
872    /// Mirrors the corresponding `PDFView` field.
873    pub page_shadows_enabled: bool,
874    /// Mirrors the corresponding `PDFView` field.
875    pub scale_factor: f64,
876    /// Mirrors the corresponding `PDFView` field.
877    pub min_scale_factor: f64,
878    /// Mirrors the corresponding `PDFView` field.
879    pub max_scale_factor: f64,
880    /// Mirrors the corresponding `PDFView` field.
881    pub auto_scales: bool,
882    /// Mirrors the corresponding `PDFView` field.
883    pub scale_factor_for_size_to_fit: f64,
884    /// Mirrors the corresponding `PDFView` field.
885    pub in_markup_mode: bool,
886    /// Mirrors the corresponding `PDFView` field.
887    pub has_document_view: bool,
888    /// Mirrors the corresponding `PDFView` field.
889    pub visible_page_count: usize,
890    /// Mirrors the corresponding `PDFView` field.
891    pub current_page_label: Option<String>,
892}
893
894impl PdfViewInfo {
895    /// Converts the stored raw PDFKit value into a typed enum.
896    #[must_use]
897    pub fn display_mode_enum(&self) -> Option<PdfDisplayMode> {
898        PdfDisplayMode::from_raw(self.display_mode)
899    }
900
901    /// Converts the stored raw PDFKit value into a typed enum.
902    #[must_use]
903    pub fn display_direction_enum(&self) -> Option<PdfDisplayDirection> {
904        PdfDisplayDirection::from_raw(self.display_direction)
905    }
906
907    /// Converts the stored raw PDFKit value into a typed enum.
908    #[must_use]
909    pub fn interpolation_quality_enum(&self) -> Option<PdfInterpolationQuality> {
910        PdfInterpolationQuality::from_raw(self.interpolation_quality)
911    }
912
913    /// Converts the stored raw PDFKit value into a typed enum.
914    #[must_use]
915    pub fn display_box_enum(&self) -> Option<DisplayBox> {
916        match self.display_box {
917            0 => Some(DisplayBox::MediaBox),
918            1 => Some(DisplayBox::CropBox),
919            2 => Some(DisplayBox::BleedBox),
920            3 => Some(DisplayBox::TrimBox),
921            4 => Some(DisplayBox::ArtBox),
922            _ => None,
923        }
924    }
925}
926
927/// Wraps `PDFThumbnailLayoutMode` values.
928#[derive(Debug, Clone, Copy, PartialEq, Eq)]
929#[repr(i32)]
930pub enum PdfThumbnailLayoutMode {
931    /// Wraps the corresponding `PDFThumbnailLayoutMode` value.
932    Vertical = 0,
933    /// Wraps the corresponding `PDFThumbnailLayoutMode` value.
934    Horizontal = 1,
935}
936
937impl PdfThumbnailLayoutMode {
938    /// Returns the raw `PDFThumbnailLayoutMode` value used by PDFKit.
939    #[must_use]
940    pub const fn as_raw(self) -> i32 {
941        self as i32
942    }
943
944    /// Converts a raw `PDFThumbnailLayoutMode` value into this Rust enum.
945    #[must_use]
946    pub const fn from_raw(raw: i32) -> Option<Self> {
947        match raw {
948            0 => Some(Self::Vertical),
949            1 => Some(Self::Horizontal),
950            _ => None,
951        }
952    }
953}
954
955/// Snapshot of `PDFThumbnailView` state.
956#[derive(Debug, Clone, Deserialize)]
957pub struct PdfThumbnailViewInfo {
958    /// Mirrors the corresponding `PDFThumbnailView` field.
959    pub has_pdf_view: bool,
960    /// Mirrors the corresponding `PDFThumbnailView` field.
961    pub background_color: Option<PdfColor>,
962    /// Mirrors the corresponding `PDFThumbnailView` field.
963    pub selected_pages_count: usize,
964    /// Mirrors the corresponding `PDFThumbnailView` field.
965    pub thumbnail_size: PdfSize,
966    /// Mirrors the corresponding `PDFThumbnailView` field.
967    pub maximum_number_of_columns: usize,
968    /// Mirrors the corresponding `PDFThumbnailView` field.
969    pub allows_dragging: bool,
970    /// Mirrors the corresponding `PDFThumbnailView` field.
971    pub allows_multiple_selection: bool,
972}
973
974#[cfg(test)]
975mod tests {
976    use super::{
977        DisplayBox, PdfActionNamedName, PdfAreaOfInterest, PdfBorderStyle, PdfColor,
978        PdfDisplayDirection, PdfDisplayMode, PdfDocumentWriteOptions,
979        PdfPageImageInitializationOptions, PdfInterpolationQuality, PdfLineStyle, PdfMarkupType,
980        PdfPoint, PdfRect, PdfSelectionGranularity, PdfSize, PdfTextAnnotationIconType,
981        PdfThumbnailLayoutMode, PdfWidgetCellState,
982    };
983
984    fn assert_close(left: f64, right: f64) {
985        assert!((left - right).abs() < f64::EPSILON, "expected {left} to match {right}");
986    }
987
988    #[test]
989    fn geometry_wrappers_preserve_field_values() {
990        let rect = PdfRect {
991            x: 1.0,
992            y: 2.0,
993            width: 3.0,
994            height: 4.0,
995        };
996        let point = PdfPoint { x: -1.0, y: 5.0 };
997        let size = PdfSize {
998            width: 8.0,
999            height: 9.0,
1000        };
1001        let color = PdfColor {
1002            red: 0.1,
1003            green: 0.2,
1004            blue: 0.3,
1005            alpha: 0.4,
1006        };
1007
1008        assert_close(rect.x, 1.0);
1009        assert_close(rect.y, 2.0);
1010        assert_close(rect.width, 3.0);
1011        assert_close(rect.height, 4.0);
1012        assert_close(point.x, -1.0);
1013        assert_close(point.y, 5.0);
1014        assert_close(size.width, 8.0);
1015        assert_close(size.height, 9.0);
1016        assert_close(color.red, 0.1);
1017        assert_close(color.green, 0.2);
1018        assert_close(color.blue, 0.3);
1019        assert_close(color.alpha, 0.4);
1020    }
1021
1022    #[test]
1023    fn action_and_annotation_enums_round_trip_raw_values() {
1024        assert_eq!(DisplayBox::CropBox.as_raw(), 1);
1025        assert_eq!(PdfBorderStyle::from_raw(4), Some(PdfBorderStyle::Underline));
1026        assert_eq!(PdfBorderStyle::from_raw(99), None);
1027        assert_eq!(PdfActionNamedName::GoToPage.as_raw(), 7);
1028        assert_eq!(PdfActionNamedName::from_raw(7), Some(PdfActionNamedName::GoToPage));
1029        assert_eq!(PdfLineStyle::from_raw(5), Some(PdfLineStyle::ClosedArrow));
1030        assert_eq!(PdfTextAnnotationIconType::Insert.as_raw(), 6);
1031        assert_eq!(PdfTextAnnotationIconType::from_raw(6), Some(PdfTextAnnotationIconType::Insert));
1032        assert_eq!(PdfMarkupType::from_raw(3), Some(PdfMarkupType::Redact));
1033    }
1034
1035    #[test]
1036    fn view_related_enums_round_trip_raw_values() {
1037        assert_eq!(PdfDisplayMode::from_raw(3), Some(PdfDisplayMode::TwoUpContinuous));
1038        assert_eq!(PdfDisplayDirection::from_raw(1), Some(PdfDisplayDirection::Horizontal));
1039        assert_eq!(PdfInterpolationQuality::from_raw(2), Some(PdfInterpolationQuality::High));
1040        assert_eq!(PdfWidgetCellState::Mixed.as_raw(), -1);
1041        assert_eq!(PdfWidgetCellState::from_raw(-1), Some(PdfWidgetCellState::Mixed));
1042        assert_eq!(PdfSelectionGranularity::Line.as_raw(), 2);
1043        assert_eq!(PdfSelectionGranularity::from_raw(2), Some(PdfSelectionGranularity::Line));
1044        assert_eq!(PdfThumbnailLayoutMode::Horizontal.as_raw(), 1);
1045        assert_eq!(PdfThumbnailLayoutMode::from_raw(1), Some(PdfThumbnailLayoutMode::Horizontal));
1046    }
1047
1048    #[test]
1049    fn area_of_interest_bitflags_combine_and_mask() {
1050        let mut area = PdfAreaOfInterest::PAGE | PdfAreaOfInterest::TEXT;
1051        area |= PdfAreaOfInterest::LINK;
1052
1053        assert!(!PdfAreaOfInterest::NONE.intersects(PdfAreaOfInterest::PAGE));
1054        assert!(area.contains(PdfAreaOfInterest::PAGE));
1055        assert!(area.contains(PdfAreaOfInterest::TEXT));
1056        assert!(area.intersects(PdfAreaOfInterest::LINK));
1057        assert!(!area.contains(PdfAreaOfInterest::IMAGE));
1058        assert_eq!((area & PdfAreaOfInterest::TEXT).bits(), PdfAreaOfInterest::TEXT.bits());
1059        assert!(!PdfAreaOfInterest::NONE.bits().eq(&PdfAreaOfInterest::ANY.bits()));
1060    }
1061
1062    #[test]
1063    fn builder_options_capture_selected_values() {
1064        let image_options = PdfPageImageInitializationOptions::default()
1065            .with_media_box(PdfRect {
1066                x: 0.0,
1067                y: 1.0,
1068                width: 200.0,
1069                height: 100.0,
1070            })
1071            .with_rotation(90)
1072            .with_upscale_if_smaller(true)
1073            .with_compression_quality(0.8);
1074        let write_options = PdfDocumentWriteOptions::default()
1075            .with_owner_password("owner")
1076            .with_user_password("user")
1077            .with_access_permissions(0x15)
1078            .with_burn_in_annotations(true)
1079            .with_save_text_from_ocr(true)
1080            .with_save_images_as_jpeg(true)
1081            .with_optimize_images_for_screen(true);
1082
1083        assert_eq!(image_options.rotation, Some(90));
1084        assert!(image_options.upscale_if_smaller);
1085        assert_close(
1086            image_options
1087                .compression_quality
1088                .expect("compression quality should be set"),
1089            0.8,
1090        );
1091        assert_eq!(write_options.owner_password.as_deref(), Some("owner"));
1092        assert_eq!(write_options.user_password.as_deref(), Some("user"));
1093        assert_eq!(write_options.access_permissions, Some(0x15));
1094        assert!(write_options.burn_in_annotations);
1095        assert!(write_options.save_text_from_ocr);
1096        assert!(write_options.save_images_as_jpeg);
1097        assert!(write_options.optimize_images_for_screen);
1098    }
1099}