1use crate::annotation::Annotation;
10use crate::types::*;
11use pdf_syntax::object::dict::keys::*;
12use pdf_syntax::object::{Array, Dict, Name, Rect};
13
14#[derive(Debug)]
16pub struct LineAnnotation {
17 pub endpoints: Option<[f32; 4]>,
19 pub line_endings: (LineEnding, LineEnding),
21 pub caption: bool,
23 pub caption_offset: Option<[f32; 2]>,
25 pub leader_line: f32,
27 pub leader_line_extension: f32,
29 pub leader_line_offset: f32,
31}
32
33impl LineAnnotation {
34 pub fn from_annot(annot: &Annotation<'_>) -> Self {
36 let dict = annot.dict();
37 let endpoints = dict.get::<Array<'_>>(L).and_then(|arr| {
38 let mut iter = arr.iter::<f32>();
39 Some([iter.next()?, iter.next()?, iter.next()?, iter.next()?])
40 });
41 let line_endings = parse_line_endings(dict);
42 let caption = dict.get::<bool>(CAP).unwrap_or(false);
43 let caption_offset = dict.get::<Array<'_>>(CO).and_then(|arr| {
44 let mut iter = arr.iter::<f32>();
45 Some([iter.next()?, iter.next()?])
46 });
47 let leader_line = dict.get::<f32>(LL).unwrap_or(0.0);
48 let leader_line_extension = dict.get::<f32>(LLE).unwrap_or(0.0);
49 let leader_line_offset = dict.get::<f32>(LLO).unwrap_or(0.0);
50 Self {
51 endpoints,
52 line_endings,
53 caption,
54 caption_offset,
55 leader_line,
56 leader_line_extension,
57 leader_line_offset,
58 }
59 }
60}
61
62#[derive(Debug)]
64pub struct SquareCircleAnnotation {
65 pub is_circle: bool,
67 pub rd: Option<Rect>,
69}
70
71impl SquareCircleAnnotation {
72 pub fn from_annot(annot: &Annotation<'_>) -> Self {
74 let is_circle = annot.annotation_type() == AnnotationType::Circle;
75 let rd = annot.dict().get::<Rect>(RD);
76 Self { is_circle, rd }
77 }
78}
79
80#[derive(Debug)]
82pub struct PolygonAnnotation {
83 pub closed: bool,
85 pub vertices: Vec<f32>,
87 pub line_endings: (LineEnding, LineEnding),
89}
90
91impl PolygonAnnotation {
92 pub fn from_annot(annot: &Annotation<'_>) -> Self {
94 let dict = annot.dict();
95 let closed = annot.annotation_type() == AnnotationType::Polygon;
96 let vertices = dict
97 .get::<Array<'_>>(VERTICES)
98 .map(|arr| arr.iter::<f32>().collect())
99 .unwrap_or_default();
100 let line_endings = parse_line_endings(dict);
101 Self {
102 closed,
103 vertices,
104 line_endings,
105 }
106 }
107}
108
109#[derive(Debug)]
111pub struct InkAnnotation {
112 pub ink_list: Vec<Vec<f32>>,
114}
115
116impl InkAnnotation {
117 pub fn from_annot(annot: &Annotation<'_>) -> Self {
119 let dict = annot.dict();
120 let ink_list = dict
121 .get::<Array<'_>>(INKLIST)
122 .map(|outer| {
123 outer
124 .iter::<Array<'_>>()
125 .map(|inner| inner.iter::<f32>().collect())
126 .collect()
127 })
128 .unwrap_or_default();
129 Self { ink_list }
130 }
131}
132
133fn parse_line_endings(dict: &Dict<'_>) -> (LineEnding, LineEnding) {
135 dict.get::<Array<'_>>(LE)
136 .and_then(|arr| {
137 let mut iter = arr.iter::<Name>();
138 let start = iter.next().map(|n| LineEnding::from_name(n.as_ref()))?;
139 let end = iter.next().map(|n| LineEnding::from_name(n.as_ref()))?;
140 Some((start, end))
141 })
142 .unwrap_or((LineEnding::None, LineEnding::None))
143}