pdfium_render/pdf/
link.rs1use crate::bindgen::{FPDF_DOCUMENT, FPDF_LINK, FS_RECTF};
5use crate::bindings::PdfiumLibraryBindings;
6use crate::error::PdfiumError;
7use crate::pdf::action::PdfAction;
8use crate::pdf::destination::PdfDestination;
9use crate::pdf::rect::PdfRect;
10
11#[cfg(doc)]
12use {
13 crate::pdf::action::PdfActionType, crate::pdf::document::bookmark::PdfBookmark,
14 crate::pdf::document::page::annotation::PdfPageAnnotation, crate::pdf::document::page::PdfPage,
15};
16
17pub struct PdfLink<'a> {
23 handle: FPDF_LINK,
24 document: FPDF_DOCUMENT,
25 bindings: &'a dyn PdfiumLibraryBindings,
26}
27
28impl<'a> PdfLink<'a> {
29 #[inline]
30 pub(crate) fn from_pdfium(
31 handle: FPDF_LINK,
32 document: FPDF_DOCUMENT,
33 bindings: &'a dyn PdfiumLibraryBindings,
34 ) -> Self {
35 PdfLink {
36 handle,
37 document,
38 bindings,
39 }
40 }
41
42 #[inline]
44 pub(crate) fn handle(&self) -> FPDF_LINK {
45 self.handle
46 }
47
48 #[inline]
50 pub fn bindings(&self) -> &'a dyn PdfiumLibraryBindings {
51 self.bindings
52 }
53
54 pub fn action(&self) -> Option<PdfAction<'a>> {
61 let handle = self.bindings().FPDFLink_GetAction(self.handle());
62
63 if handle.is_null() {
64 None
65 } else {
66 Some(PdfAction::from_pdfium(
67 handle,
68 self.document,
69 self.bindings(),
70 ))
71 }
72 }
73
74 pub fn destination(&self) -> Option<PdfDestination<'a>> {
79 let handle = self
80 .bindings()
81 .FPDFLink_GetDest(self.document, self.handle());
82
83 if handle.is_null() {
84 None
85 } else {
86 Some(PdfDestination::from_pdfium(
87 self.document,
88 handle,
89 self.bindings(),
90 ))
91 }
92 }
93
94 pub fn rect(&self) -> Result<PdfRect, PdfiumError> {
97 let mut rect = FS_RECTF {
98 left: 0.0,
99 top: 0.0,
100 right: 0.0,
101 bottom: 0.0,
102 };
103
104 PdfRect::from_pdfium_as_result(
105 self.bindings()
106 .FPDFLink_GetAnnotRect(self.handle(), &mut rect),
107 rect,
108 self.bindings(),
109 )
110 }
111}
112
113#[cfg(test)]
114mod tests {
115 use crate::prelude::*;
116 use crate::utils::test::test_bind_to_pdfium;
117
118 #[test]
119 fn test_link_rect() -> Result<(), PdfiumError> {
120 let pdfium = test_bind_to_pdfium();
121
122 let document = pdfium.load_pdf_from_file("./test/links-test.pdf", None)?;
125
126 const EXPECTED: PdfRect = PdfRect::new_from_values(733.3627, 207.85417, 757.6127, 333.1458);
127
128 const ABS_ERR: PdfPoints = PdfPoints::new(f32::EPSILON * 1000.);
132
133 let actual = document
134 .pages()
135 .iter()
136 .next()
137 .unwrap()
138 .links()
139 .iter()
140 .next()
141 .unwrap()
142 .rect()?;
143
144 assert!((actual.top() - EXPECTED.top()).abs() < ABS_ERR);
145 assert!((actual.bottom() - EXPECTED.bottom()).abs() < ABS_ERR);
146 assert!((actual.left() - EXPECTED.left()).abs() < ABS_ERR);
147 assert!((actual.right() - EXPECTED.right()).abs() < ABS_ERR);
148
149 Ok(())
150 }
151}