66 lines
1.9 KiB
Rust
66 lines
1.9 KiB
Rust
use std::{
|
|
ffi::CString,
|
|
fs::read_to_string,
|
|
io::{Read, Write},
|
|
path::Path,
|
|
};
|
|
|
|
use log::debug;
|
|
use pyo3::{
|
|
ffi::c_str,
|
|
prelude::*,
|
|
types::{PyList, PyTuple},
|
|
};
|
|
use tempfile::NamedTempFile;
|
|
|
|
pub fn subset(data: &[u8], unicodes: &[u32]) -> Vec<u8> {
|
|
pyo3::prepare_freethreaded_python();
|
|
|
|
let mut input = NamedTempFile::new().expect("input file");
|
|
input.write_all(data).expect("writing input");
|
|
let mut output = NamedTempFile::new().expect("output file");
|
|
|
|
let path = Path::new(concat!(env!("CARGO_MANIFEST_DIR"), "/fonttools/Lib"));
|
|
let init_path = path.join("fontTools/subset/__init__.py");
|
|
let py_init = CString::new(read_to_string(init_path).unwrap()).unwrap();
|
|
let result = Python::with_gil(|py| -> PyResult<Py<PyAny>> {
|
|
let syspath = py
|
|
.import("sys")?
|
|
.getattr("path")?
|
|
.downcast_into::<PyList>()?;
|
|
syspath.insert(0, path)?;
|
|
let app: Py<PyAny> = PyModule::from_code(py, py_init.as_c_str(), c_str!(""), c_str!(""))?
|
|
.getattr("main")?
|
|
.into();
|
|
let args = PyList::new(py, vec![
|
|
input.path().to_str().unwrap(),
|
|
&format_unicodes(unicodes),
|
|
&format!("--output-file={}", output.path().to_str().unwrap()),
|
|
])?;
|
|
debug!("Running pyftsubset with {:?}", args);
|
|
let args_tuple = PyTuple::new(py, &[args])?;
|
|
app.call1(py, args_tuple)
|
|
});
|
|
result.expect("subsetting");
|
|
|
|
let mut buf = vec![];
|
|
output.read_to_end(&mut buf).expect("reading output");
|
|
buf
|
|
}
|
|
|
|
fn format_unicodes(unicodes: &[u32]) -> String {
|
|
use std::fmt::Write;
|
|
|
|
let mut s = "--unicodes=".to_owned();
|
|
let mut first = true;
|
|
for u in unicodes {
|
|
if first {
|
|
write!(s, "{:x}", u).expect("append unicode");
|
|
first = false;
|
|
} else {
|
|
write!(s, ",{:x}", u).expect("append unicode");
|
|
}
|
|
}
|
|
s
|
|
}
|