Update truetype

This commit is contained in:
Ivan Ukhov 2022-12-14 19:17:04 +01:00
parent 77eea8c887
commit 0ac2cb08da
3 changed files with 32 additions and 58 deletions

13
Cargo.lock generated
View file

@ -6839,9 +6839,12 @@ checksum = "ce607aae8ab0ab3abf3a2723a9ab6f09bb8639ed83fdd888d857b8e556c868d8"
[[package]] [[package]]
name = "truetype" name = "truetype"
version = "0.30.1" version = "0.40.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "063aa7cf1a7e56677e639c8f180a84d30b8fd788a684cfee2460418629925730" checksum = "7c628aaf2721bbf3082a712649f8735d146f8752189ad5fcbeac4b8a2d9c03cd"
dependencies = [
"typeface",
]
[[package]] [[package]]
name = "try-lock" name = "try-lock"
@ -6881,6 +6884,12 @@ version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0685c84d5d54d1c26f7d3eb96cd41550adb97baed141a761cf335d3d33bcd0ae" checksum = "0685c84d5d54d1c26f7d3eb96cd41550adb97baed141a761cf335d3d33bcd0ae"
[[package]]
name = "typeface"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "716f008359b511ef53d91e103efe33184a417619862736dcc9725126b792ae12"
[[package]] [[package]]
name = "typenum" name = "typenum"
version = "1.15.0" version = "1.15.0"

View file

@ -59,4 +59,4 @@ xml-rs = "0.8"
[target.'cfg(target_os = "windows")'.dependencies] [target.'cfg(target_os = "windows")'.dependencies]
dwrote = "0.11" dwrote = "0.11"
truetype = "0.30" truetype = { version = "0.40.0", features = ["ignore-invalid-language-ids"] }

View file

@ -65,39 +65,6 @@ fn make_tag(tag_bytes: &[u8]) -> FontTableTag {
macro_rules! try_lossy(($result:expr) => ($result.map_err(|_| (()))?)); macro_rules! try_lossy(($result:expr) => ($result.map_err(|_| (()))?));
// Given a set of records, figure out the string indices for the family and face
// names. We want name_id 1 and 2, and we need to use platform_id == 1 and
// language_id == 0 to avoid limitations in the truetype crate. We *could* just
// do our own parsing here, and use the offset/length data and pull the values out
// ourselves.
fn get_family_face_indices(records: &[truetype::naming_table::Record]) -> Option<(usize, usize)> {
let mut family_name_index = None;
let mut face_name_index = None;
for i in 0..records.len() {
// the truetype crate can only decode mac platform format names
if records[i].platform_id != 1 {
continue;
}
if records[i].language_id != 0 {
continue;
}
if records[i].name_id == 1 {
family_name_index = Some(i);
} else if records[i].name_id == 2 {
face_name_index = Some(i);
}
}
if family_name_index.is_some() && face_name_index.is_some() {
Some((family_name_index.unwrap(), face_name_index.unwrap()))
} else {
None
}
}
// We need the font (DWriteFont) in order to be able to query things like // We need the font (DWriteFont) in order to be able to query things like
// the family name, face name, weight, etc. On Windows 10, the // the family name, face name, weight, etc. On Windows 10, the
// DWriteFontFace3 interface provides this on the FontFace, but that's only // DWriteFontFace3 interface provides this on the FontFace, but that's only
@ -118,8 +85,10 @@ struct FontInfo {
impl FontInfo { impl FontInfo {
fn new_from_face(face: &FontFace) -> Result<FontInfo, ()> { fn new_from_face(face: &FontFace) -> Result<FontInfo, ()> {
use std::cmp::{max, min}; use std::cmp::{max, min};
use std::collections::HashMap;
use std::io::Cursor; use std::io::Cursor;
use truetype::{NamingTable, Value, WindowsMetrics}; use truetype::naming_table::{NameID, NamingTable};
use truetype::{Value, WindowsMetrics};
let name_table_bytes = face.get_font_table(make_tag(b"name")); let name_table_bytes = face.get_font_table(make_tag(b"name"));
let os2_table_bytes = face.get_font_table(make_tag(b"OS/2")); let os2_table_bytes = face.get_font_table(make_tag(b"OS/2"));
@ -129,27 +98,23 @@ impl FontInfo {
let mut name_table_cursor = Cursor::new(name_table_bytes.as_ref().unwrap()); let mut name_table_cursor = Cursor::new(name_table_bytes.as_ref().unwrap());
let names = try_lossy!(NamingTable::read(&mut name_table_cursor)); let names = try_lossy!(NamingTable::read(&mut name_table_cursor));
let (family, face) = match names { let mut names: HashMap<_, _> = names
NamingTable::Format0(ref table) => { .iter()
if let Some((family_index, face_index)) = get_family_face_indices(&table.records) { .filter(|((_, language_tag), value)| {
let strings = table.strings().unwrap(); value.is_some() &&
let family = strings[family_index].clone(); language_tag
let face = strings[face_index].clone(); .as_deref()
(family, face) .map_or(false, |language_tag| language_tag.starts_with("en"))
} else { })
return Err(()); .map(|((name_id, _), value)| (name_id, value.unwrap()))
} .collect();
}, let family = match names.remove(&NameID::FontFamilyName) {
NamingTable::Format1(ref table) => { Some(family) => family,
if let Some((family_index, face_index)) = get_family_face_indices(&table.records) { _ => return Err(()),
let strings = table.strings().unwrap(); };
let family = strings[family_index].clone(); let face = match names.remove(&NameID::FontSubfamilyName) {
let face = strings[face_index].clone(); Some(face) => face,
(family, face) _ => return Err(()),
} else {
return Err(());
}
},
}; };
let mut os2_table_cursor = Cursor::new(os2_table_bytes.as_ref().unwrap()); let mut os2_table_cursor = Cursor::new(os2_table_bytes.as_ref().unwrap());