use std::{ffi::CString, time::SystemTime};
use tectonic_bridge_core::{CoreBridgeLauncher, EngineAbortedError};
use tectonic_errors::prelude::*;
pub struct XdvipdfmxEngine {
paper_spec: String,
enable_compression: bool,
deterministic_tags: bool,
build_date: SystemTime,
origin_offset: Option<(f64, f64)>,
}
impl Default for XdvipdfmxEngine {
fn default() -> Self {
XdvipdfmxEngine {
paper_spec: "letter".to_owned(),
enable_compression: true,
deterministic_tags: false,
build_date: SystemTime::UNIX_EPOCH,
origin_offset: None,
}
}
}
impl XdvipdfmxEngine {
pub fn enable_compression(&mut self, enable_compression: bool) -> &mut Self {
self.enable_compression = enable_compression;
self
}
pub fn enable_deterministic_tags(&mut self, deterministic_tags: bool) -> &mut Self {
self.deterministic_tags = deterministic_tags;
self
}
pub fn build_date(&mut self, date: SystemTime) -> &mut Self {
self.build_date = date;
self
}
pub fn paper_spec(&mut self, paper_spec: String) -> &mut Self {
self.paper_spec = paper_spec;
self
}
pub fn origin_offset(&mut self, x: f64, y: f64) -> &mut Self {
self.origin_offset = Some((x, y));
self
}
pub fn process(
&mut self,
launcher: &mut CoreBridgeLauncher,
dvi: &str,
pdf: &str,
) -> Result<()> {
let paperspec_str = atry!(
CString::new(self.paper_spec.as_str());
["paper_spec may not contain internal NULs"]
);
let config = c_api::XdvipdfmxConfig {
paperspec: paperspec_str.as_c_str().as_ptr(),
enable_compression: u8::from(self.enable_compression),
deterministic_tags: u8::from(self.deterministic_tags),
build_date: self
.build_date
.duration_since(SystemTime::UNIX_EPOCH)
.expect("invalid build date")
.as_secs(),
override_origin: u8::from(self.origin_offset.is_some()),
x_offset: self.origin_offset.map(|o| o.0).unwrap_or(72.0),
y_offset: self.origin_offset.map(|o| o.1).unwrap_or(72.0),
};
let cdvi = CString::new(dvi)?;
let cpdf = CString::new(pdf)?;
launcher.with_global_lock(|state| {
let r = unsafe {
c_api::tt_engine_xdvipdfmx_main(state, &config, cdvi.as_ptr(), cpdf.as_ptr())
};
if r == 99 {
Err(EngineAbortedError::new_abort_indicator().into())
} else {
Ok(())
}
})
}
}
#[doc(hidden)]
pub mod c_api {
use tectonic_bridge_core::CoreBridgeState;
#[derive(Debug)]
#[repr(C)]
pub struct XdvipdfmxConfig {
pub paperspec: *const libc::c_char,
pub enable_compression: libc::c_uchar,
pub deterministic_tags: libc::c_uchar,
pub build_date: u64,
pub override_origin: libc::c_uchar,
pub x_offset: f64,
pub y_offset: f64,
}
#[allow(improper_ctypes)] extern "C" {
pub fn tt_engine_xdvipdfmx_main(
api: &mut CoreBridgeState,
cfg: &XdvipdfmxConfig,
dviname: *const libc::c_char,
pdfname: *const libc::c_char,
) -> libc::c_int;
}
}
mod linkage {
#[allow(unused_imports)]
use tectonic_pdf_io as clipyrenamehack;
}
#[test]
fn linkage() {}