subframe7536/maple-font · warning · ValueError

Glyph '{glyph_name}' not found in font.

Error message

Glyph '{glyph_name}' not found in font.

What it means

_get_glyph_bounds() reads yMin/yMax of a named glyph (used for 'z' and 'Z' to derive x-height/cap-height). It first checks font.getGlyphOrder(); if the requested glyph name is absent from the font's glyph set it raises this ValueError. This is an internal helper of auto_xheight_capheight.

Source

Thrown at source/py/task/merge_font/utils.py:166

        max_value = a.maxValue
        val = config.get(axis_tag, a.defaultValue)
        if min_value > val or max_value < val:
            raise Exception(f"Invalid axe value, range: [{min_value}, {max_value}]")
        coordinates[axis_tag] = val

    instance.coordinates = coordinates

    static_font, file_base_name = var2static(f, instance)
    static_font.save(output_font_path)
    static_font.close()
    f.close()


def _get_glyph_bounds(font, glyph_name):
    """Get (yMin, yMax) of a glyph by name from 'glyf' table."""
    glyph_order = font.getGlyphOrder()
    if glyph_name not in glyph_order:
        raise ValueError(f"Glyph '{glyph_name}' not found in font.")
    glyf = font["glyf"]
    glyph = glyf[glyph_name]
    if glyph.numberOfContours == 0:
        # Empty glyph
        return (0, 0)
    y_min = glyph.yMin
    y_max = glyph.yMax
    return (y_min, y_max)


def auto_xheight_capheight(font: TTFont):
    if "OS/2" not in font:
        raise ValueError("Font does not have an OS/2 table.")
    if "glyf" not in font:
        raise ValueError(
            "This script only supports TrueType (glyf) fonts. CFF support not implemented."
        )

View on GitHub (pinned to c08fda97fe)

Solutions

  1. Ensure the font includes the Latin lowercase 'z' and uppercase 'Z' glyphs before running polish().
  2. If working with a subset/custom-named font, extend _get_glyph_bounds to map via cmap (font.getBestCmap()[ord('z')]) instead of fixed names.
  3. Since auto_xheight_capheight swallows the error, manually set OS/2 sxHeight/sCapHeight if the glyphs are genuinely missing.

Example fix

# before
z_ymin, z_ymax = _get_glyph_bounds(font, "z")

# after
cmap = font.getBestCmap()
if ord('z') in cmap:
    z_ymin, z_ymax = _get_glyph_bounds(font, cmap[ord('z')])
else:
    return  # or fall back to default metrics
Defensive patterns

Strategy: validation

Validate before calling

order = set(font.getGlyphOrder())
assert "z" in order and "Z" in order, "font lacks z/Z glyphs needed for x-height/cap-height"

Type guard

def has_latin_z_glyphs(font) -> bool:
    order = set(font.getGlyphOrder())
    return "z" in order and "Z" in order

Try / catch

try:
    _get_glyph_bounds(font, "z")
except ValueError as e:
    cmap = font.getBestCmap()
    gname = cmap.get(ord("z"))
    bounds = _get_glyph_bounds(font, gname) if gname else (0, 0)

Prevention

When it happens

Trigger: auto_xheight_capheight() calls it with "z" or "Z" and the font's glyph order does not contain a glyph named exactly 'z' or 'Z' (e.g. CJK-only font, subset font, or a font using non-standard/unencoded glyph naming).

Common situations: Merging or polishing subset fonts that lack Latin glyphs; fonts whose glyphs are named 'uni007A' style or use CFF-style naming; icon fonts; auto_xheight_capheight catches exceptions and only prints them, so the ValueError may surface as a printed message and OS/2 sxHeight/sCapHeight left stale.

Related errors


AI-assisted analysis of subframe7536/maple-font@c08fda97fe (2026-08-28). Data as JSON: /api/errors/7fe9625e71fd3e77. Report an issue: GitHub.