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