{"record":{"id":"beb7a0d46f0d4775","repo":"subframe7536/maple-font","slug":"no-hhea-table-found-beb7a0","errorCode":null,"errorMessage":"No hhea table found.","messagePattern":"No hhea table found\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"source/py/utils.py","lineNumber":415,"sourceCode":"    axisValRec = ot.AxisValue()  # type: ignore\n    axisValRec.AxisIndex = axis.AxisOrdering\n    axisValRec.Flags = 0\n    axisValRec.Format = 1\n    axisValRec.ValueNameID = id\n    axisValRec.Value = 1.0\n    stat_table.AxisValueArray.AxisValue.append(axisValRec)\n    stat_table.AxisValueCount += 1\n\n\ndef adjust_line_height(\n    font: TTFont, factor: float, metric: tuple[float, float]\n) -> None:\n    \"\"\"\n    Adjust the line height of the font by modifying the hhea and OS/2 table.\n    \"\"\"\n\n    if \"hhea\" not in font:\n        raise ValueError(\"No hhea table found.\")\n    if \"OS/2\" not in font:\n        raise ValueError(\"No OS/2 table found.\")\n\n    head = font[\"head\"]\n    hhea = font[\"hhea\"]\n    os2 = font[\"OS/2\"]\n\n    asc, desc = metric\n    # Maintain original ascender/descender ratio\n    ascender_ratio = asc / (asc - desc)  # type: ignore\n    # Calculate target total height\n    target_total_height = int(round(factor * (asc - desc)))\n\n    # Calculate new metrics\n    new_ascender = int(round(target_total_height * ascender_ratio))\n    new_descender = new_ascender - target_total_height\n\n    print(f\"Change vertical metric to [{new_ascender}, {new_descender}]\")","sourceCodeStart":397,"sourceCodeEnd":433,"githubUrl":"https://github.com/subframe7536/maple-font/blob/c08fda97fef73d68c1755219852150770f6e6578/source/py/utils.py#L397-L433","documentation":"adjust_line_height rewrites line-height metrics and requires both the hhea and OS/2 tables to be present in the fontTools font object. This ValueError is raised when the 'hhea' table is missing, meaning the loaded font is malformed or of a type that lacks horizontal header metrics. It fails fast instead of silently writing partial metrics.","triggerScenarios":"Calling adjust_line_height (via build_nf, build_cn, or build_variable_fonts) on a font object where \"hhea\" not in font — e.g. a CFF/OTF variant stripped of hhea, a corrupted font file, or passing a non-TTF/incorrectly converted font object.","commonSituations":"Supplying a source font that lost its hhea table during conversion; pointing the build at a non-font or heavily subsetted font; using a font produced by a tool that dropped hhea; passing the wrong object (not a TTFont with tables loaded).","solutions":["Load the font with fontTools TTFont and ensure the hhea table exists: check `\"hhea\" in font` before calling.","Re-export or repair the source font so it includes an hhea table (e.g. via fonttools ttLib or a font editor).","Verify the build input path points at the correct TTF source, not a subsetted/stripped artifact.","Upgrade fontTools if an old version failed to read the table from a valid font."],"exampleFix":"// before\n# adjust_line_height(font, metric)  # raises if hhea missing\n// after\nfrom fontTools.ttLib import TTFont\n# font = TTFont(path)  # ensure proper load\n# if \"hhea\" not in font: raise RuntimeError(f\"{path} lacks hhea table\")\n# adjust_line_height(font, metric)","handlingStrategy":"type-guard","validationCode":"from fontTools.ttLib import TTFont\n\ndef require_tables(path, tables=(\"hhea\", \"OS/2\")):\n    font = TTFont(path)\n    missing = [t for t in tables if t not in font]\n    if missing:\n        raise ValueError(f\"{path} missing tables: {missing}\")\n    return font","typeGuard":"def has_hhea(font) -> bool:\n    return \"hhea\" in font  # fontTools TTFont supports __contains__","tryCatchPattern":"try:\n    adjust_line_height(font, metric)\nexcept ValueError as e:\n    if str(e) == \"No hhea table found.\":\n        raise RuntimeError(\"Input font is malformed: rebuild it with fontTools\") from e\n    raise","preventionTips":["Always load fonts via fontTools.ttLib.TTFont, never hand-built objects.","Check required tables (hhea, OS/2) right after loading any external font.","Don't feed subsetted/stripped fonts into line-height adjustment.","Keep fontTools up to date so valid tables parse correctly."],"tags":["font","fonttools","line-height","missing-table"],"backgroundTag":"missing-font-table","analyzedSha":"c08fda97fef73d68c1755219852150770f6e6578","analyzedAt":"2026-08-28T22:07:29.503Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}