instantiateVariableFont() in current fontTools doesn't accept a
`static` parameter (signature: varfont, axisLimits, inplace=False,
optimize=True, overlap=…, updateFontNames=False, *, downgradeCFF2=False).
Calling it with static=True raises TypeError, breaking
extract_static_instance() for any sd-fonts.yaml entry that uses the
`variable: {wght: …}` form.
Drop the unsupported kwarg; keep updateFontNames=True (name table
accuracy) and optimize=False (skip wasted gvar work when every axis
is fully pinned). The output is still a fully-pinned static instance
because all yaml-declared axes are pinned in `axes`.
Script-range boundaries alone don't bound group size — dense Unicode
blocks (CJK, user fonts) can produce groups of hundreds of KB. Add a
64 KB hard cap: when adding the next glyph would exceed it, close the
current group and start a new one with the same script ID.
64 KB is well above the largest current built-in group (~50 KB for
notosans_18 Cyrillic) and a safe transient malloc on the ESP32-C3.
The decompressor side already handles any number of groups per font.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The hot group buffer (formerly up to 50 KB BSS / heap) is removed.
During prewarm, each group is now decompressed into a transient malloc
that is freed immediately after its glyphs are extracted — only one
group buffer and the page buffer coexist at a time.
For getBitmap() cache misses (rare: only hit when a glyph wasn't
covered by prewarm), the group is also decompressed transiently and
freed after the single glyph is compacted into _hotGlyphBuf.
Peak heap during prewarm is now: page buffer + one group buffer.
Outside of prewarm, heap usage is only the page buffer itself.
Works correctly for large future fonts (Vietnamese, CJK) regardless
of group size, with no permanent allocation overhead.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>