Skip to content

Commit

Permalink
Compile meta from ufo sources
Browse files Browse the repository at this point in the history
  • Loading branch information
cmyr committed Dec 3, 2024
1 parent c1ebad0 commit d6d9f73
Show file tree
Hide file tree
Showing 7 changed files with 143 additions and 3 deletions.
2 changes: 1 addition & 1 deletion fontir/src/ir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ impl Panose {
///
/// [meta]: https://learn.microsoft.com/en-us/typography/opentype/spec/meta
/// [dlng slng]: https://learn.microsoft.com/en-us/typography/opentype/spec/meta#dlng-and-slng-design-and-supported-languages
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
#[derive(Serialize, Deserialize, Default, Debug, Clone, PartialEq, Eq)]
pub struct MetaTableValues {
/// ScriptLangTags for the design languages
pub dlng: Vec<SmolStr>,
Expand Down
38 changes: 38 additions & 0 deletions resources/testdata/MetaTable.ufo/fontinfo.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>unitsPerEm</key>
<integer>1000</integer>
<key>familyName</key>
<string>Duck Duck</string>
<key>styleName</key>
<string>Regular</string>
<key>openTypeOS2VendorID</key>
<string>RODS</string>
<key>ascender</key>
<integer>737</integer>
<key>capHeight</key>
<integer>702</integer>
<key>descender</key>
<integer>-42</integer>
<key>xHeight</key>
<integer>501</integer>
<key>openTypeOS2TypoAscender</key>
<integer>1193</integer>
<key>openTypeOS2TypoDescender</key>
<integer>-289</integer>
<key>openTypeOS2TypoLineGap</key>
<integer>42</integer>
<key>openTypeOS2WinAscent</key>
<integer>1325</integer>
<key>openTypeOS2WinDescent</key>
<integer>377</integer>
<key>openTypeHheaAscender</key>
<integer>1194</integer>
<key>openTypeHheaDescender</key>
<integer>-290</integer>
<key>openTypeHheaLineGap</key>
<integer>43</integer>
</dict>
</plist>
6 changes: 6 additions & 0 deletions resources/testdata/MetaTable.ufo/glyphs/contents.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
</dict>
</plist>
10 changes: 10 additions & 0 deletions resources/testdata/MetaTable.ufo/layercontents.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
<array>
<string>public.default</string>
<string>glyphs</string>
</array>
</array>
</plist>
19 changes: 19 additions & 0 deletions resources/testdata/MetaTable.ufo/lib.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>public.openTypeMeta</key>
<dict>
<key>dlng</key>
<array>
<string>en-latn</string>
<string>fr-latn</string>
<string>nl-Latn</string>
</array>
<key>slng</key>
<array>
<string>Latn,Cyrl</string>
</array>
</dict>
</dict>
</plist>
10 changes: 10 additions & 0 deletions resources/testdata/MetaTable.ufo/metainfo.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>creator</key>
<string>com.github.fonttools.ufoLib</string>
<key>formatVersion</key>
<integer>3</integer>
</dict>
</plist>
61 changes: 59 additions & 2 deletions ufo2fontir/src/source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ use fontir::{
error::{BadSource, BadSourceKind, Error},
ir::{
AnchorBuilder, FeaturesSource, GdefCategories, GlobalMetric, GlobalMetrics, GlyphOrder,
KernGroup, KernSide, KerningGroups, KerningInstance, NameBuilder, NameKey, NamedInstance,
Panose, PostscriptNames, StaticMetadata, DEFAULT_VENDOR_ID,
KernGroup, KernSide, KerningGroups, KerningInstance, MetaTableValues, NameBuilder, NameKey,
NamedInstance, Panose, PostscriptNames, StaticMetadata, DEFAULT_VENDOR_ID,
},
orchestration::{Context, Flags, IrWork, WorkId},
source::{Input, Source},
Expand Down Expand Up @@ -1019,6 +1019,10 @@ impl Work<Context, WorkId, Error> for StaticMetadataWork {
try_parse_date(font_info_at_default.open_type_head_created.as_ref())
.or(static_metadata.misc.created);

static_metadata.misc.meta_table = lib_plist
.get("public.openTypeMeta")
.and_then(parse_meta_table_values);

context.preliminary_glyph_order.set(glyph_order);
context.static_metadata.set(static_metadata);
Ok(())
Expand All @@ -1030,6 +1034,39 @@ fn is_glyph_only(source: &norad::designspace::Source) -> bool {
source.layer.is_some()
}

fn parse_meta_table_values(plist: &plist::Value) -> Option<MetaTableValues> {
let plist = plist.as_dictionary()?;
let mut ret = MetaTableValues::default();
for (key, value) in plist {
match key.as_str() {
"dlng" => ret.dlng = parse_meta_scriptlangtags(value).map(Into::into).collect(),
"slng" => ret.slng = parse_meta_scriptlangtags(value).map(Into::into).collect(),
other => log::warn!("unhandled meta table tag '{other}'"),
}
}
if ret.dlng.len() + ret.slng.len() > 0 {
Some(ret)
} else {
None
}
}

fn parse_meta_scriptlangtags(plist: &plist::Value) -> impl Iterator<Item = &str> {
plist
.as_array()
.into_iter()
.flatten()
.filter_map(|val| val.as_string())
// although the spec[1] says that this should be an array of strs and each
// str should be a scriptlangtag, in practice[2] it seems like it often
// ends up stored as a single comma-separated list of scriptlangtag
//
// 1: https://unifiedfontobject.org/versions/ufo3/lib.plist/#publicopentypemeta
// 2: https://github.com/aaronbell/LxgwWenkaiTC/blob/fe7a4b88e91a02c097d69ba/sources/LXGWWenKaiTC-Regular.ufo/lib.plist#L1798-L1808
.flat_map(|s| s.split(','))
.map(str::trim)
}

fn set_default_underline_pos(
metrics: &mut GlobalMetrics,
location: &NormalizedLocation,
Expand Down Expand Up @@ -2375,4 +2412,24 @@ mod tests {
let expected: Panose = [2_u8, 11, 5, 2, 4, 5, 4, 2, 2, 4].into();
assert_eq!(Some(expected), static_metadata.misc.panose);
}

#[test]
fn parse_meta_table_values() {
let (_, context) = build_static_metadata("MetaTable.ufo", default_test_flags());
let static_meta = context.static_metadata.get();
let meta_table = static_meta.misc.meta_table.as_ref().unwrap();
assert_eq!(meta_table.dlng, ["en-latn", "fr-latn", "nl-Latn"]);
assert_eq!(meta_table.slng, ["Latn", "Cyrl"]);
}

#[test]
fn ignore_empty_meta_table_values() {
let mut plist = plist::Dictionary::new();
plist.insert(
"public.openTypeMeta".into(),
plist::Value::Array(Default::default()),
);

assert!(super::parse_meta_table_values(&plist::Value::Dictionary(plist)).is_none())
}
}

0 comments on commit d6d9f73

Please sign in to comment.