pdfium_render/pdf/document/page/annotation/
variable_text.rs

1use crate::error::{PdfiumError, PdfiumInternalError};
2use crate::pdf::document::form::PdfForm;
3use crate::pdf::document::page::annotation::private::internal::PdfPageAnnotationPrivate;
4use crate::pdf::points::PdfPoints;
5use std::ffi::c_float;
6
7#[cfg(any(
8    feature = "pdfium_future",
9    feature = "pdfium_7543",
10    feature = "pdfium_7350",
11    feature = "pdfium_7215",
12    feature = "pdfium_7123",
13    feature = "pdfium_6996",
14    feature = "pdfium_6721",
15    feature = "pdfium_6666",
16    feature = "pdfium_6611",
17    feature = "pdfium_6569",
18    feature = "pdfium_6555",
19))]
20use {crate::pdf::color::PdfColor, std::ffi::c_uint};
21
22#[cfg(doc)]
23use crate::pdf::document::page::annotation::PdfPageAnnotation;
24
25/// The form of justification that should be used when displaying the text assigned
26/// to a [PdfPageAnnotation] that supports variable text.
27#[derive(Copy, Clone, Debug, PartialEq)]
28pub enum PdfPageAnnotationVariableTextJustification {
29    LeftJustified,
30    Centered,
31    RightJustified,
32}
33
34impl PdfPageAnnotationVariableTextJustification {
35    #[inline]
36    pub(crate) fn from_pdfium(value: i32) -> Result<Self, PdfiumError> {
37        match value {
38            0 => Ok(PdfPageAnnotationVariableTextJustification::LeftJustified),
39            1 => Ok(PdfPageAnnotationVariableTextJustification::Centered),
40            2 => Ok(PdfPageAnnotationVariableTextJustification::RightJustified),
41            _ => Err(PdfiumError::UnknownPageAnnotationVariableTextJustificationType),
42        }
43    }
44}
45
46/// Text-handling functions common to all [PdfPageAnnotation] types that
47/// support custom text.
48pub trait PdfPageAnnotationVariableText<'a> {
49    /// Returns the size of the text in this annotation. A value of [PdfPoints::ZERO]
50    /// indicates that the font size is determined automatically from the annotation height.
51    /// See also the [PdfPageAnnotationVariableText::is_font_auto_sized()] function.
52    fn font_size(&self, form: &PdfForm) -> Result<PdfPoints, PdfiumError>;
53
54    /// Returns `true` if the font size for this annotation is determined automatically
55    /// from the annotation height.
56    fn is_font_auto_sized(&self, form: &PdfForm) -> bool;
57
58    #[cfg(any(
59        feature = "pdfium_future",
60        feature = "pdfium_7543",
61        feature = "pdfium_7350",
62        feature = "pdfium_7215",
63        feature = "pdfium_7123",
64        feature = "pdfium_6996",
65        feature = "pdfium_6721",
66        feature = "pdfium_6666",
67        feature = "pdfium_6611",
68        feature = "pdfium_6569",
69        feature = "pdfium_6555",
70    ))]
71    /// Returns the color of the text in this annotation.
72    fn font_color(&self, form: &PdfForm) -> Result<PdfColor, PdfiumError>;
73
74    #[cfg(any(feature = "pdfium_future", feature = "pdfium_7350"))]
75    /// Sets the color of the text in this annotation.
76    fn set_font_color(&mut self, form: &PdfForm, color: PdfColor) -> Result<(), PdfiumError>;
77
78    /// Returns the form of justification that should be used when displaying the text
79    /// assigned to this annotation.
80    fn justification(&self) -> Result<PdfPageAnnotationVariableTextJustification, PdfiumError>;
81
82    /// Returns the rich text string assigned to this annotation, if any.
83    ///
84    /// Rich text support was added in PDF version 1.5.
85    fn rich_text(&self) -> Option<String>;
86}
87
88impl<'a, T> PdfPageAnnotationVariableText<'a> for T
89where
90    T: PdfPageAnnotationPrivate<'a>,
91{
92    fn font_size(&self, form: &PdfForm) -> Result<PdfPoints, PdfiumError> {
93        let mut value: c_float = 0.0;
94
95        if self
96            .bindings()
97            .is_true(self.bindings().FPDFAnnot_GetFontSize(
98                form.handle(),
99                self.handle(),
100                &mut value,
101            ))
102        {
103            Ok(PdfPoints::new(value))
104        } else {
105            Err(PdfiumError::PdfiumLibraryInternalError(
106                PdfiumInternalError::Unknown,
107            ))
108        }
109    }
110
111    #[inline]
112    fn is_font_auto_sized(&self, form: &PdfForm) -> bool {
113        match self.font_size(form) {
114            Ok(size) => size.value == 0.0,
115            _ => false,
116        }
117    }
118
119    #[cfg(any(
120        feature = "pdfium_future",
121        feature = "pdfium_7543",
122        feature = "pdfium_7350",
123        feature = "pdfium_7215",
124        feature = "pdfium_7123",
125        feature = "pdfium_6996",
126        feature = "pdfium_6721",
127        feature = "pdfium_6666",
128        feature = "pdfium_6611",
129        feature = "pdfium_6569",
130        feature = "pdfium_6555",
131    ))]
132    fn font_color(&self, form: &PdfForm) -> Result<PdfColor, PdfiumError> {
133        let mut red: c_uint = 0;
134        let mut green: c_uint = 0;
135        let mut blue: c_uint = 0;
136
137        if self
138            .bindings()
139            .is_true(self.bindings().FPDFAnnot_GetFontColor(
140                form.handle(),
141                self.handle(),
142                &mut red,
143                &mut green,
144                &mut blue,
145            ))
146        {
147            Ok(PdfColor::new(red as u8, green as u8, blue as u8, 255))
148        } else {
149            Err(PdfiumError::PdfiumLibraryInternalError(
150                PdfiumInternalError::Unknown,
151            ))
152        }
153    }
154
155    #[cfg(any(feature = "pdfium_future", feature = "pdfium_7350"))]
156    fn set_font_color(&mut self, form: &PdfForm, color: PdfColor) -> Result<(), PdfiumError> {
157        if self
158            .bindings()
159            .is_true(self.bindings().FPDFAnnot_SetFontColor(
160                form.handle(),
161                self.handle(),
162                color.red() as c_uint,
163                color.green() as c_uint,
164                color.blue() as c_uint,
165            ))
166        {
167            Ok(())
168        } else {
169            Err(PdfiumError::PdfiumLibraryInternalError(
170                PdfiumInternalError::Unknown,
171            ))
172        }
173    }
174
175    fn justification(&self) -> Result<PdfPageAnnotationVariableTextJustification, PdfiumError> {
176        let mut value: c_float = 0.0;
177
178        if self
179            .bindings()
180            .is_true(
181                self.bindings()
182                    .FPDFAnnot_GetNumberValue(self.handle(), "Q", &mut value),
183            )
184        {
185            PdfPageAnnotationVariableTextJustification::from_pdfium(value as i32)
186        } else {
187            Err(PdfiumError::PdfiumLibraryInternalError(
188                PdfiumInternalError::Unknown,
189            ))
190        }
191    }
192
193    #[inline]
194    fn rich_text(&self) -> Option<String> {
195        self.get_string_value("RV")
196    }
197}