You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Follow-up to #99. The font specimen preview now renders a fixed Repertoire grid of common glyphs. A glyph the font lacks falls back to the browser default rather than being hidden, and glyphs the font does have beyond the fixed list aren't shown. This issue tracks making the grid coverage-accurate: show exactly the glyphs the font contains, like macOS Font Book, so nothing tofus and nothing is missing.
Approach
We already fetch the font's ArrayBuffer in FontPreview (fetchFileBytes), so the parse can happen client-side.
Core: read the font's own cmap table and render only the codepoints it maps.
opentype.js exposes parse(buffer).tables.cmap.glyphIndexMap (every mapped codepoint) for .ttf/.otf/.woff.
The catch:.woff2 (the primary format in Render a font specimen when previewing font files (.woff2/.woff/.ttf/.otf) #99, and the most common web font) is Brotli-compressed and opentype.js can't decompress it. You need either a woff2→sfnt wasm decoder (wawoff2, ~300 KB wasm) on top of opentype.js, orfontkit, which handles all formats incl. woff2 in one dependency (heavier).
Recommended shape
fontkit, lazy-loaded in a Web Worker. One dep covers ttf/otf/woff/woff2; lazy import() keeps it off the main bundle (previewing a font is rare); the worker keeps multi-MB parsing off the main thread (reuse the existing layout-worker pattern).
Extract → filter → group. From the codepoint list: drop control/whitespace/unassigned, then group by Unicode block with headers (Basic Latin, Latin-1 Supplement, ...) so it reads like Font Book's sectioned view instead of a flat wall.
Cap huge fonts, visibly. A CJK font can map 20k+ glyphs. Virtualize the grid, or cap with a labeled "showing N of M" note. No silent truncation.
Graceful fallback. On parse failure or an unsupported format, fall back to the current fixed repertoire. Strictly additive: never regresses what works today.
Edge cases (mostly free)
Variable / color fonts: cmap enumerates fine.
Ligatures / stylistic alternates reached via GSUB (not in cmap): Font Book's character view doesn't show these either, so parity holds.
Symbol/Mac cmap subtables: handle multiple platform/encoding records (fontkit does this).
Bundle: zero main-bundle cost; a lazy chunk (~few hundred KB) loads only when previewing a font.
Decisions: fontkit (all formats, heavier) vs opentype.js + woff2-wasm (modular, more glue); grouped-by-block vs flat grid; virtualize vs cap+note for giant fonts.
Recommendation: fontkit + lazy worker + block grouping + fallback — cleanest path to real Font Book parity across every format #99 names.
Follow-up to #99. The font specimen preview now renders a fixed Repertoire grid of common glyphs. A glyph the font lacks falls back to the browser default rather than being hidden, and glyphs the font does have beyond the fixed list aren't shown. This issue tracks making the grid coverage-accurate: show exactly the glyphs the font contains, like macOS Font Book, so nothing tofus and nothing is missing.
Approach
We already fetch the font's
ArrayBufferinFontPreview(fetchFileBytes), so the parse can happen client-side.Core: read the font's own
cmaptable and render only the codepoints it maps.opentype.jsexposesparse(buffer).tables.cmap.glyphIndexMap(every mapped codepoint) for.ttf/.otf/.woff..woff2(the primary format in Render a font specimen when previewing font files (.woff2/.woff/.ttf/.otf) #99, and the most common web font) is Brotli-compressed andopentype.jscan't decompress it. You need either a woff2→sfnt wasm decoder (wawoff2, ~300 KB wasm) on top of opentype.js, orfontkit, which handles all formats incl. woff2 in one dependency (heavier).Recommended shape
fontkit, lazy-loaded in a Web Worker. One dep covers ttf/otf/woff/woff2; lazyimport()keeps it off the main bundle (previewing a font is rare); the worker keeps multi-MB parsing off the main thread (reuse the existing layout-worker pattern).Edge cases (mostly free)
Cost / open choices
Recommendation: fontkit + lazy worker + block grouping + fallback — cleanest path to real Font Book parity across every format #99 names.