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}