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

1//! Defines the [PdfPageLinkAnnotation] struct, exposing functionality related to a single
2//! user annotation of type [PdfPageAnnotationType::Link].
3
4use crate::bindgen::{FPDF_ANNOTATION, FPDF_DOCUMENT, FPDF_PAGE};
5use crate::bindings::PdfiumLibraryBindings;
6use crate::error::{PdfiumError, PdfiumInternalError};
7use crate::pdf::document::page::annotation::attachment_points::PdfPageAnnotationAttachmentPoints;
8use crate::pdf::document::page::annotation::objects::PdfPageAnnotationObjects;
9use crate::pdf::document::page::annotation::private::internal::PdfPageAnnotationPrivate;
10use crate::pdf::document::page::object::ownership::PdfPageObjectOwnership;
11use crate::pdf::document::page::objects::private::internal::PdfPageObjectsPrivate;
12use crate::pdf::link::PdfLink;
13
14#[cfg(doc)]
15use crate::pdf::document::page::annotation::{PdfPageAnnotation, PdfPageAnnotationType};
16
17/// A single [PdfPageAnnotation] of type [PdfPageAnnotationType::Link].
18pub struct PdfPageLinkAnnotation<'a> {
19    handle: FPDF_ANNOTATION,
20    objects: PdfPageAnnotationObjects<'a>,
21    attachment_points: PdfPageAnnotationAttachmentPoints<'a>,
22    bindings: &'a dyn PdfiumLibraryBindings,
23}
24
25impl<'a> PdfPageLinkAnnotation<'a> {
26    pub(crate) fn from_pdfium(
27        document_handle: FPDF_DOCUMENT,
28        page_handle: FPDF_PAGE,
29        annotation_handle: FPDF_ANNOTATION,
30        bindings: &'a dyn PdfiumLibraryBindings,
31    ) -> Self {
32        PdfPageLinkAnnotation {
33            handle: annotation_handle,
34            objects: PdfPageAnnotationObjects::from_pdfium(
35                document_handle,
36                page_handle,
37                annotation_handle,
38                bindings,
39            ),
40            attachment_points: PdfPageAnnotationAttachmentPoints::from_pdfium(
41                annotation_handle,
42                bindings,
43            ),
44            bindings,
45        }
46    }
47
48    /// Returns the [PdfLink] associated with this [PdfPageLinkAnnotation], if any.
49    pub fn link(&self) -> Result<PdfLink, PdfiumError> {
50        let handle = self.bindings.FPDFAnnot_GetLink(self.handle);
51
52        if handle.is_null() {
53            Err(PdfiumError::PdfiumLibraryInternalError(
54                PdfiumInternalError::Unknown,
55            ))
56        } else {
57            let document_handle = match self.objects.ownership() {
58                PdfPageObjectOwnership::Page(ownership) => Some(ownership.document_handle()),
59                PdfPageObjectOwnership::AttachedAnnotation(ownership) => {
60                    Some(ownership.document_handle())
61                }
62                PdfPageObjectOwnership::UnattachedAnnotation(ownership) => {
63                    Some(ownership.document_handle())
64                }
65                _ => None,
66            };
67
68            if let Some(document_handle) = document_handle {
69                Ok(PdfLink::from_pdfium(
70                    handle,
71                    document_handle,
72                    self.bindings(),
73                ))
74            } else {
75                Err(PdfiumError::OwnershipNotAttachedToDocument)
76            }
77        }
78    }
79
80    /// Sets the [PdfLink] associated with this [PdfPageLinkAnnotation] to the given URI.
81    pub fn set_link(&mut self, uri: &str) -> Result<(), PdfiumError> {
82        if self
83            .bindings()
84            .is_true(self.bindings().FPDFAnnot_SetURI(self.handle(), uri))
85        {
86            Ok(())
87        } else {
88            Err(PdfiumError::PdfiumLibraryInternalError(
89                PdfiumInternalError::Unknown,
90            ))
91        }
92    }
93
94    /// Returns a mutable collection of all the attachment points in this [PdfPageLinkAnnotation].
95    #[inline]
96    pub fn attachment_points_mut(&mut self) -> &mut PdfPageAnnotationAttachmentPoints<'a> {
97        &mut self.attachment_points
98    }
99}
100
101impl<'a> PdfPageAnnotationPrivate<'a> for PdfPageLinkAnnotation<'a> {
102    #[inline]
103    fn handle(&self) -> FPDF_ANNOTATION {
104        self.handle
105    }
106
107    #[inline]
108    fn ownership(&self) -> &PdfPageObjectOwnership {
109        self.objects_impl().ownership()
110    }
111
112    #[inline]
113    fn bindings(&self) -> &dyn PdfiumLibraryBindings {
114        self.bindings
115    }
116
117    #[inline]
118    fn objects_impl(&self) -> &PdfPageAnnotationObjects {
119        &self.objects
120    }
121
122    #[inline]
123    fn attachment_points_impl(&self) -> &PdfPageAnnotationAttachmentPoints {
124        &self.attachment_points
125    }
126}