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::page::PdfPage,
14 crate::pdf::document::page::annotation::PdfPageAnnotation,
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(handle, self.document, self.bindings()))
67 }
68 }
69
70 pub fn destination(&self) -> Option<PdfDestination<'a>> {
75 let handle = self.bindings().FPDFLink_GetDest(self.document, self.handle());
76
77 if handle.is_null() {
78 None
79 } else {
80 Some(PdfDestination::from_pdfium(self.document, handle, self.bindings()))
81 }
82 }
83
84 pub fn rect(&self) -> Result<PdfRect, PdfiumError> {
87 let mut rect = FS_RECTF {
88 left: 0.0,
89 top: 0.0,
90 right: 0.0,
91 bottom: 0.0,
92 };
93
94 PdfRect::from_pdfium_as_result(
95 self.bindings().FPDFLink_GetAnnotRect(self.handle(), &mut rect),
96 rect,
97 self.bindings(),
98 )
99 }
100}
101
102#[cfg(test)]
103mod tests {
104 use crate::prelude::*;
105 use crate::utils::test::{test_bind_to_pdfium, test_fixture_path};
106
107 #[test]
108 fn test_link_rect() -> Result<(), PdfiumError> {
109 let pdfium = test_bind_to_pdfium();
110
111 let document = pdfium.load_pdf_from_file(&test_fixture_path("links-test.pdf"), None)?;
112
113 const EXPECTED: PdfRect = PdfRect::new_from_values(733.3627, 207.85417, 757.6127, 333.1458);
114
115 const ABS_ERR: PdfPoints = PdfPoints::new(f32::EPSILON * 1000.);
116
117 let actual = document
118 .pages()
119 .iter()
120 .next()
121 .unwrap()
122 .links()
123 .iter()
124 .next()
125 .unwrap()
126 .rect()?;
127
128 assert!((actual.top() - EXPECTED.top()).abs() < ABS_ERR);
129 assert!((actual.bottom() - EXPECTED.bottom()).abs() < ABS_ERR);
130 assert!((actual.left() - EXPECTED.left()).abs() < ABS_ERR);
131 assert!((actual.right() - EXPECTED.right()).abs() < ABS_ERR);
132
133 Ok(())
134 }
135}