use std::ffi::c_int;
use crate::error::{Error, Result};
use crate::library::Pdfium;
use crate::sys;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum FormType {
None,
AcroForm,
XfaFull,
XfaForeground,
Unknown(i32),
}
impl FormType {
pub(crate) fn from_raw(raw: c_int) -> FormType {
match raw {
sys::FORMTYPE_NONE => FormType::None,
sys::FORMTYPE_ACRO_FORM => FormType::AcroForm,
sys::FORMTYPE_XFA_FULL => FormType::XfaFull,
sys::FORMTYPE_XFA_FOREGROUND => FormType::XfaForeground,
other => FormType::Unknown(other),
}
}
pub fn is_renderable(&self) -> bool {
matches!(self, FormType::AcroForm)
}
}
pub(crate) struct FormEnv {
info: Box<sys::FPDF_FORMFILLINFO>,
handle: sys::FPDF_FORMHANDLE,
}
unsafe impl Send for FormEnv {}
unsafe impl Sync for FormEnv {}
impl FormEnv {
pub(crate) fn new(pdfium: Pdfium, document: sys::FPDF_DOCUMENT) -> Result<FormEnv> {
let mut info = Box::new(new_formfillinfo());
let handle = pdfium.ffi(|b|
unsafe { b.FPDFDOC_InitFormFillEnvironment(document, info.as_mut()) });
if handle.is_null() {
return Err(Error::FormInitFailed);
}
Ok(FormEnv { info, handle })
}
pub(crate) fn handle(&self) -> sys::FPDF_FORMHANDLE {
self.handle
}
pub(crate) fn destroy(&mut self, bindings: &sys::Bindings) {
if !self.handle.is_null() {
unsafe { bindings.FPDFDOC_ExitFormFillEnvironment(self.handle) };
self.handle = std::ptr::null_mut();
}
let _ = &self.info; }
}
fn new_formfillinfo() -> sys::FPDF_FORMFILLINFO {
sys::FPDF_FORMFILLINFO {
version: 1,
Release: None,
FFI_Invalidate: Some(ffi_invalidate),
FFI_OutputSelectedRect: None,
FFI_SetCursor: Some(ffi_set_cursor),
FFI_SetTimer: Some(ffi_set_timer),
FFI_KillTimer: Some(ffi_kill_timer),
FFI_GetLocalTime: Some(ffi_get_local_time),
FFI_OnChange: None,
FFI_GetPage: Some(ffi_get_page),
FFI_GetCurrentPage: Some(ffi_get_current_page),
FFI_GetRotation: Some(ffi_get_rotation),
FFI_ExecuteNamedAction: Some(ffi_execute_named_action),
FFI_SetTextFieldFocus: None,
FFI_DoURIAction: None,
FFI_DoGoToAction: None,
m_pJsPlatform: std::ptr::null_mut(),
xfa_disabled: 0,
FFI_DisplayCaret: None,
FFI_GetCurrentPageIndex: None,
FFI_SetCurrentPage: None,
FFI_GotoURL: None,
FFI_GetPageViewRect: None,
FFI_PageEvent: None,
FFI_PopupMenu: None,
FFI_OpenFile: None,
FFI_EmailTo: None,
FFI_UploadTo: None,
FFI_GetPlatform: None,
FFI_GetLanguage: None,
FFI_DownloadFromURL: None,
FFI_PostRequestURL: None,
FFI_PutRequestURL: None,
FFI_OnFocusChange: None,
FFI_DoURIActionWithKeyboardModifier: None,
}
}
unsafe extern "C" fn ffi_invalidate(
_this: *mut sys::FPDF_FORMFILLINFO,
_page: sys::FPDF_PAGE,
_left: f64,
_top: f64,
_right: f64,
_bottom: f64,
) {
}
unsafe extern "C" fn ffi_set_cursor(_this: *mut sys::FPDF_FORMFILLINFO, _cursor: c_int) {}
unsafe extern "C" fn ffi_set_timer(
_this: *mut sys::FPDF_FORMFILLINFO,
_elapse: c_int,
_timer_func: sys::TimerCallback,
) -> c_int {
0
}
unsafe extern "C" fn ffi_kill_timer(_this: *mut sys::FPDF_FORMFILLINFO, _timer_id: c_int) {}
unsafe extern "C" fn ffi_get_local_time(
_this: *mut sys::FPDF_FORMFILLINFO,
) -> sys::FPDF_SYSTEMTIME {
sys::FPDF_SYSTEMTIME::default()
}
unsafe extern "C" fn ffi_get_page(
_this: *mut sys::FPDF_FORMFILLINFO,
_document: sys::FPDF_DOCUMENT,
_page_index: c_int,
) -> sys::FPDF_PAGE {
std::ptr::null_mut()
}
unsafe extern "C" fn ffi_get_current_page(
_this: *mut sys::FPDF_FORMFILLINFO,
_document: sys::FPDF_DOCUMENT,
) -> sys::FPDF_PAGE {
std::ptr::null_mut()
}
unsafe extern "C" fn ffi_get_rotation(
_this: *mut sys::FPDF_FORMFILLINFO,
_page: sys::FPDF_PAGE,
) -> c_int {
0
}
unsafe extern "C" fn ffi_execute_named_action(
_this: *mut sys::FPDF_FORMFILLINFO,
_named_action: sys::FPDF_BYTESTRING,
) {
}