Skip to main content

pdf_annot/
markup.rs

1//! Markup annotations: Text, Highlight, Underline, StrikeOut, Squiggly, Caret, Popup.
2
3extern crate alloc;
4
5use crate::annotation::Annotation;
6use crate::types::*;
7use pdf_syntax::object::dict::keys::*;
8use pdf_syntax::object::{Name, Rect};
9
10/// A text (sticky note) annotation.
11#[derive(Debug)]
12pub struct TextAnnotation {
13    /// Whether the annotation is initially open.
14    pub open: bool,
15    /// The icon name.
16    pub icon: alloc::string::String,
17}
18
19impl TextAnnotation {
20    /// Extract text annotation properties from an annotation.
21    pub fn from_annot(annot: &Annotation<'_>) -> Self {
22        let dict = annot.dict();
23        let open = dict.get::<bool>(Name::new(b"Open")).unwrap_or(false);
24        let icon = dict
25            .get::<Name>(NAME)
26            .map(|n| alloc::string::String::from(n.as_str()))
27            .unwrap_or_else(|| alloc::string::String::from("Note"));
28        Self { open, icon }
29    }
30}
31
32/// The type of text markup.
33#[derive(Debug, Clone, Copy, PartialEq, Eq)]
34pub enum TextMarkupType {
35    /// Highlight.
36    Highlight,
37    /// Underline.
38    Underline,
39    /// Squiggly underline.
40    Squiggly,
41    /// Strikeout.
42    StrikeOut,
43}
44
45/// A text markup annotation (Highlight, Underline, Squiggly, StrikeOut).
46#[derive(Debug)]
47pub struct TextMarkupAnnotation {
48    /// The markup type.
49    pub markup_type: TextMarkupType,
50    /// The quadrilateral points defining the marked-up region.
51    pub quad_points: Option<QuadPoints>,
52}
53
54impl TextMarkupAnnotation {
55    /// Extract text markup properties from an annotation.
56    pub fn from_annot(annot: &Annotation<'_>) -> Option<Self> {
57        let markup_type = match annot.annotation_type() {
58            AnnotationType::Highlight => TextMarkupType::Highlight,
59            AnnotationType::Underline => TextMarkupType::Underline,
60            AnnotationType::Squiggly => TextMarkupType::Squiggly,
61            AnnotationType::StrikeOut => TextMarkupType::StrikeOut,
62            _ => return None,
63        };
64        let quad_points = annot.quad_points();
65        Some(Self {
66            markup_type,
67            quad_points,
68        })
69    }
70}
71
72/// A caret annotation (ISO 32000-2 §12.5.6.18).
73#[derive(Debug)]
74pub struct CaretAnnotation {
75    /// The caret symbol.
76    pub symbol: alloc::string::String,
77    /// Rectangle differences.
78    pub rd: Option<Rect>,
79}
80
81impl CaretAnnotation {
82    /// Extract caret annotation properties.
83    pub fn from_annot(annot: &Annotation<'_>) -> Self {
84        let dict = annot.dict();
85        let symbol = dict
86            .get::<Name>(SY)
87            .map(|n| alloc::string::String::from(n.as_str()))
88            .unwrap_or_else(|| alloc::string::String::from("None"));
89        let rd = dict.get::<Rect>(RD);
90        Self { symbol, rd }
91    }
92}
93
94/// A popup annotation (ISO 32000-2 §12.5.6.14).
95#[derive(Debug)]
96pub struct PopupAnnotation {
97    /// Whether the popup is initially open.
98    pub open: bool,
99}
100
101impl PopupAnnotation {
102    /// Extract popup annotation properties.
103    pub fn from_annot(annot: &Annotation<'_>) -> Self {
104        let open = annot
105            .dict()
106            .get::<bool>(Name::new(b"Open"))
107            .unwrap_or(false);
108        Self { open }
109    }
110}