Skip to main content

pdfium_render/pdf/document/page/
annotation.rs

1//! Defines the [PdfPageAnnotation] struct, exposing functionality related to a single annotation.
2
3pub mod attachment_points;
4pub mod circle;
5pub mod free_text;
6pub mod highlight;
7pub mod ink;
8pub mod link;
9pub mod objects;
10pub mod popup;
11pub(crate) mod private; // Keep private so that the PdfPageAnnotationPrivate trait is not exposed.
12pub mod redacted;
13pub mod square;
14pub mod squiggly;
15pub mod stamp;
16pub mod strikeout;
17pub mod text;
18pub mod underline;
19pub mod unsupported;
20pub mod variable_text;
21pub mod widget;
22pub mod xfa_widget;
23
24use crate::bindgen::{
25    FPDF_ANNOTATION, FPDF_ANNOTATION_SUBTYPE, FPDF_ANNOT_CARET, FPDF_ANNOT_CIRCLE,
26    FPDF_ANNOT_FILEATTACHMENT, FPDF_ANNOT_FREETEXT, FPDF_ANNOT_HIGHLIGHT, FPDF_ANNOT_INK,
27    FPDF_ANNOT_LINE, FPDF_ANNOT_LINK, FPDF_ANNOT_MOVIE, FPDF_ANNOT_POLYGON, FPDF_ANNOT_POLYLINE,
28    FPDF_ANNOT_POPUP, FPDF_ANNOT_PRINTERMARK, FPDF_ANNOT_REDACT, FPDF_ANNOT_RICHMEDIA,
29    FPDF_ANNOT_SCREEN, FPDF_ANNOT_SOUND, FPDF_ANNOT_SQUARE, FPDF_ANNOT_SQUIGGLY, FPDF_ANNOT_STAMP,
30    FPDF_ANNOT_STRIKEOUT, FPDF_ANNOT_TEXT, FPDF_ANNOT_THREED, FPDF_ANNOT_TRAPNET,
31    FPDF_ANNOT_UNDERLINE, FPDF_ANNOT_UNKNOWN, FPDF_ANNOT_WATERMARK, FPDF_ANNOT_WIDGET,
32    FPDF_ANNOT_XFAWIDGET, FPDF_DOCUMENT, FPDF_FORMHANDLE, FPDF_PAGE,
33};
34use crate::bindings::PdfiumLibraryBindings;
35use crate::error::PdfiumError;
36use crate::pdf::color::PdfColor;
37use crate::pdf::document::page::annotation::attachment_points::PdfPageAnnotationAttachmentPoints;
38use crate::pdf::document::page::annotation::circle::PdfPageCircleAnnotation;
39use crate::pdf::document::page::annotation::free_text::PdfPageFreeTextAnnotation;
40use crate::pdf::document::page::annotation::highlight::PdfPageHighlightAnnotation;
41use crate::pdf::document::page::annotation::ink::PdfPageInkAnnotation;
42use crate::pdf::document::page::annotation::link::PdfPageLinkAnnotation;
43use crate::pdf::document::page::annotation::objects::PdfPageAnnotationObjects;
44use crate::pdf::document::page::annotation::popup::PdfPagePopupAnnotation;
45use crate::pdf::document::page::annotation::private::internal::{
46    PdfAnnotationFlags, PdfPageAnnotationPrivate,
47};
48use crate::pdf::document::page::annotation::redacted::PdfPageRedactedAnnotation;
49use crate::pdf::document::page::annotation::square::PdfPageSquareAnnotation;
50use crate::pdf::document::page::annotation::squiggly::PdfPageSquigglyAnnotation;
51use crate::pdf::document::page::annotation::stamp::PdfPageStampAnnotation;
52use crate::pdf::document::page::annotation::strikeout::PdfPageStrikeoutAnnotation;
53use crate::pdf::document::page::annotation::text::PdfPageTextAnnotation;
54use crate::pdf::document::page::annotation::underline::PdfPageUnderlineAnnotation;
55use crate::pdf::document::page::annotation::unsupported::PdfPageUnsupportedAnnotation;
56use crate::pdf::document::page::annotation::widget::PdfPageWidgetAnnotation;
57use crate::pdf::document::page::annotation::xfa_widget::PdfPageXfaWidgetAnnotation;
58use crate::pdf::document::page::field::PdfFormField;
59use crate::pdf::document::page::object::ownership::PdfPageObjectOwnership;
60use crate::pdf::points::PdfPoints;
61use crate::pdf::rect::PdfRect;
62use crate::pdfium::PdfiumLibraryBindingsAccessor;
63use chrono::prelude::*;
64
65#[cfg(doc)]
66use {crate::pdf::document::page::field::PdfFormFieldCommon, crate::pdf::document::page::PdfPage};
67
68/// The type of a single [PdfPageAnnotation], as defined in table 8.20 of the PDF Reference,
69/// version 1.7, on page 615.
70///
71/// Not all PDF annotation types are supported by Pdfium. For example, Pdfium does not
72/// currently support embedded sound or movie file annotations, embedded 3D animations, or
73/// annotations containing embedded file attachments.
74///
75/// Pdfium currently supports creating, editing, and rendering the following types of annotations:
76///
77/// * [PdfPageAnnotationType::Circle]
78/// * [PdfPageAnnotationType::FreeText]
79/// * [PdfPageAnnotationType::Highlight]
80/// * [PdfPageAnnotationType::Ink]
81/// * [PdfPageAnnotationType::Link]
82/// * [PdfPageAnnotationType::Popup]
83/// * [PdfPageAnnotationType::Redacted]
84/// * [PdfPageAnnotationType::Square]
85/// * [PdfPageAnnotationType::Squiggly]
86/// * [PdfPageAnnotationType::Stamp]
87/// * [PdfPageAnnotationType::Strikeout]
88/// * [PdfPageAnnotationType::Text]
89/// * [PdfPageAnnotationType::Underline]
90/// * [PdfPageAnnotationType::Widget]
91/// * [PdfPageAnnotationType::XfaWidget]
92///
93/// Note that a `FreeText` annotation is rendered directly on the page, whereas a `Text` annotation
94/// floats over the page inside its own enclosed area. Adobe often uses the term "sticky note"
95/// in reference to `Text` annotations to distinguish them from `FreeText` annotations.
96#[derive(Debug, Copy, Clone, PartialOrd, PartialEq)]
97pub enum PdfPageAnnotationType {
98    Unknown = FPDF_ANNOT_UNKNOWN as isize,
99    Text = FPDF_ANNOT_TEXT as isize,
100    Link = FPDF_ANNOT_LINK as isize,
101    FreeText = FPDF_ANNOT_FREETEXT as isize,
102    Line = FPDF_ANNOT_LINE as isize,
103    Square = FPDF_ANNOT_SQUARE as isize,
104    Circle = FPDF_ANNOT_CIRCLE as isize,
105    Polygon = FPDF_ANNOT_POLYGON as isize,
106    Polyline = FPDF_ANNOT_POLYLINE as isize,
107    Highlight = FPDF_ANNOT_HIGHLIGHT as isize,
108    Underline = FPDF_ANNOT_UNDERLINE as isize,
109    Squiggly = FPDF_ANNOT_SQUIGGLY as isize,
110    Strikeout = FPDF_ANNOT_STRIKEOUT as isize,
111    Stamp = FPDF_ANNOT_STAMP as isize,
112    Caret = FPDF_ANNOT_CARET as isize,
113    Ink = FPDF_ANNOT_INK as isize,
114    Popup = FPDF_ANNOT_POPUP as isize,
115    FileAttachment = FPDF_ANNOT_FILEATTACHMENT as isize,
116    Sound = FPDF_ANNOT_SOUND as isize,
117    Movie = FPDF_ANNOT_MOVIE as isize,
118    Widget = FPDF_ANNOT_WIDGET as isize,
119    Screen = FPDF_ANNOT_SCREEN as isize,
120    PrinterMark = FPDF_ANNOT_PRINTERMARK as isize,
121    TrapNet = FPDF_ANNOT_TRAPNET as isize,
122    Watermark = FPDF_ANNOT_WATERMARK as isize,
123    ThreeD = FPDF_ANNOT_THREED as isize,
124    RichMedia = FPDF_ANNOT_RICHMEDIA as isize,
125    XfaWidget = FPDF_ANNOT_XFAWIDGET as isize,
126    Redacted = FPDF_ANNOT_REDACT as isize,
127}
128
129impl PdfPageAnnotationType {
130    pub(crate) fn from_pdfium(
131        value: FPDF_ANNOTATION_SUBTYPE,
132    ) -> Result<PdfPageAnnotationType, PdfiumError> {
133        match value as u32 {
134            FPDF_ANNOT_UNKNOWN => Ok(PdfPageAnnotationType::Unknown),
135            FPDF_ANNOT_TEXT => Ok(PdfPageAnnotationType::Text),
136            FPDF_ANNOT_LINK => Ok(PdfPageAnnotationType::Link),
137            FPDF_ANNOT_FREETEXT => Ok(PdfPageAnnotationType::FreeText),
138            FPDF_ANNOT_LINE => Ok(PdfPageAnnotationType::Line),
139            FPDF_ANNOT_SQUARE => Ok(PdfPageAnnotationType::Square),
140            FPDF_ANNOT_CIRCLE => Ok(PdfPageAnnotationType::Circle),
141            FPDF_ANNOT_POLYGON => Ok(PdfPageAnnotationType::Polygon),
142            FPDF_ANNOT_POLYLINE => Ok(PdfPageAnnotationType::Polyline),
143            FPDF_ANNOT_HIGHLIGHT => Ok(PdfPageAnnotationType::Highlight),
144            FPDF_ANNOT_UNDERLINE => Ok(PdfPageAnnotationType::Underline),
145            FPDF_ANNOT_SQUIGGLY => Ok(PdfPageAnnotationType::Squiggly),
146            FPDF_ANNOT_STRIKEOUT => Ok(PdfPageAnnotationType::Strikeout),
147            FPDF_ANNOT_STAMP => Ok(PdfPageAnnotationType::Stamp),
148            FPDF_ANNOT_CARET => Ok(PdfPageAnnotationType::Caret),
149            FPDF_ANNOT_INK => Ok(PdfPageAnnotationType::Ink),
150            FPDF_ANNOT_POPUP => Ok(PdfPageAnnotationType::Popup),
151            FPDF_ANNOT_FILEATTACHMENT => Ok(PdfPageAnnotationType::FileAttachment),
152            FPDF_ANNOT_SOUND => Ok(PdfPageAnnotationType::Sound),
153            FPDF_ANNOT_MOVIE => Ok(PdfPageAnnotationType::Movie),
154            FPDF_ANNOT_WIDGET => Ok(PdfPageAnnotationType::Widget),
155            FPDF_ANNOT_SCREEN => Ok(PdfPageAnnotationType::Screen),
156            FPDF_ANNOT_PRINTERMARK => Ok(PdfPageAnnotationType::PrinterMark),
157            FPDF_ANNOT_TRAPNET => Ok(PdfPageAnnotationType::TrapNet),
158            FPDF_ANNOT_WATERMARK => Ok(PdfPageAnnotationType::Watermark),
159            FPDF_ANNOT_THREED => Ok(PdfPageAnnotationType::ThreeD),
160            FPDF_ANNOT_RICHMEDIA => Ok(PdfPageAnnotationType::RichMedia),
161            FPDF_ANNOT_XFAWIDGET => Ok(PdfPageAnnotationType::XfaWidget),
162            FPDF_ANNOT_REDACT => Ok(PdfPageAnnotationType::Redacted),
163            _ => Err(PdfiumError::UnknownPdfAnnotationType),
164        }
165    }
166
167    #[allow(dead_code)]
168    // The as_pdfium() function is not currently used, but we expect it to be in future
169    pub(crate) fn as_pdfium(&self) -> FPDF_ANNOTATION_SUBTYPE {
170        (match self {
171            PdfPageAnnotationType::Unknown => FPDF_ANNOT_UNKNOWN,
172            PdfPageAnnotationType::Text => FPDF_ANNOT_TEXT,
173            PdfPageAnnotationType::Link => FPDF_ANNOT_LINK,
174            PdfPageAnnotationType::FreeText => FPDF_ANNOT_FREETEXT,
175            PdfPageAnnotationType::Line => FPDF_ANNOT_LINE,
176            PdfPageAnnotationType::Square => FPDF_ANNOT_SQUARE,
177            PdfPageAnnotationType::Circle => FPDF_ANNOT_CIRCLE,
178            PdfPageAnnotationType::Polygon => FPDF_ANNOT_POLYGON,
179            PdfPageAnnotationType::Polyline => FPDF_ANNOT_POLYLINE,
180            PdfPageAnnotationType::Highlight => FPDF_ANNOT_HIGHLIGHT,
181            PdfPageAnnotationType::Underline => FPDF_ANNOT_UNDERLINE,
182            PdfPageAnnotationType::Squiggly => FPDF_ANNOT_SQUIGGLY,
183            PdfPageAnnotationType::Strikeout => FPDF_ANNOT_STRIKEOUT,
184            PdfPageAnnotationType::Stamp => FPDF_ANNOT_STAMP,
185            PdfPageAnnotationType::Caret => FPDF_ANNOT_CARET,
186            PdfPageAnnotationType::Ink => FPDF_ANNOT_INK,
187            PdfPageAnnotationType::Popup => FPDF_ANNOT_POPUP,
188            PdfPageAnnotationType::FileAttachment => FPDF_ANNOT_FILEATTACHMENT,
189            PdfPageAnnotationType::Sound => FPDF_ANNOT_SOUND,
190            PdfPageAnnotationType::Movie => FPDF_ANNOT_MOVIE,
191            PdfPageAnnotationType::Widget => FPDF_ANNOT_WIDGET,
192            PdfPageAnnotationType::Screen => FPDF_ANNOT_SCREEN,
193            PdfPageAnnotationType::PrinterMark => FPDF_ANNOT_PRINTERMARK,
194            PdfPageAnnotationType::TrapNet => FPDF_ANNOT_TRAPNET,
195            PdfPageAnnotationType::Watermark => FPDF_ANNOT_WATERMARK,
196            PdfPageAnnotationType::ThreeD => FPDF_ANNOT_THREED,
197            PdfPageAnnotationType::RichMedia => FPDF_ANNOT_RICHMEDIA,
198            PdfPageAnnotationType::XfaWidget => FPDF_ANNOT_XFAWIDGET,
199            PdfPageAnnotationType::Redacted => FPDF_ANNOT_REDACT,
200        }) as FPDF_ANNOTATION_SUBTYPE
201    }
202}
203
204/// A single user annotation on a [PdfPage].
205pub enum PdfPageAnnotation<'a> {
206    Circle(PdfPageCircleAnnotation<'a>),
207    FreeText(PdfPageFreeTextAnnotation<'a>),
208    Highlight(PdfPageHighlightAnnotation<'a>),
209    Ink(PdfPageInkAnnotation<'a>),
210    Link(PdfPageLinkAnnotation<'a>),
211    Popup(PdfPagePopupAnnotation<'a>),
212    Square(PdfPageSquareAnnotation<'a>),
213    Squiggly(PdfPageSquigglyAnnotation<'a>),
214    Stamp(PdfPageStampAnnotation<'a>),
215    Strikeout(PdfPageStrikeoutAnnotation<'a>),
216    Text(PdfPageTextAnnotation<'a>),
217    Underline(PdfPageUnderlineAnnotation<'a>),
218    Widget(PdfPageWidgetAnnotation<'a>),
219    XfaWidget(PdfPageXfaWidgetAnnotation<'a>),
220    Redacted(PdfPageRedactedAnnotation<'a>),
221
222    /// Common properties shared by all [PdfPageAnnotation] types can still be accessed for
223    /// annotations not supported by Pdfium, but annotation-specific functionality
224    /// will be unavailable.
225    Unsupported(PdfPageUnsupportedAnnotation<'a>),
226}
227
228impl<'a> PdfPageAnnotation<'a> {
229    pub(crate) fn from_pdfium(
230        document_handle: FPDF_DOCUMENT,
231        page_handle: FPDF_PAGE,
232        annotation_handle: FPDF_ANNOTATION,
233        form_handle: Option<FPDF_FORMHANDLE>,
234        bindings: &'a dyn PdfiumLibraryBindings,
235    ) -> Self {
236        let annotation_type = PdfPageAnnotationType::from_pdfium(unsafe {
237            bindings.FPDFAnnot_GetSubtype(annotation_handle)
238        })
239        .unwrap_or(PdfPageAnnotationType::Unknown);
240
241        match annotation_type {
242            PdfPageAnnotationType::Circle => {
243                PdfPageAnnotation::Circle(PdfPageCircleAnnotation::from_pdfium(
244                    document_handle,
245                    page_handle,
246                    annotation_handle,
247                ))
248            }
249            PdfPageAnnotationType::FreeText => {
250                PdfPageAnnotation::FreeText(PdfPageFreeTextAnnotation::from_pdfium(
251                    document_handle,
252                    page_handle,
253                    annotation_handle,
254                ))
255            }
256            PdfPageAnnotationType::Highlight => {
257                PdfPageAnnotation::Highlight(PdfPageHighlightAnnotation::from_pdfium(
258                    document_handle,
259                    page_handle,
260                    annotation_handle,
261                ))
262            }
263            PdfPageAnnotationType::Ink => PdfPageAnnotation::Ink(
264                PdfPageInkAnnotation::from_pdfium(document_handle, page_handle, annotation_handle),
265            ),
266            PdfPageAnnotationType::Link => PdfPageAnnotation::Link(
267                PdfPageLinkAnnotation::from_pdfium(document_handle, page_handle, annotation_handle),
268            ),
269            PdfPageAnnotationType::Popup => {
270                PdfPageAnnotation::Popup(PdfPagePopupAnnotation::from_pdfium(
271                    document_handle,
272                    page_handle,
273                    annotation_handle,
274                ))
275            }
276            PdfPageAnnotationType::Square => {
277                PdfPageAnnotation::Square(PdfPageSquareAnnotation::from_pdfium(
278                    document_handle,
279                    page_handle,
280                    annotation_handle,
281                ))
282            }
283            PdfPageAnnotationType::Squiggly => {
284                PdfPageAnnotation::Squiggly(PdfPageSquigglyAnnotation::from_pdfium(
285                    document_handle,
286                    page_handle,
287                    annotation_handle,
288                ))
289            }
290            PdfPageAnnotationType::Stamp => {
291                PdfPageAnnotation::Stamp(PdfPageStampAnnotation::from_pdfium(
292                    document_handle,
293                    page_handle,
294                    annotation_handle,
295                ))
296            }
297            PdfPageAnnotationType::Strikeout => {
298                PdfPageAnnotation::Strikeout(PdfPageStrikeoutAnnotation::from_pdfium(
299                    document_handle,
300                    page_handle,
301                    annotation_handle,
302                ))
303            }
304            PdfPageAnnotationType::Text => PdfPageAnnotation::Text(
305                PdfPageTextAnnotation::from_pdfium(document_handle, page_handle, annotation_handle),
306            ),
307            PdfPageAnnotationType::Underline => {
308                PdfPageAnnotation::Underline(PdfPageUnderlineAnnotation::from_pdfium(
309                    document_handle,
310                    page_handle,
311                    annotation_handle,
312                ))
313            }
314            PdfPageAnnotationType::Widget => {
315                PdfPageAnnotation::Widget(PdfPageWidgetAnnotation::from_pdfium(
316                    document_handle,
317                    page_handle,
318                    annotation_handle,
319                    form_handle,
320                    bindings,
321                ))
322            }
323            PdfPageAnnotationType::XfaWidget => {
324                PdfPageAnnotation::XfaWidget(PdfPageXfaWidgetAnnotation::from_pdfium(
325                    document_handle,
326                    page_handle,
327                    annotation_handle,
328                    form_handle,
329                    bindings,
330                ))
331            }
332            PdfPageAnnotationType::Redacted => {
333                PdfPageAnnotation::Redacted(PdfPageRedactedAnnotation::from_pdfium(
334                    document_handle,
335                    page_handle,
336                    annotation_handle,
337                ))
338            }
339            _ => PdfPageAnnotation::Unsupported(PdfPageUnsupportedAnnotation::from_pdfium(
340                document_handle,
341                page_handle,
342                annotation_handle,
343                annotation_type,
344            )),
345        }
346    }
347
348    #[inline]
349    pub(crate) fn unwrap_as_trait(&self) -> &dyn PdfPageAnnotationPrivate<'a> {
350        match self {
351            PdfPageAnnotation::Circle(annotation) => annotation,
352            PdfPageAnnotation::FreeText(annotation) => annotation,
353            PdfPageAnnotation::Highlight(annotation) => annotation,
354            PdfPageAnnotation::Ink(annotation) => annotation,
355            PdfPageAnnotation::Link(annotation) => annotation,
356            PdfPageAnnotation::Popup(annotation) => annotation,
357            PdfPageAnnotation::Square(annotation) => annotation,
358            PdfPageAnnotation::Squiggly(annotation) => annotation,
359            PdfPageAnnotation::Stamp(annotation) => annotation,
360            PdfPageAnnotation::Strikeout(annotation) => annotation,
361            PdfPageAnnotation::Text(annotation) => annotation,
362            PdfPageAnnotation::Underline(annotation) => annotation,
363            PdfPageAnnotation::Widget(annotation) => annotation,
364            PdfPageAnnotation::XfaWidget(annotation) => annotation,
365            PdfPageAnnotation::Redacted(annotation) => annotation,
366            PdfPageAnnotation::Unsupported(annotation) => annotation,
367        }
368    }
369
370    #[inline]
371    #[allow(dead_code)] // We don't currently use unwrap_as_trait_mut(), but we expect to in the future
372    pub(crate) fn unwrap_as_trait_mut(&mut self) -> &mut dyn PdfPageAnnotationPrivate<'a> {
373        match self {
374            PdfPageAnnotation::Circle(annotation) => annotation,
375            PdfPageAnnotation::FreeText(annotation) => annotation,
376            PdfPageAnnotation::Highlight(annotation) => annotation,
377            PdfPageAnnotation::Ink(annotation) => annotation,
378            PdfPageAnnotation::Link(annotation) => annotation,
379            PdfPageAnnotation::Popup(annotation) => annotation,
380            PdfPageAnnotation::Square(annotation) => annotation,
381            PdfPageAnnotation::Squiggly(annotation) => annotation,
382            PdfPageAnnotation::Stamp(annotation) => annotation,
383            PdfPageAnnotation::Strikeout(annotation) => annotation,
384            PdfPageAnnotation::Text(annotation) => annotation,
385            PdfPageAnnotation::Underline(annotation) => annotation,
386            PdfPageAnnotation::Widget(annotation) => annotation,
387            PdfPageAnnotation::XfaWidget(annotation) => annotation,
388            PdfPageAnnotation::Redacted(annotation) => annotation,
389            PdfPageAnnotation::Unsupported(annotation) => annotation,
390        }
391    }
392
393    /// The type of this [PdfPageAnnotation].
394    ///
395    /// Not all PDF annotation types are supported by Pdfium. For example, Pdfium does not
396    /// currently support embedded sound or movie file annotations, embedded 3D animations, or
397    /// annotations containing embedded file attachments.
398    ///
399    /// Pdfium currently supports creating, editing, and rendering the following types of annotations:
400    ///
401    /// * [PdfPageAnnotationType::Circle]
402    /// * [PdfPageAnnotationType::FreeText]
403    /// * [PdfPageAnnotationType::Highlight]
404    /// * [PdfPageAnnotationType::Ink]
405    /// * [PdfPageAnnotationType::Link]
406    /// * [PdfPageAnnotationType::Popup]
407    /// * [PdfPageAnnotationType::Redacted]
408    /// * [PdfPageAnnotationType::Square]
409    /// * [PdfPageAnnotationType::Squiggly]
410    /// * [PdfPageAnnotationType::Stamp]
411    /// * [PdfPageAnnotationType::Strikeout]
412    /// * [PdfPageAnnotationType::Text]
413    /// * [PdfPageAnnotationType::Underline]
414    /// * [PdfPageAnnotationType::Widget]
415    /// * [PdfPageAnnotationType::XfaWidget]
416    #[inline]
417    pub fn annotation_type(&self) -> PdfPageAnnotationType {
418        match self {
419            PdfPageAnnotation::Circle(_) => PdfPageAnnotationType::Circle,
420            PdfPageAnnotation::FreeText(_) => PdfPageAnnotationType::FreeText,
421            PdfPageAnnotation::Highlight(_) => PdfPageAnnotationType::Highlight,
422            PdfPageAnnotation::Ink(_) => PdfPageAnnotationType::Ink,
423            PdfPageAnnotation::Link(_) => PdfPageAnnotationType::Link,
424            PdfPageAnnotation::Popup(_) => PdfPageAnnotationType::Popup,
425            PdfPageAnnotation::Square(_) => PdfPageAnnotationType::Square,
426            PdfPageAnnotation::Squiggly(_) => PdfPageAnnotationType::Squiggly,
427            PdfPageAnnotation::Stamp(_) => PdfPageAnnotationType::Stamp,
428            PdfPageAnnotation::Strikeout(_) => PdfPageAnnotationType::Strikeout,
429            PdfPageAnnotation::Text(_) => PdfPageAnnotationType::Text,
430            PdfPageAnnotation::Underline(_) => PdfPageAnnotationType::Underline,
431            PdfPageAnnotation::Widget(_) => PdfPageAnnotationType::Widget,
432            PdfPageAnnotation::XfaWidget(_) => PdfPageAnnotationType::XfaWidget,
433            PdfPageAnnotation::Redacted(_) => PdfPageAnnotationType::Redacted,
434            PdfPageAnnotation::Unsupported(annotation) => annotation.get_type(),
435        }
436    }
437
438    /// Returns `true` if Pdfium supports creating, editing, and rendering this type of
439    /// [PdfPageAnnotation].
440    ///
441    /// Not all PDF annotation types are supported by Pdfium. For example, Pdfium does not
442    /// currently support embedded sound or movie file annotations, embedded 3D animations, or
443    /// annotations containing embedded file attachments.
444    ///
445    /// Pdfium currently supports creating, editing, and rendering the following types of annotations:
446    ///
447    /// * [PdfPageAnnotationType::Circle]
448    /// * [PdfPageAnnotationType::FreeText]
449    /// * [PdfPageAnnotationType::Highlight]
450    /// * [PdfPageAnnotationType::Ink]
451    /// * [PdfPageAnnotationType::Link]
452    /// * [PdfPageAnnotationType::Popup]
453    /// * [PdfPageAnnotationType::Redacted]
454    /// * [PdfPageAnnotationType::Square]
455    /// * [PdfPageAnnotationType::Squiggly]
456    /// * [PdfPageAnnotationType::Stamp]
457    /// * [PdfPageAnnotationType::Strikeout]
458    /// * [PdfPageAnnotationType::Text]
459    /// * [PdfPageAnnotationType::Underline]
460    /// * [PdfPageAnnotationType::Widget]
461    /// * [PdfPageAnnotationType::XfaWidget]
462    #[inline]
463    pub fn is_supported(&self) -> bool {
464        !self.is_unsupported()
465    }
466
467    /// Returns `true` if Pdfium does _not_ support creating, editing, and rendering this type of
468    /// [PdfPageAnnotation].
469    ///
470    /// Not all PDF annotation types are supported by Pdfium. For example, Pdfium does not
471    /// currently support embedded sound or movie file annotations, embedded 3D animations, or
472    /// annotations containing embedded file attachments.
473    ///
474    /// Pdfium currently supports creating, editing, and rendering the following types of annotations:
475    ///
476    /// * [PdfPageAnnotationType::Circle]
477    /// * [PdfPageAnnotationType::FreeText]
478    /// * [PdfPageAnnotationType::Highlight]
479    /// * [PdfPageAnnotationType::Ink]
480    /// * [PdfPageAnnotationType::Link]
481    /// * [PdfPageAnnotationType::Popup]
482    /// * [PdfPageAnnotationType::Redacted]
483    /// * [PdfPageAnnotationType::Square]
484    /// * [PdfPageAnnotationType::Squiggly]
485    /// * [PdfPageAnnotationType::Stamp]
486    /// * [PdfPageAnnotationType::Strikeout]
487    /// * [PdfPageAnnotationType::Text]
488    /// * [PdfPageAnnotationType::Underline]
489    /// * [PdfPageAnnotationType::Widget]
490    /// * [PdfPageAnnotationType::XfaWidget]
491    #[inline]
492    pub fn is_unsupported(&self) -> bool {
493        matches!(self, PdfPageAnnotation::Unsupported(_))
494    }
495
496    /// Returns an immutable reference to the underlying [PdfPageCircleAnnotation]
497    /// for this [PdfPageAnnotation], if this annotation has an annotation type of
498    /// [PdfPageAnnotationType::Circle].
499    #[inline]
500    pub fn as_circle_annotation(&self) -> Option<&PdfPageCircleAnnotation<'_>> {
501        match self {
502            PdfPageAnnotation::Circle(annotation) => Some(annotation),
503            _ => None,
504        }
505    }
506
507    /// Returns a mutable reference to the underlying [PdfPageCircleAnnotation]
508    /// for this [PdfPageAnnotation], if this annotation has an annotation type of
509    /// [PdfPageAnnotationType::Circle].
510    #[inline]
511    pub fn as_circle_annotation_mut(&mut self) -> Option<&mut PdfPageCircleAnnotation<'a>> {
512        match self {
513            PdfPageAnnotation::Circle(annotation) => Some(annotation),
514            _ => None,
515        }
516    }
517
518    /// Returns an immutable reference to the underlying [PdfPageFreeTextAnnotation]
519    /// for this [PdfPageAnnotation], if this annotation has an annotation type of
520    /// [PdfPageAnnotationType::FreeText].
521    #[inline]
522    pub fn as_free_text_annotation(&self) -> Option<&PdfPageFreeTextAnnotation<'_>> {
523        match self {
524            PdfPageAnnotation::FreeText(annotation) => Some(annotation),
525            _ => None,
526        }
527    }
528
529    /// Returns a mutable reference to the underlying [PdfPageFreeTextAnnotation]
530    /// for this [PdfPageAnnotation], if this annotation has an annotation type of
531    /// [PdfPageAnnotationType::FreeText].
532    #[inline]
533    pub fn as_free_text_annotation_mut(&mut self) -> Option<&mut PdfPageFreeTextAnnotation<'a>> {
534        match self {
535            PdfPageAnnotation::FreeText(annotation) => Some(annotation),
536            _ => None,
537        }
538    }
539
540    /// Returns an immutable reference to the underlying [PdfPageHighlightAnnotation]
541    /// for this [PdfPageAnnotation], if this annotation has an annotation type of
542    /// [PdfPageAnnotationType::Highlight].
543    #[inline]
544    pub fn as_highlight_annotation(&self) -> Option<&PdfPageHighlightAnnotation<'_>> {
545        match self {
546            PdfPageAnnotation::Highlight(annotation) => Some(annotation),
547            _ => None,
548        }
549    }
550
551    /// Returns a mutable reference to the underlying [PdfPageHighlightAnnotation]
552    /// for this [PdfPageAnnotation], if this annotation has an annotation type of
553    /// [PdfPageAnnotationType::Highlight].
554    #[inline]
555    pub fn as_highlight_annotation_mut(&mut self) -> Option<&mut PdfPageHighlightAnnotation<'a>> {
556        match self {
557            PdfPageAnnotation::Highlight(annotation) => Some(annotation),
558            _ => None,
559        }
560    }
561
562    /// Returns an immutable reference to the underlying [PdfPageInkAnnotation]
563    /// for this [PdfPageAnnotation], if this annotation has an annotation type of
564    /// [PdfPageAnnotationType::Ink].
565    #[inline]
566    pub fn as_ink_annotation(&self) -> Option<&PdfPageInkAnnotation<'_>> {
567        match self {
568            PdfPageAnnotation::Ink(annotation) => Some(annotation),
569            _ => None,
570        }
571    }
572
573    /// Returns a mutable reference to the underlying [PdfPageInkAnnotation]
574    /// for this [PdfPageAnnotation], if this annotation has an annotation type of
575    /// [PdfPageAnnotationType::Ink].
576    #[inline]
577    pub fn as_ink_annotation_mut(&mut self) -> Option<&mut PdfPageInkAnnotation<'a>> {
578        match self {
579            PdfPageAnnotation::Ink(annotation) => Some(annotation),
580            _ => None,
581        }
582    }
583
584    /// Returns an immutable reference to the underlying [PdfPageLinkAnnotation]
585    /// for this [PdfPageAnnotation], if this annotation has an annotation type of
586    /// [PdfPageAnnotationType::Link].
587    #[inline]
588    pub fn as_link_annotation(&self) -> Option<&PdfPageLinkAnnotation<'_>> {
589        match self {
590            PdfPageAnnotation::Link(annotation) => Some(annotation),
591            _ => None,
592        }
593    }
594
595    /// Returns a mutable reference to the underlying [PdfPageLinkAnnotation]
596    /// for this [PdfPageAnnotation], if this annotation has an annotation type of
597    /// [PdfPageAnnotationType::Link].
598    #[inline]
599    pub fn as_link_annotation_mut(&mut self) -> Option<&mut PdfPageLinkAnnotation<'a>> {
600        match self {
601            PdfPageAnnotation::Link(annotation) => Some(annotation),
602            _ => None,
603        }
604    }
605
606    /// Returns an immutable reference to the underlying [PdfPagePopupAnnotation]
607    /// for this [PdfPageAnnotation], if this annotation has an annotation type of
608    /// [PdfPageAnnotationType::Popup].
609    #[inline]
610    pub fn as_popup_annotation(&self) -> Option<&PdfPagePopupAnnotation<'_>> {
611        match self {
612            PdfPageAnnotation::Popup(annotation) => Some(annotation),
613            _ => None,
614        }
615    }
616
617    /// Returns a mutable reference to the underlying [PdfPagePopupAnnotation]
618    /// for this [PdfPageAnnotation], if this annotation has an annotation type of
619    /// [PdfPageAnnotationType::Popup].
620    #[inline]
621    pub fn as_popup_annotation_mut(&mut self) -> Option<&mut PdfPagePopupAnnotation<'a>> {
622        match self {
623            PdfPageAnnotation::Popup(annotation) => Some(annotation),
624            _ => None,
625        }
626    }
627
628    /// Returns an immutable reference to the underlying [PdfPageSquareAnnotation]
629    /// for this [PdfPageAnnotation], if this annotation has an annotation type of
630    /// [PdfPageAnnotationType::Square].
631    #[inline]
632    pub fn as_square_annotation(&self) -> Option<&PdfPageSquareAnnotation<'_>> {
633        match self {
634            PdfPageAnnotation::Square(annotation) => Some(annotation),
635            _ => None,
636        }
637    }
638
639    /// Returns a mutable reference to the underlying [PdfPageSquareAnnotation]
640    /// for this [PdfPageAnnotation], if this annotation has an annotation type of
641    /// [PdfPageAnnotationType::Square].
642    #[inline]
643    pub fn as_square_annotation_mut(&mut self) -> Option<&mut PdfPageSquareAnnotation<'a>> {
644        match self {
645            PdfPageAnnotation::Square(annotation) => Some(annotation),
646            _ => None,
647        }
648    }
649
650    /// Returns an immutable reference to the underlying [PdfPageSquigglyAnnotation]
651    /// for this [PdfPageAnnotation], if this annotation has an annotation type of
652    /// [PdfPageAnnotationType::Squiggly].
653    #[inline]
654    pub fn as_squiggly_annotation(&self) -> Option<&PdfPageSquigglyAnnotation<'_>> {
655        match self {
656            PdfPageAnnotation::Squiggly(annotation) => Some(annotation),
657            _ => None,
658        }
659    }
660
661    /// Returns a mutable reference to the underlying [PdfPageSquigglyAnnotation]
662    /// for this [PdfPageAnnotation], if this annotation has an annotation type of
663    /// [PdfPageAnnotationType::Squiggly].
664    #[inline]
665    pub fn as_squiggly_annotation_mut(&mut self) -> Option<&mut PdfPageSquigglyAnnotation<'a>> {
666        match self {
667            PdfPageAnnotation::Squiggly(annotation) => Some(annotation),
668            _ => None,
669        }
670    }
671
672    /// Returns an immutable reference to the underlying [PdfPageStampAnnotation]
673    /// for this [PdfPageAnnotation], if this annotation has an annotation type of
674    /// [PdfPageAnnotationType::Stamp].
675    #[inline]
676    pub fn as_stamp_annotation(&self) -> Option<&PdfPageStampAnnotation<'_>> {
677        match self {
678            PdfPageAnnotation::Stamp(annotation) => Some(annotation),
679            _ => None,
680        }
681    }
682
683    /// Returns a mutable reference to the underlying [PdfPageStampAnnotation]
684    /// for this [PdfPageAnnotation], if this annotation has an annotation type of
685    /// [PdfPageAnnotationType::Stamp].
686    #[inline]
687    pub fn as_stamp_annotation_mut(&mut self) -> Option<&mut PdfPageStampAnnotation<'a>> {
688        match self {
689            PdfPageAnnotation::Stamp(annotation) => Some(annotation),
690            _ => None,
691        }
692    }
693
694    /// Returns an immutable reference to the underlying [PdfPageStrikeoutAnnotation]
695    /// for this [PdfPageAnnotation], if this annotation has an annotation type of
696    /// [PdfPageAnnotationType::Strikeout].
697    #[inline]
698    pub fn as_strikeout_annotation(&self) -> Option<&PdfPageStrikeoutAnnotation<'_>> {
699        match self {
700            PdfPageAnnotation::Strikeout(annotation) => Some(annotation),
701            _ => None,
702        }
703    }
704
705    /// Returns a mutable reference to the underlying [PdfPageStrikeoutAnnotation]
706    /// for this [PdfPageAnnotation], if this annotation has an annotation type of
707    /// [PdfPageAnnotationType::Strikeout].
708    #[inline]
709    pub fn as_strikeout_annotation_mut(&mut self) -> Option<&mut PdfPageStrikeoutAnnotation<'a>> {
710        match self {
711            PdfPageAnnotation::Strikeout(annotation) => Some(annotation),
712            _ => None,
713        }
714    }
715
716    /// Returns an immutable reference to the underlying [PdfPageTextAnnotation]
717    /// for this [PdfPageAnnotation], if this annotation has an annotation type of
718    /// [PdfPageAnnotationType::Text].
719    #[inline]
720    pub fn as_text_annotation(&self) -> Option<&PdfPageTextAnnotation<'_>> {
721        match self {
722            PdfPageAnnotation::Text(annotation) => Some(annotation),
723            _ => None,
724        }
725    }
726
727    /// Returns a mutable reference to the underlying [PdfPageTextAnnotation]
728    /// for this [PdfPageAnnotation], if this annotation has an annotation type of
729    /// [PdfPageAnnotationType::Text].
730    #[inline]
731    pub fn as_text_annotation_mut(&mut self) -> Option<&mut PdfPageTextAnnotation<'a>> {
732        match self {
733            PdfPageAnnotation::Text(annotation) => Some(annotation),
734            _ => None,
735        }
736    }
737
738    /// Returns an immutable reference to the underlying [PdfPageUnderlineAnnotation]
739    /// for this [PdfPageAnnotation], if this annotation has an annotation type of
740    /// [PdfPageAnnotationType::Underline].
741    #[inline]
742    pub fn as_underline_annotation(&self) -> Option<&PdfPageUnderlineAnnotation<'_>> {
743        match self {
744            PdfPageAnnotation::Underline(annotation) => Some(annotation),
745            _ => None,
746        }
747    }
748
749    /// Returns a mutable reference to the underlying [PdfPageUnderlineAnnotation]
750    /// for this [PdfPageAnnotation], if this annotation has an annotation type of
751    /// [PdfPageAnnotationType::Underline].
752    #[inline]
753    pub fn as_underline_annotation_mut(&mut self) -> Option<&mut PdfPageUnderlineAnnotation<'a>> {
754        match self {
755            PdfPageAnnotation::Underline(annotation) => Some(annotation),
756            _ => None,
757        }
758    }
759
760    /// Returns an immutable reference to the underlying [PdfPageWidgetAnnotation]
761    /// for this [PdfPageAnnotation], if this annotation has an annotation type of
762    /// [PdfPageAnnotationType::Widget].
763    #[inline]
764    pub fn as_widget_annotation(&self) -> Option<&PdfPageWidgetAnnotation<'_>> {
765        match self {
766            PdfPageAnnotation::Widget(annotation) => Some(annotation),
767            _ => None,
768        }
769    }
770
771    /// Returns a mutable reference to the underlying [PdfPageWidgetAnnotation]
772    /// for this [PdfPageAnnotation], if this annotation has an annotation type of
773    /// [PdfPageAnnotationType::Widget].
774    #[inline]
775    pub fn as_widget_annotation_mut(&mut self) -> Option<&mut PdfPageWidgetAnnotation<'a>> {
776        match self {
777            PdfPageAnnotation::Widget(annotation) => Some(annotation),
778            _ => None,
779        }
780    }
781
782    /// Returns an immutable reference to the underlying [PdfPageXfaWidgetAnnotation]
783    /// for this [PdfPageAnnotation], if this annotation has an annotation type of
784    /// [PdfPageAnnotationType::XfaWidget].
785    #[inline]
786    pub fn as_xfa_widget_annotation(&self) -> Option<&PdfPageXfaWidgetAnnotation<'_>> {
787        match self {
788            PdfPageAnnotation::XfaWidget(annotation) => Some(annotation),
789            _ => None,
790        }
791    }
792
793    /// Returns a mutable reference to the underlying [PdfPageXfaWidgetAnnotation]
794    /// for this [PdfPageAnnotation], if this annotation has an annotation type of
795    /// [PdfPageAnnotationType::XfaWidget].
796    #[inline]
797    pub fn as_xfa_widget_annotation_mut(&mut self) -> Option<&mut PdfPageXfaWidgetAnnotation<'a>> {
798        match self {
799            PdfPageAnnotation::XfaWidget(annotation) => Some(annotation),
800            _ => None,
801        }
802    }
803
804    /// Returns an immutable reference to the underlying [PdfPageRedactedAnnotation]
805    /// for this [PdfPageAnnotation], if this annotation has an annotation type of
806    /// [PdfPageAnnotationType::Redacted].
807    #[inline]
808    pub fn as_redacted_annotation(&self) -> Option<&PdfPageRedactedAnnotation<'_>> {
809        match self {
810            PdfPageAnnotation::Redacted(annotation) => Some(annotation),
811            _ => None,
812        }
813    }
814
815    /// Returns a mutable reference to the underlying [PdfPageRedactedAnnotation]
816    /// for this [PdfPageAnnotation], if this annotation has an annotation type of
817    /// [PdfPageAnnotationType::Redacted].
818    #[inline]
819    pub fn as_redacted_annotation_mut(&mut self) -> Option<&mut PdfPageRedactedAnnotation<'a>> {
820        match self {
821            PdfPageAnnotation::Redacted(annotation) => Some(annotation),
822            _ => None,
823        }
824    }
825
826    /// Returns an immutable reference to the [PdfFormField] wrapped by this [PdfPageAnnotation],
827    /// if any.
828    ///
829    /// Only annotations of type [PdfPageAnnotationType::Widget] and [PdfPageAnnotationType::XfaWidget]
830    /// wrap form fields.
831    #[inline]
832    pub fn as_form_field(&self) -> Option<&PdfFormField<'_>> {
833        match self {
834            PdfPageAnnotation::Widget(annotation) => annotation.form_field(),
835            PdfPageAnnotation::XfaWidget(annotation) => annotation.form_field(),
836            _ => None,
837        }
838    }
839
840    /// Returns a mutable reference to the [PdfFormField] wrapped by this [PdfPageAnnotation],
841    /// if any.
842    ///
843    /// Only annotations of type [PdfPageAnnotationType::Widget] and [PdfPageAnnotationType::XfaWidget]
844    /// wrap form fields.
845    #[inline]
846    pub fn as_form_field_mut(&mut self) -> Option<&mut PdfFormField<'a>> {
847        match self {
848            PdfPageAnnotation::Widget(annotation) => annotation.form_field_mut(),
849            PdfPageAnnotation::XfaWidget(annotation) => annotation.form_field_mut(),
850            _ => None,
851        }
852    }
853}
854
855/// Functionality common to all [PdfPageAnnotation] objects, regardless of their [PdfPageAnnotationType].
856pub trait PdfPageAnnotationCommon {
857    /// Returns the name of this [PdfPageAnnotation], if any. This is a text string uniquely identifying
858    /// this annotation among all the annotations attached to the containing page.
859    fn name(&self) -> Option<String>;
860
861    /// Returns `true` if this [PdfPageAnnotation] supports applying text markup to the page
862    /// by setting the annotation contents using the [PdfPageAnnotationCommon::set_contents()]
863    /// function.
864    fn is_markup_annotation(&self) -> bool;
865
866    /// Returns `true` if this [PdfPageAnnotation] supports setting attachment points that
867    /// visually associate it with a `PdfPageObject`.
868    fn has_attachment_points(&self) -> bool;
869
870    /// Returns the bounding box of this [PdfPageAnnotation].
871    fn bounds(&self) -> Result<PdfRect, PdfiumError>;
872
873    /// Sets the bounding box of this [PdfPageAnnotation].
874    ///
875    /// This sets the position, the width, and the height of the annotation in a single operation.
876    /// To set these properties separately, use the [PdfPageAnnotationCommon::set_position()],
877    /// [PdfPageAnnotationCommon::set_width()], and [PdfPageAnnotationCommon::set_height()] functions.
878    fn set_bounds(&mut self, bounds: PdfRect) -> Result<(), PdfiumError>;
879
880    /// Sets the bottom right corner of this [PdfPageAnnotation] to the given values.
881    ///
882    /// To set the position, the width, and the height of the annotation in a single operation,
883    /// use the [PdfPageAnnotationCommon::set_bounds()] function.
884    fn set_position(&mut self, x: PdfPoints, y: PdfPoints) -> Result<(), PdfiumError>;
885
886    /// Sets the width of this [PdfPageAnnotation] to the given value.
887    ///
888    /// To set the position, the width, and the height of the annotation in a single operation,
889    /// use the [PdfPageAnnotationCommon::set_bounds()] function.
890    fn set_width(&mut self, width: PdfPoints) -> Result<(), PdfiumError>;
891
892    /// Sets the height of this [PdfPageAnnotation] to the given value.
893    ///
894    /// To set the position, the width, and the height of the annotation in a single operation,
895    /// use the [PdfPageAnnotationCommon::set_bounds()] function.
896    fn set_height(&mut self, width: PdfPoints) -> Result<(), PdfiumError>;
897
898    /// Returns the text to be displayed for this [PdfPageAnnotation], or, if this type of annotation
899    /// does not display text, an alternate description of the annotation's contents in human-readable
900    /// form. In either case this text is useful when extracting the document's contents in support
901    /// of accessibility to users with disabilities or for other purposes.
902    fn contents(&self) -> Option<String>;
903
904    /// Sets the text to be displayed for this [PdfPageAnnotation], or, if this type of annotation
905    /// does not display text, an alternate description of the annotation's contents in human-readable
906    /// form for providing accessibility to users with disabilities or for other purposes.
907    fn set_contents(&mut self, contents: &str) -> Result<(), PdfiumError>;
908
909    /// Returns the name of the creator of this [PdfPageAnnotation], if any.
910    fn creator(&self) -> Option<String>;
911
912    /// Sets the name of the creator of this [PdfPageAnnotation].
913    fn set_creator(&mut self, creator: &str) -> Result<(), PdfiumError>;
914
915    /// Returns the date and time when this [PdfPageAnnotation] was originally created, if any.
916    fn creation_date(&self) -> Option<String>;
917
918    /// Sets the date and time when this [PdfPageAnnotation] was originally created.
919    fn set_creation_date(&mut self, date: DateTime<Utc>) -> Result<(), PdfiumError>;
920
921    /// Returns the date and time when this [PdfPageAnnotation] was last modified, if any.
922    fn modification_date(&self) -> Option<String>;
923
924    /// Sets the date and time when this [PdfPageAnnotation] was last modified.
925    fn set_modification_date(&mut self, date: DateTime<Utc>) -> Result<(), PdfiumError>;
926
927    /// Returns the color of any filled paths in this [PdfPageAnnotation].
928    fn fill_color(&self) -> Result<PdfColor, PdfiumError>;
929
930    /// Sets the color of any filled paths in this [PdfPageAnnotation].
931    fn set_fill_color(&mut self, fill_color: PdfColor) -> Result<(), PdfiumError>;
932
933    /// Returns the color of any stroked paths in this [PdfPageAnnotation].
934    fn stroke_color(&self) -> Result<PdfColor, PdfiumError>;
935
936    /// Sets the color of any stroked paths in this [PdfPageAnnotation].
937    fn set_stroke_color(&mut self, stroke_color: PdfColor) -> Result<(), PdfiumError>;
938
939    /// Returns `true` if this [PdfPageAnnotation] should not be displayed to the user
940    /// if it does not belong to one of the standard annotation types and no annotation
941    /// handler is available that supports it.
942    fn is_invisible_if_unsupported(&self) -> bool;
943
944    /// Controls whether or not this [PdfPageAnnotation] should be displayed to the user
945    /// if it does not belong to one of the standard annotation types and no annotation
946    /// handler is available that supports it.
947    fn set_is_invisible_if_unsupported(&mut self, is_invisible: bool) -> Result<(), PdfiumError>;
948
949    /// Returns `true` if this [PdfPageAnnotation] should not be displayed or printed,
950    /// nor allowed to interact with the user, regardless of its annotation type or whether
951    /// an annotation handler is available that supports it.
952    ///
953    /// This flag was added in PDF version 1.2.
954    fn is_hidden(&self) -> bool;
955
956    /// Controls whether or not this [PdfPageAnnotation] should be displayed, printed,
957    /// and allowed to interact with the user, regardless of its annotation type or whether
958    /// an annotation handler is available that supports it.
959    ///
960    /// This flag was added in PDF version 1.2.
961    fn set_is_hidden(&mut self, is_hidden: bool) -> Result<(), PdfiumError>;
962
963    /// Returns `true` if this [PdfPageAnnotation] should be printed when the
964    /// page is printed.
965    ///
966    /// This can be useful, for example, for annotations representing interactive
967    /// push buttons, which would serve no meaningful purpose on the printed page.
968    ///
969    /// This flag was added in PDF version 1.2.
970    fn is_printed(&self) -> bool;
971
972    /// Controls whether or not this [PdfPageAnnotation] should be printed when the
973    /// page is printed.
974    ///
975    /// This can be useful, for example, for annotations representing interactive
976    /// push buttons, which would serve no meaningful purpose on the printed page.
977    ///
978    /// This flag was added in PDF version 1.2.
979    fn set_is_printed(&mut self, is_printed: bool) -> Result<(), PdfiumError>;
980
981    /// Returns `true` if the appearance of this [PdfPageAnnotation] should scale to match
982    /// the magnification of the page. If `false`, the location of the annotation on the
983    /// page (defined by the upper-left corner of its annotation rectangle) will remain fixed,
984    /// regardless of the page magnification.
985    ///
986    /// This flag was added in PDF version 1.3.
987    fn is_zoomable(&self) -> bool;
988
989    /// Controls whether or not the appearance of this [PdfPageAnnotation] should scale to
990    /// match the magnification of the page.
991    ///
992    /// This flag was added in PDF version 1.3.
993    fn set_is_zoomable(&mut self, is_zoomable: bool) -> Result<(), PdfiumError>;
994
995    /// Returns `true` if the appearance of this [PdfPageAnnotation] should rotate to match
996    /// the rotation of the page. If `false`, the upper-left corner of the annotation rectangle
997    /// will remain in a fixed location on the page, regardless of the page rotation.
998    ///
999    /// This flag was added in PDF version 1.3.
1000    fn is_rotatable(&self) -> bool;
1001
1002    /// Controls whether or not the appearance of this [PdfPageAnnotation] should rotate
1003    /// to match the rotation of the page.
1004    ///
1005    /// This flag was added in PDF version 1.3.
1006    fn set_is_rotatable(&mut self, is_rotatable: bool) -> Result<(), PdfiumError>;
1007
1008    /// Returns `true` if this [PdfPageAnnotation] should not be displayed to, or allowed to
1009    /// interact with, the user. The annotation may be printed (depending on the setting of
1010    /// the [PdfPageAnnotationCommon::is_printed()] flag) but should be considered
1011    /// hidden for purposes of on-screen display and user interaction.
1012    ///
1013    /// This flag was added in PDF version 1.3.
1014    fn is_printable_but_not_viewable(&self) -> bool;
1015
1016    /// Controls whether or not this [PdfPageAnnotation] should be displayed to, and allowed
1017    /// to interact with, the user. Whether or not the annotation should be printed is
1018    /// controlled separately by the [PdfPageAnnotationCommon::set_is_printed()] function.
1019    ///
1020    /// This flag was added in PDF version 1.3.
1021    fn set_is_printable_but_not_viewable(
1022        &mut self,
1023        is_printable_but_not_viewable: bool,
1024    ) -> Result<(), PdfiumError>;
1025
1026    /// Returns `true` if this [PdfPageAnnotation] should not be allowed to interact
1027    /// with the user. The annotation may be displayed or printed (depending on the settings
1028    /// of the [PdfPageAnnotationCommon::is_printed()] and [PdfPageAnnotationCommon::is_printable_but_not_viewable()]
1029    /// flags) but should not respond to mouse clicks or change its appearance
1030    /// in response to mouse motions.
1031    ///
1032    /// This flag is ignored for widget annotations; its function is subsumed by
1033    /// the [PdfFormFieldCommon::is_read_only()] flag of the associated form field.
1034    ///
1035    /// THis flag was added in PDF version 1.3.
1036    fn is_read_only(&self) -> bool;
1037
1038    /// Controls whether or not this [PdfPageAnnotation] should be allowed to interact
1039    /// with the user.
1040    ///
1041    /// This flag is ignored for widget annotations; its function is subsumed by
1042    /// the [PdfFormFieldCommon::is_read_only()] flag of the associated form field.
1043    ///
1044    /// THis flag was added in PDF version 1.3.
1045    fn set_is_read_only(&mut self, is_read_only: bool) -> Result<(), PdfiumError>;
1046
1047    /// Returns `true` if this [PdfPageAnnotation] is locked. Locked annotations cannot be
1048    /// deleted, repositioned, or resized by the user. The content of a locked annotation
1049    /// may still be editable, depending on the setting of the [PdfPageAnnotationCommon::is_editable()]
1050    /// flag.
1051    fn is_locked(&self) -> bool;
1052
1053    /// Controls whether or not this [PdfPageAnnotation] is locked. Locked annotations cannot be
1054    /// deleted, repositioned, or resized by the user. The content of a locked annotation
1055    /// may still be editable, depending on the setting of the [PdfPageAnnotationCommon::set_is_editable()]
1056    /// function.
1057    fn set_is_locked(&mut self, is_locked: bool) -> Result<(), PdfiumError>;
1058
1059    /// Returns `true` if the contents of this [PdfPageAnnotation] can be edited by the user.
1060    /// This setting does not control whether or not the annotation can be deleted,
1061    /// repositioned, or resized; those properties are controlled by the
1062    /// [PdfPageAnnotationCommon::is_locked()] flag.
1063    fn is_editable(&self) -> bool;
1064
1065    /// Controls whether or not the contents of this [PdfPageAnnotation] can be edited by the user.
1066    /// This setting does not control whether or not the annotation can be deleted,
1067    /// repositioned, or resized; those properties are controlled by the
1068    /// [PdfPageAnnotationCommon::set_is_locked()] function.
1069    fn set_is_editable(&mut self, is_editable: bool) -> Result<(), PdfiumError>;
1070
1071    /// Returns an immutable collection of all the page objects in this [PdfPageAnnotation].
1072    ///
1073    /// Page objects can be retrieved from any type of [PdfPageAnnotation], but Pdfium currently
1074    /// only permits adding new page objects to, or removing existing page objects from, annotations
1075    /// of types [PdfPageAnnotationType::Ink] and [PdfPageAnnotationType::Stamp]. All other annotation
1076    /// types are read-only.
1077    ///
1078    /// To gain access to the mutable collection of page objects inside an ink or stamp annotation,
1079    /// you must first unwrap the annotation, like so:
1080    /// ```
1081    /// annotation.as_stamp_annotation_mut().unwrap().objects_mut();
1082    /// ```
1083    fn objects(&self) -> &PdfPageAnnotationObjects<'_>;
1084
1085    /// Returns an immutable collection of the attachment points that visually associate
1086    /// this [PdfPageAnnotation] with one or more `PdfPageObject` objects on this `PdfPage`.
1087    ///
1088    /// This collection is provided for all annotation types, but it will always be empty
1089    /// if the annotation does not support attachment points. Pdfium supports attachment points
1090    /// for all markup annotations and the Link annotation, but not for any other annotation type.
1091    /// The [PdfPageAnnotationCommon::has_attachment_points()] function will return `true`
1092    /// if the annotation supports attachment points.
1093    ///
1094    /// To gain access to the mutable collection of attachment points inside a supported
1095    /// annotation, you must first unwrap the annotation, like so:
1096    /// ```
1097    /// annotation.as_link_annotation_mut().unwrap().attachment_points_mut();
1098    /// ```
1099    fn attachment_points(&self) -> &PdfPageAnnotationAttachmentPoints<'_>;
1100}
1101
1102// Blanket implementation for all PdfPageAnnotation types.
1103
1104impl<'a, T> PdfPageAnnotationCommon for T
1105where
1106    T: PdfPageAnnotationPrivate<'a>,
1107{
1108    #[inline]
1109    fn name(&self) -> Option<String> {
1110        self.name_impl()
1111    }
1112
1113    #[inline]
1114    fn is_markup_annotation(&self) -> bool {
1115        self.is_markup_annotation_impl()
1116    }
1117
1118    #[inline]
1119    fn has_attachment_points(&self) -> bool {
1120        self.has_attachment_points_impl()
1121    }
1122
1123    #[inline]
1124    fn bounds(&self) -> Result<PdfRect, PdfiumError> {
1125        self.bounds_impl()
1126    }
1127
1128    #[inline]
1129    fn set_bounds(&mut self, bounds: PdfRect) -> Result<(), PdfiumError> {
1130        self.set_bounds_impl(bounds)
1131    }
1132
1133    #[inline]
1134    fn set_position(&mut self, x: PdfPoints, y: PdfPoints) -> Result<(), PdfiumError> {
1135        self.set_position_impl(x, y)
1136    }
1137
1138    #[inline]
1139    fn set_width(&mut self, width: PdfPoints) -> Result<(), PdfiumError> {
1140        self.set_width_impl(width)
1141    }
1142
1143    #[inline]
1144    fn set_height(&mut self, height: PdfPoints) -> Result<(), PdfiumError> {
1145        self.set_height_impl(height)
1146    }
1147
1148    #[inline]
1149    fn contents(&self) -> Option<String> {
1150        self.contents_impl()
1151    }
1152
1153    #[inline]
1154    fn set_contents(&mut self, contents: &str) -> Result<(), PdfiumError> {
1155        self.set_contents_impl(contents)
1156    }
1157
1158    #[inline]
1159    fn creator(&self) -> Option<String> {
1160        self.creator_impl()
1161    }
1162
1163    #[inline]
1164    fn set_creator(&mut self, creator: &str) -> Result<(), PdfiumError> {
1165        self.set_creator_impl(creator)
1166    }
1167
1168    #[inline]
1169    fn creation_date(&self) -> Option<String> {
1170        self.creation_date_impl()
1171    }
1172
1173    #[inline]
1174    fn set_creation_date(&mut self, date: DateTime<Utc>) -> Result<(), PdfiumError> {
1175        self.set_creation_date_impl(date)
1176    }
1177
1178    #[inline]
1179    fn modification_date(&self) -> Option<String> {
1180        self.modification_date_impl()
1181    }
1182
1183    #[inline]
1184    fn set_modification_date(&mut self, date: DateTime<Utc>) -> Result<(), PdfiumError> {
1185        self.set_modification_date_impl(date)
1186    }
1187
1188    #[inline]
1189    fn fill_color(&self) -> Result<PdfColor, PdfiumError> {
1190        self.fill_color_impl()
1191    }
1192
1193    #[inline]
1194    fn set_fill_color(&mut self, fill_color: PdfColor) -> Result<(), PdfiumError> {
1195        self.set_fill_color_impl(fill_color)
1196    }
1197
1198    #[inline]
1199    fn stroke_color(&self) -> Result<PdfColor, PdfiumError> {
1200        self.stroke_color_impl()
1201    }
1202
1203    #[inline]
1204    fn set_stroke_color(&mut self, stroke_color: PdfColor) -> Result<(), PdfiumError> {
1205        self.set_stroke_color_impl(stroke_color)
1206    }
1207
1208    #[inline]
1209    fn objects(&self) -> &PdfPageAnnotationObjects<'_> {
1210        self.objects_impl()
1211    }
1212
1213    #[inline]
1214    fn attachment_points(&self) -> &PdfPageAnnotationAttachmentPoints<'_> {
1215        self.attachment_points_impl()
1216    }
1217
1218    #[inline]
1219    fn is_invisible_if_unsupported(&self) -> bool {
1220        self.get_flags_impl()
1221            .contains(PdfAnnotationFlags::Invisible)
1222    }
1223
1224    #[inline]
1225    fn set_is_invisible_if_unsupported(&mut self, is_invisible: bool) -> Result<(), PdfiumError> {
1226        self.update_one_flag_impl(PdfAnnotationFlags::Invisible, is_invisible)
1227    }
1228
1229    #[inline]
1230    fn is_hidden(&self) -> bool {
1231        self.get_flags_impl().contains(PdfAnnotationFlags::Hidden)
1232    }
1233
1234    #[inline]
1235    fn set_is_hidden(&mut self, is_hidden: bool) -> Result<(), PdfiumError> {
1236        self.update_one_flag_impl(PdfAnnotationFlags::Hidden, is_hidden)
1237    }
1238
1239    #[inline]
1240    fn is_printed(&self) -> bool {
1241        self.get_flags_impl().contains(PdfAnnotationFlags::Print)
1242    }
1243
1244    #[inline]
1245    fn set_is_printed(&mut self, is_printed: bool) -> Result<(), PdfiumError> {
1246        self.update_one_flag_impl(PdfAnnotationFlags::Print, is_printed)
1247    }
1248
1249    #[inline]
1250    fn is_zoomable(&self) -> bool {
1251        !self.get_flags_impl().contains(PdfAnnotationFlags::NoZoom)
1252    }
1253
1254    #[inline]
1255    fn set_is_zoomable(&mut self, is_zoomable: bool) -> Result<(), PdfiumError> {
1256        self.update_one_flag_impl(PdfAnnotationFlags::NoZoom, !is_zoomable)
1257    }
1258
1259    #[inline]
1260    fn is_rotatable(&self) -> bool {
1261        !self.get_flags_impl().contains(PdfAnnotationFlags::NoRotate)
1262    }
1263
1264    #[inline]
1265    fn set_is_rotatable(&mut self, is_rotatable: bool) -> Result<(), PdfiumError> {
1266        self.update_one_flag_impl(PdfAnnotationFlags::NoRotate, !is_rotatable)
1267    }
1268
1269    #[inline]
1270    fn is_printable_but_not_viewable(&self) -> bool {
1271        self.get_flags_impl().contains(PdfAnnotationFlags::NoView)
1272    }
1273
1274    #[inline]
1275    fn set_is_printable_but_not_viewable(
1276        &mut self,
1277        is_printable_but_not_viewable: bool,
1278    ) -> Result<(), PdfiumError> {
1279        self.update_one_flag_impl(PdfAnnotationFlags::NoView, is_printable_but_not_viewable)
1280    }
1281
1282    #[inline]
1283    fn is_read_only(&self) -> bool {
1284        self.get_flags_impl().contains(PdfAnnotationFlags::ReadOnly)
1285    }
1286
1287    #[inline]
1288    fn set_is_read_only(&mut self, is_read_only: bool) -> Result<(), PdfiumError> {
1289        self.update_one_flag_impl(PdfAnnotationFlags::ReadOnly, is_read_only)
1290    }
1291
1292    #[inline]
1293    fn is_locked(&self) -> bool {
1294        self.get_flags_impl().contains(PdfAnnotationFlags::Locked)
1295    }
1296
1297    #[inline]
1298    fn set_is_locked(&mut self, is_locked: bool) -> Result<(), PdfiumError> {
1299        self.update_one_flag_impl(PdfAnnotationFlags::Locked, is_locked)
1300    }
1301
1302    #[inline]
1303    fn is_editable(&self) -> bool {
1304        !self
1305            .get_flags_impl()
1306            .contains(PdfAnnotationFlags::LockedContents)
1307    }
1308
1309    #[inline]
1310    fn set_is_editable(&mut self, is_editable: bool) -> Result<(), PdfiumError> {
1311        self.update_one_flag_impl(PdfAnnotationFlags::LockedContents, !is_editable)
1312    }
1313}
1314
1315impl<'a> PdfPageAnnotationPrivate<'a> for PdfPageAnnotation<'a> {
1316    #[inline]
1317    fn handle(&self) -> FPDF_ANNOTATION {
1318        self.unwrap_as_trait().handle()
1319    }
1320
1321    #[inline]
1322    fn ownership(&self) -> &PdfPageObjectOwnership {
1323        self.unwrap_as_trait().ownership()
1324    }
1325
1326    #[inline]
1327    fn objects_impl(&self) -> &PdfPageAnnotationObjects<'_> {
1328        self.unwrap_as_trait().objects_impl()
1329    }
1330
1331    #[inline]
1332    fn attachment_points_impl(&self) -> &PdfPageAnnotationAttachmentPoints<'_> {
1333        self.unwrap_as_trait().attachment_points_impl()
1334    }
1335}
1336
1337impl<'a> Drop for PdfPageAnnotation<'a> {
1338    /// Closes this [PdfPageAnnotation], releasing held memory.
1339    #[inline]
1340    fn drop(&mut self) {
1341        unsafe {
1342            self.bindings().FPDFPage_CloseAnnot(self.handle());
1343        }
1344    }
1345}
1346
1347impl<'a> PdfiumLibraryBindingsAccessor<'a> for PdfPageAnnotation<'a> {}
1348
1349#[cfg(feature = "thread_safe")]
1350unsafe impl<'a> Send for PdfPageAnnotation<'a> {}
1351
1352#[cfg(feature = "thread_safe")]
1353unsafe impl<'a> Sync for PdfPageAnnotation<'a> {}