1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
use crate::{
actions::{Actions, UriAction},
destination::Destination,
error::PdfResult,
objects::Dictionary,
pdf_enum, Resolve,
};
use super::BorderStyle;
/// A link annotation represents either a hypertext link to a destination elsewhere
/// in the document or an action to be performed
#[derive(Debug)]
pub(crate) struct LinkAnnotation {
/// An action that shall be performed when the link annotation is activated
a: Option<Actions>,
/// A destination that shall be displayed when the annotation is activated
// todo: not permitted if `a` is present
dest: Option<Destination>,
/// The annotation's highlighting mode, the visual effect that shall be used
/// when the mouse button is pressed or held down inside its active area
h: HighlightingMode,
/// A URI action formerly associated with this annotation. When Web Capture
/// changes an annotation from a URI to a go-to action, it uses this entry to
/// save the data from the original URI action so that it can be changed back
/// in case the target page for the goto action is subsequently deleted.
pa: Option<UriAction>,
/// An array of 8 * n numbers specifying the coordinates of n quadrilaterals in
/// default user space that comprise the region in which the link should be
/// activated. The coordinates for each quadrilateral are given in the order
///
/// x1 y1 x2 y2 x3 y3 x4 y4
///
/// specifying the four vertices of the quadrilateral in counterclockwise order.
/// For orientation purposes, such as when applying an underline border style, the
/// bottom of a quadrilateral is the line formed by (x1, y1) and (x2, y2).
///
/// If this entry is not present or the conforming reader does not recognize it,
/// the region specified by the Rect entry should be used. QuadPoints shall be
/// ignored if any coordinate in the array lies outside the region specified by Rect
quad_points: Option<Vec<f32>>,
/// A border style dictionary specifying the line width and dash pattern to be used
/// in drawing the annotation's border.
///
/// The annotation dictionary's AP entry, if present, takes precedence over the BS entry
bs: Option<BorderStyle>,
}
pdf_enum!(
#[derive(Debug)]
pub enum HighlightingMode {
/// No highlighting
None = "N",
/// Invert the contents of the annotation rectangle
Invert = "I",
/// Invert the annotation's border
Outline = "O",
/// Display the annotation as if it were being pushed below the surface of the page.
Push = "P",
}
);
impl Default for HighlightingMode {
fn default() -> Self {
Self::Invert
}
}
impl LinkAnnotation {
const TYPE: &'static str = "Link";
pub fn from_dict(dict: &mut Dictionary, resolver: &mut impl Resolve) -> PdfResult<Self> {
let a = dict
.get_dict("A", resolver)?
.map(|actions| Actions::from_dict(actions, resolver))
.transpose()?;
let dest = dict
.get_object("Dest", resolver)?
.map(|dest| Destination::from_obj(dest, resolver))
.transpose()?;
let h = dict
.get_name("H", resolver)?
.as_deref()
.map(HighlightingMode::from_str)
.transpose()?
.unwrap_or_default();
let pa = dict
.get_dict("PA", resolver)?
.map(|dict| UriAction::from_dict(dict, resolver))
.transpose()?;
let quad_points = None;
let bs = dict
.get_dict("BS", resolver)?
.map(|dict| BorderStyle::from_dict(dict, resolver))
.transpose()?;
Ok(Self {
a,
dest,
h,
pa,
quad_points,
bs,
})
}
}