Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parse and use production names from GlyphData.xml #1311

Closed
wants to merge 11 commits into from
Closed
61 changes: 55 additions & 6 deletions glyphs-reader/data/update.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class GlyphInfo:
name: str
category: str
subcategory: Optional[str]
production_name: Optional[str]


def codename(name: Optional[str]) -> Optional[str]:
Expand All @@ -48,6 +49,7 @@ def read_glyph_info(file: str) -> Tuple[GlyphInfo]:
e.attrib["name"].strip(),
codename(e.attrib["category"]),
codename(e.attrib.get("subCategory", None)),
e.attrib.get("production", None),
)
if info.name not in by_name:
by_name[info.name] = info
Expand All @@ -62,7 +64,10 @@ def read_glyph_info(file: str) -> Tuple[GlyphInfo]:
print(f'Ignoring alt name "{alt_name}", already taken')
continue
by_name[alt_name] = dataclasses.replace(
by_name[e.attrib["name"]], name=alt_name, codepoint=None
by_name[e.attrib["name"]],
name=alt_name,
codepoint=None,
production_name=None,
)

return tuple(by_name.values())
Expand Down Expand Up @@ -121,6 +126,20 @@ def main():
f"Multiple names are assigned 0x{codepoint:04x}, using the first one we saw"
)

production_names = []
production_name_to_info_idx = {}
for i, gi in enumerate(glyph_infos):
if gi.production_name is None:
production_names.append("")
continue
production_names.append(gi.production_name)
if gi.production_name in production_name_to_info_idx:
print(
f"Multiple names are assigned {gi.production_name}, using the first one we saw"
)
else:
production_name_to_info_idx[gi.production_name] = i

dest_file = Path(__file__).parent.parent / "src" / "glyphslib_data.rs"

with open(dest_file, "w") as f:
Expand All @@ -131,7 +150,7 @@ def main():
f.write(f"//! {len(glyph_infos)} glyph metadata records taken from glyphsLib\n")
f.write("\n")
f.write(
"use crate::glyphdata::{qr, q1, q2, q3, Category, QueryResult, Subcategory};\n"
"use crate::glyphdata::{qr, q1, q2, q3, Category, QueryPartialResult, Subcategory};\n"
)
f.write("\n")

Expand All @@ -143,7 +162,7 @@ def main():

f.write("// Sorted by name, has unique names, therefore safe to bsearch\n")

f.write("pub(crate) const GLYPH_INFO: &[(&str, QueryResult)] = &[\n")
f.write("pub(crate) const GLYPH_INFO: &[(&str, QueryPartialResult)] = &[\n")
lines = [""]
for gi in glyph_infos:
category = min_categories[gi.category]
Expand All @@ -165,9 +184,6 @@ def main():
if gi.codepoint is not None:
codepoint = f"Some(0x{gi.codepoint})"

subcategory = "None"
if gi.subcategory is not None:
subcategory = f"Some({min_subcategories[gi.subcategory]})"
fragment = f'("{gi.name}", {entry}),'
if (len(lines[-1]) + len(fragment)) > 100:
lines[-1] += "\n"
Expand Down Expand Up @@ -196,6 +212,39 @@ def main():
f.write("\n")
f.write("];\n")

f.write("// Sorted by name, has unique names, therefore safe to bsearch\n")
f.write("pub(crate) const PRODUCTION_NAMES: &[&str] = &[\n")
lines = [""]
assert len(glyph_infos) == len(production_names)
for production_name in production_names:
fragment = f'"{production_name}",'
if (len(lines[-1]) + len(fragment)) > 100:
lines[-1] += "\n"
lines.append("")
lines[-1] += fragment

for line in lines:
f.write(line)
f.write("\n")
f.write("];\n")

f.write(
"// Sorted by production name, has unique production names, therefore safe to bsearch\n"
)
f.write("pub(crate) const PRODUCTION_NAME_TO_INFO_IDX: &[(&str, usize)] = &[\n")
lines = [""]
for name, i in sorted(production_name_to_info_idx.items()):
fragment = f'("{name}", {i}),'
if (len(lines[-1]) + len(fragment)) > 100:
lines[-1] += "\n"
lines.append("")
lines[-1] += fragment

for line in lines:
f.write(line)
f.write("\n")
f.write("];\n")


if __name__ == "__main__":
main()
7 changes: 6 additions & 1 deletion glyphs-reader/src/font.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,7 @@ pub struct Glyph {
pub right_kern: Option<SmolStr>,
pub category: Option<Category>,
pub sub_category: Option<Subcategory>,
pub production_name: Option<SmolStr>,
}

impl Glyph {
Expand Down Expand Up @@ -781,6 +782,7 @@ struct RawGlyph {
unicode: Option<String>,
category: Option<SmolStr>,
sub_category: Option<SmolStr>,
production_name: Option<SmolStr>,
#[fromplist(ignore)]
other_stuff: BTreeMap<String, Plist>,
}
Expand Down Expand Up @@ -2111,17 +2113,19 @@ impl RawGlyph {

let mut category = parse_category(self.category.as_deref(), &self.glyphname);
let mut sub_category = parse_category(self.sub_category.as_deref(), &self.glyphname);
let mut production_name = self.production_name;

let codepoints = self
.unicode
.map(|s| parse_codepoint_str(&s, codepoint_radix))
.unwrap_or_default();

if category.is_none() || sub_category.is_none() {
if category.is_none() || sub_category.is_none() || production_name.is_none() {
if let Some(result) = glyph_data.query(&self.glyphname, Some(&codepoints)) {
// if they were manually set don't change them, otherwise do
category = category.or(Some(result.category));
sub_category = sub_category.or(result.subcategory);
production_name = production_name.or(result.production_name.map(SmolStr::new));
}
}

Expand All @@ -2134,6 +2138,7 @@ impl RawGlyph {
unicode: codepoints,
category,
sub_category,
production_name,
})
}
}
Expand Down
Loading