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