pdfium_render/pdf/document/page/
field.rs1pub mod button;
5pub mod checkbox;
6pub mod combo;
7pub mod list;
8pub mod option;
9pub mod options;
10pub(crate) mod private; pub mod radio;
12pub mod signature;
13pub mod text;
14pub mod unknown;
15
16use crate::bindgen::{
17 FPDF_ANNOTATION, FPDF_FORMFIELD_CHECKBOX, FPDF_FORMFIELD_COMBOBOX, FPDF_FORMFIELD_LISTBOX,
18 FPDF_FORMFIELD_PUSHBUTTON, FPDF_FORMFIELD_RADIOBUTTON, FPDF_FORMFIELD_SIGNATURE,
19 FPDF_FORMFIELD_TEXTFIELD, FPDF_FORMFIELD_UNKNOWN, FPDF_FORMHANDLE,
20};
21use crate::bindings::PdfiumLibraryBindings;
22use crate::error::PdfiumError;
23use crate::pdf::appearance_mode::PdfAppearanceMode;
24use crate::pdf::document::page::field::button::PdfFormPushButtonField;
25use crate::pdf::document::page::field::checkbox::PdfFormCheckboxField;
26use crate::pdf::document::page::field::combo::PdfFormComboBoxField;
27use crate::pdf::document::page::field::list::PdfFormListBoxField;
28use crate::pdf::document::page::field::private::internal::PdfFormFieldPrivate;
29use crate::pdf::document::page::field::radio::PdfFormRadioButtonField;
30use crate::pdf::document::page::field::signature::PdfFormSignatureField;
31use crate::pdf::document::page::field::text::PdfFormTextField;
32use crate::pdf::document::page::field::unknown::PdfFormUnknownField;
33use std::os::raw::c_int;
34
35#[cfg(doc)]
36use crate::pdf::document::form::PdfForm;
37
38#[derive(Debug, Copy, Clone, PartialOrd, PartialEq)]
40pub enum PdfFormFieldType {
41 Unknown = FPDF_FORMFIELD_UNKNOWN as isize,
44 PushButton = FPDF_FORMFIELD_PUSHBUTTON as isize,
45 Checkbox = FPDF_FORMFIELD_CHECKBOX as isize,
46 RadioButton = FPDF_FORMFIELD_RADIOBUTTON as isize,
47 ComboBox = FPDF_FORMFIELD_COMBOBOX as isize,
48 ListBox = FPDF_FORMFIELD_LISTBOX as isize,
49 Text = FPDF_FORMFIELD_TEXTFIELD as isize,
50 Signature = FPDF_FORMFIELD_SIGNATURE as isize,
51}
52
53impl PdfFormFieldType {
54 #[inline]
55 #[allow(dead_code)]
56 pub(crate) fn from_pdfium(value: c_int) -> Result<PdfFormFieldType, PdfiumError> {
57 match value as u32 {
58 FPDF_FORMFIELD_UNKNOWN => Ok(PdfFormFieldType::Unknown),
59 FPDF_FORMFIELD_PUSHBUTTON => Ok(PdfFormFieldType::PushButton),
60 FPDF_FORMFIELD_CHECKBOX => Ok(PdfFormFieldType::Checkbox),
61 FPDF_FORMFIELD_RADIOBUTTON => Ok(PdfFormFieldType::RadioButton),
62 FPDF_FORMFIELD_COMBOBOX => Ok(PdfFormFieldType::ComboBox),
63 FPDF_FORMFIELD_LISTBOX => Ok(PdfFormFieldType::ListBox),
64 FPDF_FORMFIELD_TEXTFIELD => Ok(PdfFormFieldType::Text),
65 FPDF_FORMFIELD_SIGNATURE => Ok(PdfFormFieldType::Signature),
66 _ => Err(PdfiumError::UnknownFormFieldType),
67 }
68 }
69
70 #[inline]
71 #[allow(dead_code)]
72 pub(crate) fn as_pdfium(&self) -> u32 {
74 match self {
75 PdfFormFieldType::Unknown => FPDF_FORMFIELD_UNKNOWN,
76 PdfFormFieldType::PushButton => FPDF_FORMFIELD_PUSHBUTTON,
77 PdfFormFieldType::Checkbox => FPDF_FORMFIELD_CHECKBOX,
78 PdfFormFieldType::RadioButton => FPDF_FORMFIELD_RADIOBUTTON,
79 PdfFormFieldType::ComboBox => FPDF_FORMFIELD_COMBOBOX,
80 PdfFormFieldType::ListBox => FPDF_FORMFIELD_LISTBOX,
81 PdfFormFieldType::Text => FPDF_FORMFIELD_TEXTFIELD,
82 PdfFormFieldType::Signature => FPDF_FORMFIELD_SIGNATURE,
83 }
84 }
85}
86
87pub enum PdfFormField<'a> {
89 PushButton(PdfFormPushButtonField<'a>),
90 Checkbox(PdfFormCheckboxField<'a>),
91 RadioButton(PdfFormRadioButtonField<'a>),
92 ComboBox(PdfFormComboBoxField<'a>),
93 ListBox(PdfFormListBoxField<'a>),
94 Signature(PdfFormSignatureField<'a>),
95 Text(PdfFormTextField<'a>),
96 Unknown(PdfFormUnknownField<'a>),
97}
98
99impl<'a> PdfFormField<'a> {
100 pub(crate) fn from_pdfium(
101 form_handle: FPDF_FORMHANDLE,
102 annotation_handle: FPDF_ANNOTATION,
103 bindings: &'a dyn PdfiumLibraryBindings,
104 ) -> Option<Self> {
105 let result = bindings.FPDFAnnot_GetFormFieldType(form_handle, annotation_handle);
106
107 if result == -1 {
108 return None;
109 }
110
111 let form_field_type =
112 PdfFormFieldType::from_pdfium(result).unwrap_or(PdfFormFieldType::Unknown);
113
114 Some(match form_field_type {
115 PdfFormFieldType::PushButton => PdfFormField::PushButton(
116 PdfFormPushButtonField::from_pdfium(form_handle, annotation_handle, bindings),
117 ),
118 PdfFormFieldType::Checkbox => PdfFormField::Checkbox(
119 PdfFormCheckboxField::from_pdfium(form_handle, annotation_handle, bindings),
120 ),
121 PdfFormFieldType::RadioButton => PdfFormField::RadioButton(
122 PdfFormRadioButtonField::from_pdfium(form_handle, annotation_handle, bindings),
123 ),
124 PdfFormFieldType::ComboBox => PdfFormField::ComboBox(
125 PdfFormComboBoxField::from_pdfium(form_handle, annotation_handle, bindings),
126 ),
127 PdfFormFieldType::ListBox => PdfFormField::ListBox(PdfFormListBoxField::from_pdfium(
128 form_handle,
129 annotation_handle,
130 bindings,
131 )),
132 PdfFormFieldType::Text => PdfFormField::Text(PdfFormTextField::from_pdfium(
133 form_handle,
134 annotation_handle,
135 bindings,
136 )),
137 PdfFormFieldType::Signature => PdfFormField::Signature(
138 PdfFormSignatureField::from_pdfium(form_handle, annotation_handle, bindings),
139 ),
140 _ => PdfFormField::Unknown(PdfFormUnknownField::from_pdfium(
141 form_handle,
142 annotation_handle,
143 bindings,
144 )),
145 })
146 }
147
148 #[inline]
149 pub(crate) fn unwrap_as_trait(&self) -> &dyn PdfFormFieldPrivate<'a> {
150 match self {
151 PdfFormField::PushButton(field) => field,
152 PdfFormField::Checkbox(field) => field,
153 PdfFormField::RadioButton(field) => field,
154 PdfFormField::ComboBox(field) => field,
155 PdfFormField::ListBox(field) => field,
156 PdfFormField::Signature(field) => field,
157 PdfFormField::Text(field) => field,
158 PdfFormField::Unknown(field) => field,
159 }
160 }
161
162 #[inline]
164 pub fn field_type(&self) -> PdfFormFieldType {
165 match self {
166 PdfFormField::PushButton(_) => PdfFormFieldType::PushButton,
167 PdfFormField::Checkbox(_) => PdfFormFieldType::Checkbox,
168 PdfFormField::RadioButton(_) => PdfFormFieldType::RadioButton,
169 PdfFormField::ComboBox(_) => PdfFormFieldType::ComboBox,
170 PdfFormField::ListBox(_) => PdfFormFieldType::ListBox,
171 PdfFormField::Signature(_) => PdfFormFieldType::Signature,
172 PdfFormField::Text(_) => PdfFormFieldType::Text,
173 PdfFormField::Unknown(_) => PdfFormFieldType::Unknown,
174 }
175 }
176
177 #[inline]
180 pub fn as_push_button_field(&self) -> Option<&PdfFormPushButtonField> {
181 match self {
182 PdfFormField::PushButton(field) => Some(field),
183 _ => None,
184 }
185 }
186
187 #[inline]
190 pub fn as_checkbox_field(&self) -> Option<&PdfFormCheckboxField> {
191 match self {
192 PdfFormField::Checkbox(field) => Some(field),
193 _ => None,
194 }
195 }
196
197 #[inline]
200 pub fn as_checkbox_field_mut(&mut self) -> Option<&mut PdfFormCheckboxField<'a>> {
201 match self {
202 PdfFormField::Checkbox(field) => Some(field),
203 _ => None,
204 }
205 }
206
207 #[inline]
210 pub fn as_radio_button_field(&self) -> Option<&PdfFormRadioButtonField> {
211 match self {
212 PdfFormField::RadioButton(field) => Some(field),
213 _ => None,
214 }
215 }
216
217 #[inline]
220 pub fn as_radio_button_field_mut(&mut self) -> Option<&mut PdfFormRadioButtonField<'a>> {
221 match self {
222 PdfFormField::RadioButton(field) => Some(field),
223 _ => None,
224 }
225 }
226
227 #[inline]
230 pub fn as_combo_box_field(&self) -> Option<&PdfFormComboBoxField> {
231 match self {
232 PdfFormField::ComboBox(field) => Some(field),
233 _ => None,
234 }
235 }
236
237 #[inline]
240 pub fn as_list_box_field(&self) -> Option<&PdfFormListBoxField> {
241 match self {
242 PdfFormField::ListBox(field) => Some(field),
243 _ => None,
244 }
245 }
246
247 #[inline]
250 pub fn as_signature_field(&self) -> Option<&PdfFormSignatureField> {
251 match self {
252 PdfFormField::Signature(field) => Some(field),
253 _ => None,
254 }
255 }
256
257 #[inline]
260 pub fn as_text_field(&self) -> Option<&PdfFormTextField> {
261 match self {
262 PdfFormField::Text(field) => Some(field),
263 _ => None,
264 }
265 }
266
267 pub fn as_text_field_mut(&mut self) -> Option<&mut PdfFormTextField<'a>> {
270 match self {
271 PdfFormField::Text(field) => Some(field),
272 _ => None,
273 }
274 }
275
276 #[inline]
279 pub fn as_unknown_field(&self) -> Option<&PdfFormUnknownField> {
280 match self {
281 PdfFormField::Unknown(field) => Some(field),
282 _ => None,
283 }
284 }
285}
286
287pub trait PdfFormFieldCommon {
289 fn name(&self) -> Option<String>;
291
292 fn appearance_stream(&self) -> Option<String>;
294
295 fn appearance_mode_value(&self, appearance_mode: PdfAppearanceMode) -> Option<String>;
298}
299
300impl<'a, T> PdfFormFieldCommon for T
303where
304 T: PdfFormFieldPrivate<'a>,
305{
306 #[inline]
307 fn name(&self) -> Option<String> {
308 self.name_impl()
309 }
310
311 #[inline]
312 fn appearance_stream(&self) -> Option<String> {
313 self.appearance_stream_impl()
314 }
315
316 #[inline]
317 fn appearance_mode_value(&self, appearance_mode: PdfAppearanceMode) -> Option<String> {
318 self.appearance_mode_value_impl(appearance_mode)
319 }
320}
321
322impl<'a> PdfFormFieldPrivate<'a> for PdfFormField<'a> {
323 #[inline]
324 fn form_handle(&self) -> &FPDF_FORMHANDLE {
325 self.unwrap_as_trait().form_handle()
326 }
327
328 #[inline]
329 fn annotation_handle(&self) -> &FPDF_ANNOTATION {
330 self.unwrap_as_trait().annotation_handle()
331 }
332
333 #[inline]
334 fn bindings(&self) -> &dyn PdfiumLibraryBindings {
335 self.unwrap_as_trait().bindings()
336 }
337}
338
339impl<'a> From<PdfFormPushButtonField<'a>> for PdfFormField<'a> {
340 #[inline]
341 fn from(field: PdfFormPushButtonField<'a>) -> Self {
342 Self::PushButton(field)
343 }
344}
345
346impl<'a> From<PdfFormCheckboxField<'a>> for PdfFormField<'a> {
347 #[inline]
348 fn from(field: PdfFormCheckboxField<'a>) -> Self {
349 Self::Checkbox(field)
350 }
351}
352
353impl<'a> From<PdfFormRadioButtonField<'a>> for PdfFormField<'a> {
354 #[inline]
355 fn from(field: PdfFormRadioButtonField<'a>) -> Self {
356 Self::RadioButton(field)
357 }
358}
359
360impl<'a> From<PdfFormComboBoxField<'a>> for PdfFormField<'a> {
361 #[inline]
362 fn from(field: PdfFormComboBoxField<'a>) -> Self {
363 Self::ComboBox(field)
364 }
365}
366
367impl<'a> From<PdfFormListBoxField<'a>> for PdfFormField<'a> {
368 #[inline]
369 fn from(field: PdfFormListBoxField<'a>) -> Self {
370 Self::ListBox(field)
371 }
372}
373
374impl<'a> From<PdfFormTextField<'a>> for PdfFormField<'a> {
375 #[inline]
376 fn from(field: PdfFormTextField<'a>) -> Self {
377 Self::Text(field)
378 }
379}
380
381impl<'a> From<PdfFormSignatureField<'a>> for PdfFormField<'a> {
382 #[inline]
383 fn from(field: PdfFormSignatureField<'a>) -> Self {
384 Self::Signature(field)
385 }
386}
387
388impl<'a> From<PdfFormUnknownField<'a>> for PdfFormField<'a> {
389 #[inline]
390 fn from(field: PdfFormUnknownField<'a>) -> Self {
391 Self::Unknown(field)
392 }
393}