Skip to main content

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.bindings().is_true(unsafe {
96            self.bindings()
97                .FPDFAnnot_GetFontSize(form.handle(), self.handle(), &mut value)
98        }) {
99            Ok(PdfPoints::new(value))
100        } else {
101            Err(PdfiumError::PdfiumLibraryInternalError(
102                PdfiumInternalError::Unknown,
103            ))
104        }
105    }
106
107    #[inline]
108    fn is_font_auto_sized(&self, form: &PdfForm) -> bool {
109        match self.font_size(form) {
110            Ok(size) => size.value == 0.0,
111            _ => false,
112        }
113    }
114
115    #[cfg(any(
116        feature = "pdfium_future",
117        feature = "pdfium_7543",
118        feature = "pdfium_7350",
119        feature = "pdfium_7215",
120        feature = "pdfium_7123",
121        feature = "pdfium_6996",
122        feature = "pdfium_6721",
123        feature = "pdfium_6666",
124        feature = "pdfium_6611",
125        feature = "pdfium_6569",
126        feature = "pdfium_6555",
127    ))]
128    fn font_color(&self, form: &PdfForm) -> Result<PdfColor, PdfiumError> {
129        let mut red: c_uint = 0;
130        let mut green: c_uint = 0;
131        let mut blue: c_uint = 0;
132
133        if self.bindings().is_true(unsafe {
134            self.bindings().FPDFAnnot_GetFontColor(
135                form.handle(),
136                self.handle(),
137                &mut red,
138                &mut green,
139                &mut blue,
140            )
141        }) {
142            Ok(PdfColor::new(red as u8, green as u8, blue as u8, 255))
143        } else {
144            Err(PdfiumError::PdfiumLibraryInternalError(
145                PdfiumInternalError::Unknown,
146            ))
147        }
148    }
149
150    #[cfg(any(feature = "pdfium_future", feature = "pdfium_7350"))]
151    fn set_font_color(&mut self, form: &PdfForm, color: PdfColor) -> Result<(), PdfiumError> {
152        if self.bindings().is_true(unsafe {
153            self.bindings().FPDFAnnot_SetFontColor(
154                form.handle(),
155                self.handle(),
156                color.red() as c_uint,
157                color.green() as c_uint,
158                color.blue() as c_uint,
159            )
160        }) {
161            Ok(())
162        } else {
163            Err(PdfiumError::PdfiumLibraryInternalError(
164                PdfiumInternalError::Unknown,
165            ))
166        }
167    }
168
169    fn justification(&self) -> Result<PdfPageAnnotationVariableTextJustification, PdfiumError> {
170        let mut value: c_float = 0.0;
171
172        if self.bindings().is_true(unsafe {
173            self.bindings()
174                .FPDFAnnot_GetNumberValue(self.handle(), "Q", &mut value)
175        }) {
176            PdfPageAnnotationVariableTextJustification::from_pdfium(value as i32)
177        } else {
178            Err(PdfiumError::PdfiumLibraryInternalError(
179                PdfiumInternalError::Unknown,
180            ))
181        }
182    }
183
184    #[inline]
185    fn rich_text(&self) -> Option<String> {
186        self.get_string_value("RV")
187    }
188}