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