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