Skip to main content

pdfium_render/pdf/document/page/annotation/
common.rs

1//! Defines the [PdfPageAnnotationCommon] trait, exposing functionality common to all
2//! [PdfPageAnnotation] objects, regardless of their [PdfPageAnnotationType].
3
4use crate::error::PdfiumError;
5use crate::pdf::color::PdfColor;
6use crate::pdf::document::page::annotation::attachment_points::PdfPageAnnotationAttachmentPoints;
7use crate::pdf::document::page::annotation::objects::PdfPageAnnotationObjects;
8use crate::pdf::document::page::annotation::private::internal::{PdfAnnotationFlags, PdfPageAnnotationPrivateStyle};
9use crate::pdf::points::PdfPoints;
10use crate::pdf::rect::PdfRect;
11use chrono::prelude::*;
12
13#[cfg(doc)]
14use crate::pdf::document::page::PdfPage;
15#[cfg(doc)]
16use crate::pdf::document::page::annotation::{PdfPageAnnotation, PdfPageAnnotationType};
17
18pub trait PdfPageAnnotationCommon {
19    /// Returns the name of this [PdfPageAnnotation], if any. This is a text string uniquely identifying
20    /// this annotation among all the annotations attached to the containing page.
21    fn name(&self) -> Option<String>;
22
23    /// Returns `true` if this [PdfPageAnnotation] supports applying text markup to the page
24    /// by setting the annotation contents using the [PdfPageAnnotationCommon::set_contents()]
25    /// function.
26    fn is_markup_annotation(&self) -> bool;
27
28    /// Returns `true` if this [PdfPageAnnotation] supports setting attachment points that
29    /// visually associate it with a `PdfPageObject`.
30    fn has_attachment_points(&self) -> bool;
31
32    /// Returns the bounding box of this [PdfPageAnnotation].
33    fn bounds(&self) -> Result<PdfRect, PdfiumError>;
34
35    /// Sets the bounding box of this [PdfPageAnnotation].
36    ///
37    /// This sets the position, the width, and the height of the annotation in a single operation.
38    /// To set these properties separately, use the [PdfPageAnnotationCommon::set_position()],
39    /// [PdfPageAnnotationCommon::set_width()], and [PdfPageAnnotationCommon::set_height()] functions.
40    fn set_bounds(&mut self, bounds: PdfRect) -> Result<(), PdfiumError>;
41
42    /// Sets the bottom right corner of this [PdfPageAnnotation] to the given values.
43    ///
44    /// To set the position, the width, and the height of the annotation in a single operation,
45    /// use the [PdfPageAnnotationCommon::set_bounds()] function.
46    fn set_position(&mut self, x: PdfPoints, y: PdfPoints) -> Result<(), PdfiumError>;
47
48    /// Sets the width of this [PdfPageAnnotation] to the given value.
49    ///
50    /// To set the position, the width, and the height of the annotation in a single operation,
51    /// use the [PdfPageAnnotationCommon::set_bounds()] function.
52    fn set_width(&mut self, width: PdfPoints) -> Result<(), PdfiumError>;
53
54    /// Sets the height of this [PdfPageAnnotation] to the given value.
55    ///
56    /// To set the position, the width, and the height of the annotation in a single operation,
57    /// use the [PdfPageAnnotationCommon::set_bounds()] function.
58    fn set_height(&mut self, width: PdfPoints) -> Result<(), PdfiumError>;
59
60    /// Returns the text to be displayed for this [PdfPageAnnotation], or, if this type of annotation
61    /// does not display text, an alternate description of the annotation's contents in human-readable
62    /// form. In either case this text is useful when extracting the document's contents in support
63    /// of accessibility to users with disabilities or for other purposes.
64    fn contents(&self) -> Option<String>;
65
66    /// Sets the text to be displayed for this [PdfPageAnnotation], or, if this type of annotation
67    /// does not display text, an alternate description of the annotation's contents in human-readable
68    /// form for providing accessibility to users with disabilities or for other purposes.
69    fn set_contents(&mut self, contents: &str) -> Result<(), PdfiumError>;
70
71    /// Returns the name of the creator of this [PdfPageAnnotation], if any.
72    fn creator(&self) -> Option<String>;
73
74    /// Sets the name of the creator of this [PdfPageAnnotation].
75    fn set_creator(&mut self, creator: &str) -> Result<(), PdfiumError>;
76
77    /// Returns the date and time when this [PdfPageAnnotation] was originally created, if any.
78    fn creation_date(&self) -> Option<String>;
79
80    /// Sets the date and time when this [PdfPageAnnotation] was originally created.
81    fn set_creation_date(&mut self, date: DateTime<Utc>) -> Result<(), PdfiumError>;
82
83    /// Returns the date and time when this [PdfPageAnnotation] was last modified, if any.
84    fn modification_date(&self) -> Option<String>;
85
86    /// Sets the date and time when this [PdfPageAnnotation] was last modified.
87    fn set_modification_date(&mut self, date: DateTime<Utc>) -> Result<(), PdfiumError>;
88
89    /// Returns the color of any filled paths in this [PdfPageAnnotation].
90    fn fill_color(&self) -> Result<PdfColor, PdfiumError>;
91
92    /// Sets the color of any filled paths in this [PdfPageAnnotation].
93    fn set_fill_color(&mut self, fill_color: PdfColor) -> Result<(), PdfiumError>;
94
95    /// Returns the color of any stroked paths in this [PdfPageAnnotation].
96    fn stroke_color(&self) -> Result<PdfColor, PdfiumError>;
97
98    /// Sets the color of any stroked paths in this [PdfPageAnnotation].
99    fn set_stroke_color(&mut self, stroke_color: PdfColor) -> Result<(), PdfiumError>;
100
101    /// Returns `true` if this [PdfPageAnnotation] should not be displayed to the user
102    /// if it does not belong to one of the standard annotation types and no annotation
103    /// handler is available that supports it.
104    fn is_invisible_if_unsupported(&self) -> bool;
105
106    /// Controls whether or not this [PdfPageAnnotation] should be displayed to the user
107    /// if it does not belong to one of the standard annotation types and no annotation
108    /// handler is available that supports it.
109    fn set_is_invisible_if_unsupported(&mut self, is_invisible: bool) -> Result<(), PdfiumError>;
110
111    /// Returns `true` if this [PdfPageAnnotation] should not be displayed or printed,
112    /// nor allowed to interact with the user, regardless of its annotation type or whether
113    /// an annotation handler is available that supports it.
114    ///
115    /// This flag was added in PDF version 1.2.
116    fn is_hidden(&self) -> bool;
117
118    /// Controls whether or not this [PdfPageAnnotation] should be displayed, printed,
119    /// and allowed to interact with the user, regardless of its annotation type or whether
120    /// an annotation handler is available that supports it.
121    ///
122    /// This flag was added in PDF version 1.2.
123    fn set_is_hidden(&mut self, is_hidden: bool) -> Result<(), PdfiumError>;
124
125    /// Returns `true` if this [PdfPageAnnotation] should be printed when the
126    /// page is printed.
127    ///
128    /// This can be useful, for example, for annotations representing interactive
129    /// push buttons, which would serve no meaningful purpose on the printed page.
130    ///
131    /// This flag was added in PDF version 1.2.
132    fn is_printed(&self) -> bool;
133
134    /// Controls whether or not this [PdfPageAnnotation] should be printed when the
135    /// page is printed.
136    ///
137    /// This can be useful, for example, for annotations representing interactive
138    /// push buttons, which would serve no meaningful purpose on the printed page.
139    ///
140    /// This flag was added in PDF version 1.2.
141    fn set_is_printed(&mut self, is_printed: bool) -> Result<(), PdfiumError>;
142
143    /// Returns `true` if the appearance of this [PdfPageAnnotation] should scale to match
144    /// the magnification of the page. If `false`, the location of the annotation on the
145    /// page (defined by the upper-left corner of its annotation rectangle) will remain fixed,
146    /// regardless of the page magnification.
147    ///
148    /// This flag was added in PDF version 1.3.
149    fn is_zoomable(&self) -> bool;
150
151    /// Controls whether or not the appearance of this [PdfPageAnnotation] should scale to
152    /// match the magnification of the page.
153    ///
154    /// This flag was added in PDF version 1.3.
155    fn set_is_zoomable(&mut self, is_zoomable: bool) -> Result<(), PdfiumError>;
156
157    /// Returns `true` if the appearance of this [PdfPageAnnotation] should rotate to match
158    /// the rotation of the page. If `false`, the upper-left corner of the annotation rectangle
159    /// will remain in a fixed location on the page, regardless of the page rotation.
160    ///
161    /// This flag was added in PDF version 1.3.
162    fn is_rotatable(&self) -> bool;
163
164    /// Controls whether or not the appearance of this [PdfPageAnnotation] should rotate
165    /// to match the rotation of the page.
166    ///
167    /// This flag was added in PDF version 1.3.
168    fn set_is_rotatable(&mut self, is_rotatable: bool) -> Result<(), PdfiumError>;
169
170    /// Returns `true` if this [PdfPageAnnotation] should not be displayed to, or allowed to
171    /// interact with, the user. The annotation may be printed (depending on the setting of
172    /// the [PdfPageAnnotationCommon::is_printed()] flag) but should be considered
173    /// hidden for purposes of on-screen display and user interaction.
174    ///
175    /// This flag was added in PDF version 1.3.
176    fn is_printable_but_not_viewable(&self) -> bool;
177
178    /// Controls whether or not this [PdfPageAnnotation] should be displayed to, and allowed
179    /// to interact with, the user. Whether or not the annotation should be printed is
180    /// controlled separately by the [PdfPageAnnotationCommon::set_is_printed()] function.
181    ///
182    /// This flag was added in PDF version 1.3.
183    fn set_is_printable_but_not_viewable(&mut self, is_printable_but_not_viewable: bool) -> Result<(), PdfiumError>;
184
185    /// Returns `true` if this [PdfPageAnnotation] should not be allowed to interact
186    /// with the user. The annotation may be displayed or printed (depending on the settings
187    /// of the [PdfPageAnnotationCommon::is_printed()] and [PdfPageAnnotationCommon::is_printable_but_not_viewable()]
188    /// flags) but should not respond to mouse clicks or change its appearance
189    /// in response to mouse motions.
190    ///
191    /// This flag is ignored for widget annotations; its function is subsumed by
192    /// the [PdfFormFieldCommon::is_read_only()] flag of the associated form field.
193    ///
194    /// THis flag was added in PDF version 1.3.
195    fn is_read_only(&self) -> bool;
196
197    /// Controls whether or not this [PdfPageAnnotation] should be allowed to interact
198    /// with the user.
199    ///
200    /// This flag is ignored for widget annotations; its function is subsumed by
201    /// the [PdfFormFieldCommon::is_read_only()] flag of the associated form field.
202    ///
203    /// THis flag was added in PDF version 1.3.
204    fn set_is_read_only(&mut self, is_read_only: bool) -> Result<(), PdfiumError>;
205
206    /// Returns `true` if this [PdfPageAnnotation] is locked. Locked annotations cannot be
207    /// deleted, repositioned, or resized by the user. The content of a locked annotation
208    /// may still be editable, depending on the setting of the [PdfPageAnnotationCommon::is_editable()]
209    /// flag.
210    fn is_locked(&self) -> bool;
211
212    /// Controls whether or not this [PdfPageAnnotation] is locked. Locked annotations cannot be
213    /// deleted, repositioned, or resized by the user. The content of a locked annotation
214    /// may still be editable, depending on the setting of the [PdfPageAnnotationCommon::set_is_editable()]
215    /// function.
216    fn set_is_locked(&mut self, is_locked: bool) -> Result<(), PdfiumError>;
217
218    /// Returns `true` if the contents of this [PdfPageAnnotation] can be edited by the user.
219    /// This setting does not control whether or not the annotation can be deleted,
220    /// repositioned, or resized; those properties are controlled by the
221    /// [PdfPageAnnotationCommon::is_locked()] flag.
222    fn is_editable(&self) -> bool;
223
224    /// Controls whether or not the contents of this [PdfPageAnnotation] can be edited by the user.
225    /// This setting does not control whether or not the annotation can be deleted,
226    /// repositioned, or resized; those properties are controlled by the
227    /// [PdfPageAnnotationCommon::set_is_locked()] function.
228    fn set_is_editable(&mut self, is_editable: bool) -> Result<(), PdfiumError>;
229
230    /// Returns an immutable collection of all the page objects in this [PdfPageAnnotation].
231    ///
232    /// Page objects can be retrieved from any type of [PdfPageAnnotation], but Pdfium currently
233    /// only permits adding new page objects to, or removing existing page objects from, annotations
234    /// of types [PdfPageAnnotationType::Ink] and [PdfPageAnnotationType::Stamp]. All other annotation
235    /// types are read-only.
236    ///
237    /// To gain access to the mutable collection of page objects inside an ink or stamp annotation,
238    /// you must first unwrap the annotation, like so:
239    /// ```
240    /// annotation.as_stamp_annotation_mut().unwrap().objects_mut();
241    /// ```
242    fn objects(&self) -> &PdfPageAnnotationObjects<'_>;
243
244    /// Returns an immutable collection of the attachment points that visually associate
245    /// this [PdfPageAnnotation] with one or more `PdfPageObject` objects on this `PdfPage`.
246    ///
247    /// This collection is provided for all annotation types, but it will always be empty
248    /// if the annotation does not support attachment points. Pdfium supports attachment points
249    /// for all markup annotations and the Link annotation, but not for any other annotation type.
250    /// The [PdfPageAnnotationCommon::has_attachment_points()] function will return `true`
251    /// if the annotation supports attachment points.
252    ///
253    /// To gain access to the mutable collection of attachment points inside a supported
254    /// annotation, you must first unwrap the annotation, like so:
255    /// ```
256    /// annotation.as_link_annotation_mut().unwrap().attachment_points_mut();
257    /// ```
258    fn attachment_points(&self) -> &PdfPageAnnotationAttachmentPoints<'_>;
259}
260
261impl<'a, T> PdfPageAnnotationCommon for T
262where
263    T: PdfPageAnnotationPrivateStyle<'a>,
264{
265    #[inline]
266    fn name(&self) -> Option<String> {
267        self.name_impl()
268    }
269
270    #[inline]
271    fn is_markup_annotation(&self) -> bool {
272        self.is_markup_annotation_impl()
273    }
274
275    #[inline]
276    fn has_attachment_points(&self) -> bool {
277        self.has_attachment_points_impl()
278    }
279
280    #[inline]
281    fn bounds(&self) -> Result<PdfRect, PdfiumError> {
282        self.bounds_impl()
283    }
284
285    #[inline]
286    fn set_bounds(&mut self, bounds: PdfRect) -> Result<(), PdfiumError> {
287        self.set_bounds_impl(bounds)
288    }
289
290    #[inline]
291    fn set_position(&mut self, x: PdfPoints, y: PdfPoints) -> Result<(), PdfiumError> {
292        self.set_position_impl(x, y)
293    }
294
295    #[inline]
296    fn set_width(&mut self, width: PdfPoints) -> Result<(), PdfiumError> {
297        self.set_width_impl(width)
298    }
299
300    #[inline]
301    fn set_height(&mut self, height: PdfPoints) -> Result<(), PdfiumError> {
302        self.set_height_impl(height)
303    }
304
305    #[inline]
306    fn contents(&self) -> Option<String> {
307        self.contents_impl()
308    }
309
310    #[inline]
311    fn set_contents(&mut self, contents: &str) -> Result<(), PdfiumError> {
312        self.set_contents_impl(contents)
313    }
314
315    #[inline]
316    fn creator(&self) -> Option<String> {
317        self.creator_impl()
318    }
319
320    #[inline]
321    fn set_creator(&mut self, creator: &str) -> Result<(), PdfiumError> {
322        self.set_creator_impl(creator)
323    }
324
325    #[inline]
326    fn creation_date(&self) -> Option<String> {
327        self.creation_date_impl()
328    }
329
330    #[inline]
331    fn set_creation_date(&mut self, date: DateTime<Utc>) -> Result<(), PdfiumError> {
332        self.set_creation_date_impl(date)
333    }
334
335    #[inline]
336    fn modification_date(&self) -> Option<String> {
337        self.modification_date_impl()
338    }
339
340    #[inline]
341    fn set_modification_date(&mut self, date: DateTime<Utc>) -> Result<(), PdfiumError> {
342        self.set_modification_date_impl(date)
343    }
344
345    #[inline]
346    fn fill_color(&self) -> Result<PdfColor, PdfiumError> {
347        self.fill_color_impl()
348    }
349
350    #[inline]
351    fn set_fill_color(&mut self, fill_color: PdfColor) -> Result<(), PdfiumError> {
352        self.set_fill_color_impl(fill_color)
353    }
354
355    #[inline]
356    fn stroke_color(&self) -> Result<PdfColor, PdfiumError> {
357        self.stroke_color_impl()
358    }
359
360    #[inline]
361    fn set_stroke_color(&mut self, stroke_color: PdfColor) -> Result<(), PdfiumError> {
362        self.set_stroke_color_impl(stroke_color)
363    }
364
365    #[inline]
366    fn objects(&self) -> &PdfPageAnnotationObjects<'_> {
367        self.objects_impl()
368    }
369
370    #[inline]
371    fn attachment_points(&self) -> &PdfPageAnnotationAttachmentPoints<'_> {
372        self.attachment_points_impl()
373    }
374
375    #[inline]
376    fn is_invisible_if_unsupported(&self) -> bool {
377        self.get_flags_impl().contains(PdfAnnotationFlags::Invisible)
378    }
379
380    #[inline]
381    fn set_is_invisible_if_unsupported(&mut self, is_invisible: bool) -> Result<(), PdfiumError> {
382        self.update_one_flag_impl(PdfAnnotationFlags::Invisible, is_invisible)
383    }
384
385    #[inline]
386    fn is_hidden(&self) -> bool {
387        self.get_flags_impl().contains(PdfAnnotationFlags::Hidden)
388    }
389
390    #[inline]
391    fn set_is_hidden(&mut self, is_hidden: bool) -> Result<(), PdfiumError> {
392        self.update_one_flag_impl(PdfAnnotationFlags::Hidden, is_hidden)
393    }
394
395    #[inline]
396    fn is_printed(&self) -> bool {
397        self.get_flags_impl().contains(PdfAnnotationFlags::Print)
398    }
399
400    #[inline]
401    fn set_is_printed(&mut self, is_printed: bool) -> Result<(), PdfiumError> {
402        self.update_one_flag_impl(PdfAnnotationFlags::Print, is_printed)
403    }
404
405    #[inline]
406    fn is_zoomable(&self) -> bool {
407        !self.get_flags_impl().contains(PdfAnnotationFlags::NoZoom)
408    }
409
410    #[inline]
411    fn set_is_zoomable(&mut self, is_zoomable: bool) -> Result<(), PdfiumError> {
412        self.update_one_flag_impl(PdfAnnotationFlags::NoZoom, !is_zoomable)
413    }
414
415    #[inline]
416    fn is_rotatable(&self) -> bool {
417        !self.get_flags_impl().contains(PdfAnnotationFlags::NoRotate)
418    }
419
420    #[inline]
421    fn set_is_rotatable(&mut self, is_rotatable: bool) -> Result<(), PdfiumError> {
422        self.update_one_flag_impl(PdfAnnotationFlags::NoRotate, !is_rotatable)
423    }
424
425    #[inline]
426    fn is_printable_but_not_viewable(&self) -> bool {
427        self.get_flags_impl().contains(PdfAnnotationFlags::NoView)
428    }
429
430    #[inline]
431    fn set_is_printable_but_not_viewable(&mut self, is_printable_but_not_viewable: bool) -> Result<(), PdfiumError> {
432        self.update_one_flag_impl(PdfAnnotationFlags::NoView, is_printable_but_not_viewable)
433    }
434
435    #[inline]
436    fn is_read_only(&self) -> bool {
437        self.get_flags_impl().contains(PdfAnnotationFlags::ReadOnly)
438    }
439
440    #[inline]
441    fn set_is_read_only(&mut self, is_read_only: bool) -> Result<(), PdfiumError> {
442        self.update_one_flag_impl(PdfAnnotationFlags::ReadOnly, is_read_only)
443    }
444
445    #[inline]
446    fn is_locked(&self) -> bool {
447        self.get_flags_impl().contains(PdfAnnotationFlags::Locked)
448    }
449
450    #[inline]
451    fn set_is_locked(&mut self, is_locked: bool) -> Result<(), PdfiumError> {
452        self.update_one_flag_impl(PdfAnnotationFlags::Locked, is_locked)
453    }
454
455    #[inline]
456    fn is_editable(&self) -> bool {
457        !self.get_flags_impl().contains(PdfAnnotationFlags::LockedContents)
458    }
459
460    #[inline]
461    fn set_is_editable(&mut self, is_editable: bool) -> Result<(), PdfiumError> {
462        self.update_one_flag_impl(PdfAnnotationFlags::LockedContents, !is_editable)
463    }
464}