Skip to main content

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(document_handle, page_handle, annotation_handle, bindings),
35            attachment_points: PdfPageAnnotationAttachmentPoints::from_pdfium(annotation_handle, bindings),
36            bindings,
37        }
38    }
39
40    /// Returns the [PdfLink] associated with this [PdfPageLinkAnnotation], if any.
41    pub fn link(&self) -> Result<PdfLink<'_>, PdfiumError> {
42        let handle = self.bindings.FPDFAnnot_GetLink(self.handle);
43
44        if handle.is_null() {
45            Err(PdfiumError::PdfiumLibraryInternalError(PdfiumInternalError::Unknown))
46        } else {
47            let document_handle = match self.objects.ownership() {
48                PdfPageObjectOwnership::Page(ownership) => Some(ownership.document_handle()),
49                PdfPageObjectOwnership::AttachedAnnotation(ownership) => Some(ownership.document_handle()),
50                PdfPageObjectOwnership::UnattachedAnnotation(ownership) => Some(ownership.document_handle()),
51                _ => None,
52            };
53
54            if let Some(document_handle) = document_handle {
55                Ok(PdfLink::from_pdfium(handle, document_handle, self.bindings()))
56            } else {
57                Err(PdfiumError::OwnershipNotAttachedToDocument)
58            }
59        }
60    }
61
62    /// Sets the [PdfLink] associated with this [PdfPageLinkAnnotation] to the given URI.
63    pub fn set_link(&mut self, uri: &str) -> Result<(), PdfiumError> {
64        if self
65            .bindings()
66            .is_true(self.bindings().FPDFAnnot_SetURI(self.handle(), uri))
67        {
68            Ok(())
69        } else {
70            Err(PdfiumError::PdfiumLibraryInternalError(PdfiumInternalError::Unknown))
71        }
72    }
73
74    /// Returns a mutable collection of all the attachment points in this [PdfPageLinkAnnotation].
75    #[inline]
76    pub fn attachment_points_mut(&mut self) -> &mut PdfPageAnnotationAttachmentPoints<'a> {
77        &mut self.attachment_points
78    }
79}
80
81impl<'a> PdfPageAnnotationPrivate<'a> for PdfPageLinkAnnotation<'a> {
82    #[inline]
83    fn handle(&self) -> FPDF_ANNOTATION {
84        self.handle
85    }
86
87    #[inline]
88    fn ownership(&self) -> &PdfPageObjectOwnership {
89        self.objects_impl().ownership()
90    }
91
92    #[inline]
93    fn bindings(&self) -> &dyn PdfiumLibraryBindings {
94        self.bindings
95    }
96
97    #[inline]
98    fn objects_impl(&self) -> &PdfPageAnnotationObjects<'_> {
99        &self.objects
100    }
101
102    #[inline]
103    fn attachment_points_impl(&self) -> &PdfPageAnnotationAttachmentPoints<'_> {
104        &self.attachment_points
105    }
106}