font subsetting: pyftsubset -> allsorts
This commit is contained in:
92
build.rs
92
build.rs
@@ -1,8 +1,14 @@
|
||||
use epaint::{
|
||||
FontFamily,
|
||||
text::{FontData, FontDefinitions, FontTweak},
|
||||
use allsorts::{
|
||||
binary::read::ReadScope,
|
||||
font::{Font, MatchingPresentation},
|
||||
font_data::FontData as AllsortsFontData,
|
||||
subset::subset,
|
||||
tag,
|
||||
};
|
||||
use epaint::{
|
||||
text::{FontData, FontDefinitions, FontTweak},
|
||||
FontFamily,
|
||||
};
|
||||
use run_script::ScriptOptions;
|
||||
use std::{
|
||||
collections::BTreeMap,
|
||||
env,
|
||||
@@ -18,52 +24,44 @@ include!(concat!(
|
||||
));
|
||||
|
||||
fn font_stripper(from: &str, out: &str, unicodes: Vec<char>) -> Result<Vec<u8>, String> {
|
||||
let unicodes: Vec<String> = unicodes.iter().map(|c| to_unicode_hash(*c)).collect();
|
||||
let font_path = format!("{}/assets/{}", env!("CARGO_MANIFEST_DIR"), from);
|
||||
let font_data = std::fs::read(&font_path).map_err(|e| e.to_string())?;
|
||||
let scope = ReadScope::new(&font_data);
|
||||
let font_file = scope
|
||||
.read::<AllsortsFontData>()
|
||||
.map_err(|e| format!("Failed to read font data: {}", e))?;
|
||||
let provider = font_file
|
||||
.table_provider(0)
|
||||
.map_err(|e| format!("Failed to get table provider: {}", e))?;
|
||||
let mut font = Font::new(provider).map_err(|e| format!("Failed to create font: {:?}", e))?;
|
||||
|
||||
let mut glyph_ids = Vec::new();
|
||||
for &ch in &unicodes {
|
||||
let mut glyph_ids_curr = font
|
||||
.map_glyphs(
|
||||
&ch.to_string(),
|
||||
tag::LATN,
|
||||
MatchingPresentation::NotRequired,
|
||||
)
|
||||
.into_iter()
|
||||
.map(|glyph| glyph.glyph_index)
|
||||
.collect();
|
||||
|
||||
glyph_ids.append(&mut glyph_ids_curr);
|
||||
}
|
||||
// Include .notdef glyph
|
||||
glyph_ids.push(0);
|
||||
glyph_ids.sort();
|
||||
glyph_ids.dedup();
|
||||
|
||||
let subset_data = subset(&font.font_table_provider, &glyph_ids)
|
||||
.map_err(|e| format!("Failed to subset font: {}", e))?;
|
||||
|
||||
let new_path = [&env::var("OUT_DIR").unwrap(), out].concat();
|
||||
let unicodes_formatted = unicodes
|
||||
.iter()
|
||||
.map(|u| format!("U+{}", u))
|
||||
.collect::<Vec<String>>()
|
||||
.join(",");
|
||||
std::fs::write(&new_path, &subset_data)
|
||||
.map_err(|e| format!("Failed to write subset font: {}", e))?;
|
||||
|
||||
// Test to see if pyftsubset is found
|
||||
let pyftsubset_detect = run_script::run("whereis pyftsubset", &(vec![]), &ScriptOptions::new());
|
||||
match pyftsubset_detect {
|
||||
Ok((_i, s1, _s2)) => {
|
||||
if s1 == "pyftsubset: " {
|
||||
return Err(String::from("pyftsubset not found"));
|
||||
}
|
||||
}
|
||||
// It was not, return an error and abort
|
||||
Err(x) => return Err(x.to_string()),
|
||||
}
|
||||
|
||||
let script_result = run_script::run(
|
||||
&format!(
|
||||
"pyftsubset {}/assets/{} --unicodes={}
|
||||
mv {}/assets/{} {}",
|
||||
env!("CARGO_MANIFEST_DIR"),
|
||||
from,
|
||||
unicodes_formatted,
|
||||
env!("CARGO_MANIFEST_DIR"),
|
||||
from.replace(".ttf", ".subset.ttf"),
|
||||
new_path
|
||||
),
|
||||
&(vec![]),
|
||||
&ScriptOptions::new(),
|
||||
);
|
||||
|
||||
if let Ok((_, _, error)) = script_result {
|
||||
if error.is_empty() {
|
||||
return Ok(std::fs::read(new_path).unwrap());
|
||||
} else {
|
||||
return Err(error);
|
||||
}
|
||||
} else if let Err(error) = script_result {
|
||||
return Err(error.to_string());
|
||||
}
|
||||
unreachable!()
|
||||
Ok(subset_data)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
||||
Reference in New Issue
Block a user