From 8395d6116f4e528bb68acf36d2789c4ec4864cc6 Mon Sep 17 00:00:00 2001 From: Harry Dalton Date: Tue, 5 Nov 2024 23:29:05 +0000 Subject: [PATCH] Include empty glyphs when calculating max width, to match fonttools Most fields in `hhea` are set based on glyphs with bounds: https://github.com/fonttools/fonttools/blob/e04dfaab/Lib/fontTools/ttLib/tables/_h_h_e_a.py#L101-L119 but `advanceWidthMax` is an exception to this, as it considers every glyph that has an entry in the `hmtx` table: https://github.com/fonttools/fonttools/blob/e04dfaab/Lib/fontTools/ttLib/tables/_h_h_e_a.py#L73 --- fontbe/src/metrics_and_limits.rs | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/fontbe/src/metrics_and_limits.rs b/fontbe/src/metrics_and_limits.rs index a0403969..9a46fbb8 100644 --- a/fontbe/src/metrics_and_limits.rs +++ b/fontbe/src/metrics_and_limits.rs @@ -81,6 +81,9 @@ impl GlyphLimits { impl FontLimits { fn update(&mut self, id: GlyphId16, advance: u16, glyph: &Glyph) { + // max advance width should consider every glyph that has an hmtx entry + self.advance_width_max = max(self.advance_width_max, advance); + // min side bearings are only for non-empty glyphs // we will presume only simple glyphs with no contours are empty if let Some(bbox) = glyph.data.bbox() { @@ -103,7 +106,6 @@ impl FontLimits { .x_max_extent .map(|v| max(v, bbox.x_max)) .or(Some(bbox.x_max)); - self.advance_width_max = max(self.advance_width_max, advance); self.bbox = self.bbox.map(|b| b.union(bbox)).or(Some(bbox)); } @@ -385,4 +387,19 @@ mod tests { ) ); } + + #[test] + fn empty_glyph_contributes_to_max() { + let width = 123u16; + + // confirm that empty glyphs still contribute to the advance_width_max + // field, as they will still originate an hmtx entry + let mut glyph_limits = FontLimits::default(); + glyph_limits.update( + GlyphId16::NOTDEF, + width, + &crate::orchestration::Glyph::new("empty".into(), RawGlyph::Empty), + ); + assert_eq!(width, glyph_limits.advance_width_max); + } }