@weasel-js/font 1.15.0 → 1.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-SP6N5MJQ.js → chunk-I7OQG2DF.js} +49 -2
- package/dist/chunk-I7OQG2DF.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/{test-seams-BIu4iq6A.d.ts → test-seams-DUZZDLT-.d.ts} +11 -0
- package/dist/test-seams.d.ts +1 -1
- package/dist/test-seams.js +1 -1
- package/package.json +2 -2
- package/dist/chunk-SP6N5MJQ.js.map +0 -1
package/dist/test-seams.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { a6 as __setGlyphRasterizerForTests, a7 as _getPagesForTests, a8 as _resetDomFacesForTests, a9 as _resetDynamicFontsForTests, aa as _resetFallbackForTests, ab as _resetFontOutlinesForTests, ac as _resetFontRegistryForTests } from './test-seams-
|
|
1
|
+
export { a6 as __setGlyphRasterizerForTests, a7 as _getPagesForTests, a8 as _resetDomFacesForTests, a9 as _resetDynamicFontsForTests, aa as _resetFallbackForTests, ab as _resetFontOutlinesForTests, ac as _resetFontRegistryForTests } from './test-seams-DUZZDLT-.js';
|
|
2
2
|
import '@weasel-js/registry';
|
|
3
3
|
import './fontStyle-D1y21YZ9.js';
|
package/dist/test-seams.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { __setGlyphRasterizerForTests, _getPagesForTests, _resetDomFacesForTests, _resetDynamicFontsForTests, _resetFallbackForTests, _resetFontOutlinesForTests, _resetFontRegistryForTests } from './chunk-
|
|
1
|
+
export { __setGlyphRasterizerForTests, _getPagesForTests, _resetDomFacesForTests, _resetDynamicFontsForTests, _resetFallbackForTests, _resetFontOutlinesForTests, _resetFontRegistryForTests } from './chunk-I7OQG2DF.js';
|
|
2
2
|
import './chunk-XQPRAGHF.js';
|
|
3
3
|
//# sourceMappingURL=test-seams.js.map
|
|
4
4
|
//# sourceMappingURL=test-seams.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@weasel-js/font",
|
|
3
|
-
"version": "1.15.
|
|
3
|
+
"version": "1.15.1",
|
|
4
4
|
"description": "MSDF font atlases, glyph metrics, and runtime glyph rasterization for @weasel-js/core. Registry, kerning-aware glyph layout, and the SDF text shader source.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"provenance": true
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
|
-
"@weasel-js/registry": "1.15.
|
|
53
|
+
"@weasel-js/registry": "1.15.1",
|
|
54
54
|
"opentype.js": "2.0.0"
|
|
55
55
|
}
|
|
56
56
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/textureCacheKey.ts","../src/glyphReady.ts","../src/fallback.ts","../src/dynamic/dynamicPages.ts","../src/dynamic/shelfPack.ts","../src/dynamic/distanceTransform.ts","../src/dynamic/bakeQueue.ts","../src/dynamic/glyphRasterizer.ts","../src/dynamic/sharpColor.ts","../src/dynamic/fontLoads.ts","../src/dynamic/dynamicAtlas.ts","../src/outline/OutlineFace.ts","../src/outline/tag.ts","../src/outline/dataFork.ts","../src/outline/sfnt.ts","../src/outline/gposKerning.ts","../src/outline/opentypeParser.ts","../src/outline/outlineRegistry.ts","../src/variantKey.ts","../src/atlasResult.ts","../src/registerFont.ts","../src/domFace.ts"],"names":["last","generation","faces","forgetGlyphs","names","view","tag","warnOnce","warned","createReflectable","settle","pending","policy"],"mappings":"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","file":"chunk-SP6N5MJQ.js","sourcesContent":["import type { FontStyle } from './fontStyle';\n\nlet last = { family: '', weight: NaN, style: '', key: '' };\n\n/** The texture cache key used by `ensureFontTexture` for a given variant. */\nexport function textureCacheKey(family: string, weight: number, style: FontStyle): string {\n // Asked for every glyph group the renderer draws, every frame, and nearly\n // always for the same face as the last call.\n if (last.family === family && last.weight === weight && last.style === style) return last.key;\n last = { family, weight, style, key: `${family}|${weight}|${style}` };\n return last.key;\n}\n","/**\n * \"A glyph the renderer asked for can now paint\" — the redraw signal shared\n * by every asynchronous glyph source. Both lazy tiers land their work after\n * the frame that asked for it, so both have to tell the canvas to draw again.\n */\n\nimport { createEmitter } from '@weasel-js/registry';\n\nlet ready = createEmitter();\n\n/** Advanced by every `notifyGlyphReady`, so state can be checked rather than\n * listened for. See {@link glyphGeneration}. */\nlet generation = 0;\n\n/**\n * How many times glyph availability has changed — the pull-based companion to\n * {@link subscribeGlyphReady}, for caches that cannot hold a subscription.\n * Subscribing at module load makes a consumer partially mocking\n * `@weasel-js/font` break at import rather than at use.\n *\n * Callers keep the last value they saw and compare; any difference means\n * anything derived from font metrics is stale. The absolute value carries no\n * meaning and may wrap in principle — compare with `!==`, not `<`.\n */\nexport function glyphGeneration(): number {\n return generation;\n}\n\n/**\n * Subscribe to glyph availability. Fires after a batch of deferred SDF bakes\n * completes, and when an atlas or outline face finishes loading — text that\n * painted nothing (or painted from a lower tier) can now paint. Also fires\n * when such a load fails, since text laid out while it was pending is stale\n * either way. Returns an unsubscribe.\n */\nexport function subscribeGlyphReady(cb: () => void): () => void {\n return ready.subscribe(cb);\n}\n\n/** Advanced by every `notifyGlyphReady` and by no `notifyGlyphBaked`. */\nlet faces = 0;\n\n/**\n * How many times the faces themselves have changed: a registration, a load\n * landing or failing, a fallback policy, a canvas face measured again or its\n * pages emptied. Unlike {@link glyphGeneration} it holds still when a deferred\n * bake lands, which fills in an atlas rect and moves no pen — so text measured\n * under one value is still measured right while the value stands. Compare\n * with `!==`.\n */\nexport function faceGeneration(): number {\n return faces;\n}\n\n/** @internal Fired by a glyph source when what it measures or serves changed. */\nexport function notifyGlyphReady(): void {\n generation++;\n faces++;\n ready.emit();\n}\n\n/** @internal Fired when deferred bakes land: glyphs already measured can now\n * paint, and nothing about their faces changed. */\nexport function notifyGlyphBaked(): void {\n generation++;\n ready.emit();\n}\n\n/** @internal Test seam — the subscriber set is module state. */\nexport function _clearGlyphReadySubscribers(): void {\n ready = createEmitter();\n}\n","/**\n * Cross-family fallback policy. The per-family chain in `resolveFontVariant`\n * (weight → style → synthetic) has always been rich; what was missing is what\n * happens when the family itself was never registered. That case used to\n * render nothing at all, which is the single most common cause of \"my text is\n * invisible\".\n */\n\nimport { notifyGlyphReady } from './glyphReady';\n\n/**\n * What happens when a requested family has no baked atlas:\n * - `'substitute'` — render with the default family (see\n * `setDefaultFontFamily`), reporting the swap on `ResolveResult.substituted`.\n * - `'canvas'` — auto-enroll the family with the dynamic canvas-SDF\n * rasterizer. The consumer gets the *real* typeface if the browser has it,\n * at canvas-SDF quality rather than baked-MSDF quality.\n * - `'none'` — hard miss; the run renders nothing.\n */\nexport type FontFallbackPolicy = 'substitute' | 'canvas' | 'none';\n\nlet policy: FontFallbackPolicy = 'substitute';\nlet defaultFamily: string | null = null;\n\n/** Set what happens when text asks for a family that was never registered.\n * Process-wide; defaults to `'substitute'`. */\nexport function setFontFallbackPolicy(next: FontFallbackPolicy): void {\n if (next === policy) return;\n policy = next;\n notifyGlyphReady();\n}\n\n/** The cross-family fallback policy currently in force. */\nexport function getFontFallbackPolicy(): FontFallbackPolicy {\n return policy;\n}\n\n/** Explicit default family for `'substitute'`. When unset, the first\n * registered family wins — the right answer for the common case of an app\n * that registers exactly one. */\nexport function setDefaultFontFamily(family: string): void {\n if (family === defaultFamily) return;\n defaultFamily = family;\n notifyGlyphReady();\n}\n\n/** The family `setDefaultFontFamily` named, or `null` if none was set — in\n * which case `'substitute'` falls back to the first registered family. */\nexport function getDefaultFontFamily(): string | null {\n return defaultFamily;\n}\n\n/**\n * Warn-once gate for the cross-family fallback warnings. The messages are\n * built in `registerFont.ts` (they read the registry to name the actual gap),\n * but the dedup state lives here so `_resetFallbackForTests` clears it —\n * warnings about a fallback are fallback state. While it sat in\n * `registerFont.ts`, only a registry reset cleared it, and a test that reset\n * just the policy silently swallowed its next warning.\n */\nconst warnedFallbacks = new Set<string>();\n\n/** @internal Claim `key` for a one-time warning; true the first time only. */\nexport function claimFallbackWarning(key: string): boolean {\n if (warnedFallbacks.has(key)) return false;\n warnedFallbacks.add(key);\n return true;\n}\n\n/** @internal Whether `key` has been claimed since the last reset. */\nexport function fallbackWarningClaimed(key: string): boolean {\n return warnedFallbacks.has(key);\n}\n\n/** @internal Also called by `_resetFontRegistryForTests`: dropping the fonts\n * a warning was about has to drop the warning too. */\nexport function _clearFallbackWarnings(): void {\n warnedFallbacks.clear();\n}\n\n/** Test helper. Do not call from product code. */\nexport function _resetFallbackForTests(): void {\n policy = 'substitute';\n defaultFamily = null;\n warnedFallbacks.clear();\n}\n","/**\n * The dynamic glyph atlas's pages: their CPU-side bytes, and bringing each\n * renderer's texture of one up to date. Three sets: distance fields, one byte a\n * texel; color glyphs, four; and color glyphs baked again larger, four, on\n * pages that fill and empty on their own.\n */\n\nimport type { GlyphTextureSink } from '../textureSink';\n\n/** Side of every dynamic-atlas page, in texels: a glyph's rect over it is its uv. */\nexport const PAGE_SIZE = 1024;\nexport const MAX_PAGES = 4;\n\ninterface DynamicPage {\n data: Uint8Array;\n /** Bumps on every write; each write appends a patch with seq = version. */\n version: number;\n patches: { seq: number; x: number; y: number; w: number; h: number }[];\n}\n\n/** How one set of pages reaches a texture. */\ninterface PageFormat {\n /** Bytes per texel. */\n channels: number;\n idPrefix: string;\n upload(cache: GlyphTextureSink, id: string, data: Uint8Array): void;\n patch(cache: GlyphTextureSink, id: string, x: number, y: number, w: number, h: number, data: Uint8Array): void;\n}\n\nclass PageSet {\n pages: DynamicPage[] = [];\n // Per-GL-cache upload progress: last page version each cache has seen.\n // WeakMap-keyed so disposed renderers don't pin anything.\n private uploaded = new WeakMap<GlyphTextureSink, Map<number, number>>();\n\n constructor(private readonly format: PageFormat) {}\n\n textureId(page: number): string {\n return `${this.format.idPrefix}${page}`;\n }\n\n /** Copy a `w`×`h` block of texels into page `pageIndex` at `(x, y)`. */\n blit(pageIndex: number, x: number, y: number, w: number, h: number, bytes: Uint8Array | Uint8ClampedArray): void {\n const n = this.format.channels;\n while (this.pages.length <= pageIndex) {\n this.pages.push({ data: new Uint8Array(PAGE_SIZE * PAGE_SIZE * n), version: 0, patches: [] });\n }\n const page = this.pages[pageIndex];\n for (let row = 0; row < h; row++) {\n page.data.set(bytes.subarray(row * w * n, (row + 1) * w * n), ((y + row) * PAGE_SIZE + x) * n);\n }\n page.version++;\n page.patches.push({ seq: page.version, x, y, w, h });\n }\n\n /** Zero every page. One whole-page patch stands in for all the patches before it. */\n clear(): void {\n for (const page of this.pages) {\n page.data.fill(0);\n page.version++;\n page.patches = [{ seq: page.version, x: 0, y: 0, w: PAGE_SIZE, h: PAGE_SIZE }];\n }\n }\n\n /** Bring `cache`'s copy of page `pageIndex` up to date: a full upload the\n * first time, patches after. Returns false if the page doesn't exist yet. */\n sync(cache: GlyphTextureSink, pageIndex: number): boolean {\n const page = this.pages[pageIndex];\n if (!page) return false;\n const n = this.format.channels;\n const id = this.textureId(pageIndex);\n let seen = this.uploaded.get(cache);\n if (!seen) {\n seen = new Map();\n this.uploaded.set(cache, seen);\n }\n if (!cache.has(id)) {\n this.format.upload(cache, id, page.data);\n seen.set(pageIndex, page.version);\n return true;\n }\n const last = seen.get(pageIndex) ?? 0;\n if (last >= page.version) return true;\n for (const patch of page.patches) {\n if (patch.seq <= last) continue;\n const tight = new Uint8Array(patch.w * patch.h * n);\n for (let row = 0; row < patch.h; row++) {\n const src = ((patch.y + row) * PAGE_SIZE + patch.x) * n;\n tight.set(page.data.subarray(src, src + patch.w * n), row * patch.w * n);\n }\n this.format.patch(cache, id, patch.x, patch.y, patch.w, patch.h, tight);\n }\n seen.set(pageIndex, page.version);\n return true;\n }\n}\n\nconst fields = new PageSet({\n channels: 1,\n idPrefix: 'weasel-dyn-sdf-page-',\n upload: (cache, id, data) => cache.uploadR8(id, PAGE_SIZE, PAGE_SIZE, data),\n patch: (cache, id, x, y, w, h, data) => cache.subImageR8(id, x, y, w, h, data),\n});\n\nconst colors = new PageSet({\n channels: 4,\n idPrefix: 'weasel-dyn-color-page-',\n upload: (cache, id, data) => cache.uploadRGBA(id, PAGE_SIZE, PAGE_SIZE, data),\n patch: (cache, id, x, y, w, h, data) => cache.subImageRGBA(id, x, y, w, h, data),\n});\n\nconst sharpColors = new PageSet({\n channels: 4,\n idPrefix: 'weasel-dyn-color-sharp-page-',\n upload: (cache, id, data) => cache.uploadRGBA(id, PAGE_SIZE, PAGE_SIZE, data),\n patch: (cache, id, x, y, w, h, data) => cache.subImageRGBA(id, x, y, w, h, data),\n});\n\n/** Copy a `w`×`h` block of field bytes into field page `pageIndex` at `(x, y)`. */\nexport function blitToPage(\n pageIndex: number, x: number, y: number, w: number, h: number, bytes: Uint8Array,\n): void {\n fields.blit(pageIndex, x, y, w, h, bytes);\n}\n\n/** Copy a `w`×`h` block of premultiplied RGBA texels into color page `pageIndex` at `(x, y)`. */\nexport function blitToColorPage(\n pageIndex: number, x: number, y: number, w: number, h: number, rgba: Uint8ClampedArray,\n): void {\n colors.blit(pageIndex, x, y, w, h, rgba);\n}\n\n/** Copy a `w`×`h` block of premultiplied RGBA texels into sharp color page `pageIndex` at `(x, y)`. */\nexport function blitToSharpColorPage(\n pageIndex: number, x: number, y: number, w: number, h: number, rgba: Uint8ClampedArray,\n): void {\n sharpColors.blit(pageIndex, x, y, w, h, rgba);\n}\n\n/** Zero every page of every set. */\nexport function clearPages(): void {\n fields.clear();\n colors.clear();\n sharpColors.clear();\n}\n\n/** Zero the sharp color pages alone. */\nexport function clearSharpPages(): void {\n sharpColors.clear();\n}\n\n/** Texture-cache key for a dynamic field page (parallel to `textureCacheKey`). */\nexport function dynamicPageTextureId(page: number): string {\n return fields.textureId(page);\n}\n\n/** Texture-cache key for a page of color glyphs. */\nexport function colorPageTextureId(page: number): string {\n return colors.textureId(page);\n}\n\n/** Texture-cache key for a page of color glyphs baked larger. */\nexport function sharpColorPageTextureId(page: number): string {\n return sharpColors.textureId(page);\n}\n\n/** Bring `cache`'s copy of field page `pageIndex` up to date: full R8 upload\n * the first time, `texSubImage2D` patches after. Returns false if the page\n * doesn't exist yet. */\nexport function syncDynamicPageTexture(cache: GlyphTextureSink, pageIndex: number): boolean {\n return fields.sync(cache, pageIndex);\n}\n\n/** The same for a page of color glyphs, whose texels are premultiplied RGBA. */\nexport function syncColorPageTexture(cache: GlyphTextureSink, pageIndex: number): boolean {\n return colors.sync(cache, pageIndex);\n}\n\n/** The same for a page of color glyphs baked larger. */\nexport function syncSharpColorPageTexture(cache: GlyphTextureSink, pageIndex: number): boolean {\n return sharpColors.sync(cache, pageIndex);\n}\n\n/** @internal test seam — inspect CPU-side field pages. */\nexport function _getPagesForTests(): readonly DynamicPage[] {\n return fields.pages;\n}\n\n/** @internal test seam — inspect CPU-side color pages. */\nexport function _getColorPagesForTests(): readonly DynamicPage[] {\n return colors.pages;\n}\n\n/** @internal test seam — inspect CPU-side sharp color pages. */\nexport function _getSharpColorPagesForTests(): readonly DynamicPage[] {\n return sharpColors.pages;\n}\n\n/** @internal test seam — forget every page. */\nexport function _resetPagesForTests(): void {\n fields.pages = [];\n colors.pages = [];\n sharpColors.pages = [];\n}\n","/**\n * Shelf packer for the dynamic glyph atlas: fixed-size square pages, rows\n * (\"shelves\") of same-ish-height rects filled left to right. Simple and\n * good enough for glyph rects; no rotation, and no free: the atlas reclaims\n * room by replacing the packer.\n */\n\nexport interface ShelfAlloc {\n page: number;\n x: number;\n y: number;\n}\n\ninterface Shelf { y: number; height: number; x: number; }\ninterface Page { shelves: Shelf[]; nextY: number; }\n\nexport class ShelfPacker {\n private pages: Page[] = [];\n\n constructor(\n private readonly pageSize: number,\n private readonly maxPages: number,\n ) {}\n\n get pageCount(): number {\n return this.pages.length;\n }\n\n /** Whether an empty page could hold a w×h rect. */\n fits(w: number, h: number): boolean {\n return w <= this.pageSize && h <= this.pageSize;\n }\n\n /** Allocate a w×h rect. Returns null when capacity is out. */\n alloc(w: number, h: number): ShelfAlloc | null {\n if (!this.fits(w, h)) return null;\n for (let p = 0; p < this.pages.length; p++) {\n const spot = this.allocInPage(this.pages[p], w, h);\n if (spot) return { page: p, ...spot };\n }\n if (this.pages.length < this.maxPages) {\n const page: Page = { shelves: [], nextY: 0 };\n this.pages.push(page);\n const spot = this.allocInPage(page, w, h);\n if (spot) return { page: this.pages.length - 1, ...spot };\n }\n return null;\n }\n\n private allocInPage(page: Page, w: number, h: number): { x: number; y: number } | null {\n for (const shelf of page.shelves) {\n if (h <= shelf.height && shelf.x + w <= this.pageSize) {\n const x = shelf.x;\n shelf.x += w;\n return { x, y: shelf.y };\n }\n }\n if (page.nextY + h <= this.pageSize) {\n const shelf: Shelf = { y: page.nextY, height: h, x: w };\n page.shelves.push(shelf);\n page.nextY += h;\n return { x: 0, y: shelf.y };\n }\n return null;\n }\n\n}\n","/**\n * Euclidean distance transform for runtime SDF glyph baking (the TinySDF\n * technique): antialiased canvas coverage in → single-channel SDF bytes out.\n *\n * Uses Felzenszwalb & Huttenlocher's 1D squared-distance transform applied\n * along columns then rows. Pure JS, no dependencies, no allocation beyond\n * the work arrays sized to the input.\n */\n\nconst INF = 1e20;\n\n/** One 1D pass of the squared EDT (Felzenszwalb & Huttenlocher 2012, §2). */\nfunction edt1d(\n f: Float64Array, d: Float64Array, v: Int32Array, z: Float64Array, n: number,\n): void {\n v[0] = 0;\n z[0] = -INF;\n z[1] = INF;\n let k = 0;\n for (let q = 1; q < n; q++) {\n let s = (f[q] + q * q - (f[v[k]] + v[k] * v[k])) / (2 * q - 2 * v[k]);\n while (s <= z[k]) {\n k--;\n s = (f[q] + q * q - (f[v[k]] + v[k] * v[k])) / (2 * q - 2 * v[k]);\n }\n k++;\n v[k] = q;\n z[k] = s;\n z[k + 1] = INF;\n }\n k = 0;\n for (let q = 0; q < n; q++) {\n while (z[k + 1] < q) k++;\n d[q] = (q - v[k]) * (q - v[k]) + f[v[k]];\n }\n}\n\n/** In-place 2D squared EDT over `grid` (width × height): columns, then rows. */\nfunction edt2d(\n grid: Float64Array, width: number, height: number,\n f: Float64Array, d: Float64Array, v: Int32Array, z: Float64Array,\n): void {\n for (let x = 0; x < width; x++) {\n for (let y = 0; y < height; y++) f[y] = grid[y * width + x];\n edt1d(f, d, v, z, height);\n for (let y = 0; y < height; y++) grid[y * width + x] = d[y];\n }\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) f[x] = grid[y * width + x];\n edt1d(f, d, v, z, width);\n for (let x = 0; x < width; x++) grid[y * width + x] = d[x];\n }\n}\n\n/**\n * Convert an alpha-coverage bitmap (0–255) to single-channel SDF bytes.\n * Signed distance is positive outside the shape; the output maps it as\n * `255 − 255·(dist/radius + cutoff)` clamped to [0,255], so with\n * cutoff 0.5 the shape edge lands at byte ~128 (shader threshold 0.5).\n */\nexport function alphaToSdf(\n alpha: Uint8ClampedArray | Uint8Array,\n width: number,\n height: number,\n radius: number,\n cutoff: number,\n): Uint8Array {\n const n = width * height;\n const gridOuter = new Float64Array(n);\n const gridInner = new Float64Array(n);\n const size = Math.max(width, height);\n const f = new Float64Array(size);\n const d = new Float64Array(size);\n const v = new Int32Array(size);\n const z = new Float64Array(size + 1);\n\n for (let i = 0; i < n; i++) {\n const a = alpha[i] / 255;\n gridOuter[i] = a === 1 ? 0 : a === 0 ? INF : Math.max(0, 0.5 - a) ** 2;\n gridInner[i] = a === 1 ? INF : a === 0 ? 0 : Math.max(0, a - 0.5) ** 2;\n }\n edt2d(gridOuter, width, height, f, d, v, z);\n edt2d(gridInner, width, height, f, d, v, z);\n\n const out = new Uint8Array(n);\n for (let i = 0; i < n; i++) {\n const dist = Math.sqrt(gridOuter[i]) - Math.sqrt(gridInner[i]);\n const byte = Math.round(255 - 255 * (dist / radius + cutoff));\n out[i] = byte < 0 ? 0 : byte > 255 ? 255 : byte;\n }\n return out;\n}\n","/**\n * Baking measured glyphs into the dynamic atlas's pages: a few a frame, the\n * rest on later ticks, and every page emptied whole when the field or color\n * set fills. The sharp color set, larger bakes of color glyphs, empties alone.\n */\n\nimport type { BmFontChar } from '../FontAtlas';\nimport { notifyGlyphBaked, notifyGlyphReady } from '../glyphReady';\nimport { ShelfPacker } from './shelfPack';\nimport {\n PAGE_SIZE, MAX_PAGES, blitToPage, blitToColorPage, blitToSharpColorPage, clearPages, clearSharpPages,\n} from './dynamicPages';\nimport { alphaToSdf } from './distanceTransform';\nimport type { RasterizedColorGlyph, RasterizedGlyph } from './glyphRasterizer';\n\nexport const SDF_RADIUS = 8;\nexport const SDF_CUTOFF = 0.5;\n/** How many glyphs the dynamic atlas will rasterize synchronously before\n * deferring the rest to a later flush. Caps the frame cost of text that\n * suddenly needs many new glyphs; the leftovers arrive a tick later and\n * notify through `onGlyphReady`. */\nexport const DEFAULT_BAKE_BUDGET = 16;\n\ntype Raster = RasterizedGlyph | RasterizedColorGlyph;\ninterface PendingBake { char: BmFontChar; raster: Raster; sharp: boolean; }\n\n/** Room on one set of pages, and whether that set is waiting to be emptied. */\ninterface Room {\n packer: ShelfPacker;\n /** False from an emptying of the pages until a frame asks for no new glyph\n * with none waiting to bake: until what was on screen has baked again. */\n settled: boolean;\n reclaimScheduled: boolean;\n}\n\nconst newRoom = (): Room => ({ packer: new ShelfPacker(PAGE_SIZE, MAX_PAGES), settled: true, reclaimScheduled: false });\n\nlet fieldRoom = newRoom();\nlet colorRoom = newRoom();\nlet sharpRoom = newRoom();\nlet pending: PendingBake[] = [];\nlet flushScheduled = false;\nlet budget = DEFAULT_BAKE_BUDGET;\n/** Glyphs measured since the frame began. */\nlet asked = 0;\nlet forgetGlyphs: () => void = () => {};\nlet forgetSharp: () => void = () => {};\nconst warned = new Set<string>();\n\n/** Name what forgets every glyph record when the pages are emptied. */\nexport function onPagesEmptied(forget: () => void): void {\n forgetGlyphs = forget;\n}\n\n/** Name what forgets every sharp color bake when its pages are emptied, alone\n * or with the rest. */\nexport function onSharpPagesEmptied(forget: () => void): void {\n forgetSharp = forget;\n}\n\n/**\n * Give a freshly measured glyph its atlas rect: now while the frame has bakes\n * left, else on a later tick. `char` keeps page -1 until it lands.\n */\nexport function requestBake(char: BmFontChar, raster: Raster, sharp = false): void {\n asked++;\n if (raster.width === 0 || raster.height === 0) {\n char.page = 0; // blank glyph (space): nothing to bake\n return;\n }\n if (budget > 0) {\n budget--;\n bake(char, raster, sharp);\n } else {\n pending.push({ char, raster, sharp });\n scheduleFlush();\n }\n}\n\n/** Abandon the bakes still waiting for any of `chars`. */\nexport function dropBakes(chars: ReadonlySet<BmFontChar>): void {\n pending = pending.filter((job) => !chars.has(job.char));\n}\n\nfunction bake(char: BmFontChar, raster: Raster, sharp: boolean): void {\n const color = 'rgba' in raster;\n const room = sharp ? sharpRoom : color ? colorRoom : fieldRoom;\n const spot = room.packer.alloc(raster.width, raster.height);\n if (!spot) {\n noRoom(room, raster, sharp ? reclaimSharp : reclaim);\n return;\n }\n if (color && sharp) {\n blitToSharpColorPage(spot.page, spot.x, spot.y, raster.width, raster.height, raster.rgba);\n } else if (color) {\n blitToColorPage(spot.page, spot.x, spot.y, raster.width, raster.height, raster.rgba);\n } else {\n const sdf = alphaToSdf(raster.alpha, raster.width, raster.height, SDF_RADIUS, SDF_CUTOFF);\n blitToPage(spot.page, spot.x, spot.y, raster.width, raster.height, sdf);\n }\n char.x = spot.x;\n char.y = spot.y;\n char.width = raster.width;\n char.height = raster.height;\n char.page = spot.page;\n}\n\n/** A glyph found no room, and stays invisible for the frame that asked. */\nfunction noRoom(room: Room, raster: Raster, empty: () => void): void {\n if (!room.packer.fits(raster.width, raster.height)) {\n warnOnce('weasel DynamicGlyphAtlas: a glyph is larger than a page and will not render.');\n } else if (!room.settled) {\n // A sharp bake that finds no room leaves its glyph on a softer one, so it\n // goes unsaid.\n if (room === sharpRoom) return;\n warnOnce(\n `weasel DynamicGlyphAtlas: more glyphs are in use at once than its pages hold ` +\n `(${MAX_PAGES} × ${PAGE_SIZE}²); the rest will not render.`);\n } else if (!room.reclaimScheduled) {\n room.reclaimScheduled = true;\n setTimeout(empty, 0);\n }\n}\n\nfunction warnOnce(message: string): void {\n if (warned.has(message)) return;\n warned.add(message);\n console.warn(message);\n}\n\n/**\n * Empty every page and forget every glyph, so the text on screen bakes again\n * into the room that leaves. Run off a timer, never from `bake`: a frame part\n * drawn has already placed quads on the rects this gives away.\n */\nfunction reclaim(): void {\n fieldRoom = { ...newRoom(), settled: false };\n colorRoom = { ...newRoom(), settled: false };\n sharpRoom = { ...newRoom(), settled: false };\n pending = [];\n clearPages();\n forgetGlyphs();\n forgetSharp();\n notifyGlyphReady();\n}\n\n/** `reclaim` for the sharp color pages alone. Every glyph keeps its base bake\n * and draws from that until a sharper one lands again. */\nfunction reclaimSharp(): void {\n sharpRoom = { ...newRoom(), settled: false };\n pending = pending.filter((job) => !job.sharp);\n clearSharpPages();\n forgetSharp();\n notifyGlyphReady();\n}\n\nfunction scheduleFlush(): void {\n if (flushScheduled) return;\n flushScheduled = true;\n setTimeout(flushPending, 0);\n}\n\nfunction flushPending(): void {\n flushScheduled = false;\n let n = 0;\n while (pending.length > 0 && n < DEFAULT_BAKE_BUDGET) {\n const job = pending.shift()!;\n if (job.char.page !== -1) continue; // already baked\n bake(job.char, job.raster, job.sharp);\n n++;\n }\n if (pending.length > 0) scheduleFlush();\n notifyGlyphBaked();\n}\n\n/** Reset the per-frame synchronous bake budget. Called by\n * `WeaselRenderer.render()` at frame start; the headless\n * `renderSceneToPixels` path passes Infinity so print never defers. */\nexport function resetBakeBudget(n: number = DEFAULT_BAKE_BUDGET): void {\n budget = n;\n if (asked === 0 && pending.length === 0) {\n fieldRoom.settled = true;\n colorRoom.settled = true;\n sharpRoom.settled = true;\n }\n asked = 0;\n}\n\n/** @internal test seam — forget every bake and all the room given out. */\nexport function _resetBakeQueueForTests(): void {\n fieldRoom = newRoom();\n colorRoom = newRoom();\n sharpRoom = newRoom();\n pending = [];\n flushScheduled = false;\n asked = 0;\n warned.clear();\n budget = DEFAULT_BAKE_BUDGET;\n}\n","/**\n * Canvas-2D glyph rasterizer for the dynamic SDF atlas. `fillText` is the\n * only web-platform route to *installed* machine fonts (no outline access),\n * which is exactly why this tier exists.\n *\n * Coordinate contract (all values in bake-size px, i.e. at BAKE_SIZE):\n * bitmap left = penX + left (left is negative: pad + left bearing)\n * bitmap top = baseline − top (top is positive above the baseline)\n * pen advance = advance\n * The bitmap includes a PAD border on all four sides so the SDF field has\n * room to fall off. Blank glyphs (e.g. space) return width/height 0.\n *\n * On BAKE_SIZE: mean per-pixel coverage error of the reconstructed field\n * against a direct `fillText` of the same glyph at each display size:\n *\n * display px 12 16 24 32 48 64 96 128\n * error .096 .083 .059 .039 .024 .023 .037 .049\n *\n * The error is minimized *at* the bake size, so raising BAKE_SIZE does not\n * improve small text — it moves the sweet spot away from the 12–32px range\n * and makes it worse. The 12–16px error is not undersampling: supersampling\n * the reconstruction recovers almost nothing there. What is left is a hinted\n * rasterizer placing stems on the pixel grid, which no size-independent field\n * can encode, so more taps, a bigger bake, or mipmaps buy nothing.\n */\n\nimport type { FontStyle } from '../fontStyle';\nimport { cssFamilyName } from '../cssFamily';\n\nexport const BAKE_SIZE = 48;\nexport const PAD = 8;\n\nexport interface FaceMetrics {\n ascent: number;\n descent: number;\n}\n\nexport interface RasterizedGlyph {\n width: number;\n height: number;\n alpha: Uint8ClampedArray;\n left: number;\n top: number;\n advance: number;\n}\n\n/** A glyph in its own colors. Placed as a {@link RasterizedGlyph} is. */\nexport interface RasterizedColorGlyph {\n width: number;\n height: number;\n /** Premultiplied RGBA, four bytes a texel. */\n rgba: Uint8ClampedArray;\n left: number;\n top: number;\n advance: number;\n}\n\nexport interface GlyphRasterizer {\n faceMetrics(family: string, weight: number, style: FontStyle): FaceMetrics;\n rasterize(\n family: string, weight: number, style: FontStyle, codepoint: number,\n ): RasterizedGlyph;\n /** `text`, one grapheme cluster, as the color glyph the platform draws for\n * it, or null when it draws none: no ink, or ink in the fill color alone.\n * Drawn at `size` px, `BAKE_SIZE` when omitted, and measured in its px. */\n rasterizeColor?(\n family: string, weight: number, style: FontStyle, text: string, size?: number,\n ): RasterizedColorGlyph | null;\n}\n\n/** Ink this far below white did not come from the white fill. */\nconst COLORED_BELOW = 240;\n\n/** `data`, straight RGBA drawn with a white fill, premultiplied. Null when\n * every inked texel is the fill's white: a glyph with no color of its own. */\nexport function premultipliedColor(data: Uint8ClampedArray): Uint8ClampedArray | null {\n const out = new Uint8ClampedArray(data.length);\n let colored = false;\n for (let i = 0; i < data.length; i += 4) {\n const a = data[i + 3];\n if (a === 0) continue;\n const r = data[i], g = data[i + 1], b = data[i + 2];\n if (a >= 128 && Math.min(r, g, b) < COLORED_BELOW) colored = true;\n out[i] = Math.round((r * a) / 255);\n out[i + 1] = Math.round((g * a) / 255);\n out[i + 2] = Math.round((b * a) / 255);\n out[i + 3] = a;\n }\n return colored ? out : null;\n}\n\ntype Canvas2D = OffscreenCanvasRenderingContext2D | CanvasRenderingContext2D;\n\n/** Engines report font-box metrics in whole pixels, so they are read at a\n * size where that rounding is a thousandth of an em, not a fiftieth. */\nconst METRICS_SIZE = 1000;\n\nfunction cssFontString(weight: number, style: FontStyle, family: string, size = BAKE_SIZE): string {\n return `${style === 'italic' ? 'italic ' : ''}${weight} ${size}px ${cssFamilyName(family)}`;\n}\n\nexport function createCanvasRasterizer(): GlyphRasterizer {\n let canvas: OffscreenCanvas | HTMLCanvasElement;\n if (typeof OffscreenCanvas !== 'undefined') {\n canvas = new OffscreenCanvas(BAKE_SIZE * 3, BAKE_SIZE * 3);\n } else if (typeof document !== 'undefined') {\n canvas = document.createElement('canvas');\n canvas.width = BAKE_SIZE * 3;\n canvas.height = BAKE_SIZE * 3;\n } else {\n throw new Error('weasel DynamicGlyphAtlas: no canvas available for glyph rasterization');\n }\n const ctx = canvas.getContext('2d', { willReadFrequently: true }) as Canvas2D | null;\n if (!ctx) throw new Error('weasel DynamicGlyphAtlas: 2D context unavailable');\n\n function setFont(family: string, weight: number, style: FontStyle, size = BAKE_SIZE): void {\n ctx!.font = cssFontString(weight, style, family, size);\n ctx!.textBaseline = 'alphabetic';\n ctx!.textAlign = 'left';\n }\n\n /** `text` filled in white at `size` px, as straight RGBA. No ink is a box of no size. */\n function draw(family: string, weight: number, style: FontStyle, text: string, size = BAKE_SIZE): {\n data: Uint8ClampedArray; width: number; height: number; left: number; top: number; advance: number;\n } {\n setFont(family, weight, style, size);\n const m = ctx!.measureText(text);\n const advance = m.width;\n const inkLeft = Math.ceil(m.actualBoundingBoxLeft ?? 0);\n const inkRight = Math.ceil(m.actualBoundingBoxRight ?? advance);\n const inkAscent = Math.ceil(m.actualBoundingBoxAscent ?? size * 0.8);\n const inkDescent = Math.ceil(m.actualBoundingBoxDescent ?? size * 0.2);\n const inkW = inkLeft + inkRight;\n const inkH = inkAscent + inkDescent;\n if (inkW <= 0 || inkH <= 0) {\n return { data: new Uint8ClampedArray(0), width: 0, height: 0, left: 0, top: 0, advance };\n }\n const w = inkW + 2 * PAD;\n const h = inkH + 2 * PAD;\n if (canvas.width < w || canvas.height < h) {\n canvas.width = Math.max(canvas.width, w);\n canvas.height = Math.max(canvas.height, h);\n setFont(family, weight, style, size); // resizing resets 2D state\n }\n ctx!.clearRect(0, 0, w, h);\n ctx!.fillStyle = '#fff';\n ctx!.fillText(text, PAD + inkLeft, PAD + inkAscent);\n return {\n data: ctx!.getImageData(0, 0, w, h).data,\n width: w, height: h, left: -(inkLeft + PAD), top: inkAscent + PAD, advance,\n };\n }\n\n return {\n faceMetrics(family, weight, style) {\n setFont(family, weight, style, METRICS_SIZE);\n const m = ctx!.measureText('Hg');\n const k = BAKE_SIZE / METRICS_SIZE;\n return {\n ascent: (m.fontBoundingBoxAscent ?? METRICS_SIZE * 0.8) * k,\n descent: (m.fontBoundingBoxDescent ?? METRICS_SIZE * 0.2) * k,\n };\n },\n\n rasterize(family, weight, style, codepoint) {\n const { data, ...box } = draw(family, weight, style, String.fromCodePoint(codepoint));\n const alpha = new Uint8ClampedArray(box.width * box.height);\n for (let i = 0; i < alpha.length; i++) alpha[i] = data[i * 4 + 3];\n return { ...box, alpha };\n },\n\n rasterizeColor(family, weight, style, text, size) {\n const { data, ...box } = draw(family, weight, style, text, size);\n const rgba = premultipliedColor(data);\n return rgba && { ...box, rgba };\n },\n };\n}\n","/**\n * Color glyphs baked again larger. A color glyph is a bitmap baked at\n * `BAKE_SIZE`, so it blurs when drawn much bigger than that; this re-rasters\n * it at `BAKE_SIZE × 2^level` onto pages of its own, the way a vector image\n * re-rasterizes in power-of-two steps. One emoji at the largest level takes\n * the room of sixty at the base size, so these pages fill and empty without\n * taking the base bakes with them.\n */\n\nimport type { BmFontChar } from '../FontAtlas';\nimport { onSharpPagesEmptied, requestBake } from './bakeQueue';\nimport { BAKE_SIZE, type RasterizedColorGlyph } from './glyphRasterizer';\n\n/** The largest level baked: `BAKE_SIZE × 2^3`, 384px. */\nexport const MAX_SHARP_LEVEL = 3;\n\n/** A color glyph baked at `BAKE_SIZE × 2^level`. */\nexport interface SharperColorGlyph {\n level: number;\n /**\n * Its rect on sharp color page `glyph.page` (`sharpColorPageTextureId`), in\n * that bake's texels. Its `xoffset` and `yoffset` are in the base bake's px,\n * as the base record's are, so both place from the same pen; it covers\n * `width / 2^level` of them.\n */\n glyph: BmFontChar;\n}\n\ninterface Source {\n raster(size: number): RasterizedColorGlyph | null;\n /** The face's baseline, which the base record's `yoffset` is measured from. */\n base: number;\n /** By level; null where the platform drew nothing. Read only while\n * `generation` is current. */\n levels: (SharperColorGlyph | null)[];\n generation: number;\n}\n\nconst sources = new WeakMap<BmFontChar, Source>();\nlet generation = 0;\n\nonSharpPagesEmptied(() => {\n generation++;\n});\n\n/** Let `char`, a base color bake, be baked again larger by `raster`. */\nexport function addSharpSource(\n char: BmFontChar, base: number, raster: (size: number) => RasterizedColorGlyph | null,\n): void {\n sources.set(char, { raster, base, levels: [], generation });\n}\n\nfunction levelsOf(source: Source): (SharperColorGlyph | null)[] {\n if (source.generation !== generation) {\n source.levels = [];\n source.generation = generation;\n }\n return source.levels;\n}\n\n/** The sharper bakes `char` has asked for, baked or waiting. */\nexport function sharpBakesOf(char: BmFontChar): BmFontChar[] {\n const source = sources.get(char);\n if (!source) return [];\n return levelsOf(source).flatMap((sharp) => (sharp ? [sharp.glyph] : []));\n}\n\nfunction requestLevel(source: Source, level: number): SharperColorGlyph | null {\n const levels = levelsOf(source);\n const known = levels[level];\n if (known !== undefined) return known;\n const k = 2 ** level;\n const raster = source.raster(BAKE_SIZE * k);\n const sharp: SharperColorGlyph | null = raster && {\n level,\n glyph: {\n id: 0, x: 0, y: 0, width: 0, height: 0,\n xoffset: raster.left / k,\n yoffset: source.base - raster.top / k,\n xadvance: raster.advance / k,\n page: -1,\n color: true,\n },\n };\n levels[level] = sharp;\n if (sharp && raster) requestBake(sharp.glyph, raster, true);\n return sharp;\n}\n\n/**\n * A bake of `char`, a base color bake, sharper than it for drawing at `scale`\n * device pixels to one of its texels: the power of two at or above `scale`,\n * up to {@link MAX_SHARP_LEVEL}. Asks for that bake if it has not been, and\n * until it lands serves the sharpest level that has. Null when the base bake\n * is the sharpest there is.\n */\nexport function sharperColorGlyph(char: BmFontChar, scale: number): SharperColorGlyph | null {\n const source = sources.get(char);\n if (!source || !(scale > 1)) return null;\n const wanted = Math.min(MAX_SHARP_LEVEL, Math.ceil(Math.log2(scale)));\n requestLevel(source, wanted);\n const levels = levelsOf(source);\n for (let level = wanted; level > 0; level--) {\n const sharp = levels[level];\n if (sharp && sharp.glyph.page >= 0) return sharp;\n }\n return null;\n}\n","/**\n * The document's font loads, as family names. A canvas draws a family whose\n * web font is still loading in a fallback face and reports nothing when the\n * real one lands, so whatever measured through a canvas has to hear it here.\n */\n\n/** A family name as two spellings of it compare: unquoted, lower case. */\nexport function familyKey(family: string): string {\n return family.trim().replace(/^([\"'])(.*)\\1$/, '$2').toLowerCase();\n}\n\n/**\n * Call `onLoaded` with the families of each batch of faces `document.fonts`\n * finishes loading. Returns a function that stops it. Does nothing where\n * there is no font set to listen to.\n *\n * A face loaded before it is added to the set is never announced.\n */\nexport function watchFontLoads(onLoaded: (families: string[]) => void): () => void {\n const fonts = typeof document === 'undefined' ? undefined : document.fonts;\n if (!fonts?.addEventListener) return () => {};\n const listener = (event: Event): void => {\n const faces = (event as Partial<FontFaceSetLoadEvent>).fontfaces ?? [];\n if (faces.length > 0) onLoaded(faces.map((face) => face.family));\n };\n fonts.addEventListener('loadingdone', listener);\n return () => fonts.removeEventListener('loadingdone', listener);\n}\n","/**\n * DynamicGlyphAtlas — runtime single-channel SDF glyphs for canvas-sourced\n * (installed machine) fonts. TinySDF technique: canvas fillText at 48 px →\n * Euclidean distance transform → shelf-packed R8 pages (1024², max 4). When\n * the pages fill they are emptied whole and the text on screen bakes again.\n *\n * Baked MSDF atlases always win: this tier only serves families registered\n * via `registerCanvasFont` that have no baked entry (see resolveFontVariant).\n *\n * Faces expose a BmFont-shaped `font` whose charMap grows as glyphs are\n * requested, so `layoutRuns` consumes them through the same code path as\n * baked atlases. A char's advance is valid immediately (measureText); its\n * atlas rect fills in when the bake lands (width 0 / page -1 until then, so\n * layout advances the pen but emits no quad).\n *\n * An emoji is the one glyph kept as the canvas drew it: `requestCluster`\n * rasterizes a whole grapheme cluster in its own colors onto a second set of\n * pages, RGBA, that fill and empty with the field pages, and bakes it again\n * larger for drawing past its size (`sharpColor.ts`).\n */\n\nimport type { FontStyle } from '../fontStyle';\nimport type { BmFont, BmFontChar } from '../FontAtlas';\n// `fallback.ts` imports nothing, so this edge cannot close a cycle; keep it\n// that way. (registerFont.ts imports both this module and fallback.ts.)\nimport { getFontFallbackPolicy } from '../fallback';\nimport { notifyGlyphReady, _clearGlyphReadySubscribers } from '../glyphReady';\nimport { PAGE_SIZE, MAX_PAGES, _resetPagesForTests } from './dynamicPages';\nimport { dropBakes, onPagesEmptied, requestBake, _resetBakeQueueForTests } from './bakeQueue';\nimport { familyKey, watchFontLoads } from './fontLoads';\nimport { createCanvasRasterizer, BAKE_SIZE, type GlyphRasterizer } from './glyphRasterizer';\nimport { addSharpSource, sharpBakesOf } from './sharpColor';\n\nexport { PAGE_SIZE, MAX_PAGES };\nexport {\n syncDynamicPageTexture, dynamicPageTextureId, syncColorPageTexture, colorPageTextureId,\n syncSharpColorPageTexture, sharpColorPageTextureId, _getPagesForTests,\n} from './dynamicPages';\nexport { sharperColorGlyph, MAX_SHARP_LEVEL, type SharperColorGlyph } from './sharpColor';\nexport { SDF_RADIUS, SDF_CUTOFF, DEFAULT_BAKE_BUDGET, resetBakeBudget } from './bakeQueue';\n\n/** A face whose glyphs are rasterized on demand into a shared atlas page, rather than shipped as a prebuilt one. */\nexport interface DynamicFace {\n family: string;\n weight: number;\n style: FontStyle;\n /** BmFont-shaped view consumed by layoutRuns; charMap grows lazily. */\n font: BmFont;\n /** Char record for `cp`, measured on first request (advance always valid\n * immediately; atlas rect fills in when the bake lands). */\n requestGlyph(cp: number): BmFontChar;\n /**\n * The color glyph the platform draws for the grapheme cluster `text`,\n * measured on first request as `requestGlyph`'s is, or null when it draws\n * none. Its record is marked `color` and its rect is on a color page. It is\n * not in `font.charMap`, which holds one code point each.\n */\n requestCluster(text: string): BmFontChar | null;\n}\n\ninterface Face extends DynamicFace {\n clusters: Map<string, BmFontChar | null>;\n}\n\n/** One family served by the dynamic canvas-SDF tier. See `listCanvasFonts`. */\nexport interface CanvasFontEntry {\n family: string;\n /** `'explicit'` — a `registerCanvasFont` call; `'auto'` — the `'canvas'`\n * fallback policy enrolled it on a miss, and the enrollment lapses if\n * that policy changes. */\n enrollment: 'explicit' | 'auto';\n}\n\nconst canvasFamilies = new Set<string>();\n// Enrollment provenance; see `isCanvasFont`. Tracked here rather than in\n// fallback.ts so the two sets can only ever be mutated together.\nconst autoEnrolledFamilies = new Set<string>();\nlet faces = new Map<string, Face>();\nlet rasterizer: GlyphRasterizer | null = null;\nlet stopWatchingLoads: (() => void) | null = null;\n\nfunction forgetGlyphs(face: Face): void {\n face.font.charMap.clear();\n face.font.chars.length = 0;\n face.clusters.clear();\n}\n\nonPagesEmptied(() => {\n for (const face of faces.values()) forgetGlyphs(face);\n});\n\nfunction getRasterizer(): GlyphRasterizer {\n if (!rasterizer) rasterizer = createCanvasRasterizer();\n return rasterizer;\n}\n\n/** Mark `family` as canvas-sourced: when no baked atlas covers it,\n * resolveFontVariant serves it from this dynamic atlas. */\nexport function registerCanvasFont(family: string): void {\n if (isExplicitCanvasFont(family)) return;\n canvasFamilies.add(family);\n // An explicit call promotes a previously auto-enrolled family for good.\n autoEnrolledFamilies.delete(family);\n notifyGlyphReady();\n}\n\n/**\n * Will `family` be served by the dynamic canvas-SDF tier *right now*?\n *\n * Service, not membership — the answer depends on the fallback policy in\n * force and can change without any enrollment call:\n * - explicitly enrolled via `registerCanvasFont` → `true` under every\n * policy; a consumer naming a family outranks the policy.\n * - auto-enrolled by the `'canvas'` policy → `true` only while that policy\n * is still in force. The enrollment lapses rather than being discarded,\n * so returning to `'canvas'` makes it `true` again.\n * - never enrolled → `false`, including under `'canvas'` (that policy\n * enrolls lazily, on the first miss).\n */\nexport function isCanvasFont(family: string): boolean {\n if (!canvasFamilies.has(family)) return false;\n return !autoEnrolledFamilies.has(family) || getFontFallbackPolicy() === 'canvas';\n}\n\n/**\n * Every family the dynamic canvas-SDF tier will serve *right now* — the\n * enumeration companion to `isCanvasFont`, which answers one family at a\n * time. Same \"service, not membership\" rule: an auto-enrolled family appears\n * only while the `'canvas'` policy is in force. `listFonts` reports the baked\n * registry alone.\n *\n * `enrollment` distinguishes a consumer's explicit `registerCanvasFont` from\n * a lazy enrollment the policy made on a miss; both render identically, but\n * only the explicit one survives a policy change.\n */\nexport function listCanvasFonts(): readonly CanvasFontEntry[] {\n const out: CanvasFontEntry[] = [];\n for (const family of canvasFamilies) {\n if (!isCanvasFont(family)) continue;\n out.push({ family, enrollment: autoEnrolledFamilies.has(family) ? 'auto' : 'explicit' });\n }\n return out.sort((a, b) => a.family.localeCompare(b.family));\n}\n\n/**\n * @internal Enroll `family` on behalf of the `'canvas'` fallback policy.\n * Distinct from `registerCanvasFont` only in provenance: the enrollment\n * lapses (see `isExplicitCanvasFont`) if the policy later changes.\n */\nexport function autoEnrollCanvasFont(family: string): void {\n if (canvasFamilies.has(family) && !autoEnrolledFamilies.has(family)) return;\n canvasFamilies.add(family);\n autoEnrolledFamilies.add(family);\n}\n\n/**\n * @internal Enrolled by a consumer's own `registerCanvasFont` call rather than\n * by the `'canvas'` policy. Only these are served by the dynamic tier\n * regardless of the policy in force; an auto-enrolled family falls back to\n * whatever the current policy says once that policy is no longer `'canvas'`.\n */\nexport function isExplicitCanvasFont(family: string): boolean {\n return canvasFamilies.has(family) && !autoEnrolledFamilies.has(family);\n}\n\n/** Remove a canvas family. Its faces are dropped; the room its glyphs took\n * comes back when the pages next fill and are emptied. */\nexport function unregisterCanvasFont(family: string): void {\n if (!canvasFamilies.has(family)) return;\n canvasFamilies.delete(family);\n autoEnrolledFamilies.delete(family);\n for (const key of [...faces.keys()]) {\n if (faces.get(key)!.family === family) faces.delete(key);\n }\n notifyGlyphReady();\n}\n\n/**\n * Internal resolver helper — not part of the public barrel; consumers go\n * through registerCanvasFont + resolveFontVariant.\n */\nexport function getDynamicFace(\n family: string, weight: number, style: FontStyle,\n): DynamicFace {\n const key = `${family}|${weight}|${style}`;\n const existing = faces.get(key);\n if (existing) return existing;\n\n const r = getRasterizer();\n const font: BmFont = {\n info: { face: family, size: BAKE_SIZE },\n common: { lineHeight: 0, base: 0, scaleW: PAGE_SIZE, scaleH: PAGE_SIZE },\n chars: [],\n kernings: [], // no kerning in v1 (measured-pair kerning is future work)\n charMap: new Map(),\n kerningMap: new Map(),\n };\n\n /** An unbaked record for a glyph the rasterizer placed at `left`, `top`. */\n const record = (id: number, raster: { left: number; top: number; advance: number }): BmFontChar => ({\n id, x: 0, y: 0, width: 0, height: 0,\n xoffset: raster.left,\n yoffset: font.common.base - raster.top,\n xadvance: raster.advance,\n page: -1,\n });\n const clusters = new Map<string, BmFontChar | null>();\n\n const face: Face = {\n family, weight, style, font, clusters,\n requestGlyph(cp: number): BmFontChar {\n const cached = font.charMap.get(cp);\n if (cached) return cached;\n const raster = r.rasterize(family, weight, style, cp);\n const char = record(cp, raster);\n font.charMap.set(cp, char);\n font.chars.push(char);\n requestBake(char, raster);\n return char;\n },\n requestCluster(text: string): BmFontChar | null {\n const cached = clusters.get(text);\n if (cached !== undefined) return cached;\n const raster = r.rasterizeColor?.(family, weight, style, text) ?? null;\n const char: BmFontChar | null = raster && { ...record(text.codePointAt(0)!, raster), color: true };\n clusters.set(text, char);\n if (char && raster) {\n requestBake(char, raster);\n addSharpSource(char, font.common.base, (size) => r.rasterizeColor?.(family, weight, style, text, size) ?? null);\n }\n return char;\n },\n };\n measureFace(face);\n faces.set(key, face);\n stopWatchingLoads ??= watchFontLoads(refreshFamilies);\n return face;\n}\n\n/** Read `face`'s metrics off the canvas, and forget the glyphs measured before. */\nfunction measureFace(face: Face): void {\n const { font } = face;\n const metrics = getRasterizer().faceMetrics(face.family, face.weight, face.style);\n font.common.lineHeight = Math.round(metrics.ascent + metrics.descent);\n font.common.base = Math.round(metrics.ascent);\n // Unrounded, unlike `common`: layout places the baseline from these.\n font.faceMetrics = { ascent: metrics.ascent / BAKE_SIZE, descent: metrics.descent / BAKE_SIZE };\n forgetGlyphs(face);\n}\n\n/**\n * Measure `family`'s canvas faces again, or every family's when none is named.\n *\n * The tier keeps each face's metrics and each glyph's shape and advance from\n * the first time it is asked. A web font that finishes loading after that is\n * picked up from `document.fonts` without this call; a face the document\n * never announces, one loaded before it was added, needs it.\n */\nexport function refreshCanvasFont(family?: string): void {\n refreshFamilies(family === undefined ? null : [family]);\n}\n\nfunction refreshFamilies(families: readonly string[] | null): void {\n const keys = families && new Set(families.map(familyKey));\n const dropped = new Set<BmFontChar>();\n let measured = 0;\n for (const face of faces.values()) {\n if (keys && !face.family.split(',').some((name) => keys.has(familyKey(name)))) continue;\n for (const char of face.font.chars) dropped.add(char);\n for (const char of face.clusters.values()) {\n if (!char) continue;\n dropped.add(char);\n for (const sharp of sharpBakesOf(char)) dropped.add(sharp);\n }\n measureFace(face);\n measured++;\n }\n if (measured === 0) return;\n // Their rects stay taken until the pages next fill and are emptied.\n dropBakes(dropped);\n notifyGlyphReady();\n}\n\n/** @internal test seam — inject a fake rasterizer (jsdom has no canvas\n * metrics). Pass null to restore the lazy default. */\nexport function __setGlyphRasterizerForTests(r: GlyphRasterizer | null): void {\n rasterizer = r;\n}\n\n/** @internal test seam — clear all dynamic-font state. */\nexport function _resetDynamicFontsForTests(): void {\n canvasFamilies.clear();\n autoEnrolledFamilies.clear();\n faces = new Map();\n _resetPagesForTests();\n _resetBakeQueueForTests();\n stopWatchingLoads?.();\n stopWatchingLoads = null;\n _clearGlyphReadySubscribers();\n rasterizer = null;\n}\n","/**\n * The parsed-font seam for the outline tier.\n *\n * A face describes a glyph as **SVG path data in em space**: one unit is one\n * em, y grows downward, and the origin sits on the baseline at the glyph's pen\n * position. That is independent of size, zoom, and position, so a glyph is\n * tessellated once and transformed per instance.\n *\n * `d` and not a command stream: `@weasel-js/core` depends on this package and\n * never the reverse, so it cannot name core's `PolygonPath`, and SVG `d` is\n * the kit's language for geometry crossing a boundary (`docs/conventions.md`).\n */\n\nimport type { FaceMetrics } from '../faceMetrics';\n\n/** A parsed font face, viewed only as a source of glyph outlines. See the\n * module comment for the em-space contract `glyphD` returns. */\nexport interface OutlineFace {\n /** Font design units per em. Reported for diagnostics; `glyphD` has already\n * divided by it, so callers never need to. */\n unitsPerEm: number;\n /**\n * Distance from the line top to the baseline, in em units — the outline\n * tier's analogue of a `BmFont`'s `common.base`.\n *\n * The default parser reports `faceMetrics.ascent`, the ascent a browser\n * sets the face with, so a face used for metrics puts text on the same\n * baseline as an atlas of the same font and as the DOM edit overlay.\n */\n ascender: number;\n /** The face's decoration and script metrics, derived with\n * `faceMetricsFromTables` so they match an atlas baked from the same\n * font. Optional: a custom parser that omits it leaves layout on its\n * defaults. */\n faceMetrics?: FaceMetrics;\n /**\n * Em-space SVG path data for `cp`, or `null` when this face has no glyph\n * for the codepoint *or* the glyph has no contours (a space).\n */\n glyphD(cp: number): string | null;\n /**\n * Advance width for `cp` in em units, or `null` when the face has no glyph\n * for it. A space has an advance and no contours.\n */\n advanceOf(cp: number): number | null;\n /** Kerning adjustment between two codepoints, in em units — negative pulls\n * them together. `0` when the face kerns neither this pair nor at all. */\n kernOf(left: number, right: number): number;\n /** The face's raw material for embedding it whole in another format (a PDF).\n * Optional: a custom parser that has no sfnt behind it omits it, and so\n * does the built-in one for a WOFF file. */\n embedding?(): FaceEmbedding;\n}\n\n/** What a document format needs to embed one face as a font program. */\nexport interface FaceEmbedding {\n /** One face's sfnt: a collection member is cut out of its collection. */\n sfnt: ArrayBuffer;\n postScriptName: string;\n unitsPerEm: number;\n /** `'cff'` when the face has a `CFF ` table and no `glyf`. */\n outlines: 'truetype' | 'cff';\n /** False when OS/2 fsType forbids embedding (bit 1, 0x0002) or allows\n * bitmaps only (bit 9, 0x0200). */\n embeddable: boolean;\n /** Glyph index for a codepoint; `null` for `.notdef` (0). */\n glyphIndexOf(cp: number): number | null;\n /** Advance of a glyph, in font units. */\n advanceOfGlyph(gid: number): number;\n /** Font units. */\n ascent: number;\n /** Font units, negative below the baseline. */\n descent: number;\n /** Font units. */\n capHeight: number;\n /** Degrees counterclockwise from vertical; negative leans right. */\n italicAngle: number;\n /** `[xMin, yMin, xMax, yMax]` in font units. */\n bbox: readonly [number, number, number, number];\n}\n\n/**\n * Turn font file bytes into a face. May be async: the default implementation\n * dynamically imports its parser.\n */\nexport type OutlineParser = (bytes: ArrayBuffer) => OutlineFace | Promise<OutlineFace>;\n\n/**\n * Decimal places kept when serializing em-space coordinates.\n *\n * Below: 1e-5 em is 0.01px on a 1000px-tall glyph. Above: `pathFromD`'s\n * tokenizer splits argument runs on *letters*, so a coordinate that JavaScript\n * prints in exponential form (`1e-7`) would tokenize as the command `e`.\n * Numbers stay in positional notation down to 1e-6, so five decimals cannot\n * produce one.\n */\nexport const OUTLINE_PRECISION = 5;\n","/** The four-character tag at `offset`: a table name, a resource type, a signature. */\nexport function tagAt(view: DataView, offset: number): string {\n return String.fromCharCode(\n view.getUint8(offset), view.getUint8(offset + 1),\n view.getUint8(offset + 2), view.getUint8(offset + 3),\n );\n}\n","/**\n * Datafork TrueType (`.dfont`): a Macintosh resource fork written to a file's\n * data fork, holding each face as one whole sfnt in an `sfnt` resource.\n *\n * The fork is a data segment and a map. The map's type list names each\n * resource type and points at its reference list; a reference gives a\n * resource's offset into the data segment, where a length precedes its bytes.\n */\n\nimport { tagAt } from './tag';\n\nconst RESOURCE_HEADER_BYTES = 16;\nconst TYPE_ENTRY_BYTES = 8;\nconst REFERENCE_BYTES = 12;\n\n/** Every signature that opens a font file this tier can hand to a parser. */\nconst FONT_SIGNATURES: ReadonlySet<string> = new Set([\n '\\x00\\x01\\x00\\x00', 'true', 'typ1', 'OTTO', 'ttcf', 'wOFF', 'wOF2',\n]);\n\n/**\n * Is `bytes` a Datafork TrueType file (`.dfont`)?\n *\n * Unlike every other font format it opens with no signature — just the\n * resource header's four big-endian offsets. It is recognized by those\n * adding up, which is why the signature check has to run first: an sfnt's\n * header bytes are numbers too, and nothing stops them from coincidentally\n * being consistent.\n */\nexport function isDataForkFont(bytes: ArrayBuffer): boolean {\n if (bytes.byteLength < RESOURCE_HEADER_BYTES) return false;\n const view = new DataView(bytes);\n if (FONT_SIGNATURES.has(tagAt(view, 0))) return false;\n const dataOffset = view.getUint32(0);\n const mapOffset = view.getUint32(4);\n const dataLength = view.getUint32(8);\n const mapLength = view.getUint32(12);\n return dataOffset >= RESOURCE_HEADER_BYTES\n && dataOffset + dataLength === mapOffset\n && mapOffset + mapLength <= bytes.byteLength;\n}\n\nconst truncated = (): Error =>\n new Error('Datafork TrueType (.dfont) is truncated: a resource runs past the end of its segment.');\n\n/**\n * Each `sfnt` resource of a `.dfont`, in map order, as standalone font bytes.\n * Empty when the fork holds none.\n */\nexport function sfntResources(bytes: ArrayBuffer): ArrayBuffer[] {\n const view = new DataView(bytes);\n const dataOffset = view.getUint32(0);\n const mapOffset = view.getUint32(4);\n const dataLength = view.getUint32(8);\n const mapEnd = mapOffset + view.getUint32(12);\n /** `count` bytes at `at` lie inside the map. */\n const inMap = (at: number, count: number): boolean => at >= mapOffset && at + count <= mapEnd;\n\n if (!inMap(mapOffset + 24, 2)) return [];\n const typeList = mapOffset + view.getUint16(mapOffset + 24);\n if (!inMap(typeList, 2)) return [];\n // Counts are stored less one, so an empty list reads as 0xffff.\n const typeCount = (view.getUint16(typeList) + 1) & 0xffff;\n\n const out: ArrayBuffer[] = [];\n for (let t = 0; t < typeCount; t++) {\n const entry = typeList + 2 + t * TYPE_ENTRY_BYTES;\n if (!inMap(entry, TYPE_ENTRY_BYTES)) throw truncated();\n if (tagAt(view, entry) !== 'sfnt') continue;\n const count = view.getUint16(entry + 4) + 1;\n const references = typeList + view.getUint16(entry + 6);\n for (let i = 0; i < count; i++) {\n const ref = references + i * REFERENCE_BYTES;\n if (!inMap(ref, REFERENCE_BYTES)) throw truncated();\n // A three-byte offset, behind the one-byte attributes it shares a word with.\n const offset = view.getUint32(ref + 4) & 0xffffff;\n if (offset + 4 > dataLength) throw truncated();\n const start = dataOffset + offset + 4;\n const length = view.getUint32(start - 4);\n if (offset + 4 + length > dataLength) throw truncated();\n out.push(bytes.slice(start, start + length));\n }\n }\n return out;\n}\n","/**\n * TrueType/OpenType collection unpacking.\n *\n * `queryLocalFonts()` hands back the font file behind a face, and on macOS\n * many of them — Helvetica, Times, Courier, Menlo — are `.ttc` collections\n * holding every weight and style in a single file with one shared glyph\n * store. A collection's header is `ttcf` rather than an sfnt version, so\n * opentype.js throws on it.\n *\n * A collection is N table directories over one pool of tables: pick the\n * directory whose PostScript name matches the face we were asked for, then\n * re-emit it as a standalone sfnt with the tables copied and the offsets\n * rewritten. This runs before anything parses, so it is parser-agnostic.\n * fontkit handles `.ttc` and `.dfont` natively, but is ~5.6 MB unpacked\n * across nine dependencies.\n *\n * `.dfont` (Datafork TrueType) is the other container: whole fonts inside a\n * Macintosh resource map, read by `dataFork.ts` and selected here by the same\n * PostScript name.\n */\n\nimport { isDataForkFont, sfntResources } from './dataFork';\nimport { tagAt } from './tag';\n\nexport { isDataForkFont };\n\nconst SFNT_HEADER_BYTES = 12;\nconst TABLE_RECORD_BYTES = 16;\n\n/** Is `bytes` a font collection rather than a single font? */\nexport function isFontCollection(bytes: ArrayBuffer): boolean {\n if (bytes.byteLength < 4) return false;\n return tagAt(new DataView(bytes), 0) === 'ttcf';\n}\n\ninterface TableRecord { tag: string; offset: number; length: number; checksum: number }\n\nfunction readTableDirectory(view: DataView, dirOffset: number): TableRecord[] {\n const numTables = view.getUint16(dirOffset + 4);\n const records: TableRecord[] = [];\n for (let i = 0; i < numTables; i++) {\n const at = dirOffset + SFNT_HEADER_BYTES + i * TABLE_RECORD_BYTES;\n records.push({\n tag: tagAt(view, at),\n checksum: view.getUint32(at + 4),\n offset: view.getUint32(at + 8),\n length: view.getUint32(at + 12),\n });\n }\n return records;\n}\n\n/**\n * PostScript name (`name` table, nameID 6) of a sub-font, or `null` when it\n * carries none. PostScript names are ASCII by specification, so both the\n * Macintosh (single-byte) and Windows (UTF-16BE) encodings reduce to \"take\n * every byte that isn't a zero pad\".\n */\nfunction postScriptNameAt(view: DataView, records: readonly TableRecord[]): string | null {\n const name = records.find((r) => r.tag === 'name');\n if (!name) return null;\n const base = name.offset;\n const count = view.getUint16(base + 2);\n const stringOffset = view.getUint16(base + 4);\n for (let i = 0; i < count; i++) {\n const rec = base + 6 + i * 12;\n if (view.getUint16(rec + 6) !== 6) continue; // nameID 6 === PostScript name\n const length = view.getUint16(rec + 8);\n const offset = view.getUint16(rec + 10);\n let out = '';\n for (let b = 0; b < length; b++) {\n const code = view.getUint8(base + stringOffset + offset + b);\n if (code !== 0) out += String.fromCharCode(code);\n }\n if (out.length > 0) return out;\n }\n return null;\n}\n\n/** Re-emit the table directory at `dirOffset` as a standalone sfnt buffer. */\nfunction extractFont(source: ArrayBuffer, view: DataView, dirOffset: number): ArrayBuffer {\n const records = readTableDirectory(view, dirOffset);\n // Tables are copied 4-byte aligned, which is what the format requires and\n // what every checksum in the directory was computed over.\n const padded = (n: number): number => (n + 3) & ~3;\n let total = SFNT_HEADER_BYTES + records.length * TABLE_RECORD_BYTES;\n for (const r of records) {\n if (r.offset + r.length > source.byteLength) {\n throw new Error(`font collection is truncated: table \"${r.tag}\" runs past the end of the file`);\n }\n total += padded(r.length);\n }\n\n const out = new ArrayBuffer(total);\n const dst = new DataView(out);\n const dstBytes = new Uint8Array(out);\n const srcBytes = new Uint8Array(source);\n\n dst.setUint32(0, view.getUint32(dirOffset)); // sfntVersion\n dst.setUint16(4, records.length);\n // searchRange / entrySelector / rangeShift are a binary-search hint over the\n // table records. Recomputed rather than copied: the member directory's\n // values describe its own table count, which is usually but not always the\n // same, and a wrong hint is a parser walking off the end of the directory.\n const entrySelector = Math.floor(Math.log2(records.length));\n const searchRange = 2 ** entrySelector * 16;\n dst.setUint16(6, searchRange);\n dst.setUint16(8, entrySelector);\n dst.setUint16(10, records.length * 16 - searchRange);\n\n let cursor = SFNT_HEADER_BYTES + records.length * TABLE_RECORD_BYTES;\n records.forEach((r, i) => {\n const at = SFNT_HEADER_BYTES + i * TABLE_RECORD_BYTES;\n for (let b = 0; b < 4; b++) dst.setUint8(at + b, r.tag.charCodeAt(b));\n dst.setUint32(at + 4, r.checksum);\n dst.setUint32(at + 8, cursor);\n dst.setUint32(at + 12, r.length);\n dstBytes.set(srcBytes.subarray(r.offset, r.offset + r.length), cursor);\n cursor += padded(r.length);\n });\n return out;\n}\n\n/**\n * Standalone font bytes for one member of a collection or a `.dfont`.\n *\n * `postScriptName` selects the member; when it is absent or matches nothing,\n * the first member is returned, `matched` says which happened, and `names`\n * lists every member's PostScript name. A single font passes through\n * unchanged.\n */\nexport function sfntFromCollection(\n bytes: ArrayBuffer,\n postScriptName?: string,\n): { bytes: ArrayBuffer; matched: boolean; names: readonly (string | null)[] } {\n const members = membersOf(bytes);\n if (!members) return { bytes, matched: true, names: [] };\n const names = members.map((m) => m.name);\n const at = postScriptName ? names.indexOf(postScriptName) : 0;\n return { bytes: members[Math.max(at, 0)].bytes(), matched: at >= 0, names };\n}\n\ninterface Member { name: string | null; bytes: () => ArrayBuffer }\n\n/** The fonts a container holds, or `null` when `bytes` is a single font. */\nfunction membersOf(bytes: ArrayBuffer): Member[] | null {\n if (isDataForkFont(bytes)) {\n const fonts = sfntResources(bytes);\n if (fonts.length === 0) throw new Error('Datafork TrueType (.dfont) holds no sfnt resource.');\n return fonts.map((font) => {\n const view = new DataView(font);\n return { name: postScriptNameAt(view, readTableDirectory(view, 0)), bytes: () => font };\n });\n }\n if (!isFontCollection(bytes)) return null;\n\n const view = new DataView(bytes);\n const numFonts = view.getUint32(8);\n if (numFonts === 0) throw new Error('font collection contains no fonts');\n\n const members: Member[] = [];\n for (let i = 0; i < numFonts; i++) {\n const dirOffset = view.getUint32(12 + i * 4);\n members.push({\n name: postScriptNameAt(view, readTableDirectory(view, dirOffset)),\n bytes: () => extractFont(bytes, view, dirOffset),\n });\n }\n return members;\n}\n","/**\n * Pair kerning read straight from a font's GPOS `kern` feature.\n *\n * opentype.js reads GPOS kerning only from lookups of type 2 and skips type 9\n * (Extension), which is where a large font puts its main kerning — Inter's\n * class-based pairs all sit behind one. So the pair lookups are read here,\n * extensions unwrapped.\n *\n * Scope: horizontal pair adjustment (PairPos formats 1 and 2), first glyph's\n * XAdvance, lookups of every `kern` feature in LookupList order regardless of\n * script. Contextual and mark positioning are out of scope — they don't\n * change a Latin run's width.\n *\n * Self-contained on purpose: `scripts/gen-font.ts` imports it under plain\n * Node, which strips types but resolves nothing else.\n */\n\n/** Kerning between two glyph ids, in font units; negative pulls them together. */\nexport type PairKerning = (left: number, right: number) => number;\n\n/**\n * Read the `kern` feature's pair lookups from a single-font sfnt (not a\n * collection). `null` when the font has no GPOS table or no `kern` feature —\n * the caller then falls back to the legacy `kern` table.\n */\nexport function gposPairKerning(bytes: ArrayBuffer): PairKerning | null {\n const v = new DataView(bytes);\n // A WOFF's tables are compressed; opentype.js reads those, this does not.\n const version = v.byteLength >= 12 ? tag(v, 0) : '';\n if (version !== '\\0\\x01\\0\\0' && version !== 'true' && version !== 'OTTO') return null;\n const gpos = tableOffset(v, 'GPOS');\n if (gpos === null) return null;\n\n const featureList = gpos + v.getUint16(gpos + 6);\n const lookupList = gpos + v.getUint16(gpos + 8);\n const lookupIndexes = new Set<number>();\n const featureCount = v.getUint16(featureList);\n for (let i = 0; i < featureCount; i++) {\n const rec = featureList + 2 + i * 6;\n if (tag(v, rec) !== 'kern') continue;\n const feature = featureList + v.getUint16(rec + 4);\n const count = v.getUint16(feature + 2);\n for (let j = 0; j < count; j++) lookupIndexes.add(v.getUint16(feature + 4 + j * 2));\n }\n if (lookupIndexes.size === 0) return null;\n\n const lookups: number[][] = [];\n for (const index of [...lookupIndexes].sort((a, b) => a - b)) {\n const lookup = lookupList + v.getUint16(lookupList + 2 + index * 2);\n const type = v.getUint16(lookup);\n const subtables: number[] = [];\n const count = v.getUint16(lookup + 4);\n for (let j = 0; j < count; j++) {\n let sub = lookup + v.getUint16(lookup + 6 + j * 2);\n let subType = type;\n if (type === 9) {\n subType = v.getUint16(sub + 2);\n sub += v.getUint32(sub + 4);\n }\n if (subType === 2) subtables.push(sub);\n }\n if (subtables.length > 0) lookups.push(subtables);\n }\n\n const memo = new Map<number, number>();\n return (left, right) => {\n const key = left * 0x10000 + right;\n const hit = memo.get(key);\n if (hit !== undefined) return hit;\n let total = 0;\n for (const subtables of lookups) {\n for (const sub of subtables) {\n const value = pairValue(v, sub, left, right);\n if (value !== null) { total += value; break; }\n }\n }\n memo.set(key, total);\n return total;\n };\n}\n\nfunction tag(v: DataView, at: number): string {\n return String.fromCharCode(v.getUint8(at), v.getUint8(at + 1), v.getUint8(at + 2), v.getUint8(at + 3));\n}\n\nfunction tableOffset(v: DataView, name: string): number | null {\n const count = v.getUint16(4);\n for (let i = 0; i < count; i++) {\n const rec = 12 + i * 16;\n if (tag(v, rec) === name) return v.getUint32(rec + 8);\n }\n return null;\n}\n\n/** Bytes in a ValueRecord of this format: two per set bit. */\nfunction valueSize(format: number): number {\n let n = 0;\n for (let f = format; f; f >>= 1) n += f & 1;\n return n * 2;\n}\n\n/** XAdvance of the ValueRecord at `at`, or 0 when the format carries none. */\nfunction xAdvance(v: DataView, at: number, format: number): number {\n if (!(format & 0x4)) return 0;\n return v.getInt16(at + (format & 0x1 ? 2 : 0) + (format & 0x2 ? 2 : 0));\n}\n\n/** The subtable's adjustment for this pair, or `null` when it does not apply. */\nfunction pairValue(v: DataView, sub: number, left: number, right: number): number | null {\n const format = v.getUint16(sub);\n const covIndex = coverageIndex(v, sub + v.getUint16(sub + 2), left);\n if (covIndex < 0) return null;\n const vf1 = v.getUint16(sub + 4);\n const vf2 = v.getUint16(sub + 6);\n const recordSize = 2 + valueSize(vf1) + valueSize(vf2);\n\n if (format === 1) {\n const pairSet = sub + v.getUint16(sub + 10 + covIndex * 2);\n let lo = 0;\n let hi = v.getUint16(pairSet) - 1;\n while (lo <= hi) {\n const mid = (lo + hi) >> 1;\n const rec = pairSet + 2 + mid * recordSize;\n const second = v.getUint16(rec);\n if (second === right) return xAdvance(v, rec + 2, vf1);\n if (second < right) lo = mid + 1; else hi = mid - 1;\n }\n return null;\n }\n if (format === 2) {\n const class1 = classOf(v, sub + v.getUint16(sub + 8), left);\n const class2 = classOf(v, sub + v.getUint16(sub + 10), right);\n const class1Count = v.getUint16(sub + 12);\n const class2Count = v.getUint16(sub + 14);\n if (class1 >= class1Count || class2 >= class2Count) return null;\n const rec = sub + 16 + (class1 * class2Count + class2) * (recordSize - 2);\n return xAdvance(v, rec, vf1);\n }\n return null;\n}\n\nfunction coverageIndex(v: DataView, cov: number, glyph: number): number {\n const format = v.getUint16(cov);\n const count = v.getUint16(cov + 2);\n let lo = 0;\n let hi = count - 1;\n if (format === 1) {\n while (lo <= hi) {\n const mid = (lo + hi) >> 1;\n const g = v.getUint16(cov + 4 + mid * 2);\n if (g === glyph) return mid;\n if (g < glyph) lo = mid + 1; else hi = mid - 1;\n }\n return -1;\n }\n if (format === 2) {\n while (lo <= hi) {\n const mid = (lo + hi) >> 1;\n const rec = cov + 4 + mid * 6;\n const start = v.getUint16(rec);\n const end = v.getUint16(rec + 2);\n if (glyph < start) hi = mid - 1;\n else if (glyph > end) lo = mid + 1;\n else return v.getUint16(rec + 4) + glyph - start;\n }\n }\n return -1;\n}\n\nfunction classOf(v: DataView, def: number, glyph: number): number {\n const format = v.getUint16(def);\n if (format === 1) {\n const start = v.getUint16(def + 2);\n const count = v.getUint16(def + 4);\n const i = glyph - start;\n return i >= 0 && i < count ? v.getUint16(def + 6 + i * 2) : 0;\n }\n if (format === 2) {\n let lo = 0;\n let hi = v.getUint16(def + 2) - 1;\n while (lo <= hi) {\n const mid = (lo + hi) >> 1;\n const rec = def + 4 + mid * 6;\n if (glyph < v.getUint16(rec)) hi = mid - 1;\n else if (glyph > v.getUint16(rec + 2)) lo = mid + 1;\n else return v.getUint16(rec + 4);\n }\n }\n return 0;\n}\n","/**\n * The default `OutlineParser`: opentype.js, loaded on demand.\n *\n * The import is dynamic because opentype.js is ~49 kB gzipped and most\n * consumers render text through a baked atlas and never touch an outline.\n * The other candidate was Typr — smaller, but unmaintained and untyped.\n *\n * `glyph.getPath(0, 0, 1)` already emits exactly what `OutlineFace` promises:\n * font units divided by the em, y flipped to grow downward, and the origin on\n * the baseline at the pen position, so no transform is applied here.\n */\n\nimport { OUTLINE_PRECISION, type FaceEmbedding, type OutlineFace, type OutlineParser } from './OutlineFace';\nimport { sfntFromCollection } from './sfnt';\nimport { gposPairKerning, type PairKerning } from './gposKerning';\nimport { faceMetricsFromTables, type FaceMetricTables } from '../faceMetrics';\n\ntype OpenType = typeof import('opentype.js');\n\nlet modulePromise: Promise<OpenType> | null = null;\n\n/** Load (once) and cache the parser module. */\nfunction loadOpenType(): Promise<OpenType> {\n modulePromise ??= import('opentype.js');\n return modulePromise;\n}\n\n/**\n * opentype.js 2.0 publishes ESM under `module` and a UMD bundle under `main`.\n * Only a bundler reads `module`; Node takes the UMD one, whose named exports\n * it cannot detect, so `ns.parse` is `undefined` there and every face fails to\n * load. The registry catches that and degrades to the SDF tier, so a headless\n * consumer, which has no atlas, gets no glyphs and no explanation.\n *\n * Exported for the test: the suite resolves through vite, which reads\n * `module` and therefore cannot reproduce the shape that breaks.\n */\nexport function parserOf(ns: OpenType): OpenType['parse'] {\n const interop = ns as OpenType & { default?: OpenType };\n return interop.default?.parse ?? ns.parse;\n}\n\n/**\n * Wrap a parsed opentype.js font.\n *\n * `charToGlyphIndex` reports 0 — `.notdef` — for a codepoint the font does\n * not cover. That is a real glyph (the tofu box) and it renders, so report\n * the miss instead and let the caller's fallback ladder run.\n */\nfunction faceFor(\n font: import('opentype.js').Font, gpos: PairKerning | null, sfnt: ArrayBuffer,\n): OutlineFace {\n const upem = font.unitsPerEm;\n // Typed `any` by the 1.x typings; read through the narrow shape instead.\n const { hhea, post, os2 } = font.tables as Pick<FaceMetricTables, 'hhea' | 'post' | 'os2'>;\n const faceMetrics = faceMetricsFromTables({ unitsPerEm: upem, hhea, post, os2 });\n return {\n unitsPerEm: upem,\n ascender: faceMetrics?.ascent ?? font.ascender / upem,\n ...(faceMetrics ? { faceMetrics } : {}),\n advanceOf(cp: number): number | null {\n const index = font.charToGlyphIndex(String.fromCodePoint(cp));\n if (!index) return null;\n return (font.glyphs.get(index).advanceWidth ?? 0) / upem;\n },\n ...(isSfnt(sfnt) ? { embedding: () => embeddingOf(font, sfnt) } : {}),\n kernOf(left: number, right: number): number {\n const l = font.charToGlyphIndex(String.fromCodePoint(left));\n const r = font.charToGlyphIndex(String.fromCodePoint(right));\n if (!l || !r) return 0;\n if (gpos) return gpos(l, r) / upem;\n return font.getKerningValue(font.glyphs.get(l), font.glyphs.get(r)) / upem;\n },\n glyphD(cp: number): string | null {\n const index = font.charToGlyphIndex(String.fromCodePoint(cp));\n if (!index) return null;\n const d = font.glyphs.get(index).getPath(0, 0, 1).toPathData(OUTLINE_PRECISION);\n // A glyph with no contours (a space) serializes to the empty string.\n return d.length > 0 ? d : null;\n },\n };\n}\n\ninterface EmbedTables {\n os2?: { fsType?: number; sCapHeight?: number };\n head?: { xMin: number; yMin: number; xMax: number; yMax: number };\n post?: { italicAngle?: number };\n glyf?: unknown;\n cff?: unknown;\n}\n\n/** TrueType (`00 01 00 00`, `true`) or CFF (`OTTO`): a WOFF's bytes are not what FontFile2 holds. */\nfunction isSfnt(bytes: ArrayBuffer): boolean {\n if (bytes.byteLength < 4) return false;\n const tag = new DataView(bytes).getUint32(0);\n return tag === 0x00010000 || tag === 0x74727565 || tag === 0x4f54544f;\n}\n\n/** fsType bits that rule out embedding the outlines: restricted license, and bitmap embedding only. */\nconst NO_OUTLINE_EMBEDDING = 0x0002 | 0x0200;\n\nfunction embeddingOf(font: import('opentype.js').Font, sfnt: ArrayBuffer): FaceEmbedding {\n // Typed `any` by the 1.x typings; read through the narrow shape instead.\n const t = font.tables as EmbedTables;\n const englishName = (font as { getEnglishName?: (key: string) => string | undefined })\n .getEnglishName?.('postScriptName');\n return {\n sfnt,\n postScriptName: englishName ?? '',\n unitsPerEm: font.unitsPerEm,\n outlines: t.cff && !t.glyf ? 'cff' : 'truetype',\n embeddable: ((t.os2?.fsType ?? 0) & NO_OUTLINE_EMBEDDING) === 0,\n glyphIndexOf(cp) {\n return font.charToGlyphIndex(String.fromCodePoint(cp)) || null;\n },\n advanceOfGlyph: (gid) => font.glyphs.get(gid).advanceWidth ?? 0,\n ascent: font.ascender,\n descent: font.descender,\n capHeight: t.os2?.sCapHeight || font.ascender,\n italicAngle: t.post?.italicAngle ?? 0,\n bbox: [t.head?.xMin ?? 0, t.head?.yMin ?? 0, t.head?.xMax ?? 0, t.head?.yMax ?? 0],\n };\n}\n\n/**\n * Parse font file bytes into a face. Accepts single fonts and collections\n * (`.ttc`, `.dfont`); `postScriptName` picks the member of a collection, and\n * is ignored for a single font. A collection with no member of that name\n * rejects: its first member is usually Regular, and bold text drawn from it\n * is lighter above the outline threshold than below it.\n */\nexport function createOpenTypeParser(postScriptName?: string): OutlineParser {\n return async (bytes: ArrayBuffer): Promise<OutlineFace> => {\n const parse = parserOf(await loadOpenType());\n const { bytes: single, matched, names } = sfntFromCollection(bytes, postScriptName);\n if (!matched) {\n throw new Error(\n `no member of the font file is named \"${postScriptName}\" (it holds ${names.join(', ')})`);\n }\n return faceFor(parse(single), gposPairKerning(single), single);\n };\n}\n\n/** The parser used when a registration supplies none of its own. */\nexport const openTypeParser: OutlineParser = createOpenTypeParser();\n\n/** @internal Test seam — drop the memoized module so a test can re-import. */\nexport function _resetOpenTypeModuleForTests(): void {\n modulePromise = null;\n}\n","/**\n * The outline tier's registry: which faces have real font bytes behind them,\n * and what a given glyph looks like.\n *\n * ### What this tier is for\n *\n * A distance field is a *sampled* representation: the dynamic canvas-SDF tier\n * (`../dynamic/`) reconstructs its field from a 48px raster, so magnifying it\n * past a few times the bake size exposes the raster as contour wobble. Above a\n * size threshold the glyph's outline goes to the path renderer instead, which\n * is exact at every zoom and takes strokes and non-solid fills.\n *\n * Below the threshold the atlas still wins: outlines carry no hinting and no\n * stem darkening, so body text at 12–16px rendered from them looks *worse*\n * than a platform rasterizer that puts stems on the pixel grid.\n *\n * ### Metric neutrality (the load-bearing invariant)\n *\n * This tier replaces how a glyph is *painted*, never where it sits. Advances,\n * kerning, line breaking, and baselines all keep coming from whichever tier\n * resolved the run, so zooming past the threshold cannot reflow text. The cost\n * is that a face whose real advances disagree with the atlas's inherits the\n * atlas's.\n *\n * ### Availability\n *\n * Bytes arrive asynchronously, and in the local case behind a permission the\n * user can refuse, so `glyphOutline` answers `null` until a face is loaded and\n * forever if it failed, and the caller falls back to SDF. A family must never\n * render *nothing* because the outline tier could not get bytes.\n */\n\nimport { createReflectable, type Reflection } from '@weasel-js/registry';\nimport { notifyGlyphReady } from '../glyphReady';\nimport type { OutlineFace, OutlineParser } from './OutlineFace';\nimport type { FontStyle } from '../fontStyle';\nimport { openTypeParser } from './opentypeParser';\n\n/**\n * Where a face's bytes come from. A URL is fetched; a buffer or blob is used\n * as-is; a thunk is called at first use.\n */\nexport type OutlineSource =\n | string\n | ArrayBuffer\n | Blob\n | (() => ArrayBuffer | Blob | Promise<ArrayBuffer | Blob>);\n\n/** Which face within a family to register outlines for. Defaults to weight\n * 400, style `'normal'`. */\nexport interface OutlineVariant {\n weight?: number;\n style?: FontStyle;\n}\n\n/** Options for registering an outline font. */\nexport interface OutlineFontOptions {\n /** Override the default opentype.js parser. Mostly a test seam; also the\n * hook for a consumer who already has a font parser in their bundle. */\n parser?: OutlineParser;\n /**\n * The `@font-face` `src` that gives DOM text this face — what the text edit\n * overlay sets its glyphs in, so they match the canvas's. Defaults to\n * `url(…)` of a URL source and to the bytes themselves otherwise; a face\n * whose bytes the browser cannot load directly, such as one member of a\n * `.ttc`, names it here instead (`local(\"Helvetica-Bold\")`).\n */\n cssSrc?: string;\n}\n\n/** Load state of one registered face. */\nexport type OutlineStatus = 'idle' | 'loading' | 'ready' | 'failed';\n\n/** One registered outline face and its load state. */\nexport interface OutlineFaceInfo {\n readonly family: string;\n readonly weight: number;\n readonly style: FontStyle;\n readonly status: OutlineStatus;\n}\n\ninterface FaceSlot extends OutlineFaceInfo {\n source: OutlineSource;\n cssSrc: string | undefined;\n parser: OutlineParser;\n status: OutlineStatus;\n face: OutlineFace | null;\n /** Memoized `glyphD` answers, including the `null` misses — a codepoint the\n * face lacks is asked for on every frame that draws it. */\n glyphs: Map<number, string | null>;\n /** The in-flight or settled load, so every caller waiting on it shares one parse. */\n load: Promise<void> | null;\n}\n\nconst slots = createReflectable<FaceSlot>();\n\n/** Every registered outline face, keyed `family|weight|style`. */\nexport const fontOutlineRegistry: Reflection<OutlineFaceInfo> = slots.reflection;\n\nfunction slotKey(family: string, weight: number, style: FontStyle): string {\n return `${family}|${weight}|${style}`;\n}\n\nfunction normalize(v: OutlineVariant): { weight: number; style: FontStyle } {\n return { weight: v.weight ?? 400, style: v.style ?? 'normal' };\n}\n\n/**\n * Register font file bytes for one face, so text set in it can render from\n * outlines above the size threshold.\n *\n * Registration is cheap and synchronous: nothing is fetched, and the parser\n * is not even imported, until a frame actually asks for a glyph from this\n * face.\n *\n * The variant must match exactly what the layout tier resolved — this is\n * deliberately *not* a fallback chain. Painting 400-weight outlines at\n * 700-weight advances looks worse than the SDF it replaced; a miss falls back\n * to SDF instead.\n */\nexport function registerFontOutlines(\n family: string,\n variant: OutlineVariant,\n source: OutlineSource,\n opts: OutlineFontOptions = {},\n): void {\n const { weight, style } = normalize(variant);\n slots.set(slotKey(family, weight, style), {\n family, weight, style, source,\n cssSrc: opts.cssSrc,\n parser: opts.parser ?? openTypeParser,\n status: 'idle',\n face: null,\n glyphs: new Map(),\n load: null,\n });\n // Layouts cache which tier each run resolved to and poll `glyphGeneration()`\n // to know when to drop it; a registration that leaves it still is invisible.\n notifyGlyphReady();\n if (source instanceof ArrayBuffer) announceBytes(slots.get(slotKey(family, weight, style))!, source);\n}\n\n/** Drop a registration. Glyphs already handed out stay valid — they are\n * plain path data — but nothing further resolves from this face. */\nexport function unregisterFontOutlines(family: string, variant: OutlineVariant = {}): void {\n const { weight, style } = normalize(variant);\n // Only when something was actually dropped: a miss must not invalidate any layout.\n if (slots.delete(slotKey(family, weight, style))) notifyGlyphReady();\n}\n\n/**\n * Is an outline face registered for this exact variant? Answers `true` while\n * the bytes are still loading; use `outlineStatus` for \"can it right now\".\n */\nexport function hasFontOutlines(\n family: string, weight = 400, style: FontStyle = 'normal',\n): boolean {\n return slots.has(slotKey(family, weight, style));\n}\n\n/** Load state of a registered face; `null` when nothing is registered. */\nexport function outlineStatus(\n family: string, weight = 400, style: FontStyle = 'normal',\n): OutlineStatus | null {\n return slots.get(slotKey(family, weight, style))?.status ?? null;\n}\n\n/** Every registered outline face and its load state — the enumeration a\n * debug overlay or font picker needs, mirroring `listFonts`. */\nexport function listFontOutlines(): readonly OutlineFaceInfo[] {\n return slots.entries()\n .map(({ value: { family, weight, style, status } }) => ({ family, weight, style, status }))\n .sort((a, b) => a.family.localeCompare(b.family) || a.weight - b.weight\n || a.style.localeCompare(b.style));\n}\n\n/**\n * Close every contour of a glyph's path data.\n *\n * A glyph contour is closed by definition, but not every serializer writes\n * the `Z` that says so, and the omission is invisible until someone *strokes*\n * the outline: a fill closes the contour implicitly, while a stroke leaves the\n * closing edge unpainted, with a cap at each loose end. Normalized here rather\n * than in one parser so it covers every consumer-supplied `OutlineParser`.\n */\nexport function closeContours(d: string): string {\n let out = '';\n let start = 0;\n for (let i = 1; i < d.length; i++) {\n const c = d[i];\n if (c !== 'M' && c !== 'm') continue;\n out += closeOne(d.slice(start, i));\n start = i;\n }\n return out + closeOne(d.slice(start));\n}\n\nfunction closeOne(contour: string): string {\n const trimmed = contour.trimEnd();\n if (trimmed.length === 0) return '';\n const last = trimmed[trimmed.length - 1];\n return last === 'Z' || last === 'z' ? trimmed : `${trimmed}Z`;\n}\n\n/**\n * Em-space SVG path data for one glyph of a registered outline face, or `null`\n * when this tier cannot serve it — no registration, bytes still loading, load\n * failed, no such glyph, or a glyph with no contours.\n *\n * Synchronous and non-throwing: a face that has not been parsed yet starts\n * loading and answers `null` for now, so a renderer can call this every frame\n * and fall through to another text tier until the outline arrives.\n */\nexport function glyphOutline(\n family: string,\n weight: number,\n style: FontStyle,\n cp: number,\n): string | null {\n const slot = slots.get(slotKey(family, weight, style));\n if (!slot) return null;\n if (slot.status === 'idle') {\n void beginLoad(slot);\n return null;\n }\n if (slot.status !== 'ready') return null;\n\n const cached = slot.glyphs.get(cp);\n if (cached !== undefined) return cached;\n let d: string | null = null;\n try {\n const raw = slot.face!.glyphD(cp);\n d = raw === null ? null : closeContours(raw);\n } catch (err) {\n // A parser that throws on one glyph should cost that glyph, not the face.\n warnOnce(`glyph|${slotKey(family, weight, style)}`,\n `weasel: outline face \"${family}\" (${weight}/${style}) could not produce a glyph ` +\n `for U+${cp.toString(16).toUpperCase().padStart(4, '0')} — ` +\n `${err instanceof Error ? err.message : String(err)}. Falling back to the SDF tier.`);\n }\n slot.glyphs.set(cp, d);\n return d;\n}\n\n/**\n * Metrics for a registered outline face, or `null` when this tier cannot\n * supply them yet — nothing registered, bytes still loading, or a failed load.\n *\n * The face is the *only* metrics source for a family that has no atlas. A\n * family that has an atlas resolves to the atlas before anything asks here,\n * so registering outlines cannot move text that was already rendering.\n *\n * Starts the load on a first call and answers `null` for now, like\n * `glyphOutline`.\n */\nexport function outlineMetrics(\n family: string,\n weight: number,\n style: FontStyle,\n): OutlineFace | null {\n const slot = slots.get(slotKey(family, weight, style));\n if (!slot) return null;\n if (slot.status === 'idle') {\n void beginLoad(slot);\n return null;\n }\n return slot.status === 'ready' ? slot.face! : null;\n}\n\n/**\n * Load a registered face's bytes now and resolve with its settled status:\n * `'ready'`, `'failed'`, or `null` when nothing is registered for the\n * variant. Never rejects — a failed load is a status. For a caller that needs\n * the geometry in one go, such as converting text to paths.\n */\nexport async function loadFontOutlines(\n family: string, variant: OutlineVariant = {},\n): Promise<OutlineStatus | null> {\n const { weight, style } = normalize(variant);\n const slot = slots.get(slotKey(family, weight, style));\n if (!slot) return null;\n await beginLoad(slot);\n return slot.status;\n}\n\nfunction beginLoad(slot: FaceSlot): Promise<void> {\n slot.load ??= runLoad(slot);\n return slot.load;\n}\n\nasync function runLoad(slot: FaceSlot): Promise<void> {\n slot.status = 'loading';\n slots.bump();\n try {\n const bytes = await readSource(slot.source);\n announceBytes(slot, bytes);\n slot.face = await slot.parser(bytes);\n slot.status = 'ready';\n slots.bump();\n // The frame that asked for these glyphs has long since drawn, and on a\n // static document nothing else invalidates the canvas.\n notifyGlyphReady();\n } catch (err) {\n slot.status = 'failed';\n slots.bump();\n // A layout that found this face still loading deferred its judgment on\n // the family; wake it so it can make one.\n notifyGlyphReady();\n warnOnce(`load|${slotKey(slot.family, slot.weight, slot.style)}`,\n `weasel registerFontOutlines(\"${slot.family}\" ${slot.weight}/${slot.style}): ` +\n `${err instanceof Error ? err.message : String(err)}. Large text in this face ` +\n `keeps rendering from the SDF tier.`);\n }\n}\n\n/**\n * Where DOM text gets one face, from {@link outlineCssSource}. `registration`\n * is the same object until the face is registered again.\n */\nexport type OutlineCssSource =\n /** The registration's `cssSrc`, which names what the bytes cannot. */\n | { registration: OutlineFaceInfo; src: string }\n /** A URL source, as `url(…)`: interchangeable with its bytes. */\n | { registration: OutlineFaceInfo; url: string }\n | { registration: OutlineFaceInfo; bytes: () => Promise<ArrayBuffer> };\n\n/**\n * Where DOM text gets this face. `null` when nothing is registered.\n * In-package only.\n */\nexport function outlineCssSource(\n family: string, weight: number, style: FontStyle,\n): OutlineCssSource | null {\n const slot = slots.get(slotKey(family, weight, style));\n if (!slot) return null;\n if (slot.cssSrc !== undefined) return { registration: slot, src: slot.cssSrc };\n if (typeof slot.source === 'string') {\n return { registration: slot, url: `url(${JSON.stringify(slot.source)})` };\n }\n const source = slot.source;\n return { registration: slot, bytes: () => readSource(source) };\n}\n\n/** `registration` is the one {@link outlineCssSource} names. */\ntype BytesListener = (registration: OutlineFaceInfo, bytes: ArrayBuffer) => void;\nlet bytesListener: BytesListener | null = null;\n\n/**\n * Hear about a face's bytes the moment they are in hand — handed to\n * `registerFontOutlines` directly, or read because the canvas asked for the\n * face. Never earlier: a URL or thunk registration fetches nothing until then.\n * One listener; in-package only.\n */\nexport function onOutlineBytes(listener: BytesListener): void {\n bytesListener = listener;\n}\n\nfunction announceBytes(slot: FaceSlot, bytes: ArrayBuffer): void {\n try {\n bytesListener?.(slot, bytes);\n } catch {\n // DOM text falling behind must not cost the canvas its outlines.\n }\n}\n\nasync function readSource(source: OutlineSource): Promise<ArrayBuffer> {\n const resolved = typeof source === 'function' ? await source() : source;\n if (typeof resolved === 'string') {\n const res = await fetch(resolved);\n if (!res.ok) throw new Error(`HTTP ${res.status} fetching ${resolved}`);\n return res.arrayBuffer();\n }\n if (resolved instanceof ArrayBuffer) return resolved;\n return resolved.arrayBuffer();\n}\n\n// Loading and glyph lookup both run off the render loop, so an unguarded warn\n// would repeat every frame.\nconst warned = new Set<string>();\n\nfunction warnOnce(key: string, message: string): void {\n if (warned.has(key)) return;\n warned.add(key);\n console.warn(message);\n}\n\n/** @internal Test seam — registry and warn-once keys are module state. */\nexport function _resetFontOutlinesForTests(): void {\n slots.clear();\n warned.clear();\n}\n","import type { FontStyle } from './fontStyle';\n\n/** Keys already built, by style and weight, so resolving a face every frame\n * builds no string. */\nconst variantKeys = new Map<FontStyle, Map<number, string>>();\n\n/** A registered variant's key in its family's map: `<weight>|<style>`. */\nexport function variantKey(weight: number, style: FontStyle): string {\n let byWeight = variantKeys.get(style);\n if (byWeight === undefined) variantKeys.set(style, (byWeight = new Map()));\n let key = byWeight.get(weight);\n if (key === undefined) {\n key = `${weight}|${style}`;\n if (byWeight.size < 1024) byWeight.set(weight, key);\n }\n return key;\n}\n","import type { FontStyle } from './fontStyle';\nimport type { FontEntry, ResolveResult } from './registerFont';\n\n/** A resolution landing on a baked atlas face. */\nexport function atlasResult(\n entry: FontEntry, family: string, weight: number, style: FontStyle, bold: boolean, italic: boolean,\n): ResolveResult {\n return { entry, resolved: { family, weight, style }, synthetic: { bold, italic }, source: 'atlas' };\n}\n\nconst exactResults = new WeakMap<FontEntry, Readonly<ResolveResult>>();\n\n/** The exact match on `entry`, one frozen object per face for as long as the\n * face stays registered. */\nexport function sharedExactResult(\n entry: FontEntry, family: string, weight: number, style: FontStyle,\n): Readonly<ResolveResult> {\n const hit = exactResults.get(entry);\n if (hit !== undefined && hit.resolved.family === family && hit.resolved.weight === weight\n && hit.resolved.style === style) return hit;\n const r = atlasResult(entry, family, weight, style, false, false);\n Object.freeze(r.resolved);\n Object.freeze(r.synthetic);\n exactResults.set(entry, Object.freeze(r));\n return r;\n}\n","/**\n * The atlas font registry, keyed by (family, weight, style), and the fallback\n * chain that resolves a request against it.\n */\n\nimport { textureCacheKey } from './textureCacheKey';\nimport { variantKey } from './variantKey';\nimport { createReflectable, type Reflection } from '@weasel-js/registry';\nimport type { FontStyle } from './fontStyle';\nimport { notifyGlyphReady } from './glyphReady';\nimport { parseBmFont, type BmFont } from './FontAtlas';\nimport type { GlyphTextureSink } from './textureSink';\nimport {\n isCanvasFont, isExplicitCanvasFont, autoEnrollCanvasFont, getDynamicFace,\n type DynamicFace,\n} from './dynamic/dynamicAtlas';\nimport {\n getFontFallbackPolicy, getDefaultFontFamily,\n claimFallbackWarning, _clearFallbackWarnings,\n} from './fallback';\nimport {\n hasFontOutlines, listFontOutlines, loadFontOutlines, outlineMetrics, outlineStatus,\n} from './outline/outlineRegistry';\nimport type { OutlineFace } from './outline/OutlineFace';\nimport type { FaceMetrics } from './faceMetrics';\nimport { atlasResult, sharedExactResult } from './atlasResult';\n\n/** A registered face: its parsed metrics and the atlas image to sample. */\nexport interface FontEntry {\n font: BmFont;\n bitmap: ImageBitmap;\n}\n\n/** Which face within a family. Defaults to weight 400, style `'normal'`. */\nexport interface FontVariant {\n weight?: number;\n style?: FontStyle;\n}\n\n\n/** One family's registered faces, keyed `${weight}|${style}`. */\nexport type FontFamilyFaces = ReadonlyMap<string, FontEntry>;\n\nconst registry = createReflectable<FontFamilyFaces>();\n\n/** Every registered family and its faces, in registration order. `listFonts`\n * is the same set shaped for a font picker. */\nexport const fontRegistry: Reflection<FontFamilyFaces> = registry.reflection;\n\nfunction normalizeVariant(v: FontVariant): { weight: number; style: FontStyle } {\n return {\n weight: v.weight ?? 400,\n style: v.style ?? 'normal',\n };\n}\n\n/** Atlas registrations still fetching, per family. One token per call, so a\n * reset that clears the map cannot be undone by a late `finally`. */\nconst inFlight = new Map<string, Set<object>>();\n\n/** One variant's fetch, keyed `family|weight|style`, so a lazy declaration and\n * an eager call for the same face share it. */\nconst loads = new Map<string, Promise<void>>();\n\n/** A lazily registered variant nothing has asked for yet. */\ninterface Declared {\n metricsUrl: string;\n atlasUrl: string;\n promise: Promise<void>;\n settle: (load: Promise<void>) => void;\n}\n\n/** Lazy registrations not yet started, per family, keyed like `registry`. */\nconst declared = new Map<string, Map<string, Declared>>();\n\n/** Every family `registerFont` was called for, eager or lazy, in call order —\n * what \"the first registered family\" means to the substitute policy. */\nconst registeredFamilies = new Set<string>();\n\n/** Test helper. Do not call from product code. */\nexport function _resetFontRegistryForTests(): void {\n registry.clear();\n inFlight.clear();\n loads.clear();\n declared.clear();\n registeredFamilies.clear();\n _clearFallbackWarnings();\n}\n\n/** Exact lookup — does NOT walk the fallback chain. Use `resolveFontVariant` for that. */\nexport function getFont(\n family: string,\n weight: number = 400,\n style: FontStyle = 'normal',\n): FontEntry | null {\n return registry.get(family)?.get(variantKey(weight, style)) ?? null;\n}\n\n/**\n * The decoration and script metrics of an exact `(family, weight, style)` —\n * the atlas's when one is registered, else a loaded outline face's. Like\n * {@link getFont}, it walks no fallback chain and enrolls no canvas font.\n * An idle outline face starts loading, as it would for layout.\n * A run already resolved for layout reads `faceMetricsOf(result)` instead.\n */\nexport function faceMetricsFor(\n family: string,\n weight: number = 400,\n style: FontStyle = 'normal',\n): FaceMetrics | undefined {\n return getFont(family, weight, style)?.font.faceMetrics\n ?? outlineMetrics(family, weight, style === 'italic' ? 'italic' : 'normal')?.faceMetrics;\n}\n\n/** One family in the registry and the variants registered for it — what a\n * font picker can honestly offer. */\nexport interface RegisteredFont {\n family: string;\n variants: readonly { weight: number; style: FontStyle }[];\n}\n\n/**\n * Enumerate the registry. Families come back in registration order; variants\n * sorted by weight, then style.\n */\nexport function listFonts(): readonly RegisteredFont[] {\n const out: RegisteredFont[] = [];\n for (const family of registeredFamilies) {\n const keys = new Set([\n ...(registry.get(family)?.keys() ?? []),\n ...(declared.get(family)?.keys() ?? []),\n ]);\n if (keys.size === 0) continue;\n const variants = [...keys]\n .map((key) => {\n const [w, s] = key.split('|') as [string, FontStyle];\n return { weight: Number(w), style: s };\n })\n .sort((a, b) => a.weight - b.weight || a.style.localeCompare(b.style));\n out.push({ family, variants });\n }\n return out;\n}\n\n/**\n * The weights `family` has a real face for, on the atlas tier or the outline\n * tier, in either style. Ascending and deduplicated; empty for a family\n * nothing registered. An outline face whose load failed is left out. The\n * canvas tier is not consulted: it rasterizes whatever weight it is asked for.\n */\nexport function listFontWeights(family: string): readonly number[] {\n const weights = new Set<number>();\n for (const key of registry.get(family)?.keys() ?? []) weights.add(Number(key.split('|')[0]));\n for (const key of declared.get(family)?.keys() ?? []) weights.add(Number(key.split('|')[0]));\n for (const face of listFontOutlines()) {\n if (face.family === family && face.status !== 'failed') weights.add(face.weight);\n }\n return [...weights].sort((a, b) => a - b);\n}\n\n/** Options for {@link registerFont}. */\nexport interface RegisterFontOptions {\n /**\n * Fetch nothing until text first resolves this face. Layout treats the face\n * as pending from registration on, so a run set in it lays out as nothing —\n * never in a fallback face's metrics — and relays out when the atlas lands.\n * The returned promise settles with that load, so it never settles for a\n * face no text uses.\n */\n lazy?: boolean;\n}\n\n/**\n * Register a baked MSDF atlas and its metrics as one variant of `family`.\n * Resolves once the face is usable; re-registering a variant that is already\n * present is a no-op.\n *\n * Eager by default: both files are fetched now. With `{ lazy: true }` they are\n * fetched the first time text asks for the family.\n */\nexport function registerFont(\n family: string,\n variant: FontVariant,\n metricsUrl: string,\n atlasUrl: string,\n opts: RegisterFontOptions = {},\n): Promise<void> {\n const { weight, style } = normalizeVariant(variant);\n const key = variantKey(weight, style);\n registeredFamilies.add(family);\n\n if (registry.get(family)?.has(key)) return Promise.resolve();\n if (!opts.lazy) return loadVariant(family, key, metricsUrl, atlasUrl);\n\n const running = loads.get(`${family}|${key}`);\n if (running) return running;\n const existing = declared.get(family)?.get(key);\n if (existing) return existing.promise;\n\n let settle!: (load: Promise<void>) => void;\n const promise = new Promise<void>((resolve, reject) => {\n settle = (load) => { load.then(resolve, reject); };\n });\n const variants = declared.get(family) ?? new Map<string, Declared>();\n declared.set(family, variants.set(key, { metricsUrl, atlasUrl, promise, settle }));\n // A layout that already missed on this family caches that miss until the\n // generation moves; this is what makes it ask again, and so start the load.\n notifyGlyphReady();\n return promise;\n}\n\n/** Start (or join) the fetch for one variant, consuming any lazy declaration. */\nfunction loadVariant(\n family: string, key: string, metricsUrl: string, atlasUrl: string,\n): Promise<void> {\n const id = `${family}|${key}`;\n const running = loads.get(id);\n if (running) return running;\n\n const load = fetchVariant(family, key, metricsUrl, atlasUrl);\n loads.set(id, load);\n const settleLoad = () => { if (loads.get(id) === load) loads.delete(id); };\n load.then(settleLoad, settleLoad);\n\n const pendingLazy = declared.get(family)?.get(key);\n if (pendingLazy) {\n const variants = declared.get(family)!;\n variants.delete(key);\n if (variants.size === 0) declared.delete(family);\n pendingLazy.settle(load);\n }\n return load;\n}\n\nasync function fetchVariant(\n family: string, key: string, metricsUrl: string, atlasUrl: string,\n): Promise<void> {\n const [weight, style] = key.split('|') as [string, FontStyle];\n const token = {};\n const tokens = inFlight.get(family) ?? new Set<object>();\n inFlight.set(family, tokens.add(token));\n try {\n const [metricsRes, atlasRes] = await Promise.all([\n fetch(metricsUrl),\n fetch(atlasUrl),\n ]);\n\n if (!metricsRes.ok) {\n throw new Error(`HTTP ${metricsRes.status} fetching metrics from ${metricsUrl}`);\n }\n if (!atlasRes.ok) {\n throw new Error(`HTTP ${atlasRes.status} fetching atlas from ${atlasUrl}`);\n }\n\n const [rawJson, blob] = await Promise.all([\n metricsRes.json(),\n atlasRes.blob(),\n ]);\n\n const font = parseBmFont(rawJson);\n const bitmap = await createImageBitmap(blob);\n\n // Copy the family as it is now, not as it was before the await: another\n // variant of it may have landed meanwhile, and a stale copy would drop it.\n registry.set(family, new Map(registry.get(family)).set(key, { font, bitmap }));\n settle(family, token);\n // Same meaning the lazy tiers give it: text that was painting from a\n // fallback face — or painting nothing — can now paint from this one.\n notifyGlyphReady();\n } catch (err) {\n settle(family, token);\n // Layout held back its no-metrics warning while this was in flight; the\n // relayout this triggers is where that warning finally gets to fire.\n notifyGlyphReady();\n throw new Error(\n `weasel registerFont(\"${family}\" ${weight}/${style}): ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n}\n\n/**\n * Start the lazy loads a request for `(family, weight, style)` needs: the\n * exact variant when it was declared, otherwise every declared variant of the\n * family, since the within-family chain may land on any of them.\n */\nfunction wakeDeclared(family: string, weight: number, style: FontStyle): void {\n const variants = declared.get(family);\n if (!variants) return;\n const exact = variantKey(weight, style);\n const keys = variants.has(exact) ? [exact] : [...variants.keys()];\n for (const key of keys) {\n const { metricsUrl, atlasUrl } = variants.get(key)!;\n // The declaration's own promise carries the failure to its caller.\n loadVariant(family, key, metricsUrl, atlasUrl).catch(() => {});\n }\n}\n\n/** One face text is set in, the way a render asks for it — what\n * {@link warmFonts} takes to load that face and nothing else. Weight\n * defaults to 400 and style to `'normal'`. */\nexport interface FontRequest {\n family: string;\n weight?: number;\n style?: FontStyle;\n}\n\n/**\n * Load registered atlases ahead of their first use, so a synchronous render —\n * `renderSceneToPixels`, an export, a print — draws text set in a lazily\n * registered face rather than nothing. With no list, loads every family\n * `registerFont` was called for.\n *\n * A family name loads every variant registered for it. A {@link FontRequest}\n * loads what resolving that one variant would draw with: the exact variant\n * when one was registered, otherwise every variant of the family, since the\n * within-family chain may land on any; the family the `'substitute'` policy\n * would draw instead when the requested one has no atlas; and the variant's\n * outline face when one is registered.\n *\n * Resolves once they have all landed; a registered variant counts as loaded.\n * Rejects when a load fails, or for a family name `registerFont` never saw —\n * a {@link FontRequest} for such a family is not an error, since the canvas\n * and outline tiers serve families no atlas was registered for.\n */\nexport function warmFonts(fonts?: readonly (string | FontRequest)[]): Promise<void> {\n const pending: Promise<unknown>[] = [];\n for (const font of fonts ?? [...registeredFamilies]) {\n if (typeof font !== 'string') {\n const { weight, style } = normalizeVariant(font);\n pending.push(...variantLoads(font.family, weight, style));\n continue;\n }\n if (!registeredFamilies.has(font)) {\n return Promise.reject(new Error(`weasel warmFonts: \"${font}\" was never registered.`));\n }\n for (const [key, { metricsUrl, atlasUrl }] of [...(declared.get(font) ?? [])]) {\n loadVariant(font, key, metricsUrl, atlasUrl);\n }\n pending.push(...familyLoads(font));\n }\n return Promise.all(pending).then(() => undefined);\n}\n\n/** Every atlas fetch running for `family`. */\nfunction familyLoads(family: string): Promise<void>[] {\n return [...loads].filter(([id]) => id.startsWith(`${family}|`)).map(([, load]) => load);\n}\n\n/** The loads `(family, weight, style)` resolves through, started — the same\n * tiers, in the same order, as `resolveFontVariantInternal`. */\nfunction variantLoads(family: string, weight: number, style: FontStyle): Promise<unknown>[] {\n const out: Promise<unknown>[] = [];\n const outlines = hasFontOutlines(family, weight, style);\n if (outlines) out.push(loadFontOutlines(family, { weight, style }));\n const key = variantKey(weight, style);\n if (registry.get(family)?.has(key)) return out;\n wakeDeclared(family, weight, style);\n const exact = loads.get(`${family}|${key}`);\n if (exact) return [...out, exact];\n if (registry.has(family) || atlasPending(family)) return [...out, ...familyLoads(family)];\n if (outlines || isExplicitCanvasFont(family) || getFontFallbackPolicy() !== 'substitute') return out;\n const fallback = getDefaultFontFamily() ?? firstRegisteredFamily();\n return fallback !== null && fallback !== family ? [...out, ...variantLoads(fallback, weight, style)] : out;\n}\n\n/** Is an atlas for this family on its way — declared lazily or fetching? */\nfunction atlasPending(family: string): boolean {\n return inFlight.has(family) || declared.has(family);\n}\n\nfunction settle(family: string, token: object): void {\n const tokens = inFlight.get(family);\n if (!tokens?.delete(token)) return;\n if (tokens.size === 0) inFlight.delete(family);\n}\n\n/**\n * Could a registration that has not landed yet still serve this request?\n * True while any `registerFont` for the family is fetching — the within-family\n * chain may resolve to whichever variant it brings — or while an outline face\n * registered for this exact variant has not finished loading. Tells a face\n * that is missing from one that is merely late.\n */\nexport function fontPending(family: string, weight = 400, style: FontStyle = 'normal'): boolean {\n if (atlasPending(family)) return true;\n const outline = outlineStatus(family, weight, style === 'italic' ? 'italic' : 'normal');\n return outline === 'idle' || outline === 'loading';\n}\n\n/**\n * Ensure the atlas for `(family, weight, style)` is uploaded to\n * `textureCache`. Cache key is `${family}|${weight}|${style}` so each\n * variant occupies its own texture slot.\n */\nexport function ensureFontTexture(\n family: string,\n weight: number,\n style: FontStyle,\n textureCache: GlyphTextureSink,\n): boolean {\n const entry = getFont(family, weight, style);\n if (!entry) return false;\n textureCache.upload(textureCacheKey(family, weight, style), entry.bitmap);\n return true;\n}\n\nexport { textureCacheKey } from './textureCacheKey';\n\n/** Kept as a no-op for context-restore call sites; per-cache dedup handles it now. */\nexport function markAllFontsNotUploaded(): void {}\n\n/** What `resolveFontVariant` found: the atlas to draw with, the face it\n * actually landed on after walking the fallback chain, and what has to be\n * synthesized to cover the difference. */\nexport interface ResolveResult {\n entry: FontEntry | null;\n /**\n * The (family, weight, style) triple that was actually matched. May differ\n * from the requested values when the resolver walked the fallback chain —\n * including `family`, when the cross-family policy substituted a default.\n *\n * This is the atlas identity: pass all three to `getFont` /\n * `textureCacheKey` and the lookup hits. Keying a draw on the *requested*\n * family resolves to no atlas at all and paints nothing.\n *\n * The synthetic flags describe the gap between requested and resolved for\n * shader-side compensation. When `entry` is null, these mirror the\n * requested values.\n */\n resolved: { family: string; weight: number; style: FontStyle };\n synthetic: { bold: boolean; italic: boolean };\n /** Which tier resolved: a baked MSDF atlas, the runtime canvas-SDF dynamic\n * atlas, or a parsed font face serving both geometry and metrics. Misses\n * report 'atlas' (the default tier). */\n source: 'atlas' | 'canvas' | 'outline';\n /** Set only when source === 'canvas': the dynamic face whose BmFont-shaped\n * `font` layoutRuns consumes in place of `entry.font`. */\n dynamicFace?: DynamicFace;\n /** Set only when source === 'outline': the parsed face supplying advances,\n * kerning and the baseline. There is no atlas behind this tier, so it is\n * the only metrics source the run has. */\n outlineFace?: OutlineFace;\n /**\n * Set when the requested family was not registered and the fallback policy\n * substituted a different one, so a UI can say \"Inter — not loaded, showing\n * Roboto\".\n */\n substituted?: { requested: string; resolved: string };\n}\n\nfunction missResolveResult(\n family: string, weight: number, style: FontStyle, suppressWarn = false,\n): ResolveResult {\n // Canvas-dynamic tier. Dynamic faces rasterize the real weight/style — no\n // synthetic flags.\n //\n // Explicit enrollment only. A family the `'canvas'` policy enrolled for\n // itself must not keep routing here after the policy changes, or `'none'`\n // could never restore the hard miss it documents.\n if (isExplicitCanvasFont(family)) {\n return {\n entry: null,\n dynamicFace: getDynamicFace(family, weight, style),\n resolved: { family, weight, style },\n synthetic: { bold: false, italic: false },\n source: 'canvas',\n };\n }\n\n // Outline-only: a family with parsed font bytes and no atlas. Ranked above\n // every fallback below because it is the *real* face, and below explicit\n // canvas enrollment, which is a consumer saying which tier it wants.\n const face = outlineMetrics(family, weight, style === 'italic' ? 'italic' : 'normal');\n if (face) {\n return {\n entry: null,\n outlineFace: face,\n resolved: { family, weight, style },\n synthetic: { bold: false, italic: false },\n source: 'outline',\n };\n }\n // Its bytes are on their way, which outranks a stand-in as a pending atlas does.\n if (fontPending(family, weight, style)) return pendingMiss(family, weight, style);\n\n const policy = getFontFallbackPolicy();\n\n if (policy === 'canvas') {\n // Auto-enroll: the browser probably has this family even though no atlas\n // was baked for it. Real typeface, canvas-SDF quality.\n autoEnrollCanvasFont(family);\n return {\n entry: null,\n dynamicFace: getDynamicFace(family, weight, style),\n resolved: { family, weight, style },\n synthetic: { bold: false, italic: false },\n source: 'canvas',\n };\n }\n\n if (policy === 'substitute') {\n const fallback = getDefaultFontFamily() ?? firstRegisteredFamily();\n // Guard against recursing when the default family is itself unknown.\n // Canvas families never enter `registry`, so membership there alone would\n // reject `setDefaultFontFamily` pointed at one. `isCanvasFont` answers\n // \"served by the dynamic tier right now\": a family the `'canvas'` policy\n // auto-enrolled is not served under this policy.\n if (fallback !== null && fallback !== family) {\n if (registry.has(fallback) || isCanvasFont(fallback) || atlasPending(fallback)) {\n // A probe, not a top-level request: suppress, so this recursion can't\n // land in the `fallback === family` branch below and double-warn.\n const result = resolveFontVariantInternal(fallback, weight, style, true, false);\n // Renderable, not baked: a fallback served by the dynamic tier reports\n // `entry: null` with a dynamicFace.\n if (result.entry !== null || result.dynamicFace !== undefined) {\n if (!suppressWarn) warnMissingFamilyOnce(family, weight, style, fallback);\n return { ...result, substituted: { requested: family, resolved: fallback } };\n }\n // Still loading: nothing to swap to yet, and nothing to warn about.\n if (atlasPending(fallback)) return pendingMiss(family, weight, style);\n }\n // Substitution was supposed to happen and produced nothing: text is\n // invisible, so say which of the two families to fix.\n if (!suppressWarn) warnUnusableDefaultOnce(family, weight, style, fallback);\n } else if (fallback === family && !suppressWarn) {\n // The family that can't serve this variant *is* the effective default.\n // Nothing renders and, without this branch, nothing is logged either.\n if (registry.has(family)) {\n warnSelfUnusableDefaultOnce(family, weight, style);\n } else {\n // Unregistered, yet still the effective default: it can only have been\n // named explicitly, because the implicit one is the first *registered*\n // family.\n warnUnregisteredDefaultOnce(family, weight, style);\n }\n }\n }\n\n return {\n entry: null,\n resolved: { family, weight, style },\n synthetic: { bold: false, italic: false },\n source: 'atlas',\n };\n}\n\n/** The first family an app registered that has, or will have, an atlas. */\nfunction firstRegisteredFamily(): string | null {\n for (const family of registeredFamilies) {\n if (registry.has(family) || atlasPending(family)) return family;\n }\n return null;\n}\n\n/** A miss that is only late: nothing substituted, nothing warned. */\nfunction pendingMiss(family: string, weight: number, style: FontStyle): ResolveResult {\n return {\n entry: null,\n resolved: { family, weight, style },\n synthetic: { bold: false, italic: false },\n source: 'atlas',\n };\n}\n\n// Resolution runs per frame, so an unguarded warn would flood the console.\n// The claimed keys live in fallback.ts so both reset seams clear them.\nfunction warnMissingFamilyOnce(\n family: string, weight: number, style: FontStyle, resolved: string,\n): void {\n if (!claimFallbackWarning(`substituted|${family}|${weight}|${style}`)) return;\n const cause = registry.has(family)\n ? `has no variant matching ${weight}/${style}, and none of its registered ` +\n `variants are close enough for the within-family chain to substitute — ` +\n `rendering with \"${resolved}\" instead. Bake that variant with ` +\n `registerFont(\"${family}\", { weight: ${weight}, style: '${style}' }, …)`\n : `is not registered — rendering with \"${resolved}\" instead. ` +\n `Call registerFont(\"${family}\", …)`;\n console.warn(\n `weasel: font family \"${family}\" (${weight}/${style}) ${cause}. ` +\n `Advance widths will differ from the requested font. Use ` +\n `setFontFallbackPolicy('none') to make this a hard miss instead.`,\n );\n}\n\n/**\n * The substitute policy engaged and still came up empty: nothing renders, and\n * the fix is almost always in the fallback family rather than the requested one.\n */\nfunction warnUnusableDefaultOnce(\n family: string, weight: number, style: FontStyle, fallback: string,\n): void {\n if (!claimFallbackWarning(`unusable-default|${family}|${weight}|${style}`)) return;\n const origin = getDefaultFontFamily() === fallback\n ? 'set via setDefaultFontFamily'\n : 'the first registered family, since setDefaultFontFamily was never called';\n // A fallback the `'canvas'` policy auto-enrolled has nothing serving it\n // under this policy, so it counts as not registered.\n const gap = registry.has(fallback) || isCanvasFont(fallback)\n ? `has no variant that can serve ${weight}/${style}`\n : 'is not registered either';\n console.warn(\n `weasel: font family \"${family}\" (${weight}/${style}) is not available, and ` +\n `the fallback family \"${fallback}\" (${origin}) ${gap} — this text will not ` +\n `render at all. Bake that variant with registerFont(\"${fallback}\", ` +\n `{ weight: ${weight}, style: '${style}' }, …), or point ` +\n `setDefaultFontFamily() at a family that covers it.`,\n );\n}\n\n/**\n * The requested family is registered and is also the effective default, so\n * there is nowhere left to fall back to.\n */\nfunction warnSelfUnusableDefaultOnce(\n family: string, weight: number, style: FontStyle,\n): void {\n if (!claimFallbackWarning(`self-unusable-default|${family}|${weight}|${style}`)) return;\n const origin = getDefaultFontFamily() === family\n ? 'set via setDefaultFontFamily'\n : 'the first registered family, since setDefaultFontFamily was never called';\n console.warn(\n `weasel: font family \"${family}\" (${weight}/${style}) has no variant that can ` +\n `serve this request, and \"${family}\" is also the fallback family (${origin}) — ` +\n `there is nothing left to fall back to, so this text will not render at all. ` +\n `Bake that variant with registerFont(\"${family}\", { weight: ${weight}, ` +\n `style: '${style}' }, …), or point setDefaultFontFamily() at a different family.`,\n );\n}\n\n/**\n * The requested family is the explicitly set default, and that default names\n * a family that was never registered at all.\n */\nfunction warnUnregisteredDefaultOnce(\n family: string, weight: number, style: FontStyle,\n): void {\n if (!claimFallbackWarning(`unregistered-default|${family}|${weight}|${style}`)) return;\n console.warn(\n `weasel: font family \"${family}\" (${weight}/${style}) was never registered, and ` +\n `it is also the fallback family — setDefaultFontFamily(\"${family}\") names a ` +\n `family with no registered variants at all, so there is nothing left to fall ` +\n `back to and this text will not render at all. Call registerFont(\"${family}\", ` +\n `{ weight: ${weight}, style: '${style}' }, …), or point setDefaultFontFamily() ` +\n `at a family you have registered.`,\n );\n}\n\nfunction weightBucket(w: number): 'regular' | 'bold' {\n return w >= 600 ? 'bold' : 'regular';\n}\n\n/**\n * Resolve a `(family, weight, style)` request to a registered font entry,\n * walking the fallback chain when an exact match isn't available. Returns\n * synthetic flags describing the gap between requested and resolved so the\n * renderer can apply SDF-thicken / vertex-skew fakes.\n */\nexport function resolveFontVariant(\n family: string,\n weight: number,\n style: FontStyle,\n): ResolveResult {\n return resolveFontVariantInternal(family, weight, style, false, false);\n}\n\n/**\n * {@link resolveFontVariant} for a caller that only reads the result: an exact\n * match is one frozen object per face rather than a new one each call, so text\n * laid out every frame resolves its faces without allocating.\n */\nexport function cachedFontVariant(family: string, weight: number, style: FontStyle): Readonly<ResolveResult> {\n return resolveFontVariantInternal(family, weight, style, false, true);\n}\n\n/**\n * Escalate a *single codepoint* to the dynamic tier when the atlas that\n * resolved for the run has no glyph for it.\n *\n * A baked MSDF atlas covers a fixed charset, so a run it serves can still\n * contain a character it never baked — an em dash, a curly quote. The dynamic\n * tier rasterizes on demand from installed fonts and can serve those.\n *\n * Returns a canvas-tier `ResolveResult` whose `dynamicFace` the caller drives\n * with `requestGlyph(cp)`, or `null` when escalation isn't available: under\n * policy `'none'`, which documents a miss as a *hard* miss, or with no canvas\n * to rasterize into (SSR, a jsdom test without one).\n */\nexport function resolveGlyphFallback(\n family: string,\n weight: number,\n style: FontStyle,\n): ResolveResult | null {\n if (getFontFallbackPolicy() === 'none') return null;\n try {\n return {\n entry: null,\n dynamicFace: getDynamicFace(family, weight, style),\n resolved: { family, weight, style },\n // The dynamic tier rasterizes the real weight and style, so there is\n // nothing for the shader to fake.\n synthetic: { bold: false, italic: false },\n source: 'canvas',\n };\n } catch {\n return null;\n }\n}\n\n/**\n * `suppressWarn` is set only by the recursive substitution probe in\n * `missResolveResult`, which resolves the fallback family purely to check\n * whether it renders. The probe must not emit — or claim the warn-once key\n * for — a message about a resolution the caller never made.\n */\nfunction resolveFontVariantInternal(\n family: string,\n weight: number,\n style: FontStyle,\n suppressWarn: boolean,\n shared: boolean,\n): ResolveResult {\n wakeDeclared(family, weight, style);\n // An atlas on its way outranks every stand-in: laying out in a fallback's\n // metrics now would reflow the text when the real face lands.\n // A landed variant is not on its way, even before its load promise settles:\n // `fetchVariant` wakes subscribers first, and they resolve synchronously.\n const exactKey = variantKey(weight, style);\n if (loads.size > 0 && loads.has(`${family}|${exactKey}`) && !registry.get(family)?.has(exactKey)) {\n return pendingMiss(family, weight, style);\n }\n const familyMap = registry.get(family);\n if (!familyMap || familyMap.size === 0) {\n if (atlasPending(family)) return pendingMiss(family, weight, style);\n return missResolveResult(family, weight, style, suppressWarn);\n }\n\n // 1. Exact match\n const exact = familyMap.get(exactKey);\n if (exact) {\n return shared\n ? sharedExactResult(exact, family, weight, style)\n : atlasResult(exact, family, weight, style, false, false);\n }\n\n // 2. Same style, nearest weight in same bucket (ties broken by higher weight)\n const requestedBucket = weightBucket(weight);\n let bestSameStyle: { entry: FontEntry; weight: number; distance: number } | null = null;\n for (const [key, entry] of familyMap) {\n const [wStr, s] = key.split('|') as [string, FontStyle];\n const w = Number(wStr);\n if (s !== style) continue;\n if (weightBucket(w) !== requestedBucket) continue;\n const distance = Math.abs(w - weight);\n if (\n bestSameStyle === null ||\n distance < bestSameStyle.distance ||\n (distance === bestSameStyle.distance && w > bestSameStyle.weight)\n ) {\n bestSameStyle = { entry, weight: w, distance };\n }\n }\n if (bestSameStyle) return atlasResult(bestSameStyle.entry, family, bestSameStyle.weight, style, false, false);\n\n // 3. (family, 400, style)\n const sameStyleRegular = familyMap.get(variantKey(400, style));\n if (sameStyleRegular) return atlasResult(sameStyleRegular, family, 400, style, weight >= 600, false);\n\n // 4. (family, weight, 'normal') — same weight, no italic\n const sameWeightNormal = familyMap.get(variantKey(weight, 'normal'));\n if (sameWeightNormal) return atlasResult(sameWeightNormal, family, weight, 'normal', false, style === 'italic');\n\n // 4b. Nearest weight, normal style, same bucket\n let bestNormal: { entry: FontEntry; weight: number; distance: number } | null = null;\n for (const [key, entry] of familyMap) {\n const [wStr, s] = key.split('|') as [string, FontStyle];\n const w = Number(wStr);\n if (s !== 'normal') continue;\n if (weightBucket(w) !== requestedBucket) continue;\n const distance = Math.abs(w - weight);\n if (\n bestNormal === null ||\n distance < bestNormal.distance ||\n (distance === bestNormal.distance && w > bestNormal.weight)\n ) {\n bestNormal = { entry, weight: w, distance };\n }\n }\n if (bestNormal) {\n return atlasResult(bestNormal.entry, family, bestNormal.weight, 'normal', false, style === 'italic');\n }\n\n // 5. (family, 400, 'normal') — last resort within family\n const regular = familyMap.get(variantKey(400, 'normal'));\n if (regular) return atlasResult(regular, family, 400, 'normal', weight >= 600, style === 'italic');\n\n return missResolveResult(family, weight, style, suppressWarn);\n}\n","/**\n * The face the canvas draws, handed to DOM text.\n *\n * A family name means one thing to the registry and another to CSS: the kit\n * may draw `sans-serif` from a baked Inter atlas while a `font-family:\n * sans-serif` in the page resolves to Helvetica. Anything the DOM sets in\n * place of canvas text — the text edit overlay above all — asks here instead\n * of writing the name through. The answer names a private `FontFace` loaded\n * from the file `registerFontOutlines` holds, with the family itself as\n * fallback while that loads. An atlas-only family has no file, so the DOM gets\n * the browser's own face for the name.\n */\n\nimport type { FontStyle } from './fontStyle';\nimport { cssFamilyName } from './cssFamily';\nimport { resolveFontVariant, type FontVariant } from './registerFont';\nimport {\n listFontOutlines, outlineCssSource, onOutlineBytes, type OutlineFaceInfo,\n} from './outline/outlineRegistry';\n\ninterface Loaded {\n /** The registration the face was built from, so a re-registration replaces it. */\n from: OutlineFaceInfo;\n face: FontFace | null;\n /** Settles once the face has loaded or failed; `settled` says it has. */\n done: Promise<void>;\n settled: boolean;\n}\n\n/** Private CSS family per registry family. */\nconst names = new Map<string, string>();\n/** Faces added to `document.fonts`, keyed `family|weight|style`. */\nconst faces = new Map<string, Loaded>();\nconst warned = new Set<string>();\n\nfunction domFonts(): boolean {\n return typeof FontFace !== 'undefined' && typeof document !== 'undefined' && !!document.fonts;\n}\n\nfunction nameFor(family: string): string {\n let name = names.get(family);\n if (!name) {\n name = `weasel-face-${names.size}`;\n names.set(family, name);\n }\n return name;\n}\n\n// Bytes already in hand make the DOM face too, so an edit opening later finds\n// it loaded instead of starting the load itself.\nonOutlineBytes((registration, bytes) => {\n if (!domFonts()) return;\n const { family, weight, style } = registration;\n ensureFace(nameFor(family), family, weight, style, bytes);\n});\n\n/**\n * The outline family and registered variants DOM text in `family` is set in,\n * or `null` when the DOM should use `family` as it stands.\n */\nfunction privateFamily(family: string, variant: FontVariant): {\n target: string; variants: readonly OutlineFaceInfo[];\n} | null {\n if (!domFonts()) return null;\n const resolved = resolveFontVariant(family, variant.weight ?? 400, variant.style ?? 'normal');\n if (resolved.source === 'canvas') return null;\n const target = resolved.resolved.family;\n const variants = listFontOutlines().filter((f) => f.family === target && f.status !== 'failed');\n if (variants.length === 0) {\n if (resolved.entry && !warned.has(target)) {\n warned.add(target);\n console.warn(\n `weasel: \"${target}\" draws from a baked atlas with no font file registered, so DOM text ` +\n `in it (the text edit overlay) uses the browser's own \"${family}\" and will not match the ` +\n `canvas. Register the file the atlas was baked from: registerFontOutlines(\"${target}\", …).`,\n );\n }\n return null;\n }\n return { target, variants };\n}\n\n/**\n * The CSS `font-family` value that sets DOM text in the face the canvas draws\n * for `family` at this variant.\n *\n * - A family the canvas draws through the browser (`registerCanvasFont`, or\n * the `'canvas'` fallback policy) comes back unchanged: the DOM already\n * resolves the name to the same face.\n * - A family drawn from a baked atlas or from outlines comes back as a private\n * face built from its `registerFontOutlines` file, in every registered\n * weight and style, followed by `family` as the fallback.\n * - Under the `'substitute'` policy, the face is the substitute's.\n *\n * Starts loading the face on first call and never waits for it; ask\n * {@link cssFontFamilyLoading} for that. Outside a browser, `family` comes\n * back unchanged.\n */\nexport function cssFontFamily(family: string, variant: FontVariant = {}): string {\n const priv = privateFamily(family, variant);\n if (!priv) return family;\n const name = nameFor(priv.target);\n for (const v of priv.variants) ensureFace(name, v.family, v.weight, v.style);\n return `${JSON.stringify(name)}, ${cssFamilyName(family)}`;\n}\n\n/**\n * The load still in flight for the face {@link cssFontFamily} names for\n * `family` at this variant, or `null` when there is nothing to wait for: it\n * has loaded or failed, or the DOM uses `family` as it stands. Waits on the\n * variant's own face when one is registered and on the whole family\n * otherwise, since the browser then picks among them. Starts the load like\n * `cssFontFamily` does, and never rejects.\n *\n * `null` rather than a settled promise, so a caller whose face is loaded goes\n * on in the same task instead of a microtask later.\n */\nexport function cssFontFamilyLoading(\n family: string, variant: FontVariant = {},\n): Promise<void> | null {\n const priv = privateFamily(family, variant);\n if (!priv) return null;\n const name = nameFor(priv.target);\n for (const v of priv.variants) ensureFace(name, v.family, v.weight, v.style);\n const weight = variant.weight ?? 400;\n const style = variant.style ?? 'normal';\n const exact = priv.variants.filter((v) => v.weight === weight && v.style === style);\n const pending = (exact.length > 0 ? exact : priv.variants)\n .map((v) => faces.get(`${v.family}|${v.weight}|${v.style}`))\n .filter((l): l is Loaded => l !== undefined && !l.settled)\n .map((l) => l.done);\n return pending.length === 0 ? null : Promise.all(pending).then(() => {});\n}\n\nfunction ensureFace(\n name: string, family: string, weight: number, style: FontStyle, bytes?: ArrayBuffer,\n): void {\n const key = `${family}|${weight}|${style}`;\n const css = outlineCssSource(family, weight, style);\n if (!css) return;\n const have = faces.get(key);\n if (have?.from === css.registration) return;\n if (have?.face) document.fonts.delete(have.face);\n\n let settle!: () => void;\n const entry: Loaded = {\n from: css.registration, face: null, settled: false,\n done: new Promise<void>((r) => { settle = r; }),\n };\n const finish = () => {\n entry.settled = true;\n settle();\n };\n faces.set(key, entry);\n // `swap`: once the overlay's hold runs out it shows the fallback, never nothing.\n const descriptors: FontFaceDescriptors = { weight: String(weight), style, display: 'swap' };\n const add = (face: FontFace) => {\n if (faces.get(key) !== entry) return finish();\n entry.face = face;\n document.fonts.add(face);\n face.load().then(finish, () => {\n finish();\n // The fallback in the stack keeps the text visible; say why it differs.\n console.warn(`weasel: could not load \"${family}\" (${weight}/${style}) for DOM text; ` +\n 'the text edit overlay falls back to the browser\\'s own face.');\n });\n };\n if ('src' in css) add(new FontFace(name, css.src, descriptors));\n // Bytes in hand spare the browser fetching the same URL a second time.\n else if (bytes !== undefined) add(new FontFace(name, bytes, descriptors));\n else if ('url' in css) add(new FontFace(name, css.url, descriptors));\n else css.bytes().then((buf) => add(new FontFace(name, buf, descriptors)), finish);\n}\n\n/** @internal Test seam — module state. */\nexport function _resetDomFacesForTests(): void {\n if (typeof document !== 'undefined' && document.fonts) {\n for (const { face } of faces.values()) if (face) document.fonts.delete(face);\n }\n names.clear();\n faces.clear();\n warned.clear();\n}\n"]}
|