{"record":{"id":"b67cf650eff8d568","repo":"subframe7536/maple-font","slug":"this-script-only-supports-truetype-glyf-fonts-c","errorCode":null,"errorMessage":"This script only supports TrueType (glyf) fonts. CFF support not implemented.","messagePattern":"This script only supports TrueType \\(glyf\\) fonts\\. CFF support not implemented\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"source/py/task/merge_font/utils.py","lineNumber":181,"sourceCode":"    \"\"\"Get (yMin, yMax) of a glyph by name from 'glyf' table.\"\"\"\n    glyph_order = font.getGlyphOrder()\n    if glyph_name not in glyph_order:\n        raise ValueError(f\"Glyph '{glyph_name}' not found in font.\")\n    glyf = font[\"glyf\"]\n    glyph = glyf[glyph_name]\n    if glyph.numberOfContours == 0:\n        # Empty glyph\n        return (0, 0)\n    y_min = glyph.yMin\n    y_max = glyph.yMax\n    return (y_min, y_max)\n\n\ndef auto_xheight_capheight(font: TTFont):\n    if \"OS/2\" not in font:\n        raise ValueError(\"Font does not have an OS/2 table.\")\n    if \"glyf\" not in font:\n        raise ValueError(\n            \"This script only supports TrueType (glyf) fonts. CFF support not implemented.\"\n        )\n\n    try:\n        # Get bounds\n        z_ymin, z_ymax = _get_glyph_bounds(font, \"z\")\n        Z_ymin, Z_ymax = _get_glyph_bounds(font, \"Z\")\n\n        x_height = round(z_ymax)  # xHeight = top of lowercase 'z'\n        cap_height = round(Z_ymax)  # capHeight = top of uppercase 'Z'\n\n        # Update OS/2 table\n        os2 = font[\"OS/2\"]\n        os2.sxHeight = x_height  # type: ignore\n        os2.sCapHeight = cap_height  # type: ignore\n    except Exception as e:\n        print(e)\n","sourceCodeStart":163,"sourceCodeEnd":199,"githubUrl":"https://github.com/subframe7536/maple-font/blob/c08fda97fef73d68c1755219852150770f6e6578/source/py/task/merge_font/utils.py#L163-L199","documentation":"auto_xheight_capheight() reads glyph outlines from the 'glyf' table (TrueType outlines) via _get_glyph_bounds. If the font uses CFF/PostScript outlines ('CFF ' table instead of 'glyf'), it raises this ValueError because CFF support is not implemented in this script.","triggerScenarios":"Running polish() on an OTF (CFF-flavored) font or any TTFont lacking a 'glyf' table while auto x-height computation is enabled.","commonSituations":"Feeding .otf CFF fonts (e.g. Adobe-sourced fonts) into a pipeline designed for .ttf; fonts converted to CFF; mixed inputs where some family members are CFF.","solutions":["Convert the CFF font to TrueType outlines (e.g. fontTools cu2qu: fontTools.ttLib with cu2qu or `otf2ttf`) before processing.","Use a TTF source of the same font instead of the OTF.","Guard the call: only run auto_xheight_capheight when 'glyf' in font."],"exampleFix":"# before\npython merge_font.py --input Font.otf\n\n# after\n# convert CFF to glyf first\nfrom fontTools.ttLib import TTFont\nf = TTFont(\"Font.otf\")\nf.flavor = None  # then run cu2qu-based otf2ttf conversion\n# or simply use Font.ttf","handlingStrategy":"validation","validationCode":"if \"glyf\" not in font:\n    # convert CFF -> TrueType first, e.g. with cu2qu-based otf2ttf\n    raise RuntimeError(f\"{font.reader.file.name} is CFF; convert to TTF before processing\")","typeGuard":"def is_truetype_outline(font) -> bool:\n    return \"glyf\" in font and \"CFF \" not in font","tryCatchPattern":"try:\n    auto_xheight_capheight(font)\nexcept ValueError as e:\n    if \"glyf\" in str(e):\n        font = otf2ttf(font)  # convert outlines then retry\n        auto_xheight_capheight(font)\n    else:\n        raise","preventionTips":["Normalize all inputs to TTF/TrueType outlines at the start of the pipeline.","Reject .otf/CFF inputs early with a clear message.","Keep an otf2ttf (cu2qu) conversion step available in the build toolchain."],"tags":["python","fonts","cff","truetype","fonttools"],"backgroundTag":"cff-not-supported","analyzedSha":"c08fda97fef73d68c1755219852150770f6e6578","analyzedAt":"2026-08-28T22:07:29.503Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}