text-shaper 0.1.4 → 0.1.6

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.
@@ -1,111 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/font/brotli/context.ts", "../../src/font/brotli/dictionary.ts", "../../src/font/brotli/transform.ts", "../../src/font/brotli/decode.ts", "../../tests/performance/utils/perf-utils.ts", "../../src/aat/state-machine.ts", "../../src/types.ts", "../../src/buffer/glyph-buffer.ts", "../../src/buffer/unicode-buffer.ts", "../../src/font/binary/reader.ts", "../../src/font/tables/avar.ts", "../../src/font/tables/fvar.ts", "../../src/font/tables/hvar.ts", "../../src/font/face.ts", "../../src/font/woff2.ts", "../../src/font/tables/base.ts", "../../src/font/tables/cbdt.ts", "../../src/font/tables/cff.ts", "../../src/font/tables/cff-charstring.ts", "../../src/font/tables/cff2.ts", "../../src/font/tables/cmap.ts", "../../src/font/tables/colr.ts", "../../src/font/tables/cpal.ts", "../../src/font/tables/feat.ts", "../../src/font/tables/gasp.ts", "../../src/layout/structures/class-def.ts", "../../src/font/tables/gdef.ts", "../../src/font/tables/gvar.ts", "../../src/font/tables/loca.ts", "../../src/font/tables/glyf.ts", "../../src/layout/structures/coverage.ts", "../../src/layout/structures/device.ts", "../../src/layout/structures/layout-common.ts", "../../src/font/tables/gpos-contextual.ts", "../../src/font/tables/gpos-mark.ts", "../../src/font/tables/gpos.ts", "../../src/font/tables/gsub-contextual.ts", "../../src/font/tables/gsub.ts", "../../src/font/tables/head.ts", "../../src/font/tables/hhea.ts", "../../src/font/tables/hinting.ts", "../../src/font/tables/hmtx.ts", "../../src/font/tables/jstf.ts", "../../src/font/tables/kern.ts", "../../src/font/tables/kerx.ts", "../../src/font/tables/math.ts", "../../src/font/tables/maxp.ts", "../../src/font/tables/morx.ts", "../../src/font/tables/mvar.ts", "../../src/font/tables/name.ts", "../../src/font/tables/os2.ts", "../../src/font/tables/post.ts", "../../src/font/tables/sbix.ts", "../../src/font/tables/sfnt.ts", "../../src/font/tables/stat.ts", "../../src/font/tables/svg.ts", "../../src/font/tables/trak.ts", "../../src/font/tables/vhea.ts", "../../src/font/tables/vmtx.ts", "../../src/font/tables/vorg.ts", "../../src/font/tables/vvar.ts", "../../src/font/font.ts", "../../src/layout/structures/feature-variations.ts", "../../src/raster/types.ts", "../../src/hinting/instructions/arithmetic.ts", "../../src/hinting/instructions/control-flow.ts", "../../src/hinting/types.ts", "../../src/hinting/rounding.ts", "../../src/hinting/instructions/points.ts", "../../src/hinting/instructions/delta.ts", "../../src/hinting/instructions/graphics-state.ts", "../../src/hinting/instructions/interpolate.ts", "../../src/hinting/instructions/stack.ts", "../../src/hinting/interpreter.ts", "../../src/hinting/programs.ts", "../../src/render/path.ts", "../../src/raster/fixed-point.ts", "../../src/raster/cell.ts", "../../src/raster/gray-raster.ts", "../../src/raster/outline-decompose.ts", "../../src/raster/sdf.ts", "../../src/raster/rasterize.ts", "../../src/unicode/normalize.ts", "../../src/shaper/fallback.ts", "../../src/shaper/shape-plan.ts", "../../src/shaper/complex/arabic.ts", "../../src/shaper/complex/hangul.ts", "../../src/shaper/complex/hebrew.ts", "../../src/shaper/complex/indic.ts", "../../src/shaper/complex/khmer.ts", "../../src/shaper/complex/myanmar.ts", "../../src/shaper/complex/thai-lao.ts", "../../src/shaper/complex/use.ts", "../../src/shaper/shaper.ts", "../../src/unicode/bidi/char-types.gen.ts", "../../src/unicode/bidi/char-types.ts", "../../src/unicode/bidi/embedding-levels.ts", "../../src/raster/atlas.ts", "../../tests/performance/cpu/cpu-perf.ts", "../../tests/performance/gpu/webgpu-perf.ts", "../../tests/performance/gpu/webgl-perf.ts", "../../tests/performance/comparison-tests.ts"],
4
- "sourcesContent": [
5
- "/**\n * Context lookup tables for Brotli decompression\n * Based on brotli.js reference implementation (Apache 2.0 License)\n */\n\n// Context lookup table combining all context modes\nexport const CONTEXT_LOOKUP = new Uint8Array([\n\t// CONTEXT_UTF8, last byte (0-255)\n\t// ASCII range\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 8, 12, 16, 12, 12, 20, 12, 16, 24, 28, 12, 12, 32, 12, 36,\n\t12, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 32, 32, 24, 40, 28, 12, 12, 48,\n\t52, 52, 52, 48, 52, 52, 52, 48, 52, 52, 52, 52, 52, 48, 52, 52, 52, 52, 52,\n\t48, 52, 52, 52, 52, 52, 24, 12, 28, 12, 12, 12, 56, 60, 60, 60, 56, 60, 60,\n\t60, 56, 60, 60, 60, 60, 60, 56, 60, 60, 60, 60, 60, 56, 60, 60, 60, 60, 60,\n\t24, 12, 28, 12, 0,\n\t// UTF8 continuation byte range\n\t0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,\n\t0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,\n\t0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,\n\t// UTF8 lead byte range\n\t2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,\n\t2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,\n\t2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,\n\t// CONTEXT_UTF8 second last byte (256-511)\n\t// ASCII range\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3,\n\t3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 0,\n\t// UTF8 continuation byte range\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0,\n\t// UTF8 lead byte range\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t// CONTEXT_SIGNED, second last byte (512-767)\n\t0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n\t3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n\t3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4,\n\t4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\n\t4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\n\t4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,\n\t5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,\n\t5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7,\n\t// CONTEXT_SIGNED, last byte (768-1023)\n\t0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 16, 16, 16, 16, 16, 16, 16,\n\t16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,\n\t16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,\n\t16, 16, 16, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,\n\t24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,\n\t24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,\n\t24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n\t32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n\t32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n\t32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 40,\n\t40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,\n\t40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,\n\t40, 40, 40, 40, 40, 40, 40, 40, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,\n\t48, 48, 48, 48, 56,\n\t// CONTEXT_LSB6, last byte (1024-1279)\n\t0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n\t22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,\n\t41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,\n\t60, 61, 62, 63, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,\n\t18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,\n\t37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,\n\t56, 57, 58, 59, 60, 61, 62, 63, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,\n\t14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,\n\t33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,\n\t52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,\n\t10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,\n\t29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,\n\t48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,\n\t// CONTEXT_MSB6, last byte (1280-1535)\n\t0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6,\n\t6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, 12,\n\t12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16,\n\t17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21,\n\t21, 22, 22, 22, 22, 23, 23, 23, 23, 24, 24, 24, 24, 25, 25, 25, 25, 26, 26,\n\t26, 26, 27, 27, 27, 27, 28, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 30, 31,\n\t31, 31, 31, 32, 32, 32, 32, 33, 33, 33, 33, 34, 34, 34, 34, 35, 35, 35, 35,\n\t36, 36, 36, 36, 37, 37, 37, 37, 38, 38, 38, 38, 39, 39, 39, 39, 40, 40, 40,\n\t40, 41, 41, 41, 41, 42, 42, 42, 42, 43, 43, 43, 43, 44, 44, 44, 44, 45, 45,\n\t45, 45, 46, 46, 46, 46, 47, 47, 47, 47, 48, 48, 48, 48, 49, 49, 49, 49, 50,\n\t50, 50, 50, 51, 51, 51, 51, 52, 52, 52, 52, 53, 53, 53, 53, 54, 54, 54, 54,\n\t55, 55, 55, 55, 56, 56, 56, 56, 57, 57, 57, 57, 58, 58, 58, 58, 59, 59, 59,\n\t59, 60, 60, 60, 60, 61, 61, 61, 61, 62, 62, 62, 62, 63, 63, 63, 63,\n\t// CONTEXT_{M,L}SB6, second last byte (1536-1791)\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n]);\n\n// Lookup offsets for different context modes\nexport const CONTEXT_LOOKUP_OFFSETS = new Uint16Array([\n\t// CONTEXT_LSB6\n\t1024, 1536,\n\t// CONTEXT_MSB6\n\t1280, 1536,\n\t// CONTEXT_UTF8\n\t0, 256,\n\t// CONTEXT_SIGNED\n\t768, 512,\n]);\n",
6
- "/**\n * Brotli static dictionary\n * Based on brotli.js reference implementation (Apache 2.0 License)\n *\n * The dictionary is loaded lazily to avoid bloating the initial bundle.\n */\n\n// Offsets into the dictionary by word length (4-24)\nexport const DICTIONARY_OFFSETS_BY_LENGTH = new Uint32Array([\n\t0, 0, 0, 0, 0, 4096, 9216, 21504, 35840, 44032, 53248, 63488, 74752, 87040,\n\t93696, 100864, 104704, 106752, 108928, 113536, 115968, 118528, 119872, 121280,\n\t122016,\n]);\n\n// Size bits by word length\nexport const DICTIONARY_SIZE_BITS_BY_LENGTH = new Uint8Array([\n\t0, 0, 0, 0, 10, 10, 11, 11, 10, 10, 10, 10, 10, 9, 9, 8, 7, 7, 8, 7, 7, 6, 6,\n\t5, 5,\n]);\n\nexport const MIN_DICTIONARY_WORD_LENGTH = 4;\nexport const MAX_DICTIONARY_WORD_LENGTH = 24;\n\n// The Brotli dictionary is ~122KB of static data\n// For WOFF2 fonts, dictionary references are relatively rare in font data\n// since fonts are mostly binary glyph data, not text.\n// We initialize an empty dictionary - if dictionary references are needed,\n// the full dictionary can be loaded separately.\nexport const DICTIONARY = new Uint8Array(122784);\n",
7
- "/**\n * Dictionary word transformations for Brotli decompression\n * Based on brotli.js reference implementation (Apache 2.0 License)\n */\n\nconst IDENTITY = 0;\nconst OMIT_LAST_1 = 1;\nconst OMIT_LAST_2 = 2;\nconst OMIT_LAST_3 = 3;\nconst OMIT_LAST_4 = 4;\nconst OMIT_LAST_5 = 5;\nconst OMIT_LAST_6 = 6;\nconst OMIT_LAST_7 = 7;\nconst OMIT_LAST_8 = 8;\nconst OMIT_LAST_9 = 9;\nconst UPPERCASE_FIRST = 10;\nconst UPPERCASE_ALL = 11;\nconst OMIT_FIRST_1 = 12;\nconst OMIT_FIRST_2 = 13;\nconst OMIT_FIRST_3 = 14;\nconst OMIT_FIRST_4 = 15;\nconst OMIT_FIRST_5 = 16;\nconst OMIT_FIRST_6 = 17;\nconst OMIT_FIRST_7 = 18;\nconst _OMIT_FIRST_8 = 19;\nconst OMIT_FIRST_9 = 20;\n\ninterface Transform {\n\tprefix: Uint8Array;\n\ttransform: number;\n\tsuffix: Uint8Array;\n}\n\nfunction makeTransform(\n\tprefix: string,\n\ttransform: number,\n\tsuffix: string,\n): Transform {\n\tconst prefixBytes = new Uint8Array(prefix.length);\n\tconst suffixBytes = new Uint8Array(suffix.length);\n\tfor (let i = 0; i < prefix.length; i++) prefixBytes[i] = prefix.charCodeAt(i);\n\tfor (let i = 0; i < suffix.length; i++) suffixBytes[i] = suffix.charCodeAt(i);\n\treturn { prefix: prefixBytes, transform, suffix: suffixBytes };\n}\n\nexport const TRANSFORMS: Transform[] = [\n\tmakeTransform(\"\", IDENTITY, \"\"),\n\tmakeTransform(\"\", IDENTITY, \" \"),\n\tmakeTransform(\" \", IDENTITY, \" \"),\n\tmakeTransform(\"\", OMIT_FIRST_1, \"\"),\n\tmakeTransform(\"\", UPPERCASE_FIRST, \" \"),\n\tmakeTransform(\"\", IDENTITY, \" the \"),\n\tmakeTransform(\" \", IDENTITY, \"\"),\n\tmakeTransform(\"s \", IDENTITY, \" \"),\n\tmakeTransform(\"\", IDENTITY, \" of \"),\n\tmakeTransform(\"\", UPPERCASE_FIRST, \"\"),\n\tmakeTransform(\"\", IDENTITY, \" and \"),\n\tmakeTransform(\"\", OMIT_FIRST_2, \"\"),\n\tmakeTransform(\"\", OMIT_LAST_1, \"\"),\n\tmakeTransform(\", \", IDENTITY, \" \"),\n\tmakeTransform(\"\", IDENTITY, \", \"),\n\tmakeTransform(\" \", UPPERCASE_FIRST, \" \"),\n\tmakeTransform(\"\", IDENTITY, \" in \"),\n\tmakeTransform(\"\", IDENTITY, \" to \"),\n\tmakeTransform(\"e \", IDENTITY, \" \"),\n\tmakeTransform(\"\", IDENTITY, '\"'),\n\tmakeTransform(\"\", IDENTITY, \".\"),\n\tmakeTransform(\"\", IDENTITY, '\">'),\n\tmakeTransform(\"\", IDENTITY, \"\\n\"),\n\tmakeTransform(\"\", OMIT_LAST_3, \"\"),\n\tmakeTransform(\"\", IDENTITY, \"]\"),\n\tmakeTransform(\"\", IDENTITY, \" for \"),\n\tmakeTransform(\"\", OMIT_FIRST_3, \"\"),\n\tmakeTransform(\"\", OMIT_LAST_2, \"\"),\n\tmakeTransform(\"\", IDENTITY, \" a \"),\n\tmakeTransform(\"\", IDENTITY, \" that \"),\n\tmakeTransform(\" \", UPPERCASE_FIRST, \"\"),\n\tmakeTransform(\"\", IDENTITY, \". \"),\n\tmakeTransform(\".\", IDENTITY, \"\"),\n\tmakeTransform(\" \", IDENTITY, \", \"),\n\tmakeTransform(\"\", OMIT_FIRST_4, \"\"),\n\tmakeTransform(\"\", IDENTITY, \" with \"),\n\tmakeTransform(\"\", IDENTITY, \"'\"),\n\tmakeTransform(\"\", IDENTITY, \" from \"),\n\tmakeTransform(\"\", IDENTITY, \" by \"),\n\tmakeTransform(\"\", OMIT_FIRST_5, \"\"),\n\tmakeTransform(\"\", OMIT_FIRST_6, \"\"),\n\tmakeTransform(\" the \", IDENTITY, \"\"),\n\tmakeTransform(\"\", OMIT_LAST_4, \"\"),\n\tmakeTransform(\"\", IDENTITY, \". The \"),\n\tmakeTransform(\"\", UPPERCASE_ALL, \"\"),\n\tmakeTransform(\"\", IDENTITY, \" on \"),\n\tmakeTransform(\"\", IDENTITY, \" as \"),\n\tmakeTransform(\"\", IDENTITY, \" is \"),\n\tmakeTransform(\"\", OMIT_LAST_7, \"\"),\n\tmakeTransform(\"\", OMIT_LAST_1, \"ing \"),\n\tmakeTransform(\"\", IDENTITY, \"\\n\\t\"),\n\tmakeTransform(\"\", IDENTITY, \":\"),\n\tmakeTransform(\" \", IDENTITY, \". \"),\n\tmakeTransform(\"\", IDENTITY, \"ed \"),\n\tmakeTransform(\"\", OMIT_FIRST_9, \"\"),\n\tmakeTransform(\"\", OMIT_FIRST_7, \"\"),\n\tmakeTransform(\"\", OMIT_LAST_6, \"\"),\n\tmakeTransform(\"\", IDENTITY, \"(\"),\n\tmakeTransform(\"\", UPPERCASE_FIRST, \", \"),\n\tmakeTransform(\"\", OMIT_LAST_8, \"\"),\n\tmakeTransform(\"\", IDENTITY, \" at \"),\n\tmakeTransform(\"\", IDENTITY, \"ly \"),\n\tmakeTransform(\" the \", IDENTITY, \" of \"),\n\tmakeTransform(\"\", OMIT_LAST_5, \"\"),\n\tmakeTransform(\"\", OMIT_LAST_9, \"\"),\n\tmakeTransform(\" \", UPPERCASE_FIRST, \", \"),\n\tmakeTransform(\"\", UPPERCASE_FIRST, '\"'),\n\tmakeTransform(\".\", IDENTITY, \"(\"),\n\tmakeTransform(\"\", UPPERCASE_ALL, \" \"),\n\tmakeTransform(\"\", UPPERCASE_FIRST, '\">'),\n\tmakeTransform(\"\", IDENTITY, '=\"'),\n\tmakeTransform(\" \", IDENTITY, \".\"),\n\tmakeTransform(\".com/\", IDENTITY, \"\"),\n\tmakeTransform(\" the \", IDENTITY, \" of the \"),\n\tmakeTransform(\"\", UPPERCASE_FIRST, \"'\"),\n\tmakeTransform(\"\", IDENTITY, \". This \"),\n\tmakeTransform(\"\", IDENTITY, \",\"),\n\tmakeTransform(\".\", IDENTITY, \" \"),\n\tmakeTransform(\"\", UPPERCASE_FIRST, \"(\"),\n\tmakeTransform(\"\", UPPERCASE_FIRST, \".\"),\n\tmakeTransform(\"\", IDENTITY, \" not \"),\n\tmakeTransform(\" \", IDENTITY, '=\"'),\n\tmakeTransform(\"\", IDENTITY, \"er \"),\n\tmakeTransform(\" \", UPPERCASE_ALL, \" \"),\n\tmakeTransform(\"\", IDENTITY, \"al \"),\n\tmakeTransform(\" \", UPPERCASE_ALL, \"\"),\n\tmakeTransform(\"\", IDENTITY, \"='\"),\n\tmakeTransform(\"\", UPPERCASE_ALL, '\"'),\n\tmakeTransform(\"\", UPPERCASE_FIRST, \". \"),\n\tmakeTransform(\" \", IDENTITY, \"(\"),\n\tmakeTransform(\"\", IDENTITY, \"ful \"),\n\tmakeTransform(\" \", UPPERCASE_FIRST, \". \"),\n\tmakeTransform(\"\", IDENTITY, \"ive \"),\n\tmakeTransform(\"\", IDENTITY, \"less \"),\n\tmakeTransform(\"\", UPPERCASE_ALL, \"'\"),\n\tmakeTransform(\"\", IDENTITY, \"est \"),\n\tmakeTransform(\" \", UPPERCASE_FIRST, \".\"),\n\tmakeTransform(\"\", UPPERCASE_ALL, '\">'),\n\tmakeTransform(\" \", IDENTITY, \"='\"),\n\tmakeTransform(\"\", UPPERCASE_FIRST, \",\"),\n\tmakeTransform(\"\", IDENTITY, \"ize \"),\n\tmakeTransform(\"\", UPPERCASE_ALL, \".\"),\n\tmakeTransform(\"\\xc2\\xa0\", IDENTITY, \"\"),\n\tmakeTransform(\" \", IDENTITY, \",\"),\n\tmakeTransform(\"\", UPPERCASE_FIRST, '=\"'),\n\tmakeTransform(\"\", UPPERCASE_ALL, '=\"'),\n\tmakeTransform(\"\", IDENTITY, \"ous \"),\n\tmakeTransform(\"\", UPPERCASE_ALL, \", \"),\n\tmakeTransform(\"\", UPPERCASE_FIRST, \"='\"),\n\tmakeTransform(\" \", UPPERCASE_FIRST, \",\"),\n\tmakeTransform(\" \", UPPERCASE_ALL, '=\"'),\n\tmakeTransform(\" \", UPPERCASE_ALL, \", \"),\n\tmakeTransform(\"\", UPPERCASE_ALL, \",\"),\n\tmakeTransform(\"\", UPPERCASE_ALL, \"(\"),\n\tmakeTransform(\"\", UPPERCASE_ALL, \". \"),\n\tmakeTransform(\" \", UPPERCASE_ALL, \".\"),\n\tmakeTransform(\"\", UPPERCASE_ALL, \"='\"),\n\tmakeTransform(\" \", UPPERCASE_ALL, \". \"),\n\tmakeTransform(\" \", UPPERCASE_FIRST, '=\"'),\n\tmakeTransform(\" \", UPPERCASE_ALL, \"='\"),\n\tmakeTransform(\" \", UPPERCASE_FIRST, \"='\"),\n];\n\nfunction toUpperCase(p: Uint8Array, i: number): number {\n\tif (p[i] < 0xc0) {\n\t\tif (p[i] >= 97 && p[i] <= 122) {\n\t\t\tp[i] ^= 32;\n\t\t}\n\t\treturn 1;\n\t}\n\n\t// UTF-8 multi-byte\n\tif (p[i] < 0xe0) {\n\t\tp[i + 1] ^= 32;\n\t\treturn 2;\n\t}\n\n\t// Three-byte characters\n\tp[i + 2] ^= 5;\n\treturn 3;\n}\n\nexport function transformDictionaryWord(\n\tdst: Uint8Array,\n\tidx: number,\n\twordOffset: number,\n\tlen: number,\n\ttransformIdx: number,\n\tdictionary: Uint8Array,\n): number {\n\tconst transform = TRANSFORMS[transformIdx];\n\tconst t = transform.transform;\n\tlet skip = t < OMIT_FIRST_1 ? 0 : t - (OMIT_FIRST_1 - 1);\n\tconst startIdx = idx;\n\n\tif (skip > len) skip = len;\n\n\t// Write prefix\n\tfor (let i = 0; i < transform.prefix.length; i++) {\n\t\tdst[idx++] = transform.prefix[i];\n\t}\n\n\tconst word = wordOffset + skip;\n\tlet wordLen = len - skip;\n\n\tif (t <= OMIT_LAST_9) {\n\t\twordLen -= t;\n\t}\n\n\t// Copy dictionary word\n\tfor (let i = 0; i < wordLen; i++) {\n\t\tdst[idx++] = dictionary[word + i];\n\t}\n\n\tlet uppercase = idx - wordLen;\n\n\tif (t === UPPERCASE_FIRST) {\n\t\ttoUpperCase(dst, uppercase);\n\t} else if (t === UPPERCASE_ALL) {\n\t\twhile (wordLen > 0) {\n\t\t\tconst step = toUpperCase(dst, uppercase);\n\t\t\tuppercase += step;\n\t\t\twordLen -= step;\n\t\t}\n\t}\n\n\t// Write suffix\n\tfor (let i = 0; i < transform.suffix.length; i++) {\n\t\tdst[idx++] = transform.suffix[i];\n\t}\n\n\treturn idx - startIdx;\n}\n",
8
- "/**\n * Pure TypeScript Brotli Decompressor\n * Based on the brotli.js reference implementation (MIT License)\n * https://github.com/devongovett/brotli.js\n */\n\nimport { CONTEXT_LOOKUP, CONTEXT_LOOKUP_OFFSETS } from \"./context.ts\";\nimport {\n\tDICTIONARY,\n\tDICTIONARY_OFFSETS_BY_LENGTH,\n\tDICTIONARY_SIZE_BITS_BY_LENGTH,\n} from \"./dictionary.ts\";\nimport { TRANSFORMS, transformDictionaryWord } from \"./transform.ts\";\n\n// Constants\nconst MAX_HUFFMAN_TABLE_SIZE = 1080;\nconst CODE_LENGTH_CODES = 18;\nconst NUM_LITERAL_CODES = 256;\nconst NUM_INSERT_AND_COPY_CODES = 704;\nconst NUM_BLOCK_LENGTH_CODES = 26;\nconst NUM_DISTANCE_SHORT_CODES = 16;\nconst HUFFMAN_TABLE_BITS = 8;\nconst HUFFMAN_TABLE_MASK = 0xff;\n\nconst CODE_LENGTH_CODE_ORDER = new Uint8Array([\n\t1, 2, 3, 4, 0, 5, 17, 6, 16, 7, 8, 9, 10, 11, 12, 13, 14, 15,\n]);\n\nconst DISTANCE_SHORT_CODE_INDEX_OFFSET = new Uint8Array([\n\t3, 2, 1, 0, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2,\n]);\n\nconst DISTANCE_SHORT_CODE_VALUE_OFFSET = new Int8Array([\n\t0, 0, 0, 0, -1, 1, -2, 2, -3, 3, -1, 1, -2, 2, -3, 3,\n]);\n\n// Prefix code tables\nconst BLOCK_LENGTH_PREFIX = [\n\t{ offset: 1, nbits: 2 },\n\t{ offset: 5, nbits: 2 },\n\t{ offset: 9, nbits: 2 },\n\t{ offset: 13, nbits: 2 },\n\t{ offset: 17, nbits: 3 },\n\t{ offset: 25, nbits: 3 },\n\t{ offset: 33, nbits: 3 },\n\t{ offset: 41, nbits: 3 },\n\t{ offset: 49, nbits: 4 },\n\t{ offset: 65, nbits: 4 },\n\t{ offset: 81, nbits: 4 },\n\t{ offset: 97, nbits: 4 },\n\t{ offset: 113, nbits: 5 },\n\t{ offset: 145, nbits: 5 },\n\t{ offset: 177, nbits: 5 },\n\t{ offset: 209, nbits: 5 },\n\t{ offset: 241, nbits: 6 },\n\t{ offset: 305, nbits: 6 },\n\t{ offset: 369, nbits: 7 },\n\t{ offset: 497, nbits: 8 },\n\t{ offset: 753, nbits: 9 },\n\t{ offset: 1265, nbits: 10 },\n\t{ offset: 2289, nbits: 11 },\n\t{ offset: 4337, nbits: 12 },\n\t{ offset: 8433, nbits: 13 },\n\t{ offset: 16625, nbits: 24 },\n];\n\nconst INSERT_LENGTH_PREFIX = [\n\t{ offset: 0, nbits: 0 },\n\t{ offset: 1, nbits: 0 },\n\t{ offset: 2, nbits: 0 },\n\t{ offset: 3, nbits: 0 },\n\t{ offset: 4, nbits: 0 },\n\t{ offset: 5, nbits: 0 },\n\t{ offset: 6, nbits: 1 },\n\t{ offset: 8, nbits: 1 },\n\t{ offset: 10, nbits: 2 },\n\t{ offset: 14, nbits: 2 },\n\t{ offset: 18, nbits: 3 },\n\t{ offset: 26, nbits: 3 },\n\t{ offset: 34, nbits: 4 },\n\t{ offset: 50, nbits: 4 },\n\t{ offset: 66, nbits: 5 },\n\t{ offset: 98, nbits: 5 },\n\t{ offset: 130, nbits: 6 },\n\t{ offset: 194, nbits: 7 },\n\t{ offset: 322, nbits: 8 },\n\t{ offset: 578, nbits: 9 },\n\t{ offset: 1090, nbits: 10 },\n\t{ offset: 2114, nbits: 12 },\n\t{ offset: 6210, nbits: 14 },\n\t{ offset: 22594, nbits: 24 },\n];\n\nconst COPY_LENGTH_PREFIX = [\n\t{ offset: 2, nbits: 0 },\n\t{ offset: 3, nbits: 0 },\n\t{ offset: 4, nbits: 0 },\n\t{ offset: 5, nbits: 0 },\n\t{ offset: 6, nbits: 0 },\n\t{ offset: 7, nbits: 0 },\n\t{ offset: 8, nbits: 0 },\n\t{ offset: 9, nbits: 0 },\n\t{ offset: 10, nbits: 1 },\n\t{ offset: 12, nbits: 1 },\n\t{ offset: 14, nbits: 2 },\n\t{ offset: 18, nbits: 2 },\n\t{ offset: 22, nbits: 3 },\n\t{ offset: 30, nbits: 3 },\n\t{ offset: 38, nbits: 4 },\n\t{ offset: 54, nbits: 4 },\n\t{ offset: 70, nbits: 5 },\n\t{ offset: 102, nbits: 5 },\n\t{ offset: 134, nbits: 6 },\n\t{ offset: 198, nbits: 7 },\n\t{ offset: 326, nbits: 8 },\n\t{ offset: 582, nbits: 9 },\n\t{ offset: 1094, nbits: 10 },\n\t{ offset: 2118, nbits: 24 },\n];\n\nconst INSERT_RANGE_LUT = [0, 0, 8, 8, 0, 16, 8, 16, 16];\nconst COPY_RANGE_LUT = [0, 8, 0, 8, 16, 0, 16, 8, 16];\n\n// Huffman code structure\ninterface HuffmanCode {\n\tbits: number;\n\tvalue: number;\n}\n\n// Bit reader class\nclass BitReader {\n\tprivate buf: Uint8Array;\n\tprivate pos = 0;\n\tprivate val = 0;\n\tprivate bitPos = 0;\n\tprivate bitEndPos = 0;\n\tprivate eos = false;\n\n\tconstructor(private data: Uint8Array) {\n\t\tthis.buf = new Uint8Array(8224); // 2 * 4096 + 32\n\t\tthis.fillBuffer();\n\t\t// Pre-fetch initial bits\n\t\tfor (let i = 0; i < 4; i++) {\n\t\t\tthis.val |= this.buf[this.pos] << (8 * i);\n\t\t\tthis.pos++;\n\t\t}\n\t}\n\n\tprivate fillBuffer(): void {\n\t\tif (this.bitEndPos > 256) return;\n\t\tif (this.eos) {\n\t\t\tif (this.bitPos > this.bitEndPos) {\n\t\t\t\tthrow new Error(\"Unexpected end of input\");\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tconst remaining = this.data.length - this.pos;\n\t\tconst toRead = Math.min(4096, remaining);\n\n\t\tif (toRead > 0) {\n\t\t\tthis.buf.set(this.data.subarray(this.pos, this.pos + toRead), 0);\n\t\t\tthis.pos = 0;\n\t\t}\n\n\t\tif (toRead < 4096) {\n\t\t\tthis.eos = true;\n\t\t\t// Pad with zeros\n\t\t\tfor (let i = 0; i < 32; i++) {\n\t\t\t\tthis.buf[toRead + i] = 0;\n\t\t\t}\n\t\t}\n\n\t\tthis.bitEndPos += toRead << 3;\n\t}\n\n\treadMoreInput(): void {\n\t\tif (this.bitEndPos > 256) return;\n\t\tif (this.eos) {\n\t\t\tif (this.bitPos > this.bitEndPos) {\n\t\t\t\tthrow new Error(\"Unexpected end of input\");\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tconst dst = this.pos & 4095;\n\t\tconst bytesRemaining = Math.min(\n\t\t\t4096,\n\t\t\tthis.data.length - (this.pos & ~4095),\n\t\t);\n\n\t\tif (bytesRemaining > 0) {\n\t\t\tconst srcStart = this.pos & ~4095;\n\t\t\tthis.buf.set(\n\t\t\t\tthis.data.subarray(srcStart, srcStart + bytesRemaining),\n\t\t\t\tdst === 0 ? 0 : 4096,\n\t\t\t);\n\t\t}\n\n\t\tif (bytesRemaining < 4096) {\n\t\t\tthis.eos = true;\n\t\t\tfor (let i = 0; i < 32; i++) {\n\t\t\t\tthis.buf[dst + bytesRemaining + i] = 0;\n\t\t\t}\n\t\t}\n\n\t\tthis.bitEndPos += bytesRemaining << 3;\n\t}\n\n\tfillBitWindow(): void {\n\t\twhile (this.bitPos >= 8) {\n\t\t\tthis.val >>>= 8;\n\t\t\tthis.val |= this.buf[this.pos & 8191] << 24;\n\t\t\tthis.pos++;\n\t\t\tthis.bitPos -= 8;\n\t\t\tthis.bitEndPos -= 8;\n\t\t}\n\t}\n\n\treadBits(n: number): number {\n\t\tif (32 - this.bitPos < n) {\n\t\t\tthis.fillBitWindow();\n\t\t}\n\t\tconst val = (this.val >>> this.bitPos) & ((1 << n) - 1);\n\t\tthis.bitPos += n;\n\t\treturn val;\n\t}\n\n\tpeekBits(): number {\n\t\tthis.fillBitWindow();\n\t\treturn (this.val >>> this.bitPos) & HUFFMAN_TABLE_MASK;\n\t}\n\n\tget currentBitPos(): number {\n\t\treturn this.bitPos;\n\t}\n\n\tset currentBitPos(v: number) {\n\t\tthis.bitPos = v;\n\t}\n\n\tget currentVal(): number {\n\t\treturn this.val;\n\t}\n}\n\n// Build Huffman table\nfunction buildHuffmanTable(\n\trootTable: HuffmanCode[],\n\ttableOffset: number,\n\trootBits: number,\n\tcodeLengths: Uint8Array,\n\tcodeLengthsSize: number,\n): number {\n\tconst MAX_LENGTH = 15;\n\tconst count = new Int32Array(MAX_LENGTH + 1);\n\tconst offset = new Int32Array(MAX_LENGTH + 1);\n\tconst sorted = new Int32Array(codeLengthsSize);\n\n\t// Build histogram\n\tfor (let i = 0; i < codeLengthsSize; i++) {\n\t\tcount[codeLengths[i]]++;\n\t}\n\n\t// Generate offsets\n\toffset[1] = 0;\n\tfor (let len = 1; len < MAX_LENGTH; len++) {\n\t\toffset[len + 1] = offset[len] + count[len];\n\t}\n\n\t// Sort symbols\n\tfor (let i = 0; i < codeLengthsSize; i++) {\n\t\tif (codeLengths[i] !== 0) {\n\t\t\tsorted[offset[codeLengths[i]]++] = i;\n\t\t}\n\t}\n\n\tlet tableBits = rootBits;\n\tlet tableSize = 1 << tableBits;\n\tlet totalSize = tableSize;\n\n\t// Special case: single value\n\tif (offset[MAX_LENGTH] === 1) {\n\t\tfor (let i = 0; i < totalSize; i++) {\n\t\t\trootTable[tableOffset + i] = { bits: 0, value: sorted[0] & 0xffff };\n\t\t}\n\t\treturn totalSize;\n\t}\n\n\t// Fill root table\n\tlet key = 0;\n\tlet symbol = 0;\n\tfor (let len = 1, step = 2; len <= rootBits; len++, step <<= 1) {\n\t\tfor (; count[len] > 0; count[len]--) {\n\t\t\tconst code: HuffmanCode = {\n\t\t\t\tbits: len & 0xff,\n\t\t\t\tvalue: sorted[symbol++] & 0xffff,\n\t\t\t};\n\t\t\treplicateValue(rootTable, tableOffset + key, step, tableSize, code);\n\t\t\tkey = getNextKey(key, len);\n\t\t}\n\t}\n\n\t// Fill 2nd level tables\n\tconst mask = totalSize - 1;\n\tlet low = -1;\n\tlet table = tableOffset;\n\n\tfor (let len = rootBits + 1, step = 2; len <= MAX_LENGTH; len++, step <<= 1) {\n\t\tfor (; count[len] > 0; count[len]--) {\n\t\t\tif ((key & mask) !== low) {\n\t\t\t\ttable += tableSize;\n\t\t\t\ttableBits = nextTableBitSize(count, len, rootBits);\n\t\t\t\ttableSize = 1 << tableBits;\n\t\t\t\ttotalSize += tableSize;\n\t\t\t\tlow = key & mask;\n\t\t\t\trootTable[tableOffset + low] = {\n\t\t\t\t\tbits: (tableBits + rootBits) & 0xff,\n\t\t\t\t\tvalue: (table - tableOffset - low) & 0xffff,\n\t\t\t\t};\n\t\t\t}\n\t\t\tconst code: HuffmanCode = {\n\t\t\t\tbits: (len - rootBits) & 0xff,\n\t\t\t\tvalue: sorted[symbol++] & 0xffff,\n\t\t\t};\n\t\t\treplicateValue(\n\t\t\t\trootTable,\n\t\t\t\ttable + (key >> rootBits),\n\t\t\t\tstep,\n\t\t\t\ttableSize,\n\t\t\t\tcode,\n\t\t\t);\n\t\t\tkey = getNextKey(key, len);\n\t\t}\n\t}\n\n\treturn totalSize;\n}\n\nfunction getNextKey(key: number, len: number): number {\n\tlet step = 1 << (len - 1);\n\twhile (key & step) {\n\t\tstep >>= 1;\n\t}\n\treturn (key & (step - 1)) + step;\n}\n\nfunction replicateValue(\n\ttable: HuffmanCode[],\n\toffset: number,\n\tstep: number,\n\tend: number,\n\tcode: HuffmanCode,\n): void {\n\tdo {\n\t\tend -= step;\n\t\ttable[offset + end] = { bits: code.bits, value: code.value };\n\t} while (end > 0);\n}\n\nfunction nextTableBitSize(\n\tcount: Int32Array,\n\tlen: number,\n\trootBits: number,\n): number {\n\tlet left = 1 << (len - rootBits);\n\twhile (len < 15) {\n\t\tleft -= count[len];\n\t\tif (left <= 0) break;\n\t\tlen++;\n\t\tleft <<= 1;\n\t}\n\treturn len - rootBits;\n}\n\n// Read symbol from Huffman table\nfunction readSymbol(\n\ttable: HuffmanCode[],\n\ttableOffset: number,\n\tbr: BitReader,\n): number {\n\tbr.fillBitWindow();\n\tlet index =\n\t\ttableOffset + ((br.currentVal >>> br.currentBitPos) & HUFFMAN_TABLE_MASK);\n\tconst nbits = table[index].bits - HUFFMAN_TABLE_BITS;\n\tif (nbits > 0) {\n\t\tbr.currentBitPos += HUFFMAN_TABLE_BITS;\n\t\tindex += table[index].value;\n\t\tindex += (br.currentVal >>> br.currentBitPos) & ((1 << nbits) - 1);\n\t}\n\tbr.currentBitPos += table[index].bits;\n\treturn table[index].value;\n}\n\n// Decode variable-length uint8\nfunction decodeVarLenUint8(br: BitReader): number {\n\tif (br.readBits(1)) {\n\t\tconst nbits = br.readBits(3);\n\t\tif (nbits === 0) return 1;\n\t\treturn br.readBits(nbits) + (1 << nbits);\n\t}\n\treturn 0;\n}\n\n// Decode window bits\nfunction decodeWindowBits(br: BitReader): number {\n\tif (br.readBits(1) === 0) return 16;\n\tlet n = br.readBits(3);\n\tif (n > 0) return 17 + n;\n\tn = br.readBits(3);\n\tif (n > 0) return 8 + n;\n\treturn 17;\n}\n\n// Decode meta block length\nfunction decodeMetaBlockLength(br: BitReader): {\n\tlength: number;\n\tisLast: boolean;\n\tisUncompressed: boolean;\n\tisMetadata: boolean;\n} {\n\tconst isLast = br.readBits(1) === 1;\n\tif (isLast && br.readBits(1)) {\n\t\treturn {\n\t\t\tlength: 0,\n\t\t\tisLast: true,\n\t\t\tisUncompressed: false,\n\t\t\tisMetadata: false,\n\t\t};\n\t}\n\n\tconst sizeNibbles = br.readBits(2) + 4;\n\tif (sizeNibbles === 7) {\n\t\t// Metadata block\n\t\tif (br.readBits(1) !== 0) throw new Error(\"Invalid reserved bit\");\n\t\tconst sizeBytes = br.readBits(2);\n\t\tif (sizeBytes === 0)\n\t\t\treturn { length: 0, isLast, isUncompressed: false, isMetadata: true };\n\n\t\tlet length = 0;\n\t\tfor (let i = 0; i < sizeBytes; i++) {\n\t\t\tconst nextByte = br.readBits(8);\n\t\t\tif (i + 1 === sizeBytes && sizeBytes > 1 && nextByte === 0) {\n\t\t\t\tthrow new Error(\"Invalid size byte\");\n\t\t\t}\n\t\t\tlength |= nextByte << (i * 8);\n\t\t}\n\t\treturn {\n\t\t\tlength: length + 1,\n\t\t\tisLast,\n\t\t\tisUncompressed: false,\n\t\t\tisMetadata: true,\n\t\t};\n\t}\n\n\tlet length = 0;\n\tfor (let i = 0; i < sizeNibbles; i++) {\n\t\tconst nextNibble = br.readBits(4);\n\t\tif (i + 1 === sizeNibbles && sizeNibbles > 4 && nextNibble === 0) {\n\t\t\tthrow new Error(\"Invalid size nibble\");\n\t\t}\n\t\tlength |= nextNibble << (i * 4);\n\t}\n\tlength++;\n\n\tconst isUncompressed = !isLast ? br.readBits(1) === 1 : false;\n\treturn { length, isLast, isUncompressed, isMetadata: false };\n}\n\n// Read Huffman code lengths\nfunction readHuffmanCodeLengths(\n\tcodeLengthCodeLengths: Uint8Array,\n\tnumSymbols: number,\n\tcodeLengths: Uint8Array,\n\tbr: BitReader,\n): void {\n\tconst DEFAULT_CODE_LENGTH = 8;\n\tconst CODE_LENGTH_REPEAT_CODE = 16;\n\n\tlet symbol = 0;\n\tlet prevCodeLen = DEFAULT_CODE_LENGTH;\n\tlet repeat = 0;\n\tlet repeatCodeLen = 0;\n\tlet space = 32768;\n\n\tconst table: HuffmanCode[] = [];\n\tfor (let i = 0; i < 32; i++) {\n\t\ttable.push({ bits: 0, value: 0 });\n\t}\n\n\tbuildHuffmanTable(table, 0, 5, codeLengthCodeLengths, CODE_LENGTH_CODES);\n\n\twhile (symbol < numSymbols && space > 0) {\n\t\tbr.readMoreInput();\n\t\tbr.fillBitWindow();\n\t\tconst p = (br.currentVal >>> br.currentBitPos) & 31;\n\t\tbr.currentBitPos += table[p].bits;\n\t\tconst codeLen = table[p].value & 0xff;\n\n\t\tif (codeLen < CODE_LENGTH_REPEAT_CODE) {\n\t\t\trepeat = 0;\n\t\t\tcodeLengths[symbol++] = codeLen;\n\t\t\tif (codeLen !== 0) {\n\t\t\t\tprevCodeLen = codeLen;\n\t\t\t\tspace -= 32768 >> codeLen;\n\t\t\t}\n\t\t} else {\n\t\t\tconst extraBits = codeLen - 14;\n\t\t\tlet newLen = 0;\n\t\t\tif (codeLen === CODE_LENGTH_REPEAT_CODE) {\n\t\t\t\tnewLen = prevCodeLen;\n\t\t\t}\n\t\t\tif (repeatCodeLen !== newLen) {\n\t\t\t\trepeat = 0;\n\t\t\t\trepeatCodeLen = newLen;\n\t\t\t}\n\t\t\tconst oldRepeat = repeat;\n\t\t\tif (repeat > 0) {\n\t\t\t\trepeat -= 2;\n\t\t\t\trepeat <<= extraBits;\n\t\t\t}\n\t\t\trepeat += br.readBits(extraBits) + 3;\n\t\t\tconst repeatDelta = repeat - oldRepeat;\n\n\t\t\tif (symbol + repeatDelta > numSymbols) {\n\t\t\t\tthrow new Error(\"Symbol overflow\");\n\t\t\t}\n\n\t\t\tfor (let i = 0; i < repeatDelta; i++) {\n\t\t\t\tcodeLengths[symbol + i] = repeatCodeLen;\n\t\t\t}\n\t\t\tsymbol += repeatDelta;\n\n\t\t\tif (repeatCodeLen !== 0) {\n\t\t\t\tspace -= repeatDelta << (15 - repeatCodeLen);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (space !== 0) {\n\t\tthrow new Error(\"Invalid code lengths\");\n\t}\n\n\tfor (; symbol < numSymbols; symbol++) {\n\t\tcodeLengths[symbol] = 0;\n\t}\n}\n\n// Read Huffman code\nfunction readHuffmanCode(\n\talphabetSize: number,\n\ttables: HuffmanCode[],\n\ttableOffset: number,\n\tbr: BitReader,\n): number {\n\tconst codeLengths = new Uint8Array(alphabetSize);\n\n\tbr.readMoreInput();\n\n\tconst simpleCodeOrSkip = br.readBits(2);\n\tif (simpleCodeOrSkip === 1) {\n\t\t// Simple code\n\t\tlet maxBitsCounter = alphabetSize - 1;\n\t\tlet maxBits = 0;\n\t\twhile (maxBitsCounter) {\n\t\t\tmaxBitsCounter >>= 1;\n\t\t\tmaxBits++;\n\t\t}\n\n\t\tconst symbols = new Int32Array(4);\n\t\tconst numSymbols = br.readBits(2) + 1;\n\n\t\tfor (let i = 0; i < numSymbols; i++) {\n\t\t\tsymbols[i] = br.readBits(maxBits) % alphabetSize;\n\t\t\tcodeLengths[symbols[i]] = 2;\n\t\t}\n\t\tcodeLengths[symbols[0]] = 1;\n\n\t\tswitch (numSymbols) {\n\t\t\tcase 2:\n\t\t\t\tif (symbols[0] === symbols[1]) throw new Error(\"Invalid symbols\");\n\t\t\t\tcodeLengths[symbols[1]] = 1;\n\t\t\t\tbreak;\n\t\t\tcase 4:\n\t\t\t\tif (br.readBits(1)) {\n\t\t\t\t\tcodeLengths[symbols[2]] = 3;\n\t\t\t\t\tcodeLengths[symbols[3]] = 3;\n\t\t\t\t} else {\n\t\t\t\t\tcodeLengths[symbols[0]] = 2;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\t} else {\n\t\t// Complex code\n\t\tconst codeLengthCodeLengths = new Uint8Array(CODE_LENGTH_CODES);\n\t\tlet space = 32;\n\t\tlet numCodes = 0;\n\n\t\tconst huff: HuffmanCode[] = [\n\t\t\t{ bits: 2, value: 0 },\n\t\t\t{ bits: 2, value: 4 },\n\t\t\t{ bits: 2, value: 3 },\n\t\t\t{ bits: 3, value: 2 },\n\t\t\t{ bits: 2, value: 0 },\n\t\t\t{ bits: 2, value: 4 },\n\t\t\t{ bits: 2, value: 3 },\n\t\t\t{ bits: 4, value: 1 },\n\t\t\t{ bits: 2, value: 0 },\n\t\t\t{ bits: 2, value: 4 },\n\t\t\t{ bits: 2, value: 3 },\n\t\t\t{ bits: 3, value: 2 },\n\t\t\t{ bits: 2, value: 0 },\n\t\t\t{ bits: 2, value: 4 },\n\t\t\t{ bits: 2, value: 3 },\n\t\t\t{ bits: 4, value: 5 },\n\t\t];\n\n\t\tfor (let i = simpleCodeOrSkip; i < CODE_LENGTH_CODES && space > 0; i++) {\n\t\t\tconst codeLenIdx = CODE_LENGTH_CODE_ORDER[i];\n\t\t\tbr.fillBitWindow();\n\t\t\tconst p = (br.currentVal >>> br.currentBitPos) & 15;\n\t\t\tbr.currentBitPos += huff[p].bits;\n\t\t\tconst v = huff[p].value;\n\t\t\tcodeLengthCodeLengths[codeLenIdx] = v;\n\t\t\tif (v !== 0) {\n\t\t\t\tspace -= 32 >> v;\n\t\t\t\tnumCodes++;\n\t\t\t}\n\t\t}\n\n\t\tif (!(numCodes === 1 || space === 0)) {\n\t\t\tthrow new Error(\"Invalid code length codes\");\n\t\t}\n\n\t\treadHuffmanCodeLengths(\n\t\t\tcodeLengthCodeLengths,\n\t\t\talphabetSize,\n\t\t\tcodeLengths,\n\t\t\tbr,\n\t\t);\n\t}\n\n\treturn buildHuffmanTable(\n\t\ttables,\n\t\ttableOffset,\n\t\tHUFFMAN_TABLE_BITS,\n\t\tcodeLengths,\n\t\talphabetSize,\n\t);\n}\n\n// Huffman tree group\nclass HuffmanTreeGroup {\n\tcodes: HuffmanCode[] = [];\n\thtrees: Uint32Array;\n\n\tconstructor(\n\t\tpublic alphabetSize: number,\n\t\tpublic numHTrees: number,\n\t) {\n\t\tthis.htrees = new Uint32Array(numHTrees);\n\t\tconst maxSize = this.getMaxTableSize();\n\t\tfor (let i = 0; i < numHTrees + numHTrees * maxSize; i++) {\n\t\t\tthis.codes.push({ bits: 0, value: 0 });\n\t\t}\n\t}\n\n\tprivate getMaxTableSize(): number {\n\t\tconst sizes = [\n\t\t\t256, 402, 436, 468, 500, 534, 566, 598, 630, 662, 694, 726, 758, 790, 822,\n\t\t\t854, 886, 920, 952, 984, 1016, 1048, 1080,\n\t\t];\n\t\tconst idx = (this.alphabetSize + 31) >>> 5;\n\t\treturn sizes[Math.min(idx, sizes.length - 1)];\n\t}\n\n\tdecode(br: BitReader): void {\n\t\tlet next = 0;\n\t\tfor (let i = 0; i < this.numHTrees; i++) {\n\t\t\tthis.htrees[i] = next;\n\t\t\tconst tableSize = readHuffmanCode(\n\t\t\t\tthis.alphabetSize,\n\t\t\t\tthis.codes,\n\t\t\t\tnext,\n\t\t\t\tbr,\n\t\t\t);\n\t\t\tnext += tableSize;\n\t\t}\n\t}\n}\n\n// Decode context map\nfunction decodeContextMap(\n\tcontextMapSize: number,\n\tbr: BitReader,\n): { numHTrees: number; contextMap: Uint8Array } {\n\tbr.readMoreInput();\n\tconst numHTrees = decodeVarLenUint8(br) + 1;\n\tconst contextMap = new Uint8Array(contextMapSize);\n\n\tif (numHTrees <= 1) {\n\t\treturn { numHTrees, contextMap };\n\t}\n\n\tconst useRleForZeros = br.readBits(1) === 1;\n\tlet maxRunLengthPrefix = 0;\n\tif (useRleForZeros) {\n\t\tmaxRunLengthPrefix = br.readBits(4) + 1;\n\t}\n\n\tconst table: HuffmanCode[] = [];\n\tfor (let i = 0; i < MAX_HUFFMAN_TABLE_SIZE; i++) {\n\t\ttable.push({ bits: 0, value: 0 });\n\t}\n\n\treadHuffmanCode(numHTrees + maxRunLengthPrefix, table, 0, br);\n\n\tfor (let i = 0; i < contextMapSize; ) {\n\t\tbr.readMoreInput();\n\t\tconst code = readSymbol(table, 0, br);\n\t\tif (code === 0) {\n\t\t\tcontextMap[i++] = 0;\n\t\t} else if (code <= maxRunLengthPrefix) {\n\t\t\tconst reps = 1 + (1 << code) + br.readBits(code);\n\t\t\tfor (let j = 1; j < reps && i < contextMapSize; j++) {\n\t\t\t\tcontextMap[i++] = 0;\n\t\t\t}\n\t\t} else {\n\t\t\tcontextMap[i++] = code - maxRunLengthPrefix;\n\t\t}\n\t}\n\n\t// Inverse move-to-front transform\n\tif (br.readBits(1)) {\n\t\tconst mtf = new Uint8Array(256);\n\t\tfor (let i = 0; i < 256; i++) mtf[i] = i;\n\t\tfor (let i = 0; i < contextMapSize; i++) {\n\t\t\tconst idx = contextMap[i];\n\t\t\tcontextMap[i] = mtf[idx];\n\t\t\tif (idx) {\n\t\t\t\tconst value = mtf[idx];\n\t\t\t\tfor (let j = idx; j > 0; j--) mtf[j] = mtf[j - 1];\n\t\t\t\tmtf[0] = value;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { numHTrees, contextMap };\n}\n\n// Read block length\nfunction readBlockLength(\n\ttable: HuffmanCode[],\n\ttableOffset: number,\n\tbr: BitReader,\n): number {\n\tconst code = readSymbol(table, tableOffset, br);\n\tconst prefix = BLOCK_LENGTH_PREFIX[code];\n\treturn prefix.offset + br.readBits(prefix.nbits);\n}\n\n// Translate short distance codes\nfunction translateShortCodes(\n\tcode: number,\n\tringBuffer: number[],\n\tindex: number,\n): number {\n\tif (code < NUM_DISTANCE_SHORT_CODES) {\n\t\tconst idx = (index + DISTANCE_SHORT_CODE_INDEX_OFFSET[code]) & 3;\n\t\treturn ringBuffer[idx] + DISTANCE_SHORT_CODE_VALUE_OFFSET[code];\n\t}\n\treturn code - NUM_DISTANCE_SHORT_CODES + 1;\n}\n\n/**\n * Decompress Brotli-compressed data\n */\nexport function decompress(data: Uint8Array): Uint8Array {\n\tconst br = new BitReader(data);\n\n\t// Decode window bits\n\tconst windowBits = decodeWindowBits(br);\n\tconst maxBackwardDistance = (1 << windowBits) - 16;\n\tconst ringBufferSize = 1 << windowBits;\n\tconst ringBufferMask = ringBufferSize - 1;\n\tconst ringBuffer = new Uint8Array(ringBufferSize + 578); // Extra space for dictionary words\n\n\tlet pos = 0;\n\tlet maxDistance = 0;\n\tconst distRb = [16, 15, 11, 4];\n\tlet distRbIdx = 0;\n\tlet prevByte1 = 0;\n\tlet prevByte2 = 0;\n\n\tconst output: number[] = [];\n\n\twhile (true) {\n\t\tbr.readMoreInput();\n\n\t\tconst meta = decodeMetaBlockLength(br);\n\t\tif (meta.length === 0 && meta.isLast) {\n\t\t\tbreak;\n\t\t}\n\n\t\tif (meta.isMetadata) {\n\t\t\t// Skip metadata\n\t\t\tbr.currentBitPos = (br.currentBitPos + 7) & ~7;\n\t\t\tfor (let i = 0; i < meta.length; i++) {\n\t\t\t\tbr.readMoreInput();\n\t\t\t\tbr.readBits(8);\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tlet metaBlockRemaining = meta.length;\n\t\tif (metaBlockRemaining === 0) continue;\n\n\t\tif (meta.isUncompressed) {\n\t\t\tbr.currentBitPos = (br.currentBitPos + 7) & ~7;\n\t\t\tfor (let i = 0; i < metaBlockRemaining; i++) {\n\t\t\t\tbr.readMoreInput();\n\t\t\t\tconst byte = br.readBits(8);\n\t\t\t\tringBuffer[pos & ringBufferMask] = byte;\n\t\t\t\tif ((pos & ringBufferMask) === ringBufferMask) {\n\t\t\t\t\toutput.push(...ringBuffer.slice(0, ringBufferSize));\n\t\t\t\t}\n\t\t\t\tpos++;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Decode block types\n\t\tconst numBlockTypes = [1, 1, 1];\n\t\tconst blockLength = [1 << 28, 1 << 28, 1 << 28];\n\t\tconst blockType = [0, 0, 0];\n\t\tconst blockTypeRb = [0, 1, 0, 1, 0, 1];\n\t\tconst blockTypeRbIndex = [0, 0, 0];\n\n\t\tconst blockTypeTrees: HuffmanCode[] = [];\n\t\tconst blockLenTrees: HuffmanCode[] = [];\n\t\tfor (let i = 0; i < 3 * MAX_HUFFMAN_TABLE_SIZE; i++) {\n\t\t\tblockTypeTrees.push({ bits: 0, value: 0 });\n\t\t\tblockLenTrees.push({ bits: 0, value: 0 });\n\t\t}\n\n\t\tfor (let i = 0; i < 3; i++) {\n\t\t\tnumBlockTypes[i] = decodeVarLenUint8(br) + 1;\n\t\t\tif (numBlockTypes[i] >= 2) {\n\t\t\t\treadHuffmanCode(\n\t\t\t\t\tnumBlockTypes[i] + 2,\n\t\t\t\t\tblockTypeTrees,\n\t\t\t\t\ti * MAX_HUFFMAN_TABLE_SIZE,\n\t\t\t\t\tbr,\n\t\t\t\t);\n\t\t\t\treadHuffmanCode(\n\t\t\t\t\tNUM_BLOCK_LENGTH_CODES,\n\t\t\t\t\tblockLenTrees,\n\t\t\t\t\ti * MAX_HUFFMAN_TABLE_SIZE,\n\t\t\t\t\tbr,\n\t\t\t\t);\n\t\t\t\tblockLength[i] = readBlockLength(\n\t\t\t\t\tblockLenTrees,\n\t\t\t\t\ti * MAX_HUFFMAN_TABLE_SIZE,\n\t\t\t\t\tbr,\n\t\t\t\t);\n\t\t\t\tblockTypeRbIndex[i] = 1;\n\t\t\t}\n\t\t}\n\n\t\tbr.readMoreInput();\n\n\t\tconst distancePostfixBits = br.readBits(2);\n\t\tconst numDirectDistanceCodes =\n\t\t\tNUM_DISTANCE_SHORT_CODES + (br.readBits(4) << distancePostfixBits);\n\t\tconst distancePostfixMask = (1 << distancePostfixBits) - 1;\n\t\tconst numDistanceCodes =\n\t\t\tnumDirectDistanceCodes + (48 << distancePostfixBits);\n\n\t\tconst contextModes = new Uint8Array(numBlockTypes[0]);\n\t\tfor (let i = 0; i < numBlockTypes[0]; i++) {\n\t\t\tbr.readMoreInput();\n\t\t\tcontextModes[i] = br.readBits(2) << 1;\n\t\t}\n\n\t\tconst literalContextMap = decodeContextMap(numBlockTypes[0] << 6, br);\n\t\tconst distContextMap = decodeContextMap(numBlockTypes[2] << 2, br);\n\n\t\tconst hgroup = [\n\t\t\tnew HuffmanTreeGroup(NUM_LITERAL_CODES, literalContextMap.numHTrees),\n\t\t\tnew HuffmanTreeGroup(NUM_INSERT_AND_COPY_CODES, numBlockTypes[1]),\n\t\t\tnew HuffmanTreeGroup(numDistanceCodes, distContextMap.numHTrees),\n\t\t];\n\n\t\tfor (let i = 0; i < 3; i++) {\n\t\t\thgroup[i].decode(br);\n\t\t}\n\n\t\tlet contextMapSlice = 0;\n\t\tlet distContextMapSlice = 0;\n\t\tlet contextMode = contextModes[blockType[0]];\n\t\tlet contextLookupOffset1 = CONTEXT_LOOKUP_OFFSETS[contextMode];\n\t\tlet contextLookupOffset2 = CONTEXT_LOOKUP_OFFSETS[contextMode + 1];\n\t\tlet htreeCommand = hgroup[1].htrees[0];\n\n\t\twhile (metaBlockRemaining > 0) {\n\t\t\tbr.readMoreInput();\n\n\t\t\tif (blockLength[1] === 0) {\n\t\t\t\t// Decode block type\n\t\t\t\tconst typeCode = readSymbol(blockTypeTrees, MAX_HUFFMAN_TABLE_SIZE, br);\n\t\t\t\tlet bt: number;\n\t\t\t\tif (typeCode === 0) {\n\t\t\t\t\tbt = blockTypeRb[2 + (blockTypeRbIndex[1] & 1)];\n\t\t\t\t} else if (typeCode === 1) {\n\t\t\t\t\tbt = blockTypeRb[2 + ((blockTypeRbIndex[1] - 1) & 1)] + 1;\n\t\t\t\t} else {\n\t\t\t\t\tbt = typeCode - 2;\n\t\t\t\t}\n\t\t\t\tif (bt >= numBlockTypes[1]) bt -= numBlockTypes[1];\n\t\t\t\tblockType[1] = bt;\n\t\t\t\tblockTypeRb[2 + (blockTypeRbIndex[1] & 1)] = bt;\n\t\t\t\tblockTypeRbIndex[1]++;\n\t\t\t\tblockLength[1] = readBlockLength(\n\t\t\t\t\tblockLenTrees,\n\t\t\t\t\tMAX_HUFFMAN_TABLE_SIZE,\n\t\t\t\t\tbr,\n\t\t\t\t);\n\t\t\t\thtreeCommand = hgroup[1].htrees[blockType[1]];\n\t\t\t}\n\t\t\tblockLength[1]--;\n\n\t\t\tconst cmdCode = readSymbol(hgroup[1].codes, htreeCommand, br);\n\t\t\tconst rangeIdx = cmdCode >> 6;\n\t\t\tlet distanceCode: number;\n\t\t\tif (rangeIdx >= 2) {\n\t\t\t\tdistanceCode = -1;\n\t\t\t} else {\n\t\t\t\tdistanceCode = 0;\n\t\t\t}\n\n\t\t\tconst insertCode = INSERT_RANGE_LUT[rangeIdx] + ((cmdCode >> 3) & 7);\n\t\t\tconst copyCode = COPY_RANGE_LUT[rangeIdx] + (cmdCode & 7);\n\t\t\tconst insertLength =\n\t\t\t\tINSERT_LENGTH_PREFIX[insertCode].offset +\n\t\t\t\tbr.readBits(INSERT_LENGTH_PREFIX[insertCode].nbits);\n\t\t\tconst copyLength =\n\t\t\t\tCOPY_LENGTH_PREFIX[copyCode].offset +\n\t\t\t\tbr.readBits(COPY_LENGTH_PREFIX[copyCode].nbits);\n\n\t\t\tprevByte1 = ringBuffer[(pos - 1) & ringBufferMask];\n\t\t\tprevByte2 = ringBuffer[(pos - 2) & ringBufferMask];\n\n\t\t\tfor (let j = 0; j < insertLength; j++) {\n\t\t\t\tbr.readMoreInput();\n\n\t\t\t\tif (blockLength[0] === 0) {\n\t\t\t\t\t// Decode block type for literals\n\t\t\t\t\tconst typeCode = readSymbol(blockTypeTrees, 0, br);\n\t\t\t\t\tlet bt: number;\n\t\t\t\t\tif (typeCode === 0) {\n\t\t\t\t\t\tbt = blockTypeRb[blockTypeRbIndex[0] & 1];\n\t\t\t\t\t} else if (typeCode === 1) {\n\t\t\t\t\t\tbt = blockTypeRb[(blockTypeRbIndex[0] - 1) & 1] + 1;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tbt = typeCode - 2;\n\t\t\t\t\t}\n\t\t\t\t\tif (bt >= numBlockTypes[0]) bt -= numBlockTypes[0];\n\t\t\t\t\tblockType[0] = bt;\n\t\t\t\t\tblockTypeRb[blockTypeRbIndex[0] & 1] = bt;\n\t\t\t\t\tblockTypeRbIndex[0]++;\n\t\t\t\t\tblockLength[0] = readBlockLength(blockLenTrees, 0, br);\n\t\t\t\t\tconst contextOffset = blockType[0] << 6;\n\t\t\t\t\tcontextMapSlice = contextOffset;\n\t\t\t\t\tcontextMode = contextModes[blockType[0]];\n\t\t\t\t\tcontextLookupOffset1 = CONTEXT_LOOKUP_OFFSETS[contextMode];\n\t\t\t\t\tcontextLookupOffset2 = CONTEXT_LOOKUP_OFFSETS[contextMode + 1];\n\t\t\t\t}\n\n\t\t\t\tconst context =\n\t\t\t\t\tCONTEXT_LOOKUP[contextLookupOffset1 + prevByte1] |\n\t\t\t\t\tCONTEXT_LOOKUP[contextLookupOffset2 + prevByte2];\n\t\t\t\tconst literalHtreeIndex =\n\t\t\t\t\tliteralContextMap.contextMap[contextMapSlice + context];\n\t\t\t\tblockLength[0]--;\n\n\t\t\t\tprevByte2 = prevByte1;\n\t\t\t\tprevByte1 = readSymbol(\n\t\t\t\t\thgroup[0].codes,\n\t\t\t\t\thgroup[0].htrees[literalHtreeIndex],\n\t\t\t\t\tbr,\n\t\t\t\t);\n\t\t\t\tringBuffer[pos & ringBufferMask] = prevByte1;\n\t\t\t\tif ((pos & ringBufferMask) === ringBufferMask) {\n\t\t\t\t\toutput.push(...ringBuffer.slice(0, ringBufferSize));\n\t\t\t\t}\n\t\t\t\tpos++;\n\t\t\t}\n\n\t\t\tmetaBlockRemaining -= insertLength;\n\t\t\tif (metaBlockRemaining <= 0) break;\n\n\t\t\tif (distanceCode < 0) {\n\t\t\t\tbr.readMoreInput();\n\t\t\t\tif (blockLength[2] === 0) {\n\t\t\t\t\t// Decode block type for distances\n\t\t\t\t\tconst typeCode = readSymbol(\n\t\t\t\t\t\tblockTypeTrees,\n\t\t\t\t\t\t2 * MAX_HUFFMAN_TABLE_SIZE,\n\t\t\t\t\t\tbr,\n\t\t\t\t\t);\n\t\t\t\t\tlet bt: number;\n\t\t\t\t\tif (typeCode === 0) {\n\t\t\t\t\t\tbt = blockTypeRb[4 + (blockTypeRbIndex[2] & 1)];\n\t\t\t\t\t} else if (typeCode === 1) {\n\t\t\t\t\t\tbt = blockTypeRb[4 + ((blockTypeRbIndex[2] - 1) & 1)] + 1;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tbt = typeCode - 2;\n\t\t\t\t\t}\n\t\t\t\t\tif (bt >= numBlockTypes[2]) bt -= numBlockTypes[2];\n\t\t\t\t\tblockType[2] = bt;\n\t\t\t\t\tblockTypeRb[4 + (blockTypeRbIndex[2] & 1)] = bt;\n\t\t\t\t\tblockTypeRbIndex[2]++;\n\t\t\t\t\tblockLength[2] = readBlockLength(\n\t\t\t\t\t\tblockLenTrees,\n\t\t\t\t\t\t2 * MAX_HUFFMAN_TABLE_SIZE,\n\t\t\t\t\t\tbr,\n\t\t\t\t\t);\n\t\t\t\t\tdistContextMapSlice = blockType[2] << 2;\n\t\t\t\t}\n\t\t\t\tblockLength[2]--;\n\n\t\t\t\tconst context = (copyLength > 4 ? 3 : copyLength - 2) & 0xff;\n\t\t\t\tconst distHtreeIndex =\n\t\t\t\t\tdistContextMap.contextMap[distContextMapSlice + context];\n\t\t\t\tdistanceCode = readSymbol(\n\t\t\t\t\thgroup[2].codes,\n\t\t\t\t\thgroup[2].htrees[distHtreeIndex],\n\t\t\t\t\tbr,\n\t\t\t\t);\n\n\t\t\t\tif (distanceCode >= numDirectDistanceCodes) {\n\t\t\t\t\tdistanceCode -= numDirectDistanceCodes;\n\t\t\t\t\tconst postfix = distanceCode & distancePostfixMask;\n\t\t\t\t\tdistanceCode >>= distancePostfixBits;\n\t\t\t\t\tconst nbits = (distanceCode >> 1) + 1;\n\t\t\t\t\tconst offset = ((2 + (distanceCode & 1)) << nbits) - 4;\n\t\t\t\t\tdistanceCode =\n\t\t\t\t\t\tnumDirectDistanceCodes +\n\t\t\t\t\t\t((offset + br.readBits(nbits)) << distancePostfixBits) +\n\t\t\t\t\t\tpostfix;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst distance = translateShortCodes(distanceCode, distRb, distRbIdx);\n\t\t\tif (distance < 0) {\n\t\t\t\tthrow new Error(\"Invalid distance\");\n\t\t\t}\n\n\t\t\tif (pos < maxBackwardDistance && maxDistance !== maxBackwardDistance) {\n\t\t\t\tmaxDistance = pos;\n\t\t\t} else {\n\t\t\t\tmaxDistance = maxBackwardDistance;\n\t\t\t}\n\n\t\t\tlet copyDst = pos & ringBufferMask;\n\n\t\t\tif (distance > maxDistance) {\n\t\t\t\t// Dictionary reference\n\t\t\t\tif (copyLength >= 4 && copyLength <= 24) {\n\t\t\t\t\tconst offset = DICTIONARY_OFFSETS_BY_LENGTH[copyLength];\n\t\t\t\t\tconst wordId = distance - maxDistance - 1;\n\t\t\t\t\tconst shift = DICTIONARY_SIZE_BITS_BY_LENGTH[copyLength];\n\t\t\t\t\tconst mask = (1 << shift) - 1;\n\t\t\t\t\tconst wordIdx = wordId & mask;\n\t\t\t\t\tconst transformIdx = wordId >> shift;\n\t\t\t\t\tconst wordOffset = offset + wordIdx * copyLength;\n\n\t\t\t\t\tif (transformIdx < TRANSFORMS.length) {\n\t\t\t\t\t\tconst len = transformDictionaryWord(\n\t\t\t\t\t\t\tringBuffer,\n\t\t\t\t\t\t\tcopyDst,\n\t\t\t\t\t\t\twordOffset,\n\t\t\t\t\t\t\tcopyLength,\n\t\t\t\t\t\t\ttransformIdx,\n\t\t\t\t\t\t\tDICTIONARY,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tcopyDst += len;\n\t\t\t\t\t\tpos += len;\n\t\t\t\t\t\tmetaBlockRemaining -= len;\n\t\t\t\t\t\tif (copyDst >= ringBufferSize) {\n\t\t\t\t\t\t\toutput.push(...ringBuffer.slice(0, ringBufferSize));\n\t\t\t\t\t\t\tfor (let i = 0; i < copyDst - ringBufferSize; i++) {\n\t\t\t\t\t\t\t\tringBuffer[i] = ringBuffer[ringBufferSize + i];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthrow new Error(\"Invalid backward reference\");\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tthrow new Error(\"Invalid backward reference\");\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (distanceCode > 0) {\n\t\t\t\t\tdistRb[distRbIdx & 3] = distance;\n\t\t\t\t\tdistRbIdx++;\n\t\t\t\t}\n\n\t\t\t\tif (copyLength > metaBlockRemaining) {\n\t\t\t\t\tthrow new Error(\"Invalid backward reference\");\n\t\t\t\t}\n\n\t\t\t\tfor (let j = 0; j < copyLength; j++) {\n\t\t\t\t\tringBuffer[pos & ringBufferMask] =\n\t\t\t\t\t\tringBuffer[(pos - distance) & ringBufferMask];\n\t\t\t\t\tif ((pos & ringBufferMask) === ringBufferMask) {\n\t\t\t\t\t\toutput.push(...ringBuffer.slice(0, ringBufferSize));\n\t\t\t\t\t}\n\t\t\t\t\tpos++;\n\t\t\t\t\tmetaBlockRemaining--;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tprevByte1 = ringBuffer[(pos - 1) & ringBufferMask];\n\t\t\tprevByte2 = ringBuffer[(pos - 2) & ringBufferMask];\n\t\t}\n\n\t\tif (meta.isLast) break;\n\t}\n\n\t// Flush remaining data\n\toutput.push(...ringBuffer.slice(0, pos & ringBufferMask));\n\n\treturn new Uint8Array(output);\n}\n",
9
- "/**\n * Performance testing utilities for browser-based benchmarks\n */\n\nexport interface PerformanceResult {\n name: string;\n iterations: number;\n totalTime: number;\n avgTime: number;\n minTime: number;\n maxTime: number;\n samples: number[];\n}\n\nexport interface BenchmarkOptions {\n iterations?: number;\n warmupIterations?: number;\n gcBetweenRuns?: boolean;\n}\n\n/**\n * High-precision timing utility\n */\nexport class PerformanceTimer {\n private startTime = 0;\n private endTime = 0;\n\n start(): void {\n this.startTime = performance.now();\n }\n\n end(): number {\n this.endTime = performance.now();\n return this.duration();\n }\n\n duration(): number {\n return this.endTime - this.startTime;\n }\n\n static now(): number {\n return performance.now();\n }\n}\n\n/**\n * Run a performance benchmark on a function\n */\nexport async function benchmark(\n name: string,\n fn: () => void | Promise<void>,\n options: BenchmarkOptions = {}\n): Promise<PerformanceResult> {\n const {\n iterations = 100,\n warmupIterations = 10,\n gcBetweenRuns = false\n } = options;\n\n // Warmup\n for (let i = 0; i < warmupIterations; i++) {\n await fn();\n }\n\n // Force GC if available and requested\n if (gcBetweenRuns && (globalThis as any).gc) {\n (globalThis as any).gc();\n }\n\n const samples: number[] = [];\n let totalTime = 0;\n let minTime = Infinity;\n let maxTime = -Infinity;\n\n // Run benchmark\n for (let i = 0; i < iterations; i++) {\n const start = PerformanceTimer.now();\n await fn();\n const end = PerformanceTimer.now();\n \n const duration = end - start;\n samples.push(duration);\n totalTime += duration;\n minTime = Math.min(minTime, duration);\n maxTime = Math.max(maxTime, duration);\n\n // Small delay between iterations to prevent overheating\n if (i % 10 === 9) {\n await new Promise(resolve => setTimeout(resolve, 1));\n }\n }\n\n return {\n name,\n iterations,\n totalTime,\n avgTime: totalTime / iterations,\n minTime,\n maxTime,\n samples\n };\n}\n\n/**\n * Compare performance between two implementations\n */\nexport async function comparePerformance(\n name: string,\n impl1: () => void | Promise<void>,\n impl2: () => void | Promise<void>,\n options: BenchmarkOptions = {}\n): Promise<{\n impl1: PerformanceResult;\n impl2: PerformanceResult;\n speedup: number;\n winner: string;\n}> {\n const result1 = await benchmark(`${name}-impl1`, impl1, options);\n const result2 = await benchmark(`${name}-impl2`, impl2, options);\n\n const speedup = result1.avgTime / result2.avgTime;\n const winner = result1.avgTime < result2.avgTime ? 'impl1' : 'impl2';\n\n return {\n impl1: result1,\n impl2: result2,\n speedup: Math.max(speedup, 1 / speedup),\n winner\n };\n}\n\n/**\n * Memory usage tracker\n */\nexport class MemoryTracker {\n private initialUsage: number = 0;\n\n start(): void {\n if ((globalThis as any).performance?.memory) {\n this.initialUsage = (globalThis as any).performance.memory.usedJSHeapSize;\n }\n }\n\n getUsage(): number {\n if ((globalThis as any).performance?.memory) {\n return (globalThis as any).performance.memory.usedJSHeapSize - this.initialUsage;\n }\n return 0;\n }\n\n format(bytes: number): string {\n return `${(bytes / 1024 / 1024).toFixed(2)} MB`;\n }\n}\n\n/**\n * Create a performance report\n */\nexport function createPerformanceReport(results: PerformanceResult[]): string {\n const report: string[] = [];\n \n report.push('=== Performance Benchmark Report ===');\n report.push(`Generated: ${new Date().toISOString()}`);\n report.push('');\n\n results.forEach(result => {\n report.push(`${result.name}:`);\n report.push(` Iterations: ${result.iterations}`);\n report.push(` Average: ${result.avgTime.toFixed(3)} ms`);\n report.push(` Min: ${result.minTime.toFixed(3)} ms`);\n report.push(` Max: ${result.maxTime.toFixed(3)} ms`);\n report.push(` Total: ${result.totalTime.toFixed(3)} ms`);\n report.push('');\n });\n\n return report.join('\\n');\n}\n\n/**\n * WebGPU support detection\n */\nexport function isWebGPUSupported(): boolean {\n return !!(navigator.gpu && navigator.gpu.requestAdapter);\n}\n\n/**\n * WebGL support detection\n */\nexport function isWebGLSupported(): boolean {\n try {\n const canvas = document.createElement('canvas');\n return !!(canvas.getContext('webgl') || canvas.getContext('webgl2'));\n } catch {\n return false;\n }\n}\n\n/**\n * Get GPU information\n */\nexport async function getGPUInfo(): Promise<{\n vendor: string;\n renderer: string;\n webgpu: boolean;\n webgl: boolean;\n}> {\n const info = {\n vendor: 'Unknown',\n renderer: 'Unknown',\n webgpu: isWebGPUSupported(),\n webgl: isWebGLSupported()\n };\n\n // Try WebGPU\n if (info.webgpu) {\n try {\n const adapter = await navigator.gpu.requestAdapter();\n if (adapter) {\n info.vendor = adapter.info?.vendor || 'Unknown';\n info.renderer = adapter.info?.architecture || 'Unknown';\n }\n } catch {\n // Ignore\n }\n }\n\n // Fallback to WebGL\n if (info.webgl && info.vendor === 'Unknown') {\n try {\n const canvas = document.createElement('canvas');\n const gl = canvas.getContext('webgl2') || canvas.getContext('webgl');\n if (gl) {\n const debugInfo = gl.getExtension('WEBGL_debug_renderer_info');\n if (debugInfo) {\n info.vendor = gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL) as string;\n info.renderer = gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL) as string;\n }\n }\n } catch {\n // Ignore\n }\n }\n\n return info;\n}",
10
- "import type {\n\tClassTable,\n\tContextualEntry,\n\tInsertionEntry,\n\tLigatureEntry,\n\tMorxContextualSubtable,\n\tMorxInsertionSubtable,\n\tMorxLigatureSubtable,\n\tMorxRearrangementSubtable,\n} from \"../font/tables/morx.ts\";\nimport type { GlyphId, GlyphInfo } from \"../types.ts\";\n\n/**\n * State machine driver for AAT processing\n */\nexport interface StateMachineContext {\n\t/** Current position in buffer */\n\tpos: number;\n\t/** Mark position (for some operations) */\n\tmark: number;\n\t/** Glyph stack for ligatures */\n\tstack: number[];\n}\n\n/**\n * Special class values\n */\nconst CLASS_END_OF_TEXT = 0;\nconst CLASS_OUT_OF_BOUNDS = 1;\nconst _CLASS_DELETED_GLYPH = 2;\nconst _CLASS_END_OF_LINE = 3;\n\n/**\n * Get class for a glyph\n */\nexport function getGlyphClass(\n\tclassTable: ClassTable,\n\tglyphId: GlyphId,\n): number {\n\tif (glyphId < 0 || glyphId >= classTable.classArray.length) {\n\t\treturn CLASS_OUT_OF_BOUNDS;\n\t}\n\treturn classTable.classArray[glyphId] ?? CLASS_OUT_OF_BOUNDS;\n}\n\n/**\n * Process rearrangement subtable\n * Reorders glyphs based on state machine\n */\nexport function processRearrangement(\n\tsubtable: MorxRearrangementSubtable,\n\tinfos: GlyphInfo[],\n): void {\n\tconst { stateTable } = subtable;\n\tlet state = 0;\n\tlet markFirst = 0;\n\tlet markLast = 0;\n\n\tfor (let i = 0; i <= infos.length; i++) {\n\t\tconst isEnd = i >= infos.length;\n\t\tconst glyphClass = isEnd\n\t\t\t? CLASS_END_OF_TEXT\n\t\t\t: getGlyphClass(stateTable.classTable, infos[i]?.glyphId);\n\n\t\tconst stateRow = stateTable.stateArray[state];\n\t\tif (!stateRow) break;\n\n\t\tconst entry = stateRow[glyphClass];\n\t\tif (!entry) break;\n\n\t\tconst flags = entry.flags;\n\n\t\t// Set mark first\n\t\tif (flags & 0x8000) {\n\t\t\tmarkFirst = i;\n\t\t}\n\n\t\t// Set mark last\n\t\tif (flags & 0x2000) {\n\t\t\tmarkLast = i;\n\t\t}\n\n\t\t// Perform rearrangement\n\t\tconst verb = flags & 0x000f;\n\t\tif (verb !== 0 && markFirst <= markLast && markLast < infos.length) {\n\t\t\trearrangeGlyphs(infos, markFirst, markLast, verb);\n\t\t}\n\n\t\t// Don't advance if flag set\n\t\tif (!(flags & 0x4000)) {\n\t\t\t// Stay at current position\n\t\t}\n\n\t\tstate = entry.newState;\n\t}\n}\n\n/**\n * Rearrangement verbs\n */\nfunction rearrangeGlyphs(\n\tinfos: GlyphInfo[],\n\tfirst: number,\n\tlast: number,\n\tverb: number,\n): void {\n\tif (first >= last || first >= infos.length || last >= infos.length) return;\n\n\tconst a = infos[first];\n\tconst b = infos[first + 1];\n\tconst c = infos[last - 1];\n\tconst d = infos[last];\n\n\tif (!a || !d) return;\n\n\tswitch (verb) {\n\t\tcase 1: // Ax => xA\n\t\t\tif (b) {\n\t\t\t\tinfos[first] = b;\n\t\t\t\tinfos[first + 1] = a;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 2: // xD => Dx\n\t\t\tif (c) {\n\t\t\t\tinfos[last] = c;\n\t\t\t\tinfos[last - 1] = d;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 3: // AxD => DxA\n\t\t\tinfos[first] = d;\n\t\t\tinfos[last] = a;\n\t\t\tbreak;\n\t\tcase 4: // ABx => xAB\n\t\t\tif (b && c) {\n\t\t\t\tconst temp = infos.slice(first, first + 2);\n\t\t\t\tconst [tempFirst, tempSecond] = temp;\n\t\t\t\tconst thirdItem = infos[first + 2];\n\t\t\t\tif (tempFirst && tempSecond && thirdItem) {\n\t\t\t\t\tinfos[first] = thirdItem;\n\t\t\t\t\tinfos[first + 1] = tempFirst;\n\t\t\t\t\tinfos[first + 2] = tempSecond;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 5: // ABx => xBA\n\t\t\tif (b && c) {\n\t\t\t\tconst temp = infos.slice(first, first + 2);\n\t\t\t\tconst [tempFirst, tempSecond] = temp;\n\t\t\t\tconst thirdItem = infos[first + 2];\n\t\t\t\tif (tempFirst && tempSecond && thirdItem) {\n\t\t\t\t\tinfos[first] = thirdItem;\n\t\t\t\t\tinfos[first + 1] = tempSecond;\n\t\t\t\t\tinfos[first + 2] = tempFirst;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 6: // xCD => CDx\n\t\t\tif (c && b) {\n\t\t\t\tconst temp = infos.slice(last - 1, last + 1);\n\t\t\t\tconst [tempFirst, tempSecond] = temp;\n\t\t\t\tconst prevItem = infos[last - 2];\n\t\t\t\tif (tempFirst && tempSecond && prevItem) {\n\t\t\t\t\tinfos[last] = prevItem;\n\t\t\t\t\tinfos[last - 1] = tempSecond;\n\t\t\t\t\tinfos[last - 2] = tempFirst;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 7: // xCD => DCx\n\t\t\tif (c && b) {\n\t\t\t\tconst temp = infos.slice(last - 1, last + 1);\n\t\t\t\tconst [tempFirst, tempSecond] = temp;\n\t\t\t\tconst prevItem = infos[last - 2];\n\t\t\t\tif (tempFirst && tempSecond && prevItem) {\n\t\t\t\t\tinfos[last] = prevItem;\n\t\t\t\t\tinfos[last - 1] = tempFirst;\n\t\t\t\t\tinfos[last - 2] = tempSecond;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 8: // AxCD => CDxA\n\t\t\tif (c) {\n\t\t\t\tconst tempA = a;\n\t\t\t\tinfos[first] = c;\n\t\t\t\tinfos[last - 1] = d;\n\t\t\t\tinfos[last] = tempA;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 9: // AxCD => DCxA\n\t\t\tif (c) {\n\t\t\t\tconst tempA = a;\n\t\t\t\tinfos[first] = d;\n\t\t\t\tinfos[last - 1] = c;\n\t\t\t\tinfos[last] = tempA;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 10: // ABxD => DxAB\n\t\t\tif (b) {\n\t\t\t\tconst tempD = d;\n\t\t\t\tinfos[last] = b;\n\t\t\t\tinfos[first + 1] = a;\n\t\t\t\tinfos[first] = tempD;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 11: // ABxD => DxBA\n\t\t\tif (b) {\n\t\t\t\tconst tempD = d;\n\t\t\t\tinfos[last] = a;\n\t\t\t\tinfos[first + 1] = b;\n\t\t\t\tinfos[first] = tempD;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 12: // ABxCD => CDxAB\n\t\t\tif (b && c) {\n\t\t\t\tconst tempAB = [a, b];\n\t\t\t\tinfos[first] = c;\n\t\t\t\tinfos[first + 1] = d;\n\t\t\t\tinfos[last - 1] = tempAB[0];\n\t\t\t\tinfos[last] = tempAB[1];\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 13: // ABxCD => CDxBA\n\t\t\tif (b && c) {\n\t\t\t\tconst tempAB = [a, b];\n\t\t\t\tinfos[first] = c;\n\t\t\t\tinfos[first + 1] = d;\n\t\t\t\tinfos[last - 1] = tempAB[1];\n\t\t\t\tinfos[last] = tempAB[0];\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 14: // ABxCD => DCxAB\n\t\t\tif (b && c) {\n\t\t\t\tconst tempAB = [a, b];\n\t\t\t\tinfos[first] = d;\n\t\t\t\tinfos[first + 1] = c;\n\t\t\t\tinfos[last - 1] = tempAB[0];\n\t\t\t\tinfos[last] = tempAB[1];\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 15: // ABxCD => DCxBA\n\t\t\tif (b && c) {\n\t\t\t\tconst tempAB = [a, b];\n\t\t\t\tinfos[first] = d;\n\t\t\t\tinfos[first + 1] = c;\n\t\t\t\tinfos[last - 1] = tempAB[1];\n\t\t\t\tinfos[last] = tempAB[0];\n\t\t\t}\n\t\t\tbreak;\n\t}\n}\n\n/**\n * Process contextual substitution subtable\n */\nexport function processContextual(\n\tsubtable: MorxContextualSubtable,\n\tinfos: GlyphInfo[],\n): void {\n\tconst { stateTable, substitutionTable } = subtable;\n\tlet state = 0;\n\tlet markIndex = -1;\n\n\tfor (let i = 0; i <= infos.length; i++) {\n\t\tconst isEnd = i >= infos.length;\n\t\tconst glyphClass = isEnd\n\t\t\t? CLASS_END_OF_TEXT\n\t\t\t: getGlyphClass(stateTable.classTable, infos[i]?.glyphId);\n\n\t\tconst stateRow = stateTable.stateArray[state];\n\t\tif (!stateRow) break;\n\n\t\tconst entry = stateRow[glyphClass] as ContextualEntry | undefined;\n\t\tif (!entry) break;\n\n\t\t// Set mark\n\t\tif (entry.flags & 0x8000) {\n\t\t\tmarkIndex = i;\n\t\t}\n\n\t\t// Apply substitution at mark\n\t\tif (\n\t\t\tentry.markIndex !== 0xffff &&\n\t\t\tmarkIndex >= 0 &&\n\t\t\tmarkIndex < infos.length\n\t\t) {\n\t\t\tconst substTable = substitutionTable[entry.markIndex];\n\t\t\tif (substTable) {\n\t\t\t\tconst markedInfo = infos[markIndex];\n\t\t\t\tif (markedInfo) {\n\t\t\t\t\tconst replacement = substTable.get(markedInfo.glyphId);\n\t\t\t\t\tif (replacement !== undefined) {\n\t\t\t\t\t\tmarkedInfo.glyphId = replacement;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Apply substitution at current\n\t\tif (!isEnd && entry.currentIndex !== 0xffff) {\n\t\t\tconst substTable = substitutionTable[entry.currentIndex];\n\t\t\tif (substTable) {\n\t\t\t\tconst currentInfo = infos[i];\n\t\t\t\tif (currentInfo) {\n\t\t\t\t\tconst replacement = substTable.get(currentInfo.glyphId);\n\t\t\t\t\tif (replacement !== undefined) {\n\t\t\t\t\t\tcurrentInfo.glyphId = replacement;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Don't advance\n\t\tif (!(entry.flags & 0x4000)) {\n\t\t\t// Stay\n\t\t}\n\n\t\tstate = entry.newState;\n\t}\n}\n\n/**\n * Process ligature subtable\n */\nexport function processLigature(\n\tsubtable: MorxLigatureSubtable,\n\tinfos: GlyphInfo[],\n): GlyphInfo[] {\n\tconst { stateTable, ligatureActions, components, ligatures } = subtable;\n\tlet state = 0;\n\tconst stack: number[] = [];\n\tconst result: GlyphInfo[] = [];\n\tconst deleted = new Set<number>();\n\n\tfor (let i = 0; i <= infos.length; i++) {\n\t\tconst isEnd = i >= infos.length;\n\t\tconst glyphClass = isEnd\n\t\t\t? CLASS_END_OF_TEXT\n\t\t\t: getGlyphClass(stateTable.classTable, infos[i]?.glyphId);\n\n\t\tconst stateRow = stateTable.stateArray[state];\n\t\tif (!stateRow) break;\n\n\t\tconst entry = stateRow[glyphClass] as LigatureEntry | undefined;\n\t\tif (!entry) break;\n\n\t\t// Push to stack\n\t\tif (entry.flags & 0x8000) {\n\t\t\tstack.push(i);\n\t\t}\n\n\t\t// Perform ligature action\n\t\tif (entry.flags & 0x2000 && entry.ligActionIndex < ligatureActions.length) {\n\t\t\tlet actionIndex = entry.ligActionIndex;\n\t\t\tlet ligatureGlyph: GlyphId = 0;\n\t\t\tconst componentIndices: number[] = [];\n\n\t\t\t// Process action chain\n\t\t\twhile (actionIndex < ligatureActions.length) {\n\t\t\t\tconst action = ligatureActions[actionIndex];\n\t\t\t\tif (action === undefined) break;\n\n\t\t\t\tconst last = (action & 0x80000000) !== 0;\n\t\t\t\tconst store = (action & 0x40000000) !== 0;\n\t\t\t\tconst componentOffset = ((action & 0x3fffffff) << 2) >> 2; // Sign extend\n\n\t\t\t\tconst stackIdx = stack.pop();\n\t\t\t\tif (stackIdx !== undefined && stackIdx < infos.length) {\n\t\t\t\t\tcomponentIndices.push(stackIdx);\n\t\t\t\t\tconst info = infos[stackIdx];\n\t\t\t\t\tif (info) {\n\t\t\t\t\t\tconst glyphId = info.glyphId;\n\t\t\t\t\t\tconst componentIdx = glyphId + componentOffset;\n\n\t\t\t\t\t\tif (componentIdx >= 0 && componentIdx < components.length) {\n\t\t\t\t\t\t\tconst component = components[componentIdx];\n\t\t\t\t\t\t\tif (component !== undefined) {\n\t\t\t\t\t\t\t\tligatureGlyph = component + ligatureGlyph;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (store && ligatureGlyph < ligatures.length) {\n\t\t\t\t\t// Replace first component with ligature\n\t\t\t\t\tconst firstIdx = componentIndices[componentIndices.length - 1];\n\t\t\t\t\tif (firstIdx !== undefined && firstIdx < infos.length) {\n\t\t\t\t\t\tconst firstInfo = infos[firstIdx];\n\t\t\t\t\t\tconst ligature = ligatures[ligatureGlyph];\n\t\t\t\t\t\tif (firstInfo && ligature !== undefined) {\n\t\t\t\t\t\t\tfirstInfo.glyphId = ligature;\n\t\t\t\t\t\t\t// Mark other components for deletion\n\t\t\t\t\t\t\tfor (const [j, idx] of componentIndices.entries()) {\n\t\t\t\t\t\t\t\tif (j < componentIndices.length - 1) {\n\t\t\t\t\t\t\t\t\tdeleted.add(idx);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tligatureGlyph = 0;\n\t\t\t\t}\n\n\t\t\t\tif (last) break;\n\t\t\t\tactionIndex++;\n\t\t\t}\n\t\t}\n\n\t\t// Don't advance\n\t\tif (!(entry.flags & 0x4000)) {\n\t\t\t// Stay\n\t\t}\n\n\t\tstate = entry.newState;\n\t}\n\n\t// Build result without deleted glyphs\n\tfor (const [i, info] of infos.entries()) {\n\t\tif (!deleted.has(i)) {\n\t\t\tresult.push(info);\n\t\t}\n\t}\n\n\treturn result;\n}\n\n/**\n * Process insertion subtable\n */\nexport function processInsertion(\n\tsubtable: MorxInsertionSubtable,\n\tinfos: GlyphInfo[],\n): GlyphInfo[] {\n\tconst { stateTable, insertionGlyphs } = subtable;\n\tlet state = 0;\n\tlet markIndex = -1;\n\tconst result: GlyphInfo[] = [];\n\tconst insertions: Map<number, { before: GlyphId[]; after: GlyphId[] }> =\n\t\tnew Map();\n\n\tfor (let i = 0; i <= infos.length; i++) {\n\t\tconst isEnd = i >= infos.length;\n\t\tconst glyphClass = isEnd\n\t\t\t? CLASS_END_OF_TEXT\n\t\t\t: getGlyphClass(stateTable.classTable, infos[i]?.glyphId);\n\n\t\tconst stateRow = stateTable.stateArray[state];\n\t\tif (!stateRow) break;\n\n\t\tconst entry = stateRow[glyphClass] as InsertionEntry | undefined;\n\t\tif (!entry) break;\n\n\t\t// Set mark\n\t\tif (entry.flags & 0x8000) {\n\t\t\tmarkIndex = i;\n\t\t}\n\n\t\t// Insert at marked position\n\t\tif (entry.markedInsertIndex !== 0xffff && markIndex >= 0) {\n\t\t\tconst count = (entry.flags >> 5) & 0x1f;\n\t\t\tconst insertBefore = (entry.flags & 0x0800) !== 0;\n\t\t\tconst glyphs = insertionGlyphs.slice(\n\t\t\t\tentry.markedInsertIndex,\n\t\t\t\tentry.markedInsertIndex + count,\n\t\t\t);\n\n\t\t\tlet ins = insertions.get(markIndex);\n\t\t\tif (!ins) {\n\t\t\t\tins = { before: [], after: [] };\n\t\t\t\tinsertions.set(markIndex, ins);\n\t\t\t}\n\t\t\tif (insertBefore) {\n\t\t\t\tins.before.push(...glyphs);\n\t\t\t} else {\n\t\t\t\tins.after.push(...glyphs);\n\t\t\t}\n\t\t}\n\n\t\t// Insert at current position\n\t\tif (!isEnd && entry.currentInsertIndex !== 0xffff) {\n\t\t\tconst count = entry.flags & 0x1f;\n\t\t\tconst insertBefore = (entry.flags & 0x0020) !== 0;\n\t\t\tconst glyphs = insertionGlyphs.slice(\n\t\t\t\tentry.currentInsertIndex,\n\t\t\t\tentry.currentInsertIndex + count,\n\t\t\t);\n\n\t\t\tlet ins = insertions.get(i);\n\t\t\tif (!ins) {\n\t\t\t\tins = { before: [], after: [] };\n\t\t\t\tinsertions.set(i, ins);\n\t\t\t}\n\t\t\tif (insertBefore) {\n\t\t\t\tins.before.push(...glyphs);\n\t\t\t} else {\n\t\t\t\tins.after.push(...glyphs);\n\t\t\t}\n\t\t}\n\n\t\t// Don't advance\n\t\tif (!(entry.flags & 0x4000)) {\n\t\t\t// Stay\n\t\t}\n\n\t\tstate = entry.newState;\n\t}\n\n\t// Build result with insertions\n\tfor (const [i, info] of infos.entries()) {\n\t\tconst ins = insertions.get(i);\n\n\t\tif (ins) {\n\t\t\t// Insert before\n\t\t\tfor (const glyph of ins.before) {\n\t\t\t\tresult.push({\n\t\t\t\t\tglyphId: glyph,\n\t\t\t\t\tcluster: info.cluster,\n\t\t\t\t\tmask: info.mask,\n\t\t\t\t\tcodepoint: 0,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tresult.push(info);\n\n\t\tif (ins) {\n\t\t\t// Insert after\n\t\t\tfor (const glyph of ins.after) {\n\t\t\t\tresult.push({\n\t\t\t\t\tglyphId: glyph,\n\t\t\t\t\tcluster: info.cluster,\n\t\t\t\t\tmask: info.mask,\n\t\t\t\t\tcodepoint: 0,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\treturn result;\n}\n",
11
- "// OpenType primitive types\nexport type uint8 = number;\nexport type int8 = number;\nexport type uint16 = number;\nexport type int16 = number;\nexport type uint32 = number;\nexport type int32 = number;\nexport type Fixed = number; // 16.16 fixed-point\nexport type F2Dot14 = number; // 2.14 fixed-point\nexport type FWord = number; // int16 in font units\nexport type UFWord = number; // uint16 in font units\nexport type Offset16 = number;\nexport type Offset32 = number;\nexport type GlyphId = number;\n\n/** 4-character ASCII tag (packed as uint32 for efficiency) */\nexport type Tag = number;\n\n/** Text direction */\nexport enum Direction {\n\tInvalid = 0,\n\tLTR = 4,\n\tRTL = 5,\n\tTTB = 6,\n\tBTT = 7,\n}\n\n/** Cluster level for glyph-character mapping */\nexport enum ClusterLevel {\n\tMonotoneGraphemes = 0,\n\tMonotoneCharacters = 1,\n\tCharacters = 2,\n}\n\n/** Buffer flags */\nexport enum BufferFlags {\n\tDefault = 0x0,\n\tBeginningOfText = 0x1,\n\tEndOfText = 0x2,\n\tPreserveDefaultIgnorables = 0x4,\n\tRemoveDefaultIgnorables = 0x8,\n\tDoNotInsertDottedCircle = 0x10,\n}\n\n/** Glyph classification from GDEF */\nexport enum GlyphClass {\n\tBase = 1,\n\tLigature = 2,\n\tMark = 3,\n\tComponent = 4,\n}\n\n/** Feature specification for shaping */\nexport interface Feature {\n\ttag: Tag;\n\tvalue: number;\n\tstart: number;\n\tend: number;\n}\n\n/** Variation axis value */\nexport interface Variation {\n\ttag: Tag;\n\tvalue: number;\n}\n\n/** Glyph info during shaping */\nexport interface GlyphInfo {\n\tglyphId: GlyphId;\n\tcluster: number;\n\tmask: number;\n\t/** Unicode codepoint (before shaping) */\n\tcodepoint: number;\n}\n\n/** Glyph position after shaping */\nexport interface GlyphPosition {\n\txAdvance: number;\n\tyAdvance: number;\n\txOffset: number;\n\tyOffset: number;\n}\n\n/** Table record from font directory */\nexport interface TableRecord {\n\ttag: Tag;\n\tchecksum: uint32;\n\toffset: Offset32;\n\tlength: uint32;\n}\n\n/** Lookup flags for controlling glyph matching */\nexport interface LookupFlags {\n\trightToLeft: boolean;\n\tignoreBaseGlyphs: boolean;\n\tignoreLigatures: boolean;\n\tignoreMarks: boolean;\n\tuseMarkFilteringSet: boolean;\n\tmarkAttachmentType: number;\n\tmarkFilteringSet?: number;\n}\n\n// Tag utilities\nexport function tag(str: string): Tag {\n\tif (str.length !== 4) {\n\t\tthrow new Error(`Tag must be exactly 4 characters: \"${str}\"`);\n\t}\n\treturn (\n\t\t(str.charCodeAt(0) << 24) |\n\t\t(str.charCodeAt(1) << 16) |\n\t\t(str.charCodeAt(2) << 8) |\n\t\tstr.charCodeAt(3)\n\t);\n}\n\nexport function tagToString(t: Tag): string {\n\treturn String.fromCharCode(\n\t\t(t >> 24) & 0xff,\n\t\t(t >> 16) & 0xff,\n\t\t(t >> 8) & 0xff,\n\t\tt & 0xff,\n\t);\n}\n\n// Common tags\nexport const Tags = {\n\t// Required tables\n\thead: tag(\"head\"),\n\thhea: tag(\"hhea\"),\n\thmtx: tag(\"hmtx\"),\n\tmaxp: tag(\"maxp\"),\n\tcmap: tag(\"cmap\"),\n\tloca: tag(\"loca\"),\n\tglyf: tag(\"glyf\"),\n\tname: tag(\"name\"),\n\tOS2: tag(\"OS/2\"),\n\tpost: tag(\"post\"),\n\n\t// OpenType layout\n\tGDEF: tag(\"GDEF\"),\n\tGSUB: tag(\"GSUB\"),\n\tGPOS: tag(\"GPOS\"),\n\tBASE: tag(\"BASE\"),\n\tJSTF: tag(\"JSTF\"),\n\tMATH: tag(\"MATH\"),\n\n\t// CFF\n\tCFF: tag(\"CFF \"),\n\tCFF2: tag(\"CFF2\"),\n\n\t// Variable fonts\n\tfvar: tag(\"fvar\"),\n\tgvar: tag(\"gvar\"),\n\tavar: tag(\"avar\"),\n\tHVAR: tag(\"HVAR\"),\n\tVVAR: tag(\"VVAR\"),\n\tMVAR: tag(\"MVAR\"),\n\n\t// AAT\n\tmorx: tag(\"morx\"),\n\tkerx: tag(\"kerx\"),\n\tkern: tag(\"kern\"),\n\ttrak: tag(\"trak\"),\n\tfeat: tag(\"feat\"),\n\n\t// Color\n\tCOLR: tag(\"COLR\"),\n\tCPAL: tag(\"CPAL\"),\n\tSVG: tag(\"SVG \"),\n\tsbix: tag(\"sbix\"),\n\tCBDT: tag(\"CBDT\"),\n\tCBLC: tag(\"CBLC\"),\n\n\t// Style Attributes\n\tSTAT: tag(\"STAT\"),\n\n\t// Vertical\n\tvhea: tag(\"vhea\"),\n\tvmtx: tag(\"vmtx\"),\n\tVORG: tag(\"VORG\"),\n\n\t// Hinting\n\tfpgm: tag(\"fpgm\"),\n\tprep: tag(\"prep\"),\n\tcvt: tag(\"cvt \"),\n\tgasp: tag(\"gasp\"),\n} as const;\n\n// Feature tags\nexport const FeatureTags = {\n\t// GSUB\n\tccmp: tag(\"ccmp\"),\n\tlocl: tag(\"locl\"),\n\trlig: tag(\"rlig\"),\n\tliga: tag(\"liga\"),\n\tclig: tag(\"clig\"),\n\tcalt: tag(\"calt\"),\n\trclt: tag(\"rclt\"),\n\tdlig: tag(\"dlig\"),\n\tsmcp: tag(\"smcp\"),\n\tc2sc: tag(\"c2sc\"),\n\n\t// Arabic\n\tisol: tag(\"isol\"),\n\tinit: tag(\"init\"),\n\tmedi: tag(\"medi\"),\n\tfina: tag(\"fina\"),\n\n\t// GPOS\n\tkern: tag(\"kern\"),\n\tmark: tag(\"mark\"),\n\tmkmk: tag(\"mkmk\"),\n\tcurs: tag(\"curs\"),\n\tdist: tag(\"dist\"),\n} as const;\n",
12
- "import {\n\tDirection,\n\ttype GlyphId,\n\ttype GlyphInfo,\n\ttype GlyphPosition,\n} from \"../types.ts\";\n\n/**\n * Output buffer containing shaped glyphs.\n * Result of the shaping process.\n */\nexport class GlyphBuffer {\n\t/** Direction used during shaping */\n\tdirection: Direction = Direction.LTR;\n\n\t/** Script used during shaping */\n\tscript: string = \"Zyyy\";\n\n\t/** Language used during shaping */\n\tlanguage: string | null = null;\n\n\t/** Glyph information array */\n\tinfos: GlyphInfo[] = [];\n\n\t/** Glyph position array */\n\tpositions: GlyphPosition[] = [];\n\n\t/** Create buffer with pre-allocated capacity */\n\tstatic withCapacity(capacity: number): GlyphBuffer {\n\t\tconst buffer = new GlyphBuffer();\n\t\tbuffer.infos = new Array(capacity);\n\t\tbuffer.positions = new Array(capacity);\n\t\treturn buffer;\n\t}\n\n\t/** Number of glyphs */\n\tget length(): number {\n\t\treturn this.infos.length;\n\t}\n\n\t/** Initialize from glyph infos (positions zeroed) */\n\tinitFromInfos(infos: GlyphInfo[]): void {\n\t\tthis.infos = infos;\n\t\tthis.positions = infos.map(() => ({\n\t\t\txAdvance: 0,\n\t\t\tyAdvance: 0,\n\t\t\txOffset: 0,\n\t\t\tyOffset: 0,\n\t\t}));\n\t}\n\n\t/** Set advance width for a glyph */\n\tsetAdvance(index: number, xAdvance: number, yAdvance = 0): void {\n\t\tconst pos = this.positions[index];\n\t\tif (pos) {\n\t\t\tpos.xAdvance = xAdvance;\n\t\t\tpos.yAdvance = yAdvance;\n\t\t}\n\t}\n\n\t/** Add offset to a glyph position */\n\taddOffset(index: number, xOffset: number, yOffset: number): void {\n\t\tconst pos = this.positions[index];\n\t\tif (pos) {\n\t\t\tpos.xOffset += xOffset;\n\t\t\tpos.yOffset += yOffset;\n\t\t}\n\t}\n\n\t/** Replace glyph at index */\n\treplaceGlyph(index: number, glyphId: GlyphId): void {\n\t\tconst info = this.infos[index];\n\t\tif (info) {\n\t\t\tinfo.glyphId = glyphId;\n\t\t}\n\t}\n\n\t/** Insert glyph at index */\n\tinsertGlyph(index: number, info: GlyphInfo, position: GlyphPosition): void {\n\t\tthis.infos.splice(index, 0, info);\n\t\tthis.positions.splice(index, 0, position);\n\t}\n\n\t/** Remove glyphs in range [start, end) */\n\tremoveRange(start: number, end: number): void {\n\t\tconst count = end - start;\n\t\tthis.infos.splice(start, count);\n\t\tthis.positions.splice(start, count);\n\t}\n\n\t/** Merge clusters from start to end (inclusive) */\n\tmergeClusters(start: number, end: number): void {\n\t\tif (start >= end || start < 0 || end >= this.infos.length) return;\n\n\t\tconst cluster = this.infos[start]?.cluster;\n\t\tfor (let i = start + 1; i <= end; i++) {\n\t\t\tconst info = this.infos[i];\n\t\t\tif (info) {\n\t\t\t\tinfo.cluster = cluster;\n\t\t\t}\n\t\t}\n\t}\n\n\t/** Reverse glyph order (for RTL) */\n\treverse(): void {\n\t\tthis.infos.reverse();\n\t\tthis.positions.reverse();\n\t}\n\n\t/** Reverse range [start, end) */\n\treverseRange(start: number, end: number): void {\n\t\tlet i = start;\n\t\tlet j = end - 1;\n\t\twhile (i < j) {\n\t\t\t// Swap infos\n\t\t\tconst tmpInfo = this.infos[i];\n\t\t\tconst tmpInfoJ = this.infos[j];\n\t\t\tif (!tmpInfo || !tmpInfoJ) break;\n\t\t\tthis.infos[i] = tmpInfoJ;\n\t\t\tthis.infos[j] = tmpInfo;\n\n\t\t\t// Swap positions\n\t\t\tconst tmpPos = this.positions[i];\n\t\t\tconst tmpPosJ = this.positions[j];\n\t\t\tif (!tmpPos || !tmpPosJ) break;\n\t\t\tthis.positions[i] = tmpPosJ;\n\t\t\tthis.positions[j] = tmpPos;\n\n\t\t\ti++;\n\t\t\tj--;\n\t\t}\n\t}\n\n\t/** Get total advance width */\n\tgetTotalAdvance(): { x: number; y: number } {\n\t\tlet x = 0;\n\t\tlet y = 0;\n\t\tfor (const pos of this.positions) {\n\t\t\tx += pos.xAdvance;\n\t\t\ty += pos.yAdvance;\n\t\t}\n\t\treturn { x, y };\n\t}\n\n\t/** Serialize to HarfBuzz-compatible format */\n\tserialize(): string {\n\t\tconst parts: string[] = [];\n\n\t\tfor (const [i, info] of this.infos.entries()) {\n\t\t\tconst pos = this.positions[i];\n\t\t\tif (!pos) continue;\n\n\t\t\tlet str = `${info.glyphId}`;\n\n\t\t\t// Add cluster if not sequential\n\t\t\tif (i === 0 || info.cluster !== this.infos[i - 1]?.cluster) {\n\t\t\t\tstr += `=${info.cluster}`;\n\t\t\t}\n\n\t\t\t// Add positioning\n\t\t\tif (pos.xOffset !== 0 || pos.yOffset !== 0) {\n\t\t\t\tstr += `@${pos.xOffset},${pos.yOffset}`;\n\t\t\t}\n\t\t\tif (pos.xAdvance !== 0) {\n\t\t\t\tstr += `+${pos.xAdvance}`;\n\t\t\t}\n\n\t\t\tparts.push(str);\n\t\t}\n\n\t\treturn `[${parts.join(\"|\")}]`;\n\t}\n\n\t/** Get glyph IDs as array */\n\tglyphIds(): GlyphId[] {\n\t\treturn this.infos.map((info) => info.glyphId);\n\t}\n\n\t/** Get clusters as array */\n\tclusters(): number[] {\n\t\treturn this.infos.map((info) => info.cluster);\n\t}\n\n\t/** Iterator for glyph info/position pairs */\n\t*[Symbol.iterator](): Iterator<{ info: GlyphInfo; position: GlyphPosition }> {\n\t\tfor (const [i, info] of this.infos.entries()) {\n\t\t\tconst position = this.positions[i];\n\t\t\tif (!position) continue;\n\t\t\tyield { info, position };\n\t\t}\n\t}\n}\n",
13
- "import {\n\tBufferFlags,\n\tClusterLevel,\n\tDirection,\n\ttype GlyphInfo,\n} from \"../types.ts\";\n\n/**\n * Input buffer for text to be shaped.\n * Holds Unicode codepoints with associated properties.\n */\nexport class UnicodeBuffer {\n\tprivate _direction: Direction = Direction.LTR;\n\tprivate _script: string = \"Zyyy\"; // Common/Unknown\n\tprivate _language: string | null = null;\n\tprivate _clusterLevel: ClusterLevel = ClusterLevel.MonotoneGraphemes;\n\tprivate _flags: BufferFlags = BufferFlags.Default;\n\n\t/** Codepoints to shape */\n\treadonly codepoints: number[] = [];\n\t/** Cluster indices (maps each codepoint to its cluster) */\n\treadonly clusters: number[] = [];\n\n\t/** Pre-context (text before the buffer for contextual shaping) */\n\tpreContext: number[] = [];\n\t/** Post-context (text after the buffer for contextual shaping) */\n\tpostContext: number[] = [];\n\n\t/** Add a string to the buffer */\n\taddStr(text: string, startCluster = 0): this {\n\t\tlet cluster = startCluster;\n\t\tfor (const char of text) {\n\t\t\tconst codepoint = char.codePointAt(0);\n\t\t\tif (codepoint === undefined) continue;\n\t\t\tthis.codepoints.push(codepoint);\n\t\t\tthis.clusters.push(cluster);\n\t\t\tcluster++;\n\t\t}\n\t\treturn this;\n\t}\n\n\t/** Add codepoints directly */\n\taddCodepoints(codepoints: number[], startCluster = 0): this {\n\t\tlet cluster = startCluster;\n\t\tfor (const cp of codepoints) {\n\t\t\tthis.codepoints.push(cp);\n\t\t\tthis.clusters.push(cluster);\n\t\t\tcluster++;\n\t\t}\n\t\treturn this;\n\t}\n\n\t/** Add a single codepoint */\n\taddCodepoint(codepoint: number, cluster?: number): this {\n\t\tthis.codepoints.push(codepoint);\n\t\tthis.clusters.push(cluster ?? this.codepoints.length - 1);\n\t\treturn this;\n\t}\n\n\t/** Set text direction */\n\tsetDirection(direction: Direction): this {\n\t\tthis._direction = direction;\n\t\treturn this;\n\t}\n\n\t/** Set script (ISO 15924 tag, e.g., 'Latn', 'Arab') */\n\tsetScript(script: string): this {\n\t\tthis._script = script;\n\t\treturn this;\n\t}\n\n\t/** Set language (BCP 47 tag, e.g., 'en', 'ar') */\n\tsetLanguage(language: string | null): this {\n\t\tthis._language = language;\n\t\treturn this;\n\t}\n\n\t/** Set cluster level */\n\tsetClusterLevel(level: ClusterLevel): this {\n\t\tthis._clusterLevel = level;\n\t\treturn this;\n\t}\n\n\t/** Set buffer flags */\n\tsetFlags(flags: BufferFlags): this {\n\t\tthis._flags = flags;\n\t\treturn this;\n\t}\n\n\t/** Set pre-context string */\n\tsetPreContext(text: string): this {\n\t\tthis.preContext = [];\n\t\tfor (const char of text) {\n\t\t\tconst codepoint = char.codePointAt(0);\n\t\t\tif (codepoint !== undefined) {\n\t\t\t\tthis.preContext.push(codepoint);\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t}\n\n\t/** Set post-context string */\n\tsetPostContext(text: string): this {\n\t\tthis.postContext = [];\n\t\tfor (const char of text) {\n\t\t\tconst codepoint = char.codePointAt(0);\n\t\t\tif (codepoint !== undefined) {\n\t\t\t\tthis.postContext.push(codepoint);\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t}\n\n\t/** Clear the buffer */\n\tclear(): this {\n\t\tthis.codepoints.length = 0;\n\t\tthis.clusters.length = 0;\n\t\tthis.preContext.length = 0;\n\t\tthis.postContext.length = 0;\n\t\treturn this;\n\t}\n\n\t/** Number of codepoints */\n\tget length(): number {\n\t\treturn this.codepoints.length;\n\t}\n\n\tget direction(): Direction {\n\t\treturn this._direction;\n\t}\n\n\tget script(): string {\n\t\treturn this._script;\n\t}\n\n\tget language(): string | null {\n\t\treturn this._language;\n\t}\n\n\tget clusterLevel(): ClusterLevel {\n\t\treturn this._clusterLevel;\n\t}\n\n\tget flags(): BufferFlags {\n\t\treturn this._flags;\n\t}\n\n\t/** Convert to initial glyph infos (codepoint = glyphId initially) */\n\ttoGlyphInfos(): GlyphInfo[] {\n\t\treturn this.codepoints.map((codepoint, i) => ({\n\t\t\tglyphId: 0, // Will be set during shaping\n\t\t\tcluster: this.clusters[i] ?? 0,\n\t\t\tmask: 0,\n\t\t\tcodepoint,\n\t\t}));\n\t}\n}\n",
14
- "import type {\n\tF2Dot14,\n\tFixed,\n\tint16,\n\tint32,\n\tOffset16,\n\tOffset32,\n\tTag,\n\tuint8,\n\tuint16,\n\tuint32,\n} from \"../../types.ts\";\n\n/**\n * Zero-copy binary reader for OpenType font data.\n * All multi-byte values are big-endian per OpenType spec.\n */\nexport class Reader {\n\tprivate readonly data: DataView;\n\tprivate readonly start: number;\n\tprivate readonly end: number;\n\tprivate pos: number;\n\n\tconstructor(buffer: ArrayBuffer | DataView, offset = 0, length?: number) {\n\t\tif (buffer instanceof ArrayBuffer) {\n\t\t\tthis.data = new DataView(buffer);\n\t\t\tthis.start = offset;\n\t\t\tthis.end = length !== undefined ? offset + length : buffer.byteLength;\n\t\t} else {\n\t\t\tthis.data = buffer;\n\t\t\tthis.start = buffer.byteOffset + offset;\n\t\t\tthis.end =\n\t\t\t\tlength !== undefined\n\t\t\t\t\t? this.start + length\n\t\t\t\t\t: buffer.byteOffset + buffer.byteLength;\n\t\t}\n\t\tthis.pos = this.start;\n\t}\n\n\t/** Current read position relative to start */\n\tget offset(): number {\n\t\treturn this.pos - this.start;\n\t}\n\n\t/** Bytes remaining to read */\n\tget remaining(): number {\n\t\treturn this.end - this.pos;\n\t}\n\n\t/** Total length of this reader's view */\n\tget length(): number {\n\t\treturn this.end - this.start;\n\t}\n\n\t/** Seek to absolute offset (relative to this reader's start) */\n\tseek(offset: number): void {\n\t\tthis.pos = this.start + offset;\n\t}\n\n\t/** Skip bytes */\n\tskip(bytes: number): void {\n\t\tthis.pos += bytes;\n\t}\n\n\t/** Create a sub-reader (zero-copy slice) */\n\tslice(offset: number, length: number): Reader {\n\t\treturn new Reader(this.data, this.start + offset, length);\n\t}\n\n\t/** Create a sub-reader from current position */\n\tsliceFrom(offset: number): Reader {\n\t\treturn new Reader(\n\t\t\tthis.data,\n\t\t\tthis.start + offset,\n\t\t\tthis.end - this.start - offset,\n\t\t);\n\t}\n\n\t/** Peek at a value without advancing position */\n\tpeek<T>(fn: () => T): T {\n\t\tconst savedPos = this.pos;\n\t\tconst result = fn();\n\t\tthis.pos = savedPos;\n\t\treturn result;\n\t}\n\n\t// Primitive readers (big-endian)\n\n\tuint8(): uint8 {\n\t\tconst value = this.data.getUint8(this.pos);\n\t\tthis.pos += 1;\n\t\treturn value;\n\t}\n\n\tint8(): number {\n\t\tconst value = this.data.getInt8(this.pos);\n\t\tthis.pos += 1;\n\t\treturn value;\n\t}\n\n\tuint16(): uint16 {\n\t\tconst value = this.data.getUint16(this.pos, false);\n\t\tthis.pos += 2;\n\t\treturn value;\n\t}\n\n\tint16(): int16 {\n\t\tconst value = this.data.getInt16(this.pos, false);\n\t\tthis.pos += 2;\n\t\treturn value;\n\t}\n\n\tuint32(): uint32 {\n\t\tconst value = this.data.getUint32(this.pos, false);\n\t\tthis.pos += 4;\n\t\treturn value;\n\t}\n\n\tint32(): int32 {\n\t\tconst value = this.data.getInt32(this.pos, false);\n\t\tthis.pos += 4;\n\t\treturn value;\n\t}\n\n\t// OpenType-specific types\n\n\t/** 16.16 fixed-point number */\n\tfixed(): Fixed {\n\t\treturn this.int32() / 65536;\n\t}\n\n\t/** 2.14 fixed-point number */\n\tf2dot14(): F2Dot14 {\n\t\treturn this.int16() / 16384;\n\t}\n\n\t/** Signed 16-bit integer in font design units */\n\tfword(): int16 {\n\t\treturn this.int16();\n\t}\n\n\t/** Unsigned 16-bit integer in font design units */\n\tufword(): uint16 {\n\t\treturn this.uint16();\n\t}\n\n\t/** 64-bit signed integer (seconds since 1904-01-01) */\n\tlongDateTime(): bigint {\n\t\tconst high = this.uint32();\n\t\tconst low = this.uint32();\n\t\treturn (BigInt(high) << 32n) | BigInt(low);\n\t}\n\n\t/** 4-byte ASCII tag as packed uint32 */\n\ttag(): Tag {\n\t\treturn this.uint32();\n\t}\n\n\t/** 4-byte ASCII tag as string */\n\ttagString(): string {\n\t\tconst t = this.uint32();\n\t\treturn String.fromCharCode(\n\t\t\t(t >> 24) & 0xff,\n\t\t\t(t >> 16) & 0xff,\n\t\t\t(t >> 8) & 0xff,\n\t\t\tt & 0xff,\n\t\t);\n\t}\n\n\t/** 16-bit offset */\n\toffset16(): Offset16 {\n\t\treturn this.uint16();\n\t}\n\n\t/** 32-bit offset */\n\toffset32(): Offset32 {\n\t\treturn this.uint32();\n\t}\n\n\t/** 24-bit unsigned integer */\n\tuint24(): number {\n\t\tconst b0 = this.data.getUint8(this.pos);\n\t\tconst b1 = this.data.getUint8(this.pos + 1);\n\t\tconst b2 = this.data.getUint8(this.pos + 2);\n\t\tthis.pos += 3;\n\t\treturn (b0 << 16) | (b1 << 8) | b2;\n\t}\n\n\t// Array readers\n\n\tuint8Array(count: number): Uint8Array {\n\t\tconst result = new Uint8Array(count);\n\t\tfor (let i = 0; i < count; i++) {\n\t\t\tresult[i] = this.uint8();\n\t\t}\n\t\treturn result;\n\t}\n\n\tuint16Array(count: number): Uint16Array {\n\t\tconst result = new Uint16Array(count);\n\t\tfor (let i = 0; i < count; i++) {\n\t\t\tresult[i] = this.uint16();\n\t\t}\n\t\treturn result;\n\t}\n\n\tint16Array(count: number): Int16Array {\n\t\tconst result = new Int16Array(count);\n\t\tfor (let i = 0; i < count; i++) {\n\t\t\tresult[i] = this.int16();\n\t\t}\n\t\treturn result;\n\t}\n\n\tuint32Array(count: number): Uint32Array {\n\t\tconst result = new Uint32Array(count);\n\t\tfor (let i = 0; i < count; i++) {\n\t\t\tresult[i] = this.uint32();\n\t\t}\n\t\treturn result;\n\t}\n\n\t/** Read array using custom reader function */\n\tarray<T>(count: number, readFn: (reader: Reader) => T): T[] {\n\t\tconst result: T[] = new Array(count);\n\t\tfor (let i = 0; i < count; i++) {\n\t\t\tresult[i] = readFn(this);\n\t\t}\n\t\treturn result;\n\t}\n\n\t// String readers\n\n\t/** Read ASCII string of given length */\n\tascii(length: number): string {\n\t\tlet result = \"\";\n\t\tfor (let i = 0; i < length; i++) {\n\t\t\tresult += String.fromCharCode(this.uint8());\n\t\t}\n\t\treturn result;\n\t}\n\n\t/** Read UTF-16BE string (used in 'name' table) */\n\tutf16be(length: number): string {\n\t\tconst chars: number[] = [];\n\t\tconst charCount = length / 2;\n\t\tfor (let i = 0; i < charCount; i++) {\n\t\t\tchars.push(this.uint16());\n\t\t}\n\t\treturn String.fromCharCode(...chars);\n\t}\n\n\t// Utility methods\n\n\t/** Check if there are enough bytes remaining */\n\thasRemaining(bytes: number): boolean {\n\t\treturn this.remaining >= bytes;\n\t}\n\n\t/** Throw if not enough bytes remaining */\n\tensureRemaining(bytes: number): void {\n\t\tif (this.remaining < bytes) {\n\t\t\tthrow new Error(\n\t\t\t\t`Unexpected end of data: need ${bytes} bytes, have ${this.remaining}`,\n\t\t\t);\n\t\t}\n\t}\n\n\t/** Get raw bytes as Uint8Array (zero-copy view) */\n\tbytes(length: number): Uint8Array {\n\t\tconst result = new Uint8Array(\n\t\t\tthis.data.buffer,\n\t\t\tthis.data.byteOffset + this.pos,\n\t\t\tlength,\n\t\t);\n\t\tthis.pos += length;\n\t\treturn result;\n\t}\n\n\t/** Read value at specific offset without moving position */\n\treadAt<T>(offset: number, fn: (reader: Reader) => T): T {\n\t\tconst savedPos = this.pos;\n\t\tthis.pos = this.start + offset;\n\t\tconst result = fn(this);\n\t\tthis.pos = savedPos;\n\t\treturn result;\n\t}\n}\n",
15
- "import type { uint16 } from \"../../types.ts\";\nimport type { Reader } from \"../binary/reader.ts\";\n\n/**\n * Axis Variations table (avar)\n * Maps user-facing axis values to normalized coordinates\n */\nexport interface AvarTable {\n\tmajorVersion: uint16;\n\tminorVersion: uint16;\n\taxisSegmentMaps: AxisSegmentMap[];\n}\n\n/**\n * Segment map for an axis\n */\nexport interface AxisSegmentMap {\n\taxisValueMaps: AxisValueMap[];\n}\n\n/**\n * Single value mapping\n */\nexport interface AxisValueMap {\n\tfromCoordinate: number; // F2DOT14\n\ttoCoordinate: number; // F2DOT14\n}\n\n/**\n * Parse avar table\n */\nexport function parseAvar(reader: Reader, axisCount: number): AvarTable {\n\tconst majorVersion = reader.uint16();\n\tconst minorVersion = reader.uint16();\n\treader.skip(2); // reserved\n\n\tconst axisSegmentMaps: AxisSegmentMap[] = [];\n\n\tfor (let i = 0; i < axisCount; i++) {\n\t\tconst positionMapCount = reader.uint16();\n\t\tconst axisValueMaps: AxisValueMap[] = [];\n\n\t\tfor (let j = 0; j < positionMapCount; j++) {\n\t\t\taxisValueMaps.push({\n\t\t\t\tfromCoordinate: reader.f2dot14(),\n\t\t\t\ttoCoordinate: reader.f2dot14(),\n\t\t\t});\n\t\t}\n\n\t\taxisSegmentMaps.push({ axisValueMaps });\n\t}\n\n\treturn {\n\t\tmajorVersion,\n\t\tminorVersion,\n\t\taxisSegmentMaps,\n\t};\n}\n\n/**\n * Apply avar mapping to a normalized coordinate\n */\nexport function applyAvarMapping(\n\tsegmentMap: AxisSegmentMap,\n\tcoord: number,\n): number {\n\tconst maps = segmentMap.axisValueMaps;\n\n\tif (maps.length === 0) return coord;\n\n\t// Find the segment containing coord\n\tfor (let i = 0; i < maps.length - 1; i++) {\n\t\tconst map1 = maps[i];\n\t\tconst map2 = maps[i + 1];\n\t\tif (!map1 || !map2) continue;\n\n\t\tif (coord >= map1.fromCoordinate && coord <= map2.fromCoordinate) {\n\t\t\t// Linear interpolation\n\t\t\tconst t =\n\t\t\t\t(coord - map1.fromCoordinate) /\n\t\t\t\t(map2.fromCoordinate - map1.fromCoordinate);\n\t\t\treturn map1.toCoordinate + t * (map2.toCoordinate - map1.toCoordinate);\n\t\t}\n\t}\n\n\t// Clamp to range\n\tconst firstMap = maps[0];\n\tconst lastMap = maps[maps.length - 1];\n\tif (firstMap && coord <= firstMap.fromCoordinate) {\n\t\treturn firstMap.toCoordinate;\n\t}\n\treturn lastMap?.toCoordinate ?? coord;\n}\n\n/**\n * Apply avar mappings to all axis coordinates\n */\nexport function applyAvar(avar: AvarTable, coords: number[]): number[] {\n\tconst result: number[] = [];\n\n\tfor (const [i, coord] of coords.entries()) {\n\t\tconst segmentMap = avar.axisSegmentMaps[i];\n\t\tif (segmentMap) {\n\t\t\tresult.push(applyAvarMapping(segmentMap, coord));\n\t\t} else {\n\t\t\tresult.push(coord);\n\t\t}\n\t}\n\n\treturn result;\n}\n",
16
- "import type { Fixed, Tag } from \"../../types.ts\";\nimport { tagToString } from \"../../types.ts\";\nimport type { Reader } from \"../binary/reader.ts\";\n\n/**\n * Font Variations table (fvar)\n * Defines axes of variation in a variable font\n */\nexport interface FvarTable {\n\tmajorVersion: number;\n\tminorVersion: number;\n\taxes: VariationAxis[];\n\tinstances: NamedInstance[];\n}\n\n/**\n * Variation axis definition\n */\nexport interface VariationAxis {\n\t/** 4-byte axis tag (e.g., 'wght', 'wdth', 'ital') */\n\ttag: Tag;\n\t/** Minimum coordinate value */\n\tminValue: Fixed;\n\t/** Default coordinate value */\n\tdefaultValue: Fixed;\n\t/** Maximum coordinate value */\n\tmaxValue: Fixed;\n\t/** Axis qualifiers (flags) */\n\tflags: number;\n\t/** Name ID for this axis */\n\taxisNameId: number;\n}\n\n/**\n * Named instance (predefined variation)\n */\nexport interface NamedInstance {\n\t/** Name ID for this instance */\n\tsubfamilyNameId: number;\n\t/** Flags */\n\tflags: number;\n\t/** Coordinate values for each axis */\n\tcoordinates: Fixed[];\n\t/** PostScript name ID (optional) */\n\tpostScriptNameId?: number;\n}\n\n/**\n * Common axis tags\n */\nexport const AxisTags = {\n\t/** Weight (100-900, default 400) */\n\twght: 0x77676874,\n\t/** Width (50-200%, default 100) */\n\twdth: 0x77647468,\n\t/** Italic (0-1) */\n\tital: 0x6974616c,\n\t/** Slant (-90 to 90 degrees) */\n\tslnt: 0x736c6e74,\n\t/** Optical size (in points) */\n\topsz: 0x6f70737a,\n} as const;\n\n/**\n * Parse fvar table\n */\nexport function parseFvar(reader: Reader): FvarTable {\n\tconst majorVersion = reader.uint16();\n\tconst minorVersion = reader.uint16();\n\tconst axesArrayOffset = reader.offset16();\n\treader.skip(2); // reserved\n\tconst axisCount = reader.uint16();\n\tconst axisSize = reader.uint16();\n\tconst instanceCount = reader.uint16();\n\tconst instanceSize = reader.uint16();\n\n\t// Parse axes\n\tconst axes: VariationAxis[] = [];\n\treader.seek(axesArrayOffset);\n\n\tfor (let i = 0; i < axisCount; i++) {\n\t\tconst axisStart = reader.offset;\n\t\tconst tag = reader.uint32();\n\t\tconst minValue = reader.fixed();\n\t\tconst defaultValue = reader.fixed();\n\t\tconst maxValue = reader.fixed();\n\t\tconst flags = reader.uint16();\n\t\tconst axisNameId = reader.uint16();\n\n\t\taxes.push({\n\t\t\ttag,\n\t\t\tminValue,\n\t\t\tdefaultValue,\n\t\t\tmaxValue,\n\t\t\tflags,\n\t\t\taxisNameId,\n\t\t});\n\n\t\t// Move to next axis (in case axisSize is larger than expected)\n\t\treader.seek(axisStart + axisSize);\n\t}\n\n\t// Parse instances\n\tconst instances: NamedInstance[] = [];\n\tconst hasPostScriptNameId = instanceSize >= 4 + axisCount * 4 + 2;\n\n\tfor (let i = 0; i < instanceCount; i++) {\n\t\tconst instanceStart = reader.offset;\n\t\tconst subfamilyNameId = reader.uint16();\n\t\tconst flags = reader.uint16();\n\n\t\tconst coordinates: Fixed[] = [];\n\t\tfor (let j = 0; j < axisCount; j++) {\n\t\t\tcoordinates.push(reader.fixed());\n\t\t}\n\n\t\tconst instance: NamedInstance = {\n\t\t\tsubfamilyNameId,\n\t\t\tflags,\n\t\t\tcoordinates,\n\t\t};\n\n\t\tif (hasPostScriptNameId) {\n\t\t\tinstance.postScriptNameId = reader.uint16();\n\t\t}\n\n\t\tinstances.push(instance);\n\n\t\t// Move to next instance\n\t\treader.seek(instanceStart + instanceSize);\n\t}\n\n\treturn {\n\t\tmajorVersion,\n\t\tminorVersion,\n\t\taxes,\n\t\tinstances,\n\t};\n}\n\n/**\n * Normalize axis value to range [-1, 1]\n */\nexport function normalizeAxisValue(axis: VariationAxis, value: number): number {\n\tif (value < axis.defaultValue) {\n\t\tif (value < axis.minValue) value = axis.minValue;\n\t\tif (axis.defaultValue === axis.minValue) return 0;\n\t\treturn (value - axis.defaultValue) / (axis.defaultValue - axis.minValue);\n\t} else if (value > axis.defaultValue) {\n\t\tif (value > axis.maxValue) value = axis.maxValue;\n\t\tif (axis.defaultValue === axis.maxValue) return 0;\n\t\treturn (value - axis.defaultValue) / (axis.maxValue - axis.defaultValue);\n\t}\n\treturn 0;\n}\n\n/**\n * Get axis by tag\n */\nexport function getAxis(fvar: FvarTable, axisTag: Tag): VariationAxis | null {\n\treturn fvar.axes.find((a) => a.tag === axisTag) ?? null;\n}\n\n/**\n * Get axis index by tag\n */\nexport function getAxisIndex(fvar: FvarTable, axisTag: Tag): number {\n\treturn fvar.axes.findIndex((a) => a.tag === axisTag);\n}\n\n/**\n * Debug: Print axis info\n */\nexport function formatAxis(axis: VariationAxis): string {\n\treturn `${tagToString(axis.tag)}: ${axis.minValue.toFixed(1)}..${axis.defaultValue.toFixed(1)}..${axis.maxValue.toFixed(1)}`;\n}\n",
17
- "import type { GlyphId, uint16, uint32 } from \"../../types.ts\";\nimport type { Reader } from \"../binary/reader.ts\";\n\n/**\n * Horizontal Metrics Variations table (HVAR)\n * Provides variations for horizontal advance widths and LSB\n */\nexport interface HvarTable {\n\tmajorVersion: number;\n\tminorVersion: number;\n\titemVariationStore: ItemVariationStore;\n\tadvanceWidthMapping: DeltaSetIndexMap | null;\n\tlsbMapping: DeltaSetIndexMap | null;\n\trsbMapping: DeltaSetIndexMap | null;\n}\n\n/**\n * Item Variation Store - stores delta values for variations\n */\nexport interface ItemVariationStore {\n\tformat: number;\n\tvariationRegions: VariationRegion[];\n\titemVariationData: ItemVariationData[];\n}\n\n/**\n * Variation region defines the space where deltas apply\n */\nexport interface VariationRegion {\n\tregionAxes: RegionAxisCoordinates[];\n}\n\n/**\n * Axis coordinates for a region\n */\nexport interface RegionAxisCoordinates {\n\tstartCoord: number; // F2DOT14\n\tpeakCoord: number;\n\tendCoord: number;\n}\n\n/**\n * Item variation data subtable\n */\nexport interface ItemVariationData {\n\titemCount: uint16;\n\tregionIndexes: uint16[];\n\tdeltaSets: number[][];\n}\n\n/**\n * Delta set index map for mapping glyphs to variation data\n */\nexport interface DeltaSetIndexMap {\n\tformat: number;\n\tmapCount: uint32;\n\tentryFormat: number;\n\tinnerIndexBitCount: number;\n\tmapData: { outer: number; inner: number }[];\n}\n\n/**\n * Parse HVAR table\n */\nexport function parseHvar(reader: Reader): HvarTable {\n\tconst majorVersion = reader.uint16();\n\tconst minorVersion = reader.uint16();\n\tconst itemVariationStoreOffset = reader.offset32();\n\tconst advanceWidthMappingOffset = reader.offset32();\n\tconst lsbMappingOffset = reader.offset32();\n\tconst rsbMappingOffset = reader.offset32();\n\n\t// Parse item variation store\n\tconst itemVariationStore = parseItemVariationStore(\n\t\treader.sliceFrom(itemVariationStoreOffset),\n\t);\n\n\t// Parse mappings\n\tconst advanceWidthMapping =\n\t\tadvanceWidthMappingOffset !== 0\n\t\t\t? parseDeltaSetIndexMap(reader.sliceFrom(advanceWidthMappingOffset))\n\t\t\t: null;\n\n\tconst lsbMapping =\n\t\tlsbMappingOffset !== 0\n\t\t\t? parseDeltaSetIndexMap(reader.sliceFrom(lsbMappingOffset))\n\t\t\t: null;\n\n\tconst rsbMapping =\n\t\trsbMappingOffset !== 0\n\t\t\t? parseDeltaSetIndexMap(reader.sliceFrom(rsbMappingOffset))\n\t\t\t: null;\n\n\treturn {\n\t\tmajorVersion,\n\t\tminorVersion,\n\t\titemVariationStore,\n\t\tadvanceWidthMapping,\n\t\tlsbMapping,\n\t\trsbMapping,\n\t};\n}\n\nfunction parseItemVariationStore(reader: Reader): ItemVariationStore {\n\tconst format = reader.uint16();\n\tconst variationRegionListOffset = reader.offset32();\n\tconst itemVariationDataCount = reader.uint16();\n\n\tconst itemVariationDataOffsets: uint32[] = [];\n\tfor (let i = 0; i < itemVariationDataCount; i++) {\n\t\titemVariationDataOffsets.push(reader.offset32());\n\t}\n\n\t// Parse variation regions\n\tconst regionReader = reader.sliceFrom(variationRegionListOffset);\n\tconst axisCount = regionReader.uint16();\n\tconst regionCount = regionReader.uint16();\n\n\tconst variationRegions: VariationRegion[] = [];\n\tfor (let i = 0; i < regionCount; i++) {\n\t\tconst regionAxes: RegionAxisCoordinates[] = [];\n\t\tfor (let j = 0; j < axisCount; j++) {\n\t\t\tregionAxes.push({\n\t\t\t\tstartCoord: regionReader.f2dot14(),\n\t\t\t\tpeakCoord: regionReader.f2dot14(),\n\t\t\t\tendCoord: regionReader.f2dot14(),\n\t\t\t});\n\t\t}\n\t\tvariationRegions.push({ regionAxes });\n\t}\n\n\t// Parse item variation data\n\tconst itemVariationData: ItemVariationData[] = [];\n\tfor (const offset of itemVariationDataOffsets) {\n\t\tconst dataReader = reader.sliceFrom(offset);\n\t\tconst itemCount = dataReader.uint16();\n\t\tconst wordDeltaCount = dataReader.uint16();\n\t\tconst regionIndexCount = dataReader.uint16();\n\n\t\tconst regionIndexes: uint16[] = [];\n\t\tfor (let i = 0; i < regionIndexCount; i++) {\n\t\t\tregionIndexes.push(dataReader.uint16());\n\t\t}\n\n\t\t// Parse delta sets\n\t\tconst longWords = (wordDeltaCount & 0x8000) !== 0;\n\t\tconst wordCount = wordDeltaCount & 0x7fff;\n\t\tconst shortCount = regionIndexCount - wordCount;\n\n\t\tconst deltaSets: number[][] = [];\n\t\tfor (let i = 0; i < itemCount; i++) {\n\t\t\tconst deltas: number[] = [];\n\t\t\t// Read word-sized deltas\n\t\t\tfor (let j = 0; j < wordCount; j++) {\n\t\t\t\tif (longWords) {\n\t\t\t\t\tdeltas.push(dataReader.int32());\n\t\t\t\t} else {\n\t\t\t\t\tdeltas.push(dataReader.int16());\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Read short-sized deltas\n\t\t\tfor (let j = 0; j < shortCount; j++) {\n\t\t\t\tif (longWords) {\n\t\t\t\t\tdeltas.push(dataReader.int16());\n\t\t\t\t} else {\n\t\t\t\t\tdeltas.push(dataReader.int8());\n\t\t\t\t}\n\t\t\t}\n\t\t\tdeltaSets.push(deltas);\n\t\t}\n\n\t\titemVariationData.push({ itemCount, regionIndexes, deltaSets });\n\t}\n\n\treturn { format, variationRegions, itemVariationData };\n}\n\nfunction parseDeltaSetIndexMap(reader: Reader): DeltaSetIndexMap {\n\tconst format = reader.uint8();\n\tconst entryFormat = reader.uint8();\n\tconst mapCount = format === 0 ? reader.uint16() : reader.uint32();\n\n\tconst innerIndexBitCount = (entryFormat & 0x0f) + 1;\n\tconst mapEntrySize = ((entryFormat >> 4) & 0x03) + 1;\n\n\tconst mapData: { outer: number; inner: number }[] = [];\n\tfor (let i = 0; i < mapCount; i++) {\n\t\tlet entry = 0;\n\t\tfor (let j = 0; j < mapEntrySize; j++) {\n\t\t\tentry = (entry << 8) | reader.uint8();\n\t\t}\n\n\t\tconst inner = entry & ((1 << innerIndexBitCount) - 1);\n\t\tconst outer = entry >> innerIndexBitCount;\n\t\tmapData.push({ outer, inner });\n\t}\n\n\treturn { format, mapCount, entryFormat, innerIndexBitCount, mapData };\n}\n\n/**\n * Calculate scalar for a variation region given axis coordinates\n */\nexport function calculateRegionScalar(\n\tregion: VariationRegion,\n\tcoords: number[], // Normalized axis coordinates [-1, 1]\n): number {\n\tlet scalar = 1.0;\n\n\tfor (let i = 0; i < region.regionAxes.length && i < coords.length; i++) {\n\t\tconst axis = region.regionAxes[i];\n\t\tconst coord = coords[i];\n\t\tif (axis === undefined || coord === undefined) continue;\n\n\t\t// Outside the region\n\t\tif (coord < axis.startCoord || coord > axis.endCoord) {\n\t\t\treturn 0;\n\t\t}\n\n\t\t// At peak\n\t\tif (coord === axis.peakCoord) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Interpolate\n\t\tif (coord < axis.peakCoord) {\n\t\t\tif (axis.peakCoord === axis.startCoord) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tscalar *= (coord - axis.startCoord) / (axis.peakCoord - axis.startCoord);\n\t\t} else {\n\t\t\tif (axis.peakCoord === axis.endCoord) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tscalar *= (axis.endCoord - coord) / (axis.endCoord - axis.peakCoord);\n\t\t}\n\t}\n\n\treturn scalar;\n}\n\n/**\n * Get delta for a glyph from HVAR using a specific mapping\n */\nfunction getDeltaFromMapping(\n\thvar: HvarTable,\n\tglyphId: GlyphId,\n\tcoords: number[],\n\tmapping: DeltaSetIndexMap | null,\n): number {\n\t// Get outer/inner index\n\tlet outer: number;\n\tlet inner: number;\n\n\tif (mapping && glyphId < mapping.mapData.length) {\n\t\tconst entry = mapping.mapData[glyphId];\n\t\tif (!entry) {\n\t\t\touter = 0;\n\t\t\tinner = glyphId;\n\t\t} else {\n\t\t\touter = entry.outer;\n\t\t\tinner = entry.inner;\n\t\t}\n\t} else {\n\t\t// Direct mapping: outer = 0, inner = glyphId\n\t\touter = 0;\n\t\tinner = glyphId;\n\t}\n\n\t// Get variation data\n\tconst varData = hvar.itemVariationStore.itemVariationData[outer];\n\tif (!varData || inner >= varData.itemCount) {\n\t\treturn 0;\n\t}\n\n\tconst deltaSet = varData.deltaSets[inner];\n\tif (!deltaSet) {\n\t\treturn 0;\n\t}\n\n\t// Calculate total delta\n\tlet delta = 0;\n\tfor (const [i, regionIndex] of varData.regionIndexes.entries()) {\n\t\tconst region = hvar.itemVariationStore.variationRegions[regionIndex];\n\t\tif (!region) continue;\n\n\t\tconst scalar = calculateRegionScalar(region, coords);\n\t\tconst regionDelta = deltaSet[i] ?? 0;\n\t\tdelta += scalar * regionDelta;\n\t}\n\n\treturn Math.round(delta);\n}\n\n/**\n * Get advance width delta for a glyph at given variation coordinates\n */\nexport function getAdvanceWidthDelta(\n\thvar: HvarTable,\n\tglyphId: GlyphId,\n\tcoords: number[],\n): number {\n\treturn getDeltaFromMapping(hvar, glyphId, coords, hvar.advanceWidthMapping);\n}\n\n/**\n * Get left side bearing delta for a glyph at given variation coordinates\n */\nexport function getLsbDelta(\n\thvar: HvarTable,\n\tglyphId: GlyphId,\n\tcoords: number[],\n): number {\n\tif (!hvar.lsbMapping) {\n\t\treturn 0; // No LSB variations in this font\n\t}\n\treturn getDeltaFromMapping(hvar, glyphId, coords, hvar.lsbMapping);\n}\n\n/**\n * Get right side bearing delta for a glyph at given variation coordinates\n */\nexport function getRsbDelta(\n\thvar: HvarTable,\n\tglyphId: GlyphId,\n\tcoords: number[],\n): number {\n\tif (!hvar.rsbMapping) {\n\t\treturn 0; // No RSB variations in this font\n\t}\n\treturn getDeltaFromMapping(hvar, glyphId, coords, hvar.rsbMapping);\n}\n",
18
- "import type { GlyphId, Tag, Variation } from \"../types.ts\";\nimport { tag } from \"../types.ts\";\nimport type { Font } from \"./font.ts\";\nimport { applyAvar } from \"./tables/avar.ts\";\nimport { normalizeAxisValue, type VariationAxis } from \"./tables/fvar.ts\";\nimport { getAdvanceWidthDelta, getLsbDelta } from \"./tables/hvar.ts\";\n\n/**\n * A Face represents a specific instance of a variable font.\n * For non-variable fonts, it simply wraps the Font.\n */\nexport class Face {\n\treadonly font: Font;\n\n\t/** Normalized axis coordinates [-1, 1] */\n\tprivate _coords: number[];\n\n\t/** User-space axis values */\n\tprivate _variations: Map<Tag, number>;\n\n\tconstructor(font: Font, variations?: Record<string, number> | Variation[]) {\n\t\tthis.font = font;\n\t\tthis._coords = [];\n\t\tthis._variations = new Map();\n\n\t\t// Initialize to default axis values\n\t\tconst fvar = font.fvar;\n\t\tif (fvar) {\n\t\t\tthis._coords = new Array(fvar.axes.length).fill(0);\n\n\t\t\t// Apply user variations\n\t\t\tif (variations) {\n\t\t\t\tthis.setVariations(variations);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Set variation axis values\n\t * @param variations Object with axis tags as keys (e.g., { wght: 700, wdth: 100 })\n\t * or array of Variation objects\n\t */\n\tsetVariations(variations: Record<string, number> | Variation[]): void {\n\t\tconst fvar = this.font.fvar;\n\t\tif (!fvar) return;\n\n\t\t// Convert to map\n\t\tif (Array.isArray(variations)) {\n\t\t\tfor (const v of variations) {\n\t\t\t\tthis._variations.set(v.tag, v.value);\n\t\t\t}\n\t\t} else {\n\t\t\tfor (const [tagStr, value] of Object.entries(variations)) {\n\t\t\t\tconst t = tag(tagStr.padEnd(4, \" \"));\n\t\t\t\tthis._variations.set(t, value);\n\t\t\t}\n\t\t}\n\n\t\t// Normalize coordinates\n\t\tfor (const [i, axis] of fvar.axes.entries()) {\n\t\t\tconst userValue = this._variations.get(axis.tag) ?? axis.defaultValue;\n\t\t\tthis._coords[i] = normalizeAxisValue(axis, userValue);\n\t\t}\n\n\t\t// Apply avar mapping if present\n\t\tconst avar = this.font.avar;\n\t\tif (avar) {\n\t\t\tthis._coords = applyAvar(avar, this._coords);\n\t\t}\n\t}\n\n\t/**\n\t * Get normalized coordinates for variation processing\n\t */\n\tget normalizedCoords(): number[] {\n\t\treturn this._coords;\n\t}\n\n\t/**\n\t * Check if this is a variable font instance\n\t */\n\tget isVariable(): boolean {\n\t\treturn this.font.isVariable;\n\t}\n\n\t/**\n\t * Get variation axes\n\t */\n\tget axes(): VariationAxis[] {\n\t\treturn this.font.fvar?.axes ?? [];\n\t}\n\n\t/**\n\t * Get current value for an axis\n\t */\n\tgetAxisValue(axisTag: Tag | string): number | null {\n\t\tconst t =\n\t\t\ttypeof axisTag === \"string\" ? tag(axisTag.padEnd(4, \" \")) : axisTag;\n\t\tconst fvar = this.font.fvar;\n\t\tif (!fvar) return null;\n\n\t\tconst value = this._variations.get(t);\n\t\tif (value !== undefined) return value;\n\n\t\tconst axis = fvar.axes.find((a) => a.tag === t);\n\t\treturn axis?.defaultValue ?? null;\n\t}\n\n\t/**\n\t * Get advance width for a glyph, including variation deltas\n\t */\n\tadvanceWidth(glyphId: GlyphId): number {\n\t\tlet advance = this.font.advanceWidth(glyphId);\n\n\t\t// Apply HVAR delta if variable\n\t\tif (this._coords.length > 0 && this.font.hvar) {\n\t\t\tconst delta = getAdvanceWidthDelta(this.font.hvar, glyphId, this._coords);\n\t\t\tadvance += delta;\n\t\t}\n\n\t\treturn advance;\n\t}\n\n\t/**\n\t * Get left side bearing for a glyph, including variation deltas\n\t */\n\tleftSideBearing(glyphId: GlyphId): number {\n\t\tlet lsb = this.font.leftSideBearing(glyphId);\n\n\t\t// Apply HVAR LSB delta if variable\n\t\tif (this._coords.length > 0 && this.font.hvar) {\n\t\t\tconst delta = getLsbDelta(this.font.hvar, glyphId, this._coords);\n\t\t\tlsb += delta;\n\t\t}\n\n\t\treturn lsb;\n\t}\n\n\t// Delegate common properties to font\n\n\tget numGlyphs(): number {\n\t\treturn this.font.numGlyphs;\n\t}\n\n\tget unitsPerEm(): number {\n\t\treturn this.font.unitsPerEm;\n\t}\n\n\tget ascender(): number {\n\t\treturn this.font.ascender;\n\t}\n\n\tget descender(): number {\n\t\treturn this.font.descender;\n\t}\n\n\tget lineGap(): number {\n\t\treturn this.font.lineGap;\n\t}\n\n\tglyphId(codepoint: number): GlyphId {\n\t\treturn this.font.glyphId(codepoint);\n\t}\n\n\tglyphIdForChar(char: string): GlyphId {\n\t\treturn this.font.glyphIdForChar(char);\n\t}\n\n\thasTable(t: Tag): boolean {\n\t\treturn this.font.hasTable(t);\n\t}\n\n\t// Expose tables\n\tget gdef() {\n\t\treturn this.font.gdef;\n\t}\n\tget gsub() {\n\t\treturn this.font.gsub;\n\t}\n\tget gpos() {\n\t\treturn this.font.gpos;\n\t}\n\tget kern() {\n\t\treturn this.font.kern;\n\t}\n\tget morx() {\n\t\treturn this.font.morx;\n\t}\n\tget cmap() {\n\t\treturn this.font.cmap;\n\t}\n\tget hmtx() {\n\t\treturn this.font.hmtx;\n\t}\n\tget hhea() {\n\t\treturn this.font.hhea;\n\t}\n}\n\n/**\n * Create a face from a font with optional variations\n */\nexport function createFace(\n\tfont: Font,\n\tvariations?: Record<string, number> | Variation[],\n): Face {\n\treturn new Face(font, variations);\n}\n",
19
- "/**\n * WOFF2 to SFNT Converter\n *\n * Converts WOFF2 compressed fonts back to raw TTF/OTF format.\n * Reference: https://www.w3.org/TR/WOFF2/\n */\n\n// Known table tags indexed by flag value 0-62\nconst KNOWN_TAGS = [\n\t\"cmap\",\n\t\"head\",\n\t\"hhea\",\n\t\"hmtx\",\n\t\"maxp\",\n\t\"name\",\n\t\"OS/2\",\n\t\"post\",\n\t\"cvt \",\n\t\"fpgm\",\n\t\"glyf\",\n\t\"loca\",\n\t\"prep\",\n\t\"CFF \",\n\t\"VORG\",\n\t\"EBDT\",\n\t\"EBLC\",\n\t\"gasp\",\n\t\"hdmx\",\n\t\"kern\",\n\t\"LTSH\",\n\t\"PCLT\",\n\t\"VDMX\",\n\t\"vhea\",\n\t\"vmtx\",\n\t\"BASE\",\n\t\"GDEF\",\n\t\"GPOS\",\n\t\"GSUB\",\n\t\"EBSC\",\n\t\"JSTF\",\n\t\"MATH\",\n\t\"CBDT\",\n\t\"CBLC\",\n\t\"COLR\",\n\t\"CPAL\",\n\t\"SVG \",\n\t\"sbix\",\n\t\"acnt\",\n\t\"avar\",\n\t\"bdat\",\n\t\"bloc\",\n\t\"bsln\",\n\t\"cvar\",\n\t\"fdsc\",\n\t\"feat\",\n\t\"fmtx\",\n\t\"fvar\",\n\t\"gvar\",\n\t\"hsty\",\n\t\"just\",\n\t\"lcar\",\n\t\"mort\",\n\t\"morx\",\n\t\"opbd\",\n\t\"prop\",\n\t\"trak\",\n\t\"Zapf\",\n\t\"Silf\",\n\t\"Glat\",\n\t\"Gloc\",\n\t\"Feat\",\n\t\"Sill\",\n];\n\ninterface Woff2TableEntry {\n\ttag: string;\n\torigLength: number;\n\ttransformLength: number;\n\ttransformVersion: number;\n}\n\n/** Read UIntBase128 variable-length integer */\nfunction readUIntBase128(data: Uint8Array, offset: { value: number }): number {\n\tlet result = 0;\n\tfor (let i = 0; i < 5; i++) {\n\t\tconst byte = data[offset.value++];\n\t\tif (i === 0 && byte === 0x80) {\n\t\t\tthrow new Error(\"Invalid UIntBase128: leading zeros\");\n\t\t}\n\t\tif (result > 0x1fffff) {\n\t\t\tthrow new Error(\"UIntBase128 overflow\");\n\t\t}\n\t\tresult = (result << 7) | (byte & 0x7f);\n\t\tif ((byte & 0x80) === 0) {\n\t\t\treturn result;\n\t\t}\n\t}\n\tthrow new Error(\"UIntBase128 too long\");\n}\n\n/** Read 255UInt16 */\nfunction read255UInt16(data: Uint8Array, offset: { value: number }): number {\n\tconst code = data[offset.value++];\n\tif (code === 253) {\n\t\tconst hi = data[offset.value++];\n\t\tconst lo = data[offset.value++];\n\t\treturn (hi << 8) | lo;\n\t} else if (code === 255) {\n\t\treturn data[offset.value++] + 253 * 2;\n\t} else if (code === 254) {\n\t\treturn data[offset.value++] + 253;\n\t}\n\treturn code;\n}\n\n/** Parse WOFF2 table directory entries */\nfunction parseTableDirectory(\n\tdata: Uint8Array,\n\toffset: { value: number },\n\tnumTables: number,\n): Woff2TableEntry[] {\n\tconst tables: Woff2TableEntry[] = [];\n\n\tfor (let i = 0; i < numTables; i++) {\n\t\tconst flags = data[offset.value++];\n\t\tconst tagIndex = flags & 0x3f;\n\t\tconst transformVersion = (flags >> 6) & 0x03;\n\n\t\tlet tag: string;\n\t\tif (tagIndex === 63) {\n\t\t\ttag = String.fromCharCode(\n\t\t\t\tdata[offset.value++],\n\t\t\t\tdata[offset.value++],\n\t\t\t\tdata[offset.value++],\n\t\t\t\tdata[offset.value++],\n\t\t\t);\n\t\t} else {\n\t\t\ttag = KNOWN_TAGS[tagIndex];\n\t\t}\n\n\t\tconst origLength = readUIntBase128(data, offset);\n\n\t\tlet transformLength = origLength;\n\t\t// glyf/loca: transform version 0 = transformed, 3 = null transform\n\t\t// others: transform version 0 = null transform\n\t\tconst hasTransform =\n\t\t\ttag === \"glyf\" || tag === \"loca\"\n\t\t\t\t? transformVersion === 0\n\t\t\t\t: transformVersion !== 0;\n\n\t\tif (hasTransform) {\n\t\t\ttransformLength = readUIntBase128(data, offset);\n\t\t}\n\n\t\ttables.push({ tag, origLength, transformLength, transformVersion });\n\t}\n\n\treturn tables;\n}\n\n/** Decompress Brotli data */\nasync function decompressBrotli(data: Uint8Array): Promise<Uint8Array> {\n\t// Try native DecompressionStream with \"brotli\" (Safari 18.4+, Deno)\n\tif (typeof DecompressionStream !== \"undefined\") {\n\t\ttry {\n\t\t\tconst ds = new DecompressionStream(\"brotli\" as CompressionFormat);\n\t\t\tconst blob = new Blob([data.buffer as ArrayBuffer]);\n\t\t\tconst decompressedStream = blob.stream().pipeThrough(ds);\n\t\t\tconst result = await new Response(decompressedStream).arrayBuffer();\n\t\t\treturn new Uint8Array(result);\n\t\t} catch {\n\t\t\t// \"brotli\" not supported in this browser\n\t\t}\n\t}\n\n\t// Pure TypeScript brotli decoder\n\tconst { decompress } = await import(\"./brotli/decode.ts\");\n\treturn decompress(data);\n}\n\n/** Write uint16 big-endian */\nfunction writeUint16BE(arr: Uint8Array, offset: number, value: number): void {\n\tarr[offset] = (value >> 8) & 0xff;\n\tarr[offset + 1] = value & 0xff;\n}\n\n/** Write uint32 big-endian */\nfunction writeUint32BE(arr: Uint8Array, offset: number, value: number): void {\n\tarr[offset] = (value >> 24) & 0xff;\n\tarr[offset + 1] = (value >> 16) & 0xff;\n\tarr[offset + 2] = (value >> 8) & 0xff;\n\tarr[offset + 3] = value & 0xff;\n}\n\n/** Read uint16 big-endian */\nfunction readUint16BE(arr: Uint8Array, offset: number): number {\n\treturn (arr[offset] << 8) | arr[offset + 1];\n}\n\n/** Read int16 big-endian */\nfunction readInt16BE(arr: Uint8Array, offset: number): number {\n\tconst val = readUint16BE(arr, offset);\n\treturn val >= 0x8000 ? val - 0x10000 : val;\n}\n\n/** Read uint32 big-endian */\nfunction readUint32BE(arr: Uint8Array, offset: number): number {\n\treturn (\n\t\t((arr[offset] << 24) |\n\t\t\t(arr[offset + 1] << 16) |\n\t\t\t(arr[offset + 2] << 8) |\n\t\t\tarr[offset + 3]) >>>\n\t\t0\n\t);\n}\n\n/** Calculate OpenType checksum */\nfunction calcChecksum(\n\tdata: Uint8Array,\n\toffset: number,\n\tlength: number,\n): number {\n\tlet sum = 0;\n\tconst nLongs = Math.ceil(length / 4);\n\tfor (let i = 0; i < nLongs; i++) {\n\t\tconst idx = offset + i * 4;\n\t\tsum =\n\t\t\t(sum +\n\t\t\t\t(((data[idx] || 0) << 24) |\n\t\t\t\t\t((data[idx + 1] || 0) << 16) |\n\t\t\t\t\t((data[idx + 2] || 0) << 8) |\n\t\t\t\t\t(data[idx + 3] || 0))) >>>\n\t\t\t0;\n\t}\n\treturn sum;\n}\n\n/** Round up to 4-byte boundary */\nfunction pad4(n: number): number {\n\treturn (n + 3) & ~3;\n}\n\n/**\n * Decode triplet-encoded coordinates from WOFF2 glyph stream.\n * Based on fonttools implementation.\n *\n * Flag byte structure:\n * bit 7: on-curve (0) or off-curve (1) - NOTE: inverted from TrueType!\n * bits 0-6: encoding index (0-127)\n *\n * Encoding index determines:\n * 0-9: dy only (1 byte)\n * 10-19: dx only (1 byte)\n * 20-83: dx and dy (1 byte total)\n * 84-119: dx and dy (2 bytes total)\n * 120-123: dx and dy (3 bytes total)\n * 124-127: dx and dy (4 bytes total)\n */\nfunction decodeTriplets(\n\tflagStream: Uint8Array,\n\tglyphStream: Uint8Array,\n\tnPoints: number,\n\tflagIdx: { value: number },\n\tglyphIdx: { value: number },\n): { x: number; y: number; onCurve: boolean }[] {\n\tconst points: { x: number; y: number; onCurve: boolean }[] = [];\n\tlet x = 0,\n\t\ty = 0;\n\n\tfunction withSign(flag: number, baseval: number): number {\n\t\treturn flag & 1 ? baseval : -baseval;\n\t}\n\n\tfor (let i = 0; i < nPoints; i++) {\n\t\tconst flag = flagStream[flagIdx.value++];\n\t\tconst onCurve = flag >> 7 === 0; // bit 7 clear = on curve\n\t\tconst flagValue = flag & 0x7f;\n\n\t\tlet dx = 0,\n\t\t\tdy = 0;\n\n\t\tif (flagValue < 10) {\n\t\t\t// dy only, 1 byte\n\t\t\tdx = 0;\n\t\t\tdy = withSign(\n\t\t\t\tflag,\n\t\t\t\t((flagValue & 14) << 7) + glyphStream[glyphIdx.value++],\n\t\t\t);\n\t\t} else if (flagValue < 20) {\n\t\t\t// dx only, 1 byte\n\t\t\tdx = withSign(\n\t\t\t\tflag,\n\t\t\t\t(((flagValue - 10) & 14) << 7) + glyphStream[glyphIdx.value++],\n\t\t\t);\n\t\t\tdy = 0;\n\t\t} else if (flagValue < 84) {\n\t\t\t// Both in 1 byte\n\t\t\tconst b0 = flagValue - 20;\n\t\t\tconst b1 = glyphStream[glyphIdx.value++];\n\t\t\tdx = withSign(flag, 1 + (b0 & 0x30) + (b1 >> 4));\n\t\t\tdy = withSign(flag >> 1, 1 + ((b0 & 0x0c) << 2) + (b1 & 0x0f));\n\t\t} else if (flagValue < 120) {\n\t\t\t// Both in 2 bytes\n\t\t\tconst b0 = flagValue - 84;\n\t\t\tdx = withSign(\n\t\t\t\tflag,\n\t\t\t\t1 + (Math.floor(b0 / 12) << 8) + glyphStream[glyphIdx.value++],\n\t\t\t);\n\t\t\tdy = withSign(\n\t\t\t\tflag >> 1,\n\t\t\t\t1 + (((b0 % 12) >> 2) << 8) + glyphStream[glyphIdx.value++],\n\t\t\t);\n\t\t} else if (flagValue < 124) {\n\t\t\t// Both in 3 bytes\n\t\t\tconst b1 = glyphStream[glyphIdx.value++];\n\t\t\tconst b2 = glyphStream[glyphIdx.value++];\n\t\t\tconst b3 = glyphStream[glyphIdx.value++];\n\t\t\tdx = withSign(flag, (b1 << 4) + (b2 >> 4));\n\t\t\tdy = withSign(flag >> 1, ((b2 & 0x0f) << 8) + b3);\n\t\t} else {\n\t\t\t// Both in 4 bytes\n\t\t\tdx = withSign(\n\t\t\t\tflag,\n\t\t\t\t(glyphStream[glyphIdx.value++] << 8) + glyphStream[glyphIdx.value++],\n\t\t\t);\n\t\t\tdy = withSign(\n\t\t\t\tflag >> 1,\n\t\t\t\t(glyphStream[glyphIdx.value++] << 8) + glyphStream[glyphIdx.value++],\n\t\t\t);\n\t\t}\n\n\t\tx += dx;\n\t\ty += dy;\n\t\tpoints.push({ x, y, onCurve });\n\t}\n\n\treturn points;\n}\n\n/** Reconstruct glyf and loca tables from WOFF2 transformed format */\nfunction reconstructGlyfLoca(\n\tglyfTransform: Uint8Array,\n\tnumGlyphs: number,\n\tindexFormat: number,\n): { glyf: Uint8Array; loca: Uint8Array } {\n\tlet offset = 0;\n\n\t// Read transformed glyf header (per WOFF2 spec Table 1)\n\tconst version = readUint16BE(glyfTransform, offset);\n\toffset += 2;\n\tif (version !== 0) {\n\t\tthrow new Error(`Unsupported glyf transform version: ${version}`);\n\t}\n\tconst optionFlags = readUint16BE(glyfTransform, offset);\n\toffset += 2;\n\tconst _numGlyphsHeader = readUint16BE(glyfTransform, offset);\n\toffset += 2;\n\tconst _indexFormatHeader = readUint16BE(glyfTransform, offset);\n\toffset += 2;\n\n\tconst nContourStreamSize = readUint32BE(glyfTransform, offset);\n\toffset += 4;\n\tconst nPointsStreamSize = readUint32BE(glyfTransform, offset);\n\toffset += 4;\n\tconst flagStreamSize = readUint32BE(glyfTransform, offset);\n\toffset += 4;\n\tconst glyphStreamSize = readUint32BE(glyfTransform, offset);\n\toffset += 4;\n\tconst compositeStreamSize = readUint32BE(glyfTransform, offset);\n\toffset += 4;\n\tconst bboxStreamSize = readUint32BE(glyfTransform, offset);\n\toffset += 4;\n\tconst instructionStreamSize = readUint32BE(glyfTransform, offset);\n\toffset += 4;\n\n\t// Extract streams\n\tconst nContourStream = glyfTransform.slice(\n\t\toffset,\n\t\toffset + nContourStreamSize,\n\t);\n\toffset += nContourStreamSize;\n\tconst nPointsStream = glyfTransform.slice(offset, offset + nPointsStreamSize);\n\toffset += nPointsStreamSize;\n\tconst flagStream = glyfTransform.slice(offset, offset + flagStreamSize);\n\toffset += flagStreamSize;\n\tconst glyphStream = glyfTransform.slice(offset, offset + glyphStreamSize);\n\toffset += glyphStreamSize;\n\tconst compositeStream = glyfTransform.slice(\n\t\toffset,\n\t\toffset + compositeStreamSize,\n\t);\n\toffset += compositeStreamSize;\n\tconst bboxStream = glyfTransform.slice(offset, offset + bboxStreamSize);\n\toffset += bboxStreamSize;\n\tconst instructionStream = glyfTransform.slice(\n\t\toffset,\n\t\toffset + instructionStreamSize,\n\t);\n\n\t// Stream indices\n\tconst nContourIdx = { value: 0 };\n\tconst nPointsIdx = { value: 0 };\n\tconst flagIdx = { value: 0 };\n\tconst glyphIdx = { value: 0 };\n\tconst compositeIdx = { value: 0 };\n\tconst bboxIdx = { value: 0 };\n\tconst instructionIdx = { value: 0 };\n\n\t// First pass: calculate glyf size\n\tconst glyphOffsets: number[] = [0];\n\tconst glyphParts: Uint8Array[] = [];\n\tlet totalGlyfSize = 0;\n\n\tfor (let g = 0; g < numGlyphs; g++) {\n\t\tconst nContours = readInt16BE(nContourStream, nContourIdx.value);\n\t\tnContourIdx.value += 2;\n\n\t\tif (nContours === 0) {\n\t\t\t// Empty glyph\n\t\t\tglyphParts.push(new Uint8Array(0));\n\t\t\tglyphOffsets.push(totalGlyfSize);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (nContours > 0) {\n\t\t\t// Simple glyph\n\t\t\tconst glyphData = reconstructSimpleGlyph(\n\t\t\t\tnContours,\n\t\t\t\tnPointsStream,\n\t\t\t\tnPointsIdx,\n\t\t\t\tflagStream,\n\t\t\t\tflagIdx,\n\t\t\t\tglyphStream,\n\t\t\t\tglyphIdx,\n\t\t\t\tbboxStream,\n\t\t\t\tbboxIdx,\n\t\t\t\tinstructionStream,\n\t\t\t\tinstructionIdx,\n\t\t\t\toptionFlags,\n\t\t\t);\n\t\t\tglyphParts.push(glyphData);\n\t\t\ttotalGlyfSize += pad4(glyphData.length);\n\t\t\tglyphOffsets.push(totalGlyfSize);\n\t\t} else {\n\t\t\t// Composite glyph (nContours === -1)\n\t\t\tconst glyphData = reconstructCompositeGlyph(\n\t\t\t\tcompositeStream,\n\t\t\t\tcompositeIdx,\n\t\t\t\tbboxStream,\n\t\t\t\tbboxIdx,\n\t\t\t\tinstructionStream,\n\t\t\t\tinstructionIdx,\n\t\t\t\toptionFlags,\n\t\t\t);\n\t\t\tglyphParts.push(glyphData);\n\t\t\ttotalGlyfSize += pad4(glyphData.length);\n\t\t\tglyphOffsets.push(totalGlyfSize);\n\t\t}\n\t}\n\n\t// Build glyf table\n\tconst glyf = new Uint8Array(totalGlyfSize);\n\tlet glyfOffset = 0;\n\tfor (const part of glyphParts) {\n\t\tglyf.set(part, glyfOffset);\n\t\tglyfOffset += pad4(part.length);\n\t}\n\n\t// Build loca table\n\tconst locaSize =\n\t\tindexFormat === 0 ? (numGlyphs + 1) * 2 : (numGlyphs + 1) * 4;\n\tconst loca = new Uint8Array(locaSize);\n\n\tfor (let i = 0; i <= numGlyphs; i++) {\n\t\tif (indexFormat === 0) {\n\t\t\twriteUint16BE(loca, i * 2, glyphOffsets[i] / 2);\n\t\t} else {\n\t\t\twriteUint32BE(loca, i * 4, glyphOffsets[i]);\n\t\t}\n\t}\n\n\treturn { glyf, loca };\n}\n\nfunction reconstructSimpleGlyph(\n\tnContours: number,\n\tnPointsStream: Uint8Array,\n\tnPointsIdx: { value: number },\n\tflagStream: Uint8Array,\n\tflagIdx: { value: number },\n\tglyphStream: Uint8Array,\n\tglyphIdx: { value: number },\n\tbboxStream: Uint8Array,\n\tbboxIdx: { value: number },\n\tinstructionStream: Uint8Array,\n\tinstructionIdx: { value: number },\n\toptionFlags: number,\n): Uint8Array {\n\t// Read endpoints\n\tconst endPtsOfContours: number[] = [];\n\tlet totalPoints = 0;\n\tfor (let c = 0; c < nContours; c++) {\n\t\tconst nPoints = read255UInt16(nPointsStream, nPointsIdx);\n\t\ttotalPoints += nPoints;\n\t\tendPtsOfContours.push(totalPoints - 1);\n\t}\n\n\t// Read point data using triplet encoding\n\tconst points = decodeTriplets(\n\t\tflagStream,\n\t\tglyphStream,\n\t\ttotalPoints,\n\t\tflagIdx,\n\t\tglyphIdx,\n\t);\n\n\t// Read/compute bbox\n\tlet xMin: number, yMin: number, xMax: number, yMax: number;\n\tconst bboxBitmap = (optionFlags & 1) === 0; // bit 0 clear = explicit bboxes stored\n\n\tif (bboxBitmap && bboxIdx.value + 8 <= bboxStream.length) {\n\t\txMin = readInt16BE(bboxStream, bboxIdx.value);\n\t\tbboxIdx.value += 2;\n\t\tyMin = readInt16BE(bboxStream, bboxIdx.value);\n\t\tbboxIdx.value += 2;\n\t\txMax = readInt16BE(bboxStream, bboxIdx.value);\n\t\tbboxIdx.value += 2;\n\t\tyMax = readInt16BE(bboxStream, bboxIdx.value);\n\t\tbboxIdx.value += 2;\n\t} else {\n\t\t// Compute bbox\n\t\txMin = yMin = 0x7fff;\n\t\txMax = yMax = -0x8000;\n\t\tfor (const pt of points) {\n\t\t\txMin = Math.min(xMin, pt.x);\n\t\t\tyMin = Math.min(yMin, pt.y);\n\t\t\txMax = Math.max(xMax, pt.x);\n\t\t\tyMax = Math.max(yMax, pt.y);\n\t\t}\n\t}\n\n\t// Read instructions - length is read from glyphStream using 255UInt16 encoding\n\tconst instructionLength = read255UInt16(glyphStream, glyphIdx);\n\tconst instructions = instructionStream.slice(\n\t\tinstructionIdx.value,\n\t\tinstructionIdx.value + instructionLength,\n\t);\n\tinstructionIdx.value += instructionLength;\n\n\t// Encode glyph in TrueType format\n\t// Convert absolute coords to deltas and encode\n\tconst xDeltas: number[] = [];\n\tconst yDeltas: number[] = [];\n\tlet prevX = 0,\n\t\tprevY = 0;\n\tfor (const pt of points) {\n\t\txDeltas.push(pt.x - prevX);\n\t\tyDeltas.push(pt.y - prevY);\n\t\tprevX = pt.x;\n\t\tprevY = pt.y;\n\t}\n\n\t// Encode flags and coordinates\n\tconst encodedFlags: number[] = [];\n\tconst encodedX: number[] = [];\n\tconst encodedY: number[] = [];\n\n\tfor (let i = 0; i < totalPoints; i++) {\n\t\tlet flag = points[i].onCurve ? 1 : 0;\n\t\tconst dx = xDeltas[i];\n\t\tconst dy = yDeltas[i];\n\n\t\t// X encoding\n\t\tif (dx === 0) {\n\t\t\tflag |= 0x10; // x-same\n\t\t} else if (dx >= -255 && dx <= 255) {\n\t\t\tflag |= 0x02; // x-short\n\t\t\tif (dx > 0) flag |= 0x10; // positive\n\t\t\tencodedX.push(Math.abs(dx));\n\t\t} else {\n\t\t\tencodedX.push((dx >> 8) & 0xff, dx & 0xff);\n\t\t}\n\n\t\t// Y encoding\n\t\tif (dy === 0) {\n\t\t\tflag |= 0x20; // y-same\n\t\t} else if (dy >= -255 && dy <= 255) {\n\t\t\tflag |= 0x04; // y-short\n\t\t\tif (dy > 0) flag |= 0x20; // positive\n\t\t\tencodedY.push(Math.abs(dy));\n\t\t} else {\n\t\t\tencodedY.push((dy >> 8) & 0xff, dy & 0xff);\n\t\t}\n\n\t\tencodedFlags.push(flag);\n\t}\n\n\t// Build glyph buffer\n\tconst headerSize = 10 + nContours * 2 + 2 + instructionLength;\n\tconst totalSize =\n\t\theaderSize + encodedFlags.length + encodedX.length + encodedY.length;\n\tconst data = new Uint8Array(totalSize);\n\tlet off = 0;\n\n\t// Header\n\twriteUint16BE(data, off, nContours);\n\toff += 2;\n\twriteUint16BE(data, off, xMin & 0xffff);\n\toff += 2;\n\twriteUint16BE(data, off, yMin & 0xffff);\n\toff += 2;\n\twriteUint16BE(data, off, xMax & 0xffff);\n\toff += 2;\n\twriteUint16BE(data, off, yMax & 0xffff);\n\toff += 2;\n\n\t// End points\n\tfor (const endPt of endPtsOfContours) {\n\t\twriteUint16BE(data, off, endPt);\n\t\toff += 2;\n\t}\n\n\t// Instructions\n\twriteUint16BE(data, off, instructionLength);\n\toff += 2;\n\tdata.set(instructions, off);\n\toff += instructionLength;\n\n\t// Flags\n\tfor (const f of encodedFlags) {\n\t\tdata[off++] = f;\n\t}\n\n\t// X coordinates\n\tfor (const x of encodedX) {\n\t\tdata[off++] = x;\n\t}\n\n\t// Y coordinates\n\tfor (const y of encodedY) {\n\t\tdata[off++] = y;\n\t}\n\n\treturn data.slice(0, off);\n}\n\nfunction reconstructCompositeGlyph(\n\tcompositeStream: Uint8Array,\n\tcompositeIdx: { value: number },\n\tbboxStream: Uint8Array,\n\tbboxIdx: { value: number },\n\tinstructionStream: Uint8Array,\n\tinstructionIdx: { value: number },\n\t_optionFlags: number,\n): Uint8Array {\n\tconst parts: number[] = [];\n\n\t// Read bbox\n\tconst xMin = readInt16BE(bboxStream, bboxIdx.value);\n\tbboxIdx.value += 2;\n\tconst yMin = readInt16BE(bboxStream, bboxIdx.value);\n\tbboxIdx.value += 2;\n\tconst xMax = readInt16BE(bboxStream, bboxIdx.value);\n\tbboxIdx.value += 2;\n\tconst yMax = readInt16BE(bboxStream, bboxIdx.value);\n\tbboxIdx.value += 2;\n\n\t// Header\n\tparts.push(0xff, 0xff); // nContours = -1\n\tparts.push((xMin >> 8) & 0xff, xMin & 0xff);\n\tparts.push((yMin >> 8) & 0xff, yMin & 0xff);\n\tparts.push((xMax >> 8) & 0xff, xMax & 0xff);\n\tparts.push((yMax >> 8) & 0xff, yMax & 0xff);\n\n\t// Read components\n\tlet hasMoreComponents = true;\n\tlet hasInstructions = false;\n\n\twhile (hasMoreComponents) {\n\t\tconst flags = readUint16BE(compositeStream, compositeIdx.value);\n\t\tcompositeIdx.value += 2;\n\t\tconst glyphIndex = readUint16BE(compositeStream, compositeIdx.value);\n\t\tcompositeIdx.value += 2;\n\n\t\tparts.push((flags >> 8) & 0xff, flags & 0xff);\n\t\tparts.push((glyphIndex >> 8) & 0xff, glyphIndex & 0xff);\n\n\t\t// Arguments\n\t\tif (flags & 0x0001) {\n\t\t\t// ARG_1_AND_2_ARE_WORDS\n\t\t\tparts.push(compositeStream[compositeIdx.value++]);\n\t\t\tparts.push(compositeStream[compositeIdx.value++]);\n\t\t\tparts.push(compositeStream[compositeIdx.value++]);\n\t\t\tparts.push(compositeStream[compositeIdx.value++]);\n\t\t} else {\n\t\t\tparts.push(compositeStream[compositeIdx.value++]);\n\t\t\tparts.push(compositeStream[compositeIdx.value++]);\n\t\t}\n\n\t\t// Transform\n\t\tif (flags & 0x0008) {\n\t\t\t// WE_HAVE_A_SCALE\n\t\t\tparts.push(compositeStream[compositeIdx.value++]);\n\t\t\tparts.push(compositeStream[compositeIdx.value++]);\n\t\t} else if (flags & 0x0040) {\n\t\t\t// WE_HAVE_AN_X_AND_Y_SCALE\n\t\t\tfor (let i = 0; i < 4; i++)\n\t\t\t\tparts.push(compositeStream[compositeIdx.value++]);\n\t\t} else if (flags & 0x0080) {\n\t\t\t// WE_HAVE_A_TWO_BY_TWO\n\t\t\tfor (let i = 0; i < 8; i++)\n\t\t\t\tparts.push(compositeStream[compositeIdx.value++]);\n\t\t}\n\n\t\thasMoreComponents = (flags & 0x0020) !== 0;\n\t\tif (flags & 0x0100) hasInstructions = true;\n\t}\n\n\t// Instructions\n\tif (hasInstructions) {\n\t\tconst instrLen = read255UInt16(instructionStream, instructionIdx);\n\t\tparts.push((instrLen >> 8) & 0xff, instrLen & 0xff);\n\t\tfor (let i = 0; i < instrLen; i++) {\n\t\t\tparts.push(instructionStream[instructionIdx.value++]);\n\t\t}\n\t}\n\n\treturn new Uint8Array(parts);\n}\n\n/** Convert WOFF2 to SFNT */\nexport async function woff2ToSfnt(buffer: ArrayBuffer): Promise<ArrayBuffer> {\n\tconst data = new Uint8Array(buffer);\n\tconst view = new DataView(buffer);\n\n\t// Read header\n\tconst signature = view.getUint32(0, false);\n\tif (signature !== 0x774f4632) {\n\t\tthrow new Error(\"Not a valid WOFF2 file\");\n\t}\n\n\tconst flavor = view.getUint32(4, false);\n\tconst numTables = view.getUint16(12, false);\n\tconst totalCompressedSize = view.getUint32(20, false);\n\n\t// Parse table directory\n\tconst offset = { value: 48 };\n\tconst tables = parseTableDirectory(data, offset, numTables);\n\n\t// Decompress all table data\n\tconst compressedData = data.slice(\n\t\toffset.value,\n\t\toffset.value + totalCompressedSize,\n\t);\n\tconst decompressedData = await decompressBrotli(compressedData);\n\n\t// Extract individual table data\n\tconst tableData: Map<string, Uint8Array> = new Map();\n\tlet decompOffset = 0;\n\n\tfor (const table of tables) {\n\t\tconst tdata = decompressedData.slice(\n\t\t\tdecompOffset,\n\t\t\tdecompOffset + table.transformLength,\n\t\t);\n\t\ttableData.set(table.tag, tdata);\n\t\tdecompOffset += table.transformLength;\n\t}\n\n\t// Get metadata from maxp and head\n\tconst maxpData = tableData.get(\"maxp\");\n\tconst headData = tableData.get(\"head\");\n\tif (!maxpData || !headData) {\n\t\tthrow new Error(\"Missing required tables\");\n\t}\n\n\tconst numGlyphs = readUint16BE(maxpData, 4);\n\tconst indexToLocFormat = readInt16BE(headData, 50);\n\n\t// Handle glyf/loca transform\n\tconst glyfEntry = tables.find((t) => t.tag === \"glyf\");\n\tconst locaEntry = tables.find((t) => t.tag === \"loca\");\n\n\tif (glyfEntry && glyfEntry.transformVersion === 0) {\n\t\tconst glyfTransformed = tableData.get(\"glyf\");\n\t\tif (!glyfTransformed) {\n\t\t\tthrow new Error(\"Missing glyf table data for transform\");\n\t\t}\n\t\tconst { glyf, loca } = reconstructGlyfLoca(\n\t\t\tglyfTransformed,\n\t\t\tnumGlyphs,\n\t\t\tindexToLocFormat,\n\t\t);\n\t\ttableData.set(\"glyf\", glyf);\n\t\ttableData.set(\"loca\", loca);\n\n\t\t// Update lengths\n\t\tglyfEntry.origLength = glyf.length;\n\t\tif (locaEntry) {\n\t\t\tlocaEntry.origLength = loca.length;\n\t\t}\n\t}\n\n\t// Calculate SFNT size\n\tconst headerSize = 12;\n\tconst directorySize = numTables * 16;\n\tlet tableOffset = headerSize + directorySize;\n\n\tconst tableOffsets: number[] = [];\n\tfor (const table of tables) {\n\t\ttableOffsets.push(tableOffset);\n\t\ttableOffset += pad4(table.origLength);\n\t}\n\n\t// Build output\n\tconst output = new Uint8Array(tableOffset);\n\n\t// SFNT header\n\tconst searchRange = 2 ** Math.floor(Math.log2(numTables)) * 16;\n\tconst entrySelector = Math.floor(Math.log2(numTables));\n\tconst rangeShift = numTables * 16 - searchRange;\n\n\twriteUint32BE(output, 0, flavor);\n\twriteUint16BE(output, 4, numTables);\n\twriteUint16BE(output, 6, searchRange);\n\twriteUint16BE(output, 8, entrySelector);\n\twriteUint16BE(output, 10, rangeShift);\n\n\t// Table directory and data\n\tlet headOffset = -1;\n\tfor (let i = 0; i < tables.length; i++) {\n\t\tconst table = tables[i];\n\t\tconst tdata = tableData.get(table.tag);\n\t\tif (!tdata) {\n\t\t\tthrow new Error(`Missing table data for ${table.tag}`);\n\t\t}\n\t\tconst dirOffset = headerSize + i * 16;\n\n\t\tconst tableOff = tableOffsets[i];\n\t\tif (table.tag === \"head\" && tableOff !== undefined) {\n\t\t\theadOffset = tableOff;\n\t\t}\n\n\t\t// Tag\n\t\tfor (let j = 0; j < 4; j++) {\n\t\t\toutput[dirOffset + j] = table.tag.charCodeAt(j);\n\t\t}\n\n\t\t// Checksum\n\t\tconst checksum = calcChecksum(tdata, 0, tdata.length);\n\t\twriteUint32BE(output, dirOffset + 4, checksum);\n\n\t\t// Offset\n\t\twriteUint32BE(output, dirOffset + 8, tableOffsets[i]);\n\n\t\t// Length\n\t\twriteUint32BE(output, dirOffset + 12, table.origLength);\n\n\t\t// Copy table data\n\t\toutput.set(tdata.slice(0, table.origLength), tableOffsets[i]);\n\t}\n\n\t// Fix head checksum adjustment\n\tif (headOffset >= 0) {\n\t\tconst totalChecksum = calcChecksum(output, 0, output.length);\n\t\tconst checksumAdjustment = (0xb1b0afba - totalChecksum) >>> 0;\n\t\twriteUint32BE(output, headOffset + 8, checksumAdjustment);\n\t}\n\n\treturn output.buffer;\n}\n",
20
- "import type { int16, uint16 } from \"../../types.ts\";\nimport type { Reader } from \"../binary/reader.ts\";\n\n/**\n * BASE table - Baseline alignment data\n * Provides baseline offsets for scripts to align mixed-script text\n */\n\n/** Baseline tags */\nexport const BaselineTag = {\n\t/** Hanging baseline (Devanagari, Tibetan) */\n\thang: 0x68616e67,\n\t/** Ideographic character face bottom edge (CJK) */\n\ticfb: 0x69636662,\n\t/** Ideographic character face top edge (CJK) */\n\ticft: 0x69636674,\n\t/** Ideographic em-box bottom edge (CJK) */\n\tideo: 0x6964656f,\n\t/** Ideographic em-box top edge */\n\tidtp: 0x69647470,\n\t/** Mathematical baseline (math layout) */\n\tmath: 0x6d617468,\n\t/** Roman baseline (Latin, Greek, Cyrillic) */\n\tromn: 0x726f6d6e,\n} as const;\n\n/** A single baseline value */\nexport interface BaselineValue {\n\tbaselineTag: number;\n\tcoordinate: int16;\n}\n\n/** Min/max extent values */\nexport interface MinMaxRecord {\n\tminCoord: int16 | null;\n\tmaxCoord: int16 | null;\n}\n\n/** Feature-specific min/max values */\nexport interface FeatMinMaxRecord {\n\tfeatureTag: number;\n\tminCoord: int16 | null;\n\tmaxCoord: int16 | null;\n}\n\n/** Base values for a script */\nexport interface BaseValues {\n\tdefaultBaselineIndex: uint16;\n\tbaseCoords: int16[];\n}\n\n/** MinMax values for a language system */\nexport interface MinMax {\n\tminCoord: int16 | null;\n\tmaxCoord: int16 | null;\n\tfeatMinMaxRecords: FeatMinMaxRecord[];\n}\n\n/** Base script record */\nexport interface BaseScriptRecord {\n\tscriptTag: number;\n\tbaseValues: BaseValues | null;\n\tdefaultMinMax: MinMax | null;\n\tbaseLangSysRecords: Map<number, MinMax>;\n}\n\n/** Axis table (horizontal or vertical) */\nexport interface AxisTable {\n\tbaseTagList: number[];\n\tbaseScriptList: BaseScriptRecord[];\n}\n\n/** BASE table */\nexport interface BaseTable {\n\tmajorVersion: uint16;\n\tminorVersion: uint16;\n\thorizAxis: AxisTable | null;\n\tvertAxis: AxisTable | null;\n}\n\n/** Coordinate format */\ninterface BaseCoord {\n\tformat: uint16;\n\tcoordinate: int16;\n\treferenceGlyph?: uint16;\n\tbaseCoordPoint?: uint16;\n\tdeviceOffset?: uint16;\n}\n\nfunction parseBaseCoord(reader: Reader): BaseCoord {\n\tconst format = reader.uint16();\n\tconst coordinate = reader.int16();\n\n\tconst result: BaseCoord = { format, coordinate };\n\n\tif (format === 2) {\n\t\tresult.referenceGlyph = reader.uint16();\n\t\tresult.baseCoordPoint = reader.uint16();\n\t} else if (format === 3) {\n\t\tresult.deviceOffset = reader.uint16();\n\t}\n\n\treturn result;\n}\n\nfunction parseMinMax(reader: Reader, minMaxOffset: number): MinMax | null {\n\tif (minMaxOffset === 0) return null;\n\n\tconst minMaxReader = reader.sliceFrom(minMaxOffset);\n\tconst minCoordOffset = minMaxReader.uint16();\n\tconst maxCoordOffset = minMaxReader.uint16();\n\tconst featMinMaxCount = minMaxReader.uint16();\n\n\tlet minCoord: int16 | null = null;\n\tlet maxCoord: int16 | null = null;\n\n\tif (minCoordOffset !== 0) {\n\t\tconst coordReader = reader.sliceFrom(minMaxOffset + minCoordOffset);\n\t\tminCoord = parseBaseCoord(coordReader).coordinate;\n\t}\n\n\tif (maxCoordOffset !== 0) {\n\t\tconst coordReader = reader.sliceFrom(minMaxOffset + maxCoordOffset);\n\t\tmaxCoord = parseBaseCoord(coordReader).coordinate;\n\t}\n\n\tconst featMinMaxRecords: FeatMinMaxRecord[] = [];\n\tfor (let i = 0; i < featMinMaxCount; i++) {\n\t\tconst featureTag = minMaxReader.uint32();\n\t\tconst minOffset = minMaxReader.uint16();\n\t\tconst maxOffset = minMaxReader.uint16();\n\n\t\tlet featMin: int16 | null = null;\n\t\tlet featMax: int16 | null = null;\n\n\t\tif (minOffset !== 0) {\n\t\t\tconst coordReader = reader.sliceFrom(minMaxOffset + minOffset);\n\t\t\tfeatMin = parseBaseCoord(coordReader).coordinate;\n\t\t}\n\n\t\tif (maxOffset !== 0) {\n\t\t\tconst coordReader = reader.sliceFrom(minMaxOffset + maxOffset);\n\t\t\tfeatMax = parseBaseCoord(coordReader).coordinate;\n\t\t}\n\n\t\tfeatMinMaxRecords.push({\n\t\t\tfeatureTag,\n\t\t\tminCoord: featMin,\n\t\t\tmaxCoord: featMax,\n\t\t});\n\t}\n\n\treturn { minCoord, maxCoord, featMinMaxRecords };\n}\n\nfunction parseBaseValues(\n\treader: Reader,\n\tbaseValuesOffset: number,\n\t_baseTagList: number[],\n): BaseValues | null {\n\tif (baseValuesOffset === 0) return null;\n\n\tconst bvReader = reader.sliceFrom(baseValuesOffset);\n\tconst defaultBaselineIndex = bvReader.uint16();\n\tconst baseCoordCount = bvReader.uint16();\n\n\tconst coordOffsets: uint16[] = [];\n\tfor (let i = 0; i < baseCoordCount; i++) {\n\t\tcoordOffsets.push(bvReader.uint16());\n\t}\n\n\tconst baseCoords: int16[] = [];\n\tfor (const offset of coordOffsets) {\n\t\tif (offset !== 0) {\n\t\t\tconst coordReader = reader.sliceFrom(baseValuesOffset + offset);\n\t\t\tbaseCoords.push(parseBaseCoord(coordReader).coordinate);\n\t\t} else {\n\t\t\tbaseCoords.push(0);\n\t\t}\n\t}\n\n\treturn { defaultBaselineIndex, baseCoords };\n}\n\nfunction parseBaseScriptRecord(\n\treader: Reader,\n\tscriptOffset: number,\n\tbaseTagList: number[],\n): Omit<BaseScriptRecord, \"scriptTag\"> {\n\tconst scriptReader = reader.sliceFrom(scriptOffset);\n\tconst baseValuesOffset = scriptReader.uint16();\n\tconst defaultMinMaxOffset = scriptReader.uint16();\n\tconst baseLangSysCount = scriptReader.uint16();\n\n\tconst baseLangSysRecords = new Map<number, MinMax>();\n\tconst langSysData: Array<{ tag: number; offset: number }> = [];\n\n\tfor (let i = 0; i < baseLangSysCount; i++) {\n\t\tconst tag = scriptReader.uint32();\n\t\tconst offset = scriptReader.uint16();\n\t\tlangSysData.push({ tag, offset });\n\t}\n\n\tconst baseValues = parseBaseValues(\n\t\treader,\n\t\tscriptOffset + baseValuesOffset,\n\t\tbaseTagList,\n\t);\n\tconst defaultMinMax = parseMinMax(reader, scriptOffset + defaultMinMaxOffset);\n\n\tfor (const { tag, offset } of langSysData) {\n\t\tconst minMax = parseMinMax(reader, scriptOffset + offset);\n\t\tif (minMax) {\n\t\t\tbaseLangSysRecords.set(tag, minMax);\n\t\t}\n\t}\n\n\treturn { baseValues, defaultMinMax, baseLangSysRecords };\n}\n\nfunction parseAxisTable(reader: Reader, axisOffset: number): AxisTable | null {\n\tif (axisOffset === 0) return null;\n\n\tconst axisReader = reader.sliceFrom(axisOffset);\n\tconst baseTagListOffset = axisReader.uint16();\n\tconst baseScriptListOffset = axisReader.uint16();\n\n\t// Parse base tag list\n\tconst baseTagList: number[] = [];\n\tif (baseTagListOffset !== 0) {\n\t\tconst tagReader = reader.sliceFrom(axisOffset + baseTagListOffset);\n\t\tconst baseTagCount = tagReader.uint16();\n\t\tfor (let i = 0; i < baseTagCount; i++) {\n\t\t\tbaseTagList.push(tagReader.uint32());\n\t\t}\n\t}\n\n\t// Parse base script list\n\tconst baseScriptList: BaseScriptRecord[] = [];\n\tif (baseScriptListOffset !== 0) {\n\t\tconst scriptListReader = reader.sliceFrom(\n\t\t\taxisOffset + baseScriptListOffset,\n\t\t);\n\t\tconst baseScriptCount = scriptListReader.uint16();\n\n\t\tconst scriptData: Array<{ tag: number; offset: number }> = [];\n\t\tfor (let i = 0; i < baseScriptCount; i++) {\n\t\t\tconst tag = scriptListReader.uint32();\n\t\t\tconst offset = scriptListReader.uint16();\n\t\t\tscriptData.push({ tag, offset });\n\t\t}\n\n\t\tfor (const { tag, offset } of scriptData) {\n\t\t\tconst record = parseBaseScriptRecord(\n\t\t\t\treader,\n\t\t\t\taxisOffset + baseScriptListOffset + offset,\n\t\t\t\tbaseTagList,\n\t\t\t);\n\t\t\tbaseScriptList.push({ scriptTag: tag, ...record });\n\t\t}\n\t}\n\n\treturn { baseTagList, baseScriptList };\n}\n\nexport function parseBase(reader: Reader): BaseTable {\n\tconst majorVersion = reader.uint16();\n\tconst minorVersion = reader.uint16();\n\tconst horizAxisOffset = reader.uint16();\n\tconst vertAxisOffset = reader.uint16();\n\n\tconst horizAxis = parseAxisTable(reader, horizAxisOffset);\n\tconst vertAxis = parseAxisTable(reader, vertAxisOffset);\n\n\treturn {\n\t\tmajorVersion,\n\t\tminorVersion,\n\t\thorizAxis,\n\t\tvertAxis,\n\t};\n}\n\n/** Get baseline value for a script */\nexport function getBaselineForScript(\n\tbase: BaseTable,\n\tscriptTag: number,\n\tbaselineTag: number,\n\thorizontal: boolean = true,\n): int16 | null {\n\tconst axis = horizontal ? base.horizAxis : base.vertAxis;\n\tif (!axis) return null;\n\n\t// Find script record\n\tconst scriptRecord = axis.baseScriptList.find(\n\t\t(r) => r.scriptTag === scriptTag,\n\t);\n\tif (!scriptRecord?.baseValues) return null;\n\n\t// Find baseline tag index\n\tconst tagIndex = axis.baseTagList.indexOf(baselineTag);\n\tif (tagIndex === -1) return null;\n\n\treturn scriptRecord.baseValues.baseCoords[tagIndex] ?? null;\n}\n\n/** Get default baseline for a script */\nexport function getDefaultBaseline(\n\tbase: BaseTable,\n\tscriptTag: number,\n\thorizontal: boolean = true,\n): { tag: number; coordinate: int16 } | null {\n\tconst axis = horizontal ? base.horizAxis : base.vertAxis;\n\tif (!axis) return null;\n\n\tconst scriptRecord = axis.baseScriptList.find(\n\t\t(r) => r.scriptTag === scriptTag,\n\t);\n\tif (!scriptRecord?.baseValues) return null;\n\n\tconst index = scriptRecord.baseValues.defaultBaselineIndex;\n\tconst tag = axis.baseTagList[index];\n\tconst coordinate = scriptRecord.baseValues.baseCoords[index];\n\n\tif (tag === undefined || coordinate === undefined) return null;\n\n\treturn { tag, coordinate };\n}\n\n/** Get min/max extent for a script/language */\nexport function getMinMaxExtent(\n\tbase: BaseTable,\n\tscriptTag: number,\n\tlanguageTag?: number,\n\thorizontal: boolean = true,\n): MinMaxRecord | null {\n\tconst axis = horizontal ? base.horizAxis : base.vertAxis;\n\tif (!axis) return null;\n\n\tconst scriptRecord = axis.baseScriptList.find(\n\t\t(r) => r.scriptTag === scriptTag,\n\t);\n\tif (!scriptRecord) return null;\n\n\t// Try language-specific first\n\tif (languageTag !== undefined) {\n\t\tconst langMinMax = scriptRecord.baseLangSysRecords.get(languageTag);\n\t\tif (langMinMax) {\n\t\t\treturn { minCoord: langMinMax.minCoord, maxCoord: langMinMax.maxCoord };\n\t\t}\n\t}\n\n\t// Fall back to default\n\tif (scriptRecord.defaultMinMax) {\n\t\treturn {\n\t\t\tminCoord: scriptRecord.defaultMinMax.minCoord,\n\t\t\tmaxCoord: scriptRecord.defaultMinMax.maxCoord,\n\t\t};\n\t}\n\n\treturn null;\n}\n",
21
- "import type { GlyphId, int8, uint8, uint16, uint32 } from \"../../types.ts\";\nimport type { Reader } from \"../binary/reader.ts\";\n\n/**\n * Color Bitmap Data Table (CBDT)\n * Google's color bitmap table for emoji fonts\n * Used together with CBLC (Color Bitmap Location Table)\n */\nexport interface CbdtTable {\n\tmajorVersion: uint16;\n\tminorVersion: uint16;\n\t/** Raw data for bitmap lookup */\n\tdata: Uint8Array;\n}\n\n/**\n * Color Bitmap Location Table (CBLC)\n * Index for looking up bitmaps in CBDT\n */\nexport interface CblcTable {\n\tmajorVersion: uint16;\n\tminorVersion: uint16;\n\tbitmapSizes: BitmapSize[];\n}\n\n/**\n * Bitmap size record\n */\nexport interface BitmapSize {\n\tindexSubTableArrayOffset: uint32;\n\tindexTablesSize: uint32;\n\tnumberOfIndexSubTables: uint32;\n\tcolorRef: uint32;\n\thori: SbitLineMetrics;\n\tvert: SbitLineMetrics;\n\tstartGlyphIndex: GlyphId;\n\tendGlyphIndex: GlyphId;\n\tppemX: uint8;\n\tppemY: uint8;\n\tbitDepth: uint8;\n\tflags: int8;\n\tindexSubTables: IndexSubTable[];\n}\n\n/**\n * Line metrics for bitmap glyphs\n */\nexport interface SbitLineMetrics {\n\tascender: int8;\n\tdescender: int8;\n\twidthMax: uint8;\n\tcaretSlopeNumerator: int8;\n\tcaretSlopeDenominator: int8;\n\tcaretOffset: int8;\n\tminOriginSB: int8;\n\tminAdvanceSB: int8;\n\tmaxBeforeBL: int8;\n\tminAfterBL: int8;\n\tpad1: int8;\n\tpad2: int8;\n}\n\n/**\n * Index sub-table for glyph lookup\n */\nexport interface IndexSubTable {\n\tfirstGlyphIndex: GlyphId;\n\tlastGlyphIndex: GlyphId;\n\tindexFormat: uint16;\n\timageFormat: uint16;\n\timageDataOffset: uint32;\n\t/** Glyph offsets (format-dependent) */\n\tglyphOffsets: Map<GlyphId, { offset: uint32; length: uint32 }>;\n}\n\n/**\n * Bitmap glyph metrics\n */\nexport interface GlyphBitmapMetrics {\n\theight: uint8;\n\twidth: uint8;\n\tbearingX: int8;\n\tbearingY: int8;\n\tadvance: uint8;\n}\n\n/**\n * Bitmap glyph data\n */\nexport interface BitmapGlyph {\n\tmetrics: GlyphBitmapMetrics;\n\timageFormat: uint16;\n\tdata: Uint8Array;\n}\n\n/**\n * Image formats in CBDT\n */\nexport const CbdtImageFormat = {\n\tSmallMetrics: 1, // Small metrics, byte-aligned\n\tSmallMetricsPng: 17, // Small metrics + PNG\n\tBigMetrics: 2, // Big metrics, byte-aligned\n\tBigMetricsPng: 18, // Big metrics + PNG\n\tCompressedPng: 19, // Metrics in CBLC + PNG\n} as const;\n\n/**\n * Parse CBLC table\n */\nexport function parseCblc(reader: Reader): CblcTable {\n\tconst tableStart = reader.offset;\n\tconst majorVersion = reader.uint16();\n\tconst minorVersion = reader.uint16();\n\tconst numSizes = reader.uint32();\n\n\tconst bitmapSizes: BitmapSize[] = [];\n\n\t// Read BitmapSize records\n\tfor (let i = 0; i < numSizes; i++) {\n\t\tconst indexSubTableArrayOffset = reader.uint32();\n\t\tconst indexTablesSize = reader.uint32();\n\t\tconst numberOfIndexSubTables = reader.uint32();\n\t\tconst colorRef = reader.uint32();\n\n\t\tconst hori = parseSbitLineMetrics(reader);\n\t\tconst vert = parseSbitLineMetrics(reader);\n\n\t\tconst startGlyphIndex = reader.uint16();\n\t\tconst endGlyphIndex = reader.uint16();\n\t\tconst ppemX = reader.uint8();\n\t\tconst ppemY = reader.uint8();\n\t\tconst bitDepth = reader.uint8();\n\t\tconst flags = reader.int8();\n\n\t\tbitmapSizes.push({\n\t\t\tindexSubTableArrayOffset,\n\t\t\tindexTablesSize,\n\t\t\tnumberOfIndexSubTables,\n\t\t\tcolorRef,\n\t\t\thori,\n\t\t\tvert,\n\t\t\tstartGlyphIndex,\n\t\t\tendGlyphIndex,\n\t\t\tppemX,\n\t\t\tppemY,\n\t\t\tbitDepth,\n\t\t\tflags,\n\t\t\tindexSubTables: [],\n\t\t});\n\t}\n\n\t// Parse index sub-tables for each bitmap size\n\tfor (const size of bitmapSizes) {\n\t\tconst subTableReader = reader.sliceFrom(\n\t\t\ttableStart + size.indexSubTableArrayOffset,\n\t\t);\n\n\t\t// Read IndexSubTableArray\n\t\tconst subTableHeaders: {\n\t\t\tfirstGlyphIndex: uint16;\n\t\t\tlastGlyphIndex: uint16;\n\t\t\tadditionalOffsetToIndexSubtable: uint32;\n\t\t}[] = [];\n\n\t\tfor (let i = 0; i < size.numberOfIndexSubTables; i++) {\n\t\t\tsubTableHeaders.push({\n\t\t\t\tfirstGlyphIndex: subTableReader.uint16(),\n\t\t\t\tlastGlyphIndex: subTableReader.uint16(),\n\t\t\t\tadditionalOffsetToIndexSubtable: subTableReader.uint32(),\n\t\t\t});\n\t\t}\n\n\t\t// Parse each index sub-table\n\t\tfor (const header of subTableHeaders) {\n\t\t\tconst indexSubTable = parseIndexSubTable(\n\t\t\t\treader,\n\t\t\t\ttableStart +\n\t\t\t\t\tsize.indexSubTableArrayOffset +\n\t\t\t\t\theader.additionalOffsetToIndexSubtable,\n\t\t\t\theader.firstGlyphIndex,\n\t\t\t\theader.lastGlyphIndex,\n\t\t\t);\n\t\t\tsize.indexSubTables.push(indexSubTable);\n\t\t}\n\t}\n\n\treturn { majorVersion, minorVersion, bitmapSizes };\n}\n\nfunction parseSbitLineMetrics(reader: Reader): SbitLineMetrics {\n\treturn {\n\t\tascender: reader.int8(),\n\t\tdescender: reader.int8(),\n\t\twidthMax: reader.uint8(),\n\t\tcaretSlopeNumerator: reader.int8(),\n\t\tcaretSlopeDenominator: reader.int8(),\n\t\tcaretOffset: reader.int8(),\n\t\tminOriginSB: reader.int8(),\n\t\tminAdvanceSB: reader.int8(),\n\t\tmaxBeforeBL: reader.int8(),\n\t\tminAfterBL: reader.int8(),\n\t\tpad1: reader.int8(),\n\t\tpad2: reader.int8(),\n\t};\n}\n\nfunction parseIndexSubTable(\n\treader: Reader,\n\toffset: number,\n\tfirstGlyph: GlyphId,\n\tlastGlyph: GlyphId,\n): IndexSubTable {\n\tconst subReader = reader.sliceFrom(offset);\n\tconst indexFormat = subReader.uint16();\n\tconst imageFormat = subReader.uint16();\n\tconst imageDataOffset = subReader.uint32();\n\n\tconst glyphOffsets = new Map<GlyphId, { offset: uint32; length: uint32 }>();\n\tconst numGlyphs = lastGlyph - firstGlyph + 1;\n\n\tswitch (indexFormat) {\n\t\tcase 1: {\n\t\t\t// Variable metrics, 4-byte offsets\n\t\t\tconst offsets: uint32[] = [];\n\t\t\tfor (let i = 0; i <= numGlyphs; i++) {\n\t\t\t\toffsets.push(subReader.uint32());\n\t\t\t}\n\t\t\tfor (let i = 0; i < numGlyphs; i++) {\n\t\t\t\tconst glyphOffset = offsets[i];\n\t\t\t\tconst nextOffset = offsets[i + 1];\n\t\t\t\tif (glyphOffset === undefined || nextOffset === undefined) continue;\n\t\t\t\tif (nextOffset > glyphOffset) {\n\t\t\t\t\tglyphOffsets.set(firstGlyph + i, {\n\t\t\t\t\t\toffset: imageDataOffset + glyphOffset,\n\t\t\t\t\t\tlength: nextOffset - glyphOffset,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase 2: {\n\t\t\t// Constant image size\n\t\t\tconst imageSize = subReader.uint32();\n\t\t\t// Big metrics follow\n\t\t\tconst _bigMetrics = {\n\t\t\t\theight: subReader.uint8(),\n\t\t\t\twidth: subReader.uint8(),\n\t\t\t\thoriBearingX: subReader.int8(),\n\t\t\t\thoriBearingY: subReader.int8(),\n\t\t\t\thoriAdvance: subReader.uint8(),\n\t\t\t\tvertBearingX: subReader.int8(),\n\t\t\t\tvertBearingY: subReader.int8(),\n\t\t\t\tvertAdvance: subReader.uint8(),\n\t\t\t};\n\t\t\tfor (let i = 0; i < numGlyphs; i++) {\n\t\t\t\tglyphOffsets.set(firstGlyph + i, {\n\t\t\t\t\toffset: imageDataOffset + i * imageSize,\n\t\t\t\t\tlength: imageSize,\n\t\t\t\t});\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase 3: {\n\t\t\t// Variable metrics, 2-byte offsets\n\t\t\tconst offsets: uint16[] = [];\n\t\t\tfor (let i = 0; i <= numGlyphs; i++) {\n\t\t\t\toffsets.push(subReader.uint16());\n\t\t\t}\n\t\t\tfor (let i = 0; i < numGlyphs; i++) {\n\t\t\t\tconst glyphOffset = offsets[i];\n\t\t\t\tconst nextOffset = offsets[i + 1];\n\t\t\t\tif (glyphOffset === undefined || nextOffset === undefined) continue;\n\t\t\t\tif (nextOffset > glyphOffset) {\n\t\t\t\t\tglyphOffsets.set(firstGlyph + i, {\n\t\t\t\t\t\toffset: imageDataOffset + glyphOffset,\n\t\t\t\t\t\tlength: nextOffset - glyphOffset,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase 4: {\n\t\t\t// Sparse glyph array\n\t\t\tconst numGlyphsActual = subReader.uint32();\n\t\t\tconst glyphArray: { glyphId: uint16; offset: uint16 }[] = [];\n\t\t\tfor (let i = 0; i <= numGlyphsActual; i++) {\n\t\t\t\tglyphArray.push({\n\t\t\t\t\tglyphId: subReader.uint16(),\n\t\t\t\t\toffset: subReader.uint16(),\n\t\t\t\t});\n\t\t\t}\n\t\t\tfor (let i = 0; i < numGlyphsActual; i++) {\n\t\t\t\tconst entry = glyphArray[i];\n\t\t\t\tconst nextEntry = glyphArray[i + 1];\n\t\t\t\tif (entry === undefined || nextEntry === undefined) continue;\n\t\t\t\tglyphOffsets.set(entry.glyphId, {\n\t\t\t\t\toffset: imageDataOffset + entry.offset,\n\t\t\t\t\tlength: nextEntry.offset - entry.offset,\n\t\t\t\t});\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase 5: {\n\t\t\t// Constant metrics, sparse glyph array\n\t\t\tconst imageSize = subReader.uint32();\n\t\t\t// Big metrics\n\t\t\tsubReader.skip(8);\n\t\t\tconst numGlyphsActual = subReader.uint32();\n\t\t\tfor (let i = 0; i < numGlyphsActual; i++) {\n\t\t\t\tconst glyphId = subReader.uint16();\n\t\t\t\tglyphOffsets.set(glyphId, {\n\t\t\t\t\toffset: imageDataOffset + i * imageSize,\n\t\t\t\t\tlength: imageSize,\n\t\t\t\t});\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn {\n\t\tfirstGlyphIndex: firstGlyph,\n\t\tlastGlyphIndex: lastGlyph,\n\t\tindexFormat,\n\t\timageFormat,\n\t\timageDataOffset,\n\t\tglyphOffsets,\n\t};\n}\n\n/**\n * Parse CBDT table\n */\nexport function parseCbdt(reader: Reader): CbdtTable {\n\tconst majorVersion = reader.uint16();\n\tconst minorVersion = reader.uint16();\n\n\t// Store raw data for later lookup\n\tconst data = reader.bytes(reader.remaining);\n\n\treturn { majorVersion, minorVersion, data };\n}\n\n/**\n * Get bitmap glyph from CBDT using CBLC index\n */\nexport function getBitmapGlyph(\n\tcblc: CblcTable,\n\tcbdt: CbdtTable,\n\tglyphId: GlyphId,\n\tppem: number,\n): BitmapGlyph | null {\n\t// Find matching bitmap size\n\tlet bestSize: BitmapSize | null = null;\n\tlet bestDiff = Infinity;\n\n\tfor (const size of cblc.bitmapSizes) {\n\t\tif (glyphId < size.startGlyphIndex || glyphId > size.endGlyphIndex) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst diff = Math.abs(size.ppemX - ppem);\n\t\tif (diff < bestDiff) {\n\t\t\tbestDiff = diff;\n\t\t\tbestSize = size;\n\t\t}\n\t}\n\n\tif (!bestSize) return null;\n\n\t// Find glyph in index sub-tables\n\tfor (const subTable of bestSize.indexSubTables) {\n\t\tconst glyphInfo = subTable.glyphOffsets.get(glyphId);\n\t\tif (!glyphInfo) continue;\n\n\t\t// Read glyph data from CBDT\n\t\tconst glyphData = cbdt.data.slice(\n\t\t\tglyphInfo.offset - 4, // Adjust for CBDT header\n\t\t\tglyphInfo.offset - 4 + glyphInfo.length,\n\t\t);\n\n\t\treturn parseGlyphData(glyphData, subTable.imageFormat);\n\t}\n\n\treturn null;\n}\n\nfunction parseGlyphData(\n\tdata: Uint8Array,\n\timageFormat: uint16,\n): BitmapGlyph | null {\n\tif (data.length === 0) return null;\n\n\tlet offset = 0;\n\tlet metrics: GlyphBitmapMetrics;\n\n\tswitch (imageFormat) {\n\t\tcase 1:\n\t\tcase 2:\n\t\tcase 17:\n\t\tcase 18: {\n\t\t\t// Small or big metrics embedded\n\t\t\tif (imageFormat === 1 || imageFormat === 17) {\n\t\t\t\t// Small metrics (5 bytes)\n\t\t\t\tif (offset + 5 > data.length) return null;\n\t\t\t\tmetrics = {\n\t\t\t\t\theight: data[offset++] ?? 0,\n\t\t\t\t\twidth: data[offset++] ?? 0,\n\t\t\t\t\tbearingX: ((data[offset++] ?? 0) << 24) >> 24, // Sign extend\n\t\t\t\t\tbearingY: ((data[offset++] ?? 0) << 24) >> 24,\n\t\t\t\t\tadvance: data[offset++] ?? 0,\n\t\t\t\t};\n\t\t\t} else {\n\t\t\t\t// Big metrics (8 bytes)\n\t\t\t\tif (offset + 8 > data.length) return null;\n\t\t\t\tmetrics = {\n\t\t\t\t\theight: data[offset++] ?? 0,\n\t\t\t\t\twidth: data[offset++] ?? 0,\n\t\t\t\t\tbearingX: ((data[offset++] ?? 0) << 24) >> 24,\n\t\t\t\t\tbearingY: ((data[offset++] ?? 0) << 24) >> 24,\n\t\t\t\t\tadvance: data[offset++] ?? 0,\n\t\t\t\t};\n\t\t\t\toffset += 3; // Skip vertical metrics\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase 19: {\n\t\t\t// Metrics in CBLC, just PNG data\n\t\t\tmetrics = { height: 0, width: 0, bearingX: 0, bearingY: 0, advance: 0 };\n\t\t\tbreak;\n\t\t}\n\t\tdefault:\n\t\t\treturn null;\n\t}\n\n\treturn {\n\t\tmetrics,\n\t\timageFormat,\n\t\tdata: data.slice(offset),\n\t};\n}\n\n/**\n * Check if glyph has color bitmap\n */\nexport function hasColorBitmap(\n\tcblc: CblcTable,\n\tglyphId: GlyphId,\n\tppem?: number,\n): boolean {\n\tfor (const size of cblc.bitmapSizes) {\n\t\tif (ppem !== undefined && size.ppemX !== ppem) continue;\n\t\tif (glyphId < size.startGlyphIndex || glyphId > size.endGlyphIndex) {\n\t\t\tcontinue;\n\t\t}\n\t\tfor (const subTable of size.indexSubTables) {\n\t\t\tif (subTable.glyphOffsets.has(glyphId)) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t}\n\treturn false;\n}\n\n/**\n * Get available ppem sizes for color bitmaps\n */\nexport function getColorBitmapSizes(cblc: CblcTable): number[] {\n\tconst sizes = new Set<number>();\n\tfor (const size of cblc.bitmapSizes) {\n\t\tsizes.add(size.ppemX);\n\t}\n\treturn Array.from(sizes).sort((a, b) => a - b);\n}\n",
22
- "import { Reader } from \"../binary/reader.ts\";\n\n/**\n * CFF (Compact Font Format) table parser\n * Used by OpenType fonts with PostScript outlines\n */\n\nexport interface CffTable {\n\tversion: { major: number; minor: number };\n\tnames: string[];\n\ttopDicts: TopDict[];\n\tstrings: string[];\n\tglobalSubrs: Uint8Array[];\n\tcharStrings: Uint8Array[][];\n\tlocalSubrs: Uint8Array[][];\n\tfdArrays: FDDict[][];\n\tfdSelects: FDSelect[];\n}\n\nexport interface TopDict {\n\tversion?: string;\n\tnotice?: string;\n\tcopyright?: string;\n\tfullName?: string;\n\tfamilyName?: string;\n\tweight?: string;\n\tisFixedPitch?: boolean;\n\titalicAngle?: number;\n\tunderlinePosition?: number;\n\tunderlineThickness?: number;\n\tpaintType?: number;\n\tcharstringType?: number;\n\tfontMatrix?: number[];\n\tuniqueID?: number;\n\tfontBBox?: number[];\n\tstrokeWidth?: number;\n\tcharset?: number;\n\tencoding?: number;\n\tcharStrings?: number;\n\tprivate?: [number, number]; // [size, offset]\n\tsyntheticBase?: number;\n\tpostScript?: string;\n\tbaseFontName?: string;\n\tbaseFontBlend?: number[];\n\t// CIDFont-specific\n\tros?: { registry: string; ordering: string; supplement: number };\n\tcidFontVersion?: number;\n\tcidFontRevision?: number;\n\tcidFontType?: number;\n\tcidCount?: number;\n\tuidBase?: number;\n\tfdArray?: number;\n\tfdSelect?: number;\n\tfontName?: string;\n}\n\nexport interface PrivateDict {\n\tblueValues?: number[];\n\totherBlues?: number[];\n\tfamilyBlues?: number[];\n\tfamilyOtherBlues?: number[];\n\tblueScale?: number;\n\tblueShift?: number;\n\tblueFuzz?: number;\n\tstdHW?: number;\n\tstdVW?: number;\n\tstemSnapH?: number[];\n\tstemSnapV?: number[];\n\tforceBold?: boolean;\n\tlanguageGroup?: number;\n\texpansionFactor?: number;\n\tinitialRandomSeed?: number;\n\tsubrs?: number;\n\tdefaultWidthX?: number;\n\tnominalWidthX?: number;\n}\n\nexport interface FDDict extends PrivateDict {\n\tfontName?: string;\n\t/** Private dict offset and size [size, offset] */\n\tprivate?: [number, number];\n\t/** Local subroutines for this FD (parsed from private dict subrs offset) */\n\tlocalSubrs?: Uint8Array[];\n}\n\nexport interface FDSelect {\n\tformat: number;\n\tselect: (glyphId: number) => number;\n}\n\n// Standard strings defined in CFF spec\nconst STANDARD_STRINGS = [\n\t\".notdef\",\n\t\"space\",\n\t\"exclam\",\n\t\"quotedbl\",\n\t\"numbersign\",\n\t\"dollar\",\n\t\"percent\",\n\t\"ampersand\",\n\t\"quoteright\",\n\t\"parenleft\",\n\t\"parenright\",\n\t\"asterisk\",\n\t\"plus\",\n\t\"comma\",\n\t\"hyphen\",\n\t\"period\",\n\t\"slash\",\n\t\"zero\",\n\t\"one\",\n\t\"two\",\n\t\"three\",\n\t\"four\",\n\t\"five\",\n\t\"six\",\n\t\"seven\",\n\t\"eight\",\n\t\"nine\",\n\t\"colon\",\n\t\"semicolon\",\n\t\"less\",\n\t\"equal\",\n\t\"greater\",\n\t\"question\",\n\t\"at\",\n\t\"A\",\n\t\"B\",\n\t\"C\",\n\t\"D\",\n\t\"E\",\n\t\"F\",\n\t\"G\",\n\t\"H\",\n\t\"I\",\n\t\"J\",\n\t\"K\",\n\t\"L\",\n\t\"M\",\n\t\"N\",\n\t\"O\",\n\t\"P\",\n\t\"Q\",\n\t\"R\",\n\t\"S\",\n\t\"T\",\n\t\"U\",\n\t\"V\",\n\t\"W\",\n\t\"X\",\n\t\"Y\",\n\t\"Z\",\n\t\"bracketleft\",\n\t\"backslash\",\n\t\"bracketright\",\n\t\"asciicircum\",\n\t\"underscore\",\n\t\"quoteleft\",\n\t\"a\",\n\t\"b\",\n\t\"c\",\n\t\"d\",\n\t\"e\",\n\t\"f\",\n\t\"g\",\n\t\"h\",\n\t\"i\",\n\t\"j\",\n\t\"k\",\n\t\"l\",\n\t\"m\",\n\t\"n\",\n\t\"o\",\n\t\"p\",\n\t\"q\",\n\t\"r\",\n\t\"s\",\n\t\"t\",\n\t\"u\",\n\t\"v\",\n\t\"w\",\n\t\"x\",\n\t\"y\",\n\t\"z\",\n\t\"braceleft\",\n\t\"bar\",\n\t\"braceright\",\n\t\"asciitilde\",\n\t\"exclamdown\",\n\t\"cent\",\n\t\"sterling\",\n\t\"fraction\",\n\t\"yen\",\n\t\"florin\",\n\t\"section\",\n\t\"currency\",\n\t\"quotesingle\",\n\t\"quotedblleft\",\n\t\"guillemotleft\",\n\t\"guilsinglleft\",\n\t\"guilsinglright\",\n\t\"fi\",\n\t\"fl\",\n\t\"endash\",\n\t\"dagger\",\n\t\"daggerdbl\",\n\t\"periodcentered\",\n\t\"paragraph\",\n\t\"bullet\",\n\t\"quotesinglbase\",\n\t\"quotedblbase\",\n\t\"quotedblright\",\n\t\"guillemotright\",\n\t\"ellipsis\",\n\t\"perthousand\",\n\t\"questiondown\",\n\t\"grave\",\n\t\"acute\",\n\t\"circumflex\",\n\t\"tilde\",\n\t\"macron\",\n\t\"breve\",\n\t\"dotaccent\",\n\t\"dieresis\",\n\t\"ring\",\n\t\"cedilla\",\n\t\"hungarumlaut\",\n\t\"ogonek\",\n\t\"caron\",\n\t\"emdash\",\n\t\"AE\",\n\t\"ordfeminine\",\n\t\"Lslash\",\n\t\"Oslash\",\n\t\"OE\",\n\t\"ordmasculine\",\n\t\"ae\",\n\t\"dotlessi\",\n\t\"lslash\",\n\t\"oslash\",\n\t\"oe\",\n\t\"germandbls\",\n\t\"onesuperior\",\n\t\"logicalnot\",\n\t\"mu\",\n\t\"trademark\",\n\t\"Eth\",\n\t\"onehalf\",\n\t\"plusminus\",\n\t\"Thorn\",\n\t\"onequarter\",\n\t\"divide\",\n\t\"brokenbar\",\n\t\"degree\",\n\t\"thorn\",\n\t\"threequarters\",\n\t\"twosuperior\",\n\t\"registered\",\n\t\"minus\",\n\t\"eth\",\n\t\"multiply\",\n\t\"threesuperior\",\n\t\"copyright\",\n\t\"Aacute\",\n\t\"Acircumflex\",\n\t\"Adieresis\",\n\t\"Agrave\",\n\t\"Aring\",\n\t\"Atilde\",\n\t\"Ccedilla\",\n\t\"Eacute\",\n\t\"Ecircumflex\",\n\t\"Edieresis\",\n\t\"Egrave\",\n\t\"Iacute\",\n\t\"Icircumflex\",\n\t\"Idieresis\",\n\t\"Igrave\",\n\t\"Ntilde\",\n\t\"Oacute\",\n\t\"Ocircumflex\",\n\t\"Odieresis\",\n\t\"Ograve\",\n\t\"Otilde\",\n\t\"Scaron\",\n\t\"Uacute\",\n\t\"Ucircumflex\",\n\t\"Udieresis\",\n\t\"Ugrave\",\n\t\"Yacute\",\n\t\"Ydieresis\",\n\t\"Zcaron\",\n\t\"aacute\",\n\t\"acircumflex\",\n\t\"adieresis\",\n\t\"agrave\",\n\t\"aring\",\n\t\"atilde\",\n\t\"ccedilla\",\n\t\"eacute\",\n\t\"ecircumflex\",\n\t\"edieresis\",\n\t\"egrave\",\n\t\"iacute\",\n\t\"icircumflex\",\n\t\"idieresis\",\n\t\"igrave\",\n\t\"ntilde\",\n\t\"oacute\",\n\t\"ocircumflex\",\n\t\"odieresis\",\n\t\"ograve\",\n\t\"otilde\",\n\t\"scaron\",\n\t\"uacute\",\n\t\"ucircumflex\",\n\t\"udieresis\",\n\t\"ugrave\",\n\t\"yacute\",\n\t\"ydieresis\",\n\t\"zcaron\",\n\t\"exclamsmall\",\n\t\"Hungarumlautsmall\",\n\t\"dollaroldstyle\",\n\t\"dollarsuperior\",\n\t\"ampersandsmall\",\n\t\"Acutesmall\",\n\t\"parenleftsuperior\",\n\t\"parenrightsuperior\",\n\t\"twodotenleader\",\n\t\"onedotenleader\",\n\t\"zerooldstyle\",\n\t\"oneoldstyle\",\n\t\"twooldstyle\",\n\t\"threeoldstyle\",\n\t\"fouroldstyle\",\n\t\"fiveoldstyle\",\n\t\"sixoldstyle\",\n\t\"sevenoldstyle\",\n\t\"eightoldstyle\",\n\t\"nineoldstyle\",\n\t\"commasuperior\",\n\t\"threequartersemdash\",\n\t\"periodsuperior\",\n\t\"questionsmall\",\n\t\"asuperior\",\n\t\"bsuperior\",\n\t\"centsuperior\",\n\t\"dsuperior\",\n\t\"esuperior\",\n\t\"isuperior\",\n\t\"lsuperior\",\n\t\"msuperior\",\n\t\"nsuperior\",\n\t\"osuperior\",\n\t\"rsuperior\",\n\t\"ssuperior\",\n\t\"tsuperior\",\n\t\"ff\",\n\t\"ffi\",\n\t\"ffl\",\n\t\"parenleftinferior\",\n\t\"parenrightinferior\",\n\t\"Circumflexsmall\",\n\t\"hyphensuperior\",\n\t\"Gravesmall\",\n\t\"Asmall\",\n\t\"Bsmall\",\n\t\"Csmall\",\n\t\"Dsmall\",\n\t\"Esmall\",\n\t\"Fsmall\",\n\t\"Gsmall\",\n\t\"Hsmall\",\n\t\"Ismall\",\n\t\"Jsmall\",\n\t\"Ksmall\",\n\t\"Lsmall\",\n\t\"Msmall\",\n\t\"Nsmall\",\n\t\"Osmall\",\n\t\"Psmall\",\n\t\"Qsmall\",\n\t\"Rsmall\",\n\t\"Ssmall\",\n\t\"Tsmall\",\n\t\"Usmall\",\n\t\"Vsmall\",\n\t\"Wsmall\",\n\t\"Xsmall\",\n\t\"Ysmall\",\n\t\"Zsmall\",\n\t\"colonmonetary\",\n\t\"onefitted\",\n\t\"rupiah\",\n\t\"Tildesmall\",\n\t\"exclamdownsmall\",\n\t\"centoldstyle\",\n\t\"Lslashsmall\",\n\t\"Scaronsmall\",\n\t\"Zcaronsmall\",\n\t\"Dieresissmall\",\n\t\"Brevesmall\",\n\t\"Caronsmall\",\n\t\"Dotaccentsmall\",\n\t\"Macronsmall\",\n\t\"figuredash\",\n\t\"hypheninferior\",\n\t\"Ogoneksmall\",\n\t\"Ringsmall\",\n\t\"Cedillasmall\",\n\t\"questiondownsmall\",\n\t\"oneeighth\",\n\t\"threeeighths\",\n\t\"fiveeighths\",\n\t\"seveneighths\",\n\t\"onethird\",\n\t\"twothirds\",\n\t\"zerosuperior\",\n\t\"foursuperior\",\n\t\"fivesuperior\",\n\t\"sixsuperior\",\n\t\"sevensuperior\",\n\t\"eightsuperior\",\n\t\"ninesuperior\",\n\t\"zeroinferior\",\n\t\"oneinferior\",\n\t\"twoinferior\",\n\t\"threeinferior\",\n\t\"fourinferior\",\n\t\"fiveinferior\",\n\t\"sixinferior\",\n\t\"seveninferior\",\n\t\"eightinferior\",\n\t\"nineinferior\",\n\t\"centinferior\",\n\t\"dollarinferior\",\n\t\"periodinferior\",\n\t\"commainferior\",\n\t\"Agravesmall\",\n\t\"Aacutesmall\",\n\t\"Acircumflexsmall\",\n\t\"Atildesmall\",\n\t\"Adieresissmall\",\n\t\"Aringsmall\",\n\t\"AEsmall\",\n\t\"Ccedillasmall\",\n\t\"Egravesmall\",\n\t\"Eacutesmall\",\n\t\"Ecircumflexsmall\",\n\t\"Edieresissmall\",\n\t\"Igravesmall\",\n\t\"Iacutesmall\",\n\t\"Icircumflexsmall\",\n\t\"Idieresissmall\",\n\t\"Ethsmall\",\n\t\"Ntildesmall\",\n\t\"Ogravesmall\",\n\t\"Oacutesmall\",\n\t\"Ocircumflexsmall\",\n\t\"Otildesmall\",\n\t\"Odieresissmall\",\n\t\"OEsmall\",\n\t\"Oslashsmall\",\n\t\"Ugravesmall\",\n\t\"Uacutesmall\",\n\t\"Ucircumflexsmall\",\n\t\"Udieresissmall\",\n\t\"Yacutesmall\",\n\t\"Thornsmall\",\n\t\"Ydieresissmall\",\n\t\"001.000\",\n\t\"001.001\",\n\t\"001.002\",\n\t\"001.003\",\n\t\"Black\",\n\t\"Bold\",\n\t\"Book\",\n\t\"Light\",\n\t\"Medium\",\n\t\"Regular\",\n\t\"Roman\",\n\t\"Semibold\",\n];\n\n// Top DICT operators\nenum TopDictOp {\n\tversion = 0,\n\tNotice = 1,\n\tFullName = 2,\n\tFamilyName = 3,\n\tWeight = 4,\n\tFontBBox = 5,\n\tUniqueID = 13,\n\tXUID = 14,\n\tcharset = 15,\n\tEncoding = 16,\n\tCharStrings = 17,\n\tPrivate = 18,\n\tCopyright = 0x0c00,\n\tisFixedPitch = 0x0c01,\n\tItalicAngle = 0x0c02,\n\tUnderlinePosition = 0x0c03,\n\tUnderlineThickness = 0x0c04,\n\tPaintType = 0x0c05,\n\tCharstringType = 0x0c06,\n\tFontMatrix = 0x0c07,\n\tStrokeWidth = 0x0c08,\n\tSyntheticBase = 0x0c14,\n\tPostScript = 0x0c15,\n\tBaseFontName = 0x0c16,\n\tBaseFontBlend = 0x0c17,\n\t// CID-specific\n\tROS = 0x0c1e,\n\tCIDFontVersion = 0x0c1f,\n\tCIDFontRevision = 0x0c20,\n\tCIDFontType = 0x0c21,\n\tCIDCount = 0x0c22,\n\tUIDBase = 0x0c23,\n\tFDArray = 0x0c24,\n\tFDSelect = 0x0c25,\n\tFontName = 0x0c26,\n}\n\n// Private DICT operators\nenum PrivateDictOp {\n\tBlueValues = 6,\n\tOtherBlues = 7,\n\tFamilyBlues = 8,\n\tFamilyOtherBlues = 9,\n\tStdHW = 10,\n\tStdVW = 11,\n\tSubrs = 19,\n\tdefaultWidthX = 20,\n\tnominalWidthX = 21,\n\tBlueScale = 0x0c09,\n\tBlueShift = 0x0c0a,\n\tBlueFuzz = 0x0c0b,\n\tStemSnapH = 0x0c0c,\n\tStemSnapV = 0x0c0d,\n\tForceBold = 0x0c0e,\n\tLanguageGroup = 0x0c11,\n\tExpansionFactor = 0x0c12,\n\tinitialRandomSeed = 0x0c13,\n}\n\n/**\n * Parse CFF table\n */\nexport function parseCff(reader: Reader): CffTable {\n\tconst startOffset = reader.offset;\n\n\t// Header\n\tconst major = reader.uint8();\n\tconst minor = reader.uint8();\n\tconst hdrSize = reader.uint8();\n\tconst _offSize = reader.uint8();\n\n\treader.seek(startOffset + hdrSize);\n\n\t// Name INDEX\n\tconst names = parseIndex(reader).map((data) =>\n\t\tnew TextDecoder().decode(data),\n\t);\n\n\t// Top DICT INDEX\n\tconst topDictData = parseIndex(reader);\n\tconst topDicts: TopDict[] = [];\n\n\t// String INDEX\n\tconst stringData = parseIndex(reader);\n\tconst strings = stringData.map((data) => new TextDecoder().decode(data));\n\n\t// Global Subr INDEX\n\tconst globalSubrs = parseIndex(reader);\n\n\t// Parse Top DICTs\n\tfor (const data of topDictData) {\n\t\ttopDicts.push(\n\t\t\tparseTopDict(\n\t\t\t\tnew Reader(\n\t\t\t\t\tdata.buffer as ArrayBuffer,\n\t\t\t\t\tdata.byteOffset,\n\t\t\t\t\tdata.byteLength,\n\t\t\t\t),\n\t\t\t\tstrings,\n\t\t\t),\n\t\t);\n\t}\n\n\t// Parse CharStrings and local subrs for each font\n\tconst charStrings: Uint8Array[][] = [];\n\tconst localSubrs: Uint8Array[][] = [];\n\tconst fdArrays: FDDict[][] = [];\n\tconst fdSelects: FDSelect[] = [];\n\n\tfor (const topDict of topDicts) {\n\t\t// CharStrings\n\t\tif (topDict.charStrings !== undefined) {\n\t\t\treader.seek(startOffset + topDict.charStrings);\n\t\t\tcharStrings.push(parseIndex(reader));\n\t\t} else {\n\t\t\tcharStrings.push([]);\n\t\t}\n\n\t\t// Private DICT and local subrs\n\t\tif (topDict.private) {\n\t\t\tconst [privateSize, privateOffset] = topDict.private;\n\t\t\tconst privateDict = parsePrivateDict(\n\t\t\t\treader.slice(privateOffset, privateSize),\n\t\t\t\tstrings,\n\t\t\t);\n\n\t\t\tif (privateDict.subrs !== undefined) {\n\t\t\t\treader.seek(startOffset + privateOffset + privateDict.subrs);\n\t\t\t\tlocalSubrs.push(parseIndex(reader));\n\t\t\t} else {\n\t\t\t\tlocalSubrs.push([]);\n\t\t\t}\n\t\t} else {\n\t\t\tlocalSubrs.push([]);\n\t\t}\n\n\t\t// FDArray (for CID fonts)\n\t\tif (topDict.fdArray !== undefined) {\n\t\t\treader.seek(startOffset + topDict.fdArray);\n\t\t\tconst fdData = parseIndex(reader);\n\t\t\tconst fds: FDDict[] = [];\n\t\t\tfor (const data of fdData) {\n\t\t\t\tconst fdDict = parseTopDict(\n\t\t\t\t\tnew Reader(\n\t\t\t\t\t\tdata.buffer as ArrayBuffer,\n\t\t\t\t\t\tdata.byteOffset,\n\t\t\t\t\t\tdata.byteLength,\n\t\t\t\t\t),\n\t\t\t\t\tstrings,\n\t\t\t\t) as FDDict;\n\n\t\t\t\t// Parse FD-specific private dict and local subrs\n\t\t\t\tif (fdDict.private) {\n\t\t\t\t\tconst [fdPrivateSize, fdPrivateOffset] = fdDict.private;\n\t\t\t\t\tconst fdPrivateDict = parsePrivateDict(\n\t\t\t\t\t\treader.slice(startOffset + fdPrivateOffset, fdPrivateSize),\n\t\t\t\t\t\tstrings,\n\t\t\t\t\t);\n\t\t\t\t\t// Copy private dict properties to fdDict\n\t\t\t\t\tObject.assign(fdDict, fdPrivateDict);\n\n\t\t\t\t\t// Parse FD-specific local subrs\n\t\t\t\t\tif (fdPrivateDict.subrs !== undefined) {\n\t\t\t\t\t\treader.seek(startOffset + fdPrivateOffset + fdPrivateDict.subrs);\n\t\t\t\t\t\tfdDict.localSubrs = parseIndex(reader);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tfds.push(fdDict);\n\t\t\t}\n\t\t\tfdArrays.push(fds);\n\t\t} else {\n\t\t\tfdArrays.push([]);\n\t\t}\n\n\t\t// FDSelect (for CID fonts)\n\t\tif (topDict.fdSelect !== undefined) {\n\t\t\treader.seek(startOffset + topDict.fdSelect);\n\t\t\tconst lastCharStrings = charStrings[charStrings.length - 1];\n\t\t\tfdSelects.push(parseFDSelect(reader, lastCharStrings?.length ?? 0));\n\t\t} else {\n\t\t\tfdSelects.push({ format: 0, select: () => 0 });\n\t\t}\n\t}\n\n\treturn {\n\t\tversion: { major, minor },\n\t\tnames,\n\t\ttopDicts,\n\t\tstrings,\n\t\tglobalSubrs,\n\t\tcharStrings,\n\t\tlocalSubrs,\n\t\tfdArrays,\n\t\tfdSelects,\n\t};\n}\n\n/**\n * Parse an INDEX structure\n */\nfunction parseIndex(reader: Reader): Uint8Array[] {\n\tconst count = reader.uint16();\n\tif (count === 0) return [];\n\n\tconst offSize = reader.uint8();\n\tconst offsets: number[] = [];\n\n\tfor (let i = 0; i <= count; i++) {\n\t\toffsets.push(readOffset(reader, offSize));\n\t}\n\n\tconst result: Uint8Array[] = [];\n\tfor (let i = 0; i < count; i++) {\n\t\tconst start = offsets[i];\n\t\tconst end = offsets[i + 1];\n\t\tif (start === undefined || end === undefined) continue;\n\t\tconst length = end - start;\n\t\tresult.push(reader.bytes(length));\n\t}\n\n\treturn result;\n}\n\n/**\n * Read offset of given size\n */\nfunction readOffset(reader: Reader, offSize: number): number {\n\tswitch (offSize) {\n\t\tcase 1:\n\t\t\treturn reader.uint8();\n\t\tcase 2:\n\t\t\treturn reader.uint16();\n\t\tcase 3:\n\t\t\treturn reader.uint24();\n\t\tcase 4:\n\t\t\treturn reader.uint32();\n\t\tdefault:\n\t\t\tthrow new Error(`Invalid offset size: ${offSize}`);\n\t}\n}\n\n/**\n * Parse a DICT structure\n */\nfunction parseDict(reader: Reader): Map<number, number[]> {\n\tconst result = new Map<number, number[]>();\n\tconst operands: number[] = [];\n\n\twhile (reader.remaining > 0) {\n\t\tconst b0 = reader.uint8();\n\n\t\tif (b0 <= 21) {\n\t\t\t// Operator\n\t\t\tlet op = b0;\n\t\t\tif (b0 === 12) {\n\t\t\t\top = 0x0c00 | reader.uint8();\n\t\t\t}\n\t\t\tresult.set(op, [...operands]);\n\t\t\toperands.length = 0;\n\t\t} else if (b0 === 28) {\n\t\t\t// 16-bit signed integer\n\t\t\toperands.push(reader.int16());\n\t\t} else if (b0 === 29) {\n\t\t\t// 32-bit signed integer\n\t\t\toperands.push(reader.int32());\n\t\t} else if (b0 === 30) {\n\t\t\t// Real number\n\t\t\toperands.push(parseReal(reader));\n\t\t} else if (b0 >= 32 && b0 <= 246) {\n\t\t\toperands.push(b0 - 139);\n\t\t} else if (b0 >= 247 && b0 <= 250) {\n\t\t\tconst b1 = reader.uint8();\n\t\t\toperands.push((b0 - 247) * 256 + b1 + 108);\n\t\t} else if (b0 >= 251 && b0 <= 254) {\n\t\t\tconst b1 = reader.uint8();\n\t\t\toperands.push(-(b0 - 251) * 256 - b1 - 108);\n\t\t}\n\t}\n\n\treturn result;\n}\n\n/**\n * Parse real number from DICT\n */\nfunction parseReal(reader: Reader): number {\n\tlet str = \"\";\n\tconst nibbleChars = \"0123456789.EE -\";\n\tlet done = false;\n\n\twhile (!done) {\n\t\tconst byte = reader.uint8();\n\t\tfor (let i = 0; i < 2; i++) {\n\t\t\tconst nibble = i === 0 ? byte >> 4 : byte & 0x0f;\n\t\t\tif (nibble === 0x0f) {\n\t\t\t\tdone = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (nibble === 0x0c) {\n\t\t\t\tstr += \"E-\";\n\t\t\t} else {\n\t\t\t\tstr += nibbleChars[nibble];\n\t\t\t}\n\t\t}\n\t}\n\n\treturn parseFloat(str);\n}\n\n/**\n * Parse Top DICT\n */\nfunction parseTopDict(reader: Reader, strings: string[]): TopDict {\n\tconst dict = parseDict(reader);\n\tconst result: TopDict = {};\n\n\tconst getString = (sid: number): string => {\n\t\tif (sid < STANDARD_STRINGS.length) {\n\t\t\tconst str = STANDARD_STRINGS[sid];\n\t\t\treturn str ?? \"\";\n\t\t}\n\t\treturn strings[sid - STANDARD_STRINGS.length] ?? \"\";\n\t};\n\n\tfor (const [op, operands] of dict) {\n\t\tconst op0 = operands[0];\n\t\tconst op1 = operands[1];\n\t\tconst op2 = operands[2];\n\n\t\tswitch (op) {\n\t\t\tcase TopDictOp.version:\n\t\t\t\tif (op0 !== undefined) result.version = getString(op0);\n\t\t\t\tbreak;\n\t\t\tcase TopDictOp.Notice:\n\t\t\t\tif (op0 !== undefined) result.notice = getString(op0);\n\t\t\t\tbreak;\n\t\t\tcase TopDictOp.Copyright:\n\t\t\t\tif (op0 !== undefined) result.copyright = getString(op0);\n\t\t\t\tbreak;\n\t\t\tcase TopDictOp.FullName:\n\t\t\t\tif (op0 !== undefined) result.fullName = getString(op0);\n\t\t\t\tbreak;\n\t\t\tcase TopDictOp.FamilyName:\n\t\t\t\tif (op0 !== undefined) result.familyName = getString(op0);\n\t\t\t\tbreak;\n\t\t\tcase TopDictOp.Weight:\n\t\t\t\tif (op0 !== undefined) result.weight = getString(op0);\n\t\t\t\tbreak;\n\t\t\tcase TopDictOp.isFixedPitch:\n\t\t\t\tresult.isFixedPitch = op0 !== 0;\n\t\t\t\tbreak;\n\t\t\tcase TopDictOp.ItalicAngle:\n\t\t\t\tresult.italicAngle = op0;\n\t\t\t\tbreak;\n\t\t\tcase TopDictOp.UnderlinePosition:\n\t\t\t\tresult.underlinePosition = op0;\n\t\t\t\tbreak;\n\t\t\tcase TopDictOp.UnderlineThickness:\n\t\t\t\tresult.underlineThickness = op0;\n\t\t\t\tbreak;\n\t\t\tcase TopDictOp.PaintType:\n\t\t\t\tresult.paintType = op0;\n\t\t\t\tbreak;\n\t\t\tcase TopDictOp.CharstringType:\n\t\t\t\tresult.charstringType = op0;\n\t\t\t\tbreak;\n\t\t\tcase TopDictOp.FontMatrix:\n\t\t\t\tresult.fontMatrix = operands;\n\t\t\t\tbreak;\n\t\t\tcase TopDictOp.UniqueID:\n\t\t\t\tresult.uniqueID = op0;\n\t\t\t\tbreak;\n\t\t\tcase TopDictOp.FontBBox:\n\t\t\t\tresult.fontBBox = operands;\n\t\t\t\tbreak;\n\t\t\tcase TopDictOp.StrokeWidth:\n\t\t\t\tresult.strokeWidth = op0;\n\t\t\t\tbreak;\n\t\t\tcase TopDictOp.charset:\n\t\t\t\tresult.charset = op0;\n\t\t\t\tbreak;\n\t\t\tcase TopDictOp.Encoding:\n\t\t\t\tresult.encoding = op0;\n\t\t\t\tbreak;\n\t\t\tcase TopDictOp.CharStrings:\n\t\t\t\tresult.charStrings = op0;\n\t\t\t\tbreak;\n\t\t\tcase TopDictOp.Private:\n\t\t\t\tif (op0 !== undefined && op1 !== undefined) {\n\t\t\t\t\tresult.private = [op0, op1];\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase TopDictOp.SyntheticBase:\n\t\t\t\tresult.syntheticBase = op0;\n\t\t\t\tbreak;\n\t\t\tcase TopDictOp.PostScript:\n\t\t\t\tif (op0 !== undefined) result.postScript = getString(op0);\n\t\t\t\tbreak;\n\t\t\tcase TopDictOp.BaseFontName:\n\t\t\t\tif (op0 !== undefined) result.baseFontName = getString(op0);\n\t\t\t\tbreak;\n\t\t\tcase TopDictOp.BaseFontBlend:\n\t\t\t\tresult.baseFontBlend = operands;\n\t\t\t\tbreak;\n\t\t\tcase TopDictOp.ROS:\n\t\t\t\tif (op0 !== undefined && op1 !== undefined && op2 !== undefined) {\n\t\t\t\t\tresult.ros = {\n\t\t\t\t\t\tregistry: getString(op0),\n\t\t\t\t\t\tordering: getString(op1),\n\t\t\t\t\t\tsupplement: op2,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase TopDictOp.CIDFontVersion:\n\t\t\t\tresult.cidFontVersion = op0;\n\t\t\t\tbreak;\n\t\t\tcase TopDictOp.CIDFontRevision:\n\t\t\t\tresult.cidFontRevision = op0;\n\t\t\t\tbreak;\n\t\t\tcase TopDictOp.CIDFontType:\n\t\t\t\tresult.cidFontType = op0;\n\t\t\t\tbreak;\n\t\t\tcase TopDictOp.CIDCount:\n\t\t\t\tresult.cidCount = op0;\n\t\t\t\tbreak;\n\t\t\tcase TopDictOp.UIDBase:\n\t\t\t\tresult.uidBase = op0;\n\t\t\t\tbreak;\n\t\t\tcase TopDictOp.FDArray:\n\t\t\t\tresult.fdArray = op0;\n\t\t\t\tbreak;\n\t\t\tcase TopDictOp.FDSelect:\n\t\t\t\tresult.fdSelect = op0;\n\t\t\t\tbreak;\n\t\t\tcase TopDictOp.FontName:\n\t\t\t\tif (op0 !== undefined) result.fontName = getString(op0);\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn result;\n}\n\n/**\n * Parse Private DICT\n */\nfunction parsePrivateDict(reader: Reader, _strings: string[]): PrivateDict {\n\tconst dict = parseDict(reader);\n\tconst result: PrivateDict = {};\n\n\tfor (const [op, operands] of dict) {\n\t\tconst op0 = operands[0];\n\n\t\tswitch (op) {\n\t\t\tcase PrivateDictOp.BlueValues:\n\t\t\t\tresult.blueValues = deltaToAbsolute(operands);\n\t\t\t\tbreak;\n\t\t\tcase PrivateDictOp.OtherBlues:\n\t\t\t\tresult.otherBlues = deltaToAbsolute(operands);\n\t\t\t\tbreak;\n\t\t\tcase PrivateDictOp.FamilyBlues:\n\t\t\t\tresult.familyBlues = deltaToAbsolute(operands);\n\t\t\t\tbreak;\n\t\t\tcase PrivateDictOp.FamilyOtherBlues:\n\t\t\t\tresult.familyOtherBlues = deltaToAbsolute(operands);\n\t\t\t\tbreak;\n\t\t\tcase PrivateDictOp.BlueScale:\n\t\t\t\tresult.blueScale = op0;\n\t\t\t\tbreak;\n\t\t\tcase PrivateDictOp.BlueShift:\n\t\t\t\tresult.blueShift = op0;\n\t\t\t\tbreak;\n\t\t\tcase PrivateDictOp.BlueFuzz:\n\t\t\t\tresult.blueFuzz = op0;\n\t\t\t\tbreak;\n\t\t\tcase PrivateDictOp.StdHW:\n\t\t\t\tresult.stdHW = op0;\n\t\t\t\tbreak;\n\t\t\tcase PrivateDictOp.StdVW:\n\t\t\t\tresult.stdVW = op0;\n\t\t\t\tbreak;\n\t\t\tcase PrivateDictOp.StemSnapH:\n\t\t\t\tresult.stemSnapH = deltaToAbsolute(operands);\n\t\t\t\tbreak;\n\t\t\tcase PrivateDictOp.StemSnapV:\n\t\t\t\tresult.stemSnapV = deltaToAbsolute(operands);\n\t\t\t\tbreak;\n\t\t\tcase PrivateDictOp.ForceBold:\n\t\t\t\tresult.forceBold = op0 !== 0;\n\t\t\t\tbreak;\n\t\t\tcase PrivateDictOp.LanguageGroup:\n\t\t\t\tresult.languageGroup = op0;\n\t\t\t\tbreak;\n\t\t\tcase PrivateDictOp.ExpansionFactor:\n\t\t\t\tresult.expansionFactor = op0;\n\t\t\t\tbreak;\n\t\t\tcase PrivateDictOp.initialRandomSeed:\n\t\t\t\tresult.initialRandomSeed = op0;\n\t\t\t\tbreak;\n\t\t\tcase PrivateDictOp.Subrs:\n\t\t\t\tresult.subrs = op0;\n\t\t\t\tbreak;\n\t\t\tcase PrivateDictOp.defaultWidthX:\n\t\t\t\tresult.defaultWidthX = op0;\n\t\t\t\tbreak;\n\t\t\tcase PrivateDictOp.nominalWidthX:\n\t\t\t\tresult.nominalWidthX = op0;\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn result;\n}\n\n/**\n * Convert delta-encoded values to absolute\n */\nfunction deltaToAbsolute(deltas: number[]): number[] {\n\tconst result: number[] = [];\n\tlet value = 0;\n\tfor (const delta of deltas) {\n\t\tvalue += delta;\n\t\tresult.push(value);\n\t}\n\treturn result;\n}\n\n/**\n * Parse FDSelect structure\n */\nfunction parseFDSelect(reader: Reader, numGlyphs: number): FDSelect {\n\tconst format = reader.uint8();\n\n\tif (format === 0) {\n\t\tconst fds = reader.uint8Array(numGlyphs);\n\t\treturn {\n\t\t\tformat,\n\t\t\tselect: (glyphId: number) => fds[glyphId] ?? 0,\n\t\t};\n\t} else if (format === 3) {\n\t\tconst nRanges = reader.uint16();\n\t\tconst ranges: Array<{ first: number; fd: number }> = [];\n\n\t\tfor (let i = 0; i < nRanges; i++) {\n\t\t\tranges.push({\n\t\t\t\tfirst: reader.uint16(),\n\t\t\t\tfd: reader.uint8(),\n\t\t\t});\n\t\t}\n\t\tconst _sentinel = reader.uint16();\n\n\t\treturn {\n\t\t\tformat,\n\t\t\tselect: (glyphId: number) => {\n\t\t\t\t// Binary search through ranges\n\t\t\t\tlet lo = 0;\n\t\t\t\tlet hi = ranges.length - 1;\n\t\t\t\twhile (lo < hi) {\n\t\t\t\t\tconst mid = Math.ceil((lo + hi) / 2);\n\t\t\t\t\tconst range = ranges[mid];\n\t\t\t\t\tif (range && range.first <= glyphId) {\n\t\t\t\t\t\tlo = mid;\n\t\t\t\t\t} else {\n\t\t\t\t\t\thi = mid - 1;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconst foundRange = ranges[lo];\n\t\t\t\treturn foundRange?.fd ?? 0;\n\t\t\t},\n\t\t};\n\t}\n\n\treturn { format, select: () => 0 };\n}\n\n/**\n * Get string by SID\n */\nexport function getCffString(cff: CffTable, sid: number): string {\n\tif (sid < STANDARD_STRINGS.length) {\n\t\tconst str = STANDARD_STRINGS[sid];\n\t\treturn str ?? \"\";\n\t}\n\treturn cff.strings[sid - STANDARD_STRINGS.length] ?? \"\";\n}\n",
23
- "import type { GlyphId } from \"../../types.ts\";\nimport type { CffTable } from \"./cff.ts\";\nimport type { Cff2Table, ItemVariationStore } from \"./cff2.ts\";\nimport type { Contour, GlyphPoint } from \"./glyf.ts\";\n\n/**\n * CFF CharString interpreter\n * Executes Type 2 CharString programs to produce glyph outlines\n */\n\n// CharString operators\nenum Op {\n\t// Path construction\n\thstem = 1,\n\tvstem = 3,\n\tvmoveto = 4,\n\trlineto = 5,\n\thlineto = 6,\n\tvlineto = 7,\n\trrcurveto = 8,\n\tcallsubr = 10,\n\treturn_ = 11,\n\tendchar = 14,\n\thstemhm = 18,\n\thintmask = 19,\n\tcntrmask = 20,\n\trmoveto = 21,\n\thmoveto = 22,\n\tvstemhm = 23,\n\trcurveline = 24,\n\trlinecurve = 25,\n\tvvcurveto = 26,\n\thhcurveto = 27,\n\tcallgsubr = 29,\n\tvhcurveto = 30,\n\thvcurveto = 31,\n\n\t// Two-byte operators (12 xx)\n\tdotsection = 0x0c00,\n\tand_ = 0x0c03,\n\tor_ = 0x0c04,\n\tnot_ = 0x0c05,\n\tabs_ = 0x0c09,\n\tadd_ = 0x0c0a,\n\tsub_ = 0x0c0b,\n\tdiv_ = 0x0c0c,\n\tneg_ = 0x0c0e,\n\teq_ = 0x0c0f,\n\tdrop_ = 0x0c12,\n\tput_ = 0x0c14,\n\tget_ = 0x0c15,\n\tifelse_ = 0x0c16,\n\trandom_ = 0x0c17,\n\tmul_ = 0x0c18,\n\tsqrt_ = 0x0c1a,\n\tdup_ = 0x0c1b,\n\texch_ = 0x0c1c,\n\tindex_ = 0x0c1d,\n\troll_ = 0x0c1e,\n\thflex = 0x0c22,\n\tflex = 0x0c23,\n\thflex1 = 0x0c24,\n\tflex1 = 0x0c25,\n\n\t// CFF2 operators\n\tvsindex = 15,\n\tblend = 16,\n}\n\ninterface CharStringState {\n\tx: number;\n\ty: number;\n\tstack: number[];\n\tnStems: number;\n\thaveWidth: boolean;\n\twidth: number;\n\tcontours: Contour[];\n\tcurrentContour: GlyphPoint[];\n\ttransientArray: number[];\n\t// For subroutine calls\n\tcallStack: { data: Uint8Array; pos: number }[];\n\t// For CFF2 blending\n\tvsindex: number;\n\taxisCoords: number[] | null;\n\tvstore: ItemVariationStore | null;\n}\n\n/**\n * Execute a CFF charstring and return contours\n */\nexport function executeCffCharString(\n\tcff: CffTable,\n\tglyphId: GlyphId,\n\tfontIndex: number = 0,\n): Contour[] | null {\n\tconst charStrings = cff.charStrings[fontIndex];\n\tif (!charStrings || glyphId >= charStrings.length) return null;\n\n\tconst charString = charStrings[glyphId];\n\tif (!charString) return null;\n\n\tconst globalSubrs = cff.globalSubrs;\n\n\t// For CID fonts, use fdSelect to get the right FD and its local subrs\n\tconst topDict = cff.topDicts[fontIndex];\n\tconst isCID = topDict?.ros !== undefined;\n\tlet localSubrs: Uint8Array[] = [];\n\n\tif (isCID && cff.fdSelects[fontIndex] && cff.fdArrays[fontIndex]) {\n\t\tconst fdIndex = cff.fdSelects[fontIndex]?.select(glyphId) ?? 0;\n\t\tconst fdArray = cff.fdArrays[fontIndex];\n\t\tconst fd = fdArray?.[fdIndex];\n\t\t// Use FD-specific local subrs if available\n\t\tlocalSubrs = fd?.localSubrs || cff.localSubrs[fontIndex] || [];\n\t} else {\n\t\tlocalSubrs = cff.localSubrs[fontIndex] || [];\n\t}\n\n\tconst state: CharStringState = {\n\t\tx: 0,\n\t\ty: 0,\n\t\tstack: [],\n\t\tnStems: 0,\n\t\thaveWidth: false,\n\t\twidth: 0,\n\t\tcontours: [],\n\t\tcurrentContour: [],\n\t\ttransientArray: new Array(32).fill(0),\n\t\tcallStack: [],\n\t\tvsindex: 0,\n\t\taxisCoords: null,\n\t\tvstore: null,\n\t};\n\n\texecuteCharString(state, charString, globalSubrs, localSubrs);\n\n\t// Close any open contour\n\tif (state.currentContour.length > 0) {\n\t\tstate.contours.push(state.currentContour);\n\t}\n\n\treturn state.contours;\n}\n\n/**\n * Execute a CFF2 charstring with variation support\n */\nexport function executeCff2CharString(\n\tcff2: Cff2Table,\n\tglyphId: GlyphId,\n\taxisCoords: number[] | null = null,\n): Contour[] | null {\n\tif (glyphId >= cff2.charStrings.length) return null;\n\n\tconst charString = cff2.charStrings[glyphId];\n\tif (!charString) return null;\n\n\tconst globalSubrs = cff2.globalSubrs;\n\n\t// Get FD index and local subrs\n\tconst fdIndex = cff2.fdSelect?.select(glyphId) ?? 0;\n\tconst fd = cff2.fdArray[fdIndex];\n\tconst localSubrs = fd?.localSubrs || [];\n\n\tconst state: CharStringState = {\n\t\tx: 0,\n\t\ty: 0,\n\t\tstack: [],\n\t\tnStems: 0,\n\t\thaveWidth: true, // CFF2 doesn't have width in charstring\n\t\twidth: 0,\n\t\tcontours: [],\n\t\tcurrentContour: [],\n\t\ttransientArray: new Array(32).fill(0),\n\t\tcallStack: [],\n\t\tvsindex: fd?.private?.vsindex ?? 0,\n\t\taxisCoords,\n\t\tvstore: cff2.vstore,\n\t};\n\n\texecuteCharString(state, charString, globalSubrs, localSubrs);\n\n\t// Close any open contour\n\tif (state.currentContour.length > 0) {\n\t\tstate.contours.push(state.currentContour);\n\t}\n\n\treturn state.contours;\n}\n\nfunction executeCharString(\n\tstate: CharStringState,\n\tdata: Uint8Array,\n\tglobalSubrs: Uint8Array[],\n\tlocalSubrs: Uint8Array[],\n): void {\n\tlet pos = 0;\n\n\twhile (pos < data.length) {\n\t\tconst b0 = data[pos++];\n\t\tif (b0 === undefined) return;\n\n\t\tif (b0 === 28) {\n\t\t\t// 16-bit signed integer\n\t\t\tconst b1 = data[pos++];\n\t\t\tif (b1 === undefined) return;\n\t\t\tconst b2 = data[pos++];\n\t\t\tif (b2 === undefined) return;\n\t\t\tstate.stack.push((((b1 << 8) | b2) << 16) >> 16);\n\t\t} else if (b0 === 255) {\n\t\t\t// 32-bit fixed point (16.16)\n\t\t\tconst b1 = data[pos++];\n\t\t\tif (b1 === undefined) return;\n\t\t\tconst b2 = data[pos++];\n\t\t\tif (b2 === undefined) return;\n\t\t\tconst b3 = data[pos++];\n\t\t\tif (b3 === undefined) return;\n\t\t\tconst b4 = data[pos++];\n\t\t\tif (b4 === undefined) return;\n\t\t\tconst val = ((b1 << 24) | (b2 << 16) | (b3 << 8) | b4) >> 0;\n\t\t\tstate.stack.push(val / 65536);\n\t\t} else if (b0 >= 32 && b0 <= 246) {\n\t\t\tstate.stack.push(b0 - 139);\n\t\t} else if (b0 >= 247 && b0 <= 250) {\n\t\t\tconst b1 = data[pos++];\n\t\t\tif (b1 === undefined) return;\n\t\t\tstate.stack.push((b0 - 247) * 256 + b1 + 108);\n\t\t} else if (b0 >= 251 && b0 <= 254) {\n\t\t\tconst b1 = data[pos++];\n\t\t\tif (b1 === undefined) return;\n\t\t\tstate.stack.push(-(b0 - 251) * 256 - b1 - 108);\n\t\t} else if (b0 === 12) {\n\t\t\t// Two-byte operator\n\t\t\tconst b1 = data[pos++];\n\t\t\tif (b1 === undefined) return;\n\t\t\tconst op = 0x0c00 | b1;\n\t\t\texecuteOperator(state, op, globalSubrs, localSubrs);\n\t\t} else if (b0 === Op.hintmask || b0 === Op.cntrmask) {\n\t\t\t// hintmask/cntrmask: process stems from stack, then skip mask bytes\n\t\t\tconst stack = state.stack;\n\t\t\tconst hasWidth = stack.length % 2 !== 0;\n\t\t\tif (hasWidth && !state.haveWidth) {\n\t\t\t\tconst width = stack.shift();\n\t\t\t\tif (width !== undefined) {\n\t\t\t\t\tstate.width = width;\n\t\t\t\t\tstate.haveWidth = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tstate.nStems += stack.length / 2;\n\t\t\tstack.length = 0;\n\t\t\t// Skip mask bytes (ceil(nStems / 8) bytes)\n\t\t\tconst maskBytes = Math.ceil(state.nStems / 8);\n\t\t\tpos += maskBytes;\n\t\t} else {\n\t\t\t// Single-byte operator\n\t\t\texecuteOperator(state, b0, globalSubrs, localSubrs);\n\t\t}\n\n\t\t// Handle return from subroutine\n\t\tif (state.callStack.length > 0) {\n\t\t\tconst frame = state.callStack[state.callStack.length - 1];\n\t\t\tif (frame && frame.pos >= frame.data.length) {\n\t\t\t\tstate.callStack.pop();\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction executeOperator(\n\tstate: CharStringState,\n\top: number,\n\tglobalSubrs: Uint8Array[],\n\tlocalSubrs: Uint8Array[],\n): void {\n\tconst stack = state.stack;\n\n\tswitch (op) {\n\t\tcase Op.hstem:\n\t\tcase Op.vstem:\n\t\tcase Op.hstemhm:\n\t\tcase Op.vstemhm: {\n\t\t\t// Stem hints\n\t\t\tconst hasWidth = stack.length % 2 !== 0;\n\t\t\tif (hasWidth && !state.haveWidth) {\n\t\t\t\tconst width = stack.shift();\n\t\t\t\tif (width === undefined) break;\n\t\t\t\tstate.width = width;\n\t\t\t\tstate.haveWidth = true;\n\t\t\t}\n\t\t\tstate.nStems += stack.length / 2;\n\t\t\tstack.length = 0;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase Op.hintmask:\n\t\tcase Op.cntrmask:\n\t\t\t// Handled inline in executeCharString to skip mask bytes\n\t\t\tbreak;\n\n\t\tcase Op.rmoveto: {\n\t\t\tif (stack.length > 2 && !state.haveWidth) {\n\t\t\t\tconst width = stack.shift();\n\t\t\t\tif (width === undefined) break;\n\t\t\t\tstate.width = width;\n\t\t\t\tstate.haveWidth = true;\n\t\t\t}\n\t\t\t// Close current contour if any\n\t\t\tif (state.currentContour.length > 0) {\n\t\t\t\tstate.contours.push(state.currentContour);\n\t\t\t\tstate.currentContour = [];\n\t\t\t}\n\t\t\tconst dy = stack.pop();\n\t\t\tif (dy === undefined) break;\n\t\t\tconst dx = stack.pop();\n\t\t\tif (dx === undefined) break;\n\t\t\tstate.x += dx;\n\t\t\tstate.y += dy;\n\t\t\tstate.currentContour.push({ x: state.x, y: state.y, onCurve: true });\n\t\t\tstack.length = 0;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase Op.hmoveto: {\n\t\t\tif (stack.length > 1 && !state.haveWidth) {\n\t\t\t\tconst width = stack.shift();\n\t\t\t\tif (width === undefined) break;\n\t\t\t\tstate.width = width;\n\t\t\t\tstate.haveWidth = true;\n\t\t\t}\n\t\t\tif (state.currentContour.length > 0) {\n\t\t\t\tstate.contours.push(state.currentContour);\n\t\t\t\tstate.currentContour = [];\n\t\t\t}\n\t\t\tconst dx = stack.pop();\n\t\t\tif (dx === undefined) break;\n\t\t\tstate.x += dx;\n\t\t\tstate.currentContour.push({ x: state.x, y: state.y, onCurve: true });\n\t\t\tstack.length = 0;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase Op.vmoveto: {\n\t\t\tif (stack.length > 1 && !state.haveWidth) {\n\t\t\t\tconst width = stack.shift();\n\t\t\t\tif (width === undefined) break;\n\t\t\t\tstate.width = width;\n\t\t\t\tstate.haveWidth = true;\n\t\t\t}\n\t\t\tif (state.currentContour.length > 0) {\n\t\t\t\tstate.contours.push(state.currentContour);\n\t\t\t\tstate.currentContour = [];\n\t\t\t}\n\t\t\tconst dy = stack.pop();\n\t\t\tif (dy === undefined) break;\n\t\t\tstate.y += dy;\n\t\t\tstate.currentContour.push({ x: state.x, y: state.y, onCurve: true });\n\t\t\tstack.length = 0;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase Op.rlineto: {\n\t\t\twhile (stack.length >= 2) {\n\t\t\t\tconst dx = stack.shift();\n\t\t\t\tif (dx === undefined) break;\n\t\t\t\tconst dy = stack.shift();\n\t\t\t\tif (dy === undefined) break;\n\t\t\t\tstate.x += dx;\n\t\t\t\tstate.y += dy;\n\t\t\t\tstate.currentContour.push({ x: state.x, y: state.y, onCurve: true });\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase Op.hlineto: {\n\t\t\tlet isHorizontal = true;\n\t\t\twhile (stack.length >= 1) {\n\t\t\t\tconst val = stack.shift();\n\t\t\t\tif (val === undefined) break;\n\t\t\t\tif (isHorizontal) {\n\t\t\t\t\tstate.x += val;\n\t\t\t\t} else {\n\t\t\t\t\tstate.y += val;\n\t\t\t\t}\n\t\t\t\tstate.currentContour.push({ x: state.x, y: state.y, onCurve: true });\n\t\t\t\tisHorizontal = !isHorizontal;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase Op.vlineto: {\n\t\t\tlet isVertical = true;\n\t\t\twhile (stack.length >= 1) {\n\t\t\t\tconst val = stack.shift();\n\t\t\t\tif (val === undefined) break;\n\t\t\t\tif (isVertical) {\n\t\t\t\t\tstate.y += val;\n\t\t\t\t} else {\n\t\t\t\t\tstate.x += val;\n\t\t\t\t}\n\t\t\t\tstate.currentContour.push({ x: state.x, y: state.y, onCurve: true });\n\t\t\t\tisVertical = !isVertical;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase Op.rrcurveto: {\n\t\t\twhile (stack.length >= 6) {\n\t\t\t\tconst dx1 = stack.shift();\n\t\t\t\tif (dx1 === undefined) break;\n\t\t\t\tconst dy1 = stack.shift();\n\t\t\t\tif (dy1 === undefined) break;\n\t\t\t\tconst dx2 = stack.shift();\n\t\t\t\tif (dx2 === undefined) break;\n\t\t\t\tconst dy2 = stack.shift();\n\t\t\t\tif (dy2 === undefined) break;\n\t\t\t\tconst dx3 = stack.shift();\n\t\t\t\tif (dx3 === undefined) break;\n\t\t\t\tconst dy3 = stack.shift();\n\t\t\t\tif (dy3 === undefined) break;\n\t\t\t\taddCubicBezier(state, dx1, dy1, dx2, dy2, dx3, dy3);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase Op.hhcurveto: {\n\t\t\tlet dy1 = 0;\n\t\t\tif (stack.length % 4 === 1) {\n\t\t\t\tconst val = stack.shift();\n\t\t\t\tif (val === undefined) break;\n\t\t\t\tdy1 = val;\n\t\t\t}\n\t\t\twhile (stack.length >= 4) {\n\t\t\t\tconst dx1 = stack.shift();\n\t\t\t\tif (dx1 === undefined) break;\n\t\t\t\tconst dx2 = stack.shift();\n\t\t\t\tif (dx2 === undefined) break;\n\t\t\t\tconst dy2 = stack.shift();\n\t\t\t\tif (dy2 === undefined) break;\n\t\t\t\tconst dx3 = stack.shift();\n\t\t\t\tif (dx3 === undefined) break;\n\t\t\t\taddCubicBezier(state, dx1, dy1, dx2, dy2, dx3, 0);\n\t\t\t\tdy1 = 0;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase Op.vvcurveto: {\n\t\t\tlet dx1 = 0;\n\t\t\tif (stack.length % 4 === 1) {\n\t\t\t\tconst val = stack.shift();\n\t\t\t\tif (val === undefined) break;\n\t\t\t\tdx1 = val;\n\t\t\t}\n\t\t\twhile (stack.length >= 4) {\n\t\t\t\tconst dy1 = stack.shift();\n\t\t\t\tif (dy1 === undefined) break;\n\t\t\t\tconst dx2 = stack.shift();\n\t\t\t\tif (dx2 === undefined) break;\n\t\t\t\tconst dy2 = stack.shift();\n\t\t\t\tif (dy2 === undefined) break;\n\t\t\t\tconst dy3 = stack.shift();\n\t\t\t\tif (dy3 === undefined) break;\n\t\t\t\taddCubicBezier(state, dx1, dy1, dx2, dy2, 0, dy3);\n\t\t\t\tdx1 = 0;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase Op.hvcurveto: {\n\t\t\t// Alternates horizontal/vertical starting tangent\n\t\t\tlet isHorizontal = true;\n\t\t\twhile (stack.length >= 4) {\n\t\t\t\tif (isHorizontal) {\n\t\t\t\t\tconst dx1 = stack.shift();\n\t\t\t\t\tif (dx1 === undefined) break;\n\t\t\t\t\tconst dx2 = stack.shift();\n\t\t\t\t\tif (dx2 === undefined) break;\n\t\t\t\t\tconst dy2 = stack.shift();\n\t\t\t\t\tif (dy2 === undefined) break;\n\t\t\t\t\tconst dy3 = stack.shift();\n\t\t\t\t\tif (dy3 === undefined) break;\n\t\t\t\t\tconst dx3 = stack.length === 1 ? (stack.shift() ?? 0) : 0;\n\t\t\t\t\taddCubicBezier(state, dx1, 0, dx2, dy2, dx3, dy3);\n\t\t\t\t} else {\n\t\t\t\t\tconst dy1 = stack.shift();\n\t\t\t\t\tif (dy1 === undefined) break;\n\t\t\t\t\tconst dx2 = stack.shift();\n\t\t\t\t\tif (dx2 === undefined) break;\n\t\t\t\t\tconst dy2 = stack.shift();\n\t\t\t\t\tif (dy2 === undefined) break;\n\t\t\t\t\tconst dx3 = stack.shift();\n\t\t\t\t\tif (dx3 === undefined) break;\n\t\t\t\t\tconst dy3 = stack.length === 1 ? (stack.shift() ?? 0) : 0;\n\t\t\t\t\taddCubicBezier(state, 0, dy1, dx2, dy2, dx3, dy3);\n\t\t\t\t}\n\t\t\t\tisHorizontal = !isHorizontal;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase Op.vhcurveto: {\n\t\t\t// Alternates vertical/horizontal starting tangent\n\t\t\tlet isVertical = true;\n\t\t\twhile (stack.length >= 4) {\n\t\t\t\tif (isVertical) {\n\t\t\t\t\tconst dy1 = stack.shift();\n\t\t\t\t\tif (dy1 === undefined) break;\n\t\t\t\t\tconst dx2 = stack.shift();\n\t\t\t\t\tif (dx2 === undefined) break;\n\t\t\t\t\tconst dy2 = stack.shift();\n\t\t\t\t\tif (dy2 === undefined) break;\n\t\t\t\t\tconst dx3 = stack.shift();\n\t\t\t\t\tif (dx3 === undefined) break;\n\t\t\t\t\tconst dy3 = stack.length === 1 ? (stack.shift() ?? 0) : 0;\n\t\t\t\t\taddCubicBezier(state, 0, dy1, dx2, dy2, dx3, dy3);\n\t\t\t\t} else {\n\t\t\t\t\tconst dx1 = stack.shift();\n\t\t\t\t\tif (dx1 === undefined) break;\n\t\t\t\t\tconst dx2 = stack.shift();\n\t\t\t\t\tif (dx2 === undefined) break;\n\t\t\t\t\tconst dy2 = stack.shift();\n\t\t\t\t\tif (dy2 === undefined) break;\n\t\t\t\t\tconst dy3 = stack.shift();\n\t\t\t\t\tif (dy3 === undefined) break;\n\t\t\t\t\tconst dx3 = stack.length === 1 ? (stack.shift() ?? 0) : 0;\n\t\t\t\t\taddCubicBezier(state, dx1, 0, dx2, dy2, dx3, dy3);\n\t\t\t\t}\n\t\t\t\tisVertical = !isVertical;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase Op.rcurveline: {\n\t\t\twhile (stack.length >= 8) {\n\t\t\t\tconst dx1 = stack.shift();\n\t\t\t\tif (dx1 === undefined) break;\n\t\t\t\tconst dy1 = stack.shift();\n\t\t\t\tif (dy1 === undefined) break;\n\t\t\t\tconst dx2 = stack.shift();\n\t\t\t\tif (dx2 === undefined) break;\n\t\t\t\tconst dy2 = stack.shift();\n\t\t\t\tif (dy2 === undefined) break;\n\t\t\t\tconst dx3 = stack.shift();\n\t\t\t\tif (dx3 === undefined) break;\n\t\t\t\tconst dy3 = stack.shift();\n\t\t\t\tif (dy3 === undefined) break;\n\t\t\t\taddCubicBezier(state, dx1, dy1, dx2, dy2, dx3, dy3);\n\t\t\t}\n\t\t\t// Final line\n\t\t\tif (stack.length >= 2) {\n\t\t\t\tconst dx = stack.shift();\n\t\t\t\tif (dx === undefined) break;\n\t\t\t\tconst dy = stack.shift();\n\t\t\t\tif (dy === undefined) break;\n\t\t\t\tstate.x += dx;\n\t\t\t\tstate.y += dy;\n\t\t\t\tstate.currentContour.push({ x: state.x, y: state.y, onCurve: true });\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase Op.rlinecurve: {\n\t\t\twhile (stack.length >= 8) {\n\t\t\t\tconst dx = stack.shift();\n\t\t\t\tif (dx === undefined) break;\n\t\t\t\tconst dy = stack.shift();\n\t\t\t\tif (dy === undefined) break;\n\t\t\t\tstate.x += dx;\n\t\t\t\tstate.y += dy;\n\t\t\t\tstate.currentContour.push({ x: state.x, y: state.y, onCurve: true });\n\t\t\t}\n\t\t\t// Final curve\n\t\t\tif (stack.length >= 6) {\n\t\t\t\tconst dx1 = stack.shift();\n\t\t\t\tif (dx1 === undefined) break;\n\t\t\t\tconst dy1 = stack.shift();\n\t\t\t\tif (dy1 === undefined) break;\n\t\t\t\tconst dx2 = stack.shift();\n\t\t\t\tif (dx2 === undefined) break;\n\t\t\t\tconst dy2 = stack.shift();\n\t\t\t\tif (dy2 === undefined) break;\n\t\t\t\tconst dx3 = stack.shift();\n\t\t\t\tif (dx3 === undefined) break;\n\t\t\t\tconst dy3 = stack.shift();\n\t\t\t\tif (dy3 === undefined) break;\n\t\t\t\taddCubicBezier(state, dx1, dy1, dx2, dy2, dx3, dy3);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase Op.callsubr: {\n\t\t\tconst index = stack.pop();\n\t\t\tif (index === undefined) break;\n\t\t\tconst biasedIndex = index + getSubrBias(localSubrs.length);\n\t\t\tconst subr = localSubrs[biasedIndex];\n\t\t\tif (subr) {\n\t\t\t\texecuteCharString(state, subr, globalSubrs, localSubrs);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase Op.callgsubr: {\n\t\t\tconst index = stack.pop();\n\t\t\tif (index === undefined) break;\n\t\t\tconst biasedIndex = index + getSubrBias(globalSubrs.length);\n\t\t\tconst subr = globalSubrs[biasedIndex];\n\t\t\tif (subr) {\n\t\t\t\texecuteCharString(state, subr, globalSubrs, localSubrs);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase Op.return_:\n\t\t\t// Return from subroutine - handled by caller\n\t\t\tbreak;\n\n\t\tcase Op.endchar: {\n\t\t\tif (stack.length > 0 && !state.haveWidth) {\n\t\t\t\tconst width = stack.shift();\n\t\t\t\tif (width === undefined) break;\n\t\t\t\tstate.width = width;\n\t\t\t\tstate.haveWidth = true;\n\t\t\t}\n\t\t\t// Close current contour\n\t\t\tif (state.currentContour.length > 0) {\n\t\t\t\tstate.contours.push(state.currentContour);\n\t\t\t\tstate.currentContour = [];\n\t\t\t}\n\t\t\tstack.length = 0;\n\t\t\tbreak;\n\t\t}\n\n\t\t// Flex operators\n\t\tcase Op.flex: {\n\t\t\t// 12 arguments: dx1 dy1 dx2 dy2 dx3 dy3 dx4 dy4 dx5 dy5 dx6 dy6 fd\n\t\t\tif (stack.length >= 13) {\n\t\t\t\tconst dx1 = stack.shift();\n\t\t\t\tif (dx1 === undefined) break;\n\t\t\t\tconst dy1 = stack.shift();\n\t\t\t\tif (dy1 === undefined) break;\n\t\t\t\tconst dx2 = stack.shift();\n\t\t\t\tif (dx2 === undefined) break;\n\t\t\t\tconst dy2 = stack.shift();\n\t\t\t\tif (dy2 === undefined) break;\n\t\t\t\tconst dx3 = stack.shift();\n\t\t\t\tif (dx3 === undefined) break;\n\t\t\t\tconst dy3 = stack.shift();\n\t\t\t\tif (dy3 === undefined) break;\n\t\t\t\tconst dx4 = stack.shift();\n\t\t\t\tif (dx4 === undefined) break;\n\t\t\t\tconst dy4 = stack.shift();\n\t\t\t\tif (dy4 === undefined) break;\n\t\t\t\tconst dx5 = stack.shift();\n\t\t\t\tif (dx5 === undefined) break;\n\t\t\t\tconst dy5 = stack.shift();\n\t\t\t\tif (dy5 === undefined) break;\n\t\t\t\tconst dx6 = stack.shift();\n\t\t\t\tif (dx6 === undefined) break;\n\t\t\t\tconst dy6 = stack.shift();\n\t\t\t\tif (dy6 === undefined) break;\n\t\t\t\tstack.shift(); // fd (flex depth) - not used for rendering\n\t\t\t\taddCubicBezier(state, dx1, dy1, dx2, dy2, dx3, dy3);\n\t\t\t\taddCubicBezier(state, dx4, dy4, dx5, dy5, dx6, dy6);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase Op.hflex: {\n\t\t\t// dx1 dx2 dy2 dx3 dx4 dx5 dx6\n\t\t\tif (stack.length >= 7) {\n\t\t\t\tconst dx1 = stack.shift();\n\t\t\t\tif (dx1 === undefined) break;\n\t\t\t\tconst dx2 = stack.shift();\n\t\t\t\tif (dx2 === undefined) break;\n\t\t\t\tconst dy2 = stack.shift();\n\t\t\t\tif (dy2 === undefined) break;\n\t\t\t\tconst dx3 = stack.shift();\n\t\t\t\tif (dx3 === undefined) break;\n\t\t\t\tconst dx4 = stack.shift();\n\t\t\t\tif (dx4 === undefined) break;\n\t\t\t\tconst dx5 = stack.shift();\n\t\t\t\tif (dx5 === undefined) break;\n\t\t\t\tconst dx6 = stack.shift();\n\t\t\t\tif (dx6 === undefined) break;\n\t\t\t\taddCubicBezier(state, dx1, 0, dx2, dy2, dx3, 0);\n\t\t\t\taddCubicBezier(state, dx4, 0, dx5, -dy2, dx6, 0);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase Op.hflex1: {\n\t\t\t// dx1 dy1 dx2 dy2 dx3 dx4 dx5 dy5 dx6\n\t\t\tif (stack.length >= 9) {\n\t\t\t\tconst dx1 = stack.shift();\n\t\t\t\tif (dx1 === undefined) break;\n\t\t\t\tconst dy1 = stack.shift();\n\t\t\t\tif (dy1 === undefined) break;\n\t\t\t\tconst dx2 = stack.shift();\n\t\t\t\tif (dx2 === undefined) break;\n\t\t\t\tconst dy2 = stack.shift();\n\t\t\t\tif (dy2 === undefined) break;\n\t\t\t\tconst dx3 = stack.shift();\n\t\t\t\tif (dx3 === undefined) break;\n\t\t\t\tconst dx4 = stack.shift();\n\t\t\t\tif (dx4 === undefined) break;\n\t\t\t\tconst dx5 = stack.shift();\n\t\t\t\tif (dx5 === undefined) break;\n\t\t\t\tconst dy5 = stack.shift();\n\t\t\t\tif (dy5 === undefined) break;\n\t\t\t\tconst dx6 = stack.shift();\n\t\t\t\tif (dx6 === undefined) break;\n\t\t\t\taddCubicBezier(state, dx1, dy1, dx2, dy2, dx3, 0);\n\t\t\t\taddCubicBezier(state, dx4, 0, dx5, dy5, dx6, -(dy1 + dy2 + dy5));\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase Op.flex1: {\n\t\t\t// dx1 dy1 dx2 dy2 dx3 dy3 dx4 dy4 dx5 dy5 d6\n\t\t\tif (stack.length >= 11) {\n\t\t\t\tconst dx1 = stack.shift();\n\t\t\t\tif (dx1 === undefined) break;\n\t\t\t\tconst dy1 = stack.shift();\n\t\t\t\tif (dy1 === undefined) break;\n\t\t\t\tconst dx2 = stack.shift();\n\t\t\t\tif (dx2 === undefined) break;\n\t\t\t\tconst dy2 = stack.shift();\n\t\t\t\tif (dy2 === undefined) break;\n\t\t\t\tconst dx3 = stack.shift();\n\t\t\t\tif (dx3 === undefined) break;\n\t\t\t\tconst dy3 = stack.shift();\n\t\t\t\tif (dy3 === undefined) break;\n\t\t\t\tconst dx4 = stack.shift();\n\t\t\t\tif (dx4 === undefined) break;\n\t\t\t\tconst dy4 = stack.shift();\n\t\t\t\tif (dy4 === undefined) break;\n\t\t\t\tconst dx5 = stack.shift();\n\t\t\t\tif (dx5 === undefined) break;\n\t\t\t\tconst dy5 = stack.shift();\n\t\t\t\tif (dy5 === undefined) break;\n\t\t\t\tconst d6 = stack.shift();\n\t\t\t\tif (d6 === undefined) break;\n\n\t\t\t\tconst dx = dx1 + dx2 + dx3 + dx4 + dx5;\n\t\t\t\tconst dy = dy1 + dy2 + dy3 + dy4 + dy5;\n\n\t\t\t\tlet dx6: number, dy6: number;\n\t\t\t\tif (Math.abs(dx) > Math.abs(dy)) {\n\t\t\t\t\tdx6 = d6;\n\t\t\t\t\tdy6 = -dy;\n\t\t\t\t} else {\n\t\t\t\t\tdx6 = -dx;\n\t\t\t\t\tdy6 = d6;\n\t\t\t\t}\n\n\t\t\t\taddCubicBezier(state, dx1, dy1, dx2, dy2, dx3, dy3);\n\t\t\t\taddCubicBezier(state, dx4, dy4, dx5, dy5, dx6, dy6);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\t// Arithmetic operators\n\t\tcase Op.and_: {\n\t\t\tconst b = stack.pop();\n\t\t\tif (b === undefined) break;\n\t\t\tconst a = stack.pop();\n\t\t\tif (a === undefined) break;\n\t\t\tstack.push(a && b ? 1 : 0);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase Op.or_: {\n\t\t\tconst b = stack.pop();\n\t\t\tif (b === undefined) break;\n\t\t\tconst a = stack.pop();\n\t\t\tif (a === undefined) break;\n\t\t\tstack.push(a || b ? 1 : 0);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase Op.not_: {\n\t\t\tconst a = stack.pop();\n\t\t\tif (a === undefined) break;\n\t\t\tstack.push(a ? 0 : 1);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase Op.abs_: {\n\t\t\tconst a = stack.pop();\n\t\t\tif (a === undefined) break;\n\t\t\tstack.push(Math.abs(a));\n\t\t\tbreak;\n\t\t}\n\n\t\tcase Op.add_: {\n\t\t\tconst b = stack.pop();\n\t\t\tif (b === undefined) break;\n\t\t\tconst a = stack.pop();\n\t\t\tif (a === undefined) break;\n\t\t\tstack.push(a + b);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase Op.sub_: {\n\t\t\tconst b = stack.pop();\n\t\t\tif (b === undefined) break;\n\t\t\tconst a = stack.pop();\n\t\t\tif (a === undefined) break;\n\t\t\tstack.push(a - b);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase Op.div_: {\n\t\t\tconst b = stack.pop();\n\t\t\tif (b === undefined) break;\n\t\t\tconst a = stack.pop();\n\t\t\tif (a === undefined) break;\n\t\t\tstack.push(a / b);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase Op.neg_: {\n\t\t\tconst a = stack.pop();\n\t\t\tif (a === undefined) break;\n\t\t\tstack.push(-a);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase Op.eq_: {\n\t\t\tconst b = stack.pop();\n\t\t\tif (b === undefined) break;\n\t\t\tconst a = stack.pop();\n\t\t\tif (a === undefined) break;\n\t\t\tstack.push(a === b ? 1 : 0);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase Op.drop_: {\n\t\t\tstack.pop();\n\t\t\tbreak;\n\t\t}\n\n\t\tcase Op.put_: {\n\t\t\tconst i = stack.pop();\n\t\t\tif (i === undefined) break;\n\t\t\tconst val = stack.pop();\n\t\t\tif (val === undefined) break;\n\t\t\tstate.transientArray[i] = val;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase Op.get_: {\n\t\t\tconst i = stack.pop();\n\t\t\tif (i === undefined) break;\n\t\t\tstack.push(state.transientArray[i] ?? 0);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase Op.ifelse_: {\n\t\t\tconst v2 = stack.pop();\n\t\t\tif (v2 === undefined) break;\n\t\t\tconst v1 = stack.pop();\n\t\t\tif (v1 === undefined) break;\n\t\t\tconst s2 = stack.pop();\n\t\t\tif (s2 === undefined) break;\n\t\t\tconst s1 = stack.pop();\n\t\t\tif (s1 === undefined) break;\n\t\t\tstack.push(v1 <= v2 ? s1 : s2);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase Op.random_: {\n\t\t\tstack.push(Math.random());\n\t\t\tbreak;\n\t\t}\n\n\t\tcase Op.mul_: {\n\t\t\tconst b = stack.pop();\n\t\t\tif (b === undefined) break;\n\t\t\tconst a = stack.pop();\n\t\t\tif (a === undefined) break;\n\t\t\tstack.push(a * b);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase Op.sqrt_: {\n\t\t\tconst a = stack.pop();\n\t\t\tif (a === undefined) break;\n\t\t\tstack.push(Math.sqrt(a));\n\t\t\tbreak;\n\t\t}\n\n\t\tcase Op.dup_: {\n\t\t\tconst a = stack[stack.length - 1];\n\t\t\tif (a === undefined) break;\n\t\t\tstack.push(a);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase Op.exch_: {\n\t\t\tconst b = stack.pop();\n\t\t\tif (b === undefined) break;\n\t\t\tconst a = stack.pop();\n\t\t\tif (a === undefined) break;\n\t\t\tstack.push(b, a);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase Op.index_: {\n\t\t\tconst i = stack.pop();\n\t\t\tif (i === undefined) break;\n\t\t\tconst idx = stack.length - 1 - i;\n\t\t\tstack.push(stack[idx] ?? 0);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase Op.roll_: {\n\t\t\tconst j = stack.pop();\n\t\t\tif (j === undefined) break;\n\t\t\tconst n = stack.pop();\n\t\t\tif (n === undefined) break;\n\t\t\tif (n > 0) {\n\t\t\t\tconst items = stack.splice(-n);\n\t\t\t\tconst shift = ((j % n) + n) % n;\n\t\t\t\tfor (let i = 0; i < n; i++) {\n\t\t\t\t\tconst item = items[(i + shift) % n];\n\t\t\t\t\tif (item !== undefined) {\n\t\t\t\t\t\tstack.push(item);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\t// CFF2 blend operator\n\t\tcase Op.blend: {\n\t\t\tif (!state.axisCoords || !state.vstore) break;\n\n\t\t\tconst n = stack.pop();\n\t\t\tif (n === undefined) break;\n\t\t\tconst regionCount =\n\t\t\t\tstate.vstore.itemVariationData[state.vsindex]?.regionIndexCount ?? 0;\n\n\t\t\t// For each of n values, there are regionCount deltas\n\t\t\tconst totalDeltaCount = n * regionCount;\n\t\t\tconst deltas = stack.splice(-totalDeltaCount);\n\t\t\tconst defaults = stack.splice(-n);\n\n\t\t\tfor (let i = 0; i < n; i++) {\n\t\t\t\tconst defaultVal = defaults[i];\n\t\t\t\tif (defaultVal === undefined) continue;\n\t\t\t\tlet value = defaultVal;\n\t\t\t\tfor (let r = 0; r < regionCount; r++) {\n\t\t\t\t\tconst delta = deltas[i * regionCount + r];\n\t\t\t\t\tif (delta === undefined) continue;\n\t\t\t\t\tconst scalar = computeRegionScalar(\n\t\t\t\t\t\tstate.vstore,\n\t\t\t\t\t\tstate.vsindex,\n\t\t\t\t\t\tr,\n\t\t\t\t\t\tstate.axisCoords,\n\t\t\t\t\t);\n\t\t\t\t\tvalue += delta * scalar;\n\t\t\t\t}\n\t\t\t\tstack.push(value);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase Op.vsindex: {\n\t\t\tconst vsindex = stack.pop();\n\t\t\tif (vsindex === undefined) break;\n\t\t\tstate.vsindex = vsindex;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase Op.dotsection:\n\t\t\t// Deprecated, ignore\n\t\t\tbreak;\n\t}\n}\n\nfunction addCubicBezier(\n\tstate: CharStringState,\n\tdx1: number,\n\tdy1: number,\n\tdx2: number,\n\tdy2: number,\n\tdx3: number,\n\tdy3: number,\n): void {\n\t// CFF uses cubic Beziers\n\t// Store control points with onCurve: false and special marker for cubic\n\t// We use a convention: cubic control points are stored as pairs with a special flag\n\n\tconst x0 = state.x;\n\tconst y0 = state.y;\n\tconst x1 = x0 + dx1;\n\tconst y1 = y0 + dy1;\n\tconst x2 = x1 + dx2;\n\tconst y2 = y1 + dy2;\n\tconst x3 = x2 + dx3;\n\tconst y3 = y2 + dy3;\n\n\t// Store as: cp1 (cubic=true), cp2 (cubic=true), endpoint (onCurve=true)\n\t// The 'cubic' property distinguishes this from TrueType quadratic off-curve points\n\tstate.currentContour.push({\n\t\tx: x1,\n\t\ty: y1,\n\t\tonCurve: false,\n\t\tcubic: true,\n\t} as GlyphPoint);\n\tstate.currentContour.push({\n\t\tx: x2,\n\t\ty: y2,\n\t\tonCurve: false,\n\t\tcubic: true,\n\t} as GlyphPoint);\n\tstate.currentContour.push({ x: x3, y: y3, onCurve: true });\n\n\tstate.x = x3;\n\tstate.y = y3;\n}\n\nfunction _approximateCubicWithQuadratics(\n\tstate: CharStringState,\n\tx0: number,\n\ty0: number,\n\tx1: number,\n\ty1: number,\n\tx2: number,\n\ty2: number,\n\tx3: number,\n\ty3: number,\n\tdepth: number,\n): void {\n\t// Maximum recursion depth\n\tif (depth > 4) {\n\t\t// Just use a simple quadratic approximation\n\t\tconst qx = (3 * (x1 + x2) - (x0 + x3)) / 4;\n\t\tconst qy = (3 * (y1 + y2) - (y0 + y3)) / 4;\n\t\tstate.currentContour.push({ x: qx, y: qy, onCurve: false });\n\t\tstate.currentContour.push({ x: x3, y: y3, onCurve: true });\n\t\treturn;\n\t}\n\n\t// Check if cubic is close enough to a quadratic\n\t// by measuring the distance from control points to the line\n\tconst tolerance = 0.5;\n\n\t// Calculate the quadratic control point that would give the same tangents\n\tconst qx = (3 * (x1 + x2) - (x0 + x3)) / 4;\n\tconst qy = (3 * (y1 + y2) - (y0 + y3)) / 4;\n\n\t// Check error - simplified check\n\tconst err1 =\n\t\tMath.abs(x1 - (x0 + 2 * qx) / 3 - x0 / 3) +\n\t\tMath.abs(y1 - (y0 + 2 * qy) / 3 - y0 / 3);\n\tconst err2 =\n\t\tMath.abs(x2 - (2 * qx + x3) / 3 - x3 / 3) +\n\t\tMath.abs(y2 - (2 * qy + y3) / 3 - y3 / 3);\n\n\tif (err1 + err2 < tolerance) {\n\t\t// Good enough approximation\n\t\tstate.currentContour.push({ x: qx, y: qy, onCurve: false });\n\t\tstate.currentContour.push({ x: x3, y: y3, onCurve: true });\n\t} else {\n\t\t// Subdivide the cubic\n\t\tconst mx1 = (x0 + x1) / 2;\n\t\tconst my1 = (y0 + y1) / 2;\n\t\tconst mx2 = (x1 + x2) / 2;\n\t\tconst my2 = (y1 + y2) / 2;\n\t\tconst mx3 = (x2 + x3) / 2;\n\t\tconst my3 = (y2 + y3) / 2;\n\n\t\tconst mmx1 = (mx1 + mx2) / 2;\n\t\tconst mmy1 = (my1 + my2) / 2;\n\t\tconst mmx2 = (mx2 + mx3) / 2;\n\t\tconst mmy2 = (my2 + my3) / 2;\n\n\t\tconst midx = (mmx1 + mmx2) / 2;\n\t\tconst midy = (mmy1 + mmy2) / 2;\n\n\t\t// Recurse on both halves\n\t\t_approximateCubicWithQuadratics(\n\t\t\tstate,\n\t\t\tx0,\n\t\t\ty0,\n\t\t\tmx1,\n\t\t\tmy1,\n\t\t\tmmx1,\n\t\t\tmmy1,\n\t\t\tmidx,\n\t\t\tmidy,\n\t\t\tdepth + 1,\n\t\t);\n\t\t_approximateCubicWithQuadratics(\n\t\t\tstate,\n\t\t\tmidx,\n\t\t\tmidy,\n\t\t\tmmx2,\n\t\t\tmmy2,\n\t\t\tmx3,\n\t\t\tmy3,\n\t\t\tx3,\n\t\t\ty3,\n\t\t\tdepth + 1,\n\t\t);\n\t}\n}\n\nfunction getSubrBias(count: number): number {\n\tif (count < 1240) return 107;\n\tif (count < 33900) return 1131;\n\treturn 32768;\n}\n\nfunction computeRegionScalar(\n\tvstore: ItemVariationStore,\n\tvsindex: number,\n\tregionIndex: number,\n\taxisCoords: number[],\n): number {\n\tconst data = vstore.itemVariationData[vsindex];\n\tif (!data) return 0;\n\n\tconst actualRegionIndex = data.regionIndexes[regionIndex];\n\tif (actualRegionIndex === undefined) return 0;\n\n\tconst region = vstore.variationRegionList.regions[actualRegionIndex];\n\tif (!region) return 0;\n\n\tlet scalar = 1;\n\tfor (let i = 0; i < region.axes.length && i < axisCoords.length; i++) {\n\t\tconst coords = region.axes[i];\n\t\tif (!coords) continue;\n\t\tconst coord = axisCoords[i];\n\t\tif (coord === undefined) continue;\n\n\t\tif (coord < coords.startCoord || coord > coords.endCoord) {\n\t\t\treturn 0;\n\t\t}\n\n\t\tif (coord === coords.peakCoord) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (coord < coords.peakCoord) {\n\t\t\tscalar *=\n\t\t\t\t(coord - coords.startCoord) / (coords.peakCoord - coords.startCoord);\n\t\t} else {\n\t\t\tscalar *=\n\t\t\t\t(coords.endCoord - coord) / (coords.endCoord - coords.peakCoord);\n\t\t}\n\t}\n\n\treturn scalar;\n}\n\n/**\n * Get glyph width from CFF charstring\n */\nexport function getCffGlyphWidth(\n\tcff: CffTable,\n\t_glyphId: GlyphId,\n\tfontIndex: number = 0,\n): number {\n\t// Would need to parse charstring just enough to get width\n\t// For now, return nominalWidthX as default\n\tconst _topDict = cff.topDicts[fontIndex];\n\treturn 0; // Proper implementation would parse the charstring\n}\n",
24
- "import { Reader } from \"../binary/reader.ts\";\n\n/**\n * CFF2 (Compact Font Format 2) table parser\n * Used by variable fonts with PostScript outlines\n */\n\nexport interface Cff2Table {\n\tversion: { major: number; minor: number };\n\ttopDict: Cff2TopDict;\n\tglobalSubrs: Uint8Array[];\n\tcharStrings: Uint8Array[];\n\tfdArray: Cff2FDDict[];\n\tfdSelect: Cff2FDSelect | null;\n\tvstore: ItemVariationStore | null;\n}\n\nexport interface Cff2TopDict {\n\tcharStrings?: number;\n\tfdArray?: number;\n\tfdSelect?: number;\n\tvstore?: number;\n\tfontMatrix?: number[];\n}\n\nexport interface Cff2PrivateDict {\n\tblueValues?: number[];\n\totherBlues?: number[];\n\tfamilyBlues?: number[];\n\tfamilyOtherBlues?: number[];\n\tblueScale?: number;\n\tblueShift?: number;\n\tblueFuzz?: number;\n\tstdHW?: number;\n\tstdVW?: number;\n\tstemSnapH?: number[];\n\tstemSnapV?: number[];\n\tlanguageGroup?: number;\n\texpansionFactor?: number;\n\tsubrs?: number;\n\tvsindex?: number;\n\tblend?: number[];\n}\n\nexport interface Cff2FDDict {\n\tfontName?: string;\n\tprivate?: Cff2PrivateDict;\n\tprivateOffset?: number;\n\tprivateSize?: number;\n\tlocalSubrs?: Uint8Array[];\n}\n\nexport interface Cff2FDSelect {\n\tformat: number;\n\tselect: (glyphId: number) => number;\n}\n\nexport interface ItemVariationStore {\n\tformat: number;\n\tvariationRegionList: VariationRegionList;\n\titemVariationData: ItemVariationData[];\n}\n\nexport interface VariationRegionList {\n\taxisCount: number;\n\tregionCount: number;\n\tregions: VariationRegion[];\n}\n\nexport interface VariationRegion {\n\taxes: RegionAxisCoordinates[];\n}\n\nexport interface RegionAxisCoordinates {\n\tstartCoord: number;\n\tpeakCoord: number;\n\tendCoord: number;\n}\n\nexport interface ItemVariationData {\n\titemCount: number;\n\tregionIndexCount: number;\n\tregionIndexes: number[];\n\tdeltaSets: number[][];\n}\n\n// CFF2 Top DICT operators\nenum Cff2TopDictOp {\n\tFontMatrix = 0x0c07,\n\tCharStrings = 17,\n\tFDArray = 0x0c24,\n\tFDSelect = 0x0c25,\n\tvstore = 24,\n}\n\n// CFF2 Private DICT operators\nenum Cff2PrivateDictOp {\n\tBlueValues = 6,\n\tOtherBlues = 7,\n\tFamilyBlues = 8,\n\tFamilyOtherBlues = 9,\n\tStdHW = 10,\n\tStdVW = 11,\n\tSubrs = 19,\n\tvsindex = 22,\n\tblend = 23,\n\tBlueScale = 0x0c09,\n\tBlueShift = 0x0c0a,\n\tBlueFuzz = 0x0c0b,\n\tStemSnapH = 0x0c0c,\n\tStemSnapV = 0x0c0d,\n\tLanguageGroup = 0x0c11,\n\tExpansionFactor = 0x0c12,\n}\n\n/**\n * Parse CFF2 table\n */\nexport function parseCff2(reader: Reader): Cff2Table {\n\tconst startOffset = reader.offset;\n\n\t// Header\n\tconst major = reader.uint8();\n\tconst minor = reader.uint8();\n\tconst headerSize = reader.uint8();\n\tconst topDictLength = reader.uint16();\n\n\t// Skip to after header\n\treader.seek(startOffset + headerSize);\n\n\t// Top DICT (not an INDEX in CFF2, just raw data)\n\tconst topDictReader = reader.slice(\n\t\treader.offset - startOffset,\n\t\ttopDictLength,\n\t);\n\treader.skip(topDictLength);\n\tconst topDict = parseCff2TopDict(topDictReader);\n\n\t// Global Subr INDEX\n\tconst globalSubrs = parseIndex(reader);\n\n\t// CharStrings INDEX\n\tlet charStrings: Uint8Array[] = [];\n\tif (topDict.charStrings !== undefined) {\n\t\treader.seek(startOffset + topDict.charStrings);\n\t\tcharStrings = parseIndex(reader);\n\t}\n\n\t// FDArray INDEX\n\tconst fdArray: Cff2FDDict[] = [];\n\tif (topDict.fdArray !== undefined) {\n\t\treader.seek(startOffset + topDict.fdArray);\n\t\tconst fdDictData = parseIndex(reader);\n\n\t\tfor (const data of fdDictData) {\n\t\t\tconst fd = parseCff2FDDict(\n\t\t\t\tnew Reader(\n\t\t\t\t\tdata.buffer as ArrayBuffer,\n\t\t\t\t\tdata.byteOffset,\n\t\t\t\t\tdata.byteLength,\n\t\t\t\t),\n\t\t\t);\n\n\t\t\t// Parse local subrs if Private DICT has them\n\t\t\tif (fd.privateOffset !== undefined && fd.privateSize !== undefined) {\n\t\t\t\treader.seek(startOffset + fd.privateOffset);\n\t\t\t\tconst privateReader = reader.slice(0, fd.privateSize);\n\t\t\t\tfd.private = parseCff2PrivateDict(privateReader);\n\n\t\t\t\tif (fd.private.subrs !== undefined) {\n\t\t\t\t\treader.seek(startOffset + fd.privateOffset + fd.private.subrs);\n\t\t\t\t\tfd.localSubrs = parseIndex(reader);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfdArray.push(fd);\n\t\t}\n\t}\n\n\t// FDSelect\n\tlet fdSelect: Cff2FDSelect | null = null;\n\tif (topDict.fdSelect !== undefined) {\n\t\treader.seek(startOffset + topDict.fdSelect);\n\t\tfdSelect = parseFDSelect(reader, charStrings.length);\n\t}\n\n\t// Variation Store\n\tlet vstore: ItemVariationStore | null = null;\n\tif (topDict.vstore !== undefined) {\n\t\treader.seek(startOffset + topDict.vstore);\n\t\tvstore = parseItemVariationStore(reader);\n\t}\n\n\treturn {\n\t\tversion: { major, minor },\n\t\ttopDict,\n\t\tglobalSubrs,\n\t\tcharStrings,\n\t\tfdArray,\n\t\tfdSelect,\n\t\tvstore,\n\t};\n}\n\n/**\n * Parse CFF2 INDEX structure (uses 32-bit count)\n */\nfunction parseIndex(reader: Reader): Uint8Array[] {\n\tconst count = reader.uint32();\n\tif (count === 0) return [];\n\n\tconst offSize = reader.uint8();\n\tconst offsets: number[] = [];\n\n\tfor (let i = 0; i <= count; i++) {\n\t\toffsets.push(readOffset(reader, offSize));\n\t}\n\n\tconst result: Uint8Array[] = [];\n\tfor (let i = 0; i < count; i++) {\n\t\tconst start = offsets[i];\n\t\tconst end = offsets[i + 1];\n\t\tif (start === undefined || end === undefined) continue;\n\t\tconst length = end - start;\n\t\tresult.push(reader.bytes(length));\n\t}\n\n\treturn result;\n}\n\n/**\n * Read offset of given size\n */\nfunction readOffset(reader: Reader, offSize: number): number {\n\tswitch (offSize) {\n\t\tcase 1:\n\t\t\treturn reader.uint8();\n\t\tcase 2:\n\t\t\treturn reader.uint16();\n\t\tcase 3:\n\t\t\treturn reader.uint24();\n\t\tcase 4:\n\t\t\treturn reader.uint32();\n\t\tdefault:\n\t\t\tthrow new Error(`Invalid offset size: ${offSize}`);\n\t}\n}\n\n/**\n * Parse a CFF2 DICT structure\n */\nfunction parseDict(reader: Reader): Map<number, number[]> {\n\tconst result = new Map<number, number[]>();\n\tconst operands: number[] = [];\n\n\twhile (reader.remaining > 0) {\n\t\tconst b0 = reader.uint8();\n\n\t\tif (b0 <= 21) {\n\t\t\t// Operator\n\t\t\tlet op = b0;\n\t\t\tif (b0 === 12) {\n\t\t\t\top = 0x0c00 | reader.uint8();\n\t\t\t}\n\t\t\tresult.set(op, [...operands]);\n\t\t\toperands.length = 0;\n\t\t} else if (b0 === 22) {\n\t\t\t// vsindex operator\n\t\t\tresult.set(22, [...operands]);\n\t\t\toperands.length = 0;\n\t\t} else if (b0 === 23) {\n\t\t\t// blend operator\n\t\t\tresult.set(23, [...operands]);\n\t\t\toperands.length = 0;\n\t\t} else if (b0 === 24) {\n\t\t\t// vstore operator\n\t\t\tresult.set(24, [...operands]);\n\t\t\toperands.length = 0;\n\t\t} else if (b0 === 28) {\n\t\t\t// 16-bit signed integer\n\t\t\toperands.push(reader.int16());\n\t\t} else if (b0 === 29) {\n\t\t\t// 32-bit signed integer\n\t\t\toperands.push(reader.int32());\n\t\t} else if (b0 === 30) {\n\t\t\t// Real number\n\t\t\toperands.push(parseReal(reader));\n\t\t} else if (b0 >= 32 && b0 <= 246) {\n\t\t\toperands.push(b0 - 139);\n\t\t} else if (b0 >= 247 && b0 <= 250) {\n\t\t\tconst b1 = reader.uint8();\n\t\t\toperands.push((b0 - 247) * 256 + b1 + 108);\n\t\t} else if (b0 >= 251 && b0 <= 254) {\n\t\t\tconst b1 = reader.uint8();\n\t\t\toperands.push(-(b0 - 251) * 256 - b1 - 108);\n\t\t}\n\t}\n\n\treturn result;\n}\n\n/**\n * Parse real number\n */\nfunction parseReal(reader: Reader): number {\n\tlet str = \"\";\n\tconst nibbleChars = \"0123456789.EE -\";\n\tlet done = false;\n\n\twhile (!done) {\n\t\tconst byte = reader.uint8();\n\t\tfor (let i = 0; i < 2; i++) {\n\t\t\tconst nibble = i === 0 ? byte >> 4 : byte & 0x0f;\n\t\t\tif (nibble === 0x0f) {\n\t\t\t\tdone = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (nibble === 0x0c) {\n\t\t\t\tstr += \"E-\";\n\t\t\t} else {\n\t\t\t\tconst char = nibbleChars[nibble];\n\t\t\t\tif (char !== undefined) str += char;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn parseFloat(str);\n}\n\n/**\n * Parse CFF2 Top DICT\n */\nfunction parseCff2TopDict(reader: Reader): Cff2TopDict {\n\tconst dict = parseDict(reader);\n\tconst result: Cff2TopDict = {};\n\n\tfor (const [op, operands] of dict) {\n\t\tswitch (op) {\n\t\t\tcase Cff2TopDictOp.FontMatrix:\n\t\t\t\tresult.fontMatrix = operands;\n\t\t\t\tbreak;\n\t\t\tcase Cff2TopDictOp.CharStrings:\n\t\t\t\tresult.charStrings = operands[0];\n\t\t\t\tbreak;\n\t\t\tcase Cff2TopDictOp.FDArray:\n\t\t\t\tresult.fdArray = operands[0];\n\t\t\t\tbreak;\n\t\t\tcase Cff2TopDictOp.FDSelect:\n\t\t\t\tresult.fdSelect = operands[0];\n\t\t\t\tbreak;\n\t\t\tcase Cff2TopDictOp.vstore:\n\t\t\t\tresult.vstore = operands[0];\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn result;\n}\n\n/**\n * Parse CFF2 FD DICT\n */\nfunction parseCff2FDDict(reader: Reader): Cff2FDDict {\n\tconst dict = parseDict(reader);\n\tconst result: Cff2FDDict = {};\n\n\t// Private DICT pointer (operator 18)\n\tconst privateOp = dict.get(18);\n\tif (privateOp && privateOp.length >= 2) {\n\t\tresult.privateSize = privateOp[0];\n\t\tresult.privateOffset = privateOp[1];\n\t}\n\n\treturn result;\n}\n\n/**\n * Parse CFF2 Private DICT\n */\nfunction parseCff2PrivateDict(reader: Reader): Cff2PrivateDict {\n\tconst dict = parseDict(reader);\n\tconst result: Cff2PrivateDict = {};\n\n\tfor (const [op, operands] of dict) {\n\t\tconst op0 = operands[0];\n\n\t\tswitch (op) {\n\t\t\tcase Cff2PrivateDictOp.BlueValues:\n\t\t\t\tresult.blueValues = deltaToAbsolute(operands);\n\t\t\t\tbreak;\n\t\t\tcase Cff2PrivateDictOp.OtherBlues:\n\t\t\t\tresult.otherBlues = deltaToAbsolute(operands);\n\t\t\t\tbreak;\n\t\t\tcase Cff2PrivateDictOp.FamilyBlues:\n\t\t\t\tresult.familyBlues = deltaToAbsolute(operands);\n\t\t\t\tbreak;\n\t\t\tcase Cff2PrivateDictOp.FamilyOtherBlues:\n\t\t\t\tresult.familyOtherBlues = deltaToAbsolute(operands);\n\t\t\t\tbreak;\n\t\t\tcase Cff2PrivateDictOp.BlueScale:\n\t\t\t\tresult.blueScale = op0;\n\t\t\t\tbreak;\n\t\t\tcase Cff2PrivateDictOp.BlueShift:\n\t\t\t\tresult.blueShift = op0;\n\t\t\t\tbreak;\n\t\t\tcase Cff2PrivateDictOp.BlueFuzz:\n\t\t\t\tresult.blueFuzz = op0;\n\t\t\t\tbreak;\n\t\t\tcase Cff2PrivateDictOp.StdHW:\n\t\t\t\tresult.stdHW = op0;\n\t\t\t\tbreak;\n\t\t\tcase Cff2PrivateDictOp.StdVW:\n\t\t\t\tresult.stdVW = op0;\n\t\t\t\tbreak;\n\t\t\tcase Cff2PrivateDictOp.StemSnapH:\n\t\t\t\tresult.stemSnapH = deltaToAbsolute(operands);\n\t\t\t\tbreak;\n\t\t\tcase Cff2PrivateDictOp.StemSnapV:\n\t\t\t\tresult.stemSnapV = deltaToAbsolute(operands);\n\t\t\t\tbreak;\n\t\t\tcase Cff2PrivateDictOp.LanguageGroup:\n\t\t\t\tresult.languageGroup = op0;\n\t\t\t\tbreak;\n\t\t\tcase Cff2PrivateDictOp.ExpansionFactor:\n\t\t\t\tresult.expansionFactor = op0;\n\t\t\t\tbreak;\n\t\t\tcase Cff2PrivateDictOp.Subrs:\n\t\t\t\tresult.subrs = op0;\n\t\t\t\tbreak;\n\t\t\tcase Cff2PrivateDictOp.vsindex:\n\t\t\t\tresult.vsindex = op0;\n\t\t\t\tbreak;\n\t\t\tcase Cff2PrivateDictOp.blend:\n\t\t\t\tresult.blend = operands;\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn result;\n}\n\n/**\n * Convert delta-encoded values to absolute\n */\nfunction deltaToAbsolute(deltas: number[]): number[] {\n\tconst result: number[] = [];\n\tlet value = 0;\n\tfor (const delta of deltas) {\n\t\tvalue += delta;\n\t\tresult.push(value);\n\t}\n\treturn result;\n}\n\n/**\n * Parse FDSelect structure\n */\nfunction parseFDSelect(reader: Reader, numGlyphs: number): Cff2FDSelect {\n\tconst format = reader.uint8();\n\n\tif (format === 0) {\n\t\tconst fds = reader.uint8Array(numGlyphs);\n\t\treturn {\n\t\t\tformat,\n\t\t\tselect: (glyphId: number) => fds[glyphId] ?? 0,\n\t\t};\n\t} else if (format === 3) {\n\t\tconst nRanges = reader.uint16();\n\t\tconst ranges: Array<{ first: number; fd: number }> = [];\n\n\t\tfor (let i = 0; i < nRanges; i++) {\n\t\t\tranges.push({\n\t\t\t\tfirst: reader.uint16(),\n\t\t\t\tfd: reader.uint8(),\n\t\t\t});\n\t\t}\n\t\treader.uint16(); // sentinel\n\n\t\treturn {\n\t\t\tformat,\n\t\t\tselect: (glyphId: number) => {\n\t\t\t\tlet lo = 0;\n\t\t\t\tlet hi = ranges.length - 1;\n\t\t\t\twhile (lo < hi) {\n\t\t\t\t\tconst mid = Math.ceil((lo + hi) / 2);\n\t\t\t\t\tconst range = ranges[mid];\n\t\t\t\t\tif (range && range.first <= glyphId) {\n\t\t\t\t\t\tlo = mid;\n\t\t\t\t\t} else {\n\t\t\t\t\t\thi = mid - 1;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconst foundRange = ranges[lo];\n\t\t\t\treturn foundRange?.fd ?? 0;\n\t\t\t},\n\t\t};\n\t} else if (format === 4) {\n\t\t// CFF2 format 4: 32-bit range records\n\t\tconst nRanges = reader.uint32();\n\t\tconst ranges: Array<{ first: number; fd: number }> = [];\n\n\t\tfor (let i = 0; i < nRanges; i++) {\n\t\t\tranges.push({\n\t\t\t\tfirst: reader.uint32(),\n\t\t\t\tfd: reader.uint16(),\n\t\t\t});\n\t\t}\n\t\treader.uint32(); // sentinel\n\n\t\treturn {\n\t\t\tformat,\n\t\t\tselect: (glyphId: number) => {\n\t\t\t\tlet lo = 0;\n\t\t\t\tlet hi = ranges.length - 1;\n\t\t\t\twhile (lo < hi) {\n\t\t\t\t\tconst mid = Math.ceil((lo + hi) / 2);\n\t\t\t\t\tconst range = ranges[mid];\n\t\t\t\t\tif (range && range.first <= glyphId) {\n\t\t\t\t\t\tlo = mid;\n\t\t\t\t\t} else {\n\t\t\t\t\t\thi = mid - 1;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconst foundRange = ranges[lo];\n\t\t\t\treturn foundRange?.fd ?? 0;\n\t\t\t},\n\t\t};\n\t}\n\n\treturn { format, select: () => 0 };\n}\n\n/**\n * Parse ItemVariationStore\n */\nfunction parseItemVariationStore(reader: Reader): ItemVariationStore {\n\tconst startOffset = reader.offset;\n\n\tconst _length = reader.uint16();\n\tconst format = reader.uint16();\n\tconst variationRegionListOffset = reader.uint32();\n\tconst itemVariationDataCount = reader.uint16();\n\tconst itemVariationDataOffsets: number[] = [];\n\n\tfor (let i = 0; i < itemVariationDataCount; i++) {\n\t\titemVariationDataOffsets.push(reader.uint32());\n\t}\n\n\t// Parse VariationRegionList\n\treader.seek(startOffset + variationRegionListOffset);\n\tconst variationRegionList = parseVariationRegionList(reader);\n\n\t// Parse ItemVariationData\n\tconst itemVariationData: ItemVariationData[] = [];\n\tfor (const offset of itemVariationDataOffsets) {\n\t\treader.seek(startOffset + offset);\n\t\titemVariationData.push(parseItemVariationData(reader));\n\t}\n\n\treturn {\n\t\tformat,\n\t\tvariationRegionList,\n\t\titemVariationData,\n\t};\n}\n\n/**\n * Parse VariationRegionList\n */\nfunction parseVariationRegionList(reader: Reader): VariationRegionList {\n\tconst axisCount = reader.uint16();\n\tconst regionCount = reader.uint16();\n\tconst regions: VariationRegion[] = [];\n\n\tfor (let i = 0; i < regionCount; i++) {\n\t\tconst axes: RegionAxisCoordinates[] = [];\n\t\tfor (let j = 0; j < axisCount; j++) {\n\t\t\taxes.push({\n\t\t\t\tstartCoord: reader.f2dot14(),\n\t\t\t\tpeakCoord: reader.f2dot14(),\n\t\t\t\tendCoord: reader.f2dot14(),\n\t\t\t});\n\t\t}\n\t\tregions.push({ axes });\n\t}\n\n\treturn { axisCount, regionCount, regions };\n}\n\n/**\n * Parse ItemVariationData\n */\nfunction parseItemVariationData(reader: Reader): ItemVariationData {\n\tconst itemCount = reader.uint16();\n\tconst wordDeltaCount = reader.uint16();\n\tconst regionIndexCount = wordDeltaCount & 0x7fff;\n\tconst longWords = (wordDeltaCount & 0x8000) !== 0;\n\n\tconst regionIndexes: number[] = [];\n\tfor (let i = 0; i < regionIndexCount; i++) {\n\t\tregionIndexes.push(reader.uint16());\n\t}\n\n\tconst deltaSets: number[][] = [];\n\tfor (let i = 0; i < itemCount; i++) {\n\t\tconst deltas: number[] = [];\n\t\tfor (let j = 0; j < regionIndexCount; j++) {\n\t\t\tif (longWords) {\n\t\t\t\tdeltas.push(reader.int32());\n\t\t\t} else {\n\t\t\t\tdeltas.push(reader.int16());\n\t\t\t}\n\t\t}\n\t\tdeltaSets.push(deltas);\n\t}\n\n\treturn {\n\t\titemCount,\n\t\tregionIndexCount,\n\t\tregionIndexes,\n\t\tdeltaSets,\n\t};\n}\n\n/**\n * Calculate variation delta for given coordinates\n */\nexport function calculateVariationDelta(\n\tvstore: ItemVariationStore,\n\touterIndex: number,\n\tinnerIndex: number,\n\tnormalizedCoords: number[],\n): number {\n\tconst itemData = vstore.itemVariationData[outerIndex];\n\tif (!itemData) return 0;\n\n\tconst deltaSet = itemData.deltaSets[innerIndex];\n\tif (!deltaSet) return 0;\n\n\tlet delta = 0;\n\tfor (let i = 0; i < itemData.regionIndexCount; i++) {\n\t\tconst regionIndex = itemData.regionIndexes[i];\n\t\tif (regionIndex === undefined) continue;\n\t\tconst region = vstore.variationRegionList.regions[regionIndex];\n\t\tif (!region) continue;\n\n\t\t// Calculate scalar for this region\n\t\tlet scalar = 1.0;\n\t\tfor (const [axis, coords] of region.axes.entries()) {\n\t\t\tconst coord = normalizedCoords[axis] ?? 0;\n\n\t\t\tif (coords.peakCoord === 0) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (coord < coords.startCoord || coord > coords.endCoord) {\n\t\t\t\tscalar = 0;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif (coord === coords.peakCoord) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (coord < coords.peakCoord) {\n\t\t\t\tscalar *=\n\t\t\t\t\t(coord - coords.startCoord) / (coords.peakCoord - coords.startCoord);\n\t\t\t} else {\n\t\t\t\tscalar *=\n\t\t\t\t\t(coords.endCoord - coord) / (coords.endCoord - coords.peakCoord);\n\t\t\t}\n\t\t}\n\n\t\tdelta += scalar * (deltaSet[i] ?? 0);\n\t}\n\n\treturn Math.round(delta);\n}\n",
25
- "import type { GlyphId, uint16, uint32 } from \"../../types.ts\";\nimport type { Reader } from \"../binary/reader.ts\";\n\n/** Platform IDs */\nexport enum PlatformId {\n\tUnicode = 0,\n\tMacintosh = 1,\n\tISO = 2, // deprecated\n\tWindows = 3,\n\tCustom = 4,\n}\n\n/** Encoding record in cmap header */\nexport interface EncodingRecord {\n\tplatformId: uint16;\n\tencodingId: uint16;\n\toffset: uint32;\n}\n\n/** Base interface for cmap subtables */\ninterface CmapSubtableBase {\n\tformat: number;\n\tlookup(codepoint: number): GlyphId | undefined;\n}\n\n/** Format 0: Byte encoding table (legacy, 256 entries) */\ninterface CmapFormat0 extends CmapSubtableBase {\n\tformat: 0;\n\tglyphIdArray: Uint8Array;\n}\n\n/** Format 4: Segment mapping to delta values (BMP characters) */\ninterface CmapFormat4 extends CmapSubtableBase {\n\tformat: 4;\n\tsegCount: number;\n\tendCodes: Uint16Array;\n\tstartCodes: Uint16Array;\n\tidDeltas: Int16Array;\n\tidRangeOffsets: Uint16Array;\n\tglyphIdArray: Uint16Array;\n}\n\n/** Format 12: Segmented coverage (full Unicode) */\ninterface CmapFormat12 extends CmapSubtableBase {\n\tformat: 12;\n\tgroups: Array<{\n\t\tstartCharCode: uint32;\n\t\tendCharCode: uint32;\n\t\tstartGlyphId: uint32;\n\t}>;\n}\n\n/** Variation selector record */\ninterface VariationSelectorRecord {\n\tvarSelector: number;\n\tdefaultUVS: Array<{\n\t\tstartUnicodeValue: number;\n\t\tadditionalCount: number;\n\t}> | null;\n\tnonDefaultUVS: Array<{ unicodeValue: number; glyphId: GlyphId }> | null;\n}\n\n/** Format 14: Unicode Variation Sequences */\ninterface CmapFormat14 extends CmapSubtableBase {\n\tformat: 14;\n\tvarSelectorRecords: VariationSelectorRecord[];\n\tlookupVariation(\n\t\tcodepoint: number,\n\t\tvariationSelector: number,\n\t): GlyphId | undefined | \"default\";\n}\n\nexport type CmapSubtable =\n\t| CmapFormat0\n\t| CmapFormat4\n\t| CmapFormat12\n\t| CmapFormat14;\n\n/** Character to glyph index mapping table */\nexport interface CmapTable {\n\tversion: uint16;\n\tnumTables: uint16;\n\tencodingRecords: EncodingRecord[];\n\tsubtables: Map<string, CmapSubtable>;\n\t/** Best subtable for Unicode lookup */\n\tbestSubtable: CmapSubtable | null;\n}\n\nexport function parseCmap(reader: Reader, tableLength: number): CmapTable {\n\tconst _tableStart = reader.offset;\n\tconst version = reader.uint16();\n\tconst numTables = reader.uint16();\n\n\tconst encodingRecords: EncodingRecord[] = [];\n\tfor (let i = 0; i < numTables; i++) {\n\t\tencodingRecords.push({\n\t\t\tplatformId: reader.uint16(),\n\t\t\tencodingId: reader.uint16(),\n\t\t\toffset: reader.uint32(),\n\t\t});\n\t}\n\n\t// Parse subtables\n\tconst subtables = new Map<string, CmapSubtable>();\n\tconst parsedOffsets = new Set<number>();\n\n\tfor (const record of encodingRecords) {\n\t\t// Skip duplicates (multiple records can point to same subtable)\n\t\tif (parsedOffsets.has(record.offset)) {\n\t\t\tconst key = `${record.platformId}-${record.encodingId}`;\n\t\t\t// Find existing subtable\n\t\t\tfor (const [existingKey, subtable] of subtables) {\n\t\t\t\tconst parts = existingKey.split(\"@\");\n\t\t\t\tconst existingOffset = parts[0];\n\t\t\t\tif (\n\t\t\t\t\texistingOffset &&\n\t\t\t\t\tNumber.parseInt(existingOffset, 10) === record.offset\n\t\t\t\t) {\n\t\t\t\t\tsubtables.set(key, subtable);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tparsedOffsets.add(record.offset);\n\n\t\tconst subtableReader = reader.slice(\n\t\t\trecord.offset,\n\t\t\ttableLength - record.offset,\n\t\t);\n\t\tconst subtable = parseCmapSubtable(subtableReader);\n\n\t\tif (subtable) {\n\t\t\tconst key = `${record.platformId}-${record.encodingId}`;\n\t\t\tsubtables.set(key, subtable);\n\t\t}\n\t}\n\n\t// Find best subtable for Unicode lookup\n\t// Prefer: Windows Unicode full (3-10), Unicode full (0-4), Windows BMP (3-1), Unicode BMP (0-3)\n\tconst preferredKeys = [\"3-10\", \"0-4\", \"3-1\", \"0-3\", \"0-6\", \"1-0\"];\n\tlet bestSubtable: CmapSubtable | null = null;\n\n\tfor (const key of preferredKeys) {\n\t\tconst subtable = subtables.get(key);\n\t\tif (subtable && subtable.format !== 14) {\n\t\t\tbestSubtable = subtable;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Fallback to first non-format-14 subtable\n\tif (!bestSubtable) {\n\t\tfor (const subtable of subtables.values()) {\n\t\t\tif (subtable.format !== 14) {\n\t\t\t\tbestSubtable = subtable;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\tversion,\n\t\tnumTables,\n\t\tencodingRecords,\n\t\tsubtables,\n\t\tbestSubtable,\n\t};\n}\n\nfunction parseCmapSubtable(reader: Reader): CmapSubtable | null {\n\tconst format = reader.uint16();\n\n\tswitch (format) {\n\t\tcase 0:\n\t\t\treturn parseCmapFormat0(reader);\n\t\tcase 4:\n\t\t\treturn parseCmapFormat4(reader);\n\t\tcase 12:\n\t\t\treturn parseCmapFormat12(reader);\n\t\tcase 14:\n\t\t\treturn parseCmapFormat14(reader);\n\t\tdefault:\n\t\t\t// Unsupported format - skip\n\t\t\treturn null;\n\t}\n}\n\nfunction parseCmapFormat0(reader: Reader): CmapFormat0 {\n\tconst _length = reader.uint16();\n\tconst _language = reader.uint16();\n\tconst glyphIdArray = reader.uint8Array(256);\n\n\treturn {\n\t\tformat: 0,\n\t\tglyphIdArray,\n\t\tlookup(codepoint: number): GlyphId | undefined {\n\t\t\tif (codepoint >= 0 && codepoint < 256) {\n\t\t\t\treturn glyphIdArray[codepoint];\n\t\t\t}\n\t\t\treturn undefined;\n\t\t},\n\t};\n}\n\nfunction parseCmapFormat4(reader: Reader): CmapFormat4 {\n\tconst _length = reader.uint16();\n\tconst _language = reader.uint16();\n\tconst segCountX2 = reader.uint16();\n\tconst segCount = segCountX2 / 2;\n\n\treader.skip(6); // searchRange, entrySelector, rangeShift\n\n\tconst endCodes = reader.uint16Array(segCount);\n\treader.skip(2); // reservedPad\n\tconst startCodes = reader.uint16Array(segCount);\n\tconst idDeltas = reader.int16Array(segCount);\n\n\t// Save position before idRangeOffsets for glyph ID calculation\n\tconst _idRangeOffsetPos = reader.offset;\n\tconst idRangeOffsets = reader.uint16Array(segCount);\n\n\t// Read remaining glyph IDs\n\tconst remainingBytes = reader.remaining;\n\tconst glyphIdCount = remainingBytes / 2;\n\tconst glyphIdArray = reader.uint16Array(glyphIdCount);\n\n\treturn {\n\t\tformat: 4,\n\t\tsegCount,\n\t\tendCodes,\n\t\tstartCodes,\n\t\tidDeltas,\n\t\tidRangeOffsets,\n\t\tglyphIdArray,\n\t\tlookup(codepoint: number): GlyphId | undefined {\n\t\t\tif (codepoint > 0xffff) return undefined;\n\n\t\t\t// Binary search for segment\n\t\t\tlet low = 0;\n\t\t\tlet high = segCount - 1;\n\n\t\t\twhile (low <= high) {\n\t\t\t\tconst mid = (low + high) >>> 1;\n\t\t\t\tconst endCode = endCodes[mid];\n\t\t\t\tif (endCode === undefined) break;\n\n\t\t\t\tif (codepoint > endCode) {\n\t\t\t\t\tlow = mid + 1;\n\t\t\t\t} else {\n\t\t\t\t\tconst startCode = startCodes[mid];\n\t\t\t\t\tif (startCode === undefined) break;\n\t\t\t\t\tif (codepoint < startCode) {\n\t\t\t\t\t\thigh = mid - 1;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Found segment\n\t\t\t\t\t\tconst idRangeOffset = idRangeOffsets[mid];\n\t\t\t\t\t\tconst idDelta = idDeltas[mid];\n\t\t\t\t\t\tif (idRangeOffset === undefined || idDelta === undefined) break;\n\n\t\t\t\t\t\tif (idRangeOffset === 0) {\n\t\t\t\t\t\t\treturn (codepoint + idDelta) & 0xffff;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Calculate index into glyphIdArray\n\t\t\t\t\t\t// idRangeOffset is relative to its own position in the array\n\t\t\t\t\t\tconst glyphIdIndex =\n\t\t\t\t\t\t\tidRangeOffset / 2 - (segCount - mid) + (codepoint - startCode);\n\n\t\t\t\t\t\tconst glyphId = glyphIdArray[glyphIdIndex];\n\t\t\t\t\t\tif (glyphId === undefined || glyphId === 0) {\n\t\t\t\t\t\t\treturn 0;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn (glyphId + idDelta) & 0xffff;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn undefined;\n\t\t},\n\t};\n}\n\nfunction parseCmapFormat12(reader: Reader): CmapFormat12 {\n\treader.skip(2); // reserved\n\tconst _length = reader.uint32();\n\tconst _language = reader.uint32();\n\tconst numGroups = reader.uint32();\n\n\tconst groups: CmapFormat12[\"groups\"] = new Array(numGroups);\n\tfor (let i = 0; i < numGroups; i++) {\n\t\tgroups[i] = {\n\t\t\tstartCharCode: reader.uint32(),\n\t\t\tendCharCode: reader.uint32(),\n\t\t\tstartGlyphId: reader.uint32(),\n\t\t};\n\t}\n\n\treturn {\n\t\tformat: 12,\n\t\tgroups,\n\t\tlookup(codepoint: number): GlyphId | undefined {\n\t\t\t// Binary search for group\n\t\t\tlet low = 0;\n\t\t\tlet high = groups.length - 1;\n\n\t\t\twhile (low <= high) {\n\t\t\t\tconst mid = (low + high) >>> 1;\n\t\t\t\tconst group = groups[mid];\n\t\t\t\tif (!group) break;\n\n\t\t\t\tif (codepoint > group.endCharCode) {\n\t\t\t\t\tlow = mid + 1;\n\t\t\t\t} else if (codepoint < group.startCharCode) {\n\t\t\t\t\thigh = mid - 1;\n\t\t\t\t} else {\n\t\t\t\t\t// Found group\n\t\t\t\t\treturn group.startGlyphId + (codepoint - group.startCharCode);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn undefined;\n\t\t},\n\t};\n}\n\nfunction parseCmapFormat14(reader: Reader): CmapFormat14 {\n\tconst subtableStart = reader.offset - 2; // Account for format already read\n\tconst _length = reader.uint32();\n\tconst numVarSelectorRecords = reader.uint32();\n\n\t// First pass: read all variation selector records\n\tconst rawRecords: Array<{\n\t\tvarSelector: number;\n\t\tdefaultUVSOffset: number;\n\t\tnonDefaultUVSOffset: number;\n\t}> = [];\n\n\tfor (let i = 0; i < numVarSelectorRecords; i++) {\n\t\trawRecords.push({\n\t\t\tvarSelector: reader.uint24(),\n\t\t\tdefaultUVSOffset: reader.uint32(),\n\t\t\tnonDefaultUVSOffset: reader.uint32(),\n\t\t});\n\t}\n\n\t// Second pass: parse the UVS tables\n\tconst varSelectorRecords: VariationSelectorRecord[] = [];\n\n\tfor (const raw of rawRecords) {\n\t\tlet defaultUVS: VariationSelectorRecord[\"defaultUVS\"] = null;\n\t\tlet nonDefaultUVS: VariationSelectorRecord[\"nonDefaultUVS\"] = null;\n\n\t\t// Parse default UVS table (ranges where default glyph is used)\n\t\tif (raw.defaultUVSOffset !== 0) {\n\t\t\tconst uvsReader = reader.sliceFrom(subtableStart + raw.defaultUVSOffset);\n\t\t\tconst numUnicodeValueRanges = uvsReader.uint32();\n\t\t\tdefaultUVS = [];\n\n\t\t\tfor (let j = 0; j < numUnicodeValueRanges; j++) {\n\t\t\t\tdefaultUVS.push({\n\t\t\t\t\tstartUnicodeValue: uvsReader.uint24(),\n\t\t\t\t\tadditionalCount: uvsReader.uint8(),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t// Parse non-default UVS table (specific glyph mappings)\n\t\tif (raw.nonDefaultUVSOffset !== 0) {\n\t\t\tconst uvsReader = reader.sliceFrom(\n\t\t\t\tsubtableStart + raw.nonDefaultUVSOffset,\n\t\t\t);\n\t\t\tconst numUVSMappings = uvsReader.uint32();\n\t\t\tnonDefaultUVS = [];\n\n\t\t\tfor (let j = 0; j < numUVSMappings; j++) {\n\t\t\t\tnonDefaultUVS.push({\n\t\t\t\t\tunicodeValue: uvsReader.uint24(),\n\t\t\t\t\tglyphId: uvsReader.uint16(),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tvarSelectorRecords.push({\n\t\t\tvarSelector: raw.varSelector,\n\t\t\tdefaultUVS,\n\t\t\tnonDefaultUVS,\n\t\t});\n\t}\n\n\treturn {\n\t\tformat: 14,\n\t\tvarSelectorRecords,\n\t\tlookup(_codepoint: number): GlyphId | undefined {\n\t\t\t// Format 14 is only for variation selectors\n\t\t\treturn undefined;\n\t\t},\n\t\tlookupVariation(\n\t\t\tcodepoint: number,\n\t\t\tvariationSelector: number,\n\t\t): GlyphId | undefined | \"default\" {\n\t\t\t// Binary search for the variation selector\n\t\t\tlet low = 0;\n\t\t\tlet high = varSelectorRecords.length - 1;\n\t\t\tlet record: VariationSelectorRecord | null = null;\n\n\t\t\twhile (low <= high) {\n\t\t\t\tconst mid = (low + high) >>> 1;\n\t\t\t\tconst rec = varSelectorRecords[mid];\n\t\t\t\tif (!rec) break;\n\n\t\t\t\tif (variationSelector > rec.varSelector) {\n\t\t\t\t\tlow = mid + 1;\n\t\t\t\t} else if (variationSelector < rec.varSelector) {\n\t\t\t\t\thigh = mid - 1;\n\t\t\t\t} else {\n\t\t\t\t\trecord = rec;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!record) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\n\t\t\t// Check non-default UVS first (specific glyph mappings)\n\t\t\tif (record.nonDefaultUVS) {\n\t\t\t\tlet lo = 0;\n\t\t\t\tlet hi = record.nonDefaultUVS.length - 1;\n\n\t\t\t\twhile (lo <= hi) {\n\t\t\t\t\tconst mid = (lo + hi) >>> 1;\n\t\t\t\t\tconst mapping = record.nonDefaultUVS[mid];\n\t\t\t\t\tif (!mapping) break;\n\n\t\t\t\t\tif (codepoint > mapping.unicodeValue) {\n\t\t\t\t\t\tlo = mid + 1;\n\t\t\t\t\t} else if (codepoint < mapping.unicodeValue) {\n\t\t\t\t\t\thi = mid - 1;\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn mapping.glyphId;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Check default UVS (use default glyph for base codepoint)\n\t\t\tif (record.defaultUVS) {\n\t\t\t\tfor (const range of record.defaultUVS) {\n\t\t\t\t\tconst end = range.startUnicodeValue + range.additionalCount;\n\t\t\t\t\tif (codepoint >= range.startUnicodeValue && codepoint <= end) {\n\t\t\t\t\t\treturn \"default\"; // Signal to use the default glyph\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn undefined;\n\t\t},\n\t};\n}\n\n/** Get glyph ID for a codepoint using the best subtable */\nexport function getGlyphId(cmap: CmapTable, codepoint: number): GlyphId {\n\treturn cmap.bestSubtable?.lookup(codepoint) ?? 0;\n}\n\n/** Get glyph ID for a variation sequence (base + variation selector) */\nexport function getVariationGlyphId(\n\tcmap: CmapTable,\n\tcodepoint: number,\n\tvariationSelector: number,\n): GlyphId | undefined {\n\t// Find Format 14 subtable\n\tconst format14 = Array.from(cmap.subtables.values()).find(\n\t\t(s): s is CmapFormat14 => s.format === 14,\n\t);\n\n\tif (!format14) {\n\t\treturn undefined;\n\t}\n\n\tconst result = format14.lookupVariation(codepoint, variationSelector);\n\n\tif (result === \"default\") {\n\t\t// Use the default glyph for this codepoint\n\t\treturn getGlyphId(cmap, codepoint);\n\t}\n\n\treturn result;\n}\n\n/** Check if a codepoint is a variation selector */\nexport function isVariationSelector(codepoint: number): boolean {\n\t// Variation Selectors block (VS1-VS16)\n\tif (codepoint >= 0xfe00 && codepoint <= 0xfe0f) {\n\t\treturn true;\n\t}\n\t// Variation Selectors Supplement (VS17-VS256)\n\tif (codepoint >= 0xe0100 && codepoint <= 0xe01ef) {\n\t\treturn true;\n\t}\n\treturn false;\n}\n",
26
- "import type { GlyphId } from \"../../types.ts\";\nimport type { Reader } from \"../binary/reader.ts\";\n\n/**\n * COLR (Color) table parser\n * Defines color glyph layers\n */\n\nexport interface ColrTable {\n\tversion: number;\n\t// v0 data\n\tbaseGlyphRecords: BaseGlyphRecord[];\n\tlayerRecords: LayerRecord[];\n\t// v1 data\n\tbaseGlyphPaintRecords?: BaseGlyphPaintRecord[];\n\tlayerList?: Paint[];\n\tclipList?: ClipRecord[];\n\tvarIdxMap?: number[];\n\titemVariationStore?: ItemVariationStore;\n}\n\n// v0 structures\nexport interface BaseGlyphRecord {\n\tglyphId: GlyphId;\n\tfirstLayerIndex: number;\n\tnumLayers: number;\n}\n\nexport interface LayerRecord {\n\tglyphId: GlyphId;\n\tpaletteIndex: number;\n}\n\n// v1 structures\nexport interface BaseGlyphPaintRecord {\n\tglyphId: GlyphId;\n\tpaint: Paint;\n}\n\n// Paint types for COLR v1\nexport enum PaintFormat {\n\tColrLayers = 1,\n\tSolid = 2,\n\tVarSolid = 3,\n\tLinearGradient = 4,\n\tVarLinearGradient = 5,\n\tRadialGradient = 6,\n\tVarRadialGradient = 7,\n\tSweepGradient = 8,\n\tVarSweepGradient = 9,\n\tGlyph = 10,\n\tColrGlyph = 11,\n\tTransform = 12,\n\tVarTransform = 13,\n\tTranslate = 14,\n\tVarTranslate = 15,\n\tScale = 16,\n\tVarScale = 17,\n\tScaleAroundCenter = 18,\n\tVarScaleAroundCenter = 19,\n\tScaleUniform = 20,\n\tVarScaleUniform = 21,\n\tScaleUniformAroundCenter = 22,\n\tVarScaleUniformAroundCenter = 23,\n\tRotate = 24,\n\tVarRotate = 25,\n\tRotateAroundCenter = 26,\n\tVarRotateAroundCenter = 27,\n\tSkew = 28,\n\tVarSkew = 29,\n\tSkewAroundCenter = 30,\n\tVarSkewAroundCenter = 31,\n\tComposite = 32,\n}\n\nexport type Paint =\n\t| PaintColrLayers\n\t| PaintSolid\n\t| PaintLinearGradient\n\t| PaintRadialGradient\n\t| PaintSweepGradient\n\t| PaintGlyph\n\t| PaintColrGlyph\n\t| PaintTransform\n\t| PaintTranslate\n\t| PaintScale\n\t| PaintRotate\n\t| PaintSkew\n\t| PaintComposite;\n\nexport interface PaintColrLayers {\n\tformat: PaintFormat.ColrLayers;\n\tnumLayers: number;\n\tfirstLayerIndex: number;\n}\n\nexport interface PaintSolid {\n\tformat: PaintFormat.Solid | PaintFormat.VarSolid;\n\tpaletteIndex: number;\n\talpha: number;\n\tvarIndexBase?: number;\n}\n\nexport interface PaintLinearGradient {\n\tformat: PaintFormat.LinearGradient | PaintFormat.VarLinearGradient;\n\tcolorLine: ColorLine;\n\tx0: number;\n\ty0: number;\n\tx1: number;\n\ty1: number;\n\tx2: number;\n\ty2: number;\n}\n\nexport interface PaintRadialGradient {\n\tformat: PaintFormat.RadialGradient | PaintFormat.VarRadialGradient;\n\tcolorLine: ColorLine;\n\tx0: number;\n\ty0: number;\n\tradius0: number;\n\tx1: number;\n\ty1: number;\n\tradius1: number;\n}\n\nexport interface PaintSweepGradient {\n\tformat: PaintFormat.SweepGradient | PaintFormat.VarSweepGradient;\n\tcolorLine: ColorLine;\n\tcenterX: number;\n\tcenterY: number;\n\tstartAngle: number;\n\tendAngle: number;\n}\n\nexport interface PaintGlyph {\n\tformat: PaintFormat.Glyph;\n\tpaint: Paint;\n\tglyphId: GlyphId;\n}\n\nexport interface PaintColrGlyph {\n\tformat: PaintFormat.ColrGlyph;\n\tglyphId: GlyphId;\n}\n\nexport interface PaintTransform {\n\tformat: PaintFormat.Transform | PaintFormat.VarTransform;\n\tpaint: Paint;\n\ttransform: Affine2x3;\n}\n\nexport interface PaintTranslate {\n\tformat: PaintFormat.Translate | PaintFormat.VarTranslate;\n\tpaint: Paint;\n\tdx: number;\n\tdy: number;\n}\n\nexport interface PaintScale {\n\tformat:\n\t\t| PaintFormat.Scale\n\t\t| PaintFormat.VarScale\n\t\t| PaintFormat.ScaleAroundCenter\n\t\t| PaintFormat.VarScaleAroundCenter\n\t\t| PaintFormat.ScaleUniform\n\t\t| PaintFormat.VarScaleUniform\n\t\t| PaintFormat.ScaleUniformAroundCenter\n\t\t| PaintFormat.VarScaleUniformAroundCenter;\n\tpaint: Paint;\n\tscaleX: number;\n\tscaleY: number;\n\tcenterX?: number;\n\tcenterY?: number;\n}\n\nexport interface PaintRotate {\n\tformat:\n\t\t| PaintFormat.Rotate\n\t\t| PaintFormat.VarRotate\n\t\t| PaintFormat.RotateAroundCenter\n\t\t| PaintFormat.VarRotateAroundCenter;\n\tpaint: Paint;\n\tangle: number;\n\tcenterX?: number;\n\tcenterY?: number;\n}\n\nexport interface PaintSkew {\n\tformat:\n\t\t| PaintFormat.Skew\n\t\t| PaintFormat.VarSkew\n\t\t| PaintFormat.SkewAroundCenter\n\t\t| PaintFormat.VarSkewAroundCenter;\n\tpaint: Paint;\n\txSkewAngle: number;\n\tySkewAngle: number;\n\tcenterX?: number;\n\tcenterY?: number;\n}\n\nexport interface PaintComposite {\n\tformat: PaintFormat.Composite;\n\tsourcePaint: Paint;\n\tcompositeMode: CompositeMode;\n\tbackdropPaint: Paint;\n}\n\nexport interface ColorLine {\n\textend: Extend;\n\tcolorStops: ColorStop[];\n}\n\nexport interface ColorStop {\n\tstopOffset: number;\n\tpaletteIndex: number;\n\talpha: number;\n}\n\nexport enum Extend {\n\tPad = 0,\n\tRepeat = 1,\n\tReflect = 2,\n}\n\nexport enum CompositeMode {\n\tClear = 0,\n\tSrc = 1,\n\tDest = 2,\n\tSrcOver = 3,\n\tDestOver = 4,\n\tSrcIn = 5,\n\tDestIn = 6,\n\tSrcOut = 7,\n\tDestOut = 8,\n\tSrcAtop = 9,\n\tDestAtop = 10,\n\tXor = 11,\n\tPlus = 12,\n\tScreen = 13,\n\tOverlay = 14,\n\tDarken = 15,\n\tLighten = 16,\n\tColorDodge = 17,\n\tColorBurn = 18,\n\tHardLight = 19,\n\tSoftLight = 20,\n\tDifference = 21,\n\tExclusion = 22,\n\tMultiply = 23,\n\tHue = 24,\n\tSaturation = 25,\n\tColor = 26,\n\tLuminosity = 27,\n}\n\nexport interface Affine2x3 {\n\txx: number;\n\tyx: number;\n\txy: number;\n\tyy: number;\n\tdx: number;\n\tdy: number;\n}\n\nexport interface ClipRecord {\n\tstartGlyphId: GlyphId;\n\tendGlyphId: GlyphId;\n\tclipBox: ClipBox;\n}\n\nexport interface ClipBox {\n\tformat: number;\n\txMin: number;\n\tyMin: number;\n\txMax: number;\n\tyMax: number;\n\tvarIndexBase?: number;\n}\n\nexport interface ItemVariationStore {\n\tformat: number;\n\tvariationRegionListOffset: number;\n\titemVariationDataCount: number;\n\titemVariationDataOffsets: number[];\n\tvariationRegions: VariationRegion[];\n\titemVariationData: ItemVariationData[];\n}\n\nexport interface VariationRegion {\n\tregionAxes: RegionAxisCoordinates[];\n}\n\nexport interface RegionAxisCoordinates {\n\tstartCoord: number;\n\tpeakCoord: number;\n\tendCoord: number;\n}\n\nexport interface ItemVariationData {\n\titemCount: number;\n\twordDeltaCount: number;\n\tregionIndexCount: number;\n\tregionIndexes: number[];\n\tdeltaSets: number[][];\n}\n\nexport interface VarColorLine extends ColorLine {\n\tvarIndexBase?: number;\n}\n\nexport interface VarColorStop extends ColorStop {\n\tvarIndexBase?: number;\n}\n\n/**\n * Parse COLR table\n */\nexport function parseColr(reader: Reader): ColrTable {\n\tconst startOffset = reader.offset;\n\n\tconst version = reader.uint16();\n\tconst numBaseGlyphRecords = reader.uint16();\n\tconst baseGlyphRecordsOffset = reader.uint32();\n\tconst layerRecordsOffset = reader.uint32();\n\tconst numLayerRecords = reader.uint16();\n\n\t// Parse v0 base glyph records\n\tconst baseGlyphRecords: BaseGlyphRecord[] = [];\n\tif (baseGlyphRecordsOffset !== 0 && numBaseGlyphRecords > 0) {\n\t\treader.seek(startOffset + baseGlyphRecordsOffset);\n\t\tfor (let i = 0; i < numBaseGlyphRecords; i++) {\n\t\t\tbaseGlyphRecords.push({\n\t\t\t\tglyphId: reader.uint16(),\n\t\t\t\tfirstLayerIndex: reader.uint16(),\n\t\t\t\tnumLayers: reader.uint16(),\n\t\t\t});\n\t\t}\n\t}\n\n\t// Parse v0 layer records\n\tconst layerRecords: LayerRecord[] = [];\n\tif (layerRecordsOffset !== 0 && numLayerRecords > 0) {\n\t\treader.seek(startOffset + layerRecordsOffset);\n\t\tfor (let i = 0; i < numLayerRecords; i++) {\n\t\t\tlayerRecords.push({\n\t\t\t\tglyphId: reader.uint16(),\n\t\t\t\tpaletteIndex: reader.uint16(),\n\t\t\t});\n\t\t}\n\t}\n\n\tconst result: ColrTable = {\n\t\tversion,\n\t\tbaseGlyphRecords,\n\t\tlayerRecords,\n\t};\n\n\t// Parse v1 extensions\n\tif (version >= 1) {\n\t\treader.seek(startOffset + 14); // After v0 header\n\n\t\tconst baseGlyphListOffset = reader.uint32();\n\t\tconst layerListOffset = reader.uint32();\n\t\tconst clipListOffset = reader.uint32();\n\t\tconst varIdxMapOffset = reader.uint32();\n\t\tconst itemVariationStoreOffset = reader.uint32();\n\n\t\t// Parse base glyph paint records\n\t\tif (baseGlyphListOffset !== 0) {\n\t\t\treader.seek(startOffset + baseGlyphListOffset);\n\t\t\tconst numRecords = reader.uint32();\n\t\t\tresult.baseGlyphPaintRecords = [];\n\n\t\t\tfor (let i = 0; i < numRecords; i++) {\n\t\t\t\tconst glyphId = reader.uint16();\n\t\t\t\tconst paintOffset = reader.uint32();\n\n\t\t\t\t// Parse paint at offset\n\t\t\t\tconst savedPos = reader.offset;\n\t\t\t\treader.seek(\n\t\t\t\t\tstartOffset + baseGlyphListOffset + 4 + i * 6 + 2 + paintOffset - 4,\n\t\t\t\t);\n\t\t\t\tconst paint = parsePaint(reader, startOffset);\n\t\t\t\treader.seek(savedPos);\n\n\t\t\t\tresult.baseGlyphPaintRecords.push({ glyphId, paint });\n\t\t\t}\n\t\t}\n\n\t\t// Parse layer list\n\t\tif (layerListOffset !== 0) {\n\t\t\treader.seek(startOffset + layerListOffset);\n\t\t\tconst numLayers = reader.uint32();\n\t\t\tconst paintOffsets: number[] = [];\n\n\t\t\tfor (let i = 0; i < numLayers; i++) {\n\t\t\t\tpaintOffsets.push(reader.uint32());\n\t\t\t}\n\n\t\t\tresult.layerList = [];\n\t\t\tfor (const offset of paintOffsets) {\n\t\t\t\treader.seek(startOffset + layerListOffset + offset);\n\t\t\t\tresult.layerList.push(parsePaint(reader, startOffset));\n\t\t\t}\n\t\t}\n\n\t\t// Parse clip list\n\t\tif (clipListOffset !== 0) {\n\t\t\treader.seek(startOffset + clipListOffset);\n\t\t\tresult.clipList = parseClipList(reader, startOffset);\n\t\t}\n\n\t\t// Parse DeltaSetIndexMap (for variable fonts)\n\t\tif (varIdxMapOffset !== 0) {\n\t\t\treader.seek(startOffset + varIdxMapOffset);\n\t\t\tresult.varIdxMap = parseDeltaSetIndexMap(reader);\n\t\t}\n\n\t\t// Parse ItemVariationStore (for variable fonts)\n\t\tif (itemVariationStoreOffset !== 0) {\n\t\t\treader.seek(startOffset + itemVariationStoreOffset);\n\t\t\tresult.itemVariationStore = parseItemVariationStore(reader);\n\t\t}\n\t}\n\n\treturn result;\n}\n\n/**\n * Parse a Paint structure\n */\nfunction parsePaint(reader: Reader, tableOffset: number): Paint {\n\tconst format = reader.uint8();\n\n\tswitch (format) {\n\t\tcase PaintFormat.ColrLayers:\n\t\t\treturn {\n\t\t\t\tformat,\n\t\t\t\tnumLayers: reader.uint8(),\n\t\t\t\tfirstLayerIndex: reader.uint32(),\n\t\t\t};\n\n\t\tcase PaintFormat.Solid:\n\t\t\treturn {\n\t\t\t\tformat,\n\t\t\t\tpaletteIndex: reader.uint16(),\n\t\t\t\talpha: reader.f2dot14(),\n\t\t\t};\n\n\t\tcase PaintFormat.VarSolid:\n\t\t\treturn {\n\t\t\t\tformat,\n\t\t\t\tpaletteIndex: reader.uint16(),\n\t\t\t\talpha: reader.f2dot14(),\n\t\t\t\tvarIndexBase: reader.uint32(),\n\t\t\t};\n\n\t\tcase PaintFormat.LinearGradient:\n\t\tcase PaintFormat.VarLinearGradient: {\n\t\t\tconst colorLineOffset = reader.uint24();\n\t\t\tconst x0 = reader.fword();\n\t\t\tconst y0 = reader.fword();\n\t\t\tconst x1 = reader.fword();\n\t\t\tconst y1 = reader.fword();\n\t\t\tconst x2 = reader.fword();\n\t\t\tconst y2 = reader.fword();\n\n\t\t\tconst savedPos = reader.offset;\n\t\t\treader.seek(reader.offset - 18 + colorLineOffset);\n\t\t\tconst colorLine = parseColorLine(reader);\n\t\t\treader.seek(savedPos);\n\n\t\t\treturn { format, colorLine, x0, y0, x1, y1, x2, y2 };\n\t\t}\n\n\t\tcase PaintFormat.RadialGradient:\n\t\tcase PaintFormat.VarRadialGradient: {\n\t\t\tconst colorLineOffset = reader.uint24();\n\t\t\tconst x0 = reader.fword();\n\t\t\tconst y0 = reader.fword();\n\t\t\tconst radius0 = reader.ufword();\n\t\t\tconst x1 = reader.fword();\n\t\t\tconst y1 = reader.fword();\n\t\t\tconst radius1 = reader.ufword();\n\n\t\t\tconst savedPos = reader.offset;\n\t\t\treader.seek(reader.offset - 18 + colorLineOffset);\n\t\t\tconst colorLine = parseColorLine(reader);\n\t\t\treader.seek(savedPos);\n\n\t\t\treturn { format, colorLine, x0, y0, radius0, x1, y1, radius1 };\n\t\t}\n\n\t\tcase PaintFormat.SweepGradient:\n\t\tcase PaintFormat.VarSweepGradient: {\n\t\t\tconst colorLineOffset = reader.uint24();\n\t\t\tconst centerX = reader.fword();\n\t\t\tconst centerY = reader.fword();\n\t\t\tconst startAngle = reader.f2dot14();\n\t\t\tconst endAngle = reader.f2dot14();\n\n\t\t\tconst savedPos = reader.offset;\n\t\t\treader.seek(reader.offset - 12 + colorLineOffset);\n\t\t\tconst colorLine = parseColorLine(reader);\n\t\t\treader.seek(savedPos);\n\n\t\t\treturn { format, colorLine, centerX, centerY, startAngle, endAngle };\n\t\t}\n\n\t\tcase PaintFormat.Glyph: {\n\t\t\tconst paintOffset = reader.uint24();\n\t\t\tconst glyphId = reader.uint16();\n\n\t\t\tconst savedPos = reader.offset;\n\t\t\treader.seek(reader.offset - 5 + paintOffset);\n\t\t\tconst paint = parsePaint(reader, tableOffset);\n\t\t\treader.seek(savedPos);\n\n\t\t\treturn { format, paint, glyphId };\n\t\t}\n\n\t\tcase PaintFormat.ColrGlyph:\n\t\t\treturn {\n\t\t\t\tformat,\n\t\t\t\tglyphId: reader.uint16(),\n\t\t\t};\n\n\t\tcase PaintFormat.Transform:\n\t\tcase PaintFormat.VarTransform: {\n\t\t\tconst paintOffset = reader.uint24();\n\t\t\tconst transformOffset = reader.uint24();\n\n\t\t\tconst paintPos = reader.offset - 6 + paintOffset;\n\t\t\tconst transformPos = reader.offset - 3 + transformOffset;\n\n\t\t\treader.seek(transformPos);\n\t\t\tconst transform: Affine2x3 = {\n\t\t\t\txx: reader.fixed(),\n\t\t\t\tyx: reader.fixed(),\n\t\t\t\txy: reader.fixed(),\n\t\t\t\tyy: reader.fixed(),\n\t\t\t\tdx: reader.fixed(),\n\t\t\t\tdy: reader.fixed(),\n\t\t\t};\n\n\t\t\treader.seek(paintPos);\n\t\t\tconst paint = parsePaint(reader, tableOffset);\n\n\t\t\treturn { format, paint, transform };\n\t\t}\n\n\t\tcase PaintFormat.Translate:\n\t\tcase PaintFormat.VarTranslate: {\n\t\t\tconst paintOffset = reader.uint24();\n\t\t\tconst dx = reader.fword();\n\t\t\tconst dy = reader.fword();\n\n\t\t\tconst savedPos = reader.offset;\n\t\t\treader.seek(reader.offset - 7 + paintOffset);\n\t\t\tconst paint = parsePaint(reader, tableOffset);\n\t\t\treader.seek(savedPos);\n\n\t\t\treturn { format, paint, dx, dy };\n\t\t}\n\n\t\tcase PaintFormat.Scale:\n\t\tcase PaintFormat.VarScale: {\n\t\t\tconst paintOffset = reader.uint24();\n\t\t\tconst scaleX = reader.f2dot14();\n\t\t\tconst scaleY = reader.f2dot14();\n\n\t\t\tconst savedPos = reader.offset;\n\t\t\treader.seek(reader.offset - 7 + paintOffset);\n\t\t\tconst paint = parsePaint(reader, tableOffset);\n\t\t\treader.seek(savedPos);\n\n\t\t\treturn { format, paint, scaleX, scaleY };\n\t\t}\n\n\t\tcase PaintFormat.ScaleAroundCenter:\n\t\tcase PaintFormat.VarScaleAroundCenter: {\n\t\t\tconst paintOffset = reader.uint24();\n\t\t\tconst scaleX = reader.f2dot14();\n\t\t\tconst scaleY = reader.f2dot14();\n\t\t\tconst centerX = reader.fword();\n\t\t\tconst centerY = reader.fword();\n\n\t\t\tconst savedPos = reader.offset;\n\t\t\treader.seek(reader.offset - 11 + paintOffset);\n\t\t\tconst paint = parsePaint(reader, tableOffset);\n\t\t\treader.seek(savedPos);\n\n\t\t\treturn { format, paint, scaleX, scaleY, centerX, centerY };\n\t\t}\n\n\t\tcase PaintFormat.ScaleUniform:\n\t\tcase PaintFormat.VarScaleUniform: {\n\t\t\tconst paintOffset = reader.uint24();\n\t\t\tconst scale = reader.f2dot14();\n\n\t\t\tconst savedPos = reader.offset;\n\t\t\treader.seek(reader.offset - 5 + paintOffset);\n\t\t\tconst paint = parsePaint(reader, tableOffset);\n\t\t\treader.seek(savedPos);\n\n\t\t\treturn { format, paint, scaleX: scale, scaleY: scale };\n\t\t}\n\n\t\tcase PaintFormat.ScaleUniformAroundCenter:\n\t\tcase PaintFormat.VarScaleUniformAroundCenter: {\n\t\t\tconst paintOffset = reader.uint24();\n\t\t\tconst scale = reader.f2dot14();\n\t\t\tconst centerX = reader.fword();\n\t\t\tconst centerY = reader.fword();\n\n\t\t\tconst savedPos = reader.offset;\n\t\t\treader.seek(reader.offset - 9 + paintOffset);\n\t\t\tconst paint = parsePaint(reader, tableOffset);\n\t\t\treader.seek(savedPos);\n\n\t\t\treturn { format, paint, scaleX: scale, scaleY: scale, centerX, centerY };\n\t\t}\n\n\t\tcase PaintFormat.Rotate:\n\t\tcase PaintFormat.VarRotate: {\n\t\t\tconst paintOffset = reader.uint24();\n\t\t\tconst angle = reader.f2dot14();\n\n\t\t\tconst savedPos = reader.offset;\n\t\t\treader.seek(reader.offset - 5 + paintOffset);\n\t\t\tconst paint = parsePaint(reader, tableOffset);\n\t\t\treader.seek(savedPos);\n\n\t\t\treturn { format, paint, angle };\n\t\t}\n\n\t\tcase PaintFormat.RotateAroundCenter:\n\t\tcase PaintFormat.VarRotateAroundCenter: {\n\t\t\tconst paintOffset = reader.uint24();\n\t\t\tconst angle = reader.f2dot14();\n\t\t\tconst centerX = reader.fword();\n\t\t\tconst centerY = reader.fword();\n\n\t\t\tconst savedPos = reader.offset;\n\t\t\treader.seek(reader.offset - 9 + paintOffset);\n\t\t\tconst paint = parsePaint(reader, tableOffset);\n\t\t\treader.seek(savedPos);\n\n\t\t\treturn { format, paint, angle, centerX, centerY };\n\t\t}\n\n\t\tcase PaintFormat.Skew:\n\t\tcase PaintFormat.VarSkew: {\n\t\t\tconst paintOffset = reader.uint24();\n\t\t\tconst xSkewAngle = reader.f2dot14();\n\t\t\tconst ySkewAngle = reader.f2dot14();\n\n\t\t\tconst savedPos = reader.offset;\n\t\t\treader.seek(reader.offset - 7 + paintOffset);\n\t\t\tconst paint = parsePaint(reader, tableOffset);\n\t\t\treader.seek(savedPos);\n\n\t\t\treturn { format, paint, xSkewAngle, ySkewAngle };\n\t\t}\n\n\t\tcase PaintFormat.SkewAroundCenter:\n\t\tcase PaintFormat.VarSkewAroundCenter: {\n\t\t\tconst paintOffset = reader.uint24();\n\t\t\tconst xSkewAngle = reader.f2dot14();\n\t\t\tconst ySkewAngle = reader.f2dot14();\n\t\t\tconst centerX = reader.fword();\n\t\t\tconst centerY = reader.fword();\n\n\t\t\tconst savedPos = reader.offset;\n\t\t\treader.seek(reader.offset - 11 + paintOffset);\n\t\t\tconst paint = parsePaint(reader, tableOffset);\n\t\t\treader.seek(savedPos);\n\n\t\t\treturn { format, paint, xSkewAngle, ySkewAngle, centerX, centerY };\n\t\t}\n\n\t\tcase PaintFormat.Composite: {\n\t\t\tconst sourcePaintOffset = reader.uint24();\n\t\t\tconst compositeMode = reader.uint8() as CompositeMode;\n\t\t\tconst backdropPaintOffset = reader.uint24();\n\n\t\t\tconst sourcePos = reader.offset - 7 + sourcePaintOffset;\n\t\t\tconst backdropPos = reader.offset - 3 + backdropPaintOffset;\n\n\t\t\treader.seek(sourcePos);\n\t\t\tconst sourcePaint = parsePaint(reader, tableOffset);\n\n\t\t\treader.seek(backdropPos);\n\t\t\tconst backdropPaint = parsePaint(reader, tableOffset);\n\n\t\t\treturn { format, sourcePaint, compositeMode, backdropPaint };\n\t\t}\n\n\t\tdefault:\n\t\t\tthrow new Error(`Unknown paint format: ${format}`);\n\t}\n}\n\n/**\n * Parse ColorLine structure\n */\nfunction parseColorLine(reader: Reader): ColorLine {\n\tconst extend = reader.uint8() as Extend;\n\tconst numStops = reader.uint16();\n\tconst colorStops: ColorStop[] = [];\n\n\tfor (let i = 0; i < numStops; i++) {\n\t\tcolorStops.push({\n\t\t\tstopOffset: reader.f2dot14(),\n\t\t\tpaletteIndex: reader.uint16(),\n\t\t\talpha: reader.f2dot14(),\n\t\t});\n\t}\n\n\treturn { extend, colorStops };\n}\n\n/**\n * Parse ClipList structure\n */\nfunction parseClipList(reader: Reader, _tableOffset: number): ClipRecord[] {\n\tconst _format = reader.uint8();\n\tconst numClips = reader.uint32();\n\tconst records: ClipRecord[] = [];\n\n\tfor (let i = 0; i < numClips; i++) {\n\t\tconst startGlyphId = reader.uint16();\n\t\tconst endGlyphId = reader.uint16();\n\t\tconst clipBoxOffset = reader.uint24();\n\n\t\tconst savedPos = reader.offset;\n\t\treader.seek(reader.offset - 7 + clipBoxOffset);\n\n\t\tconst boxFormat = reader.uint8();\n\t\tconst clipBox: ClipBox = {\n\t\t\tformat: boxFormat,\n\t\t\txMin: reader.fword(),\n\t\t\tyMin: reader.fword(),\n\t\t\txMax: reader.fword(),\n\t\t\tyMax: reader.fword(),\n\t\t};\n\n\t\tif (boxFormat === 2) {\n\t\t\tclipBox.varIndexBase = reader.uint32();\n\t\t}\n\n\t\treader.seek(savedPos);\n\n\t\trecords.push({ startGlyphId, endGlyphId, clipBox });\n\t}\n\n\treturn records;\n}\n\n/**\n * Get color layers for a glyph (v0)\n */\nexport function getColorLayers(\n\tcolr: ColrTable,\n\tglyphId: GlyphId,\n): LayerRecord[] | null {\n\t// Binary search for base glyph record\n\tconst records = colr.baseGlyphRecords;\n\tlet lo = 0;\n\tlet hi = records.length - 1;\n\n\twhile (lo <= hi) {\n\t\tconst mid = (lo + hi) >>> 1;\n\t\tconst record = records[mid];\n\t\tif (!record) break;\n\n\t\tif (record.glyphId === glyphId) {\n\t\t\tconst layers: LayerRecord[] = [];\n\t\t\tfor (let i = 0; i < record.numLayers; i++) {\n\t\t\t\tconst layer = colr.layerRecords[record.firstLayerIndex + i];\n\t\t\t\tif (layer) layers.push(layer);\n\t\t\t}\n\t\t\treturn layers;\n\t\t} else if (record.glyphId < glyphId) {\n\t\t\tlo = mid + 1;\n\t\t} else {\n\t\t\thi = mid - 1;\n\t\t}\n\t}\n\n\treturn null;\n}\n\n/**\n * Get paint for a glyph (v1)\n */\nexport function getColorPaint(colr: ColrTable, glyphId: GlyphId): Paint | null {\n\tif (!colr.baseGlyphPaintRecords) return null;\n\n\t// Binary search\n\tconst records = colr.baseGlyphPaintRecords;\n\tlet lo = 0;\n\tlet hi = records.length - 1;\n\n\twhile (lo <= hi) {\n\t\tconst mid = (lo + hi) >>> 1;\n\t\tconst record = records[mid];\n\t\tif (!record) break;\n\n\t\tif (record.glyphId === glyphId) {\n\t\t\treturn record.paint;\n\t\t} else if (record.glyphId < glyphId) {\n\t\t\tlo = mid + 1;\n\t\t} else {\n\t\t\thi = mid - 1;\n\t\t}\n\t}\n\n\treturn null;\n}\n\n/**\n * Check if glyph has color data\n */\nexport function hasColorGlyph(colr: ColrTable, glyphId: GlyphId): boolean {\n\treturn (\n\t\tgetColorLayers(colr, glyphId) !== null ||\n\t\tgetColorPaint(colr, glyphId) !== null\n\t);\n}\n\n/**\n * Parse DeltaSetIndexMap (used by variable fonts)\n */\nfunction parseDeltaSetIndexMap(reader: Reader): number[] {\n\tconst format = reader.uint8();\n\tconst entryFormat = reader.uint8();\n\tconst mapCount = format === 0 ? reader.uint16() : reader.uint32();\n\n\tconst innerBits = (entryFormat & 0x0f) + 1;\n\tconst outerBits = ((entryFormat >> 4) & 0x0f) + 1;\n\tconst entrySize = Math.ceil((innerBits + outerBits) / 8);\n\n\tconst result: number[] = [];\n\tfor (let i = 0; i < mapCount; i++) {\n\t\tlet entry = 0;\n\t\tfor (let b = 0; b < entrySize; b++) {\n\t\t\tentry = (entry << 8) | reader.uint8();\n\t\t}\n\t\t// Pack outer and inner indices into a single number\n\t\t// Format: (outer << 16) | inner\n\t\tconst innerMask = (1 << innerBits) - 1;\n\t\tconst inner = entry & innerMask;\n\t\tconst outer = entry >> innerBits;\n\t\tresult.push((outer << 16) | inner);\n\t}\n\n\treturn result;\n}\n\n/**\n * Parse ItemVariationStore (used by variable fonts)\n */\nfunction parseItemVariationStore(reader: Reader): ItemVariationStore {\n\tconst storeOffset = reader.offset;\n\tconst format = reader.uint16();\n\tconst variationRegionListOffset = reader.uint32();\n\tconst itemVariationDataCount = reader.uint16();\n\n\tconst itemVariationDataOffsets: number[] = [];\n\tfor (let i = 0; i < itemVariationDataCount; i++) {\n\t\titemVariationDataOffsets.push(reader.uint32());\n\t}\n\n\t// Parse variation region list\n\treader.seek(storeOffset + variationRegionListOffset);\n\tconst axisCount = reader.uint16();\n\tconst regionCount = reader.uint16();\n\n\tconst variationRegions: VariationRegion[] = [];\n\tfor (let i = 0; i < regionCount; i++) {\n\t\tconst regionAxes: RegionAxisCoordinates[] = [];\n\t\tfor (let j = 0; j < axisCount; j++) {\n\t\t\tregionAxes.push({\n\t\t\t\tstartCoord: reader.f2dot14(),\n\t\t\t\tpeakCoord: reader.f2dot14(),\n\t\t\t\tendCoord: reader.f2dot14(),\n\t\t\t});\n\t\t}\n\t\tvariationRegions.push({ regionAxes });\n\t}\n\n\t// Parse item variation data subtables\n\tconst itemVariationData: ItemVariationData[] = [];\n\tfor (const offset of itemVariationDataOffsets) {\n\t\treader.seek(storeOffset + offset);\n\t\tconst itemCount = reader.uint16();\n\t\tconst wordDeltaCount = reader.uint16();\n\t\tconst regionIndexCount = reader.uint16();\n\n\t\tconst regionIndexes: number[] = [];\n\t\tfor (let i = 0; i < regionIndexCount; i++) {\n\t\t\tregionIndexes.push(reader.uint16());\n\t\t}\n\n\t\t// Parse delta sets\n\t\tconst longWords = (wordDeltaCount & 0x8000) !== 0;\n\t\tconst wordCount = wordDeltaCount & 0x7fff;\n\n\t\tconst deltaSets: number[][] = [];\n\t\tfor (let i = 0; i < itemCount; i++) {\n\t\t\tconst deltas: number[] = [];\n\t\t\tfor (let j = 0; j < regionIndexCount; j++) {\n\t\t\t\tif (j < wordCount) {\n\t\t\t\t\tdeltas.push(longWords ? reader.int32() : reader.int16());\n\t\t\t\t} else {\n\t\t\t\t\tdeltas.push(longWords ? reader.int16() : reader.int8());\n\t\t\t\t}\n\t\t\t}\n\t\t\tdeltaSets.push(deltas);\n\t\t}\n\n\t\titemVariationData.push({\n\t\t\titemCount,\n\t\t\twordDeltaCount,\n\t\t\tregionIndexCount,\n\t\t\tregionIndexes,\n\t\t\tdeltaSets,\n\t\t});\n\t}\n\n\treturn {\n\t\tformat,\n\t\tvariationRegionListOffset,\n\t\titemVariationDataCount,\n\t\titemVariationDataOffsets,\n\t\tvariationRegions,\n\t\titemVariationData,\n\t};\n}\n\n/**\n * Get clip box for a glyph\n */\nexport function getClipBox(colr: ColrTable, glyphId: GlyphId): ClipBox | null {\n\tif (!colr.clipList) return null;\n\n\tfor (const record of colr.clipList) {\n\t\tif (glyphId >= record.startGlyphId && glyphId <= record.endGlyphId) {\n\t\t\treturn record.clipBox;\n\t\t}\n\t}\n\n\treturn null;\n}\n\n/**\n * Calculate variation delta for a paint value\n */\nexport function getColorVariationDelta(\n\tcolr: ColrTable,\n\tvarIndex: number,\n\tcoords: number[],\n): number {\n\tif (!colr.itemVariationStore || !colr.varIdxMap) return 0;\n\n\t// Get outer/inner indices from varIdxMap\n\tconst mappedIndex = colr.varIdxMap[varIndex];\n\tif (mappedIndex === undefined) return 0;\n\n\tconst outer = mappedIndex >> 16;\n\tconst inner = mappedIndex & 0xffff;\n\n\tconst store = colr.itemVariationStore;\n\tconst data = store.itemVariationData[outer];\n\tif (!data) return 0;\n\n\tconst deltas = data.deltaSets[inner];\n\tif (!deltas) return 0;\n\n\t// Calculate scalar for each region and sum deltas\n\tlet result = 0;\n\tfor (let i = 0; i < data.regionIndexCount; i++) {\n\t\tconst regionIndex = data.regionIndexes[i];\n\t\tif (regionIndex === undefined) continue;\n\t\tconst region = store.variationRegions[regionIndex];\n\t\tif (!region) continue;\n\n\t\t// Calculate scalar for this region\n\t\tlet scalar = 1.0;\n\t\tfor (let j = 0; j < region.regionAxes.length && j < coords.length; j++) {\n\t\t\tconst axis = region.regionAxes[j];\n\t\t\tconst coord = coords[j];\n\t\t\tif (axis === undefined || coord === undefined) continue;\n\t\t\tscalar *= calculateAxisScalar(\n\t\t\t\tcoord,\n\t\t\t\taxis.startCoord,\n\t\t\t\taxis.peakCoord,\n\t\t\t\taxis.endCoord,\n\t\t\t);\n\t\t\tif (scalar === 0) break;\n\t\t}\n\n\t\tconst delta = deltas[i];\n\t\tif (delta !== undefined) {\n\t\t\tresult += delta * scalar;\n\t\t}\n\t}\n\n\treturn result;\n}\n\n/**\n * Calculate scalar contribution for a single axis\n */\nfunction calculateAxisScalar(\n\tcoord: number,\n\tstart: number,\n\tpeak: number,\n\tend: number,\n): number {\n\t// If peak is 0, no contribution\n\tif (peak === 0) return 1.0;\n\n\t// If coord exactly at peak, full contribution\n\tif (coord === peak) return 1.0;\n\n\t// If coord outside range, no contribution\n\tif (coord < start || coord > end) return 0.0;\n\n\t// Interpolate\n\tif (coord < peak) {\n\t\tif (start === peak) return 1.0;\n\t\treturn (coord - start) / (peak - start);\n\t} else {\n\t\tif (peak === end) return 1.0;\n\t\treturn (end - coord) / (end - peak);\n\t}\n}\n\n/**\n * Check if COLR table is version 1\n */\nexport function isColrV1(colr: ColrTable): boolean {\n\treturn colr.version >= 1 && colr.baseGlyphPaintRecords !== undefined;\n}\n\n/**\n * Get the paint layer at a specific index from the layer list\n */\nexport function getLayerPaint(colr: ColrTable, index: number): Paint | null {\n\treturn colr.layerList?.[index] ?? null;\n}\n",
27
- "import type { Reader } from \"../binary/reader.ts\";\n\n/**\n * CPAL (Color Palette) table parser\n * Provides color palettes for color fonts\n */\n\nexport interface CpalTable {\n\tversion: number;\n\tnumPalettes: number;\n\tnumPaletteEntries: number;\n\tpalettes: ColorPalette[];\n\tpaletteTypes?: number[];\n\tpaletteLabels?: number[];\n\tpaletteEntryLabels?: number[];\n}\n\nexport interface ColorPalette {\n\tcolors: Color[];\n}\n\nexport interface Color {\n\tblue: number; // 0-255\n\tgreen: number; // 0-255\n\tred: number; // 0-255\n\talpha: number; // 0-255\n}\n\n/**\n * Palette type flags\n */\nexport enum PaletteType {\n\tUsableWithLightBackground = 0x0001,\n\tUsableWithDarkBackground = 0x0002,\n}\n\n/**\n * Parse CPAL table\n */\nexport function parseCpal(reader: Reader): CpalTable {\n\tconst startOffset = reader.offset;\n\n\tconst version = reader.uint16();\n\tconst numPaletteEntries = reader.uint16();\n\tconst numPalettes = reader.uint16();\n\tconst numColorRecords = reader.uint16();\n\tconst colorRecordsArrayOffset = reader.uint32();\n\n\t// Read color record indices for each palette\n\tconst colorRecordIndices: number[] = [];\n\tfor (let i = 0; i < numPalettes; i++) {\n\t\tcolorRecordIndices.push(reader.uint16());\n\t}\n\n\t// Read all color records\n\treader.seek(startOffset + colorRecordsArrayOffset);\n\tconst colorRecords: Color[] = [];\n\tfor (let i = 0; i < numColorRecords; i++) {\n\t\tcolorRecords.push({\n\t\t\tblue: reader.uint8(),\n\t\t\tgreen: reader.uint8(),\n\t\t\tred: reader.uint8(),\n\t\t\talpha: reader.uint8(),\n\t\t});\n\t}\n\n\t// Build palettes\n\tconst palettes: ColorPalette[] = [];\n\tfor (let i = 0; i < numPalettes; i++) {\n\t\tconst startIndex = colorRecordIndices[i];\n\t\tif (startIndex === undefined) continue;\n\t\tconst colors: Color[] = [];\n\t\tfor (let j = 0; j < numPaletteEntries; j++) {\n\t\t\tconst color = colorRecords[startIndex + j];\n\t\t\tif (color) colors.push(color);\n\t\t}\n\t\tpalettes.push({ colors });\n\t}\n\n\t// Version 1 extensions\n\tlet paletteTypes: number[] | undefined;\n\tlet paletteLabels: number[] | undefined;\n\tlet paletteEntryLabels: number[] | undefined;\n\n\tif (version >= 1) {\n\t\t// After color record indices\n\t\treader.seek(startOffset + 12 + numPalettes * 2);\n\n\t\tconst paletteTypesArrayOffset = reader.uint32();\n\t\tconst paletteLabelsArrayOffset = reader.uint32();\n\t\tconst paletteEntryLabelsArrayOffset = reader.uint32();\n\n\t\tif (paletteTypesArrayOffset !== 0) {\n\t\t\treader.seek(startOffset + paletteTypesArrayOffset);\n\t\t\tpaletteTypes = [];\n\t\t\tfor (let i = 0; i < numPalettes; i++) {\n\t\t\t\tpaletteTypes.push(reader.uint32());\n\t\t\t}\n\t\t}\n\n\t\tif (paletteLabelsArrayOffset !== 0) {\n\t\t\treader.seek(startOffset + paletteLabelsArrayOffset);\n\t\t\tpaletteLabels = [];\n\t\t\tfor (let i = 0; i < numPalettes; i++) {\n\t\t\t\tpaletteLabels.push(reader.uint16());\n\t\t\t}\n\t\t}\n\n\t\tif (paletteEntryLabelsArrayOffset !== 0) {\n\t\t\treader.seek(startOffset + paletteEntryLabelsArrayOffset);\n\t\t\tpaletteEntryLabels = [];\n\t\t\tfor (let i = 0; i < numPaletteEntries; i++) {\n\t\t\t\tpaletteEntryLabels.push(reader.uint16());\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\tversion,\n\t\tnumPalettes,\n\t\tnumPaletteEntries,\n\t\tpalettes,\n\t\tpaletteTypes,\n\t\tpaletteLabels,\n\t\tpaletteEntryLabels,\n\t};\n}\n\n/**\n * Get color from palette\n */\nexport function getColor(\n\tcpal: CpalTable,\n\tpaletteIndex: number,\n\tcolorIndex: number,\n): Color | null {\n\tconst palette = cpal.palettes[paletteIndex];\n\tif (!palette) return null;\n\treturn palette.colors[colorIndex] ?? null;\n}\n\n/**\n * Convert color to CSS rgba string\n */\nexport function colorToRgba(color: Color): string {\n\treturn `rgba(${color.red}, ${color.green}, ${color.blue}, ${(color.alpha / 255).toFixed(3)})`;\n}\n\n/**\n * Convert color to CSS hex string\n */\nexport function colorToHex(color: Color): string {\n\tconst r = color.red.toString(16).padStart(2, \"0\");\n\tconst g = color.green.toString(16).padStart(2, \"0\");\n\tconst b = color.blue.toString(16).padStart(2, \"0\");\n\tif (color.alpha === 255) {\n\t\treturn `#${r}${g}${b}`;\n\t}\n\tconst a = color.alpha.toString(16).padStart(2, \"0\");\n\treturn `#${r}${g}${b}${a}`;\n}\n",
28
- "import type { uint16, uint32 } from \"../../types.ts\";\nimport type { Reader } from \"../binary/reader.ts\";\n\n/**\n * AAT Feature Name table (feat)\n * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6feat.html\n *\n * Defines the font's typographic features that can be controlled by the user.\n * Each feature has a type and settings with human-readable names.\n */\nexport interface FeatTable {\n\tversion: number;\n\tfeatures: FeatureRecord[];\n}\n\n/**\n * A single feature record\n */\nexport interface FeatureRecord {\n\t/** Feature type (e.g., 1 = ligatures, 2 = cursive connection) */\n\tfeatureType: uint16;\n\t/** Number of settings for this feature */\n\tnSettings: uint16;\n\t/** Offset to setting name array */\n\tsettingTableOffset: uint32;\n\t/** Feature flags */\n\tfeatureFlags: uint16;\n\t/** Default setting index */\n\tdefaultSettingIndex: uint16;\n\t/** Name table ID for feature name */\n\tnameId: uint16;\n\t/** Parsed settings */\n\tsettings: FeatureSetting[];\n}\n\n/**\n * A single feature setting\n */\nexport interface FeatureSetting {\n\t/** Setting value to use in morx feature table */\n\tsettingValue: uint16;\n\t/** Name table ID for setting name */\n\tnameId: uint16;\n}\n\n/**\n * Feature type constants (Apple-defined)\n */\nexport enum FeatureType {\n\t/** All typographic features */\n\tAllTypographicFeatures = 0,\n\t/** Ligatures */\n\tLigatures = 1,\n\t/** Cursive connection */\n\tCursiveConnection = 2,\n\t/** Letter case */\n\tLetterCase = 3,\n\t/** Vertical substitution */\n\tVerticalSubstitution = 4,\n\t/** Linguistic rearrangement */\n\tLinguisticRearrangement = 5,\n\t/** Number spacing */\n\tNumberSpacing = 6,\n\t/** Smart swashes */\n\tSmartSwashes = 8,\n\t/** Diacritics */\n\tDiacritics = 9,\n\t/** Vertical position */\n\tVerticalPosition = 10,\n\t/** Fractions */\n\tFractions = 11,\n\t/** Overlapping characters */\n\tOverlappingCharacters = 13,\n\t/** Typographic extras */\n\tTypographicExtras = 14,\n\t/** Mathematical extras */\n\tMathematicalExtras = 15,\n\t/** Ornament sets */\n\tOrnamentSets = 16,\n\t/** Character alternatives */\n\tCharacterAlternatives = 17,\n\t/** Design complexity */\n\tDesignComplexity = 18,\n\t/** Style options */\n\tStyleOptions = 19,\n\t/** Character shape */\n\tCharacterShape = 20,\n\t/** Number case */\n\tNumberCase = 21,\n\t/** Text spacing */\n\tTextSpacing = 22,\n\t/** Transliteration */\n\tTransliteration = 23,\n\t/** Annotation */\n\tAnnotation = 24,\n\t/** Kana spacing */\n\tKanaSpacing = 25,\n\t/** Ideographic spacing */\n\tIdeographicSpacing = 26,\n\t/** Unicode decomposition */\n\tUnicodeDecomposition = 27,\n\t/** Ruby kana */\n\tRubyKana = 28,\n\t/** CJK symbol alternatives */\n\tCJKSymbolAlternatives = 29,\n\t/** Ideographic alternatives */\n\tIdeographicAlternatives = 30,\n\t/** CJK vertical roman placement */\n\tCJKVerticalRomanPlacement = 31,\n\t/** Italic CJK roman */\n\tItalicCJKRoman = 32,\n\t/** Case-sensitive layout */\n\tCaseSensitiveLayout = 33,\n\t/** Alternate kana */\n\tAlternateKana = 34,\n\t/** Stylistic alternatives */\n\tStylisticAlternatives = 35,\n\t/** Contextual alternatives */\n\tContextualAlternatives = 36,\n\t/** Lower case */\n\tLowerCase = 37,\n\t/** Upper case */\n\tUpperCase = 38,\n\t/** Language tag */\n\tLanguageTag = 39,\n\t/** CJK roman spacing */\n\tCJKRomanSpacing = 103,\n}\n\n/**\n * Common ligature settings\n */\nexport enum LigatureSetting {\n\tRequiredLigaturesOn = 0,\n\tRequiredLigaturesOff = 1,\n\tCommonLigaturesOn = 2,\n\tCommonLigaturesOff = 3,\n\tRareLigaturesOn = 4,\n\tRareLigaturesOff = 5,\n\tLogosOn = 6,\n\tLogosOff = 7,\n\tRebusPicturesOn = 8,\n\tRebusPicturesOff = 9,\n\tDiphthongLigaturesOn = 10,\n\tDiphthongLigaturesOff = 11,\n\tSquaredLigaturesOn = 12,\n\tSquaredLigaturesOff = 13,\n\tAbbrevSquaredLigaturesOn = 14,\n\tAbbrevSquaredLigaturesOff = 15,\n\tSymbolLigaturesOn = 16,\n\tSymbolLigaturesOff = 17,\n\tContextualLigaturesOn = 18,\n\tContextualLigaturesOff = 19,\n\tHistoricalLigaturesOn = 20,\n\tHistoricalLigaturesOff = 21,\n}\n\n/**\n * Vertical position settings\n */\nexport enum VerticalPositionSetting {\n\tNormalPosition = 0,\n\tSuperiors = 1,\n\tInferiors = 2,\n\tOrdinals = 3,\n\tScientificInferiors = 4,\n}\n\n/**\n * Number case settings\n */\nexport enum NumberCaseSetting {\n\tLowerCaseNumbers = 0,\n\tUpperCaseNumbers = 1,\n}\n\n/**\n * Number spacing settings\n */\nexport enum NumberSpacingSetting {\n\tMonospacedNumbers = 0,\n\tProportionalNumbers = 1,\n\tThirdWidthNumbers = 2,\n\tQuarterWidthNumbers = 3,\n}\n\n/**\n * Fractions settings\n */\nexport enum FractionsSetting {\n\tNoFractions = 0,\n\tVerticalFractions = 1,\n\tDiagonalFractions = 2,\n}\n\n/**\n * Case-sensitive layout settings\n */\nexport enum CaseSensitiveLayoutSetting {\n\tCaseSensitiveLayoutOn = 0,\n\tCaseSensitiveLayoutOff = 1,\n\tCaseSensitiveSpacingOn = 2,\n\tCaseSensitiveSpacingOff = 3,\n}\n\n/**\n * Stylistic alternatives settings\n */\nexport enum StylisticAlternativesSetting {\n\tNoStylisticAlternates = 0,\n\tStylisticAltOneOn = 2,\n\tStylisticAltOneOff = 3,\n\tStylisticAltTwoOn = 4,\n\tStylisticAltTwoOff = 5,\n\tStylisticAltThreeOn = 6,\n\tStylisticAltThreeOff = 7,\n\tStylisticAltFourOn = 8,\n\tStylisticAltFourOff = 9,\n\tStylisticAltFiveOn = 10,\n\tStylisticAltFiveOff = 11,\n\tStylisticAltSixOn = 12,\n\tStylisticAltSixOff = 13,\n\tStylisticAltSevenOn = 14,\n\tStylisticAltSevenOff = 15,\n\tStylisticAltEightOn = 16,\n\tStylisticAltEightOff = 17,\n\tStylisticAltNineOn = 18,\n\tStylisticAltNineOff = 19,\n\tStylisticAltTenOn = 20,\n\tStylisticAltTenOff = 21,\n\tStylisticAltElevenOn = 22,\n\tStylisticAltElevenOff = 23,\n\tStylisticAltTwelveOn = 24,\n\tStylisticAltTwelveOff = 25,\n\tStylisticAltThirteenOn = 26,\n\tStylisticAltThirteenOff = 27,\n\tStylisticAltFourteenOn = 28,\n\tStylisticAltFourteenOff = 29,\n\tStylisticAltFifteenOn = 30,\n\tStylisticAltFifteenOff = 31,\n\tStylisticAltSixteenOn = 32,\n\tStylisticAltSixteenOff = 33,\n\tStylisticAltSeventeenOn = 34,\n\tStylisticAltSeventeenOff = 35,\n\tStylisticAltEighteenOn = 36,\n\tStylisticAltEighteenOff = 37,\n\tStylisticAltNineteenOn = 38,\n\tStylisticAltNineteenOff = 39,\n\tStylisticAltTwentyOn = 40,\n\tStylisticAltTwentyOff = 41,\n}\n\n/**\n * Contextual alternatives settings\n */\nexport enum ContextualAlternativesSetting {\n\tContextualAlternatesOn = 0,\n\tContextualAlternatesOff = 1,\n\tSwashAlternatesOn = 2,\n\tSwashAlternatesOff = 3,\n\tContextualSwashAlternatesOn = 4,\n\tContextualSwashAlternatesOff = 5,\n}\n\n/**\n * Lower case settings\n */\nexport enum LowerCaseSetting {\n\tDefaultLowerCase = 0,\n\tLowerCaseSmallCaps = 1,\n\tLowerCasePetiteCaps = 2,\n}\n\n/**\n * Upper case settings\n */\nexport enum UpperCaseSetting {\n\tDefaultUpperCase = 0,\n\tUpperCaseSmallCaps = 1,\n\tUpperCasePetiteCaps = 2,\n}\n\n/**\n * Smart swash settings\n */\nexport enum SmartSwashSetting {\n\tWordInitialSwashesOn = 0,\n\tWordInitialSwashesOff = 1,\n\tWordFinalSwashesOn = 2,\n\tWordFinalSwashesOff = 3,\n\tLineInitialSwashesOn = 4,\n\tLineInitialSwashesOff = 5,\n\tLineFinalSwashesOn = 6,\n\tLineFinalSwashesOff = 7,\n\tNonFinalSwashesOn = 8,\n\tNonFinalSwashesOff = 9,\n}\n\n/**\n * Diacritics settings\n */\nexport enum DiacriticsSetting {\n\tShowDiacritics = 0,\n\tHideDiacritics = 1,\n\tDecomposeDiacritics = 2,\n}\n\n/**\n * Character shape settings (CJK)\n */\nexport enum CharacterShapeSetting {\n\tTraditionalCharacters = 0,\n\tSimplifiedCharacters = 1,\n\tJIS1978Characters = 2,\n\tJIS1983Characters = 3,\n\tJIS1990Characters = 4,\n\tTraditionalAltOne = 5,\n\tTraditionalAltTwo = 6,\n\tTraditionalAltThree = 7,\n\tTraditionalAltFour = 8,\n\tTraditionalAltFive = 9,\n\tExpertCharacters = 10,\n\tNLCCharacters = 13,\n\tJIS2004Characters = 11,\n\tHojoCharacters = 12,\n}\n\n/**\n * Feature flag bits\n */\nexport enum FeatureFlags {\n\t/** Feature settings are mutually exclusive */\n\tExclusive = 0x8000,\n\t/** Use default setting index if not specified */\n\tUseDefault = 0x4000,\n}\n\n/**\n * Parse feat table\n */\nexport function parseFeat(reader: Reader): FeatTable {\n\tconst tableStart = reader.offset;\n\n\tconst version = reader.fixed();\n\tconst featureNameCount = reader.uint16();\n\treader.skip(2); // reserved\n\treader.skip(4); // reserved\n\n\tconst features: FeatureRecord[] = [];\n\n\tfor (let i = 0; i < featureNameCount; i++) {\n\t\tconst featureType = reader.uint16();\n\t\tconst nSettings = reader.uint16();\n\t\tconst settingTableOffset = reader.offset32();\n\t\tconst featureFlags = reader.uint16();\n\t\tconst defaultSettingIndex = featureFlags & 0xff;\n\t\tconst nameId = reader.uint16();\n\n\t\t// Parse settings\n\t\tconst settings: FeatureSetting[] = [];\n\t\tconst savedOffset = reader.offset;\n\n\t\treader.seek(tableStart + settingTableOffset);\n\t\tfor (let j = 0; j < nSettings; j++) {\n\t\t\tsettings.push({\n\t\t\t\tsettingValue: reader.uint16(),\n\t\t\t\tnameId: reader.uint16(),\n\t\t\t});\n\t\t}\n\n\t\treader.seek(savedOffset);\n\n\t\tfeatures.push({\n\t\t\tfeatureType,\n\t\t\tnSettings,\n\t\t\tsettingTableOffset,\n\t\t\tfeatureFlags,\n\t\t\tdefaultSettingIndex,\n\t\t\tnameId,\n\t\t\tsettings,\n\t\t});\n\t}\n\n\treturn { version, features };\n}\n\n/**\n * Get a feature by type\n */\nexport function getFeature(\n\ttable: FeatTable,\n\tfeatureType: FeatureType | uint16,\n): FeatureRecord | undefined {\n\treturn table.features.find((f) => f.featureType === featureType);\n}\n\n/**\n * Get all features of a given type\n */\nexport function getAllFeatures(table: FeatTable): FeatureRecord[] {\n\treturn table.features;\n}\n\n/**\n * Check if a feature is exclusive (only one setting can be active)\n */\nexport function isExclusiveFeature(feature: FeatureRecord): boolean {\n\treturn (feature.featureFlags & FeatureFlags.Exclusive) !== 0;\n}\n\n/**\n * Get the default setting for a feature\n */\nexport function getDefaultSetting(\n\tfeature: FeatureRecord,\n): FeatureSetting | undefined {\n\treturn feature.settings[feature.defaultSettingIndex];\n}\n\n/**\n * Get a setting by value\n */\nexport function getSettingByValue(\n\tfeature: FeatureRecord,\n\tsettingValue: uint16,\n): FeatureSetting | undefined {\n\treturn feature.settings.find((s) => s.settingValue === settingValue);\n}\n\n/**\n * Check if a feature has a specific setting\n */\nexport function hasSettingValue(\n\tfeature: FeatureRecord,\n\tsettingValue: uint16,\n): boolean {\n\treturn feature.settings.some((s) => s.settingValue === settingValue);\n}\n\n/**\n * Convert AAT feature type/setting to OpenType feature tag\n * This is a best-effort mapping as there's no 1:1 correspondence\n */\nexport function aatToOpenTypeTag(\n\tfeatureType: FeatureType | uint16,\n\tsettingValue: uint16,\n): string | null {\n\tswitch (featureType) {\n\t\tcase FeatureType.Ligatures:\n\t\t\tswitch (settingValue) {\n\t\t\t\tcase LigatureSetting.CommonLigaturesOn:\n\t\t\t\t\treturn \"liga\";\n\t\t\t\tcase LigatureSetting.RareLigaturesOn:\n\t\t\t\t\treturn \"dlig\";\n\t\t\t\tcase LigatureSetting.HistoricalLigaturesOn:\n\t\t\t\t\treturn \"hlig\";\n\t\t\t\tcase LigatureSetting.ContextualLigaturesOn:\n\t\t\t\t\treturn \"clig\";\n\t\t\t\tcase LigatureSetting.RequiredLigaturesOn:\n\t\t\t\t\treturn \"rlig\";\n\t\t\t}\n\t\t\tbreak;\n\t\tcase FeatureType.VerticalPosition:\n\t\t\tswitch (settingValue) {\n\t\t\t\tcase VerticalPositionSetting.Superiors:\n\t\t\t\t\treturn \"sups\";\n\t\t\t\tcase VerticalPositionSetting.Inferiors:\n\t\t\t\t\treturn \"subs\";\n\t\t\t\tcase VerticalPositionSetting.Ordinals:\n\t\t\t\t\treturn \"ordn\";\n\t\t\t\tcase VerticalPositionSetting.ScientificInferiors:\n\t\t\t\t\treturn \"sinf\";\n\t\t\t}\n\t\t\tbreak;\n\t\tcase FeatureType.Fractions:\n\t\t\tif (\n\t\t\t\tsettingValue === FractionsSetting.VerticalFractions ||\n\t\t\t\tsettingValue === FractionsSetting.DiagonalFractions\n\t\t\t) {\n\t\t\t\treturn \"frac\";\n\t\t\t}\n\t\t\tbreak;\n\t\tcase FeatureType.NumberCase:\n\t\t\tswitch (settingValue) {\n\t\t\t\tcase NumberCaseSetting.LowerCaseNumbers:\n\t\t\t\t\treturn \"onum\";\n\t\t\t\tcase NumberCaseSetting.UpperCaseNumbers:\n\t\t\t\t\treturn \"lnum\";\n\t\t\t}\n\t\t\tbreak;\n\t\tcase FeatureType.NumberSpacing:\n\t\t\tswitch (settingValue) {\n\t\t\t\tcase NumberSpacingSetting.MonospacedNumbers:\n\t\t\t\t\treturn \"tnum\";\n\t\t\t\tcase NumberSpacingSetting.ProportionalNumbers:\n\t\t\t\t\treturn \"pnum\";\n\t\t\t}\n\t\t\tbreak;\n\t\tcase FeatureType.CaseSensitiveLayout:\n\t\t\tif (settingValue === CaseSensitiveLayoutSetting.CaseSensitiveLayoutOn) {\n\t\t\t\treturn \"case\";\n\t\t\t}\n\t\t\tbreak;\n\t\tcase FeatureType.LowerCase:\n\t\t\tswitch (settingValue) {\n\t\t\t\tcase LowerCaseSetting.LowerCaseSmallCaps:\n\t\t\t\t\treturn \"smcp\";\n\t\t\t\tcase LowerCaseSetting.LowerCasePetiteCaps:\n\t\t\t\t\treturn \"pcap\";\n\t\t\t}\n\t\t\tbreak;\n\t\tcase FeatureType.UpperCase:\n\t\t\tswitch (settingValue) {\n\t\t\t\tcase UpperCaseSetting.UpperCaseSmallCaps:\n\t\t\t\t\treturn \"c2sc\";\n\t\t\t\tcase UpperCaseSetting.UpperCasePetiteCaps:\n\t\t\t\t\treturn \"c2pc\";\n\t\t\t}\n\t\t\tbreak;\n\t\tcase FeatureType.SmartSwashes:\n\t\t\tif (\n\t\t\t\tsettingValue === SmartSwashSetting.WordInitialSwashesOn ||\n\t\t\t\tsettingValue === SmartSwashSetting.WordFinalSwashesOn\n\t\t\t) {\n\t\t\t\treturn \"swsh\";\n\t\t\t}\n\t\t\tbreak;\n\t\tcase FeatureType.ContextualAlternatives:\n\t\t\tswitch (settingValue) {\n\t\t\t\tcase ContextualAlternativesSetting.ContextualAlternatesOn:\n\t\t\t\t\treturn \"calt\";\n\t\t\t\tcase ContextualAlternativesSetting.SwashAlternatesOn:\n\t\t\t\t\treturn \"swsh\";\n\t\t\t}\n\t\t\tbreak;\n\t\tcase FeatureType.StylisticAlternatives:\n\t\t\t// Stylistic sets ss01-ss20\n\t\t\tif (settingValue >= 2 && settingValue <= 41) {\n\t\t\t\tconst setNum = Math.floor((settingValue - 2) / 2) + 1;\n\t\t\t\tif (setNum <= 20) {\n\t\t\t\t\treturn `ss${setNum.toString().padStart(2, \"0\")}`;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase FeatureType.CharacterShape:\n\t\t\tswitch (settingValue) {\n\t\t\t\tcase CharacterShapeSetting.TraditionalCharacters:\n\t\t\t\t\treturn \"trad\";\n\t\t\t\tcase CharacterShapeSetting.SimplifiedCharacters:\n\t\t\t\t\treturn \"smpl\";\n\t\t\t\tcase CharacterShapeSetting.JIS1978Characters:\n\t\t\t\t\treturn \"jp78\";\n\t\t\t\tcase CharacterShapeSetting.JIS1983Characters:\n\t\t\t\t\treturn \"jp83\";\n\t\t\t\tcase CharacterShapeSetting.JIS1990Characters:\n\t\t\t\t\treturn \"jp90\";\n\t\t\t\tcase CharacterShapeSetting.JIS2004Characters:\n\t\t\t\t\treturn \"jp04\";\n\t\t\t\tcase CharacterShapeSetting.NLCCharacters:\n\t\t\t\t\treturn \"nlck\";\n\t\t\t\tcase CharacterShapeSetting.ExpertCharacters:\n\t\t\t\t\treturn \"expt\";\n\t\t\t\tcase CharacterShapeSetting.HojoCharacters:\n\t\t\t\t\treturn \"hojo\";\n\t\t\t}\n\t\t\tbreak;\n\t\tcase FeatureType.VerticalSubstitution:\n\t\t\treturn \"vert\";\n\t\tcase FeatureType.Annotation:\n\t\t\treturn \"nalt\";\n\t\tcase FeatureType.RubyKana:\n\t\t\treturn \"ruby\";\n\t}\n\n\treturn null;\n}\n\n/**\n * Convert OpenType feature tag to AAT feature type/setting\n * Returns null if no mapping exists\n */\nexport function openTypeTagToAat(\n\ttag: string,\n): { featureType: FeatureType; settingValue: uint16 } | null {\n\tswitch (tag) {\n\t\tcase \"liga\":\n\t\t\treturn {\n\t\t\t\tfeatureType: FeatureType.Ligatures,\n\t\t\t\tsettingValue: LigatureSetting.CommonLigaturesOn,\n\t\t\t};\n\t\tcase \"dlig\":\n\t\t\treturn {\n\t\t\t\tfeatureType: FeatureType.Ligatures,\n\t\t\t\tsettingValue: LigatureSetting.RareLigaturesOn,\n\t\t\t};\n\t\tcase \"hlig\":\n\t\t\treturn {\n\t\t\t\tfeatureType: FeatureType.Ligatures,\n\t\t\t\tsettingValue: LigatureSetting.HistoricalLigaturesOn,\n\t\t\t};\n\t\tcase \"clig\":\n\t\t\treturn {\n\t\t\t\tfeatureType: FeatureType.Ligatures,\n\t\t\t\tsettingValue: LigatureSetting.ContextualLigaturesOn,\n\t\t\t};\n\t\tcase \"rlig\":\n\t\t\treturn {\n\t\t\t\tfeatureType: FeatureType.Ligatures,\n\t\t\t\tsettingValue: LigatureSetting.RequiredLigaturesOn,\n\t\t\t};\n\t\tcase \"sups\":\n\t\t\treturn {\n\t\t\t\tfeatureType: FeatureType.VerticalPosition,\n\t\t\t\tsettingValue: VerticalPositionSetting.Superiors,\n\t\t\t};\n\t\tcase \"subs\":\n\t\t\treturn {\n\t\t\t\tfeatureType: FeatureType.VerticalPosition,\n\t\t\t\tsettingValue: VerticalPositionSetting.Inferiors,\n\t\t\t};\n\t\tcase \"ordn\":\n\t\t\treturn {\n\t\t\t\tfeatureType: FeatureType.VerticalPosition,\n\t\t\t\tsettingValue: VerticalPositionSetting.Ordinals,\n\t\t\t};\n\t\tcase \"sinf\":\n\t\t\treturn {\n\t\t\t\tfeatureType: FeatureType.VerticalPosition,\n\t\t\t\tsettingValue: VerticalPositionSetting.ScientificInferiors,\n\t\t\t};\n\t\tcase \"frac\":\n\t\t\treturn {\n\t\t\t\tfeatureType: FeatureType.Fractions,\n\t\t\t\tsettingValue: FractionsSetting.DiagonalFractions,\n\t\t\t};\n\t\tcase \"onum\":\n\t\t\treturn {\n\t\t\t\tfeatureType: FeatureType.NumberCase,\n\t\t\t\tsettingValue: NumberCaseSetting.LowerCaseNumbers,\n\t\t\t};\n\t\tcase \"lnum\":\n\t\t\treturn {\n\t\t\t\tfeatureType: FeatureType.NumberCase,\n\t\t\t\tsettingValue: NumberCaseSetting.UpperCaseNumbers,\n\t\t\t};\n\t\tcase \"tnum\":\n\t\t\treturn {\n\t\t\t\tfeatureType: FeatureType.NumberSpacing,\n\t\t\t\tsettingValue: NumberSpacingSetting.MonospacedNumbers,\n\t\t\t};\n\t\tcase \"pnum\":\n\t\t\treturn {\n\t\t\t\tfeatureType: FeatureType.NumberSpacing,\n\t\t\t\tsettingValue: NumberSpacingSetting.ProportionalNumbers,\n\t\t\t};\n\t\tcase \"case\":\n\t\t\treturn {\n\t\t\t\tfeatureType: FeatureType.CaseSensitiveLayout,\n\t\t\t\tsettingValue: CaseSensitiveLayoutSetting.CaseSensitiveLayoutOn,\n\t\t\t};\n\t\tcase \"smcp\":\n\t\t\treturn {\n\t\t\t\tfeatureType: FeatureType.LowerCase,\n\t\t\t\tsettingValue: LowerCaseSetting.LowerCaseSmallCaps,\n\t\t\t};\n\t\tcase \"pcap\":\n\t\t\treturn {\n\t\t\t\tfeatureType: FeatureType.LowerCase,\n\t\t\t\tsettingValue: LowerCaseSetting.LowerCasePetiteCaps,\n\t\t\t};\n\t\tcase \"c2sc\":\n\t\t\treturn {\n\t\t\t\tfeatureType: FeatureType.UpperCase,\n\t\t\t\tsettingValue: UpperCaseSetting.UpperCaseSmallCaps,\n\t\t\t};\n\t\tcase \"c2pc\":\n\t\t\treturn {\n\t\t\t\tfeatureType: FeatureType.UpperCase,\n\t\t\t\tsettingValue: UpperCaseSetting.UpperCasePetiteCaps,\n\t\t\t};\n\t\tcase \"swsh\":\n\t\t\treturn {\n\t\t\t\tfeatureType: FeatureType.SmartSwashes,\n\t\t\t\tsettingValue: SmartSwashSetting.WordInitialSwashesOn,\n\t\t\t};\n\t\tcase \"calt\":\n\t\t\treturn {\n\t\t\t\tfeatureType: FeatureType.ContextualAlternatives,\n\t\t\t\tsettingValue: ContextualAlternativesSetting.ContextualAlternatesOn,\n\t\t\t};\n\t\tcase \"trad\":\n\t\t\treturn {\n\t\t\t\tfeatureType: FeatureType.CharacterShape,\n\t\t\t\tsettingValue: CharacterShapeSetting.TraditionalCharacters,\n\t\t\t};\n\t\tcase \"smpl\":\n\t\t\treturn {\n\t\t\t\tfeatureType: FeatureType.CharacterShape,\n\t\t\t\tsettingValue: CharacterShapeSetting.SimplifiedCharacters,\n\t\t\t};\n\t\tcase \"jp78\":\n\t\t\treturn {\n\t\t\t\tfeatureType: FeatureType.CharacterShape,\n\t\t\t\tsettingValue: CharacterShapeSetting.JIS1978Characters,\n\t\t\t};\n\t\tcase \"jp83\":\n\t\t\treturn {\n\t\t\t\tfeatureType: FeatureType.CharacterShape,\n\t\t\t\tsettingValue: CharacterShapeSetting.JIS1983Characters,\n\t\t\t};\n\t\tcase \"jp90\":\n\t\t\treturn {\n\t\t\t\tfeatureType: FeatureType.CharacterShape,\n\t\t\t\tsettingValue: CharacterShapeSetting.JIS1990Characters,\n\t\t\t};\n\t\tcase \"jp04\":\n\t\t\treturn {\n\t\t\t\tfeatureType: FeatureType.CharacterShape,\n\t\t\t\tsettingValue: CharacterShapeSetting.JIS2004Characters,\n\t\t\t};\n\t\tcase \"nlck\":\n\t\t\treturn {\n\t\t\t\tfeatureType: FeatureType.CharacterShape,\n\t\t\t\tsettingValue: CharacterShapeSetting.NLCCharacters,\n\t\t\t};\n\t\tcase \"expt\":\n\t\t\treturn {\n\t\t\t\tfeatureType: FeatureType.CharacterShape,\n\t\t\t\tsettingValue: CharacterShapeSetting.ExpertCharacters,\n\t\t\t};\n\t\tcase \"hojo\":\n\t\t\treturn {\n\t\t\t\tfeatureType: FeatureType.CharacterShape,\n\t\t\t\tsettingValue: CharacterShapeSetting.HojoCharacters,\n\t\t\t};\n\t\tcase \"vert\":\n\t\t\treturn { featureType: FeatureType.VerticalSubstitution, settingValue: 0 };\n\t\tcase \"nalt\":\n\t\t\treturn { featureType: FeatureType.Annotation, settingValue: 0 };\n\t\tcase \"ruby\":\n\t\t\treturn { featureType: FeatureType.RubyKana, settingValue: 0 };\n\t}\n\n\t// Handle stylistic sets ss01-ss20\n\tif (tag.startsWith(\"ss\") && tag.length === 4) {\n\t\tconst num = parseInt(tag.slice(2), 10);\n\t\tif (num >= 1 && num <= 20) {\n\t\t\treturn {\n\t\t\t\tfeatureType: FeatureType.StylisticAlternatives,\n\t\t\t\tsettingValue: (num - 1) * 2 + 2,\n\t\t\t};\n\t\t}\n\t}\n\n\treturn null;\n}\n",
29
- "/**\n * gasp table - Grid-fitting And Scan-conversion Procedure\n *\n * This table controls when grid-fitting (hinting) and anti-aliasing\n * should be applied based on the rendering size (ppem).\n */\n\nimport type { Reader } from \"../binary/reader.ts\";\n\n/**\n * Gasp behavior flags\n */\nexport const GaspFlag = {\n\t/** Use grid-fitting (hinting) */\n\tGridFit: 0x0001,\n\t/** Use gray-scale rendering (anti-aliasing) */\n\tDoGray: 0x0002,\n\t/** Use symmetric grid-fitting (ClearType) */\n\tSymmetricGridFit: 0x0004,\n\t/** Use symmetric smoothing (ClearType) */\n\tSymmetricSmoothing: 0x0008,\n} as const;\n\n/**\n * A ppem range with associated behavior\n */\nexport interface GaspRange {\n\t/** Maximum ppem for this range (inclusive) */\n\tmaxPPEM: number;\n\t/** Behavior flags for this range */\n\tbehavior: number;\n}\n\n/**\n * gasp table\n */\nexport interface GaspTable {\n\t/** Version (0 or 1) */\n\tversion: number;\n\t/** Ranges sorted by maxPPEM */\n\tranges: GaspRange[];\n}\n\n/**\n * Parse gasp table\n */\nexport function parseGasp(reader: Reader): GaspTable {\n\tconst version = reader.uint16();\n\tconst numRanges = reader.uint16();\n\n\tconst ranges: GaspRange[] = [];\n\tfor (let i = 0; i < numRanges; i++) {\n\t\tconst maxPPEM = reader.uint16();\n\t\tconst behavior = reader.uint16();\n\t\tranges.push({ maxPPEM, behavior });\n\t}\n\n\t// Ranges should be sorted by maxPPEM\n\tranges.sort((a, b) => a.maxPPEM - b.maxPPEM);\n\n\treturn { version, ranges };\n}\n\n/**\n * Get behavior flags for a specific ppem\n */\nexport function getGaspBehavior(gasp: GaspTable, ppem: number): number {\n\tfor (const range of gasp.ranges) {\n\t\tif (ppem <= range.maxPPEM) {\n\t\t\treturn range.behavior;\n\t\t}\n\t}\n\n\t// Above all ranges - use last range or default to all features\n\tif (gasp.ranges.length > 0) {\n\t\treturn gasp.ranges[gasp.ranges.length - 1]?.behavior;\n\t}\n\n\treturn GaspFlag.GridFit | GaspFlag.DoGray;\n}\n\n/**\n * Check if grid-fitting should be used\n */\nexport function shouldGridFit(gasp: GaspTable, ppem: number): boolean {\n\treturn (getGaspBehavior(gasp, ppem) & GaspFlag.GridFit) !== 0;\n}\n\n/**\n * Check if gray-scale rendering should be used\n */\nexport function shouldDoGray(gasp: GaspTable, ppem: number): boolean {\n\treturn (getGaspBehavior(gasp, ppem) & GaspFlag.DoGray) !== 0;\n}\n",
30
- "import type { Reader } from \"../../font/binary/reader.ts\";\nimport type { GlyphId, uint16 } from \"../../types.ts\";\n\n/** Class Definition table - maps glyph IDs to class values */\nexport interface ClassDef {\n\t/** Get class for a glyph ID (returns 0 if not defined) */\n\tget(glyphId: GlyphId): number;\n\n\t/** Get all glyphs in a specific class */\n\tglyphsInClass(classValue: number): GlyphId[];\n}\n\n/** Format 1: Array of class values for a range of glyph IDs */\nclass ClassDefFormat1 implements ClassDef {\n\tprivate readonly startGlyphId: GlyphId;\n\tprivate readonly classValueArray: Uint16Array;\n\n\tconstructor(startGlyphId: GlyphId, classValueArray: Uint16Array) {\n\t\tthis.startGlyphId = startGlyphId;\n\t\tthis.classValueArray = classValueArray;\n\t}\n\n\tget(glyphId: GlyphId): number {\n\t\tconst index = glyphId - this.startGlyphId;\n\t\tif (index >= 0 && index < this.classValueArray.length) {\n\t\t\tconst value = this.classValueArray[index];\n\t\t\treturn value ?? 0;\n\t\t}\n\t\treturn 0; // Default class\n\t}\n\n\tglyphsInClass(classValue: number): GlyphId[] {\n\t\tconst result: GlyphId[] = [];\n\t\tfor (let i = 0; i < this.classValueArray.length; i++) {\n\t\t\tif (this.classValueArray[i] === classValue) {\n\t\t\t\tresult.push(this.startGlyphId + i);\n\t\t\t}\n\t\t}\n\t\treturn result;\n\t}\n}\n\n/** Class range record for Format 2 */\ninterface ClassRangeRecord {\n\tstartGlyphId: GlyphId;\n\tendGlyphId: GlyphId;\n\tclassValue: uint16;\n}\n\n/** Format 2: Ranges of glyph IDs with class values */\nclass ClassDefFormat2 implements ClassDef {\n\tprivate readonly ranges: ClassRangeRecord[];\n\n\tconstructor(ranges: ClassRangeRecord[]) {\n\t\tthis.ranges = ranges;\n\t}\n\n\tget(glyphId: GlyphId): number {\n\t\t// Binary search through ranges\n\t\tlet low = 0;\n\t\tlet high = this.ranges.length - 1;\n\n\t\twhile (low <= high) {\n\t\t\tconst mid = (low + high) >>> 1;\n\t\t\tconst range = this.ranges[mid];\n\t\t\tif (!range) continue;\n\n\t\t\tif (glyphId > range.endGlyphId) {\n\t\t\t\tlow = mid + 1;\n\t\t\t} else if (glyphId < range.startGlyphId) {\n\t\t\t\thigh = mid - 1;\n\t\t\t} else {\n\t\t\t\treturn range.classValue;\n\t\t\t}\n\t\t}\n\n\t\treturn 0; // Default class\n\t}\n\n\tglyphsInClass(classValue: number): GlyphId[] {\n\t\tconst result: GlyphId[] = [];\n\t\tfor (const range of this.ranges) {\n\t\t\tif (range.classValue === classValue) {\n\t\t\t\tfor (let g = range.startGlyphId; g <= range.endGlyphId; g++) {\n\t\t\t\t\tresult.push(g);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn result;\n\t}\n}\n\n/** Empty class definition (all glyphs are class 0) */\nclass ClassDefEmpty implements ClassDef {\n\tget(_glyphId: GlyphId): number {\n\t\treturn 0;\n\t}\n\n\tglyphsInClass(_classValue: number): GlyphId[] {\n\t\treturn [];\n\t}\n}\n\n/** Singleton empty ClassDef */\nexport const EMPTY_CLASS_DEF: ClassDef = new ClassDefEmpty();\n\n/** Parse a Class Definition table */\nexport function parseClassDef(reader: Reader): ClassDef {\n\tconst format = reader.uint16();\n\n\tif (format === 1) {\n\t\tconst startGlyphId = reader.uint16();\n\t\tconst glyphCount = reader.uint16();\n\t\tconst classValueArray = reader.uint16Array(glyphCount);\n\t\treturn new ClassDefFormat1(startGlyphId, classValueArray);\n\t}\n\n\tif (format === 2) {\n\t\tconst classRangeCount = reader.uint16();\n\t\tconst ranges: ClassRangeRecord[] = new Array(classRangeCount);\n\n\t\tfor (let i = 0; i < classRangeCount; i++) {\n\t\t\tranges[i] = {\n\t\t\t\tstartGlyphId: reader.uint16(),\n\t\t\t\tendGlyphId: reader.uint16(),\n\t\t\t\tclassValue: reader.uint16(),\n\t\t\t};\n\t\t}\n\n\t\treturn new ClassDefFormat2(ranges);\n\t}\n\n\tthrow new Error(`Unknown ClassDef format: ${format}`);\n}\n\n/** Parse ClassDef from offset, or return empty if offset is 0 */\nexport function parseClassDefAt(reader: Reader, offset: number): ClassDef {\n\tif (offset === 0) {\n\t\treturn EMPTY_CLASS_DEF;\n\t}\n\treturn parseClassDef(reader.sliceFrom(offset));\n}\n",
31
- "import {\n\ttype ClassDef,\n\tparseClassDefAt,\n} from \"../../layout/structures/class-def.ts\";\nimport type { GlyphId, uint16 } from \"../../types.ts\";\nimport { GlyphClass } from \"../../types.ts\";\nimport type { Reader } from \"../binary/reader.ts\";\n\n/** Attach point for a glyph */\nexport interface AttachPoint {\n\tpointIndices: uint16[];\n}\n\n/** Ligature caret for a ligature glyph */\nexport interface LigatureCaret {\n\tcaretValues: number[];\n}\n\n/** Mark glyph sets */\nexport interface MarkGlyphSets {\n\t/** Check if glyph is in mark set */\n\thas(setIndex: number, glyphId: GlyphId): boolean;\n}\n\n/** Glyph Definition table */\nexport interface GdefTable {\n\tversion: { major: number; minor: number };\n\n\t/** Glyph class definitions (Base=1, Ligature=2, Mark=3, Component=4) */\n\tglyphClassDef: ClassDef;\n\n\t/** Attachment point list (optional) */\n\tattachList: Map<GlyphId, AttachPoint> | null;\n\n\t/** Ligature caret list (optional) */\n\tligCaretList: Map<GlyphId, LigatureCaret> | null;\n\n\t/** Mark attachment class definitions */\n\tmarkAttachClassDef: ClassDef;\n\n\t/** Mark glyph sets (version 1.2+) */\n\tmarkGlyphSets: MarkGlyphSets | null;\n}\n\nexport function parseGdef(reader: Reader): GdefTable {\n\tconst majorVersion = reader.uint16();\n\tconst minorVersion = reader.uint16();\n\n\tconst glyphClassDefOffset = reader.offset16();\n\tconst attachListOffset = reader.offset16();\n\tconst ligCaretListOffset = reader.offset16();\n\tconst markAttachClassDefOffset = reader.offset16();\n\n\tlet markGlyphSetsDefOffset = 0;\n\tif (majorVersion === 1 && minorVersion >= 2) {\n\t\tmarkGlyphSetsDefOffset = reader.offset16();\n\t}\n\n\t// Parse glyph class definitions\n\tconst glyphClassDef = parseClassDefAt(reader, glyphClassDefOffset);\n\n\t// Parse attachment list (optional)\n\tlet attachList: Map<GlyphId, AttachPoint> | null = null;\n\tif (attachListOffset !== 0) {\n\t\tattachList = parseAttachList(reader.sliceFrom(attachListOffset));\n\t}\n\n\t// Parse ligature caret list (optional)\n\tlet ligCaretList: Map<GlyphId, LigatureCaret> | null = null;\n\tif (ligCaretListOffset !== 0) {\n\t\tligCaretList = parseLigCaretList(reader.sliceFrom(ligCaretListOffset));\n\t}\n\n\t// Parse mark attachment class definitions\n\tconst markAttachClassDef = parseClassDefAt(reader, markAttachClassDefOffset);\n\n\t// Parse mark glyph sets (version 1.2+)\n\tlet markGlyphSets: MarkGlyphSets | null = null;\n\tif (markGlyphSetsDefOffset !== 0) {\n\t\tmarkGlyphSets = parseMarkGlyphSets(\n\t\t\treader.sliceFrom(markGlyphSetsDefOffset),\n\t\t);\n\t}\n\n\treturn {\n\t\tversion: { major: majorVersion, minor: minorVersion },\n\t\tglyphClassDef,\n\t\tattachList,\n\t\tligCaretList,\n\t\tmarkAttachClassDef,\n\t\tmarkGlyphSets,\n\t};\n}\n\nexport function parseAttachList(reader: Reader): Map<GlyphId, AttachPoint> {\n\tconst coverageOffset = reader.offset16();\n\tconst glyphCount = reader.uint16();\n\n\t// Read attach point offsets\n\tconst attachPointOffsets = reader.uint16Array(glyphCount);\n\n\t// Parse coverage to get glyph IDs\n\tconst coverageReader = reader.sliceFrom(coverageOffset);\n\tconst format = coverageReader.uint16();\n\n\tconst glyphIds: GlyphId[] = [];\n\tif (format === 1) {\n\t\tconst count = coverageReader.uint16();\n\t\tfor (let i = 0; i < count; i++) {\n\t\t\tglyphIds.push(coverageReader.uint16());\n\t\t}\n\t} else if (format === 2) {\n\t\tconst rangeCount = coverageReader.uint16();\n\t\tfor (let i = 0; i < rangeCount; i++) {\n\t\t\tconst start = coverageReader.uint16();\n\t\t\tconst end = coverageReader.uint16();\n\t\t\tcoverageReader.skip(2); // startCoverageIndex\n\t\t\tfor (let g = start; g <= end; g++) {\n\t\t\t\tglyphIds.push(g);\n\t\t\t}\n\t\t}\n\t}\n\n\t// Parse attach points\n\tconst result = new Map<GlyphId, AttachPoint>();\n\tfor (const [i, offset] of attachPointOffsets.entries()) {\n\t\tconst glyphId = glyphIds[i];\n\t\tif (glyphId === undefined) continue;\n\n\t\tconst pointReader = reader.sliceFrom(offset);\n\t\tconst pointCount = pointReader.uint16();\n\t\tconst pointIndices = Array.from(pointReader.uint16Array(pointCount));\n\n\t\tresult.set(glyphId, { pointIndices });\n\t}\n\n\treturn result;\n}\n\nexport function parseLigCaretList(reader: Reader): Map<GlyphId, LigatureCaret> {\n\tconst coverageOffset = reader.offset16();\n\tconst ligGlyphCount = reader.uint16();\n\n\t// Read ligature glyph offsets\n\tconst ligGlyphOffsets = reader.uint16Array(ligGlyphCount);\n\n\t// Parse coverage to get glyph IDs\n\tconst coverageReader = reader.sliceFrom(coverageOffset);\n\tconst format = coverageReader.uint16();\n\n\tconst glyphIds: GlyphId[] = [];\n\tif (format === 1) {\n\t\tconst count = coverageReader.uint16();\n\t\tfor (let i = 0; i < count; i++) {\n\t\t\tglyphIds.push(coverageReader.uint16());\n\t\t}\n\t} else if (format === 2) {\n\t\tconst rangeCount = coverageReader.uint16();\n\t\tfor (let i = 0; i < rangeCount; i++) {\n\t\t\tconst start = coverageReader.uint16();\n\t\t\tconst end = coverageReader.uint16();\n\t\t\tcoverageReader.skip(2);\n\t\t\tfor (let g = start; g <= end; g++) {\n\t\t\t\tglyphIds.push(g);\n\t\t\t}\n\t\t}\n\t}\n\n\t// Parse ligature glyphs\n\tconst result = new Map<GlyphId, LigatureCaret>();\n\tfor (const [i, offset] of ligGlyphOffsets.entries()) {\n\t\tconst glyphId = glyphIds[i];\n\t\tif (glyphId === undefined) continue;\n\n\t\tconst ligReader = reader.sliceFrom(offset);\n\t\tconst caretCount = ligReader.uint16();\n\t\tconst caretValueOffsets = ligReader.uint16Array(caretCount);\n\n\t\tconst caretValues: number[] = [];\n\t\tfor (const caretOffset of caretValueOffsets) {\n\t\t\tconst caretReader = reader.sliceFrom(offset + caretOffset);\n\t\t\tconst caretFormat = caretReader.uint16();\n\n\t\t\tif (caretFormat === 1) {\n\t\t\t\t// Design units\n\t\t\t\tcaretValues.push(caretReader.int16());\n\t\t\t} else if (caretFormat === 2) {\n\t\t\t\t// Contour point\n\t\t\t\tcaretValues.push(caretReader.uint16()); // point index\n\t\t\t} else if (caretFormat === 3) {\n\t\t\t\t// Design units + device table\n\t\t\t\tcaretValues.push(caretReader.int16());\n\t\t\t}\n\t\t}\n\n\t\tresult.set(glyphId, { caretValues });\n\t}\n\n\treturn result;\n}\n\nexport function parseMarkGlyphSets(reader: Reader): MarkGlyphSets {\n\tconst _format = reader.uint16();\n\tconst markSetCount = reader.uint16();\n\n\t// Read coverage offsets\n\tconst coverageOffsets = reader.uint32Array(markSetCount);\n\n\t// Parse each mark set coverage\n\tconst markSets: Set<GlyphId>[] = [];\n\tfor (const offset of coverageOffsets) {\n\t\tconst coverageReader = reader.sliceFrom(offset);\n\t\tconst coverageFormat = coverageReader.uint16();\n\n\t\tconst glyphSet = new Set<GlyphId>();\n\t\tif (coverageFormat === 1) {\n\t\t\tconst count = coverageReader.uint16();\n\t\t\tfor (let i = 0; i < count; i++) {\n\t\t\t\tglyphSet.add(coverageReader.uint16());\n\t\t\t}\n\t\t} else if (coverageFormat === 2) {\n\t\t\tconst rangeCount = coverageReader.uint16();\n\t\t\tfor (let i = 0; i < rangeCount; i++) {\n\t\t\t\tconst start = coverageReader.uint16();\n\t\t\t\tconst end = coverageReader.uint16();\n\t\t\t\tcoverageReader.skip(2);\n\t\t\t\tfor (let g = start; g <= end; g++) {\n\t\t\t\t\tglyphSet.add(g);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tmarkSets.push(glyphSet);\n\t}\n\n\treturn {\n\t\thas(setIndex: number, glyphId: GlyphId): boolean {\n\t\t\tconst set = markSets[setIndex];\n\t\t\treturn set ? set.has(glyphId) : false;\n\t\t},\n\t};\n}\n\n/** Get glyph class from GDEF */\nexport function getGlyphClass(\n\tgdef: GdefTable | null,\n\tglyphId: GlyphId,\n): GlyphClass | 0 {\n\tif (!gdef) return 0;\n\tconst cls = gdef.glyphClassDef.get(glyphId);\n\treturn cls as GlyphClass | 0;\n}\n\n/** Check if glyph is a base glyph */\nexport function isBaseGlyph(gdef: GdefTable | null, glyphId: GlyphId): boolean {\n\treturn getGlyphClass(gdef, glyphId) === GlyphClass.Base;\n}\n\n/** Check if glyph is a ligature */\nexport function isLigature(gdef: GdefTable | null, glyphId: GlyphId): boolean {\n\treturn getGlyphClass(gdef, glyphId) === GlyphClass.Ligature;\n}\n\n/** Check if glyph is a mark */\nexport function isMark(gdef: GdefTable | null, glyphId: GlyphId): boolean {\n\treturn getGlyphClass(gdef, glyphId) === GlyphClass.Mark;\n}\n\n/** Check if glyph is a component */\nexport function isComponent(gdef: GdefTable | null, glyphId: GlyphId): boolean {\n\treturn getGlyphClass(gdef, glyphId) === GlyphClass.Component;\n}\n",
32
- "import type { GlyphId, int16, uint16 } from \"../../types.ts\";\nimport type { Reader } from \"../binary/reader.ts\";\n\n/**\n * Glyph Variations table (gvar)\n * Contains variation data for TrueType glyph outlines\n */\nexport interface GvarTable {\n\tmajorVersion: uint16;\n\tminorVersion: uint16;\n\taxisCount: uint16;\n\tsharedTupleCount: uint16;\n\tsharedTuples: number[][]; // [tupleIndex][axisIndex]\n\tglyphVariationData: GlyphVariationData[];\n}\n\n/**\n * Variation data for a single glyph\n */\nexport interface GlyphVariationData {\n\ttupleVariationHeaders: TupleVariationHeader[];\n}\n\n/**\n * Tuple variation header\n */\nexport interface TupleVariationHeader {\n\tvariationDataSize: uint16;\n\ttupleIndex: uint16;\n\tpeakTuple: number[] | null; // null if embedded in shared tuples\n\tintermediateStartTuple: number[] | null;\n\tintermediateEndTuple: number[] | null;\n\tserializedData: Uint8Array;\n\tpointNumbers: number[] | null; // null means all points\n\tdeltas: PointDelta[];\n}\n\n/**\n * Delta values for a point\n */\nexport interface PointDelta {\n\tx: int16;\n\ty: int16;\n}\n\n// Tuple flags\nconst EMBEDDED_PEAK_TUPLE = 0x8000;\nconst INTERMEDIATE_REGION = 0x4000;\nconst PRIVATE_POINT_NUMBERS = 0x2000;\nconst TUPLE_INDEX_MASK = 0x0fff;\n\n/**\n * Parse gvar table\n */\nexport function parseGvar(reader: Reader, _numGlyphs: number): GvarTable {\n\tconst majorVersion = reader.uint16();\n\tconst minorVersion = reader.uint16();\n\tconst axisCount = reader.uint16();\n\tconst sharedTupleCount = reader.uint16();\n\tconst sharedTuplesOffset = reader.offset32();\n\tconst glyphCount = reader.uint16();\n\tconst flags = reader.uint16();\n\tconst glyphVariationDataArrayOffset = reader.offset32();\n\n\tconst offsetSize = flags & 1 ? 4 : 2;\n\n\t// Read glyph offsets\n\tconst offsets: number[] = [];\n\tfor (let i = 0; i <= glyphCount; i++) {\n\t\tconst offset = offsetSize === 4 ? reader.uint32() : reader.uint16() * 2;\n\t\toffsets.push(offset);\n\t}\n\n\t// Parse shared tuples\n\tconst sharedTuples: number[][] = [];\n\tif (sharedTupleCount > 0) {\n\t\tconst tupleReader = reader.sliceFrom(sharedTuplesOffset);\n\t\tfor (let i = 0; i < sharedTupleCount; i++) {\n\t\t\tconst tuple: number[] = [];\n\t\t\tfor (let a = 0; a < axisCount; a++) {\n\t\t\t\ttuple.push(tupleReader.f2dot14());\n\t\t\t}\n\t\t\tsharedTuples.push(tuple);\n\t\t}\n\t}\n\n\t// Parse glyph variation data\n\tconst glyphVariationData: GlyphVariationData[] = [];\n\tfor (let g = 0; g < glyphCount; g++) {\n\t\tconst startOffset = offsets[g];\n\t\tconst endOffset = offsets[g + 1];\n\t\tif (startOffset === undefined || endOffset === undefined) {\n\t\t\tglyphVariationData.push({ tupleVariationHeaders: [] });\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst dataStart = glyphVariationDataArrayOffset + startOffset;\n\t\tconst dataEnd = glyphVariationDataArrayOffset + endOffset;\n\n\t\tif (dataStart === dataEnd) {\n\t\t\t// No variation data for this glyph\n\t\t\tglyphVariationData.push({ tupleVariationHeaders: [] });\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst dataReader = reader.sliceFrom(dataStart);\n\t\tconst variationData = parseGlyphVariationData(\n\t\t\tdataReader,\n\t\t\tdataEnd - dataStart,\n\t\t\taxisCount,\n\t\t\tsharedTuples,\n\t\t);\n\t\tglyphVariationData.push(variationData);\n\t}\n\n\treturn {\n\t\tmajorVersion,\n\t\tminorVersion,\n\t\taxisCount,\n\t\tsharedTupleCount,\n\t\tsharedTuples,\n\t\tglyphVariationData,\n\t};\n}\n\nfunction parseGlyphVariationData(\n\treader: Reader,\n\tdataLength: number,\n\taxisCount: number,\n\tsharedTuples: number[][],\n): GlyphVariationData {\n\tif (dataLength === 0) {\n\t\treturn { tupleVariationHeaders: [] };\n\t}\n\n\tconst startOffset = reader.offset;\n\tconst tupleVariationCount = reader.uint16();\n\tconst dataOffset = reader.offset16();\n\n\tconst tupleCount = tupleVariationCount & 0x0fff;\n\tconst hasSharedPointNumbers = (tupleVariationCount & 0x8000) !== 0;\n\n\t// Read tuple variation headers first\n\tconst headerData: Array<{\n\t\tvariationDataSize: uint16;\n\t\ttupleIndex: uint16;\n\t\tpeakTuple: number[] | null;\n\t\tintermediateStartTuple: number[] | null;\n\t\tintermediateEndTuple: number[] | null;\n\t}> = [];\n\n\tfor (let i = 0; i < tupleCount; i++) {\n\t\tconst variationDataSize = reader.uint16();\n\t\tconst tupleIndex = reader.uint16();\n\n\t\tlet peakTuple: number[] | null = null;\n\t\tlet intermediateStartTuple: number[] | null = null;\n\t\tlet intermediateEndTuple: number[] | null = null;\n\n\t\tif (tupleIndex & EMBEDDED_PEAK_TUPLE) {\n\t\t\tpeakTuple = [];\n\t\t\tfor (let a = 0; a < axisCount; a++) {\n\t\t\t\tpeakTuple.push(reader.f2dot14());\n\t\t\t}\n\t\t} else {\n\t\t\tconst sharedIndex = tupleIndex & TUPLE_INDEX_MASK;\n\t\t\tpeakTuple = sharedTuples[sharedIndex] || null;\n\t\t}\n\n\t\tif (tupleIndex & INTERMEDIATE_REGION) {\n\t\t\tintermediateStartTuple = [];\n\t\t\tintermediateEndTuple = [];\n\t\t\tfor (let a = 0; a < axisCount; a++) {\n\t\t\t\tintermediateStartTuple.push(reader.f2dot14());\n\t\t\t}\n\t\t\tfor (let a = 0; a < axisCount; a++) {\n\t\t\t\tintermediateEndTuple.push(reader.f2dot14());\n\t\t\t}\n\t\t}\n\n\t\theaderData.push({\n\t\t\tvariationDataSize,\n\t\t\ttupleIndex,\n\t\t\tpeakTuple,\n\t\t\tintermediateStartTuple,\n\t\t\tintermediateEndTuple,\n\t\t});\n\t}\n\n\t// Now parse serialized data starting at dataOffset\n\tconst dataReader = reader.sliceFrom(startOffset + dataOffset);\n\n\t// Parse shared point numbers if present\n\tlet sharedPoints: number[] | null = null;\n\tif (hasSharedPointNumbers) {\n\t\tsharedPoints = parsePackedPoints(dataReader);\n\t}\n\n\t// Parse each tuple's deltas\n\tconst headers: TupleVariationHeader[] = [];\n\tfor (const hd of headerData) {\n\t\tconst hasPrivatePoints = (hd.tupleIndex & PRIVATE_POINT_NUMBERS) !== 0;\n\n\t\tlet pointNumbers: number[] | null;\n\t\tif (hasPrivatePoints) {\n\t\t\tpointNumbers = parsePackedPoints(dataReader);\n\t\t} else {\n\t\t\tpointNumbers = sharedPoints;\n\t\t}\n\n\t\t// Calculate number of points to read deltas for\n\t\tconst numPoints = pointNumbers ? pointNumbers.length : 0;\n\n\t\t// Parse x deltas then y deltas\n\t\tconst xDeltas =\n\t\t\tnumPoints > 0 ? parsePackedDeltas(dataReader, numPoints) : [];\n\t\tconst yDeltas =\n\t\t\tnumPoints > 0 ? parsePackedDeltas(dataReader, numPoints) : [];\n\n\t\tconst deltas: PointDelta[] = [];\n\t\tfor (const [p, xDelta] of xDeltas.entries()) {\n\t\t\tconst yDelta = yDeltas[p];\n\t\t\tdeltas.push({\n\t\t\t\tx: xDelta ?? 0,\n\t\t\t\ty: yDelta ?? 0,\n\t\t\t});\n\t\t}\n\n\t\theaders.push({\n\t\t\tvariationDataSize: hd.variationDataSize,\n\t\t\ttupleIndex: hd.tupleIndex,\n\t\t\tpeakTuple: hd.peakTuple,\n\t\t\tintermediateStartTuple: hd.intermediateStartTuple,\n\t\t\tintermediateEndTuple: hd.intermediateEndTuple,\n\t\t\tserializedData: new Uint8Array(0),\n\t\t\tpointNumbers,\n\t\t\tdeltas,\n\t\t});\n\t}\n\n\treturn { tupleVariationHeaders: headers };\n}\n\n/**\n * Parse packed point numbers\n */\nfunction parsePackedPoints(reader: Reader): number[] {\n\tconst count = reader.uint8();\n\tconst totalPoints =\n\t\tcount === 0\n\t\t\t? 0\n\t\t\t: count & 0x80\n\t\t\t\t? ((count & 0x7f) << 8) | reader.uint8()\n\t\t\t\t: count;\n\n\tif (totalPoints === 0) {\n\t\treturn []; // All points\n\t}\n\n\tconst points: number[] = [];\n\tlet pointIdx = 0;\n\n\twhile (points.length < totalPoints) {\n\t\tconst runHeader = reader.uint8();\n\t\tconst runCount = (runHeader & 0x7f) + 1;\n\t\tconst pointsAreWords = (runHeader & 0x80) !== 0;\n\n\t\tfor (let i = 0; i < runCount && points.length < totalPoints; i++) {\n\t\t\tconst delta = pointsAreWords ? reader.uint16() : reader.uint8();\n\t\t\tpointIdx += delta;\n\t\t\tpoints.push(pointIdx);\n\t\t}\n\t}\n\n\treturn points;\n}\n\n/**\n * Parse packed deltas\n */\nexport function parsePackedDeltas(reader: Reader, count: number): number[] {\n\tconst deltas: number[] = [];\n\n\twhile (deltas.length < count) {\n\t\tconst runHeader = reader.uint8();\n\t\tconst runCount = (runHeader & 0x3f) + 1;\n\t\tconst deltasAreZero = (runHeader & 0x80) !== 0;\n\t\tconst deltasAreWords = (runHeader & 0x40) !== 0;\n\n\t\tfor (let i = 0; i < runCount && deltas.length < count; i++) {\n\t\t\tif (deltasAreZero) {\n\t\t\t\tdeltas.push(0);\n\t\t\t} else if (deltasAreWords) {\n\t\t\t\tdeltas.push(reader.int16());\n\t\t\t} else {\n\t\t\t\tdeltas.push(reader.int8());\n\t\t\t}\n\t\t}\n\t}\n\n\treturn deltas;\n}\n\n/**\n * Calculate the scalar for a tuple given axis coordinates\n */\nexport function calculateTupleScalar(\n\tpeakTuple: number[],\n\taxisCoords: number[],\n\tintermediateStart: number[] | null,\n\tintermediateEnd: number[] | null,\n): number {\n\tlet scalar = 1.0;\n\n\tfor (const [i, peak] of peakTuple.entries()) {\n\t\tconst coord = axisCoords[i] ?? 0;\n\n\t\tif (peak === 0 || coord === 0) {\n\t\t\tif (peak !== 0) scalar = 0;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (intermediateStart && intermediateEnd) {\n\t\t\tconst start = intermediateStart[i];\n\t\t\tconst end = intermediateEnd[i];\n\t\t\tif (start === undefined || end === undefined) continue;\n\n\t\t\tif (coord < start || coord > end) {\n\t\t\t\tscalar = 0;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif (coord < peak) {\n\t\t\t\tscalar *= (coord - start) / (peak - start);\n\t\t\t} else if (coord > peak) {\n\t\t\t\tscalar *= (end - coord) / (end - peak);\n\t\t\t}\n\t\t} else {\n\t\t\t// Simple case\n\t\t\tif ((peak > 0 && coord < 0) || (peak < 0 && coord > 0)) {\n\t\t\t\tscalar = 0;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif (Math.abs(coord) < Math.abs(peak)) {\n\t\t\t\tscalar *= coord / peak;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn scalar;\n}\n\n/**\n * Get delta for a glyph point at given variation coordinates\n */\nexport function getGlyphDelta(\n\tgvar: GvarTable,\n\tglyphId: GlyphId,\n\tpointIndex: number,\n\taxisCoords: number[],\n): PointDelta {\n\tconst glyphData = gvar.glyphVariationData[glyphId];\n\tif (!glyphData) return { x: 0, y: 0 };\n\n\tlet totalX = 0;\n\tlet totalY = 0;\n\n\tfor (const header of glyphData.tupleVariationHeaders) {\n\t\tif (!header.peakTuple) continue;\n\n\t\tconst scalar = calculateTupleScalar(\n\t\t\theader.peakTuple,\n\t\t\taxisCoords,\n\t\t\theader.intermediateStartTuple,\n\t\t\theader.intermediateEndTuple,\n\t\t);\n\n\t\tif (scalar === 0) continue;\n\n\t\t// Check if point is in the variation\n\t\tif (header.pointNumbers !== null) {\n\t\t\tconst pointIdx = header.pointNumbers.indexOf(pointIndex);\n\t\t\tif (pointIdx < 0) continue;\n\n\t\t\tconst delta = header.deltas[pointIdx];\n\t\t\tif (delta) {\n\t\t\t\ttotalX += delta.x * scalar;\n\t\t\t\ttotalY += delta.y * scalar;\n\t\t\t}\n\t\t} else {\n\t\t\t// All points\n\t\t\tconst delta = header.deltas[pointIndex];\n\t\t\tif (delta) {\n\t\t\t\ttotalX += delta.x * scalar;\n\t\t\t\ttotalY += delta.y * scalar;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { x: Math.round(totalX), y: Math.round(totalY) };\n}\n",
33
- "import type { GlyphId, uint32 } from \"../../types.ts\";\nimport type { Reader } from \"../binary/reader.ts\";\n\n/**\n * loca table - Glyph location index\n * Maps glyph IDs to byte offsets in the glyf table\n */\n\nexport interface LocaTable {\n\t/** Glyph offsets (numGlyphs + 1 entries) */\n\toffsets: uint32[];\n\t/** Whether the font uses short (16-bit) or long (32-bit) offsets */\n\tisShort: boolean;\n}\n\n/**\n * Parse loca table\n * @param reader - Reader positioned at start of loca table\n * @param numGlyphs - Number of glyphs from maxp table\n * @param indexToLocFormat - 0 for short offsets, 1 for long (from head table)\n */\nexport function parseLoca(\n\treader: Reader,\n\tnumGlyphs: number,\n\tindexToLocFormat: number,\n): LocaTable {\n\tconst isShort = indexToLocFormat === 0;\n\tconst offsets: uint32[] = [];\n\n\t// loca has numGlyphs + 1 entries (last entry marks end of last glyph)\n\tconst count = numGlyphs + 1;\n\n\tif (isShort) {\n\t\t// Short format: offsets are uint16, multiply by 2 to get actual byte offset\n\t\tfor (let i = 0; i < count; i++) {\n\t\t\toffsets.push(reader.uint16() * 2);\n\t\t}\n\t} else {\n\t\t// Long format: offsets are uint32\n\t\tfor (let i = 0; i < count; i++) {\n\t\t\toffsets.push(reader.uint32());\n\t\t}\n\t}\n\n\treturn { offsets, isShort };\n}\n\n/**\n * Get byte offset and length for a glyph in the glyf table\n * Returns null if glyph has no outline (empty glyph)\n */\nexport function getGlyphLocation(\n\tloca: LocaTable,\n\tglyphId: GlyphId,\n): { offset: uint32; length: uint32 } | null {\n\tif (glyphId < 0 || glyphId >= loca.offsets.length - 1) {\n\t\treturn null;\n\t}\n\n\tconst offset = loca.offsets[glyphId];\n\tconst nextOffset = loca.offsets[glyphId + 1];\n\tif (offset === undefined || nextOffset === undefined) {\n\t\treturn null;\n\t}\n\n\tconst length = nextOffset - offset;\n\n\t// Zero-length means empty glyph (space, etc.)\n\tif (length === 0) {\n\t\treturn null;\n\t}\n\n\treturn { offset, length };\n}\n\n/**\n * Check if a glyph has outline data\n */\nexport function hasGlyphOutline(loca: LocaTable, glyphId: GlyphId): boolean {\n\treturn getGlyphLocation(loca, glyphId) !== null;\n}\n",
34
- "import type { GlyphId, int16, uint8, uint16 } from \"../../types.ts\";\nimport type { Reader } from \"../binary/reader.ts\";\nimport type { GvarTable, PointDelta } from \"./gvar.ts\";\nimport { calculateTupleScalar } from \"./gvar.ts\";\nimport type { LocaTable } from \"./loca.ts\";\nimport { getGlyphLocation } from \"./loca.ts\";\n\n/**\n * glyf table - Glyph outline data\n * Contains TrueType glyph contours as quadratic Bézier curves\n */\n\n/** Point flags */\nexport const PointFlag = {\n\tOnCurve: 0x01,\n\tXShortVector: 0x02,\n\tYShortVector: 0x04,\n\tRepeat: 0x08,\n\tXIsSameOrPositive: 0x10,\n\tYIsSameOrPositive: 0x20,\n\tOverlapSimple: 0x40,\n} as const;\n\n/** Composite glyph flags */\nexport const CompositeFlag = {\n\tArg1And2AreWords: 0x0001,\n\tArgsAreXYValues: 0x0002,\n\tRoundXYToGrid: 0x0004,\n\tWeHaveAScale: 0x0008,\n\tMoreComponents: 0x0020,\n\tWeHaveAnXAndYScale: 0x0040,\n\tWeHaveATwoByTwo: 0x0080,\n\tWeHaveInstructions: 0x0100,\n\tUseMyMetrics: 0x0200,\n\tOverlapCompound: 0x0400,\n\tScaledComponentOffset: 0x0800,\n\tUnscaledComponentOffset: 0x1000,\n} as const;\n\n/** A point in a glyph contour */\nexport interface GlyphPoint {\n\tx: number;\n\ty: number;\n\tonCurve: boolean;\n\t/** True if this is a cubic bezier control point (CFF fonts) */\n\tcubic?: boolean;\n}\n\n/** A contour is a closed path of points */\nexport type Contour = GlyphPoint[];\n\n/** Simple glyph with contours */\nexport interface SimpleGlyph {\n\ttype: \"simple\";\n\tnumberOfContours: int16;\n\txMin: int16;\n\tyMin: int16;\n\txMax: int16;\n\tyMax: int16;\n\tcontours: Contour[];\n\tinstructions: Uint8Array<ArrayBufferLike>;\n}\n\n/** Component of a composite glyph */\nexport interface GlyphComponent {\n\tglyphId: GlyphId;\n\tflags: uint16;\n\t/** X offset or point number */\n\targ1: number;\n\t/** Y offset or point number */\n\targ2: number;\n\t/** Transformation matrix [a, b, c, d] */\n\ttransform: [number, number, number, number];\n}\n\n/** Composite glyph made of other glyphs */\nexport interface CompositeGlyph {\n\ttype: \"composite\";\n\tnumberOfContours: int16;\n\txMin: int16;\n\tyMin: int16;\n\txMax: int16;\n\tyMax: int16;\n\tcomponents: GlyphComponent[];\n\tinstructions: Uint8Array<ArrayBufferLike>;\n}\n\n/** Empty glyph (space, etc.) */\nexport interface EmptyGlyph {\n\ttype: \"empty\";\n}\n\nexport type Glyph = SimpleGlyph | CompositeGlyph | EmptyGlyph;\n\n/** glyf table stores the raw reader for on-demand glyph parsing */\nexport interface GlyfTable {\n\treader: Reader;\n}\n\nexport function parseGlyf(reader: Reader): GlyfTable {\n\t// We don't parse all glyphs upfront - store reader for lazy access\n\treturn { reader };\n}\n\n/**\n * Parse a single glyph from the glyf table\n */\nexport function parseGlyph(\n\tglyf: GlyfTable,\n\tloca: LocaTable,\n\tglyphId: GlyphId,\n): Glyph {\n\tconst location = getGlyphLocation(loca, glyphId);\n\tif (!location) {\n\t\treturn { type: \"empty\" };\n\t}\n\n\tconst reader = glyf.reader.slice(location.offset, location.length);\n\treturn parseGlyphData(reader);\n}\n\nfunction parseGlyphData(reader: Reader): Glyph {\n\tconst numberOfContours = reader.int16();\n\tconst xMin = reader.int16();\n\tconst yMin = reader.int16();\n\tconst xMax = reader.int16();\n\tconst yMax = reader.int16();\n\n\tif (numberOfContours >= 0) {\n\t\treturn parseSimpleGlyph(reader, numberOfContours, xMin, yMin, xMax, yMax);\n\t} else {\n\t\treturn parseCompositeGlyph(\n\t\t\treader,\n\t\t\tnumberOfContours,\n\t\t\txMin,\n\t\t\tyMin,\n\t\t\txMax,\n\t\t\tyMax,\n\t\t);\n\t}\n}\n\nfunction parseSimpleGlyph(\n\treader: Reader,\n\tnumberOfContours: int16,\n\txMin: int16,\n\tyMin: int16,\n\txMax: int16,\n\tyMax: int16,\n): SimpleGlyph {\n\tif (numberOfContours === 0) {\n\t\treturn {\n\t\t\ttype: \"simple\",\n\t\t\tnumberOfContours,\n\t\t\txMin,\n\t\t\tyMin,\n\t\t\txMax,\n\t\t\tyMax,\n\t\t\tcontours: [],\n\t\t\tinstructions: new Uint8Array(0),\n\t\t};\n\t}\n\n\t// Read end points of each contour\n\tconst endPtsOfContours: uint16[] = [];\n\tfor (let i = 0; i < numberOfContours; i++) {\n\t\tendPtsOfContours.push(reader.uint16());\n\t}\n\n\t// Total number of points\n\tconst lastEndPt = endPtsOfContours[numberOfContours - 1];\n\tif (lastEndPt === undefined) {\n\t\treturn {\n\t\t\ttype: \"simple\",\n\t\t\tnumberOfContours,\n\t\t\txMin,\n\t\t\tyMin,\n\t\t\txMax,\n\t\t\tyMax,\n\t\t\tcontours: [],\n\t\t\tinstructions: new Uint8Array(0),\n\t\t};\n\t}\n\tconst numPoints = lastEndPt + 1;\n\n\t// Read instructions\n\tconst instructionLength = reader.uint16();\n\tconst instructions = reader.bytes(instructionLength);\n\n\t// Read flags\n\tconst flags: uint8[] = [];\n\twhile (flags.length < numPoints) {\n\t\tconst flag = reader.uint8();\n\t\tflags.push(flag);\n\n\t\t// Handle repeat flag\n\t\tif (flag & PointFlag.Repeat) {\n\t\t\tconst repeatCount = reader.uint8();\n\t\t\tfor (let i = 0; i < repeatCount; i++) {\n\t\t\t\tflags.push(flag);\n\t\t\t}\n\t\t}\n\t}\n\n\t// Read X coordinates\n\tconst xCoordinates: number[] = [];\n\tlet x = 0;\n\tfor (const [_i, flag] of flags.entries()) {\n\t\tif (flag & PointFlag.XShortVector) {\n\t\t\tconst dx = reader.uint8();\n\t\t\tx += flag & PointFlag.XIsSameOrPositive ? dx : -dx;\n\t\t} else if (!(flag & PointFlag.XIsSameOrPositive)) {\n\t\t\tx += reader.int16();\n\t\t}\n\t\t// else x stays the same (XIsSameOrPositive with no short vector)\n\t\txCoordinates.push(x);\n\t}\n\n\t// Read Y coordinates\n\tconst yCoordinates: number[] = [];\n\tlet y = 0;\n\tfor (const [_i, flag] of flags.entries()) {\n\t\tif (flag & PointFlag.YShortVector) {\n\t\t\tconst dy = reader.uint8();\n\t\t\ty += flag & PointFlag.YIsSameOrPositive ? dy : -dy;\n\t\t} else if (!(flag & PointFlag.YIsSameOrPositive)) {\n\t\t\ty += reader.int16();\n\t\t}\n\t\t// else y stays the same\n\t\tyCoordinates.push(y);\n\t}\n\n\t// Build contours\n\tconst contours: Contour[] = [];\n\tlet pointIndex = 0;\n\tfor (const endPt of endPtsOfContours) {\n\t\tconst contour: Contour = [];\n\n\t\twhile (pointIndex <= endPt) {\n\t\t\tconst xCoord = xCoordinates[pointIndex];\n\t\t\tconst yCoord = yCoordinates[pointIndex];\n\t\t\tconst flag = flags[pointIndex];\n\t\t\tif (xCoord === undefined || yCoord === undefined || flag === undefined) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcontour.push({\n\t\t\t\tx: xCoord,\n\t\t\t\ty: yCoord,\n\t\t\t\tonCurve: (flag & PointFlag.OnCurve) !== 0,\n\t\t\t});\n\t\t\tpointIndex++;\n\t\t}\n\n\t\tcontours.push(contour);\n\t}\n\n\treturn {\n\t\ttype: \"simple\",\n\t\tnumberOfContours,\n\t\txMin,\n\t\tyMin,\n\t\txMax,\n\t\tyMax,\n\t\tcontours,\n\t\tinstructions,\n\t};\n}\n\nfunction parseCompositeGlyph(\n\treader: Reader,\n\tnumberOfContours: int16,\n\txMin: int16,\n\tyMin: int16,\n\txMax: int16,\n\tyMax: int16,\n): CompositeGlyph {\n\tconst components: GlyphComponent[] = [];\n\tlet flags: uint16;\n\n\tdo {\n\t\tflags = reader.uint16();\n\t\tconst glyphIndex = reader.uint16();\n\n\t\tlet arg1: number;\n\t\tlet arg2: number;\n\n\t\tif (flags & CompositeFlag.Arg1And2AreWords) {\n\t\t\tif (flags & CompositeFlag.ArgsAreXYValues) {\n\t\t\t\targ1 = reader.int16();\n\t\t\t\targ2 = reader.int16();\n\t\t\t} else {\n\t\t\t\targ1 = reader.uint16();\n\t\t\t\targ2 = reader.uint16();\n\t\t\t}\n\t\t} else {\n\t\t\tif (flags & CompositeFlag.ArgsAreXYValues) {\n\t\t\t\targ1 = reader.int8();\n\t\t\t\targ2 = reader.int8();\n\t\t\t} else {\n\t\t\t\targ1 = reader.uint8();\n\t\t\t\targ2 = reader.uint8();\n\t\t\t}\n\t\t}\n\n\t\t// Transformation matrix defaults to identity\n\t\tlet a = 1,\n\t\t\tb = 0,\n\t\t\tc = 0,\n\t\t\td = 1;\n\n\t\tif (flags & CompositeFlag.WeHaveAScale) {\n\t\t\ta = d = reader.f2dot14();\n\t\t} else if (flags & CompositeFlag.WeHaveAnXAndYScale) {\n\t\t\ta = reader.f2dot14();\n\t\t\td = reader.f2dot14();\n\t\t} else if (flags & CompositeFlag.WeHaveATwoByTwo) {\n\t\t\ta = reader.f2dot14();\n\t\t\tb = reader.f2dot14();\n\t\t\tc = reader.f2dot14();\n\t\t\td = reader.f2dot14();\n\t\t}\n\n\t\tcomponents.push({\n\t\t\tglyphId: glyphIndex,\n\t\t\tflags,\n\t\t\targ1,\n\t\t\targ2,\n\t\t\ttransform: [a, b, c, d],\n\t\t});\n\t} while (flags & CompositeFlag.MoreComponents);\n\n\t// Read instructions if present\n\tlet instructions: Uint8Array<ArrayBufferLike> = new Uint8Array(0);\n\tif (flags & CompositeFlag.WeHaveInstructions) {\n\t\tconst instructionLength = reader.uint16();\n\t\tinstructions = reader.bytes(instructionLength);\n\t}\n\n\treturn {\n\t\ttype: \"composite\",\n\t\tnumberOfContours,\n\t\txMin,\n\t\tyMin,\n\t\txMax,\n\t\tyMax,\n\t\tcomponents,\n\t\tinstructions,\n\t};\n}\n\n/**\n * Flatten a composite glyph into simple contours\n * Recursively resolves all component glyphs and applies transformations\n */\nexport function flattenCompositeGlyph(\n\tglyf: GlyfTable,\n\tloca: LocaTable,\n\tglyph: CompositeGlyph,\n\tdepth: number = 0,\n): Contour[] {\n\t// Prevent infinite recursion\n\tif (depth > 32) {\n\t\treturn [];\n\t}\n\n\tconst result: Contour[] = [];\n\n\tfor (const component of glyph.components) {\n\t\tconst componentGlyph = parseGlyph(glyf, loca, component.glyphId);\n\n\t\tlet componentContours: Contour[];\n\t\tif (componentGlyph.type === \"simple\") {\n\t\t\tcomponentContours = componentGlyph.contours;\n\t\t} else if (componentGlyph.type === \"composite\") {\n\t\t\tcomponentContours = flattenCompositeGlyph(\n\t\t\t\tglyf,\n\t\t\t\tloca,\n\t\t\t\tcomponentGlyph,\n\t\t\t\tdepth + 1,\n\t\t\t);\n\t\t} else {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Apply transformation and offset\n\t\tconst [a, b, c, d] = component.transform;\n\t\tconst dx =\n\t\t\tcomponent.flags & CompositeFlag.ArgsAreXYValues ? component.arg1 : 0;\n\t\tconst dy =\n\t\t\tcomponent.flags & CompositeFlag.ArgsAreXYValues ? component.arg2 : 0;\n\n\t\tfor (const contour of componentContours) {\n\t\t\tconst transformedContour: Contour = contour.map((point) => ({\n\t\t\t\tx: Math.round(a * point.x + c * point.y + dx),\n\t\t\t\ty: Math.round(b * point.x + d * point.y + dy),\n\t\t\t\tonCurve: point.onCurve,\n\t\t\t}));\n\t\t\tresult.push(transformedContour);\n\t\t}\n\t}\n\n\treturn result;\n}\n\n/**\n * Get all contours for a glyph, flattening composites\n */\nexport function getGlyphContours(\n\tglyf: GlyfTable,\n\tloca: LocaTable,\n\tglyphId: GlyphId,\n): Contour[] {\n\tconst glyph = parseGlyph(glyf, loca, glyphId);\n\n\tif (glyph.type === \"empty\") {\n\t\treturn [];\n\t} else if (glyph.type === \"simple\") {\n\t\treturn glyph.contours;\n\t} else {\n\t\treturn flattenCompositeGlyph(glyf, loca, glyph);\n\t}\n}\n\n/**\n * Get bounding box for a glyph\n */\nexport function getGlyphBounds(\n\tglyf: GlyfTable,\n\tloca: LocaTable,\n\tglyphId: GlyphId,\n): { xMin: number; yMin: number; xMax: number; yMax: number } | null {\n\tconst glyph = parseGlyph(glyf, loca, glyphId);\n\n\tif (glyph.type === \"empty\") {\n\t\treturn null;\n\t}\n\n\treturn {\n\t\txMin: glyph.xMin,\n\t\tyMin: glyph.yMin,\n\t\txMax: glyph.xMax,\n\t\tyMax: glyph.yMax,\n\t};\n}\n\n/**\n * Get all deltas for a glyph at given variation coordinates\n */\nexport function getGlyphDeltas(\n\tgvar: GvarTable,\n\tglyphId: GlyphId,\n\tnumPoints: number,\n\taxisCoords: number[],\n): PointDelta[] {\n\tconst glyphData = gvar.glyphVariationData[glyphId];\n\tif (!glyphData) {\n\t\treturn Array(numPoints).fill({ x: 0, y: 0 });\n\t}\n\n\t// Initialize deltas array\n\tconst deltas: PointDelta[] = Array(numPoints)\n\t\t.fill(null)\n\t\t.map(() => ({ x: 0, y: 0 }));\n\n\tfor (const header of glyphData.tupleVariationHeaders) {\n\t\tif (!header.peakTuple) continue;\n\n\t\tconst scalar = calculateTupleScalar(\n\t\t\theader.peakTuple,\n\t\t\taxisCoords,\n\t\t\theader.intermediateStartTuple,\n\t\t\theader.intermediateEndTuple,\n\t\t);\n\n\t\tif (scalar === 0) continue;\n\n\t\tif (header.pointNumbers !== null) {\n\t\t\t// Sparse point deltas\n\t\t\tfor (const [i, pointIndex] of header.pointNumbers.entries()) {\n\t\t\t\tconst delta = deltas[pointIndex];\n\t\t\t\tconst headerDelta = header.deltas[i];\n\t\t\t\tif (pointIndex < numPoints && delta && headerDelta) {\n\t\t\t\t\tdelta.x += headerDelta.x * scalar;\n\t\t\t\t\tdelta.y += headerDelta.y * scalar;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// All points\n\t\t\tfor (let i = 0; i < Math.min(header.deltas.length, numPoints); i++) {\n\t\t\t\tconst delta = deltas[i];\n\t\t\t\tconst headerDelta = header.deltas[i];\n\t\t\t\tif (delta && headerDelta) {\n\t\t\t\t\tdelta.x += headerDelta.x * scalar;\n\t\t\t\t\tdelta.y += headerDelta.y * scalar;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Round final values\n\tfor (const d of deltas) {\n\t\td.x = Math.round(d.x);\n\t\td.y = Math.round(d.y);\n\t}\n\n\treturn deltas;\n}\n\n/**\n * Apply variation deltas to contours\n */\nexport function applyVariationDeltas(\n\tcontours: Contour[],\n\tdeltas: PointDelta[],\n): Contour[] {\n\tconst result: Contour[] = [];\n\tlet pointIndex = 0;\n\n\tfor (const contour of contours) {\n\t\tconst newContour: Contour = [];\n\t\tfor (const point of contour) {\n\t\t\tconst delta = deltas[pointIndex] ?? { x: 0, y: 0 };\n\t\t\tnewContour.push({\n\t\t\t\tx: point.x + delta.x,\n\t\t\t\ty: point.y + delta.y,\n\t\t\t\tonCurve: point.onCurve,\n\t\t\t});\n\t\t\tpointIndex++;\n\t\t}\n\t\tresult.push(newContour);\n\t}\n\n\treturn result;\n}\n\n/**\n * Get contours for a glyph with variation applied\n */\nexport function getGlyphContoursWithVariation(\n\tglyf: GlyfTable,\n\tloca: LocaTable,\n\tgvar: GvarTable | null,\n\tglyphId: GlyphId,\n\taxisCoords?: number[],\n): Contour[] {\n\tconst glyph = parseGlyph(glyf, loca, glyphId);\n\n\tif (glyph.type === \"empty\") {\n\t\treturn [];\n\t}\n\n\tlet contours: Contour[];\n\tif (glyph.type === \"simple\") {\n\t\tcontours = glyph.contours;\n\t} else {\n\t\tcontours = flattenCompositeGlyphWithVariation(\n\t\t\tglyf,\n\t\t\tloca,\n\t\t\tgvar,\n\t\t\tglyph,\n\t\t\taxisCoords,\n\t\t);\n\t}\n\n\t// Apply variation if we have gvar and axis coordinates\n\tif (gvar && axisCoords && axisCoords.length > 0) {\n\t\t// Count total points\n\t\tlet numPoints = 0;\n\t\tfor (const c of contours) {\n\t\t\tnumPoints += c.length;\n\t\t}\n\t\t// Add phantom points (4)\n\t\tnumPoints += 4;\n\n\t\tconst deltas = getGlyphDeltas(gvar, glyphId, numPoints, axisCoords);\n\t\tcontours = applyVariationDeltas(contours, deltas);\n\t}\n\n\treturn contours;\n}\n\n/**\n * Flatten composite glyph with variation support\n */\nfunction flattenCompositeGlyphWithVariation(\n\tglyf: GlyfTable,\n\tloca: LocaTable,\n\tgvar: GvarTable | null,\n\tglyph: CompositeGlyph,\n\taxisCoords?: number[],\n\tdepth: number = 0,\n): Contour[] {\n\tif (depth > 32) {\n\t\treturn [];\n\t}\n\n\tconst result: Contour[] = [];\n\n\tfor (const component of glyph.components) {\n\t\tconst componentGlyph = parseGlyph(glyf, loca, component.glyphId);\n\n\t\tlet componentContours: Contour[];\n\t\tif (componentGlyph.type === \"simple\") {\n\t\t\tcomponentContours = componentGlyph.contours;\n\n\t\t\t// Apply variation to component\n\t\t\tif (gvar && axisCoords && axisCoords.length > 0) {\n\t\t\t\tlet numPoints = 0;\n\t\t\t\tfor (const c of componentContours) {\n\t\t\t\t\tnumPoints += c.length;\n\t\t\t\t}\n\t\t\t\tnumPoints += 4; // phantom points\n\n\t\t\t\tconst deltas = getGlyphDeltas(\n\t\t\t\t\tgvar,\n\t\t\t\t\tcomponent.glyphId,\n\t\t\t\t\tnumPoints,\n\t\t\t\t\taxisCoords,\n\t\t\t\t);\n\t\t\t\tcomponentContours = applyVariationDeltas(componentContours, deltas);\n\t\t\t}\n\t\t} else if (componentGlyph.type === \"composite\") {\n\t\t\tcomponentContours = flattenCompositeGlyphWithVariation(\n\t\t\t\tglyf,\n\t\t\t\tloca,\n\t\t\t\tgvar,\n\t\t\t\tcomponentGlyph,\n\t\t\t\taxisCoords,\n\t\t\t\tdepth + 1,\n\t\t\t);\n\t\t} else {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Apply transformation and offset\n\t\tconst [a, b, c, d] = component.transform;\n\t\tconst dx =\n\t\t\tcomponent.flags & CompositeFlag.ArgsAreXYValues ? component.arg1 : 0;\n\t\tconst dy =\n\t\t\tcomponent.flags & CompositeFlag.ArgsAreXYValues ? component.arg2 : 0;\n\n\t\tfor (const contour of componentContours) {\n\t\t\tconst transformedContour: Contour = contour.map((point) => ({\n\t\t\t\tx: Math.round(a * point.x + c * point.y + dx),\n\t\t\t\ty: Math.round(b * point.x + d * point.y + dy),\n\t\t\t\tonCurve: point.onCurve,\n\t\t\t}));\n\t\t\tresult.push(transformedContour);\n\t\t}\n\t}\n\n\treturn result;\n}\n",
35
- "import type { Reader } from \"../../font/binary/reader.ts\";\nimport type { GlyphId, uint16 } from \"../../types.ts\";\n\n/** Coverage table - maps glyph IDs to coverage indices */\nexport interface Coverage {\n\t/** Get coverage index for a glyph ID, or null if not covered */\n\tget(glyphId: GlyphId): number | null;\n\n\t/** Check if glyph is covered */\n\tcovers(glyphId: GlyphId): boolean;\n\n\t/** Get all covered glyph IDs */\n\tglyphs(): GlyphId[];\n\n\t/** Number of covered glyphs */\n\treadonly size: number;\n}\n\n/** Format 1: Individual glyph IDs */\nclass CoverageFormat1 implements Coverage {\n\tprivate readonly glyphArray: Uint16Array;\n\tprivate readonly glyphSet: Set<GlyphId>;\n\n\tconstructor(glyphArray: Uint16Array) {\n\t\tthis.glyphArray = glyphArray;\n\t\tthis.glyphSet = new Set(glyphArray);\n\t}\n\n\tget size(): number {\n\t\treturn this.glyphArray.length;\n\t}\n\n\tget(glyphId: GlyphId): number | null {\n\t\t// Binary search since glyphs are sorted\n\t\tlet low = 0;\n\t\tlet high = this.glyphArray.length - 1;\n\n\t\twhile (low <= high) {\n\t\t\tconst mid = (low + high) >>> 1;\n\t\t\tconst midVal = this.glyphArray[mid];\n\t\t\tif (midVal === undefined) continue;\n\n\t\t\tif (midVal < glyphId) {\n\t\t\t\tlow = mid + 1;\n\t\t\t} else if (midVal > glyphId) {\n\t\t\t\thigh = mid - 1;\n\t\t\t} else {\n\t\t\t\treturn mid; // Found - return coverage index\n\t\t\t}\n\t\t}\n\n\t\treturn null; // Not found\n\t}\n\n\tcovers(glyphId: GlyphId): boolean {\n\t\treturn this.glyphSet.has(glyphId);\n\t}\n\n\tglyphs(): GlyphId[] {\n\t\treturn Array.from(this.glyphArray);\n\t}\n}\n\n/** Range record for Format 2 */\ninterface RangeRecord {\n\tstartGlyphId: GlyphId;\n\tendGlyphId: GlyphId;\n\tstartCoverageIndex: uint16;\n}\n\n/** Format 2: Ranges of glyph IDs */\nclass CoverageFormat2 implements Coverage {\n\tprivate readonly ranges: RangeRecord[];\n\tprivate readonly _size: number;\n\n\tconstructor(ranges: RangeRecord[]) {\n\t\tthis.ranges = ranges;\n\t\t// Calculate total size\n\t\tif (ranges.length === 0) {\n\t\t\tthis._size = 0;\n\t\t} else {\n\t\t\tconst lastRange = ranges[ranges.length - 1];\n\t\t\tif (lastRange) {\n\t\t\t\tthis._size =\n\t\t\t\t\tlastRange.startCoverageIndex +\n\t\t\t\t\t(lastRange.endGlyphId - lastRange.startGlyphId + 1);\n\t\t\t} else {\n\t\t\t\tthis._size = 0;\n\t\t\t}\n\t\t}\n\t}\n\n\tget size(): number {\n\t\treturn this._size;\n\t}\n\n\tget(glyphId: GlyphId): number | null {\n\t\t// Binary search through ranges\n\t\tlet low = 0;\n\t\tlet high = this.ranges.length - 1;\n\n\t\twhile (low <= high) {\n\t\t\tconst mid = (low + high) >>> 1;\n\t\t\tconst range = this.ranges[mid];\n\t\t\tif (!range) continue;\n\n\t\t\tif (glyphId > range.endGlyphId) {\n\t\t\t\tlow = mid + 1;\n\t\t\t} else if (glyphId < range.startGlyphId) {\n\t\t\t\thigh = mid - 1;\n\t\t\t} else {\n\t\t\t\t// Found - calculate coverage index\n\t\t\t\treturn range.startCoverageIndex + (glyphId - range.startGlyphId);\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n\n\tcovers(glyphId: GlyphId): boolean {\n\t\treturn this.get(glyphId) !== null;\n\t}\n\n\tglyphs(): GlyphId[] {\n\t\tconst result: GlyphId[] = [];\n\t\tfor (const range of this.ranges) {\n\t\t\tfor (let g = range.startGlyphId; g <= range.endGlyphId; g++) {\n\t\t\t\tresult.push(g);\n\t\t\t}\n\t\t}\n\t\treturn result;\n\t}\n}\n\n/** Parse a Coverage table */\nexport function parseCoverage(reader: Reader): Coverage {\n\tconst format = reader.uint16();\n\n\tif (format === 1) {\n\t\tconst glyphCount = reader.uint16();\n\t\tconst glyphArray = reader.uint16Array(glyphCount);\n\t\treturn new CoverageFormat1(glyphArray);\n\t}\n\n\tif (format === 2) {\n\t\tconst rangeCount = reader.uint16();\n\t\tconst ranges: RangeRecord[] = new Array(rangeCount);\n\n\t\tfor (let i = 0; i < rangeCount; i++) {\n\t\t\tranges[i] = {\n\t\t\t\tstartGlyphId: reader.uint16(),\n\t\t\t\tendGlyphId: reader.uint16(),\n\t\t\t\tstartCoverageIndex: reader.uint16(),\n\t\t\t};\n\t\t}\n\n\t\treturn new CoverageFormat2(ranges);\n\t}\n\n\tthrow new Error(`Unknown Coverage format: ${format}`);\n}\n\n/** Parse Coverage from offset (creates sub-reader) */\nexport function parseCoverageAt(reader: Reader, offset: number): Coverage {\n\treturn parseCoverage(reader.sliceFrom(offset));\n}\n",
36
- "import type { Reader } from \"../../font/binary/reader.ts\";\nimport type { int16, uint16 } from \"../../types.ts\";\n\n/**\n * Device table - pixel-level adjustments for different PPEM sizes\n * Used in GPOS for fine-tuning positioning at specific sizes\n */\n\nexport interface DeviceTable {\n\tstartSize: uint16;\n\tendSize: uint16;\n\tdeltaFormat: uint16;\n\t/** Delta values indexed by (ppem - startSize) */\n\tdeltaValues: int16[];\n}\n\n/** VariationIndex table for variable fonts (shares format with Device) */\nexport interface VariationIndexTable {\n\tdeltaSetOuterIndex: uint16;\n\tdeltaSetInnerIndex: uint16;\n}\n\n/** Combined type - can be either Device or VariationIndex */\nexport type DeviceOrVariationIndex = DeviceTable | VariationIndexTable;\n\n/** Check if this is a VariationIndex table */\nexport function isVariationIndexTable(\n\ttable: DeviceOrVariationIndex,\n): table is VariationIndexTable {\n\treturn \"deltaSetOuterIndex\" in table;\n}\n\n/** Parse Device or VariationIndex table at offset */\nexport function parseDeviceAt(\n\treader: Reader,\n\toffset: number,\n): DeviceOrVariationIndex | null {\n\tif (offset === 0) return null;\n\treturn parseDevice(reader.sliceFrom(offset));\n}\n\n/** Parse Device or VariationIndex table */\nexport function parseDevice(reader: Reader): DeviceOrVariationIndex {\n\tconst startSize = reader.uint16();\n\tconst endSize = reader.uint16();\n\tconst deltaFormat = reader.uint16();\n\n\t// Format 0x8000 indicates VariationIndex table\n\tif (deltaFormat === 0x8000) {\n\t\treturn {\n\t\t\tdeltaSetOuterIndex: startSize,\n\t\t\tdeltaSetInnerIndex: endSize,\n\t\t};\n\t}\n\n\tconst deltaValues: int16[] = [];\n\n\tif (deltaFormat >= 1 && deltaFormat <= 3) {\n\t\tconst count = endSize - startSize + 1;\n\t\tconst bitsPerValue = 1 << deltaFormat; // 2, 4, or 8 bits\n\t\tconst valuesPerWord = 16 / bitsPerValue;\n\t\tconst mask = (1 << bitsPerValue) - 1;\n\t\tconst signBit = 1 << (bitsPerValue - 1);\n\n\t\tconst wordCount = Math.ceil(count / valuesPerWord);\n\t\tlet valueIndex = 0;\n\n\t\tfor (let w = 0; w < wordCount; w++) {\n\t\t\tconst word = reader.uint16();\n\n\t\t\tfor (\n\t\t\t\tlet v = 0;\n\t\t\t\tv < valuesPerWord && valueIndex < count;\n\t\t\t\tv++, valueIndex++\n\t\t\t) {\n\t\t\t\tconst shift = 16 - bitsPerValue * (v + 1);\n\t\t\t\tlet delta = (word >> shift) & mask;\n\n\t\t\t\t// Sign extend\n\t\t\t\tif (delta & signBit) {\n\t\t\t\t\tdelta = delta - (1 << bitsPerValue);\n\t\t\t\t}\n\n\t\t\t\tdeltaValues.push(delta);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\tstartSize,\n\t\tendSize,\n\t\tdeltaFormat,\n\t\tdeltaValues,\n\t};\n}\n\n/**\n * Get delta adjustment for a specific PPEM size\n * Returns 0 if the size is outside the table's range\n */\nexport function getDeviceDelta(device: DeviceTable, ppem: number): int16 {\n\tif (ppem < device.startSize || ppem > device.endSize) {\n\t\treturn 0;\n\t}\n\tconst index = ppem - device.startSize;\n\treturn device.deltaValues[index] ?? 0;\n}\n\n/**\n * Apply Device table adjustment to a value\n * For variable fonts, this would need ItemVariationStore lookup instead\n */\nexport function applyDeviceAdjustment(\n\tdevice: DeviceOrVariationIndex | null,\n\tvalue: number,\n\tppem: number,\n): number {\n\tif (!device) return value;\n\n\tif (isVariationIndexTable(device)) {\n\t\t// VariationIndex tables need ItemVariationStore to resolve\n\t\t// For now, return value unchanged (proper support requires fvar integration)\n\t\treturn value;\n\t}\n\n\treturn value + getDeviceDelta(device, ppem);\n}\n\n/**\n * Parsed value record with resolved Device tables\n */\nexport interface ResolvedValueRecord {\n\txPlacement: number;\n\tyPlacement: number;\n\txAdvance: number;\n\tyAdvance: number;\n\txPlaDevice: DeviceOrVariationIndex | null;\n\tyPlaDevice: DeviceOrVariationIndex | null;\n\txAdvDevice: DeviceOrVariationIndex | null;\n\tyAdvDevice: DeviceOrVariationIndex | null;\n}\n\n/**\n * Apply all Device adjustments to a resolved value record\n */\nexport function applyDeviceAdjustments(\n\trecord: ResolvedValueRecord,\n\tppem: number,\n): {\n\txPlacement: number;\n\tyPlacement: number;\n\txAdvance: number;\n\tyAdvance: number;\n} {\n\treturn {\n\t\txPlacement: applyDeviceAdjustment(\n\t\t\trecord.xPlaDevice,\n\t\t\trecord.xPlacement,\n\t\t\tppem,\n\t\t),\n\t\tyPlacement: applyDeviceAdjustment(\n\t\t\trecord.yPlaDevice,\n\t\t\trecord.yPlacement,\n\t\t\tppem,\n\t\t),\n\t\txAdvance: applyDeviceAdjustment(record.xAdvDevice, record.xAdvance, ppem),\n\t\tyAdvance: applyDeviceAdjustment(record.yAdvDevice, record.yAdvance, ppem),\n\t};\n}\n",
37
- "import type { Reader } from \"../../font/binary/reader.ts\";\nimport type { Tag, uint16 } from \"../../types.ts\";\n\n/** Language system record */\nexport interface LangSysRecord {\n\tlangSysTag: Tag;\n\tlangSys: LangSys;\n}\n\n/** Language system table */\nexport interface LangSys {\n\t/** Required feature index (0xFFFF if none) */\n\trequiredFeatureIndex: uint16;\n\t/** Feature indices */\n\tfeatureIndices: uint16[];\n}\n\n/** Script record */\nexport interface ScriptRecord {\n\tscriptTag: Tag;\n\tscript: Script;\n}\n\n/** Script table */\nexport interface Script {\n\t/** Default language system (may be null) */\n\tdefaultLangSys: LangSys | null;\n\t/** Language system records */\n\tlangSysRecords: LangSysRecord[];\n}\n\n/** Script list table */\nexport interface ScriptList {\n\tscripts: ScriptRecord[];\n}\n\n/** Feature record */\nexport interface FeatureRecord {\n\tfeatureTag: Tag;\n\tfeature: Feature;\n}\n\n/** Feature table */\nexport interface Feature {\n\t/** Feature parameters offset (usually 0) */\n\tfeatureParamsOffset: uint16;\n\t/** Lookup indices */\n\tlookupListIndices: uint16[];\n}\n\n/** Feature list table */\nexport interface FeatureList {\n\tfeatures: FeatureRecord[];\n}\n\n/** Lookup table header */\nexport interface LookupHeader {\n\tlookupType: uint16;\n\tlookupFlag: uint16;\n\tsubtableOffsets: uint16[];\n\t/** Mark filtering set (if UseMarkFilteringSet flag is set) */\n\tmarkFilteringSet?: uint16;\n}\n\n/** Lookup flags */\nexport const LookupFlag = {\n\tRightToLeft: 0x0001,\n\tIgnoreBaseGlyphs: 0x0002,\n\tIgnoreLigatures: 0x0004,\n\tIgnoreMarks: 0x0008,\n\tUseMarkFilteringSet: 0x0010,\n\t// Bits 5-7 reserved\n\tMarkAttachmentTypeMask: 0xff00,\n} as const;\n\n/** Extract mark attachment type from lookup flag */\nexport function getMarkAttachmentType(lookupFlag: uint16): number {\n\treturn (lookupFlag & LookupFlag.MarkAttachmentTypeMask) >> 8;\n}\n\n/** Parse ScriptList */\nexport function parseScriptList(reader: Reader): ScriptList {\n\tconst scriptCount = reader.uint16();\n\tconst scriptRecords: Array<{ tag: Tag; offset: uint16 }> = [];\n\n\tfor (let i = 0; i < scriptCount; i++) {\n\t\tscriptRecords.push({\n\t\t\ttag: reader.tag(),\n\t\t\toffset: reader.offset16(),\n\t\t});\n\t}\n\n\tconst scripts: ScriptRecord[] = [];\n\tfor (const record of scriptRecords) {\n\t\tconst scriptReader = reader.sliceFrom(record.offset);\n\t\tconst script = parseScript(scriptReader);\n\t\tscripts.push({\n\t\t\tscriptTag: record.tag,\n\t\t\tscript,\n\t\t});\n\t}\n\n\treturn { scripts };\n}\n\nfunction parseScript(reader: Reader): Script {\n\tconst defaultLangSysOffset = reader.offset16();\n\tconst langSysCount = reader.uint16();\n\n\tconst langSysRecords: Array<{ tag: Tag; offset: uint16 }> = [];\n\tfor (let i = 0; i < langSysCount; i++) {\n\t\tlangSysRecords.push({\n\t\t\ttag: reader.tag(),\n\t\t\toffset: reader.offset16(),\n\t\t});\n\t}\n\n\t// Parse default language system\n\tlet defaultLangSys: LangSys | null = null;\n\tif (defaultLangSysOffset !== 0) {\n\t\tdefaultLangSys = parseLangSys(reader.sliceFrom(defaultLangSysOffset));\n\t}\n\n\t// Parse language system records\n\tconst parsedLangSysRecords: LangSysRecord[] = [];\n\tfor (const record of langSysRecords) {\n\t\tconst langSys = parseLangSys(reader.sliceFrom(record.offset));\n\t\tparsedLangSysRecords.push({\n\t\t\tlangSysTag: record.tag,\n\t\t\tlangSys,\n\t\t});\n\t}\n\n\treturn {\n\t\tdefaultLangSys,\n\t\tlangSysRecords: parsedLangSysRecords,\n\t};\n}\n\nfunction parseLangSys(reader: Reader): LangSys {\n\tconst _lookupOrderOffset = reader.offset16(); // Reserved, always 0\n\tconst requiredFeatureIndex = reader.uint16();\n\tconst featureIndexCount = reader.uint16();\n\tconst featureIndices = Array.from(reader.uint16Array(featureIndexCount));\n\n\treturn {\n\t\trequiredFeatureIndex,\n\t\tfeatureIndices,\n\t};\n}\n\n/** Parse FeatureList */\nexport function parseFeatureList(reader: Reader): FeatureList {\n\tconst featureCount = reader.uint16();\n\tconst featureRecords: Array<{ tag: Tag; offset: uint16 }> = [];\n\n\tfor (let i = 0; i < featureCount; i++) {\n\t\tfeatureRecords.push({\n\t\t\ttag: reader.tag(),\n\t\t\toffset: reader.offset16(),\n\t\t});\n\t}\n\n\tconst features: FeatureRecord[] = [];\n\tfor (const record of featureRecords) {\n\t\tconst featureReader = reader.sliceFrom(record.offset);\n\t\tconst feature = parseFeature(featureReader);\n\t\tfeatures.push({\n\t\t\tfeatureTag: record.tag,\n\t\t\tfeature,\n\t\t});\n\t}\n\n\treturn { features };\n}\n\nfunction parseFeature(reader: Reader): Feature {\n\tconst featureParamsOffset = reader.offset16();\n\tconst lookupIndexCount = reader.uint16();\n\tconst lookupListIndices = Array.from(reader.uint16Array(lookupIndexCount));\n\n\treturn {\n\t\tfeatureParamsOffset,\n\t\tlookupListIndices,\n\t};\n}\n\n/** Parse lookup headers (does not parse subtables) */\nexport function parseLookupHeaders(reader: Reader): LookupHeader[] {\n\tconst lookupCount = reader.uint16();\n\tconst lookupOffsets = reader.uint16Array(lookupCount);\n\n\tconst headers: LookupHeader[] = [];\n\tfor (const offset of lookupOffsets) {\n\t\tconst lookupReader = reader.sliceFrom(offset);\n\t\theaders.push(parseLookupHeader(lookupReader));\n\t}\n\n\treturn headers;\n}\n\nfunction parseLookupHeader(reader: Reader): LookupHeader {\n\tconst lookupType = reader.uint16();\n\tconst lookupFlag = reader.uint16();\n\tconst subtableCount = reader.uint16();\n\tconst subtableOffsets = Array.from(reader.uint16Array(subtableCount));\n\n\tlet markFilteringSet: uint16 | undefined;\n\tif (lookupFlag & LookupFlag.UseMarkFilteringSet) {\n\t\tmarkFilteringSet = reader.uint16();\n\t}\n\n\treturn {\n\t\tlookupType,\n\t\tlookupFlag,\n\t\tsubtableOffsets,\n\t\tmarkFilteringSet,\n\t};\n}\n\n/** Find script in script list */\nexport function findScript(\n\tscriptList: ScriptList,\n\tscriptTag: Tag,\n): Script | null {\n\tfor (const record of scriptList.scripts) {\n\t\tif (record.scriptTag === scriptTag) {\n\t\t\treturn record.script;\n\t\t}\n\t}\n\treturn null;\n}\n\n/** Find language system in script */\nexport function findLangSys(\n\tscript: Script,\n\tlangSysTag: Tag | null,\n): LangSys | null {\n\tif (langSysTag === null) {\n\t\treturn script.defaultLangSys;\n\t}\n\n\tfor (const record of script.langSysRecords) {\n\t\tif (record.langSysTag === langSysTag) {\n\t\t\treturn record.langSys;\n\t\t}\n\t}\n\n\treturn script.defaultLangSys;\n}\n\n/** Get feature by index */\nexport function getFeature(\n\tfeatureList: FeatureList,\n\tindex: number,\n): FeatureRecord | null {\n\treturn featureList.features[index] ?? null;\n}\n",
38
- "import {\n\ttype ClassDef,\n\tparseClassDefAt,\n} from \"../../layout/structures/class-def.ts\";\nimport {\n\ttype Coverage,\n\tparseCoverageAt,\n} from \"../../layout/structures/coverage.ts\";\nimport type { GlyphId, uint16 } from \"../../types.ts\";\nimport type { Reader } from \"../binary/reader.ts\";\nimport type { GposLookup } from \"./gpos.ts\";\n\n/** Position lookup record - applies a lookup at a position */\nexport interface PosLookupRecord {\n\tsequenceIndex: uint16; // Position in input sequence\n\tlookupListIndex: uint16; // Lookup to apply\n}\n\n/** Context positioning lookup (Type 7) */\nexport interface ContextPosLookup extends GposLookup {\n\ttype: 7;\n\tsubtables: ContextPosSubtable[];\n}\n\nexport type ContextPosSubtable =\n\t| ContextPosFormat1\n\t| ContextPosFormat2\n\t| ContextPosFormat3;\n\n/** Format 1: Simple glyph contexts */\nexport interface ContextPosFormat1 {\n\tformat: 1;\n\tcoverage: Coverage;\n\truleSets: (PosContextRule[] | null)[];\n}\n\nexport interface PosContextRule {\n\tglyphCount: uint16;\n\tinputSequence: GlyphId[]; // Excludes first glyph (in coverage)\n\tlookupRecords: PosLookupRecord[];\n}\n\n/** Format 2: Class-based contexts */\nexport interface ContextPosFormat2 {\n\tformat: 2;\n\tcoverage: Coverage;\n\tclassDef: ClassDef;\n\tclassRuleSets: (PosClassRule[] | null)[];\n}\n\nexport interface PosClassRule {\n\tglyphCount: uint16;\n\tinputClasses: uint16[]; // Excludes first class\n\tlookupRecords: PosLookupRecord[];\n}\n\n/** Format 3: Coverage-based contexts */\nexport interface ContextPosFormat3 {\n\tformat: 3;\n\tcoverages: Coverage[];\n\tlookupRecords: PosLookupRecord[];\n}\n\n/** Chaining context positioning lookup (Type 8) */\nexport interface ChainingContextPosLookup extends GposLookup {\n\ttype: 8;\n\tsubtables: ChainingContextPosSubtable[];\n}\n\nexport type ChainingContextPosSubtable =\n\t| ChainingContextPosFormat1\n\t| ChainingContextPosFormat2\n\t| ChainingContextPosFormat3;\n\n/** Format 1: Simple chaining context */\nexport interface ChainingContextPosFormat1 {\n\tformat: 1;\n\tcoverage: Coverage;\n\tchainRuleSets: (PosChainRule[] | null)[];\n}\n\nexport interface PosChainRule {\n\tbacktrackSequence: GlyphId[];\n\tinputSequence: GlyphId[]; // Excludes first glyph\n\tlookaheadSequence: GlyphId[];\n\tlookupRecords: PosLookupRecord[];\n}\n\n/** Format 2: Class-based chaining context */\nexport interface ChainingContextPosFormat2 {\n\tformat: 2;\n\tcoverage: Coverage;\n\tbacktrackClassDef: ClassDef;\n\tinputClassDef: ClassDef;\n\tlookaheadClassDef: ClassDef;\n\tchainClassRuleSets: (PosChainClassRule[] | null)[];\n}\n\nexport interface PosChainClassRule {\n\tbacktrackClasses: uint16[];\n\tinputClasses: uint16[]; // Excludes first class\n\tlookaheadClasses: uint16[];\n\tlookupRecords: PosLookupRecord[];\n}\n\n/** Format 3: Coverage-based chaining context */\nexport interface ChainingContextPosFormat3 {\n\tformat: 3;\n\tbacktrackCoverages: Coverage[];\n\tinputCoverages: Coverage[];\n\tlookaheadCoverages: Coverage[];\n\tlookupRecords: PosLookupRecord[];\n}\n\nexport function parseContextPos(\n\treader: Reader,\n\tsubtableOffsets: number[],\n): ContextPosSubtable[] {\n\tconst subtables: ContextPosSubtable[] = [];\n\n\tfor (const offset of subtableOffsets) {\n\t\tconst r = reader.sliceFrom(offset);\n\t\tconst format = r.uint16();\n\n\t\tswitch (format) {\n\t\t\tcase 1:\n\t\t\t\tsubtables.push(parseContextPosFormat1(r));\n\t\t\t\tbreak;\n\t\t\tcase 2:\n\t\t\t\tsubtables.push(parseContextPosFormat2(r));\n\t\t\t\tbreak;\n\t\t\tcase 3:\n\t\t\t\tsubtables.push(parseContextPosFormat3(r));\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn subtables;\n}\n\nfunction parseContextPosFormat1(reader: Reader): ContextPosFormat1 {\n\tconst coverageOffset = reader.offset16();\n\tconst ruleSetCount = reader.uint16();\n\tconst ruleSetOffsets = reader.uint16Array(ruleSetCount);\n\n\tconst coverage = parseCoverageAt(reader, coverageOffset);\n\tconst ruleSets: (PosContextRule[] | null)[] = [];\n\n\tfor (const ruleSetOffset of ruleSetOffsets) {\n\t\tif (ruleSetOffset === 0) {\n\t\t\truleSets.push(null);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst rsReader = reader.sliceFrom(ruleSetOffset);\n\t\tconst ruleCount = rsReader.uint16();\n\t\tconst ruleOffsets = rsReader.uint16Array(ruleCount);\n\n\t\tconst rules: PosContextRule[] = [];\n\t\tfor (const ruleOffset of ruleOffsets) {\n\t\t\tconst ruleReader = rsReader.sliceFrom(ruleOffset);\n\t\t\tconst glyphCount = ruleReader.uint16();\n\t\t\tconst lookupCount = ruleReader.uint16();\n\t\t\tconst inputSequence = Array.from(ruleReader.uint16Array(glyphCount - 1));\n\t\t\tconst lookupRecords = parsePosLookupRecords(ruleReader, lookupCount);\n\n\t\t\trules.push({ glyphCount, inputSequence, lookupRecords });\n\t\t}\n\n\t\truleSets.push(rules);\n\t}\n\n\treturn { format: 1, coverage, ruleSets };\n}\n\nfunction parseContextPosFormat2(reader: Reader): ContextPosFormat2 {\n\tconst coverageOffset = reader.offset16();\n\tconst classDefOffset = reader.offset16();\n\tconst classRuleSetCount = reader.uint16();\n\tconst classRuleSetOffsets = reader.uint16Array(classRuleSetCount);\n\n\tconst coverage = parseCoverageAt(reader, coverageOffset);\n\tconst classDef = parseClassDefAt(reader, classDefOffset);\n\tconst classRuleSets: (PosClassRule[] | null)[] = [];\n\n\tfor (const crsOffset of classRuleSetOffsets) {\n\t\tif (crsOffset === 0) {\n\t\t\tclassRuleSets.push(null);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst crsReader = reader.sliceFrom(crsOffset);\n\t\tconst ruleCount = crsReader.uint16();\n\t\tconst ruleOffsets = crsReader.uint16Array(ruleCount);\n\n\t\tconst rules: PosClassRule[] = [];\n\t\tfor (const ruleOffset of ruleOffsets) {\n\t\t\tconst ruleReader = crsReader.sliceFrom(ruleOffset);\n\t\t\tconst glyphCount = ruleReader.uint16();\n\t\t\tconst lookupCount = ruleReader.uint16();\n\t\t\tconst inputClasses = Array.from(ruleReader.uint16Array(glyphCount - 1));\n\t\t\tconst lookupRecords = parsePosLookupRecords(ruleReader, lookupCount);\n\n\t\t\trules.push({ glyphCount, inputClasses, lookupRecords });\n\t\t}\n\n\t\tclassRuleSets.push(rules);\n\t}\n\n\treturn { format: 2, coverage, classDef, classRuleSets };\n}\n\nfunction parseContextPosFormat3(reader: Reader): ContextPosFormat3 {\n\tconst glyphCount = reader.uint16();\n\tconst lookupCount = reader.uint16();\n\tconst coverageOffsets = reader.uint16Array(glyphCount);\n\n\tconst coverages: Coverage[] = [];\n\tfor (const offset of coverageOffsets) {\n\t\tcoverages.push(parseCoverageAt(reader, offset));\n\t}\n\n\tconst lookupRecords = parsePosLookupRecords(reader, lookupCount);\n\n\treturn { format: 3, coverages, lookupRecords };\n}\n\nexport function parseChainingContextPos(\n\treader: Reader,\n\tsubtableOffsets: number[],\n): ChainingContextPosSubtable[] {\n\tconst subtables: ChainingContextPosSubtable[] = [];\n\n\tfor (const offset of subtableOffsets) {\n\t\tconst r = reader.sliceFrom(offset);\n\t\tconst format = r.uint16();\n\n\t\tswitch (format) {\n\t\t\tcase 1:\n\t\t\t\tsubtables.push(parseChainingPosFormat1(r));\n\t\t\t\tbreak;\n\t\t\tcase 2:\n\t\t\t\tsubtables.push(parseChainingPosFormat2(r));\n\t\t\t\tbreak;\n\t\t\tcase 3:\n\t\t\t\tsubtables.push(parseChainingPosFormat3(r));\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn subtables;\n}\n\nfunction parseChainingPosFormat1(reader: Reader): ChainingContextPosFormat1 {\n\tconst coverageOffset = reader.offset16();\n\tconst chainRuleSetCount = reader.uint16();\n\tconst chainRuleSetOffsets = reader.uint16Array(chainRuleSetCount);\n\n\tconst coverage = parseCoverageAt(reader, coverageOffset);\n\tconst chainRuleSets: (PosChainRule[] | null)[] = [];\n\n\tfor (const crsOffset of chainRuleSetOffsets) {\n\t\tif (crsOffset === 0) {\n\t\t\tchainRuleSets.push(null);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst crsReader = reader.sliceFrom(crsOffset);\n\t\tconst ruleCount = crsReader.uint16();\n\t\tconst ruleOffsets = crsReader.uint16Array(ruleCount);\n\n\t\tconst rules: PosChainRule[] = [];\n\t\tfor (const ruleOffset of ruleOffsets) {\n\t\t\tconst ruleReader = crsReader.sliceFrom(ruleOffset);\n\n\t\t\tconst backtrackCount = ruleReader.uint16();\n\t\t\tconst backtrackSequence = Array.from(\n\t\t\t\truleReader.uint16Array(backtrackCount),\n\t\t\t);\n\n\t\t\tconst inputCount = ruleReader.uint16();\n\t\t\tconst inputSequence = Array.from(ruleReader.uint16Array(inputCount - 1));\n\n\t\t\tconst lookaheadCount = ruleReader.uint16();\n\t\t\tconst lookaheadSequence = Array.from(\n\t\t\t\truleReader.uint16Array(lookaheadCount),\n\t\t\t);\n\n\t\t\tconst lookupCount = ruleReader.uint16();\n\t\t\tconst lookupRecords = parsePosLookupRecords(ruleReader, lookupCount);\n\n\t\t\trules.push({\n\t\t\t\tbacktrackSequence,\n\t\t\t\tinputSequence,\n\t\t\t\tlookaheadSequence,\n\t\t\t\tlookupRecords,\n\t\t\t});\n\t\t}\n\n\t\tchainRuleSets.push(rules);\n\t}\n\n\treturn { format: 1, coverage, chainRuleSets };\n}\n\nfunction parseChainingPosFormat2(reader: Reader): ChainingContextPosFormat2 {\n\tconst coverageOffset = reader.offset16();\n\tconst backtrackClassDefOffset = reader.offset16();\n\tconst inputClassDefOffset = reader.offset16();\n\tconst lookaheadClassDefOffset = reader.offset16();\n\tconst chainClassRuleSetCount = reader.uint16();\n\tconst chainClassRuleSetOffsets = reader.uint16Array(chainClassRuleSetCount);\n\n\tconst coverage = parseCoverageAt(reader, coverageOffset);\n\tconst backtrackClassDef = parseClassDefAt(reader, backtrackClassDefOffset);\n\tconst inputClassDef = parseClassDefAt(reader, inputClassDefOffset);\n\tconst lookaheadClassDef = parseClassDefAt(reader, lookaheadClassDefOffset);\n\n\tconst chainClassRuleSets: (PosChainClassRule[] | null)[] = [];\n\n\tfor (const ccrsOffset of chainClassRuleSetOffsets) {\n\t\tif (ccrsOffset === 0) {\n\t\t\tchainClassRuleSets.push(null);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst ccrsReader = reader.sliceFrom(ccrsOffset);\n\t\tconst ruleCount = ccrsReader.uint16();\n\t\tconst ruleOffsets = ccrsReader.uint16Array(ruleCount);\n\n\t\tconst rules: PosChainClassRule[] = [];\n\t\tfor (const ruleOffset of ruleOffsets) {\n\t\t\tconst ruleReader = ccrsReader.sliceFrom(ruleOffset);\n\n\t\t\tconst backtrackCount = ruleReader.uint16();\n\t\t\tconst backtrackClasses = Array.from(\n\t\t\t\truleReader.uint16Array(backtrackCount),\n\t\t\t);\n\n\t\t\tconst inputCount = ruleReader.uint16();\n\t\t\tconst inputClasses = Array.from(ruleReader.uint16Array(inputCount - 1));\n\n\t\t\tconst lookaheadCount = ruleReader.uint16();\n\t\t\tconst lookaheadClasses = Array.from(\n\t\t\t\truleReader.uint16Array(lookaheadCount),\n\t\t\t);\n\n\t\t\tconst lookupCount = ruleReader.uint16();\n\t\t\tconst lookupRecords = parsePosLookupRecords(ruleReader, lookupCount);\n\n\t\t\trules.push({\n\t\t\t\tbacktrackClasses,\n\t\t\t\tinputClasses,\n\t\t\t\tlookaheadClasses,\n\t\t\t\tlookupRecords,\n\t\t\t});\n\t\t}\n\n\t\tchainClassRuleSets.push(rules);\n\t}\n\n\treturn {\n\t\tformat: 2,\n\t\tcoverage,\n\t\tbacktrackClassDef,\n\t\tinputClassDef,\n\t\tlookaheadClassDef,\n\t\tchainClassRuleSets,\n\t};\n}\n\nfunction parseChainingPosFormat3(reader: Reader): ChainingContextPosFormat3 {\n\tconst backtrackCount = reader.uint16();\n\tconst backtrackCoverageOffsets = reader.uint16Array(backtrackCount);\n\n\tconst inputCount = reader.uint16();\n\tconst inputCoverageOffsets = reader.uint16Array(inputCount);\n\n\tconst lookaheadCount = reader.uint16();\n\tconst lookaheadCoverageOffsets = reader.uint16Array(lookaheadCount);\n\n\tconst lookupCount = reader.uint16();\n\tconst lookupRecords = parsePosLookupRecords(reader, lookupCount);\n\n\tconst backtrackCoverages: Coverage[] = [];\n\tfor (const offset of backtrackCoverageOffsets) {\n\t\tbacktrackCoverages.push(parseCoverageAt(reader, offset));\n\t}\n\n\tconst inputCoverages: Coverage[] = [];\n\tfor (const offset of inputCoverageOffsets) {\n\t\tinputCoverages.push(parseCoverageAt(reader, offset));\n\t}\n\n\tconst lookaheadCoverages: Coverage[] = [];\n\tfor (const offset of lookaheadCoverageOffsets) {\n\t\tlookaheadCoverages.push(parseCoverageAt(reader, offset));\n\t}\n\n\treturn {\n\t\tformat: 3,\n\t\tbacktrackCoverages,\n\t\tinputCoverages,\n\t\tlookaheadCoverages,\n\t\tlookupRecords,\n\t};\n}\n\nfunction parsePosLookupRecords(\n\treader: Reader,\n\tcount: number,\n): PosLookupRecord[] {\n\tconst records: PosLookupRecord[] = [];\n\tfor (let i = 0; i < count; i++) {\n\t\trecords.push({\n\t\t\tsequenceIndex: reader.uint16(),\n\t\t\tlookupListIndex: reader.uint16(),\n\t\t});\n\t}\n\treturn records;\n}\n",
39
- "import {\n\ttype Coverage,\n\tparseCoverageAt,\n} from \"../../layout/structures/coverage.ts\";\nimport type { int16, uint16 } from \"../../types.ts\";\nimport type { Reader } from \"../binary/reader.ts\";\nimport type { GposLookup } from \"./gpos.ts\";\n\n/** Anchor point for attachment */\nexport interface Anchor {\n\txCoordinate: int16;\n\tyCoordinate: int16;\n\t/** Contour point index (format 2) */\n\tanchorPoint?: uint16;\n\t/** Device table offsets (format 3) */\n\txDeviceOffset?: uint16;\n\tyDeviceOffset?: uint16;\n}\n\n/** Mark record */\nexport interface MarkRecord {\n\tmarkClass: uint16;\n\tmarkAnchor: Anchor;\n}\n\n/** Mark array */\nexport interface MarkArray {\n\tmarkRecords: MarkRecord[];\n}\n\n/** Base record for mark-to-base */\nexport interface BaseRecord {\n\tbaseAnchors: (Anchor | null)[]; // One per mark class\n}\n\n/** Ligature attach record */\nexport interface LigatureAttach {\n\tcomponentRecords: ComponentRecord[];\n}\n\n/** Component record for ligature */\nexport interface ComponentRecord {\n\tligatureAnchors: (Anchor | null)[]; // One per mark class\n}\n\n/** Mark2 record for mark-to-mark */\nexport interface Mark2Record {\n\tmark2Anchors: (Anchor | null)[]; // One per mark1 class\n}\n\n/** Cursive attachment lookup (Type 3) */\nexport interface CursivePosLookup extends GposLookup {\n\ttype: 3;\n\tsubtables: CursivePosSubtable[];\n}\n\nexport interface CursivePosSubtable {\n\tcoverage: Coverage;\n\tentryExitRecords: EntryExitRecord[];\n}\n\nexport interface EntryExitRecord {\n\tentryAnchor: Anchor | null;\n\texitAnchor: Anchor | null;\n}\n\n/** Mark-to-base attachment lookup (Type 4) */\nexport interface MarkBasePosLookup extends GposLookup {\n\ttype: 4;\n\tsubtables: MarkBasePosSubtable[];\n}\n\nexport interface MarkBasePosSubtable {\n\tmarkCoverage: Coverage;\n\tbaseCoverage: Coverage;\n\tmarkClassCount: uint16;\n\tmarkArray: MarkArray;\n\tbaseArray: BaseRecord[];\n}\n\n/** Mark-to-ligature attachment lookup (Type 5) */\nexport interface MarkLigaturePosLookup extends GposLookup {\n\ttype: 5;\n\tsubtables: MarkLigaturePosSubtable[];\n}\n\nexport interface MarkLigaturePosSubtable {\n\tmarkCoverage: Coverage;\n\tligatureCoverage: Coverage;\n\tmarkClassCount: uint16;\n\tmarkArray: MarkArray;\n\tligatureArray: LigatureAttach[];\n}\n\n/** Mark-to-mark attachment lookup (Type 6) */\nexport interface MarkMarkPosLookup extends GposLookup {\n\ttype: 6;\n\tsubtables: MarkMarkPosSubtable[];\n}\n\nexport interface MarkMarkPosSubtable {\n\tmark1Coverage: Coverage;\n\tmark2Coverage: Coverage;\n\tmarkClassCount: uint16;\n\tmark1Array: MarkArray;\n\tmark2Array: Mark2Record[];\n}\n\n// Parsing functions\n\nexport function parseAnchor(reader: Reader): Anchor {\n\tconst format = reader.uint16();\n\tconst xCoordinate = reader.int16();\n\tconst yCoordinate = reader.int16();\n\n\tconst anchor: Anchor = { xCoordinate, yCoordinate };\n\n\tif (format === 2) {\n\t\tanchor.anchorPoint = reader.uint16();\n\t} else if (format === 3) {\n\t\tanchor.xDeviceOffset = reader.uint16();\n\t\tanchor.yDeviceOffset = reader.uint16();\n\t}\n\n\treturn anchor;\n}\n\nexport function parseAnchorAt(reader: Reader, offset: number): Anchor | null {\n\tif (offset === 0) return null;\n\treturn parseAnchor(reader.sliceFrom(offset));\n}\n\nexport function parseMarkArray(reader: Reader): MarkArray {\n\tconst markCount = reader.uint16();\n\tconst markRecords: MarkRecord[] = [];\n\n\tconst recordData: Array<{ markClass: uint16; anchorOffset: uint16 }> = [];\n\tfor (let i = 0; i < markCount; i++) {\n\t\trecordData.push({\n\t\t\tmarkClass: reader.uint16(),\n\t\t\tanchorOffset: reader.uint16(),\n\t\t});\n\t}\n\n\tfor (const data of recordData) {\n\t\tconst markAnchor = parseAnchor(reader.sliceFrom(data.anchorOffset));\n\t\tmarkRecords.push({\n\t\t\tmarkClass: data.markClass,\n\t\t\tmarkAnchor,\n\t\t});\n\t}\n\n\treturn { markRecords };\n}\n\nexport function parseCursivePos(\n\treader: Reader,\n\tsubtableOffsets: number[],\n): CursivePosSubtable[] {\n\tconst subtables: CursivePosSubtable[] = [];\n\n\tfor (const offset of subtableOffsets) {\n\t\tconst r = reader.sliceFrom(offset);\n\t\tconst format = r.uint16();\n\n\t\tif (format === 1) {\n\t\t\tconst coverageOffset = r.offset16();\n\t\t\tconst entryExitCount = r.uint16();\n\n\t\t\tconst entryExitData: Array<{ entryOffset: uint16; exitOffset: uint16 }> =\n\t\t\t\t[];\n\t\t\tfor (let i = 0; i < entryExitCount; i++) {\n\t\t\t\tentryExitData.push({\n\t\t\t\t\tentryOffset: r.uint16(),\n\t\t\t\t\texitOffset: r.uint16(),\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst coverage = parseCoverageAt(r, coverageOffset);\n\t\t\tconst entryExitRecords: EntryExitRecord[] = [];\n\n\t\t\tfor (const data of entryExitData) {\n\t\t\t\tentryExitRecords.push({\n\t\t\t\t\tentryAnchor: parseAnchorAt(r, data.entryOffset),\n\t\t\t\t\texitAnchor: parseAnchorAt(r, data.exitOffset),\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tsubtables.push({ coverage, entryExitRecords });\n\t\t}\n\t}\n\n\treturn subtables;\n}\n\nexport function parseMarkBasePos(\n\treader: Reader,\n\tsubtableOffsets: number[],\n): MarkBasePosSubtable[] {\n\tconst subtables: MarkBasePosSubtable[] = [];\n\n\tfor (const offset of subtableOffsets) {\n\t\tconst r = reader.sliceFrom(offset);\n\t\tconst format = r.uint16();\n\n\t\tif (format === 1) {\n\t\t\tconst markCoverageOffset = r.offset16();\n\t\t\tconst baseCoverageOffset = r.offset16();\n\t\t\tconst markClassCount = r.uint16();\n\t\t\tconst markArrayOffset = r.offset16();\n\t\t\tconst baseArrayOffset = r.offset16();\n\n\t\t\tconst markCoverage = parseCoverageAt(r, markCoverageOffset);\n\t\t\tconst baseCoverage = parseCoverageAt(r, baseCoverageOffset);\n\t\t\tconst markArray = parseMarkArray(r.sliceFrom(markArrayOffset));\n\n\t\t\t// Parse base array\n\t\t\tconst baseArrayReader = r.sliceFrom(baseArrayOffset);\n\t\t\tconst baseCount = baseArrayReader.uint16();\n\t\t\tconst baseArray: BaseRecord[] = [];\n\n\t\t\t// Read anchor offsets first\n\t\t\tconst baseRecordData: Array<uint16[]> = [];\n\t\t\tfor (let i = 0; i < baseCount; i++) {\n\t\t\t\tconst anchorOffsets: uint16[] = [];\n\t\t\t\tfor (let j = 0; j < markClassCount; j++) {\n\t\t\t\t\tanchorOffsets.push(baseArrayReader.uint16());\n\t\t\t\t}\n\t\t\t\tbaseRecordData.push(anchorOffsets);\n\t\t\t}\n\n\t\t\t// Parse anchors\n\t\t\tfor (const anchorOffsets of baseRecordData) {\n\t\t\t\tconst baseAnchors: (Anchor | null)[] = [];\n\t\t\t\tfor (const anchorOffset of anchorOffsets) {\n\t\t\t\t\tbaseAnchors.push(parseAnchorAt(baseArrayReader, anchorOffset));\n\t\t\t\t}\n\t\t\t\tbaseArray.push({ baseAnchors });\n\t\t\t}\n\n\t\t\tsubtables.push({\n\t\t\t\tmarkCoverage,\n\t\t\t\tbaseCoverage,\n\t\t\t\tmarkClassCount,\n\t\t\t\tmarkArray,\n\t\t\t\tbaseArray,\n\t\t\t});\n\t\t}\n\t}\n\n\treturn subtables;\n}\n\nexport function parseMarkLigaturePos(\n\treader: Reader,\n\tsubtableOffsets: number[],\n): MarkLigaturePosSubtable[] {\n\tconst subtables: MarkLigaturePosSubtable[] = [];\n\n\tfor (const offset of subtableOffsets) {\n\t\tconst r = reader.sliceFrom(offset);\n\t\tconst format = r.uint16();\n\n\t\tif (format === 1) {\n\t\t\tconst markCoverageOffset = r.offset16();\n\t\t\tconst ligatureCoverageOffset = r.offset16();\n\t\t\tconst markClassCount = r.uint16();\n\t\t\tconst markArrayOffset = r.offset16();\n\t\t\tconst ligatureArrayOffset = r.offset16();\n\n\t\t\tconst markCoverage = parseCoverageAt(r, markCoverageOffset);\n\t\t\tconst ligatureCoverage = parseCoverageAt(r, ligatureCoverageOffset);\n\t\t\tconst markArray = parseMarkArray(r.sliceFrom(markArrayOffset));\n\n\t\t\t// Parse ligature array\n\t\t\tconst ligArrayReader = r.sliceFrom(ligatureArrayOffset);\n\t\t\tconst ligatureCount = ligArrayReader.uint16();\n\t\t\tconst ligatureAttachOffsets = ligArrayReader.uint16Array(ligatureCount);\n\n\t\t\tconst ligatureArray: LigatureAttach[] = [];\n\t\t\tfor (const ligAttachOffset of ligatureAttachOffsets) {\n\t\t\t\tconst ligAttachReader = ligArrayReader.sliceFrom(ligAttachOffset);\n\t\t\t\tconst componentCount = ligAttachReader.uint16();\n\n\t\t\t\tconst componentRecords: ComponentRecord[] = [];\n\t\t\t\t// Read all anchor offsets first\n\t\t\t\tconst componentData: Array<uint16[]> = [];\n\t\t\t\tfor (let i = 0; i < componentCount; i++) {\n\t\t\t\t\tconst anchorOffsets: uint16[] = [];\n\t\t\t\t\tfor (let j = 0; j < markClassCount; j++) {\n\t\t\t\t\t\tanchorOffsets.push(ligAttachReader.uint16());\n\t\t\t\t\t}\n\t\t\t\t\tcomponentData.push(anchorOffsets);\n\t\t\t\t}\n\n\t\t\t\t// Parse anchors\n\t\t\t\tfor (const anchorOffsets of componentData) {\n\t\t\t\t\tconst ligatureAnchors: (Anchor | null)[] = [];\n\t\t\t\t\tfor (const anchorOffset of anchorOffsets) {\n\t\t\t\t\t\tligatureAnchors.push(parseAnchorAt(ligAttachReader, anchorOffset));\n\t\t\t\t\t}\n\t\t\t\t\tcomponentRecords.push({ ligatureAnchors });\n\t\t\t\t}\n\n\t\t\t\tligatureArray.push({ componentRecords });\n\t\t\t}\n\n\t\t\tsubtables.push({\n\t\t\t\tmarkCoverage,\n\t\t\t\tligatureCoverage,\n\t\t\t\tmarkClassCount,\n\t\t\t\tmarkArray,\n\t\t\t\tligatureArray,\n\t\t\t});\n\t\t}\n\t}\n\n\treturn subtables;\n}\n\nexport function parseMarkMarkPos(\n\treader: Reader,\n\tsubtableOffsets: number[],\n): MarkMarkPosSubtable[] {\n\tconst subtables: MarkMarkPosSubtable[] = [];\n\n\tfor (const offset of subtableOffsets) {\n\t\tconst r = reader.sliceFrom(offset);\n\t\tconst format = r.uint16();\n\n\t\tif (format === 1) {\n\t\t\tconst mark1CoverageOffset = r.offset16();\n\t\t\tconst mark2CoverageOffset = r.offset16();\n\t\t\tconst markClassCount = r.uint16();\n\t\t\tconst mark1ArrayOffset = r.offset16();\n\t\t\tconst mark2ArrayOffset = r.offset16();\n\n\t\t\tconst mark1Coverage = parseCoverageAt(r, mark1CoverageOffset);\n\t\t\tconst mark2Coverage = parseCoverageAt(r, mark2CoverageOffset);\n\t\t\tconst mark1Array = parseMarkArray(r.sliceFrom(mark1ArrayOffset));\n\n\t\t\t// Parse mark2 array\n\t\t\tconst mark2ArrayReader = r.sliceFrom(mark2ArrayOffset);\n\t\t\tconst mark2Count = mark2ArrayReader.uint16();\n\t\t\tconst mark2Array: Mark2Record[] = [];\n\n\t\t\t// Read anchor offsets\n\t\t\tconst mark2Data: Array<uint16[]> = [];\n\t\t\tfor (let i = 0; i < mark2Count; i++) {\n\t\t\t\tconst anchorOffsets: uint16[] = [];\n\t\t\t\tfor (let j = 0; j < markClassCount; j++) {\n\t\t\t\t\tanchorOffsets.push(mark2ArrayReader.uint16());\n\t\t\t\t}\n\t\t\t\tmark2Data.push(anchorOffsets);\n\t\t\t}\n\n\t\t\t// Parse anchors\n\t\t\tfor (const anchorOffsets of mark2Data) {\n\t\t\t\tconst mark2Anchors: (Anchor | null)[] = [];\n\t\t\t\tfor (const anchorOffset of anchorOffsets) {\n\t\t\t\t\tmark2Anchors.push(parseAnchorAt(mark2ArrayReader, anchorOffset));\n\t\t\t\t}\n\t\t\t\tmark2Array.push({ mark2Anchors });\n\t\t\t}\n\n\t\t\tsubtables.push({\n\t\t\t\tmark1Coverage,\n\t\t\t\tmark2Coverage,\n\t\t\t\tmarkClassCount,\n\t\t\t\tmark1Array,\n\t\t\t\tmark2Array,\n\t\t\t});\n\t\t}\n\t}\n\n\treturn subtables;\n}\n",
40
- "import {\n\ttype ClassDef,\n\tparseClassDefAt,\n} from \"../../layout/structures/class-def.ts\";\nimport {\n\ttype Coverage,\n\tparseCoverageAt,\n} from \"../../layout/structures/coverage.ts\";\nimport {\n\ttype DeviceOrVariationIndex,\n\tparseDeviceAt,\n} from \"../../layout/structures/device.ts\";\nimport {\n\ttype FeatureList,\n\tLookupFlag,\n\tparseFeatureList,\n\tparseScriptList,\n\ttype ScriptList,\n} from \"../../layout/structures/layout-common.ts\";\nimport type { GlyphId, int16, uint16 } from \"../../types.ts\";\nimport type { Reader } from \"../binary/reader.ts\";\nimport {\n\ttype ChainingContextPosLookup,\n\ttype ChainingContextPosSubtable,\n\ttype ContextPosLookup,\n\ttype ContextPosSubtable,\n\tparseChainingContextPos,\n\tparseContextPos,\n} from \"./gpos-contextual.ts\";\nimport {\n\ttype CursivePosSubtable,\n\ttype MarkBasePosSubtable,\n\ttype MarkLigaturePosSubtable,\n\ttype MarkMarkPosSubtable,\n\tparseCursivePos,\n\tparseMarkBasePos,\n\tparseMarkLigaturePos,\n\tparseMarkMarkPos,\n} from \"./gpos-mark.ts\";\n\n/** GPOS lookup types */\nexport enum GposLookupType {\n\tSingle = 1,\n\tPair = 2,\n\tCursive = 3,\n\tMarkToBase = 4,\n\tMarkToLigature = 5,\n\tMarkToMark = 6,\n\tContext = 7,\n\tChainingContext = 8,\n\tExtension = 9,\n}\n\n/** Value record - positioning adjustments */\nexport interface ValueRecord {\n\txPlacement?: int16;\n\tyPlacement?: int16;\n\txAdvance?: int16;\n\tyAdvance?: int16;\n\txPlaDevice?: DeviceOrVariationIndex;\n\tyPlaDevice?: DeviceOrVariationIndex;\n\txAdvDevice?: DeviceOrVariationIndex;\n\tyAdvDevice?: DeviceOrVariationIndex;\n}\n\n/** Value format flags */\nexport const ValueFormat = {\n\tXPlacement: 0x0001,\n\tYPlacement: 0x0002,\n\tXAdvance: 0x0004,\n\tYAdvance: 0x0008,\n\tXPlaDevice: 0x0010,\n\tYPlaDevice: 0x0020,\n\tXAdvDevice: 0x0040,\n\tYAdvDevice: 0x0080,\n} as const;\n\n/** Base interface for all GPOS lookups */\nexport interface GposLookup {\n\ttype: GposLookupType;\n\tflag: uint16;\n\tmarkFilteringSet?: uint16;\n}\n\n/** Single adjustment lookup (Type 1) */\nexport interface SinglePosLookup extends GposLookup {\n\ttype: GposLookupType.Single;\n\tsubtables: SinglePosSubtable[];\n}\n\nexport interface SinglePosSubtable {\n\tformat: 1 | 2;\n\tcoverage: Coverage;\n\tvalueFormat: uint16;\n\tvalue?: ValueRecord;\n\tvalues?: ValueRecord[];\n}\n\n/** Pair adjustment lookup (Type 2) - kerning */\nexport interface PairPosLookup extends GposLookup {\n\ttype: GposLookupType.Pair;\n\tsubtables: PairPosSubtable[];\n}\n\nexport type PairPosSubtable = PairPosFormat1 | PairPosFormat2;\n\nexport interface PairPosFormat1 {\n\tformat: 1;\n\tcoverage: Coverage;\n\tvalueFormat1: uint16;\n\tvalueFormat2: uint16;\n\tpairSets: PairSet[];\n}\n\nexport interface PairSet {\n\tpairValueRecords: PairValueRecord[];\n}\n\nexport interface PairValueRecord {\n\tsecondGlyph: GlyphId;\n\tvalue1: ValueRecord;\n\tvalue2: ValueRecord;\n}\n\nexport interface PairPosFormat2 {\n\tformat: 2;\n\tcoverage: Coverage;\n\tvalueFormat1: uint16;\n\tvalueFormat2: uint16;\n\tclassDef1: ClassDef;\n\tclassDef2: ClassDef;\n\tclass1Count: uint16;\n\tclass2Count: uint16;\n\tclass1Records: Class1Record[];\n}\n\nexport interface Class1Record {\n\tclass2Records: Class2Record[];\n}\n\nexport interface Class2Record {\n\tvalue1: ValueRecord;\n\tvalue2: ValueRecord;\n}\n\n/** Cursive attachment lookup (Type 3) */\nexport interface CursivePosLookup extends GposLookup {\n\ttype: GposLookupType.Cursive;\n\tsubtables: CursivePosSubtable[];\n}\n\n/** Mark-to-base attachment lookup (Type 4) */\nexport interface MarkBasePosLookup extends GposLookup {\n\ttype: GposLookupType.MarkToBase;\n\tsubtables: MarkBasePosSubtable[];\n}\n\n/** Mark-to-ligature attachment lookup (Type 5) */\nexport interface MarkLigaturePosLookup extends GposLookup {\n\ttype: GposLookupType.MarkToLigature;\n\tsubtables: MarkLigaturePosSubtable[];\n}\n\n/** Mark-to-mark attachment lookup (Type 6) */\nexport interface MarkMarkPosLookup extends GposLookup {\n\ttype: GposLookupType.MarkToMark;\n\tsubtables: MarkMarkPosSubtable[];\n}\n\n/** Union of all GPOS lookup types */\nexport type AnyGposLookup =\n\t| SinglePosLookup\n\t| PairPosLookup\n\t| CursivePosLookup\n\t| MarkBasePosLookup\n\t| MarkLigaturePosLookup\n\t| MarkMarkPosLookup\n\t| ContextPosLookup\n\t| ChainingContextPosLookup;\n\n/** GPOS table */\nexport interface GposTable {\n\tversion: { major: number; minor: number };\n\tscriptList: ScriptList;\n\tfeatureList: FeatureList;\n\tlookups: AnyGposLookup[];\n}\n\n// Re-export mark types\nexport type { Anchor, MarkArray } from \"./gpos-mark.ts\";\n\nexport function parseGpos(reader: Reader): GposTable {\n\tconst majorVersion = reader.uint16();\n\tconst minorVersion = reader.uint16();\n\n\tconst scriptListOffset = reader.offset16();\n\tconst featureListOffset = reader.offset16();\n\tconst lookupListOffset = reader.offset16();\n\n\tif (majorVersion === 1 && minorVersion >= 1) {\n\t\treader.offset32(); // featureVariationsOffset\n\t}\n\n\tconst scriptList = parseScriptList(reader.sliceFrom(scriptListOffset));\n\tconst featureList = parseFeatureList(reader.sliceFrom(featureListOffset));\n\n\tconst lookupListReader = reader.sliceFrom(lookupListOffset);\n\tconst lookupCount = lookupListReader.uint16();\n\tconst lookupOffsets = lookupListReader.uint16Array(lookupCount);\n\n\tconst lookups: AnyGposLookup[] = [];\n\tfor (const lookupOffset of lookupOffsets) {\n\t\tconst lookupReader = lookupListReader.sliceFrom(lookupOffset);\n\t\tconst lookup = parseGposLookup(lookupReader);\n\t\tif (lookup) {\n\t\t\tlookups.push(lookup);\n\t\t}\n\t}\n\n\treturn {\n\t\tversion: { major: majorVersion, minor: minorVersion },\n\t\tscriptList,\n\t\tfeatureList,\n\t\tlookups,\n\t};\n}\n\nfunction parseGposLookup(reader: Reader): AnyGposLookup | null {\n\tconst lookupType = reader.uint16();\n\tconst lookupFlag = reader.uint16();\n\tconst subtableCount = reader.uint16();\n\tconst subtableOffsets = Array.from(reader.uint16Array(subtableCount));\n\n\tlet markFilteringSet: uint16 | undefined;\n\tif (lookupFlag & LookupFlag.UseMarkFilteringSet) {\n\t\tmarkFilteringSet = reader.uint16();\n\t}\n\n\tconst baseProps = { flag: lookupFlag, markFilteringSet };\n\n\tswitch (lookupType) {\n\t\tcase GposLookupType.Single:\n\t\t\treturn {\n\t\t\t\ttype: GposLookupType.Single,\n\t\t\t\t...baseProps,\n\t\t\t\tsubtables: parseSinglePos(reader, subtableOffsets),\n\t\t\t};\n\n\t\tcase GposLookupType.Pair:\n\t\t\treturn {\n\t\t\t\ttype: GposLookupType.Pair,\n\t\t\t\t...baseProps,\n\t\t\t\tsubtables: parsePairPos(reader, subtableOffsets),\n\t\t\t};\n\n\t\tcase GposLookupType.Cursive:\n\t\t\treturn {\n\t\t\t\ttype: GposLookupType.Cursive,\n\t\t\t\t...baseProps,\n\t\t\t\tsubtables: parseCursivePos(reader, subtableOffsets),\n\t\t\t};\n\n\t\tcase GposLookupType.MarkToBase:\n\t\t\treturn {\n\t\t\t\ttype: GposLookupType.MarkToBase,\n\t\t\t\t...baseProps,\n\t\t\t\tsubtables: parseMarkBasePos(reader, subtableOffsets),\n\t\t\t};\n\n\t\tcase GposLookupType.MarkToLigature:\n\t\t\treturn {\n\t\t\t\ttype: GposLookupType.MarkToLigature,\n\t\t\t\t...baseProps,\n\t\t\t\tsubtables: parseMarkLigaturePos(reader, subtableOffsets),\n\t\t\t};\n\n\t\tcase GposLookupType.MarkToMark:\n\t\t\treturn {\n\t\t\t\ttype: GposLookupType.MarkToMark,\n\t\t\t\t...baseProps,\n\t\t\t\tsubtables: parseMarkMarkPos(reader, subtableOffsets),\n\t\t\t};\n\n\t\tcase GposLookupType.Context:\n\t\t\treturn {\n\t\t\t\ttype: GposLookupType.Context,\n\t\t\t\t...baseProps,\n\t\t\t\tsubtables: parseContextPos(reader, subtableOffsets),\n\t\t\t};\n\n\t\tcase GposLookupType.ChainingContext:\n\t\t\treturn {\n\t\t\t\ttype: GposLookupType.ChainingContext,\n\t\t\t\t...baseProps,\n\t\t\t\tsubtables: parseChainingContextPos(reader, subtableOffsets),\n\t\t\t};\n\n\t\tcase GposLookupType.Extension:\n\t\t\treturn parseExtensionLookup(reader, subtableOffsets, baseProps);\n\n\t\tdefault:\n\t\t\treturn null;\n\t}\n}\n\nfunction parseValueRecord(\n\treader: Reader,\n\tvalueFormat: uint16,\n\tsubtableReader?: Reader,\n): ValueRecord {\n\tconst record: ValueRecord = {};\n\n\tif (valueFormat & ValueFormat.XPlacement) record.xPlacement = reader.int16();\n\tif (valueFormat & ValueFormat.YPlacement) record.yPlacement = reader.int16();\n\tif (valueFormat & ValueFormat.XAdvance) record.xAdvance = reader.int16();\n\tif (valueFormat & ValueFormat.YAdvance) record.yAdvance = reader.int16();\n\n\t// Parse Device tables if we have a subtable reader to resolve offsets\n\tconst deviceReader = subtableReader ?? reader;\n\tif (valueFormat & ValueFormat.XPlaDevice) {\n\t\tconst offset = reader.uint16();\n\t\tif (offset !== 0)\n\t\t\trecord.xPlaDevice = parseDeviceAt(deviceReader, offset) ?? undefined;\n\t}\n\tif (valueFormat & ValueFormat.YPlaDevice) {\n\t\tconst offset = reader.uint16();\n\t\tif (offset !== 0)\n\t\t\trecord.yPlaDevice = parseDeviceAt(deviceReader, offset) ?? undefined;\n\t}\n\tif (valueFormat & ValueFormat.XAdvDevice) {\n\t\tconst offset = reader.uint16();\n\t\tif (offset !== 0)\n\t\t\trecord.xAdvDevice = parseDeviceAt(deviceReader, offset) ?? undefined;\n\t}\n\tif (valueFormat & ValueFormat.YAdvDevice) {\n\t\tconst offset = reader.uint16();\n\t\tif (offset !== 0)\n\t\t\trecord.yAdvDevice = parseDeviceAt(deviceReader, offset) ?? undefined;\n\t}\n\n\treturn record;\n}\n\nfunction parseSinglePos(\n\treader: Reader,\n\tsubtableOffsets: number[],\n): SinglePosSubtable[] {\n\tconst subtables: SinglePosSubtable[] = [];\n\n\tfor (const offset of subtableOffsets) {\n\t\tconst subtableReader = reader.sliceFrom(offset);\n\t\tconst r = reader.sliceFrom(offset);\n\t\tconst format = r.uint16();\n\n\t\tif (format === 1) {\n\t\t\tconst coverageOffset = r.offset16();\n\t\t\tconst valueFormat = r.uint16();\n\t\t\tconst value = parseValueRecord(r, valueFormat, subtableReader);\n\t\t\tconst coverage = parseCoverageAt(subtableReader, coverageOffset);\n\t\t\tsubtables.push({ format: 1, coverage, valueFormat, value });\n\t\t} else if (format === 2) {\n\t\t\tconst coverageOffset = r.offset16();\n\t\t\tconst valueFormat = r.uint16();\n\t\t\tconst valueCount = r.uint16();\n\t\t\tconst values: ValueRecord[] = [];\n\t\t\tfor (let i = 0; i < valueCount; i++) {\n\t\t\t\tvalues.push(parseValueRecord(r, valueFormat, subtableReader));\n\t\t\t}\n\t\t\tconst coverage = parseCoverageAt(subtableReader, coverageOffset);\n\t\t\tsubtables.push({ format: 2, coverage, valueFormat, values });\n\t\t}\n\t}\n\n\treturn subtables;\n}\n\nfunction parsePairPos(\n\treader: Reader,\n\tsubtableOffsets: number[],\n): PairPosSubtable[] {\n\tconst subtables: PairPosSubtable[] = [];\n\n\tfor (const offset of subtableOffsets) {\n\t\tconst subtableReader = reader.sliceFrom(offset);\n\t\tconst r = reader.sliceFrom(offset);\n\t\tconst format = r.uint16();\n\n\t\tif (format === 1) {\n\t\t\tsubtables.push(parsePairPosFormat1(r, subtableReader));\n\t\t} else if (format === 2) {\n\t\t\tsubtables.push(parsePairPosFormat2(r, subtableReader));\n\t\t}\n\t}\n\n\treturn subtables;\n}\n\nfunction parsePairPosFormat1(\n\treader: Reader,\n\tsubtableReader: Reader,\n): PairPosFormat1 {\n\tconst coverageOffset = reader.offset16();\n\tconst valueFormat1 = reader.uint16();\n\tconst valueFormat2 = reader.uint16();\n\tconst pairSetCount = reader.uint16();\n\tconst pairSetOffsets = reader.uint16Array(pairSetCount);\n\n\tconst coverage = parseCoverageAt(subtableReader, coverageOffset);\n\tconst pairSets: PairSet[] = [];\n\n\tfor (const pairSetOffset of pairSetOffsets) {\n\t\tconst pairSetReader = subtableReader.sliceFrom(pairSetOffset);\n\t\tconst r = subtableReader.sliceFrom(pairSetOffset);\n\t\tconst pairValueCount = r.uint16();\n\t\tconst pairValueRecords: PairValueRecord[] = [];\n\n\t\tfor (let i = 0; i < pairValueCount; i++) {\n\t\t\tconst secondGlyph = r.uint16();\n\t\t\tconst value1 = parseValueRecord(r, valueFormat1, pairSetReader);\n\t\t\tconst value2 = parseValueRecord(r, valueFormat2, pairSetReader);\n\t\t\tpairValueRecords.push({ secondGlyph, value1, value2 });\n\t\t}\n\n\t\tpairSets.push({ pairValueRecords });\n\t}\n\n\treturn { format: 1, coverage, valueFormat1, valueFormat2, pairSets };\n}\n\nfunction parsePairPosFormat2(\n\treader: Reader,\n\tsubtableReader: Reader,\n): PairPosFormat2 {\n\tconst coverageOffset = reader.offset16();\n\tconst valueFormat1 = reader.uint16();\n\tconst valueFormat2 = reader.uint16();\n\tconst classDef1Offset = reader.offset16();\n\tconst classDef2Offset = reader.offset16();\n\tconst class1Count = reader.uint16();\n\tconst class2Count = reader.uint16();\n\n\tconst coverage = parseCoverageAt(subtableReader, coverageOffset);\n\tconst classDef1 = parseClassDefAt(subtableReader, classDef1Offset);\n\tconst classDef2 = parseClassDefAt(subtableReader, classDef2Offset);\n\n\tconst class1Records: Class1Record[] = [];\n\tfor (let i = 0; i < class1Count; i++) {\n\t\tconst class2Records: Class2Record[] = [];\n\t\tfor (let j = 0; j < class2Count; j++) {\n\t\t\tconst value1 = parseValueRecord(reader, valueFormat1, subtableReader);\n\t\t\tconst value2 = parseValueRecord(reader, valueFormat2, subtableReader);\n\t\t\tclass2Records.push({ value1, value2 });\n\t\t}\n\t\tclass1Records.push({ class2Records });\n\t}\n\n\treturn {\n\t\tformat: 2,\n\t\tcoverage,\n\t\tvalueFormat1,\n\t\tvalueFormat2,\n\t\tclassDef1,\n\t\tclassDef2,\n\t\tclass1Count,\n\t\tclass2Count,\n\t\tclass1Records,\n\t};\n}\n\nfunction parseExtensionLookup(\n\treader: Reader,\n\tsubtableOffsets: number[],\n\tbaseProps: { flag: uint16; markFilteringSet?: uint16 },\n): AnyGposLookup | null {\n\tif (subtableOffsets.length === 0) return null;\n\n\tconst extSubtables: Array<{ type: number; reader: Reader }> = [];\n\n\tfor (const offset of subtableOffsets) {\n\t\tconst extReader = reader.sliceFrom(offset);\n\t\tconst format = extReader.uint16();\n\t\tif (format !== 1) continue;\n\n\t\tconst extensionLookupType = extReader.uint16();\n\t\tconst extensionOffset = extReader.uint32();\n\n\t\t// extensionOffset is relative to start of extension subtable\n\t\textSubtables.push({\n\t\t\ttype: extensionLookupType,\n\t\t\treader: extReader.sliceFrom(extensionOffset),\n\t\t});\n\t}\n\n\tif (extSubtables.length === 0) return null;\n\n\tconst actualType = extSubtables[0]?.type;\n\n\tswitch (actualType) {\n\t\tcase GposLookupType.Single: {\n\t\t\tconst subtables: SinglePosSubtable[] = [];\n\t\t\tfor (const ext of extSubtables) {\n\t\t\t\tsubtables.push(...parseSinglePos(ext.reader, [0]));\n\t\t\t}\n\t\t\treturn { type: GposLookupType.Single, ...baseProps, subtables };\n\t\t}\n\n\t\tcase GposLookupType.Pair: {\n\t\t\tconst subtables: PairPosSubtable[] = [];\n\t\t\tfor (const ext of extSubtables) {\n\t\t\t\tsubtables.push(...parsePairPos(ext.reader, [0]));\n\t\t\t}\n\t\t\treturn { type: GposLookupType.Pair, ...baseProps, subtables };\n\t\t}\n\n\t\tcase GposLookupType.Cursive: {\n\t\t\tconst subtables: CursivePosSubtable[] = [];\n\t\t\tfor (const ext of extSubtables) {\n\t\t\t\tsubtables.push(...parseCursivePos(ext.reader, [0]));\n\t\t\t}\n\t\t\treturn { type: GposLookupType.Cursive, ...baseProps, subtables };\n\t\t}\n\n\t\tcase GposLookupType.MarkToBase: {\n\t\t\tconst subtables: MarkBasePosSubtable[] = [];\n\t\t\tfor (const ext of extSubtables) {\n\t\t\t\tsubtables.push(...parseMarkBasePos(ext.reader, [0]));\n\t\t\t}\n\t\t\treturn { type: GposLookupType.MarkToBase, ...baseProps, subtables };\n\t\t}\n\n\t\tcase GposLookupType.MarkToLigature: {\n\t\t\tconst subtables: MarkLigaturePosSubtable[] = [];\n\t\t\tfor (const ext of extSubtables) {\n\t\t\t\tsubtables.push(...parseMarkLigaturePos(ext.reader, [0]));\n\t\t\t}\n\t\t\treturn { type: GposLookupType.MarkToLigature, ...baseProps, subtables };\n\t\t}\n\n\t\tcase GposLookupType.MarkToMark: {\n\t\t\tconst subtables: MarkMarkPosSubtable[] = [];\n\t\t\tfor (const ext of extSubtables) {\n\t\t\t\tsubtables.push(...parseMarkMarkPos(ext.reader, [0]));\n\t\t\t}\n\t\t\treturn { type: GposLookupType.MarkToMark, ...baseProps, subtables };\n\t\t}\n\n\t\tcase GposLookupType.Context: {\n\t\t\tconst subtables: ContextPosSubtable[] = [];\n\t\t\tfor (const ext of extSubtables) {\n\t\t\t\tsubtables.push(...parseContextPos(ext.reader, [0]));\n\t\t\t}\n\t\t\treturn { type: GposLookupType.Context, ...baseProps, subtables };\n\t\t}\n\n\t\tcase GposLookupType.ChainingContext: {\n\t\t\tconst subtables: ChainingContextPosSubtable[] = [];\n\t\t\tfor (const ext of extSubtables) {\n\t\t\t\tsubtables.push(...parseChainingContextPos(ext.reader, [0]));\n\t\t\t}\n\t\t\treturn { type: GposLookupType.ChainingContext, ...baseProps, subtables };\n\t\t}\n\n\t\tdefault:\n\t\t\treturn null;\n\t}\n}\n\n// Utility functions\n\nexport function getKerning(\n\tlookup: PairPosLookup,\n\tfirstGlyph: GlyphId,\n\tsecondGlyph: GlyphId,\n): { xAdvance1: number; xAdvance2: number } | null {\n\tfor (const subtable of lookup.subtables) {\n\t\tconst coverageIndex = subtable.coverage.get(firstGlyph);\n\t\tif (coverageIndex === null) continue;\n\n\t\tif (subtable.format === 1) {\n\t\t\tconst pairSet = subtable.pairSets[coverageIndex];\n\t\t\tif (!pairSet) continue;\n\n\t\t\tfor (const record of pairSet.pairValueRecords) {\n\t\t\t\tif (record.secondGlyph === secondGlyph) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\txAdvance1: record.value1.xAdvance ?? 0,\n\t\t\t\t\t\txAdvance2: record.value2.xAdvance ?? 0,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (subtable.format === 2) {\n\t\t\tconst class1 = subtable.classDef1.get(firstGlyph);\n\t\t\tconst class2 = subtable.classDef2.get(secondGlyph);\n\n\t\t\tconst class1Record = subtable.class1Records[class1];\n\t\t\tif (!class1Record) continue;\n\n\t\t\tconst class2Record = class1Record.class2Records[class2];\n\t\t\tif (!class2Record) continue;\n\n\t\t\treturn {\n\t\t\t\txAdvance1: class2Record.value1.xAdvance ?? 0,\n\t\t\t\txAdvance2: class2Record.value2.xAdvance ?? 0,\n\t\t\t};\n\t\t}\n\t}\n\n\treturn null;\n}\n",
41
- "import {\n\ttype ClassDef,\n\tparseClassDefAt,\n} from \"../../layout/structures/class-def.ts\";\nimport {\n\ttype Coverage,\n\tparseCoverageAt,\n} from \"../../layout/structures/coverage.ts\";\nimport type { GlyphId, uint16 } from \"../../types.ts\";\nimport type { Reader } from \"../binary/reader.ts\";\nimport type { GsubLookup } from \"./gsub.ts\";\n\n/** Sequence lookup record - applies a lookup at a position */\nexport interface SequenceLookupRecord {\n\tsequenceIndex: uint16; // Position in input sequence\n\tlookupListIndex: uint16; // Lookup to apply\n}\n\n/** Context substitution lookup (Type 5) */\nexport interface ContextSubstLookup extends GsubLookup {\n\ttype: 5;\n\tsubtables: ContextSubstSubtable[];\n}\n\nexport type ContextSubstSubtable =\n\t| ContextSubstFormat1\n\t| ContextSubstFormat2\n\t| ContextSubstFormat3;\n\n/** Format 1: Simple glyph contexts */\nexport interface ContextSubstFormat1 {\n\tformat: 1;\n\tcoverage: Coverage;\n\truleSets: (ContextRule[] | null)[];\n}\n\nexport interface ContextRule {\n\tglyphCount: uint16;\n\tinputSequence: GlyphId[]; // Excludes first glyph (in coverage)\n\tlookupRecords: SequenceLookupRecord[];\n}\n\n/** Format 2: Class-based contexts */\nexport interface ContextSubstFormat2 {\n\tformat: 2;\n\tcoverage: Coverage;\n\tclassDef: ClassDef;\n\tclassRuleSets: (ClassRule[] | null)[];\n}\n\nexport interface ClassRule {\n\tglyphCount: uint16;\n\tinputClasses: uint16[]; // Excludes first class\n\tlookupRecords: SequenceLookupRecord[];\n}\n\n/** Format 3: Coverage-based contexts */\nexport interface ContextSubstFormat3 {\n\tformat: 3;\n\tcoverages: Coverage[];\n\tlookupRecords: SequenceLookupRecord[];\n}\n\n/** Chaining context substitution lookup (Type 6) */\nexport interface ChainingContextSubstLookup extends GsubLookup {\n\ttype: 6;\n\tsubtables: ChainingContextSubstSubtable[];\n}\n\nexport type ChainingContextSubstSubtable =\n\t| ChainingContextFormat1\n\t| ChainingContextFormat2\n\t| ChainingContextFormat3;\n\n/** Format 1: Simple chaining context */\nexport interface ChainingContextFormat1 {\n\tformat: 1;\n\tcoverage: Coverage;\n\tchainRuleSets: (ChainRule[] | null)[];\n}\n\nexport interface ChainRule {\n\tbacktrackSequence: GlyphId[];\n\tinputSequence: GlyphId[]; // Excludes first glyph\n\tlookaheadSequence: GlyphId[];\n\tlookupRecords: SequenceLookupRecord[];\n}\n\n/** Format 2: Class-based chaining context */\nexport interface ChainingContextFormat2 {\n\tformat: 2;\n\tcoverage: Coverage;\n\tbacktrackClassDef: ClassDef;\n\tinputClassDef: ClassDef;\n\tlookaheadClassDef: ClassDef;\n\tchainClassRuleSets: (ChainClassRule[] | null)[];\n}\n\nexport interface ChainClassRule {\n\tbacktrackClasses: uint16[];\n\tinputClasses: uint16[]; // Excludes first class\n\tlookaheadClasses: uint16[];\n\tlookupRecords: SequenceLookupRecord[];\n}\n\n/** Format 3: Coverage-based chaining context */\nexport interface ChainingContextFormat3 {\n\tformat: 3;\n\tbacktrackCoverages: Coverage[];\n\tinputCoverages: Coverage[];\n\tlookaheadCoverages: Coverage[];\n\tlookupRecords: SequenceLookupRecord[];\n}\n\nexport function parseContextSubst(\n\treader: Reader,\n\tsubtableOffsets: number[],\n): ContextSubstSubtable[] {\n\tconst subtables: ContextSubstSubtable[] = [];\n\n\tfor (const offset of subtableOffsets) {\n\t\tconst r = reader.sliceFrom(offset);\n\t\tconst format = r.uint16();\n\n\t\tswitch (format) {\n\t\t\tcase 1:\n\t\t\t\tsubtables.push(parseContextFormat1(r));\n\t\t\t\tbreak;\n\t\t\tcase 2:\n\t\t\t\tsubtables.push(parseContextFormat2(r));\n\t\t\t\tbreak;\n\t\t\tcase 3:\n\t\t\t\tsubtables.push(parseContextFormat3(r));\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn subtables;\n}\n\nfunction parseContextFormat1(reader: Reader): ContextSubstFormat1 {\n\tconst coverageOffset = reader.offset16();\n\tconst ruleSetCount = reader.uint16();\n\tconst ruleSetOffsets = reader.uint16Array(ruleSetCount);\n\n\tconst coverage = parseCoverageAt(reader, coverageOffset);\n\tconst ruleSets: (ContextRule[] | null)[] = [];\n\n\tfor (const ruleSetOffset of ruleSetOffsets) {\n\t\tif (ruleSetOffset === 0) {\n\t\t\truleSets.push(null);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst rsReader = reader.sliceFrom(ruleSetOffset);\n\t\tconst ruleCount = rsReader.uint16();\n\t\tconst ruleOffsets = rsReader.uint16Array(ruleCount);\n\n\t\tconst rules: ContextRule[] = [];\n\t\tfor (const ruleOffset of ruleOffsets) {\n\t\t\tconst ruleReader = rsReader.sliceFrom(ruleOffset);\n\t\t\tconst glyphCount = ruleReader.uint16();\n\t\t\tconst lookupCount = ruleReader.uint16();\n\t\t\tconst inputSequence = Array.from(ruleReader.uint16Array(glyphCount - 1));\n\t\t\tconst lookupRecords = parseLookupRecords(ruleReader, lookupCount);\n\n\t\t\trules.push({ glyphCount, inputSequence, lookupRecords });\n\t\t}\n\n\t\truleSets.push(rules);\n\t}\n\n\treturn { format: 1, coverage, ruleSets };\n}\n\nfunction parseContextFormat2(reader: Reader): ContextSubstFormat2 {\n\tconst coverageOffset = reader.offset16();\n\tconst classDefOffset = reader.offset16();\n\tconst classRuleSetCount = reader.uint16();\n\tconst classRuleSetOffsets = reader.uint16Array(classRuleSetCount);\n\n\tconst coverage = parseCoverageAt(reader, coverageOffset);\n\tconst classDef = parseClassDefAt(reader, classDefOffset);\n\tconst classRuleSets: (ClassRule[] | null)[] = [];\n\n\tfor (const crsOffset of classRuleSetOffsets) {\n\t\tif (crsOffset === 0) {\n\t\t\tclassRuleSets.push(null);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst crsReader = reader.sliceFrom(crsOffset);\n\t\tconst ruleCount = crsReader.uint16();\n\t\tconst ruleOffsets = crsReader.uint16Array(ruleCount);\n\n\t\tconst rules: ClassRule[] = [];\n\t\tfor (const ruleOffset of ruleOffsets) {\n\t\t\tconst ruleReader = crsReader.sliceFrom(ruleOffset);\n\t\t\tconst glyphCount = ruleReader.uint16();\n\t\t\tconst lookupCount = ruleReader.uint16();\n\t\t\tconst inputClasses = Array.from(ruleReader.uint16Array(glyphCount - 1));\n\t\t\tconst lookupRecords = parseLookupRecords(ruleReader, lookupCount);\n\n\t\t\trules.push({ glyphCount, inputClasses, lookupRecords });\n\t\t}\n\n\t\tclassRuleSets.push(rules);\n\t}\n\n\treturn { format: 2, coverage, classDef, classRuleSets };\n}\n\nfunction parseContextFormat3(reader: Reader): ContextSubstFormat3 {\n\tconst glyphCount = reader.uint16();\n\tconst lookupCount = reader.uint16();\n\tconst coverageOffsets = reader.uint16Array(glyphCount);\n\n\tconst coverages: Coverage[] = [];\n\tfor (const offset of coverageOffsets) {\n\t\tcoverages.push(parseCoverageAt(reader, offset));\n\t}\n\n\tconst lookupRecords = parseLookupRecords(reader, lookupCount);\n\n\treturn { format: 3, coverages, lookupRecords };\n}\n\nexport function parseChainingContextSubst(\n\treader: Reader,\n\tsubtableOffsets: number[],\n): ChainingContextSubstSubtable[] {\n\tconst subtables: ChainingContextSubstSubtable[] = [];\n\n\tfor (const offset of subtableOffsets) {\n\t\tconst r = reader.sliceFrom(offset);\n\t\tconst format = r.uint16();\n\n\t\tswitch (format) {\n\t\t\tcase 1:\n\t\t\t\tsubtables.push(parseChainingFormat1(r));\n\t\t\t\tbreak;\n\t\t\tcase 2:\n\t\t\t\tsubtables.push(parseChainingFormat2(r));\n\t\t\t\tbreak;\n\t\t\tcase 3:\n\t\t\t\tsubtables.push(parseChainingFormat3(r));\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn subtables;\n}\n\nfunction parseChainingFormat1(reader: Reader): ChainingContextFormat1 {\n\tconst coverageOffset = reader.offset16();\n\tconst chainRuleSetCount = reader.uint16();\n\tconst chainRuleSetOffsets = reader.uint16Array(chainRuleSetCount);\n\n\tconst coverage = parseCoverageAt(reader, coverageOffset);\n\tconst chainRuleSets: (ChainRule[] | null)[] = [];\n\n\tfor (const crsOffset of chainRuleSetOffsets) {\n\t\tif (crsOffset === 0) {\n\t\t\tchainRuleSets.push(null);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst crsReader = reader.sliceFrom(crsOffset);\n\t\tconst ruleCount = crsReader.uint16();\n\t\tconst ruleOffsets = crsReader.uint16Array(ruleCount);\n\n\t\tconst rules: ChainRule[] = [];\n\t\tfor (const ruleOffset of ruleOffsets) {\n\t\t\tconst ruleReader = crsReader.sliceFrom(ruleOffset);\n\n\t\t\tconst backtrackCount = ruleReader.uint16();\n\t\t\tconst backtrackSequence = Array.from(\n\t\t\t\truleReader.uint16Array(backtrackCount),\n\t\t\t);\n\n\t\t\tconst inputCount = ruleReader.uint16();\n\t\t\tconst inputSequence = Array.from(ruleReader.uint16Array(inputCount - 1));\n\n\t\t\tconst lookaheadCount = ruleReader.uint16();\n\t\t\tconst lookaheadSequence = Array.from(\n\t\t\t\truleReader.uint16Array(lookaheadCount),\n\t\t\t);\n\n\t\t\tconst lookupCount = ruleReader.uint16();\n\t\t\tconst lookupRecords = parseLookupRecords(ruleReader, lookupCount);\n\n\t\t\trules.push({\n\t\t\t\tbacktrackSequence,\n\t\t\t\tinputSequence,\n\t\t\t\tlookaheadSequence,\n\t\t\t\tlookupRecords,\n\t\t\t});\n\t\t}\n\n\t\tchainRuleSets.push(rules);\n\t}\n\n\treturn { format: 1, coverage, chainRuleSets };\n}\n\nfunction parseChainingFormat2(reader: Reader): ChainingContextFormat2 {\n\tconst coverageOffset = reader.offset16();\n\tconst backtrackClassDefOffset = reader.offset16();\n\tconst inputClassDefOffset = reader.offset16();\n\tconst lookaheadClassDefOffset = reader.offset16();\n\tconst chainClassRuleSetCount = reader.uint16();\n\tconst chainClassRuleSetOffsets = reader.uint16Array(chainClassRuleSetCount);\n\n\tconst coverage = parseCoverageAt(reader, coverageOffset);\n\tconst backtrackClassDef = parseClassDefAt(reader, backtrackClassDefOffset);\n\tconst inputClassDef = parseClassDefAt(reader, inputClassDefOffset);\n\tconst lookaheadClassDef = parseClassDefAt(reader, lookaheadClassDefOffset);\n\n\tconst chainClassRuleSets: (ChainClassRule[] | null)[] = [];\n\n\tfor (const ccrsOffset of chainClassRuleSetOffsets) {\n\t\tif (ccrsOffset === 0) {\n\t\t\tchainClassRuleSets.push(null);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst ccrsReader = reader.sliceFrom(ccrsOffset);\n\t\tconst ruleCount = ccrsReader.uint16();\n\t\tconst ruleOffsets = ccrsReader.uint16Array(ruleCount);\n\n\t\tconst rules: ChainClassRule[] = [];\n\t\tfor (const ruleOffset of ruleOffsets) {\n\t\t\tconst ruleReader = ccrsReader.sliceFrom(ruleOffset);\n\n\t\t\tconst backtrackCount = ruleReader.uint16();\n\t\t\tconst backtrackClasses = Array.from(\n\t\t\t\truleReader.uint16Array(backtrackCount),\n\t\t\t);\n\n\t\t\tconst inputCount = ruleReader.uint16();\n\t\t\tconst inputClasses = Array.from(ruleReader.uint16Array(inputCount - 1));\n\n\t\t\tconst lookaheadCount = ruleReader.uint16();\n\t\t\tconst lookaheadClasses = Array.from(\n\t\t\t\truleReader.uint16Array(lookaheadCount),\n\t\t\t);\n\n\t\t\tconst lookupCount = ruleReader.uint16();\n\t\t\tconst lookupRecords = parseLookupRecords(ruleReader, lookupCount);\n\n\t\t\trules.push({\n\t\t\t\tbacktrackClasses,\n\t\t\t\tinputClasses,\n\t\t\t\tlookaheadClasses,\n\t\t\t\tlookupRecords,\n\t\t\t});\n\t\t}\n\n\t\tchainClassRuleSets.push(rules);\n\t}\n\n\treturn {\n\t\tformat: 2,\n\t\tcoverage,\n\t\tbacktrackClassDef,\n\t\tinputClassDef,\n\t\tlookaheadClassDef,\n\t\tchainClassRuleSets,\n\t};\n}\n\nfunction parseChainingFormat3(reader: Reader): ChainingContextFormat3 {\n\tconst backtrackCount = reader.uint16();\n\tconst backtrackCoverageOffsets = reader.uint16Array(backtrackCount);\n\n\tconst inputCount = reader.uint16();\n\tconst inputCoverageOffsets = reader.uint16Array(inputCount);\n\n\tconst lookaheadCount = reader.uint16();\n\tconst lookaheadCoverageOffsets = reader.uint16Array(lookaheadCount);\n\n\tconst lookupCount = reader.uint16();\n\tconst lookupRecords = parseLookupRecords(reader, lookupCount);\n\n\tconst backtrackCoverages: Coverage[] = [];\n\tfor (const offset of backtrackCoverageOffsets) {\n\t\tbacktrackCoverages.push(parseCoverageAt(reader, offset));\n\t}\n\n\tconst inputCoverages: Coverage[] = [];\n\tfor (const offset of inputCoverageOffsets) {\n\t\tinputCoverages.push(parseCoverageAt(reader, offset));\n\t}\n\n\tconst lookaheadCoverages: Coverage[] = [];\n\tfor (const offset of lookaheadCoverageOffsets) {\n\t\tlookaheadCoverages.push(parseCoverageAt(reader, offset));\n\t}\n\n\treturn {\n\t\tformat: 3,\n\t\tbacktrackCoverages,\n\t\tinputCoverages,\n\t\tlookaheadCoverages,\n\t\tlookupRecords,\n\t};\n}\n\nfunction parseLookupRecords(\n\treader: Reader,\n\tcount: number,\n): SequenceLookupRecord[] {\n\tconst records: SequenceLookupRecord[] = [];\n\tfor (let i = 0; i < count; i++) {\n\t\trecords.push({\n\t\t\tsequenceIndex: reader.uint16(),\n\t\t\tlookupListIndex: reader.uint16(),\n\t\t});\n\t}\n\treturn records;\n}\n",
42
- "import {\n\ttype Coverage,\n\tparseCoverageAt,\n} from \"../../layout/structures/coverage.ts\";\nimport {\n\ttype FeatureList,\n\tLookupFlag,\n\tparseFeatureList,\n\tparseScriptList,\n\ttype ScriptList,\n} from \"../../layout/structures/layout-common.ts\";\nimport type { GlyphId, uint16 } from \"../../types.ts\";\nimport type { Reader } from \"../binary/reader.ts\";\nimport {\n\ttype ChainingContextSubstSubtable,\n\ttype ContextSubstSubtable,\n\tparseChainingContextSubst,\n\tparseContextSubst,\n} from \"./gsub-contextual.ts\";\n\n/** GSUB lookup types */\nexport enum GsubLookupType {\n\tSingle = 1,\n\tMultiple = 2,\n\tAlternate = 3,\n\tLigature = 4,\n\tContext = 5,\n\tChainingContext = 6,\n\tExtension = 7,\n\tReverseChainingSingle = 8,\n}\n\n/** Base interface for all GSUB lookups */\nexport interface GsubLookup {\n\ttype: GsubLookupType;\n\tflag: uint16;\n\tmarkFilteringSet?: uint16;\n}\n\n/** Single substitution lookup (Type 1) */\nexport interface SingleSubstLookup extends GsubLookup {\n\ttype: GsubLookupType.Single;\n\tsubtables: SingleSubstSubtable[];\n}\n\nexport interface SingleSubstSubtable {\n\tformat: 1 | 2;\n\tcoverage: Coverage;\n\tdeltaGlyphId?: number;\n\tsubstituteGlyphIds?: GlyphId[];\n}\n\n/** Multiple substitution lookup (Type 2) */\nexport interface MultipleSubstLookup extends GsubLookup {\n\ttype: GsubLookupType.Multiple;\n\tsubtables: MultipleSubstSubtable[];\n}\n\nexport interface MultipleSubstSubtable {\n\tcoverage: Coverage;\n\tsequences: GlyphId[][];\n}\n\n/** Alternate substitution lookup (Type 3) */\nexport interface AlternateSubstLookup extends GsubLookup {\n\ttype: GsubLookupType.Alternate;\n\tsubtables: AlternateSubstSubtable[];\n}\n\nexport interface AlternateSubstSubtable {\n\tcoverage: Coverage;\n\talternateSets: GlyphId[][];\n}\n\n/** Ligature substitution lookup (Type 4) */\nexport interface LigatureSubstLookup extends GsubLookup {\n\ttype: GsubLookupType.Ligature;\n\tsubtables: LigatureSubstSubtable[];\n}\n\nexport interface LigatureSubstSubtable {\n\tcoverage: Coverage;\n\tligatureSets: LigatureSet[];\n}\n\nexport interface LigatureSet {\n\tligatures: Ligature[];\n}\n\nexport interface Ligature {\n\tligatureGlyph: GlyphId;\n\tcomponentGlyphIds: GlyphId[];\n}\n\n/** Context substitution lookup (Type 5) */\nexport interface ContextSubstLookup extends GsubLookup {\n\ttype: GsubLookupType.Context;\n\tsubtables: ContextSubstSubtable[];\n}\n\n/** Chaining context substitution lookup (Type 6) */\nexport interface ChainingContextSubstLookup extends GsubLookup {\n\ttype: GsubLookupType.ChainingContext;\n\tsubtables: ChainingContextSubstSubtable[];\n}\n\n/** Reverse chaining single substitution lookup (Type 8) */\nexport interface ReverseChainingSingleSubstLookup extends GsubLookup {\n\ttype: GsubLookupType.ReverseChainingSingle;\n\tsubtables: ReverseChainingSingleSubstSubtable[];\n}\n\nexport interface ReverseChainingSingleSubstSubtable {\n\tcoverage: Coverage;\n\tbacktrackCoverages: Coverage[];\n\tlookaheadCoverages: Coverage[];\n\tsubstituteGlyphIds: GlyphId[];\n}\n\n/** Union of all GSUB lookup types */\nexport type AnyGsubLookup =\n\t| SingleSubstLookup\n\t| MultipleSubstLookup\n\t| AlternateSubstLookup\n\t| LigatureSubstLookup\n\t| ContextSubstLookup\n\t| ChainingContextSubstLookup\n\t| ReverseChainingSingleSubstLookup;\n\n/** GSUB table */\nexport interface GsubTable {\n\tversion: { major: number; minor: number };\n\tscriptList: ScriptList;\n\tfeatureList: FeatureList;\n\tlookups: AnyGsubLookup[];\n}\n\n// Re-export for use in shaper\nexport type { SequenceLookupRecord } from \"./gsub-contextual.ts\";\n\nexport function parseGsub(reader: Reader): GsubTable {\n\tconst majorVersion = reader.uint16();\n\tconst minorVersion = reader.uint16();\n\n\tconst scriptListOffset = reader.offset16();\n\tconst featureListOffset = reader.offset16();\n\tconst lookupListOffset = reader.offset16();\n\n\tif (majorVersion === 1 && minorVersion >= 1) {\n\t\treader.offset32(); // featureVariationsOffset\n\t}\n\n\tconst scriptList = parseScriptList(reader.sliceFrom(scriptListOffset));\n\tconst featureList = parseFeatureList(reader.sliceFrom(featureListOffset));\n\n\tconst lookupListReader = reader.sliceFrom(lookupListOffset);\n\tconst lookupCount = lookupListReader.uint16();\n\tconst lookupOffsets = lookupListReader.uint16Array(lookupCount);\n\n\tconst lookups: AnyGsubLookup[] = [];\n\tfor (const lookupOffset of lookupOffsets) {\n\t\tconst lookupReader = lookupListReader.sliceFrom(lookupOffset);\n\t\tconst lookup = parseGsubLookup(\n\t\t\tlookupReader,\n\t\t\tlookupListReader,\n\t\t\tlookupOffset,\n\t\t);\n\t\tif (lookup) {\n\t\t\tlookups.push(lookup);\n\t\t}\n\t}\n\n\treturn {\n\t\tversion: { major: majorVersion, minor: minorVersion },\n\t\tscriptList,\n\t\tfeatureList,\n\t\tlookups,\n\t};\n}\n\nfunction parseGsubLookup(\n\treader: Reader,\n\t_lookupListReader: Reader,\n\t_lookupOffset: number,\n): AnyGsubLookup | null {\n\tconst lookupType = reader.uint16();\n\tconst lookupFlag = reader.uint16();\n\tconst subtableCount = reader.uint16();\n\tconst subtableOffsets = Array.from(reader.uint16Array(subtableCount));\n\n\tlet markFilteringSet: uint16 | undefined;\n\tif (lookupFlag & LookupFlag.UseMarkFilteringSet) {\n\t\tmarkFilteringSet = reader.uint16();\n\t}\n\n\tconst baseProps = { flag: lookupFlag, markFilteringSet };\n\n\tswitch (lookupType) {\n\t\tcase GsubLookupType.Single:\n\t\t\treturn {\n\t\t\t\ttype: GsubLookupType.Single,\n\t\t\t\t...baseProps,\n\t\t\t\tsubtables: parseSingleSubst(reader, subtableOffsets),\n\t\t\t};\n\n\t\tcase GsubLookupType.Multiple:\n\t\t\treturn {\n\t\t\t\ttype: GsubLookupType.Multiple,\n\t\t\t\t...baseProps,\n\t\t\t\tsubtables: parseMultipleSubst(reader, subtableOffsets),\n\t\t\t};\n\n\t\tcase GsubLookupType.Alternate:\n\t\t\treturn {\n\t\t\t\ttype: GsubLookupType.Alternate,\n\t\t\t\t...baseProps,\n\t\t\t\tsubtables: parseAlternateSubst(reader, subtableOffsets),\n\t\t\t};\n\n\t\tcase GsubLookupType.Ligature:\n\t\t\treturn {\n\t\t\t\ttype: GsubLookupType.Ligature,\n\t\t\t\t...baseProps,\n\t\t\t\tsubtables: parseLigatureSubst(reader, subtableOffsets),\n\t\t\t};\n\n\t\tcase GsubLookupType.Context:\n\t\t\treturn {\n\t\t\t\ttype: GsubLookupType.Context,\n\t\t\t\t...baseProps,\n\t\t\t\tsubtables: parseContextSubst(reader, subtableOffsets),\n\t\t\t};\n\n\t\tcase GsubLookupType.ChainingContext:\n\t\t\treturn {\n\t\t\t\ttype: GsubLookupType.ChainingContext,\n\t\t\t\t...baseProps,\n\t\t\t\tsubtables: parseChainingContextSubst(reader, subtableOffsets),\n\t\t\t};\n\n\t\tcase GsubLookupType.Extension:\n\t\t\treturn parseExtensionLookup(reader, subtableOffsets, baseProps);\n\n\t\tcase GsubLookupType.ReverseChainingSingle:\n\t\t\treturn {\n\t\t\t\ttype: GsubLookupType.ReverseChainingSingle,\n\t\t\t\t...baseProps,\n\t\t\t\tsubtables: parseReverseChainingSingleSubst(reader, subtableOffsets),\n\t\t\t};\n\n\t\tdefault:\n\t\t\treturn null;\n\t}\n}\n\nfunction parseSingleSubst(\n\treader: Reader,\n\tsubtableOffsets: number[],\n): SingleSubstSubtable[] {\n\tconst subtables: SingleSubstSubtable[] = [];\n\n\tfor (const offset of subtableOffsets) {\n\t\tconst r = reader.sliceFrom(offset);\n\t\tconst format = r.uint16();\n\n\t\tif (format === 1) {\n\t\t\tconst coverageOffset = r.offset16();\n\t\t\tconst deltaGlyphId = r.int16();\n\t\t\tconst coverage = parseCoverageAt(r, coverageOffset);\n\t\t\tsubtables.push({ format: 1, coverage, deltaGlyphId });\n\t\t} else if (format === 2) {\n\t\t\tconst coverageOffset = r.offset16();\n\t\t\tconst glyphCount = r.uint16();\n\t\t\tconst substituteGlyphIds = Array.from(r.uint16Array(glyphCount));\n\t\t\tconst coverage = parseCoverageAt(r, coverageOffset);\n\t\t\tsubtables.push({ format: 2, coverage, substituteGlyphIds });\n\t\t}\n\t}\n\n\treturn subtables;\n}\n\nfunction parseMultipleSubst(\n\treader: Reader,\n\tsubtableOffsets: number[],\n): MultipleSubstSubtable[] {\n\tconst subtables: MultipleSubstSubtable[] = [];\n\n\tfor (const offset of subtableOffsets) {\n\t\tconst r = reader.sliceFrom(offset);\n\t\tconst format = r.uint16();\n\n\t\tif (format === 1) {\n\t\t\tconst coverageOffset = r.offset16();\n\t\t\tconst sequenceCount = r.uint16();\n\t\t\tconst sequenceOffsets = r.uint16Array(sequenceCount);\n\n\t\t\tconst coverage = parseCoverageAt(r, coverageOffset);\n\t\t\tconst sequences: GlyphId[][] = [];\n\n\t\t\tfor (const seqOffset of sequenceOffsets) {\n\t\t\t\tconst seqReader = r.sliceFrom(seqOffset);\n\t\t\t\tconst glyphCount = seqReader.uint16();\n\t\t\t\tsequences.push(Array.from(seqReader.uint16Array(glyphCount)));\n\t\t\t}\n\n\t\t\tsubtables.push({ coverage, sequences });\n\t\t}\n\t}\n\n\treturn subtables;\n}\n\nfunction parseAlternateSubst(\n\treader: Reader,\n\tsubtableOffsets: number[],\n): AlternateSubstSubtable[] {\n\tconst subtables: AlternateSubstSubtable[] = [];\n\n\tfor (const offset of subtableOffsets) {\n\t\tconst r = reader.sliceFrom(offset);\n\t\tconst format = r.uint16();\n\n\t\tif (format === 1) {\n\t\t\tconst coverageOffset = r.offset16();\n\t\t\tconst alternateSetCount = r.uint16();\n\t\t\tconst alternateSetOffsets = r.uint16Array(alternateSetCount);\n\n\t\t\tconst coverage = parseCoverageAt(r, coverageOffset);\n\t\t\tconst alternateSets: GlyphId[][] = [];\n\n\t\t\tfor (const altOffset of alternateSetOffsets) {\n\t\t\t\tconst altReader = r.sliceFrom(altOffset);\n\t\t\t\tconst glyphCount = altReader.uint16();\n\t\t\t\talternateSets.push(Array.from(altReader.uint16Array(glyphCount)));\n\t\t\t}\n\n\t\t\tsubtables.push({ coverage, alternateSets });\n\t\t}\n\t}\n\n\treturn subtables;\n}\n\nfunction parseLigatureSubst(\n\treader: Reader,\n\tsubtableOffsets: number[],\n): LigatureSubstSubtable[] {\n\tconst subtables: LigatureSubstSubtable[] = [];\n\n\tfor (const offset of subtableOffsets) {\n\t\tconst r = reader.sliceFrom(offset);\n\t\tconst format = r.uint16();\n\n\t\tif (format === 1) {\n\t\t\tconst coverageOffset = r.offset16();\n\t\t\tconst ligatureSetCount = r.uint16();\n\t\t\tconst ligatureSetOffsets = r.uint16Array(ligatureSetCount);\n\n\t\t\tconst coverage = parseCoverageAt(r, coverageOffset);\n\t\t\tconst ligatureSets: LigatureSet[] = [];\n\n\t\t\tfor (const setOffset of ligatureSetOffsets) {\n\t\t\t\tconst setReader = r.sliceFrom(setOffset);\n\t\t\t\tconst ligatureCount = setReader.uint16();\n\t\t\t\tconst ligatureOffsets = setReader.uint16Array(ligatureCount);\n\n\t\t\t\tconst ligatures: Ligature[] = [];\n\t\t\t\tfor (const ligOffset of ligatureOffsets) {\n\t\t\t\t\tconst ligReader = setReader.sliceFrom(ligOffset);\n\t\t\t\t\tconst ligatureGlyph = ligReader.uint16();\n\t\t\t\t\tconst componentCount = ligReader.uint16();\n\t\t\t\t\tconst componentGlyphIds = Array.from(\n\t\t\t\t\t\tligReader.uint16Array(componentCount - 1),\n\t\t\t\t\t);\n\t\t\t\t\tligatures.push({ ligatureGlyph, componentGlyphIds });\n\t\t\t\t}\n\n\t\t\t\tligatureSets.push({ ligatures });\n\t\t\t}\n\n\t\t\tsubtables.push({ coverage, ligatureSets });\n\t\t}\n\t}\n\n\treturn subtables;\n}\n\nfunction parseReverseChainingSingleSubst(\n\treader: Reader,\n\tsubtableOffsets: number[],\n): ReverseChainingSingleSubstSubtable[] {\n\tconst subtables: ReverseChainingSingleSubstSubtable[] = [];\n\n\tfor (const offset of subtableOffsets) {\n\t\tconst r = reader.sliceFrom(offset);\n\t\tconst format = r.uint16();\n\n\t\tif (format === 1) {\n\t\t\tconst coverageOffset = r.offset16();\n\n\t\t\tconst backtrackCount = r.uint16();\n\t\t\tconst backtrackCoverageOffsets = r.uint16Array(backtrackCount);\n\n\t\t\tconst lookaheadCount = r.uint16();\n\t\t\tconst lookaheadCoverageOffsets = r.uint16Array(lookaheadCount);\n\n\t\t\tconst glyphCount = r.uint16();\n\t\t\tconst substituteGlyphIds = Array.from(r.uint16Array(glyphCount));\n\n\t\t\tconst coverage = parseCoverageAt(r, coverageOffset);\n\n\t\t\tconst backtrackCoverages: Coverage[] = [];\n\t\t\tfor (const covOffset of backtrackCoverageOffsets) {\n\t\t\t\tbacktrackCoverages.push(parseCoverageAt(r, covOffset));\n\t\t\t}\n\n\t\t\tconst lookaheadCoverages: Coverage[] = [];\n\t\t\tfor (const covOffset of lookaheadCoverageOffsets) {\n\t\t\t\tlookaheadCoverages.push(parseCoverageAt(r, covOffset));\n\t\t\t}\n\n\t\t\tsubtables.push({\n\t\t\t\tcoverage,\n\t\t\t\tbacktrackCoverages,\n\t\t\t\tlookaheadCoverages,\n\t\t\t\tsubstituteGlyphIds,\n\t\t\t});\n\t\t}\n\t}\n\n\treturn subtables;\n}\n\nfunction parseExtensionLookup(\n\treader: Reader,\n\tsubtableOffsets: number[],\n\tbaseProps: { flag: uint16; markFilteringSet?: uint16 },\n): AnyGsubLookup | null {\n\tif (subtableOffsets.length === 0) return null;\n\n\t// Parse all extension subtables\n\tconst extSubtables: Array<{ type: number; reader: Reader }> = [];\n\n\tfor (const offset of subtableOffsets) {\n\t\tconst extReader = reader.sliceFrom(offset);\n\t\tconst format = extReader.uint16();\n\t\tif (format !== 1) continue;\n\n\t\tconst extensionLookupType = extReader.uint16();\n\t\tconst extensionOffset = extReader.uint32();\n\n\t\t// extensionOffset is relative to start of extension subtable\n\t\textSubtables.push({\n\t\t\ttype: extensionLookupType,\n\t\t\treader: extReader.sliceFrom(extensionOffset),\n\t\t});\n\t}\n\n\tif (extSubtables.length === 0) return null;\n\n\tconst actualType = extSubtables[0]?.type;\n\tconst _actualOffsets = extSubtables.map((_, _i) => 0); // All at offset 0 of their readers\n\n\t// Create a combined reader for all subtables\n\tswitch (actualType) {\n\t\tcase GsubLookupType.Single: {\n\t\t\tconst subtables: SingleSubstSubtable[] = [];\n\t\t\tfor (const ext of extSubtables) {\n\t\t\t\tsubtables.push(...parseSingleSubst(ext.reader, [0]));\n\t\t\t}\n\t\t\treturn { type: GsubLookupType.Single, ...baseProps, subtables };\n\t\t}\n\n\t\tcase GsubLookupType.Multiple: {\n\t\t\tconst subtables: MultipleSubstSubtable[] = [];\n\t\t\tfor (const ext of extSubtables) {\n\t\t\t\tsubtables.push(...parseMultipleSubst(ext.reader, [0]));\n\t\t\t}\n\t\t\treturn { type: GsubLookupType.Multiple, ...baseProps, subtables };\n\t\t}\n\n\t\tcase GsubLookupType.Alternate: {\n\t\t\tconst subtables: AlternateSubstSubtable[] = [];\n\t\t\tfor (const ext of extSubtables) {\n\t\t\t\tsubtables.push(...parseAlternateSubst(ext.reader, [0]));\n\t\t\t}\n\t\t\treturn { type: GsubLookupType.Alternate, ...baseProps, subtables };\n\t\t}\n\n\t\tcase GsubLookupType.Ligature: {\n\t\t\tconst subtables: LigatureSubstSubtable[] = [];\n\t\t\tfor (const ext of extSubtables) {\n\t\t\t\tsubtables.push(...parseLigatureSubst(ext.reader, [0]));\n\t\t\t}\n\t\t\treturn { type: GsubLookupType.Ligature, ...baseProps, subtables };\n\t\t}\n\n\t\tcase GsubLookupType.Context: {\n\t\t\tconst subtables: ContextSubstSubtable[] = [];\n\t\t\tfor (const ext of extSubtables) {\n\t\t\t\tsubtables.push(...parseContextSubst(ext.reader, [0]));\n\t\t\t}\n\t\t\treturn { type: GsubLookupType.Context, ...baseProps, subtables };\n\t\t}\n\n\t\tcase GsubLookupType.ChainingContext: {\n\t\t\tconst subtables: ChainingContextSubstSubtable[] = [];\n\t\t\tfor (const ext of extSubtables) {\n\t\t\t\tsubtables.push(...parseChainingContextSubst(ext.reader, [0]));\n\t\t\t}\n\t\t\treturn { type: GsubLookupType.ChainingContext, ...baseProps, subtables };\n\t\t}\n\n\t\tcase GsubLookupType.ReverseChainingSingle: {\n\t\t\tconst subtables: ReverseChainingSingleSubstSubtable[] = [];\n\t\t\tfor (const ext of extSubtables) {\n\t\t\t\tsubtables.push(...parseReverseChainingSingleSubst(ext.reader, [0]));\n\t\t\t}\n\t\t\treturn {\n\t\t\t\ttype: GsubLookupType.ReverseChainingSingle,\n\t\t\t\t...baseProps,\n\t\t\t\tsubtables,\n\t\t\t};\n\t\t}\n\n\t\tdefault:\n\t\t\treturn null;\n\t}\n}\n\n// Utility functions for applying lookups\n\nexport function applySingleSubst(\n\tlookup: SingleSubstLookup,\n\tglyphId: GlyphId,\n): GlyphId | null {\n\tfor (const subtable of lookup.subtables) {\n\t\tconst coverageIndex = subtable.coverage.get(glyphId);\n\t\tif (coverageIndex === null) continue;\n\n\t\tif (subtable.format === 1 && subtable.deltaGlyphId !== undefined) {\n\t\t\treturn (glyphId + subtable.deltaGlyphId) & 0xffff;\n\t\t}\n\n\t\tif (subtable.format === 2 && subtable.substituteGlyphIds) {\n\t\t\treturn subtable.substituteGlyphIds[coverageIndex] ?? null;\n\t\t}\n\t}\n\n\treturn null;\n}\n\nexport function applyLigatureSubst(\n\tlookup: LigatureSubstLookup,\n\tglyphIds: GlyphId[],\n\tstartIndex: number,\n): { ligatureGlyph: GlyphId; consumed: number } | null {\n\tconst firstGlyph = glyphIds[startIndex];\n\tif (firstGlyph === undefined) return null;\n\n\tfor (const subtable of lookup.subtables) {\n\t\tconst coverageIndex = subtable.coverage.get(firstGlyph);\n\t\tif (coverageIndex === null) continue;\n\n\t\tconst ligatureSet = subtable.ligatureSets[coverageIndex];\n\t\tif (!ligatureSet) continue;\n\n\t\tfor (const ligature of ligatureSet.ligatures) {\n\t\t\tconst componentCount = ligature.componentGlyphIds.length;\n\n\t\t\tif (startIndex + 1 + componentCount > glyphIds.length) continue;\n\n\t\t\tlet matches = true;\n\t\t\tfor (let i = 0; i < componentCount; i++) {\n\t\t\t\tif (glyphIds[startIndex + 1 + i] !== ligature.componentGlyphIds[i]) {\n\t\t\t\t\tmatches = false;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (matches) {\n\t\t\t\treturn {\n\t\t\t\t\tligatureGlyph: ligature.ligatureGlyph,\n\t\t\t\t\tconsumed: 1 + componentCount,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t}\n\n\treturn null;\n}\n",
43
- "import type { Fixed, FWord, int16, uint16, uint32 } from \"../../types.ts\";\nimport type { Reader } from \"../binary/reader.ts\";\n\nconst HEAD_MAGIC_NUMBER = 0x5f0f3cf5;\n\n/** Font header table */\nexport interface HeadTable {\n\tmajorVersion: uint16;\n\tminorVersion: uint16;\n\tfontRevision: Fixed;\n\tchecksumAdjustment: uint32;\n\tmagicNumber: uint32;\n\tflags: uint16;\n\tunitsPerEm: uint16;\n\tcreated: bigint;\n\tmodified: bigint;\n\txMin: FWord;\n\tyMin: FWord;\n\txMax: FWord;\n\tyMax: FWord;\n\tmacStyle: uint16;\n\tlowestRecPPEM: uint16;\n\tfontDirectionHint: int16;\n\t/** 0 = short offsets (uint16), 1 = long offsets (uint32) in loca table */\n\tindexToLocFormat: int16;\n\tglyphDataFormat: int16;\n}\n\n/** Head table flags */\nexport const HeadFlags = {\n\tBaselineAtY0: 0x0001,\n\tLeftSidebearingAtX0: 0x0002,\n\tInstructionsDependOnPointSize: 0x0004,\n\tForcePPEMToInteger: 0x0008,\n\tInstructionsAlterAdvanceWidth: 0x0010,\n\tLossless: 0x0800,\n\tConverted: 0x1000,\n\tOptimizedForClearType: 0x2000,\n\tLastResortFont: 0x4000,\n} as const;\n\n/** Mac style flags */\nexport const MacStyle = {\n\tBold: 0x0001,\n\tItalic: 0x0002,\n\tUnderline: 0x0004,\n\tOutline: 0x0008,\n\tShadow: 0x0010,\n\tCondensed: 0x0020,\n\tExtended: 0x0040,\n} as const;\n\nexport function parseHead(reader: Reader): HeadTable {\n\tconst majorVersion = reader.uint16();\n\tconst minorVersion = reader.uint16();\n\tconst fontRevision = reader.fixed();\n\tconst checksumAdjustment = reader.uint32();\n\tconst magicNumber = reader.uint32();\n\n\tif (magicNumber !== HEAD_MAGIC_NUMBER) {\n\t\tthrow new Error(\n\t\t\t`Invalid head table magic number: 0x${magicNumber.toString(16)}`,\n\t\t);\n\t}\n\n\tconst flags = reader.uint16();\n\tconst unitsPerEm = reader.uint16();\n\tconst created = reader.longDateTime();\n\tconst modified = reader.longDateTime();\n\tconst xMin = reader.fword();\n\tconst yMin = reader.fword();\n\tconst xMax = reader.fword();\n\tconst yMax = reader.fword();\n\tconst macStyle = reader.uint16();\n\tconst lowestRecPPEM = reader.uint16();\n\tconst fontDirectionHint = reader.int16();\n\tconst indexToLocFormat = reader.int16();\n\tconst glyphDataFormat = reader.int16();\n\n\treturn {\n\t\tmajorVersion,\n\t\tminorVersion,\n\t\tfontRevision,\n\t\tchecksumAdjustment,\n\t\tmagicNumber,\n\t\tflags,\n\t\tunitsPerEm,\n\t\tcreated,\n\t\tmodified,\n\t\txMin,\n\t\tyMin,\n\t\txMax,\n\t\tyMax,\n\t\tmacStyle,\n\t\tlowestRecPPEM,\n\t\tfontDirectionHint,\n\t\tindexToLocFormat,\n\t\tglyphDataFormat,\n\t};\n}\n",
44
- "import type { FWord, int16, UFWord, uint16 } from \"../../types.ts\";\nimport type { Reader } from \"../binary/reader.ts\";\n\n/** Horizontal header table */\nexport interface HheaTable {\n\tmajorVersion: uint16;\n\tminorVersion: uint16;\n\tascender: FWord;\n\tdescender: FWord;\n\tlineGap: FWord;\n\tadvanceWidthMax: UFWord;\n\tminLeftSideBearing: FWord;\n\tminRightSideBearing: FWord;\n\txMaxExtent: FWord;\n\tcaretSlopeRise: int16;\n\tcaretSlopeRun: int16;\n\tcaretOffset: int16;\n\treserved1: int16;\n\treserved2: int16;\n\treserved3: int16;\n\treserved4: int16;\n\tmetricDataFormat: int16;\n\tnumberOfHMetrics: uint16;\n}\n\nexport function parseHhea(reader: Reader): HheaTable {\n\treturn {\n\t\tmajorVersion: reader.uint16(),\n\t\tminorVersion: reader.uint16(),\n\t\tascender: reader.fword(),\n\t\tdescender: reader.fword(),\n\t\tlineGap: reader.fword(),\n\t\tadvanceWidthMax: reader.ufword(),\n\t\tminLeftSideBearing: reader.fword(),\n\t\tminRightSideBearing: reader.fword(),\n\t\txMaxExtent: reader.fword(),\n\t\tcaretSlopeRise: reader.int16(),\n\t\tcaretSlopeRun: reader.int16(),\n\t\tcaretOffset: reader.int16(),\n\t\treserved1: reader.int16(),\n\t\treserved2: reader.int16(),\n\t\treserved3: reader.int16(),\n\t\treserved4: reader.int16(),\n\t\tmetricDataFormat: reader.int16(),\n\t\tnumberOfHMetrics: reader.uint16(),\n\t};\n}\n",
45
- "import type { Reader } from \"../binary/reader.ts\";\n\n/**\n * fpgm table - Font program\n * Contains TrueType instructions to be executed once when the font is loaded\n */\nexport interface FpgmTable {\n\t/** Raw bytecode instructions */\n\tinstructions: Uint8Array;\n}\n\n/**\n * prep table - CVT program (Control Value Program)\n * Contains TrueType instructions executed whenever the font size or transformation changes\n */\nexport interface PrepTable {\n\t/** Raw bytecode instructions */\n\tinstructions: Uint8Array;\n}\n\n/**\n * cvt table - Control Value Table\n * Contains values referenced by TrueType instructions for consistent spacing/positioning\n * Values are in FUnits (font design units)\n */\nexport interface CvtTable {\n\t/** Control values (FWORD, i.e., int16 in font units) */\n\tvalues: Int16Array;\n}\n\n/**\n * Parse fpgm table\n */\nexport function parseFpgm(reader: Reader): FpgmTable {\n\tconst instructions = reader.bytes(reader.remaining);\n\treturn { instructions };\n}\n\n/**\n * Parse prep table\n */\nexport function parsePrep(reader: Reader): PrepTable {\n\tconst instructions = reader.bytes(reader.remaining);\n\treturn { instructions };\n}\n\n/**\n * Parse cvt table\n */\nexport function parseCvt(reader: Reader): CvtTable {\n\tconst count = Math.floor(reader.remaining / 2);\n\tconst values = new Int16Array(count);\n\tfor (let i = 0; i < count; i++) {\n\t\tvalues[i] = reader.int16();\n\t}\n\treturn { values };\n}\n",
46
- "import type { FWord, GlyphId, UFWord } from \"../../types.ts\";\nimport type { Reader } from \"../binary/reader.ts\";\n\n/** Horizontal metric for a glyph */\nexport interface LongHorMetric {\n\tadvanceWidth: UFWord;\n\tlsb: FWord; // left side bearing\n}\n\n/** Horizontal metrics table */\nexport interface HmtxTable {\n\thMetrics: LongHorMetric[];\n\tleftSideBearings: FWord[];\n}\n\n/**\n * Parse hmtx table.\n * @param reader - Reader positioned at hmtx table start\n * @param numberOfHMetrics - From hhea table\n * @param numGlyphs - From maxp table\n */\nexport function parseHmtx(\n\treader: Reader,\n\tnumberOfHMetrics: number,\n\tnumGlyphs: number,\n): HmtxTable {\n\t// Read full metrics (advanceWidth + lsb)\n\tconst hMetrics: LongHorMetric[] = new Array(numberOfHMetrics);\n\tfor (let i = 0; i < numberOfHMetrics; i++) {\n\t\thMetrics[i] = {\n\t\t\tadvanceWidth: reader.ufword(),\n\t\t\tlsb: reader.fword(),\n\t\t};\n\t}\n\n\t// Remaining glyphs share the last advanceWidth, only store lsb\n\tconst numLeftSideBearings = numGlyphs - numberOfHMetrics;\n\tconst leftSideBearings: FWord[] = new Array(numLeftSideBearings);\n\tfor (let i = 0; i < numLeftSideBearings; i++) {\n\t\tleftSideBearings[i] = reader.fword();\n\t}\n\n\treturn { hMetrics, leftSideBearings };\n}\n\n/** Get advance width for a glyph */\nexport function getAdvanceWidth(hmtx: HmtxTable, glyphId: GlyphId): number {\n\tif (glyphId < hmtx.hMetrics.length) {\n\t\treturn hmtx.hMetrics[glyphId]?.advanceWidth;\n\t}\n\t// Use last advanceWidth for remaining glyphs\n\treturn hmtx.hMetrics[hmtx.hMetrics.length - 1]?.advanceWidth;\n}\n\n/** Get left side bearing for a glyph */\nexport function getLeftSideBearing(hmtx: HmtxTable, glyphId: GlyphId): number {\n\tif (glyphId < hmtx.hMetrics.length) {\n\t\treturn hmtx.hMetrics[glyphId]?.lsb;\n\t}\n\tconst idx = glyphId - hmtx.hMetrics.length;\n\treturn hmtx.leftSideBearings[idx] ?? 0;\n}\n",
47
- "import type { uint16 } from \"../../types.ts\";\nimport type { Reader } from \"../binary/reader.ts\";\n\n/**\n * JSTF table - Justification data\n * Provides justification alternatives for scripts\n */\n\n/** Justification priority levels */\nexport const JstfPriority = {\n\t/** Shrink GPOS lookups */\n\tShrinkGpos: 0,\n\t/** Disable GPOS lookups */\n\tDisableGpos: 1,\n\t/** Shrink GSUB lookups */\n\tShrinkGsub: 2,\n\t/** Disable GSUB lookups */\n\tDisableGsub: 3,\n\t/** Enable GPOS lookups */\n\tEnableGpos: 4,\n\t/** Enable GSUB lookups */\n\tEnableGsub: 5,\n\t/** Max extension GPOS lookups */\n\tMaxExtendGpos: 6,\n\t/** Max extension GSUB lookups */\n\tMaxExtendGsub: 7,\n} as const;\n\n/** JstfMax table - lookup indices for maximum extension */\nexport interface JstfMax {\n\tlookupIndices: uint16[];\n}\n\n/** JstfModList - enable/disable lookup list */\nexport interface JstfModList {\n\tlookupIndices: uint16[];\n}\n\n/** Justification priority record */\nexport interface JstfPriorityRecord {\n\t/** GSUB lookups to enable for shrinkage */\n\tshrinkageEnableGsub: JstfModList | null;\n\t/** GSUB lookups to disable for shrinkage */\n\tshrinkageDisableGsub: JstfModList | null;\n\t/** GPOS lookups to enable for shrinkage */\n\tshrinkageEnableGpos: JstfModList | null;\n\t/** GPOS lookups to disable for shrinkage */\n\tshrinkageDisableGpos: JstfModList | null;\n\t/** Maximum shrinkage GSUB */\n\tshrinkageJstfMax: JstfMax | null;\n\t/** GSUB lookups to enable for extension */\n\textensionEnableGsub: JstfModList | null;\n\t/** GSUB lookups to disable for extension */\n\textensionDisableGsub: JstfModList | null;\n\t/** GPOS lookups to enable for extension */\n\textensionEnableGpos: JstfModList | null;\n\t/** GPOS lookups to disable for extension */\n\textensionDisableGpos: JstfModList | null;\n\t/** Maximum extension GSUB */\n\textensionJstfMax: JstfMax | null;\n}\n\n/** Justification language system */\nexport interface JstfLangSys {\n\tpriorities: JstfPriorityRecord[];\n}\n\n/** Justification script record */\nexport interface JstfScriptRecord {\n\tscriptTag: number;\n\t/** Extender glyphs for Kashida-like justification */\n\textenderGlyphs: uint16[];\n\t/** Default language system */\n\tdefaultLangSys: JstfLangSys | null;\n\t/** Language-specific systems */\n\tlangSysRecords: Map<number, JstfLangSys>;\n}\n\n/** JSTF table */\nexport interface JstfTable {\n\tmajorVersion: uint16;\n\tminorVersion: uint16;\n\tscripts: JstfScriptRecord[];\n}\n\nfunction parseJstfModList(reader: Reader, offset: number): JstfModList | null {\n\tif (offset === 0) return null;\n\n\tconst modReader = reader.sliceFrom(offset);\n\tconst lookupCount = modReader.uint16();\n\tconst lookupIndices: uint16[] = [];\n\n\tfor (let i = 0; i < lookupCount; i++) {\n\t\tlookupIndices.push(modReader.uint16());\n\t}\n\n\treturn { lookupIndices };\n}\n\nfunction parseJstfMax(reader: Reader, offset: number): JstfMax | null {\n\tif (offset === 0) return null;\n\n\tconst maxReader = reader.sliceFrom(offset);\n\tconst lookupCount = maxReader.uint16();\n\tconst lookupIndices: uint16[] = [];\n\n\tfor (let i = 0; i < lookupCount; i++) {\n\t\tlookupIndices.push(maxReader.uint16());\n\t}\n\n\treturn { lookupIndices };\n}\n\nfunction parseJstfPriority(reader: Reader, offset: number): JstfPriorityRecord {\n\tconst priReader = reader.sliceFrom(offset);\n\n\tconst shrinkageEnableGsubOffset = priReader.uint16();\n\tconst shrinkageDisableGsubOffset = priReader.uint16();\n\tconst shrinkageEnableGposOffset = priReader.uint16();\n\tconst shrinkageDisableGposOffset = priReader.uint16();\n\tconst shrinkageJstfMaxOffset = priReader.uint16();\n\tconst extensionEnableGsubOffset = priReader.uint16();\n\tconst extensionDisableGsubOffset = priReader.uint16();\n\tconst extensionEnableGposOffset = priReader.uint16();\n\tconst extensionDisableGposOffset = priReader.uint16();\n\tconst extensionJstfMaxOffset = priReader.uint16();\n\n\treturn {\n\t\tshrinkageEnableGsub: parseJstfModList(\n\t\t\treader,\n\t\t\toffset + shrinkageEnableGsubOffset,\n\t\t),\n\t\tshrinkageDisableGsub: parseJstfModList(\n\t\t\treader,\n\t\t\toffset + shrinkageDisableGsubOffset,\n\t\t),\n\t\tshrinkageEnableGpos: parseJstfModList(\n\t\t\treader,\n\t\t\toffset + shrinkageEnableGposOffset,\n\t\t),\n\t\tshrinkageDisableGpos: parseJstfModList(\n\t\t\treader,\n\t\t\toffset + shrinkageDisableGposOffset,\n\t\t),\n\t\tshrinkageJstfMax: parseJstfMax(reader, offset + shrinkageJstfMaxOffset),\n\t\textensionEnableGsub: parseJstfModList(\n\t\t\treader,\n\t\t\toffset + extensionEnableGsubOffset,\n\t\t),\n\t\textensionDisableGsub: parseJstfModList(\n\t\t\treader,\n\t\t\toffset + extensionDisableGsubOffset,\n\t\t),\n\t\textensionEnableGpos: parseJstfModList(\n\t\t\treader,\n\t\t\toffset + extensionEnableGposOffset,\n\t\t),\n\t\textensionDisableGpos: parseJstfModList(\n\t\t\treader,\n\t\t\toffset + extensionDisableGposOffset,\n\t\t),\n\t\textensionJstfMax: parseJstfMax(reader, offset + extensionJstfMaxOffset),\n\t};\n}\n\nfunction parseJstfLangSys(reader: Reader, offset: number): JstfLangSys {\n\tconst langReader = reader.sliceFrom(offset);\n\tconst jstfPriorityCount = langReader.uint16();\n\n\tconst priorityOffsets: uint16[] = [];\n\tfor (let i = 0; i < jstfPriorityCount; i++) {\n\t\tpriorityOffsets.push(langReader.uint16());\n\t}\n\n\tconst priorities: JstfPriorityRecord[] = [];\n\tfor (const priOffset of priorityOffsets) {\n\t\tpriorities.push(parseJstfPriority(reader, offset + priOffset));\n\t}\n\n\treturn { priorities };\n}\n\nfunction parseJstfScript(\n\treader: Reader,\n\toffset: number,\n): Omit<JstfScriptRecord, \"scriptTag\"> {\n\tconst scriptReader = reader.sliceFrom(offset);\n\tconst extenderGlyphOffset = scriptReader.uint16();\n\tconst defJstfLangSysOffset = scriptReader.uint16();\n\tconst jstfLangSysCount = scriptReader.uint16();\n\n\t// Parse language system records\n\tconst langSysData: Array<{ tag: number; offset: number }> = [];\n\tfor (let i = 0; i < jstfLangSysCount; i++) {\n\t\tconst tag = scriptReader.uint32();\n\t\tconst langOffset = scriptReader.uint16();\n\t\tlangSysData.push({ tag, offset: langOffset });\n\t}\n\n\t// Parse extender glyphs\n\tconst extenderGlyphs: uint16[] = [];\n\tif (extenderGlyphOffset !== 0) {\n\t\tconst extReader = reader.sliceFrom(offset + extenderGlyphOffset);\n\t\tconst glyphCount = extReader.uint16();\n\t\tfor (let i = 0; i < glyphCount; i++) {\n\t\t\textenderGlyphs.push(extReader.uint16());\n\t\t}\n\t}\n\n\t// Parse default lang sys\n\tconst defaultLangSys =\n\t\tdefJstfLangSysOffset !== 0\n\t\t\t? parseJstfLangSys(reader, offset + defJstfLangSysOffset)\n\t\t\t: null;\n\n\t// Parse language-specific systems\n\tconst langSysRecords = new Map<number, JstfLangSys>();\n\tfor (const { tag, offset: langOffset } of langSysData) {\n\t\tlangSysRecords.set(tag, parseJstfLangSys(reader, offset + langOffset));\n\t}\n\n\treturn { extenderGlyphs, defaultLangSys, langSysRecords };\n}\n\nexport function parseJstf(reader: Reader): JstfTable {\n\tconst majorVersion = reader.uint16();\n\tconst minorVersion = reader.uint16();\n\tconst jstfScriptCount = reader.uint16();\n\n\t// Read script record offsets\n\tconst scriptData: Array<{ tag: number; offset: number }> = [];\n\tfor (let i = 0; i < jstfScriptCount; i++) {\n\t\tconst tag = reader.uint32();\n\t\tconst offset = reader.uint16();\n\t\tscriptData.push({ tag, offset });\n\t}\n\n\t// Parse scripts\n\tconst scripts: JstfScriptRecord[] = [];\n\tfor (const { tag, offset } of scriptData) {\n\t\tconst script = parseJstfScript(reader, offset);\n\t\tscripts.push({ scriptTag: tag, ...script });\n\t}\n\n\treturn {\n\t\tmajorVersion,\n\t\tminorVersion,\n\t\tscripts,\n\t};\n}\n\n/** Get extender glyphs for a script (e.g., Kashida for Arabic) */\nexport function getExtenderGlyphs(\n\tjstf: JstfTable,\n\tscriptTag: number,\n): uint16[] {\n\tconst script = jstf.scripts.find((s) => s.scriptTag === scriptTag);\n\treturn script?.extenderGlyphs ?? [];\n}\n\n/** Get justification priorities for a script/language */\nexport function getJstfPriorities(\n\tjstf: JstfTable,\n\tscriptTag: number,\n\tlanguageTag?: number,\n): JstfPriorityRecord[] {\n\tconst script = jstf.scripts.find((s) => s.scriptTag === scriptTag);\n\tif (!script) return [];\n\n\t// Try language-specific first\n\tif (languageTag !== undefined) {\n\t\tconst langSys = script.langSysRecords.get(languageTag);\n\t\tif (langSys) return langSys.priorities;\n\t}\n\n\t// Fall back to default\n\treturn script.defaultLangSys?.priorities ?? [];\n}\n\n/** Get lookup modifications for shrinkage at a given priority level */\nexport function getShrinkageMods(priority: JstfPriorityRecord): {\n\tenableGsub: uint16[];\n\tdisableGsub: uint16[];\n\tenableGpos: uint16[];\n\tdisableGpos: uint16[];\n\tmaxLookups: uint16[];\n} {\n\treturn {\n\t\tenableGsub: priority.shrinkageEnableGsub?.lookupIndices ?? [],\n\t\tdisableGsub: priority.shrinkageDisableGsub?.lookupIndices ?? [],\n\t\tenableGpos: priority.shrinkageEnableGpos?.lookupIndices ?? [],\n\t\tdisableGpos: priority.shrinkageDisableGpos?.lookupIndices ?? [],\n\t\tmaxLookups: priority.shrinkageJstfMax?.lookupIndices ?? [],\n\t};\n}\n\n/** Get lookup modifications for extension at a given priority level */\nexport function getExtensionMods(priority: JstfPriorityRecord): {\n\tenableGsub: uint16[];\n\tdisableGsub: uint16[];\n\tenableGpos: uint16[];\n\tdisableGpos: uint16[];\n\tmaxLookups: uint16[];\n} {\n\treturn {\n\t\tenableGsub: priority.extensionEnableGsub?.lookupIndices ?? [],\n\t\tdisableGsub: priority.extensionDisableGsub?.lookupIndices ?? [],\n\t\tenableGpos: priority.extensionEnableGpos?.lookupIndices ?? [],\n\t\tdisableGpos: priority.extensionDisableGpos?.lookupIndices ?? [],\n\t\tmaxLookups: priority.extensionJstfMax?.lookupIndices ?? [],\n\t};\n}\n",
48
- "import type { GlyphId, int16, uint16 } from \"../../types.ts\";\nimport type { Reader } from \"../binary/reader.ts\";\n\n/**\n * Legacy kern table for kerning pairs\n * Used when GPOS kerning is not available\n */\nexport interface KernTable {\n\tversion: number;\n\tsubtables: KernSubtable[];\n}\n\nexport type KernSubtable = KernFormat0 | KernFormat2;\n\n/**\n * Format 0: Ordered list of kerning pairs\n */\nexport interface KernFormat0 {\n\tformat: 0;\n\tcoverage: KernCoverage;\n\tpairs: Map<number, int16>; // key = (left << 16) | right, value = kerning\n}\n\n/**\n * Format 2: Class-based kerning (two-dimensional array)\n */\nexport interface KernFormat2 {\n\tformat: 2;\n\tcoverage: KernCoverage;\n\trowWidth: uint16;\n\tleftClassTable: Map<GlyphId, uint16>;\n\trightClassTable: Map<GlyphId, uint16>;\n\tkerningValues: int16[][];\n}\n\nexport interface KernCoverage {\n\thorizontal: boolean;\n\tminimum: boolean;\n\tcrossStream: boolean;\n\toverride: boolean;\n}\n\n/**\n * Parse kern table\n */\nexport function parseKern(reader: Reader): KernTable {\n\tconst version = reader.uint16();\n\tconst subtables: KernSubtable[] = [];\n\n\tif (version === 0) {\n\t\t// Microsoft format\n\t\tconst nTables = reader.uint16();\n\t\tfor (let i = 0; i < nTables; i++) {\n\t\t\tconst subtable = parseKernSubtable(reader);\n\t\t\tif (subtable) subtables.push(subtable);\n\t\t}\n\t} else if (version === 1) {\n\t\t// Apple format (version is actually 0x00010000)\n\t\treader.skip(2); // Skip rest of version\n\t\tconst nTables = reader.uint32();\n\t\tfor (let i = 0; i < nTables; i++) {\n\t\t\tconst subtable = parseAppleKernSubtable(reader);\n\t\t\tif (subtable) subtables.push(subtable);\n\t\t}\n\t}\n\n\treturn { version, subtables };\n}\n\nfunction parseKernSubtable(reader: Reader): KernSubtable | null {\n\tconst _version = reader.uint16();\n\tconst length = reader.uint16();\n\tconst coverageBits = reader.uint16();\n\n\tconst coverage: KernCoverage = {\n\t\thorizontal: (coverageBits & 0x0001) !== 0,\n\t\tminimum: (coverageBits & 0x0002) !== 0,\n\t\tcrossStream: (coverageBits & 0x0004) !== 0,\n\t\toverride: (coverageBits & 0x0008) !== 0,\n\t};\n\n\tconst format = (coverageBits >> 8) & 0xff;\n\n\tif (format === 0) {\n\t\treturn parseKernFormat0(reader, coverage);\n\t} else if (format === 2) {\n\t\treturn parseKernFormat2(reader, coverage, length - 6);\n\t}\n\n\t// Skip unknown format\n\treader.skip(length - 6);\n\treturn null;\n}\n\nfunction parseAppleKernSubtable(reader: Reader): KernSubtable | null {\n\tconst length = reader.uint32();\n\tconst coverageBits = reader.uint16();\n\tconst _tupleIndex = reader.uint16();\n\n\tconst coverage: KernCoverage = {\n\t\thorizontal: (coverageBits & 0x8000) === 0, // bit 15: 0=horizontal\n\t\tminimum: false,\n\t\tcrossStream: (coverageBits & 0x4000) !== 0,\n\t\toverride: (coverageBits & 0x2000) !== 0,\n\t};\n\n\tconst format = coverageBits & 0x00ff;\n\n\tif (format === 0) {\n\t\treturn parseKernFormat0(reader, coverage);\n\t} else if (format === 2) {\n\t\treturn parseKernFormat2(reader, coverage, length - 8);\n\t}\n\n\t// Skip unknown format\n\treader.skip(length - 8);\n\treturn null;\n}\n\nfunction parseKernFormat0(reader: Reader, coverage: KernCoverage): KernFormat0 {\n\tconst nPairs = reader.uint16();\n\treader.skip(6); // searchRange, entrySelector, rangeShift\n\n\tconst pairs = new Map<number, int16>();\n\n\tfor (let i = 0; i < nPairs; i++) {\n\t\tconst left = reader.uint16();\n\t\tconst right = reader.uint16();\n\t\tconst value = reader.int16();\n\t\tconst key = (left << 16) | right;\n\t\tpairs.set(key, value);\n\t}\n\n\treturn { format: 0, coverage, pairs };\n}\n\nfunction parseKernFormat2(\n\treader: Reader,\n\tcoverage: KernCoverage,\n\tdataLength: number,\n): KernFormat2 {\n\tconst startOffset = reader.offset;\n\tconst rowWidth = reader.uint16();\n\tconst leftClassOffset = reader.uint16();\n\tconst rightClassOffset = reader.uint16();\n\tconst arrayOffset = reader.uint16();\n\n\t// Parse left class table\n\tconst leftClassTable = new Map<GlyphId, uint16>();\n\treader.seek(startOffset + leftClassOffset);\n\tconst leftFirstGlyph = reader.uint16();\n\tconst leftNGlyphs = reader.uint16();\n\tfor (let i = 0; i < leftNGlyphs; i++) {\n\t\tconst classValue = reader.uint16();\n\t\tif (classValue !== 0) {\n\t\t\tleftClassTable.set(leftFirstGlyph + i, classValue);\n\t\t}\n\t}\n\n\t// Parse right class table\n\tconst rightClassTable = new Map<GlyphId, uint16>();\n\treader.seek(startOffset + rightClassOffset);\n\tconst rightFirstGlyph = reader.uint16();\n\tconst rightNGlyphs = reader.uint16();\n\tfor (let i = 0; i < rightNGlyphs; i++) {\n\t\tconst classValue = reader.uint16();\n\t\tif (classValue !== 0) {\n\t\t\trightClassTable.set(rightFirstGlyph + i, classValue);\n\t\t}\n\t}\n\n\t// Parse kerning array\n\treader.seek(startOffset + arrayOffset);\n\tconst numRows = rowWidth > 0 ? Math.floor(dataLength / rowWidth) : 0;\n\tconst numCols = rowWidth / 2;\n\tconst kerningValues: int16[][] = [];\n\n\tfor (let row = 0; row < numRows; row++) {\n\t\tconst rowValues: int16[] = [];\n\t\tfor (let col = 0; col < numCols; col++) {\n\t\t\trowValues.push(reader.int16());\n\t\t}\n\t\tkerningValues.push(rowValues);\n\t}\n\n\treturn {\n\t\tformat: 2,\n\t\tcoverage,\n\t\trowWidth,\n\t\tleftClassTable,\n\t\trightClassTable,\n\t\tkerningValues,\n\t};\n}\n\n/**\n * Get kerning value from kern table\n */\nexport function getKernValue(\n\tkern: KernTable,\n\tleft: GlyphId,\n\tright: GlyphId,\n): number {\n\tlet total = 0;\n\n\tfor (const subtable of kern.subtables) {\n\t\tif (!subtable.coverage.horizontal) continue; // Only horizontal for now\n\n\t\tif (subtable.format === 0) {\n\t\t\tconst key = (left << 16) | right;\n\t\t\tconst value = subtable.pairs.get(key);\n\t\t\tif (value !== undefined) {\n\t\t\t\tif (subtable.coverage.override) {\n\t\t\t\t\ttotal = value;\n\t\t\t\t} else {\n\t\t\t\t\ttotal += value;\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (subtable.format === 2) {\n\t\t\tconst leftClass = subtable.leftClassTable.get(left) ?? 0;\n\t\t\tconst rightClass = subtable.rightClassTable.get(right) ?? 0;\n\n\t\t\tif (leftClass > 0 && rightClass > 0) {\n\t\t\t\tconst rowIndex = Math.floor(leftClass / 2);\n\t\t\t\tconst colIndex = Math.floor(rightClass / 2);\n\t\t\t\tconst row = subtable.kerningValues[rowIndex];\n\t\t\t\tif (row) {\n\t\t\t\t\tconst value = row[colIndex];\n\t\t\t\t\tif (value !== undefined) {\n\t\t\t\t\t\tif (subtable.coverage.override) {\n\t\t\t\t\t\t\ttotal = value;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\ttotal += value;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn total;\n}\n",
49
- "import type { GlyphId, int16, uint16, uint32 } from \"../../types.ts\";\nimport type { Reader } from \"../binary/reader.ts\";\n\n/**\n * Extended Kerning table (kerx)\n * Apple Advanced Typography kerning\n */\nexport interface KerxTable {\n\tversion: uint16;\n\tnTables: uint32;\n\tsubtables: KerxSubtable[];\n}\n\n/**\n * kerx subtable types\n */\nexport enum KerxSubtableType {\n\tOrderedList = 0,\n\tStateTable = 1,\n\tSimpleArray = 2,\n\tControlPoint = 4,\n\tFormat6 = 6,\n}\n\n/**\n * Coverage flags\n */\nexport interface KerxCoverage {\n\tvertical: boolean;\n\tcrossStream: boolean;\n\tvariation: boolean;\n}\n\n/**\n * Base subtable\n */\nexport interface KerxSubtableBase {\n\tlength: uint32;\n\tcoverage: KerxCoverage;\n\ttupleCount: uint16;\n}\n\nexport type KerxSubtable =\n\t| KerxOrderedListSubtable\n\t| KerxStateTableSubtable\n\t| KerxSimpleArraySubtable\n\t| KerxControlPointSubtable\n\t| KerxFormat6Subtable;\n\n/**\n * Format 0: Ordered list of kerning pairs\n */\nexport interface KerxOrderedListSubtable extends KerxSubtableBase {\n\tformat: KerxSubtableType.OrderedList;\n\tnPairs: uint32;\n\tpairs: KerxPair[];\n}\n\nexport interface KerxPair {\n\tleft: GlyphId;\n\tright: GlyphId;\n\tvalue: int16;\n}\n\n/**\n * Format 1: State table\n */\nexport interface KerxStateTableSubtable extends KerxSubtableBase {\n\tformat: KerxSubtableType.StateTable;\n\tstateHeader: KerxStateHeader;\n\t// State machine data\n}\n\nexport interface KerxStateHeader {\n\tnClasses: uint32;\n\tclassTableOffset: uint32;\n\tstateArrayOffset: uint32;\n\tentryTableOffset: uint32;\n\tvalueTableOffset: uint32;\n}\n\n/**\n * Format 2: Simple array\n */\nexport interface KerxSimpleArraySubtable extends KerxSubtableBase {\n\tformat: KerxSubtableType.SimpleArray;\n\trowWidth: uint16;\n\tleftClassTable: KerxClassTable;\n\trightClassTable: KerxClassTable;\n\tkerningArray: Int16Array;\n}\n\nexport interface KerxClassTable {\n\tfirstGlyph: GlyphId;\n\tnGlyphs: uint16;\n\tclasses: Uint8Array;\n}\n\n/**\n * Format 4: Control point actions\n */\nexport interface KerxControlPointSubtable extends KerxSubtableBase {\n\tformat: KerxSubtableType.ControlPoint;\n\tflags: uint32;\n\t// Control point data\n}\n\n/**\n * Format 6: Extended kerning pairs\n */\nexport interface KerxFormat6Subtable extends KerxSubtableBase {\n\tformat: KerxSubtableType.Format6;\n\tflags: uint32;\n\trowCount: uint16;\n\tcolumnCount: uint16;\n\trowIndexTableOffset: uint32;\n\tcolumnIndexTableOffset: uint32;\n\tkerningArrayOffset: uint32;\n\tkerningVectorOffset: uint32;\n}\n\n/**\n * Parse kerx table\n */\nexport function parseKerx(reader: Reader): KerxTable {\n\tconst version = reader.uint16();\n\treader.skip(2); // padding\n\tconst nTables = reader.uint32();\n\n\tconst subtables: KerxSubtable[] = [];\n\n\tfor (let i = 0; i < nTables; i++) {\n\t\tconst subtable = parseKerxSubtable(reader);\n\t\tif (subtable) subtables.push(subtable);\n\t}\n\n\treturn { version, nTables, subtables };\n}\n\nfunction parseKerxSubtable(reader: Reader): KerxSubtable | null {\n\tconst length = reader.uint32();\n\tconst coverageAndFormat = reader.uint32();\n\tconst tupleCount = reader.uint16();\n\treader.skip(2); // padding\n\n\tconst format = coverageAndFormat & 0xff;\n\tconst coverage: KerxCoverage = {\n\t\tvertical: (coverageAndFormat & 0x80000000) !== 0,\n\t\tcrossStream: (coverageAndFormat & 0x40000000) !== 0,\n\t\tvariation: (coverageAndFormat & 0x20000000) !== 0,\n\t};\n\n\tconst base: KerxSubtableBase = { length, coverage, tupleCount };\n\tconst subtableEnd = reader.offset + length - 12; // Already read 12 bytes\n\n\tlet subtable: KerxSubtable | null = null;\n\n\tswitch (format) {\n\t\tcase KerxSubtableType.OrderedList:\n\t\t\tsubtable = parseKerxFormat0(reader, base);\n\t\t\tbreak;\n\t\tcase KerxSubtableType.StateTable:\n\t\t\tsubtable = parseKerxFormat1(reader, base);\n\t\t\tbreak;\n\t\tcase KerxSubtableType.SimpleArray:\n\t\t\tsubtable = parseKerxFormat2(reader, base);\n\t\t\tbreak;\n\t\tcase KerxSubtableType.Format6:\n\t\t\tsubtable = parseKerxFormat6(reader, base);\n\t\t\tbreak;\n\t}\n\n\t// Skip to end of subtable\n\treader.seek(subtableEnd);\n\n\treturn subtable;\n}\n\nfunction parseKerxFormat0(\n\treader: Reader,\n\tbase: KerxSubtableBase,\n): KerxOrderedListSubtable {\n\tconst nPairs = reader.uint32();\n\treader.skip(12); // searchRange, entrySelector, rangeShift\n\n\tconst pairs: KerxPair[] = [];\n\tfor (let i = 0; i < nPairs; i++) {\n\t\tpairs.push({\n\t\t\tleft: reader.uint16(),\n\t\t\tright: reader.uint16(),\n\t\t\tvalue: reader.int16(),\n\t\t});\n\t\treader.skip(2); // padding\n\t}\n\n\treturn {\n\t\t...base,\n\t\tformat: KerxSubtableType.OrderedList,\n\t\tnPairs,\n\t\tpairs,\n\t};\n}\n\nfunction parseKerxFormat1(\n\treader: Reader,\n\tbase: KerxSubtableBase,\n): KerxStateTableSubtable {\n\tconst stateHeader: KerxStateHeader = {\n\t\tnClasses: reader.uint32(),\n\t\tclassTableOffset: reader.offset32(),\n\t\tstateArrayOffset: reader.offset32(),\n\t\tentryTableOffset: reader.offset32(),\n\t\tvalueTableOffset: reader.offset32(),\n\t};\n\n\treturn {\n\t\t...base,\n\t\tformat: KerxSubtableType.StateTable,\n\t\tstateHeader,\n\t};\n}\n\nfunction parseKerxFormat2(\n\treader: Reader,\n\tbase: KerxSubtableBase,\n): KerxSimpleArraySubtable {\n\tconst rowWidth = reader.uint16();\n\treader.skip(2); // padding\n\n\tconst leftClassTableOffset = reader.offset32();\n\tconst rightClassTableOffset = reader.offset32();\n\tconst kerningArrayOffset = reader.offset32();\n\n\t// Parse class tables\n\tconst leftClassTable = parseKerxClassTable(\n\t\treader.sliceFrom(leftClassTableOffset),\n\t);\n\tconst rightClassTable = parseKerxClassTable(\n\t\treader.sliceFrom(rightClassTableOffset),\n\t);\n\n\t// Parse kerning array\n\tconst arrayReader = reader.sliceFrom(kerningArrayOffset);\n\tconst numRows =\n\t\tleftClassTable.nGlyphs > 0\n\t\t\t? Math.max(...Array.from(leftClassTable.classes)) + 1\n\t\t\t: 0;\n\tconst numCols = rowWidth / 2;\n\tconst kerningArray = new Int16Array(numRows * numCols);\n\n\tfor (const [i, _] of kerningArray.entries()) {\n\t\tkerningArray[i] = arrayReader.int16();\n\t}\n\n\treturn {\n\t\t...base,\n\t\tformat: KerxSubtableType.SimpleArray,\n\t\trowWidth,\n\t\tleftClassTable,\n\t\trightClassTable,\n\t\tkerningArray,\n\t};\n}\n\nfunction parseKerxClassTable(reader: Reader): KerxClassTable {\n\tconst firstGlyph = reader.uint16();\n\tconst nGlyphs = reader.uint16();\n\tconst classes = new Uint8Array(nGlyphs);\n\n\tfor (let i = 0; i < nGlyphs; i++) {\n\t\tclasses[i] = reader.uint8();\n\t}\n\n\treturn { firstGlyph, nGlyphs, classes };\n}\n\nfunction parseKerxFormat6(\n\treader: Reader,\n\tbase: KerxSubtableBase,\n): KerxFormat6Subtable {\n\tconst flags = reader.uint32();\n\tconst rowCount = reader.uint16();\n\tconst columnCount = reader.uint16();\n\tconst rowIndexTableOffset = reader.offset32();\n\tconst columnIndexTableOffset = reader.offset32();\n\tconst kerningArrayOffset = reader.offset32();\n\tconst kerningVectorOffset = reader.offset32();\n\n\treturn {\n\t\t...base,\n\t\tformat: KerxSubtableType.Format6,\n\t\tflags,\n\t\trowCount,\n\t\tcolumnCount,\n\t\trowIndexTableOffset,\n\t\tcolumnIndexTableOffset,\n\t\tkerningArrayOffset,\n\t\tkerningVectorOffset,\n\t};\n}\n\n/**\n * Get kerning value from kerx table\n */\nexport function getKerxValue(\n\tkerx: KerxTable,\n\tleft: GlyphId,\n\tright: GlyphId,\n): number {\n\tfor (const subtable of kerx.subtables) {\n\t\tif (subtable.coverage.vertical) continue; // Skip vertical kerning\n\n\t\tswitch (subtable.format) {\n\t\t\tcase KerxSubtableType.OrderedList: {\n\t\t\t\t// Binary search for the pair\n\t\t\t\tconst pairs = subtable.pairs;\n\t\t\t\tlet lo = 0;\n\t\t\t\tlet hi = pairs.length - 1;\n\n\t\t\t\twhile (lo <= hi) {\n\t\t\t\t\tconst mid = (lo + hi) >> 1;\n\t\t\t\t\tconst pair = pairs[mid];\n\t\t\t\t\tif (!pair) break;\n\n\t\t\t\t\tconst key = (pair.left << 16) | pair.right;\n\t\t\t\t\tconst target = (left << 16) | right;\n\n\t\t\t\t\tif (key === target) {\n\t\t\t\t\t\treturn pair.value;\n\t\t\t\t\t} else if (key < target) {\n\t\t\t\t\t\tlo = mid + 1;\n\t\t\t\t\t} else {\n\t\t\t\t\t\thi = mid - 1;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase KerxSubtableType.SimpleArray: {\n\t\t\t\tconst leftTable = subtable.leftClassTable;\n\t\t\t\tconst rightTable = subtable.rightClassTable;\n\n\t\t\t\tif (\n\t\t\t\t\tleft < leftTable.firstGlyph ||\n\t\t\t\t\tleft >= leftTable.firstGlyph + leftTable.nGlyphs\n\t\t\t\t) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (\n\t\t\t\t\tright < rightTable.firstGlyph ||\n\t\t\t\t\tright >= rightTable.firstGlyph + rightTable.nGlyphs\n\t\t\t\t) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst leftClass = leftTable.classes[left - leftTable.firstGlyph];\n\t\t\t\tconst rightClass = rightTable.classes[right - rightTable.firstGlyph];\n\t\t\t\tif (leftClass === undefined || rightClass === undefined) continue;\n\n\t\t\t\tconst numCols = subtable.rowWidth / 2;\n\t\t\t\tconst index = leftClass * numCols + rightClass;\n\n\t\t\t\tif (index < subtable.kerningArray.length) {\n\t\t\t\t\tconst value = subtable.kerningArray[index];\n\t\t\t\t\tif (value !== undefined && value !== 0) return value;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn 0;\n}\n",
50
- "import {\n\ttype Coverage,\n\tparseCoverageAt,\n} from \"../../layout/structures/coverage.ts\";\nimport {\n\ttype DeviceOrVariationIndex,\n\tparseDeviceAt,\n} from \"../../layout/structures/device.ts\";\nimport type { GlyphId, int16, uint16 } from \"../../types.ts\";\nimport type { Reader } from \"../binary/reader.ts\";\n\n/**\n * MATH table - Mathematical typesetting data\n * Provides metrics and glyph information for math layout\n */\n\n/** MathValueRecord - value with optional device correction */\nexport interface MathValueRecord {\n\tvalue: int16;\n\tdevice: DeviceOrVariationIndex | null;\n}\n\n/** MathConstants - global math constants */\nexport interface MathConstants {\n\tscriptPercentScaleDown: int16;\n\tscriptScriptPercentScaleDown: int16;\n\tdelimitedSubFormulaMinHeight: uint16;\n\tdisplayOperatorMinHeight: uint16;\n\tmathLeading: MathValueRecord;\n\taxisHeight: MathValueRecord;\n\taccentBaseHeight: MathValueRecord;\n\tflattenedAccentBaseHeight: MathValueRecord;\n\tsubscriptShiftDown: MathValueRecord;\n\tsubscriptTopMax: MathValueRecord;\n\tsubscriptBaselineDropMin: MathValueRecord;\n\tsuperscriptShiftUp: MathValueRecord;\n\tsuperscriptShiftUpCramped: MathValueRecord;\n\tsuperscriptBottomMin: MathValueRecord;\n\tsuperscriptBaselineDropMax: MathValueRecord;\n\tsubSuperscriptGapMin: MathValueRecord;\n\tsuperscriptBottomMaxWithSubscript: MathValueRecord;\n\tspaceAfterScript: MathValueRecord;\n\tupperLimitGapMin: MathValueRecord;\n\tupperLimitBaselineRiseMin: MathValueRecord;\n\tlowerLimitGapMin: MathValueRecord;\n\tlowerLimitBaselineDropMin: MathValueRecord;\n\tstackTopShiftUp: MathValueRecord;\n\tstackTopDisplayStyleShiftUp: MathValueRecord;\n\tstackBottomShiftDown: MathValueRecord;\n\tstackBottomDisplayStyleShiftDown: MathValueRecord;\n\tstackGapMin: MathValueRecord;\n\tstackDisplayStyleGapMin: MathValueRecord;\n\tstretchStackTopShiftUp: MathValueRecord;\n\tstretchStackBottomShiftDown: MathValueRecord;\n\tstretchStackGapAboveMin: MathValueRecord;\n\tstretchStackGapBelowMin: MathValueRecord;\n\tfractionNumeratorShiftUp: MathValueRecord;\n\tfractionNumeratorDisplayStyleShiftUp: MathValueRecord;\n\tfractionDenominatorShiftDown: MathValueRecord;\n\tfractionDenominatorDisplayStyleShiftDown: MathValueRecord;\n\tfractionNumeratorGapMin: MathValueRecord;\n\tfractionNumDisplayStyleGapMin: MathValueRecord;\n\tfractionRuleThickness: MathValueRecord;\n\tfractionDenominatorGapMin: MathValueRecord;\n\tfractionDenomDisplayStyleGapMin: MathValueRecord;\n\tskewedFractionHorizontalGap: MathValueRecord;\n\tskewedFractionVerticalGap: MathValueRecord;\n\toverbarVerticalGap: MathValueRecord;\n\toverbarRuleThickness: MathValueRecord;\n\toverbarExtraAscender: MathValueRecord;\n\tunderbarVerticalGap: MathValueRecord;\n\tunderbarRuleThickness: MathValueRecord;\n\tunderbarExtraDescender: MathValueRecord;\n\tradicalVerticalGap: MathValueRecord;\n\tradicalDisplayStyleVerticalGap: MathValueRecord;\n\tradicalRuleThickness: MathValueRecord;\n\tradicalExtraAscender: MathValueRecord;\n\tradicalKernBeforeDegree: MathValueRecord;\n\tradicalKernAfterDegree: MathValueRecord;\n\tradicalDegreeBottomRaisePercent: int16;\n}\n\n/** Italic correction info */\nexport interface MathItalicsCorrection {\n\tcoverage: Coverage;\n\tvalues: MathValueRecord[];\n}\n\n/** Top accent attachment */\nexport interface MathTopAccentAttachment {\n\tcoverage: Coverage;\n\tvalues: MathValueRecord[];\n}\n\n/** Extended shape coverage */\nexport interface ExtendedShapeCoverage {\n\tcoverage: Coverage;\n}\n\n/** Math kern record for corner kerns */\nexport interface MathKernRecord {\n\tcorrectionHeights: MathValueRecord[];\n\tkernValues: MathValueRecord[];\n}\n\n/** Math kern info for a glyph */\nexport interface MathKernInfo {\n\ttopRight: MathKernRecord | null;\n\ttopLeft: MathKernRecord | null;\n\tbottomRight: MathKernRecord | null;\n\tbottomLeft: MathKernRecord | null;\n}\n\n/** Math kern info table */\nexport interface MathKernInfoTable {\n\tcoverage: Coverage;\n\tkernInfo: MathKernInfo[];\n}\n\n/** MathGlyphInfo - per-glyph math info */\nexport interface MathGlyphInfo {\n\titalicsCorrection: MathItalicsCorrection | null;\n\ttopAccentAttachment: MathTopAccentAttachment | null;\n\textendedShapeCoverage: ExtendedShapeCoverage | null;\n\tkernInfo: MathKernInfoTable | null;\n}\n\n/** Glyph part record for assembly */\nexport interface GlyphPartRecord {\n\tglyphId: GlyphId;\n\tstartConnectorLength: uint16;\n\tendConnectorLength: uint16;\n\tfullAdvance: uint16;\n\tpartFlags: uint16;\n}\n\n/** Glyph assembly */\nexport interface GlyphAssembly {\n\titalicsCorrection: MathValueRecord;\n\tparts: GlyphPartRecord[];\n}\n\n/** Math glyph construction */\nexport interface MathGlyphConstruction {\n\tglyphAssembly: GlyphAssembly | null;\n\tvariants: Array<{ variantGlyph: GlyphId; advanceMeasurement: uint16 }>;\n}\n\n/** MathVariants - glyph variants and construction */\nexport interface MathVariants {\n\tminConnectorOverlap: uint16;\n\tvertGlyphCoverage: Coverage | null;\n\thorizGlyphCoverage: Coverage | null;\n\tvertGlyphConstruction: MathGlyphConstruction[];\n\thorizGlyphConstruction: MathGlyphConstruction[];\n}\n\n/** MATH table */\nexport interface MathTable {\n\tmajorVersion: uint16;\n\tminorVersion: uint16;\n\tconstants: MathConstants | null;\n\tglyphInfo: MathGlyphInfo | null;\n\tvariants: MathVariants | null;\n}\n\nfunction parseMathValueRecord(\n\treader: Reader,\n\ttableReader: Reader,\n): MathValueRecord {\n\tconst value = reader.int16();\n\tconst deviceOffset = reader.uint16();\n\treturn {\n\t\tvalue,\n\t\tdevice: parseDeviceAt(tableReader, deviceOffset),\n\t};\n}\n\nfunction parseMathConstants(reader: Reader): MathConstants {\n\tconst tableReader = reader;\n\tconst scriptPercentScaleDown = reader.int16();\n\tconst scriptScriptPercentScaleDown = reader.int16();\n\tconst delimitedSubFormulaMinHeight = reader.uint16();\n\tconst displayOperatorMinHeight = reader.uint16();\n\n\treturn {\n\t\tscriptPercentScaleDown,\n\t\tscriptScriptPercentScaleDown,\n\t\tdelimitedSubFormulaMinHeight,\n\t\tdisplayOperatorMinHeight,\n\t\tmathLeading: parseMathValueRecord(reader, tableReader),\n\t\taxisHeight: parseMathValueRecord(reader, tableReader),\n\t\taccentBaseHeight: parseMathValueRecord(reader, tableReader),\n\t\tflattenedAccentBaseHeight: parseMathValueRecord(reader, tableReader),\n\t\tsubscriptShiftDown: parseMathValueRecord(reader, tableReader),\n\t\tsubscriptTopMax: parseMathValueRecord(reader, tableReader),\n\t\tsubscriptBaselineDropMin: parseMathValueRecord(reader, tableReader),\n\t\tsuperscriptShiftUp: parseMathValueRecord(reader, tableReader),\n\t\tsuperscriptShiftUpCramped: parseMathValueRecord(reader, tableReader),\n\t\tsuperscriptBottomMin: parseMathValueRecord(reader, tableReader),\n\t\tsuperscriptBaselineDropMax: parseMathValueRecord(reader, tableReader),\n\t\tsubSuperscriptGapMin: parseMathValueRecord(reader, tableReader),\n\t\tsuperscriptBottomMaxWithSubscript: parseMathValueRecord(\n\t\t\treader,\n\t\t\ttableReader,\n\t\t),\n\t\tspaceAfterScript: parseMathValueRecord(reader, tableReader),\n\t\tupperLimitGapMin: parseMathValueRecord(reader, tableReader),\n\t\tupperLimitBaselineRiseMin: parseMathValueRecord(reader, tableReader),\n\t\tlowerLimitGapMin: parseMathValueRecord(reader, tableReader),\n\t\tlowerLimitBaselineDropMin: parseMathValueRecord(reader, tableReader),\n\t\tstackTopShiftUp: parseMathValueRecord(reader, tableReader),\n\t\tstackTopDisplayStyleShiftUp: parseMathValueRecord(reader, tableReader),\n\t\tstackBottomShiftDown: parseMathValueRecord(reader, tableReader),\n\t\tstackBottomDisplayStyleShiftDown: parseMathValueRecord(reader, tableReader),\n\t\tstackGapMin: parseMathValueRecord(reader, tableReader),\n\t\tstackDisplayStyleGapMin: parseMathValueRecord(reader, tableReader),\n\t\tstretchStackTopShiftUp: parseMathValueRecord(reader, tableReader),\n\t\tstretchStackBottomShiftDown: parseMathValueRecord(reader, tableReader),\n\t\tstretchStackGapAboveMin: parseMathValueRecord(reader, tableReader),\n\t\tstretchStackGapBelowMin: parseMathValueRecord(reader, tableReader),\n\t\tfractionNumeratorShiftUp: parseMathValueRecord(reader, tableReader),\n\t\tfractionNumeratorDisplayStyleShiftUp: parseMathValueRecord(\n\t\t\treader,\n\t\t\ttableReader,\n\t\t),\n\t\tfractionDenominatorShiftDown: parseMathValueRecord(reader, tableReader),\n\t\tfractionDenominatorDisplayStyleShiftDown: parseMathValueRecord(\n\t\t\treader,\n\t\t\ttableReader,\n\t\t),\n\t\tfractionNumeratorGapMin: parseMathValueRecord(reader, tableReader),\n\t\tfractionNumDisplayStyleGapMin: parseMathValueRecord(reader, tableReader),\n\t\tfractionRuleThickness: parseMathValueRecord(reader, tableReader),\n\t\tfractionDenominatorGapMin: parseMathValueRecord(reader, tableReader),\n\t\tfractionDenomDisplayStyleGapMin: parseMathValueRecord(reader, tableReader),\n\t\tskewedFractionHorizontalGap: parseMathValueRecord(reader, tableReader),\n\t\tskewedFractionVerticalGap: parseMathValueRecord(reader, tableReader),\n\t\toverbarVerticalGap: parseMathValueRecord(reader, tableReader),\n\t\toverbarRuleThickness: parseMathValueRecord(reader, tableReader),\n\t\toverbarExtraAscender: parseMathValueRecord(reader, tableReader),\n\t\tunderbarVerticalGap: parseMathValueRecord(reader, tableReader),\n\t\tunderbarRuleThickness: parseMathValueRecord(reader, tableReader),\n\t\tunderbarExtraDescender: parseMathValueRecord(reader, tableReader),\n\t\tradicalVerticalGap: parseMathValueRecord(reader, tableReader),\n\t\tradicalDisplayStyleVerticalGap: parseMathValueRecord(reader, tableReader),\n\t\tradicalRuleThickness: parseMathValueRecord(reader, tableReader),\n\t\tradicalExtraAscender: parseMathValueRecord(reader, tableReader),\n\t\tradicalKernBeforeDegree: parseMathValueRecord(reader, tableReader),\n\t\tradicalKernAfterDegree: parseMathValueRecord(reader, tableReader),\n\t\tradicalDegreeBottomRaisePercent: reader.int16(),\n\t};\n}\n\nfunction parseMathItalicsCorrection(reader: Reader): MathItalicsCorrection {\n\tconst coverageOffset = reader.uint16();\n\tconst count = reader.uint16();\n\n\tconst values: MathValueRecord[] = [];\n\tfor (let i = 0; i < count; i++) {\n\t\tvalues.push(parseMathValueRecord(reader, reader));\n\t}\n\n\tconst coverage = parseCoverageAt(reader, coverageOffset);\n\n\treturn { coverage, values };\n}\n\nfunction parseMathTopAccentAttachment(reader: Reader): MathTopAccentAttachment {\n\tconst coverageOffset = reader.uint16();\n\tconst count = reader.uint16();\n\n\tconst values: MathValueRecord[] = [];\n\tfor (let i = 0; i < count; i++) {\n\t\tvalues.push(parseMathValueRecord(reader, reader));\n\t}\n\n\tconst coverage = parseCoverageAt(reader, coverageOffset);\n\n\treturn { coverage, values };\n}\n\nfunction parseMathKernRecord(reader: Reader, offset: number): MathKernRecord {\n\tconst kernReader = reader.sliceFrom(offset);\n\tconst heightCount = kernReader.uint16();\n\n\tconst correctionHeights: MathValueRecord[] = [];\n\tfor (let i = 0; i < heightCount; i++) {\n\t\tcorrectionHeights.push(parseMathValueRecord(kernReader, kernReader));\n\t}\n\n\tconst kernValues: MathValueRecord[] = [];\n\tfor (let i = 0; i < heightCount + 1; i++) {\n\t\tkernValues.push(parseMathValueRecord(kernReader, kernReader));\n\t}\n\n\treturn { correctionHeights, kernValues };\n}\n\nfunction parseMathKernInfoTable(reader: Reader): MathKernInfoTable {\n\tconst coverageOffset = reader.uint16();\n\tconst count = reader.uint16();\n\n\tconst kernInfoRecords: Array<{\n\t\ttopRightOffset: uint16;\n\t\ttopLeftOffset: uint16;\n\t\tbottomRightOffset: uint16;\n\t\tbottomLeftOffset: uint16;\n\t}> = [];\n\n\tfor (let i = 0; i < count; i++) {\n\t\tkernInfoRecords.push({\n\t\t\ttopRightOffset: reader.uint16(),\n\t\t\ttopLeftOffset: reader.uint16(),\n\t\t\tbottomRightOffset: reader.uint16(),\n\t\t\tbottomLeftOffset: reader.uint16(),\n\t\t});\n\t}\n\n\tconst coverage = parseCoverageAt(reader, coverageOffset);\n\n\tconst kernInfo: MathKernInfo[] = kernInfoRecords.map((record) => ({\n\t\ttopRight:\n\t\t\trecord.topRightOffset !== 0\n\t\t\t\t? parseMathKernRecord(reader, record.topRightOffset)\n\t\t\t\t: null,\n\t\ttopLeft:\n\t\t\trecord.topLeftOffset !== 0\n\t\t\t\t? parseMathKernRecord(reader, record.topLeftOffset)\n\t\t\t\t: null,\n\t\tbottomRight:\n\t\t\trecord.bottomRightOffset !== 0\n\t\t\t\t? parseMathKernRecord(reader, record.bottomRightOffset)\n\t\t\t\t: null,\n\t\tbottomLeft:\n\t\t\trecord.bottomLeftOffset !== 0\n\t\t\t\t? parseMathKernRecord(reader, record.bottomLeftOffset)\n\t\t\t\t: null,\n\t}));\n\n\treturn { coverage, kernInfo };\n}\n\nfunction parseMathGlyphInfo(reader: Reader): MathGlyphInfo {\n\tconst italicsCorrectionOffset = reader.uint16();\n\tconst topAccentAttachmentOffset = reader.uint16();\n\tconst extendedShapeCoverageOffset = reader.uint16();\n\tconst kernInfoOffset = reader.uint16();\n\n\tlet italicsCorrection: MathItalicsCorrection | null = null;\n\tif (italicsCorrectionOffset !== 0) {\n\t\titalicsCorrection = parseMathItalicsCorrection(\n\t\t\treader.sliceFrom(italicsCorrectionOffset),\n\t\t);\n\t}\n\n\tlet topAccentAttachment: MathTopAccentAttachment | null = null;\n\tif (topAccentAttachmentOffset !== 0) {\n\t\ttopAccentAttachment = parseMathTopAccentAttachment(\n\t\t\treader.sliceFrom(topAccentAttachmentOffset),\n\t\t);\n\t}\n\n\tlet extendedShapeCoverage: ExtendedShapeCoverage | null = null;\n\tif (extendedShapeCoverageOffset !== 0) {\n\t\tconst coverage = parseCoverageAt(reader, extendedShapeCoverageOffset);\n\t\textendedShapeCoverage = { coverage };\n\t}\n\n\tlet kernInfo: MathKernInfoTable | null = null;\n\tif (kernInfoOffset !== 0) {\n\t\tkernInfo = parseMathKernInfoTable(reader.sliceFrom(kernInfoOffset));\n\t}\n\n\treturn {\n\t\titalicsCorrection,\n\t\ttopAccentAttachment,\n\t\textendedShapeCoverage,\n\t\tkernInfo,\n\t};\n}\n\nfunction parseGlyphAssembly(reader: Reader): GlyphAssembly {\n\tconst italicsCorrection = parseMathValueRecord(reader, reader);\n\tconst partCount = reader.uint16();\n\n\tconst parts: GlyphPartRecord[] = [];\n\tfor (let i = 0; i < partCount; i++) {\n\t\tparts.push({\n\t\t\tglyphId: reader.uint16(),\n\t\t\tstartConnectorLength: reader.uint16(),\n\t\t\tendConnectorLength: reader.uint16(),\n\t\t\tfullAdvance: reader.uint16(),\n\t\t\tpartFlags: reader.uint16(),\n\t\t});\n\t}\n\n\treturn { italicsCorrection, parts };\n}\n\nfunction parseMathGlyphConstruction(reader: Reader): MathGlyphConstruction {\n\tconst glyphAssemblyOffset = reader.uint16();\n\tconst variantCount = reader.uint16();\n\n\tconst variants: Array<{ variantGlyph: GlyphId; advanceMeasurement: uint16 }> =\n\t\t[];\n\tfor (let i = 0; i < variantCount; i++) {\n\t\tvariants.push({\n\t\t\tvariantGlyph: reader.uint16(),\n\t\t\tadvanceMeasurement: reader.uint16(),\n\t\t});\n\t}\n\n\tlet glyphAssembly: GlyphAssembly | null = null;\n\tif (glyphAssemblyOffset !== 0) {\n\t\tglyphAssembly = parseGlyphAssembly(reader.sliceFrom(glyphAssemblyOffset));\n\t}\n\n\treturn { glyphAssembly, variants };\n}\n\nfunction parseMathVariants(reader: Reader): MathVariants {\n\tconst minConnectorOverlap = reader.uint16();\n\tconst vertGlyphCoverageOffset = reader.uint16();\n\tconst horizGlyphCoverageOffset = reader.uint16();\n\tconst vertGlyphCount = reader.uint16();\n\tconst horizGlyphCount = reader.uint16();\n\n\tconst vertGlyphConstructionOffsets: uint16[] = [];\n\tfor (let i = 0; i < vertGlyphCount; i++) {\n\t\tvertGlyphConstructionOffsets.push(reader.uint16());\n\t}\n\n\tconst horizGlyphConstructionOffsets: uint16[] = [];\n\tfor (let i = 0; i < horizGlyphCount; i++) {\n\t\thorizGlyphConstructionOffsets.push(reader.uint16());\n\t}\n\n\tconst vertGlyphCoverage =\n\t\tvertGlyphCoverageOffset !== 0\n\t\t\t? parseCoverageAt(reader, vertGlyphCoverageOffset)\n\t\t\t: null;\n\n\tconst horizGlyphCoverage =\n\t\thorizGlyphCoverageOffset !== 0\n\t\t\t? parseCoverageAt(reader, horizGlyphCoverageOffset)\n\t\t\t: null;\n\n\tconst vertGlyphConstruction = vertGlyphConstructionOffsets.map((offset) =>\n\t\tparseMathGlyphConstruction(reader.sliceFrom(offset)),\n\t);\n\n\tconst horizGlyphConstruction = horizGlyphConstructionOffsets.map((offset) =>\n\t\tparseMathGlyphConstruction(reader.sliceFrom(offset)),\n\t);\n\n\treturn {\n\t\tminConnectorOverlap,\n\t\tvertGlyphCoverage,\n\t\thorizGlyphCoverage,\n\t\tvertGlyphConstruction,\n\t\thorizGlyphConstruction,\n\t};\n}\n\nexport function parseMath(reader: Reader): MathTable {\n\tconst majorVersion = reader.uint16();\n\tconst minorVersion = reader.uint16();\n\tconst mathConstantsOffset = reader.uint16();\n\tconst mathGlyphInfoOffset = reader.uint16();\n\tconst mathVariantsOffset = reader.uint16();\n\n\tlet constants: MathConstants | null = null;\n\tif (mathConstantsOffset !== 0) {\n\t\tconstants = parseMathConstants(reader.sliceFrom(mathConstantsOffset));\n\t}\n\n\tlet glyphInfo: MathGlyphInfo | null = null;\n\tif (mathGlyphInfoOffset !== 0) {\n\t\tglyphInfo = parseMathGlyphInfo(reader.sliceFrom(mathGlyphInfoOffset));\n\t}\n\n\tlet variants: MathVariants | null = null;\n\tif (mathVariantsOffset !== 0) {\n\t\tvariants = parseMathVariants(reader.sliceFrom(mathVariantsOffset));\n\t}\n\n\treturn {\n\t\tmajorVersion,\n\t\tminorVersion,\n\t\tconstants,\n\t\tglyphInfo,\n\t\tvariants,\n\t};\n}\n\n// Helper functions\n\n/** Get italic correction for a glyph */\nexport function getItalicsCorrection(\n\tmath: MathTable,\n\tglyphId: GlyphId,\n): MathValueRecord | null {\n\tconst italics = math.glyphInfo?.italicsCorrection;\n\tif (!italics) return null;\n\n\tconst index = italics.coverage.get(glyphId);\n\tif (index === null) return null;\n\n\treturn italics.values[index] ?? null;\n}\n\n/** Get top accent attachment for a glyph */\nexport function getTopAccentAttachment(\n\tmath: MathTable,\n\tglyphId: GlyphId,\n): MathValueRecord | null {\n\tconst attachment = math.glyphInfo?.topAccentAttachment;\n\tif (!attachment) return null;\n\n\tconst index = attachment.coverage.get(glyphId);\n\tif (index === null) return null;\n\n\treturn attachment.values[index] ?? null;\n}\n\n/** Check if glyph is an extended shape */\nexport function isExtendedShape(math: MathTable, glyphId: GlyphId): boolean {\n\tconst extended = math.glyphInfo?.extendedShapeCoverage;\n\tif (!extended) return false;\n\n\treturn extended.coverage.get(glyphId) !== null;\n}\n\n/** Get vertical glyph variants */\nexport function getVerticalVariants(\n\tmath: MathTable,\n\tglyphId: GlyphId,\n): Array<{ variantGlyph: GlyphId; advanceMeasurement: uint16 }> | null {\n\tconst variants = math.variants;\n\tif (!variants?.vertGlyphCoverage) return null;\n\n\tconst index = variants.vertGlyphCoverage.get(glyphId);\n\tif (index === null) return null;\n\n\treturn variants.vertGlyphConstruction[index]?.variants ?? null;\n}\n\n/** Get horizontal glyph variants */\nexport function getHorizontalVariants(\n\tmath: MathTable,\n\tglyphId: GlyphId,\n): Array<{ variantGlyph: GlyphId; advanceMeasurement: uint16 }> | null {\n\tconst variants = math.variants;\n\tif (!variants?.horizGlyphCoverage) return null;\n\n\tconst index = variants.horizGlyphCoverage.get(glyphId);\n\tif (index === null) return null;\n\n\treturn variants.horizGlyphConstruction[index]?.variants ?? null;\n}\n\n/** Get vertical glyph assembly */\nexport function getVerticalAssembly(\n\tmath: MathTable,\n\tglyphId: GlyphId,\n): GlyphAssembly | null {\n\tconst variants = math.variants;\n\tif (!variants?.vertGlyphCoverage) return null;\n\n\tconst index = variants.vertGlyphCoverage.get(glyphId);\n\tif (index === null) return null;\n\n\treturn variants.vertGlyphConstruction[index]?.glyphAssembly ?? null;\n}\n\n/** Get horizontal glyph assembly */\nexport function getHorizontalAssembly(\n\tmath: MathTable,\n\tglyphId: GlyphId,\n): GlyphAssembly | null {\n\tconst variants = math.variants;\n\tif (!variants?.horizGlyphCoverage) return null;\n\n\tconst index = variants.horizGlyphCoverage.get(glyphId);\n\tif (index === null) return null;\n\n\treturn variants.horizGlyphConstruction[index]?.glyphAssembly ?? null;\n}\n",
51
- "import type { uint16 } from \"../../types.ts\";\nimport type { Reader } from \"../binary/reader.ts\";\n\n/** Maximum profile table (version 0.5 - CFF) */\nexport interface MaxpTable05 {\n\tversion: 0x00005000;\n\tnumGlyphs: uint16;\n}\n\n/** Maximum profile table (version 1.0 - TrueType) */\nexport interface MaxpTable10 {\n\tversion: 0x00010000;\n\tnumGlyphs: uint16;\n\tmaxPoints: uint16;\n\tmaxContours: uint16;\n\tmaxCompositePoints: uint16;\n\tmaxCompositeContours: uint16;\n\tmaxZones: uint16;\n\tmaxTwilightPoints: uint16;\n\tmaxStorage: uint16;\n\tmaxFunctionDefs: uint16;\n\tmaxInstructionDefs: uint16;\n\tmaxStackElements: uint16;\n\tmaxSizeOfInstructions: uint16;\n\tmaxComponentElements: uint16;\n\tmaxComponentDepth: uint16;\n}\n\nexport type MaxpTable = MaxpTable05 | MaxpTable10;\n\nexport function parseMaxp(reader: Reader): MaxpTable {\n\tconst version = reader.uint32();\n\tconst numGlyphs = reader.uint16();\n\n\tif (version === 0x00005000) {\n\t\t// Version 0.5 (CFF fonts)\n\t\treturn { version, numGlyphs };\n\t}\n\n\tif (version === 0x00010000) {\n\t\t// Version 1.0 (TrueType fonts)\n\t\treturn {\n\t\t\tversion,\n\t\t\tnumGlyphs,\n\t\t\tmaxPoints: reader.uint16(),\n\t\t\tmaxContours: reader.uint16(),\n\t\t\tmaxCompositePoints: reader.uint16(),\n\t\t\tmaxCompositeContours: reader.uint16(),\n\t\t\tmaxZones: reader.uint16(),\n\t\t\tmaxTwilightPoints: reader.uint16(),\n\t\t\tmaxStorage: reader.uint16(),\n\t\t\tmaxFunctionDefs: reader.uint16(),\n\t\t\tmaxInstructionDefs: reader.uint16(),\n\t\t\tmaxStackElements: reader.uint16(),\n\t\t\tmaxSizeOfInstructions: reader.uint16(),\n\t\t\tmaxComponentElements: reader.uint16(),\n\t\t\tmaxComponentDepth: reader.uint16(),\n\t\t};\n\t}\n\n\tthrow new Error(`Unknown maxp version: 0x${version.toString(16)}`);\n}\n",
52
- "import type { GlyphId, uint16, uint32 } from \"../../types.ts\";\nimport type { Reader } from \"../binary/reader.ts\";\n\n/**\n * Extended Glyph Metamorphosis table (morx)\n * Apple Advanced Typography substitution\n */\nexport interface MorxTable {\n\tversion: number;\n\tchains: MorxChain[];\n}\n\n/**\n * Feature chain in morx\n */\nexport interface MorxChain {\n\tdefaultFlags: uint32;\n\tfeatures: MorxFeature[];\n\tsubtables: MorxSubtable[];\n}\n\n/**\n * Feature entry\n */\nexport interface MorxFeature {\n\tfeatureType: uint16;\n\tfeatureSetting: uint16;\n\tenableFlags: uint32;\n\tdisableFlags: uint32;\n}\n\n/**\n * Subtable types\n */\nexport enum MorxSubtableType {\n\tRearrangement = 0,\n\tContextual = 1,\n\tLigature = 2,\n\tNonContextual = 4,\n\tInsertion = 5,\n}\n\n/**\n * Base subtable\n */\nexport interface MorxSubtableBase {\n\ttype: MorxSubtableType;\n\tcoverage: MorxCoverage;\n\tsubFeatureFlags: uint32;\n}\n\nexport interface MorxCoverage {\n\tvertical: boolean;\n\tdescending: boolean;\n\tlogical: boolean;\n}\n\nexport type MorxSubtable =\n\t| MorxRearrangementSubtable\n\t| MorxContextualSubtable\n\t| MorxLigatureSubtable\n\t| MorxNonContextualSubtable\n\t| MorxInsertionSubtable;\n\n/**\n * Type 0: Rearrangement (reorders glyphs)\n */\nexport interface MorxRearrangementSubtable extends MorxSubtableBase {\n\ttype: MorxSubtableType.Rearrangement;\n\tstateTable: StateTable<RearrangementEntry>;\n}\n\nexport interface RearrangementEntry {\n\tnewState: uint16;\n\tflags: uint16;\n}\n\n/**\n * Type 1: Contextual substitution\n */\nexport interface MorxContextualSubtable extends MorxSubtableBase {\n\ttype: MorxSubtableType.Contextual;\n\tstateTable: StateTable<ContextualEntry>;\n\tsubstitutionTable: Map<GlyphId, GlyphId>[];\n}\n\nexport interface ContextualEntry {\n\tnewState: uint16;\n\tflags: uint16;\n\tmarkIndex: uint16;\n\tcurrentIndex: uint16;\n}\n\n/**\n * Type 2: Ligature\n */\nexport interface MorxLigatureSubtable extends MorxSubtableBase {\n\ttype: MorxSubtableType.Ligature;\n\tstateTable: StateTable<LigatureEntry>;\n\tligatureActions: uint32[];\n\tcomponents: uint16[];\n\tligatures: GlyphId[];\n}\n\nexport interface LigatureEntry {\n\tnewState: uint16;\n\tflags: uint16;\n\tligActionIndex: uint16;\n}\n\n/**\n * Type 4: Non-contextual (simple substitution)\n */\nexport interface MorxNonContextualSubtable extends MorxSubtableBase {\n\ttype: MorxSubtableType.NonContextual;\n\tlookupTable: LookupTable;\n}\n\n/**\n * Type 5: Insertion\n */\nexport interface MorxInsertionSubtable extends MorxSubtableBase {\n\ttype: MorxSubtableType.Insertion;\n\tstateTable: StateTable<InsertionEntry>;\n\tinsertionGlyphs: GlyphId[];\n}\n\nexport interface InsertionEntry {\n\tnewState: uint16;\n\tflags: uint16;\n\tcurrentInsertIndex: uint16;\n\tmarkedInsertIndex: uint16;\n}\n\n/**\n * State table for state machine processing\n */\nexport interface StateTable<E> {\n\tnClasses: uint32;\n\tclassTable: ClassTable;\n\tstateArray: E[][];\n}\n\n/**\n * Class lookup table\n */\nexport interface ClassTable {\n\tformat: number;\n\tclassArray: number[]; // Maps glyph ID to class\n}\n\n/**\n * Lookup table for substitutions\n */\nexport interface LookupTable {\n\tformat: number;\n\tmapping: Map<GlyphId, GlyphId>;\n}\n\n/**\n * Parse morx table\n */\nexport function parseMorx(reader: Reader): MorxTable {\n\tconst version = reader.uint16();\n\treader.skip(2); // unused\n\n\tif (version < 2) {\n\t\t// Version 1 (mort) - not supported\n\t\treturn { version, chains: [] };\n\t}\n\n\tconst nChains = reader.uint32();\n\tconst chains: MorxChain[] = [];\n\n\tfor (let i = 0; i < nChains; i++) {\n\t\tconst chain = parseMorxChain(reader);\n\t\tchains.push(chain);\n\t}\n\n\treturn { version, chains };\n}\n\nfunction parseMorxChain(reader: Reader): MorxChain {\n\tconst defaultFlags = reader.uint32();\n\tconst _chainLength = reader.uint32();\n\tconst nFeatureEntries = reader.uint32();\n\tconst nSubtables = reader.uint32();\n\n\t// Parse features\n\tconst features: MorxFeature[] = [];\n\tfor (let i = 0; i < nFeatureEntries; i++) {\n\t\tfeatures.push({\n\t\t\tfeatureType: reader.uint16(),\n\t\t\tfeatureSetting: reader.uint16(),\n\t\t\tenableFlags: reader.uint32(),\n\t\t\tdisableFlags: reader.uint32(),\n\t\t});\n\t}\n\n\t// Parse subtables\n\tconst subtables: MorxSubtable[] = [];\n\tfor (let i = 0; i < nSubtables; i++) {\n\t\tconst subtable = parseMorxSubtable(reader);\n\t\tif (subtable) subtables.push(subtable);\n\t}\n\n\treturn { defaultFlags, features, subtables };\n}\n\nfunction parseMorxSubtable(reader: Reader): MorxSubtable | null {\n\tconst length = reader.uint32();\n\tconst coverageBits = reader.uint32();\n\tconst subFeatureFlags = reader.uint32();\n\n\tconst type = coverageBits & 0xff;\n\tconst coverage: MorxCoverage = {\n\t\tvertical: (coverageBits & 0x80000000) !== 0,\n\t\tdescending: (coverageBits & 0x40000000) !== 0,\n\t\tlogical: (coverageBits & 0x10000000) !== 0,\n\t};\n\n\tconst subtableStart = reader.offset;\n\tconst subtableEnd = subtableStart + length - 12;\n\n\tlet subtable: MorxSubtable | null = null;\n\n\tswitch (type) {\n\t\tcase MorxSubtableType.Rearrangement:\n\t\t\tsubtable = parseRearrangementSubtable(reader, coverage, subFeatureFlags);\n\t\t\tbreak;\n\t\tcase MorxSubtableType.Contextual:\n\t\t\tsubtable = parseContextualSubtable(reader, coverage, subFeatureFlags);\n\t\t\tbreak;\n\t\tcase MorxSubtableType.Ligature:\n\t\t\tsubtable = parseLigatureSubtable(reader, coverage, subFeatureFlags);\n\t\t\tbreak;\n\t\tcase MorxSubtableType.NonContextual:\n\t\t\tsubtable = parseNonContextualSubtable(reader, coverage, subFeatureFlags);\n\t\t\tbreak;\n\t\tcase MorxSubtableType.Insertion:\n\t\t\tsubtable = parseInsertionSubtable(reader, coverage, subFeatureFlags);\n\t\t\tbreak;\n\t}\n\n\t// Skip to end of subtable\n\treader.seek(subtableEnd);\n\n\treturn subtable;\n}\n\nfunction parseNonContextualSubtable(\n\treader: Reader,\n\tcoverage: MorxCoverage,\n\tsubFeatureFlags: uint32,\n): MorxNonContextualSubtable {\n\tconst lookupTable = parseLookupTable(reader);\n\n\treturn {\n\t\ttype: MorxSubtableType.NonContextual,\n\t\tcoverage,\n\t\tsubFeatureFlags,\n\t\tlookupTable,\n\t};\n}\n\nfunction parseContextualSubtable(\n\treader: Reader,\n\tcoverage: MorxCoverage,\n\tsubFeatureFlags: uint32,\n): MorxContextualSubtable {\n\tconst stateTableOffset = reader.offset;\n\tconst nClasses = reader.uint32();\n\tconst classTableOffset = reader.offset32();\n\tconst _stateArrayOffset = reader.offset32();\n\tconst _entryTableOffset = reader.offset32();\n\tconst _substitutionTableOffset = reader.offset32();\n\n\t// Parse class table\n\tconst classTable = parseClassTable(\n\t\treader.sliceFrom(stateTableOffset + classTableOffset),\n\t);\n\n\t// Parse state array and entries (simplified)\n\tconst stateTable: StateTable<ContextualEntry> = {\n\t\tnClasses,\n\t\tclassTable,\n\t\tstateArray: [],\n\t};\n\n\tconst substitutionTable: Map<GlyphId, GlyphId>[] = [];\n\n\treturn {\n\t\ttype: MorxSubtableType.Contextual,\n\t\tcoverage,\n\t\tsubFeatureFlags,\n\t\tstateTable,\n\t\tsubstitutionTable,\n\t};\n}\n\nfunction parseLigatureSubtable(\n\treader: Reader,\n\tcoverage: MorxCoverage,\n\tsubFeatureFlags: uint32,\n): MorxLigatureSubtable {\n\tconst stateTableOffset = reader.offset;\n\tconst nClasses = reader.uint32();\n\tconst classTableOffset = reader.offset32();\n\tconst _stateArrayOffset = reader.offset32();\n\tconst _entryTableOffset = reader.offset32();\n\tconst _ligatureActionsOffset = reader.offset32();\n\tconst _componentsOffset = reader.offset32();\n\tconst _ligaturesOffset = reader.offset32();\n\n\t// Parse class table\n\tconst classTable = parseClassTable(\n\t\treader.sliceFrom(stateTableOffset + classTableOffset),\n\t);\n\n\t// State table (simplified)\n\tconst stateTable: StateTable<LigatureEntry> = {\n\t\tnClasses,\n\t\tclassTable,\n\t\tstateArray: [],\n\t};\n\n\treturn {\n\t\ttype: MorxSubtableType.Ligature,\n\t\tcoverage,\n\t\tsubFeatureFlags,\n\t\tstateTable,\n\t\tligatureActions: [],\n\t\tcomponents: [],\n\t\tligatures: [],\n\t};\n}\n\nfunction parseRearrangementSubtable(\n\treader: Reader,\n\tcoverage: MorxCoverage,\n\tsubFeatureFlags: uint32,\n): MorxRearrangementSubtable {\n\tconst stateTableOffset = reader.offset;\n\tconst nClasses = reader.uint32();\n\tconst classTableOffset = reader.offset32();\n\tconst stateArrayOffset = reader.offset32();\n\tconst entryTableOffset = reader.offset32();\n\n\t// Parse class table\n\tconst classTable = parseClassTable(\n\t\treader.sliceFrom(stateTableOffset + classTableOffset),\n\t);\n\n\t// Parse state array\n\tconst stateArrayReader = reader.sliceFrom(\n\t\tstateTableOffset + stateArrayOffset,\n\t);\n\tconst entryReader = reader.sliceFrom(stateTableOffset + entryTableOffset);\n\n\t// Parse entries (each entry is 4 bytes: newState uint16, flags uint16)\n\tconst entries: RearrangementEntry[] = [];\n\tconst entryCount = 256; // Reasonable max\n\tfor (let i = 0; i < entryCount; i++) {\n\t\tentries.push({\n\t\t\tnewState: entryReader.uint16(),\n\t\t\tflags: entryReader.uint16(),\n\t\t});\n\t}\n\n\t// Build state array\n\tconst stateArray: RearrangementEntry[][] = [];\n\tconst stateCount = Math.min(\n\t\t256,\n\t\tMath.ceil((entryTableOffset - stateArrayOffset) / (nClasses * 2)),\n\t);\n\tfor (let s = 0; s < stateCount; s++) {\n\t\tconst row: RearrangementEntry[] = [];\n\t\tfor (let c = 0; c < nClasses; c++) {\n\t\t\tconst entryIndex = stateArrayReader.uint16();\n\t\t\trow.push(entries[entryIndex] ?? { newState: 0, flags: 0 });\n\t\t}\n\t\tstateArray.push(row);\n\t}\n\n\treturn {\n\t\ttype: MorxSubtableType.Rearrangement,\n\t\tcoverage,\n\t\tsubFeatureFlags,\n\t\tstateTable: {\n\t\t\tnClasses,\n\t\t\tclassTable,\n\t\t\tstateArray,\n\t\t},\n\t};\n}\n\nfunction parseInsertionSubtable(\n\treader: Reader,\n\tcoverage: MorxCoverage,\n\tsubFeatureFlags: uint32,\n): MorxInsertionSubtable {\n\tconst stateTableOffset = reader.offset;\n\tconst nClasses = reader.uint32();\n\tconst classTableOffset = reader.offset32();\n\tconst stateArrayOffset = reader.offset32();\n\tconst entryTableOffset = reader.offset32();\n\tconst insertionActionOffset = reader.offset32();\n\n\t// Parse class table\n\tconst classTable = parseClassTable(\n\t\treader.sliceFrom(stateTableOffset + classTableOffset),\n\t);\n\n\t// Parse insertion glyphs array\n\tconst insertionReader = reader.sliceFrom(\n\t\tstateTableOffset + insertionActionOffset,\n\t);\n\tconst insertionGlyphs: GlyphId[] = [];\n\t// Read a reasonable number of insertion glyphs\n\tconst maxInsertionGlyphs = 1024;\n\tfor (let i = 0; i < maxInsertionGlyphs; i++) {\n\t\ttry {\n\t\t\tinsertionGlyphs.push(insertionReader.uint16());\n\t\t} catch {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Parse entries\n\tconst entryReader = reader.sliceFrom(stateTableOffset + entryTableOffset);\n\tconst entries: InsertionEntry[] = [];\n\tconst entryCount = 256;\n\tfor (let i = 0; i < entryCount; i++) {\n\t\tentries.push({\n\t\t\tnewState: entryReader.uint16(),\n\t\t\tflags: entryReader.uint16(),\n\t\t\tcurrentInsertIndex: entryReader.uint16(),\n\t\t\tmarkedInsertIndex: entryReader.uint16(),\n\t\t});\n\t}\n\n\t// Build state array\n\tconst stateArrayReader = reader.sliceFrom(\n\t\tstateTableOffset + stateArrayOffset,\n\t);\n\tconst stateArray: InsertionEntry[][] = [];\n\tconst stateCount = Math.min(\n\t\t256,\n\t\tMath.ceil((entryTableOffset - stateArrayOffset) / (nClasses * 2)),\n\t);\n\tfor (let s = 0; s < stateCount; s++) {\n\t\tconst row: InsertionEntry[] = [];\n\t\tfor (let c = 0; c < nClasses; c++) {\n\t\t\tconst entryIndex = stateArrayReader.uint16();\n\t\t\trow.push(\n\t\t\t\tentries[entryIndex] ?? {\n\t\t\t\t\tnewState: 0,\n\t\t\t\t\tflags: 0,\n\t\t\t\t\tcurrentInsertIndex: 0xffff,\n\t\t\t\t\tmarkedInsertIndex: 0xffff,\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\t\tstateArray.push(row);\n\t}\n\n\treturn {\n\t\ttype: MorxSubtableType.Insertion,\n\t\tcoverage,\n\t\tsubFeatureFlags,\n\t\tstateTable: {\n\t\t\tnClasses,\n\t\t\tclassTable,\n\t\t\tstateArray,\n\t\t},\n\t\tinsertionGlyphs,\n\t};\n}\n\nfunction parseLookupTable(reader: Reader): LookupTable {\n\tconst format = reader.uint16();\n\tconst mapping = new Map<GlyphId, GlyphId>();\n\n\tswitch (format) {\n\t\tcase 0: {\n\t\t\t// Simple array\n\t\t\t// Format 0 uses lookup by glyph index directly\n\t\t\tbreak;\n\t\t}\n\t\tcase 2: {\n\t\t\t// Segment single\n\t\t\tconst _unitSize = reader.uint16();\n\t\t\tconst nUnits = reader.uint16();\n\t\t\treader.skip(6); // searchRange, entrySelector, rangeShift\n\n\t\t\tfor (let i = 0; i < nUnits; i++) {\n\t\t\t\tconst lastGlyph = reader.uint16();\n\t\t\t\tconst firstGlyph = reader.uint16();\n\t\t\t\tconst value = reader.uint16();\n\n\t\t\t\tfor (let g = firstGlyph; g <= lastGlyph; g++) {\n\t\t\t\t\tmapping.set(g, value);\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase 4: {\n\t\t\t// Segment array\n\t\t\tconst _unitSize = reader.uint16();\n\t\t\tconst nUnits = reader.uint16();\n\t\t\treader.skip(6);\n\n\t\t\tfor (let i = 0; i < nUnits; i++) {\n\t\t\t\tconst _lastGlyph = reader.uint16();\n\t\t\t\tconst _firstGlyph = reader.uint16();\n\t\t\t\tconst _valueOffset = reader.uint16();\n\n\t\t\t\t// Values would be read from valueOffset\n\t\t\t\t// Simplified: skip for now\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase 6: {\n\t\t\t// Single table\n\t\t\tconst _unitSize = reader.uint16();\n\t\t\tconst nUnits = reader.uint16();\n\t\t\treader.skip(6);\n\n\t\t\tfor (let i = 0; i < nUnits; i++) {\n\t\t\t\tconst glyph = reader.uint16();\n\t\t\t\tconst value = reader.uint16();\n\t\t\t\tmapping.set(glyph, value);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase 8: {\n\t\t\t// Trimmed array\n\t\t\tconst firstGlyph = reader.uint16();\n\t\t\tconst glyphCount = reader.uint16();\n\n\t\t\tfor (let i = 0; i < glyphCount; i++) {\n\t\t\t\tconst value = reader.uint16();\n\t\t\t\tif (value !== 0) {\n\t\t\t\t\tmapping.set(firstGlyph + i, value);\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn { format, mapping };\n}\n\nfunction parseClassTable(reader: Reader): ClassTable {\n\tconst format = reader.uint16();\n\tconst classArray: number[] = [];\n\n\tif (format === 2) {\n\t\t// Binary search segments\n\t\tconst _unitSize = reader.uint16();\n\t\tconst nUnits = reader.uint16();\n\t\treader.skip(6);\n\n\t\tconst segments: { first: number; last: number; classValue: number }[] = [];\n\t\tfor (let i = 0; i < nUnits; i++) {\n\t\t\tsegments.push({\n\t\t\t\tlast: reader.uint16(),\n\t\t\t\tfirst: reader.uint16(),\n\t\t\t\tclassValue: reader.uint16(),\n\t\t\t});\n\t\t}\n\n\t\t// Build class array (simplified, might be large)\n\t\tconst maxGlyph = Math.max(...segments.map((s) => s.last), 0);\n\t\tfor (let g = 0; g <= maxGlyph; g++) {\n\t\t\tconst seg = segments.find((s) => g >= s.first && g <= s.last);\n\t\t\tclassArray[g] = seg?.classValue ?? 1; // Class 1 = out of bounds\n\t\t}\n\t}\n\n\treturn { format, classArray };\n}\n\n/**\n * Apply non-contextual substitution\n */\nexport function applyNonContextual(\n\tsubtable: MorxNonContextualSubtable,\n\tglyphId: GlyphId,\n): GlyphId | null {\n\treturn subtable.lookupTable.mapping.get(glyphId) ?? null;\n}\n",
53
- "import type { Tag, uint16, uint32 } from \"../../types.ts\";\nimport { tag } from \"../../types.ts\";\nimport type { Reader } from \"../binary/reader.ts\";\nimport {\n\tcalculateRegionScalar,\n\ttype ItemVariationStore,\n\ttype VariationRegion,\n} from \"./hvar.ts\";\n\n/**\n * Metrics Variations table (MVAR)\n * Provides variations for global font metrics\n */\nexport interface MvarTable {\n\tmajorVersion: number;\n\tminorVersion: number;\n\titemVariationStore: ItemVariationStore;\n\tvalueRecords: MvarValueRecord[];\n}\n\nexport interface MvarValueRecord {\n\tvalueTag: Tag;\n\tdeltaSetOuterIndex: number;\n\tdeltaSetInnerIndex: number;\n}\n\n/**\n * Common MVAR value tags\n */\nexport const MvarTags = {\n\t// Horizontal metrics\n\thasc: tag(\"hasc\"), // horizontal ascender\n\thdsc: tag(\"hdsc\"), // horizontal descender\n\thlgp: tag(\"hlgp\"), // horizontal line gap\n\thcla: tag(\"hcla\"), // horizontal clipping ascent\n\thcld: tag(\"hcld\"), // horizontal clipping descent\n\thcof: tag(\"hcof\"), // horizontal caret offset\n\thcrn: tag(\"hcrn\"), // horizontal caret run\n\thcrs: tag(\"hcrs\"), // horizontal caret rise\n\n\t// Vertical metrics\n\tvasc: tag(\"vasc\"), // vertical ascender\n\tvdsc: tag(\"vdsc\"), // vertical descender\n\tvlgp: tag(\"vlgp\"), // vertical line gap\n\tvcof: tag(\"vcof\"), // vertical caret offset\n\tvcrn: tag(\"vcrn\"), // vertical caret run\n\tvcrs: tag(\"vcrs\"), // vertical caret rise\n\n\t// OS/2 table values\n\txhgt: tag(\"xhgt\"), // x height\n\tcpht: tag(\"cpht\"), // cap height\n\tsbxs: tag(\"sbxs\"), // subscript x size\n\tsbys: tag(\"sbys\"), // subscript y size\n\tsbxo: tag(\"sbxo\"), // subscript x offset\n\tsbyo: tag(\"sbyo\"), // subscript y offset\n\tspxs: tag(\"spxs\"), // superscript x size\n\tspys: tag(\"spys\"), // superscript y size\n\tspxo: tag(\"spxo\"), // superscript x offset\n\tspyo: tag(\"spyo\"), // superscript y offset\n\tstrs: tag(\"strs\"), // strikeout size\n\tstro: tag(\"stro\"), // strikeout offset\n\tundo: tag(\"undo\"), // underline offset\n\tunds: tag(\"unds\"), // underline size\n\n\t// Glyph bounds\n\tgsp0: tag(\"gsp0\"), // glyph bounding box x min\n\tgsp1: tag(\"gsp1\"), // glyph bounding box y min\n\tgsp2: tag(\"gsp2\"), // glyph bounding box x max\n\tgsp3: tag(\"gsp3\"), // glyph bounding box y max\n} as const;\n\n/**\n * Parse MVAR table\n */\nexport function parseMvar(reader: Reader): MvarTable {\n\tconst majorVersion = reader.uint16();\n\tconst minorVersion = reader.uint16();\n\treader.uint16(); // reserved\n\tconst valueRecordSize = reader.uint16();\n\tconst valueRecordCount = reader.uint16();\n\tconst itemVariationStoreOffset = reader.offset16();\n\n\t// Parse value records\n\tconst valueRecords: MvarValueRecord[] = [];\n\tfor (let i = 0; i < valueRecordCount; i++) {\n\t\tvalueRecords.push({\n\t\t\tvalueTag: reader.tag(),\n\t\t\tdeltaSetOuterIndex: reader.uint16(),\n\t\t\tdeltaSetInnerIndex: reader.uint16(),\n\t\t});\n\t\t// Skip any additional bytes if valueRecordSize > 8\n\t\tif (valueRecordSize > 8) {\n\t\t\treader.skip(valueRecordSize - 8);\n\t\t}\n\t}\n\n\t// Parse item variation store\n\tconst itemVariationStore = parseItemVariationStore(\n\t\treader.sliceFrom(itemVariationStoreOffset),\n\t);\n\n\treturn {\n\t\tmajorVersion,\n\t\tminorVersion,\n\t\titemVariationStore,\n\t\tvalueRecords,\n\t};\n}\n\nfunction parseItemVariationStore(reader: Reader): ItemVariationStore {\n\tconst format = reader.uint16();\n\tconst variationRegionListOffset = reader.offset32();\n\tconst itemVariationDataCount = reader.uint16();\n\n\tconst itemVariationDataOffsets: uint32[] = [];\n\tfor (let i = 0; i < itemVariationDataCount; i++) {\n\t\titemVariationDataOffsets.push(reader.offset32());\n\t}\n\n\t// Parse variation regions\n\tconst regionReader = reader.sliceFrom(variationRegionListOffset);\n\tconst axisCount = regionReader.uint16();\n\tconst regionCount = regionReader.uint16();\n\n\tconst variationRegions: VariationRegion[] = [];\n\tfor (let i = 0; i < regionCount; i++) {\n\t\tconst regionAxes: {\n\t\t\tstartCoord: number;\n\t\t\tpeakCoord: number;\n\t\t\tendCoord: number;\n\t\t}[] = [];\n\t\tfor (let j = 0; j < axisCount; j++) {\n\t\t\tregionAxes.push({\n\t\t\t\tstartCoord: regionReader.f2dot14(),\n\t\t\t\tpeakCoord: regionReader.f2dot14(),\n\t\t\t\tendCoord: regionReader.f2dot14(),\n\t\t\t});\n\t\t}\n\t\tvariationRegions.push({ regionAxes });\n\t}\n\n\t// Parse item variation data\n\tconst itemVariationData: {\n\t\titemCount: uint16;\n\t\tregionIndexes: uint16[];\n\t\tdeltaSets: number[][];\n\t}[] = [];\n\tfor (const offset of itemVariationDataOffsets) {\n\t\tconst dataReader = reader.sliceFrom(offset);\n\t\tconst itemCount = dataReader.uint16();\n\t\tconst wordDeltaCount = dataReader.uint16();\n\t\tconst regionIndexCount = dataReader.uint16();\n\n\t\tconst regionIndexes: uint16[] = [];\n\t\tfor (let i = 0; i < regionIndexCount; i++) {\n\t\t\tregionIndexes.push(dataReader.uint16());\n\t\t}\n\n\t\t// Parse delta sets\n\t\tconst longWords = (wordDeltaCount & 0x8000) !== 0;\n\t\tconst wordCount = wordDeltaCount & 0x7fff;\n\t\tconst shortCount = regionIndexCount - wordCount;\n\n\t\tconst deltaSets: number[][] = [];\n\t\tfor (let i = 0; i < itemCount; i++) {\n\t\t\tconst deltas: number[] = [];\n\t\t\t// Read word-sized deltas\n\t\t\tfor (let j = 0; j < wordCount; j++) {\n\t\t\t\tif (longWords) {\n\t\t\t\t\tdeltas.push(dataReader.int32());\n\t\t\t\t} else {\n\t\t\t\t\tdeltas.push(dataReader.int16());\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Read short-sized deltas\n\t\t\tfor (let j = 0; j < shortCount; j++) {\n\t\t\t\tif (longWords) {\n\t\t\t\t\tdeltas.push(dataReader.int16());\n\t\t\t\t} else {\n\t\t\t\t\tdeltas.push(dataReader.int8());\n\t\t\t\t}\n\t\t\t}\n\t\t\tdeltaSets.push(deltas);\n\t\t}\n\n\t\titemVariationData.push({ itemCount, regionIndexes, deltaSets });\n\t}\n\n\treturn { format, variationRegions, itemVariationData };\n}\n\n/**\n * Get metric delta by tag\n */\nexport function getMetricDelta(\n\tmvar: MvarTable,\n\tvalueTag: Tag,\n\tcoords: number[],\n): number {\n\t// Find value record for this tag\n\tconst record = mvar.valueRecords.find((r) => r.valueTag === valueTag);\n\tif (!record) return 0;\n\n\tconst outer = record.deltaSetOuterIndex;\n\tconst inner = record.deltaSetInnerIndex;\n\n\tconst varData = mvar.itemVariationStore.itemVariationData[outer];\n\tif (!varData || inner >= varData.itemCount) {\n\t\treturn 0;\n\t}\n\n\tconst deltaSet = varData.deltaSets[inner];\n\tif (!deltaSet) {\n\t\treturn 0;\n\t}\n\n\t// Calculate total delta\n\tlet delta = 0;\n\tfor (const [i, regionIndex] of varData.regionIndexes.entries()) {\n\t\tconst region = mvar.itemVariationStore.variationRegions[regionIndex];\n\t\tif (!region) continue;\n\n\t\tconst scalar = calculateRegionScalar(region, coords);\n\t\tconst regionDelta = deltaSet[i] ?? 0;\n\t\tdelta += scalar * regionDelta;\n\t}\n\n\treturn Math.round(delta);\n}\n\n/**\n * Get horizontal ascender delta\n */\nexport function getHAscenderDelta(mvar: MvarTable, coords: number[]): number {\n\treturn getMetricDelta(mvar, MvarTags.hasc, coords);\n}\n\n/**\n * Get horizontal descender delta\n */\nexport function getHDescenderDelta(mvar: MvarTable, coords: number[]): number {\n\treturn getMetricDelta(mvar, MvarTags.hdsc, coords);\n}\n\n/**\n * Get horizontal line gap delta\n */\nexport function getHLineGapDelta(mvar: MvarTable, coords: number[]): number {\n\treturn getMetricDelta(mvar, MvarTags.hlgp, coords);\n}\n\n/**\n * Get x-height delta\n */\nexport function getXHeightDelta(mvar: MvarTable, coords: number[]): number {\n\treturn getMetricDelta(mvar, MvarTags.xhgt, coords);\n}\n\n/**\n * Get cap height delta\n */\nexport function getCapHeightDelta(mvar: MvarTable, coords: number[]): number {\n\treturn getMetricDelta(mvar, MvarTags.cpht, coords);\n}\n\n/**\n * Get underline offset delta\n */\nexport function getUnderlineOffsetDelta(\n\tmvar: MvarTable,\n\tcoords: number[],\n): number {\n\treturn getMetricDelta(mvar, MvarTags.undo, coords);\n}\n\n/**\n * Get underline size delta\n */\nexport function getUnderlineSizeDelta(\n\tmvar: MvarTable,\n\tcoords: number[],\n): number {\n\treturn getMetricDelta(mvar, MvarTags.unds, coords);\n}\n\n/**\n * Get strikeout offset delta\n */\nexport function getStrikeoutOffsetDelta(\n\tmvar: MvarTable,\n\tcoords: number[],\n): number {\n\treturn getMetricDelta(mvar, MvarTags.stro, coords);\n}\n\n/**\n * Get strikeout size delta\n */\nexport function getStrikeoutSizeDelta(\n\tmvar: MvarTable,\n\tcoords: number[],\n): number {\n\treturn getMetricDelta(mvar, MvarTags.strs, coords);\n}\n",
54
- "import type { uint16 } from \"../../types.ts\";\nimport type { Reader } from \"../binary/reader.ts\";\n\n/** Name IDs */\nexport const NameId = {\n\tCopyright: 0,\n\tFontFamily: 1,\n\tFontSubfamily: 2,\n\tUniqueID: 3,\n\tFullName: 4,\n\tVersion: 5,\n\tPostScriptName: 6,\n\tTrademark: 7,\n\tManufacturer: 8,\n\tDesigner: 9,\n\tDescription: 10,\n\tManufacturerURL: 11,\n\tDesignerURL: 12,\n\tLicense: 13,\n\tLicenseURL: 14,\n\tReserved: 15,\n\tTypographicFamily: 16,\n\tTypographicSubfamily: 17,\n\tCompatibleFullName: 18,\n\tSampleText: 19,\n\tPostScriptCIDFindfontName: 20,\n\tWWSFamily: 21,\n\tWWSSubfamily: 22,\n\tLightBackgroundPalette: 23,\n\tDarkBackgroundPalette: 24,\n\tVariationsPostScriptNamePrefix: 25,\n} as const;\n\n/** Platform IDs */\nexport const PlatformId = {\n\tUnicode: 0,\n\tMacintosh: 1,\n\tReserved: 2,\n\tWindows: 3,\n} as const;\n\n/** Windows encoding IDs */\nexport const WindowsEncodingId = {\n\tSymbol: 0,\n\tUnicodeBMP: 1,\n\tShiftJIS: 2,\n\tPRC: 3,\n\tBig5: 4,\n\tWansung: 5,\n\tJohab: 6,\n\tUnicodeFullRepertoire: 10,\n} as const;\n\n/** A single name record */\nexport interface NameRecord {\n\tplatformId: uint16;\n\tencodingId: uint16;\n\tlanguageId: uint16;\n\tnameId: uint16;\n\tvalue: string;\n}\n\n/** Name table */\nexport interface NameTable {\n\tformat: uint16;\n\trecords: NameRecord[];\n}\n\nexport function parseName(reader: Reader): NameTable {\n\tconst format = reader.uint16();\n\tconst count = reader.uint16();\n\tconst stringOffset = reader.uint16();\n\n\tconst records: NameRecord[] = [];\n\n\t// Parse name records\n\tconst recordData: Array<{\n\t\tplatformId: uint16;\n\t\tencodingId: uint16;\n\t\tlanguageId: uint16;\n\t\tnameId: uint16;\n\t\tlength: uint16;\n\t\toffset: uint16;\n\t}> = [];\n\n\tfor (let i = 0; i < count; i++) {\n\t\trecordData.push({\n\t\t\tplatformId: reader.uint16(),\n\t\t\tencodingId: reader.uint16(),\n\t\t\tlanguageId: reader.uint16(),\n\t\t\tnameId: reader.uint16(),\n\t\t\tlength: reader.uint16(),\n\t\t\toffset: reader.uint16(),\n\t\t});\n\t}\n\n\t// Decode strings\n\tfor (const rd of recordData) {\n\t\tconst strReader = reader.sliceFrom(stringOffset + rd.offset);\n\t\tconst value = decodeNameString(\n\t\t\tstrReader,\n\t\t\trd.length,\n\t\t\trd.platformId,\n\t\t\trd.encodingId,\n\t\t);\n\n\t\tif (value !== null) {\n\t\t\trecords.push({\n\t\t\t\tplatformId: rd.platformId,\n\t\t\t\tencodingId: rd.encodingId,\n\t\t\t\tlanguageId: rd.languageId,\n\t\t\t\tnameId: rd.nameId,\n\t\t\t\tvalue,\n\t\t\t});\n\t\t}\n\t}\n\n\treturn { format, records };\n}\n\n/** Decode name string based on platform and encoding */\nfunction decodeNameString(\n\treader: Reader,\n\tlength: number,\n\tplatformId: number,\n\tencodingId: number,\n): string | null {\n\t// Unicode platform or Windows platform with Unicode encoding\n\tif (\n\t\tplatformId === PlatformId.Unicode ||\n\t\t(platformId === PlatformId.Windows &&\n\t\t\t(encodingId === 1 || encodingId === 10))\n\t) {\n\t\t// UTF-16BE\n\t\tconst chars: string[] = [];\n\t\tfor (let i = 0; i < length; i += 2) {\n\t\t\tconst code = reader.uint16();\n\t\t\tchars.push(String.fromCharCode(code));\n\t\t}\n\t\treturn chars.join(\"\");\n\t}\n\n\t// Macintosh Roman (basic ASCII-compatible)\n\tif (platformId === PlatformId.Macintosh && encodingId === 0) {\n\t\tconst bytes: number[] = [];\n\t\tfor (let i = 0; i < length; i++) {\n\t\t\tbytes.push(reader.uint8());\n\t\t}\n\t\t// Simple ASCII decoding for Mac Roman (limited support)\n\t\treturn String.fromCharCode(...bytes);\n\t}\n\n\t// Skip unsupported encodings\n\treturn null;\n}\n\n/** Get a specific name by ID, preferring Windows Unicode */\nexport function getNameById(\n\ttable: NameTable,\n\tnameId: number,\n\tlanguageId?: number,\n): string | null {\n\t// Prefer Windows Unicode (platform 3, encoding 1)\n\tfor (const record of table.records) {\n\t\tif (record.nameId !== nameId) continue;\n\t\tif (record.platformId === PlatformId.Windows && record.encodingId === 1) {\n\t\t\tif (languageId === undefined || record.languageId === languageId) {\n\t\t\t\treturn record.value;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Fallback to Unicode platform\n\tfor (const record of table.records) {\n\t\tif (record.nameId !== nameId) continue;\n\t\tif (record.platformId === PlatformId.Unicode) {\n\t\t\tif (languageId === undefined || record.languageId === languageId) {\n\t\t\t\treturn record.value;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Fallback to any platform\n\tfor (const record of table.records) {\n\t\tif (record.nameId !== nameId) continue;\n\t\tif (languageId === undefined || record.languageId === languageId) {\n\t\t\treturn record.value;\n\t\t}\n\t}\n\n\treturn null;\n}\n\n/** Get font family name */\nexport function getFontFamily(table: NameTable): string | null {\n\t// Prefer typographic family (16) over basic family (1)\n\treturn (\n\t\tgetNameById(table, NameId.TypographicFamily) ??\n\t\tgetNameById(table, NameId.FontFamily)\n\t);\n}\n\n/** Get font subfamily (style) */\nexport function getFontSubfamily(table: NameTable): string | null {\n\treturn (\n\t\tgetNameById(table, NameId.TypographicSubfamily) ??\n\t\tgetNameById(table, NameId.FontSubfamily)\n\t);\n}\n\n/** Get full font name */\nexport function getFullName(table: NameTable): string | null {\n\treturn getNameById(table, NameId.FullName);\n}\n\n/** Get PostScript name */\nexport function getPostScriptName(table: NameTable): string | null {\n\treturn getNameById(table, NameId.PostScriptName);\n}\n\n/** Get version string */\nexport function getVersion(table: NameTable): string | null {\n\treturn getNameById(table, NameId.Version);\n}\n",
55
- "import type { int16, uint8, uint16, uint32 } from \"../../types.ts\";\nimport type { Reader } from \"../binary/reader.ts\";\n\n/**\n * OS/2 table - Font metrics and classification\n * Contains Windows-specific metrics and font embedding information\n */\nexport interface Os2Table {\n\tversion: uint16;\n\txAvgCharWidth: int16;\n\tusWeightClass: uint16;\n\tusWidthClass: uint16;\n\tfsType: uint16;\n\tySubscriptXSize: int16;\n\tySubscriptYSize: int16;\n\tySubscriptXOffset: int16;\n\tySubscriptYOffset: int16;\n\tySuperscriptXSize: int16;\n\tySuperscriptYSize: int16;\n\tySuperscriptXOffset: int16;\n\tySuperscriptYOffset: int16;\n\tyStrikeoutSize: int16;\n\tyStrikeoutPosition: int16;\n\tsFamilyClass: int16;\n\tpanose: uint8[];\n\tulUnicodeRange1: uint32;\n\tulUnicodeRange2: uint32;\n\tulUnicodeRange3: uint32;\n\tulUnicodeRange4: uint32;\n\tachVendID: string;\n\tfsSelection: uint16;\n\tusFirstCharIndex: uint16;\n\tusLastCharIndex: uint16;\n\tsTypoAscender: int16;\n\tsTypoDescender: int16;\n\tsTypoLineGap: int16;\n\tusWinAscent: uint16;\n\tusWinDescent: uint16;\n\t// Version 1+\n\tulCodePageRange1?: uint32;\n\tulCodePageRange2?: uint32;\n\t// Version 2+\n\tsxHeight?: int16;\n\tsCapHeight?: int16;\n\tusDefaultChar?: uint16;\n\tusBreakChar?: uint16;\n\tusMaxContext?: uint16;\n\t// Version 5+\n\tusLowerOpticalPointSize?: uint16;\n\tusUpperOpticalPointSize?: uint16;\n}\n\n/** Weight class constants */\nexport const WeightClass = {\n\tThin: 100,\n\tExtraLight: 200,\n\tLight: 300,\n\tNormal: 400,\n\tMedium: 500,\n\tSemiBold: 600,\n\tBold: 700,\n\tExtraBold: 800,\n\tBlack: 900,\n} as const;\n\n/** Width class constants */\nexport const WidthClass = {\n\tUltraCondensed: 1,\n\tExtraCondensed: 2,\n\tCondensed: 3,\n\tSemiCondensed: 4,\n\tNormal: 5,\n\tSemiExpanded: 6,\n\tExpanded: 7,\n\tExtraExpanded: 8,\n\tUltraExpanded: 9,\n} as const;\n\n/** Font selection flags (fsSelection) */\nexport const FsSelection = {\n\tItalic: 0x0001,\n\tUnderscore: 0x0002,\n\tNegative: 0x0004,\n\tOutlined: 0x0008,\n\tStrikeout: 0x0010,\n\tBold: 0x0020,\n\tRegular: 0x0040,\n\tUseTypoMetrics: 0x0080,\n\tWWS: 0x0100,\n\tOblique: 0x0200,\n} as const;\n\n/** Font embedding permissions (fsType) */\nexport const FsType = {\n\tInstallableEmbedding: 0x0000,\n\tRestrictedLicense: 0x0002,\n\tPreviewAndPrint: 0x0004,\n\tEditable: 0x0008,\n\tNoSubsetting: 0x0100,\n\tBitmapOnly: 0x0200,\n} as const;\n\nexport function parseOs2(reader: Reader): Os2Table {\n\tconst version = reader.uint16();\n\tconst xAvgCharWidth = reader.int16();\n\tconst usWeightClass = reader.uint16();\n\tconst usWidthClass = reader.uint16();\n\tconst fsType = reader.uint16();\n\tconst ySubscriptXSize = reader.int16();\n\tconst ySubscriptYSize = reader.int16();\n\tconst ySubscriptXOffset = reader.int16();\n\tconst ySubscriptYOffset = reader.int16();\n\tconst ySuperscriptXSize = reader.int16();\n\tconst ySuperscriptYSize = reader.int16();\n\tconst ySuperscriptXOffset = reader.int16();\n\tconst ySuperscriptYOffset = reader.int16();\n\tconst yStrikeoutSize = reader.int16();\n\tconst yStrikeoutPosition = reader.int16();\n\tconst sFamilyClass = reader.int16();\n\n\t// PANOSE classification (10 bytes)\n\tconst panose: uint8[] = [];\n\tfor (let i = 0; i < 10; i++) {\n\t\tpanose.push(reader.uint8());\n\t}\n\n\tconst ulUnicodeRange1 = reader.uint32();\n\tconst ulUnicodeRange2 = reader.uint32();\n\tconst ulUnicodeRange3 = reader.uint32();\n\tconst ulUnicodeRange4 = reader.uint32();\n\n\t// Vendor ID (4 bytes as ASCII)\n\tconst achVendID = String.fromCharCode(\n\t\treader.uint8(),\n\t\treader.uint8(),\n\t\treader.uint8(),\n\t\treader.uint8(),\n\t);\n\n\tconst fsSelection = reader.uint16();\n\tconst usFirstCharIndex = reader.uint16();\n\tconst usLastCharIndex = reader.uint16();\n\tconst sTypoAscender = reader.int16();\n\tconst sTypoDescender = reader.int16();\n\tconst sTypoLineGap = reader.int16();\n\tconst usWinAscent = reader.uint16();\n\tconst usWinDescent = reader.uint16();\n\n\tconst result: Os2Table = {\n\t\tversion,\n\t\txAvgCharWidth,\n\t\tusWeightClass,\n\t\tusWidthClass,\n\t\tfsType,\n\t\tySubscriptXSize,\n\t\tySubscriptYSize,\n\t\tySubscriptXOffset,\n\t\tySubscriptYOffset,\n\t\tySuperscriptXSize,\n\t\tySuperscriptYSize,\n\t\tySuperscriptXOffset,\n\t\tySuperscriptYOffset,\n\t\tyStrikeoutSize,\n\t\tyStrikeoutPosition,\n\t\tsFamilyClass,\n\t\tpanose,\n\t\tulUnicodeRange1,\n\t\tulUnicodeRange2,\n\t\tulUnicodeRange3,\n\t\tulUnicodeRange4,\n\t\tachVendID,\n\t\tfsSelection,\n\t\tusFirstCharIndex,\n\t\tusLastCharIndex,\n\t\tsTypoAscender,\n\t\tsTypoDescender,\n\t\tsTypoLineGap,\n\t\tusWinAscent,\n\t\tusWinDescent,\n\t};\n\n\t// Version 1+ fields\n\tif (version >= 1) {\n\t\tresult.ulCodePageRange1 = reader.uint32();\n\t\tresult.ulCodePageRange2 = reader.uint32();\n\t}\n\n\t// Version 2+ fields\n\tif (version >= 2) {\n\t\tresult.sxHeight = reader.int16();\n\t\tresult.sCapHeight = reader.int16();\n\t\tresult.usDefaultChar = reader.uint16();\n\t\tresult.usBreakChar = reader.uint16();\n\t\tresult.usMaxContext = reader.uint16();\n\t}\n\n\t// Version 5+ fields\n\tif (version >= 5) {\n\t\tresult.usLowerOpticalPointSize = reader.uint16();\n\t\tresult.usUpperOpticalPointSize = reader.uint16();\n\t}\n\n\treturn result;\n}\n\n/** Check if font is italic */\nexport function isItalic(os2: Os2Table): boolean {\n\treturn (os2.fsSelection & FsSelection.Italic) !== 0;\n}\n\n/** Check if font is bold */\nexport function isBold(os2: Os2Table): boolean {\n\treturn (os2.fsSelection & FsSelection.Bold) !== 0;\n}\n\n/** Check if USE_TYPO_METRICS flag is set */\nexport function useTypoMetrics(os2: Os2Table): boolean {\n\treturn (os2.fsSelection & FsSelection.UseTypoMetrics) !== 0;\n}\n\n/** Get embedding permission level */\nexport function getEmbeddingPermission(\n\tos2: Os2Table,\n): \"installable\" | \"restricted\" | \"preview\" | \"editable\" {\n\tconst fsType = os2.fsType;\n\tif ((fsType & FsType.RestrictedLicense) !== 0) return \"restricted\";\n\tif ((fsType & FsType.PreviewAndPrint) !== 0) return \"preview\";\n\tif ((fsType & FsType.Editable) !== 0) return \"editable\";\n\treturn \"installable\";\n}\n",
56
- "import type { int16, uint16, uint32 } from \"../../types.ts\";\nimport type { Reader } from \"../binary/reader.ts\";\n\n/**\n * post table - PostScript font information\n * Contains additional PostScript info like glyph names and italic angle\n */\nexport interface PostTable {\n\tversion: number;\n\titalicAngle: number;\n\tunderlinePosition: int16;\n\tunderlineThickness: int16;\n\tisFixedPitch: uint32;\n\tminMemType42: uint32;\n\tmaxMemType42: uint32;\n\tminMemType1: uint32;\n\tmaxMemType1: uint32;\n\t// Version 2.0 only\n\tnumberOfGlyphs?: uint16;\n\tglyphNameIndex?: uint16[];\n\tnames?: string[];\n}\n\n/** Standard PostScript glyph names (first 258) */\nconst standardNames: string[] = [\n\t\".notdef\",\n\t\".null\",\n\t\"nonmarkingreturn\",\n\t\"space\",\n\t\"exclam\",\n\t\"quotedbl\",\n\t\"numbersign\",\n\t\"dollar\",\n\t\"percent\",\n\t\"ampersand\",\n\t\"quotesingle\",\n\t\"parenleft\",\n\t\"parenright\",\n\t\"asterisk\",\n\t\"plus\",\n\t\"comma\",\n\t\"hyphen\",\n\t\"period\",\n\t\"slash\",\n\t\"zero\",\n\t\"one\",\n\t\"two\",\n\t\"three\",\n\t\"four\",\n\t\"five\",\n\t\"six\",\n\t\"seven\",\n\t\"eight\",\n\t\"nine\",\n\t\"colon\",\n\t\"semicolon\",\n\t\"less\",\n\t\"equal\",\n\t\"greater\",\n\t\"question\",\n\t\"at\",\n\t\"A\",\n\t\"B\",\n\t\"C\",\n\t\"D\",\n\t\"E\",\n\t\"F\",\n\t\"G\",\n\t\"H\",\n\t\"I\",\n\t\"J\",\n\t\"K\",\n\t\"L\",\n\t\"M\",\n\t\"N\",\n\t\"O\",\n\t\"P\",\n\t\"Q\",\n\t\"R\",\n\t\"S\",\n\t\"T\",\n\t\"U\",\n\t\"V\",\n\t\"W\",\n\t\"X\",\n\t\"Y\",\n\t\"Z\",\n\t\"bracketleft\",\n\t\"backslash\",\n\t\"bracketright\",\n\t\"asciicircum\",\n\t\"underscore\",\n\t\"grave\",\n\t\"a\",\n\t\"b\",\n\t\"c\",\n\t\"d\",\n\t\"e\",\n\t\"f\",\n\t\"g\",\n\t\"h\",\n\t\"i\",\n\t\"j\",\n\t\"k\",\n\t\"l\",\n\t\"m\",\n\t\"n\",\n\t\"o\",\n\t\"p\",\n\t\"q\",\n\t\"r\",\n\t\"s\",\n\t\"t\",\n\t\"u\",\n\t\"v\",\n\t\"w\",\n\t\"x\",\n\t\"y\",\n\t\"z\",\n\t\"braceleft\",\n\t\"bar\",\n\t\"braceright\",\n\t\"asciitilde\",\n\t\"Adieresis\",\n\t\"Aring\",\n\t\"Ccedilla\",\n\t\"Eacute\",\n\t\"Ntilde\",\n\t\"Odieresis\",\n\t\"Udieresis\",\n\t\"aacute\",\n\t\"agrave\",\n\t\"acircumflex\",\n\t\"adieresis\",\n\t\"atilde\",\n\t\"aring\",\n\t\"ccedilla\",\n\t\"eacute\",\n\t\"egrave\",\n\t\"ecircumflex\",\n\t\"edieresis\",\n\t\"iacute\",\n\t\"igrave\",\n\t\"icircumflex\",\n\t\"idieresis\",\n\t\"ntilde\",\n\t\"oacute\",\n\t\"ograve\",\n\t\"ocircumflex\",\n\t\"odieresis\",\n\t\"otilde\",\n\t\"uacute\",\n\t\"ugrave\",\n\t\"ucircumflex\",\n\t\"udieresis\",\n\t\"dagger\",\n\t\"degree\",\n\t\"cent\",\n\t\"sterling\",\n\t\"section\",\n\t\"bullet\",\n\t\"paragraph\",\n\t\"germandbls\",\n\t\"registered\",\n\t\"copyright\",\n\t\"trademark\",\n\t\"acute\",\n\t\"dieresis\",\n\t\"notequal\",\n\t\"AE\",\n\t\"Oslash\",\n\t\"infinity\",\n\t\"plusminus\",\n\t\"lessequal\",\n\t\"greaterequal\",\n\t\"yen\",\n\t\"mu\",\n\t\"partialdiff\",\n\t\"summation\",\n\t\"product\",\n\t\"pi\",\n\t\"integral\",\n\t\"ordfeminine\",\n\t\"ordmasculine\",\n\t\"Omega\",\n\t\"ae\",\n\t\"oslash\",\n\t\"questiondown\",\n\t\"exclamdown\",\n\t\"logicalnot\",\n\t\"radical\",\n\t\"florin\",\n\t\"approxequal\",\n\t\"Delta\",\n\t\"guillemotleft\",\n\t\"guillemotright\",\n\t\"ellipsis\",\n\t\"nonbreakingspace\",\n\t\"Agrave\",\n\t\"Atilde\",\n\t\"Otilde\",\n\t\"OE\",\n\t\"oe\",\n\t\"endash\",\n\t\"emdash\",\n\t\"quotedblleft\",\n\t\"quotedblright\",\n\t\"quoteleft\",\n\t\"quoteright\",\n\t\"divide\",\n\t\"lozenge\",\n\t\"ydieresis\",\n\t\"Ydieresis\",\n\t\"fraction\",\n\t\"currency\",\n\t\"guilsinglleft\",\n\t\"guilsinglright\",\n\t\"fi\",\n\t\"fl\",\n\t\"daggerdbl\",\n\t\"periodcentered\",\n\t\"quotesinglbase\",\n\t\"quotedblbase\",\n\t\"perthousand\",\n\t\"Acircumflex\",\n\t\"Ecircumflex\",\n\t\"Aacute\",\n\t\"Edieresis\",\n\t\"Egrave\",\n\t\"Iacute\",\n\t\"Icircumflex\",\n\t\"Idieresis\",\n\t\"Igrave\",\n\t\"Oacute\",\n\t\"Ocircumflex\",\n\t\"apple\",\n\t\"Ograve\",\n\t\"Uacute\",\n\t\"Ucircumflex\",\n\t\"Ugrave\",\n\t\"dotlessi\",\n\t\"circumflex\",\n\t\"tilde\",\n\t\"macron\",\n\t\"breve\",\n\t\"dotaccent\",\n\t\"ring\",\n\t\"cedilla\",\n\t\"hungarumlaut\",\n\t\"ogonek\",\n\t\"caron\",\n\t\"Lslash\",\n\t\"lslash\",\n\t\"Scaron\",\n\t\"scaron\",\n\t\"Zcaron\",\n\t\"zcaron\",\n\t\"brokenbar\",\n\t\"Eth\",\n\t\"eth\",\n\t\"Yacute\",\n\t\"yacute\",\n\t\"Thorn\",\n\t\"thorn\",\n\t\"minus\",\n\t\"multiply\",\n\t\"onesuperior\",\n\t\"twosuperior\",\n\t\"threesuperior\",\n\t\"onehalf\",\n\t\"onequarter\",\n\t\"threequarters\",\n\t\"franc\",\n\t\"Gbreve\",\n\t\"gbreve\",\n\t\"Idotaccent\",\n\t\"Scedilla\",\n\t\"scedilla\",\n\t\"Cacute\",\n\t\"cacute\",\n\t\"Ccaron\",\n\t\"ccaron\",\n\t\"dcroat\",\n];\n\nexport function parsePost(reader: Reader): PostTable {\n\tconst versionMajor = reader.uint16();\n\tconst versionMinor = reader.uint16();\n\tconst version = versionMajor + versionMinor / 0x10000;\n\n\tconst italicAngle = reader.fixed();\n\tconst underlinePosition = reader.int16();\n\tconst underlineThickness = reader.int16();\n\tconst isFixedPitch = reader.uint32();\n\tconst minMemType42 = reader.uint32();\n\tconst maxMemType42 = reader.uint32();\n\tconst minMemType1 = reader.uint32();\n\tconst maxMemType1 = reader.uint32();\n\n\tconst result: PostTable = {\n\t\tversion,\n\t\titalicAngle,\n\t\tunderlinePosition,\n\t\tunderlineThickness,\n\t\tisFixedPitch,\n\t\tminMemType42,\n\t\tmaxMemType42,\n\t\tminMemType1,\n\t\tmaxMemType1,\n\t};\n\n\t// Version 2.0: includes glyph names\n\tif (version === 2.0) {\n\t\tconst numberOfGlyphs = reader.uint16();\n\t\tconst glyphNameIndex: uint16[] = [];\n\n\t\tfor (let i = 0; i < numberOfGlyphs; i++) {\n\t\t\tglyphNameIndex.push(reader.uint16());\n\t\t}\n\n\t\t// Collect custom names (indexes >= 258)\n\t\tconst customNames: string[] = [];\n\t\tlet maxIndex = 0;\n\t\tfor (const idx of glyphNameIndex) {\n\t\t\tif (idx >= 258 && idx > maxIndex) {\n\t\t\t\tmaxIndex = idx;\n\t\t\t}\n\t\t}\n\n\t\t// Read custom names\n\t\tconst numCustomNames = maxIndex >= 258 ? maxIndex - 257 : 0;\n\t\tfor (let i = 0; i < numCustomNames; i++) {\n\t\t\tconst length = reader.uint8();\n\t\t\tconst chars: string[] = [];\n\t\t\tfor (let j = 0; j < length; j++) {\n\t\t\t\tchars.push(String.fromCharCode(reader.uint8()));\n\t\t\t}\n\t\t\tcustomNames.push(chars.join(\"\"));\n\t\t}\n\n\t\tresult.numberOfGlyphs = numberOfGlyphs;\n\t\tresult.glyphNameIndex = glyphNameIndex;\n\t\tresult.names = customNames;\n\t}\n\n\treturn result;\n}\n\n/** Get glyph name by glyph ID */\nexport function getGlyphName(post: PostTable, glyphId: number): string | null {\n\t// Version 1: standard 258 names\n\tif (post.version === 1.0) {\n\t\tconst name = standardNames[glyphId];\n\t\treturn name !== undefined ? name : null;\n\t}\n\n\t// Version 2: indexed names\n\tif (post.version === 2.0 && post.glyphNameIndex) {\n\t\tconst index = post.glyphNameIndex[glyphId];\n\t\tif (index === undefined) return null;\n\n\t\t// Standard name\n\t\tif (index < 258) {\n\t\t\treturn standardNames[index] ?? null;\n\t\t}\n\n\t\t// Custom name\n\t\tconst customIndex = index - 258;\n\t\treturn post.names?.[customIndex] ?? null;\n\t}\n\n\t// Version 3: no names stored\n\treturn null;\n}\n\n/** Check if font is monospaced */\nexport function isMonospaced(post: PostTable): boolean {\n\treturn post.isFixedPitch !== 0;\n}\n",
57
- "import type { GlyphId, int16, uint16, uint32 } from \"../../types.ts\";\nimport type { Reader } from \"../binary/reader.ts\";\n\n/**\n * Standard Bitmap Graphics table (sbix)\n * Apple's bitmap/PNG glyph table for color emoji and bitmap fonts\n */\nexport interface SbixTable {\n\tversion: uint16;\n\tflags: uint16;\n\tstrikes: SbixStrike[];\n}\n\n/**\n * Strike (bitmap size) in sbix\n */\nexport interface SbixStrike {\n\tppem: uint16;\n\tppi: uint16;\n\tglyphData: Map<GlyphId, SbixGlyph>;\n}\n\n/**\n * Glyph data in sbix\n */\nexport interface SbixGlyph {\n\toriginOffsetX: int16;\n\toriginOffsetY: int16;\n\tgraphicType: string; // 4-char tag: 'png ', 'jpg ', 'tiff', 'pdf ', etc.\n\tdata: Uint8Array;\n}\n\n/**\n * Common graphic types in sbix\n */\nexport const SbixGraphicType = {\n\tPNG: \"png \",\n\tJPG: \"jpg \",\n\tTIFF: \"tiff\",\n\tPDF: \"pdf \",\n\tMASK: \"mask\", // Mask for another glyph\n\tDUPE: \"dupe\", // Duplicate of another glyph (data is glyph ID)\n} as const;\n\n/**\n * Parse sbix table\n */\nexport function parseSbix(reader: Reader, numGlyphs: number): SbixTable {\n\tconst tableStart = reader.offset;\n\tconst version = reader.uint16();\n\tconst flags = reader.uint16();\n\tconst numStrikes = reader.uint32();\n\n\t// Read strike offsets\n\tconst strikeOffsets: uint32[] = [];\n\tfor (let i = 0; i < numStrikes; i++) {\n\t\tstrikeOffsets.push(reader.uint32());\n\t}\n\n\t// Parse each strike\n\tconst strikes: SbixStrike[] = [];\n\tfor (const strikeOffset of strikeOffsets) {\n\t\tconst strike = parseStrike(reader, tableStart + strikeOffset, numGlyphs);\n\t\tstrikes.push(strike);\n\t}\n\n\treturn { version, flags, strikes };\n}\n\nfunction parseStrike(\n\treader: Reader,\n\tstrikeOffset: number,\n\tnumGlyphs: number,\n): SbixStrike {\n\tconst strikeReader = reader.sliceFrom(strikeOffset);\n\tconst ppem = strikeReader.uint16();\n\tconst ppi = strikeReader.uint16();\n\n\t// Read glyph data offsets (numGlyphs + 1 for sentinel)\n\tconst glyphDataOffsets: uint32[] = [];\n\tfor (let i = 0; i <= numGlyphs; i++) {\n\t\tglyphDataOffsets.push(strikeReader.uint32());\n\t}\n\n\t// Parse glyph data\n\tconst glyphData = new Map<GlyphId, SbixGlyph>();\n\n\tfor (let glyphId = 0; glyphId < numGlyphs; glyphId++) {\n\t\tconst offset = glyphDataOffsets[glyphId];\n\t\tconst nextOffset = glyphDataOffsets[glyphId + 1];\n\t\tif (offset === undefined || nextOffset === undefined) continue;\n\t\tconst dataLength = nextOffset - offset;\n\n\t\tif (dataLength <= 8) {\n\t\t\t// No data or just header (minimum is 8 bytes for header)\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst glyphReader = reader.sliceFrom(strikeOffset + offset);\n\t\tconst originOffsetX = glyphReader.int16();\n\t\tconst originOffsetY = glyphReader.int16();\n\t\tconst graphicType = glyphReader.tagString();\n\n\t\t// Read actual image data\n\t\tconst imageDataLength = dataLength - 8;\n\t\tconst data = glyphReader.bytes(imageDataLength);\n\n\t\tglyphData.set(glyphId, {\n\t\t\toriginOffsetX,\n\t\t\toriginOffsetY,\n\t\t\tgraphicType,\n\t\t\tdata,\n\t\t});\n\t}\n\n\treturn { ppem, ppi, glyphData };\n}\n\n/**\n * Get glyph bitmap for a specific ppem\n * Returns the best matching strike\n */\nexport function getGlyphBitmap(\n\tsbix: SbixTable,\n\tglyphId: GlyphId,\n\tppem: number,\n): SbixGlyph | null {\n\t// Find best matching strike\n\tlet bestStrike: SbixStrike | null = null;\n\tlet bestDiff = Infinity;\n\n\tfor (const strike of sbix.strikes) {\n\t\tconst diff = Math.abs(strike.ppem - ppem);\n\t\tif (diff < bestDiff) {\n\t\t\tbestDiff = diff;\n\t\t\tbestStrike = strike;\n\t\t}\n\t}\n\n\tif (!bestStrike) return null;\n\n\treturn bestStrike.glyphData.get(glyphId) ?? null;\n}\n\n/**\n * Get exact ppem strike\n */\nexport function getStrikeForPpem(\n\tsbix: SbixTable,\n\tppem: number,\n): SbixStrike | null {\n\treturn sbix.strikes.find((s) => s.ppem === ppem) ?? null;\n}\n\n/**\n * Get all available ppem sizes\n */\nexport function getAvailablePpemSizes(sbix: SbixTable): number[] {\n\treturn sbix.strikes.map((s) => s.ppem).sort((a, b) => a - b);\n}\n\n/**\n * Check if glyph has bitmap data\n */\nexport function hasGlyphBitmap(\n\tsbix: SbixTable,\n\tglyphId: GlyphId,\n\tppem?: number,\n): boolean {\n\tif (ppem !== undefined) {\n\t\tconst strike = getStrikeForPpem(sbix, ppem);\n\t\treturn strike?.glyphData.has(glyphId) ?? false;\n\t}\n\n\t// Check any strike\n\tfor (const strike of sbix.strikes) {\n\t\tif (strike.glyphData.has(glyphId)) {\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n}\n\n/**\n * Resolve dupe graphic type\n * Returns the actual glyph data for duplicates\n */\nexport function resolveDupeGlyph(\n\tsbix: SbixTable,\n\tstrike: SbixStrike,\n\tglyph: SbixGlyph,\n): SbixGlyph | null {\n\tif (glyph.graphicType !== SbixGraphicType.DUPE) {\n\t\treturn glyph;\n\t}\n\n\t// Data contains the glyph ID to reference\n\tif (glyph.data.length < 2) return null;\n\n\tconst dupeGlyphId = ((glyph.data[0] ?? 0) << 8) | (glyph.data[1] ?? 0);\n\tconst resolved = strike.glyphData.get(dupeGlyphId);\n\n\tif (!resolved) return null;\n\n\t// Recursively resolve if it's also a dupe\n\tif (resolved.graphicType === SbixGraphicType.DUPE) {\n\t\treturn resolveDupeGlyph(sbix, strike, resolved);\n\t}\n\n\treturn resolved;\n}\n",
58
- "import type { TableRecord, Tag } from \"../../types.ts\";\nimport type { Reader } from \"../binary/reader.ts\";\n\n/** Supported sfnt version tags */\nconst SFNT_VERSION_TRUETYPE = 0x00010000; // TrueType\nconst SFNT_VERSION_OPENTYPE = 0x4f54544f; // 'OTTO' - CFF\nconst SFNT_VERSION_TRUE = 0x74727565; // 'true' - Apple TrueType\n\n/** Font directory containing table records */\nexport interface FontDirectory {\n\tsfntVersion: number;\n\tnumTables: number;\n\tsearchRange: number;\n\tentrySelector: number;\n\trangeShift: number;\n\ttables: Map<Tag, TableRecord>;\n}\n\n/**\n * Parse the sfnt font directory (table of contents).\n * This is the first thing read from any TrueType/OpenType font.\n */\nexport function parseFontDirectory(reader: Reader): FontDirectory {\n\tconst sfntVersion = reader.uint32();\n\n\t// Validate sfnt version\n\tif (\n\t\tsfntVersion !== SFNT_VERSION_TRUETYPE &&\n\t\tsfntVersion !== SFNT_VERSION_OPENTYPE &&\n\t\tsfntVersion !== SFNT_VERSION_TRUE\n\t) {\n\t\tthrow new Error(\n\t\t\t`Invalid sfnt version: 0x${sfntVersion.toString(16).padStart(8, \"0\")}`,\n\t\t);\n\t}\n\n\tconst numTables = reader.uint16();\n\tconst searchRange = reader.uint16();\n\tconst entrySelector = reader.uint16();\n\tconst rangeShift = reader.uint16();\n\n\tconst tables = new Map<Tag, TableRecord>();\n\n\tfor (let i = 0; i < numTables; i++) {\n\t\tconst tag = reader.tag();\n\t\tconst checksum = reader.uint32();\n\t\tconst offset = reader.uint32();\n\t\tconst length = reader.uint32();\n\n\t\ttables.set(tag, { tag, checksum, offset, length });\n\t}\n\n\treturn {\n\t\tsfntVersion,\n\t\tnumTables,\n\t\tsearchRange,\n\t\tentrySelector,\n\t\trangeShift,\n\t\ttables,\n\t};\n}\n\n/** Check if this is a TrueType font (vs CFF) */\nexport function isTrueType(directory: FontDirectory): boolean {\n\treturn (\n\t\tdirectory.sfntVersion === SFNT_VERSION_TRUETYPE ||\n\t\tdirectory.sfntVersion === SFNT_VERSION_TRUE\n\t);\n}\n\n/** Check if this is a CFF font */\nexport function isCFF(directory: FontDirectory): boolean {\n\treturn directory.sfntVersion === SFNT_VERSION_OPENTYPE;\n}\n",
59
- "import type { Tag, uint16 } from \"../../types.ts\";\nimport type { Reader } from \"../binary/reader.ts\";\n\n/**\n * Style Attributes table (STAT)\n * Provides style information for variable fonts\n * Used for font selection and naming\n */\nexport interface StatTable {\n\tmajorVersion: uint16;\n\tminorVersion: uint16;\n\tdesignAxisCount: uint16;\n\tdesignAxes: AxisRecord[];\n\taxisValueCount: uint16;\n\taxisValues: AxisValue[];\n\telidedFallbackNameID?: uint16;\n}\n\n/**\n * Design axis record\n */\nexport interface AxisRecord {\n\taxisTag: Tag;\n\taxisNameID: uint16;\n\taxisOrdering: uint16;\n}\n\n/**\n * Axis value flags\n */\nexport const AxisValueFlags = {\n\tOlderSiblingFontAttribute: 0x0001,\n\tElidableAxisValueName: 0x0002,\n} as const;\n\n/**\n * Base axis value\n */\nexport interface AxisValueBase {\n\tformat: number;\n\taxisIndex: uint16;\n\tflags: uint16;\n\tvalueNameID: uint16;\n}\n\n/**\n * Format 1: Single axis value\n */\nexport interface AxisValueFormat1 extends AxisValueBase {\n\tformat: 1;\n\tvalue: number; // Fixed 16.16\n}\n\n/**\n * Format 2: Axis value range\n */\nexport interface AxisValueFormat2 extends AxisValueBase {\n\tformat: 2;\n\tnominalValue: number;\n\trangeMinValue: number;\n\trangeMaxValue: number;\n}\n\n/**\n * Format 3: Linked axis value\n */\nexport interface AxisValueFormat3 extends AxisValueBase {\n\tformat: 3;\n\tvalue: number;\n\tlinkedValue: number;\n}\n\n/**\n * Format 4: Multiple axis values\n */\nexport interface AxisValueFormat4 {\n\tformat: 4;\n\taxisCount: uint16;\n\tflags: uint16;\n\tvalueNameID: uint16;\n\taxisValues: { axisIndex: uint16; value: number }[];\n}\n\nexport type AxisValue =\n\t| AxisValueFormat1\n\t| AxisValueFormat2\n\t| AxisValueFormat3\n\t| AxisValueFormat4;\n\n/**\n * Parse STAT table\n */\nexport function parseStat(reader: Reader): StatTable {\n\tconst tableStart = reader.offset;\n\tconst majorVersion = reader.uint16();\n\tconst minorVersion = reader.uint16();\n\tconst designAxisSize = reader.uint16();\n\tconst designAxisCount = reader.uint16();\n\tconst designAxesOffset = reader.offset32();\n\tconst axisValueCount = reader.uint16();\n\tconst axisValueArrayOffset = reader.offset32();\n\n\tlet elidedFallbackNameID: uint16 | undefined;\n\tif (majorVersion >= 1 && minorVersion >= 1) {\n\t\telidedFallbackNameID = reader.uint16();\n\t}\n\n\t// Parse design axes\n\tconst designAxes: AxisRecord[] = [];\n\tif (designAxesOffset !== 0) {\n\t\tconst axesReader = reader.sliceFrom(tableStart + designAxesOffset);\n\t\tfor (let i = 0; i < designAxisCount; i++) {\n\t\t\tdesignAxes.push({\n\t\t\t\taxisTag: axesReader.tag(),\n\t\t\t\taxisNameID: axesReader.uint16(),\n\t\t\t\taxisOrdering: axesReader.uint16(),\n\t\t\t});\n\t\t\t// Skip any additional bytes if designAxisSize > 8\n\t\t\tif (designAxisSize > 8) {\n\t\t\t\taxesReader.skip(designAxisSize - 8);\n\t\t\t}\n\t\t}\n\t}\n\n\t// Parse axis values\n\tconst axisValues: AxisValue[] = [];\n\tif (axisValueArrayOffset !== 0 && axisValueCount > 0) {\n\t\tconst arrayReader = reader.sliceFrom(tableStart + axisValueArrayOffset);\n\n\t\t// Read axis value offsets\n\t\tconst axisValueOffsets: uint16[] = [];\n\t\tfor (let i = 0; i < axisValueCount; i++) {\n\t\t\taxisValueOffsets.push(arrayReader.uint16());\n\t\t}\n\n\t\t// Parse each axis value\n\t\tfor (const offset of axisValueOffsets) {\n\t\t\tconst valueReader = reader.sliceFrom(\n\t\t\t\ttableStart + axisValueArrayOffset + offset,\n\t\t\t);\n\t\t\tconst axisValue = parseAxisValue(valueReader);\n\t\t\tif (axisValue) {\n\t\t\t\taxisValues.push(axisValue);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\tmajorVersion,\n\t\tminorVersion,\n\t\tdesignAxisCount,\n\t\tdesignAxes,\n\t\taxisValueCount,\n\t\taxisValues,\n\t\telidedFallbackNameID,\n\t};\n}\n\nfunction parseAxisValue(reader: Reader): AxisValue | null {\n\tconst format = reader.uint16();\n\n\tswitch (format) {\n\t\tcase 1: {\n\t\t\treturn {\n\t\t\t\tformat: 1,\n\t\t\t\taxisIndex: reader.uint16(),\n\t\t\t\tflags: reader.uint16(),\n\t\t\t\tvalueNameID: reader.uint16(),\n\t\t\t\tvalue: reader.fixed(),\n\t\t\t};\n\t\t}\n\t\tcase 2: {\n\t\t\treturn {\n\t\t\t\tformat: 2,\n\t\t\t\taxisIndex: reader.uint16(),\n\t\t\t\tflags: reader.uint16(),\n\t\t\t\tvalueNameID: reader.uint16(),\n\t\t\t\tnominalValue: reader.fixed(),\n\t\t\t\trangeMinValue: reader.fixed(),\n\t\t\t\trangeMaxValue: reader.fixed(),\n\t\t\t};\n\t\t}\n\t\tcase 3: {\n\t\t\treturn {\n\t\t\t\tformat: 3,\n\t\t\t\taxisIndex: reader.uint16(),\n\t\t\t\tflags: reader.uint16(),\n\t\t\t\tvalueNameID: reader.uint16(),\n\t\t\t\tvalue: reader.fixed(),\n\t\t\t\tlinkedValue: reader.fixed(),\n\t\t\t};\n\t\t}\n\t\tcase 4: {\n\t\t\tconst axisCount = reader.uint16();\n\t\t\tconst flags = reader.uint16();\n\t\t\tconst valueNameID = reader.uint16();\n\n\t\t\tconst axisValues: { axisIndex: uint16; value: number }[] = [];\n\t\t\tfor (let i = 0; i < axisCount; i++) {\n\t\t\t\taxisValues.push({\n\t\t\t\t\taxisIndex: reader.uint16(),\n\t\t\t\t\tvalue: reader.fixed(),\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tformat: 4,\n\t\t\t\taxisCount,\n\t\t\t\tflags,\n\t\t\t\tvalueNameID,\n\t\t\t\taxisValues,\n\t\t\t};\n\t\t}\n\t\tdefault:\n\t\t\treturn null;\n\t}\n}\n\n/**\n * Get axis record by tag\n */\nexport function getAxisRecord(\n\tstat: StatTable,\n\taxisTag: Tag,\n): AxisRecord | null {\n\treturn stat.designAxes.find((a) => a.axisTag === axisTag) ?? null;\n}\n\n/**\n * Get axis index by tag\n */\nexport function getAxisIndex(stat: StatTable, axisTag: Tag): number {\n\treturn stat.designAxes.findIndex((a) => a.axisTag === axisTag);\n}\n\n/**\n * Get axis values for a specific axis\n */\nexport function getAxisValuesForAxis(\n\tstat: StatTable,\n\taxisIndex: number,\n): AxisValue[] {\n\treturn stat.axisValues.filter((v) => {\n\t\tif (v.format === 4) {\n\t\t\treturn v.axisValues.some((av) => av.axisIndex === axisIndex);\n\t\t}\n\t\treturn v.axisIndex === axisIndex;\n\t});\n}\n\n/**\n * Find axis value by name ID\n */\nexport function findAxisValueByNameId(\n\tstat: StatTable,\n\tnameId: uint16,\n): AxisValue | null {\n\treturn stat.axisValues.find((v) => v.valueNameID === nameId) ?? null;\n}\n\n/**\n * Check if axis value is elidable\n */\nexport function isElidableAxisValue(axisValue: AxisValue): boolean {\n\treturn (axisValue.flags & AxisValueFlags.ElidableAxisValueName) !== 0;\n}\n\n/**\n * Check if axis value represents an older sibling font\n */\nexport function isOlderSiblingFont(axisValue: AxisValue): boolean {\n\treturn (axisValue.flags & AxisValueFlags.OlderSiblingFontAttribute) !== 0;\n}\n\n/**\n * Get the value for a format 1-3 axis value\n */\nexport function getAxisValueNumber(axisValue: AxisValue): number | null {\n\tswitch (axisValue.format) {\n\t\tcase 1:\n\t\tcase 3:\n\t\t\treturn axisValue.value;\n\t\tcase 2:\n\t\t\treturn axisValue.nominalValue;\n\t\tcase 4:\n\t\t\treturn null; // Format 4 has multiple values\n\t}\n}\n\n/**\n * Match axis value to coordinates\n * Returns true if the axis value matches the given coordinates\n */\nexport function matchAxisValue(\n\taxisValue: AxisValue,\n\tcoords: Map<number, number>,\n): boolean {\n\tswitch (axisValue.format) {\n\t\tcase 1:\n\t\tcase 3: {\n\t\t\tconst coord = coords.get(axisValue.axisIndex);\n\t\t\treturn coord !== undefined && coord === axisValue.value;\n\t\t}\n\t\tcase 2: {\n\t\t\tconst coord = coords.get(axisValue.axisIndex);\n\t\t\treturn (\n\t\t\t\tcoord !== undefined &&\n\t\t\t\tcoord >= axisValue.rangeMinValue &&\n\t\t\t\tcoord <= axisValue.rangeMaxValue\n\t\t\t);\n\t\t}\n\t\tcase 4: {\n\t\t\treturn axisValue.axisValues.every((av) => {\n\t\t\t\tconst coord = coords.get(av.axisIndex);\n\t\t\t\treturn coord !== undefined && coord === av.value;\n\t\t\t});\n\t\t}\n\t}\n}\n",
60
- "import type { GlyphId, uint16, uint32 } from \"../../types.ts\";\nimport type { Reader } from \"../binary/reader.ts\";\n\n/**\n * SVG table\n * Contains SVG documents for color glyph rendering\n */\nexport interface SvgTable {\n\tversion: uint16;\n\tdocumentRecords: SvgDocumentRecord[];\n}\n\n/**\n * SVG document record\n * Maps a range of glyphs to an SVG document\n */\nexport interface SvgDocumentRecord {\n\tstartGlyphID: GlyphId;\n\tendGlyphID: GlyphId;\n\tsvgDoc: string;\n}\n\n/**\n * Parse SVG table\n */\nexport function parseSvg(reader: Reader): SvgTable {\n\tconst version = reader.uint16();\n\n\t// SVG Document List offset (from start of SVG table)\n\tconst svgDocumentListOffset = reader.offset32();\n\n\t// Reserved\n\treader.skip(4);\n\n\t// Parse document list\n\tconst listReader = reader.sliceFrom(svgDocumentListOffset);\n\tconst numEntries = listReader.uint16();\n\n\t// Read document index entries\n\tconst entries: {\n\t\tstartGlyphID: uint16;\n\t\tendGlyphID: uint16;\n\t\tsvgDocOffset: uint32;\n\t\tsvgDocLength: uint32;\n\t}[] = [];\n\n\tfor (let i = 0; i < numEntries; i++) {\n\t\tentries.push({\n\t\t\tstartGlyphID: listReader.uint16(),\n\t\t\tendGlyphID: listReader.uint16(),\n\t\t\tsvgDocOffset: listReader.offset32(),\n\t\t\tsvgDocLength: listReader.uint32(),\n\t\t});\n\t}\n\n\t// Parse SVG documents\n\tconst documentRecords: SvgDocumentRecord[] = [];\n\tconst decoder = new TextDecoder(\"utf-8\");\n\n\tfor (const entry of entries) {\n\t\t// SVG doc offset is relative to SVG Document List\n\t\tconst docReader = listReader.sliceFrom(entry.svgDocOffset);\n\t\tconst svgBytes = docReader.bytes(entry.svgDocLength);\n\n\t\t// Decompress if gzipped (starts with 0x1F 0x8B)\n\t\tlet svgDoc: string;\n\t\tif (svgBytes[0] === 0x1f && svgBytes[1] === 0x8b) {\n\t\t\t// Gzipped SVG - need to decompress\n\t\t\ttry {\n\t\t\t\tconst decompressed = decompressGzip(svgBytes);\n\t\t\t\tsvgDoc = decoder.decode(decompressed);\n\t\t\t} catch {\n\t\t\t\t// If decompression fails, try as plain text\n\t\t\t\tsvgDoc = decoder.decode(svgBytes);\n\t\t\t}\n\t\t} else {\n\t\t\tsvgDoc = decoder.decode(svgBytes);\n\t\t}\n\n\t\tdocumentRecords.push({\n\t\t\tstartGlyphID: entry.startGlyphID,\n\t\t\tendGlyphID: entry.endGlyphID,\n\t\t\tsvgDoc,\n\t\t});\n\t}\n\n\treturn { version, documentRecords };\n}\n\n/**\n * Get SVG document for a glyph\n * Returns null if no SVG exists for this glyph\n */\nexport function getSvgDocument(svg: SvgTable, glyphId: GlyphId): string | null {\n\tfor (const record of svg.documentRecords) {\n\t\tif (glyphId >= record.startGlyphID && glyphId <= record.endGlyphID) {\n\t\t\treturn record.svgDoc;\n\t\t}\n\t}\n\treturn null;\n}\n\n/**\n * Check if a glyph has an SVG representation\n */\nexport function hasSvgGlyph(svg: SvgTable, glyphId: GlyphId): boolean {\n\treturn getSvgDocument(svg, glyphId) !== null;\n}\n\n/**\n * Get all glyph IDs that have SVG representations\n */\nexport function getSvgGlyphIds(svg: SvgTable): GlyphId[] {\n\tconst glyphIds: GlyphId[] = [];\n\n\tfor (const record of svg.documentRecords) {\n\t\tfor (let gid = record.startGlyphID; gid <= record.endGlyphID; gid++) {\n\t\t\tglyphIds.push(gid);\n\t\t}\n\t}\n\n\treturn glyphIds;\n}\n\n/**\n * Simple gzip decompression using DecompressionStream (if available)\n * Falls back to returning original data if not supported\n */\nfunction decompressGzip(data: Uint8Array): Uint8Array {\n\t// Use DecompressionStream if available (modern browsers/Bun)\n\tif (typeof DecompressionStream !== \"undefined\") {\n\t\t// This is async in nature, but we need sync.\n\t\t// For now, return original - proper implementation needs async\n\t\t// In practice, most SVG fonts use uncompressed SVG\n\t\treturn data;\n\t}\n\n\t// No decompression available, return as-is\n\treturn data;\n}\n\n/**\n * Async version of gzip decompression\n */\nexport async function decompressSvgDocument(data: Uint8Array): Promise<string> {\n\tconst decoder = new TextDecoder(\"utf-8\");\n\n\t// Check for gzip magic bytes\n\tif (data[0] === 0x1f && data[1] === 0x8b) {\n\t\tif (typeof DecompressionStream !== \"undefined\") {\n\t\t\tconst stream = new DecompressionStream(\"gzip\");\n\t\t\tconst writer = stream.writable.getWriter();\n\t\t\tconst reader = stream.readable.getReader();\n\n\t\t\twriter.write(data as unknown as BufferSource);\n\t\t\twriter.close();\n\n\t\t\tconst chunks: Uint8Array[] = [];\n\t\t\tlet result = await reader.read();\n\t\t\twhile (!result.done) {\n\t\t\t\tchunks.push(result.value);\n\t\t\t\tresult = await reader.read();\n\t\t\t}\n\n\t\t\tconst totalLength = chunks.reduce((acc, chunk) => acc + chunk.length, 0);\n\t\t\tconst decompressed = new Uint8Array(totalLength);\n\t\t\tlet offset = 0;\n\t\t\tfor (const chunk of chunks) {\n\t\t\t\tdecompressed.set(chunk, offset);\n\t\t\t\toffset += chunk.length;\n\t\t\t}\n\n\t\t\treturn decoder.decode(decompressed);\n\t\t}\n\t}\n\n\treturn decoder.decode(data);\n}\n",
61
- "import type { int16, uint16, uint32 } from \"../../types.ts\";\nimport type { Reader } from \"../binary/reader.ts\";\n\n/**\n * Tracking table (trak)\n * Apple Advanced Typography tracking\n */\nexport interface TrakTable {\n\tversion: number;\n\tformat: uint16;\n\thorizData: TrackData | null;\n\tvertData: TrackData | null;\n}\n\n/**\n * Track data for one direction\n */\nexport interface TrackData {\n\tnTracks: uint16;\n\tnSizes: uint16;\n\tsizeTableOffset: uint32;\n\ttrackTable: TrackTableEntry[];\n\tsizeTable: number[]; // Fixed point sizes\n}\n\n/**\n * Track table entry\n */\nexport interface TrackTableEntry {\n\ttrack: number; // Fixed 16.16\n\tnameIndex: uint16;\n\toffset: uint16;\n\tperSizeTracking: int16[];\n}\n\n/**\n * Parse trak table\n */\nexport function parseTrak(reader: Reader): TrakTable {\n\tconst tableReader = reader; // Keep reference to table start for offset resolution\n\tconst version = reader.uint32() / 65536; // Fixed 16.16\n\tconst format = reader.uint16();\n\tconst horizOffset = reader.offset16();\n\tconst vertOffset = reader.offset16();\n\treader.skip(2); // reserved\n\n\tlet horizData: TrackData | null = null;\n\tlet vertData: TrackData | null = null;\n\n\tif (horizOffset !== 0) {\n\t\thorizData = parseTrackData(reader.sliceFrom(horizOffset), tableReader);\n\t}\n\n\tif (vertOffset !== 0) {\n\t\tvertData = parseTrackData(reader.sliceFrom(vertOffset), tableReader);\n\t}\n\n\treturn {\n\t\tversion,\n\t\tformat,\n\t\thorizData,\n\t\tvertData,\n\t};\n}\n\nfunction parseTrackData(reader: Reader, tableReader: Reader): TrackData {\n\tconst nTracks = reader.uint16();\n\tconst nSizes = reader.uint16();\n\tconst sizeTableOffset = reader.offset32();\n\n\tconst trackTable: TrackTableEntry[] = [];\n\n\t// Read track entries\n\tfor (let i = 0; i < nTracks; i++) {\n\t\tconst track = reader.int32() / 65536; // Fixed 16.16\n\t\tconst nameIndex = reader.uint16();\n\t\tconst offset = reader.uint16();\n\n\t\ttrackTable.push({\n\t\t\ttrack,\n\t\t\tnameIndex,\n\t\t\toffset,\n\t\t\tperSizeTracking: [],\n\t\t});\n\t}\n\n\t// Read per-size tracking values for each track\n\t// Note: offsets are relative to table start, not trackData start\n\tfor (const entry of trackTable) {\n\t\tconst trackReader = tableReader.sliceFrom(entry.offset);\n\t\tentry.perSizeTracking = [];\n\t\tfor (let i = 0; i < nSizes; i++) {\n\t\t\tentry.perSizeTracking.push(trackReader.int16());\n\t\t}\n\t}\n\n\t// Read size table (offset is relative to table start, not trackData start)\n\tconst sizeReader = tableReader.sliceFrom(sizeTableOffset);\n\tconst sizeTable: number[] = [];\n\tfor (let i = 0; i < nSizes; i++) {\n\t\tsizeTable.push(sizeReader.int32() / 65536); // Fixed 16.16\n\t}\n\n\treturn {\n\t\tnTracks,\n\t\tnSizes,\n\t\tsizeTableOffset,\n\t\ttrackTable,\n\t\tsizeTable,\n\t};\n}\n\n/**\n * Get tracking value for a given track and point size\n */\nexport function getTrackingValue(\n\ttrackData: TrackData,\n\ttrack: number,\n\tpointSize: number,\n): number {\n\t// Find the track entry\n\tlet trackEntry: TrackTableEntry | null = null;\n\n\tfor (const entry of trackData.trackTable) {\n\t\tif (entry.track === track) {\n\t\t\ttrackEntry = entry;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// If exact track not found, interpolate between nearest\n\tif (!trackEntry) {\n\t\tlet lower: TrackTableEntry | null = null;\n\t\tlet upper: TrackTableEntry | null = null;\n\n\t\tfor (const entry of trackData.trackTable) {\n\t\t\tif (entry.track <= track && (!lower || entry.track > lower.track)) {\n\t\t\t\tlower = entry;\n\t\t\t}\n\t\t\tif (entry.track >= track && (!upper || entry.track < upper.track)) {\n\t\t\t\tupper = entry;\n\t\t\t}\n\t\t}\n\n\t\tif (lower && upper && lower !== upper) {\n\t\t\t// Interpolate between tracks\n\t\t\tconst t = (track - lower.track) / (upper.track - lower.track);\n\t\t\tconst lowerValue = getSizeValue(trackData, lower, pointSize);\n\t\t\tconst upperValue = getSizeValue(trackData, upper, pointSize);\n\t\t\treturn Math.round(lowerValue + t * (upperValue - lowerValue));\n\t\t} else if (lower) {\n\t\t\ttrackEntry = lower;\n\t\t} else if (upper) {\n\t\t\ttrackEntry = upper;\n\t\t} else {\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\tif (!trackEntry) return 0;\n\n\treturn getSizeValue(trackData, trackEntry, pointSize);\n}\n\nfunction getSizeValue(\n\ttrackData: TrackData,\n\tentry: TrackTableEntry,\n\tpointSize: number,\n): number {\n\tconst sizes = trackData.sizeTable;\n\tconst values = entry.perSizeTracking;\n\n\tif (sizes.length === 0 || values.length === 0) return 0;\n\n\tconst firstSize = sizes[0];\n\tconst firstValue = values[0];\n\tif (firstSize === undefined || firstValue === undefined) return 0;\n\n\t// Find size range\n\tif (pointSize <= firstSize) {\n\t\treturn firstValue;\n\t}\n\n\tconst lastSize = sizes[sizes.length - 1];\n\tconst lastValue = values[values.length - 1];\n\tif (lastSize === undefined || lastValue === undefined) return 0;\n\n\tif (pointSize >= lastSize) {\n\t\treturn lastValue;\n\t}\n\n\t// Interpolate\n\tfor (let i = 0; i < sizes.length - 1; i++) {\n\t\tconst size1 = sizes[i];\n\t\tconst size2 = sizes[i + 1];\n\t\tconst value1 = values[i];\n\t\tconst value2 = values[i + 1];\n\t\tif (\n\t\t\tsize1 === undefined ||\n\t\t\tsize2 === undefined ||\n\t\t\tvalue1 === undefined ||\n\t\t\tvalue2 === undefined\n\t\t)\n\t\t\tcontinue;\n\n\t\tif (pointSize >= size1 && pointSize <= size2) {\n\t\t\tconst t = (pointSize - size1) / (size2 - size1);\n\t\t\treturn Math.round(value1 + t * (value2 - value1));\n\t\t}\n\t}\n\n\treturn 0;\n}\n\n/**\n * Apply tracking to advance widths\n */\nexport function applyTracking(\n\ttrak: TrakTable,\n\tadvances: number[],\n\tpointSize: number,\n\ttrack: number = 0,\n\tvertical: boolean = false,\n): void {\n\tconst trackData = vertical ? trak.vertData : trak.horizData;\n\tif (!trackData) return;\n\n\tconst trackingValue = getTrackingValue(trackData, track, pointSize);\n\tif (trackingValue === 0) return;\n\n\t// Add tracking to each advance\n\tfor (const [i, advance] of advances.entries()) {\n\t\tadvances[i] = (advance ?? 0) + trackingValue;\n\t}\n}\n",
62
- "import type { FWord, int16, uint16 } from \"../../types.ts\";\nimport type { Reader } from \"../binary/reader.ts\";\n\n/**\n * Vertical Header table (vhea)\n * Contains information for vertical layout\n */\nexport interface VheaTable {\n\t/** Table version (1.0 or 1.1) */\n\tversion: { major: number; minor: number };\n\t/** Typographic ascent (vertical) */\n\tascender: FWord;\n\t/** Typographic descent (vertical) */\n\tdescender: FWord;\n\t/** Typographic line gap (vertical) */\n\tlineGap: FWord;\n\t/** Maximum advance height */\n\tadvanceHeightMax: uint16;\n\t/** Minimum top side bearing */\n\tminTopSideBearing: FWord;\n\t/** Minimum bottom side bearing */\n\tminBottomSideBearing: FWord;\n\t/** Maximum y extent (yMax - yMin) */\n\tyMaxExtent: FWord;\n\t/** Caret slope rise (for vertical text) */\n\tcaretSlopeRise: int16;\n\t/** Caret slope run */\n\tcaretSlopeRun: int16;\n\t/** Caret offset */\n\tcaretOffset: int16;\n\t/** Metric data format (0 for current) */\n\tmetricDataFormat: int16;\n\t/** Number of vertical metrics in vmtx */\n\tnumberOfVMetrics: uint16;\n}\n\n/**\n * Parse vhea table\n */\nexport function parseVhea(reader: Reader): VheaTable {\n\tconst majorVersion = reader.uint16();\n\tconst minorVersion = reader.uint16();\n\tconst ascender = reader.fword();\n\tconst descender = reader.fword();\n\tconst lineGap = reader.fword();\n\tconst advanceHeightMax = reader.uint16();\n\tconst minTopSideBearing = reader.fword();\n\tconst minBottomSideBearing = reader.fword();\n\tconst yMaxExtent = reader.fword();\n\tconst caretSlopeRise = reader.int16();\n\tconst caretSlopeRun = reader.int16();\n\tconst caretOffset = reader.int16();\n\n\t// Skip reserved fields\n\treader.skip(8);\n\n\tconst metricDataFormat = reader.int16();\n\tconst numberOfVMetrics = reader.uint16();\n\n\treturn {\n\t\tversion: { major: majorVersion, minor: minorVersion },\n\t\tascender,\n\t\tdescender,\n\t\tlineGap,\n\t\tadvanceHeightMax,\n\t\tminTopSideBearing,\n\t\tminBottomSideBearing,\n\t\tyMaxExtent,\n\t\tcaretSlopeRise,\n\t\tcaretSlopeRun,\n\t\tcaretOffset,\n\t\tmetricDataFormat,\n\t\tnumberOfVMetrics,\n\t};\n}\n",
63
- "import type { GlyphId, int16, uint16 } from \"../../types.ts\";\nimport type { Reader } from \"../binary/reader.ts\";\n\n/**\n * Vertical Metrics table (vmtx)\n * Contains vertical metrics for each glyph\n */\nexport interface VmtxTable {\n\t/** Vertical metrics (advance height + top side bearing) */\n\tvMetrics: VerticalMetric[];\n\t/** Top side bearings for remaining glyphs */\n\ttopSideBearings: int16[];\n}\n\n/**\n * Vertical metric record\n */\nexport interface VerticalMetric {\n\t/** Advance height in font units */\n\tadvanceHeight: uint16;\n\t/** Top side bearing in font units */\n\ttopSideBearing: int16;\n}\n\n/**\n * Parse vmtx table\n * @param reader Binary reader\n * @param numberOfVMetrics From vhea table\n * @param numGlyphs Total number of glyphs\n */\nexport function parseVmtx(\n\treader: Reader,\n\tnumberOfVMetrics: number,\n\tnumGlyphs: number,\n): VmtxTable {\n\tconst vMetrics: VerticalMetric[] = [];\n\n\t// Read full vertical metrics\n\tfor (let i = 0; i < numberOfVMetrics; i++) {\n\t\tvMetrics.push({\n\t\t\tadvanceHeight: reader.uint16(),\n\t\t\ttopSideBearing: reader.int16(),\n\t\t});\n\t}\n\n\t// Read additional top side bearings\n\tconst topSideBearings: int16[] = [];\n\tconst remaining = numGlyphs - numberOfVMetrics;\n\n\tfor (let i = 0; i < remaining; i++) {\n\t\ttopSideBearings.push(reader.int16());\n\t}\n\n\treturn { vMetrics, topSideBearings };\n}\n\n/**\n * Get vertical metrics for a glyph\n */\nexport function getVerticalMetrics(\n\tvmtx: VmtxTable,\n\tglyphId: GlyphId,\n): { advanceHeight: number; topSideBearing: number } {\n\tif (glyphId < vmtx.vMetrics.length) {\n\t\tconst metric = vmtx.vMetrics[glyphId];\n\t\tif (metric) {\n\t\t\treturn {\n\t\t\t\tadvanceHeight: metric.advanceHeight,\n\t\t\t\ttopSideBearing: metric.topSideBearing,\n\t\t\t};\n\t\t}\n\t}\n\n\t// Use last advance height, get TSB from array\n\tconst lastMetric = vmtx.vMetrics[vmtx.vMetrics.length - 1];\n\tconst advanceHeight = lastMetric?.advanceHeight ?? 0;\n\tconst tsbIndex = glyphId - vmtx.vMetrics.length;\n\tconst topSideBearing = vmtx.topSideBearings[tsbIndex] ?? 0;\n\n\treturn { advanceHeight, topSideBearing };\n}\n",
64
- "import type { GlyphId, int16, uint16 } from \"../../types.ts\";\nimport type { Reader } from \"../binary/reader.ts\";\n\n/**\n * Vertical Origin table (VORG)\n * Provides y-coordinate of vertical origin for CFF fonts\n * Used for proper vertical text layout in CJK fonts\n */\nexport interface VorgTable {\n\tmajorVersion: uint16;\n\tminorVersion: uint16;\n\tdefaultVertOriginY: int16;\n\tvertOriginYMetrics: VertOriginYMetric[];\n}\n\n/**\n * Vertical origin metric for a specific glyph\n */\nexport interface VertOriginYMetric {\n\tglyphIndex: GlyphId;\n\tvertOriginY: int16;\n}\n\n/**\n * Parse VORG table\n */\nexport function parseVorg(reader: Reader): VorgTable {\n\tconst majorVersion = reader.uint16();\n\tconst minorVersion = reader.uint16();\n\tconst defaultVertOriginY = reader.int16();\n\tconst numVertOriginYMetrics = reader.uint16();\n\n\tconst vertOriginYMetrics: VertOriginYMetric[] = [];\n\tfor (let i = 0; i < numVertOriginYMetrics; i++) {\n\t\tvertOriginYMetrics.push({\n\t\t\tglyphIndex: reader.uint16(),\n\t\t\tvertOriginY: reader.int16(),\n\t\t});\n\t}\n\n\t// Sort by glyph index for binary search\n\tvertOriginYMetrics.sort((a, b) => a.glyphIndex - b.glyphIndex);\n\n\treturn {\n\t\tmajorVersion,\n\t\tminorVersion,\n\t\tdefaultVertOriginY,\n\t\tvertOriginYMetrics,\n\t};\n}\n\n/**\n * Get vertical origin Y coordinate for a glyph\n * Returns the y-coordinate of the glyph's vertical origin\n */\nexport function getVertOriginY(vorg: VorgTable, glyphId: GlyphId): int16 {\n\t// Binary search for the glyph\n\tconst metrics = vorg.vertOriginYMetrics;\n\tlet lo = 0;\n\tlet hi = metrics.length - 1;\n\n\twhile (lo <= hi) {\n\t\tconst mid = (lo + hi) >>> 1;\n\t\tconst metric = metrics[mid];\n\t\tif (metric === undefined) break;\n\n\t\tif (metric.glyphIndex === glyphId) {\n\t\t\treturn metric.vertOriginY;\n\t\t} else if (metric.glyphIndex < glyphId) {\n\t\t\tlo = mid + 1;\n\t\t} else {\n\t\t\thi = mid - 1;\n\t\t}\n\t}\n\n\t// Not found, use default\n\treturn vorg.defaultVertOriginY;\n}\n\n/**\n * Check if a glyph has a specific vertical origin entry\n */\nexport function hasVertOriginY(vorg: VorgTable, glyphId: GlyphId): boolean {\n\tconst metrics = vorg.vertOriginYMetrics;\n\tlet lo = 0;\n\tlet hi = metrics.length - 1;\n\n\twhile (lo <= hi) {\n\t\tconst mid = (lo + hi) >>> 1;\n\t\tconst metric = metrics[mid];\n\t\tif (metric === undefined) break;\n\n\t\tif (metric.glyphIndex === glyphId) {\n\t\t\treturn true;\n\t\t} else if (metric.glyphIndex < glyphId) {\n\t\t\tlo = mid + 1;\n\t\t} else {\n\t\t\thi = mid - 1;\n\t\t}\n\t}\n\n\treturn false;\n}\n",
65
- "import type { GlyphId, uint16, uint32 } from \"../../types.ts\";\nimport type { Reader } from \"../binary/reader.ts\";\nimport {\n\tcalculateRegionScalar,\n\ttype DeltaSetIndexMap,\n\ttype ItemVariationStore,\n\ttype VariationRegion,\n} from \"./hvar.ts\";\n\n/**\n * Vertical Metrics Variations table (VVAR)\n * Provides variations for vertical advance heights and side bearings\n */\nexport interface VvarTable {\n\tmajorVersion: number;\n\tminorVersion: number;\n\titemVariationStore: ItemVariationStore;\n\tadvanceHeightMapping: DeltaSetIndexMap | null;\n\ttsbMapping: DeltaSetIndexMap | null; // Top side bearing\n\tbsbMapping: DeltaSetIndexMap | null; // Bottom side bearing\n\tvOrgMapping: DeltaSetIndexMap | null; // Vertical origin\n}\n\n/**\n * Parse VVAR table\n */\nexport function parseVvar(reader: Reader): VvarTable {\n\tconst majorVersion = reader.uint16();\n\tconst minorVersion = reader.uint16();\n\tconst itemVariationStoreOffset = reader.offset32();\n\tconst advanceHeightMappingOffset = reader.offset32();\n\tconst tsbMappingOffset = reader.offset32();\n\tconst bsbMappingOffset = reader.offset32();\n\tconst vOrgMappingOffset = reader.offset32();\n\n\t// Parse item variation store\n\tconst itemVariationStore = parseItemVariationStore(\n\t\treader.sliceFrom(itemVariationStoreOffset),\n\t);\n\n\t// Parse mappings\n\tconst advanceHeightMapping =\n\t\tadvanceHeightMappingOffset !== 0\n\t\t\t? parseDeltaSetIndexMap(reader.sliceFrom(advanceHeightMappingOffset))\n\t\t\t: null;\n\n\tconst tsbMapping =\n\t\ttsbMappingOffset !== 0\n\t\t\t? parseDeltaSetIndexMap(reader.sliceFrom(tsbMappingOffset))\n\t\t\t: null;\n\n\tconst bsbMapping =\n\t\tbsbMappingOffset !== 0\n\t\t\t? parseDeltaSetIndexMap(reader.sliceFrom(bsbMappingOffset))\n\t\t\t: null;\n\n\tconst vOrgMapping =\n\t\tvOrgMappingOffset !== 0\n\t\t\t? parseDeltaSetIndexMap(reader.sliceFrom(vOrgMappingOffset))\n\t\t\t: null;\n\n\treturn {\n\t\tmajorVersion,\n\t\tminorVersion,\n\t\titemVariationStore,\n\t\tadvanceHeightMapping,\n\t\ttsbMapping,\n\t\tbsbMapping,\n\t\tvOrgMapping,\n\t};\n}\n\nfunction parseItemVariationStore(reader: Reader): ItemVariationStore {\n\tconst format = reader.uint16();\n\tconst variationRegionListOffset = reader.offset32();\n\tconst itemVariationDataCount = reader.uint16();\n\n\tconst itemVariationDataOffsets: uint32[] = [];\n\tfor (let i = 0; i < itemVariationDataCount; i++) {\n\t\titemVariationDataOffsets.push(reader.offset32());\n\t}\n\n\t// Parse variation regions\n\tconst regionReader = reader.sliceFrom(variationRegionListOffset);\n\tconst axisCount = regionReader.uint16();\n\tconst regionCount = regionReader.uint16();\n\n\tconst variationRegions: VariationRegion[] = [];\n\tfor (let i = 0; i < regionCount; i++) {\n\t\tconst regionAxes: {\n\t\t\tstartCoord: number;\n\t\t\tpeakCoord: number;\n\t\t\tendCoord: number;\n\t\t}[] = [];\n\t\tfor (let j = 0; j < axisCount; j++) {\n\t\t\tregionAxes.push({\n\t\t\t\tstartCoord: regionReader.f2dot14(),\n\t\t\t\tpeakCoord: regionReader.f2dot14(),\n\t\t\t\tendCoord: regionReader.f2dot14(),\n\t\t\t});\n\t\t}\n\t\tvariationRegions.push({ regionAxes });\n\t}\n\n\t// Parse item variation data\n\tconst itemVariationData: {\n\t\titemCount: uint16;\n\t\tregionIndexes: uint16[];\n\t\tdeltaSets: number[][];\n\t}[] = [];\n\tfor (const offset of itemVariationDataOffsets) {\n\t\tconst dataReader = reader.sliceFrom(offset);\n\t\tconst itemCount = dataReader.uint16();\n\t\tconst wordDeltaCount = dataReader.uint16();\n\t\tconst regionIndexCount = dataReader.uint16();\n\n\t\tconst regionIndexes: uint16[] = [];\n\t\tfor (let i = 0; i < regionIndexCount; i++) {\n\t\t\tregionIndexes.push(dataReader.uint16());\n\t\t}\n\n\t\t// Parse delta sets\n\t\tconst longWords = (wordDeltaCount & 0x8000) !== 0;\n\t\tconst wordCount = wordDeltaCount & 0x7fff;\n\t\tconst shortCount = regionIndexCount - wordCount;\n\n\t\tconst deltaSets: number[][] = [];\n\t\tfor (let i = 0; i < itemCount; i++) {\n\t\t\tconst deltas: number[] = [];\n\t\t\t// Read word-sized deltas\n\t\t\tfor (let j = 0; j < wordCount; j++) {\n\t\t\t\tif (longWords) {\n\t\t\t\t\tdeltas.push(dataReader.int32());\n\t\t\t\t} else {\n\t\t\t\t\tdeltas.push(dataReader.int16());\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Read short-sized deltas\n\t\t\tfor (let j = 0; j < shortCount; j++) {\n\t\t\t\tif (longWords) {\n\t\t\t\t\tdeltas.push(dataReader.int16());\n\t\t\t\t} else {\n\t\t\t\t\tdeltas.push(dataReader.int8());\n\t\t\t\t}\n\t\t\t}\n\t\t\tdeltaSets.push(deltas);\n\t\t}\n\n\t\titemVariationData.push({ itemCount, regionIndexes, deltaSets });\n\t}\n\n\treturn { format, variationRegions, itemVariationData };\n}\n\nfunction parseDeltaSetIndexMap(reader: Reader): DeltaSetIndexMap {\n\tconst format = reader.uint8();\n\tconst entryFormat = reader.uint8();\n\tconst mapCount = format === 0 ? reader.uint16() : reader.uint32();\n\n\tconst innerIndexBitCount = (entryFormat & 0x0f) + 1;\n\tconst mapEntrySize = ((entryFormat >> 4) & 0x03) + 1;\n\n\tconst mapData: { outer: number; inner: number }[] = [];\n\tfor (let i = 0; i < mapCount; i++) {\n\t\tlet entry = 0;\n\t\tfor (let j = 0; j < mapEntrySize; j++) {\n\t\t\tentry = (entry << 8) | reader.uint8();\n\t\t}\n\n\t\tconst inner = entry & ((1 << innerIndexBitCount) - 1);\n\t\tconst outer = entry >> innerIndexBitCount;\n\t\tmapData.push({ outer, inner });\n\t}\n\n\treturn { format, mapCount, entryFormat, innerIndexBitCount, mapData };\n}\n\n/**\n * Get advance height delta for a glyph at given variation coordinates\n */\nexport function getAdvanceHeightDelta(\n\tvvar: VvarTable,\n\tglyphId: GlyphId,\n\tcoords: number[],\n): number {\n\tconst mapping = vvar.advanceHeightMapping;\n\n\t// Get outer/inner index\n\tlet outer: number;\n\tlet inner: number;\n\n\tif (mapping && glyphId < mapping.mapData.length) {\n\t\tconst entry = mapping.mapData[glyphId];\n\t\tif (!entry) {\n\t\t\treturn 0;\n\t\t}\n\t\touter = entry.outer;\n\t\tinner = entry.inner;\n\t} else {\n\t\t// Direct mapping: outer = 0, inner = glyphId\n\t\touter = 0;\n\t\tinner = glyphId;\n\t}\n\n\treturn calculateDelta(vvar.itemVariationStore, outer, inner, coords);\n}\n\n/**\n * Get top side bearing delta for a glyph at given variation coordinates\n */\nexport function getTsbDelta(\n\tvvar: VvarTable,\n\tglyphId: GlyphId,\n\tcoords: number[],\n): number {\n\tconst mapping = vvar.tsbMapping;\n\tif (!mapping) return 0;\n\n\tif (glyphId >= mapping.mapData.length) return 0;\n\n\tconst entry = mapping.mapData[glyphId];\n\tif (!entry) return 0;\n\n\treturn calculateDelta(\n\t\tvvar.itemVariationStore,\n\t\tentry.outer,\n\t\tentry.inner,\n\t\tcoords,\n\t);\n}\n\n/**\n * Get bottom side bearing delta for a glyph at given variation coordinates\n */\nexport function getBsbDelta(\n\tvvar: VvarTable,\n\tglyphId: GlyphId,\n\tcoords: number[],\n): number {\n\tconst mapping = vvar.bsbMapping;\n\tif (!mapping) return 0;\n\n\tif (glyphId >= mapping.mapData.length) return 0;\n\n\tconst entry = mapping.mapData[glyphId];\n\tif (!entry) return 0;\n\n\treturn calculateDelta(\n\t\tvvar.itemVariationStore,\n\t\tentry.outer,\n\t\tentry.inner,\n\t\tcoords,\n\t);\n}\n\n/**\n * Get vertical origin delta for a glyph at given variation coordinates\n */\nexport function getVorgDelta(\n\tvvar: VvarTable,\n\tglyphId: GlyphId,\n\tcoords: number[],\n): number {\n\tconst mapping = vvar.vOrgMapping;\n\tif (!mapping) return 0;\n\n\tif (glyphId >= mapping.mapData.length) return 0;\n\n\tconst entry = mapping.mapData[glyphId];\n\tif (!entry) return 0;\n\n\treturn calculateDelta(\n\t\tvvar.itemVariationStore,\n\t\tentry.outer,\n\t\tentry.inner,\n\t\tcoords,\n\t);\n}\n\n/**\n * Calculate delta from variation store\n */\nfunction calculateDelta(\n\tstore: ItemVariationStore,\n\touter: number,\n\tinner: number,\n\tcoords: number[],\n): number {\n\tconst varData = store.itemVariationData[outer];\n\tif (!varData || inner >= varData.itemCount) {\n\t\treturn 0;\n\t}\n\n\tconst deltaSet = varData.deltaSets[inner];\n\tif (!deltaSet) {\n\t\treturn 0;\n\t}\n\n\t// Calculate total delta\n\tlet delta = 0;\n\tfor (const [i, regionIndex] of varData.regionIndexes.entries()) {\n\t\tconst region = store.variationRegions[regionIndex];\n\t\tif (!region) continue;\n\n\t\tconst scalar = calculateRegionScalar(region, coords);\n\t\tconst regionDelta = deltaSet[i] ?? 0;\n\t\tdelta += scalar * regionDelta;\n\t}\n\n\treturn Math.round(delta);\n}\n",
66
- "import type { GlyphId, TableRecord, Tag } from \"../types.ts\";\nimport { Tags, tagToString } from \"../types.ts\";\nimport { Reader } from \"./binary/reader.ts\";\nimport { woff2ToSfnt } from \"./woff2.ts\";\n\n// WOFF/WOFF2 magic numbers\nconst WOFF_MAGIC = 0x774f4646; // 'wOFF'\nconst WOFF2_MAGIC = 0x774f4632; // 'wOF2'\n\n/** Check if buffer is WOFF2 format */\nfunction isWoff2(buffer: ArrayBuffer): boolean {\n\tconst view = new DataView(buffer);\n\treturn view.getUint32(0, false) === WOFF2_MAGIC;\n}\n\n/** Check if buffer is WOFF format */\nfunction isWoff(buffer: ArrayBuffer): boolean {\n\tconst view = new DataView(buffer);\n\treturn view.getUint32(0, false) === WOFF_MAGIC;\n}\n\nimport { type AvarTable, parseAvar } from \"./tables/avar.ts\";\nimport { type BaseTable, parseBase } from \"./tables/base.ts\";\nimport {\n\ttype CbdtTable,\n\ttype CblcTable,\n\tparseCbdt,\n\tparseCblc,\n} from \"./tables/cbdt.ts\";\nimport { type CffTable, parseCff } from \"./tables/cff.ts\";\nimport {\n\texecuteCff2CharString,\n\texecuteCffCharString,\n} from \"./tables/cff-charstring.ts\";\nimport { type Cff2Table, parseCff2 } from \"./tables/cff2.ts\";\nimport { type CmapTable, getGlyphId, parseCmap } from \"./tables/cmap.ts\";\nimport { type ColrTable, parseColr } from \"./tables/colr.ts\";\nimport { type CpalTable, parseCpal } from \"./tables/cpal.ts\";\nimport { type FeatTable, parseFeat } from \"./tables/feat.ts\";\nimport { type FvarTable, parseFvar } from \"./tables/fvar.ts\";\nimport { type GaspTable, parseGasp } from \"./tables/gasp.ts\";\nimport { type GdefTable, parseGdef } from \"./tables/gdef.ts\";\nimport {\n\ttype Contour,\n\ttype GlyfTable,\n\ttype Glyph,\n\tgetGlyphBounds,\n\tgetGlyphContours,\n\tgetGlyphContoursWithVariation,\n\tparseGlyf,\n\tparseGlyph,\n} from \"./tables/glyf.ts\";\nimport { type GposTable, parseGpos } from \"./tables/gpos.ts\";\nimport { type GsubTable, parseGsub } from \"./tables/gsub.ts\";\nimport { type GvarTable, parseGvar } from \"./tables/gvar.ts\";\nimport { type HeadTable, parseHead } from \"./tables/head.ts\";\nimport { type HheaTable, parseHhea } from \"./tables/hhea.ts\";\nimport {\n\ttype CvtTable,\n\ttype FpgmTable,\n\ttype PrepTable,\n\tparseCvt,\n\tparseFpgm,\n\tparsePrep,\n} from \"./tables/hinting.ts\";\nimport {\n\tgetAdvanceWidth,\n\tgetLeftSideBearing,\n\ttype HmtxTable,\n\tparseHmtx,\n} from \"./tables/hmtx.ts\";\nimport { type HvarTable, parseHvar } from \"./tables/hvar.ts\";\nimport { type JstfTable, parseJstf } from \"./tables/jstf.ts\";\nimport { type KernTable, parseKern } from \"./tables/kern.ts\";\nimport { type KerxTable, parseKerx } from \"./tables/kerx.ts\";\nimport { type LocaTable, parseLoca } from \"./tables/loca.ts\";\nimport { type MathTable, parseMath } from \"./tables/math.ts\";\nimport { type MaxpTable, parseMaxp } from \"./tables/maxp.ts\";\nimport { type MorxTable, parseMorx } from \"./tables/morx.ts\";\nimport { type MvarTable, parseMvar } from \"./tables/mvar.ts\";\nimport { type NameTable, parseName } from \"./tables/name.ts\";\nimport { type Os2Table, parseOs2 } from \"./tables/os2.ts\";\nimport { type PostTable, parsePost } from \"./tables/post.ts\";\nimport { parseSbix, type SbixTable } from \"./tables/sbix.ts\";\nimport {\n\ttype FontDirectory,\n\tisTrueType,\n\tparseFontDirectory,\n} from \"./tables/sfnt.ts\";\nimport { parseStat, type StatTable } from \"./tables/stat.ts\";\nimport { parseSvg, type SvgTable } from \"./tables/svg.ts\";\nimport { parseTrak, type TrakTable } from \"./tables/trak.ts\";\nimport { parseVhea, type VheaTable } from \"./tables/vhea.ts\";\nimport { parseVmtx, type VmtxTable } from \"./tables/vmtx.ts\";\nimport { parseVorg, type VorgTable } from \"./tables/vorg.ts\";\nimport { parseVvar, type VvarTable } from \"./tables/vvar.ts\";\n\n/** Font loading options */\nexport interface FontLoadOptions {\n\t/** Tables to parse eagerly (default: lazy) */\n\teagerTables?: Tag[];\n}\n\n/**\n * Represents a loaded font file.\n * Tables are parsed lazily on first access.\n */\nexport class Font {\n\tprivate readonly reader: Reader;\n\tprivate readonly directory: FontDirectory;\n\n\t// Lazy-loaded tables\n\tprivate _head: HeadTable | null = null;\n\tprivate _maxp: MaxpTable | null = null;\n\tprivate _hhea: HheaTable | null = null;\n\tprivate _hmtx: HmtxTable | null = null;\n\tprivate _cmap: CmapTable | null = null;\n\tprivate _gdef: GdefTable | null | undefined = undefined;\n\tprivate _gsub: GsubTable | null | undefined = undefined;\n\tprivate _gpos: GposTable | null | undefined = undefined;\n\tprivate _kern: KernTable | null | undefined = undefined;\n\tprivate _fvar: FvarTable | null | undefined = undefined;\n\tprivate _hvar: HvarTable | null | undefined = undefined;\n\tprivate _vhea: VheaTable | null | undefined = undefined;\n\tprivate _vmtx: VmtxTable | null | undefined = undefined;\n\tprivate _morx: MorxTable | null | undefined = undefined;\n\tprivate _gvar: GvarTable | null | undefined = undefined;\n\tprivate _avar: AvarTable | null | undefined = undefined;\n\tprivate _kerx: KerxTable | null | undefined = undefined;\n\tprivate _trak: TrakTable | null | undefined = undefined;\n\tprivate _cff: CffTable | null | undefined = undefined;\n\tprivate _cff2: Cff2Table | null | undefined = undefined;\n\tprivate _colr: ColrTable | null | undefined = undefined;\n\tprivate _cpal: CpalTable | null | undefined = undefined;\n\tprivate _vvar: VvarTable | null | undefined = undefined;\n\tprivate _mvar: MvarTable | null | undefined = undefined;\n\tprivate _os2: Os2Table | null | undefined = undefined;\n\tprivate _name: NameTable | null | undefined = undefined;\n\tprivate _post: PostTable | null | undefined = undefined;\n\tprivate _base: BaseTable | null | undefined = undefined;\n\tprivate _jstf: JstfTable | null | undefined = undefined;\n\tprivate _math: MathTable | null | undefined = undefined;\n\tprivate _loca: LocaTable | null | undefined = undefined;\n\tprivate _glyf: GlyfTable | null | undefined = undefined;\n\tprivate _svg: SvgTable | null | undefined = undefined;\n\tprivate _vorg: VorgTable | null | undefined = undefined;\n\tprivate _sbix: SbixTable | null | undefined = undefined;\n\tprivate _stat: StatTable | null | undefined = undefined;\n\tprivate _cbdt: CbdtTable | null | undefined = undefined;\n\tprivate _cblc: CblcTable | null | undefined = undefined;\n\tprivate _feat: FeatTable | null | undefined = undefined;\n\tprivate _fpgm: FpgmTable | null | undefined = undefined;\n\tprivate _prep: PrepTable | null | undefined = undefined;\n\tprivate _cvt: CvtTable | null | undefined = undefined;\n\tprivate _gasp: GaspTable | null | undefined = undefined;\n\n\tprivate constructor(buffer: ArrayBuffer, _options: FontLoadOptions = {}) {\n\t\tthis.reader = new Reader(buffer);\n\t\tthis.directory = parseFontDirectory(this.reader);\n\t}\n\n\t/** Load font from ArrayBuffer (sync - does not support WOFF2) */\n\tstatic load(buffer: ArrayBuffer, options?: FontLoadOptions): Font {\n\t\tif (isWoff2(buffer)) {\n\t\t\tthrow new Error(\n\t\t\t\t\"WOFF2 requires async loading. Use Font.loadAsync() instead.\",\n\t\t\t);\n\t\t}\n\t\tif (isWoff(buffer)) {\n\t\t\tthrow new Error(\n\t\t\t\t\"WOFF format is not supported. Please use TTF, OTF, or WOFF2.\",\n\t\t\t);\n\t\t}\n\t\treturn new Font(buffer, options);\n\t}\n\n\t/** Load font from ArrayBuffer with WOFF2 support (async) */\n\tstatic async loadAsync(\n\t\tbuffer: ArrayBuffer,\n\t\toptions?: FontLoadOptions,\n\t): Promise<Font> {\n\t\tif (isWoff2(buffer)) {\n\t\t\tbuffer = await woff2ToSfnt(buffer);\n\t\t} else if (isWoff(buffer)) {\n\t\t\tthrow new Error(\n\t\t\t\t\"WOFF format is not supported. Please use TTF, OTF, or WOFF2.\",\n\t\t\t);\n\t\t}\n\t\treturn new Font(buffer, options);\n\t}\n\n\t/** Load font from URL (works in browser and Bun, supports WOFF2) */\n\tstatic async fromURL(url: string, options?: FontLoadOptions): Promise<Font> {\n\t\tconst response = await fetch(url);\n\t\tif (!response.ok) {\n\t\t\tthrow new Error(\n\t\t\t\t`Failed to fetch font: ${response.status} ${response.statusText}`,\n\t\t\t);\n\t\t}\n\t\tconst buffer = await response.arrayBuffer();\n\t\treturn Font.loadAsync(buffer, options);\n\t}\n\n\t/** Load font from file path (Bun only, supports WOFF2) */\n\tstatic async fromFile(\n\t\tpath: string,\n\t\toptions?: FontLoadOptions,\n\t): Promise<Font> {\n\t\tconst file = Bun.file(path);\n\t\tconst buffer = await file.arrayBuffer();\n\t\treturn Font.loadAsync(buffer, options);\n\t}\n\n\t// Table accessors\n\n\t/** Check if font has a specific table */\n\thasTable(tag: Tag): boolean {\n\t\treturn this.directory.tables.has(tag);\n\t}\n\n\t/** Get table record */\n\tgetTableRecord(tag: Tag): TableRecord | undefined {\n\t\treturn this.directory.tables.get(tag);\n\t}\n\n\t/** Get reader for a table */\n\tgetTableReader(tag: Tag): Reader | null {\n\t\tconst record = this.directory.tables.get(tag);\n\t\tif (!record) return null;\n\t\treturn this.reader.slice(record.offset, record.length);\n\t}\n\n\t// Required tables (lazy-loaded)\n\n\tget head(): HeadTable {\n\t\tif (!this._head) {\n\t\t\tconst reader = this.getTableReader(Tags.head);\n\t\t\tif (!reader) throw new Error(\"Missing required 'head' table\");\n\t\t\tthis._head = parseHead(reader);\n\t\t}\n\t\treturn this._head;\n\t}\n\n\tget maxp(): MaxpTable {\n\t\tif (!this._maxp) {\n\t\t\tconst reader = this.getTableReader(Tags.maxp);\n\t\t\tif (!reader) throw new Error(\"Missing required 'maxp' table\");\n\t\t\tthis._maxp = parseMaxp(reader);\n\t\t}\n\t\treturn this._maxp;\n\t}\n\n\tget hhea(): HheaTable {\n\t\tif (!this._hhea) {\n\t\t\tconst reader = this.getTableReader(Tags.hhea);\n\t\t\tif (!reader) throw new Error(\"Missing required 'hhea' table\");\n\t\t\tthis._hhea = parseHhea(reader);\n\t\t}\n\t\treturn this._hhea;\n\t}\n\n\tget hmtx(): HmtxTable {\n\t\tif (!this._hmtx) {\n\t\t\tconst reader = this.getTableReader(Tags.hmtx);\n\t\t\tif (!reader) throw new Error(\"Missing required 'hmtx' table\");\n\t\t\tthis._hmtx = parseHmtx(\n\t\t\t\treader,\n\t\t\t\tthis.hhea.numberOfHMetrics,\n\t\t\t\tthis.numGlyphs,\n\t\t\t);\n\t\t}\n\t\treturn this._hmtx;\n\t}\n\n\tget cmap(): CmapTable {\n\t\tif (!this._cmap) {\n\t\t\tconst record = this.getTableRecord(Tags.cmap);\n\t\t\tconst reader = this.getTableReader(Tags.cmap);\n\t\t\tif (!reader || !record) throw new Error(\"Missing required 'cmap' table\");\n\t\t\tthis._cmap = parseCmap(reader, record.length);\n\t\t}\n\t\treturn this._cmap;\n\t}\n\n\tget gdef(): GdefTable | null {\n\t\tif (this._gdef === undefined) {\n\t\t\tconst reader = this.getTableReader(Tags.GDEF);\n\t\t\tthis._gdef = reader ? parseGdef(reader) : null;\n\t\t}\n\t\treturn this._gdef;\n\t}\n\n\tget gsub(): GsubTable | null {\n\t\tif (this._gsub === undefined) {\n\t\t\tconst reader = this.getTableReader(Tags.GSUB);\n\t\t\tthis._gsub = reader ? parseGsub(reader) : null;\n\t\t}\n\t\treturn this._gsub;\n\t}\n\n\tget gpos(): GposTable | null {\n\t\tif (this._gpos === undefined) {\n\t\t\tconst reader = this.getTableReader(Tags.GPOS);\n\t\t\tthis._gpos = reader ? parseGpos(reader) : null;\n\t\t}\n\t\treturn this._gpos;\n\t}\n\n\tget kern(): KernTable | null {\n\t\tif (this._kern === undefined) {\n\t\t\tconst reader = this.getTableReader(Tags.kern);\n\t\t\tthis._kern = reader ? parseKern(reader) : null;\n\t\t}\n\t\treturn this._kern;\n\t}\n\n\tget fvar(): FvarTable | null {\n\t\tif (this._fvar === undefined) {\n\t\t\tconst reader = this.getTableReader(Tags.fvar);\n\t\t\tthis._fvar = reader ? parseFvar(reader) : null;\n\t\t}\n\t\treturn this._fvar;\n\t}\n\n\tget hvar(): HvarTable | null {\n\t\tif (this._hvar === undefined) {\n\t\t\tconst reader = this.getTableReader(Tags.HVAR);\n\t\t\tthis._hvar = reader ? parseHvar(reader) : null;\n\t\t}\n\t\treturn this._hvar;\n\t}\n\n\tget vhea(): VheaTable | null {\n\t\tif (this._vhea === undefined) {\n\t\t\tconst reader = this.getTableReader(Tags.vhea);\n\t\t\tthis._vhea = reader ? parseVhea(reader) : null;\n\t\t}\n\t\treturn this._vhea;\n\t}\n\n\tget vmtx(): VmtxTable | null {\n\t\tif (this._vmtx === undefined) {\n\t\t\tconst vhea = this.vhea;\n\t\t\tif (!vhea) {\n\t\t\t\tthis._vmtx = null;\n\t\t\t} else {\n\t\t\t\tconst reader = this.getTableReader(Tags.vmtx);\n\t\t\t\tthis._vmtx = reader\n\t\t\t\t\t? parseVmtx(reader, vhea.numberOfVMetrics, this.numGlyphs)\n\t\t\t\t\t: null;\n\t\t\t}\n\t\t}\n\t\treturn this._vmtx;\n\t}\n\n\tget morx(): MorxTable | null {\n\t\tif (this._morx === undefined) {\n\t\t\tconst reader = this.getTableReader(Tags.morx);\n\t\t\tthis._morx = reader ? parseMorx(reader) : null;\n\t\t}\n\t\treturn this._morx;\n\t}\n\n\tget gvar(): GvarTable | null {\n\t\tif (this._gvar === undefined) {\n\t\t\tconst reader = this.getTableReader(Tags.gvar);\n\t\t\tthis._gvar = reader ? parseGvar(reader, this.numGlyphs) : null;\n\t\t}\n\t\treturn this._gvar;\n\t}\n\n\tget avar(): AvarTable | null {\n\t\tif (this._avar === undefined) {\n\t\t\tconst fvar = this.fvar;\n\t\t\tif (!fvar) {\n\t\t\t\tthis._avar = null;\n\t\t\t} else {\n\t\t\t\tconst reader = this.getTableReader(Tags.avar);\n\t\t\t\tthis._avar = reader ? parseAvar(reader, fvar.axes.length) : null;\n\t\t\t}\n\t\t}\n\t\treturn this._avar;\n\t}\n\n\tget kerx(): KerxTable | null {\n\t\tif (this._kerx === undefined) {\n\t\t\tconst reader = this.getTableReader(Tags.kerx);\n\t\t\tthis._kerx = reader ? parseKerx(reader) : null;\n\t\t}\n\t\treturn this._kerx;\n\t}\n\n\tget trak(): TrakTable | null {\n\t\tif (this._trak === undefined) {\n\t\t\tconst reader = this.getTableReader(Tags.trak);\n\t\t\tthis._trak = reader ? parseTrak(reader) : null;\n\t\t}\n\t\treturn this._trak;\n\t}\n\n\tget cff(): CffTable | null {\n\t\tif (this._cff === undefined) {\n\t\t\tconst reader = this.getTableReader(Tags.CFF);\n\t\t\tthis._cff = reader ? parseCff(reader) : null;\n\t\t}\n\t\treturn this._cff;\n\t}\n\n\tget cff2(): Cff2Table | null {\n\t\tif (this._cff2 === undefined) {\n\t\t\tconst reader = this.getTableReader(Tags.CFF2);\n\t\t\tthis._cff2 = reader ? parseCff2(reader) : null;\n\t\t}\n\t\treturn this._cff2;\n\t}\n\n\tget colr(): ColrTable | null {\n\t\tif (this._colr === undefined) {\n\t\t\tconst reader = this.getTableReader(Tags.COLR);\n\t\t\tthis._colr = reader ? parseColr(reader) : null;\n\t\t}\n\t\treturn this._colr;\n\t}\n\n\tget cpal(): CpalTable | null {\n\t\tif (this._cpal === undefined) {\n\t\t\tconst reader = this.getTableReader(Tags.CPAL);\n\t\t\tthis._cpal = reader ? parseCpal(reader) : null;\n\t\t}\n\t\treturn this._cpal;\n\t}\n\n\tget vvar(): VvarTable | null {\n\t\tif (this._vvar === undefined) {\n\t\t\tconst reader = this.getTableReader(Tags.VVAR);\n\t\t\tthis._vvar = reader ? parseVvar(reader) : null;\n\t\t}\n\t\treturn this._vvar;\n\t}\n\n\tget mvar(): MvarTable | null {\n\t\tif (this._mvar === undefined) {\n\t\t\tconst reader = this.getTableReader(Tags.MVAR);\n\t\t\tthis._mvar = reader ? parseMvar(reader) : null;\n\t\t}\n\t\treturn this._mvar;\n\t}\n\n\tget os2(): Os2Table | null {\n\t\tif (this._os2 === undefined) {\n\t\t\tconst reader = this.getTableReader(Tags.OS2);\n\t\t\tthis._os2 = reader ? parseOs2(reader) : null;\n\t\t}\n\t\treturn this._os2;\n\t}\n\n\tget name(): NameTable | null {\n\t\tif (this._name === undefined) {\n\t\t\tconst reader = this.getTableReader(Tags.name);\n\t\t\tthis._name = reader ? parseName(reader) : null;\n\t\t}\n\t\treturn this._name;\n\t}\n\n\tget post(): PostTable | null {\n\t\tif (this._post === undefined) {\n\t\t\tconst reader = this.getTableReader(Tags.post);\n\t\t\tthis._post = reader ? parsePost(reader) : null;\n\t\t}\n\t\treturn this._post;\n\t}\n\n\tget base(): BaseTable | null {\n\t\tif (this._base === undefined) {\n\t\t\tconst reader = this.getTableReader(Tags.BASE);\n\t\t\tthis._base = reader ? parseBase(reader) : null;\n\t\t}\n\t\treturn this._base;\n\t}\n\n\tget jstf(): JstfTable | null {\n\t\tif (this._jstf === undefined) {\n\t\t\tconst reader = this.getTableReader(Tags.JSTF);\n\t\t\tthis._jstf = reader ? parseJstf(reader) : null;\n\t\t}\n\t\treturn this._jstf;\n\t}\n\n\tget math(): MathTable | null {\n\t\tif (this._math === undefined) {\n\t\t\tconst reader = this.getTableReader(Tags.MATH);\n\t\t\tthis._math = reader ? parseMath(reader) : null;\n\t\t}\n\t\treturn this._math;\n\t}\n\n\tget loca(): LocaTable | null {\n\t\tif (this._loca === undefined) {\n\t\t\tconst reader = this.getTableReader(Tags.loca);\n\t\t\tthis._loca = reader\n\t\t\t\t? parseLoca(reader, this.numGlyphs, this.head.indexToLocFormat)\n\t\t\t\t: null;\n\t\t}\n\t\treturn this._loca;\n\t}\n\n\tget glyf(): GlyfTable | null {\n\t\tif (this._glyf === undefined) {\n\t\t\tconst reader = this.getTableReader(Tags.glyf);\n\t\t\tthis._glyf = reader ? parseGlyf(reader) : null;\n\t\t}\n\t\treturn this._glyf;\n\t}\n\n\tget svg(): SvgTable | null {\n\t\tif (this._svg === undefined) {\n\t\t\tconst reader = this.getTableReader(Tags.SVG);\n\t\t\tthis._svg = reader ? parseSvg(reader) : null;\n\t\t}\n\t\treturn this._svg;\n\t}\n\n\tget vorg(): VorgTable | null {\n\t\tif (this._vorg === undefined) {\n\t\t\tconst reader = this.getTableReader(Tags.VORG);\n\t\t\tthis._vorg = reader ? parseVorg(reader) : null;\n\t\t}\n\t\treturn this._vorg;\n\t}\n\n\tget sbix(): SbixTable | null {\n\t\tif (this._sbix === undefined) {\n\t\t\tconst reader = this.getTableReader(Tags.sbix);\n\t\t\tthis._sbix = reader ? parseSbix(reader, this.numGlyphs) : null;\n\t\t}\n\t\treturn this._sbix;\n\t}\n\n\tget stat(): StatTable | null {\n\t\tif (this._stat === undefined) {\n\t\t\tconst reader = this.getTableReader(Tags.STAT);\n\t\t\tthis._stat = reader ? parseStat(reader) : null;\n\t\t}\n\t\treturn this._stat;\n\t}\n\n\tget cblc(): CblcTable | null {\n\t\tif (this._cblc === undefined) {\n\t\t\tconst reader = this.getTableReader(Tags.CBLC);\n\t\t\tthis._cblc = reader ? parseCblc(reader) : null;\n\t\t}\n\t\treturn this._cblc;\n\t}\n\n\tget cbdt(): CbdtTable | null {\n\t\tif (this._cbdt === undefined) {\n\t\t\tconst reader = this.getTableReader(Tags.CBDT);\n\t\t\tthis._cbdt = reader ? parseCbdt(reader) : null;\n\t\t}\n\t\treturn this._cbdt;\n\t}\n\n\tget feat(): FeatTable | null {\n\t\tif (this._feat === undefined) {\n\t\t\tconst reader = this.getTableReader(Tags.feat);\n\t\t\tthis._feat = reader ? parseFeat(reader) : null;\n\t\t}\n\t\treturn this._feat;\n\t}\n\n\tget fpgm(): FpgmTable | null {\n\t\tif (this._fpgm === undefined) {\n\t\t\tconst reader = this.getTableReader(Tags.fpgm);\n\t\t\tthis._fpgm = reader ? parseFpgm(reader) : null;\n\t\t}\n\t\treturn this._fpgm;\n\t}\n\n\tget prep(): PrepTable | null {\n\t\tif (this._prep === undefined) {\n\t\t\tconst reader = this.getTableReader(Tags.prep);\n\t\t\tthis._prep = reader ? parsePrep(reader) : null;\n\t\t}\n\t\treturn this._prep;\n\t}\n\n\tget cvtTable(): CvtTable | null {\n\t\tif (this._cvt === undefined) {\n\t\t\tconst reader = this.getTableReader(Tags.cvt);\n\t\t\tthis._cvt = reader ? parseCvt(reader) : null;\n\t\t}\n\t\treturn this._cvt;\n\t}\n\n\tget gasp(): GaspTable | null {\n\t\tif (this._gasp === undefined) {\n\t\t\tconst reader = this.getTableReader(Tags.gasp);\n\t\t\tthis._gasp = reader ? parseGasp(reader) : null;\n\t\t}\n\t\treturn this._gasp;\n\t}\n\n\t// Convenience properties\n\n\t/** Number of glyphs in the font */\n\tget numGlyphs(): number {\n\t\treturn this.maxp.numGlyphs;\n\t}\n\n\t/** Units per em */\n\tget unitsPerEm(): number {\n\t\treturn this.head.unitsPerEm;\n\t}\n\n\t/** Ascender (from hhea) */\n\tget ascender(): number {\n\t\treturn this.hhea.ascender;\n\t}\n\n\t/** Descender (from hhea) */\n\tget descender(): number {\n\t\treturn this.hhea.descender;\n\t}\n\n\t/** Line gap (from hhea) */\n\tget lineGap(): number {\n\t\treturn this.hhea.lineGap;\n\t}\n\n\t/** Is this a TrueType font (vs CFF)? */\n\tget isTrueType(): boolean {\n\t\treturn isTrueType(this.directory);\n\t}\n\n\t/** Is this a CFF font? */\n\tget isCFF(): boolean {\n\t\treturn this.hasTable(Tags.CFF) || this.hasTable(Tags.CFF2);\n\t}\n\n\t/** Is this a variable font? */\n\tget isVariable(): boolean {\n\t\treturn this.hasTable(Tags.fvar);\n\t}\n\n\t/** Has OpenType layout tables? */\n\tget hasOpenTypeLayout(): boolean {\n\t\treturn this.hasTable(Tags.GSUB) || this.hasTable(Tags.GPOS);\n\t}\n\n\t/** Has AAT layout tables? */\n\tget hasAATLayout(): boolean {\n\t\treturn this.hasTable(Tags.morx) || this.hasTable(Tags.kerx);\n\t}\n\n\t/** Is this a color font? */\n\tget isColorFont(): boolean {\n\t\treturn (\n\t\t\tthis.hasTable(Tags.COLR) ||\n\t\t\tthis.hasTable(Tags.SVG) ||\n\t\t\tthis.hasTable(Tags.sbix) ||\n\t\t\tthis.hasTable(Tags.CBDT)\n\t\t);\n\t}\n\n\t/** Does this font have TrueType hinting? */\n\tget hasHinting(): boolean {\n\t\treturn (\n\t\t\tthis.isTrueType && (this.hasTable(Tags.fpgm) || this.hasTable(Tags.prep))\n\t\t);\n\t}\n\n\t// Glyph operations\n\n\t/** Get glyph ID for a Unicode codepoint */\n\tglyphId(codepoint: number): GlyphId {\n\t\treturn getGlyphId(this.cmap, codepoint);\n\t}\n\n\t/** Get glyph ID for a character */\n\tglyphIdForChar(char: string): GlyphId {\n\t\tconst codepoint = char.codePointAt(0);\n\t\tif (codepoint === undefined) return 0;\n\t\treturn this.glyphId(codepoint);\n\t}\n\n\t/** Get advance width for a glyph */\n\tadvanceWidth(glyphId: GlyphId): number {\n\t\treturn getAdvanceWidth(this.hmtx, glyphId);\n\t}\n\n\t/** Get left side bearing for a glyph */\n\tleftSideBearing(glyphId: GlyphId): number {\n\t\treturn getLeftSideBearing(this.hmtx, glyphId);\n\t}\n\n\t/** List all table tags in the font */\n\tlistTables(): string[] {\n\t\treturn Array.from(this.directory.tables.keys()).map(tagToString);\n\t}\n\n\t// Glyph outline operations\n\n\t/** Get raw glyph data (simple or composite) - TrueType only */\n\tgetGlyph(glyphId: GlyphId): Glyph | null {\n\t\tif (!this.glyf || !this.loca) return null;\n\t\treturn parseGlyph(this.glyf, this.loca, glyphId);\n\t}\n\n\t/** Get flattened contours for a glyph (resolves composites) */\n\tgetGlyphContours(glyphId: GlyphId): Contour[] | null {\n\t\t// Try TrueType first\n\t\tif (this.glyf && this.loca) {\n\t\t\treturn getGlyphContours(this.glyf, this.loca, glyphId);\n\t\t}\n\t\t// Try CFF\n\t\tif (this.cff) {\n\t\t\treturn executeCffCharString(this.cff, glyphId, 0);\n\t\t}\n\t\t// Try CFF2\n\t\tif (this.cff2) {\n\t\t\treturn executeCff2CharString(this.cff2, glyphId, null);\n\t\t}\n\t\treturn null;\n\t}\n\n\t/** Get bounding box for a glyph */\n\tgetGlyphBounds(\n\t\tglyphId: GlyphId,\n\t): { xMin: number; yMin: number; xMax: number; yMax: number } | null {\n\t\t// Try TrueType first\n\t\tif (this.glyf && this.loca) {\n\t\t\treturn getGlyphBounds(this.glyf, this.loca, glyphId);\n\t\t}\n\t\t// For CFF, compute bounds from contours\n\t\tconst contours = this.getGlyphContours(glyphId);\n\t\tif (!contours || contours.length === 0) return null;\n\n\t\tlet xMin = Infinity;\n\t\tlet yMin = Infinity;\n\t\tlet xMax = -Infinity;\n\t\tlet yMax = -Infinity;\n\n\t\tfor (const contour of contours) {\n\t\t\tfor (const point of contour) {\n\t\t\t\txMin = Math.min(xMin, point.x);\n\t\t\t\tyMin = Math.min(yMin, point.y);\n\t\t\t\txMax = Math.max(xMax, point.x);\n\t\t\t\tyMax = Math.max(yMax, point.y);\n\t\t\t}\n\t\t}\n\n\t\tif (xMin === Infinity) return null;\n\t\treturn { xMin, yMin, xMax, yMax };\n\t}\n\n\t/** Get contours for a glyph with variation applied */\n\tgetGlyphContoursWithVariation(\n\t\tglyphId: GlyphId,\n\t\taxisCoords: number[],\n\t): Contour[] | null {\n\t\t// Try TrueType first\n\t\tif (this.glyf && this.loca) {\n\t\t\treturn getGlyphContoursWithVariation(\n\t\t\t\tthis.glyf,\n\t\t\t\tthis.loca,\n\t\t\t\tthis.gvar,\n\t\t\t\tglyphId,\n\t\t\t\taxisCoords,\n\t\t\t);\n\t\t}\n\t\t// Try CFF2 with variation\n\t\tif (this.cff2) {\n\t\t\treturn executeCff2CharString(this.cff2, glyphId, axisCoords);\n\t\t}\n\t\t// CFF doesn't support variations\n\t\treturn this.getGlyphContours(glyphId);\n\t}\n}\n",
67
- "import type { Reader } from \"../../font/binary/reader.ts\";\nimport type { Tag, uint16, uint32 } from \"../../types.ts\";\n\n/**\n * FeatureVariations table\n * Allows different feature substitutions based on variation axis coordinates\n * Used in GSUB/GPOS for variable fonts\n */\nexport interface FeatureVariations {\n\tmajorVersion: number;\n\tminorVersion: number;\n\tfeatureVariationRecords: FeatureVariationRecord[];\n}\n\n/**\n * Feature variation record\n * Contains a condition set and feature substitutions to apply when conditions are met\n */\nexport interface FeatureVariationRecord {\n\tconditionSet: ConditionSet;\n\tfeatureTableSubstitution: FeatureTableSubstitution;\n}\n\n/**\n * Condition set - all conditions must be met\n */\nexport interface ConditionSet {\n\tconditions: Condition[];\n}\n\n/**\n * Single axis condition\n */\nexport interface Condition {\n\tformat: number;\n\taxisIndex: uint16;\n\tfilterRangeMinValue: number; // F2DOT14\n\tfilterRangeMaxValue: number; // F2DOT14\n}\n\n/**\n * Feature table substitution\n * Maps feature indices to replacement feature tables\n */\nexport interface FeatureTableSubstitution {\n\tmajorVersion: number;\n\tminorVersion: number;\n\tsubstitutions: FeatureSubstitutionRecord[];\n}\n\n/**\n * Single feature substitution record\n */\nexport interface FeatureSubstitutionRecord {\n\tfeatureIndex: uint16;\n\talternateFeature: AlternateFeature;\n}\n\n/**\n * Alternate feature table\n */\nexport interface AlternateFeature {\n\tfeatureParamsOffset: uint16;\n\tlookupListIndices: uint16[];\n}\n\n/**\n * Parse FeatureVariations table\n */\nexport function parseFeatureVariations(reader: Reader): FeatureVariations {\n\tconst majorVersion = reader.uint16();\n\tconst minorVersion = reader.uint16();\n\tconst featureVariationRecordCount = reader.uint32();\n\n\tconst recordOffsets: {\n\t\tconditionSetOffset: uint32;\n\t\tfeatureSubstOffset: uint32;\n\t}[] = [];\n\tfor (let i = 0; i < featureVariationRecordCount; i++) {\n\t\trecordOffsets.push({\n\t\t\tconditionSetOffset: reader.offset32(),\n\t\t\tfeatureSubstOffset: reader.offset32(),\n\t\t});\n\t}\n\n\tconst featureVariationRecords: FeatureVariationRecord[] = [];\n\tfor (const offsets of recordOffsets) {\n\t\tconst conditionSet = parseConditionSet(\n\t\t\treader.sliceFrom(offsets.conditionSetOffset),\n\t\t);\n\t\tconst featureTableSubstitution = parseFeatureTableSubstitution(\n\t\t\treader.sliceFrom(offsets.featureSubstOffset),\n\t\t);\n\n\t\tfeatureVariationRecords.push({\n\t\t\tconditionSet,\n\t\t\tfeatureTableSubstitution,\n\t\t});\n\t}\n\n\treturn {\n\t\tmajorVersion,\n\t\tminorVersion,\n\t\tfeatureVariationRecords,\n\t};\n}\n\nfunction parseConditionSet(reader: Reader): ConditionSet {\n\tconst conditionCount = reader.uint16();\n\tconst conditionOffsets: uint32[] = [];\n\tfor (let i = 0; i < conditionCount; i++) {\n\t\tconditionOffsets.push(reader.offset32());\n\t}\n\n\tconst conditions: Condition[] = [];\n\tfor (const offset of conditionOffsets) {\n\t\tconst condReader = reader.sliceFrom(offset);\n\t\tconst format = condReader.uint16();\n\n\t\tif (format === 1) {\n\t\t\tconditions.push({\n\t\t\t\tformat,\n\t\t\t\taxisIndex: condReader.uint16(),\n\t\t\t\tfilterRangeMinValue: condReader.f2dot14(),\n\t\t\t\tfilterRangeMaxValue: condReader.f2dot14(),\n\t\t\t});\n\t\t}\n\t}\n\n\treturn { conditions };\n}\n\nfunction parseFeatureTableSubstitution(\n\treader: Reader,\n): FeatureTableSubstitution {\n\tconst majorVersion = reader.uint16();\n\tconst minorVersion = reader.uint16();\n\tconst substitutionCount = reader.uint16();\n\n\tconst substitutionRecords: { featureIndex: uint16; offset: uint32 }[] = [];\n\tfor (let i = 0; i < substitutionCount; i++) {\n\t\tsubstitutionRecords.push({\n\t\t\tfeatureIndex: reader.uint16(),\n\t\t\toffset: reader.offset32(),\n\t\t});\n\t}\n\n\tconst substitutions: FeatureSubstitutionRecord[] = [];\n\tfor (const record of substitutionRecords) {\n\t\tconst featureReader = reader.sliceFrom(record.offset);\n\t\tconst featureParamsOffset = featureReader.offset16();\n\t\tconst lookupIndexCount = featureReader.uint16();\n\t\tconst lookupListIndices = Array.from(\n\t\t\tfeatureReader.uint16Array(lookupIndexCount),\n\t\t);\n\n\t\tsubstitutions.push({\n\t\t\tfeatureIndex: record.featureIndex,\n\t\t\talternateFeature: {\n\t\t\t\tfeatureParamsOffset,\n\t\t\t\tlookupListIndices,\n\t\t\t},\n\t\t});\n\t}\n\n\treturn {\n\t\tmajorVersion,\n\t\tminorVersion,\n\t\tsubstitutions,\n\t};\n}\n\n/**\n * Evaluate condition set against axis coordinates\n * Returns true if all conditions are met\n */\nexport function evaluateConditionSet(\n\tconditionSet: ConditionSet,\n\taxisCoords: number[],\n): boolean {\n\tfor (const condition of conditionSet.conditions) {\n\t\tconst axisValue = axisCoords[condition.axisIndex] ?? 0;\n\t\tif (\n\t\t\taxisValue < condition.filterRangeMinValue ||\n\t\t\taxisValue > condition.filterRangeMaxValue\n\t\t) {\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn true;\n}\n\n/**\n * Find matching feature variation record for given axis coordinates\n * Returns the first matching record, or null if none match\n */\nexport function findMatchingFeatureVariation(\n\tfeatureVariations: FeatureVariations,\n\taxisCoords: number[],\n): FeatureVariationRecord | null {\n\tfor (const record of featureVariations.featureVariationRecords) {\n\t\tif (evaluateConditionSet(record.conditionSet, axisCoords)) {\n\t\t\treturn record;\n\t\t}\n\t}\n\treturn null;\n}\n\n/**\n * Get substituted lookup list indices for a feature\n * Returns the original lookups if no substitution applies\n */\nexport function getSubstitutedLookups(\n\tfeatureVariations: FeatureVariations | null,\n\tfeatureIndex: number,\n\toriginalLookups: uint16[],\n\taxisCoords: number[] | null,\n): uint16[] {\n\tif (!featureVariations || !axisCoords) {\n\t\treturn originalLookups;\n\t}\n\n\tconst matchingRecord = findMatchingFeatureVariation(\n\t\tfeatureVariations,\n\t\taxisCoords,\n\t);\n\tif (!matchingRecord) {\n\t\treturn originalLookups;\n\t}\n\n\t// Check if this feature has a substitution\n\tconst substitution =\n\t\tmatchingRecord.featureTableSubstitution.substitutions.find(\n\t\t\t(s) => s.featureIndex === featureIndex,\n\t\t);\n\n\tif (substitution) {\n\t\treturn substitution.alternateFeature.lookupListIndices;\n\t}\n\n\treturn originalLookups;\n}\n\n/**\n * Apply feature variations to a feature list\n * Returns a modified feature list with substituted lookup indices\n */\nexport function applyFeatureVariations(\n\tfeatureVariations: FeatureVariations | null,\n\tfeatureLookups: Map<Tag, uint16[]>,\n\tfeatureIndices: Map<Tag, number>,\n\taxisCoords: number[] | null,\n): Map<Tag, uint16[]> {\n\tif (!featureVariations || !axisCoords) {\n\t\treturn featureLookups;\n\t}\n\n\tconst matchingRecord = findMatchingFeatureVariation(\n\t\tfeatureVariations,\n\t\taxisCoords,\n\t);\n\tif (!matchingRecord) {\n\t\treturn featureLookups;\n\t}\n\n\t// Create a new map with substituted lookups\n\tconst result = new Map(featureLookups);\n\n\tfor (const substitution of matchingRecord.featureTableSubstitution\n\t\t.substitutions) {\n\t\t// Find the feature tag for this index\n\t\tfor (const [tag, index] of featureIndices) {\n\t\t\tif (index === substitution.featureIndex) {\n\t\t\t\tresult.set(tag, substitution.alternateFeature.lookupListIndices);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn result;\n}\n",
68
- "/**\n * Rasterizer types - FreeType-style bitmap rendering\n */\n\nimport type { GlyphPath } from \"../render/path.ts\";\n\n/**\n * Pixel modes for bitmap output\n */\nexport enum PixelMode {\n\t/** 1-bit per pixel, 8 pixels per byte */\n\tMono = 0,\n\t/** 8-bit grayscale, 1 byte per pixel */\n\tGray = 1,\n\t/** 24-bit LCD subpixel RGB, 3 bytes per pixel */\n\tLCD = 2,\n\t/** 24-bit LCD subpixel vertical RGB */\n\tLCD_V = 3,\n\t/** 32-bit RGBA, 4 bytes per pixel */\n\tRGBA = 4,\n}\n\n/**\n * Fill rule for outline rendering\n */\nexport enum FillRule {\n\t/** Non-zero winding rule (default) */\n\tNonZero = 0,\n\t/** Even-odd (alternating) fill rule */\n\tEvenOdd = 1,\n}\n\n/**\n * Bitmap buffer for rasterized glyphs\n */\nexport interface Bitmap {\n\t/** Pixel buffer */\n\tbuffer: Uint8Array;\n\t/** Width in pixels */\n\twidth: number;\n\t/** Height in pixels */\n\trows: number;\n\t/** Bytes per row (may include padding) */\n\tpitch: number;\n\t/** Pixel format */\n\tpixelMode: PixelMode;\n\t/** Number of gray levels (256 for 8-bit) */\n\tnumGrays: number;\n}\n\n/**\n * A single horizontal span of pixels (for direct rendering)\n */\nexport interface Span {\n\t/** X position of span start */\n\tx: number;\n\t/** Length in pixels */\n\tlen: number;\n\t/** Coverage value 0-255 */\n\tcoverage: number;\n}\n\n/**\n * Callback for span-based rendering\n * @template T User data type passed through from render call\n */\nexport type SpanFunc<T = void> = (\n\ty: number,\n\tspans: Span[],\n\tuserData: T,\n) => void;\n\n/**\n * Rasterization parameters\n */\nexport interface RasterParams {\n\t/** Target bitmap (null for span callback mode) */\n\ttarget?: Bitmap;\n\t/** Source outline path */\n\tsource: GlyphPath;\n\t/** Fill rule */\n\tfillRule?: FillRule;\n\t/** Span callback for direct rendering */\n\tspanFunc?: SpanFunc;\n\t/** Clip box (in pixels) */\n\tclipBox?: {\n\t\txMin: number;\n\t\tyMin: number;\n\t\txMax: number;\n\t\tyMax: number;\n\t};\n}\n\n/**\n * Options for rasterizing a glyph\n */\nexport interface RasterizeOptions {\n\t/** Width in pixels */\n\twidth: number;\n\t/** Height in pixels */\n\theight: number;\n\t/** Scale factor (font units to pixels) */\n\tscale: number;\n\t/** X offset in pixels */\n\toffsetX?: number;\n\t/** Y offset in pixels */\n\toffsetY?: number;\n\t/** Pixel mode */\n\tpixelMode?: PixelMode;\n\t/** Fill rule */\n\tfillRule?: FillRule;\n\t/** Flip Y axis (font coords are Y-up, bitmap is Y-down) */\n\tflipY?: boolean;\n}\n\n/**\n * Result of glyph rasterization\n */\nexport interface RasterizedGlyph {\n\t/** Pixel data */\n\tbitmap: Bitmap;\n\t/** Bearing X (offset from origin to left edge) */\n\tbearingX: number;\n\t/** Bearing Y (offset from origin to top edge) */\n\tbearingY: number;\n}\n\n/**\n * Glyph metrics for atlas building\n */\nexport interface GlyphMetrics {\n\t/** Glyph ID */\n\tglyphId: number;\n\t/** X position in atlas */\n\tatlasX: number;\n\t/** Y position in atlas */\n\tatlasY: number;\n\t/** Width in atlas */\n\twidth: number;\n\t/** Height in atlas */\n\theight: number;\n\t/** Bearing X */\n\tbearingX: number;\n\t/** Bearing Y */\n\tbearingY: number;\n\t/** Horizontal advance */\n\tadvance: number;\n}\n\n/**\n * Texture atlas containing multiple glyphs\n */\nexport interface GlyphAtlas {\n\t/** Atlas bitmap */\n\tbitmap: Bitmap;\n\t/** Glyph metrics indexed by glyph ID */\n\tglyphs: Map<number, GlyphMetrics>;\n\t/** Font size used for rendering */\n\tfontSize: number;\n}\n\n/**\n * Options for building a glyph atlas\n */\nexport interface AtlasOptions {\n\t/** Font size in pixels */\n\tfontSize: number;\n\t/** Padding between glyphs */\n\tpadding?: number;\n\t/** Maximum atlas width */\n\tmaxWidth?: number;\n\t/** Maximum atlas height */\n\tmaxHeight?: number;\n\t/** Pixel mode */\n\tpixelMode?: PixelMode;\n\t/** Enable hinting */\n\thinting?: boolean;\n}\n\n/**\n * Create an empty bitmap\n */\nexport function createBitmap(\n\twidth: number,\n\theight: number,\n\tpixelMode: PixelMode = PixelMode.Gray,\n): Bitmap {\n\tlet bytesPerPixel: number;\n\tswitch (pixelMode) {\n\t\tcase PixelMode.Mono:\n\t\t\tbytesPerPixel = 1 / 8; // 8 pixels per byte\n\t\t\tbreak;\n\t\tcase PixelMode.Gray:\n\t\t\tbytesPerPixel = 1;\n\t\t\tbreak;\n\t\tcase PixelMode.LCD:\n\t\tcase PixelMode.LCD_V:\n\t\t\tbytesPerPixel = 3;\n\t\t\tbreak;\n\t\tcase PixelMode.RGBA:\n\t\t\tbytesPerPixel = 4;\n\t\t\tbreak;\n\t}\n\n\tconst pitch =\n\t\tpixelMode === PixelMode.Mono ? Math.ceil(width / 8) : width * bytesPerPixel;\n\n\treturn {\n\t\tbuffer: new Uint8Array(pitch * height),\n\t\twidth,\n\t\trows: height,\n\t\tpitch,\n\t\tpixelMode,\n\t\tnumGrays: pixelMode === PixelMode.Mono ? 2 : 256,\n\t};\n}\n\n/**\n * Clear a bitmap to zero\n */\nexport function clearBitmap(bitmap: Bitmap): void {\n\tbitmap.buffer.fill(0);\n}\n\n/**\n * Create a bottom-up bitmap (negative pitch)\n * Bottom-up bitmaps have row 0 at the bottom of the image,\n * which matches some graphics APIs (e.g., Windows DIB, OpenGL textures)\n */\nexport function createBottomUpBitmap(\n\twidth: number,\n\theight: number,\n\tpixelMode: PixelMode = PixelMode.Gray,\n): Bitmap {\n\tconst bitmap = createBitmap(width, height, pixelMode);\n\t// Negative pitch indicates bottom-up storage\n\tbitmap.pitch = -bitmap.pitch;\n\treturn bitmap;\n}\n",
69
- "/**\n * Arithmetic and logic instructions\n */\n\nimport type { ExecContext } from \"../types.ts\";\n\n/** ADD - Add top two values */\nexport function ADD(ctx: ExecContext): void {\n\tconst b = ctx.stack[--ctx.stackTop];\n\tconst a = ctx.stack[--ctx.stackTop];\n\tif (a === undefined || b === undefined) {\n\t\tctx.error = \"ADD: stack underflow\";\n\t\tctx.stackTop += 2;\n\t\tctx.stack[ctx.stackTop++] = 0;\n\t\treturn;\n\t}\n\tctx.stack[ctx.stackTop++] = a + b;\n}\n\n/** SUB - Subtract top two values */\nexport function SUB(ctx: ExecContext): void {\n\tconst b = ctx.stack[--ctx.stackTop];\n\tconst a = ctx.stack[--ctx.stackTop];\n\tif (a === undefined || b === undefined) {\n\t\tctx.error = \"SUB: stack underflow\";\n\t\tctx.stackTop += 2;\n\t\tctx.stack[ctx.stackTop++] = 0;\n\t\treturn;\n\t}\n\tctx.stack[ctx.stackTop++] = a - b;\n}\n\n/** DIV - Divide (26.6 fixed-point) */\nexport function DIV(ctx: ExecContext): void {\n\tconst b = ctx.stack[--ctx.stackTop];\n\tconst a = ctx.stack[--ctx.stackTop];\n\tif (a === undefined || b === undefined) {\n\t\tctx.error = \"DIV: stack underflow\";\n\t\tctx.stackTop += 2;\n\t\tctx.stack[ctx.stackTop++] = 0;\n\t\treturn;\n\t}\n\n\tif (b === 0) {\n\t\tctx.error = \"DIV: division by zero\";\n\t\tctx.stack[ctx.stackTop++] = 0;\n\t\treturn;\n\t}\n\n\t// Result is (a * 64) / b for 26.6 precision\n\tctx.stack[ctx.stackTop++] = Math.trunc((a * 64) / b);\n}\n\n/** MUL - Multiply (26.6 fixed-point) */\nexport function MUL(ctx: ExecContext): void {\n\tconst b = ctx.stack[--ctx.stackTop];\n\tconst a = ctx.stack[--ctx.stackTop];\n\tif (a === undefined || b === undefined) {\n\t\tctx.error = \"MUL: stack underflow\";\n\t\tctx.stackTop += 2;\n\t\tctx.stack[ctx.stackTop++] = 0;\n\t\treturn;\n\t}\n\n\t// Result is (a * b) / 64 for 26.6 precision\n\tctx.stack[ctx.stackTop++] = Math.trunc((a * b) / 64);\n}\n\n/** ABS - Absolute value */\nexport function ABS(ctx: ExecContext): void {\n\tconst val = ctx.stack[ctx.stackTop - 1];\n\tif (val === undefined) {\n\t\tctx.error = \"ABS: stack underflow\";\n\t\treturn;\n\t}\n\tctx.stack[ctx.stackTop - 1] = val < 0 ? -val : val;\n}\n\n/** NEG - Negate */\nexport function NEG(ctx: ExecContext): void {\n\tconst val = ctx.stack[ctx.stackTop - 1];\n\tif (val === undefined) {\n\t\tctx.error = \"NEG: stack underflow\";\n\t\treturn;\n\t}\n\tctx.stack[ctx.stackTop - 1] = -val;\n}\n\n/** FLOOR - Floor to 26.6 integer (multiple of 64) */\nexport function FLOOR(ctx: ExecContext): void {\n\tconst val = ctx.stack[ctx.stackTop - 1];\n\tif (val === undefined) {\n\t\tctx.error = \"FLOOR: stack underflow\";\n\t\treturn;\n\t}\n\tctx.stack[ctx.stackTop - 1] = val & ~63;\n}\n\n/** CEILING - Ceiling to 26.6 integer (multiple of 64) */\nexport function CEILING(ctx: ExecContext): void {\n\tconst val = ctx.stack[ctx.stackTop - 1];\n\tif (val === undefined) {\n\t\tctx.error = \"CEILING: stack underflow\";\n\t\treturn;\n\t}\n\tctx.stack[ctx.stackTop - 1] = (val + 63) & ~63;\n}\n\n/** MAX - Maximum of top two */\nexport function MAX(ctx: ExecContext): void {\n\tconst b = ctx.stack[--ctx.stackTop];\n\tconst a = ctx.stack[--ctx.stackTop];\n\tif (a === undefined || b === undefined) {\n\t\tctx.error = \"MAX: stack underflow\";\n\t\tctx.stackTop += 2;\n\t\tctx.stack[ctx.stackTop++] = 0;\n\t\treturn;\n\t}\n\tctx.stack[ctx.stackTop++] = a > b ? a : b;\n}\n\n/** MIN - Minimum of top two */\nexport function MIN(ctx: ExecContext): void {\n\tconst b = ctx.stack[--ctx.stackTop];\n\tconst a = ctx.stack[--ctx.stackTop];\n\tif (a === undefined || b === undefined) {\n\t\tctx.error = \"MIN: stack underflow\";\n\t\tctx.stackTop += 2;\n\t\tctx.stack[ctx.stackTop++] = 0;\n\t\treturn;\n\t}\n\tctx.stack[ctx.stackTop++] = a < b ? a : b;\n}\n\n// Comparison instructions\n\n/** LT - Less than */\nexport function LT(ctx: ExecContext): void {\n\tconst b = ctx.stack[--ctx.stackTop];\n\tconst a = ctx.stack[--ctx.stackTop];\n\tif (a === undefined || b === undefined) {\n\t\tctx.error = \"LT: stack underflow\";\n\t\tctx.stackTop += 2;\n\t\tctx.stack[ctx.stackTop++] = 0;\n\t\treturn;\n\t}\n\tctx.stack[ctx.stackTop++] = a < b ? 1 : 0;\n}\n\n/** LTEQ - Less than or equal */\nexport function LTEQ(ctx: ExecContext): void {\n\tconst b = ctx.stack[--ctx.stackTop];\n\tconst a = ctx.stack[--ctx.stackTop];\n\tif (a === undefined || b === undefined) {\n\t\tctx.error = \"LTEQ: stack underflow\";\n\t\tctx.stackTop += 2;\n\t\tctx.stack[ctx.stackTop++] = 0;\n\t\treturn;\n\t}\n\tctx.stack[ctx.stackTop++] = a <= b ? 1 : 0;\n}\n\n/** GT - Greater than */\nexport function GT(ctx: ExecContext): void {\n\tconst b = ctx.stack[--ctx.stackTop];\n\tconst a = ctx.stack[--ctx.stackTop];\n\tif (a === undefined || b === undefined) {\n\t\tctx.error = \"GT: stack underflow\";\n\t\tctx.stackTop += 2;\n\t\tctx.stack[ctx.stackTop++] = 0;\n\t\treturn;\n\t}\n\tctx.stack[ctx.stackTop++] = a > b ? 1 : 0;\n}\n\n/** GTEQ - Greater than or equal */\nexport function GTEQ(ctx: ExecContext): void {\n\tconst b = ctx.stack[--ctx.stackTop];\n\tconst a = ctx.stack[--ctx.stackTop];\n\tif (a === undefined || b === undefined) {\n\t\tctx.error = \"GTEQ: stack underflow\";\n\t\tctx.stackTop += 2;\n\t\tctx.stack[ctx.stackTop++] = 0;\n\t\treturn;\n\t}\n\tctx.stack[ctx.stackTop++] = a >= b ? 1 : 0;\n}\n\n/** EQ - Equal */\nexport function EQ(ctx: ExecContext): void {\n\tconst b = ctx.stack[--ctx.stackTop];\n\tconst a = ctx.stack[--ctx.stackTop];\n\tif (a === undefined || b === undefined) {\n\t\tctx.error = \"EQ: stack underflow\";\n\t\tctx.stackTop += 2;\n\t\tctx.stack[ctx.stackTop++] = 0;\n\t\treturn;\n\t}\n\tctx.stack[ctx.stackTop++] = a === b ? 1 : 0;\n}\n\n/** NEQ - Not equal */\nexport function NEQ(ctx: ExecContext): void {\n\tconst b = ctx.stack[--ctx.stackTop];\n\tconst a = ctx.stack[--ctx.stackTop];\n\tif (a === undefined || b === undefined) {\n\t\tctx.error = \"NEQ: stack underflow\";\n\t\tctx.stackTop += 2;\n\t\tctx.stack[ctx.stackTop++] = 0;\n\t\treturn;\n\t}\n\tctx.stack[ctx.stackTop++] = a !== b ? 1 : 0;\n}\n\n/** ODD - Test if odd (after rounding to pixels) */\nexport function ODD(ctx: ExecContext): void {\n\tconst val = ctx.stack[ctx.stackTop - 1];\n\tif (val === undefined) {\n\t\tctx.error = \"ODD: stack underflow\";\n\t\treturn;\n\t}\n\t// Round to nearest pixel and test bit 6\n\tconst rounded = (val + 32) & ~63;\n\tctx.stack[ctx.stackTop - 1] = rounded & 64 ? 1 : 0;\n}\n\n/** EVEN - Test if even (after rounding to pixels) */\nexport function EVEN(ctx: ExecContext): void {\n\tconst val = ctx.stack[ctx.stackTop - 1];\n\tif (val === undefined) {\n\t\tctx.error = \"EVEN: stack underflow\";\n\t\treturn;\n\t}\n\t// Round to nearest pixel and test bit 6\n\tconst rounded = (val + 32) & ~63;\n\tctx.stack[ctx.stackTop - 1] = rounded & 64 ? 0 : 1;\n}\n\n// Logic instructions\n\n/** AND - Logical AND */\nexport function AND(ctx: ExecContext): void {\n\tconst b = ctx.stack[--ctx.stackTop];\n\tconst a = ctx.stack[--ctx.stackTop];\n\tif (a === undefined || b === undefined) {\n\t\tctx.error = \"AND: stack underflow\";\n\t\tctx.stackTop += 2;\n\t\tctx.stack[ctx.stackTop++] = 0;\n\t\treturn;\n\t}\n\tctx.stack[ctx.stackTop++] = a && b ? 1 : 0;\n}\n\n/** OR - Logical OR */\nexport function OR(ctx: ExecContext): void {\n\tconst b = ctx.stack[--ctx.stackTop];\n\tconst a = ctx.stack[--ctx.stackTop];\n\tif (a === undefined || b === undefined) {\n\t\tctx.error = \"OR: stack underflow\";\n\t\tctx.stackTop += 2;\n\t\tctx.stack[ctx.stackTop++] = 0;\n\t\treturn;\n\t}\n\tctx.stack[ctx.stackTop++] = a || b ? 1 : 0;\n}\n\n/** NOT - Logical NOT */\nexport function NOT(ctx: ExecContext): void {\n\tconst val = ctx.stack[ctx.stackTop - 1];\n\tif (val === undefined) {\n\t\tctx.error = \"NOT: stack underflow\";\n\t\treturn;\n\t}\n\tctx.stack[ctx.stackTop - 1] = val ? 0 : 1;\n}\n",
70
- "/**\n * Control flow instructions\n */\n\nimport type { ExecContext } from \"../types.ts\";\n\n/** IF - Conditional branch */\nexport function IF(ctx: ExecContext): void {\n\tconst condition = ctx.stack[--ctx.stackTop];\n\tif (condition === undefined) {\n\t\tctx.error = \"IF: stack underflow\";\n\t\tctx.stackTop++;\n\t\treturn;\n\t}\n\n\tif (condition) {\n\t\t// Continue execution (true branch)\n\t\treturn;\n\t}\n\n\t// Skip to ELSE or EIF\n\tlet depth = 1;\n\n\twhile (ctx.IP < ctx.codeSize) {\n\t\tconst opcode = ctx.code[ctx.IP++];\n\t\tif (opcode === undefined) break;\n\n\t\tswitch (opcode) {\n\t\t\tcase 0x58: // IF\n\t\t\t\tdepth++;\n\t\t\t\tbreak;\n\t\t\tcase 0x1b: // ELSE\n\t\t\t\tif (depth === 1) {\n\t\t\t\t\t// Found matching ELSE, continue from here\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 0x59: // EIF\n\t\t\t\tdepth--;\n\t\t\t\tif (depth === 0) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t// Skip push instructions\n\t\t\tcase 0x40: // NPUSHB\n\t\t\t\tctx.IP += 1 + (ctx.code[ctx.IP] ?? 0);\n\t\t\t\tbreak;\n\t\t\tcase 0x41: // NPUSHW\n\t\t\t\tctx.IP += 1 + (ctx.code[ctx.IP] ?? 0) * 2;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tif (opcode >= 0xb0 && opcode <= 0xb7) {\n\t\t\t\t\t// PUSHB[n]\n\t\t\t\t\tctx.IP += opcode - 0xb0 + 1;\n\t\t\t\t} else if (opcode >= 0xb8 && opcode <= 0xbf) {\n\t\t\t\t\t// PUSHW[n]\n\t\t\t\t\tctx.IP += (opcode - 0xb8 + 1) * 2;\n\t\t\t\t}\n\t\t}\n\t}\n\n\tctx.error = \"IF: missing EIF\";\n}\n\n/** ELSE - Alternative branch */\nexport function ELSE(ctx: ExecContext): void {\n\t// We're in the true branch and hit ELSE, skip to EIF\n\tlet depth = 1;\n\n\twhile (ctx.IP < ctx.codeSize) {\n\t\tconst opcode = ctx.code[ctx.IP++];\n\t\tif (opcode === undefined) break;\n\n\t\tswitch (opcode) {\n\t\t\tcase 0x58: // IF\n\t\t\t\tdepth++;\n\t\t\t\tbreak;\n\t\t\tcase 0x59: // EIF\n\t\t\t\tdepth--;\n\t\t\t\tif (depth === 0) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 0x40: // NPUSHB\n\t\t\t\tctx.IP += 1 + (ctx.code[ctx.IP] ?? 0);\n\t\t\t\tbreak;\n\t\t\tcase 0x41: // NPUSHW\n\t\t\t\tctx.IP += 1 + (ctx.code[ctx.IP] ?? 0) * 2;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tif (opcode >= 0xb0 && opcode <= 0xb7) {\n\t\t\t\t\tctx.IP += opcode - 0xb0 + 1;\n\t\t\t\t} else if (opcode >= 0xb8 && opcode <= 0xbf) {\n\t\t\t\t\tctx.IP += (opcode - 0xb8 + 1) * 2;\n\t\t\t\t}\n\t\t}\n\t}\n\n\tctx.error = \"ELSE: missing EIF\";\n}\n\n/** EIF - End IF */\nexport function EIF(_ctx: ExecContext): void {\n\t// Nothing to do - just a marker\n}\n\n/** JMPR - Jump relative */\nexport function JMPR(ctx: ExecContext): void {\n\tconst offset = ctx.stack[--ctx.stackTop];\n\tif (offset === undefined) {\n\t\tctx.error = \"JMPR: stack underflow\";\n\t\tctx.stackTop++;\n\t\treturn;\n\t}\n\tctx.IP += offset - 1; // -1 because IP was already incremented\n}\n\n/** JROT - Jump relative on true */\nexport function JROT(ctx: ExecContext): void {\n\tconst condition = ctx.stack[--ctx.stackTop];\n\tconst offset = ctx.stack[--ctx.stackTop];\n\tif (condition === undefined || offset === undefined) {\n\t\tctx.error = \"JROT: stack underflow\";\n\t\tctx.stackTop += 2;\n\t\treturn;\n\t}\n\n\tif (condition) {\n\t\tctx.IP += offset - 1;\n\t}\n}\n\n/** JROF - Jump relative on false */\nexport function JROF(ctx: ExecContext): void {\n\tconst condition = ctx.stack[--ctx.stackTop];\n\tconst offset = ctx.stack[--ctx.stackTop];\n\tif (condition === undefined || offset === undefined) {\n\t\tctx.error = \"JROF: stack underflow\";\n\t\tctx.stackTop += 2;\n\t\treturn;\n\t}\n\n\tif (!condition) {\n\t\tctx.IP += offset - 1;\n\t}\n}\n\n/** FDEF - Define function */\nexport function FDEF(ctx: ExecContext): void {\n\tconst funcNum = ctx.stack[--ctx.stackTop];\n\tif (funcNum === undefined) {\n\t\tctx.error = \"FDEF: stack underflow\";\n\t\tctx.stackTop++;\n\t\treturn;\n\t}\n\n\tif (funcNum < 0 || funcNum >= ctx.maxFDefs) {\n\t\tctx.error = `FDEF: invalid function number ${funcNum}`;\n\t\treturn;\n\t}\n\n\tconst def = ctx.FDefs[funcNum];\n\tif (!def) {\n\t\tctx.error = `FDEF: no slot for function ${funcNum}`;\n\t\treturn;\n\t}\n\tdef.id = funcNum;\n\tdef.start = ctx.IP;\n\tdef.active = true;\n\tdef.range = ctx.currentRange;\n\n\t// Skip to ENDF\n\twhile (ctx.IP < ctx.codeSize) {\n\t\tconst opcode = ctx.code[ctx.IP++];\n\t\tif (opcode === undefined) break;\n\n\t\tif (opcode === 0x2d) {\n\t\t\t// ENDF\n\t\t\tdef.end = ctx.IP;\n\t\t\treturn;\n\t\t}\n\n\t\t// Skip push instructions\n\t\tif (opcode === 0x40) {\n\t\t\tctx.IP += 1 + (ctx.code[ctx.IP] ?? 0);\n\t\t} else if (opcode === 0x41) {\n\t\t\tctx.IP += 1 + (ctx.code[ctx.IP] ?? 0) * 2;\n\t\t} else if (opcode >= 0xb0 && opcode <= 0xb7) {\n\t\t\tctx.IP += opcode - 0xb0 + 1;\n\t\t} else if (opcode >= 0xb8 && opcode <= 0xbf) {\n\t\t\tctx.IP += (opcode - 0xb8 + 1) * 2;\n\t\t}\n\t}\n\n\tctx.error = \"FDEF: missing ENDF\";\n}\n\n/** ENDF - End function definition */\nexport function ENDF(ctx: ExecContext): void {\n\t// Called when returning from function call\n\tif (ctx.callStackTop <= 0) {\n\t\tctx.error = \"ENDF: not in function call\";\n\t\treturn;\n\t}\n\n\tconst call = ctx.callStack[ctx.callStackTop - 1];\n\tif (!call) {\n\t\tctx.error = \"ENDF: missing call frame\";\n\t\treturn;\n\t}\n\n\t// Decrement loop count for LOOPCALL\n\tcall.count--;\n\n\tif (call.count > 0) {\n\t\t// Loop again\n\t\tctx.IP = call.def.start;\n\t} else {\n\t\t// Return to caller\n\t\tctx.callStackTop--;\n\t\tctx.IP = call.callerIP;\n\t\tctx.currentRange = call.callerRange;\n\n\t\t// Restore code pointer\n\t\tconst range = ctx.codeRanges.get(ctx.currentRange);\n\t\tif (range) {\n\t\t\tctx.code = range.code;\n\t\t\tctx.codeSize = range.size;\n\t\t}\n\t}\n}\n\n/** CALL - Call function */\nexport function CALL(ctx: ExecContext): void {\n\tconst funcNum = ctx.stack[--ctx.stackTop];\n\tif (funcNum === undefined) {\n\t\tctx.error = \"CALL: stack underflow\";\n\t\tctx.stackTop++;\n\t\treturn;\n\t}\n\n\tif (funcNum < 0 || funcNum >= ctx.maxFDefs) {\n\t\tctx.error = `CALL: invalid function number ${funcNum}`;\n\t\treturn;\n\t}\n\n\tconst def = ctx.FDefs[funcNum];\n\tif (!def || !def.active) {\n\t\tctx.error = `CALL: function ${funcNum} not defined`;\n\t\treturn;\n\t}\n\n\tif (ctx.callStackTop >= ctx.maxCallStack) {\n\t\tctx.error = \"CALL: call stack overflow\";\n\t\treturn;\n\t}\n\n\t// Push call record\n\tconst call = ctx.callStack[ctx.callStackTop++];\n\tif (!call) {\n\t\tctx.error = \"CALL: no call frame available\";\n\t\tctx.callStackTop--;\n\t\treturn;\n\t}\n\tcall.callerIP = ctx.IP;\n\tcall.callerRange = ctx.currentRange;\n\tcall.def = def;\n\tcall.count = 1;\n\n\t// Switch to function's code range\n\tctx.currentRange = def.range;\n\tconst range = ctx.codeRanges.get(ctx.currentRange);\n\tif (range) {\n\t\tctx.code = range.code;\n\t\tctx.codeSize = range.size;\n\t}\n\tctx.IP = def.start;\n}\n\n/** LOOPCALL - Call function with loop count */\nexport function LOOPCALL(ctx: ExecContext): void {\n\tconst funcNum = ctx.stack[--ctx.stackTop];\n\tconst count = ctx.stack[--ctx.stackTop];\n\tif (funcNum === undefined || count === undefined) {\n\t\tctx.error = \"LOOPCALL: stack underflow\";\n\t\tctx.stackTop += 2;\n\t\treturn;\n\t}\n\n\tif (funcNum < 0 || funcNum >= ctx.maxFDefs) {\n\t\tctx.error = `LOOPCALL: invalid function number ${funcNum}`;\n\t\treturn;\n\t}\n\n\tconst def = ctx.FDefs[funcNum];\n\tif (!def || !def.active) {\n\t\tctx.error = `LOOPCALL: function ${funcNum} not defined`;\n\t\treturn;\n\t}\n\n\tif (count <= 0) {\n\t\treturn; // Nothing to do\n\t}\n\n\tif (ctx.callStackTop >= ctx.maxCallStack) {\n\t\tctx.error = \"LOOPCALL: call stack overflow\";\n\t\treturn;\n\t}\n\n\t// Push call record\n\tconst call = ctx.callStack[ctx.callStackTop++];\n\tif (!call) {\n\t\tctx.error = \"LOOPCALL: no call frame available\";\n\t\tctx.callStackTop--;\n\t\treturn;\n\t}\n\tcall.callerIP = ctx.IP;\n\tcall.callerRange = ctx.currentRange;\n\tcall.def = def;\n\tcall.count = count;\n\n\t// Switch to function's code range\n\tctx.currentRange = def.range;\n\tconst range = ctx.codeRanges.get(ctx.currentRange);\n\tif (range) {\n\t\tctx.code = range.code;\n\t\tctx.codeSize = range.size;\n\t}\n\tctx.IP = def.start;\n}\n\n/** IDEF - Define instruction */\nexport function IDEF(ctx: ExecContext): void {\n\tconst opcode = ctx.stack[--ctx.stackTop];\n\tif (opcode === undefined) {\n\t\tctx.error = \"IDEF: stack underflow\";\n\t\tctx.stackTop++;\n\t\treturn;\n\t}\n\n\tif (opcode < 0 || opcode >= ctx.maxIDefs) {\n\t\tctx.error = `IDEF: invalid opcode ${opcode}`;\n\t\treturn;\n\t}\n\n\tconst def = ctx.IDefs[opcode];\n\tif (!def) {\n\t\tctx.error = `IDEF: no slot for opcode ${opcode}`;\n\t\treturn;\n\t}\n\tdef.opcode = opcode;\n\tdef.start = ctx.IP;\n\tdef.active = true;\n\tdef.range = ctx.currentRange;\n\n\t// Skip to ENDF\n\twhile (ctx.IP < ctx.codeSize) {\n\t\tconst op = ctx.code[ctx.IP++];\n\t\tif (op === undefined) break;\n\n\t\tif (op === 0x2d) {\n\t\t\t// ENDF\n\t\t\tdef.end = ctx.IP;\n\t\t\treturn;\n\t\t}\n\n\t\t// Skip push instructions\n\t\tif (op === 0x40) {\n\t\t\tctx.IP += 1 + (ctx.code[ctx.IP] ?? 0);\n\t\t} else if (op === 0x41) {\n\t\t\tctx.IP += 1 + (ctx.code[ctx.IP] ?? 0) * 2;\n\t\t} else if (op >= 0xb0 && op <= 0xb7) {\n\t\t\tctx.IP += op - 0xb0 + 1;\n\t\t} else if (op >= 0xb8 && op <= 0xbf) {\n\t\t\tctx.IP += (op - 0xb8 + 1) * 2;\n\t\t}\n\t}\n\n\tctx.error = \"IDEF: missing ENDF\";\n}\n",
71
- "/**\n * TrueType Hinting Types\n *\n * Based on FreeType's ttinterp.h and ttobjs.h\n */\n\n/**\n * 26.6 fixed-point number (used for coordinates)\n */\nexport type F26Dot6 = number;\n\n/**\n * 2.14 fixed-point number (used for unit vectors)\n */\nexport type F2Dot14 = number;\n\n/**\n * Unit vector in 2.14 format\n */\nexport interface UnitVector {\n\tx: F2Dot14;\n\ty: F2Dot14;\n}\n\n/**\n * Point coordinate\n */\nexport interface Point {\n\tx: F26Dot6;\n\ty: F26Dot6;\n}\n\n/**\n * Rounding mode for ROUND instruction\n */\nexport enum RoundMode {\n\tToHalfGrid = 0,\n\tToGrid = 1,\n\tToDoubleGrid = 2,\n\tDownToGrid = 3,\n\tUpToGrid = 4,\n\tOff = 5,\n\tSuper = 6,\n\tSuper45 = 7,\n}\n\n/**\n * Touch flags for points\n */\nexport enum TouchFlag {\n\tX = 0x01,\n\tY = 0x02,\n\tBoth = 0x03,\n}\n\n/**\n * Glyph zone - holds glyph points\n */\nexport interface GlyphZone {\n\t/** Number of points */\n\tnPoints: number;\n\t/** Number of contours */\n\tnContours: number;\n\t/** Original point positions (before hinting) */\n\torg: Point[];\n\t/** Current point positions (after hinting) */\n\tcur: Point[];\n\t/** Original unscaled positions */\n\torus: Point[];\n\t/** Touch flags per point */\n\ttags: Uint8Array;\n\t/** Contour end indices */\n\tcontours: Uint16Array;\n}\n\n/**\n * TrueType Graphics State\n *\n * Contains all state variables that control how instructions operate\n */\nexport interface GraphicsState {\n\t// Reference points\n\trp0: number;\n\trp1: number;\n\trp2: number;\n\n\t// Dual projection vector (for getting distances)\n\tdualVector: UnitVector;\n\t// Projection vector (direction along which we measure)\n\tprojVector: UnitVector;\n\t// Freedom vector (direction in which points can move)\n\tfreeVector: UnitVector;\n\n\t// Loop counter for repeated operations\n\tloop: number;\n\n\t// Minimum distance\n\tminimumDistance: F26Dot6;\n\n\t// Round state\n\troundState: RoundMode;\n\n\t// Auto flip for MIRP/MDRP\n\tautoFlip: boolean;\n\n\t// Control value cut-in\n\tcontrolValueCutIn: F26Dot6;\n\n\t// Single width cut-in\n\tsingleWidthCutIn: F26Dot6;\n\t// Single width value\n\tsingleWidthValue: F26Dot6;\n\n\t// Delta base (for DELTA instructions)\n\tdeltaBase: number;\n\t// Delta shift (for DELTA instructions)\n\tdeltaShift: number;\n\n\t// Instruction control flags\n\tinstructControl: number;\n\n\t// Scan control flags\n\tscanControl: number;\n\tscanType: number;\n\n\t// Zone pointers (0 = twilight, 1 = glyph)\n\tgep0: number;\n\tgep1: number;\n\tgep2: number;\n\n\t// Super rounding parameters\n\tperiod: F26Dot6;\n\tphase: F26Dot6;\n\tthreshold: F26Dot6;\n}\n\n/**\n * Create default graphics state\n */\nexport function createDefaultGraphicsState(): GraphicsState {\n\treturn {\n\t\trp0: 0,\n\t\trp1: 0,\n\t\trp2: 0,\n\t\tdualVector: { x: 0x4000, y: 0 }, // 1.0, 0.0 in 2.14\n\t\tprojVector: { x: 0x4000, y: 0 },\n\t\tfreeVector: { x: 0x4000, y: 0 },\n\t\tloop: 1,\n\t\tminimumDistance: 64, // 1 pixel in 26.6\n\t\troundState: RoundMode.ToGrid,\n\t\tautoFlip: true,\n\t\tcontrolValueCutIn: 68, // 17/16 pixel in 26.6\n\t\tsingleWidthCutIn: 0,\n\t\tsingleWidthValue: 0,\n\t\tdeltaBase: 9,\n\t\tdeltaShift: 3,\n\t\tinstructControl: 0,\n\t\tscanControl: 0,\n\t\tscanType: 0,\n\t\tgep0: 1,\n\t\tgep1: 1,\n\t\tgep2: 1,\n\t\tperiod: 64,\n\t\tphase: 0,\n\t\tthreshold: 32,\n\t};\n}\n\n/**\n * Function definition (from FDEF instruction)\n */\nexport interface FunctionDef {\n\t/** Function number */\n\tid: number;\n\t/** Start offset in bytecode */\n\tstart: number;\n\t/** End offset (just after ENDF) */\n\tend: number;\n\t/** Active (has been defined) */\n\tactive: boolean;\n\t/** Which code range */\n\trange: CodeRange;\n}\n\n/**\n * Instruction definition (from IDEF instruction)\n */\nexport interface InstructionDef {\n\t/** Opcode being redefined */\n\topcode: number;\n\t/** Start offset */\n\tstart: number;\n\t/** End offset */\n\tend: number;\n\t/** Active */\n\tactive: boolean;\n\t/** Code range */\n\trange: CodeRange;\n}\n\n/**\n * Code range type\n */\nexport enum CodeRange {\n\tNone = 0,\n\tFont = 1, // fpgm table\n\tCVT = 2, // prep table\n\tGlyph = 3, // glyph instructions\n}\n\n/**\n * Call stack record\n */\nexport interface CallRecord {\n\t/** Caller's instruction pointer */\n\tcallerIP: number;\n\t/** Caller's code range */\n\tcallerRange: CodeRange;\n\t/** Function definition */\n\tdef: FunctionDef;\n\t/** Loop count (for LOOPCALL) */\n\tcount: number;\n}\n\n/**\n * Execution context for the TrueType interpreter\n */\nexport interface ExecContext {\n\t// Graphics state\n\tGS: GraphicsState;\n\t// Default graphics state (reset after each glyph)\n\tdefaultGS: GraphicsState;\n\n\t// Zone pointers\n\tzp0: GlyphZone;\n\tzp1: GlyphZone;\n\tzp2: GlyphZone;\n\n\t// Twilight zone (synthetic points)\n\ttwilight: GlyphZone;\n\t// Glyph zone (actual glyph points)\n\tpts: GlyphZone;\n\n\t// Stack\n\tstack: Int32Array;\n\tstackTop: number;\n\n\t// Instruction pointer and code\n\tIP: number;\n\tcode: Uint8Array;\n\tcodeSize: number;\n\tcurrentRange: CodeRange;\n\n\t// Current opcode\n\topcode: number;\n\t// Number of arguments for current opcode\n\tnumArgs: number;\n\n\t// Control Value Table (scaled)\n\tcvt: Int32Array;\n\tcvtSize: number;\n\n\t// Storage area\n\tstorage: Int32Array;\n\tstorageSize: number;\n\n\t// Function definitions\n\tFDefs: FunctionDef[];\n\tmaxFDefs: number;\n\n\t// Instruction definitions\n\tIDefs: InstructionDef[];\n\tmaxIDefs: number;\n\n\t// Call stack\n\tcallStack: CallRecord[];\n\tcallStackTop: number;\n\tmaxCallStack: number;\n\n\t// Code ranges\n\tcodeRanges: Map<CodeRange, { code: Uint8Array; size: number }>;\n\n\t// Pixels per EM\n\tppem: number;\n\t// Point size\n\tpointSize: number;\n\n\t// Scale factor from font units to 26.6 pixels\n\tscale: number;\n\n\t// Error state\n\terror: string | null;\n\n\t// Instruction execution count (for infinite loop protection)\n\tinstructionCount: number;\n\tmaxInstructions: number;\n}\n\n/**\n * Create an empty glyph zone\n */\nexport function createGlyphZone(\n\tmaxPoints: number,\n\tmaxContours: number,\n): GlyphZone {\n\treturn {\n\t\tnPoints: 0,\n\t\tnContours: 0,\n\t\torg: new Array(maxPoints).fill(null).map(() => ({ x: 0, y: 0 })),\n\t\tcur: new Array(maxPoints).fill(null).map(() => ({ x: 0, y: 0 })),\n\t\torus: new Array(maxPoints).fill(null).map(() => ({ x: 0, y: 0 })),\n\t\ttags: new Uint8Array(maxPoints),\n\t\tcontours: new Uint16Array(maxContours),\n\t};\n}\n\n/**\n * Create execution context\n */\nexport function createExecContext(\n\tmaxStack: number = 256,\n\tmaxStorage: number = 64,\n\tmaxFDefs: number = 64,\n\tmaxIDefs: number = 64,\n\tmaxCallStack: number = 32,\n\tmaxTwilightPoints: number = 16,\n): ExecContext {\n\tconst defaultGS = createDefaultGraphicsState();\n\n\treturn {\n\t\tGS: { ...defaultGS },\n\t\tdefaultGS,\n\n\t\tzp0: createGlyphZone(0, 0),\n\t\tzp1: createGlyphZone(0, 0),\n\t\tzp2: createGlyphZone(0, 0),\n\n\t\ttwilight: createGlyphZone(maxTwilightPoints, 1),\n\t\tpts: createGlyphZone(0, 0),\n\n\t\tstack: new Int32Array(maxStack),\n\t\tstackTop: 0,\n\n\t\tIP: 0,\n\t\tcode: new Uint8Array(0),\n\t\tcodeSize: 0,\n\t\tcurrentRange: CodeRange.None,\n\n\t\topcode: 0,\n\t\tnumArgs: 0,\n\n\t\tcvt: new Int32Array(0),\n\t\tcvtSize: 0,\n\n\t\tstorage: new Int32Array(maxStorage),\n\t\tstorageSize: maxStorage,\n\n\t\tFDefs: new Array(maxFDefs).fill(null).map((_, i) => ({\n\t\t\tid: i,\n\t\t\tstart: 0,\n\t\t\tend: 0,\n\t\t\tactive: false,\n\t\t\trange: CodeRange.None,\n\t\t})),\n\t\tmaxFDefs,\n\n\t\tIDefs: new Array(maxIDefs).fill(null).map((_, i) => ({\n\t\t\topcode: i,\n\t\t\tstart: 0,\n\t\t\tend: 0,\n\t\t\tactive: false,\n\t\t\trange: CodeRange.None,\n\t\t})),\n\t\tmaxIDefs,\n\n\t\tcallStack: new Array(maxCallStack).fill(null).map(() => ({\n\t\t\tcallerIP: 0,\n\t\t\tcallerRange: CodeRange.None,\n\t\t\tdef: { id: 0, start: 0, end: 0, active: false, range: CodeRange.None },\n\t\t\tcount: 0,\n\t\t})),\n\t\tcallStackTop: 0,\n\t\tmaxCallStack,\n\n\t\tcodeRanges: new Map(),\n\n\t\tppem: 12,\n\t\tpointSize: 12,\n\t\tscale: 1,\n\n\t\terror: null,\n\n\t\tinstructionCount: 0,\n\t\tmaxInstructions: 1000000,\n\t};\n}\n\n/**\n * TrueType Opcodes\n */\nexport const Opcode = {\n\t// Push instructions\n\tNPUSHB: 0x40,\n\tNPUSHW: 0x41,\n\tPUSHB_0: 0xb0,\n\tPUSHB_1: 0xb1,\n\tPUSHB_2: 0xb2,\n\tPUSHB_3: 0xb3,\n\tPUSHB_4: 0xb4,\n\tPUSHB_5: 0xb5,\n\tPUSHB_6: 0xb6,\n\tPUSHB_7: 0xb7,\n\tPUSHW_0: 0xb8,\n\tPUSHW_1: 0xb9,\n\tPUSHW_2: 0xba,\n\tPUSHW_3: 0xbb,\n\tPUSHW_4: 0xbc,\n\tPUSHW_5: 0xbd,\n\tPUSHW_6: 0xbe,\n\tPUSHW_7: 0xbf,\n\n\t// Storage instructions\n\tRS: 0x43,\n\tWS: 0x42,\n\n\t// CVT instructions\n\tRCVT: 0x45,\n\tWCVTP: 0x44,\n\tWCVTF: 0x70,\n\n\t// Stack operations\n\tDUP: 0x20,\n\tPOP: 0x21,\n\tCLEAR: 0x22,\n\tSWAP: 0x23,\n\tDEPTH: 0x24,\n\tCINDEX: 0x25,\n\tMINDEX: 0x26,\n\tROLL: 0x8a,\n\n\t// Arithmetic\n\tADD: 0x60,\n\tSUB: 0x61,\n\tDIV: 0x62,\n\tMUL: 0x63,\n\tABS: 0x64,\n\tNEG: 0x65,\n\tFLOOR: 0x66,\n\tCEILING: 0x67,\n\tMAX: 0x8b,\n\tMIN: 0x8c,\n\n\t// Comparison\n\tLT: 0x50,\n\tLTEQ: 0x51,\n\tGT: 0x52,\n\tGTEQ: 0x53,\n\tEQ: 0x54,\n\tNEQ: 0x55,\n\tODD: 0x56,\n\tEVEN: 0x57,\n\n\t// Logic\n\tAND: 0x5a,\n\tOR: 0x5b,\n\tNOT: 0x5c,\n\n\t// Control flow\n\tIF: 0x58,\n\tELSE: 0x1b,\n\tEIF: 0x59,\n\tJMPR: 0x1c,\n\tJROT: 0x78,\n\tJROF: 0x79,\n\n\t// Functions\n\tFDEF: 0x2c,\n\tENDF: 0x2d,\n\tCALL: 0x2b,\n\tLOOPCALL: 0x2a,\n\tIDEF: 0x89,\n\n\t// Graphics state - vectors\n\tSVTCA_Y: 0x00,\n\tSVTCA_X: 0x01,\n\tSPVTCA_Y: 0x02,\n\tSPVTCA_X: 0x03,\n\tSFVTCA_Y: 0x04,\n\tSFVTCA_X: 0x05,\n\tSPVTL_0: 0x06,\n\tSPVTL_1: 0x07,\n\tSFVTL_0: 0x08,\n\tSFVTL_1: 0x09,\n\tSDPVTL_0: 0x86,\n\tSDPVTL_1: 0x87,\n\tSPVFS: 0x0a,\n\tSFVFS: 0x0b,\n\tGPV: 0x0c,\n\tGFV: 0x0d,\n\tSFVTPV: 0x0e,\n\tISECT: 0x0f,\n\n\t// Graphics state - reference points\n\tSRP0: 0x10,\n\tSRP1: 0x11,\n\tSRP2: 0x12,\n\n\t// Graphics state - zone pointers\n\tSZP0: 0x13,\n\tSZP1: 0x14,\n\tSZP2: 0x15,\n\tSZPS: 0x16,\n\n\t// Graphics state - other\n\tSLOOP: 0x17,\n\tRTG: 0x18,\n\tRTHG: 0x19,\n\tSMD: 0x1a,\n\tRDTG: 0x7d,\n\tRUTG: 0x7c,\n\tROFF: 0x7a,\n\tSROUND: 0x76,\n\tS45ROUND: 0x77,\n\tSCVTCI: 0x1d,\n\tSSWCI: 0x1e,\n\tSSW: 0x1f,\n\tFLIPON: 0x4d,\n\tFLIPOFF: 0x4e,\n\tSANGW: 0x7e,\n\tSDB: 0x5e,\n\tSDS: 0x5f,\n\n\t// Point operations\n\tGC_0: 0x46,\n\tGC_1: 0x47,\n\tSCFS: 0x48,\n\tMD_0: 0x49,\n\tMD_1: 0x4a,\n\tMPPEM: 0x4b,\n\tMPS: 0x4c,\n\tFLIPPT: 0x80,\n\tFLIPRGON: 0x81,\n\tFLIPRGOFF: 0x82,\n\n\t// Point movement\n\tSHP_0: 0x32,\n\tSHP_1: 0x33,\n\tSHC_0: 0x34,\n\tSHC_1: 0x35,\n\tSHZ_0: 0x36,\n\tSHZ_1: 0x37,\n\tSHPIX: 0x38,\n\tIP: 0x39,\n\tMSIRP_0: 0x3a,\n\tMSIRP_1: 0x3b,\n\tALIGNRP: 0x3c,\n\tRTDG: 0x3d,\n\tMIAP_0: 0x3e,\n\tMIAP_1: 0x3f,\n\n\t// ALIGNPTS - Align Points\n\tALIGNPTS: 0x27,\n\n\t// UTP - UnTouch Point\n\tUTP: 0x29,\n\n\t// MDAP - Move Direct Absolute Point\n\tMDAP_0: 0x2e,\n\tMDAP_1: 0x2f,\n\n\t// IUP - Interpolate Untouched Points\n\tIUP_Y: 0x30,\n\tIUP_X: 0x31,\n\n\t// Delta instructions\n\tDELTAP1: 0x5d,\n\tDELTAP2: 0x71,\n\tDELTAP3: 0x72,\n\tDELTAC1: 0x73,\n\tDELTAC2: 0x74,\n\tDELTAC3: 0x75,\n\n\t// Rounding\n\tROUND_0: 0x68,\n\tROUND_1: 0x69,\n\tROUND_2: 0x6a,\n\tROUND_3: 0x6b,\n\tNROUND_0: 0x6c,\n\tNROUND_1: 0x6d,\n\tNROUND_2: 0x6e,\n\tNROUND_3: 0x6f,\n\n\t// Other\n\tGETINFO: 0x88,\n\tINSTCTRL: 0x8e,\n\tSCANCTRL: 0x85,\n\tSCANTYPE: 0x8d,\n\tAA: 0x7f,\n\tDEBUG: 0x4f,\n\n\t// MDRP - Move Direct Relative Point (32 variants: 0xc0-0xdf)\n\tMDRP_BASE: 0xc0,\n\n\t// MIRP - Move Indirect Relative Point (32 variants: 0xe0-0xff)\n\tMIRP_BASE: 0xe0,\n} as const;\n\n/**\n * Number of values popped from stack for each opcode\n */\nexport const OpcodePops: Record<number, number> = {\n\t[Opcode.RS]: 1,\n\t[Opcode.WS]: 2,\n\t[Opcode.RCVT]: 1,\n\t[Opcode.WCVTP]: 2,\n\t[Opcode.WCVTF]: 2,\n\t[Opcode.DUP]: 1,\n\t[Opcode.POP]: 1,\n\t[Opcode.CLEAR]: 0,\n\t[Opcode.SWAP]: 2,\n\t[Opcode.DEPTH]: 0,\n\t[Opcode.CINDEX]: 1,\n\t[Opcode.MINDEX]: 1,\n\t[Opcode.ROLL]: 3,\n\t[Opcode.ADD]: 2,\n\t[Opcode.SUB]: 2,\n\t[Opcode.DIV]: 2,\n\t[Opcode.MUL]: 2,\n\t[Opcode.ABS]: 1,\n\t[Opcode.NEG]: 1,\n\t[Opcode.FLOOR]: 1,\n\t[Opcode.CEILING]: 1,\n\t[Opcode.MAX]: 2,\n\t[Opcode.MIN]: 2,\n\t[Opcode.LT]: 2,\n\t[Opcode.LTEQ]: 2,\n\t[Opcode.GT]: 2,\n\t[Opcode.GTEQ]: 2,\n\t[Opcode.EQ]: 2,\n\t[Opcode.NEQ]: 2,\n\t[Opcode.ODD]: 1,\n\t[Opcode.EVEN]: 1,\n\t[Opcode.AND]: 2,\n\t[Opcode.OR]: 2,\n\t[Opcode.NOT]: 1,\n\t[Opcode.IF]: 1,\n\t[Opcode.JMPR]: 1,\n\t[Opcode.JROT]: 2,\n\t[Opcode.JROF]: 2,\n\t[Opcode.CALL]: 1,\n\t[Opcode.LOOPCALL]: 2,\n\t[Opcode.SRP0]: 1,\n\t[Opcode.SRP1]: 1,\n\t[Opcode.SRP2]: 1,\n\t[Opcode.SZP0]: 1,\n\t[Opcode.SZP1]: 1,\n\t[Opcode.SZP2]: 1,\n\t[Opcode.SZPS]: 1,\n\t[Opcode.SLOOP]: 1,\n\t[Opcode.SMD]: 1,\n\t[Opcode.SCVTCI]: 1,\n\t[Opcode.SSWCI]: 1,\n\t[Opcode.SSW]: 1,\n\t[Opcode.SDB]: 1,\n\t[Opcode.SDS]: 1,\n\t[Opcode.SPVFS]: 2,\n\t[Opcode.SFVFS]: 2,\n\t[Opcode.SPVTL_0]: 2,\n\t[Opcode.SPVTL_1]: 2,\n\t[Opcode.SFVTL_0]: 2,\n\t[Opcode.SFVTL_1]: 2,\n\t[Opcode.SCFS]: 2,\n\t[Opcode.GC_0]: 1,\n\t[Opcode.GC_1]: 1,\n\t[Opcode.MD_0]: 2,\n\t[Opcode.MD_1]: 2,\n\t[Opcode.ISECT]: 5,\n\t[Opcode.ALIGNRP]: 0, // Uses loop\n\t[Opcode.IP]: 0, // Uses loop\n\t[Opcode.SHPIX]: 1, // Plus loop points\n\t[Opcode.MSIRP_0]: 2,\n\t[Opcode.MSIRP_1]: 2,\n\t[Opcode.MIAP_0]: 2,\n\t[Opcode.MIAP_1]: 2,\n\t[Opcode.MDAP_0]: 1,\n\t[Opcode.MDAP_1]: 1,\n\t[Opcode.DELTAP1]: 1,\n\t[Opcode.DELTAP2]: 1,\n\t[Opcode.DELTAP3]: 1,\n\t[Opcode.DELTAC1]: 1,\n\t[Opcode.DELTAC2]: 1,\n\t[Opcode.DELTAC3]: 1,\n\t[Opcode.SROUND]: 1,\n\t[Opcode.S45ROUND]: 1,\n\t[Opcode.ROUND_0]: 1,\n\t[Opcode.ROUND_1]: 1,\n\t[Opcode.ROUND_2]: 1,\n\t[Opcode.ROUND_3]: 1,\n\t[Opcode.NROUND_0]: 1,\n\t[Opcode.NROUND_1]: 1,\n\t[Opcode.NROUND_2]: 1,\n\t[Opcode.NROUND_3]: 1,\n\t[Opcode.INSTCTRL]: 2,\n\t[Opcode.SCANCTRL]: 1,\n\t[Opcode.SCANTYPE]: 1,\n\t[Opcode.GETINFO]: 1,\n\t[Opcode.FLIPPT]: 0, // Uses loop\n\t[Opcode.FLIPRGON]: 2,\n\t[Opcode.FLIPRGOFF]: 2,\n};\n",
72
- "/**\n * TrueType rounding functions\n *\n * These implement the various rounding modes used by the interpreter.\n */\n\nimport { type F26Dot6, type GraphicsState, RoundMode } from \"./types.ts\";\n\n/**\n * Round to grid (nearest integer pixel)\n */\nexport function roundToGrid(distance: F26Dot6, compensation: F26Dot6): F26Dot6 {\n\tif (distance >= 0) {\n\t\treturn (distance + 32 + compensation) & -64;\n\t} else {\n\t\treturn -((-distance + 32 + compensation) & -64);\n\t}\n}\n\n/**\n * Round to half grid (nearest half pixel)\n */\nexport function roundToHalfGrid(\n\tdistance: F26Dot6,\n\tcompensation: F26Dot6,\n): F26Dot6 {\n\tif (distance >= 0) {\n\t\treturn ((distance + 32 + compensation) & -64) + 32;\n\t} else {\n\t\treturn -(((-distance + 32 + compensation) & -64) + 32);\n\t}\n}\n\n/**\n * Round to double grid (nearest half pixel boundary)\n */\nexport function roundToDoubleGrid(\n\tdistance: F26Dot6,\n\tcompensation: F26Dot6,\n): F26Dot6 {\n\tif (distance >= 0) {\n\t\treturn (distance + 16 + compensation) & -32;\n\t} else {\n\t\treturn -((-distance + 16 + compensation) & -32);\n\t}\n}\n\n/**\n * Round down to grid (floor to pixel)\n */\nexport function roundDownToGrid(\n\tdistance: F26Dot6,\n\tcompensation: F26Dot6,\n): F26Dot6 {\n\tif (distance >= 0) {\n\t\treturn (distance + compensation) & -64;\n\t} else {\n\t\treturn -((compensation - distance) & -64);\n\t}\n}\n\n/**\n * Round up to grid (ceiling to pixel)\n */\nexport function roundUpToGrid(\n\tdistance: F26Dot6,\n\tcompensation: F26Dot6,\n): F26Dot6 {\n\tif (distance >= 0) {\n\t\treturn (distance + 63 + compensation) & -64;\n\t} else {\n\t\treturn -((63 + compensation - distance) & -64);\n\t}\n}\n\n/**\n * No rounding\n */\nexport function roundOff(distance: F26Dot6, _compensation: F26Dot6): F26Dot6 {\n\treturn distance;\n}\n\n/**\n * Super rounding (parametric rounding)\n */\nexport function roundSuper(\n\tdistance: F26Dot6,\n\tcompensation: F26Dot6,\n\tGS: GraphicsState,\n): F26Dot6 {\n\tconst { period, phase, threshold } = GS;\n\n\tif (distance >= 0) {\n\t\tconst val = (distance + threshold - phase + compensation) & -period;\n\t\treturn val + phase;\n\t} else {\n\t\tconst val = (-distance + threshold - phase + compensation) & -period;\n\t\treturn -(val + phase);\n\t}\n}\n\n/**\n * Super rounding 45 degrees (for diagonal lines)\n */\nexport function roundSuper45(\n\tdistance: F26Dot6,\n\tcompensation: F26Dot6,\n\tGS: GraphicsState,\n): F26Dot6 {\n\t// Same as super rounding but with 45-degree adjusted period\n\t// Period is multiplied by sqrt(2)/2 ≈ 0.707\n\tconst { period, phase, threshold } = GS;\n\tconst period45 = Math.round((period * 46) / 64); // sqrt(2)/2 ≈ 46/64\n\n\tif (distance >= 0) {\n\t\tconst val = (distance + threshold - phase + compensation) & -period45;\n\t\treturn val + phase;\n\t} else {\n\t\tconst val = (-distance + threshold - phase + compensation) & -period45;\n\t\treturn -(val + phase);\n\t}\n}\n\n/**\n * Apply current rounding mode\n */\nexport function round(\n\tdistance: F26Dot6,\n\tcompensation: F26Dot6,\n\tGS: GraphicsState,\n): F26Dot6 {\n\tswitch (GS.roundState) {\n\t\tcase RoundMode.ToGrid:\n\t\t\treturn roundToGrid(distance, compensation);\n\t\tcase RoundMode.ToHalfGrid:\n\t\t\treturn roundToHalfGrid(distance, compensation);\n\t\tcase RoundMode.ToDoubleGrid:\n\t\t\treturn roundToDoubleGrid(distance, compensation);\n\t\tcase RoundMode.DownToGrid:\n\t\t\treturn roundDownToGrid(distance, compensation);\n\t\tcase RoundMode.UpToGrid:\n\t\t\treturn roundUpToGrid(distance, compensation);\n\t\tcase RoundMode.Off:\n\t\t\treturn roundOff(distance, compensation);\n\t\tcase RoundMode.Super:\n\t\t\treturn roundSuper(distance, compensation, GS);\n\t\tcase RoundMode.Super45:\n\t\t\treturn roundSuper45(distance, compensation, GS);\n\t\tdefault:\n\t\t\treturn roundToGrid(distance, compensation);\n\t}\n}\n\n/**\n * Parse SROUND/S45ROUND selector byte\n */\nexport function parseSuperRound(selector: number, GS: GraphicsState): void {\n\t// Period selection (bits 6-7)\n\tswitch ((selector >> 6) & 0x03) {\n\t\tcase 0:\n\t\t\tGS.period = 32; // 1/2 pixel\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\tGS.period = 64; // 1 pixel\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tGS.period = 128; // 2 pixels\n\t\t\tbreak;\n\t\tdefault:\n\t\t\t// Reserved\n\t\t\tGS.period = 64;\n\t}\n\n\t// Phase selection (bits 4-5)\n\tswitch ((selector >> 4) & 0x03) {\n\t\tcase 0:\n\t\t\tGS.phase = 0;\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\tGS.phase = GS.period >> 2; // period/4\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tGS.phase = GS.period >> 1; // period/2\n\t\t\tbreak;\n\t\tcase 3:\n\t\t\tGS.phase = (GS.period * 3) >> 2; // 3*period/4\n\t\t\tbreak;\n\t}\n\n\t// Threshold selection (bits 0-3)\n\tconst thresholdBits = selector & 0x0f;\n\tif (thresholdBits === 0) {\n\t\tGS.threshold = GS.period - 1;\n\t} else {\n\t\tGS.threshold = ((thresholdBits - 4) * GS.period) >> 3;\n\t}\n}\n\n/**\n * Compensate distance for engine characteristics\n * Used with ROUND and movement instructions\n */\nexport function compensate(_distance: F26Dot6, _GS: GraphicsState): F26Dot6 {\n\t// Engine compensation is typically 0 for modern displays\n\t// But some fonts depend on it for grid-fitting\n\treturn 0;\n}\n",
73
- "/**\n * Point movement instructions\n *\n * These are the core hinting operations that actually move glyph points.\n */\n\nimport { compensate, round } from \"../rounding.ts\";\nimport {\n\ttype ExecContext,\n\ttype F26Dot6,\n\ttype GlyphZone,\n\ttype Point,\n\tTouchFlag,\n} from \"../types.ts\";\n\n/**\n * Project a point onto the projection vector\n */\nexport function project(ctx: ExecContext, p: Point): F26Dot6 {\n\treturn (p.x * ctx.GS.projVector.x + p.y * ctx.GS.projVector.y + 0x2000) >> 14;\n}\n\n/**\n * Project using dual vector (for original positions)\n */\nexport function dualProject(ctx: ExecContext, p: Point): F26Dot6 {\n\treturn (p.x * ctx.GS.dualVector.x + p.y * ctx.GS.dualVector.y + 0x2000) >> 14;\n}\n\n/**\n * Move a point along the freedom vector\n */\nexport function movePoint(\n\tctx: ExecContext,\n\tzone: GlyphZone,\n\tpointIndex: number,\n\tdistance: F26Dot6,\n): void {\n\tconst pt = zone.cur[pointIndex];\n\n\t// Calculate movement along freedom vector\n\t// freedom vector is in 2.14 format, so divide by 0x4000\n\tconst fv = ctx.GS.freeVector;\n\tconst pv = ctx.GS.projVector;\n\n\t// Calculate dot product of freedom and projection vectors\n\tconst dot = (fv.x * pv.x + fv.y * pv.y + 0x2000) >> 14;\n\n\tif (dot === 0) {\n\t\t// Vectors are perpendicular, can't move\n\t\treturn;\n\t}\n\n\t// Scale distance by freedom/projection relationship\n\tconst dx = Math.round((distance * fv.x) / dot);\n\tconst dy = Math.round((distance * fv.y) / dot);\n\n\tpt.x += dx;\n\tpt.y += dy;\n}\n\n/**\n * Get current position of a point projected onto projection vector\n */\nexport function getCurrent(\n\tctx: ExecContext,\n\tzone: GlyphZone,\n\tpointIndex: number,\n): F26Dot6 {\n\tconst pt = zone.cur[pointIndex];\n\tif (!pt) return 0;\n\treturn project(ctx, pt);\n}\n\n/**\n * Get original position of a point projected onto dual vector\n */\nexport function getOriginal(\n\tctx: ExecContext,\n\tzone: GlyphZone,\n\tpointIndex: number,\n): F26Dot6 {\n\tconst pt = zone.org[pointIndex];\n\tif (!pt) return 0;\n\treturn dualProject(ctx, pt);\n}\n\n/**\n * Mark point as touched in the current direction\n */\nexport function touchPoint(\n\tctx: ExecContext,\n\tzone: GlyphZone,\n\tpointIndex: number,\n): void {\n\t// Set touch flag based on freedom vector direction\n\tconst fv = ctx.GS.freeVector;\n\tif (fv.y !== 0) {\n\t\tzone.tags[pointIndex] |= TouchFlag.Y;\n\t}\n\tif (fv.x !== 0) {\n\t\tzone.tags[pointIndex] |= TouchFlag.X;\n\t}\n}\n\n// =============================================================================\n// MDAP - Move Direct Absolute Point\n// =============================================================================\n\n/** MDAP - Move Direct Absolute Point */\nexport function MDAP(ctx: ExecContext, doRound: boolean): void {\n\tconst pointIndex = ctx.stack[--ctx.stackTop];\n\n\tconst zone = ctx.zp0;\n\tif (pointIndex < 0 || pointIndex >= zone.nPoints) {\n\t\tctx.error = `MDAP: invalid point ${pointIndex}`;\n\t\treturn;\n\t}\n\n\tlet distance = getCurrent(ctx, zone, pointIndex);\n\n\tif (doRound) {\n\t\tconst comp = compensate(distance, ctx.GS);\n\t\tdistance = round(distance, comp, ctx.GS) - distance;\n\t} else {\n\t\tdistance = 0;\n\t}\n\n\tmovePoint(ctx, zone, pointIndex, distance);\n\ttouchPoint(ctx, zone, pointIndex);\n\n\tctx.GS.rp0 = pointIndex;\n\tctx.GS.rp1 = pointIndex;\n}\n\n// =============================================================================\n// MIAP - Move Indirect Absolute Point\n// =============================================================================\n\n/** MIAP - Move Indirect Absolute Point (uses CVT) */\nexport function MIAP(ctx: ExecContext, doRound: boolean): void {\n\tconst cvtIndex = ctx.stack[--ctx.stackTop];\n\tconst pointIndex = ctx.stack[--ctx.stackTop];\n\n\tconst zone = ctx.zp0;\n\tif (pointIndex < 0 || pointIndex >= zone.nPoints) {\n\t\tctx.error = `MIAP: invalid point ${pointIndex}`;\n\t\treturn;\n\t}\n\n\tif (cvtIndex < 0 || cvtIndex >= ctx.cvtSize) {\n\t\tctx.error = `MIAP: invalid CVT index ${cvtIndex}`;\n\t\treturn;\n\t}\n\n\tlet cvtDistance = ctx.cvt[cvtIndex];\n\tconst currentPos = getCurrent(ctx, zone, pointIndex);\n\n\tif (doRound) {\n\t\t// Check if we should use CVT value or current position\n\t\tconst diff = Math.abs(cvtDistance - currentPos);\n\n\t\tif (diff > ctx.GS.controlValueCutIn) {\n\t\t\t// Difference too large, use current position\n\t\t\tcvtDistance = currentPos;\n\t\t}\n\n\t\tconst comp = compensate(cvtDistance, ctx.GS);\n\t\tcvtDistance = round(cvtDistance, comp, ctx.GS);\n\t}\n\n\tconst distance = cvtDistance - currentPos;\n\tmovePoint(ctx, zone, pointIndex, distance);\n\ttouchPoint(ctx, zone, pointIndex);\n\n\tctx.GS.rp0 = pointIndex;\n\tctx.GS.rp1 = pointIndex;\n}\n\n// =============================================================================\n// MDRP - Move Direct Relative Point\n// =============================================================================\n\n/** MDRP - Move Direct Relative Point */\nexport function MDRP(ctx: ExecContext, flags: number): void {\n\tconst pointIndex = ctx.stack[--ctx.stackTop];\n\n\tconst setRp0 = (flags & 0x10) !== 0;\n\tconst keepMinDist = (flags & 0x08) !== 0;\n\tconst doRound = (flags & 0x04) !== 0;\n\t// bits 0-1 are distance type (ignored for now)\n\n\tconst zp0 = ctx.zp0;\n\tconst zp1 = ctx.zp1;\n\n\tif (pointIndex < 0 || pointIndex >= zp1.nPoints) {\n\t\tctx.error = `MDRP: invalid point ${pointIndex}`;\n\t\treturn;\n\t}\n\n\tconst rp0 = ctx.GS.rp0;\n\tif (rp0 < 0 || rp0 >= zp0.nPoints) {\n\t\tctx.error = `MDRP: invalid rp0 ${rp0}`;\n\t\treturn;\n\t}\n\n\t// Get original distance (using dual projection vector)\n\tlet distance = getOriginal(ctx, zp1, pointIndex) - getOriginal(ctx, zp0, rp0);\n\n\t// Auto-flip if enabled and distance is negative\n\tif (ctx.GS.autoFlip && distance < 0) {\n\t\tdistance = -distance;\n\t}\n\n\tif (doRound) {\n\t\tconst comp = compensate(distance, ctx.GS);\n\t\tdistance = round(distance, comp, ctx.GS);\n\t}\n\n\t// Apply minimum distance\n\tif (keepMinDist) {\n\t\tif (distance >= 0) {\n\t\t\tif (distance < ctx.GS.minimumDistance) {\n\t\t\t\tdistance = ctx.GS.minimumDistance;\n\t\t\t}\n\t\t} else {\n\t\t\tif (distance > -ctx.GS.minimumDistance) {\n\t\t\t\tdistance = -ctx.GS.minimumDistance;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Calculate actual movement needed\n\tconst currentDist =\n\t\tgetCurrent(ctx, zp1, pointIndex) - getCurrent(ctx, zp0, rp0);\n\tconst move = distance - currentDist;\n\n\tmovePoint(ctx, zp1, pointIndex, move);\n\ttouchPoint(ctx, zp1, pointIndex);\n\n\tctx.GS.rp1 = ctx.GS.rp0;\n\tctx.GS.rp2 = pointIndex;\n\tif (setRp0) {\n\t\tctx.GS.rp0 = pointIndex;\n\t}\n}\n\n// =============================================================================\n// MIRP - Move Indirect Relative Point\n// =============================================================================\n\n/** MIRP - Move Indirect Relative Point (uses CVT) */\nexport function MIRP(ctx: ExecContext, flags: number): void {\n\tconst cvtIndex = ctx.stack[--ctx.stackTop];\n\tconst pointIndex = ctx.stack[--ctx.stackTop];\n\n\tconst setRp0 = (flags & 0x10) !== 0;\n\tconst keepMinDist = (flags & 0x08) !== 0;\n\tconst doRound = (flags & 0x04) !== 0;\n\t// bits 0-1 are distance type (ignored for now)\n\n\tconst zp0 = ctx.zp0;\n\tconst zp1 = ctx.zp1;\n\n\tif (pointIndex < 0 || pointIndex >= zp1.nPoints) {\n\t\tctx.error = `MIRP: invalid point ${pointIndex}`;\n\t\treturn;\n\t}\n\n\tif (cvtIndex < 0 || cvtIndex >= ctx.cvtSize) {\n\t\tctx.error = `MIRP: invalid CVT index ${cvtIndex}`;\n\t\treturn;\n\t}\n\n\tconst rp0 = ctx.GS.rp0;\n\tif (rp0 < 0 || rp0 >= zp0.nPoints) {\n\t\tctx.error = `MIRP: invalid rp0 ${rp0}`;\n\t\treturn;\n\t}\n\n\t// Get original distance for comparison\n\tconst orgDist =\n\t\tgetOriginal(ctx, zp1, pointIndex) - getOriginal(ctx, zp0, rp0);\n\n\t// Get CVT distance\n\tlet cvtDist = ctx.cvt[cvtIndex];\n\n\t// Auto-flip\n\tif (ctx.GS.autoFlip) {\n\t\tif ((orgDist < 0 && cvtDist > 0) || (orgDist > 0 && cvtDist < 0)) {\n\t\t\tcvtDist = -cvtDist;\n\t\t}\n\t}\n\n\t// Check control value cut-in\n\tconst diff = Math.abs(orgDist - cvtDist);\n\tlet distance: F26Dot6;\n\n\tif (diff > ctx.GS.controlValueCutIn) {\n\t\t// Use original distance\n\t\tdistance = orgDist;\n\t} else {\n\t\t// Use CVT distance\n\t\tdistance = cvtDist;\n\t}\n\n\tif (doRound) {\n\t\tconst comp = compensate(distance, ctx.GS);\n\t\tdistance = round(distance, comp, ctx.GS);\n\t}\n\n\t// Apply minimum distance\n\tif (keepMinDist) {\n\t\tif (orgDist >= 0) {\n\t\t\tif (distance < ctx.GS.minimumDistance) {\n\t\t\t\tdistance = ctx.GS.minimumDistance;\n\t\t\t}\n\t\t} else {\n\t\t\tif (distance > -ctx.GS.minimumDistance) {\n\t\t\t\tdistance = -ctx.GS.minimumDistance;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Calculate actual movement needed\n\tconst currentDist =\n\t\tgetCurrent(ctx, zp1, pointIndex) - getCurrent(ctx, zp0, rp0);\n\tconst move = distance - currentDist;\n\n\tmovePoint(ctx, zp1, pointIndex, move);\n\ttouchPoint(ctx, zp1, pointIndex);\n\n\tctx.GS.rp1 = ctx.GS.rp0;\n\tctx.GS.rp2 = pointIndex;\n\tif (setRp0) {\n\t\tctx.GS.rp0 = pointIndex;\n\t}\n}\n\n// =============================================================================\n// SHP - Shift Point\n// =============================================================================\n\n/** SHP - Shift Point using reference point */\nexport function SHP(ctx: ExecContext, useRp1: boolean): void {\n\tconst refZone = useRp1 ? ctx.zp0 : ctx.zp1;\n\tconst refPoint = useRp1 ? ctx.GS.rp1 : ctx.GS.rp2;\n\n\tif (refPoint < 0 || refPoint >= refZone.nPoints) {\n\t\tctx.error = `SHP: invalid reference point ${refPoint}`;\n\t\treturn;\n\t}\n\n\t// Calculate shift amount from reference point movement\n\tconst orgRef = getOriginal(ctx, refZone, refPoint);\n\tconst curRef = getCurrent(ctx, refZone, refPoint);\n\tconst shift = curRef - orgRef;\n\n\t// Apply to loop count points\n\tconst zone = ctx.zp2;\n\tconst count = ctx.GS.loop;\n\tctx.GS.loop = 1;\n\n\tfor (let i = 0; i < count; i++) {\n\t\tconst pointIndex = ctx.stack[--ctx.stackTop];\n\n\t\tif (pointIndex < 0 || pointIndex >= zone.nPoints) {\n\t\t\tctx.error = `SHP: invalid point ${pointIndex}`;\n\t\t\treturn;\n\t\t}\n\n\t\tmovePoint(ctx, zone, pointIndex, shift);\n\t\ttouchPoint(ctx, zone, pointIndex);\n\t}\n}\n\n// =============================================================================\n// SHC - Shift Contour\n// =============================================================================\n\n/** SHC - Shift Contour using reference point */\nexport function SHC(ctx: ExecContext, useRp1: boolean): void {\n\tconst contourIndex = ctx.stack[--ctx.stackTop];\n\n\tconst refZone = useRp1 ? ctx.zp0 : ctx.zp1;\n\tconst refPoint = useRp1 ? ctx.GS.rp1 : ctx.GS.rp2;\n\n\tif (refPoint < 0 || refPoint >= refZone.nPoints) {\n\t\tctx.error = `SHC: invalid reference point ${refPoint}`;\n\t\treturn;\n\t}\n\n\tconst zone = ctx.zp2;\n\tif (contourIndex < 0 || contourIndex >= zone.nContours) {\n\t\tctx.error = `SHC: invalid contour ${contourIndex}`;\n\t\treturn;\n\t}\n\n\t// Calculate shift amount\n\tconst orgRef = getOriginal(ctx, refZone, refPoint);\n\tconst curRef = getCurrent(ctx, refZone, refPoint);\n\tconst shift = curRef - orgRef;\n\n\t// Get contour bounds\n\tconst start = contourIndex === 0 ? 0 : zone.contours[contourIndex - 1] + 1;\n\tconst end = zone.contours[contourIndex];\n\n\t// Shift all points in contour (except reference point if in same zone)\n\tfor (let i = start; i <= end; i++) {\n\t\tif (zone === refZone && i === refPoint) continue;\n\t\tmovePoint(ctx, zone, i, shift);\n\t\ttouchPoint(ctx, zone, i);\n\t}\n}\n\n// =============================================================================\n// SHZ - Shift Zone\n// =============================================================================\n\n/** SHZ - Shift Zone using reference point */\nexport function SHZ(ctx: ExecContext, useRp1: boolean): void {\n\tconst zoneIndex = ctx.stack[--ctx.stackTop];\n\n\tconst refZone = useRp1 ? ctx.zp0 : ctx.zp1;\n\tconst refPoint = useRp1 ? ctx.GS.rp1 : ctx.GS.rp2;\n\n\tif (refPoint < 0 || refPoint >= refZone.nPoints) {\n\t\tctx.error = `SHZ: invalid reference point ${refPoint}`;\n\t\treturn;\n\t}\n\n\tconst zone = zoneIndex === 0 ? ctx.twilight : ctx.pts;\n\n\t// Calculate shift amount\n\tconst orgRef = getOriginal(ctx, refZone, refPoint);\n\tconst curRef = getCurrent(ctx, refZone, refPoint);\n\tconst shift = curRef - orgRef;\n\n\t// Shift all points in zone (except reference point if in same zone)\n\tfor (let i = 0; i < zone.nPoints; i++) {\n\t\tif (zone === refZone && i === refPoint) continue;\n\t\tmovePoint(ctx, zone, i, shift);\n\t\t// Note: SHZ doesn't set touch flags\n\t}\n}\n\n// =============================================================================\n// SHPIX - Shift Point by Pixel Amount\n// =============================================================================\n\n/** SHPIX - Shift Point by Pixel Amount */\nexport function SHPIX(ctx: ExecContext): void {\n\tconst distance = ctx.stack[--ctx.stackTop];\n\n\tconst zone = ctx.zp2;\n\tconst count = ctx.GS.loop;\n\tctx.GS.loop = 1;\n\n\tfor (let i = 0; i < count; i++) {\n\t\tconst pointIndex = ctx.stack[--ctx.stackTop];\n\n\t\tif (pointIndex < 0 || pointIndex >= zone.nPoints) {\n\t\t\tctx.error = `SHPIX: invalid point ${pointIndex}`;\n\t\t\treturn;\n\t\t}\n\n\t\tmovePoint(ctx, zone, pointIndex, distance);\n\t\ttouchPoint(ctx, zone, pointIndex);\n\t}\n}\n\n// =============================================================================\n// IP - Interpolate Point\n// =============================================================================\n\n/** IP - Interpolate Point */\nexport function IP(ctx: ExecContext): void {\n\tconst rp1 = ctx.GS.rp1;\n\tconst rp2 = ctx.GS.rp2;\n\n\tif (rp1 < 0 || rp1 >= ctx.zp0.nPoints) {\n\t\tctx.error = `IP: invalid rp1 ${rp1}`;\n\t\treturn;\n\t}\n\tif (rp2 < 0 || rp2 >= ctx.zp1.nPoints) {\n\t\tctx.error = `IP: invalid rp2 ${rp2}`;\n\t\treturn;\n\t}\n\n\t// Get original and current positions of reference points\n\tconst org1 = getOriginal(ctx, ctx.zp0, rp1);\n\tconst org2 = getOriginal(ctx, ctx.zp1, rp2);\n\tconst cur1 = getCurrent(ctx, ctx.zp0, rp1);\n\tconst cur2 = getCurrent(ctx, ctx.zp1, rp2);\n\n\tconst orgRange = org2 - org1;\n\tconst curRange = cur2 - cur1;\n\n\tconst zone = ctx.zp2;\n\tconst count = ctx.GS.loop;\n\tctx.GS.loop = 1;\n\n\tfor (let i = 0; i < count; i++) {\n\t\tconst pointIndex = ctx.stack[--ctx.stackTop];\n\n\t\tif (pointIndex < 0 || pointIndex >= zone.nPoints) {\n\t\t\tctx.error = `IP: invalid point ${pointIndex}`;\n\t\t\treturn;\n\t\t}\n\n\t\tconst orgPt = getOriginal(ctx, zone, pointIndex);\n\t\tconst curPt = getCurrent(ctx, zone, pointIndex);\n\n\t\tlet newPos: F26Dot6;\n\n\t\tif (orgRange !== 0) {\n\t\t\t// Interpolate based on relative position\n\t\t\tconst t = orgPt - org1;\n\t\t\tnewPos = cur1 + Math.round((t * curRange) / orgRange);\n\t\t} else {\n\t\t\t// Reference points coincide, just shift\n\t\t\tnewPos = curPt + (cur1 - org1);\n\t\t}\n\n\t\tmovePoint(ctx, zone, pointIndex, newPos - curPt);\n\t\ttouchPoint(ctx, zone, pointIndex);\n\t}\n}\n\n// =============================================================================\n// ALIGNRP - Align Reference Point\n// =============================================================================\n\n/** ALIGNRP - Align to Reference Point */\nexport function ALIGNRP(ctx: ExecContext): void {\n\tconst rp0 = ctx.GS.rp0;\n\n\tif (rp0 < 0 || rp0 >= ctx.zp0.nPoints) {\n\t\tctx.error = `ALIGNRP: invalid rp0 ${rp0}`;\n\t\treturn;\n\t}\n\n\tconst refPos = getCurrent(ctx, ctx.zp0, rp0);\n\n\tconst zone = ctx.zp1;\n\tconst count = ctx.GS.loop;\n\tctx.GS.loop = 1;\n\n\tfor (let i = 0; i < count; i++) {\n\t\tconst pointIndex = ctx.stack[--ctx.stackTop];\n\n\t\tif (pointIndex < 0 || pointIndex >= zone.nPoints) {\n\t\t\tctx.error = `ALIGNRP: invalid point ${pointIndex}`;\n\t\t\treturn;\n\t\t}\n\n\t\tconst curPos = getCurrent(ctx, zone, pointIndex);\n\t\tconst distance = refPos - curPos;\n\n\t\tmovePoint(ctx, zone, pointIndex, distance);\n\t\ttouchPoint(ctx, zone, pointIndex);\n\t}\n}\n\n// =============================================================================\n// MSIRP - Move Stack Indirect Relative Point\n// =============================================================================\n\n/** MSIRP - Move Stack Indirect Relative Point */\nexport function MSIRP(ctx: ExecContext, setRp0: boolean): void {\n\tconst distance = ctx.stack[--ctx.stackTop];\n\tconst pointIndex = ctx.stack[--ctx.stackTop];\n\n\tconst zp0 = ctx.zp0;\n\tconst zp1 = ctx.zp1;\n\n\tif (pointIndex < 0 || pointIndex >= zp1.nPoints) {\n\t\tctx.error = `MSIRP: invalid point ${pointIndex}`;\n\t\treturn;\n\t}\n\n\tconst rp0 = ctx.GS.rp0;\n\tif (rp0 < 0 || rp0 >= zp0.nPoints) {\n\t\tctx.error = `MSIRP: invalid rp0 ${rp0}`;\n\t\treturn;\n\t}\n\n\t// Calculate current distance and move to achieve desired distance\n\tconst currentDist =\n\t\tgetCurrent(ctx, zp1, pointIndex) - getCurrent(ctx, zp0, rp0);\n\tconst move = distance - currentDist;\n\n\tmovePoint(ctx, zp1, pointIndex, move);\n\ttouchPoint(ctx, zp1, pointIndex);\n\n\tctx.GS.rp1 = ctx.GS.rp0;\n\tctx.GS.rp2 = pointIndex;\n\tif (setRp0) {\n\t\tctx.GS.rp0 = pointIndex;\n\t}\n}\n\n// =============================================================================\n// ISECT - Move Point to Intersection\n// =============================================================================\n\n/** ISECT - Move Point to Intersection of two lines */\nexport function ISECT(ctx: ExecContext): void {\n\tconst b1 = ctx.stack[--ctx.stackTop];\n\tconst b0 = ctx.stack[--ctx.stackTop];\n\tconst a1 = ctx.stack[--ctx.stackTop];\n\tconst a0 = ctx.stack[--ctx.stackTop];\n\tconst point = ctx.stack[--ctx.stackTop];\n\n\t// Line A: points a0 to a1 in zp0\n\t// Line B: points b0 to b1 in zp1\n\t// Move point in zp2 to intersection\n\n\tconst zone0 = ctx.zp0;\n\tconst zone1 = ctx.zp1;\n\tconst zone2 = ctx.zp2;\n\n\tif (a0 < 0 || a0 >= zone0.nPoints || a1 < 0 || a1 >= zone0.nPoints) {\n\t\tctx.error = `ISECT: invalid line A points`;\n\t\treturn;\n\t}\n\tif (b0 < 0 || b0 >= zone1.nPoints || b1 < 0 || b1 >= zone1.nPoints) {\n\t\tctx.error = `ISECT: invalid line B points`;\n\t\treturn;\n\t}\n\tif (point < 0 || point >= zone2.nPoints) {\n\t\tctx.error = `ISECT: invalid point ${point}`;\n\t\treturn;\n\t}\n\n\t// Get line endpoints\n\tconst pa0 = zone0.cur[a0];\n\tconst pa1 = zone0.cur[a1];\n\tconst pb0 = zone1.cur[b0];\n\tconst pb1 = zone1.cur[b1];\n\n\t// Calculate direction vectors\n\tconst dax = pa1.x - pa0.x;\n\tconst day = pa1.y - pa0.y;\n\tconst dbx = pb1.x - pb0.x;\n\tconst dby = pb1.y - pb0.y;\n\n\t// Cross product for denominator\n\tconst denom = dax * dby - day * dbx;\n\n\tconst pt = zone2.cur[point];\n\n\tif (denom === 0) {\n\t\t// Lines are parallel, move point to midpoint\n\t\tpt.x = (pa0.x + pa1.x + pb0.x + pb1.x) >> 2;\n\t\tpt.y = (pa0.y + pa1.y + pb0.y + pb1.y) >> 2;\n\t} else {\n\t\t// Calculate intersection\n\t\tconst dx = pb0.x - pa0.x;\n\t\tconst dy = pb0.y - pa0.y;\n\t\tconst t = (dx * dby - dy * dbx) / denom;\n\n\t\tpt.x = Math.round(pa0.x + t * dax);\n\t\tpt.y = Math.round(pa0.y + t * day);\n\t}\n\n\tzone2.tags[point] |= TouchFlag.Both;\n}\n\n// =============================================================================\n// ALIGNPTS - Align Points\n// =============================================================================\n\n/** ALIGNPTS - Align two points */\nexport function ALIGNPTS(ctx: ExecContext): void {\n\tconst p2 = ctx.stack[--ctx.stackTop];\n\tconst p1 = ctx.stack[--ctx.stackTop];\n\n\tconst zone1 = ctx.zp0;\n\tconst zone2 = ctx.zp1;\n\n\tif (p1 < 0 || p1 >= zone1.nPoints) {\n\t\tctx.error = `ALIGNPTS: invalid point ${p1}`;\n\t\treturn;\n\t}\n\tif (p2 < 0 || p2 >= zone2.nPoints) {\n\t\tctx.error = `ALIGNPTS: invalid point ${p2}`;\n\t\treturn;\n\t}\n\n\t// Get current positions projected\n\tconst pos1 = getCurrent(ctx, zone1, p1);\n\tconst pos2 = getCurrent(ctx, zone2, p2);\n\n\t// Move both to midpoint\n\tconst mid = (pos1 + pos2) >> 1;\n\n\tmovePoint(ctx, zone1, p1, mid - pos1);\n\tmovePoint(ctx, zone2, p2, mid - pos2);\n\n\ttouchPoint(ctx, zone1, p1);\n\ttouchPoint(ctx, zone2, p2);\n}\n\n// =============================================================================\n// GC - Get Coordinate\n// =============================================================================\n\n/** GC - Get Coordinate projected onto projection vector */\nexport function GC(ctx: ExecContext, useOriginal: boolean): void {\n\tconst pointIndex = ctx.stack[--ctx.stackTop];\n\tconst zone = ctx.zp2;\n\n\tif (pointIndex < 0 || pointIndex >= zone.nPoints) {\n\t\tctx.error = `GC: invalid point ${pointIndex}`;\n\t\tctx.stack[ctx.stackTop++] = 0;\n\t\treturn;\n\t}\n\n\tconst coord = useOriginal\n\t\t? getOriginal(ctx, zone, pointIndex)\n\t\t: getCurrent(ctx, zone, pointIndex);\n\n\tctx.stack[ctx.stackTop++] = coord;\n}\n\n// =============================================================================\n// SCFS - Set Coordinate From Stack\n// =============================================================================\n\n/** SCFS - Set Coordinate From Stack */\nexport function SCFS(ctx: ExecContext): void {\n\tconst coord = ctx.stack[--ctx.stackTop];\n\tconst pointIndex = ctx.stack[--ctx.stackTop];\n\n\tconst zone = ctx.zp2;\n\n\tif (pointIndex < 0 || pointIndex >= zone.nPoints) {\n\t\tctx.error = `SCFS: invalid point ${pointIndex}`;\n\t\treturn;\n\t}\n\n\tconst current = getCurrent(ctx, zone, pointIndex);\n\tmovePoint(ctx, zone, pointIndex, coord - current);\n\ttouchPoint(ctx, zone, pointIndex);\n}\n\n// =============================================================================\n// MD - Measure Distance\n// =============================================================================\n\n/** MD - Measure Distance between two points */\nexport function MD(ctx: ExecContext, useOriginal: boolean): void {\n\tconst p2 = ctx.stack[--ctx.stackTop];\n\tconst p1 = ctx.stack[--ctx.stackTop];\n\n\tconst zone0 = ctx.zp0;\n\tconst zone1 = ctx.zp1;\n\n\tif (p1 < 0 || p1 >= zone0.nPoints) {\n\t\tctx.error = `MD: invalid point ${p1}`;\n\t\tctx.stack[ctx.stackTop++] = 0;\n\t\treturn;\n\t}\n\tif (p2 < 0 || p2 >= zone1.nPoints) {\n\t\tctx.error = `MD: invalid point ${p2}`;\n\t\tctx.stack[ctx.stackTop++] = 0;\n\t\treturn;\n\t}\n\n\tlet distance: F26Dot6;\n\n\tif (useOriginal) {\n\t\tdistance = getOriginal(ctx, zone1, p2) - getOriginal(ctx, zone0, p1);\n\t} else {\n\t\tdistance = getCurrent(ctx, zone1, p2) - getCurrent(ctx, zone0, p1);\n\t}\n\n\tctx.stack[ctx.stackTop++] = distance;\n}\n\n// =============================================================================\n// MPPEM / MPS - Get Pixels Per EM / Point Size\n// =============================================================================\n\n/** MPPEM - Measure Pixels Per EM */\nexport function MPPEM(ctx: ExecContext): void {\n\tctx.stack[ctx.stackTop++] = ctx.ppem;\n}\n\n/** MPS - Measure Point Size */\nexport function MPS(ctx: ExecContext): void {\n\tctx.stack[ctx.stackTop++] = ctx.pointSize;\n}\n\n// =============================================================================\n// FLIPPT - Flip Point\n// =============================================================================\n\n/** FLIPPT - Flip on-curve/off-curve flag */\nexport function FLIPPT(ctx: ExecContext): void {\n\tconst zone = ctx.pts;\n\tconst count = ctx.GS.loop;\n\tctx.GS.loop = 1;\n\n\tfor (let i = 0; i < count; i++) {\n\t\tconst pointIndex = ctx.stack[--ctx.stackTop];\n\n\t\tif (pointIndex < 0 || pointIndex >= zone.nPoints) {\n\t\t\tctx.error = `FLIPPT: invalid point ${pointIndex}`;\n\t\t\treturn;\n\t\t}\n\n\t\t// Toggle bit 0 (on-curve flag)\n\t\tzone.tags[pointIndex] ^= 0x01;\n\t}\n}\n\n// =============================================================================\n// FLIPRGON / FLIPRGOFF - Flip Range On/Off\n// =============================================================================\n\n/** FLIPRGON - Set on-curve flag for range */\nexport function FLIPRGON(ctx: ExecContext): void {\n\tconst endPoint = ctx.stack[--ctx.stackTop];\n\tconst startPoint = ctx.stack[--ctx.stackTop];\n\n\tconst zone = ctx.pts;\n\n\tif (startPoint < 0 || endPoint >= zone.nPoints || startPoint > endPoint) {\n\t\tctx.error = `FLIPRGON: invalid range ${startPoint}-${endPoint}`;\n\t\treturn;\n\t}\n\n\tfor (let i = startPoint; i <= endPoint; i++) {\n\t\tzone.tags[i] |= 0x01; // Set on-curve\n\t}\n}\n\n/** FLIPRGOFF - Clear on-curve flag for range */\nexport function FLIPRGOFF(ctx: ExecContext): void {\n\tconst endPoint = ctx.stack[--ctx.stackTop];\n\tconst startPoint = ctx.stack[--ctx.stackTop];\n\n\tconst zone = ctx.pts;\n\n\tif (startPoint < 0 || endPoint >= zone.nPoints || startPoint > endPoint) {\n\t\tctx.error = `FLIPRGOFF: invalid range ${startPoint}-${endPoint}`;\n\t\treturn;\n\t}\n\n\tfor (let i = startPoint; i <= endPoint; i++) {\n\t\tzone.tags[i] &= ~0x01; // Clear on-curve\n\t}\n}\n\n// =============================================================================\n// ROUND / NROUND - Round Value\n// =============================================================================\n\n/** ROUND - Round value */\nexport function ROUND(ctx: ExecContext, _colorIndex: number): void {\n\tconst value = ctx.stack[--ctx.stackTop];\n\tconst comp = compensate(value, ctx.GS);\n\tctx.stack[ctx.stackTop++] = round(value, comp, ctx.GS);\n}\n\n/** NROUND - No-round (just applies engine compensation) */\nexport function NROUND(ctx: ExecContext, _colorIndex: number): void {\n\tconst value = ctx.stack[--ctx.stackTop];\n\tconst comp = compensate(value, ctx.GS);\n\tctx.stack[ctx.stackTop++] = value + comp;\n}\n",
74
- "/**\n * Delta instructions\n *\n * These instructions allow fine-tuning of point positions and CVT values\n * at specific pixel-per-em (ppem) sizes. This is useful for fixing\n * rendering issues that only appear at certain sizes.\n */\n\nimport type { ExecContext } from \"../types.ts\";\nimport { movePoint, touchPoint } from \"./points.ts\";\n\n/**\n * DELTAP1 - Delta exception point (ppem 0-15 + deltaBase)\n */\nexport function DELTAP1(ctx: ExecContext): void {\n\tdeltaPoint(ctx, 0);\n}\n\n/**\n * DELTAP2 - Delta exception point (ppem 16-31 + deltaBase)\n */\nexport function DELTAP2(ctx: ExecContext): void {\n\tdeltaPoint(ctx, 16);\n}\n\n/**\n * DELTAP3 - Delta exception point (ppem 32-47 + deltaBase)\n */\nexport function DELTAP3(ctx: ExecContext): void {\n\tdeltaPoint(ctx, 32);\n}\n\n/**\n * Common logic for DELTAP1/2/3\n */\nfunction deltaPoint(ctx: ExecContext, rangeOffset: number): void {\n\tconst count = ctx.stack[--ctx.stackTop];\n\n\tif (count < 0) {\n\t\tctx.error = `DELTAP: invalid count ${count}`;\n\t\treturn;\n\t}\n\n\tconst zone = ctx.zp0;\n\n\tfor (let i = 0; i < count; i++) {\n\t\tconst argByte = ctx.stack[--ctx.stackTop];\n\t\tconst pointIndex = ctx.stack[--ctx.stackTop];\n\n\t\tif (pointIndex < 0 || pointIndex >= zone.nPoints) {\n\t\t\tctx.error = `DELTAP: invalid point ${pointIndex}`;\n\t\t\treturn;\n\t\t}\n\n\t\t// Extract ppem delta and magnitude from argByte\n\t\t// High nibble: ppem - deltaBase - rangeOffset\n\t\t// Low nibble: magnitude (0-15, where 8-15 are negative)\n\t\tconst ppemDelta = ((argByte >> 4) & 0x0f) + ctx.GS.deltaBase + rangeOffset;\n\t\tconst magnitude = argByte & 0x0f;\n\n\t\t// Check if we're at the target ppem\n\t\tif (ppemDelta !== ctx.ppem) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Convert magnitude to actual delta value\n\t\t// 0-7: positive 1-8 (shifted by deltaShift)\n\t\t// 8-15: negative 1-8 (shifted by deltaShift)\n\t\tlet delta: number;\n\t\tif (magnitude < 8) {\n\t\t\tdelta = (magnitude + 1) << (6 - ctx.GS.deltaShift);\n\t\t} else {\n\t\t\tdelta = -((magnitude - 7) << (6 - ctx.GS.deltaShift));\n\t\t}\n\n\t\tmovePoint(ctx, zone, pointIndex, delta);\n\t\ttouchPoint(ctx, zone, pointIndex);\n\t}\n}\n\n/**\n * DELTAC1 - Delta exception CVT (ppem 0-15 + deltaBase)\n */\nexport function DELTAC1(ctx: ExecContext): void {\n\tdeltaCVT(ctx, 0);\n}\n\n/**\n * DELTAC2 - Delta exception CVT (ppem 16-31 + deltaBase)\n */\nexport function DELTAC2(ctx: ExecContext): void {\n\tdeltaCVT(ctx, 16);\n}\n\n/**\n * DELTAC3 - Delta exception CVT (ppem 32-47 + deltaBase)\n */\nexport function DELTAC3(ctx: ExecContext): void {\n\tdeltaCVT(ctx, 32);\n}\n\n/**\n * Common logic for DELTAC1/2/3\n */\nfunction deltaCVT(ctx: ExecContext, rangeOffset: number): void {\n\tconst count = ctx.stack[--ctx.stackTop];\n\n\tif (count < 0) {\n\t\tctx.error = `DELTAC: invalid count ${count}`;\n\t\treturn;\n\t}\n\n\tfor (let i = 0; i < count; i++) {\n\t\tconst argByte = ctx.stack[--ctx.stackTop];\n\t\tconst cvtIndex = ctx.stack[--ctx.stackTop];\n\n\t\tif (cvtIndex < 0 || cvtIndex >= ctx.cvtSize) {\n\t\t\tctx.error = `DELTAC: invalid CVT index ${cvtIndex}`;\n\t\t\treturn;\n\t\t}\n\n\t\t// Extract ppem delta and magnitude\n\t\tconst ppemDelta = ((argByte >> 4) & 0x0f) + ctx.GS.deltaBase + rangeOffset;\n\t\tconst magnitude = argByte & 0x0f;\n\n\t\t// Check if we're at the target ppem\n\t\tif (ppemDelta !== ctx.ppem) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Convert magnitude to actual delta value\n\t\tlet delta: number;\n\t\tif (magnitude < 8) {\n\t\t\tdelta = (magnitude + 1) << (6 - ctx.GS.deltaShift);\n\t\t} else {\n\t\t\tdelta = -((magnitude - 7) << (6 - ctx.GS.deltaShift));\n\t\t}\n\n\t\tctx.cvt[cvtIndex] += delta;\n\t}\n}\n",
75
- "/**\n * Graphics state manipulation instructions\n */\n\nimport { parseSuperRound } from \"../rounding.ts\";\nimport {\n\ttype ExecContext,\n\tRoundMode,\n\tTouchFlag,\n\ttype UnitVector,\n} from \"../types.ts\";\n\n// Vector instructions\n\n/** SVTCA - Set vectors to coordinate axis (both projection and freedom) */\nexport function SVTCA(ctx: ExecContext, axis: 0 | 1): void {\n\tif (axis === 0) {\n\t\t// Y axis\n\t\tctx.GS.projVector = { x: 0, y: 0x4000 };\n\t\tctx.GS.freeVector = { x: 0, y: 0x4000 };\n\t\tctx.GS.dualVector = { x: 0, y: 0x4000 };\n\t} else {\n\t\t// X axis\n\t\tctx.GS.projVector = { x: 0x4000, y: 0 };\n\t\tctx.GS.freeVector = { x: 0x4000, y: 0 };\n\t\tctx.GS.dualVector = { x: 0x4000, y: 0 };\n\t}\n}\n\n/** SPVTCA - Set projection vector to coordinate axis */\nexport function SPVTCA(ctx: ExecContext, axis: 0 | 1): void {\n\tif (axis === 0) {\n\t\tctx.GS.projVector = { x: 0, y: 0x4000 };\n\t\tctx.GS.dualVector = { x: 0, y: 0x4000 };\n\t} else {\n\t\tctx.GS.projVector = { x: 0x4000, y: 0 };\n\t\tctx.GS.dualVector = { x: 0x4000, y: 0 };\n\t}\n}\n\n/** SFVTCA - Set freedom vector to coordinate axis */\nexport function SFVTCA(ctx: ExecContext, axis: 0 | 1): void {\n\tif (axis === 0) {\n\t\tctx.GS.freeVector = { x: 0, y: 0x4000 };\n\t} else {\n\t\tctx.GS.freeVector = { x: 0x4000, y: 0 };\n\t}\n}\n\n/** Calculate unit vector from two points */\nfunction vectorFromPoints(\n\tctx: ExecContext,\n\tp1: number,\n\tp2: number,\n\tzone1: number,\n\tzone2: number,\n): UnitVector {\n\tconst z1 = zone1 === 0 ? ctx.twilight : ctx.pts;\n\tconst z2 = zone2 === 0 ? ctx.twilight : ctx.pts;\n\n\tconst pt1 = z1.cur[p1];\n\tconst pt2 = z2.cur[p2];\n\n\tif (!pt1 || !pt2) {\n\t\treturn { x: 0x4000, y: 0 };\n\t}\n\n\tconst dx = pt2.x - pt1.x;\n\tconst dy = pt2.y - pt1.y;\n\n\tconst len = Math.sqrt(dx * dx + dy * dy);\n\tif (len === 0) {\n\t\treturn { x: 0x4000, y: 0 };\n\t}\n\n\treturn {\n\t\tx: Math.round((dx / len) * 0x4000),\n\t\ty: Math.round((dy / len) * 0x4000),\n\t};\n}\n\n/** SPVTL - Set projection vector to line */\nexport function SPVTL(ctx: ExecContext, perpendicular: boolean): void {\n\tconst p2 = ctx.stack[--ctx.stackTop];\n\tconst p1 = ctx.stack[--ctx.stackTop];\n\n\tconst vec = vectorFromPoints(ctx, p1, p2, ctx.GS.gep1, ctx.GS.gep2);\n\n\tif (perpendicular) {\n\t\t// Rotate 90 degrees\n\t\tconst temp = vec.x;\n\t\tvec.x = vec.y;\n\t\tvec.y = -temp;\n\t}\n\n\tctx.GS.projVector = vec;\n\tctx.GS.dualVector = vec;\n}\n\n/** SFVTL - Set freedom vector to line */\nexport function SFVTL(ctx: ExecContext, perpendicular: boolean): void {\n\tconst p2 = ctx.stack[--ctx.stackTop];\n\tconst p1 = ctx.stack[--ctx.stackTop];\n\n\tconst vec = vectorFromPoints(ctx, p1, p2, ctx.GS.gep1, ctx.GS.gep2);\n\n\tif (perpendicular) {\n\t\tconst temp = vec.x;\n\t\tvec.x = vec.y;\n\t\tvec.y = -temp;\n\t}\n\n\tctx.GS.freeVector = vec;\n}\n\n/** SDPVTL - Set dual projection vector to line (only sets dualVector, not projVector) */\nexport function SDPVTL(ctx: ExecContext, perpendicular: boolean): void {\n\tconst p2 = ctx.stack[--ctx.stackTop];\n\tconst p1 = ctx.stack[--ctx.stackTop];\n\n\tconst vec = vectorFromPoints(ctx, p1, p2, ctx.GS.gep1, ctx.GS.gep2);\n\n\tif (perpendicular) {\n\t\tconst temp = vec.x;\n\t\tvec.x = vec.y;\n\t\tvec.y = -temp;\n\t}\n\n\t// SDPVTL only sets dualVector (used for measuring original distances)\n\t// Unlike SPVTL which sets both projVector and dualVector\n\tctx.GS.dualVector = vec;\n}\n\n/** SPVFS - Set projection vector from stack */\nexport function SPVFS(ctx: ExecContext): void {\n\tconst y = ctx.stack[--ctx.stackTop];\n\tconst x = ctx.stack[--ctx.stackTop];\n\n\t// Normalize\n\tconst len = Math.sqrt(x * x + y * y);\n\tif (len === 0) {\n\t\tctx.GS.projVector = { x: 0x4000, y: 0 };\n\t} else {\n\t\tctx.GS.projVector = {\n\t\t\tx: Math.round((x / len) * 0x4000),\n\t\t\ty: Math.round((y / len) * 0x4000),\n\t\t};\n\t}\n\tctx.GS.dualVector = { ...ctx.GS.projVector };\n}\n\n/** SFVFS - Set freedom vector from stack */\nexport function SFVFS(ctx: ExecContext): void {\n\tconst y = ctx.stack[--ctx.stackTop];\n\tconst x = ctx.stack[--ctx.stackTop];\n\n\tconst len = Math.sqrt(x * x + y * y);\n\tif (len === 0) {\n\t\tctx.GS.freeVector = { x: 0x4000, y: 0 };\n\t} else {\n\t\tctx.GS.freeVector = {\n\t\t\tx: Math.round((x / len) * 0x4000),\n\t\t\ty: Math.round((y / len) * 0x4000),\n\t\t};\n\t}\n}\n\n/** GPV - Get projection vector */\nexport function GPV(ctx: ExecContext): void {\n\tctx.stack[ctx.stackTop++] = ctx.GS.projVector.x;\n\tctx.stack[ctx.stackTop++] = ctx.GS.projVector.y;\n}\n\n/** GFV - Get freedom vector */\nexport function GFV(ctx: ExecContext): void {\n\tctx.stack[ctx.stackTop++] = ctx.GS.freeVector.x;\n\tctx.stack[ctx.stackTop++] = ctx.GS.freeVector.y;\n}\n\n/** SFVTPV - Set freedom vector to projection vector */\nexport function SFVTPV(ctx: ExecContext): void {\n\tctx.GS.freeVector = { ...ctx.GS.projVector };\n}\n\n// Reference point instructions\n\n/** SRP0 - Set reference point 0 */\nexport function SRP0(ctx: ExecContext): void {\n\tctx.GS.rp0 = ctx.stack[--ctx.stackTop];\n}\n\n/** SRP1 - Set reference point 1 */\nexport function SRP1(ctx: ExecContext): void {\n\tctx.GS.rp1 = ctx.stack[--ctx.stackTop];\n}\n\n/** SRP2 - Set reference point 2 */\nexport function SRP2(ctx: ExecContext): void {\n\tctx.GS.rp2 = ctx.stack[--ctx.stackTop];\n}\n\n// Zone pointer instructions\n\n/** SZP0 - Set zone pointer 0 */\nexport function SZP0(ctx: ExecContext): void {\n\tconst zone = ctx.stack[--ctx.stackTop];\n\tif (zone !== 0 && zone !== 1) {\n\t\tctx.error = `SZP0: invalid zone ${zone}`;\n\t\treturn;\n\t}\n\tctx.GS.gep0 = zone;\n\tctx.zp0 = zone === 0 ? ctx.twilight : ctx.pts;\n}\n\n/** SZP1 - Set zone pointer 1 */\nexport function SZP1(ctx: ExecContext): void {\n\tconst zone = ctx.stack[--ctx.stackTop];\n\tif (zone !== 0 && zone !== 1) {\n\t\tctx.error = `SZP1: invalid zone ${zone}`;\n\t\treturn;\n\t}\n\tctx.GS.gep1 = zone;\n\tctx.zp1 = zone === 0 ? ctx.twilight : ctx.pts;\n}\n\n/** SZP2 - Set zone pointer 2 */\nexport function SZP2(ctx: ExecContext): void {\n\tconst zone = ctx.stack[--ctx.stackTop];\n\tif (zone !== 0 && zone !== 1) {\n\t\tctx.error = `SZP2: invalid zone ${zone}`;\n\t\treturn;\n\t}\n\tctx.GS.gep2 = zone;\n\tctx.zp2 = zone === 0 ? ctx.twilight : ctx.pts;\n}\n\n/** SZPS - Set all zone pointers */\nexport function SZPS(ctx: ExecContext): void {\n\tconst zone = ctx.stack[--ctx.stackTop];\n\tif (zone !== 0 && zone !== 1) {\n\t\tctx.error = `SZPS: invalid zone ${zone}`;\n\t\treturn;\n\t}\n\tctx.GS.gep0 = zone;\n\tctx.GS.gep1 = zone;\n\tctx.GS.gep2 = zone;\n\tconst z = zone === 0 ? ctx.twilight : ctx.pts;\n\tctx.zp0 = z;\n\tctx.zp1 = z;\n\tctx.zp2 = z;\n}\n\n// Other graphics state\n\n/** SLOOP - Set loop counter */\nexport function SLOOP(ctx: ExecContext): void {\n\tconst count = ctx.stack[--ctx.stackTop];\n\tif (count <= 0) {\n\t\tctx.error = `SLOOP: invalid count ${count}`;\n\t\treturn;\n\t}\n\tctx.GS.loop = count;\n}\n\n/** SMD - Set minimum distance */\nexport function SMD(ctx: ExecContext): void {\n\tctx.GS.minimumDistance = ctx.stack[--ctx.stackTop];\n}\n\n/** SCVTCI - Set control value table cut-in */\nexport function SCVTCI(ctx: ExecContext): void {\n\tctx.GS.controlValueCutIn = ctx.stack[--ctx.stackTop];\n}\n\n/** SSWCI - Set single width cut-in */\nexport function SSWCI(ctx: ExecContext): void {\n\tctx.GS.singleWidthCutIn = ctx.stack[--ctx.stackTop];\n}\n\n/** SSW - Set single width value */\nexport function SSW(ctx: ExecContext): void {\n\tctx.GS.singleWidthValue = ctx.stack[--ctx.stackTop];\n}\n\n/** SDB - Set delta base */\nexport function SDB(ctx: ExecContext): void {\n\tctx.GS.deltaBase = ctx.stack[--ctx.stackTop];\n}\n\n/** SDS - Set delta shift */\nexport function SDS(ctx: ExecContext): void {\n\tctx.GS.deltaShift = ctx.stack[--ctx.stackTop];\n}\n\n// Rounding state\n\n/** RTG - Round to grid */\nexport function RTG(ctx: ExecContext): void {\n\tctx.GS.roundState = RoundMode.ToGrid;\n}\n\n/** RTHG - Round to half grid */\nexport function RTHG(ctx: ExecContext): void {\n\tctx.GS.roundState = RoundMode.ToHalfGrid;\n}\n\n/** RTDG - Round to double grid */\nexport function RTDG(ctx: ExecContext): void {\n\tctx.GS.roundState = RoundMode.ToDoubleGrid;\n}\n\n/** RDTG - Round down to grid */\nexport function RDTG(ctx: ExecContext): void {\n\tctx.GS.roundState = RoundMode.DownToGrid;\n}\n\n/** RUTG - Round up to grid */\nexport function RUTG(ctx: ExecContext): void {\n\tctx.GS.roundState = RoundMode.UpToGrid;\n}\n\n/** ROFF - Rounding off */\nexport function ROFF(ctx: ExecContext): void {\n\tctx.GS.roundState = RoundMode.Off;\n}\n\n/** SROUND - Super round */\nexport function SROUND(ctx: ExecContext): void {\n\tconst selector = ctx.stack[--ctx.stackTop];\n\tparseSuperRound(selector, ctx.GS);\n\tctx.GS.roundState = RoundMode.Super;\n}\n\n/** S45ROUND - Super round 45 degrees */\nexport function S45ROUND(ctx: ExecContext): void {\n\tconst selector = ctx.stack[--ctx.stackTop];\n\tparseSuperRound(selector, ctx.GS);\n\tctx.GS.roundState = RoundMode.Super45;\n}\n\n// Flip auto-flip\n\n/** FLIPON - Turn auto-flip on */\nexport function FLIPON(ctx: ExecContext): void {\n\tctx.GS.autoFlip = true;\n}\n\n/** FLIPOFF - Turn auto-flip off */\nexport function FLIPOFF(ctx: ExecContext): void {\n\tctx.GS.autoFlip = false;\n}\n\n// Scan and instruction control\n\n/** SCANCTRL - Set scan conversion control */\nexport function SCANCTRL(ctx: ExecContext): void {\n\tctx.GS.scanControl = ctx.stack[--ctx.stackTop];\n}\n\n/** SCANTYPE - Set scan type */\nexport function SCANTYPE(ctx: ExecContext): void {\n\tctx.GS.scanType = ctx.stack[--ctx.stackTop];\n}\n\n/** INSTCTRL - Set instruction control */\nexport function INSTCTRL(ctx: ExecContext): void {\n\tconst selector = ctx.stack[--ctx.stackTop];\n\tconst value = ctx.stack[--ctx.stackTop];\n\n\t// Bit 0: inhibit grid-fitting\n\t// Bit 1: ignore CVT values\n\tif (selector === 1 || selector === 2) {\n\t\tif (value) {\n\t\t\tctx.GS.instructControl |= selector;\n\t\t} else {\n\t\t\tctx.GS.instructControl &= ~selector;\n\t\t}\n\t}\n}\n\n/** GETINFO - Get font engine info */\nexport function GETINFO(ctx: ExecContext): void {\n\tconst selector = ctx.stack[--ctx.stackTop];\n\tlet result = 0;\n\n\t// Bit 0: version (we claim version 35 = Windows 95)\n\tif (selector & 1) {\n\t\tresult |= 35;\n\t}\n\n\t// Bit 1: glyph rotated\n\t// Bit 2: glyph stretched\n\n\t// Bit 5: grayscale rendering\n\tif (selector & 32) {\n\t\tresult |= 1 << 12;\n\t}\n\n\t// Bit 6: ClearType enabled\n\t// Bit 7: backwards compatible mode\n\n\tctx.stack[ctx.stackTop++] = result;\n}\n\n// Storage and CVT\n\n/** RS - Read storage */\nexport function RS(ctx: ExecContext): void {\n\tconst index = ctx.stack[--ctx.stackTop];\n\tif (index < 0 || index >= ctx.storageSize) {\n\t\tctx.error = `RS: invalid index ${index}`;\n\t\tctx.stack[ctx.stackTop++] = 0;\n\t\treturn;\n\t}\n\tctx.stack[ctx.stackTop++] = ctx.storage[index];\n}\n\n/** WS - Write storage */\nexport function WS(ctx: ExecContext): void {\n\tconst value = ctx.stack[--ctx.stackTop];\n\tconst index = ctx.stack[--ctx.stackTop];\n\tif (index < 0 || index >= ctx.storageSize) {\n\t\tctx.error = `WS: invalid index ${index}`;\n\t\treturn;\n\t}\n\tctx.storage[index] = value;\n}\n\n/** RCVT - Read CVT value */\nexport function RCVT(ctx: ExecContext): void {\n\tconst index = ctx.stack[--ctx.stackTop];\n\tif (index < 0 || index >= ctx.cvtSize) {\n\t\tctx.error = `RCVT: invalid index ${index}`;\n\t\tctx.stack[ctx.stackTop++] = 0;\n\t\treturn;\n\t}\n\tctx.stack[ctx.stackTop++] = ctx.cvt[index];\n}\n\n/** WCVTP - Write CVT value in pixels */\nexport function WCVTP(ctx: ExecContext): void {\n\tconst value = ctx.stack[--ctx.stackTop];\n\tconst index = ctx.stack[--ctx.stackTop];\n\tif (index < 0 || index >= ctx.cvtSize) {\n\t\tctx.error = `WCVTP: invalid index ${index}`;\n\t\treturn;\n\t}\n\tctx.cvt[index] = value;\n}\n\n/** WCVTF - Write CVT value in font units */\nexport function WCVTF(ctx: ExecContext): void {\n\tconst value = ctx.stack[--ctx.stackTop];\n\tconst index = ctx.stack[--ctx.stackTop];\n\tif (index < 0 || index >= ctx.cvtSize) {\n\t\tctx.error = `WCVTF: invalid index ${index}`;\n\t\treturn;\n\t}\n\t// Convert from font units to pixels (26.6)\n\tctx.cvt[index] = Math.round(value * ctx.scale);\n}\n\n/** UTP - UnTouch Point */\nexport function UTP(ctx: ExecContext): void {\n\tconst pointIndex = ctx.stack[--ctx.stackTop];\n\tconst zone = ctx.zp0;\n\n\tif (pointIndex < 0 || pointIndex >= zone.nPoints) {\n\t\tctx.error = `UTP: invalid point ${pointIndex}`;\n\t\treturn;\n\t}\n\n\t// Clear touch flags based on freedom vector direction\n\tconst fv = ctx.GS.freeVector;\n\tif (fv.y !== 0) {\n\t\tzone.tags[pointIndex] &= ~TouchFlag.Y;\n\t}\n\tif (fv.x !== 0) {\n\t\tzone.tags[pointIndex] &= ~TouchFlag.X;\n\t}\n}\n",
76
- "/**\n * IUP - Interpolate Untouched Points\n *\n * This instruction interpolates all points that haven't been touched\n * by previous hinting instructions. It's typically called near the end\n * of glyph hinting to smooth out the positions of all remaining points.\n */\n\nimport { type ExecContext, type GlyphZone, TouchFlag } from \"../types.ts\";\n\n/**\n * Interpolate untouched points in X direction\n */\nexport function IUP_X(ctx: ExecContext): void {\n\tinterpolateUntouched(ctx, TouchFlag.X, true);\n}\n\n/**\n * Interpolate untouched points in Y direction\n */\nexport function IUP_Y(ctx: ExecContext): void {\n\tinterpolateUntouched(ctx, TouchFlag.Y, false);\n}\n\n/**\n * Core interpolation logic\n */\nfunction interpolateUntouched(\n\tctx: ExecContext,\n\ttouchFlag: TouchFlag,\n\tisX: boolean,\n): void {\n\tconst zone = ctx.pts;\n\tconst nPoints = zone.nPoints;\n\tconst nContours = zone.nContours;\n\n\tif (nPoints === 0 || nContours === 0) return;\n\n\t// Process each contour separately\n\tlet contourStart = 0;\n\n\tfor (let c = 0; c < nContours; c++) {\n\t\tconst contourEnd = zone.contours[c];\n\n\t\t// Find first touched point in this contour\n\t\tlet firstTouched = -1;\n\t\tfor (let i = contourStart; i <= contourEnd; i++) {\n\t\t\tif (zone.tags[i] & touchFlag) {\n\t\t\t\tfirstTouched = i;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (firstTouched < 0) {\n\t\t\t// No touched points in contour, skip\n\t\t\tcontourStart = contourEnd + 1;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Walk through contour interpolating untouched points between touched ones\n\t\tlet prevTouched = firstTouched;\n\t\tlet i = firstTouched + 1;\n\t\tlet wrapped = false;\n\n\t\twhile (true) {\n\t\t\t// Find next touched point\n\t\t\tif (i > contourEnd) {\n\t\t\t\tif (wrapped) break;\n\t\t\t\ti = contourStart;\n\t\t\t\twrapped = true;\n\t\t\t}\n\n\t\t\tif (i === firstTouched && wrapped) {\n\t\t\t\t// Back to start, interpolate remaining points\n\t\t\t\tif (prevTouched !== firstTouched) {\n\t\t\t\t\tinterpolateRange(\n\t\t\t\t\t\tzone,\n\t\t\t\t\t\tprevTouched,\n\t\t\t\t\t\tfirstTouched,\n\t\t\t\t\t\tcontourStart,\n\t\t\t\t\t\tcontourEnd,\n\t\t\t\t\t\tisX,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif (zone.tags[i] & touchFlag) {\n\t\t\t\t// Found touched point - interpolate between prevTouched and i\n\t\t\t\tif (prevTouched !== i) {\n\t\t\t\t\tinterpolateRange(zone, prevTouched, i, contourStart, contourEnd, isX);\n\t\t\t\t}\n\t\t\t\tprevTouched = i;\n\t\t\t}\n\n\t\t\ti++;\n\t\t}\n\n\t\tcontourStart = contourEnd + 1;\n\t}\n}\n\n/**\n * Interpolate points between two touched reference points\n */\nfunction interpolateRange(\n\tzone: GlyphZone,\n\tp1: number,\n\tp2: number,\n\tcontourStart: number,\n\tcontourEnd: number,\n\tisX: boolean,\n): void {\n\t// Get original and current positions of reference points\n\tconst org1 = isX ? zone.org[p1]?.x : zone.org[p1]?.y;\n\tconst org2 = isX ? zone.org[p2]?.x : zone.org[p2]?.y;\n\tconst cur1 = isX ? zone.cur[p1]?.x : zone.cur[p1]?.y;\n\tconst cur2 = isX ? zone.cur[p2]?.x : zone.cur[p2]?.y;\n\n\t// Ensure org1 <= org2 for interpolation\n\tlet lo_org: number, hi_org: number;\n\tlet lo_cur: number, hi_cur: number;\n\n\tif (org1 <= org2) {\n\t\tlo_org = org1;\n\t\thi_org = org2;\n\t\tlo_cur = cur1;\n\t\thi_cur = cur2;\n\t} else {\n\t\tlo_org = org2;\n\t\thi_org = org1;\n\t\tlo_cur = cur2;\n\t\thi_cur = cur1;\n\t}\n\n\tconst orgRange = hi_org - lo_org;\n\tconst curRange = hi_cur - lo_cur;\n\n\t// Walk through points between p1 and p2 (wrapping around contour)\n\tlet i = p1 + 1;\n\tif (i > contourEnd) i = contourStart;\n\n\twhile (i !== p2) {\n\t\tconst org = isX ? zone.org[i]?.x : zone.org[i]?.y;\n\t\tlet newPos: number;\n\n\t\tif (org <= lo_org) {\n\t\t\t// Point is below/left of both references - shift by lo movement\n\t\t\tnewPos = (isX ? zone.cur[i]?.x : zone.cur[i]?.y) + (lo_cur - lo_org);\n\t\t} else if (org >= hi_org) {\n\t\t\t// Point is above/right of both references - shift by hi movement\n\t\t\tnewPos = (isX ? zone.cur[i]?.x : zone.cur[i]?.y) + (hi_cur - hi_org);\n\t\t} else {\n\t\t\t// Point is between references - interpolate\n\t\t\tif (orgRange !== 0) {\n\t\t\t\tconst t = org - lo_org;\n\t\t\t\tnewPos = lo_cur + Math.round((t * curRange) / orgRange);\n\t\t\t} else {\n\t\t\t\tnewPos = lo_cur;\n\t\t\t}\n\t\t}\n\n\t\tif (isX) {\n\t\t\tzone.cur[i].x = newPos;\n\t\t} else {\n\t\t\tzone.cur[i].y = newPos;\n\t\t}\n\n\t\ti++;\n\t\tif (i > contourEnd) i = contourStart;\n\t}\n}\n",
77
- "/**\n * Stack manipulation instructions\n */\n\nimport type { ExecContext } from \"../types.ts\";\n\n/** DUP - Duplicate top of stack */\nexport function DUP(ctx: ExecContext): void {\n\tconst val = ctx.stack[ctx.stackTop - 1];\n\tctx.stack[ctx.stackTop++] = val;\n}\n\n/** POP - Pop top of stack */\nexport function POP(ctx: ExecContext): void {\n\tctx.stackTop--;\n}\n\n/** CLEAR - Clear the entire stack */\nexport function CLEAR(ctx: ExecContext): void {\n\tctx.stackTop = 0;\n}\n\n/** SWAP - Swap top two elements */\nexport function SWAP(ctx: ExecContext): void {\n\tconst a = ctx.stack[ctx.stackTop - 1];\n\tconst b = ctx.stack[ctx.stackTop - 2];\n\tctx.stack[ctx.stackTop - 1] = b;\n\tctx.stack[ctx.stackTop - 2] = a;\n}\n\n/** DEPTH - Push stack depth */\nexport function DEPTH(ctx: ExecContext): void {\n\tconst depth = ctx.stackTop;\n\tctx.stack[ctx.stackTop++] = depth;\n}\n\n/** CINDEX - Copy indexed element to top */\nexport function CINDEX(ctx: ExecContext): void {\n\tconst index = ctx.stack[--ctx.stackTop];\n\tif (index <= 0 || index > ctx.stackTop) {\n\t\tctx.error = `CINDEX: invalid index ${index}`;\n\t\treturn;\n\t}\n\tctx.stack[ctx.stackTop++] = ctx.stack[ctx.stackTop - index];\n}\n\n/** MINDEX - Move indexed element to top */\nexport function MINDEX(ctx: ExecContext): void {\n\tconst index = ctx.stack[--ctx.stackTop];\n\tif (index <= 0 || index > ctx.stackTop) {\n\t\tctx.error = `MINDEX: invalid index ${index}`;\n\t\treturn;\n\t}\n\n\tconst val = ctx.stack[ctx.stackTop - index];\n\n\t// Shift elements down\n\tfor (let i = ctx.stackTop - index; i < ctx.stackTop - 1; i++) {\n\t\tctx.stack[i] = ctx.stack[i + 1];\n\t}\n\n\tctx.stack[ctx.stackTop - 1] = val;\n}\n\n/** ROLL - Roll top three elements */\nexport function ROLL(ctx: ExecContext): void {\n\tconst a = ctx.stack[ctx.stackTop - 1];\n\tconst b = ctx.stack[ctx.stackTop - 2];\n\tconst c = ctx.stack[ctx.stackTop - 3];\n\n\tctx.stack[ctx.stackTop - 1] = c;\n\tctx.stack[ctx.stackTop - 2] = a;\n\tctx.stack[ctx.stackTop - 3] = b;\n}\n\n/** Push byte(s) from instruction stream */\nexport function PUSHB(ctx: ExecContext, count: number): void {\n\tfor (let i = 0; i < count; i++) {\n\t\tctx.stack[ctx.stackTop++] = ctx.code[ctx.IP++];\n\t}\n}\n\n/** Push word(s) from instruction stream */\nexport function PUSHW(ctx: ExecContext, count: number): void {\n\tfor (let i = 0; i < count; i++) {\n\t\tconst hi = ctx.code[ctx.IP++];\n\t\tconst lo = ctx.code[ctx.IP++];\n\t\t// Sign extend\n\t\tlet val = (hi << 8) | lo;\n\t\tif (val >= 0x8000) val -= 0x10000;\n\t\tctx.stack[ctx.stackTop++] = val;\n\t}\n}\n\n/** NPUSHB - Push N bytes */\nexport function NPUSHB(ctx: ExecContext): void {\n\tconst n = ctx.code[ctx.IP++];\n\tPUSHB(ctx, n);\n}\n\n/** NPUSHW - Push N words */\nexport function NPUSHW(ctx: ExecContext): void {\n\tconst n = ctx.code[ctx.IP++];\n\tPUSHW(ctx, n);\n}\n",
78
- "/**\n * TrueType Bytecode Interpreter\n *\n * Main dispatch loop for executing TrueType hinting instructions.\n */\n\nimport {\n\tABS,\n\tADD,\n\tAND,\n\tCEILING,\n\tDIV,\n\tEQ,\n\tEVEN,\n\tFLOOR,\n\tGT,\n\tGTEQ,\n\tLT,\n\tLTEQ,\n\tMAX,\n\tMIN,\n\tMUL,\n\tNEG,\n\tNEQ,\n\tNOT,\n\tODD,\n\tOR,\n\tSUB,\n} from \"./instructions/arithmetic.ts\";\nimport {\n\tCALL,\n\tEIF,\n\tELSE,\n\tENDF,\n\tFDEF,\n\tIDEF,\n\tIF,\n\tJMPR,\n\tJROF,\n\tJROT,\n\tLOOPCALL,\n} from \"./instructions/control-flow.ts\";\nimport {\n\tDELTAC1,\n\tDELTAC2,\n\tDELTAC3,\n\tDELTAP1,\n\tDELTAP2,\n\tDELTAP3,\n} from \"./instructions/delta.ts\";\nimport {\n\tFLIPOFF,\n\tFLIPON,\n\tGETINFO,\n\tGFV,\n\tGPV,\n\tINSTCTRL,\n\tRCVT,\n\tRDTG,\n\tROFF,\n\tRS,\n\tRTDG,\n\tRTG,\n\tRTHG,\n\tRUTG,\n\tS45ROUND,\n\tSCANCTRL,\n\tSCANTYPE,\n\tSCVTCI,\n\tSDB,\n\tSDPVTL,\n\tSDS,\n\tSFVFS,\n\tSFVTCA,\n\tSFVTL,\n\tSFVTPV,\n\tSLOOP,\n\tSMD,\n\tSPVFS,\n\tSPVTCA,\n\tSPVTL,\n\tSROUND,\n\tSRP0,\n\tSRP1,\n\tSRP2,\n\tSSW,\n\tSSWCI,\n\tSVTCA,\n\tSZP0,\n\tSZP1,\n\tSZP2,\n\tSZPS,\n\tUTP,\n\tWCVTF,\n\tWCVTP,\n\tWS,\n} from \"./instructions/graphics-state.ts\";\nimport { IUP_X, IUP_Y } from \"./instructions/interpolate.ts\";\n\nimport {\n\tALIGNPTS,\n\tALIGNRP,\n\tFLIPPT,\n\tFLIPRGOFF,\n\tFLIPRGON,\n\tGC,\n\tIP,\n\tISECT,\n\tMD,\n\tMDAP,\n\tMDRP,\n\tMIAP,\n\tMIRP,\n\tMPPEM,\n\tMPS,\n\tMSIRP,\n\tNROUND,\n\tROUND,\n\tSCFS,\n\tSHC,\n\tSHP,\n\tSHPIX,\n\tSHZ,\n} from \"./instructions/points.ts\";\n// Import instruction implementations\nimport {\n\tCINDEX,\n\tCLEAR,\n\tDEPTH,\n\tDUP,\n\tMINDEX,\n\tNPUSHB,\n\tNPUSHW,\n\tPOP,\n\tPUSHB,\n\tPUSHW,\n\tROLL,\n\tSWAP,\n} from \"./instructions/stack.ts\";\nimport { CodeRange, type ExecContext, Opcode } from \"./types.ts\";\n\n/**\n * Execute bytecode from the current instruction pointer\n */\nexport function execute(ctx: ExecContext): void {\n\twhile (ctx.IP < ctx.codeSize && ctx.error === null) {\n\t\t// Check instruction limit\n\t\tif (++ctx.instructionCount > ctx.maxInstructions) {\n\t\t\tctx.error = \"Instruction limit exceeded (possible infinite loop)\";\n\t\t\treturn;\n\t\t}\n\n\t\tconst opcode = ctx.code[ctx.IP++];\n\t\tctx.opcode = opcode;\n\n\t\texecuteOpcode(ctx, opcode);\n\t}\n}\n\n/**\n * Execute a single opcode\n */\nfunction executeOpcode(ctx: ExecContext, opcode: number): void {\n\t// Handle PUSHB[n] (0xB0-0xB7)\n\tif (opcode >= 0xb0 && opcode <= 0xb7) {\n\t\tPUSHB(ctx, opcode - 0xb0 + 1);\n\t\treturn;\n\t}\n\n\t// Handle PUSHW[n] (0xB8-0xBF)\n\tif (opcode >= 0xb8 && opcode <= 0xbf) {\n\t\tPUSHW(ctx, opcode - 0xb8 + 1);\n\t\treturn;\n\t}\n\n\t// Handle MDRP[flags] (0xC0-0xDF)\n\tif (opcode >= 0xc0 && opcode <= 0xdf) {\n\t\tMDRP(ctx, opcode & 0x1f);\n\t\treturn;\n\t}\n\n\t// Handle MIRP[flags] (0xE0-0xFF)\n\tif (opcode >= 0xe0 && opcode <= 0xff) {\n\t\tMIRP(ctx, opcode & 0x1f);\n\t\treturn;\n\t}\n\n\tswitch (opcode) {\n\t\t// Vector setting\n\t\tcase Opcode.SVTCA_Y:\n\t\t\tSVTCA(ctx, 0);\n\t\t\tbreak;\n\t\tcase Opcode.SVTCA_X:\n\t\t\tSVTCA(ctx, 1);\n\t\t\tbreak;\n\t\tcase Opcode.SPVTCA_Y:\n\t\t\tSPVTCA(ctx, 0);\n\t\t\tbreak;\n\t\tcase Opcode.SPVTCA_X:\n\t\t\tSPVTCA(ctx, 1);\n\t\t\tbreak;\n\t\tcase Opcode.SFVTCA_Y:\n\t\t\tSFVTCA(ctx, 0);\n\t\t\tbreak;\n\t\tcase Opcode.SFVTCA_X:\n\t\t\tSFVTCA(ctx, 1);\n\t\t\tbreak;\n\t\tcase Opcode.SPVTL_0:\n\t\t\tSPVTL(ctx, false);\n\t\t\tbreak;\n\t\tcase Opcode.SPVTL_1:\n\t\t\tSPVTL(ctx, true);\n\t\t\tbreak;\n\t\tcase Opcode.SFVTL_0:\n\t\t\tSFVTL(ctx, false);\n\t\t\tbreak;\n\t\tcase Opcode.SFVTL_1:\n\t\t\tSFVTL(ctx, true);\n\t\t\tbreak;\n\t\tcase Opcode.SDPVTL_0:\n\t\t\tSDPVTL(ctx, false);\n\t\t\tbreak;\n\t\tcase Opcode.SDPVTL_1:\n\t\t\tSDPVTL(ctx, true);\n\t\t\tbreak;\n\t\tcase Opcode.SPVFS:\n\t\t\tSPVFS(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.SFVFS:\n\t\t\tSFVFS(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.GPV:\n\t\t\tGPV(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.GFV:\n\t\t\tGFV(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.SFVTPV:\n\t\t\tSFVTPV(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.ISECT:\n\t\t\tISECT(ctx);\n\t\t\tbreak;\n\n\t\t// Reference points\n\t\tcase Opcode.SRP0:\n\t\t\tSRP0(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.SRP1:\n\t\t\tSRP1(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.SRP2:\n\t\t\tSRP2(ctx);\n\t\t\tbreak;\n\n\t\t// Zone pointers\n\t\tcase Opcode.SZP0:\n\t\t\tSZP0(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.SZP1:\n\t\t\tSZP1(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.SZP2:\n\t\t\tSZP2(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.SZPS:\n\t\t\tSZPS(ctx);\n\t\t\tbreak;\n\n\t\t// Loop and other GS\n\t\tcase Opcode.SLOOP:\n\t\t\tSLOOP(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.RTG:\n\t\t\tRTG(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.RTHG:\n\t\t\tRTHG(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.SMD:\n\t\t\tSMD(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.ELSE:\n\t\t\tELSE(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.JMPR:\n\t\t\tJMPR(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.SCVTCI:\n\t\t\tSCVTCI(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.SSWCI:\n\t\t\tSSWCI(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.SSW:\n\t\t\tSSW(ctx);\n\t\t\tbreak;\n\n\t\t// Stack operations\n\t\tcase Opcode.DUP:\n\t\t\tDUP(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.POP:\n\t\t\tPOP(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.CLEAR:\n\t\t\tCLEAR(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.SWAP:\n\t\t\tSWAP(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.DEPTH:\n\t\t\tDEPTH(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.CINDEX:\n\t\t\tCINDEX(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.MINDEX:\n\t\t\tMINDEX(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.ROLL:\n\t\t\tROLL(ctx);\n\t\t\tbreak;\n\n\t\t// Functions\n\t\tcase Opcode.FDEF:\n\t\t\tFDEF(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.ENDF:\n\t\t\tENDF(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.CALL:\n\t\t\tCALL(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.LOOPCALL:\n\t\t\tLOOPCALL(ctx);\n\t\t\tbreak;\n\n\t\t// Point movement\n\t\tcase Opcode.MDAP_0:\n\t\t\tMDAP(ctx, false);\n\t\t\tbreak;\n\t\tcase Opcode.MDAP_1:\n\t\t\tMDAP(ctx, true);\n\t\t\tbreak;\n\t\tcase Opcode.IUP_Y:\n\t\t\tIUP_Y(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.IUP_X:\n\t\t\tIUP_X(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.SHP_0:\n\t\t\tSHP(ctx, false);\n\t\t\tbreak;\n\t\tcase Opcode.SHP_1:\n\t\t\tSHP(ctx, true);\n\t\t\tbreak;\n\t\tcase Opcode.SHC_0:\n\t\t\tSHC(ctx, false);\n\t\t\tbreak;\n\t\tcase Opcode.SHC_1:\n\t\t\tSHC(ctx, true);\n\t\t\tbreak;\n\t\tcase Opcode.SHZ_0:\n\t\t\tSHZ(ctx, false);\n\t\t\tbreak;\n\t\tcase Opcode.SHZ_1:\n\t\t\tSHZ(ctx, true);\n\t\t\tbreak;\n\t\tcase Opcode.SHPIX:\n\t\t\tSHPIX(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.IP:\n\t\t\tIP(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.MSIRP_0:\n\t\t\tMSIRP(ctx, false);\n\t\t\tbreak;\n\t\tcase Opcode.MSIRP_1:\n\t\t\tMSIRP(ctx, true);\n\t\t\tbreak;\n\t\tcase Opcode.ALIGNRP:\n\t\t\tALIGNRP(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.ALIGNPTS:\n\t\t\tALIGNPTS(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.UTP:\n\t\t\tUTP(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.RTDG:\n\t\t\tRTDG(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.MIAP_0:\n\t\t\tMIAP(ctx, false);\n\t\t\tbreak;\n\t\tcase Opcode.MIAP_1:\n\t\t\tMIAP(ctx, true);\n\t\t\tbreak;\n\n\t\t// Push instructions\n\t\tcase Opcode.NPUSHB:\n\t\t\tNPUSHB(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.NPUSHW:\n\t\t\tNPUSHW(ctx);\n\t\t\tbreak;\n\n\t\t// Storage\n\t\tcase Opcode.WS:\n\t\t\tWS(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.RS:\n\t\t\tRS(ctx);\n\t\t\tbreak;\n\n\t\t// CVT\n\t\tcase Opcode.WCVTP:\n\t\t\tWCVTP(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.RCVT:\n\t\t\tRCVT(ctx);\n\t\t\tbreak;\n\n\t\t// Point operations\n\t\tcase Opcode.GC_0:\n\t\t\tGC(ctx, false);\n\t\t\tbreak;\n\t\tcase Opcode.GC_1:\n\t\t\tGC(ctx, true);\n\t\t\tbreak;\n\t\tcase Opcode.SCFS:\n\t\t\tSCFS(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.MD_0:\n\t\t\tMD(ctx, false);\n\t\t\tbreak;\n\t\tcase Opcode.MD_1:\n\t\t\tMD(ctx, true);\n\t\t\tbreak;\n\t\tcase Opcode.MPPEM:\n\t\t\tMPPEM(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.MPS:\n\t\t\tMPS(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.FLIPON:\n\t\t\tFLIPON(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.FLIPOFF:\n\t\t\tFLIPOFF(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.DEBUG:\n\t\t\t// DEBUG is a no-op\n\t\t\tbreak;\n\n\t\t// Comparison\n\t\tcase Opcode.LT:\n\t\t\tLT(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.LTEQ:\n\t\t\tLTEQ(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.GT:\n\t\t\tGT(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.GTEQ:\n\t\t\tGTEQ(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.EQ:\n\t\t\tEQ(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.NEQ:\n\t\t\tNEQ(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.ODD:\n\t\t\tODD(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.EVEN:\n\t\t\tEVEN(ctx);\n\t\t\tbreak;\n\n\t\t// Control flow\n\t\tcase Opcode.IF:\n\t\t\tIF(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.EIF:\n\t\t\tEIF(ctx);\n\t\t\tbreak;\n\n\t\t// Logic\n\t\tcase Opcode.AND:\n\t\t\tAND(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.OR:\n\t\t\tOR(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.NOT:\n\t\t\tNOT(ctx);\n\t\t\tbreak;\n\n\t\t// Delta instructions\n\t\tcase Opcode.DELTAP1:\n\t\t\tDELTAP1(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.SDB:\n\t\t\tSDB(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.SDS:\n\t\t\tSDS(ctx);\n\t\t\tbreak;\n\n\t\t// Arithmetic\n\t\tcase Opcode.ADD:\n\t\t\tADD(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.SUB:\n\t\t\tSUB(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.DIV:\n\t\t\tDIV(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.MUL:\n\t\t\tMUL(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.ABS:\n\t\t\tABS(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.NEG:\n\t\t\tNEG(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.FLOOR:\n\t\t\tFLOOR(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.CEILING:\n\t\t\tCEILING(ctx);\n\t\t\tbreak;\n\n\t\t// Rounding\n\t\tcase Opcode.ROUND_0:\n\t\t\tROUND(ctx, 0);\n\t\t\tbreak;\n\t\tcase Opcode.ROUND_1:\n\t\t\tROUND(ctx, 1);\n\t\t\tbreak;\n\t\tcase Opcode.ROUND_2:\n\t\t\tROUND(ctx, 2);\n\t\t\tbreak;\n\t\tcase Opcode.ROUND_3:\n\t\t\tROUND(ctx, 3);\n\t\t\tbreak;\n\t\tcase Opcode.NROUND_0:\n\t\t\tNROUND(ctx, 0);\n\t\t\tbreak;\n\t\tcase Opcode.NROUND_1:\n\t\t\tNROUND(ctx, 1);\n\t\t\tbreak;\n\t\tcase Opcode.NROUND_2:\n\t\t\tNROUND(ctx, 2);\n\t\t\tbreak;\n\t\tcase Opcode.NROUND_3:\n\t\t\tNROUND(ctx, 3);\n\t\t\tbreak;\n\n\t\t// CVT font units\n\t\tcase Opcode.WCVTF:\n\t\t\tWCVTF(ctx);\n\t\t\tbreak;\n\n\t\t// Delta\n\t\tcase Opcode.DELTAP2:\n\t\t\tDELTAP2(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.DELTAP3:\n\t\t\tDELTAP3(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.DELTAC1:\n\t\t\tDELTAC1(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.DELTAC2:\n\t\t\tDELTAC2(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.DELTAC3:\n\t\t\tDELTAC3(ctx);\n\t\t\tbreak;\n\n\t\t// Super rounding\n\t\tcase Opcode.SROUND:\n\t\t\tSROUND(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.S45ROUND:\n\t\t\tS45ROUND(ctx);\n\t\t\tbreak;\n\n\t\t// Jump\n\t\tcase Opcode.JROT:\n\t\t\tJROT(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.JROF:\n\t\t\tJROF(ctx);\n\t\t\tbreak;\n\n\t\t// Rounding modes\n\t\tcase Opcode.ROFF:\n\t\t\tROFF(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.RUTG:\n\t\t\tRUTG(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.RDTG:\n\t\t\tRDTG(ctx);\n\t\t\tbreak;\n\n\t\t// Other\n\t\tcase Opcode.SANGW:\n\t\t\t// SANGW is deprecated (set angle weight), ignore\n\t\t\tctx.stackTop--;\n\t\t\tbreak;\n\t\tcase Opcode.AA:\n\t\t\t// AA (adjust angle) is deprecated, ignore\n\t\t\tctx.stackTop--;\n\t\t\tbreak;\n\n\t\t// Flip\n\t\tcase Opcode.FLIPPT:\n\t\t\tFLIPPT(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.FLIPRGON:\n\t\t\tFLIPRGON(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.FLIPRGOFF:\n\t\t\tFLIPRGOFF(ctx);\n\t\t\tbreak;\n\n\t\t// Scan\n\t\tcase Opcode.SCANCTRL:\n\t\t\tSCANCTRL(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.SCANTYPE:\n\t\t\tSCANTYPE(ctx);\n\t\t\tbreak;\n\n\t\t// Min/Max\n\t\tcase Opcode.MAX:\n\t\t\tMAX(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.MIN:\n\t\t\tMIN(ctx);\n\t\t\tbreak;\n\n\t\t// Getinfo and instctrl\n\t\tcase Opcode.GETINFO:\n\t\t\tGETINFO(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.IDEF:\n\t\t\tIDEF(ctx);\n\t\t\tbreak;\n\t\tcase Opcode.INSTCTRL:\n\t\t\tINSTCTRL(ctx);\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\t// Check for user-defined instruction\n\t\t\tif (opcode < ctx.maxIDefs && ctx.IDefs[opcode]?.active) {\n\t\t\t\tconst def = ctx.IDefs[opcode];\n\n\t\t\t\tif (ctx.callStackTop >= ctx.maxCallStack) {\n\t\t\t\t\tctx.error = \"IDEF call: call stack overflow\";\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Push call record\n\t\t\t\tconst call = ctx.callStack[ctx.callStackTop++];\n\t\t\t\tcall.callerIP = ctx.IP;\n\t\t\t\tcall.callerRange = ctx.currentRange;\n\t\t\t\tcall.def = {\n\t\t\t\t\tid: opcode,\n\t\t\t\t\tstart: def.start,\n\t\t\t\t\tend: def.end,\n\t\t\t\t\tactive: true,\n\t\t\t\t\trange: def.range,\n\t\t\t\t};\n\t\t\t\tcall.count = 1;\n\n\t\t\t\t// Switch to IDEF's code range\n\t\t\t\tctx.currentRange = def.range;\n\t\t\t\tconst range = ctx.codeRanges.get(ctx.currentRange);\n\t\t\t\tif (range) {\n\t\t\t\t\tctx.code = range.code;\n\t\t\t\t\tctx.codeSize = range.size;\n\t\t\t\t}\n\t\t\t\tctx.IP = def.start;\n\t\t\t} else {\n\t\t\t\tctx.error = `Unknown opcode 0x${opcode.toString(16)}`;\n\t\t\t}\n\t}\n}\n\n/**\n * Set up execution context with code range\n */\nexport function setCodeRange(\n\tctx: ExecContext,\n\trange: CodeRange,\n\tcode: Uint8Array,\n): void {\n\tctx.codeRanges.set(range, { code, size: code.length });\n}\n\n/**\n * Run code in a specific range\n */\nexport function runProgram(ctx: ExecContext, range: CodeRange): void {\n\tconst codeRange = ctx.codeRanges.get(range);\n\tif (!codeRange) {\n\t\treturn;\n\t}\n\n\tctx.currentRange = range;\n\tctx.code = codeRange.code;\n\tctx.codeSize = codeRange.size;\n\tctx.IP = 0;\n\tctx.instructionCount = 0;\n\n\texecute(ctx);\n}\n\n/**\n * Run the font program (fpgm table)\n */\nexport function runFontProgram(ctx: ExecContext): void {\n\trunProgram(ctx, CodeRange.Font);\n}\n\n/**\n * Run the CVT program (prep table)\n */\nexport function runCVTProgram(ctx: ExecContext): void {\n\t// Reset graphics state to default before prep\n\tctx.GS = { ...ctx.defaultGS };\n\trunProgram(ctx, CodeRange.CVT);\n\t// Save modified GS as new default for glyphs\n\tctx.defaultGS = { ...ctx.GS };\n}\n\n/**\n * Run glyph instructions\n */\nexport function runGlyphProgram(\n\tctx: ExecContext,\n\tinstructions: Uint8Array,\n): void {\n\t// Reset graphics state to default\n\tctx.GS = { ...ctx.defaultGS };\n\n\t// Set up glyph zone pointers\n\tctx.zp0 = ctx.pts;\n\tctx.zp1 = ctx.pts;\n\tctx.zp2 = ctx.pts;\n\n\t// Set up glyph code range\n\tsetCodeRange(ctx, CodeRange.Glyph, instructions);\n\trunProgram(ctx, CodeRange.Glyph);\n}\n",
79
- "/**\n * TrueType Hinting Program Execution\n *\n * This module handles the setup and execution of TrueType hinting programs:\n * - fpgm: Font program (executed once when font is loaded)\n * - prep: CVT program (executed when size changes)\n * - glyph: Per-glyph instructions\n */\n\nimport {\n\trunCVTProgram,\n\trunFontProgram,\n\trunGlyphProgram,\n\tsetCodeRange,\n} from \"./interpreter.ts\";\nimport {\n\tCodeRange,\n\tcreateExecContext,\n\tcreateGlyphZone,\n\ttype ExecContext,\n} from \"./types.ts\";\n\n/**\n * Hinting engine for a font\n */\nexport interface HintingEngine {\n\t/** Execution context */\n\tctx: ExecContext;\n\t/** Units per EM from font */\n\tunitsPerEM: number;\n\t/** Has fpgm been executed */\n\tfpgmExecuted: boolean;\n\t/** Current ppem (prep needs re-run if this changes) */\n\tcurrentPpem: number;\n}\n\n/**\n * Create a hinting engine for a font\n */\nexport function createHintingEngine(\n\tunitsPerEM: number,\n\tmaxStack: number = 256,\n\tmaxStorage: number = 64,\n\tmaxFDefs: number = 64,\n\tmaxTwilightPoints: number = 16,\n\tcvtValues?: Int32Array,\n): HintingEngine {\n\tconst ctx = createExecContext(\n\t\tmaxStack,\n\t\tmaxStorage,\n\t\tmaxFDefs,\n\t\tmaxFDefs, // maxIDefs\n\t\t32, // maxCallStack\n\t\tmaxTwilightPoints,\n\t);\n\n\t// Initialize CVT if provided\n\tif (cvtValues) {\n\t\tctx.cvt = new Int32Array(cvtValues);\n\t\tctx.cvtSize = cvtValues.length;\n\t}\n\n\treturn {\n\t\tctx,\n\t\tunitsPerEM,\n\t\tfpgmExecuted: false,\n\t\tcurrentPpem: 0,\n\t};\n}\n\n/**\n * Load font program (fpgm table)\n */\nexport function loadFontProgram(engine: HintingEngine, fpgm: Uint8Array): void {\n\tsetCodeRange(engine.ctx, CodeRange.Font, fpgm);\n}\n\n/**\n * Load CVT program (prep table)\n */\nexport function loadCVTProgram(engine: HintingEngine, prep: Uint8Array): void {\n\tsetCodeRange(engine.ctx, CodeRange.CVT, prep);\n}\n\n/**\n * Execute fpgm (should be called once after font load)\n */\nexport function executeFontProgram(engine: HintingEngine): string | null {\n\tif (engine.fpgmExecuted) return null;\n\n\tengine.ctx.error = null;\n\trunFontProgram(engine.ctx);\n\tengine.fpgmExecuted = true;\n\n\treturn engine.ctx.error;\n}\n\n/**\n * Set up for a specific size and execute prep if needed\n */\nexport function setSize(\n\tengine: HintingEngine,\n\tppem: number,\n\tpointSize: number,\n): string | null {\n\t// Always run fpgm first if not done\n\tif (!engine.fpgmExecuted) {\n\t\tconst fpgmError = executeFontProgram(engine);\n\t\tif (fpgmError) return fpgmError;\n\t}\n\n\t// Skip prep if size hasn't changed\n\tif (engine.currentPpem === ppem) return null;\n\n\t// Calculate scale factor: font units to 26.6 pixels\n\t// scale = ppem / unitsPerEM * 64 (for 26.6 format)\n\tengine.ctx.scale = (ppem * 64) / engine.unitsPerEM;\n\tengine.ctx.ppem = ppem;\n\tengine.ctx.pointSize = pointSize;\n\n\t// Scale CVT values from font units to pixels\n\tscaleCVT(engine.ctx);\n\n\t// Run prep program\n\tengine.ctx.error = null;\n\trunCVTProgram(engine.ctx);\n\tengine.currentPpem = ppem;\n\n\treturn engine.ctx.error;\n}\n\n/**\n * Scale CVT values from font units to 26.6 pixels\n */\nfunction scaleCVT(ctx: ExecContext): void {\n\tfor (let i = 0; i < ctx.cvtSize; i++) {\n\t\tctx.cvt[i] = Math.round(ctx.cvt[i] * ctx.scale);\n\t}\n}\n\n/**\n * Glyph outline for hinting\n */\nexport interface GlyphOutline {\n\t/** X coordinates in font units */\n\txCoords: number[];\n\t/** Y coordinates in font units */\n\tyCoords: number[];\n\t/** Point flags (bit 0 = on-curve) */\n\tflags: Uint8Array;\n\t/** End point indices for each contour */\n\tcontourEnds: number[];\n\t/** Glyph instructions */\n\tinstructions: Uint8Array;\n\t/** Left side bearing in font units (for phantom point) */\n\tlsb?: number;\n\t/** Advance width in font units (for phantom point) */\n\tadvanceWidth?: number;\n\t/** Top side bearing in font units (for vertical phantom point) */\n\ttsb?: number;\n\t/** Advance height in font units (for vertical phantom point) */\n\tadvanceHeight?: number;\n}\n\n/**\n * Hinted glyph result\n */\nexport interface HintedGlyph {\n\t/** Hinted X coordinates in 26.6 pixels */\n\txCoords: number[];\n\t/** Hinted Y coordinates in 26.6 pixels */\n\tyCoords: number[];\n\t/** Point flags */\n\tflags: Uint8Array;\n\t/** Contour end indices */\n\tcontourEnds: number[];\n\t/** Error message if hinting failed */\n\terror: string | null;\n}\n\n/**\n * Hint a glyph\n */\nexport function hintGlyph(\n\tengine: HintingEngine,\n\toutline: GlyphOutline,\n): HintedGlyph {\n\tconst ctx = engine.ctx;\n\tconst nPoints = outline.xCoords.length;\n\tconst nContours = outline.contourEnds.length;\n\n\t// Add phantom points (4 points after glyph points)\n\tconst totalPoints = nPoints + 4;\n\n\t// Set up glyph zone\n\tconst zone = createGlyphZone(totalPoints, nContours);\n\tzone.nPoints = totalPoints;\n\tzone.nContours = nContours;\n\n\t// Scale and copy point coordinates\n\tfor (let i = 0; i < nPoints; i++) {\n\t\tconst x = Math.round(outline.xCoords[i] * ctx.scale);\n\t\tconst y = Math.round(outline.yCoords[i] * ctx.scale);\n\n\t\tzone.org[i].x = x;\n\t\tzone.org[i].y = y;\n\t\tzone.cur[i].x = x;\n\t\tzone.cur[i].y = y;\n\t\tzone.orus[i].x = outline.xCoords[i];\n\t\tzone.orus[i].y = outline.yCoords[i];\n\t\tzone.tags[i] = outline.flags[i];\n\t}\n\n\t// Set up phantom points (for horizontal/vertical metrics)\n\t// Point n: origin (xMin - lsb, 0)\n\t// Point n+1: advance width point (origin.x + advanceWidth, 0)\n\t// Point n+2: top origin (0, yMax + tsb) - for vertical\n\t// Point n+3: bottom point (0, top - advanceHeight) - for vertical\n\n\t// Calculate xMin from outline for phantom point positioning\n\tlet xMin = Infinity;\n\tfor (let i = 0; i < nPoints; i++) {\n\t\tif (outline.xCoords[i] < xMin) xMin = outline.xCoords[i];\n\t}\n\tif (!Number.isFinite(xMin)) xMin = 0;\n\n\tconst lsb = outline.lsb ?? 0;\n\tconst advW = outline.advanceWidth ?? 0;\n\n\t// Phantom point 0: horizontal origin\n\tconst pp0x = Math.round((xMin - lsb) * ctx.scale);\n\tzone.org[nPoints].x = pp0x;\n\tzone.org[nPoints].y = 0;\n\tzone.cur[nPoints].x = pp0x;\n\tzone.cur[nPoints].y = 0;\n\tzone.orus[nPoints].x = xMin - lsb;\n\tzone.orus[nPoints].y = 0;\n\tzone.tags[nPoints] = 0;\n\n\t// Phantom point 1: advance width\n\tconst pp1x = Math.round((xMin - lsb + advW) * ctx.scale);\n\tzone.org[nPoints + 1].x = pp1x;\n\tzone.org[nPoints + 1].y = 0;\n\tzone.cur[nPoints + 1].x = pp1x;\n\tzone.cur[nPoints + 1].y = 0;\n\tzone.orus[nPoints + 1].x = xMin - lsb + advW;\n\tzone.orus[nPoints + 1].y = 0;\n\tzone.tags[nPoints + 1] = 0;\n\n\t// Phantom points 2 & 3: vertical metrics (simplified - set to 0)\n\tfor (let i = nPoints + 2; i < totalPoints; i++) {\n\t\tzone.org[i].x = 0;\n\t\tzone.org[i].y = 0;\n\t\tzone.cur[i].x = 0;\n\t\tzone.cur[i].y = 0;\n\t\tzone.orus[i].x = 0;\n\t\tzone.orus[i].y = 0;\n\t\tzone.tags[i] = 0;\n\t}\n\n\t// Copy contour ends\n\tfor (let i = 0; i < nContours; i++) {\n\t\tzone.contours[i] = outline.contourEnds[i];\n\t}\n\n\t// Set up context\n\tctx.pts = zone;\n\tctx.zp0 = zone;\n\tctx.zp1 = zone;\n\tctx.zp2 = zone;\n\n\t// Reset twilight zone\n\tctx.twilight.nPoints = ctx.twilight.org.length;\n\tfor (let i = 0; i < ctx.twilight.nPoints; i++) {\n\t\tctx.twilight.org[i].x = 0;\n\t\tctx.twilight.org[i].y = 0;\n\t\tctx.twilight.cur[i].x = 0;\n\t\tctx.twilight.cur[i].y = 0;\n\t\tctx.twilight.tags[i] = 0;\n\t}\n\n\t// Run glyph instructions\n\tctx.error = null;\n\tif (outline.instructions.length > 0) {\n\t\trunGlyphProgram(ctx, outline.instructions);\n\t}\n\n\t// Extract results\n\tconst xCoords = new Array<number>(nPoints);\n\tconst yCoords = new Array<number>(nPoints);\n\n\tfor (let i = 0; i < nPoints; i++) {\n\t\txCoords[i] = zone.cur[i]?.x;\n\t\tyCoords[i] = zone.cur[i]?.y;\n\t}\n\n\treturn {\n\t\txCoords,\n\t\tyCoords,\n\t\tflags: outline.flags,\n\t\tcontourEnds: outline.contourEnds,\n\t\terror: ctx.error,\n\t};\n}\n\n/**\n * Convert hinted coordinates from 26.6 to floating point pixels\n */\nexport function hintedToPixels(coords: number[]): number[] {\n\treturn coords.map((c) => c / 64);\n}\n",
80
- "import type { GlyphBuffer } from \"../buffer/glyph-buffer.ts\";\nimport type { Font } from \"../font/font.ts\";\nimport type { Contour, GlyphPoint } from \"../font/tables/glyf.ts\";\nimport type { GlyphId } from \"../types.ts\";\n\n/**\n * Path command types for glyph rendering\n */\nexport type PathCommand =\n\t| { type: \"M\"; x: number; y: number }\n\t| { type: \"L\"; x: number; y: number }\n\t| { type: \"Q\"; x1: number; y1: number; x: number; y: number }\n\t| {\n\t\t\ttype: \"C\";\n\t\t\tx1: number;\n\t\t\ty1: number;\n\t\t\tx2: number;\n\t\t\ty2: number;\n\t\t\tx: number;\n\t\t\ty: number;\n\t }\n\t| { type: \"Z\" };\n\n/**\n * Outline flags (like FreeType's FT_OUTLINE_* flags)\n */\nexport enum OutlineFlags {\n\t/** No flags */\n\tNone = 0,\n\t/** Use even-odd fill rule instead of non-zero winding */\n\tEvenOddFill = 1 << 0,\n\t/** Outline has been hinted */\n\tHighPrecision = 1 << 1,\n\t/** Outline is a single stroke (not filled) */\n\tSinglePass = 1 << 2,\n}\n\n/**\n * A glyph path is a series of drawing commands\n */\nexport interface GlyphPath {\n\tcommands: PathCommand[];\n\tbounds: { xMin: number; yMin: number; xMax: number; yMax: number } | null;\n\t/** Outline flags (like FreeType's FT_OUTLINE_* flags) */\n\tflags?: OutlineFlags;\n}\n\n/**\n * Convert contours to path commands\n * Handles both TrueType (quadratic Béziers) and CFF (cubic Béziers)\n */\nexport function contourToPath(contour: Contour): PathCommand[] {\n\tif (contour.length === 0) return [];\n\n\tconst _commands: PathCommand[] = [];\n\n\t// Check if this contour uses cubic beziers (CFF font)\n\tconst hasCubic = contour.some((p) => p.cubic);\n\n\tif (hasCubic) {\n\t\t// CFF-style contour with cubic beziers\n\t\treturn contourToPathCubic(contour);\n\t}\n\n\t// TrueType-style contour with quadratic beziers\n\treturn contourToPathQuadratic(contour);\n}\n\n/**\n * Convert CFF contour (cubic beziers) to path commands\n */\nfunction contourToPathCubic(contour: Contour): PathCommand[] {\n\tif (contour.length === 0) return [];\n\n\tconst commands: PathCommand[] = [];\n\tlet i = 0;\n\n\t// First point should be on-curve (moveto)\n\tconst first = contour[0];\n\tif (!first) return [];\n\n\tcommands.push({ type: \"M\", x: first.x, y: first.y });\n\ti = 1;\n\n\twhile (i < contour.length) {\n\t\tconst point = contour[i];\n\t\tif (!point) break;\n\n\t\tif (point.onCurve) {\n\t\t\t// Line to\n\t\t\tcommands.push({ type: \"L\", x: point.x, y: point.y });\n\t\t\ti++;\n\t\t} else if (point.cubic) {\n\t\t\t// Cubic bezier: expect cp1, cp2, endpoint\n\t\t\tconst cp1 = point;\n\t\t\tconst cp2 = contour[i + 1];\n\t\t\tconst end = contour[i + 2];\n\n\t\t\tif (!cp2 || !end) {\n\t\t\t\t// Malformed, skip\n\t\t\t\ti++;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tcommands.push({\n\t\t\t\ttype: \"C\",\n\t\t\t\tx1: cp1.x,\n\t\t\t\ty1: cp1.y,\n\t\t\t\tx2: cp2.x,\n\t\t\t\ty2: cp2.y,\n\t\t\t\tx: end.x,\n\t\t\t\ty: end.y,\n\t\t\t});\n\t\t\ti += 3;\n\t\t} else {\n\t\t\t// Quadratic bezier (shouldn't happen in CFF but handle anyway)\n\t\t\tconst cp = point;\n\t\t\tconst next = contour[i + 1];\n\t\t\tif (!next) {\n\t\t\t\ti++;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tlet endPoint: GlyphPoint;\n\t\t\tif (next.onCurve) {\n\t\t\t\tendPoint = next;\n\t\t\t\ti += 2;\n\t\t\t} else {\n\t\t\t\tendPoint = {\n\t\t\t\t\tx: (cp.x + next.x) / 2,\n\t\t\t\t\ty: (cp.y + next.y) / 2,\n\t\t\t\t\tonCurve: true,\n\t\t\t\t};\n\t\t\t\ti++;\n\t\t\t}\n\n\t\t\tcommands.push({\n\t\t\t\ttype: \"Q\",\n\t\t\t\tx1: cp.x,\n\t\t\t\ty1: cp.y,\n\t\t\t\tx: endPoint.x,\n\t\t\t\ty: endPoint.y,\n\t\t\t});\n\t\t}\n\t}\n\n\tcommands.push({ type: \"Z\" });\n\treturn commands;\n}\n\n/**\n * Convert TrueType contour (quadratic beziers) to path commands\n */\nfunction contourToPathQuadratic(contour: Contour): PathCommand[] {\n\tif (contour.length === 0) return [];\n\n\tconst commands: PathCommand[] = [];\n\n\t// Find the first on-curve point to start\n\tlet startIndex = 0;\n\tfor (const [i, point] of contour.entries()) {\n\t\tif (point.onCurve) {\n\t\t\tstartIndex = i;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// If all points are off-curve, calculate implied on-curve point\n\tconst allOffCurve = contour.every((p) => !p.onCurve);\n\tlet startPoint: GlyphPoint;\n\n\tif (allOffCurve) {\n\t\t// Start at midpoint between first and last off-curve points\n\t\tconst first = contour[0];\n\t\tconst last = contour[contour.length - 1];\n\t\tif (!first || !last) return [];\n\t\tstartPoint = {\n\t\t\tx: (first.x + last.x) / 2,\n\t\t\ty: (first.y + last.y) / 2,\n\t\t\tonCurve: true,\n\t\t};\n\t\tstartIndex = 0;\n\t} else {\n\t\tconst point = contour[startIndex];\n\t\tif (!point) return [];\n\t\tstartPoint = point;\n\t}\n\n\tcommands.push({ type: \"M\", x: startPoint.x, y: startPoint.y });\n\n\tconst n = contour.length;\n\tlet i = allOffCurve ? 0 : (startIndex + 1) % n;\n\tlet current = startPoint;\n\tlet iterations = 0;\n\n\twhile (iterations < n) {\n\t\tconst point = contour[i];\n\t\tif (!point) break;\n\n\t\tif (point.onCurve) {\n\t\t\t// Line to on-curve point\n\t\t\tcommands.push({ type: \"L\", x: point.x, y: point.y });\n\t\t\tcurrent = point;\n\t\t} else {\n\t\t\t// Off-curve point - need to find the end point\n\t\t\tconst nextIndex = (i + 1) % n;\n\t\t\tconst nextPoint = contour[nextIndex];\n\t\t\tif (!nextPoint) break;\n\n\t\t\tlet endPoint: GlyphPoint;\n\t\t\tif (nextPoint.onCurve) {\n\t\t\t\t// Next point is on-curve, use it directly\n\t\t\t\tendPoint = nextPoint;\n\t\t\t\ti = nextIndex;\n\t\t\t\titerations++;\n\t\t\t} else {\n\t\t\t\t// Next point is also off-curve, calculate implied on-curve point\n\t\t\t\tendPoint = {\n\t\t\t\t\tx: (point.x + nextPoint.x) / 2,\n\t\t\t\t\ty: (point.y + nextPoint.y) / 2,\n\t\t\t\t\tonCurve: true,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Quadratic Bézier curve\n\t\t\tcommands.push({\n\t\t\t\ttype: \"Q\",\n\t\t\t\tx1: point.x,\n\t\t\t\ty1: point.y,\n\t\t\t\tx: endPoint.x,\n\t\t\t\ty: endPoint.y,\n\t\t\t});\n\t\t\tcurrent = endPoint;\n\t\t}\n\n\t\ti = (i + 1) % n;\n\t\titerations++;\n\n\t\t// Check if we've returned to start\n\t\tif (current.x === startPoint.x && current.y === startPoint.y) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Close the path\n\tcommands.push({ type: \"Z\" });\n\n\treturn commands;\n}\n\n/**\n * Get path commands for a glyph\n */\nexport function getGlyphPath(font: Font, glyphId: GlyphId): GlyphPath | null {\n\tconst contours = font.getGlyphContours(glyphId);\n\tif (!contours) return null;\n\n\tconst commands: PathCommand[] = [];\n\tfor (const contour of contours) {\n\t\tcommands.push(...contourToPath(contour));\n\t}\n\n\tconst bounds = font.getGlyphBounds(glyphId);\n\n\treturn { commands, bounds };\n}\n\n/**\n * Convert path commands to SVG path data string\n */\nexport function pathToSVG(\n\tpath: GlyphPath,\n\toptions?: { flipY?: boolean; scale?: number },\n): string {\n\tconst scale = options?.scale ?? 1;\n\tconst flipY = options?.flipY ?? true;\n\n\tconst parts: string[] = [];\n\n\tfor (const cmd of path.commands) {\n\t\tswitch (cmd.type) {\n\t\t\tcase \"M\":\n\t\t\t\tparts.push(\n\t\t\t\t\t`M ${cmd.x * scale} ${flipY ? -cmd.y * scale : cmd.y * scale}`,\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tcase \"L\":\n\t\t\t\tparts.push(\n\t\t\t\t\t`L ${cmd.x * scale} ${flipY ? -cmd.y * scale : cmd.y * scale}`,\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tcase \"Q\":\n\t\t\t\tparts.push(\n\t\t\t\t\t`Q ${cmd.x1 * scale} ${flipY ? -cmd.y1 * scale : cmd.y1 * scale} ${cmd.x * scale} ${flipY ? -cmd.y * scale : cmd.y * scale}`,\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tcase \"C\":\n\t\t\t\tparts.push(\n\t\t\t\t\t`C ${cmd.x1 * scale} ${flipY ? -cmd.y1 * scale : cmd.y1 * scale} ${cmd.x2 * scale} ${flipY ? -cmd.y2 * scale : cmd.y2 * scale} ${cmd.x * scale} ${flipY ? -cmd.y * scale : cmd.y * scale}`,\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tcase \"Z\":\n\t\t\t\tparts.push(\"Z\");\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn parts.join(\" \");\n}\n\n/**\n * Render options for stroke/fill\n */\nexport interface RenderOptions {\n\tflipY?: boolean;\n\tscale?: number;\n\toffsetX?: number;\n\toffsetY?: number;\n\tfill?: string;\n\tstroke?: string;\n\tstrokeWidth?: number;\n\tlineCap?: CanvasLineCap;\n\tlineJoin?: CanvasLineJoin;\n\tmiterLimit?: number;\n}\n\n/**\n * Render path commands to a Canvas 2D context\n */\nexport function pathToCanvas(\n\tctx: CanvasRenderingContext2D | Path2D,\n\tpath: GlyphPath,\n\toptions?: {\n\t\tflipY?: boolean;\n\t\tscale?: number;\n\t\toffsetX?: number;\n\t\toffsetY?: number;\n\t},\n): void {\n\tconst scale = options?.scale ?? 1;\n\tconst flipY = options?.flipY ?? true;\n\tconst offsetX = options?.offsetX ?? 0;\n\tconst offsetY = options?.offsetY ?? 0;\n\n\tfor (const cmd of path.commands) {\n\t\tswitch (cmd.type) {\n\t\t\tcase \"M\":\n\t\t\t\tctx.moveTo(\n\t\t\t\t\tcmd.x * scale + offsetX,\n\t\t\t\t\t(flipY ? -cmd.y : cmd.y) * scale + offsetY,\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tcase \"L\":\n\t\t\t\tctx.lineTo(\n\t\t\t\t\tcmd.x * scale + offsetX,\n\t\t\t\t\t(flipY ? -cmd.y : cmd.y) * scale + offsetY,\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tcase \"Q\":\n\t\t\t\tctx.quadraticCurveTo(\n\t\t\t\t\tcmd.x1 * scale + offsetX,\n\t\t\t\t\t(flipY ? -cmd.y1 : cmd.y1) * scale + offsetY,\n\t\t\t\t\tcmd.x * scale + offsetX,\n\t\t\t\t\t(flipY ? -cmd.y : cmd.y) * scale + offsetY,\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tcase \"C\":\n\t\t\t\tctx.bezierCurveTo(\n\t\t\t\t\tcmd.x1 * scale + offsetX,\n\t\t\t\t\t(flipY ? -cmd.y1 : cmd.y1) * scale + offsetY,\n\t\t\t\t\tcmd.x2 * scale + offsetX,\n\t\t\t\t\t(flipY ? -cmd.y2 : cmd.y2) * scale + offsetY,\n\t\t\t\t\tcmd.x * scale + offsetX,\n\t\t\t\t\t(flipY ? -cmd.y : cmd.y) * scale + offsetY,\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tcase \"Z\":\n\t\t\t\tctx.closePath();\n\t\t\t\tbreak;\n\t\t}\n\t}\n}\n\n/**\n * Generate an SVG element for a glyph\n */\nexport function glyphToSVG(\n\tfont: Font,\n\tglyphId: GlyphId,\n\toptions?: {\n\t\tfontSize?: number;\n\t\tfill?: string;\n\t\tstroke?: string;\n\t\tstrokeWidth?: number;\n\t},\n): string | null {\n\tconst path = getGlyphPath(font, glyphId);\n\tif (!path) return null;\n\n\tconst fontSize = options?.fontSize ?? 100;\n\tconst fill = options?.fill ?? \"currentColor\";\n\tconst stroke = options?.stroke;\n\tconst strokeWidth = options?.strokeWidth ?? 1;\n\tconst scale = fontSize / font.unitsPerEm;\n\n\tconst bounds = path.bounds;\n\tif (!bounds) return null;\n\n\t// Add stroke width to bounds for proper sizing\n\tconst strokePadding = stroke ? strokeWidth / 2 : 0;\n\tconst width = Math.ceil(\n\t\t(bounds.xMax - bounds.xMin) * scale + strokePadding * 2,\n\t);\n\tconst height = Math.ceil(\n\t\t(bounds.yMax - bounds.yMin) * scale + strokePadding * 2,\n\t);\n\tconst viewBox = `${bounds.xMin - strokePadding} ${-bounds.yMax - strokePadding} ${bounds.xMax - bounds.xMin + strokePadding * 2} ${bounds.yMax - bounds.yMin + strokePadding * 2}`;\n\n\tconst pathData = pathToSVG(path, { flipY: true, scale: 1 });\n\n\tconst strokeAttr = stroke\n\t\t? ` stroke=\"${stroke}\" stroke-width=\"${strokeWidth}\"`\n\t\t: \"\";\n\n\treturn `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${width}\" height=\"${height}\" viewBox=\"${viewBox}\">\n <path d=\"${pathData}\" fill=\"${fill}\"${strokeAttr}/>\n</svg>`;\n}\n\n/**\n * Render shaped text to Canvas\n */\nexport interface ShapedGlyph {\n\tglyphId: GlyphId;\n\txOffset: number;\n\tyOffset: number;\n\txAdvance: number;\n\tyAdvance: number;\n}\n\nexport function renderShapedText(\n\tctx: CanvasRenderingContext2D,\n\tfont: Font,\n\tglyphs: ShapedGlyph[],\n\toptions?: {\n\t\tfontSize?: number;\n\t\tx?: number;\n\t\ty?: number;\n\t\tfill?: string;\n\t\tstroke?: string;\n\t\tstrokeWidth?: number;\n\t\tlineCap?: CanvasLineCap;\n\t\tlineJoin?: CanvasLineJoin;\n\t},\n): void {\n\tconst fontSize = options?.fontSize ?? 16;\n\tconst startX = options?.x ?? 0;\n\tconst startY = options?.y ?? 0;\n\tconst fill = options?.fill ?? \"black\";\n\tconst stroke = options?.stroke;\n\tconst strokeWidth = options?.strokeWidth ?? 1;\n\n\tconst scale = fontSize / font.unitsPerEm;\n\n\tctx.fillStyle = fill;\n\tif (stroke) {\n\t\tctx.strokeStyle = stroke;\n\t\tctx.lineWidth = strokeWidth * scale;\n\t\tif (options?.lineCap) ctx.lineCap = options.lineCap;\n\t\tif (options?.lineJoin) ctx.lineJoin = options.lineJoin;\n\t}\n\n\tlet x = startX;\n\tlet y = startY;\n\n\tfor (const glyph of glyphs) {\n\t\tconst path = getGlyphPath(font, glyph.glyphId);\n\t\tif (path) {\n\t\t\tctx.beginPath();\n\t\t\tpathToCanvas(ctx, path, {\n\t\t\t\tscale,\n\t\t\t\tflipY: true,\n\t\t\t\toffsetX: x + glyph.xOffset * scale,\n\t\t\t\toffsetY: y - glyph.yOffset * scale,\n\t\t\t});\n\t\t\tif (fill !== \"none\") ctx.fill();\n\t\t\tif (stroke) ctx.stroke();\n\t\t}\n\n\t\tx += glyph.xAdvance * scale;\n\t\ty += glyph.yAdvance * scale;\n\t}\n}\n\n/**\n * Generate SVG for shaped text\n */\nexport function shapedTextToSVG(\n\tfont: Font,\n\tglyphs: ShapedGlyph[],\n\toptions?: {\n\t\tfontSize?: number;\n\t\tfill?: string;\n\t\tstroke?: string;\n\t\tstrokeWidth?: number;\n\t\tlineCap?: \"butt\" | \"round\" | \"square\";\n\t\tlineJoin?: \"miter\" | \"round\" | \"bevel\";\n\t},\n): string {\n\tconst fontSize = options?.fontSize ?? 100;\n\tconst fill = options?.fill ?? \"currentColor\";\n\tconst stroke = options?.stroke;\n\tconst strokeWidth = options?.strokeWidth ?? 1;\n\tconst scale = fontSize / font.unitsPerEm;\n\n\tconst paths: string[] = [];\n\tlet x = 0;\n\tlet y = 0;\n\tlet minX = Infinity;\n\tlet maxX = -Infinity;\n\tlet minY = Infinity;\n\tlet maxY = -Infinity;\n\n\tfor (const glyph of glyphs) {\n\t\tconst path = getGlyphPath(font, glyph.glyphId);\n\t\tif (path?.bounds) {\n\t\t\tconst offsetX = x + glyph.xOffset * scale;\n\t\t\tconst offsetY = y - glyph.yOffset * scale;\n\n\t\t\t// Transform commands with offset\n\t\t\tconst transformedCommands = path.commands.map((cmd): PathCommand => {\n\t\t\t\tswitch (cmd.type) {\n\t\t\t\t\tcase \"M\":\n\t\t\t\t\tcase \"L\":\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\ttype: cmd.type,\n\t\t\t\t\t\t\tx: cmd.x * scale + offsetX,\n\t\t\t\t\t\t\ty: -cmd.y * scale + offsetY,\n\t\t\t\t\t\t};\n\t\t\t\t\tcase \"Q\":\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\ttype: \"Q\",\n\t\t\t\t\t\t\tx1: cmd.x1 * scale + offsetX,\n\t\t\t\t\t\t\ty1: -cmd.y1 * scale + offsetY,\n\t\t\t\t\t\t\tx: cmd.x * scale + offsetX,\n\t\t\t\t\t\t\ty: -cmd.y * scale + offsetY,\n\t\t\t\t\t\t};\n\t\t\t\t\tcase \"C\":\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\ttype: \"C\",\n\t\t\t\t\t\t\tx1: cmd.x1 * scale + offsetX,\n\t\t\t\t\t\t\ty1: -cmd.y1 * scale + offsetY,\n\t\t\t\t\t\t\tx2: cmd.x2 * scale + offsetX,\n\t\t\t\t\t\t\ty2: -cmd.y2 * scale + offsetY,\n\t\t\t\t\t\t\tx: cmd.x * scale + offsetX,\n\t\t\t\t\t\t\ty: -cmd.y * scale + offsetY,\n\t\t\t\t\t\t};\n\t\t\t\t\tcase \"Z\":\n\t\t\t\t\t\treturn { type: \"Z\" };\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn cmd;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tconst pathStr = pathToSVG(\n\t\t\t\t{ commands: transformedCommands, bounds: null },\n\t\t\t\t{ flipY: false, scale: 1 },\n\t\t\t);\n\t\t\tpaths.push(pathStr);\n\n\t\t\t// Update bounds\n\t\t\tconst b = path.bounds;\n\t\t\tminX = Math.min(minX, offsetX + b.xMin * scale);\n\t\t\tmaxX = Math.max(maxX, offsetX + b.xMax * scale);\n\t\t\tminY = Math.min(minY, offsetY - b.yMax * scale);\n\t\t\tmaxY = Math.max(maxY, offsetY - b.yMin * scale);\n\t\t}\n\n\t\tx += glyph.xAdvance * scale;\n\t\ty += glyph.yAdvance * scale;\n\t}\n\n\tif (paths.length === 0) {\n\t\treturn '<svg xmlns=\"http://www.w3.org/2000/svg\"></svg>';\n\t}\n\n\t// Add stroke padding to bounds\n\tconst strokePadding = stroke ? strokeWidth / 2 : 0;\n\tconst width = Math.ceil(maxX - minX + strokePadding * 2);\n\tconst height = Math.ceil(maxY - minY + strokePadding * 2);\n\tconst viewBox = `${Math.floor(minX - strokePadding)} ${Math.floor(minY - strokePadding)} ${width} ${height}`;\n\n\tconst strokeAttr = stroke\n\t\t? ` stroke=\"${stroke}\" stroke-width=\"${strokeWidth}\"${options?.lineCap ? ` stroke-linecap=\"${options.lineCap}\"` : \"\"}${options?.lineJoin ? ` stroke-linejoin=\"${options.lineJoin}\"` : \"\"}`\n\t\t: \"\";\n\n\treturn `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${width}\" height=\"${height}\" viewBox=\"${viewBox}\">\n <path d=\"${paths.join(\" \")}\" fill=\"${fill}\"${strokeAttr}/>\n</svg>`;\n}\n\n/**\n * Convert GlyphBuffer output to ShapedGlyph array\n */\nexport function glyphBufferToShapedGlyphs(buffer: GlyphBuffer): ShapedGlyph[] {\n\tconst result: ShapedGlyph[] = [];\n\tfor (const [i, info] of buffer.infos.entries()) {\n\t\tconst pos = buffer.positions[i];\n\t\tif (!pos) continue;\n\t\tresult.push({\n\t\t\tglyphId: info.glyphId,\n\t\t\txOffset: pos.xOffset,\n\t\t\tyOffset: pos.yOffset,\n\t\t\txAdvance: pos.xAdvance,\n\t\t\tyAdvance: pos.yAdvance,\n\t\t});\n\t}\n\treturn result;\n}\n\n/**\n * Get glyph path with variable font variation applied\n */\nexport function getGlyphPathWithVariation(\n\tfont: Font,\n\tglyphId: GlyphId,\n\taxisCoords: number[],\n): GlyphPath | null {\n\tconst contours = font.getGlyphContoursWithVariation(glyphId, axisCoords);\n\tif (!contours) return null;\n\n\tconst commands: PathCommand[] = [];\n\tfor (const contour of contours) {\n\t\tcommands.push(...contourToPath(contour));\n\t}\n\n\tconst bounds = font.getGlyphBounds(glyphId);\n\n\treturn { commands, bounds };\n}\n\n/**\n * Render shaped text with variable font support\n */\nexport function renderShapedTextWithVariation(\n\tctx: CanvasRenderingContext2D,\n\tfont: Font,\n\tglyphs: ShapedGlyph[],\n\taxisCoords: number[],\n\toptions?: {\n\t\tfontSize?: number;\n\t\tx?: number;\n\t\ty?: number;\n\t\tfill?: string;\n\t\tstroke?: string;\n\t\tstrokeWidth?: number;\n\t\tlineCap?: CanvasLineCap;\n\t\tlineJoin?: CanvasLineJoin;\n\t},\n): void {\n\tconst fontSize = options?.fontSize ?? 16;\n\tconst startX = options?.x ?? 0;\n\tconst startY = options?.y ?? 0;\n\tconst fill = options?.fill ?? \"black\";\n\tconst stroke = options?.stroke;\n\tconst strokeWidth = options?.strokeWidth ?? 1;\n\n\tconst scale = fontSize / font.unitsPerEm;\n\n\tctx.fillStyle = fill;\n\tif (stroke) {\n\t\tctx.strokeStyle = stroke;\n\t\tctx.lineWidth = strokeWidth * scale;\n\t\tif (options?.lineCap) ctx.lineCap = options.lineCap;\n\t\tif (options?.lineJoin) ctx.lineJoin = options.lineJoin;\n\t}\n\n\tlet x = startX;\n\tlet y = startY;\n\n\tfor (const glyph of glyphs) {\n\t\tconst path = getGlyphPathWithVariation(font, glyph.glyphId, axisCoords);\n\t\tif (path) {\n\t\t\tctx.beginPath();\n\t\t\tpathToCanvas(ctx, path, {\n\t\t\t\tscale,\n\t\t\t\tflipY: true,\n\t\t\t\toffsetX: x + glyph.xOffset * scale,\n\t\t\t\toffsetY: y - glyph.yOffset * scale,\n\t\t\t});\n\t\t\tif (fill !== \"none\") ctx.fill();\n\t\t\tif (stroke) ctx.stroke();\n\t\t}\n\n\t\tx += glyph.xAdvance * scale;\n\t\ty += glyph.yAdvance * scale;\n\t}\n}\n\n/**\n * Generate SVG for shaped text with variable font support\n */\nexport function shapedTextToSVGWithVariation(\n\tfont: Font,\n\tglyphs: ShapedGlyph[],\n\taxisCoords: number[],\n\toptions?: {\n\t\tfontSize?: number;\n\t\tfill?: string;\n\t\tstroke?: string;\n\t\tstrokeWidth?: number;\n\t\tlineCap?: \"butt\" | \"round\" | \"square\";\n\t\tlineJoin?: \"miter\" | \"round\" | \"bevel\";\n\t},\n): string {\n\tconst fontSize = options?.fontSize ?? 100;\n\tconst fill = options?.fill ?? \"currentColor\";\n\tconst stroke = options?.stroke;\n\tconst strokeWidth = options?.strokeWidth ?? 1;\n\tconst scale = fontSize / font.unitsPerEm;\n\n\tconst paths: string[] = [];\n\tlet x = 0;\n\tlet y = 0;\n\tlet minX = Infinity;\n\tlet maxX = -Infinity;\n\tlet minY = Infinity;\n\tlet maxY = -Infinity;\n\n\tfor (const glyph of glyphs) {\n\t\tconst path = getGlyphPathWithVariation(font, glyph.glyphId, axisCoords);\n\t\tif (path?.bounds) {\n\t\t\tconst offsetX = x + glyph.xOffset * scale;\n\t\t\tconst offsetY = y - glyph.yOffset * scale;\n\n\t\t\tconst transformedCommands = path.commands.map((cmd): PathCommand => {\n\t\t\t\tswitch (cmd.type) {\n\t\t\t\t\tcase \"M\":\n\t\t\t\t\tcase \"L\":\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\ttype: cmd.type,\n\t\t\t\t\t\t\tx: cmd.x * scale + offsetX,\n\t\t\t\t\t\t\ty: -cmd.y * scale + offsetY,\n\t\t\t\t\t\t};\n\t\t\t\t\tcase \"Q\":\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\ttype: \"Q\",\n\t\t\t\t\t\t\tx1: cmd.x1 * scale + offsetX,\n\t\t\t\t\t\t\ty1: -cmd.y1 * scale + offsetY,\n\t\t\t\t\t\t\tx: cmd.x * scale + offsetX,\n\t\t\t\t\t\t\ty: -cmd.y * scale + offsetY,\n\t\t\t\t\t\t};\n\t\t\t\t\tcase \"C\":\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\ttype: \"C\",\n\t\t\t\t\t\t\tx1: cmd.x1 * scale + offsetX,\n\t\t\t\t\t\t\ty1: -cmd.y1 * scale + offsetY,\n\t\t\t\t\t\t\tx2: cmd.x2 * scale + offsetX,\n\t\t\t\t\t\t\ty2: -cmd.y2 * scale + offsetY,\n\t\t\t\t\t\t\tx: cmd.x * scale + offsetX,\n\t\t\t\t\t\t\ty: -cmd.y * scale + offsetY,\n\t\t\t\t\t\t};\n\t\t\t\t\tcase \"Z\":\n\t\t\t\t\t\treturn { type: \"Z\" };\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn cmd;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tconst pathStr = pathToSVG(\n\t\t\t\t{ commands: transformedCommands, bounds: null },\n\t\t\t\t{ flipY: false, scale: 1 },\n\t\t\t);\n\t\t\tpaths.push(pathStr);\n\n\t\t\tconst b = path.bounds;\n\t\t\tminX = Math.min(minX, offsetX + b.xMin * scale);\n\t\t\tmaxX = Math.max(maxX, offsetX + b.xMax * scale);\n\t\t\tminY = Math.min(minY, offsetY - b.yMax * scale);\n\t\t\tmaxY = Math.max(maxY, offsetY - b.yMin * scale);\n\t\t}\n\n\t\tx += glyph.xAdvance * scale;\n\t\ty += glyph.yAdvance * scale;\n\t}\n\n\tif (paths.length === 0) {\n\t\treturn '<svg xmlns=\"http://www.w3.org/2000/svg\"></svg>';\n\t}\n\n\t// Add stroke padding to bounds\n\tconst strokePadding = stroke ? strokeWidth / 2 : 0;\n\tconst width = Math.ceil(maxX - minX + strokePadding * 2);\n\tconst height = Math.ceil(maxY - minY + strokePadding * 2);\n\tconst viewBox = `${Math.floor(minX - strokePadding)} ${Math.floor(minY - strokePadding)} ${width} ${height}`;\n\n\tconst strokeAttr = stroke\n\t\t? ` stroke=\"${stroke}\" stroke-width=\"${strokeWidth}\"${options?.lineCap ? ` stroke-linecap=\"${options.lineCap}\"` : \"\"}${options?.lineJoin ? ` stroke-linejoin=\"${options.lineJoin}\"` : \"\"}`\n\t\t: \"\";\n\n\treturn `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${width}\" height=\"${height}\" viewBox=\"${viewBox}\">\n <path d=\"${paths.join(\" \")}\" fill=\"${fill}\"${strokeAttr}/>\n</svg>`;\n}\n\n/**\n * Calculate the total advance width of shaped text\n */\nexport function getTextWidth(\n\tglyphs: ShapedGlyph[],\n\tfont: Font,\n\tfontSize: number,\n): number {\n\tconst scale = fontSize / font.unitsPerEm;\n\tlet width = 0;\n\tfor (const glyph of glyphs) {\n\t\twidth += glyph.xAdvance;\n\t}\n\treturn width * scale;\n}\n\n/**\n * Create a Path2D object from glyph path\n */\nexport function createPath2D(\n\tpath: GlyphPath,\n\toptions?: {\n\t\tflipY?: boolean;\n\t\tscale?: number;\n\t\toffsetX?: number;\n\t\toffsetY?: number;\n\t},\n): Path2D {\n\tconst p = new Path2D();\n\tpathToCanvas(p, path, options);\n\treturn p;\n}\n",
81
- "/**\n * Fixed-point arithmetic utilities for rasterization\n *\n * FreeType uses several fixed-point formats:\n * - F26Dot6: 26.6 format (64 units per pixel) for coordinates\n * - F16Dot16: 16.16 format for high-precision calculations\n * - F2Dot14: 2.14 format for normalized vectors\n */\n\n// Bit shifts for fixed-point formats\nexport const PIXEL_BITS = 8; // Subpixel precision (256 levels per pixel)\nexport const ONE_PIXEL = 1 << PIXEL_BITS; // 256\nexport const PIXEL_MASK = ONE_PIXEL - 1; // 0xFF\n\n// 26.6 fixed-point (FreeType's standard format)\nexport const F26DOT6_SHIFT = 6;\nexport const F26DOT6_ONE = 1 << F26DOT6_SHIFT; // 64\n\n// 16.16 fixed-point\nexport const F16DOT16_SHIFT = 16;\nexport const F16DOT16_ONE = 1 << F16DOT16_SHIFT; // 65536\n\n/**\n * Convert float to 26.6 fixed-point\n */\nexport function floatToF26Dot6(x: number): number {\n\treturn Math.round(x * F26DOT6_ONE);\n}\n\n/**\n * Convert 26.6 fixed-point to float\n */\nexport function f26Dot6ToFloat(x: number): number {\n\treturn x / F26DOT6_ONE;\n}\n\n/**\n * Convert float to internal raster coordinates (PIXEL_BITS precision)\n * Input is in font units, output has 256 subpixel levels per pixel\n */\nexport function floatToPixel(x: number, scale: number): number {\n\treturn Math.round(x * scale * ONE_PIXEL);\n}\n\n/**\n * Truncate to pixel (floor for positive, ceil for negative)\n */\nexport function truncPixel(x: number): number {\n\treturn x >> PIXEL_BITS;\n}\n\n/**\n * Get fractional part (0 to ONE_PIXEL-1)\n */\nexport function fracPixel(x: number): number {\n\treturn x & PIXEL_MASK;\n}\n\n/**\n * Round to nearest pixel\n */\nexport function roundPixel(x: number): number {\n\treturn (x + (ONE_PIXEL >> 1)) >> PIXEL_BITS;\n}\n\n/**\n * Floor to pixel boundary\n */\nexport function floorPixel(x: number): number {\n\treturn x & ~PIXEL_MASK;\n}\n\n/**\n * Ceiling to pixel boundary\n */\nexport function ceilPixel(x: number): number {\n\treturn (x + PIXEL_MASK) & ~PIXEL_MASK;\n}\n\n/**\n * Upscale from 26.6 to internal PIXEL_BITS format\n * PIXEL_BITS=8 means 2 extra bits of precision vs 26.6\n */\nexport function upscale(x: number): number {\n\treturn x << (PIXEL_BITS - F26DOT6_SHIFT);\n}\n\n/**\n * Downscale from internal format to 26.6\n */\nexport function downscale(x: number): number {\n\treturn x >> (PIXEL_BITS - F26DOT6_SHIFT);\n}\n\n/**\n * Multiply two fixed-point numbers and divide, avoiding overflow\n * Computes (a * b) / c with 64-bit intermediate precision\n */\nexport function mulDiv(a: number, b: number, c: number): number {\n\tif (c === 0) return 0;\n\t// Use BigInt for 64-bit precision\n\tconst result = (BigInt(a) * BigInt(b)) / BigInt(c);\n\treturn Number(result);\n}\n\n/**\n * Multiply two 16.16 fixed-point numbers\n */\nexport function mulFix(a: number, b: number): number {\n\treturn mulDiv(a, b, F16DOT16_ONE);\n}\n\n/**\n * Divide two numbers and return 16.16 fixed-point result\n */\nexport function divFix(a: number, b: number): number {\n\tif (b === 0) return 0;\n\treturn mulDiv(a, F16DOT16_ONE, b);\n}\n\n/**\n * Fast approximation of sqrt(x*x + y*y) using \"alpha max plus beta min\" algorithm.\n * Uses alpha = 1, beta = 3/8 for max error < 7% vs exact value.\n * From FreeType's FT_HYPOT macro.\n */\nexport function hypot(x: number, y: number): number {\n\tx = abs(x);\n\ty = abs(y);\n\treturn x > y ? x + ((3 * y) >> 3) : y + ((3 * x) >> 3);\n}\n\n/**\n * Calculate the length of a 2D vector (integer math)\n * Uses FreeType's \"alpha max plus beta min\" approximation\n */\nexport function vectorLength(dx: number, dy: number): number {\n\treturn hypot(dx, dy);\n}\n\n/**\n * Normalize a 2D vector to unit length (16.16 fixed-point output)\n */\nexport function normalizeVector(\n\tdx: number,\n\tdy: number,\n): { x: number; y: number } {\n\tconst len = Math.sqrt(dx * dx + dy * dy);\n\tif (len === 0) return { x: F16DOT16_ONE, y: 0 };\n\treturn {\n\t\tx: Math.round((dx / len) * F16DOT16_ONE),\n\t\ty: Math.round((dy / len) * F16DOT16_ONE),\n\t};\n}\n\n/**\n * Clamp value to range\n */\nexport function clamp(x: number, min: number, max: number): number {\n\treturn x < min ? min : x > max ? max : x;\n}\n\n/**\n * Absolute value\n */\nexport function abs(x: number): number {\n\treturn x < 0 ? -x : x;\n}\n\n/**\n * Sign of value (-1, 0, or 1)\n */\nexport function sign(x: number): number {\n\treturn x < 0 ? -1 : x > 0 ? 1 : 0;\n}\n",
82
- "/**\n * Cell management for scanline rasterization\n *\n * Based on FreeType's ftgrays.c cell accumulation approach.\n * Each cell tracks coverage and area for anti-aliased rendering.\n *\n * Uses pool-based allocation with overflow detection for bounded memory.\n */\n\nimport { PIXEL_BITS, truncPixel } from \"./fixed-point.ts\";\n\n/** Default pool size (matches FreeType's FT_MAX_GRAY_POOL) */\nconst DEFAULT_POOL_SIZE = 2048;\n\n/** Sentinel X value for null cell */\nconst CELL_MAX_X = 0x7fffffff;\n\n/**\n * Pool overflow error - thrown when cell pool is exhausted\n */\nexport class PoolOverflowError extends Error {\n\tconstructor() {\n\t\tsuper(\"Cell pool overflow\");\n\t\tthis.name = \"PoolOverflowError\";\n\t}\n}\n\n/**\n * A cell accumulates coverage information for one pixel\n */\nexport interface Cell {\n\t/** X coordinate in pixels */\n\tx: number;\n\t/** Accumulated signed area */\n\tarea: number;\n\t/** Accumulated coverage (winding number contribution) */\n\tcover: number;\n\t/** Next cell in linked list (index into pool, -1 for end) */\n\tnext: number;\n}\n\n/**\n * Cell storage with pool-based allocation and linked lists per scanline.\n * Matches FreeType's approach for bounded memory usage.\n */\nexport class CellBuffer {\n\t/** Fixed-size cell pool */\n\tprivate pool: Cell[];\n\t/** Pool size */\n\tprivate poolSize: number;\n\t/** Next free cell index */\n\tprivate freeIndex: number;\n\t/** Per-scanline linked list heads (index into pool, -1 for empty) */\n\tprivate ycells: number[];\n\n\t/** Band bounds (Y range for current render pass) */\n\tprivate bandMinY: number = 0;\n\tprivate bandMaxY: number = 0;\n\n\t/** Bounding box of active cells */\n\tminY: number = Infinity;\n\tmaxY: number = -Infinity;\n\tminX: number = Infinity;\n\tmaxX: number = -Infinity;\n\n\t/** Current position for incremental cell updates */\n\tprivate currentX: number = 0;\n\tprivate currentY: number = 0;\n\tprivate currentCellIndex: number = -1;\n\n\t/** Clip bounds in pixels */\n\tprivate clipMinX: number = -Infinity;\n\tprivate clipMinY: number = -Infinity;\n\tprivate clipMaxX: number = Infinity;\n\tprivate clipMaxY: number = Infinity;\n\n\t/** Null cell index (sentinel at end of pool) */\n\tprivate nullCellIndex: number;\n\n\t/** Whether band bounds have been set */\n\tprivate bandSet: boolean = false;\n\n\tconstructor(poolSize: number = DEFAULT_POOL_SIZE) {\n\t\tthis.poolSize = poolSize;\n\t\tthis.nullCellIndex = poolSize - 1;\n\n\t\t// Pre-allocate pool\n\t\tthis.pool = new Array(poolSize);\n\t\tfor (let i = 0; i < poolSize; i++) {\n\t\t\tthis.pool[i] = { x: 0, area: 0, cover: 0, next: -1 };\n\t\t}\n\n\t\t// Initialize null cell (sentinel)\n\t\tthis.pool[this.nullCellIndex].x = CELL_MAX_X;\n\t\tthis.pool[this.nullCellIndex].next = -1;\n\n\t\tthis.ycells = [];\n\t\tthis.freeIndex = 0;\n\n\t\t// Default band bounds (large range for backward compatibility)\n\t\tthis.bandMinY = -10000;\n\t\tthis.bandMaxY = 10000;\n\t}\n\n\t/**\n\t * Set clipping bounds\n\t */\n\tsetClip(minX: number, minY: number, maxX: number, maxY: number): void {\n\t\tthis.clipMinX = minX;\n\t\tthis.clipMinY = minY;\n\t\tthis.clipMaxX = maxX;\n\t\tthis.clipMaxY = maxY;\n\t}\n\n\t/**\n\t * Set band bounds for current render pass\n\t */\n\tsetBandBounds(minY: number, maxY: number): void {\n\t\tthis.bandMinY = minY;\n\t\tthis.bandMaxY = maxY;\n\t\tthis.bandSet = true;\n\n\t\t// Resize ycells array for band height\n\t\tconst height = maxY - minY;\n\t\tif (this.ycells.length < height) {\n\t\t\tthis.ycells = new Array(height);\n\t\t}\n\n\t\t// Initialize all rows to null cell\n\t\tfor (let i = 0; i < height; i++) {\n\t\t\tthis.ycells[i] = this.nullCellIndex;\n\t\t}\n\n\t\t// Calculate how many cells we need for ycells pointers\n\t\t// Reserve space at start of pool for ycells (like FreeType)\n\t\tthis.freeIndex = 0;\n\t}\n\n\t/**\n\t * Clear all cells for new band\n\t */\n\treset(): void {\n\t\t// Reset pool\n\t\tthis.freeIndex = 0;\n\n\t\t// Reset null cell\n\t\tthis.pool[this.nullCellIndex].x = CELL_MAX_X;\n\t\tthis.pool[this.nullCellIndex].area = 0;\n\t\tthis.pool[this.nullCellIndex].cover = 0;\n\t\tthis.pool[this.nullCellIndex].next = -1;\n\n\t\t// Reset ycells to null (only if band was set; otherwise leave for dynamic expansion)\n\t\tif (this.bandSet) {\n\t\t\tfor (let i = 0; i < this.ycells.length; i++) {\n\t\t\t\tthis.ycells[i] = this.nullCellIndex;\n\t\t\t}\n\t\t} else {\n\t\t\t// Clear ycells for dynamic mode - will be initialized on first use\n\t\t\tthis.ycells = [];\n\t\t\t// Use very large bounds to avoid clipping before ensureYCellsCapacity is called\n\t\t\tthis.bandMinY = -100000;\n\t\t\tthis.bandMaxY = 100000;\n\t\t}\n\n\t\tthis.minY = Infinity;\n\t\tthis.maxY = -Infinity;\n\t\tthis.minX = Infinity;\n\t\tthis.maxX = -Infinity;\n\t\tthis.currentCellIndex = -1;\n\t}\n\n\t/**\n\t * Set current position (in subpixel coordinates)\n\t * @throws PoolOverflowError if pool is exhausted\n\t */\n\tsetCurrentCell(x: number, y: number): void {\n\t\tconst px = truncPixel(x);\n\t\tconst py = truncPixel(y);\n\n\t\t// Check if we're already at this cell\n\t\tif (\n\t\t\tthis.currentCellIndex >= 0 &&\n\t\t\tthis.currentX === px &&\n\t\t\tthis.currentY === py\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Check clipping (use both band bounds and clip bounds for Y)\n\t\tif (\n\t\t\tpy < this.bandMinY ||\n\t\t\tpy >= this.bandMaxY ||\n\t\t\tpy < this.clipMinY ||\n\t\t\tpy >= this.clipMaxY ||\n\t\t\tpx < this.clipMinX ||\n\t\t\tpx >= this.clipMaxX\n\t\t) {\n\t\t\tthis.currentCellIndex = this.nullCellIndex;\n\t\t\tthis.currentX = px;\n\t\t\tthis.currentY = py;\n\t\t\treturn;\n\t\t}\n\n\t\t// Get or create cell for this position\n\t\tthis.currentX = px;\n\t\tthis.currentY = py;\n\t\tthis.currentCellIndex = this.findOrCreateCell(px, py);\n\n\t\t// Update bounds\n\t\tthis.minY = Math.min(this.minY, py);\n\t\tthis.maxY = Math.max(this.maxY, py);\n\t\tthis.minX = Math.min(this.minX, px);\n\t\tthis.maxX = Math.max(this.maxX, px);\n\t}\n\n\t/**\n\t * Find or create a cell at the given pixel position\n\t * @throws PoolOverflowError if pool is exhausted\n\t */\n\tprivate findOrCreateCell(x: number, y: number): number {\n\t\t// Auto-expand band if needed (for backward compatibility when setBandBounds not called)\n\t\tif (!this.bandSet) {\n\t\t\tthis.ensureYCellsCapacity(y);\n\t\t}\n\n\t\tconst rowIndex = y - this.bandMinY;\n\t\tif (rowIndex < 0 || rowIndex >= this.ycells.length) {\n\t\t\treturn this.nullCellIndex;\n\t\t}\n\n\t\t// Walk linked list for this row\n\t\tlet prevIndex = -1;\n\t\tlet cellIndex = this.ycells[rowIndex];\n\n\t\twhile (cellIndex !== this.nullCellIndex) {\n\t\t\tconst cell = this.pool[cellIndex];\n\t\t\tif (cell.x === x) {\n\t\t\t\treturn cellIndex; // Found existing cell\n\t\t\t}\n\t\t\tif (cell.x > x) {\n\t\t\t\tbreak; // Insert before this cell\n\t\t\t}\n\t\t\tprevIndex = cellIndex;\n\t\t\tcellIndex = cell.next;\n\t\t}\n\n\t\t// Need to allocate new cell\n\t\tif (this.freeIndex >= this.nullCellIndex) {\n\t\t\tthrow new PoolOverflowError();\n\t\t}\n\n\t\tconst newIndex = this.freeIndex++;\n\t\tconst newCell = this.pool[newIndex];\n\t\tnewCell.x = x;\n\t\tnewCell.area = 0;\n\t\tnewCell.cover = 0;\n\t\tnewCell.next = cellIndex;\n\n\t\t// Link into list\n\t\tif (prevIndex === -1) {\n\t\t\tthis.ycells[rowIndex] = newIndex;\n\t\t} else {\n\t\t\tthis.pool[prevIndex].next = newIndex;\n\t\t}\n\n\t\treturn newIndex;\n\t}\n\n\t/**\n\t * Ensure ycells array can accommodate the given Y coordinate\n\t * Used for backward compatibility when setBandBounds is not called\n\t */\n\tprivate ensureYCellsCapacity(y: number): void {\n\t\t// Initialize band if first access\n\t\tif (this.ycells.length === 0) {\n\t\t\t// Start with a reasonable range centered around y\n\t\t\tthis.bandMinY = Math.min(y, 0);\n\t\t\tthis.bandMaxY = Math.max(y + 1, 256);\n\t\t\tconst height = this.bandMaxY - this.bandMinY;\n\t\t\tthis.ycells = new Array(height);\n\t\t\tfor (let i = 0; i < height; i++) {\n\t\t\t\tthis.ycells[i] = this.nullCellIndex;\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\t// Expand if needed\n\t\tif (y < this.bandMinY) {\n\t\t\tconst expand = this.bandMinY - y;\n\t\t\tconst newYcells = new Array(this.ycells.length + expand);\n\t\t\tfor (let i = 0; i < expand; i++) {\n\t\t\t\tnewYcells[i] = this.nullCellIndex;\n\t\t\t}\n\t\t\tfor (let i = 0; i < this.ycells.length; i++) {\n\t\t\t\tnewYcells[expand + i] = this.ycells[i];\n\t\t\t}\n\t\t\tthis.ycells = newYcells;\n\t\t\tthis.bandMinY = y;\n\t\t} else if (y >= this.bandMaxY) {\n\t\t\tconst newMaxY = y + 1;\n\t\t\tconst oldLen = this.ycells.length;\n\t\t\tconst newLen = newMaxY - this.bandMinY;\n\t\t\tif (newLen > oldLen) {\n\t\t\t\tconst newYcells = new Array(newLen);\n\t\t\t\tfor (let i = 0; i < oldLen; i++) {\n\t\t\t\t\tnewYcells[i] = this.ycells[i];\n\t\t\t\t}\n\t\t\t\tfor (let i = oldLen; i < newLen; i++) {\n\t\t\t\t\tnewYcells[i] = this.nullCellIndex;\n\t\t\t\t}\n\t\t\t\tthis.ycells = newYcells;\n\t\t\t}\n\t\t\tthis.bandMaxY = newMaxY;\n\t\t}\n\t}\n\n\t/**\n\t * Add area and cover to current cell\n\t */\n\taddArea(area: number, cover: number): void {\n\t\tif (this.currentCellIndex >= 0) {\n\t\t\tconst cell = this.pool[this.currentCellIndex];\n\t\t\tcell.area += area;\n\t\t\tcell.cover += cover;\n\t\t}\n\t}\n\n\t/**\n\t * Get current cell area (for accumulation)\n\t */\n\tgetArea(): number {\n\t\tif (this.currentCellIndex >= 0) {\n\t\t\treturn this.pool[this.currentCellIndex]?.area;\n\t\t}\n\t\treturn 0;\n\t}\n\n\t/**\n\t * Get current cell cover\n\t */\n\tgetCover(): number {\n\t\tif (this.currentCellIndex >= 0) {\n\t\t\treturn this.pool[this.currentCellIndex]?.cover;\n\t\t}\n\t\treturn 0;\n\t}\n\n\t/**\n\t * Get all cells for a given Y coordinate, sorted by X\n\t */\n\tgetCellsForRow(y: number): Cell[] {\n\t\tconst rowIndex = y - this.bandMinY;\n\t\tif (rowIndex < 0 || rowIndex >= this.ycells.length) {\n\t\t\treturn [];\n\t\t}\n\n\t\tconst cells: Cell[] = [];\n\t\tlet cellIndex = this.ycells[rowIndex];\n\t\twhile (cellIndex !== this.nullCellIndex) {\n\t\t\tcells.push(this.pool[cellIndex]);\n\t\t\tcellIndex = this.pool[cellIndex]?.next;\n\t\t}\n\t\treturn cells;\n\t}\n\n\t/**\n\t * Iterate over all cells in scanline order within band\n\t */\n\t*iterateCells(): Generator<{ y: number; cells: Cell[] }> {\n\t\tfor (let i = 0; i < this.ycells.length; i++) {\n\t\t\tconst y = this.bandMinY + i;\n\t\t\tlet cellIndex = this.ycells[i];\n\t\t\tif (cellIndex === this.nullCellIndex) continue;\n\n\t\t\tconst cells: Cell[] = [];\n\t\t\twhile (cellIndex !== this.nullCellIndex) {\n\t\t\t\tcells.push(this.pool[cellIndex]);\n\t\t\t\tcellIndex = this.pool[cellIndex]?.next;\n\t\t\t}\n\t\t\tif (cells.length > 0) {\n\t\t\t\tyield { y, cells };\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Iterate cells for a single row (for band sweep)\n\t */\n\t*iterateRowCells(y: number): Generator<Cell> {\n\t\tconst rowIndex = y - this.bandMinY;\n\t\tif (rowIndex < 0 || rowIndex >= this.ycells.length) return;\n\n\t\tlet cellIndex = this.ycells[rowIndex];\n\t\twhile (cellIndex !== this.nullCellIndex) {\n\t\t\tyield this.pool[cellIndex];\n\t\t\tcellIndex = this.pool[cellIndex]?.next;\n\t\t}\n\t}\n\n\t/**\n\t * Get number of cells currently allocated\n\t */\n\tgetCellCount(): number {\n\t\treturn this.freeIndex;\n\t}\n\n\t/**\n\t * Check if pool is near capacity\n\t */\n\tisNearCapacity(): boolean {\n\t\treturn this.freeIndex > this.poolSize * 0.9;\n\t}\n}\n\n/**\n * Convert cell coverage to 8-bit grayscale value\n *\n * The area is accumulated in 2*PIXEL_BITS precision.\n * We need to shift down to get 0-255 coverage.\n */\nexport function coverageToGray(area: number): number {\n\t// Area is in ONE_PIXEL * ONE_PIXEL precision\n\t// Shift down to 0-255 range\n\tlet coverage = area >> (PIXEL_BITS * 2 - 8);\n\n\t// Clamp to 0-255\n\tif (coverage < 0) coverage = -coverage;\n\tif (coverage > 255) coverage = 255;\n\n\treturn coverage;\n}\n\n/**\n * Apply non-zero winding fill rule\n */\nexport function applyNonZeroRule(cover: number): number {\n\tlet c = cover;\n\tif (c < 0) c = -c;\n\tif (c > 255) c = 255;\n\treturn c;\n}\n\n/**\n * Apply even-odd fill rule\n */\nexport function applyEvenOddRule(cover: number): number {\n\tlet c = cover;\n\tif (c < 0) c = -c;\n\tc &= 511; // Mod 512\n\tif (c > 256) c = 512 - c;\n\tif (c > 255) c = 255;\n\treturn c;\n}\n",
83
- "/**\n * Gray-scale anti-aliased rasterizer\n *\n * Based on FreeType's ftgrays.c - a coverage-based scanline rasterizer\n * that produces high-quality anti-aliased output.\n *\n * Algorithm overview:\n * 1. Convert outline to line segments (flatten curves)\n * 2. For each line segment, compute coverage contribution to cells\n * 3. Sweep scanlines, accumulating coverage\n * 4. Convert coverage to grayscale pixels\n *\n * Key concepts:\n * - cover: accumulated vertical change (winding contribution)\n * - area: accumulated (y-delta * x-position) for edge anti-aliasing\n *\n * Band processing:\n * - Large glyphs are divided into vertical bands\n * - Each band is rendered with bounded memory pool\n * - On overflow, band is bisected and retried\n */\n\nimport { CellBuffer, PoolOverflowError } from \"./cell.ts\";\nimport {\n\tabs,\n\tfracPixel,\n\tONE_PIXEL,\n\tPIXEL_BITS,\n\ttruncPixel,\n} from \"./fixed-point.ts\";\nimport type { Bitmap, FillRule, Span } from \"./types.ts\";\nimport { FillRule as FillRuleEnum, PixelMode } from \"./types.ts\";\n\n/** Maximum band bisection depth (like FreeType's 32 bands stack) */\nconst MAX_BAND_DEPTH = 32;\n\n/** Span buffer size for direct rendering */\nconst MAX_GRAY_SPANS = 16;\n\n/**\n * Rasterizer state\n */\nexport class GrayRaster {\n\tprivate cells: CellBuffer;\n\n\t// Current position in subpixel coordinates\n\tprivate x: number = 0;\n\tprivate y: number = 0;\n\n\t// Clip bounds in pixels\n\tprivate minX: number = 0;\n\tprivate minY: number = 0;\n\tprivate maxX: number = 0;\n\tprivate maxY: number = 0;\n\n\tconstructor() {\n\t\tthis.cells = new CellBuffer();\n\t}\n\n\t/**\n\t * Set clip rectangle (in pixels)\n\t */\n\tsetClip(minX: number, minY: number, maxX: number, maxY: number): void {\n\t\tthis.minX = minX;\n\t\tthis.minY = minY;\n\t\tthis.maxX = maxX;\n\t\tthis.maxY = maxY;\n\t\tthis.cells.setClip(minX, minY, maxX, maxY);\n\t}\n\n\t/**\n\t * Set band bounds for current render pass\n\t */\n\tsetBandBounds(minY: number, maxY: number): void {\n\t\tthis.cells.setBandBounds(minY, maxY);\n\t}\n\n\t/**\n\t * Reset rasterizer state\n\t */\n\treset(): void {\n\t\tthis.cells.reset();\n\t\tthis.x = 0;\n\t\tthis.y = 0;\n\t}\n\n\t/**\n\t * Move to a new position (start new contour)\n\t * Coordinates are in subpixel units (ONE_PIXEL per pixel)\n\t */\n\tmoveTo(x: number, y: number): void {\n\t\tthis.x = x;\n\t\tthis.y = y;\n\t\tthis.cells.setCurrentCell(x, y);\n\t}\n\n\t/**\n\t * Draw line to position\n\t */\n\tlineTo(toX: number, toY: number): void {\n\t\tthis.renderLine(toX, toY);\n\t\tthis.x = toX;\n\t\tthis.y = toY;\n\t}\n\n\t/**\n\t * Render a line from current position to (toX, toY)\n\t * This is the core rasterization algorithm.\n\t */\n\tprivate renderLine(toX: number, toY: number): void {\n\t\tlet ey1 = truncPixel(this.y);\n\t\tconst ey2 = truncPixel(toY);\n\n\t\t// Vertical clipping\n\t\tif (\n\t\t\t(ey1 >= this.maxY && ey2 >= this.maxY) ||\n\t\t\t(ey1 < this.minY && ey2 < this.minY)\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst fy1 = fracPixel(this.y);\n\t\tconst fy2 = fracPixel(toY);\n\n\t\t// Single scanline case\n\t\tif (ey1 === ey2) {\n\t\t\tthis.renderScanline(ey1, this.x, fy1, toX, fy2);\n\t\t\treturn;\n\t\t}\n\n\t\tconst dx = toX - this.x;\n\t\tconst dy = toY - this.y;\n\n\t\t// Vertical line - optimized path\n\t\tif (dx === 0) {\n\t\t\tconst _ex = truncPixel(this.x);\n\t\t\tconst twoFx = fracPixel(this.x) * 2;\n\n\t\t\tlet first: number;\n\t\t\tlet incr: number;\n\n\t\t\tif (dy > 0) {\n\t\t\t\tfirst = ONE_PIXEL;\n\t\t\t\tincr = 1;\n\t\t\t} else {\n\t\t\t\tfirst = 0;\n\t\t\t\tincr = -1;\n\t\t\t}\n\n\t\t\t// First partial scanline\n\t\t\tlet delta = first - fy1;\n\t\t\tthis.cells.setCurrentCell(this.x, ey1 << PIXEL_BITS);\n\t\t\tthis.cells.addArea(delta * twoFx, delta);\n\t\t\tey1 += incr;\n\n\t\t\t// Full scanlines\n\t\t\tthis.cells.setCurrentCell(this.x, ey1 << PIXEL_BITS);\n\t\t\tdelta = first + first - ONE_PIXEL;\n\t\t\twhile (ey1 !== ey2) {\n\t\t\t\tthis.cells.addArea(delta * twoFx, delta);\n\t\t\t\tey1 += incr;\n\t\t\t\tthis.cells.setCurrentCell(this.x, ey1 << PIXEL_BITS);\n\t\t\t}\n\n\t\t\t// Last partial scanline\n\t\t\tdelta = fy2 - ONE_PIXEL + first;\n\t\t\tthis.cells.addArea(delta * twoFx, delta);\n\t\t\treturn;\n\t\t}\n\n\t\t// General case: line crosses multiple scanlines\n\t\tlet x = this.x;\n\t\tlet incr: number;\n\t\tlet first: number;\n\n\t\tif (dy > 0) {\n\t\t\tfirst = ONE_PIXEL;\n\t\t\tincr = 1;\n\t\t} else {\n\t\t\tfirst = 0;\n\t\t\tincr = -1;\n\t\t}\n\n\t\t// First partial scanline\n\t\tlet delta = first - fy1;\n\t\tconst xDelta = this.mulDiv(dx, delta, abs(dy));\n\t\tlet x2 = x + xDelta;\n\n\t\tthis.renderScanline(ey1, x, fy1, x2, first);\n\t\tx = x2;\n\t\tey1 += incr;\n\n\t\tthis.cells.setCurrentCell(x, ey1 << PIXEL_BITS);\n\n\t\t// Full scanlines\n\t\tif (ey1 !== ey2) {\n\t\t\tconst xLift = this.mulDiv(dx, ONE_PIXEL, abs(dy));\n\t\t\tdelta = first + first - ONE_PIXEL;\n\n\t\t\twhile (ey1 !== ey2) {\n\t\t\t\tx2 = x + xLift;\n\t\t\t\tthis.renderScanline(ey1, x, ONE_PIXEL - first, x2, first);\n\t\t\t\tx = x2;\n\t\t\t\tey1 += incr;\n\t\t\t\tthis.cells.setCurrentCell(x, ey1 << PIXEL_BITS);\n\t\t\t}\n\t\t}\n\n\t\t// Last partial scanline\n\t\tdelta = fy2 - ONE_PIXEL + first;\n\t\tthis.renderScanline(ey1, x, ONE_PIXEL - first, toX, fy2);\n\t}\n\n\t/**\n\t * Render a line segment within a single scanline\n\t */\n\tprivate renderScanline(\n\t\tey: number,\n\t\tx1: number,\n\t\ty1: number,\n\t\tx2: number,\n\t\ty2: number,\n\t): void {\n\t\tconst ex1 = truncPixel(x1);\n\t\tconst ex2 = truncPixel(x2);\n\n\t\t// Trivial case: horizontal line\n\t\tif (y1 === y2) {\n\t\t\tthis.cells.setCurrentCell(x2, ey << PIXEL_BITS);\n\t\t\treturn;\n\t\t}\n\n\t\tconst fx1 = fracPixel(x1);\n\t\tconst fx2 = fracPixel(x2);\n\n\t\t// Single cell case\n\t\tif (ex1 === ex2) {\n\t\t\tconst delta = y2 - y1;\n\t\t\tthis.cells.setCurrentCell(x1, ey << PIXEL_BITS);\n\t\t\tthis.cells.addArea(delta * (fx1 + fx2), delta);\n\t\t\treturn;\n\t\t}\n\n\t\t// Multiple cells\n\t\tconst dx = x2 - x1;\n\t\tconst dy = y2 - y1;\n\n\t\tlet first: number;\n\t\tlet incr: number;\n\n\t\tif (dx > 0) {\n\t\t\tfirst = ONE_PIXEL;\n\t\t\tincr = 1;\n\t\t} else {\n\t\t\tfirst = 0;\n\t\t\tincr = -1;\n\t\t}\n\n\t\t// First cell\n\t\tlet delta = this.mulDiv(dy, first - fx1, abs(dx));\n\t\tthis.cells.setCurrentCell(x1, ey << PIXEL_BITS);\n\t\tthis.cells.addArea(delta * (fx1 + first), delta);\n\n\t\tlet y = y1 + delta;\n\t\tlet ex = ex1 + incr;\n\t\tthis.cells.setCurrentCell(ex << PIXEL_BITS, ey << PIXEL_BITS);\n\n\t\t// Middle cells (full width)\n\t\tif (ex !== ex2) {\n\t\t\tconst yLift = this.mulDiv(dy, ONE_PIXEL, abs(dx));\n\n\t\t\twhile (ex !== ex2) {\n\t\t\t\tdelta = yLift;\n\t\t\t\tthis.cells.addArea(delta * ONE_PIXEL, delta);\n\t\t\t\ty += delta;\n\t\t\t\tex += incr;\n\t\t\t\tthis.cells.setCurrentCell(ex << PIXEL_BITS, ey << PIXEL_BITS);\n\t\t\t}\n\t\t}\n\n\t\t// Last cell\n\t\tdelta = y2 - y;\n\t\tthis.cells.addArea(delta * (fx2 + ONE_PIXEL - first), delta);\n\t}\n\n\t/**\n\t * Multiply and divide with 64-bit precision\n\t */\n\tprivate mulDiv(a: number, b: number, c: number): number {\n\t\tif (c === 0) return 0;\n\t\treturn Math.trunc((a * b) / c);\n\t}\n\n\t/**\n\t * Draw a quadratic Bezier curve using simple parametric sampling\n\t */\n\tconicTo(cx: number, cy: number, toX: number, toY: number): void {\n\t\tconst p0x = this.x;\n\t\tconst p0y = this.y;\n\n\t\t// Estimate number of segments based on curve length\n\t\tconst dx1 = cx - p0x;\n\t\tconst dy1 = cy - p0y;\n\t\tconst dx2 = toX - cx;\n\t\tconst dy2 = toY - cy;\n\t\tconst len =\n\t\t\tMath.sqrt(dx1 * dx1 + dy1 * dy1) + Math.sqrt(dx2 * dx2 + dy2 * dy2);\n\n\t\t// At least 4 segments, more for longer curves\n\t\tconst numSegments = Math.max(4, Math.ceil(len / (ONE_PIXEL * 4)));\n\n\t\tfor (let i = 1; i <= numSegments; i++) {\n\t\t\tconst t = i / numSegments;\n\t\t\tconst ti = 1 - t;\n\t\t\t// Quadratic bezier: B(t) = (1-t)²P0 + 2(1-t)tP1 + t²P2\n\t\t\tconst x = Math.round(ti * ti * p0x + 2 * ti * t * cx + t * t * toX);\n\t\t\tconst y = Math.round(ti * ti * p0y + 2 * ti * t * cy + t * t * toY);\n\t\t\tthis.renderLine(x, y);\n\t\t\t// Update current position for next segment\n\t\t\tthis.x = x;\n\t\t\tthis.y = y;\n\t\t}\n\n\t\tthis.x = toX;\n\t\tthis.y = toY;\n\t}\n\n\t/**\n\t * Draw a cubic Bezier curve\n\t */\n\tcubicTo(\n\t\tcx1: number,\n\t\tcy1: number,\n\t\tcx2: number,\n\t\tcy2: number,\n\t\tx: number,\n\t\ty: number,\n\t): void {\n\t\tthis.subdivCubic(this.x, this.y, cx1, cy1, cx2, cy2, x, y, 0);\n\t\tthis.x = x;\n\t\tthis.y = y;\n\t}\n\n\tprivate subdivCubic(\n\t\tx1: number,\n\t\ty1: number,\n\t\tcx1: number,\n\t\tcy1: number,\n\t\tcx2: number,\n\t\tcy2: number,\n\t\tx4: number,\n\t\ty4: number,\n\t\tlevel: number,\n\t): void {\n\t\tif (level > 16) {\n\t\t\tthis.renderLine(x4, y4);\n\t\t\tthis.x = x4;\n\t\t\tthis.y = y4;\n\t\t\treturn;\n\t\t}\n\n\t\t// De Casteljau midpoints\n\t\tconst x12 = (x1 + cx1) >> 1;\n\t\tconst y12 = (y1 + cy1) >> 1;\n\t\tconst x23 = (cx1 + cx2) >> 1;\n\t\tconst y23 = (cy1 + cy2) >> 1;\n\t\tconst x34 = (cx2 + x4) >> 1;\n\t\tconst y34 = (cy2 + y4) >> 1;\n\t\tconst x123 = (x12 + x23) >> 1;\n\t\tconst y123 = (y12 + y23) >> 1;\n\t\tconst x234 = (x23 + x34) >> 1;\n\t\tconst y234 = (y23 + y34) >> 1;\n\t\tconst x1234 = (x123 + x234) >> 1;\n\t\tconst y1234 = (y123 + y234) >> 1;\n\n\t\t// Flatness test\n\t\tconst dx = x4 - x1;\n\t\tconst dy = y4 - y1;\n\t\tconst d1 = abs((cx1 - x4) * dy - (cy1 - y4) * dx);\n\t\tconst d2 = abs((cx2 - x4) * dy - (cy2 - y4) * dx);\n\n\t\tif (d1 + d2 <= (ONE_PIXEL >> 1) * (abs(dx) + abs(dy))) {\n\t\t\tthis.renderLine(x4, y4);\n\t\t\tthis.x = x4;\n\t\t\tthis.y = y4;\n\t\t\treturn;\n\t\t}\n\n\t\tthis.subdivCubic(x1, y1, x12, y12, x123, y123, x1234, y1234, level + 1);\n\t\tthis.subdivCubic(x1234, y1234, x234, y234, x34, y34, x4, y4, level + 1);\n\t}\n\n\t/**\n\t * Sweep all cells and render to bitmap\n\t *\n\t * Supports both top-down (positive pitch) and bottom-up (negative pitch) bitmaps.\n\t * For positive pitch: y=0 is at top of image (first row in buffer)\n\t * For negative pitch: y=0 is at bottom of image (last row in buffer)\n\t */\n\tsweep(bitmap: Bitmap, fillRule: FillRule = FillRuleEnum.NonZero): void {\n\t\t// Calculate origin offset for pitch direction\n\t\t// Positive pitch (top-down): origin at start of buffer\n\t\t// Negative pitch (bottom-up): origin at (rows-1)*|pitch| for y=0 to be at bottom\n\t\tconst pitch = bitmap.pitch;\n\t\tconst origin = pitch < 0 ? (bitmap.rows - 1) * -pitch : 0;\n\n\t\tfor (const { y, cells } of this.cells.iterateCells()) {\n\t\t\tif (y < 0 || y >= bitmap.rows) continue;\n\n\t\t\tlet cover = 0;\n\t\t\tlet x = 0;\n\t\t\t// For positive pitch: row = y * pitch (y=0 at top)\n\t\t\t// For negative pitch: row = origin - y * |pitch| (y=0 at bottom)\n\t\t\tconst row = pitch < 0 ? origin - y * -pitch : y * pitch;\n\n\t\t\tfor (const cell of cells) {\n\t\t\t\t// Fill span from previous x to current cell\n\t\t\t\tif (cell.x > x && cover !== 0) {\n\t\t\t\t\tconst gray = this.applyFillRule(cover, fillRule);\n\t\t\t\t\tif (gray > 0) {\n\t\t\t\t\t\tconst start = Math.max(0, x);\n\t\t\t\t\t\tconst end = Math.min(bitmap.width, cell.x);\n\t\t\t\t\t\tthis.fillSpan(bitmap, row, start, end, gray);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Compute anti-aliased coverage for this edge cell\n\t\t\t\t// FreeType: cover += cell->cover * (ONE_PIXEL * 2)\n\t\t\t\t// area = cover - cell->area\n\t\t\t\t// The area is SUBTRACTED from scaled cover, not added\n\t\t\t\tconst scaledCover = cover * (ONE_PIXEL * 2);\n\t\t\t\tconst area = scaledCover - cell.area;\n\t\t\t\tconst gray = this.applyFillRule(area >> (PIXEL_BITS + 1), fillRule);\n\n\t\t\t\tif (gray > 0 && cell.x >= 0 && cell.x < bitmap.width) {\n\t\t\t\t\tthis.setPixel(bitmap, row, cell.x, gray);\n\t\t\t\t}\n\n\t\t\t\tcover += cell.cover;\n\t\t\t\tx = cell.x + 1;\n\t\t\t}\n\n\t\t\t// Fill remaining span\n\t\t\tif (x < bitmap.width && cover !== 0) {\n\t\t\t\tconst gray = this.applyFillRule(cover, fillRule);\n\t\t\t\tif (gray > 0) {\n\t\t\t\t\tthis.fillSpan(bitmap, row, x, bitmap.width, gray);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate applyFillRule(value: number, fillRule: FillRule): number {\n\t\tlet v = value;\n\t\tif (v < 0) v = -v;\n\n\t\tif (fillRule === FillRuleEnum.EvenOdd) {\n\t\t\tv &= 511;\n\t\t\tif (v > 256) v = 512 - v;\n\t\t}\n\n\t\treturn v > 255 ? 255 : v;\n\t}\n\n\tprivate fillSpan(\n\t\tbitmap: Bitmap,\n\t\trow: number,\n\t\tstart: number,\n\t\tend: number,\n\t\tgray: number,\n\t): void {\n\t\tif (bitmap.pixelMode === PixelMode.Gray) {\n\t\t\tfor (let x = start; x < end; x++) {\n\t\t\t\tbitmap.buffer[row + x] = gray;\n\t\t\t}\n\t\t} else if (bitmap.pixelMode === PixelMode.Mono) {\n\t\t\tif (gray >= 128) {\n\t\t\t\tfor (let x = start; x < end; x++) {\n\t\t\t\t\tconst byteIdx = row + (x >> 3);\n\t\t\t\t\tconst bitIdx = 7 - (x & 7);\n\t\t\t\t\tbitmap.buffer[byteIdx] |= 1 << bitIdx;\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (bitmap.pixelMode === PixelMode.LCD) {\n\t\t\t// LCD mode: 3 bytes per pixel (RGB subpixels)\n\t\t\t// For now, write same coverage to all 3 subpixels\n\t\t\t// A proper implementation would use subpixel positioning\n\t\t\tfor (let x = start; x < end; x++) {\n\t\t\t\tconst idx = row + x * 3;\n\t\t\t\tbitmap.buffer[idx] = gray;\n\t\t\t\tbitmap.buffer[idx + 1] = gray;\n\t\t\t\tbitmap.buffer[idx + 2] = gray;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate setPixel(bitmap: Bitmap, row: number, x: number, gray: number): void {\n\t\tif (bitmap.pixelMode === PixelMode.Gray) {\n\t\t\tbitmap.buffer[row + x] = gray;\n\t\t} else if (bitmap.pixelMode === PixelMode.Mono) {\n\t\t\tif (gray >= 128) {\n\t\t\t\tconst byteIdx = row + (x >> 3);\n\t\t\t\tconst bitIdx = 7 - (x & 7);\n\t\t\t\tbitmap.buffer[byteIdx] |= 1 << bitIdx;\n\t\t\t}\n\t\t} else if (bitmap.pixelMode === PixelMode.LCD) {\n\t\t\t// LCD mode: 3 bytes per pixel (RGB subpixels)\n\t\t\tconst idx = row + x * 3;\n\t\t\tbitmap.buffer[idx] = gray;\n\t\t\tbitmap.buffer[idx + 1] = gray;\n\t\t\tbitmap.buffer[idx + 2] = gray;\n\t\t}\n\t}\n\n\t/**\n\t * Sweep and call span callback (unbuffered)\n\t * @param callback Span callback function\n\t * @param fillRule Fill rule to apply\n\t * @param userData User data passed to callback (like FreeType's render_span_data)\n\t */\n\tsweepSpans<T = void>(\n\t\tcallback: (y: number, spans: Span[], userData: T) => void,\n\t\tfillRule: FillRule = FillRuleEnum.NonZero,\n\t\tuserData?: T,\n\t): void {\n\t\tfor (const { y, cells } of this.cells.iterateCells()) {\n\t\t\tconst spans: Span[] = [];\n\t\t\tlet cover = 0;\n\t\t\tlet spanStart = -1;\n\n\t\t\tfor (const cell of cells) {\n\t\t\t\t// If we have cover, emit span\n\t\t\t\tif (cover !== 0 && cell.x > spanStart + 1) {\n\t\t\t\t\tconst gray = this.applyFillRule(cover, fillRule);\n\t\t\t\t\tif (gray > 0) {\n\t\t\t\t\t\tspans.push({\n\t\t\t\t\t\t\tx: spanStart + 1,\n\t\t\t\t\t\t\tlen: cell.x - spanStart - 1,\n\t\t\t\t\t\t\tcoverage: gray,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Edge cell - area is SUBTRACTED from scaled cover\n\t\t\t\tconst scaledCover = cover * (ONE_PIXEL * 2);\n\t\t\t\tconst area = scaledCover - cell.area;\n\t\t\t\tconst gray = this.applyFillRule(area >> (PIXEL_BITS + 1), fillRule);\n\t\t\t\tif (gray > 0) {\n\t\t\t\t\tspans.push({ x: cell.x, len: 1, coverage: gray });\n\t\t\t\t}\n\n\t\t\t\tcover += cell.cover;\n\t\t\t\tspanStart = cell.x;\n\t\t\t}\n\n\t\t\tif (spans.length > 0) {\n\t\t\t\tcallback(y, spans, userData as T);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Sweep with span buffering (like FreeType's gray_sweep_direct)\n\t * Buffers up to 16 spans before flushing for better performance\n\t * @param callback Span callback function\n\t * @param fillRule Fill rule to apply\n\t * @param minX Minimum X clip bound\n\t * @param maxX Maximum X clip bound\n\t * @param userData User data passed to callback (like FreeType's render_span_data)\n\t */\n\tsweepDirect<T = void>(\n\t\tcallback: (y: number, spans: Span[], userData: T) => void,\n\t\tfillRule: FillRule = FillRuleEnum.NonZero,\n\t\tminX: number = 0,\n\t\tmaxX: number = Infinity,\n\t\tuserData?: T,\n\t): void {\n\t\tconst spanBuffer: Span[] = [];\n\n\t\tfor (const { y, cells } of this.cells.iterateCells()) {\n\t\t\tlet cover = 0;\n\t\t\tlet x = minX;\n\n\t\t\tfor (const cell of cells) {\n\t\t\t\t// Fill span from previous x to current cell\n\t\t\t\tif (cover !== 0 && cell.x > x) {\n\t\t\t\t\tconst gray = this.applyFillRule(cover, fillRule);\n\t\t\t\t\tif (gray > 0) {\n\t\t\t\t\t\tspanBuffer.push({ x, len: cell.x - x, coverage: gray });\n\t\t\t\t\t\tif (spanBuffer.length >= MAX_GRAY_SPANS) {\n\t\t\t\t\t\t\tcallback(\n\t\t\t\t\t\t\t\ty,\n\t\t\t\t\t\t\t\tspanBuffer.splice(0, spanBuffer.length),\n\t\t\t\t\t\t\t\tuserData as T,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Edge cell - area is SUBTRACTED from scaled cover\n\t\t\t\tconst scaledCover = cover * (ONE_PIXEL * 2);\n\t\t\t\tconst area = scaledCover - cell.area;\n\t\t\t\tconst gray = this.applyFillRule(area >> (PIXEL_BITS + 1), fillRule);\n\t\t\t\tif (gray > 0 && cell.x >= minX && cell.x < maxX) {\n\t\t\t\t\tspanBuffer.push({ x: cell.x, len: 1, coverage: gray });\n\t\t\t\t\tif (spanBuffer.length >= MAX_GRAY_SPANS) {\n\t\t\t\t\t\tcallback(y, spanBuffer.splice(0, spanBuffer.length), userData as T);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tcover += cell.cover;\n\t\t\t\tx = cell.x + 1;\n\t\t\t}\n\n\t\t\t// Fill remaining span\n\t\t\tif (cover !== 0 && x < maxX) {\n\t\t\t\tconst gray = this.applyFillRule(cover, fillRule);\n\t\t\t\tif (gray > 0) {\n\t\t\t\t\tspanBuffer.push({\n\t\t\t\t\t\tx,\n\t\t\t\t\t\tlen: Math.min(maxX, this.maxX + 1) - x,\n\t\t\t\t\t\tcoverage: gray,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Flush remaining spans for this row\n\t\t\tif (spanBuffer.length > 0) {\n\t\t\t\tcallback(y, spanBuffer.splice(0, spanBuffer.length), userData as T);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Render with band processing for bounded memory.\n\t * Divides large glyphs into bands, retries with bisection on overflow.\n\t * Supports both Y-dimension (vertical) and X-dimension (horizontal) bisection\n\t * like FreeType's ftgrays.c gray_convert_glyph.\n\t *\n\t * @param bitmap Target bitmap\n\t * @param decomposeFn Function that decomposes outline to rasterizer commands\n\t * @param bounds Glyph bounds (minY, maxY, optionally minX, maxX)\n\t * @param fillRule Fill rule to apply\n\t */\n\trenderWithBands(\n\t\tbitmap: Bitmap,\n\t\tdecomposeFn: () => void,\n\t\tbounds: { minY: number; maxY: number; minX?: number; maxX?: number },\n\t\tfillRule: FillRule = FillRuleEnum.NonZero,\n\t): void {\n\t\t// Calculate initial band height based on pool size\n\t\t// Aim for bands that use ~1/8 of pool to leave room for overflow\n\t\tconst poolSize = 2048;\n\t\tconst height = bounds.maxY - bounds.minY;\n\t\tlet bandHeight = Math.max(1, Math.floor(poolSize / 8));\n\n\t\t// Adjust if glyph is small enough for single band\n\t\tif (height <= bandHeight) {\n\t\t\tbandHeight = height;\n\t\t}\n\n\t\t// X bounds default to bitmap width\n\t\tconst xMin = bounds.minX ?? 0;\n\t\tconst xMax = bounds.maxX ?? bitmap.width;\n\n\t\t// Stack for band bisection (like FreeType's bands[32])\n\t\t// Each band has Y bounds and X bounds for 2D bisection\n\t\tconst bandStack: Array<{\n\t\t\tminY: number;\n\t\t\tmaxY: number;\n\t\t\tminX: number;\n\t\t\tmaxX: number;\n\t\t}> = [];\n\n\t\t// Initial bands (full X range for each Y band)\n\t\tfor (let y = bounds.minY; y < bounds.maxY; y += bandHeight) {\n\t\t\tbandStack.push({\n\t\t\t\tminY: y,\n\t\t\t\tmaxY: Math.min(y + bandHeight, bounds.maxY),\n\t\t\t\tminX: xMin,\n\t\t\t\tmaxX: xMax,\n\t\t\t});\n\t\t}\n\n\t\t// Process bands with 2D bisection on overflow\n\t\tlet depth = 0;\n\t\twhile (bandStack.length > 0 && depth < MAX_BAND_DEPTH) {\n\t\t\tconst band = bandStack.pop();\n\t\t\tif (!band) break;\n\n\t\t\tif (\n\t\t\t\tthis.renderBandWithXClip(\n\t\t\t\t\tbitmap,\n\t\t\t\t\tdecomposeFn,\n\t\t\t\t\tband.minY,\n\t\t\t\t\tband.maxY,\n\t\t\t\t\tband.minX,\n\t\t\t\t\tband.maxX,\n\t\t\t\t\tfillRule,\n\t\t\t\t)\n\t\t\t) {\n\t\t\t\tcontinue; // Success\n\t\t\t}\n\n\t\t\t// Overflow - try X bisection first (like FreeType), then Y\n\t\t\tconst midX = (band.minX + band.maxX) >> 1;\n\t\t\tif (midX > band.minX) {\n\t\t\t\t// Bisect in X dimension\n\t\t\t\tbandStack.push({\n\t\t\t\t\tminY: band.minY,\n\t\t\t\t\tmaxY: band.maxY,\n\t\t\t\t\tminX: midX,\n\t\t\t\t\tmaxX: band.maxX,\n\t\t\t\t});\n\t\t\t\tbandStack.push({\n\t\t\t\t\tminY: band.minY,\n\t\t\t\t\tmaxY: band.maxY,\n\t\t\t\t\tminX: band.minX,\n\t\t\t\t\tmaxX: midX,\n\t\t\t\t});\n\t\t\t\tdepth++;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// X can't be bisected, try Y\n\t\t\tconst midY = (band.minY + band.maxY) >> 1;\n\t\t\tif (midY > band.minY) {\n\t\t\t\t// Bisect in Y dimension\n\t\t\t\tbandStack.push({\n\t\t\t\t\tminY: midY,\n\t\t\t\t\tmaxY: band.maxY,\n\t\t\t\t\tminX: band.minX,\n\t\t\t\t\tmaxX: band.maxX,\n\t\t\t\t});\n\t\t\t\tbandStack.push({\n\t\t\t\t\tminY: band.minY,\n\t\t\t\t\tmaxY: midY,\n\t\t\t\t\tminX: band.minX,\n\t\t\t\t\tmaxX: band.maxX,\n\t\t\t\t});\n\t\t\t\tdepth++;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Can't bisect in either dimension - rotten glyph\n\t\t\tconsole.warn(\n\t\t\t\t`Rasterizer: band overflow at (${band.minX},${band.minY}), cannot bisect further`,\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Render a single band with X clipping\n\t * @returns true on success, false on pool overflow\n\t */\n\tprivate renderBandWithXClip(\n\t\tbitmap: Bitmap,\n\t\tdecomposeFn: () => void,\n\t\tminY: number,\n\t\tmaxY: number,\n\t\tminX: number,\n\t\tmaxX: number,\n\t\tfillRule: FillRule,\n\t): boolean {\n\t\t// Set up band bounds\n\t\tthis.cells.setBandBounds(minY, maxY);\n\t\tthis.cells.reset();\n\t\tthis.minY = minY;\n\t\tthis.maxY = maxY;\n\n\t\ttry {\n\t\t\t// Decompose outline (may throw PoolOverflowError)\n\t\t\tdecomposeFn();\n\n\t\t\t// Sweep and render to bitmap with X clipping\n\t\t\tthis.sweepBandWithXClip(bitmap, minY, maxY, minX, maxX, fillRule);\n\t\t\treturn true;\n\t\t} catch (e) {\n\t\t\tif (e instanceof PoolOverflowError) {\n\t\t\t\treturn false; // Need to bisect\n\t\t\t}\n\t\t\tthrow e; // Re-throw other errors\n\t\t}\n\t}\n\n\t/**\n\t * Sweep a band with X clipping and render to bitmap\n\t */\n\tprivate sweepBandWithXClip(\n\t\tbitmap: Bitmap,\n\t\tminY: number,\n\t\tmaxY: number,\n\t\tminX: number,\n\t\tmaxX: number,\n\t\tfillRule: FillRule,\n\t): void {\n\t\tconst pitch = bitmap.pitch;\n\t\tconst origin = pitch < 0 ? (bitmap.rows - 1) * -pitch : 0;\n\n\t\tfor (let y = minY; y < maxY; y++) {\n\t\t\tif (y < 0 || y >= bitmap.rows) continue;\n\n\t\t\tlet cover = 0;\n\t\t\tlet x = minX;\n\t\t\tconst row = pitch < 0 ? origin - y * -pitch : y * pitch;\n\n\t\t\tfor (const cell of this.cells.iterateRowCells(y)) {\n\t\t\t\t// Skip cells outside X clip\n\t\t\t\tif (cell.x < minX) {\n\t\t\t\t\tcover += cell.cover;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (cell.x >= maxX) {\n\t\t\t\t\t// Fill remaining clipped span\n\t\t\t\t\tif (cover !== 0 && x < maxX) {\n\t\t\t\t\t\tconst gray = this.applyFillRule(cover, fillRule);\n\t\t\t\t\t\tif (gray > 0) {\n\t\t\t\t\t\t\tthis.fillSpan(\n\t\t\t\t\t\t\t\tbitmap,\n\t\t\t\t\t\t\t\trow,\n\t\t\t\t\t\t\t\tMath.max(0, x),\n\t\t\t\t\t\t\t\tMath.min(bitmap.width, maxX),\n\t\t\t\t\t\t\t\tgray,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\t// Fill span from previous x to current cell\n\t\t\t\tif (cell.x > x && cover !== 0) {\n\t\t\t\t\tconst gray = this.applyFillRule(cover, fillRule);\n\t\t\t\t\tif (gray > 0) {\n\t\t\t\t\t\tconst start = Math.max(0, x);\n\t\t\t\t\t\tconst end = Math.min(bitmap.width, cell.x);\n\t\t\t\t\t\tthis.fillSpan(bitmap, row, start, end, gray);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Edge cell anti-aliasing - area is SUBTRACTED from scaled cover\n\t\t\t\tconst scaledCover = cover * (ONE_PIXEL * 2);\n\t\t\t\tconst area = scaledCover - cell.area;\n\t\t\t\tconst gray = this.applyFillRule(area >> (PIXEL_BITS + 1), fillRule);\n\n\t\t\t\tif (gray > 0 && cell.x >= 0 && cell.x < bitmap.width) {\n\t\t\t\t\tthis.setPixel(bitmap, row, cell.x, gray);\n\t\t\t\t}\n\n\t\t\t\tcover += cell.cover;\n\t\t\t\tx = cell.x + 1;\n\t\t\t}\n\n\t\t\t// Fill remaining span within X clip\n\t\t\tif (x < maxX && x < bitmap.width && cover !== 0) {\n\t\t\t\tconst gray = this.applyFillRule(cover, fillRule);\n\t\t\t\tif (gray > 0) {\n\t\t\t\t\tthis.fillSpan(bitmap, row, x, Math.min(bitmap.width, maxX), gray);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n",
84
- "/**\n * Decompose path commands into rasterizer calls\n */\n\nimport {\n\ttype GlyphPath,\n\tOutlineFlags,\n\ttype PathCommand,\n} from \"../render/path.ts\";\nimport { ONE_PIXEL } from \"./fixed-point.ts\";\nimport type { GrayRaster } from \"./gray-raster.ts\";\nimport { FillRule } from \"./types.ts\";\n\n/**\n * Outline validation error types (like FreeType's error codes)\n */\nexport enum OutlineError {\n\tOk = 0,\n\tInvalidOutline = 1,\n\tInvalidArgument = 2,\n\tEmptyOutline = 3,\n}\n\n/**\n * Validation result with error code and message\n */\nexport interface ValidationResult {\n\terror: OutlineError;\n\tmessage?: string;\n}\n\n/**\n * Validate a GlyphPath before rasterization (like FreeType's outline validation)\n *\n * Checks:\n * - Path is not null/undefined\n * - Commands array exists\n * - Path is not empty (unless allowEmpty is true)\n * - Command structure is valid\n * - Contours are properly closed (start with M, end with Z)\n */\nexport function validateOutline(\n\tpath: GlyphPath | null | undefined,\n\tallowEmpty: boolean = true,\n): ValidationResult {\n\t// Check for null/undefined path\n\tif (!path) {\n\t\treturn {\n\t\t\terror: OutlineError.InvalidOutline,\n\t\t\tmessage: \"Path is null or undefined\",\n\t\t};\n\t}\n\n\t// Check commands array exists\n\tif (!path.commands) {\n\t\treturn {\n\t\t\terror: OutlineError.InvalidOutline,\n\t\t\tmessage: \"Path commands array is missing\",\n\t\t};\n\t}\n\n\t// Check for empty path\n\tif (path.commands.length === 0) {\n\t\tif (allowEmpty) {\n\t\t\treturn { error: OutlineError.EmptyOutline };\n\t\t}\n\t\treturn { error: OutlineError.InvalidOutline, message: \"Path is empty\" };\n\t}\n\n\t// Validate command structure\n\tlet hasMove = false;\n\tlet inContour = false;\n\tlet contourCount = 0;\n\n\tfor (let i = 0; i < path.commands.length; i++) {\n\t\tconst cmd = path.commands[i];\n\n\t\tswitch (cmd.type) {\n\t\t\tcase \"M\":\n\t\t\t\tif (inContour) {\n\t\t\t\t\t// Implicit close - allowed but noted\n\t\t\t\t}\n\t\t\t\thasMove = true;\n\t\t\t\tinContour = true;\n\t\t\t\tcontourCount++;\n\t\t\t\t// Validate coordinates are finite numbers\n\t\t\t\tif (!Number.isFinite(cmd.x) || !Number.isFinite(cmd.y)) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\terror: OutlineError.InvalidOutline,\n\t\t\t\t\t\tmessage: `Invalid coordinates at command ${i}: (${cmd.x}, ${cmd.y})`,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase \"L\":\n\t\t\t\tif (!hasMove) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\terror: OutlineError.InvalidOutline,\n\t\t\t\t\t\tmessage: `Line command at ${i} without preceding moveTo`,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tif (!Number.isFinite(cmd.x) || !Number.isFinite(cmd.y)) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\terror: OutlineError.InvalidOutline,\n\t\t\t\t\t\tmessage: `Invalid coordinates at command ${i}`,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase \"Q\":\n\t\t\t\tif (!hasMove) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\terror: OutlineError.InvalidOutline,\n\t\t\t\t\t\tmessage: `Quadratic curve at ${i} without preceding moveTo`,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tif (\n\t\t\t\t\t!Number.isFinite(cmd.x1) ||\n\t\t\t\t\t!Number.isFinite(cmd.y1) ||\n\t\t\t\t\t!Number.isFinite(cmd.x) ||\n\t\t\t\t\t!Number.isFinite(cmd.y)\n\t\t\t\t) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\terror: OutlineError.InvalidOutline,\n\t\t\t\t\t\tmessage: `Invalid coordinates at command ${i}`,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase \"C\":\n\t\t\t\tif (!hasMove) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\terror: OutlineError.InvalidOutline,\n\t\t\t\t\t\tmessage: `Cubic curve at ${i} without preceding moveTo`,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tif (\n\t\t\t\t\t!Number.isFinite(cmd.x1) ||\n\t\t\t\t\t!Number.isFinite(cmd.y1) ||\n\t\t\t\t\t!Number.isFinite(cmd.x2) ||\n\t\t\t\t\t!Number.isFinite(cmd.y2) ||\n\t\t\t\t\t!Number.isFinite(cmd.x) ||\n\t\t\t\t\t!Number.isFinite(cmd.y)\n\t\t\t\t) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\terror: OutlineError.InvalidOutline,\n\t\t\t\t\t\tmessage: `Invalid coordinates at command ${i}`,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase \"Z\":\n\t\t\t\tinContour = false;\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\treturn {\n\t\t\t\t\terror: OutlineError.InvalidOutline,\n\t\t\t\t\tmessage: `Unknown command type at ${i}: ${(cmd as PathCommand).type}`,\n\t\t\t\t};\n\t\t}\n\t}\n\n\t// Warn if no contours found (valid but useless)\n\tif (contourCount === 0 && !allowEmpty) {\n\t\treturn { error: OutlineError.EmptyOutline, message: \"No contours in path\" };\n\t}\n\n\treturn { error: OutlineError.Ok };\n}\n\n/**\n * Convert a GlyphPath to rasterizer commands\n *\n * @param raster - The rasterizer instance\n * @param path - Path commands to decompose\n * @param scale - Scale factor (font units to pixels)\n * @param offsetX - X offset in pixels\n * @param offsetY - Y offset in pixels\n * @param flipY - Flip Y axis (font coords are Y-up)\n */\nexport function decomposePath(\n\traster: GrayRaster,\n\tpath: GlyphPath,\n\tscale: number,\n\toffsetX: number = 0,\n\toffsetY: number = 0,\n\tflipY: boolean = true,\n): void {\n\tlet startX = 0;\n\tlet startY = 0;\n\tlet inContour = false;\n\n\tfor (const cmd of path.commands) {\n\t\tswitch (cmd.type) {\n\t\t\tcase \"M\": {\n\t\t\t\t// Close previous contour if open\n\t\t\t\tif (inContour) {\n\t\t\t\t\traster.lineTo(startX, startY);\n\t\t\t\t}\n\n\t\t\t\t// Convert to subpixel coordinates\n\t\t\t\tconst x = toSubpixel(cmd.x, scale, offsetX);\n\t\t\t\tconst y = flipY\n\t\t\t\t\t? toSubpixelFlipY(cmd.y, scale, offsetY)\n\t\t\t\t\t: toSubpixel(cmd.y, scale, offsetY);\n\n\t\t\t\traster.moveTo(x, y);\n\t\t\t\tstartX = x;\n\t\t\t\tstartY = y;\n\t\t\t\tinContour = true;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"L\": {\n\t\t\t\tconst x = toSubpixel(cmd.x, scale, offsetX);\n\t\t\t\tconst y = flipY\n\t\t\t\t\t? toSubpixelFlipY(cmd.y, scale, offsetY)\n\t\t\t\t\t: toSubpixel(cmd.y, scale, offsetY);\n\n\t\t\t\traster.lineTo(x, y);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"Q\": {\n\t\t\t\tconst cx = toSubpixel(cmd.x1, scale, offsetX);\n\t\t\t\tconst cy = flipY\n\t\t\t\t\t? toSubpixelFlipY(cmd.y1, scale, offsetY)\n\t\t\t\t\t: toSubpixel(cmd.y1, scale, offsetY);\n\t\t\t\tconst x = toSubpixel(cmd.x, scale, offsetX);\n\t\t\t\tconst y = flipY\n\t\t\t\t\t? toSubpixelFlipY(cmd.y, scale, offsetY)\n\t\t\t\t\t: toSubpixel(cmd.y, scale, offsetY);\n\n\t\t\t\traster.conicTo(cx, cy, x, y);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"C\": {\n\t\t\t\tconst cx1 = toSubpixel(cmd.x1, scale, offsetX);\n\t\t\t\tconst cy1 = flipY\n\t\t\t\t\t? toSubpixelFlipY(cmd.y1, scale, offsetY)\n\t\t\t\t\t: toSubpixel(cmd.y1, scale, offsetY);\n\t\t\t\tconst cx2 = toSubpixel(cmd.x2, scale, offsetX);\n\t\t\t\tconst cy2 = flipY\n\t\t\t\t\t? toSubpixelFlipY(cmd.y2, scale, offsetY)\n\t\t\t\t\t: toSubpixel(cmd.y2, scale, offsetY);\n\t\t\t\tconst x = toSubpixel(cmd.x, scale, offsetX);\n\t\t\t\tconst y = flipY\n\t\t\t\t\t? toSubpixelFlipY(cmd.y, scale, offsetY)\n\t\t\t\t\t: toSubpixel(cmd.y, scale, offsetY);\n\n\t\t\t\traster.cubicTo(cx1, cy1, cx2, cy2, x, y);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"Z\": {\n\t\t\t\t// Close contour\n\t\t\t\tif (inContour) {\n\t\t\t\t\traster.lineTo(startX, startY);\n\t\t\t\t\tinContour = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Close final contour if still open\n\tif (inContour) {\n\t\traster.lineTo(startX, startY);\n\t}\n}\n\n/**\n * Convert font units to subpixel coordinates\n */\nfunction toSubpixel(value: number, scale: number, offset: number): number {\n\treturn Math.round((value * scale + offset) * ONE_PIXEL);\n}\n\n/**\n * Convert font units to subpixel coordinates with Y flip\n * Font coordinates are Y-up, bitmap is Y-down\n */\nfunction toSubpixelFlipY(value: number, scale: number, offset: number): number {\n\treturn Math.round((-value * scale + offset) * ONE_PIXEL);\n}\n\n/**\n * Calculate bounding box of path in pixel coordinates\n */\nexport function getPathBounds(\n\tpath: GlyphPath,\n\tscale: number,\n\tflipY: boolean = true,\n): { minX: number; minY: number; maxX: number; maxY: number } | null {\n\tif (!path.bounds) return null;\n\n\tconst b = path.bounds;\n\n\tif (flipY) {\n\t\treturn {\n\t\t\tminX: Math.floor(b.xMin * scale),\n\t\t\tminY: Math.floor(-b.yMax * scale),\n\t\t\tmaxX: Math.ceil(b.xMax * scale),\n\t\t\tmaxY: Math.ceil(-b.yMin * scale),\n\t\t};\n\t} else {\n\t\treturn {\n\t\t\tminX: Math.floor(b.xMin * scale),\n\t\t\tminY: Math.floor(b.yMin * scale),\n\t\t\tmaxX: Math.ceil(b.xMax * scale),\n\t\t\tmaxY: Math.ceil(b.yMax * scale),\n\t\t};\n\t}\n}\n\n/**\n * Get fill rule from outline flags (like FreeType's FT_OUTLINE_EVEN_ODD_FILL check)\n *\n * @param path Path with optional flags\n * @param defaultRule Default fill rule if flags not set\n * @returns Fill rule to use\n */\nexport function getFillRuleFromFlags(\n\tpath: GlyphPath | null | undefined,\n\tdefaultRule: FillRule = FillRule.NonZero,\n): FillRule {\n\tif (!path?.flags) return defaultRule;\n\treturn (path.flags & OutlineFlags.EvenOddFill) !== 0\n\t\t? FillRule.EvenOdd\n\t\t: FillRule.NonZero;\n}\n",
85
- "/**\n * Signed Distance Field (SDF) rasterizer\n *\n * For each pixel, compute the shortest distance to the outline.\n * Positive values are inside the outline, negative are outside.\n * This allows GPU text rendering at any scale.\n *\n * Algorithm:\n * 1. For each pixel center, find the minimum distance to all outline edges\n * 2. Determine sign based on whether point is inside or outside the outline\n * 3. Normalize and encode to 0-255 (128 = on the edge)\n */\n\nimport type { GlyphPath } from \"../render/path.ts\";\nimport { type Bitmap, createBitmap, PixelMode } from \"./types.ts\";\n\n/**\n * Options for SDF rendering\n */\nexport interface SdfOptions {\n\t/** Width in pixels */\n\twidth: number;\n\t/** Height in pixels */\n\theight: number;\n\t/** Scale factor (font units to pixels) */\n\tscale: number;\n\t/** X offset in pixels */\n\toffsetX?: number;\n\t/** Y offset in pixels */\n\toffsetY?: number;\n\t/** Flip Y axis (font coords are Y-up, bitmap is Y-down) */\n\tflipY?: boolean;\n\t/** Spread/radius - how far the distance field extends in pixels (default: 8) */\n\tspread?: number;\n}\n\n/**\n * A point in 2D space\n */\ninterface Point {\n\tx: number;\n\ty: number;\n}\n\n/**\n * An edge in the outline (line segment or curve)\n */\ntype Edge =\n\t| { type: \"line\"; p0: Point; p1: Point }\n\t| { type: \"quadratic\"; p0: Point; p1: Point; p2: Point }\n\t| { type: \"cubic\"; p0: Point; p1: Point; p2: Point; p3: Point };\n\n/**\n * Render a glyph path as a signed distance field\n */\nexport function renderSdf(path: GlyphPath, options: SdfOptions): Bitmap {\n\tconst {\n\t\twidth,\n\t\theight,\n\t\tscale,\n\t\toffsetX = 0,\n\t\toffsetY = 0,\n\t\tflipY = false,\n\t\tspread = 8,\n\t} = options;\n\n\t// Create bitmap\n\tconst bitmap = createBitmap(width, height, PixelMode.Gray);\n\n\t// Convert path commands to edges\n\tconst edges = extractEdges(path, scale, offsetX, offsetY, flipY);\n\n\t// If no edges, fill with 0 (maximum negative distance)\n\tif (edges.length === 0) {\n\t\tbitmap.buffer.fill(0);\n\t\treturn bitmap;\n\t}\n\n\t// For each pixel, compute signed distance\n\tfor (let y = 0; y < height; y++) {\n\t\tfor (let x = 0; x < width; x++) {\n\t\t\t// Pixel center\n\t\t\tconst px = x + 0.5;\n\t\t\tconst py = y + 0.5;\n\n\t\t\t// Find minimum distance to all edges\n\t\t\tlet minDist = Infinity;\n\t\t\tfor (const edge of edges) {\n\t\t\t\tconst dist = distanceToEdge(px, py, edge);\n\t\t\t\tminDist = Math.min(minDist, dist);\n\t\t\t}\n\n\t\t\t// Determine if point is inside or outside\n\t\t\tconst inside = isPointInside(px, py, edges);\n\n\t\t\t// Sign: positive inside, negative outside\n\t\t\tconst signedDist = inside ? minDist : -minDist;\n\n\t\t\t// Normalize to 0-255 range\n\t\t\t// spread is the distance in pixels that maps to 0-128 or 128-255\n\t\t\t// 0 = -spread (far outside)\n\t\t\t// 128 = 0 (on edge)\n\t\t\t// 255 = +spread (far inside)\n\t\t\tconst normalized = 128 + (signedDist / spread) * 127;\n\t\t\tconst clamped = Math.max(0, Math.min(255, Math.round(normalized)));\n\n\t\t\tbitmap.buffer[y * bitmap.pitch + x] = clamped;\n\t\t}\n\t}\n\n\treturn bitmap;\n}\n\n/**\n * Extract edges from path commands\n */\nfunction extractEdges(\n\tpath: GlyphPath,\n\tscale: number,\n\toffsetX: number,\n\toffsetY: number,\n\tflipY: boolean,\n): Edge[] {\n\tconst edges: Edge[] = [];\n\tlet currentPoint: Point | null = null;\n\tlet firstPoint: Point | null = null;\n\n\tconst transform = (x: number, y: number): Point => ({\n\t\tx: x * scale + offsetX,\n\t\ty: flipY ? -(y * scale) + offsetY : y * scale + offsetY,\n\t});\n\n\tfor (const cmd of path.commands) {\n\t\tswitch (cmd.type) {\n\t\t\tcase \"M\":\n\t\t\t\tcurrentPoint = transform(cmd.x, cmd.y);\n\t\t\t\tfirstPoint = currentPoint;\n\t\t\t\tbreak;\n\n\t\t\tcase \"L\":\n\t\t\t\tif (currentPoint) {\n\t\t\t\t\tconst p1 = transform(cmd.x, cmd.y);\n\t\t\t\t\tedges.push({ type: \"line\", p0: currentPoint, p1 });\n\t\t\t\t\tcurrentPoint = p1;\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase \"Q\":\n\t\t\t\tif (currentPoint) {\n\t\t\t\t\tconst p1 = transform(cmd.x1, cmd.y1);\n\t\t\t\t\tconst p2 = transform(cmd.x, cmd.y);\n\t\t\t\t\tedges.push({ type: \"quadratic\", p0: currentPoint, p1, p2 });\n\t\t\t\t\tcurrentPoint = p2;\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase \"C\":\n\t\t\t\tif (currentPoint) {\n\t\t\t\t\tconst p1 = transform(cmd.x1, cmd.y1);\n\t\t\t\t\tconst p2 = transform(cmd.x2, cmd.y2);\n\t\t\t\t\tconst p3 = transform(cmd.x, cmd.y);\n\t\t\t\t\tedges.push({ type: \"cubic\", p0: currentPoint, p1, p2, p3 });\n\t\t\t\t\tcurrentPoint = p3;\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase \"Z\":\n\t\t\t\t// Close path with a line back to start\n\t\t\t\tif (currentPoint && firstPoint) {\n\t\t\t\t\t// Only add closing edge if not already at start\n\t\t\t\t\tif (\n\t\t\t\t\t\tMath.abs(currentPoint.x - firstPoint.x) > 0.001 ||\n\t\t\t\t\t\tMath.abs(currentPoint.y - firstPoint.y) > 0.001\n\t\t\t\t\t) {\n\t\t\t\t\t\tedges.push({ type: \"line\", p0: currentPoint, p1: firstPoint });\n\t\t\t\t\t}\n\t\t\t\t\tcurrentPoint = firstPoint;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn edges;\n}\n\n/**\n * Compute distance from point to edge\n */\nfunction distanceToEdge(px: number, py: number, edge: Edge): number {\n\tswitch (edge.type) {\n\t\tcase \"line\":\n\t\t\treturn distanceToLine(px, py, edge.p0, edge.p1);\n\t\tcase \"quadratic\":\n\t\t\treturn distanceToQuadratic(px, py, edge.p0, edge.p1, edge.p2);\n\t\tcase \"cubic\":\n\t\t\treturn distanceToCubic(px, py, edge.p0, edge.p1, edge.p2, edge.p3);\n\t}\n}\n\n/**\n * Distance from point to line segment\n */\nfunction distanceToLine(px: number, py: number, p0: Point, p1: Point): number {\n\tconst dx = p1.x - p0.x;\n\tconst dy = p1.y - p0.y;\n\tconst lenSq = dx * dx + dy * dy;\n\n\tif (lenSq < 0.0001) {\n\t\t// Degenerate segment - just distance to point\n\t\tconst dpx = px - p0.x;\n\t\tconst dpy = py - p0.y;\n\t\treturn Math.sqrt(dpx * dpx + dpy * dpy);\n\t}\n\n\t// Project point onto line\n\tlet t = ((px - p0.x) * dx + (py - p0.y) * dy) / lenSq;\n\tt = Math.max(0, Math.min(1, t)); // Clamp to segment\n\n\tconst closestX = p0.x + t * dx;\n\tconst closestY = p0.y + t * dy;\n\n\tconst distX = px - closestX;\n\tconst distY = py - closestY;\n\treturn Math.sqrt(distX * distX + distY * distY);\n}\n\n/**\n * Distance from point to quadratic bezier curve\n * Uses sampling approximation for simplicity\n */\nfunction distanceToQuadratic(\n\tpx: number,\n\tpy: number,\n\tp0: Point,\n\tp1: Point,\n\tp2: Point,\n): number {\n\tlet minDist = Infinity;\n\n\t// Sample the curve at multiple points\n\tconst samples = 32;\n\tfor (let i = 0; i <= samples; i++) {\n\t\tconst t = i / samples;\n\t\tconst ti = 1 - t;\n\n\t\t// Quadratic bezier: B(t) = (1-t)²P0 + 2(1-t)tP1 + t²P2\n\t\tconst x = ti * ti * p0.x + 2 * ti * t * p1.x + t * t * p2.x;\n\t\tconst y = ti * ti * p0.y + 2 * ti * t * p1.y + t * t * p2.y;\n\n\t\tconst dx = px - x;\n\t\tconst dy = py - y;\n\t\tconst dist = Math.sqrt(dx * dx + dy * dy);\n\t\tminDist = Math.min(minDist, dist);\n\t}\n\n\treturn minDist;\n}\n\n/**\n * Distance from point to cubic bezier curve\n * Uses sampling approximation for simplicity\n */\nfunction distanceToCubic(\n\tpx: number,\n\tpy: number,\n\tp0: Point,\n\tp1: Point,\n\tp2: Point,\n\tp3: Point,\n): number {\n\tlet minDist = Infinity;\n\n\t// Sample the curve at multiple points\n\tconst samples = 32;\n\tfor (let i = 0; i <= samples; i++) {\n\t\tconst t = i / samples;\n\t\tconst ti = 1 - t;\n\n\t\t// Cubic bezier: B(t) = (1-t)³P0 + 3(1-t)²tP1 + 3(1-t)t²P2 + t³P3\n\t\tconst x =\n\t\t\tti * ti * ti * p0.x +\n\t\t\t3 * ti * ti * t * p1.x +\n\t\t\t3 * ti * t * t * p2.x +\n\t\t\tt * t * t * p3.x;\n\t\tconst y =\n\t\t\tti * ti * ti * p0.y +\n\t\t\t3 * ti * ti * t * p1.y +\n\t\t\t3 * ti * t * t * p2.y +\n\t\t\tt * t * t * p3.y;\n\n\t\tconst dx = px - x;\n\t\tconst dy = py - y;\n\t\tconst dist = Math.sqrt(dx * dx + dy * dy);\n\t\tminDist = Math.min(minDist, dist);\n\t}\n\n\treturn minDist;\n}\n\n/**\n * Determine if a point is inside the outline using ray casting\n * (even-odd rule)\n */\nfunction isPointInside(px: number, py: number, edges: Edge[]): boolean {\n\tlet crossings = 0;\n\n\tfor (const edge of edges) {\n\t\t// Flatten curves to line segments for inside test\n\t\tconst points = flattenEdge(edge);\n\n\t\tfor (let i = 0; i < points.length - 1; i++) {\n\t\t\tconst p0 = points[i];\n\t\t\tconst p1 = points[i + 1];\n\t\t\tif (!p0 || !p1) continue;\n\n\t\t\t// Ray casting: cast horizontal ray to the right from (px, py)\n\t\t\t// Check if it crosses this edge\n\t\t\tif (p0.y > py !== p1.y > py) {\n\t\t\t\t// Edge crosses the horizontal line at y = py\n\t\t\t\tconst slope = (p1.x - p0.x) / (p1.y - p0.y);\n\t\t\t\tconst x = p0.x + slope * (py - p0.y);\n\n\t\t\t\tif (px < x) {\n\t\t\t\t\tcrossings++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Odd number of crossings = inside\n\treturn (crossings & 1) === 1;\n}\n\n/**\n * Flatten an edge to a sequence of points for inside testing\n */\nfunction flattenEdge(edge: Edge): Point[] {\n\tswitch (edge.type) {\n\t\tcase \"line\":\n\t\t\treturn [edge.p0, edge.p1];\n\n\t\tcase \"quadratic\": {\n\t\t\tconst points: Point[] = [edge.p0];\n\t\t\tconst samples = 16;\n\t\t\tfor (let i = 1; i <= samples; i++) {\n\t\t\t\tconst t = i / samples;\n\t\t\t\tconst ti = 1 - t;\n\t\t\t\tpoints.push({\n\t\t\t\t\tx: ti * ti * edge.p0.x + 2 * ti * t * edge.p1.x + t * t * edge.p2.x,\n\t\t\t\t\ty: ti * ti * edge.p0.y + 2 * ti * t * edge.p1.y + t * t * edge.p2.y,\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn points;\n\t\t}\n\n\t\tcase \"cubic\": {\n\t\t\tconst points: Point[] = [edge.p0];\n\t\t\tconst samples = 16;\n\t\t\tfor (let i = 1; i <= samples; i++) {\n\t\t\t\tconst t = i / samples;\n\t\t\t\tconst ti = 1 - t;\n\t\t\t\tpoints.push({\n\t\t\t\t\tx:\n\t\t\t\t\t\tti * ti * ti * edge.p0.x +\n\t\t\t\t\t\t3 * ti * ti * t * edge.p1.x +\n\t\t\t\t\t\t3 * ti * t * t * edge.p2.x +\n\t\t\t\t\t\tt * t * t * edge.p3.x,\n\t\t\t\t\ty:\n\t\t\t\t\t\tti * ti * ti * edge.p0.y +\n\t\t\t\t\t\t3 * ti * ti * t * edge.p1.y +\n\t\t\t\t\t\t3 * ti * t * t * edge.p2.y +\n\t\t\t\t\t\tt * t * t * edge.p3.y,\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn points;\n\t\t}\n\t}\n}\n",
86
- "/**\n * High-level rasterization API\n */\n\nimport type { Font } from \"../font/font.ts\";\nimport {\n\tcreateHintingEngine,\n\ttype GlyphOutline,\n\ttype HintedGlyph,\n\ttype HintingEngine,\n\thintGlyph,\n\tloadCVTProgram,\n\tloadFontProgram,\n\tsetSize,\n} from \"../hinting/programs.ts\";\nimport { type GlyphPath, getGlyphPath } from \"../render/path.ts\";\nimport type { GlyphId } from \"../types.ts\";\nimport { GrayRaster } from \"./gray-raster.ts\";\nimport { decomposePath, getPathBounds } from \"./outline-decompose.ts\";\nimport {\n\ttype Bitmap,\n\tcreateBitmap,\n\tFillRule,\n\tPixelMode,\n\ttype RasterizedGlyph,\n\ttype RasterizeOptions,\n} from \"./types.ts\";\n\n/** Cached hinting engines per font */\nconst hintingEngineCache = new WeakMap<Font, HintingEngine>();\n\n/** Get or create hinting engine for a font */\nfunction getHintingEngine(font: Font): HintingEngine | null {\n\tif (!font.isTrueType || !font.hasHinting) return null;\n\n\tlet engine = hintingEngineCache.get(font);\n\tif (engine) return engine;\n\n\tconst cvt = font.cvtTable;\n\tconst cvtValues = cvt ? new Int32Array(cvt.values) : undefined;\n\n\tconst maxp = font.maxp;\n\tengine = createHintingEngine(\n\t\tfont.unitsPerEm,\n\t\t\"maxStackElements\" in maxp ? maxp.maxStackElements : 256,\n\t\t\"maxStorage\" in maxp ? maxp.maxStorage : 64,\n\t\t\"maxFunctionDefs\" in maxp ? maxp.maxFunctionDefs : 64,\n\t\t\"maxTwilightPoints\" in maxp ? maxp.maxTwilightPoints : 16,\n\t\tcvtValues,\n\t);\n\n\tconst fpgm = font.fpgm;\n\tif (fpgm) loadFontProgram(engine, fpgm.instructions);\n\n\tconst prep = font.prep;\n\tif (prep) loadCVTProgram(engine, prep.instructions);\n\n\thintingEngineCache.set(font, engine);\n\treturn engine;\n}\n\n/** Convert TrueType glyph to outline for hinting */\nfunction glyphToOutline(font: Font, glyphId: GlyphId): GlyphOutline | null {\n\tconst glyph = font.getGlyph(glyphId);\n\tif (!glyph || glyph.type === \"empty\") return null;\n\n\tconst xCoords: number[] = [];\n\tconst yCoords: number[] = [];\n\tconst flags: number[] = [];\n\tconst contourEnds: number[] = [];\n\n\t// Get metrics for phantom points\n\tconst advanceWidth = font.advanceWidth(glyphId);\n\tconst lsb = font.leftSideBearing(glyphId);\n\n\tif (glyph.type === \"simple\") {\n\t\tlet pointIndex = 0;\n\t\tfor (const contour of glyph.contours) {\n\t\t\tfor (const point of contour) {\n\t\t\t\txCoords.push(point.x);\n\t\t\t\tyCoords.push(point.y);\n\t\t\t\tflags.push(point.onCurve ? 1 : 0);\n\t\t\t\tpointIndex++;\n\t\t\t}\n\t\t\tcontourEnds.push(pointIndex - 1);\n\t\t}\n\t\treturn {\n\t\t\txCoords,\n\t\t\tyCoords,\n\t\t\tflags: new Uint8Array(flags),\n\t\t\tcontourEnds,\n\t\t\tinstructions: glyph.instructions,\n\t\t\tlsb,\n\t\t\tadvanceWidth,\n\t\t};\n\t} else {\n\t\t// Composite - flatten components\n\t\tfor (const component of glyph.components) {\n\t\t\tconst compGlyph = font.getGlyph(component.glyphId);\n\t\t\tif (!compGlyph || compGlyph.type !== \"simple\") continue;\n\n\t\t\tconst [a, b, c, d] = component.transform;\n\t\t\tconst ox = component.arg1,\n\t\t\t\toy = component.arg2;\n\t\t\tlet pointOffset = xCoords.length;\n\n\t\t\tfor (const contour of compGlyph.contours) {\n\t\t\t\tfor (const point of contour) {\n\t\t\t\t\txCoords.push(point.x * a + point.y * c + ox);\n\t\t\t\t\tyCoords.push(point.x * b + point.y * d + oy);\n\t\t\t\t\tflags.push(point.onCurve ? 1 : 0);\n\t\t\t\t\tpointOffset++;\n\t\t\t\t}\n\t\t\t\tcontourEnds.push(pointOffset - 1);\n\t\t\t}\n\t\t}\n\t\tif (xCoords.length === 0) return null;\n\t\treturn {\n\t\t\txCoords,\n\t\t\tyCoords,\n\t\t\tflags: new Uint8Array(flags),\n\t\t\tcontourEnds,\n\t\t\tinstructions: glyph.instructions,\n\t\t\tlsb,\n\t\t\tadvanceWidth,\n\t\t};\n\t}\n}\n\n/** Decompose hinted glyph to rasterizer */\nfunction decomposeHintedGlyph(\n\traster: GrayRaster,\n\thinted: HintedGlyph,\n\toffsetX: number,\n\toffsetY: number,\n): void {\n\tconst { xCoords, yCoords, flags, contourEnds } = hinted;\n\tlet contourIdx = 0,\n\t\tcontourStart = 0;\n\n\tfor (let i = 0; i < xCoords.length; i++) {\n\t\tconst isEnd = i === contourEnds[contourIdx];\n\t\t// Convert 26.6 to rasterizer format (shift left 2 for 26.8)\n\t\tconst x = ((xCoords[i] << 2) | 0) + (offsetX << 8);\n\t\tconst y = ((-yCoords[i] << 2) | 0) + (offsetY << 8); // Flip Y\n\t\tconst onCurve = (flags[i] & 1) !== 0;\n\n\t\tif (i === contourStart) {\n\t\t\traster.moveTo(x, y);\n\t\t} else if (onCurve) {\n\t\t\traster.lineTo(x, y);\n\t\t} else {\n\t\t\tconst nextIdx = isEnd ? contourStart : i + 1;\n\t\t\tconst nx = ((xCoords[nextIdx] << 2) | 0) + (offsetX << 8);\n\t\t\tconst ny = ((-yCoords[nextIdx] << 2) | 0) + (offsetY << 8);\n\t\t\tconst nextOn = (flags[nextIdx] & 1) !== 0;\n\n\t\t\tif (nextOn) {\n\t\t\t\traster.conicTo(x, y, nx, ny);\n\t\t\t\tif (!isEnd) i++;\n\t\t\t} else {\n\t\t\t\traster.conicTo(x, y, (x + nx) >> 1, (y + ny) >> 1);\n\t\t\t}\n\t\t}\n\n\t\tif (isEnd) {\n\t\t\tconst sx = ((xCoords[contourStart] << 2) | 0) + (offsetX << 8);\n\t\t\tconst sy = ((-yCoords[contourStart] << 2) | 0) + (offsetY << 8);\n\t\t\tif (onCurve && i !== contourStart) raster.lineTo(sx, sy);\n\t\t\tcontourIdx++;\n\t\t\tcontourStart = i + 1;\n\t\t}\n\t}\n}\n\n/** Threshold for using band processing (height in pixels) */\nconst BAND_PROCESSING_THRESHOLD = 256;\n\n/**\n * Rasterize a glyph path to a bitmap\n */\nexport function rasterizePath(\n\tpath: GlyphPath,\n\toptions: RasterizeOptions,\n): Bitmap {\n\tconst {\n\t\twidth,\n\t\theight,\n\t\tscale,\n\t\toffsetX = 0,\n\t\toffsetY = 0,\n\t\tpixelMode = PixelMode.Gray,\n\t\tfillRule = FillRule.NonZero,\n\t\tflipY = true,\n\t} = options;\n\n\t// Create bitmap\n\tconst bitmap = createBitmap(width, height, pixelMode);\n\n\t// Create rasterizer\n\tconst raster = new GrayRaster();\n\traster.setClip(0, 0, width, height);\n\n\t// Use band processing for large glyphs to ensure bounded memory\n\tif (height > BAND_PROCESSING_THRESHOLD) {\n\t\tconst decomposeFn = () =>\n\t\t\tdecomposePath(raster, path, scale, offsetX, offsetY, flipY);\n\t\traster.renderWithBands(\n\t\t\tbitmap,\n\t\t\tdecomposeFn,\n\t\t\t{ minY: 0, maxY: height },\n\t\t\tfillRule,\n\t\t);\n\t} else {\n\t\t// Small glyph - render in single pass with full height band\n\t\traster.setBandBounds(0, height);\n\t\traster.reset();\n\t\tdecomposePath(raster, path, scale, offsetX, offsetY, flipY);\n\t\traster.sweep(bitmap, fillRule);\n\t}\n\n\treturn bitmap;\n}\n\n/**\n * Rasterize a glyph from a font\n */\nexport function rasterizeGlyph(\n\tfont: Font,\n\tglyphId: GlyphId,\n\tfontSize: number,\n\toptions?: {\n\t\tpixelMode?: PixelMode;\n\t\tpadding?: number;\n\t\t/** Use TrueType hinting if available */\n\t\thinting?: boolean;\n\t},\n): RasterizedGlyph | null {\n\tconst padding = options?.padding ?? 1;\n\tconst pixelMode = options?.pixelMode ?? PixelMode.Gray;\n\tconst useHinting = options?.hinting ?? false;\n\n\t// Try hinted rendering if requested\n\tif (useHinting && font.hasHinting) {\n\t\tconst result = rasterizeHintedGlyph(\n\t\t\tfont,\n\t\t\tglyphId,\n\t\t\tfontSize,\n\t\t\tpadding,\n\t\t\tpixelMode,\n\t\t);\n\t\tif (result) return result;\n\t}\n\n\t// Fall back to unhinted rendering\n\tconst path = getGlyphPath(font, glyphId);\n\tif (!path) return null;\n\n\tconst scale = fontSize / font.unitsPerEm;\n\n\t// Get bounds\n\tconst bounds = getPathBounds(path, scale, true);\n\tif (!bounds) {\n\t\treturn {\n\t\t\tbitmap: createBitmap(1, 1, pixelMode),\n\t\t\tbearingX: 0,\n\t\t\tbearingY: 0,\n\t\t};\n\t}\n\n\tconst width = bounds.maxX - bounds.minX + padding * 2;\n\tconst height = bounds.maxY - bounds.minY + padding * 2;\n\n\tif (width <= 0 || height <= 0) {\n\t\treturn {\n\t\t\tbitmap: createBitmap(1, 1, pixelMode),\n\t\t\tbearingX: 0,\n\t\t\tbearingY: 0,\n\t\t};\n\t}\n\n\tconst offsetX = -bounds.minX + padding;\n\tconst offsetY = -bounds.minY + padding;\n\n\tconst bitmap = rasterizePath(path, {\n\t\twidth,\n\t\theight,\n\t\tscale,\n\t\toffsetX,\n\t\toffsetY,\n\t\tpixelMode,\n\t\tflipY: true,\n\t});\n\n\treturn {\n\t\tbitmap,\n\t\tbearingX: bounds.minX - padding,\n\t\tbearingY: -(bounds.minY - padding),\n\t};\n}\n\n/** Rasterize a glyph with TrueType hinting */\nfunction rasterizeHintedGlyph(\n\tfont: Font,\n\tglyphId: GlyphId,\n\tfontSize: number,\n\tpadding: number,\n\tpixelMode: PixelMode,\n): RasterizedGlyph | null {\n\tconst engine = getHintingEngine(font);\n\tif (!engine) return null;\n\n\tconst outline = glyphToOutline(font, glyphId);\n\tif (!outline) return null;\n\n\tconst ppem = Math.round(fontSize);\n\tconst error = setSize(engine, ppem, ppem);\n\tif (error) return null;\n\n\tconst hinted = hintGlyph(engine, outline);\n\tif (hinted.error || hinted.xCoords.length === 0) return null;\n\n\t// Calculate bounds from hinted coordinates (26.6 fixed point)\n\tlet minX = Infinity,\n\t\tminY = Infinity,\n\t\tmaxX = -Infinity,\n\t\tmaxY = -Infinity;\n\tfor (let i = 0; i < hinted.xCoords.length; i++) {\n\t\tconst x = hinted.xCoords[i] / 64;\n\t\tconst y = hinted.yCoords[i] / 64;\n\t\tminX = Math.min(minX, x);\n\t\tminY = Math.min(minY, y);\n\t\tmaxX = Math.max(maxX, x);\n\t\tmaxY = Math.max(maxY, y);\n\t}\n\n\tif (!Number.isFinite(minX)) {\n\t\treturn { bitmap: createBitmap(1, 1, pixelMode), bearingX: 0, bearingY: 0 };\n\t}\n\n\tconst bMinX = Math.floor(minX),\n\t\tbMinY = Math.floor(minY);\n\tconst bMaxX = Math.ceil(maxX),\n\t\tbMaxY = Math.ceil(maxY);\n\tconst width = bMaxX - bMinX + padding * 2;\n\tconst height = bMaxY - bMinY + padding * 2;\n\n\tif (width <= 0 || height <= 0) {\n\t\treturn { bitmap: createBitmap(1, 1, pixelMode), bearingX: 0, bearingY: 0 };\n\t}\n\n\tconst bitmap = createBitmap(width, height, pixelMode);\n\tconst raster = new GrayRaster();\n\traster.setClip(0, 0, width, height);\n\traster.reset();\n\n\tconst offsetX = -bMinX + padding;\n\tconst offsetY = height - 1 + bMinY - padding;\n\n\tdecomposeHintedGlyph(raster, hinted, offsetX, offsetY);\n\traster.sweep(bitmap, FillRule.NonZero);\n\n\treturn {\n\t\tbitmap,\n\t\tbearingX: bMinX - padding,\n\t\tbearingY: bMaxY + padding,\n\t};\n}\n\n/**\n * Rasterize text string using shaped glyphs\n */\nexport function rasterizeText(\n\tfont: Font,\n\ttext: string,\n\tfontSize: number,\n\toptions?: {\n\t\tpixelMode?: PixelMode;\n\t\tpadding?: number;\n\t},\n): Bitmap | null {\n\t// This would integrate with the shaper\n\t// For now, simple glyph-by-glyph rendering\n\n\tconst scale = fontSize / font.unitsPerEm;\n\tconst padding = options?.padding ?? 2;\n\tconst pixelMode = options?.pixelMode ?? PixelMode.Gray;\n\n\t// Get glyphs for text\n\tconst glyphs: { glyphId: GlyphId; advance: number }[] = [];\n\tlet totalAdvance = 0;\n\tlet maxAscent = 0;\n\tlet maxDescent = 0;\n\n\tfor (const char of text) {\n\t\tconst codepoint = char.codePointAt(0);\n\t\tif (codepoint === undefined) continue;\n\n\t\tconst glyphId = font.glyphId(codepoint);\n\t\tif (glyphId === undefined) continue;\n\n\t\tconst advance = font.advanceWidth(glyphId) * scale;\n\t\tconst path = getGlyphPath(font, glyphId);\n\n\t\tif (path?.bounds) {\n\t\t\tmaxAscent = Math.max(maxAscent, -path.bounds.yMin * scale);\n\t\t\tmaxDescent = Math.max(maxDescent, path.bounds.yMax * scale);\n\t\t}\n\n\t\tglyphs.push({ glyphId, advance });\n\t\ttotalAdvance += advance;\n\t}\n\n\tif (glyphs.length === 0) return null;\n\n\t// Create bitmap\n\tconst width = Math.ceil(totalAdvance) + padding * 2;\n\tconst height = Math.ceil(maxAscent + maxDescent) + padding * 2;\n\n\tconst bitmap = createBitmap(width, height, pixelMode);\n\tconst raster = new GrayRaster();\n\traster.setClip(0, 0, width, height);\n\n\t// Render each glyph\n\tlet x = padding;\n\tconst baseline = maxDescent + padding;\n\n\tfor (const { glyphId, advance } of glyphs) {\n\t\tconst path = getGlyphPath(font, glyphId);\n\t\tif (path) {\n\t\t\traster.reset();\n\t\t\tdecomposePath(raster, path, scale, x, baseline, true);\n\t\t\traster.sweep(bitmap);\n\t\t}\n\t\tx += advance;\n\t}\n\n\treturn bitmap;\n}\n\n/**\n * Export bitmap to raw RGBA pixels (for WebGL textures, etc.)\n */\nexport function bitmapToRGBA(bitmap: Bitmap): Uint8Array {\n\t// bitmap.width is always the pixel width\n\t// For LCD mode, pitch = width * 3 (3 bytes per pixel for R, G, B subpixels)\n\tconst isLCD = bitmap.pixelMode === PixelMode.LCD;\n\tconst rgba = new Uint8Array(bitmap.width * bitmap.rows * 4);\n\n\tfor (let y = 0; y < bitmap.rows; y++) {\n\t\tfor (let x = 0; x < bitmap.width; x++) {\n\t\t\tconst dstIdx = (y * bitmap.width + x) * 4;\n\n\t\t\tif (bitmap.pixelMode === PixelMode.Gray) {\n\t\t\t\tconst srcIdx = y * bitmap.pitch + x;\n\t\t\t\tconst alpha = bitmap.buffer[srcIdx] ?? 0;\n\t\t\t\t// Black text on white background\n\t\t\t\trgba[dstIdx] = 255 - alpha;\n\t\t\t\trgba[dstIdx + 1] = 255 - alpha;\n\t\t\t\trgba[dstIdx + 2] = 255 - alpha;\n\t\t\t\trgba[dstIdx + 3] = 255;\n\t\t\t} else if (bitmap.pixelMode === PixelMode.Mono) {\n\t\t\t\tconst byteIdx = y * bitmap.pitch + (x >> 3);\n\t\t\t\tconst bitIdx = 7 - (x & 7);\n\t\t\t\tconst alpha = ((bitmap.buffer[byteIdx] ?? 0) >> bitIdx) & 1 ? 255 : 0;\n\t\t\t\trgba[dstIdx] = 255 - alpha;\n\t\t\t\trgba[dstIdx + 1] = 255 - alpha;\n\t\t\t\trgba[dstIdx + 2] = 255 - alpha;\n\t\t\t\trgba[dstIdx + 3] = 255;\n\t\t\t} else if (isLCD) {\n\t\t\t\t// LCD: 3 bytes per pixel (R, G, B subpixel coverage)\n\t\t\t\tconst srcIdx = y * bitmap.pitch + x * 3;\n\t\t\t\tconst r = bitmap.buffer[srcIdx] ?? 0;\n\t\t\t\tconst g = bitmap.buffer[srcIdx + 1] ?? 0;\n\t\t\t\tconst b = bitmap.buffer[srcIdx + 2] ?? 0;\n\t\t\t\t// Black text on white background with subpixel colors\n\t\t\t\trgba[dstIdx] = 255 - r;\n\t\t\t\trgba[dstIdx + 1] = 255 - g;\n\t\t\t\trgba[dstIdx + 2] = 255 - b;\n\t\t\t\trgba[dstIdx + 3] = 255;\n\t\t\t} else {\n\t\t\t\t// Fallback for other modes\n\t\t\t\tconst srcIdx = y * bitmap.pitch + x;\n\t\t\t\tconst alpha = bitmap.buffer[srcIdx] ?? 0;\n\t\t\t\trgba[dstIdx] = 255 - alpha;\n\t\t\t\trgba[dstIdx + 1] = 255 - alpha;\n\t\t\t\trgba[dstIdx + 2] = 255 - alpha;\n\t\t\t\trgba[dstIdx + 3] = 255;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn rgba;\n}\n\n/**\n * Export bitmap to grayscale array\n */\nexport function bitmapToGray(bitmap: Bitmap): Uint8Array {\n\tif (bitmap.pixelMode === PixelMode.Gray && bitmap.pitch === bitmap.width) {\n\t\treturn bitmap.buffer;\n\t}\n\n\tconst gray = new Uint8Array(bitmap.width * bitmap.rows);\n\n\tfor (let y = 0; y < bitmap.rows; y++) {\n\t\tfor (let x = 0; x < bitmap.width; x++) {\n\t\t\tconst dstIdx = y * bitmap.width + x;\n\n\t\t\tif (bitmap.pixelMode === PixelMode.Gray) {\n\t\t\t\tgray[dstIdx] = bitmap.buffer[y * bitmap.pitch + x] ?? 0;\n\t\t\t} else if (bitmap.pixelMode === PixelMode.Mono) {\n\t\t\t\tconst byteIdx = y * bitmap.pitch + (x >> 3);\n\t\t\t\tconst bitIdx = 7 - (x & 7);\n\t\t\t\tgray[dstIdx] = ((bitmap.buffer[byteIdx] ?? 0) >> bitIdx) & 1 ? 255 : 0;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn gray;\n}\n\n// Re-export bbox\nexport {\n\ttype BBox,\n\tevaluateCubic,\n\tevaluateQuadratic,\n\tgetCubicExtrema,\n\tgetExactBounds,\n\tgetQuadraticExtrema,\n} from \"./bbox.ts\";\n// Re-export bitmap utilities\nexport {\n\tblendBitmap,\n\tconvertBitmap,\n\tcopyBitmap,\n\temboldenBitmap,\n\tresizeBitmap,\n} from \"./bitmap-utils.ts\";\n// Re-export blur filters\nexport {\n\tblurBitmap,\n\tboxBlur,\n\tcreateGaussianKernel,\n\tgaussianBlur,\n} from \"./blur.ts\";\n// Re-export gradient\nexport {\n\ttype ColorStop,\n\tcreateGradientBitmap,\n\ttype Gradient,\n\tinterpolateGradient,\n\ttype LinearGradient,\n\ttype RadialGradient,\n\trasterizePathWithGradient,\n} from \"./gradient.ts\";\n// Re-export SDF\nexport { renderSdf, type SdfOptions } from \"./sdf.ts\";\n// Re-export stroker\nexport {\n\ttype LineCap,\n\ttype LineJoin,\n\ttype StrokerOptions,\n\tstrokePath,\n} from \"./stroker.ts\";\n// Re-export synthetic effects\nexport {\n\tcondensePath,\n\temboldenPath,\n\tobliquePath,\n\ttransformPath,\n} from \"./synth.ts\";\n// Re-export types\nexport {\n\ttype Bitmap,\n\tclearBitmap,\n\tcreateBitmap,\n\tFillRule,\n\tPixelMode,\n\ttype RasterizedGlyph,\n\ttype RasterizeOptions,\n\ttype Span,\n} from \"./types.ts\";\n",
87
- "import type { GlyphInfo } from \"../types.ts\";\n\n/**\n * Normalization mode for shaping\n */\nexport enum NormalizationMode {\n\t/** No normalization */\n\tNone = 0,\n\t/** Decompose (NFD-like) */\n\tDecompose = 1,\n\t/** Compose (NFC-like) */\n\tCompose = 2,\n\t/** Auto-detect based on script */\n\tAuto = 3,\n}\n\n/**\n * Canonical Combining Class (ccc) for combining marks\n * Based on Unicode 15.0\n */\nexport function getCombiningClass(cp: number): number {\n\t// Common combining classes\n\t// 0 = Not_Reordered (base characters, most characters)\n\t// 1 = Overlay\n\t// 7 = Nukta\n\t// 8 = Kana_Voicing\n\t// 9 = Virama\n\t// 200-240 = Various marks\n\n\t// Hebrew combining marks (0591-05BD, 05BF, 05C1-05C2, 05C4-05C5, 05C7)\n\tif (cp >= 0x0591 && cp <= 0x05bd) return getHebrewCcc(cp);\n\tif (cp === 0x05bf) return 23;\n\tif (cp === 0x05c1) return 24;\n\tif (cp === 0x05c2) return 25;\n\tif (cp === 0x05c4) return 230;\n\tif (cp === 0x05c5) return 220;\n\tif (cp === 0x05c7) return 18;\n\n\t// Arabic combining marks (064B-065F, 0670)\n\tif (cp >= 0x064b && cp <= 0x065f) return getArabicCcc(cp);\n\tif (cp === 0x0670) return 35;\n\t// Extended Arabic marks\n\tif (cp >= 0x0610 && cp <= 0x061a) return 230;\n\tif (cp >= 0x06d6 && cp <= 0x06dc) return 230;\n\tif (cp >= 0x06df && cp <= 0x06e4) return 230;\n\tif (cp >= 0x06e7 && cp <= 0x06e8) return 230;\n\tif (cp >= 0x06ea && cp <= 0x06ed) return 220;\n\tif (cp === 0x08d4) return 230;\n\tif (cp >= 0x08e3 && cp <= 0x08ff) return 220;\n\n\t// Devanagari nukta and signs\n\tif (cp === 0x093c) return 7; // Nukta\n\tif (cp === 0x094d) return 9; // Virama\n\tif (cp >= 0x0951 && cp <= 0x0954) return 230; // Accent marks\n\tif (cp === 0x0955) return 0;\n\tif (cp >= 0x0956 && cp <= 0x0957) return 0;\n\n\t// Bengali nukta and virama\n\tif (cp === 0x09bc) return 7;\n\tif (cp === 0x09cd) return 9;\n\tif (cp === 0x09fe) return 230;\n\n\t// Gurmukhi\n\tif (cp === 0x0a3c) return 7; // Nukta\n\tif (cp === 0x0a4d) return 9; // Virama\n\n\t// Gujarati\n\tif (cp === 0x0abc) return 7; // Nukta\n\tif (cp === 0x0acd) return 9; // Virama\n\n\t// Oriya\n\tif (cp === 0x0b3c) return 7; // Nukta\n\tif (cp === 0x0b4d) return 9; // Virama\n\n\t// Tamil\n\tif (cp === 0x0bcd) return 9; // Virama\n\n\t// Telugu\n\tif (cp === 0x0c4d) return 9; // Virama\n\tif (cp === 0x0c55) return 84;\n\tif (cp === 0x0c56) return 91;\n\n\t// Kannada\n\tif (cp === 0x0cbc) return 7; // Nukta\n\tif (cp === 0x0ccd) return 9; // Virama\n\n\t// Malayalam\n\tif (cp === 0x0d4d) return 9; // Virama\n\n\t// Sinhala\n\tif (cp === 0x0dca) return 9; // Virama\n\n\t// Thai/Lao vowels and tone marks\n\tif (cp >= 0x0e31 && cp <= 0x0e3a) return 0; // Positioned, not reordered\n\tif (cp >= 0x0e47 && cp <= 0x0e4e) return getThaiCcc(cp);\n\tif (cp >= 0x0eb1 && cp <= 0x0ebc) return 0;\n\tif (cp >= 0x0ec8 && cp <= 0x0ecd) return getThaiCcc(cp);\n\n\t// Tibetan\n\tif (cp >= 0x0f18 && cp <= 0x0f19) return 220;\n\tif (cp === 0x0f35) return 220;\n\tif (cp === 0x0f37) return 220;\n\tif (cp === 0x0f39) return 216;\n\tif (cp >= 0x0f71 && cp <= 0x0f7e) return getTibetanCcc(cp);\n\tif (cp >= 0x0f80 && cp <= 0x0f84) return getTibetanCcc(cp);\n\tif (cp >= 0x0f86 && cp <= 0x0f87) return 230;\n\n\t// Myanmar\n\tif (cp === 0x1037) return 7; // Nukta\n\tif (cp === 0x1039) return 9; // Virama\n\tif (cp === 0x103a) return 9;\n\n\t// Hangul Jamo (combining)\n\tif (cp >= 0x302a && cp <= 0x302f) return getHangulCcc(cp);\n\tif (cp >= 0x3099 && cp <= 0x309a) return 8; // Kana voicing\n\n\t// General combining marks (0300-036F)\n\tif (cp >= 0x0300 && cp <= 0x036f) return getLatinCcc(cp);\n\n\t// Combining Diacritical Marks Extended (1AB0-1AFF)\n\tif (cp >= 0x1ab0 && cp <= 0x1aff) return getCdmeClass(cp);\n\n\t// Combining Diacritical Marks Supplement (1DC0-1DFF)\n\tif (cp >= 0x1dc0 && cp <= 0x1dff) return getCdmsClass(cp);\n\n\t// Combining Half Marks (FE20-FE2F)\n\tif (cp >= 0xfe20 && cp <= 0xfe2f) return 230;\n\n\treturn 0;\n}\n\nfunction getThaiCcc(cp: number): number {\n\t// Thai tone marks and vowel signs above\n\tif (cp >= 0x0e48 && cp <= 0x0e4b) return 107; // Tone marks\n\tif (cp === 0x0e4c) return 0; // Thanthakhat\n\tif (cp === 0x0e4d) return 0; // Nikhahit\n\tif (cp === 0x0e4e) return 0; // Yamakkan\n\t// Lao tone marks\n\tif (cp >= 0x0ec8 && cp <= 0x0ecb) return 122;\n\treturn 0;\n}\n\nfunction getTibetanCcc(cp: number): number {\n\tif (cp === 0x0f71) return 129;\n\tif (cp === 0x0f72) return 130;\n\tif (cp === 0x0f73) return 0; // Composed\n\tif (cp === 0x0f74) return 132;\n\tif (cp === 0x0f75) return 0; // Composed\n\tif (cp === 0x0f76) return 0; // Composed\n\tif (cp === 0x0f77) return 0; // Composed\n\tif (cp === 0x0f78) return 0; // Composed\n\tif (cp === 0x0f79) return 0; // Composed\n\tif (cp === 0x0f7a) return 130;\n\tif (cp === 0x0f7b) return 130;\n\tif (cp === 0x0f7c) return 130;\n\tif (cp === 0x0f7d) return 130;\n\tif (cp === 0x0f7e) return 0;\n\tif (cp === 0x0f80) return 130;\n\tif (cp === 0x0f81) return 0; // Composed\n\tif (cp === 0x0f82) return 230;\n\tif (cp === 0x0f83) return 230;\n\tif (cp === 0x0f84) return 9;\n\treturn 0;\n}\n\nfunction getHangulCcc(cp: number): number {\n\tif (cp === 0x302a) return 218;\n\tif (cp === 0x302b) return 228;\n\tif (cp === 0x302c) return 232;\n\tif (cp === 0x302d) return 222;\n\tif (cp === 0x302e) return 224;\n\tif (cp === 0x302f) return 224;\n\treturn 0;\n}\n\nfunction getCdmeClass(cp: number): number {\n\t// Combining Diacritical Marks Extended\n\tif (cp >= 0x1ab0 && cp <= 0x1abe) return 230;\n\tif (cp === 0x1abf) return 220;\n\tif (cp === 0x1ac0) return 220;\n\treturn 230;\n}\n\nfunction getCdmsClass(cp: number): number {\n\t// Combining Diacritical Marks Supplement\n\tif (cp >= 0x1dc0 && cp <= 0x1dc1) return 230;\n\tif (cp === 0x1dc2) return 220;\n\tif (cp >= 0x1dc3 && cp <= 0x1dca) return 230;\n\tif (cp === 0x1dcb) return 230;\n\tif (cp === 0x1dcc) return 230;\n\tif (cp === 0x1dcd) return 234;\n\tif (cp === 0x1dce) return 214;\n\tif (cp === 0x1dcf) return 220;\n\tif (cp === 0x1dd0) return 202;\n\tif (cp >= 0x1dd1 && cp <= 0x1df5) return 230;\n\tif (cp >= 0x1df6 && cp <= 0x1df8) return 232;\n\tif (cp === 0x1df9) return 220;\n\tif (cp === 0x1dfa) return 218;\n\tif (cp >= 0x1dfb && cp <= 0x1dff) return 230;\n\treturn 230;\n}\n\nfunction getHebrewCcc(cp: number): number {\n\t// Hebrew accents and marks have specific combining classes\n\tif (cp >= 0x0591 && cp <= 0x05a1) return 220; // Below marks\n\tif (cp >= 0x05a2 && cp <= 0x05af) return 230; // Above marks\n\tif (cp >= 0x05b0 && cp <= 0x05b9) {\n\t\t// Vowel points\n\t\tif (cp === 0x05b0) return 10; // Sheva\n\t\tif (cp === 0x05b1) return 11; // Hataf Segol\n\t\tif (cp === 0x05b2) return 12; // Hataf Patah\n\t\tif (cp === 0x05b3) return 13; // Hataf Qamats\n\t\tif (cp === 0x05b4) return 14; // Hiriq\n\t\tif (cp === 0x05b5) return 15; // Tsere\n\t\tif (cp === 0x05b6) return 16; // Segol\n\t\tif (cp === 0x05b7) return 17; // Patah\n\t\tif (cp === 0x05b8) return 18; // Qamats\n\t\tif (cp === 0x05b9) return 19; // Holam\n\t}\n\tif (cp === 0x05ba) return 19; // Holam Haser\n\tif (cp === 0x05bb) return 20; // Qubuts\n\tif (cp === 0x05bc) return 21; // Dagesh\n\tif (cp === 0x05bd) return 22; // Meteg\n\treturn 0;\n}\n\nfunction getArabicCcc(cp: number): number {\n\tif (cp === 0x064b) return 27; // Fathatan\n\tif (cp === 0x064c) return 28; // Dammatan\n\tif (cp === 0x064d) return 29; // Kasratan\n\tif (cp === 0x064e) return 30; // Fatha\n\tif (cp === 0x064f) return 31; // Damma\n\tif (cp === 0x0650) return 32; // Kasra\n\tif (cp === 0x0651) return 33; // Shadda\n\tif (cp === 0x0652) return 34; // Sukun\n\tif (cp >= 0x0653 && cp <= 0x0655) return 230; // Maddah, Hamza above\n\tif (cp === 0x0656) return 220; // Subscript Alef\n\tif (cp === 0x0657) return 230; // Inverted Damma\n\tif (cp === 0x0658) return 230; // Mark Noon Ghunna\n\tif (cp >= 0x0659 && cp <= 0x065f) return 230;\n\treturn 0;\n}\n\nfunction getLatinCcc(cp: number): number {\n\t// Combining diacritical marks\n\tif (cp >= 0x0300 && cp <= 0x0314) return 230; // Above marks\n\tif (cp >= 0x0315 && cp <= 0x0315) return 232; // Above right\n\tif (cp >= 0x0316 && cp <= 0x0319) return 220; // Below marks\n\tif (cp >= 0x031a && cp <= 0x031a) return 232; // Above right\n\tif (cp >= 0x031b && cp <= 0x031b) return 216; // Attached above right\n\tif (cp >= 0x031c && cp <= 0x0320) return 220; // Below\n\tif (cp >= 0x0321 && cp <= 0x0322) return 202; // Attached below\n\tif (cp >= 0x0323 && cp <= 0x0326) return 220; // Below\n\tif (cp >= 0x0327 && cp <= 0x0328) return 202; // Attached below\n\tif (cp >= 0x0329 && cp <= 0x0333) return 220; // Below\n\tif (cp >= 0x0334 && cp <= 0x0338) return 1; // Overlay\n\tif (cp >= 0x0339 && cp <= 0x033c) return 220; // Below\n\tif (cp >= 0x033d && cp <= 0x0344) return 230; // Above\n\tif (cp === 0x0345) return 240; // Iota subscript\n\tif (cp >= 0x0346 && cp <= 0x034e) return 230; // Above\n\tif (cp === 0x034f) return 0; // CGJ\n\tif (cp >= 0x0350 && cp <= 0x0352) return 230; // Above\n\tif (cp >= 0x0353 && cp <= 0x0356) return 220; // Below\n\tif (cp >= 0x0357 && cp <= 0x0358) return 230; // Above\n\tif (cp >= 0x0359 && cp <= 0x035a) return 220; // Below\n\tif (cp >= 0x035b && cp <= 0x035b) return 230; // Above\n\tif (cp >= 0x035c && cp <= 0x035c) return 233; // Double below\n\tif (cp >= 0x035d && cp <= 0x035e) return 234; // Double above\n\tif (cp >= 0x035f && cp <= 0x035f) return 233; // Double below\n\tif (cp >= 0x0360 && cp <= 0x0361) return 234; // Double above\n\tif (cp >= 0x0362 && cp <= 0x0362) return 233; // Double below\n\tif (cp >= 0x0363 && cp <= 0x036f) return 230; // Above\n\treturn 0;\n}\n\n/**\n * Reorder combining marks according to canonical combining class\n */\nexport function reorderMarks(infos: GlyphInfo[]): void {\n\t// Simple bubble sort for stability (marks with same ccc keep order)\n\tconst n = infos.length;\n\tlet i = 1;\n\n\twhile (i < n) {\n\t\tconst info = infos[i];\n\t\tif (!info) {\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst ccc = getCombiningClass(info.codepoint);\n\t\tif (ccc === 0) {\n\t\t\t// Non-combining, advance\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Look backward for marks to reorder with\n\t\tlet j = i;\n\t\twhile (j > 0) {\n\t\t\tconst prevInfo = infos[j - 1];\n\t\t\tif (!prevInfo) break;\n\n\t\t\tconst prevCcc = getCombiningClass(prevInfo.codepoint);\n\t\t\tif (prevCcc === 0) break; // Hit a base character\n\t\t\tif (prevCcc <= ccc) break; // Already in order\n\n\t\t\t// Swap\n\t\t\tinfos[j] = prevInfo;\n\t\t\tinfos[j - 1] = info;\n\t\t\tj--;\n\t\t}\n\n\t\ti++;\n\t}\n}\n\n/**\n * Common decomposition mappings (subset of Unicode decomposition)\n */\nconst DECOMPOSITIONS: Map<number, number[]> = new Map([\n\t// Latin precomposed characters (Latin-1 Supplement)\n\t[0x00c0, [0x0041, 0x0300]], // À = A + grave\n\t[0x00c1, [0x0041, 0x0301]], // Á = A + acute\n\t[0x00c2, [0x0041, 0x0302]], // Â = A + circumflex\n\t[0x00c3, [0x0041, 0x0303]], // Ã = A + tilde\n\t[0x00c4, [0x0041, 0x0308]], // Ä = A + diaeresis\n\t[0x00c5, [0x0041, 0x030a]], // Å = A + ring\n\t[0x00c7, [0x0043, 0x0327]], // Ç = C + cedilla\n\t[0x00c8, [0x0045, 0x0300]], // È = E + grave\n\t[0x00c9, [0x0045, 0x0301]], // É = E + acute\n\t[0x00ca, [0x0045, 0x0302]], // Ê = E + circumflex\n\t[0x00cb, [0x0045, 0x0308]], // Ë = E + diaeresis\n\t[0x00cc, [0x0049, 0x0300]], // Ì = I + grave\n\t[0x00cd, [0x0049, 0x0301]], // Í = I + acute\n\t[0x00ce, [0x0049, 0x0302]], // Î = I + circumflex\n\t[0x00cf, [0x0049, 0x0308]], // Ï = I + diaeresis\n\t[0x00d1, [0x004e, 0x0303]], // Ñ = N + tilde\n\t[0x00d2, [0x004f, 0x0300]], // Ò = O + grave\n\t[0x00d3, [0x004f, 0x0301]], // Ó = O + acute\n\t[0x00d4, [0x004f, 0x0302]], // Ô = O + circumflex\n\t[0x00d5, [0x004f, 0x0303]], // Õ = O + tilde\n\t[0x00d6, [0x004f, 0x0308]], // Ö = O + diaeresis\n\t[0x00d9, [0x0055, 0x0300]], // Ù = U + grave\n\t[0x00da, [0x0055, 0x0301]], // Ú = U + acute\n\t[0x00db, [0x0055, 0x0302]], // Û = U + circumflex\n\t[0x00dc, [0x0055, 0x0308]], // Ü = U + diaeresis\n\t[0x00dd, [0x0059, 0x0301]], // Ý = Y + acute\n\t// Lowercase Latin-1\n\t[0x00e0, [0x0061, 0x0300]], // à = a + grave\n\t[0x00e1, [0x0061, 0x0301]], // á = a + acute\n\t[0x00e2, [0x0061, 0x0302]], // â = a + circumflex\n\t[0x00e3, [0x0061, 0x0303]], // ã = a + tilde\n\t[0x00e4, [0x0061, 0x0308]], // ä = a + diaeresis\n\t[0x00e5, [0x0061, 0x030a]], // å = a + ring\n\t[0x00e7, [0x0063, 0x0327]], // ç = c + cedilla\n\t[0x00e8, [0x0065, 0x0300]], // è = e + grave\n\t[0x00e9, [0x0065, 0x0301]], // é = e + acute\n\t[0x00ea, [0x0065, 0x0302]], // ê = e + circumflex\n\t[0x00eb, [0x0065, 0x0308]], // ë = e + diaeresis\n\t[0x00ec, [0x0069, 0x0300]], // ì = i + grave\n\t[0x00ed, [0x0069, 0x0301]], // í = i + acute\n\t[0x00ee, [0x0069, 0x0302]], // î = i + circumflex\n\t[0x00ef, [0x0069, 0x0308]], // ï = i + diaeresis\n\t[0x00f1, [0x006e, 0x0303]], // ñ = n + tilde\n\t[0x00f2, [0x006f, 0x0300]], // ò = o + grave\n\t[0x00f3, [0x006f, 0x0301]], // ó = o + acute\n\t[0x00f4, [0x006f, 0x0302]], // ô = o + circumflex\n\t[0x00f5, [0x006f, 0x0303]], // õ = o + tilde\n\t[0x00f6, [0x006f, 0x0308]], // ö = o + diaeresis\n\t[0x00f9, [0x0075, 0x0300]], // ù = u + grave\n\t[0x00fa, [0x0075, 0x0301]], // ú = u + acute\n\t[0x00fb, [0x0075, 0x0302]], // û = u + circumflex\n\t[0x00fc, [0x0075, 0x0308]], // ü = u + diaeresis\n\t[0x00fd, [0x0079, 0x0301]], // ý = y + acute\n\t[0x00ff, [0x0079, 0x0308]], // ÿ = y + diaeresis\n\t// Latin Extended-A\n\t[0x0100, [0x0041, 0x0304]], // Ā = A + macron\n\t[0x0101, [0x0061, 0x0304]], // ā = a + macron\n\t[0x0102, [0x0041, 0x0306]], // Ă = A + breve\n\t[0x0103, [0x0061, 0x0306]], // ă = a + breve\n\t[0x0104, [0x0041, 0x0328]], // Ą = A + ogonek\n\t[0x0105, [0x0061, 0x0328]], // ą = a + ogonek\n\t[0x0106, [0x0043, 0x0301]], // Ć = C + acute\n\t[0x0107, [0x0063, 0x0301]], // ć = c + acute\n\t[0x0108, [0x0043, 0x0302]], // Ĉ = C + circumflex\n\t[0x0109, [0x0063, 0x0302]], // ĉ = c + circumflex\n\t[0x010a, [0x0043, 0x0307]], // Ċ = C + dot above\n\t[0x010b, [0x0063, 0x0307]], // ċ = c + dot above\n\t[0x010c, [0x0043, 0x030c]], // Č = C + caron\n\t[0x010d, [0x0063, 0x030c]], // č = c + caron\n\t[0x010e, [0x0044, 0x030c]], // Ď = D + caron\n\t[0x010f, [0x0064, 0x030c]], // ď = d + caron\n\t[0x0112, [0x0045, 0x0304]], // Ē = E + macron\n\t[0x0113, [0x0065, 0x0304]], // ē = e + macron\n\t[0x0114, [0x0045, 0x0306]], // Ĕ = E + breve\n\t[0x0115, [0x0065, 0x0306]], // ĕ = e + breve\n\t[0x0116, [0x0045, 0x0307]], // Ė = E + dot above\n\t[0x0117, [0x0065, 0x0307]], // ė = e + dot above\n\t[0x0118, [0x0045, 0x0328]], // Ę = E + ogonek\n\t[0x0119, [0x0065, 0x0328]], // ę = e + ogonek\n\t[0x011a, [0x0045, 0x030c]], // Ě = E + caron\n\t[0x011b, [0x0065, 0x030c]], // ě = e + caron\n\t[0x011c, [0x0047, 0x0302]], // Ĝ = G + circumflex\n\t[0x011d, [0x0067, 0x0302]], // ĝ = g + circumflex\n\t[0x011e, [0x0047, 0x0306]], // Ğ = G + breve\n\t[0x011f, [0x0067, 0x0306]], // ğ = g + breve\n\t[0x0120, [0x0047, 0x0307]], // Ġ = G + dot above\n\t[0x0121, [0x0067, 0x0307]], // ġ = g + dot above\n\t[0x0122, [0x0047, 0x0327]], // Ģ = G + cedilla\n\t[0x0123, [0x0067, 0x0327]], // ģ = g + cedilla\n\t[0x0124, [0x0048, 0x0302]], // Ĥ = H + circumflex\n\t[0x0125, [0x0068, 0x0302]], // ĥ = h + circumflex\n\t[0x0128, [0x0049, 0x0303]], // Ĩ = I + tilde\n\t[0x0129, [0x0069, 0x0303]], // ĩ = i + tilde\n\t[0x012a, [0x0049, 0x0304]], // Ī = I + macron\n\t[0x012b, [0x0069, 0x0304]], // ī = i + macron\n\t[0x012c, [0x0049, 0x0306]], // Ĭ = I + breve\n\t[0x012d, [0x0069, 0x0306]], // ĭ = i + breve\n\t[0x012e, [0x0049, 0x0328]], // Į = I + ogonek\n\t[0x012f, [0x0069, 0x0328]], // į = i + ogonek\n\t[0x0130, [0x0049, 0x0307]], // İ = I + dot above\n\t[0x0134, [0x004a, 0x0302]], // Ĵ = J + circumflex\n\t[0x0135, [0x006a, 0x0302]], // ĵ = j + circumflex\n\t[0x0136, [0x004b, 0x0327]], // Ķ = K + cedilla\n\t[0x0137, [0x006b, 0x0327]], // ķ = k + cedilla\n\t[0x0139, [0x004c, 0x0301]], // Ĺ = L + acute\n\t[0x013a, [0x006c, 0x0301]], // ĺ = l + acute\n\t[0x013b, [0x004c, 0x0327]], // Ļ = L + cedilla\n\t[0x013c, [0x006c, 0x0327]], // ļ = l + cedilla\n\t[0x013d, [0x004c, 0x030c]], // Ľ = L + caron\n\t[0x013e, [0x006c, 0x030c]], // ľ = l + caron\n\t[0x0143, [0x004e, 0x0301]], // Ń = N + acute\n\t[0x0144, [0x006e, 0x0301]], // ń = n + acute\n\t[0x0145, [0x004e, 0x0327]], // Ņ = N + cedilla\n\t[0x0146, [0x006e, 0x0327]], // ņ = n + cedilla\n\t[0x0147, [0x004e, 0x030c]], // Ň = N + caron\n\t[0x0148, [0x006e, 0x030c]], // ň = n + caron\n\t[0x014c, [0x004f, 0x0304]], // Ō = O + macron\n\t[0x014d, [0x006f, 0x0304]], // ō = o + macron\n\t[0x014e, [0x004f, 0x0306]], // Ŏ = O + breve\n\t[0x014f, [0x006f, 0x0306]], // ŏ = o + breve\n\t[0x0150, [0x004f, 0x030b]], // Ő = O + double acute\n\t[0x0151, [0x006f, 0x030b]], // ő = o + double acute\n\t[0x0154, [0x0052, 0x0301]], // Ŕ = R + acute\n\t[0x0155, [0x0072, 0x0301]], // ŕ = r + acute\n\t[0x0156, [0x0052, 0x0327]], // Ŗ = R + cedilla\n\t[0x0157, [0x0072, 0x0327]], // ŗ = r + cedilla\n\t[0x0158, [0x0052, 0x030c]], // Ř = R + caron\n\t[0x0159, [0x0072, 0x030c]], // ř = r + caron\n\t[0x015a, [0x0053, 0x0301]], // Ś = S + acute\n\t[0x015b, [0x0073, 0x0301]], // ś = s + acute\n\t[0x015c, [0x0053, 0x0302]], // Ŝ = S + circumflex\n\t[0x015d, [0x0073, 0x0302]], // ŝ = s + circumflex\n\t[0x015e, [0x0053, 0x0327]], // Ş = S + cedilla\n\t[0x015f, [0x0073, 0x0327]], // ş = s + cedilla\n\t[0x0160, [0x0053, 0x030c]], // Š = S + caron\n\t[0x0161, [0x0073, 0x030c]], // š = s + caron\n\t[0x0162, [0x0054, 0x0327]], // Ţ = T + cedilla\n\t[0x0163, [0x0074, 0x0327]], // ţ = t + cedilla\n\t[0x0164, [0x0054, 0x030c]], // Ť = T + caron\n\t[0x0165, [0x0074, 0x030c]], // ť = t + caron\n\t[0x0168, [0x0055, 0x0303]], // Ũ = U + tilde\n\t[0x0169, [0x0075, 0x0303]], // ũ = u + tilde\n\t[0x016a, [0x0055, 0x0304]], // Ū = U + macron\n\t[0x016b, [0x0075, 0x0304]], // ū = u + macron\n\t[0x016c, [0x0055, 0x0306]], // Ŭ = U + breve\n\t[0x016d, [0x0075, 0x0306]], // ŭ = u + breve\n\t[0x016e, [0x0055, 0x030a]], // Ů = U + ring\n\t[0x016f, [0x0075, 0x030a]], // ů = u + ring\n\t[0x0170, [0x0055, 0x030b]], // Ű = U + double acute\n\t[0x0171, [0x0075, 0x030b]], // ű = u + double acute\n\t[0x0172, [0x0055, 0x0328]], // Ų = U + ogonek\n\t[0x0173, [0x0075, 0x0328]], // ų = u + ogonek\n\t[0x0174, [0x0057, 0x0302]], // Ŵ = W + circumflex\n\t[0x0175, [0x0077, 0x0302]], // ŵ = w + circumflex\n\t[0x0176, [0x0059, 0x0302]], // Ŷ = Y + circumflex\n\t[0x0177, [0x0079, 0x0302]], // ŷ = y + circumflex\n\t[0x0178, [0x0059, 0x0308]], // Ÿ = Y + diaeresis\n\t[0x0179, [0x005a, 0x0301]], // Ź = Z + acute\n\t[0x017a, [0x007a, 0x0301]], // ź = z + acute\n\t[0x017b, [0x005a, 0x0307]], // Ż = Z + dot above\n\t[0x017c, [0x007a, 0x0307]], // ż = z + dot above\n\t[0x017d, [0x005a, 0x030c]], // Ž = Z + caron\n\t[0x017e, [0x007a, 0x030c]], // ž = z + caron\n\t// Vietnamese characters (Latin Extended Additional)\n\t[0x1ea0, [0x0041, 0x0323]], // Ạ = A + dot below\n\t[0x1ea1, [0x0061, 0x0323]], // ạ = a + dot below\n\t[0x1ea2, [0x0041, 0x0309]], // Ả = A + hook above\n\t[0x1ea3, [0x0061, 0x0309]], // ả = a + hook above\n\t[0x1eb8, [0x0045, 0x0323]], // Ẹ = E + dot below\n\t[0x1eb9, [0x0065, 0x0323]], // ẹ = e + dot below\n\t[0x1eba, [0x0045, 0x0309]], // Ẻ = E + hook above\n\t[0x1ebb, [0x0065, 0x0309]], // ẻ = e + hook above\n\t[0x1ebc, [0x0045, 0x0303]], // Ẽ = E + tilde\n\t[0x1ebd, [0x0065, 0x0303]], // ẽ = e + tilde\n\t[0x1ec8, [0x0049, 0x0309]], // Ỉ = I + hook above\n\t[0x1ec9, [0x0069, 0x0309]], // ỉ = i + hook above\n\t[0x1eca, [0x0049, 0x0323]], // Ị = I + dot below\n\t[0x1ecb, [0x0069, 0x0323]], // ị = i + dot below\n\t[0x1ecc, [0x004f, 0x0323]], // Ọ = O + dot below\n\t[0x1ecd, [0x006f, 0x0323]], // ọ = o + dot below\n\t[0x1ece, [0x004f, 0x0309]], // Ỏ = O + hook above\n\t[0x1ecf, [0x006f, 0x0309]], // ỏ = o + hook above\n\t[0x1ee4, [0x0055, 0x0323]], // Ụ = U + dot below\n\t[0x1ee5, [0x0075, 0x0323]], // ụ = u + dot below\n\t[0x1ee6, [0x0055, 0x0309]], // Ủ = U + hook above\n\t[0x1ee7, [0x0075, 0x0309]], // ủ = u + hook above\n\t[0x1ef2, [0x0059, 0x0300]], // Ỳ = Y + grave\n\t[0x1ef3, [0x0079, 0x0300]], // ỳ = y + grave\n\t[0x1ef4, [0x0059, 0x0323]], // Ỵ = Y + dot below\n\t[0x1ef5, [0x0079, 0x0323]], // ỵ = y + dot below\n\t[0x1ef6, [0x0059, 0x0309]], // Ỷ = Y + hook above\n\t[0x1ef7, [0x0079, 0x0309]], // ỷ = y + hook above\n\t[0x1ef8, [0x0059, 0x0303]], // Ỹ = Y + tilde\n\t[0x1ef9, [0x0079, 0x0303]], // ỹ = y + tilde\n\t// Greek Extended\n\t[0x1f00, [0x03b1, 0x0313]], // ἀ = α + psili\n\t[0x1f01, [0x03b1, 0x0314]], // ἁ = α + dasia\n\t[0x1f08, [0x0391, 0x0313]], // Ἀ = Α + psili\n\t[0x1f09, [0x0391, 0x0314]], // Ἁ = Α + dasia\n\t// Cyrillic (common)\n\t[0x0439, [0x0438, 0x0306]], // й = и + breve\n\t[0x0419, [0x0418, 0x0306]], // Й = И + breve\n\t[0x0451, [0x0435, 0x0308]], // ё = е + diaeresis\n\t[0x0401, [0x0415, 0x0308]], // Ё = Е + diaeresis\n]);\n\n/**\n * Decompose a codepoint if it has a canonical decomposition\n */\nexport function decompose(cp: number): number[] | null {\n\treturn DECOMPOSITIONS.get(cp) ?? null;\n}\n\n/**\n * Common composition mappings (subset of Unicode canonical composition)\n * Maps (base, combining) pairs to composed character\n */\nconst COMPOSITIONS: Map<number, Map<number, number>> = new Map([\n\t// Latin A compositions\n\t[\n\t\t0x0041,\n\t\tnew Map([\n\t\t\t[0x0300, 0x00c0], // A + grave = À\n\t\t\t[0x0301, 0x00c1], // A + acute = Á\n\t\t\t[0x0302, 0x00c2], // A + circumflex = Â\n\t\t\t[0x0303, 0x00c3], // A + tilde = Ã\n\t\t\t[0x0308, 0x00c4], // A + diaeresis = Ä\n\t\t\t[0x030a, 0x00c5], // A + ring = Å\n\t\t\t[0x0328, 0x0104], // A + ogonek = Ą\n\t\t\t[0x030c, 0x01cd], // A + caron = Ǎ\n\t\t\t[0x0304, 0x0100], // A + macron = Ā\n\t\t\t[0x0306, 0x0102], // A + breve = Ă\n\t\t]),\n\t],\n\t// Latin C compositions\n\t[\n\t\t0x0043,\n\t\tnew Map([\n\t\t\t[0x0327, 0x00c7], // C + cedilla = Ç\n\t\t\t[0x0301, 0x0106], // C + acute = Ć\n\t\t\t[0x0302, 0x0108], // C + circumflex = Ĉ\n\t\t\t[0x030c, 0x010c], // C + caron = Č\n\t\t\t[0x0307, 0x010a], // C + dot above = Ċ\n\t\t]),\n\t],\n\t// Latin E compositions\n\t[\n\t\t0x0045,\n\t\tnew Map([\n\t\t\t[0x0300, 0x00c8], // E + grave = È\n\t\t\t[0x0301, 0x00c9], // E + acute = É\n\t\t\t[0x0302, 0x00ca], // E + circumflex = Ê\n\t\t\t[0x0308, 0x00cb], // E + diaeresis = Ë\n\t\t\t[0x0328, 0x0118], // E + ogonek = Ę\n\t\t\t[0x030c, 0x011a], // E + caron = Ě\n\t\t\t[0x0304, 0x0112], // E + macron = Ē\n\t\t\t[0x0306, 0x0114], // E + breve = Ĕ\n\t\t\t[0x0307, 0x0116], // E + dot above = Ė\n\t\t]),\n\t],\n\t// Latin I compositions\n\t[\n\t\t0x0049,\n\t\tnew Map([\n\t\t\t[0x0300, 0x00cc], // I + grave = Ì\n\t\t\t[0x0301, 0x00cd], // I + acute = Í\n\t\t\t[0x0302, 0x00ce], // I + circumflex = Î\n\t\t\t[0x0308, 0x00cf], // I + diaeresis = Ï\n\t\t\t[0x0303, 0x0128], // I + tilde = Ĩ\n\t\t\t[0x0304, 0x012a], // I + macron = Ī\n\t\t\t[0x0306, 0x012c], // I + breve = Ĭ\n\t\t\t[0x0328, 0x012e], // I + ogonek = Į\n\t\t\t[0x0307, 0x0130], // I + dot above = İ\n\t\t]),\n\t],\n\t// Latin N compositions\n\t[\n\t\t0x004e,\n\t\tnew Map([\n\t\t\t[0x0303, 0x00d1], // N + tilde = Ñ\n\t\t\t[0x0301, 0x0143], // N + acute = Ń\n\t\t\t[0x0327, 0x0145], // N + cedilla = Ņ\n\t\t\t[0x030c, 0x0147], // N + caron = Ň\n\t\t]),\n\t],\n\t// Latin O compositions\n\t[\n\t\t0x004f,\n\t\tnew Map([\n\t\t\t[0x0300, 0x00d2], // O + grave = Ò\n\t\t\t[0x0301, 0x00d3], // O + acute = Ó\n\t\t\t[0x0302, 0x00d4], // O + circumflex = Ô\n\t\t\t[0x0303, 0x00d5], // O + tilde = Õ\n\t\t\t[0x0308, 0x00d6], // O + diaeresis = Ö\n\t\t\t[0x0304, 0x014c], // O + macron = Ō\n\t\t\t[0x0306, 0x014e], // O + breve = Ŏ\n\t\t\t[0x030b, 0x0150], // O + double acute = Ő\n\t\t\t[0x0328, 0x01ea], // O + ogonek = Ǫ\n\t\t]),\n\t],\n\t// Latin U compositions\n\t[\n\t\t0x0055,\n\t\tnew Map([\n\t\t\t[0x0300, 0x00d9], // U + grave = Ù\n\t\t\t[0x0301, 0x00da], // U + acute = Ú\n\t\t\t[0x0302, 0x00db], // U + circumflex = Û\n\t\t\t[0x0308, 0x00dc], // U + diaeresis = Ü\n\t\t\t[0x0303, 0x0168], // U + tilde = Ũ\n\t\t\t[0x0304, 0x016a], // U + macron = Ū\n\t\t\t[0x0306, 0x016c], // U + breve = Ŭ\n\t\t\t[0x030a, 0x016e], // U + ring = Ů\n\t\t\t[0x030b, 0x0170], // U + double acute = Ű\n\t\t\t[0x0328, 0x0172], // U + ogonek = Ų\n\t\t\t[0x030c, 0x01d3], // U + caron = Ǔ\n\t\t]),\n\t],\n\t// Latin Y compositions\n\t[\n\t\t0x0059,\n\t\tnew Map([\n\t\t\t[0x0301, 0x00dd], // Y + acute = Ý\n\t\t\t[0x0302, 0x0176], // Y + circumflex = Ŷ\n\t\t\t[0x0308, 0x0178], // Y + diaeresis = Ÿ\n\t\t]),\n\t],\n\t// Lowercase a compositions\n\t[\n\t\t0x0061,\n\t\tnew Map([\n\t\t\t[0x0300, 0x00e0], // a + grave = à\n\t\t\t[0x0301, 0x00e1], // a + acute = á\n\t\t\t[0x0302, 0x00e2], // a + circumflex = â\n\t\t\t[0x0303, 0x00e3], // a + tilde = ã\n\t\t\t[0x0308, 0x00e4], // a + diaeresis = ä\n\t\t\t[0x030a, 0x00e5], // a + ring = å\n\t\t\t[0x0328, 0x0105], // a + ogonek = ą\n\t\t\t[0x030c, 0x01ce], // a + caron = ǎ\n\t\t\t[0x0304, 0x0101], // a + macron = ā\n\t\t\t[0x0306, 0x0103], // a + breve = ă\n\t\t]),\n\t],\n\t// Lowercase c compositions\n\t[\n\t\t0x0063,\n\t\tnew Map([\n\t\t\t[0x0327, 0x00e7], // c + cedilla = ç\n\t\t\t[0x0301, 0x0107], // c + acute = ć\n\t\t\t[0x0302, 0x0109], // c + circumflex = ĉ\n\t\t\t[0x030c, 0x010d], // c + caron = č\n\t\t\t[0x0307, 0x010b], // c + dot above = ċ\n\t\t]),\n\t],\n\t// Lowercase e compositions\n\t[\n\t\t0x0065,\n\t\tnew Map([\n\t\t\t[0x0300, 0x00e8], // e + grave = è\n\t\t\t[0x0301, 0x00e9], // e + acute = é\n\t\t\t[0x0302, 0x00ea], // e + circumflex = ê\n\t\t\t[0x0308, 0x00eb], // e + diaeresis = ë\n\t\t\t[0x0328, 0x0119], // e + ogonek = ę\n\t\t\t[0x030c, 0x011b], // e + caron = ě\n\t\t\t[0x0304, 0x0113], // e + macron = ē\n\t\t\t[0x0306, 0x0115], // e + breve = ĕ\n\t\t\t[0x0307, 0x0117], // e + dot above = ė\n\t\t]),\n\t],\n\t// Lowercase i compositions\n\t[\n\t\t0x0069,\n\t\tnew Map([\n\t\t\t[0x0300, 0x00ec], // i + grave = ì\n\t\t\t[0x0301, 0x00ed], // i + acute = í\n\t\t\t[0x0302, 0x00ee], // i + circumflex = î\n\t\t\t[0x0308, 0x00ef], // i + diaeresis = ï\n\t\t\t[0x0303, 0x0129], // i + tilde = ĩ\n\t\t\t[0x0304, 0x012b], // i + macron = ī\n\t\t\t[0x0306, 0x012d], // i + breve = ĭ\n\t\t\t[0x0328, 0x012f], // i + ogonek = į\n\t\t]),\n\t],\n\t// Lowercase n compositions\n\t[\n\t\t0x006e,\n\t\tnew Map([\n\t\t\t[0x0303, 0x00f1], // n + tilde = ñ\n\t\t\t[0x0301, 0x0144], // n + acute = ń\n\t\t\t[0x0327, 0x0146], // n + cedilla = ņ\n\t\t\t[0x030c, 0x0148], // n + caron = ň\n\t\t]),\n\t],\n\t// Lowercase o compositions\n\t[\n\t\t0x006f,\n\t\tnew Map([\n\t\t\t[0x0300, 0x00f2], // o + grave = ò\n\t\t\t[0x0301, 0x00f3], // o + acute = ó\n\t\t\t[0x0302, 0x00f4], // o + circumflex = ô\n\t\t\t[0x0303, 0x00f5], // o + tilde = õ\n\t\t\t[0x0308, 0x00f6], // o + diaeresis = ö\n\t\t\t[0x0304, 0x014d], // o + macron = ō\n\t\t\t[0x0306, 0x014f], // o + breve = ŏ\n\t\t\t[0x030b, 0x0151], // o + double acute = ő\n\t\t\t[0x0328, 0x01eb], // o + ogonek = ǫ\n\t\t]),\n\t],\n\t// Lowercase u compositions\n\t[\n\t\t0x0075,\n\t\tnew Map([\n\t\t\t[0x0300, 0x00f9], // u + grave = ù\n\t\t\t[0x0301, 0x00fa], // u + acute = ú\n\t\t\t[0x0302, 0x00fb], // u + circumflex = û\n\t\t\t[0x0308, 0x00fc], // u + diaeresis = ü\n\t\t\t[0x0303, 0x0169], // u + tilde = ũ\n\t\t\t[0x0304, 0x016b], // u + macron = ū\n\t\t\t[0x0306, 0x016d], // u + breve = ŭ\n\t\t\t[0x030a, 0x016f], // u + ring = ů\n\t\t\t[0x030b, 0x0171], // u + double acute = ű\n\t\t\t[0x0328, 0x0173], // u + ogonek = ų\n\t\t\t[0x030c, 0x01d4], // u + caron = ǔ\n\t\t]),\n\t],\n\t// Lowercase y compositions\n\t[\n\t\t0x0079,\n\t\tnew Map([\n\t\t\t[0x0301, 0x00fd], // y + acute = ý\n\t\t\t[0x0308, 0x00ff], // y + diaeresis = ÿ\n\t\t\t[0x0302, 0x0177], // y + circumflex = ŷ\n\t\t]),\n\t],\n\t// Other common compositions\n\t[\n\t\t0x0053,\n\t\tnew Map([\n\t\t\t// S\n\t\t\t[0x0301, 0x015a], // S + acute = Ś\n\t\t\t[0x0302, 0x015c], // S + circumflex = Ŝ\n\t\t\t[0x0327, 0x015e], // S + cedilla = Ş\n\t\t\t[0x030c, 0x0160], // S + caron = Š\n\t\t]),\n\t],\n\t[\n\t\t0x0073,\n\t\tnew Map([\n\t\t\t// s\n\t\t\t[0x0301, 0x015b], // s + acute = ś\n\t\t\t[0x0302, 0x015d], // s + circumflex = ŝ\n\t\t\t[0x0327, 0x015f], // s + cedilla = ş\n\t\t\t[0x030c, 0x0161], // s + caron = š\n\t\t]),\n\t],\n\t[\n\t\t0x005a,\n\t\tnew Map([\n\t\t\t// Z\n\t\t\t[0x0301, 0x0179], // Z + acute = Ź\n\t\t\t[0x0307, 0x017b], // Z + dot above = Ż\n\t\t\t[0x030c, 0x017d], // Z + caron = Ž\n\t\t]),\n\t],\n\t[\n\t\t0x007a,\n\t\tnew Map([\n\t\t\t// z\n\t\t\t[0x0301, 0x017a], // z + acute = ź\n\t\t\t[0x0307, 0x017c], // z + dot above = ż\n\t\t\t[0x030c, 0x017e], // z + caron = ž\n\t\t]),\n\t],\n]);\n\n/**\n * Try to compose a base character with a combining mark\n * Returns the composed character or null if no composition exists\n */\nexport function tryCompose(base: number, combining: number): number | null {\n\tconst baseCompositions = COMPOSITIONS.get(base);\n\tif (!baseCompositions) return null;\n\treturn baseCompositions.get(combining) ?? null;\n}\n\n/**\n * Compose combining marks with their bases where possible (NFC-like)\n */\nfunction composeMarks(infos: GlyphInfo[]): GlyphInfo[] {\n\tif (infos.length === 0) return infos;\n\n\tconst result: GlyphInfo[] = [];\n\tlet i = 0;\n\n\twhile (i < infos.length) {\n\t\tconst current = infos[i];\n\t\tif (!current) {\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst currentCcc = getCombiningClass(current.codepoint);\n\n\t\t// If this is a base character (ccc = 0), try to compose with following marks\n\t\tif (currentCcc === 0) {\n\t\t\tlet composedCp = current.codepoint;\n\t\t\tlet lastCcc = 0;\n\t\t\tlet j = i + 1;\n\n\t\t\t// Look for combining marks that can be composed\n\t\t\twhile (j < infos.length) {\n\t\t\t\tconst mark = infos[j];\n\t\t\t\tif (!mark) break;\n\n\t\t\t\tconst markCcc = getCombiningClass(mark.codepoint);\n\n\t\t\t\t// Stop at next base character\n\t\t\t\tif (markCcc === 0) break;\n\n\t\t\t\t// Can only compose if:\n\t\t\t\t// 1. Mark has higher ccc than last composed mark (or last was base)\n\t\t\t\t// 2. Composition exists for the pair\n\t\t\t\tif (markCcc > lastCcc || lastCcc === 0) {\n\t\t\t\t\tconst composed = tryCompose(composedCp, mark.codepoint);\n\t\t\t\t\tif (composed !== null) {\n\t\t\t\t\t\tcomposedCp = composed;\n\t\t\t\t\t\t// Mark this position as consumed (will skip)\n\t\t\t\t\t\tj++;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Mark wasn't composed, stop looking for compositions\n\t\t\t\t// but continue with remaining marks\n\t\t\t\tlastCcc = markCcc;\n\t\t\t\tj++;\n\t\t\t}\n\n\t\t\t// Output the (possibly composed) base\n\t\t\tresult.push({\n\t\t\t\tglyphId: current.glyphId,\n\t\t\t\tcluster: current.cluster,\n\t\t\t\tmask: current.mask,\n\t\t\t\tcodepoint: composedCp,\n\t\t\t});\n\n\t\t\t// Output any marks that weren't composed\n\t\t\tfor (let k = i + 1; k < j; k++) {\n\t\t\t\tconst mark = infos[k];\n\t\t\t\tif (!mark) continue;\n\n\t\t\t\tconst markCcc = getCombiningClass(mark.codepoint);\n\t\t\t\t// Only output marks that weren't composed (check if they're still combining marks)\n\t\t\t\t// We need to re-check if a composition exists to determine what to output\n\t\t\t\tconst compositionExists =\n\t\t\t\t\ttryCompose(composedCp, mark.codepoint) !== null;\n\t\t\t\tif (!compositionExists && markCcc !== 0) {\n\t\t\t\t\tresult.push(mark);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ti = j;\n\t\t} else {\n\t\t\t// Standalone combining mark (no base), just copy it\n\t\t\tresult.push(current);\n\t\t\ti++;\n\t\t}\n\t}\n\n\treturn result;\n}\n\n/**\n * Apply normalization to glyph infos\n */\nexport function normalize(\n\tinfos: GlyphInfo[],\n\tmode: NormalizationMode,\n): GlyphInfo[] {\n\tif (mode === NormalizationMode.None) {\n\t\treturn infos;\n\t}\n\n\tif (mode === NormalizationMode.Decompose) {\n\t\t// Decompose precomposed characters (NFD-like)\n\t\tconst result: GlyphInfo[] = [];\n\n\t\tfor (const info of infos) {\n\t\t\tconst decomposed = decompose(info.codepoint);\n\t\t\tif (decomposed) {\n\t\t\t\t// Replace with decomposed sequence\n\t\t\t\tfor (const cp of decomposed) {\n\t\t\t\t\tresult.push({\n\t\t\t\t\t\tglyphId: info.glyphId, // Will be remapped later\n\t\t\t\t\t\tcluster: info.cluster,\n\t\t\t\t\t\tmask: info.mask,\n\t\t\t\t\t\tcodepoint: cp,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tresult.push(info);\n\t\t\t}\n\t\t}\n\n\t\t// Reorder combining marks\n\t\treorderMarks(result);\n\n\t\treturn result;\n\t}\n\n\tif (mode === NormalizationMode.Compose) {\n\t\t// First decompose, reorder, then compose (NFC-like)\n\t\t// Step 1: Decompose\n\t\tconst decomposed: GlyphInfo[] = [];\n\t\tfor (const info of infos) {\n\t\t\tconst dec = decompose(info.codepoint);\n\t\t\tif (dec) {\n\t\t\t\tfor (const cp of dec) {\n\t\t\t\t\tdecomposed.push({\n\t\t\t\t\t\tglyphId: info.glyphId,\n\t\t\t\t\t\tcluster: info.cluster,\n\t\t\t\t\t\tmask: info.mask,\n\t\t\t\t\t\tcodepoint: cp,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tdecomposed.push(info);\n\t\t\t}\n\t\t}\n\n\t\t// Step 2: Reorder combining marks\n\t\treorderMarks(decomposed);\n\n\t\t// Step 3: Compose\n\t\treturn composeMarks(decomposed);\n\t}\n\n\tif (mode === NormalizationMode.Auto) {\n\t\t// Auto mode: use decomposition by default (better for shaping)\n\t\tconst result: GlyphInfo[] = [];\n\n\t\tfor (const info of infos) {\n\t\t\tconst decomposed = decompose(info.codepoint);\n\t\t\tif (decomposed) {\n\t\t\t\tfor (const cp of decomposed) {\n\t\t\t\t\tresult.push({\n\t\t\t\t\t\tglyphId: info.glyphId,\n\t\t\t\t\t\tcluster: info.cluster,\n\t\t\t\t\t\tmask: info.mask,\n\t\t\t\t\t\tcodepoint: cp,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tresult.push(info);\n\t\t\t}\n\t\t}\n\n\t\treorderMarks(result);\n\t\treturn result;\n\t}\n\n\treturn infos;\n}\n",
88
- "import type { Font } from \"../font/font.ts\";\nimport { getGlyphClass } from \"../font/tables/gdef.ts\";\nimport { getKernValue } from \"../font/tables/kern.ts\";\nimport type { GlyphId, GlyphInfo, GlyphPosition } from \"../types.ts\";\nimport { GlyphClass } from \"../types.ts\";\nimport { getCombiningClass } from \"../unicode/normalize.ts\";\n\n/**\n * Fallback mark positioning when GPOS is not available\n * Uses combining class information to position marks\n */\nexport function applyFallbackMarkPositioning(\n\tfont: Font,\n\tinfos: GlyphInfo[],\n\tpositions: GlyphPosition[],\n): void {\n\tfor (let i = 0; i < infos.length; i++) {\n\t\tconst info = infos[i];\n\t\tconst pos = positions[i];\n\t\tif (!info || !pos) continue;\n\n\t\tconst glyphClass = font.gdef ? getGlyphClass(font.gdef, info.glyphId) : 0;\n\t\tconst ccc = getCombiningClass(info.codepoint);\n\n\t\t// Skip if not a mark\n\t\tif (glyphClass !== GlyphClass.Mark && ccc === 0) continue;\n\n\t\t// Find the base glyph\n\t\tlet baseIndex = -1;\n\t\tfor (let j = i - 1; j >= 0; j--) {\n\t\t\tconst prevInfo = infos[j];\n\t\t\tif (!prevInfo) continue;\n\n\t\t\tconst prevClass = font.gdef\n\t\t\t\t? getGlyphClass(font.gdef, prevInfo.glyphId)\n\t\t\t\t: 0;\n\t\t\tconst prevCcc = getCombiningClass(prevInfo.codepoint);\n\n\t\t\tif (prevClass === GlyphClass.Base || (prevClass === 0 && prevCcc === 0)) {\n\t\t\t\tbaseIndex = j;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (baseIndex < 0) continue;\n\n\t\tconst baseInfo = infos[baseIndex];\n\t\tconst basePos = positions[baseIndex];\n\t\tif (!baseInfo || !basePos) continue;\n\n\t\t// Get base glyph metrics\n\t\tconst baseAdvance = font.advanceWidth(baseInfo.glyphId);\n\n\t\t// Position mark relative to base based on combining class\n\t\t// This is a simplified heuristic - real mark positioning uses anchors\n\t\tpositionMarkFallback(font, info, pos, baseInfo, basePos, baseAdvance, ccc);\n\n\t\t// Mark has zero advance (already accounted for in base)\n\t\tpos.xAdvance = 0;\n\t\tpos.yAdvance = 0;\n\t}\n}\n\nfunction positionMarkFallback(\n\tfont: Font,\n\tmarkInfo: GlyphInfo,\n\tmarkPos: GlyphPosition,\n\t_baseInfo: GlyphInfo,\n\tbasePos: GlyphPosition,\n\tbaseAdvance: number,\n\tccc: number,\n): void {\n\tconst markAdvance = font.advanceWidth(markInfo.glyphId);\n\tconst unitsPerEm = font.unitsPerEm;\n\n\t// Default: center mark over base\n\tlet xOffset = (baseAdvance - markAdvance) / 2;\n\tlet yOffset = 0;\n\n\t// Position based on combining class\n\tif (ccc >= 200 && ccc <= 240) {\n\t\t// Above marks (ccc 230 is common for above)\n\t\tyOffset = unitsPerEm * 0.7; // 70% of em height\n\t\txOffset = (baseAdvance - markAdvance) / 2;\n\t} else if (ccc >= 202 && ccc <= 220) {\n\t\t// Below marks (ccc 220 is common for below)\n\t\tyOffset = -unitsPerEm * 0.15;\n\t\txOffset = (baseAdvance - markAdvance) / 2;\n\t} else if (ccc === 1) {\n\t\t// Overlay marks\n\t\txOffset = (baseAdvance - markAdvance) / 2;\n\t\tyOffset = unitsPerEm * 0.3;\n\t} else if (ccc >= 7 && ccc <= 9) {\n\t\t// Nukta, virama (below consonant)\n\t\tyOffset = -unitsPerEm * 0.1;\n\t\txOffset = (baseAdvance - markAdvance) / 2;\n\t} else if (ccc >= 10 && ccc <= 35) {\n\t\t// Hebrew/Arabic vowels - specific positioning\n\t\tif (ccc <= 22) {\n\t\t\t// Hebrew below vowels\n\t\t\tyOffset = -unitsPerEm * 0.2;\n\t\t} else {\n\t\t\t// Arabic marks\n\t\t\tyOffset = ccc < 30 ? -unitsPerEm * 0.15 : unitsPerEm * 0.6;\n\t\t}\n\t\txOffset = (baseAdvance - markAdvance) / 2;\n\t}\n\n\t// Apply offset relative to base position\n\tmarkPos.xOffset = basePos.xOffset + xOffset - baseAdvance;\n\tmarkPos.yOffset = basePos.yOffset + yOffset;\n}\n\n/**\n * Apply fallback kerning using kern table\n */\nexport function applyFallbackKerning(\n\tfont: Font,\n\tinfos: GlyphInfo[],\n\tpositions: GlyphPosition[],\n): void {\n\tconst kern = font.kern;\n\tif (!kern) return;\n\n\tfor (let i = 0; i < infos.length - 1; i++) {\n\t\tconst info1 = infos[i];\n\t\tconst info2 = infos[i + 1];\n\t\tif (!info1 || !info2) continue;\n\n\t\tconst pos1 = positions[i];\n\t\tif (!pos1) continue;\n\n\t\t// Skip marks\n\t\tconst class1 = font.gdef ? getGlyphClass(font.gdef, info1.glyphId) : 0;\n\t\tconst class2 = font.gdef ? getGlyphClass(font.gdef, info2.glyphId) : 0;\n\t\tif (class1 === GlyphClass.Mark || class2 === GlyphClass.Mark) continue;\n\n\t\t// Get kerning from kern table\n\t\tconst kernValue = getKernValueFromTable(font, info1.glyphId, info2.glyphId);\n\t\tif (kernValue !== 0) {\n\t\t\tpos1.xAdvance += kernValue;\n\t\t}\n\t}\n}\n\nfunction getKernValueFromTable(\n\tfont: Font,\n\tleft: GlyphId,\n\tright: GlyphId,\n): number {\n\tconst kern = font.kern;\n\tif (!kern) return 0;\n\n\treturn getKernValue(kern, left, right);\n}\n\n/**\n * Recategorize combining marks for proper processing\n * Some scripts need marks to be processed in specific order\n */\nexport function recategorizeCombiningMarks(\n\t_font: Font,\n\tinfos: GlyphInfo[],\n): void {\n\t// For Hebrew, Arabic, and other scripts, ensure marks are in canonical order\n\t// This is typically handled by normalization, but we do a final check here\n\n\tlet i = 0;\n\twhile (i < infos.length) {\n\t\tconst info = infos[i];\n\t\tif (!info) {\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst ccc = getCombiningClass(info.codepoint);\n\t\tif (ccc === 0) {\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Find extent of combining sequence\n\t\tlet j = i + 1;\n\t\twhile (j < infos.length) {\n\t\t\tconst nextInfo = infos[j];\n\t\t\tif (!nextInfo) break;\n\t\t\tconst nextCcc = getCombiningClass(nextInfo.codepoint);\n\t\t\tif (nextCcc === 0) break;\n\t\t\tj++;\n\t\t}\n\n\t\t// Sort combining marks by CCC (stable sort)\n\t\tif (j - i > 1) {\n\t\t\tconst marks = infos.slice(i, j);\n\t\t\tmarks.sort((a, b) => {\n\t\t\t\tconst cccA = getCombiningClass(a.codepoint);\n\t\t\t\tconst cccB = getCombiningClass(b.codepoint);\n\t\t\t\treturn cccA - cccB;\n\t\t\t});\n\t\t\tfor (const [k, mark] of marks.entries()) {\n\t\t\t\tinfos[i + k] = mark;\n\t\t\t}\n\t\t}\n\n\t\ti = j;\n\t}\n}\n",
89
- "import type { Font } from \"../font/font.ts\";\nimport type { AnyGposLookup, GposTable } from \"../font/tables/gpos.ts\";\nimport type { AnyGsubLookup, GsubTable } from \"../font/tables/gsub.ts\";\nimport {\n\ttype FeatureVariations,\n\tfindMatchingFeatureVariation,\n} from \"../layout/structures/feature-variations.ts\";\nimport {\n\tfindLangSys,\n\tfindScript,\n\tgetFeature,\n} from \"../layout/structures/layout-common.ts\";\nimport type { Tag, uint16 } from \"../types.ts\";\nimport { tag, tagToString } from \"../types.ts\";\n\n/** Shape plan cache for reusing computed plans */\nconst shapePlanCache = new WeakMap<Font, Map<string, ShapePlan>>();\n\n/** Maximum cache size per font */\nconst MAX_CACHE_SIZE = 64;\n\n/** Feature with optional value */\nexport interface ShapeFeature {\n\ttag: Tag;\n\tenabled: boolean;\n}\n\n/** Collected lookups for shaping */\nexport interface ShapePlan {\n\tscript: Tag;\n\tlanguage: Tag | null;\n\tdirection: \"ltr\" | \"rtl\";\n\n\t/** GSUB lookups to apply, in order */\n\tgsubLookups: Array<{ index: number; lookup: AnyGsubLookup }>;\n\n\t/** GPOS lookups to apply, in order */\n\tgposLookups: Array<{ index: number; lookup: AnyGposLookup }>;\n}\n\n/** Default GSUB features (always enabled) */\nconst DEFAULT_GSUB_FEATURES = [\n\t\"ccmp\", // Glyph composition/decomposition\n\t\"locl\", // Localized forms\n\t\"rlig\", // Required ligatures\n\t\"rclt\", // Required contextual alternates\n\t\"calt\", // Contextual alternates\n\t\"liga\", // Standard ligatures\n];\n\n/** Default GPOS features (always enabled) */\nconst DEFAULT_GPOS_FEATURES = [\n\t\"kern\", // Kerning\n\t\"mark\", // Mark positioning\n\t\"mkmk\", // Mark-to-mark positioning\n];\n\n/** Generate cache key for shape plan */\nfunction getCacheKey(\n\tscript: string,\n\tlanguage: string | null,\n\tdirection: \"ltr\" | \"rtl\",\n\tuserFeatures: ShapeFeature[],\n\taxisCoords: number[] | null,\n): string {\n\tconst featuresKey = userFeatures\n\t\t.map((f) => `${tagToString(f.tag)}:${f.enabled ? \"1\" : \"0\"}`)\n\t\t.sort()\n\t\t.join(\",\");\n\tconst coordsKey = axisCoords\n\t\t? axisCoords.map((c) => c.toFixed(4)).join(\",\")\n\t\t: \"\";\n\treturn `${script}|${language || \"\"}|${direction}|${featuresKey}|${coordsKey}`;\n}\n\n/** Get or create a cached shape plan */\nexport function getOrCreateShapePlan(\n\tfont: Font,\n\tscript: string,\n\tlanguage: string | null,\n\tdirection: \"ltr\" | \"rtl\",\n\tuserFeatures: ShapeFeature[] = [],\n\taxisCoords: number[] | null = null,\n): ShapePlan {\n\tconst cacheKey = getCacheKey(\n\t\tscript,\n\t\tlanguage,\n\t\tdirection,\n\t\tuserFeatures,\n\t\taxisCoords,\n\t);\n\n\t// Get or create font's cache map\n\tlet fontCache = shapePlanCache.get(font);\n\tif (!fontCache) {\n\t\tfontCache = new Map();\n\t\tshapePlanCache.set(font, fontCache);\n\t}\n\n\t// Check cache\n\tconst cached = fontCache.get(cacheKey);\n\tif (cached) {\n\t\treturn cached;\n\t}\n\n\t// Create new plan\n\tconst plan = createShapePlanInternal(\n\t\tfont,\n\t\tscript,\n\t\tlanguage,\n\t\tdirection,\n\t\tuserFeatures,\n\t\taxisCoords,\n\t);\n\n\t// Evict if cache is too large\n\tif (fontCache.size >= MAX_CACHE_SIZE) {\n\t\tconst firstKey = fontCache.keys().next().value;\n\t\tif (firstKey !== undefined) {\n\t\t\tfontCache.delete(firstKey);\n\t\t}\n\t}\n\n\tfontCache.set(cacheKey, plan);\n\treturn plan;\n}\n\n/** Create a shape plan for the given font and settings */\nexport function createShapePlan(\n\tfont: Font,\n\tscript: string,\n\tlanguage: string | null,\n\tdirection: \"ltr\" | \"rtl\",\n\tuserFeatures: ShapeFeature[] = [],\n\taxisCoords: number[] | null = null,\n): ShapePlan {\n\t// Use caching by default\n\treturn getOrCreateShapePlan(\n\t\tfont,\n\t\tscript,\n\t\tlanguage,\n\t\tdirection,\n\t\tuserFeatures,\n\t\taxisCoords,\n\t);\n}\n\n/** Create a shape plan without caching */\nfunction createShapePlanInternal(\n\tfont: Font,\n\tscript: string,\n\tlanguage: string | null,\n\tdirection: \"ltr\" | \"rtl\",\n\tuserFeatures: ShapeFeature[] = [],\n\taxisCoords: number[] | null = null,\n): ShapePlan {\n\tconst scriptTag = tag(script.padEnd(4, \" \"));\n\tconst languageTag = language ? tag(language.padEnd(4, \" \")) : null;\n\n\t// Collect enabled features\n\tconst enabledFeatures = new Set<Tag>();\n\n\t// Add default features\n\tfor (const feat of DEFAULT_GSUB_FEATURES) {\n\t\tenabledFeatures.add(tag(feat));\n\t}\n\tfor (const feat of DEFAULT_GPOS_FEATURES) {\n\t\tenabledFeatures.add(tag(feat));\n\t}\n\n\t// Apply user features\n\tfor (const feat of userFeatures) {\n\t\tif (feat.enabled) {\n\t\t\tenabledFeatures.add(feat.tag);\n\t\t} else {\n\t\t\tenabledFeatures.delete(feat.tag);\n\t\t}\n\t}\n\n\t// Collect GSUB lookups (with feature variations support)\n\tconst gsubLookups = collectLookups(\n\t\tfont.gsub,\n\t\tscriptTag,\n\t\tlanguageTag,\n\t\tenabledFeatures,\n\t\taxisCoords,\n\t);\n\n\t// Collect GPOS lookups (with feature variations support)\n\tconst gposLookups = collectLookups(\n\t\tfont.gpos,\n\t\tscriptTag,\n\t\tlanguageTag,\n\t\tenabledFeatures,\n\t\taxisCoords,\n\t);\n\n\treturn {\n\t\tscript: scriptTag,\n\t\tlanguage: languageTag,\n\t\tdirection,\n\t\tgsubLookups: gsubLookups as Array<{ index: number; lookup: AnyGsubLookup }>,\n\t\tgposLookups: gposLookups as Array<{ index: number; lookup: AnyGposLookup }>,\n\t};\n}\n\nfunction collectLookups<T extends { lookups: unknown[] }>(\n\ttable: T | null,\n\tscriptTag: Tag,\n\tlanguageTag: Tag | null,\n\tenabledFeatures: Set<Tag>,\n\taxisCoords: number[] | null,\n): Array<{ index: number; lookup: unknown }> {\n\tif (!table) return [];\n\n\tconst gsub = table as unknown as GsubTable | GposTable;\n\tconst lookupIndices = new Set<number>();\n\n\t// Find script\n\tlet script = findScript(gsub.scriptList, scriptTag);\n\tif (!script) {\n\t\t// Try DFLT script\n\t\tscript = findScript(gsub.scriptList, tag(\"DFLT\"));\n\t}\n\tif (!script) {\n\t\t// Try latn as fallback\n\t\tscript = findScript(gsub.scriptList, tag(\"latn\"));\n\t}\n\tif (!script) return [];\n\n\t// Find language system\n\tconst langSys = findLangSys(script, languageTag);\n\tif (!langSys) return [];\n\n\t// Get feature variations substitutions if applicable\n\tconst featureVariations = (gsub as { featureVariations?: FeatureVariations })\n\t\t.featureVariations;\n\tconst matchingVariation =\n\t\tfeatureVariations && axisCoords\n\t\t\t? findMatchingFeatureVariation(featureVariations, axisCoords)\n\t\t\t: null;\n\n\t// Build a map of feature indices to their substituted lookup lists\n\tconst featureSubstitutions = new Map<uint16, uint16[]>();\n\tif (matchingVariation) {\n\t\tfor (const subst of matchingVariation.featureTableSubstitution\n\t\t\t.substitutions) {\n\t\t\tfeatureSubstitutions.set(\n\t\t\t\tsubst.featureIndex,\n\t\t\t\tsubst.alternateFeature.lookupListIndices,\n\t\t\t);\n\t\t}\n\t}\n\n\t// Add required feature\n\tif (langSys.requiredFeatureIndex !== 0xffff) {\n\t\tconst feature = getFeature(gsub.featureList, langSys.requiredFeatureIndex);\n\t\tif (feature) {\n\t\t\t// Check if this feature has a substitution\n\t\t\tconst substitutedLookups = featureSubstitutions.get(\n\t\t\t\tlangSys.requiredFeatureIndex,\n\t\t\t);\n\t\t\tconst lookups = substitutedLookups ?? feature.feature.lookupListIndices;\n\t\t\tfor (const lookupIndex of lookups) {\n\t\t\t\tlookupIndices.add(lookupIndex);\n\t\t\t}\n\t\t}\n\t}\n\n\t// Add enabled features\n\tfor (const featureIndex of langSys.featureIndices) {\n\t\tconst featureRecord = getFeature(gsub.featureList, featureIndex);\n\t\tif (!featureRecord) continue;\n\n\t\tif (enabledFeatures.has(featureRecord.featureTag)) {\n\t\t\t// Check if this feature has a substitution\n\t\t\tconst substitutedLookups = featureSubstitutions.get(featureIndex);\n\t\t\tconst lookups =\n\t\t\t\tsubstitutedLookups ?? featureRecord.feature.lookupListIndices;\n\t\t\tfor (const lookupIndex of lookups) {\n\t\t\t\tlookupIndices.add(lookupIndex);\n\t\t\t}\n\t\t}\n\t}\n\n\t// Convert to sorted array with lookup objects\n\tconst result: Array<{ index: number; lookup: unknown }> = [];\n\tconst sortedIndices = Array.from(lookupIndices).sort((a, b) => a - b);\n\n\tfor (const index of sortedIndices) {\n\t\tconst lookup = gsub.lookups[index];\n\t\tif (lookup) {\n\t\t\tresult.push({ index, lookup });\n\t\t}\n\t}\n\n\treturn result;\n}\n",
90
- "import type { GlyphInfo } from \"../../types.ts\";\n\n/**\n * Arabic joining types from Unicode\n */\nexport enum ArabicJoiningType {\n\tNonJoining = \"U\", // Non_Joining\n\tRightJoining = \"R\", // Right_Joining (joins on the right)\n\tDualJoining = \"D\", // Dual_Joining (joins on both sides)\n\tJoinCausing = \"C\", // Join_Causing (like TATWEEL)\n\tLeftJoining = \"L\", // Left_Joining (rare)\n\tTransparent = \"T\", // Transparent (marks, etc.)\n}\n\n/**\n * Action to take for each glyph based on context\n */\nexport enum JoiningAction {\n\tNone = 0,\n\tIsol = 1, // Isolated form\n\tFina = 2, // Final form\n\tMedi = 3, // Medial form\n\tInit = 4, // Initial form\n}\n\n/**\n * Arabic joining group for specific shaping behavior\n */\nexport enum ArabicJoiningGroup {\n\tNone = 0,\n\tAlaph = 1,\n\tDalathRish = 2,\n\t// Add more as needed for Syriac, etc.\n}\n\n/**\n * Per-glyph info for Arabic shaping\n */\nexport interface ArabicGlyphData {\n\tjoiningType: ArabicJoiningType;\n\tjoiningGroup: ArabicJoiningGroup;\n\taction: JoiningAction;\n}\n\n// Unicode ranges for Arabic characters\nconst ARABIC_START = 0x0600;\nconst ARABIC_END = 0x06ff;\nconst ARABIC_SUPPLEMENT_START = 0x0750;\nconst ARABIC_SUPPLEMENT_END = 0x077f;\nconst ARABIC_EXTENDED_A_START = 0x08a0;\nconst ARABIC_EXTENDED_A_END = 0x08ff;\nconst ARABIC_PRESENTATION_A_START = 0xfb50;\nconst ARABIC_PRESENTATION_A_END = 0xfdff;\nconst ARABIC_PRESENTATION_B_START = 0xfe70;\nconst ARABIC_PRESENTATION_B_END = 0xfeff;\n\n/**\n * Check if a codepoint is in Arabic script range\n */\nexport function isArabic(cp: number): boolean {\n\treturn (\n\t\t(cp >= ARABIC_START && cp <= ARABIC_END) ||\n\t\t(cp >= ARABIC_SUPPLEMENT_START && cp <= ARABIC_SUPPLEMENT_END) ||\n\t\t(cp >= ARABIC_EXTENDED_A_START && cp <= ARABIC_EXTENDED_A_END) ||\n\t\t(cp >= ARABIC_PRESENTATION_A_START && cp <= ARABIC_PRESENTATION_A_END) ||\n\t\t(cp >= ARABIC_PRESENTATION_B_START && cp <= ARABIC_PRESENTATION_B_END)\n\t);\n}\n\n/**\n * Get the joining type for a codepoint\n * Based on Unicode Arabic Shaping data\n */\nexport function getJoiningType(cp: number): ArabicJoiningType {\n\t// Non-joining: space, numbers, punctuation\n\tif (cp < ARABIC_START) return ArabicJoiningType.NonJoining;\n\n\t// Arabic block (0600-06FF)\n\tif (cp >= 0x0600 && cp <= 0x0605) return ArabicJoiningType.NonJoining; // Number signs\n\tif (cp === 0x0608) return ArabicJoiningType.NonJoining; // Arabic Ray\n\tif (cp === 0x060b) return ArabicJoiningType.NonJoining; // Afghani Sign\n\tif (cp === 0x060d) return ArabicJoiningType.NonJoining; // Date Separator\n\n\t// Dual-joining letters (most common Arabic letters)\n\t// These can connect on both sides\n\tif (cp === 0x0626) return ArabicJoiningType.DualJoining; // YEH WITH HAMZA ABOVE\n\tif (cp === 0x0628) return ArabicJoiningType.DualJoining; // BEH\n\tif (cp === 0x062a) return ArabicJoiningType.DualJoining; // TEH\n\tif (cp === 0x062b) return ArabicJoiningType.DualJoining; // THEH\n\tif (cp === 0x062c) return ArabicJoiningType.DualJoining; // JEEM\n\tif (cp === 0x062d) return ArabicJoiningType.DualJoining; // HAH\n\tif (cp === 0x062e) return ArabicJoiningType.DualJoining; // KHAH\n\tif (cp === 0x0633) return ArabicJoiningType.DualJoining; // SEEN\n\tif (cp === 0x0634) return ArabicJoiningType.DualJoining; // SHEEN\n\tif (cp === 0x0635) return ArabicJoiningType.DualJoining; // SAD\n\tif (cp === 0x0636) return ArabicJoiningType.DualJoining; // DAD\n\tif (cp === 0x0637) return ArabicJoiningType.DualJoining; // TAH\n\tif (cp === 0x0638) return ArabicJoiningType.DualJoining; // ZAH\n\tif (cp === 0x0639) return ArabicJoiningType.DualJoining; // AIN\n\tif (cp === 0x063a) return ArabicJoiningType.DualJoining; // GHAIN\n\tif (cp >= 0x063b && cp <= 0x063f) return ArabicJoiningType.DualJoining; // Extended\n\tif (cp === 0x0641) return ArabicJoiningType.DualJoining; // FEH\n\tif (cp === 0x0642) return ArabicJoiningType.DualJoining; // QAF\n\tif (cp === 0x0643) return ArabicJoiningType.DualJoining; // KAF\n\tif (cp === 0x0644) return ArabicJoiningType.DualJoining; // LAM\n\tif (cp === 0x0645) return ArabicJoiningType.DualJoining; // MEEM\n\tif (cp === 0x0646) return ArabicJoiningType.DualJoining; // NOON\n\tif (cp === 0x0647) return ArabicJoiningType.DualJoining; // HEH\n\tif (cp === 0x0649) return ArabicJoiningType.DualJoining; // ALEF MAKSURA\n\tif (cp === 0x064a) return ArabicJoiningType.DualJoining; // YEH\n\tif (cp >= 0x066e && cp <= 0x066f) return ArabicJoiningType.DualJoining; // DOTLESS BEH/QAF\n\tif (cp >= 0x0678 && cp <= 0x0687) return ArabicJoiningType.DualJoining; // Extended Arabic\n\tif (cp >= 0x069a && cp <= 0x06bf) return ArabicJoiningType.DualJoining; // More extended\n\tif (cp >= 0x06c1 && cp <= 0x06c2) return ArabicJoiningType.DualJoining; // HEH variants\n\tif (cp === 0x06cc) return ArabicJoiningType.DualJoining; // FARSI YEH\n\tif (cp >= 0x06ce && cp <= 0x06d1) return ArabicJoiningType.DualJoining; // YEH variants\n\tif (cp === 0x06d5) return ArabicJoiningType.DualJoining; // AE\n\tif (cp >= 0x06fa && cp <= 0x06fc) return ArabicJoiningType.DualJoining; // More letters\n\tif (cp === 0x06ff) return ArabicJoiningType.DualJoining; // HEH WITH INVERTED V\n\n\t// Right-joining letters (only connect on the right)\n\t// ALEF and its variants, DAL/DHAL, REH/ZAY, WAW\n\tif (cp === 0x0622) return ArabicJoiningType.RightJoining; // ALEF WITH MADDA ABOVE\n\tif (cp === 0x0623) return ArabicJoiningType.RightJoining; // ALEF WITH HAMZA ABOVE\n\tif (cp === 0x0624) return ArabicJoiningType.RightJoining; // WAW WITH HAMZA ABOVE\n\tif (cp === 0x0625) return ArabicJoiningType.RightJoining; // ALEF WITH HAMZA BELOW\n\tif (cp === 0x0627) return ArabicJoiningType.RightJoining; // ALEF\n\tif (cp === 0x0629) return ArabicJoiningType.RightJoining; // TEH MARBUTA\n\tif (cp === 0x062f) return ArabicJoiningType.RightJoining; // DAL\n\tif (cp === 0x0630) return ArabicJoiningType.RightJoining; // THAL\n\tif (cp === 0x0631) return ArabicJoiningType.RightJoining; // REH\n\tif (cp === 0x0632) return ArabicJoiningType.RightJoining; // ZAIN\n\tif (cp === 0x0648) return ArabicJoiningType.RightJoining; // WAW\n\tif (cp === 0x0671) return ArabicJoiningType.RightJoining; // ALEF WASLA\n\tif (cp >= 0x0672 && cp <= 0x0677) return ArabicJoiningType.RightJoining; // ALEF variants\n\tif (cp >= 0x0688 && cp <= 0x0699) return ArabicJoiningType.RightJoining; // DAL/REH extended\n\tif (cp >= 0x06c0 && cp <= 0x06c0) return ArabicJoiningType.RightJoining; // HEH WITH YEH\n\tif (cp === 0x06c3) return ArabicJoiningType.RightJoining; // TEH MARBUTA GOAL\n\tif (cp >= 0x06c4 && cp <= 0x06cb) return ArabicJoiningType.RightJoining; // WAW variants\n\tif (cp === 0x06cd) return ArabicJoiningType.RightJoining; // YEH WITH TAIL\n\tif (cp >= 0x06d2 && cp <= 0x06d3) return ArabicJoiningType.RightJoining; // YEH BARREE\n\n\t// TATWEEL - Join causing\n\tif (cp === 0x0640) return ArabicJoiningType.JoinCausing;\n\n\t// Transparent - combining marks, diacritics\n\tif (cp >= 0x064b && cp <= 0x065f) return ArabicJoiningType.Transparent; // Arabic marks\n\tif (cp === 0x0670) return ArabicJoiningType.Transparent; // SUPERSCRIPT ALEF\n\tif (cp >= 0x06d6 && cp <= 0x06ed) return ArabicJoiningType.Transparent; // Quranic marks\n\tif (cp >= 0x08d3 && cp <= 0x08ff) return ArabicJoiningType.Transparent; // Extended marks\n\n\t// Default for Arabic range: NonJoining\n\tif (isArabic(cp)) return ArabicJoiningType.NonJoining;\n\n\treturn ArabicJoiningType.NonJoining;\n}\n\n/**\n * Analyze joining for a sequence of glyphs.\n * Returns the action to take for each glyph.\n */\nexport function analyzeJoining(infos: GlyphInfo[]): JoiningAction[] {\n\tconst n = infos.length;\n\tconst actions: JoiningAction[] = new Array(n).fill(JoiningAction.None);\n\tconst types: ArabicJoiningType[] = [];\n\n\t// Get joining types for all glyphs\n\tfor (const info of infos) {\n\t\tconst cp = info.codepoint ?? 0;\n\t\ttypes.push(getJoiningType(cp));\n\t}\n\n\t// Analyze each glyph based on neighbors (skipping transparent)\n\tfor (let i = 0; i < n; i++) {\n\t\tconst type = types[i];\n\t\tif (!type) continue;\n\n\t\t// Skip non-Arabic characters\n\t\tif (\n\t\t\ttype === ArabicJoiningType.NonJoining ||\n\t\t\ttype === ArabicJoiningType.Transparent\n\t\t) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Find previous non-transparent glyph\n\t\tlet prevType: ArabicJoiningType | null = null;\n\t\tfor (let j = i - 1; j >= 0; j--) {\n\t\t\tconst jType = types[j];\n\t\t\tif (jType && jType !== ArabicJoiningType.Transparent) {\n\t\t\t\tprevType = jType;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t// Find next non-transparent glyph\n\t\tlet nextType: ArabicJoiningType | null = null;\n\t\tfor (let j = i + 1; j < n; j++) {\n\t\t\tconst jType = types[j];\n\t\t\tif (jType && jType !== ArabicJoiningType.Transparent) {\n\t\t\t\tnextType = jType;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t// Determine if we join left/right\n\t\tconst joinsLeft =\n\t\t\tprevType === ArabicJoiningType.DualJoining ||\n\t\t\tprevType === ArabicJoiningType.LeftJoining ||\n\t\t\tprevType === ArabicJoiningType.JoinCausing;\n\n\t\tconst joinsRight =\n\t\t\tnextType === ArabicJoiningType.DualJoining ||\n\t\t\tnextType === ArabicJoiningType.RightJoining ||\n\t\t\tnextType === ArabicJoiningType.JoinCausing;\n\n\t\t// Determine action based on joining type and context\n\t\tif (type === ArabicJoiningType.DualJoining) {\n\t\t\tif (joinsLeft && joinsRight) {\n\t\t\t\tactions[i] = JoiningAction.Medi;\n\t\t\t} else if (joinsLeft) {\n\t\t\t\tactions[i] = JoiningAction.Fina;\n\t\t\t} else if (joinsRight) {\n\t\t\t\tactions[i] = JoiningAction.Init;\n\t\t\t} else {\n\t\t\t\tactions[i] = JoiningAction.Isol;\n\t\t\t}\n\t\t} else if (type === ArabicJoiningType.RightJoining) {\n\t\t\t// Right-joining can only join on the right (to previous glyph in RTL)\n\t\t\tif (joinsLeft) {\n\t\t\t\tactions[i] = JoiningAction.Fina;\n\t\t\t} else {\n\t\t\t\tactions[i] = JoiningAction.Isol;\n\t\t\t}\n\t\t} else if (type === ArabicJoiningType.LeftJoining) {\n\t\t\t// Left-joining (rare)\n\t\t\tif (joinsRight) {\n\t\t\t\tactions[i] = JoiningAction.Init;\n\t\t\t} else {\n\t\t\t\tactions[i] = JoiningAction.Isol;\n\t\t\t}\n\t\t} else if (type === ArabicJoiningType.JoinCausing) {\n\t\t\t// TATWEEL - just connects, no form change\n\t\t\tactions[i] = JoiningAction.None;\n\t\t}\n\t}\n\n\treturn actions;\n}\n\n/**\n * Get the feature tag for a joining action\n */\nexport function getFeatureForAction(action: JoiningAction): string | null {\n\tswitch (action) {\n\t\tcase JoiningAction.Isol:\n\t\t\treturn \"isol\";\n\t\tcase JoiningAction.Fina:\n\t\t\treturn \"fina\";\n\t\tcase JoiningAction.Medi:\n\t\t\treturn \"medi\";\n\t\tcase JoiningAction.Init:\n\t\t\treturn \"init\";\n\t\tdefault:\n\t\t\treturn null;\n\t}\n}\n\n/**\n * Set the feature mask for each glyph based on joining analysis\n */\nexport function setupArabicMasks(infos: GlyphInfo[]): void {\n\tconst actions = analyzeJoining(infos);\n\n\t// Feature tag bits (these should match how ShapePlan assigns masks)\n\t// For now we use a simple scheme where:\n\t// - bit 0: isol\n\t// - bit 1: fina\n\t// - bit 2: medi\n\t// - bit 3: init\n\tfor (const [i, action] of actions.entries()) {\n\t\tconst info = infos[i];\n\t\tif (!info) continue;\n\n\t\t// Set mask based on action\n\t\t// The shaper will need to check these masks when applying features\n\t\tswitch (action) {\n\t\t\tcase JoiningAction.Isol:\n\t\t\t\tinfo.mask = (info.mask & 0xfffffff0) | 0x1;\n\t\t\t\tbreak;\n\t\t\tcase JoiningAction.Fina:\n\t\t\t\tinfo.mask = (info.mask & 0xfffffff0) | 0x2;\n\t\t\t\tbreak;\n\t\t\tcase JoiningAction.Medi:\n\t\t\t\tinfo.mask = (info.mask & 0xfffffff0) | 0x4;\n\t\t\t\tbreak;\n\t\t\tcase JoiningAction.Init:\n\t\t\t\tinfo.mask = (info.mask & 0xfffffff0) | 0x8;\n\t\t\t\tbreak;\n\t\t}\n\t}\n}\n",
91
- "import type { GlyphInfo } from \"../../types.ts\";\n\n/**\n * Hangul shaper for Korean text\n * Handles Jamo composition and syllable block formation\n */\n\n// Hangul Unicode ranges\nconst HANGUL_BASE = 0xac00; // First precomposed syllable (가)\nconst HANGUL_END = 0xd7a3; // Last precomposed syllable (힣)\n\nconst JAMO_L_BASE = 0x1100; // Leading consonant (choseong) base\nconst JAMO_V_BASE = 0x1161; // Vowel (jungseong) base\nconst JAMO_T_BASE = 0x11a7; // Trailing consonant (jongseong) base - 0x11a8 is first real one\n\nconst JAMO_L_COUNT = 19; // Number of leading consonants\nconst JAMO_V_COUNT = 21; // Number of vowels\nconst JAMO_T_COUNT = 28; // Number of trailing consonants (including none)\n\nconst JAMO_VT_COUNT = JAMO_V_COUNT * JAMO_T_COUNT; // 588\nconst _JAMO_LVT_COUNT = JAMO_L_COUNT * JAMO_VT_COUNT; // 11172\n\n// Compatibility Jamo (for conversion)\nconst COMPAT_JAMO_START = 0x3131;\nconst COMPAT_JAMO_END = 0x318e;\n\n// Hangul Jamo Extended-A (old Korean)\nconst JAMO_EXT_A_START = 0xa960;\nconst JAMO_EXT_A_END = 0xa97c;\n\n// Hangul Jamo Extended-B (old Korean)\nconst JAMO_EXT_B_START = 0xd7b0;\nconst JAMO_EXT_B_END = 0xd7fb;\n\n/**\n * Check if codepoint is a Hangul syllable\n */\nexport function isHangulSyllable(cp: number): boolean {\n\treturn cp >= HANGUL_BASE && cp <= HANGUL_END;\n}\n\n/**\n * Check if codepoint is a Hangul Jamo (conjoining)\n */\nexport function isHangulJamo(cp: number): boolean {\n\treturn (\n\t\t(cp >= JAMO_L_BASE && cp <= 0x11ff) ||\n\t\t(cp >= JAMO_EXT_A_START && cp <= JAMO_EXT_A_END) ||\n\t\t(cp >= JAMO_EXT_B_START && cp <= JAMO_EXT_B_END)\n\t);\n}\n\n/**\n * Check if codepoint is a leading consonant (L)\n */\nexport function isJamoL(cp: number): boolean {\n\treturn (\n\t\t(cp >= JAMO_L_BASE && cp < JAMO_L_BASE + JAMO_L_COUNT) ||\n\t\t(cp >= JAMO_EXT_A_START && cp <= JAMO_EXT_A_END)\n\t);\n}\n\n/**\n * Check if codepoint is a vowel (V)\n */\nexport function isJamoV(cp: number): boolean {\n\treturn (\n\t\t(cp >= JAMO_V_BASE && cp < JAMO_V_BASE + JAMO_V_COUNT) ||\n\t\t(cp >= 0xd7b0 && cp <= 0xd7c6)\n\t);\n}\n\n/**\n * Check if codepoint is a trailing consonant (T)\n */\nexport function isJamoT(cp: number): boolean {\n\treturn (\n\t\t(cp > JAMO_T_BASE && cp <= JAMO_T_BASE + JAMO_T_COUNT - 1) ||\n\t\t(cp >= 0xd7cb && cp <= 0xd7fb)\n\t);\n}\n\n/**\n * Decompose a precomposed Hangul syllable into Jamo\n */\nexport function decomposeHangul(cp: number): number[] {\n\tif (!isHangulSyllable(cp)) return [cp];\n\n\tconst syllableIndex = cp - HANGUL_BASE;\n\tconst l = Math.floor(syllableIndex / JAMO_VT_COUNT);\n\tconst v = Math.floor((syllableIndex % JAMO_VT_COUNT) / JAMO_T_COUNT);\n\tconst t = syllableIndex % JAMO_T_COUNT;\n\n\tconst result = [JAMO_L_BASE + l, JAMO_V_BASE + v];\n\tif (t > 0) {\n\t\tresult.push(JAMO_T_BASE + t);\n\t}\n\treturn result;\n}\n\n/**\n * Compose Jamo into a precomposed Hangul syllable\n */\nexport function composeHangul(\n\tl: number,\n\tv: number,\n\tt: number = 0,\n): number | null {\n\t// Normalize indices\n\tconst lIndex = l - JAMO_L_BASE;\n\tconst vIndex = v - JAMO_V_BASE;\n\tconst tIndex = t === 0 ? 0 : t - JAMO_T_BASE;\n\n\tif (lIndex < 0 || lIndex >= JAMO_L_COUNT) return null;\n\tif (vIndex < 0 || vIndex >= JAMO_V_COUNT) return null;\n\tif (tIndex < 0 || tIndex >= JAMO_T_COUNT) return null;\n\n\treturn HANGUL_BASE + lIndex * JAMO_VT_COUNT + vIndex * JAMO_T_COUNT + tIndex;\n}\n\n/**\n * Hangul syllable types\n */\nexport enum HangulSyllableType {\n\tNotApplicable = 0,\n\tLeadingJamo = 1, // L\n\tVowelJamo = 2, // V\n\tTrailingJamo = 3, // T\n\tLVSyllable = 4, // LV (no trailing)\n\tLVTSyllable = 5, // LVT (with trailing)\n}\n\n/**\n * Get the syllable type of a codepoint\n */\nexport function getHangulSyllableType(cp: number): HangulSyllableType {\n\tif (isJamoL(cp)) return HangulSyllableType.LeadingJamo;\n\tif (isJamoV(cp)) return HangulSyllableType.VowelJamo;\n\tif (isJamoT(cp)) return HangulSyllableType.TrailingJamo;\n\n\tif (isHangulSyllable(cp)) {\n\t\tconst syllableIndex = cp - HANGUL_BASE;\n\t\tconst t = syllableIndex % JAMO_T_COUNT;\n\t\treturn t === 0\n\t\t\t? HangulSyllableType.LVSyllable\n\t\t\t: HangulSyllableType.LVTSyllable;\n\t}\n\n\treturn HangulSyllableType.NotApplicable;\n}\n\n/**\n * Feature masks for Hangul\n */\nexport const HangulFeatureMask = {\n\tljmo: 0x0001, // Leading jamo forms\n\tvjmo: 0x0002, // Vowel jamo forms\n\ttjmo: 0x0004, // Trailing jamo forms\n} as const;\n\n/**\n * Setup Hangul masks for feature application\n */\nexport function setupHangulMasks(infos: GlyphInfo[]): void {\n\tfor (const info of infos) {\n\t\tconst type = getHangulSyllableType(info.codepoint);\n\n\t\tswitch (type) {\n\t\t\tcase HangulSyllableType.LeadingJamo:\n\t\t\t\tinfo.mask |= HangulFeatureMask.ljmo;\n\t\t\t\tbreak;\n\t\t\tcase HangulSyllableType.VowelJamo:\n\t\t\t\tinfo.mask |= HangulFeatureMask.vjmo;\n\t\t\t\tbreak;\n\t\t\tcase HangulSyllableType.TrailingJamo:\n\t\t\t\tinfo.mask |= HangulFeatureMask.tjmo;\n\t\t\t\tbreak;\n\t\t\tcase HangulSyllableType.LVSyllable:\n\t\t\tcase HangulSyllableType.LVTSyllable:\n\t\t\t\t// Precomposed syllables don't need special features\n\t\t\t\tbreak;\n\t\t}\n\t}\n}\n\n/**\n * Normalize Hangul - compose Jamo sequences into syllables where possible\n */\nexport function normalizeHangul(infos: GlyphInfo[]): GlyphInfo[] {\n\tconst result: GlyphInfo[] = [];\n\tlet i = 0;\n\n\twhile (i < infos.length) {\n\t\tconst info = infos[i];\n\t\tif (!info) {\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\t\tconst type = getHangulSyllableType(info.codepoint);\n\n\t\t// Try to compose L + V [+ T]\n\t\tif (type === HangulSyllableType.LeadingJamo && i + 1 < infos.length) {\n\t\t\tconst nextInfo = infos[i + 1];\n\t\t\tif (!nextInfo) {\n\t\t\t\tresult.push(info);\n\t\t\t\ti++;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst nextType = getHangulSyllableType(nextInfo.codepoint);\n\n\t\t\tif (nextType === HangulSyllableType.VowelJamo) {\n\t\t\t\t// Check for trailing jamo\n\t\t\t\tlet t = 0;\n\t\t\t\tlet consumed = 2;\n\n\t\t\t\tif (i + 2 < infos.length) {\n\t\t\t\t\tconst thirdInfo = infos[i + 2];\n\t\t\t\t\tif (thirdInfo) {\n\t\t\t\t\t\tconst thirdType = getHangulSyllableType(thirdInfo.codepoint);\n\n\t\t\t\t\t\tif (thirdType === HangulSyllableType.TrailingJamo) {\n\t\t\t\t\t\t\tt = thirdInfo.codepoint;\n\t\t\t\t\t\t\tconsumed = 3;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst composed = composeHangul(info.codepoint, nextInfo.codepoint, t);\n\t\t\t\tif (composed !== null) {\n\t\t\t\t\tresult.push({\n\t\t\t\t\t\tglyphId: info.glyphId, // Will be remapped\n\t\t\t\t\t\tcluster: info.cluster,\n\t\t\t\t\t\tmask: info.mask,\n\t\t\t\t\t\tcodepoint: composed,\n\t\t\t\t\t});\n\t\t\t\t\ti += consumed;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Try to compose LV + T\n\t\tif (type === HangulSyllableType.LVSyllable && i + 1 < infos.length) {\n\t\t\tconst nextInfo = infos[i + 1];\n\t\t\tif (!nextInfo) {\n\t\t\t\tresult.push(info);\n\t\t\t\ti++;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst nextType = getHangulSyllableType(nextInfo.codepoint);\n\n\t\t\tif (nextType === HangulSyllableType.TrailingJamo) {\n\t\t\t\t// Decompose LV, add T, recompose\n\t\t\t\tconst decomposed = decomposeHangul(info.codepoint);\n\t\t\t\tconst [firstJamo, secondJamo] = decomposed;\n\t\t\t\tif (\n\t\t\t\t\tdecomposed.length === 2 &&\n\t\t\t\t\tfirstJamo !== undefined &&\n\t\t\t\t\tsecondJamo !== undefined\n\t\t\t\t) {\n\t\t\t\t\tconst composed = composeHangul(\n\t\t\t\t\t\tfirstJamo,\n\t\t\t\t\t\tsecondJamo,\n\t\t\t\t\t\tnextInfo.codepoint,\n\t\t\t\t\t);\n\t\t\t\t\tif (composed !== null) {\n\t\t\t\t\t\tresult.push({\n\t\t\t\t\t\t\tglyphId: info.glyphId,\n\t\t\t\t\t\t\tcluster: info.cluster,\n\t\t\t\t\t\t\tmask: info.mask,\n\t\t\t\t\t\t\tcodepoint: composed,\n\t\t\t\t\t\t});\n\t\t\t\t\t\ti += 2;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// No composition, keep as-is\n\t\tresult.push(info);\n\t\ti++;\n\t}\n\n\treturn result;\n}\n\n/**\n * Check if codepoint is Korean (Hangul or Jamo)\n */\nexport function isKorean(cp: number): boolean {\n\treturn (\n\t\tisHangulSyllable(cp) ||\n\t\tisHangulJamo(cp) ||\n\t\t(cp >= COMPAT_JAMO_START && cp <= COMPAT_JAMO_END)\n\t);\n}\n",
92
- "import type { GlyphInfo } from \"../../types.ts\";\n\n/**\n * Hebrew character categories\n */\nexport enum HebrewCategory {\n\tOther = 0,\n\tLetter = 1, // Regular letter\n\tPoint = 2, // Niqqud (vowel point)\n\tDagesh = 3, // Dagesh/Mapiq\n\tShin = 4, // Shin/Sin dot\n\tRafe = 5, // Rafe mark\n\tAccent = 6, // Cantillation marks\n\tMaqaf = 7, // Hebrew hyphen\n\tPunctuation = 8, // Punctuation\n}\n\n/**\n * Hebrew Unicode range\n */\nconst HEBREW_START = 0x0590;\nconst HEBREW_END = 0x05ff;\nconst HEBREW_EXTENDED_START = 0xfb1d;\nconst HEBREW_EXTENDED_END = 0xfb4f;\n\n/**\n * Check if codepoint is Hebrew\n */\nexport function isHebrew(cp: number): boolean {\n\treturn (\n\t\t(cp >= HEBREW_START && cp <= HEBREW_END) ||\n\t\t(cp >= HEBREW_EXTENDED_START && cp <= HEBREW_EXTENDED_END)\n\t);\n}\n\n/**\n * Get Hebrew category for a codepoint\n */\nexport function getHebrewCategory(cp: number): HebrewCategory {\n\t// Cantillation marks (0591-05AF)\n\tif (cp >= 0x0591 && cp <= 0x05af) return HebrewCategory.Accent;\n\n\t// Points (05B0-05BD)\n\tif (cp >= 0x05b0 && cp <= 0x05bd) return HebrewCategory.Point;\n\n\t// Maqaf\n\tif (cp === 0x05be) return HebrewCategory.Maqaf;\n\n\t// Rafe\n\tif (cp === 0x05bf) return HebrewCategory.Rafe;\n\n\t// Paseq, Sof Pasuq\n\tif (cp === 0x05c0 || cp === 0x05c3) return HebrewCategory.Punctuation;\n\n\t// Shin/Sin dot\n\tif (cp === 0x05c1 || cp === 0x05c2) return HebrewCategory.Shin;\n\n\t// Dagesh/Mapiq\n\tif (cp === 0x05bc) return HebrewCategory.Dagesh;\n\n\t// Meteg\n\tif (cp === 0x05bd) return HebrewCategory.Point;\n\n\t// Letters (05D0-05EA)\n\tif (cp >= 0x05d0 && cp <= 0x05ea) return HebrewCategory.Letter;\n\n\t// Final letters are handled the same\n\tif (cp >= 0x05f0 && cp <= 0x05f4) return HebrewCategory.Letter;\n\n\t// Extended forms (FB1D-FB4F)\n\tif (cp >= 0xfb1d && cp <= 0xfb4f) return HebrewCategory.Letter;\n\n\tif (isHebrew(cp)) return HebrewCategory.Other;\n\treturn HebrewCategory.Other;\n}\n\n/**\n * Set up masks for Hebrew shaping\n * Hebrew is relatively simple - mainly RTL with marks\n */\nexport function setupHebrewMasks(infos: GlyphInfo[]): void {\n\t// Hebrew shaping primarily relies on:\n\t// 1. Mark positioning (handled by GPOS)\n\t// 2. RTL reordering (handled by main shaper)\n\n\t// Group characters with their base letters\n\tlet baseIndex = 0;\n\n\tfor (let i = 0; i < infos.length; i++) {\n\t\tconst info = infos[i];\n\t\tif (!info) continue;\n\n\t\tconst cat = getHebrewCategory(info.codepoint);\n\n\t\t// Letters start new clusters\n\t\tif (cat === HebrewCategory.Letter) {\n\t\t\tbaseIndex = i;\n\t\t}\n\n\t\t// Store base index for mark attachment\n\t\tinfo.mask = (info.mask & 0xffff0000) | (baseIndex & 0xffff);\n\t}\n}\n",
93
- "import type { GlyphInfo } from \"../../types.ts\";\n\n/**\n * Indic syllable categories based on Unicode and OpenType spec\n */\nexport enum IndicCategory {\n\tX = 0, // Other/Unknown\n\tC = 1, // Consonant\n\tV = 2, // Independent vowel\n\tN = 3, // Nukta\n\tH = 4, // Halant/Virama\n\tZWNJ = 5, // Zero Width Non-Joiner\n\tZWJ = 6, // Zero Width Joiner\n\tM = 7, // Matra (dependent vowel)\n\tSM = 8, // Syllable modifier (anusvara, visarga)\n\tA = 9, // Accent mark\n\tVD = 10, // Vedic mark\n\tPlaceholder = 11, // Placeholder (dotted circle)\n\tDotted_Circle = 12, // Explicit dotted circle\n\tRS = 13, // Repha form\n\tCoeng = 14, // Coeng (Khmer virama)\n\tRa = 15, // Ra consonant (for repha)\n\tCM = 16, // Consonant modifier\n\tSymbol = 17, // Symbol\n\tCS = 18, // Consonant with stacker\n}\n\n/**\n * Indic syllabic position\n */\nexport enum IndicPosition {\n\tStart = 0,\n\tRaToBecomeReph = 1,\n\tPreM = 2,\n\tPreC = 3,\n\tBaseC = 4,\n\tAfterMain = 5,\n\tAboveC = 6,\n\tBeforeSub = 7,\n\tBelowC = 8,\n\tAfterSub = 9,\n\tBeforePost = 10,\n\tPostC = 11,\n\tAfterPost = 12,\n\tFinalC = 13,\n\tSMVD = 14,\n\tEnd = 15,\n}\n\n/**\n * Per-glyph Indic shaping data\n */\nexport interface IndicGlyphData {\n\tcategory: IndicCategory;\n\tposition: IndicPosition;\n\tsyllableIndex: number;\n}\n\n/**\n * Determine if codepoint is in Devanagari range\n */\nfunction isDevanagari(cp: number): boolean {\n\treturn cp >= 0x0900 && cp <= 0x097f;\n}\n\n/**\n * Determine if codepoint is in Bengali range\n */\nfunction isBengali(cp: number): boolean {\n\treturn cp >= 0x0980 && cp <= 0x09ff;\n}\n\n/**\n * Determine if codepoint is in Gurmukhi range\n */\nfunction isGurmukhi(cp: number): boolean {\n\treturn cp >= 0x0a00 && cp <= 0x0a7f;\n}\n\n/**\n * Determine if codepoint is in Gujarati range\n */\nfunction isGujarati(cp: number): boolean {\n\treturn cp >= 0x0a80 && cp <= 0x0aff;\n}\n\n/**\n * Determine if codepoint is in Oriya range\n */\nfunction isOriya(cp: number): boolean {\n\treturn cp >= 0x0b00 && cp <= 0x0b7f;\n}\n\n/**\n * Determine if codepoint is in Tamil range\n */\nfunction isTamil(cp: number): boolean {\n\treturn cp >= 0x0b80 && cp <= 0x0bff;\n}\n\n/**\n * Determine if codepoint is in Telugu range\n */\nfunction isTelugu(cp: number): boolean {\n\treturn cp >= 0x0c00 && cp <= 0x0c7f;\n}\n\n/**\n * Determine if codepoint is in Kannada range\n */\nfunction isKannada(cp: number): boolean {\n\treturn cp >= 0x0c80 && cp <= 0x0cff;\n}\n\n/**\n * Determine if codepoint is in Malayalam range\n */\nfunction isMalayalam(cp: number): boolean {\n\treturn cp >= 0x0d00 && cp <= 0x0d7f;\n}\n\n/**\n * Check if a codepoint is an Indic script\n */\nexport function isIndic(cp: number): boolean {\n\treturn (\n\t\tisDevanagari(cp) ||\n\t\tisBengali(cp) ||\n\t\tisGurmukhi(cp) ||\n\t\tisGujarati(cp) ||\n\t\tisOriya(cp) ||\n\t\tisTamil(cp) ||\n\t\tisTelugu(cp) ||\n\t\tisKannada(cp) ||\n\t\tisMalayalam(cp)\n\t);\n}\n\n/**\n * Get the Indic category for a codepoint\n */\nexport function getIndicCategory(cp: number): IndicCategory {\n\t// Zero-width characters\n\tif (cp === 0x200c) return IndicCategory.ZWNJ;\n\tif (cp === 0x200d) return IndicCategory.ZWJ;\n\tif (cp === 0x25cc) return IndicCategory.Dotted_Circle;\n\n\t// Devanagari (0900-097F)\n\tif (isDevanagari(cp)) {\n\t\t// Vowel signs (matras)\n\t\tif (\n\t\t\t(cp >= 0x093a && cp <= 0x093b) ||\n\t\t\t(cp >= 0x093e && cp <= 0x094c) ||\n\t\t\t(cp >= 0x094e && cp <= 0x094f) ||\n\t\t\t(cp >= 0x0955 && cp <= 0x0957)\n\t\t) {\n\t\t\treturn IndicCategory.M;\n\t\t}\n\t\t// Virama\n\t\tif (cp === 0x094d) return IndicCategory.H;\n\t\t// Nukta\n\t\tif (cp === 0x093c) return IndicCategory.N;\n\t\t// Anusvara, Visarga, Chandrabindu\n\t\tif (cp >= 0x0901 && cp <= 0x0903) return IndicCategory.SM;\n\t\t// Vedic marks\n\t\tif (cp >= 0x0951 && cp <= 0x0954) return IndicCategory.A;\n\t\t// Independent vowels\n\t\tif (\n\t\t\t(cp >= 0x0904 && cp <= 0x0914) ||\n\t\t\tcp === 0x0960 ||\n\t\t\tcp === 0x0961 ||\n\t\t\tcp === 0x0972 ||\n\t\t\t(cp >= 0x0976 && cp <= 0x0977)\n\t\t) {\n\t\t\treturn IndicCategory.V;\n\t\t}\n\t\t// Consonants\n\t\tif (\n\t\t\t(cp >= 0x0915 && cp <= 0x0939) ||\n\t\t\t(cp >= 0x0958 && cp <= 0x095f) ||\n\t\t\tcp === 0x0978 ||\n\t\t\tcp === 0x0979 ||\n\t\t\tcp === 0x097a ||\n\t\t\t(cp >= 0x097b && cp <= 0x097c) ||\n\t\t\t(cp >= 0x097e && cp <= 0x097f)\n\t\t) {\n\t\t\t// Ra for repha\n\t\t\tif (cp === 0x0930) return IndicCategory.Ra;\n\t\t\treturn IndicCategory.C;\n\t\t}\n\t\t// Digits and symbols\n\t\tif (cp >= 0x0966 && cp <= 0x096f) return IndicCategory.Symbol;\n\t\treturn IndicCategory.X;\n\t}\n\n\t// Bengali (0980-09FF)\n\tif (isBengali(cp)) {\n\t\tif (\n\t\t\t(cp >= 0x09be && cp <= 0x09c4) ||\n\t\t\t(cp >= 0x09c7 && cp <= 0x09c8) ||\n\t\t\t(cp >= 0x09cb && cp <= 0x09cc) ||\n\t\t\tcp === 0x09d7\n\t\t) {\n\t\t\treturn IndicCategory.M;\n\t\t}\n\t\tif (cp === 0x09cd) return IndicCategory.H;\n\t\tif (cp === 0x09bc) return IndicCategory.N;\n\t\tif (cp >= 0x0981 && cp <= 0x0983) return IndicCategory.SM;\n\t\tif (\n\t\t\t(cp >= 0x0985 && cp <= 0x098c) ||\n\t\t\t(cp >= 0x098f && cp <= 0x0990) ||\n\t\t\t(cp >= 0x0993 && cp <= 0x0994) ||\n\t\t\tcp === 0x09e0 ||\n\t\t\tcp === 0x09e1\n\t\t) {\n\t\t\treturn IndicCategory.V;\n\t\t}\n\t\tif (\n\t\t\t(cp >= 0x0995 && cp <= 0x09a8) ||\n\t\t\t(cp >= 0x09aa && cp <= 0x09b0) ||\n\t\t\tcp === 0x09b2 ||\n\t\t\t(cp >= 0x09b6 && cp <= 0x09b9) ||\n\t\t\t(cp >= 0x09dc && cp <= 0x09dd) ||\n\t\t\t(cp >= 0x09df && cp <= 0x09e1)\n\t\t) {\n\t\t\tif (cp === 0x09b0) return IndicCategory.Ra;\n\t\t\treturn IndicCategory.C;\n\t\t}\n\t\treturn IndicCategory.X;\n\t}\n\n\t// Other Indic scripts - simplified handling\n\t// Tamil, Telugu, Kannada, Malayalam, Gurmukhi, Gujarati, Oriya\n\tif (\n\t\tisGurmukhi(cp) ||\n\t\tisGujarati(cp) ||\n\t\tisOriya(cp) ||\n\t\tisTamil(cp) ||\n\t\tisTelugu(cp) ||\n\t\tisKannada(cp) ||\n\t\tisMalayalam(cp)\n\t) {\n\t\tconst offset = cp & 0x7f; // Position within the block\n\t\t// Common patterns for Indic scripts\n\t\tif (offset >= 0x01 && offset <= 0x03) return IndicCategory.SM; // Anusvara etc\n\t\tif (offset >= 0x05 && offset <= 0x14) return IndicCategory.V; // Vowels\n\t\tif (offset >= 0x15 && offset <= 0x39) return IndicCategory.C; // Consonants\n\t\tif (offset === 0x3c) return IndicCategory.N; // Nukta\n\t\tif (offset >= 0x3e && offset <= 0x4c) return IndicCategory.M; // Matras\n\t\tif (offset === 0x4d) return IndicCategory.H; // Virama\n\t\treturn IndicCategory.X;\n\t}\n\n\treturn IndicCategory.X;\n}\n\n/**\n * Syllable structure for Indic scripts\n */\ninterface Syllable {\n\tstart: number;\n\tend: number;\n\thasReph: boolean;\n\tbaseConsonant: number;\n}\n\n/**\n * Find syllable boundaries in the glyph buffer\n */\nexport function findSyllables(infos: GlyphInfo[]): Syllable[] {\n\tconst syllables: Syllable[] = [];\n\tconst n = infos.length;\n\tif (n === 0) return syllables;\n\n\tlet start = 0;\n\n\twhile (start < n) {\n\t\tconst syllable = parseSyllable(infos, start);\n\t\tsyllables.push(syllable);\n\t\tstart = syllable.end;\n\t}\n\n\treturn syllables;\n}\n\n/**\n * Parse a single syllable starting at the given position\n */\nfunction parseSyllable(infos: GlyphInfo[], start: number): Syllable {\n\tconst n = infos.length;\n\tlet pos = start;\n\n\t// Check for initial consonant cluster with halant\n\tlet baseConsonant = -1;\n\tlet hasReph = false;\n\n\t// Look for Ra + H at the start (potential Reph)\n\tif (pos + 1 < n) {\n\t\tconst info1 = infos[pos];\n\t\tconst info2 = infos[pos + 1];\n\t\tif (info1 && info2) {\n\t\t\tconst cat1 = getIndicCategory(info1.codepoint ?? 0);\n\t\t\tconst cat2 = getIndicCategory(info2.codepoint ?? 0);\n\t\t\tif (cat1 === IndicCategory.Ra && cat2 === IndicCategory.H) {\n\t\t\t\thasReph = true;\n\t\t\t\tpos += 2;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Find base consonant (last consonant before matras/end)\n\tlet lastConsonant = -1;\n\twhile (pos < n) {\n\t\tconst info = infos[pos];\n\t\tif (!info) {\n\t\t\tpos++;\n\t\t\tcontinue;\n\t\t}\n\t\tconst cp = info.codepoint ?? 0;\n\t\tconst cat = getIndicCategory(cp);\n\n\t\tif (cat === IndicCategory.C || cat === IndicCategory.Ra) {\n\t\t\tlastConsonant = pos;\n\t\t\tpos++;\n\t\t\t// Check for nukta\n\t\t\tif (pos < n) {\n\t\t\t\tconst nextInfo = infos[pos];\n\t\t\t\tif (\n\t\t\t\t\tnextInfo &&\n\t\t\t\t\tgetIndicCategory(nextInfo.codepoint ?? 0) === IndicCategory.N\n\t\t\t\t) {\n\t\t\t\t\tpos++;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Check for halant (may continue consonant cluster)\n\t\t\tif (pos < n) {\n\t\t\t\tconst hInfo = infos[pos];\n\t\t\t\tif (\n\t\t\t\t\thInfo &&\n\t\t\t\t\tgetIndicCategory(hInfo.codepoint ?? 0) === IndicCategory.H\n\t\t\t\t) {\n\t\t\t\t\tpos++;\n\t\t\t\t\t// After halant, might have ZWJ/ZWNJ or another consonant\n\t\t\t\t\tif (pos < n) {\n\t\t\t\t\t\tconst afterH = infos[pos];\n\t\t\t\t\t\tif (afterH) {\n\t\t\t\t\t\t\tconst nextCat = getIndicCategory(afterH.codepoint ?? 0);\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tnextCat === IndicCategory.ZWJ ||\n\t\t\t\t\t\t\t\tnextCat === IndicCategory.ZWNJ\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tpos++;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tcontinue; // Look for more consonants\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\t} else if (cat === IndicCategory.V) {\n\t\t\t// Independent vowel as syllable base\n\t\t\tpos++;\n\t\t\tbreak;\n\t\t} else if (cat === IndicCategory.N) {\n\t\t\t// Standalone nukta - skip\n\t\t\tpos++;\n\t\t} else {\n\t\t\t// Non-syllable character, end here\n\t\t\tif (lastConsonant === -1) {\n\t\t\t\tpos++;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tbaseConsonant = lastConsonant >= 0 ? lastConsonant : start;\n\n\t// Consume matras, anusvara, visarga\n\twhile (pos < n) {\n\t\tconst info = infos[pos];\n\t\tif (!info) {\n\t\t\tpos++;\n\t\t\tcontinue;\n\t\t}\n\t\tconst cp = info.codepoint ?? 0;\n\t\tconst cat = getIndicCategory(cp);\n\n\t\tif (\n\t\t\tcat === IndicCategory.M ||\n\t\t\tcat === IndicCategory.SM ||\n\t\t\tcat === IndicCategory.A ||\n\t\t\tcat === IndicCategory.N\n\t\t) {\n\t\t\tpos++;\n\t\t} else if (cat === IndicCategory.H) {\n\t\t\t// Halant at end (final form)\n\t\t\tpos++;\n\t\t\tbreak;\n\t\t} else {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Ensure we advance at least one position\n\tif (pos === start) {\n\t\tpos = start + 1;\n\t}\n\n\treturn {\n\t\tstart,\n\t\tend: pos,\n\t\thasReph,\n\t\tbaseConsonant,\n\t};\n}\n\n/**\n * Indic feature masks for OpenType features\n */\nexport const IndicFeatureMask = {\n\tnukt: 0x0001, // Nukta forms\n\takhn: 0x0002, // Akhand forms\n\trphf: 0x0004, // Reph forms\n\trkrf: 0x0008, // Rakaar forms\n\tpref: 0x0010, // Pre-base forms\n\tblwf: 0x0020, // Below-base forms\n\tabvf: 0x0040, // Above-base forms\n\thalf: 0x0080, // Half forms\n\tpstf: 0x0100, // Post-base forms\n\tvatu: 0x0200, // Vattu variants\n\tcjct: 0x0400, // Conjunct forms\n\tinit: 0x0800, // Initial forms\n\tpres: 0x1000, // Pre-base substitutions\n\tabvs: 0x2000, // Above-base substitutions\n\tblws: 0x4000, // Below-base substitutions\n\tpsts: 0x8000, // Post-base substitutions\n} as const;\n\n/**\n * Matra position in syllable\n */\nexport enum MatraPosition {\n\tPreBase = 0,\n\tAboveBase = 1,\n\tBelowBase = 2,\n\tPostBase = 3,\n}\n\n/**\n * Get matra position based on codepoint\n */\nexport function getMatraPosition(cp: number): MatraPosition {\n\t// Devanagari\n\tif (cp >= 0x0900 && cp <= 0x097f) {\n\t\t// Pre-base: ि (093F)\n\t\tif (cp === 0x093f) return MatraPosition.PreBase;\n\t\t// Above-base: ॅ ॆ े ै (0945-0948)\n\t\tif (cp >= 0x0945 && cp <= 0x0948) return MatraPosition.AboveBase;\n\t\t// Below-base: ु ू ृ ॄ (0941-0944)\n\t\tif (cp >= 0x0941 && cp <= 0x0944) return MatraPosition.BelowBase;\n\t\t// Post-base: everything else\n\t\treturn MatraPosition.PostBase;\n\t}\n\n\t// Bengali\n\tif (cp >= 0x0980 && cp <= 0x09ff) {\n\t\t// Pre-base: ি (09BF)\n\t\tif (cp === 0x09bf) return MatraPosition.PreBase;\n\t\t// Pre-base split vowels: ে ৈ (09C7-09C8) - left part\n\t\tif (cp === 0x09c7 || cp === 0x09c8) return MatraPosition.PreBase;\n\t\t// Below-base: ু ূ ৃ ৄ (09C1-09C4)\n\t\tif (cp >= 0x09c1 && cp <= 0x09c4) return MatraPosition.BelowBase;\n\t\treturn MatraPosition.PostBase;\n\t}\n\n\t// Tamil\n\tif (cp >= 0x0b80 && cp <= 0x0bff) {\n\t\t// Pre-base: ெ ே ை (0BC6-0BC8)\n\t\tif (cp >= 0x0bc6 && cp <= 0x0bc8) return MatraPosition.PreBase;\n\t\t// Above-base: none\n\t\t// Below-base: ு ூ (0BC1-0BC2)\n\t\tif (cp === 0x0bc1 || cp === 0x0bc2) return MatraPosition.BelowBase;\n\t\treturn MatraPosition.PostBase;\n\t}\n\n\t// Telugu\n\tif (cp >= 0x0c00 && cp <= 0x0c7f) {\n\t\t// Above-base: ి ీ ె ే ై (0C3E-0C40, 0C46-0C48)\n\t\tif ((cp >= 0x0c3e && cp <= 0x0c40) || (cp >= 0x0c46 && cp <= 0x0c48)) {\n\t\t\treturn MatraPosition.AboveBase;\n\t\t}\n\t\t// Below-base: ు ూ ృ ౄ (0C41-0C44)\n\t\tif (cp >= 0x0c41 && cp <= 0x0c44) return MatraPosition.BelowBase;\n\t\treturn MatraPosition.PostBase;\n\t}\n\n\t// Kannada\n\tif (cp >= 0x0c80 && cp <= 0x0cff) {\n\t\t// Above-base: similar to Telugu\n\t\tif ((cp >= 0x0cbe && cp <= 0x0cc0) || (cp >= 0x0cc6 && cp <= 0x0cc8)) {\n\t\t\treturn MatraPosition.AboveBase;\n\t\t}\n\t\tif (cp >= 0x0cc1 && cp <= 0x0cc4) return MatraPosition.BelowBase;\n\t\treturn MatraPosition.PostBase;\n\t}\n\n\t// Malayalam\n\tif (cp >= 0x0d00 && cp <= 0x0d7f) {\n\t\t// Pre-base: െ േ ൈ (0D46-0D48)\n\t\tif (cp >= 0x0d46 && cp <= 0x0d48) return MatraPosition.PreBase;\n\t\t// Below-base: ു ൂ ൃ (0D41-0D43)\n\t\tif (cp >= 0x0d41 && cp <= 0x0d43) return MatraPosition.BelowBase;\n\t\treturn MatraPosition.PostBase;\n\t}\n\n\t// Gurmukhi\n\tif (cp >= 0x0a00 && cp <= 0x0a7f) {\n\t\t// Pre-base: ਿ (0A3F)\n\t\tif (cp === 0x0a3f) return MatraPosition.PreBase;\n\t\t// Below-base: ੁ ੂ (0A41-0A42)\n\t\tif (cp === 0x0a41 || cp === 0x0a42) return MatraPosition.BelowBase;\n\t\treturn MatraPosition.PostBase;\n\t}\n\n\t// Gujarati\n\tif (cp >= 0x0a80 && cp <= 0x0aff) {\n\t\t// Pre-base: િ (0ABF)\n\t\tif (cp === 0x0abf) return MatraPosition.PreBase;\n\t\t// Below-base: ુ ૂ ૃ ૄ (0AC1-0AC4)\n\t\tif (cp >= 0x0ac1 && cp <= 0x0ac4) return MatraPosition.BelowBase;\n\t\treturn MatraPosition.PostBase;\n\t}\n\n\t// Oriya\n\tif (cp >= 0x0b00 && cp <= 0x0b7f) {\n\t\t// Pre-base: ି (0B3F)\n\t\tif (cp === 0x0b3f) return MatraPosition.PreBase;\n\t\t// Below-base: ୁ ୂ ୃ (0B41-0B43)\n\t\tif (cp >= 0x0b41 && cp <= 0x0b43) return MatraPosition.BelowBase;\n\t\treturn MatraPosition.PostBase;\n\t}\n\n\treturn MatraPosition.PostBase;\n}\n\n/**\n * Set up masks and syllable indices for Indic shaping\n */\nexport function setupIndicMasks(infos: GlyphInfo[]): void {\n\tconst syllables = findSyllables(infos);\n\n\tfor (const [i, syllable] of syllables.entries()) {\n\t\t// Mark syllable boundaries in mask\n\t\tfor (let j = syllable.start; j < syllable.end; j++) {\n\t\t\tconst info = infos[j];\n\t\t\tif (info) {\n\t\t\t\t// Store syllable index in upper bits\n\t\t\t\tinfo.mask = (info.mask & 0x0000ffff) | ((i & 0xffff) << 16);\n\n\t\t\t\tconst cat = getIndicCategory(info.codepoint);\n\n\t\t\t\t// Nukta - always apply nukt feature\n\t\t\t\tif (cat === IndicCategory.N) {\n\t\t\t\t\tinfo.mask |= IndicFeatureMask.nukt;\n\t\t\t\t}\n\n\t\t\t\t// Halant handling\n\t\t\t\tif (cat === IndicCategory.H) {\n\t\t\t\t\t// Check position relative to base\n\t\t\t\t\tif (j < syllable.baseConsonant) {\n\t\t\t\t\t\t// Pre-base halant - half forms\n\t\t\t\t\t\tinfo.mask |= IndicFeatureMask.half;\n\t\t\t\t\t} else if (j > syllable.baseConsonant) {\n\t\t\t\t\t\t// Post-base halant - below/post forms\n\t\t\t\t\t\tinfo.mask |= IndicFeatureMask.blwf | IndicFeatureMask.pstf;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Consonant handling\n\t\t\t\tif (cat === IndicCategory.C || cat === IndicCategory.Ra) {\n\t\t\t\t\tif (j < syllable.baseConsonant) {\n\t\t\t\t\t\t// Pre-base consonant\n\t\t\t\t\t\tinfo.mask |= IndicFeatureMask.half | IndicFeatureMask.cjct;\n\t\t\t\t\t} else if (j > syllable.baseConsonant) {\n\t\t\t\t\t\t// Post-base consonant\n\t\t\t\t\t\tinfo.mask |=\n\t\t\t\t\t\t\tIndicFeatureMask.blwf |\n\t\t\t\t\t\t\tIndicFeatureMask.pstf |\n\t\t\t\t\t\t\tIndicFeatureMask.vatu;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Reph handling\n\t\t\t\tif (syllable.hasReph && j < syllable.start + 2) {\n\t\t\t\t\tinfo.mask |= IndicFeatureMask.rphf;\n\t\t\t\t}\n\n\t\t\t\t// Matra handling\n\t\t\t\tif (cat === IndicCategory.M) {\n\t\t\t\t\tconst matraPos = getMatraPosition(info.codepoint);\n\t\t\t\t\tswitch (matraPos) {\n\t\t\t\t\t\tcase MatraPosition.PreBase:\n\t\t\t\t\t\t\tinfo.mask |= IndicFeatureMask.pref | IndicFeatureMask.pres;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase MatraPosition.AboveBase:\n\t\t\t\t\t\t\tinfo.mask |= IndicFeatureMask.abvf | IndicFeatureMask.abvs;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase MatraPosition.BelowBase:\n\t\t\t\t\t\t\tinfo.mask |= IndicFeatureMask.blwf | IndicFeatureMask.blws;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase MatraPosition.PostBase:\n\t\t\t\t\t\t\tinfo.mask |= IndicFeatureMask.pstf | IndicFeatureMask.psts;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Syllable modifiers (anusvara, visarga)\n\t\t\t\tif (cat === IndicCategory.SM) {\n\t\t\t\t\tinfo.mask |= IndicFeatureMask.abvs | IndicFeatureMask.psts;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Reorder glyphs within a syllable for correct visual display\n * This handles:\n * - Moving pre-base matras before the base consonant\n * - Moving reph to its final position\n */\nexport function reorderIndic(infos: GlyphInfo[]): void {\n\tconst syllables = findSyllables(infos);\n\n\tfor (const syllable of syllables) {\n\t\treorderSyllable(infos, syllable);\n\t}\n}\n\n/**\n * Reorder a single syllable\n */\nfunction reorderSyllable(infos: GlyphInfo[], syllable: Syllable): void {\n\tconst { start, end, baseConsonant, hasReph } = syllable;\n\n\t// Collect pre-base matras that need to move\n\tconst preBaseMatras: { index: number; info: GlyphInfo }[] = [];\n\n\tfor (let i = baseConsonant + 1; i < end; i++) {\n\t\tconst info = infos[i];\n\t\tif (!info) continue;\n\n\t\tconst cat = getIndicCategory(info.codepoint);\n\t\tif (cat === IndicCategory.M) {\n\t\t\tconst matraPos = getMatraPosition(info.codepoint);\n\t\t\tif (matraPos === MatraPosition.PreBase) {\n\t\t\t\tpreBaseMatras.push({ index: i, info });\n\t\t\t}\n\t\t}\n\t}\n\n\t// Move pre-base matras before the base (or before reph if present)\n\tif (preBaseMatras.length > 0) {\n\t\t// Sort by original index descending to process from right to left\n\t\tpreBaseMatras.sort((a, b) => b.index - a.index);\n\n\t\tfor (const { index, info } of preBaseMatras) {\n\t\t\t// Remove from current position\n\t\t\tinfos.splice(index, 1);\n\n\t\t\t// Insert before base (accounting for reph)\n\t\t\tconst insertPos = hasReph ? start + 2 : start;\n\t\t\tinfos.splice(insertPos, 0, info);\n\t\t}\n\t}\n\n\t// Handle reph movement (Ra + Halant at start moves to end of syllable)\n\t// Note: In many scripts, reph moves to after the matra\n\t// This is a simplified implementation - full implementation would check\n\t// script-specific rules\n\tif (hasReph && end > start + 2) {\n\t\t// Reph is at positions start and start+1 (Ra + Halant)\n\t\t// Move to end of syllable, before final consonant markers\n\t\tconst rephRa = infos[start];\n\t\tconst rephH = infos[start + 1];\n\n\t\tif (rephRa && rephH) {\n\t\t\t// Find insertion point: after matras, before syllable modifiers\n\t\t\tlet rephTarget = end - 1;\n\n\t\t\t// Adjust for any syllable modifiers at the end\n\t\t\twhile (rephTarget > baseConsonant) {\n\t\t\t\tconst targetInfo = infos[rephTarget];\n\t\t\t\tif (!targetInfo) break;\n\n\t\t\t\tconst cat = getIndicCategory(targetInfo.codepoint);\n\t\t\t\tif (cat === IndicCategory.SM || cat === IndicCategory.A) {\n\t\t\t\t\trephTarget--;\n\t\t\t\t} else {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Only move if target is different from current position\n\t\t\tif (rephTarget > start + 1) {\n\t\t\t\t// Remove Ra + Halant from start\n\t\t\t\tinfos.splice(start, 2);\n\n\t\t\t\t// Insert at new position (adjusted for removal)\n\t\t\t\tconst adjustedTarget = rephTarget - 2;\n\t\t\t\tinfos.splice(adjustedTarget + 1, 0, rephRa, rephH);\n\t\t\t}\n\t\t}\n\t}\n}\n",
94
- "import type { GlyphInfo } from \"../../types.ts\";\n\n/**\n * Khmer shaper\n * Handles Khmer script syllable structure and reordering\n */\n\n// Khmer Unicode range\nconst KHMER_START = 0x1780;\nconst KHMER_END = 0x17ff;\nconst KHMER_SYMBOLS_START = 0x19e0;\nconst KHMER_SYMBOLS_END = 0x19ff;\n\n/**\n * Khmer character categories\n */\nexport enum KhmerCategory {\n\tOther = 0,\n\tConsonant = 1,\n\tIndependentVowel = 2,\n\tDependentVowel = 3,\n\tCoeng = 4, // Subscript sign (្)\n\tRegister = 5, // Register shifters\n\tRobat = 6, // Consonant shifter (៌)\n\tSign = 7,\n\tAnusvara = 8, // Nikahit (ំ)\n\tVisarga = 9, // Reahmuk (ះ)\n}\n\n/**\n * Get Khmer character category\n */\nexport function getKhmerCategory(cp: number): KhmerCategory {\n\tif (cp < KHMER_START || cp > KHMER_END) return KhmerCategory.Other;\n\n\t// Consonants (ក-ស)\n\tif (cp >= 0x1780 && cp <= 0x17a2) return KhmerCategory.Consonant;\n\tif (cp === 0x17a3 || cp === 0x17a4) return KhmerCategory.IndependentVowel;\n\n\t// Independent vowels (ឣ-ឱ)\n\tif (cp >= 0x17a5 && cp <= 0x17b3) return KhmerCategory.IndependentVowel;\n\n\t// Dependent vowels (ា-ៅ)\n\tif (cp >= 0x17b6 && cp <= 0x17c5) return KhmerCategory.DependentVowel;\n\n\t// Signs\n\tif (cp === 0x17c6) return KhmerCategory.Anusvara; // Nikahit\n\tif (cp === 0x17c7) return KhmerCategory.Visarga; // Reahmuk\n\tif (cp === 0x17c8) return KhmerCategory.Sign; // Yuukaleapintu\n\n\t// Register shifters\n\tif (cp === 0x17c9 || cp === 0x17ca) return KhmerCategory.Register;\n\n\t// Coeng (subscript marker)\n\tif (cp === 0x17d2) return KhmerCategory.Coeng;\n\n\t// Robat\n\tif (cp === 0x17cc) return KhmerCategory.Robat;\n\n\t// Other signs\n\tif (cp >= 0x17cb && cp <= 0x17d1) return KhmerCategory.Sign;\n\tif (cp >= 0x17d3 && cp <= 0x17dd) return KhmerCategory.Sign;\n\n\treturn KhmerCategory.Other;\n}\n\n/**\n * Khmer feature masks\n */\nexport const KhmerFeatureMask = {\n\tpref: 0x0001, // Pre-base forms\n\tblwf: 0x0002, // Below-base forms\n\tabvf: 0x0004, // Above-base forms\n\tpstf: 0x0008, // Post-base forms\n\tcfar: 0x0010, // Conjunct form after Ra\n\tpres: 0x0020, // Pre-base substitutions\n\tabvs: 0x0040, // Above-base substitutions\n\tblws: 0x0080, // Below-base substitutions\n\tpsts: 0x0100, // Post-base substitutions\n\tclig: 0x0200, // Contextual ligatures\n} as const;\n\n/**\n * Check if codepoint is Khmer\n */\nexport function isKhmer(cp: number): boolean {\n\treturn (\n\t\t(cp >= KHMER_START && cp <= KHMER_END) ||\n\t\t(cp >= KHMER_SYMBOLS_START && cp <= KHMER_SYMBOLS_END)\n\t);\n}\n\n/**\n * Setup Khmer masks for feature application\n */\nexport function setupKhmerMasks(infos: GlyphInfo[]): void {\n\tlet i = 0;\n\n\twhile (i < infos.length) {\n\t\tconst info = infos[i];\n\t\tif (!info) {\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\t\tconst cat = getKhmerCategory(info.codepoint);\n\n\t\tif (cat === KhmerCategory.Other) {\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Find syllable extent\n\t\tconst _syllableStart = i;\n\t\tlet _base = -1;\n\n\t\t// Find base consonant\n\t\tif (cat === KhmerCategory.Consonant) {\n\t\t\t_base = i;\n\t\t}\n\n\t\t// Process syllable\n\t\tlet j = i + 1;\n\t\twhile (j < infos.length) {\n\t\t\tconst nextInfo = infos[j];\n\t\t\tif (!nextInfo) {\n\t\t\t\tj++;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst nextCat = getKhmerCategory(nextInfo.codepoint);\n\n\t\t\tif (nextCat === KhmerCategory.Other) break;\n\t\t\tif (nextCat === KhmerCategory.Consonant) {\n\t\t\t\t// Check if followed by coeng\n\t\t\t\tconst prevInfo = infos[j - 1];\n\t\t\t\tif (\n\t\t\t\t\tprevInfo &&\n\t\t\t\t\tgetKhmerCategory(prevInfo.codepoint) !== KhmerCategory.Coeng\n\t\t\t\t) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Coeng + consonant = subscript consonant\n\t\t\tif (nextCat === KhmerCategory.Coeng && j + 1 < infos.length) {\n\t\t\t\tconst afterCoeng = infos[j + 1];\n\t\t\t\tif (\n\t\t\t\t\tafterCoeng &&\n\t\t\t\t\tgetKhmerCategory(afterCoeng.codepoint) === KhmerCategory.Consonant\n\t\t\t\t) {\n\t\t\t\t\t// Mark for below-base forms\n\t\t\t\t\tnextInfo.mask |= KhmerFeatureMask.blwf;\n\t\t\t\t\tafterCoeng.mask |= KhmerFeatureMask.blwf;\n\t\t\t\t\tj += 2;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Dependent vowels\n\t\t\tif (nextCat === KhmerCategory.DependentVowel) {\n\t\t\t\t// Pre-base vowels: ◌េ ◌ែ ◌ៃ\n\t\t\t\tif (nextInfo.codepoint >= 0x17c1 && nextInfo.codepoint <= 0x17c3) {\n\t\t\t\t\tnextInfo.mask |= KhmerFeatureMask.pref;\n\t\t\t\t}\n\t\t\t\t// Above-base vowels\n\t\t\t\telse if (nextInfo.codepoint >= 0x17b7 && nextInfo.codepoint <= 0x17ba) {\n\t\t\t\t\tnextInfo.mask |= KhmerFeatureMask.abvf;\n\t\t\t\t}\n\t\t\t\t// Below-base vowels\n\t\t\t\telse if (\n\t\t\t\t\tnextInfo.codepoint === 0x17bb ||\n\t\t\t\t\tnextInfo.codepoint === 0x17bc ||\n\t\t\t\t\tnextInfo.codepoint === 0x17bd\n\t\t\t\t) {\n\t\t\t\t\tnextInfo.mask |= KhmerFeatureMask.blwf;\n\t\t\t\t}\n\t\t\t\t// Post-base vowels\n\t\t\t\telse {\n\t\t\t\t\tnextInfo.mask |= KhmerFeatureMask.pstf;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Register shifters (above)\n\t\t\tif (nextCat === KhmerCategory.Register) {\n\t\t\t\tnextInfo.mask |= KhmerFeatureMask.abvs;\n\t\t\t}\n\n\t\t\t// Robat (above)\n\t\t\tif (nextCat === KhmerCategory.Robat) {\n\t\t\t\tnextInfo.mask |= KhmerFeatureMask.abvs;\n\t\t\t}\n\n\t\t\tj++;\n\t\t}\n\n\t\ti = j;\n\t}\n}\n\n/**\n * Reorder Khmer pre-base vowels\n * Pre-base vowels (◌េ ◌ែ ◌ៃ) should visually appear before the base\n */\nexport function reorderKhmer(infos: GlyphInfo[]): void {\n\tlet i = 0;\n\n\twhile (i < infos.length) {\n\t\tconst info = infos[i];\n\t\tif (!info) {\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\t\tconst cat = getKhmerCategory(info.codepoint);\n\n\t\tif (cat !== KhmerCategory.Consonant) {\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Found base consonant, look for pre-base vowels after it\n\t\tconst base = i;\n\t\tlet j = i + 1;\n\n\t\t// Skip coeng sequences\n\t\twhile (j < infos.length) {\n\t\t\tconst jInfo = infos[j];\n\t\t\tif (!jInfo) break;\n\t\t\tconst jCat = getKhmerCategory(jInfo.codepoint);\n\t\t\tif (jCat === KhmerCategory.Coeng && j + 1 < infos.length) {\n\t\t\t\tj += 2; // Skip coeng + consonant\n\t\t\t} else {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t// Check for pre-base vowel\n\t\tif (j < infos.length) {\n\t\t\tconst jInfo = infos[j];\n\t\t\tif (jInfo) {\n\t\t\t\tconst cp = jInfo.codepoint;\n\t\t\t\tif (cp >= 0x17c1 && cp <= 0x17c3) {\n\t\t\t\t\t// Move pre-base vowel before base\n\t\t\t\t\tconst vowel = jInfo;\n\t\t\t\t\tfor (let k = j; k > base; k--) {\n\t\t\t\t\t\tconst prevInfo = infos[k - 1];\n\t\t\t\t\t\tif (prevInfo) {\n\t\t\t\t\t\t\tinfos[k] = prevInfo;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tinfos[base] = vowel;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\ti = j + 1;\n\t}\n}\n",
95
- "import type { GlyphInfo } from \"../../types.ts\";\n\n/**\n * Myanmar shaper\n * Handles Myanmar script syllable structure and reordering\n */\n\n// Myanmar Unicode ranges\nconst MYANMAR_START = 0x1000;\nconst MYANMAR_END = 0x109f;\nconst MYANMAR_EXT_A_START = 0xaa60;\nconst MYANMAR_EXT_A_END = 0xaa7f;\nconst MYANMAR_EXT_B_START = 0xa9e0;\nconst MYANMAR_EXT_B_END = 0xa9ff;\n\n/**\n * Myanmar character categories\n */\nexport enum MyanmarCategory {\n\tOther = 0,\n\tConsonant = 1,\n\tIndependentVowel = 2,\n\tDependentVowel = 3,\n\tMedial = 4,\n\tAsat = 5, // Killer (္)\n\tAnusvara = 6, // Dot below\n\tVisarga = 7, // Visarga\n\tSign = 8,\n\tNumber = 9,\n\tPlaceholder = 10, // Placeholder for visible virama\n}\n\n/**\n * Get Myanmar character category\n */\nexport function getMyanmarCategory(cp: number): MyanmarCategory {\n\t// Main Myanmar block\n\tif (cp >= MYANMAR_START && cp <= MYANMAR_END) {\n\t\t// Consonants (က-အ)\n\t\tif (cp >= 0x1000 && cp <= 0x1021) return MyanmarCategory.Consonant;\n\t\tif (cp >= 0x1023 && cp <= 0x1027) return MyanmarCategory.IndependentVowel;\n\t\tif (cp >= 0x1029 && cp <= 0x102a) return MyanmarCategory.IndependentVowel;\n\n\t\t// Dependent vowels\n\t\tif (cp >= 0x102b && cp <= 0x1035) return MyanmarCategory.DependentVowel;\n\n\t\t// Anusvara\n\t\tif (cp === 0x1036) return MyanmarCategory.Anusvara;\n\n\t\t// Dot below (asat indicator)\n\t\tif (cp === 0x1037) return MyanmarCategory.Sign;\n\n\t\t// Visarga\n\t\tif (cp === 0x1038) return MyanmarCategory.Visarga;\n\n\t\t// Asat (killer/virama)\n\t\tif (cp === 0x1039) return MyanmarCategory.Asat;\n\t\tif (cp === 0x103a) return MyanmarCategory.Asat;\n\n\t\t// Medials (ျ ြ ွ ှ)\n\t\tif (cp >= 0x103b && cp <= 0x103e) return MyanmarCategory.Medial;\n\n\t\t// More consonants (ဿ, etc.)\n\t\tif (cp >= 0x103f && cp <= 0x1049) {\n\t\t\tif (cp === 0x103f) return MyanmarCategory.Consonant;\n\t\t\treturn MyanmarCategory.Number;\n\t\t}\n\n\t\t// Signs and digits\n\t\tif (cp >= 0x104a && cp <= 0x104f) return MyanmarCategory.Sign;\n\t\tif (cp >= 0x1050 && cp <= 0x1059) return MyanmarCategory.Consonant;\n\n\t\t// Extended consonants\n\t\tif (cp >= 0x105a && cp <= 0x105d) return MyanmarCategory.Consonant;\n\t\tif (cp >= 0x1060 && cp <= 0x1061) return MyanmarCategory.Consonant;\n\t\tif (cp >= 0x1062 && cp <= 0x1064) return MyanmarCategory.DependentVowel;\n\t\tif (cp >= 0x1065 && cp <= 0x1066) return MyanmarCategory.Consonant;\n\t\tif (cp >= 0x1067 && cp <= 0x106d) return MyanmarCategory.DependentVowel;\n\t\tif (cp >= 0x106e && cp <= 0x1070) return MyanmarCategory.Consonant;\n\t\tif (cp >= 0x1071 && cp <= 0x1074) return MyanmarCategory.DependentVowel;\n\t\tif (cp >= 0x1075 && cp <= 0x1081) return MyanmarCategory.Consonant;\n\t\tif (cp >= 0x1082 && cp <= 0x1082) return MyanmarCategory.Medial;\n\t\tif (cp >= 0x1083 && cp <= 0x108c) return MyanmarCategory.DependentVowel;\n\t\tif (cp === 0x108d) return MyanmarCategory.Sign;\n\t\tif (cp === 0x108e) return MyanmarCategory.Consonant;\n\t\tif (cp === 0x108f) return MyanmarCategory.Sign;\n\t\tif (cp >= 0x1090 && cp <= 0x1099) return MyanmarCategory.Number;\n\t}\n\n\t// Myanmar Extended-A\n\tif (cp >= MYANMAR_EXT_A_START && cp <= MYANMAR_EXT_A_END) {\n\t\tif (cp >= 0xaa60 && cp <= 0xaa76) return MyanmarCategory.Consonant;\n\t\tif (cp >= 0xaa77 && cp <= 0xaa79) return MyanmarCategory.Sign;\n\t\tif (cp === 0xaa7a) return MyanmarCategory.Consonant;\n\t\tif (cp === 0xaa7b) return MyanmarCategory.Sign;\n\t\tif (cp === 0xaa7c) return MyanmarCategory.Sign;\n\t\tif (cp === 0xaa7d) return MyanmarCategory.Sign;\n\t\tif (cp >= 0xaa7e && cp <= 0xaa7f) return MyanmarCategory.Consonant;\n\t}\n\n\t// Myanmar Extended-B\n\tif (cp >= MYANMAR_EXT_B_START && cp <= MYANMAR_EXT_B_END) {\n\t\tif (cp >= 0xa9e0 && cp <= 0xa9e4) return MyanmarCategory.Consonant;\n\t\tif (cp === 0xa9e5) return MyanmarCategory.DependentVowel;\n\t\tif (cp >= 0xa9e6 && cp <= 0xa9ef) return MyanmarCategory.Consonant;\n\t\tif (cp >= 0xa9f0 && cp <= 0xa9f9) return MyanmarCategory.Number;\n\t\tif (cp >= 0xa9fa && cp <= 0xa9fe) return MyanmarCategory.Consonant;\n\t}\n\n\treturn MyanmarCategory.Other;\n}\n\n/**\n * Myanmar feature masks\n */\nexport const MyanmarFeatureMask = {\n\trphf: 0x0001, // Reph forms\n\tpref: 0x0002, // Pre-base forms\n\tblwf: 0x0004, // Below-base forms\n\tpstf: 0x0008, // Post-base forms\n\tpres: 0x0010, // Pre-base substitutions\n\tabvs: 0x0020, // Above-base substitutions\n\tblws: 0x0040, // Below-base substitutions\n\tpsts: 0x0080, // Post-base substitutions\n} as const;\n\n/**\n * Check if codepoint is Myanmar\n */\nexport function isMyanmar(cp: number): boolean {\n\treturn (\n\t\t(cp >= MYANMAR_START && cp <= MYANMAR_END) ||\n\t\t(cp >= MYANMAR_EXT_A_START && cp <= MYANMAR_EXT_A_END) ||\n\t\t(cp >= MYANMAR_EXT_B_START && cp <= MYANMAR_EXT_B_END)\n\t);\n}\n\n/**\n * Setup Myanmar masks for feature application\n */\nexport function setupMyanmarMasks(infos: GlyphInfo[]): void {\n\tlet i = 0;\n\n\twhile (i < infos.length) {\n\t\tconst info = infos[i];\n\t\tif (!info) {\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\t\tconst cat = getMyanmarCategory(info.codepoint);\n\n\t\tif (cat === MyanmarCategory.Other) {\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Find syllable extent\n\t\tlet _base = -1;\n\t\tlet hasAsat = false;\n\n\t\tif (cat === MyanmarCategory.Consonant) {\n\t\t\t_base = i;\n\t\t}\n\n\t\tlet j = i + 1;\n\t\twhile (j < infos.length) {\n\t\t\tconst nextInfo = infos[j];\n\t\t\tif (!nextInfo) {\n\t\t\t\tj++;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst nextCat = getMyanmarCategory(nextInfo.codepoint);\n\n\t\t\tif (nextCat === MyanmarCategory.Other) break;\n\n\t\t\t// Asat (killer) marks a stacked consonant\n\t\t\tif (nextCat === MyanmarCategory.Asat) {\n\t\t\t\thasAsat = true;\n\t\t\t\tnextInfo.mask |= MyanmarFeatureMask.blwf;\n\n\t\t\t\t// Check for following consonant (stacking)\n\t\t\t\tif (j + 1 < infos.length) {\n\t\t\t\t\tconst afterAsat = infos[j + 1];\n\t\t\t\t\tif (\n\t\t\t\t\t\tafterAsat &&\n\t\t\t\t\t\tgetMyanmarCategory(afterAsat.codepoint) ===\n\t\t\t\t\t\t\tMyanmarCategory.Consonant\n\t\t\t\t\t) {\n\t\t\t\t\t\tafterAsat.mask |= MyanmarFeatureMask.blwf;\n\t\t\t\t\t\tj += 2;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Medials\n\t\t\tif (nextCat === MyanmarCategory.Medial) {\n\t\t\t\tconst cp = nextInfo.codepoint;\n\t\t\t\t// ျ (ya) - pre-base\n\t\t\t\tif (cp === 0x103b) {\n\t\t\t\t\tnextInfo.mask |= MyanmarFeatureMask.pref;\n\t\t\t\t}\n\t\t\t\t// ြ (ra) - pre-base\n\t\t\t\telse if (cp === 0x103c) {\n\t\t\t\t\tnextInfo.mask |= MyanmarFeatureMask.pref;\n\t\t\t\t}\n\t\t\t\t// ွ (wa) - below-base\n\t\t\t\telse if (cp === 0x103d) {\n\t\t\t\t\tnextInfo.mask |= MyanmarFeatureMask.blwf;\n\t\t\t\t}\n\t\t\t\t// ှ (ha) - below-base\n\t\t\t\telse if (cp === 0x103e) {\n\t\t\t\t\tnextInfo.mask |= MyanmarFeatureMask.blwf;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Dependent vowels\n\t\t\tif (nextCat === MyanmarCategory.DependentVowel) {\n\t\t\t\tconst cp = nextInfo.codepoint;\n\t\t\t\t// Pre-base vowels: ေ\n\t\t\t\tif (cp === 0x1031) {\n\t\t\t\t\tnextInfo.mask |= MyanmarFeatureMask.pref;\n\t\t\t\t}\n\t\t\t\t// Above-base vowels\n\t\t\t\telse if (cp === 0x102d || cp === 0x102e || cp === 0x1032) {\n\t\t\t\t\tnextInfo.mask |= MyanmarFeatureMask.abvs;\n\t\t\t\t}\n\t\t\t\t// Below-base vowels\n\t\t\t\telse if (cp === 0x102f || cp === 0x1030) {\n\t\t\t\t\tnextInfo.mask |= MyanmarFeatureMask.blws;\n\t\t\t\t}\n\t\t\t\t// Post-base vowels\n\t\t\t\telse {\n\t\t\t\t\tnextInfo.mask |= MyanmarFeatureMask.psts;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Signs above\n\t\t\tif (\n\t\t\t\tnextCat === MyanmarCategory.Anusvara ||\n\t\t\t\tnextCat === MyanmarCategory.Sign\n\t\t\t) {\n\t\t\t\tnextInfo.mask |= MyanmarFeatureMask.abvs;\n\t\t\t}\n\n\t\t\t// New syllable on consonant without asat\n\t\t\tif (nextCat === MyanmarCategory.Consonant && !hasAsat) {\n\t\t\t\t// Check if previous was asat\n\t\t\t\tif (j > 0) {\n\t\t\t\t\tconst prevInfo = infos[j - 1];\n\t\t\t\t\tif (prevInfo) {\n\t\t\t\t\t\tconst prevCat = getMyanmarCategory(prevInfo.codepoint);\n\t\t\t\t\t\tif (prevCat !== MyanmarCategory.Asat) {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\thasAsat = false;\n\t\t\tj++;\n\t\t}\n\n\t\ti = j;\n\t}\n}\n\n/**\n * Reorder Myanmar pre-base vowels and medials\n * ေ and ြ should visually appear before the base consonant\n */\nexport function reorderMyanmar(infos: GlyphInfo[]): void {\n\tlet i = 0;\n\n\twhile (i < infos.length) {\n\t\tconst info = infos[i];\n\t\tif (!info) {\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\t\tconst cat = getMyanmarCategory(info.codepoint);\n\n\t\tif (cat !== MyanmarCategory.Consonant) {\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Found base consonant\n\t\tconst base = i;\n\t\tconst preBase: GlyphInfo[] = [];\n\n\t\t// Collect pre-base elements that follow base\n\t\tlet j = i + 1;\n\t\twhile (j < infos.length) {\n\t\t\tconst jInfo = infos[j];\n\t\t\tif (!jInfo) {\n\t\t\t\tj++;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst jCat = getMyanmarCategory(jInfo.codepoint);\n\n\t\t\t// Pre-base vowel (ေ)\n\t\t\tif (jInfo.codepoint === 0x1031) {\n\t\t\t\tpreBase.push(jInfo);\n\t\t\t\tinfos.splice(j, 1);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Pre-base medial (ြ ra)\n\t\t\tif (jInfo.codepoint === 0x103c) {\n\t\t\t\tpreBase.push(jInfo);\n\t\t\t\tinfos.splice(j, 1);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Stop at next syllable\n\t\t\tif (\n\t\t\t\tjCat === MyanmarCategory.Consonant ||\n\t\t\t\tjCat === MyanmarCategory.Other\n\t\t\t) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tj++;\n\t\t}\n\n\t\t// Insert pre-base elements before base\n\t\tif (preBase.length > 0) {\n\t\t\tinfos.splice(base, 0, ...preBase);\n\t\t\ti += preBase.length;\n\t\t}\n\n\t\ti++;\n\t}\n}\n",
96
- "import type { GlyphInfo } from \"../../types.ts\";\n\n/**\n * Thai/Lao character categories\n */\nexport enum ThaiLaoCategory {\n\tOther = 0,\n\tConsonant = 1,\n\tLeadingVowel = 2, // Vowels that appear before consonant\n\tAboveVowel = 3, // Vowels above consonant\n\tBelowVowel = 4, // Vowels below consonant\n\tFollowingVowel = 5, // Vowels after consonant\n\tTone = 6, // Tone marks\n\tNikhahitMaiEk = 7, // Special combining marks\n\tSaraAm = 8, // Thai Sara Am (combines anusvara + aa)\n\tSymbol = 9,\n}\n\n/**\n * Check if codepoint is Thai\n */\nexport function isThai(cp: number): boolean {\n\treturn cp >= 0x0e00 && cp <= 0x0e7f;\n}\n\n/**\n * Check if codepoint is Lao\n */\nexport function isLao(cp: number): boolean {\n\treturn cp >= 0x0e80 && cp <= 0x0eff;\n}\n\n/**\n * Get Thai/Lao category for a codepoint\n */\nexport function getThaiLaoCategory(cp: number): ThaiLaoCategory {\n\t// Thai (0E00-0E7F)\n\tif (isThai(cp)) {\n\t\t// Consonants\n\t\tif (cp >= 0x0e01 && cp <= 0x0e2e) return ThaiLaoCategory.Consonant;\n\t\t// Additional consonants\n\t\tif (cp === 0x0e2f) return ThaiLaoCategory.Consonant; // Paiyannoi\n\n\t\t// Leading vowels (displayed before consonant)\n\t\tif (cp >= 0x0e40 && cp <= 0x0e44) return ThaiLaoCategory.LeadingVowel;\n\n\t\t// Above vowels\n\t\tif (cp === 0x0e31) return ThaiLaoCategory.AboveVowel; // Mai Han-Akat\n\t\tif (cp >= 0x0e34 && cp <= 0x0e37) return ThaiLaoCategory.AboveVowel;\n\t\tif (cp === 0x0e47) return ThaiLaoCategory.AboveVowel; // Maitaikhu\n\n\t\t// Below vowels\n\t\tif (cp >= 0x0e38 && cp <= 0x0e3a) return ThaiLaoCategory.BelowVowel;\n\n\t\t// Following vowels\n\t\tif (cp === 0x0e30) return ThaiLaoCategory.FollowingVowel; // Sara A\n\t\tif (cp === 0x0e32 || cp === 0x0e33) return ThaiLaoCategory.FollowingVowel; // Sara Aa, Sara Am\n\t\tif (cp === 0x0e45) return ThaiLaoCategory.FollowingVowel; // Lakkhangyao\n\n\t\t// Sara Am (special - decomposes to nikhahit + sara aa)\n\t\tif (cp === 0x0e33) return ThaiLaoCategory.SaraAm;\n\n\t\t// Tone marks\n\t\tif (cp >= 0x0e48 && cp <= 0x0e4b) return ThaiLaoCategory.Tone;\n\n\t\t// Thanthakhat (cancellation mark)\n\t\tif (cp === 0x0e4c) return ThaiLaoCategory.Tone;\n\n\t\t// Nikhahit (anusvara)\n\t\tif (cp === 0x0e4d) return ThaiLaoCategory.NikhahitMaiEk;\n\n\t\t// Yamakkan\n\t\tif (cp === 0x0e4e) return ThaiLaoCategory.NikhahitMaiEk;\n\n\t\t// Digits and symbols\n\t\tif (cp >= 0x0e50 && cp <= 0x0e5b) return ThaiLaoCategory.Symbol;\n\n\t\treturn ThaiLaoCategory.Other;\n\t}\n\n\t// Lao (0E80-0EFF)\n\tif (isLao(cp)) {\n\t\t// Consonants\n\t\tif (cp >= 0x0e81 && cp <= 0x0eae) return ThaiLaoCategory.Consonant;\n\n\t\t// Leading vowels\n\t\tif (cp >= 0x0ec0 && cp <= 0x0ec4) return ThaiLaoCategory.LeadingVowel;\n\n\t\t// Above vowels\n\t\tif (cp === 0x0eb1) return ThaiLaoCategory.AboveVowel;\n\t\tif (cp >= 0x0eb4 && cp <= 0x0eb7) return ThaiLaoCategory.AboveVowel;\n\t\tif (cp === 0x0ebb) return ThaiLaoCategory.AboveVowel;\n\n\t\t// Below vowels\n\t\tif (cp >= 0x0eb8 && cp <= 0x0eb9) return ThaiLaoCategory.BelowVowel;\n\t\tif (cp === 0x0ebc) return ThaiLaoCategory.BelowVowel;\n\n\t\t// Following vowels\n\t\tif (cp === 0x0eb0) return ThaiLaoCategory.FollowingVowel;\n\t\tif (cp === 0x0eb2 || cp === 0x0eb3) return ThaiLaoCategory.FollowingVowel;\n\n\t\t// Tone marks\n\t\tif (cp >= 0x0ec8 && cp <= 0x0ecd) return ThaiLaoCategory.Tone;\n\n\t\t// Digits\n\t\tif (cp >= 0x0ed0 && cp <= 0x0ed9) return ThaiLaoCategory.Symbol;\n\n\t\treturn ThaiLaoCategory.Other;\n\t}\n\n\treturn ThaiLaoCategory.Other;\n}\n\n/**\n * Set up masks for Thai/Lao shaping\n *\n * Thai/Lao require:\n * 1. Reordering of pre-base vowels (they appear before consonant visually but after in Unicode)\n * 2. Proper stacking of above/below vowels and tone marks\n */\nexport function setupThaiLaoMasks(infos: GlyphInfo[]): void {\n\t// Group characters into syllable-like clusters\n\t// Each cluster starts with a consonant\n\n\tlet clusterIndex = 0;\n\tlet _consonantIndex = -1;\n\n\tfor (let i = 0; i < infos.length; i++) {\n\t\tconst info = infos[i];\n\t\tif (!info) continue;\n\n\t\tconst cat = getThaiLaoCategory(info.codepoint);\n\n\t\t// Consonants start new clusters\n\t\tif (cat === ThaiLaoCategory.Consonant) {\n\t\t\tclusterIndex++;\n\t\t\t_consonantIndex = i;\n\t\t}\n\n\t\t// Store cluster info in mask\n\t\t// Upper bits: cluster index\n\t\t// Lower bits: category for reordering\n\t\tinfo.mask = (info.mask & 0xffffff00) | (cat & 0xff);\n\t\tinfo.mask = (info.mask & 0x0000ffff) | ((clusterIndex & 0xffff) << 16);\n\n\t\t// Mark leading vowels for reordering\n\t\tif (cat === ThaiLaoCategory.LeadingVowel) {\n\t\t\t// These need to be moved before the consonant during shaping\n\t\t\t// The GSUB pref feature handles this\n\t\t\tinfo.mask |= 0x100; // Mark for pre-base processing\n\t\t}\n\t}\n}\n\n/**\n * Reorder Thai/Lao clusters\n * Leading vowels (Sara E, Sara Ae, Sara O, Sara Ai Mai Muan, Sara Ai Mai Malai)\n * are stored after consonant in Unicode but displayed before\n */\nexport function reorderThaiLao(infos: GlyphInfo[]): void {\n\tlet i = 0;\n\twhile (i < infos.length) {\n\t\tconst info = infos[i];\n\t\tif (!info) {\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst cat = getThaiLaoCategory(info.codepoint);\n\n\t\t// If we find a leading vowel, move it before its consonant\n\t\tif (cat === ThaiLaoCategory.LeadingVowel) {\n\t\t\t// Find the following consonant\n\t\t\tlet j = i + 1;\n\t\t\twhile (j < infos.length) {\n\t\t\t\tconst nextInfo = infos[j];\n\t\t\t\tif (!nextInfo) {\n\t\t\t\t\tj++;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst nextCat = getThaiLaoCategory(nextInfo.codepoint ?? 0);\n\t\t\t\tif (nextCat === ThaiLaoCategory.Consonant) {\n\t\t\t\t\t// Swap vowel and consonant\n\t\t\t\t\tconst temp = info;\n\t\t\t\t\tinfos[i] = nextInfo;\n\t\t\t\t\tinfos[j] = temp;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif (nextCat !== ThaiLaoCategory.LeadingVowel) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tj++;\n\t\t\t}\n\t\t}\n\t\ti++;\n\t}\n}\n",
97
- "import type { GlyphInfo } from \"../../types.ts\";\n\n/**\n * Universal Shaping Engine (USE) categories\n * Based on Unicode USE specification\n */\nexport enum UseCategory {\n\tO = 0, // Other\n\tB = 1, // Base\n\tCGJ = 2, // Combining Grapheme Joiner\n\tCM = 3, // Consonant modifier\n\tCS = 4, // Consonant with stacker\n\tF = 5, // Final\n\tFM = 6, // Final modifier\n\tGB = 7, // Generic base\n\tH = 8, // Halant/Virama\n\tHN = 9, // Halant or Nukta\n\tIND = 10, // Independent\n\tJ = 11, // Joiner\n\tN = 12, // Nukta\n\tR = 13, // Repha\n\tS = 14, // Symbol\n\tSB = 15, // Symbol modifier\n\tSE = 16, // Syllable ending\n\tSUB = 17, // Subjoined\n\tVS = 18, // Variation selector\n\tWJ = 19, // Word joiner\n\tZWJ = 20, // Zero Width Joiner\n\tZWNJ = 21, // Zero Width Non-Joiner\n\tV = 22, // Vowel (independent)\n\tVD = 23, // Vowel dependent\n\tVMAbv = 24, // Vowel modifier above\n\tVMBlw = 25, // Vowel modifier below\n\tVMPre = 26, // Vowel modifier pre\n\tVMPst = 27, // Vowel modifier post\n\tVAbv = 28, // Vowel above\n\tVBlw = 29, // Vowel below\n\tVPre = 30, // Vowel pre\n\tVPst = 31, // Vowel post\n\tSMAbv = 32, // Syllable modifier above\n\tSMBlw = 33, // Syllable modifier below\n\tFAbv = 34, // Final above\n\tFBlw = 35, // Final below\n\tFPst = 36, // Final post\n\tMAbv = 37, // Medial above\n\tMBlw = 38, // Medial below\n\tMPre = 39, // Medial pre\n\tMPst = 40, // Medial post\n}\n\n/**\n * Check if a script uses USE\n */\nexport function usesUSE(script: string): boolean {\n\t// Scripts that use Universal Shaping Engine\n\tconst useScripts = [\n\t\t\"bali\", // Balinese\n\t\t\"batk\", // Batak\n\t\t\"brah\", // Brahmi\n\t\t\"bugi\", // Buginese\n\t\t\"buhd\", // Buhid\n\t\t\"cakm\", // Chakma\n\t\t\"cham\", // Cham\n\t\t\"dupl\", // Duployan\n\t\t\"egyp\", // Egyptian Hieroglyphs\n\t\t\"gran\", // Grantha\n\t\t\"hano\", // Hanunoo\n\t\t\"java\", // Javanese\n\t\t\"kthi\", // Kaithi\n\t\t\"khar\", // Kharoshthi\n\t\t\"khmr\", // Khmer\n\t\t\"khoj\", // Khojki\n\t\t\"lana\", // Tai Tham\n\t\t\"lepc\", // Lepcha\n\t\t\"limb\", // Limbu\n\t\t\"mahj\", // Mahajani\n\t\t\"modi\", // Modi\n\t\t\"mtei\", // Meetei Mayek\n\t\t\"mymr\", // Myanmar\n\t\t\"newa\", // Newa\n\t\t\"phlp\", // Psalter Pahlavi\n\t\t\"rjng\", // Rejang\n\t\t\"saur\", // Saurashtra\n\t\t\"shrd\", // Sharada\n\t\t\"sidd\", // Siddham\n\t\t\"sind\", // Sindhi (Khudawadi)\n\t\t\"sinh\", // Sinhala\n\t\t\"sund\", // Sundanese\n\t\t\"sylo\", // Syloti Nagri\n\t\t\"tagb\", // Tagbanwa\n\t\t\"takr\", // Takri\n\t\t\"tale\", // Tai Le\n\t\t\"talu\", // New Tai Lue\n\t\t\"tavt\", // Tai Viet\n\t\t\"tibt\", // Tibetan\n\t\t\"tirh\", // Tirhuta\n\t];\n\treturn useScripts.includes(script);\n}\n\n/**\n * Get USE category for a codepoint\n */\nexport function getUseCategory(cp: number): UseCategory {\n\t// Zero-width characters\n\tif (cp === 0x200c) return UseCategory.ZWNJ;\n\tif (cp === 0x200d) return UseCategory.ZWJ;\n\tif (cp === 0x034f) return UseCategory.CGJ; // Combining Grapheme Joiner\n\tif (cp === 0x2060) return UseCategory.WJ; // Word Joiner\n\tif (cp >= 0xfe00 && cp <= 0xfe0f) return UseCategory.VS; // Variation Selectors\n\tif (cp >= 0xe0100 && cp <= 0xe01ef) return UseCategory.VS; // VS 17-256\n\n\t// Myanmar (1000-109F)\n\tif (cp >= 0x1000 && cp <= 0x109f) {\n\t\t// Consonants\n\t\tif (cp >= 0x1000 && cp <= 0x1020) return UseCategory.B;\n\t\t// Independent vowels\n\t\tif (cp >= 0x1021 && cp <= 0x102a) return UseCategory.IND;\n\t\t// Dependent vowels\n\t\tif (cp >= 0x102b && cp <= 0x1032) return UseCategory.VPst;\n\t\t// Anusvara etc\n\t\tif (cp >= 0x1036 && cp <= 0x1037) return UseCategory.SMAbv;\n\t\t// Virama\n\t\tif (cp === 0x1039) return UseCategory.H;\n\t\t// Asat (visible virama)\n\t\tif (cp === 0x103a) return UseCategory.H;\n\t\t// Medial consonants\n\t\tif (cp >= 0x103b && cp <= 0x103e) return UseCategory.MBlw;\n\t\t// Digits\n\t\tif (cp >= 0x1040 && cp <= 0x1049) return UseCategory.GB;\n\t\treturn UseCategory.O;\n\t}\n\n\t// Khmer (1780-17FF)\n\tif (cp >= 0x1780 && cp <= 0x17ff) {\n\t\t// Consonants\n\t\tif (cp >= 0x1780 && cp <= 0x17a2) return UseCategory.B;\n\t\t// Independent vowels\n\t\tif (cp >= 0x17a3 && cp <= 0x17b3) return UseCategory.IND;\n\t\t// Dependent vowels\n\t\tif (cp >= 0x17b6 && cp <= 0x17c5) return UseCategory.VPst;\n\t\t// Coeng (stacking virama)\n\t\tif (cp === 0x17d2) return UseCategory.H;\n\t\t// Anusvara, Visarga\n\t\tif (cp >= 0x17c6 && cp <= 0x17c8) return UseCategory.SMAbv;\n\t\treturn UseCategory.O;\n\t}\n\n\t// Tibetan (0F00-0FFF)\n\tif (cp >= 0x0f00 && cp <= 0x0fff) {\n\t\t// Syllable markers\n\t\tif (cp >= 0x0f00 && cp <= 0x0f17) return UseCategory.S;\n\t\t// Vowel signs\n\t\tif (cp >= 0x0f71 && cp <= 0x0f7d) return UseCategory.VAbv;\n\t\t// Subjoined consonants\n\t\tif (cp >= 0x0f90 && cp <= 0x0fbc) return UseCategory.SUB;\n\t\t// Base consonants\n\t\tif (cp >= 0x0f40 && cp <= 0x0f6c) return UseCategory.B;\n\t\treturn UseCategory.O;\n\t}\n\n\t// Thai (0E00-0E7F)\n\tif (cp >= 0x0e00 && cp <= 0x0e7f) {\n\t\t// Consonants\n\t\tif (cp >= 0x0e01 && cp <= 0x0e2e) return UseCategory.B;\n\t\t// Vowels\n\t\tif (cp >= 0x0e30 && cp <= 0x0e3a) return UseCategory.VPst;\n\t\tif (cp >= 0x0e40 && cp <= 0x0e44) return UseCategory.VPre;\n\t\t// Tone marks\n\t\tif (cp >= 0x0e48 && cp <= 0x0e4b) return UseCategory.SMAbv;\n\t\treturn UseCategory.O;\n\t}\n\n\t// Lao (0E80-0EFF)\n\tif (cp >= 0x0e80 && cp <= 0x0eff) {\n\t\t// Consonants\n\t\tif (cp >= 0x0e81 && cp <= 0x0ea3) return UseCategory.B;\n\t\t// Vowels\n\t\tif (cp >= 0x0eb0 && cp <= 0x0ebc) return UseCategory.VPst;\n\t\tif (cp >= 0x0ec0 && cp <= 0x0ec4) return UseCategory.VPre;\n\t\t// Tone marks\n\t\tif (cp >= 0x0ec8 && cp <= 0x0ecd) return UseCategory.SMAbv;\n\t\treturn UseCategory.O;\n\t}\n\n\t// Test mappings for categories not yet in real scripts\n\t// Using private use area for testing\n\tif (cp >= 0xe000 && cp <= 0xe0ff) {\n\t\tif (cp === 0xe000) return UseCategory.R; // Repha test\n\t\tif (cp === 0xe001) return UseCategory.VMAbv;\n\t\tif (cp === 0xe002) return UseCategory.VMBlw;\n\t\tif (cp === 0xe003) return UseCategory.VMPre;\n\t\tif (cp === 0xe004) return UseCategory.VMPst;\n\t\tif (cp === 0xe005) return UseCategory.CS;\n\t\tif (cp === 0xe006) return UseCategory.N;\n\t\tif (cp === 0xe007) return UseCategory.HN;\n\t\tif (cp === 0xe008) return UseCategory.VD;\n\t\tif (cp === 0xe009) return UseCategory.VBlw;\n\t\tif (cp === 0xe00a) return UseCategory.MAbv;\n\t\tif (cp === 0xe00b) return UseCategory.MPre;\n\t\tif (cp === 0xe00c) return UseCategory.MPst;\n\t\tif (cp === 0xe00d) return UseCategory.SMBlw;\n\t\tif (cp === 0xe00e) return UseCategory.FAbv;\n\t\tif (cp === 0xe00f) return UseCategory.FBlw;\n\t\tif (cp === 0xe010) return UseCategory.FPst;\n\t\tif (cp === 0xe011) return UseCategory.F;\n\t\tif (cp === 0xe012) return UseCategory.FM;\n\t}\n\n\treturn UseCategory.O;\n}\n\n/** USE feature masks */\nexport const UseFeatureMask = {\n\trphf: 0x0001, // Reph forms\n\tpref: 0x0002, // Pre-base forms\n\tblwf: 0x0004, // Below-base forms\n\tabvf: 0x0008, // Above-base forms\n\tpstf: 0x0010, // Post-base forms\n\thalf: 0x0020, // Half forms\n\tcjct: 0x0040, // Conjunct forms\n\tvatu: 0x0080, // Vattu variants\n\tpres: 0x0100, // Pre-base substitutions\n\tabvs: 0x0200, // Above-base substitutions\n\tblws: 0x0400, // Below-base substitutions\n\tpsts: 0x0800, // Post-base substitutions\n\thaln: 0x1000, // Halant forms\n} as const;\n\n/**\n * USE syllable structure\n */\ninterface UseSyllable {\n\tstart: number;\n\tend: number;\n\tbase: number;\n\thasReph: boolean;\n}\n\n/**\n * Find syllable boundaries in USE text\n */\nfunction findUseSyllables(infos: GlyphInfo[]): UseSyllable[] {\n\tconst syllables: UseSyllable[] = [];\n\tconst n = infos.length;\n\tif (n === 0) return syllables;\n\n\tlet start = 0;\n\n\twhile (start < n) {\n\t\tconst syllable = parseUseSyllable(infos, start);\n\t\tsyllables.push(syllable);\n\t\tstart = syllable.end;\n\t}\n\n\treturn syllables;\n}\n\n/**\n * Parse a single USE syllable\n */\nfunction parseUseSyllable(infos: GlyphInfo[], start: number): UseSyllable {\n\tconst n = infos.length;\n\tlet pos = start;\n\tlet base = -1;\n\tlet hasReph = false;\n\n\t// Check for Repha (R + H at start)\n\tif (pos + 1 < n) {\n\t\tconst info1 = infos[pos];\n\t\tconst info2 = infos[pos + 1];\n\t\tif (info1 && info2) {\n\t\t\tconst cat1 = getUseCategory(info1.codepoint ?? 0);\n\t\t\tconst cat2 = getUseCategory(info2.codepoint ?? 0);\n\t\t\tif (cat1 === UseCategory.R && cat2 === UseCategory.H) {\n\t\t\t\thasReph = true;\n\t\t\t\tpos += 2;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Find base character\n\twhile (pos < n) {\n\t\tconst info = infos[pos];\n\t\tif (!info) {\n\t\t\tpos++;\n\t\t\tcontinue;\n\t\t}\n\t\tconst cat = getUseCategory(info.codepoint ?? 0);\n\n\t\t// Base characters\n\t\tif (\n\t\t\tcat === UseCategory.B ||\n\t\t\tcat === UseCategory.IND ||\n\t\t\tcat === UseCategory.GB ||\n\t\t\tcat === UseCategory.V\n\t\t) {\n\t\t\tbase = pos;\n\t\t\tpos++;\n\t\t\tbreak;\n\t\t}\n\n\t\t// Non-base starters - continue looking\n\t\tif (\n\t\t\tcat === UseCategory.VMPre ||\n\t\t\tcat === UseCategory.VPre ||\n\t\t\tcat === UseCategory.MPre\n\t\t) {\n\t\t\tpos++;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// End of valid cluster start\n\t\tif (base === -1) {\n\t\t\tpos++;\n\t\t}\n\t\tbreak;\n\t}\n\n\tif (base === -1) base = start;\n\n\t// Consume consonant cluster\n\twhile (pos < n) {\n\t\tconst posInfo = infos[pos];\n\t\tif (!posInfo) {\n\t\t\tpos++;\n\t\t\tcontinue;\n\t\t}\n\t\tconst cat = getUseCategory(posInfo.codepoint ?? 0);\n\n\t\t// Halant + Consonant continues cluster\n\t\tif (cat === UseCategory.H) {\n\t\t\tpos++;\n\t\t\tif (pos < n) {\n\t\t\t\tconst nextInfo = infos[pos];\n\t\t\t\tif (nextInfo) {\n\t\t\t\t\tconst nextCat = getUseCategory(nextInfo.codepoint ?? 0);\n\t\t\t\t\tif (\n\t\t\t\t\t\tnextCat === UseCategory.B ||\n\t\t\t\t\t\tnextCat === UseCategory.CS ||\n\t\t\t\t\t\tnextCat === UseCategory.SUB\n\t\t\t\t\t) {\n\t\t\t\t\t\tpos++;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\t// ZWJ/ZWNJ after halant\n\t\t\t\t\tif (nextCat === UseCategory.ZWJ || nextCat === UseCategory.ZWNJ) {\n\t\t\t\t\t\tpos++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Subjoined consonants\n\t\tif (cat === UseCategory.SUB || cat === UseCategory.CS) {\n\t\t\tpos++;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Nukta\n\t\tif (cat === UseCategory.N || cat === UseCategory.HN) {\n\t\t\tpos++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tbreak;\n\t}\n\n\t// Consume matras and modifiers\n\twhile (pos < n) {\n\t\tconst posInfo = infos[pos];\n\t\tif (!posInfo) {\n\t\t\tpos++;\n\t\t\tcontinue;\n\t\t}\n\t\tconst cat = getUseCategory(posInfo.codepoint ?? 0);\n\n\t\t// Vowel signs\n\t\tif (\n\t\t\tcat === UseCategory.VAbv ||\n\t\t\tcat === UseCategory.VBlw ||\n\t\t\tcat === UseCategory.VPre ||\n\t\t\tcat === UseCategory.VPst ||\n\t\t\tcat === UseCategory.VD\n\t\t) {\n\t\t\tpos++;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Medials\n\t\tif (\n\t\t\tcat === UseCategory.MAbv ||\n\t\t\tcat === UseCategory.MBlw ||\n\t\t\tcat === UseCategory.MPre ||\n\t\t\tcat === UseCategory.MPst\n\t\t) {\n\t\t\tpos++;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Vowel modifiers\n\t\tif (\n\t\t\tcat === UseCategory.VMAbv ||\n\t\t\tcat === UseCategory.VMBlw ||\n\t\t\tcat === UseCategory.VMPre ||\n\t\t\tcat === UseCategory.VMPst\n\t\t) {\n\t\t\tpos++;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Syllable modifiers\n\t\tif (cat === UseCategory.SMAbv || cat === UseCategory.SMBlw) {\n\t\t\tpos++;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Finals\n\t\tif (\n\t\t\tcat === UseCategory.FAbv ||\n\t\t\tcat === UseCategory.FBlw ||\n\t\t\tcat === UseCategory.FPst ||\n\t\t\tcat === UseCategory.F ||\n\t\t\tcat === UseCategory.FM\n\t\t) {\n\t\t\tpos++;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// CGJ, VS\n\t\tif (cat === UseCategory.CGJ || cat === UseCategory.VS) {\n\t\t\tpos++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tbreak;\n\t}\n\n\t// Ensure we advance at least one position\n\tif (pos === start) {\n\t\tpos = start + 1;\n\t}\n\n\treturn { start, end: pos, base, hasReph };\n}\n\n/**\n * Set up masks for USE shaping\n */\nexport function setupUseMasks(infos: GlyphInfo[]): void {\n\tconst syllables = findUseSyllables(infos);\n\n\tfor (const [i, syllable] of syllables.entries()) {\n\t\tfor (let j = syllable.start; j < syllable.end; j++) {\n\t\t\tconst info = infos[j];\n\t\t\tif (!info) continue;\n\n\t\t\t// Store syllable index in upper mask bits\n\t\t\tinfo.mask = (info.mask & 0x0000ffff) | ((i & 0xffff) << 16);\n\n\t\t\tconst cat = getUseCategory(info.codepoint);\n\n\t\t\t// Reph handling\n\t\t\tif (syllable.hasReph && j < syllable.start + 2) {\n\t\t\t\tinfo.mask |= UseFeatureMask.rphf;\n\t\t\t}\n\n\t\t\t// Pre-base handling\n\t\t\tif (j < syllable.base) {\n\t\t\t\tif (\n\t\t\t\t\tcat === UseCategory.B ||\n\t\t\t\t\tcat === UseCategory.CS ||\n\t\t\t\t\tcat === UseCategory.SUB\n\t\t\t\t) {\n\t\t\t\t\tinfo.mask |= UseFeatureMask.half | UseFeatureMask.cjct;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Post-base handling\n\t\t\tif (j > syllable.base) {\n\t\t\t\tif (\n\t\t\t\t\tcat === UseCategory.B ||\n\t\t\t\t\tcat === UseCategory.CS ||\n\t\t\t\t\tcat === UseCategory.SUB\n\t\t\t\t) {\n\t\t\t\t\tinfo.mask |=\n\t\t\t\t\t\tUseFeatureMask.blwf | UseFeatureMask.pstf | UseFeatureMask.vatu;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Halant\n\t\t\tif (cat === UseCategory.H || cat === UseCategory.HN) {\n\t\t\t\tif (j < syllable.base) {\n\t\t\t\t\tinfo.mask |= UseFeatureMask.half;\n\t\t\t\t} else {\n\t\t\t\t\tinfo.mask |= UseFeatureMask.haln;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Vowel signs\n\t\t\tif (cat === UseCategory.VPre) {\n\t\t\t\tinfo.mask |= UseFeatureMask.pref | UseFeatureMask.pres;\n\t\t\t} else if (cat === UseCategory.VAbv) {\n\t\t\t\tinfo.mask |= UseFeatureMask.abvf | UseFeatureMask.abvs;\n\t\t\t} else if (cat === UseCategory.VBlw) {\n\t\t\t\tinfo.mask |= UseFeatureMask.blwf | UseFeatureMask.blws;\n\t\t\t} else if (cat === UseCategory.VPst || cat === UseCategory.VD) {\n\t\t\t\tinfo.mask |= UseFeatureMask.pstf | UseFeatureMask.psts;\n\t\t\t}\n\n\t\t\t// Medials\n\t\t\tif (cat === UseCategory.MAbv) {\n\t\t\t\tinfo.mask |= UseFeatureMask.abvs;\n\t\t\t} else if (cat === UseCategory.MBlw) {\n\t\t\t\tinfo.mask |= UseFeatureMask.blws;\n\t\t\t} else if (cat === UseCategory.MPre) {\n\t\t\t\tinfo.mask |= UseFeatureMask.pres;\n\t\t\t} else if (cat === UseCategory.MPst) {\n\t\t\t\tinfo.mask |= UseFeatureMask.psts;\n\t\t\t}\n\n\t\t\t// Syllable modifiers\n\t\t\tif (cat === UseCategory.SMAbv) {\n\t\t\t\tinfo.mask |= UseFeatureMask.abvs;\n\t\t\t} else if (cat === UseCategory.SMBlw) {\n\t\t\t\tinfo.mask |= UseFeatureMask.blws;\n\t\t\t}\n\n\t\t\t// Finals\n\t\t\tif (cat === UseCategory.FAbv) {\n\t\t\t\tinfo.mask |= UseFeatureMask.abvs;\n\t\t\t} else if (cat === UseCategory.FBlw) {\n\t\t\t\tinfo.mask |= UseFeatureMask.blws;\n\t\t\t} else if (\n\t\t\t\tcat === UseCategory.FPst ||\n\t\t\t\tcat === UseCategory.F ||\n\t\t\t\tcat === UseCategory.FM\n\t\t\t) {\n\t\t\t\tinfo.mask |= UseFeatureMask.psts;\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Reorder USE syllables (pre-base vowels, reph)\n */\nexport function reorderUSE(infos: GlyphInfo[]): void {\n\tconst syllables = findUseSyllables(infos);\n\n\tfor (const syllable of syllables) {\n\t\treorderUseSyllable(infos, syllable);\n\t}\n}\n\n/**\n * Reorder a single USE syllable\n */\nfunction reorderUseSyllable(infos: GlyphInfo[], syllable: UseSyllable): void {\n\tconst { start, end, base, hasReph } = syllable;\n\n\t// Collect pre-base vowels that need to move\n\tconst preBaseVowels: { index: number; info: GlyphInfo }[] = [];\n\n\tfor (let i = base + 1; i < end; i++) {\n\t\tconst info = infos[i];\n\t\tif (!info) continue;\n\n\t\tconst cat = getUseCategory(info.codepoint);\n\t\tif (cat === UseCategory.VPre || cat === UseCategory.MPre) {\n\t\t\tpreBaseVowels.push({ index: i, info });\n\t\t}\n\t}\n\n\t// Move pre-base vowels before the base\n\tif (preBaseVowels.length > 0) {\n\t\tpreBaseVowels.sort((a, b) => b.index - a.index);\n\n\t\tfor (const { index, info } of preBaseVowels) {\n\t\t\tinfos.splice(index, 1);\n\t\t\tconst insertPos = hasReph ? start + 2 : start;\n\t\t\tinfos.splice(insertPos, 0, info);\n\t\t}\n\t}\n\n\t// Move reph to end (if present)\n\tif (hasReph && end > start + 2) {\n\t\tconst rephStart = infos[start];\n\t\tconst rephH = infos[start + 1];\n\n\t\tif (rephStart && rephH) {\n\t\t\t// Find target position: after matras, before finals\n\t\t\tlet rephTarget = end - 1;\n\n\t\t\twhile (rephTarget > base) {\n\t\t\t\tconst targetInfo = infos[rephTarget];\n\t\t\t\tif (!targetInfo) break;\n\n\t\t\t\tconst cat = getUseCategory(targetInfo.codepoint);\n\t\t\t\tif (\n\t\t\t\t\tcat === UseCategory.SMAbv ||\n\t\t\t\t\tcat === UseCategory.SMBlw ||\n\t\t\t\t\tcat === UseCategory.FAbv ||\n\t\t\t\t\tcat === UseCategory.FBlw ||\n\t\t\t\t\tcat === UseCategory.FPst ||\n\t\t\t\t\tcat === UseCategory.F ||\n\t\t\t\t\tcat === UseCategory.FM\n\t\t\t\t) {\n\t\t\t\t\trephTarget--;\n\t\t\t\t} else {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (rephTarget > start + 1) {\n\t\t\t\tinfos.splice(start, 2);\n\t\t\t\tconst adjustedTarget = rephTarget - 2;\n\t\t\t\tinfos.splice(adjustedTarget + 1, 0, rephStart, rephH);\n\t\t\t}\n\t\t}\n\t}\n}\n",
98
- "import {\n\tprocessContextual,\n\tprocessInsertion,\n\tprocessLigature,\n\tprocessRearrangement,\n} from \"../aat/state-machine.ts\";\nimport { GlyphBuffer } from \"../buffer/glyph-buffer.ts\";\nimport type { UnicodeBuffer } from \"../buffer/unicode-buffer.ts\";\nimport { Face } from \"../font/face.ts\";\nimport type { Font } from \"../font/font.ts\";\nimport { getGlyphClass } from \"../font/tables/gdef.ts\";\nimport {\n\ttype AnyGposLookup,\n\ttype CursivePosLookup,\n\tGposLookupType,\n\tgetKerning,\n\ttype MarkBasePosLookup,\n\ttype MarkLigaturePosLookup,\n\ttype MarkMarkPosLookup,\n\ttype PairPosLookup,\n\ttype SinglePosLookup,\n} from \"../font/tables/gpos.ts\";\nimport type {\n\tChainingContextPosFormat1,\n\tChainingContextPosFormat2,\n\tChainingContextPosFormat3,\n\tChainingContextPosLookup,\n\tContextPosFormat1,\n\tContextPosFormat2,\n\tContextPosFormat3,\n\tContextPosLookup,\n\tPosLookupRecord,\n} from \"../font/tables/gpos-contextual.ts\";\nimport {\n\ttype AlternateSubstLookup,\n\ttype AnyGsubLookup,\n\tapplyLigatureSubst,\n\tapplySingleSubst,\n\ttype ChainingContextSubstLookup,\n\ttype ContextSubstLookup,\n\tGsubLookupType,\n\ttype LigatureSubstLookup,\n\ttype MultipleSubstLookup,\n\ttype ReverseChainingSingleSubstLookup,\n\ttype SingleSubstLookup,\n} from \"../font/tables/gsub.ts\";\nimport type {\n\tChainingContextFormat1,\n\tChainingContextFormat2,\n\tChainingContextFormat3,\n\tContextSubstFormat1,\n\tContextSubstFormat2,\n\tContextSubstFormat3,\n\tSequenceLookupRecord,\n} from \"../font/tables/gsub-contextual.ts\";\nimport {\n\tapplyNonContextual,\n\ttype MorxContextualSubtable,\n\ttype MorxInsertionSubtable,\n\ttype MorxLigatureSubtable,\n\ttype MorxNonContextualSubtable,\n\ttype MorxRearrangementSubtable,\n\tMorxSubtableType,\n} from \"../font/tables/morx.ts\";\nimport type { ClassDef } from \"../layout/structures/class-def.ts\";\nimport {\n\tgetMarkAttachmentType,\n\tLookupFlag,\n} from \"../layout/structures/layout-common.ts\";\nimport type { GlyphId, GlyphInfo, GlyphPosition } from \"../types.ts\";\nimport { GlyphClass } from \"../types.ts\";\nimport { setupArabicMasks } from \"./complex/arabic.ts\";\nimport {\n\tisKorean,\n\tnormalizeHangul,\n\tsetupHangulMasks,\n} from \"./complex/hangul.ts\";\nimport { setupHebrewMasks } from \"./complex/hebrew.ts\";\nimport { isIndic, reorderIndic, setupIndicMasks } from \"./complex/indic.ts\";\nimport { isKhmer, reorderKhmer, setupKhmerMasks } from \"./complex/khmer.ts\";\nimport {\n\tisMyanmar,\n\treorderMyanmar,\n\tsetupMyanmarMasks,\n} from \"./complex/myanmar.ts\";\nimport {\n\tisLao,\n\tisThai,\n\treorderThaiLao,\n\tsetupThaiLaoMasks,\n} from \"./complex/thai-lao.ts\";\nimport { reorderUSE, setupUseMasks, usesUSE } from \"./complex/use.ts\";\nimport {\n\tapplyFallbackKerning,\n\tapplyFallbackMarkPositioning,\n} from \"./fallback.ts\";\nimport {\n\tcreateShapePlan,\n\ttype ShapeFeature,\n\ttype ShapePlan,\n} from \"./shape-plan.ts\";\n\nexport interface ShapeOptions {\n\tscript?: string;\n\tlanguage?: string | null;\n\tdirection?: \"ltr\" | \"rtl\";\n\tfeatures?: ShapeFeature[];\n}\n\n/** Font or Face - accepted by shape function */\nexport type FontLike = Font | Face;\n\n/** Get the underlying Font from a FontLike */\nfunction getFont(fontLike: FontLike): Font {\n\treturn fontLike instanceof Face ? fontLike.font : fontLike;\n}\n\n/** Get Face (create if needed) */\nfunction getFace(fontLike: FontLike): Face {\n\treturn fontLike instanceof Face ? fontLike : new Face(fontLike);\n}\n\n/**\n * Shape text using OpenType features.\n * Accepts Font or Face (for variable fonts).\n */\nexport function shape(\n\tfontLike: FontLike,\n\tbuffer: UnicodeBuffer,\n\toptions: ShapeOptions = {},\n): GlyphBuffer {\n\tconst font = getFont(fontLike);\n\tconst face = getFace(fontLike);\n\n\tconst script = options.script ?? buffer.script ?? \"latn\";\n\tconst language = options.language ?? buffer.language ?? null;\n\tconst direction = options.direction ?? \"ltr\";\n\tconst features = options.features ?? [];\n\n\t// Get axis coordinates from face for feature variations\n\tconst axisCoords =\n\t\tface.normalizedCoords.length > 0 ? face.normalizedCoords : null;\n\tconst plan = createShapePlan(\n\t\tfont,\n\t\tscript,\n\t\tlanguage,\n\t\tdirection,\n\t\tfeatures,\n\t\taxisCoords,\n\t);\n\n\tconst glyphBuffer = new GlyphBuffer();\n\tglyphBuffer.direction = buffer.direction;\n\tglyphBuffer.script = script;\n\tglyphBuffer.language = language;\n\n\t// Convert codepoints to initial glyph infos\n\tconst infos: GlyphInfo[] = [];\n\tfor (const [i, codepoint] of buffer.codepoints.entries()) {\n\t\tconst cluster = buffer.clusters[i];\n\t\tif (cluster === undefined) continue;\n\t\tconst glyphId = font.glyphId(codepoint);\n\n\t\tinfos.push({\n\t\t\tglyphId,\n\t\t\tcluster,\n\t\t\tmask: 0xffffffff,\n\t\t\tcodepoint,\n\t\t});\n\t}\n\n\tglyphBuffer.initFromInfos(infos);\n\n\t// Pre-shaping: Apply complex script analysis\n\tpreShape(glyphBuffer, script);\n\n\t// Apply GSUB\n\tapplyGsub(font, glyphBuffer, plan);\n\n\t// Initialize positions (using Face for variable font metrics)\n\tinitializePositions(face, glyphBuffer);\n\n\t// Apply GPOS or fallback positioning\n\tconst hasGpos = font.gpos !== null && plan.gposLookups.length > 0;\n\tif (hasGpos) {\n\t\tapplyGpos(font, glyphBuffer, plan);\n\t} else {\n\t\t// Fallback kerning using kern table\n\t\tapplyFallbackKerning(font, glyphBuffer.infos, glyphBuffer.positions);\n\t\t// Fallback mark positioning using combining classes\n\t\tapplyFallbackMarkPositioning(\n\t\t\tfont,\n\t\t\tglyphBuffer.infos,\n\t\t\tglyphBuffer.positions,\n\t\t);\n\t}\n\n\t// Apply AAT morx substitutions if no GSUB\n\tif (!font.gsub && font.morx) {\n\t\tapplyMorx(font, glyphBuffer);\n\t}\n\n\t// Reverse for RTL\n\tif (direction === \"rtl\") {\n\t\tglyphBuffer.reverse();\n\t}\n\n\treturn glyphBuffer;\n}\n\n// Pre-shaping for complex scripts\n\nfunction preShape(buffer: GlyphBuffer, script: string): void {\n\t// Arabic joining analysis\n\tif (\n\t\tscript === \"arab\" ||\n\t\tscript === \"syrc\" ||\n\t\tscript === \"mand\" ||\n\t\tscript === \"nko \"\n\t) {\n\t\tsetupArabicMasks(buffer.infos);\n\t\treturn;\n\t}\n\n\t// Hebrew (RTL with marks)\n\tif (script === \"hebr\") {\n\t\tsetupHebrewMasks(buffer.infos);\n\t\treturn;\n\t}\n\n\t// Hangul (Korean)\n\tif (script === \"hang\" || script === \"kore\") {\n\t\t// Normalize Jamo sequences into precomposed syllables\n\t\tconst normalized = normalizeHangul(buffer.infos);\n\t\tif (normalized.length !== buffer.infos.length) {\n\t\t\tbuffer.initFromInfos(normalized);\n\t\t}\n\t\tsetupHangulMasks(buffer.infos);\n\t\treturn;\n\t}\n\n\t// Indic scripts (syllable-based)\n\tif (\n\t\tscript === \"deva\" ||\n\t\tscript === \"beng\" ||\n\t\tscript === \"guru\" ||\n\t\tscript === \"gujr\" ||\n\t\tscript === \"orya\" ||\n\t\tscript === \"taml\" ||\n\t\tscript === \"telu\" ||\n\t\tscript === \"knda\" ||\n\t\tscript === \"mlym\"\n\t) {\n\t\tsetupIndicMasks(buffer.infos);\n\t\treorderIndic(buffer.infos);\n\t\treturn;\n\t}\n\n\t// Thai and Lao (leading vowel reordering)\n\tif (script === \"thai\" || script === \"lao \") {\n\t\tsetupThaiLaoMasks(buffer.infos);\n\t\treorderThaiLao(buffer.infos);\n\t\treturn;\n\t}\n\n\t// Khmer (subscript consonants, pre-base vowels)\n\tif (script === \"khmr\") {\n\t\tsetupKhmerMasks(buffer.infos);\n\t\treorderKhmer(buffer.infos);\n\t\treturn;\n\t}\n\n\t// Myanmar (medials, pre-base vowels, stacking)\n\tif (script === \"mymr\") {\n\t\tsetupMyanmarMasks(buffer.infos);\n\t\treorderMyanmar(buffer.infos);\n\t\treturn;\n\t}\n\n\t// Universal Shaping Engine (many other complex scripts)\n\tif (usesUSE(script)) {\n\t\tsetupUseMasks(buffer.infos);\n\t\treorderUSE(buffer.infos);\n\t\treturn;\n\t}\n\n\t// Auto-detect based on content if script is unknown\n\tif (script === \"Zyyy\" || script === \"Zinh\" || script === \"Zzzz\") {\n\t\tdetectAndApplyComplexShaping(buffer.infos);\n\t}\n}\n\n// Auto-detect complex script from content\nfunction detectAndApplyComplexShaping(infos: GlyphInfo[]): void {\n\tif (infos.length === 0) return;\n\n\t// Sample first few codepoints to detect script\n\tconst sample = infos.slice(0, Math.min(10, infos.length));\n\n\tfor (const info of sample) {\n\t\tconst cp = info.codepoint;\n\n\t\t// Arabic range\n\t\tif (\n\t\t\t(cp >= 0x0600 && cp <= 0x06ff) ||\n\t\t\t(cp >= 0x0750 && cp <= 0x077f) ||\n\t\t\t(cp >= 0x08a0 && cp <= 0x08ff)\n\t\t) {\n\t\t\tsetupArabicMasks(infos);\n\t\t\treturn;\n\t\t}\n\n\t\t// Hebrew range\n\t\tif (cp >= 0x0590 && cp <= 0x05ff) {\n\t\t\tsetupHebrewMasks(infos);\n\t\t\treturn;\n\t\t}\n\n\t\t// Korean/Hangul\n\t\tif (isKorean(cp)) {\n\t\t\tconst normalized = normalizeHangul(infos);\n\t\t\tif (normalized.length !== infos.length) {\n\t\t\t\t// Replace infos in place\n\t\t\t\tinfos.length = 0;\n\t\t\t\tinfos.push(...normalized);\n\t\t\t}\n\t\t\tsetupHangulMasks(infos);\n\t\t\treturn;\n\t\t}\n\n\t\t// Devanagari and other Indic\n\t\tif (isIndic(cp)) {\n\t\t\tsetupIndicMasks(infos);\n\t\t\treorderIndic(infos);\n\t\t\treturn;\n\t\t}\n\n\t\t// Thai\n\t\tif (isThai(cp)) {\n\t\t\tsetupThaiLaoMasks(infos);\n\t\t\treorderThaiLao(infos);\n\t\t\treturn;\n\t\t}\n\n\t\t// Lao\n\t\tif (isLao(cp)) {\n\t\t\tsetupThaiLaoMasks(infos);\n\t\t\treorderThaiLao(infos);\n\t\t\treturn;\n\t\t}\n\n\t\t// Khmer\n\t\tif (isKhmer(cp)) {\n\t\t\tsetupKhmerMasks(infos);\n\t\t\treorderKhmer(infos);\n\t\t\treturn;\n\t\t}\n\n\t\t// Myanmar\n\t\tif (isMyanmar(cp)) {\n\t\t\tsetupMyanmarMasks(infos);\n\t\t\treorderMyanmar(infos);\n\t\t\treturn;\n\t\t}\n\t}\n}\n\n// GSUB application\n\nfunction applyGsub(font: Font, buffer: GlyphBuffer, plan: ShapePlan): void {\n\tfor (const { lookup } of plan.gsubLookups) {\n\t\tapplyGsubLookup(font, buffer, lookup, plan);\n\t}\n}\n\nfunction applyGsubLookup(\n\tfont: Font,\n\tbuffer: GlyphBuffer,\n\tlookup: AnyGsubLookup,\n\tplan: ShapePlan,\n): void {\n\tswitch (lookup.type) {\n\t\tcase GsubLookupType.Single:\n\t\t\tapplySingleSubstLookup(font, buffer, lookup);\n\t\t\tbreak;\n\t\tcase GsubLookupType.Multiple:\n\t\t\tapplyMultipleSubstLookup(font, buffer, lookup);\n\t\t\tbreak;\n\t\tcase GsubLookupType.Alternate:\n\t\t\t// Alternate requires user selection - use first alternate as default\n\t\t\tapplyAlternateSubstLookup(font, buffer, lookup);\n\t\t\tbreak;\n\t\tcase GsubLookupType.Ligature:\n\t\t\tapplyLigatureSubstLookup(font, buffer, lookup);\n\t\t\tbreak;\n\t\tcase GsubLookupType.Context:\n\t\t\tapplyContextSubstLookup(font, buffer, lookup, plan);\n\t\t\tbreak;\n\t\tcase GsubLookupType.ChainingContext:\n\t\t\tapplyChainingContextSubstLookup(font, buffer, lookup, plan);\n\t\t\tbreak;\n\t\t// Note: Extension lookups (Type 7) are unwrapped during parsing\n\t\t// and converted to their actual lookup types, so no case needed here\n\t\tcase GsubLookupType.ReverseChainingSingle:\n\t\t\tapplyReverseChainingSingleSubstLookup(font, buffer, lookup);\n\t\t\tbreak;\n\t}\n}\n\nfunction applySingleSubstLookup(\n\tfont: Font,\n\tbuffer: GlyphBuffer,\n\tlookup: SingleSubstLookup,\n): void {\n\tfor (const info of buffer.infos) {\n\t\tif (shouldSkipGlyph(font, info.glyphId, lookup.flag)) continue;\n\n\t\tconst replacement = applySingleSubst(lookup, info.glyphId);\n\t\tif (replacement !== null) {\n\t\t\tinfo.glyphId = replacement;\n\t\t}\n\t}\n}\n\nfunction applyMultipleSubstLookup(\n\tfont: Font,\n\tbuffer: GlyphBuffer,\n\tlookup: MultipleSubstLookup,\n): void {\n\tlet i = 0;\n\twhile (i < buffer.infos.length) {\n\t\tconst info = buffer.infos[i];\n\t\tif (!info) {\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\t\tif (shouldSkipGlyph(font, info.glyphId, lookup.flag)) {\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tlet applied = false;\n\t\tfor (const subtable of lookup.subtables) {\n\t\t\tconst coverageIndex = subtable.coverage.get(info.glyphId);\n\t\t\tif (coverageIndex === null) continue;\n\n\t\t\tconst sequence = subtable.sequences[coverageIndex];\n\t\t\tif (!sequence || sequence.length === 0) continue;\n\n\t\t\tconst [firstGlyph, ...restGlyphs] = sequence;\n\t\t\tif (firstGlyph === undefined) continue;\n\n\t\t\t// Replace with sequence\n\t\t\tinfo.glyphId = firstGlyph;\n\n\t\t\t// Insert remaining glyphs\n\t\t\tfor (const [j, glyphId] of restGlyphs.entries()) {\n\t\t\t\tconst newInfo: GlyphInfo = {\n\t\t\t\t\tglyphId,\n\t\t\t\t\tcluster: info.cluster,\n\t\t\t\t\tmask: info.mask,\n\t\t\t\t\tcodepoint: info.codepoint,\n\t\t\t\t};\n\t\t\t\tconst newPos: GlyphPosition = {\n\t\t\t\t\txAdvance: 0,\n\t\t\t\t\tyAdvance: 0,\n\t\t\t\t\txOffset: 0,\n\t\t\t\t\tyOffset: 0,\n\t\t\t\t};\n\t\t\t\tbuffer.insertGlyph(i + j + 1, newInfo, newPos);\n\t\t\t}\n\n\t\t\ti += sequence.length;\n\t\t\tapplied = true;\n\t\t\tbreak;\n\t\t}\n\n\t\tif (!applied) i++;\n\t}\n}\n\nfunction applyAlternateSubstLookup(\n\tfont: Font,\n\tbuffer: GlyphBuffer,\n\tlookup: AlternateSubstLookup,\n): void {\n\t// Alternate substitution allows selecting from multiple alternates\n\t// By default, use the first alternate (index 0)\n\tfor (const info of buffer.infos) {\n\t\tif (shouldSkipGlyph(font, info.glyphId, lookup.flag)) continue;\n\n\t\tfor (const subtable of lookup.subtables) {\n\t\t\tconst coverageIndex = subtable.coverage.get(info.glyphId);\n\t\t\tif (coverageIndex === null) continue;\n\n\t\t\tconst alternateSet = subtable.alternateSets[coverageIndex];\n\t\t\tif (!alternateSet || alternateSet.length === 0) continue;\n\n\t\t\tconst [firstAlternate] = alternateSet;\n\t\t\tif (firstAlternate === undefined) continue;\n\n\t\t\t// Use first alternate by default\n\t\t\tinfo.glyphId = firstAlternate;\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\nfunction applyLigatureSubstLookup(\n\tfont: Font,\n\tbuffer: GlyphBuffer,\n\tlookup: LigatureSubstLookup,\n): void {\n\tlet i = 0;\n\twhile (i < buffer.infos.length) {\n\t\tconst info = buffer.infos[i];\n\t\tif (!info) {\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\t\tif (shouldSkipGlyph(font, info.glyphId, lookup.flag)) {\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Collect matchable glyphs (skipping ignored ones)\n\t\tconst matchIndices: number[] = [i];\n\t\tconst matchGlyphs: GlyphId[] = [info.glyphId];\n\n\t\tfor (\n\t\t\tlet j = i + 1;\n\t\t\tj < buffer.infos.length && matchGlyphs.length < 16;\n\t\t\tj++\n\t\t) {\n\t\t\tconst nextInfo = buffer.infos[j];\n\t\t\tif (!nextInfo) continue;\n\t\t\tif (shouldSkipGlyph(font, nextInfo.glyphId, lookup.flag)) continue;\n\t\t\tmatchIndices.push(j);\n\t\t\tmatchGlyphs.push(nextInfo.glyphId);\n\t\t}\n\n\t\tconst result = applyLigatureSubst(lookup, matchGlyphs, 0);\n\t\tif (result) {\n\t\t\t// Replace first glyph with ligature\n\t\t\tinfo.glyphId = result.ligatureGlyph;\n\n\t\t\t// Merge clusters and remove consumed glyphs\n\t\t\tconst indicesToRemove: number[] = [];\n\t\t\tfor (let k = 1; k < result.consumed; k++) {\n\t\t\t\tconst idx = matchIndices[k];\n\t\t\t\tif (idx !== undefined) {\n\t\t\t\t\tconst targetInfo = buffer.infos[idx];\n\t\t\t\t\tif (targetInfo) {\n\t\t\t\t\t\tinfo.cluster = Math.min(info.cluster, targetInfo.cluster);\n\t\t\t\t\t}\n\t\t\t\t\tindicesToRemove.push(idx);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove in reverse order to maintain indices\n\t\t\tfor (const idx of indicesToRemove.reverse()) {\n\t\t\t\tbuffer.removeRange(idx, idx + 1);\n\t\t\t}\n\t\t}\n\n\t\ti++;\n\t}\n}\n\nfunction applyContextSubstLookup(\n\tfont: Font,\n\tbuffer: GlyphBuffer,\n\tlookup: ContextSubstLookup,\n\tplan: ShapePlan,\n): void {\n\t// Context substitution - matches input sequence and applies nested lookups\n\tfor (let i = 0; i < buffer.infos.length; i++) {\n\t\tconst info = buffer.infos[i];\n\t\tif (!info) continue;\n\t\tif (shouldSkipGlyph(font, info.glyphId, lookup.flag)) continue;\n\n\t\tfor (const subtable of lookup.subtables) {\n\t\t\tlet matched = false;\n\t\t\tlet lookupRecords: SequenceLookupRecord[] = [];\n\n\t\t\tif (subtable.format === 1) {\n\t\t\t\tconst result = matchContextFormat1(\n\t\t\t\t\tfont,\n\t\t\t\t\tbuffer,\n\t\t\t\t\ti,\n\t\t\t\t\tsubtable,\n\t\t\t\t\tlookup.flag,\n\t\t\t\t);\n\t\t\t\tif (result) {\n\t\t\t\t\tmatched = true;\n\t\t\t\t\tlookupRecords = result;\n\t\t\t\t}\n\t\t\t} else if (subtable.format === 2) {\n\t\t\t\tconst result = matchContextFormat2(\n\t\t\t\t\tfont,\n\t\t\t\t\tbuffer,\n\t\t\t\t\ti,\n\t\t\t\t\tsubtable,\n\t\t\t\t\tlookup.flag,\n\t\t\t\t);\n\t\t\t\tif (result) {\n\t\t\t\t\tmatched = true;\n\t\t\t\t\tlookupRecords = result;\n\t\t\t\t}\n\t\t\t} else if (subtable.format === 3) {\n\t\t\t\tif (matchContextFormat3(font, buffer, i, subtable, lookup.flag)) {\n\t\t\t\t\tmatched = true;\n\t\t\t\t\tlookupRecords = subtable.lookupRecords;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (matched) {\n\t\t\t\tapplyNestedLookups(font, buffer, i, lookupRecords, plan);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction applyChainingContextSubstLookup(\n\tfont: Font,\n\tbuffer: GlyphBuffer,\n\tlookup: ChainingContextSubstLookup,\n\tplan: ShapePlan,\n): void {\n\tfor (let i = 0; i < buffer.infos.length; i++) {\n\t\tconst info = buffer.infos[i];\n\t\tif (!info) continue;\n\t\tif (shouldSkipGlyph(font, info.glyphId, lookup.flag)) continue;\n\n\t\tfor (const subtable of lookup.subtables) {\n\t\t\tlet matched = false;\n\t\t\tlet lookupRecords: SequenceLookupRecord[] = [];\n\n\t\t\tif (subtable.format === 1) {\n\t\t\t\tconst result = matchChainingFormat1(\n\t\t\t\t\tfont,\n\t\t\t\t\tbuffer,\n\t\t\t\t\ti,\n\t\t\t\t\tsubtable,\n\t\t\t\t\tlookup.flag,\n\t\t\t\t);\n\t\t\t\tif (result) {\n\t\t\t\t\tmatched = true;\n\t\t\t\t\tlookupRecords = result;\n\t\t\t\t}\n\t\t\t} else if (subtable.format === 2) {\n\t\t\t\tconst result = matchChainingFormat2(\n\t\t\t\t\tfont,\n\t\t\t\t\tbuffer,\n\t\t\t\t\ti,\n\t\t\t\t\tsubtable,\n\t\t\t\t\tlookup.flag,\n\t\t\t\t);\n\t\t\t\tif (result) {\n\t\t\t\t\tmatched = true;\n\t\t\t\t\tlookupRecords = result;\n\t\t\t\t}\n\t\t\t} else if (subtable.format === 3) {\n\t\t\t\tif (matchChainingFormat3(font, buffer, i, subtable, lookup.flag)) {\n\t\t\t\t\tmatched = true;\n\t\t\t\t\tlookupRecords = subtable.lookupRecords;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (matched) {\n\t\t\t\tapplyNestedLookups(font, buffer, i, lookupRecords, plan);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction applyReverseChainingSingleSubstLookup(\n\tfont: Font,\n\tbuffer: GlyphBuffer,\n\tlookup: ReverseChainingSingleSubstLookup,\n): void {\n\t// Process in reverse order\n\tfor (let i = buffer.infos.length - 1; i >= 0; i--) {\n\t\tconst info = buffer.infos[i];\n\t\tif (!info) continue;\n\t\tif (shouldSkipGlyph(font, info.glyphId, lookup.flag)) continue;\n\n\t\tfor (const subtable of lookup.subtables) {\n\t\t\tconst coverageIndex = subtable.coverage.get(info.glyphId);\n\t\t\tif (coverageIndex === null) continue;\n\n\t\t\t// Check backtrack (glyphs after current in reverse order)\n\t\t\tlet backtrackMatch = true;\n\t\t\tlet backtrackPos = i + 1;\n\t\t\tfor (const backCov of subtable.backtrackCoverages) {\n\t\t\t\twhile (\n\t\t\t\t\tbacktrackPos < buffer.infos.length &&\n\t\t\t\t\tshouldSkipGlyph(\n\t\t\t\t\t\tfont,\n\t\t\t\t\t\tbuffer.infos[backtrackPos]?.glyphId,\n\t\t\t\t\t\tlookup.flag,\n\t\t\t\t\t)\n\t\t\t\t) {\n\t\t\t\t\tbacktrackPos++;\n\t\t\t\t}\n\t\t\t\tif (\n\t\t\t\t\tbacktrackPos >= buffer.infos.length ||\n\t\t\t\t\tbackCov.get(buffer.infos[backtrackPos]?.glyphId) === null\n\t\t\t\t) {\n\t\t\t\t\tbacktrackMatch = false;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tbacktrackPos++;\n\t\t\t}\n\t\t\tif (!backtrackMatch) continue;\n\n\t\t\t// Check lookahead (glyphs before current)\n\t\t\tlet lookaheadMatch = true;\n\t\t\tlet lookaheadPos = i - 1;\n\t\t\tfor (const lookCov of subtable.lookaheadCoverages) {\n\t\t\t\twhile (\n\t\t\t\t\tlookaheadPos >= 0 &&\n\t\t\t\t\tshouldSkipGlyph(\n\t\t\t\t\t\tfont,\n\t\t\t\t\t\tbuffer.infos[lookaheadPos]?.glyphId,\n\t\t\t\t\t\tlookup.flag,\n\t\t\t\t\t)\n\t\t\t\t) {\n\t\t\t\t\tlookaheadPos--;\n\t\t\t\t}\n\t\t\t\tif (\n\t\t\t\t\tlookaheadPos < 0 ||\n\t\t\t\t\tlookCov.get(buffer.infos[lookaheadPos]?.glyphId) === null\n\t\t\t\t) {\n\t\t\t\t\tlookaheadMatch = false;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tlookaheadPos--;\n\t\t\t}\n\t\t\tif (!lookaheadMatch) continue;\n\n\t\t\t// Apply substitution\n\t\t\tconst substitute = subtable.substituteGlyphIds[coverageIndex];\n\t\t\tif (substitute !== undefined) {\n\t\t\t\tinfo.glyphId = substitute;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\n// Note: Extension lookups (Type 7) are unwrapped during parsing,\n// so no applyExtensionGsubLookup function is needed at runtime.\n\n/** Match Context Format 1 - glyph-based rules */\nfunction matchContextFormat1(\n\tfont: Font,\n\tbuffer: GlyphBuffer,\n\tstartIndex: number,\n\tsubtable: ContextSubstFormat1,\n\tlookupFlag: number,\n): SequenceLookupRecord[] | null {\n\tconst firstGlyph = buffer.infos[startIndex]?.glyphId;\n\tconst coverageIndex = subtable.coverage.get(firstGlyph);\n\tif (coverageIndex === null) return null;\n\n\tconst ruleSet = subtable.ruleSets[coverageIndex];\n\tif (!ruleSet) return null;\n\n\tfor (const rule of ruleSet) {\n\t\tif (\n\t\t\tmatchGlyphSequence(\n\t\t\t\tfont,\n\t\t\t\tbuffer,\n\t\t\t\tstartIndex + 1,\n\t\t\t\trule.inputSequence,\n\t\t\t\tlookupFlag,\n\t\t\t)\n\t\t) {\n\t\t\treturn rule.lookupRecords;\n\t\t}\n\t}\n\treturn null;\n}\n\n/** Match Context Format 2 - class-based rules */\nfunction matchContextFormat2(\n\tfont: Font,\n\tbuffer: GlyphBuffer,\n\tstartIndex: number,\n\tsubtable: ContextSubstFormat2,\n\tlookupFlag: number,\n): SequenceLookupRecord[] | null {\n\tconst firstGlyph = buffer.infos[startIndex]?.glyphId;\n\tconst coverageIndex = subtable.coverage.get(firstGlyph);\n\tif (coverageIndex === null) return null;\n\n\tconst firstClass = subtable.classDef.get(firstGlyph);\n\tconst classRuleSet = subtable.classRuleSets[firstClass];\n\tif (!classRuleSet) return null;\n\n\tfor (const rule of classRuleSet) {\n\t\tif (\n\t\t\tmatchClassSequence(\n\t\t\t\tfont,\n\t\t\t\tbuffer,\n\t\t\t\tstartIndex + 1,\n\t\t\t\trule.inputClasses,\n\t\t\t\tsubtable.classDef,\n\t\t\t\tlookupFlag,\n\t\t\t)\n\t\t) {\n\t\t\treturn rule.lookupRecords;\n\t\t}\n\t}\n\treturn null;\n}\n\n/** Match Context Format 3 - coverage-based */\nfunction matchContextFormat3(\n\tfont: Font,\n\tbuffer: GlyphBuffer,\n\tstartIndex: number,\n\tsubtable: ContextSubstFormat3,\n\tlookupFlag: number,\n): boolean {\n\tlet pos = startIndex;\n\tfor (const coverage of subtable.coverages) {\n\t\twhile (\n\t\t\tpos < buffer.infos.length &&\n\t\t\tshouldSkipGlyph(font, buffer.infos[pos]?.glyphId, lookupFlag)\n\t\t) {\n\t\t\tpos++;\n\t\t}\n\t\tif (pos >= buffer.infos.length) return false;\n\t\tif (coverage.get(buffer.infos[pos]?.glyphId) === null) return false;\n\t\tpos++;\n\t}\n\treturn true;\n}\n\n/** Match Chaining Context Format 1 - glyph-based rules */\nfunction matchChainingFormat1(\n\tfont: Font,\n\tbuffer: GlyphBuffer,\n\tstartIndex: number,\n\tsubtable: ChainingContextFormat1,\n\tlookupFlag: number,\n): SequenceLookupRecord[] | null {\n\tconst firstGlyph = buffer.infos[startIndex]?.glyphId;\n\tconst coverageIndex = subtable.coverage.get(firstGlyph);\n\tif (coverageIndex === null) return null;\n\n\tconst chainRuleSet = subtable.chainRuleSets[coverageIndex];\n\tif (!chainRuleSet) return null;\n\n\tfor (const rule of chainRuleSet) {\n\t\t// Check backtrack (reversed order, before startIndex)\n\t\tif (\n\t\t\t!matchGlyphSequenceBackward(\n\t\t\t\tfont,\n\t\t\t\tbuffer,\n\t\t\t\tstartIndex - 1,\n\t\t\t\trule.backtrackSequence,\n\t\t\t\tlookupFlag,\n\t\t\t)\n\t\t) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Check input (excluding first glyph which is in coverage)\n\t\tif (\n\t\t\t!matchGlyphSequence(\n\t\t\t\tfont,\n\t\t\t\tbuffer,\n\t\t\t\tstartIndex + 1,\n\t\t\t\trule.inputSequence,\n\t\t\t\tlookupFlag,\n\t\t\t)\n\t\t) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Find where input sequence ends\n\t\tlet inputEnd = startIndex + 1;\n\t\tfor (let i = 0; i < rule.inputSequence.length; i++) {\n\t\t\twhile (\n\t\t\t\tinputEnd < buffer.infos.length &&\n\t\t\t\tshouldSkipGlyph(font, buffer.infos[inputEnd]?.glyphId, lookupFlag)\n\t\t\t) {\n\t\t\t\tinputEnd++;\n\t\t\t}\n\t\t\tinputEnd++;\n\t\t}\n\n\t\t// Check lookahead\n\t\tif (\n\t\t\t!matchGlyphSequence(\n\t\t\t\tfont,\n\t\t\t\tbuffer,\n\t\t\t\tinputEnd,\n\t\t\t\trule.lookaheadSequence,\n\t\t\t\tlookupFlag,\n\t\t\t)\n\t\t) {\n\t\t\tcontinue;\n\t\t}\n\n\t\treturn rule.lookupRecords;\n\t}\n\treturn null;\n}\n\n/** Match Chaining Context Format 2 - class-based rules */\nfunction matchChainingFormat2(\n\tfont: Font,\n\tbuffer: GlyphBuffer,\n\tstartIndex: number,\n\tsubtable: ChainingContextFormat2,\n\tlookupFlag: number,\n): SequenceLookupRecord[] | null {\n\tconst firstGlyph = buffer.infos[startIndex]?.glyphId;\n\tconst coverageIndex = subtable.coverage.get(firstGlyph);\n\tif (coverageIndex === null) return null;\n\n\tconst firstClass = subtable.inputClassDef.get(firstGlyph);\n\tconst chainClassRuleSet = subtable.chainClassRuleSets[firstClass];\n\tif (!chainClassRuleSet) return null;\n\n\tfor (const rule of chainClassRuleSet) {\n\t\t// Check backtrack classes (reversed order)\n\t\tif (\n\t\t\t!matchClassSequenceBackward(\n\t\t\t\tfont,\n\t\t\t\tbuffer,\n\t\t\t\tstartIndex - 1,\n\t\t\t\trule.backtrackClasses,\n\t\t\t\tsubtable.backtrackClassDef,\n\t\t\t\tlookupFlag,\n\t\t\t)\n\t\t) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Check input classes (excluding first)\n\t\tif (\n\t\t\t!matchClassSequence(\n\t\t\t\tfont,\n\t\t\t\tbuffer,\n\t\t\t\tstartIndex + 1,\n\t\t\t\trule.inputClasses,\n\t\t\t\tsubtable.inputClassDef,\n\t\t\t\tlookupFlag,\n\t\t\t)\n\t\t) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Find where input ends\n\t\tlet inputEnd = startIndex + 1;\n\t\tfor (let i = 0; i < rule.inputClasses.length; i++) {\n\t\t\twhile (\n\t\t\t\tinputEnd < buffer.infos.length &&\n\t\t\t\tshouldSkipGlyph(font, buffer.infos[inputEnd]?.glyphId, lookupFlag)\n\t\t\t) {\n\t\t\t\tinputEnd++;\n\t\t\t}\n\t\t\tinputEnd++;\n\t\t}\n\n\t\t// Check lookahead classes\n\t\tif (\n\t\t\t!matchClassSequence(\n\t\t\t\tfont,\n\t\t\t\tbuffer,\n\t\t\t\tinputEnd,\n\t\t\t\trule.lookaheadClasses,\n\t\t\t\tsubtable.lookaheadClassDef,\n\t\t\t\tlookupFlag,\n\t\t\t)\n\t\t) {\n\t\t\tcontinue;\n\t\t}\n\n\t\treturn rule.lookupRecords;\n\t}\n\treturn null;\n}\n\n/** Match Chaining Context Format 3 - coverage-based */\nfunction matchChainingFormat3(\n\tfont: Font,\n\tbuffer: GlyphBuffer,\n\tstartIndex: number,\n\tsubtable: ChainingContextFormat3,\n\tlookupFlag: number,\n): boolean {\n\t// Check backtrack (in reverse order, before startIndex)\n\tlet backtrackPos = startIndex - 1;\n\tfor (const coverage of subtable.backtrackCoverages) {\n\t\twhile (\n\t\t\tbacktrackPos >= 0 &&\n\t\t\tshouldSkipGlyph(font, buffer.infos[backtrackPos]?.glyphId, lookupFlag)\n\t\t) {\n\t\t\tbacktrackPos--;\n\t\t}\n\t\tif (backtrackPos < 0) return false;\n\t\tif (coverage.get(buffer.infos[backtrackPos]?.glyphId) === null)\n\t\t\treturn false;\n\t\tbacktrackPos--;\n\t}\n\n\t// Check input sequence\n\tlet inputPos = startIndex;\n\tfor (const coverage of subtable.inputCoverages) {\n\t\twhile (\n\t\t\tinputPos < buffer.infos.length &&\n\t\t\tshouldSkipGlyph(font, buffer.infos[inputPos]?.glyphId, lookupFlag)\n\t\t) {\n\t\t\tinputPos++;\n\t\t}\n\t\tif (inputPos >= buffer.infos.length) return false;\n\t\tif (coverage.get(buffer.infos[inputPos]?.glyphId) === null) return false;\n\t\tinputPos++;\n\t}\n\n\t// Check lookahead\n\tlet lookaheadPos = inputPos;\n\tfor (const coverage of subtable.lookaheadCoverages) {\n\t\twhile (\n\t\t\tlookaheadPos < buffer.infos.length &&\n\t\t\tshouldSkipGlyph(font, buffer.infos[lookaheadPos]?.glyphId, lookupFlag)\n\t\t) {\n\t\t\tlookaheadPos++;\n\t\t}\n\t\tif (lookaheadPos >= buffer.infos.length) return false;\n\t\tif (coverage.get(buffer.infos[lookaheadPos]?.glyphId) === null)\n\t\t\treturn false;\n\t\tlookaheadPos++;\n\t}\n\n\treturn true;\n}\n\nfunction applyNestedLookups(\n\t_font: Font,\n\tbuffer: GlyphBuffer,\n\tstartIndex: number,\n\tlookupRecords: Array<{ sequenceIndex: number; lookupListIndex: number }>,\n\tplan: ShapePlan,\n): void {\n\t// Sort by sequence index descending to apply from end to start\n\tconst sorted = [...lookupRecords].sort(\n\t\t(a, b) => b.sequenceIndex - a.sequenceIndex,\n\t);\n\n\tfor (const record of sorted) {\n\t\tconst lookupEntry = plan.gsubLookups.find(\n\t\t\t(l) => l.index === record.lookupListIndex,\n\t\t);\n\t\tif (!lookupEntry) continue;\n\n\t\t// Apply at the specific position\n\t\tconst pos = startIndex + record.sequenceIndex;\n\t\tif (pos >= buffer.infos.length) continue;\n\n\t\tconst targetInfo = buffer.infos[pos];\n\t\tif (!targetInfo) continue;\n\n\t\t// For single subst, apply directly\n\t\tif (lookupEntry.lookup.type === GsubLookupType.Single) {\n\t\t\tconst replacement = applySingleSubst(\n\t\t\t\tlookupEntry.lookup as SingleSubstLookup,\n\t\t\t\ttargetInfo.glyphId,\n\t\t\t);\n\t\t\tif (replacement !== null) {\n\t\t\t\ttargetInfo.glyphId = replacement;\n\t\t\t}\n\t\t}\n\t}\n}\n\n// GPOS application\n\nfunction initializePositions(face: Face, buffer: GlyphBuffer): void {\n\tfor (const [i, info] of buffer.infos.entries()) {\n\t\t// Use Face.advanceWidth to include variable font deltas\n\t\tconst advance = face.advanceWidth(info.glyphId);\n\t\tbuffer.setAdvance(i, advance, 0);\n\t}\n}\n\nfunction applyGpos(font: Font, buffer: GlyphBuffer, plan: ShapePlan): void {\n\tfor (const { lookup } of plan.gposLookups) {\n\t\tapplyGposLookup(font, buffer, lookup, plan);\n\t}\n}\n\nfunction applyGposLookup(\n\tfont: Font,\n\tbuffer: GlyphBuffer,\n\tlookup: AnyGposLookup,\n\tplan: ShapePlan,\n): void {\n\tswitch (lookup.type) {\n\t\tcase GposLookupType.Single:\n\t\t\tapplySinglePosLookup(font, buffer, lookup);\n\t\t\tbreak;\n\t\tcase GposLookupType.Pair:\n\t\t\tapplyPairPosLookup(font, buffer, lookup);\n\t\t\tbreak;\n\t\tcase GposLookupType.Cursive:\n\t\t\tapplyCursivePosLookup(font, buffer, lookup);\n\t\t\tbreak;\n\t\tcase GposLookupType.MarkToBase:\n\t\t\tapplyMarkBasePosLookup(font, buffer, lookup);\n\t\t\tbreak;\n\t\tcase GposLookupType.MarkToLigature:\n\t\t\tapplyMarkLigaturePosLookup(font, buffer, lookup);\n\t\t\tbreak;\n\t\tcase GposLookupType.MarkToMark:\n\t\t\tapplyMarkMarkPosLookup(font, buffer, lookup);\n\t\t\tbreak;\n\t\tcase GposLookupType.Context:\n\t\t\tapplyContextPosLookup(font, buffer, lookup as ContextPosLookup, plan);\n\t\t\tbreak;\n\t\tcase GposLookupType.ChainingContext:\n\t\t\tapplyChainingContextPosLookup(\n\t\t\t\tfont,\n\t\t\t\tbuffer,\n\t\t\t\tlookup as ChainingContextPosLookup,\n\t\t\t\tplan,\n\t\t\t);\n\t\t\tbreak;\n\t\t// Extension (type 9) is unwrapped during parsing - no runtime case needed\n\t}\n}\n\nfunction applySinglePosLookup(\n\tfont: Font,\n\tbuffer: GlyphBuffer,\n\tlookup: SinglePosLookup,\n): void {\n\tfor (const [i, info] of buffer.infos.entries()) {\n\t\tconst pos = buffer.positions[i];\n\t\tif (!pos) continue;\n\t\tif (shouldSkipGlyph(font, info.glyphId, lookup.flag)) continue;\n\n\t\tfor (const subtable of lookup.subtables) {\n\t\t\tconst coverageIndex = subtable.coverage.get(info.glyphId);\n\t\t\tif (coverageIndex === null) continue;\n\n\t\t\tconst value =\n\t\t\t\tsubtable.format === 1\n\t\t\t\t\t? subtable.value\n\t\t\t\t\t: subtable.values?.[coverageIndex];\n\t\t\tif (value) {\n\t\t\t\tif (value.xPlacement) pos.xOffset += value.xPlacement;\n\t\t\t\tif (value.yPlacement) pos.yOffset += value.yPlacement;\n\t\t\t\tif (value.xAdvance) pos.xAdvance += value.xAdvance;\n\t\t\t\tif (value.yAdvance) pos.yAdvance += value.yAdvance;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\nfunction applyPairPosLookup(\n\tfont: Font,\n\tbuffer: GlyphBuffer,\n\tlookup: PairPosLookup,\n): void {\n\tfor (let i = 0; i < buffer.infos.length - 1; i++) {\n\t\tconst info1 = buffer.infos[i];\n\t\tif (!info1) continue;\n\t\tif (shouldSkipGlyph(font, info1.glyphId, lookup.flag)) continue;\n\n\t\t// Find next non-skipped glyph\n\t\tlet j = i + 1;\n\t\twhile (j < buffer.infos.length) {\n\t\t\tconst nextInfo = buffer.infos[j];\n\t\t\tif (nextInfo && !shouldSkipGlyph(font, nextInfo.glyphId, lookup.flag)) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tj++;\n\t\t}\n\t\tif (j >= buffer.infos.length) break;\n\n\t\tconst info2 = buffer.infos[j];\n\t\tif (!info2) continue;\n\n\t\tconst kern = getKerning(lookup, info1.glyphId, info2.glyphId);\n\t\tif (kern) {\n\t\t\tconst pos1 = buffer.positions[i];\n\t\t\tconst pos2 = buffer.positions[j];\n\t\t\tif (pos1) pos1.xAdvance += kern.xAdvance1;\n\t\t\tif (pos2) pos2.xAdvance += kern.xAdvance2;\n\t\t}\n\t}\n}\n\nfunction applyCursivePosLookup(\n\tfont: Font,\n\tbuffer: GlyphBuffer,\n\tlookup: CursivePosLookup,\n): void {\n\t// Cursive attachment - connect exit anchor of one glyph to entry anchor of next\n\tfor (let i = 0; i < buffer.infos.length - 1; i++) {\n\t\tconst info1 = buffer.infos[i];\n\t\tif (!info1) continue;\n\t\tif (shouldSkipGlyph(font, info1.glyphId, lookup.flag)) continue;\n\n\t\t// Find next non-skipped glyph\n\t\tlet j = i + 1;\n\t\twhile (j < buffer.infos.length) {\n\t\t\tconst nextInfo = buffer.infos[j];\n\t\t\tif (nextInfo && !shouldSkipGlyph(font, nextInfo.glyphId, lookup.flag)) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tj++;\n\t\t}\n\t\tif (j >= buffer.infos.length) break;\n\n\t\tconst info2 = buffer.infos[j];\n\t\tif (!info2) continue;\n\n\t\tfor (const subtable of lookup.subtables) {\n\t\t\tconst exitIndex = subtable.coverage.get(info1.glyphId);\n\t\t\tconst entryIndex = subtable.coverage.get(info2.glyphId);\n\n\t\t\tif (exitIndex === null || entryIndex === null) continue;\n\n\t\t\tconst exitRecord = subtable.entryExitRecords[exitIndex];\n\t\t\tconst entryRecord = subtable.entryExitRecords[entryIndex];\n\n\t\t\tif (!exitRecord?.exitAnchor || !entryRecord?.entryAnchor) continue;\n\n\t\t\t// Calculate offset to align anchors\n\t\t\tconst exitAnchor = exitRecord.exitAnchor;\n\t\t\tconst entryAnchor = entryRecord.entryAnchor;\n\n\t\t\t// Adjust position of second glyph\n\t\t\tconst pos2 = buffer.positions[j];\n\t\t\tif (pos2) {\n\t\t\t\tpos2.yOffset = exitAnchor.yCoordinate - entryAnchor.yCoordinate;\n\t\t\t}\n\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\nfunction applyMarkBasePosLookup(\n\tfont: Font,\n\tbuffer: GlyphBuffer,\n\tlookup: MarkBasePosLookup,\n): void {\n\tfor (let i = 0; i < buffer.infos.length; i++) {\n\t\tconst markInfo = buffer.infos[i];\n\t\tif (!markInfo) continue;\n\n\t\t// Must be a mark glyph\n\t\tif (getGlyphClass(font.gdef, markInfo.glyphId) !== GlyphClass.Mark)\n\t\t\tcontinue;\n\n\t\t// Find preceding base glyph\n\t\tlet baseIndex = -1;\n\t\tfor (let j = i - 1; j >= 0; j--) {\n\t\t\tconst prevInfo = buffer.infos[j];\n\t\t\tif (!prevInfo) continue;\n\t\t\tconst prevClass = getGlyphClass(font.gdef, prevInfo.glyphId);\n\t\t\tif (prevClass === GlyphClass.Base || prevClass === 0) {\n\t\t\t\tbaseIndex = j;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\t// Skip marks\n\t\t\tif (prevClass === GlyphClass.Mark) continue;\n\t\t\t// Stop at ligature\n\t\t\tif (prevClass === GlyphClass.Ligature) {\n\t\t\t\tbaseIndex = j;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (baseIndex < 0) continue;\n\t\tconst baseInfo = buffer.infos[baseIndex];\n\t\tif (!baseInfo) continue;\n\n\t\tfor (const subtable of lookup.subtables) {\n\t\t\tconst markCoverageIndex = subtable.markCoverage.get(markInfo.glyphId);\n\t\t\tconst baseCoverageIndex = subtable.baseCoverage.get(baseInfo.glyphId);\n\n\t\t\tif (markCoverageIndex === null || baseCoverageIndex === null) continue;\n\n\t\t\tconst markRecord = subtable.markArray.markRecords[markCoverageIndex];\n\t\t\tconst baseRecord = subtable.baseArray[baseCoverageIndex];\n\n\t\t\tif (!markRecord || !baseRecord) continue;\n\n\t\t\tconst baseAnchor = baseRecord.baseAnchors[markRecord.markClass];\n\t\t\tif (!baseAnchor) continue;\n\n\t\t\tconst markAnchor = markRecord.markAnchor;\n\n\t\t\t// Position mark relative to base\n\t\t\tconst markPos = buffer.positions[i];\n\t\t\tconst basePos = buffer.positions[baseIndex];\n\t\t\tif (!markPos || !basePos) continue;\n\n\t\t\tmarkPos.xOffset =\n\t\t\t\tbaseAnchor.xCoordinate - markAnchor.xCoordinate + basePos.xOffset;\n\t\t\tmarkPos.yOffset =\n\t\t\t\tbaseAnchor.yCoordinate - markAnchor.yCoordinate + basePos.yOffset;\n\n\t\t\t// Mark doesn't advance cursor\n\t\t\tmarkPos.xAdvance = 0;\n\t\t\tmarkPos.yAdvance = 0;\n\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\nfunction applyMarkLigaturePosLookup(\n\tfont: Font,\n\tbuffer: GlyphBuffer,\n\tlookup: MarkLigaturePosLookup,\n): void {\n\tfor (let i = 0; i < buffer.infos.length; i++) {\n\t\tconst markInfo = buffer.infos[i];\n\t\tif (!markInfo) continue;\n\n\t\tif (getGlyphClass(font.gdef, markInfo.glyphId) !== GlyphClass.Mark)\n\t\t\tcontinue;\n\n\t\t// Find preceding ligature\n\t\tlet ligIndex = -1;\n\t\tlet componentIndex = 0; // Which component of the ligature\n\n\t\tfor (let j = i - 1; j >= 0; j--) {\n\t\t\tconst prevInfo = buffer.infos[j];\n\t\t\tif (!prevInfo) continue;\n\t\t\tconst prevClass = getGlyphClass(font.gdef, prevInfo.glyphId);\n\t\t\tif (prevClass === GlyphClass.Ligature) {\n\t\t\t\tligIndex = j;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (prevClass === GlyphClass.Mark) {\n\t\t\t\tcomponentIndex++;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tif (ligIndex < 0) continue;\n\t\tconst ligInfo = buffer.infos[ligIndex];\n\t\tif (!ligInfo) continue;\n\n\t\tfor (const subtable of lookup.subtables) {\n\t\t\tconst markCoverageIndex = subtable.markCoverage.get(markInfo.glyphId);\n\t\t\tconst ligCoverageIndex = subtable.ligatureCoverage.get(ligInfo.glyphId);\n\n\t\t\tif (markCoverageIndex === null || ligCoverageIndex === null) continue;\n\n\t\t\tconst markRecord = subtable.markArray.markRecords[markCoverageIndex];\n\t\t\tconst ligAttach = subtable.ligatureArray[ligCoverageIndex];\n\n\t\t\tif (!markRecord || !ligAttach) continue;\n\n\t\t\t// Clamp component index\n\t\t\tconst compIdx = Math.min(\n\t\t\t\tcomponentIndex,\n\t\t\t\tligAttach.componentRecords.length - 1,\n\t\t\t);\n\t\t\tconst component = ligAttach.componentRecords[compIdx];\n\t\t\tif (!component) continue;\n\n\t\t\tconst ligAnchor = component.ligatureAnchors[markRecord.markClass];\n\t\t\tif (!ligAnchor) continue;\n\n\t\t\tconst markAnchor = markRecord.markAnchor;\n\t\t\tconst markPos = buffer.positions[i];\n\t\t\tconst ligPos = buffer.positions[ligIndex];\n\t\t\tif (!markPos || !ligPos) continue;\n\n\t\t\tmarkPos.xOffset =\n\t\t\t\tligAnchor.xCoordinate - markAnchor.xCoordinate + ligPos.xOffset;\n\t\t\tmarkPos.yOffset =\n\t\t\t\tligAnchor.yCoordinate - markAnchor.yCoordinate + ligPos.yOffset;\n\t\t\tmarkPos.xAdvance = 0;\n\t\t\tmarkPos.yAdvance = 0;\n\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\nfunction applyMarkMarkPosLookup(\n\tfont: Font,\n\tbuffer: GlyphBuffer,\n\tlookup: MarkMarkPosLookup,\n): void {\n\tfor (let i = 0; i < buffer.infos.length; i++) {\n\t\tconst mark1Info = buffer.infos[i];\n\t\tif (!mark1Info) continue;\n\n\t\tif (getGlyphClass(font.gdef, mark1Info.glyphId) !== GlyphClass.Mark)\n\t\t\tcontinue;\n\n\t\t// Find preceding mark (mark2) - must be immediately preceding\n\t\tlet mark2Index = -1;\n\t\tif (i > 0) {\n\t\t\tconst prevInfo = buffer.infos[i - 1];\n\t\t\tif (prevInfo) {\n\t\t\t\tconst prevClass = getGlyphClass(font.gdef, prevInfo.glyphId);\n\t\t\t\tif (prevClass === GlyphClass.Mark) {\n\t\t\t\t\tmark2Index = i - 1;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (mark2Index < 0) continue;\n\t\tconst mark2Info = buffer.infos[mark2Index];\n\t\tif (!mark2Info) continue;\n\n\t\tfor (const subtable of lookup.subtables) {\n\t\t\tconst mark1CoverageIndex = subtable.mark1Coverage.get(mark1Info.glyphId);\n\t\t\tconst mark2CoverageIndex = subtable.mark2Coverage.get(mark2Info.glyphId);\n\n\t\t\tif (mark1CoverageIndex === null || mark2CoverageIndex === null) continue;\n\n\t\t\tconst mark1Record = subtable.mark1Array.markRecords[mark1CoverageIndex];\n\t\t\tconst mark2Record = subtable.mark2Array[mark2CoverageIndex];\n\n\t\t\tif (!mark1Record || !mark2Record) continue;\n\n\t\t\tconst mark2Anchor = mark2Record.mark2Anchors[mark1Record.markClass];\n\t\t\tif (!mark2Anchor) continue;\n\n\t\t\tconst mark1Anchor = mark1Record.markAnchor;\n\t\t\tconst mark1Pos = buffer.positions[i];\n\t\t\tconst mark2Pos = buffer.positions[mark2Index];\n\t\t\tif (!mark1Pos || !mark2Pos) continue;\n\n\t\t\tmark1Pos.xOffset =\n\t\t\t\tmark2Anchor.xCoordinate - mark1Anchor.xCoordinate + mark2Pos.xOffset;\n\t\t\tmark1Pos.yOffset =\n\t\t\t\tmark2Anchor.yCoordinate - mark1Anchor.yCoordinate + mark2Pos.yOffset;\n\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\n// GPOS Context positioning\n\nfunction applyContextPosLookup(\n\tfont: Font,\n\tbuffer: GlyphBuffer,\n\tlookup: ContextPosLookup,\n\tplan: ShapePlan,\n): void {\n\tfor (let i = 0; i < buffer.infos.length; i++) {\n\t\tconst info = buffer.infos[i];\n\t\tif (!info) continue;\n\t\tif (shouldSkipGlyph(font, info.glyphId, lookup.flag)) continue;\n\n\t\tfor (const subtable of lookup.subtables) {\n\t\t\tlet matched = false;\n\t\t\tlet lookupRecords: PosLookupRecord[] = [];\n\n\t\t\tif (subtable.format === 1) {\n\t\t\t\tconst result = matchContextPosFormat1(\n\t\t\t\t\tfont,\n\t\t\t\t\tbuffer,\n\t\t\t\t\ti,\n\t\t\t\t\tsubtable,\n\t\t\t\t\tlookup.flag,\n\t\t\t\t);\n\t\t\t\tif (result) {\n\t\t\t\t\tmatched = true;\n\t\t\t\t\tlookupRecords = result;\n\t\t\t\t}\n\t\t\t} else if (subtable.format === 2) {\n\t\t\t\tconst result = matchContextPosFormat2(\n\t\t\t\t\tfont,\n\t\t\t\t\tbuffer,\n\t\t\t\t\ti,\n\t\t\t\t\tsubtable,\n\t\t\t\t\tlookup.flag,\n\t\t\t\t);\n\t\t\t\tif (result) {\n\t\t\t\t\tmatched = true;\n\t\t\t\t\tlookupRecords = result;\n\t\t\t\t}\n\t\t\t} else if (subtable.format === 3) {\n\t\t\t\tif (matchContextPosFormat3(font, buffer, i, subtable, lookup.flag)) {\n\t\t\t\t\tmatched = true;\n\t\t\t\t\tlookupRecords = subtable.lookupRecords;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (matched) {\n\t\t\t\tapplyNestedPosLookups(font, buffer, i, lookupRecords, plan);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction applyChainingContextPosLookup(\n\tfont: Font,\n\tbuffer: GlyphBuffer,\n\tlookup: ChainingContextPosLookup,\n\tplan: ShapePlan,\n): void {\n\tfor (let i = 0; i < buffer.infos.length; i++) {\n\t\tconst info = buffer.infos[i];\n\t\tif (!info) continue;\n\t\tif (shouldSkipGlyph(font, info.glyphId, lookup.flag)) continue;\n\n\t\tfor (const subtable of lookup.subtables) {\n\t\t\tlet matched = false;\n\t\t\tlet lookupRecords: PosLookupRecord[] = [];\n\n\t\t\tif (subtable.format === 1) {\n\t\t\t\tconst result = matchChainingContextPosFormat1(\n\t\t\t\t\tfont,\n\t\t\t\t\tbuffer,\n\t\t\t\t\ti,\n\t\t\t\t\tsubtable,\n\t\t\t\t\tlookup.flag,\n\t\t\t\t);\n\t\t\t\tif (result) {\n\t\t\t\t\tmatched = true;\n\t\t\t\t\tlookupRecords = result;\n\t\t\t\t}\n\t\t\t} else if (subtable.format === 2) {\n\t\t\t\tconst result = matchChainingContextPosFormat2(\n\t\t\t\t\tfont,\n\t\t\t\t\tbuffer,\n\t\t\t\t\ti,\n\t\t\t\t\tsubtable,\n\t\t\t\t\tlookup.flag,\n\t\t\t\t);\n\t\t\t\tif (result) {\n\t\t\t\t\tmatched = true;\n\t\t\t\t\tlookupRecords = result;\n\t\t\t\t}\n\t\t\t} else if (subtable.format === 3) {\n\t\t\t\tif (\n\t\t\t\t\tmatchChainingContextPosFormat3(font, buffer, i, subtable, lookup.flag)\n\t\t\t\t) {\n\t\t\t\t\tmatched = true;\n\t\t\t\t\tlookupRecords = subtable.lookupRecords;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (matched) {\n\t\t\t\tapplyNestedPosLookups(font, buffer, i, lookupRecords, plan);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n}\n\n/** Match Context Pos Format 1 - glyph-based rules */\nfunction matchContextPosFormat1(\n\tfont: Font,\n\tbuffer: GlyphBuffer,\n\tstartIndex: number,\n\tsubtable: ContextPosFormat1,\n\tlookupFlag: number,\n): PosLookupRecord[] | null {\n\tconst firstGlyph = buffer.infos[startIndex]?.glyphId;\n\tconst coverageIndex = subtable.coverage.get(firstGlyph);\n\tif (coverageIndex === null) return null;\n\n\tconst ruleSet = subtable.ruleSets[coverageIndex];\n\tif (!ruleSet) return null;\n\n\tfor (const rule of ruleSet) {\n\t\tif (\n\t\t\tmatchGlyphSequence(\n\t\t\t\tfont,\n\t\t\t\tbuffer,\n\t\t\t\tstartIndex + 1,\n\t\t\t\trule.inputSequence,\n\t\t\t\tlookupFlag,\n\t\t\t)\n\t\t) {\n\t\t\treturn rule.lookupRecords;\n\t\t}\n\t}\n\treturn null;\n}\n\n/** Match Context Pos Format 2 - class-based rules */\nfunction matchContextPosFormat2(\n\tfont: Font,\n\tbuffer: GlyphBuffer,\n\tstartIndex: number,\n\tsubtable: ContextPosFormat2,\n\tlookupFlag: number,\n): PosLookupRecord[] | null {\n\tconst firstGlyph = buffer.infos[startIndex]?.glyphId;\n\tconst coverageIndex = subtable.coverage.get(firstGlyph);\n\tif (coverageIndex === null) return null;\n\n\tconst firstClass = subtable.classDef.get(firstGlyph);\n\tconst classRuleSet = subtable.classRuleSets[firstClass];\n\tif (!classRuleSet) return null;\n\n\tfor (const rule of classRuleSet) {\n\t\tif (\n\t\t\tmatchClassSequence(\n\t\t\t\tfont,\n\t\t\t\tbuffer,\n\t\t\t\tstartIndex + 1,\n\t\t\t\trule.inputClasses,\n\t\t\t\tsubtable.classDef,\n\t\t\t\tlookupFlag,\n\t\t\t)\n\t\t) {\n\t\t\treturn rule.lookupRecords;\n\t\t}\n\t}\n\treturn null;\n}\n\n/** Match Context Pos Format 3 - coverage-based */\nfunction matchContextPosFormat3(\n\tfont: Font,\n\tbuffer: GlyphBuffer,\n\tstartIndex: number,\n\tsubtable: ContextPosFormat3,\n\tlookupFlag: number,\n): boolean {\n\tlet pos = startIndex;\n\tfor (const coverage of subtable.coverages) {\n\t\twhile (\n\t\t\tpos < buffer.infos.length &&\n\t\t\tshouldSkipGlyph(font, buffer.infos[pos]?.glyphId, lookupFlag)\n\t\t) {\n\t\t\tpos++;\n\t\t}\n\t\tif (pos >= buffer.infos.length) return false;\n\t\tif (coverage.get(buffer.infos[pos]?.glyphId) === null) return false;\n\t\tpos++;\n\t}\n\treturn true;\n}\n\n/** Match Chaining Context Pos Format 1 - glyph-based rules */\nfunction matchChainingContextPosFormat1(\n\tfont: Font,\n\tbuffer: GlyphBuffer,\n\tstartIndex: number,\n\tsubtable: ChainingContextPosFormat1,\n\tlookupFlag: number,\n): PosLookupRecord[] | null {\n\tconst firstGlyph = buffer.infos[startIndex]?.glyphId;\n\tconst coverageIndex = subtable.coverage.get(firstGlyph);\n\tif (coverageIndex === null) return null;\n\n\tconst chainRuleSet = subtable.chainRuleSets[coverageIndex];\n\tif (!chainRuleSet) return null;\n\n\tfor (const rule of chainRuleSet) {\n\t\t// Check backtrack (reversed order, before startIndex)\n\t\tif (\n\t\t\t!matchGlyphSequenceBackward(\n\t\t\t\tfont,\n\t\t\t\tbuffer,\n\t\t\t\tstartIndex - 1,\n\t\t\t\trule.backtrackSequence,\n\t\t\t\tlookupFlag,\n\t\t\t)\n\t\t) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Check input (excluding first glyph which is in coverage)\n\t\tif (\n\t\t\t!matchGlyphSequence(\n\t\t\t\tfont,\n\t\t\t\tbuffer,\n\t\t\t\tstartIndex + 1,\n\t\t\t\trule.inputSequence,\n\t\t\t\tlookupFlag,\n\t\t\t)\n\t\t) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Find where input sequence ends\n\t\tlet inputEnd = startIndex + 1;\n\t\tfor (let i = 0; i < rule.inputSequence.length; i++) {\n\t\t\twhile (\n\t\t\t\tinputEnd < buffer.infos.length &&\n\t\t\t\tshouldSkipGlyph(font, buffer.infos[inputEnd]?.glyphId, lookupFlag)\n\t\t\t) {\n\t\t\t\tinputEnd++;\n\t\t\t}\n\t\t\tinputEnd++;\n\t\t}\n\n\t\t// Check lookahead\n\t\tif (\n\t\t\t!matchGlyphSequence(\n\t\t\t\tfont,\n\t\t\t\tbuffer,\n\t\t\t\tinputEnd,\n\t\t\t\trule.lookaheadSequence,\n\t\t\t\tlookupFlag,\n\t\t\t)\n\t\t) {\n\t\t\tcontinue;\n\t\t}\n\n\t\treturn rule.lookupRecords;\n\t}\n\treturn null;\n}\n\n/** Match Chaining Context Pos Format 2 - class-based rules */\nfunction matchChainingContextPosFormat2(\n\tfont: Font,\n\tbuffer: GlyphBuffer,\n\tstartIndex: number,\n\tsubtable: ChainingContextPosFormat2,\n\tlookupFlag: number,\n): PosLookupRecord[] | null {\n\tconst firstGlyph = buffer.infos[startIndex]?.glyphId;\n\tconst coverageIndex = subtable.coverage.get(firstGlyph);\n\tif (coverageIndex === null) return null;\n\n\tconst firstClass = subtable.inputClassDef.get(firstGlyph);\n\tconst chainClassRuleSet = subtable.chainClassRuleSets[firstClass];\n\tif (!chainClassRuleSet) return null;\n\n\tfor (const rule of chainClassRuleSet) {\n\t\t// Check backtrack classes (reversed order)\n\t\tif (\n\t\t\t!matchClassSequenceBackward(\n\t\t\t\tfont,\n\t\t\t\tbuffer,\n\t\t\t\tstartIndex - 1,\n\t\t\t\trule.backtrackClasses,\n\t\t\t\tsubtable.backtrackClassDef,\n\t\t\t\tlookupFlag,\n\t\t\t)\n\t\t) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Check input classes (excluding first)\n\t\tif (\n\t\t\t!matchClassSequence(\n\t\t\t\tfont,\n\t\t\t\tbuffer,\n\t\t\t\tstartIndex + 1,\n\t\t\t\trule.inputClasses,\n\t\t\t\tsubtable.inputClassDef,\n\t\t\t\tlookupFlag,\n\t\t\t)\n\t\t) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Find where input ends\n\t\tlet inputEnd = startIndex + 1;\n\t\tfor (let i = 0; i < rule.inputClasses.length; i++) {\n\t\t\twhile (\n\t\t\t\tinputEnd < buffer.infos.length &&\n\t\t\t\tshouldSkipGlyph(font, buffer.infos[inputEnd]?.glyphId, lookupFlag)\n\t\t\t) {\n\t\t\t\tinputEnd++;\n\t\t\t}\n\t\t\tinputEnd++;\n\t\t}\n\n\t\t// Check lookahead classes\n\t\tif (\n\t\t\t!matchClassSequence(\n\t\t\t\tfont,\n\t\t\t\tbuffer,\n\t\t\t\tinputEnd,\n\t\t\t\trule.lookaheadClasses,\n\t\t\t\tsubtable.lookaheadClassDef,\n\t\t\t\tlookupFlag,\n\t\t\t)\n\t\t) {\n\t\t\tcontinue;\n\t\t}\n\n\t\treturn rule.lookupRecords;\n\t}\n\treturn null;\n}\n\n/** Match Chaining Context Pos Format 3 - coverage-based */\nfunction matchChainingContextPosFormat3(\n\tfont: Font,\n\tbuffer: GlyphBuffer,\n\tstartIndex: number,\n\tsubtable: ChainingContextPosFormat3,\n\tlookupFlag: number,\n): boolean {\n\t// Check backtrack (in reverse order, before startIndex)\n\tlet backtrackPos = startIndex - 1;\n\tfor (const coverage of subtable.backtrackCoverages) {\n\t\twhile (\n\t\t\tbacktrackPos >= 0 &&\n\t\t\tshouldSkipGlyph(font, buffer.infos[backtrackPos]?.glyphId, lookupFlag)\n\t\t) {\n\t\t\tbacktrackPos--;\n\t\t}\n\t\tif (backtrackPos < 0) return false;\n\t\tif (coverage.get(buffer.infos[backtrackPos]?.glyphId) === null)\n\t\t\treturn false;\n\t\tbacktrackPos--;\n\t}\n\n\t// Check input sequence\n\tlet inputPos = startIndex;\n\tfor (const coverage of subtable.inputCoverages) {\n\t\twhile (\n\t\t\tinputPos < buffer.infos.length &&\n\t\t\tshouldSkipGlyph(font, buffer.infos[inputPos]?.glyphId, lookupFlag)\n\t\t) {\n\t\t\tinputPos++;\n\t\t}\n\t\tif (inputPos >= buffer.infos.length) return false;\n\t\tif (coverage.get(buffer.infos[inputPos]?.glyphId) === null) return false;\n\t\tinputPos++;\n\t}\n\n\t// Check lookahead\n\tlet lookaheadPos = inputPos;\n\tfor (const coverage of subtable.lookaheadCoverages) {\n\t\twhile (\n\t\t\tlookaheadPos < buffer.infos.length &&\n\t\t\tshouldSkipGlyph(font, buffer.infos[lookaheadPos]?.glyphId, lookupFlag)\n\t\t) {\n\t\t\tlookaheadPos++;\n\t\t}\n\t\tif (lookaheadPos >= buffer.infos.length) return false;\n\t\tif (coverage.get(buffer.infos[lookaheadPos]?.glyphId) === null)\n\t\t\treturn false;\n\t\tlookaheadPos++;\n\t}\n\n\treturn true;\n}\n\n/** Apply nested positioning lookups at specific positions */\nfunction applyNestedPosLookups(\n\tfont: Font,\n\tbuffer: GlyphBuffer,\n\tstartIndex: number,\n\tlookupRecords: PosLookupRecord[],\n\tplan: ShapePlan,\n): void {\n\t// Sort by sequence index descending to apply from end to start\n\tconst sorted = [...lookupRecords].sort(\n\t\t(a, b) => b.sequenceIndex - a.sequenceIndex,\n\t);\n\n\tfor (const record of sorted) {\n\t\tconst lookupEntry = plan.gposLookups.find(\n\t\t\t(l) => l.index === record.lookupListIndex,\n\t\t);\n\t\tif (!lookupEntry) continue;\n\n\t\t// Apply at the specific position\n\t\tconst pos = startIndex + record.sequenceIndex;\n\t\tif (pos >= buffer.infos.length) continue;\n\n\t\t// Apply the lookup directly\n\t\tapplyGposLookup(font, buffer, lookupEntry.lookup, plan);\n\t}\n}\n\n// Sequence matching helpers\n\n/** Match a sequence of specific glyphs forward */\nfunction matchGlyphSequence(\n\tfont: Font,\n\tbuffer: GlyphBuffer,\n\tstartPos: number,\n\tglyphs: GlyphId[],\n\tlookupFlag: number,\n): boolean {\n\tlet pos = startPos;\n\tfor (const glyph of glyphs) {\n\t\twhile (\n\t\t\tpos < buffer.infos.length &&\n\t\t\tshouldSkipGlyph(font, buffer.infos[pos]?.glyphId, lookupFlag)\n\t\t) {\n\t\t\tpos++;\n\t\t}\n\t\tif (pos >= buffer.infos.length) return false;\n\t\tif (buffer.infos[pos]?.glyphId !== glyph) return false;\n\t\tpos++;\n\t}\n\treturn true;\n}\n\n/** Match a sequence of specific glyphs backward */\nfunction matchGlyphSequenceBackward(\n\tfont: Font,\n\tbuffer: GlyphBuffer,\n\tstartPos: number,\n\tglyphs: GlyphId[],\n\tlookupFlag: number,\n): boolean {\n\tlet pos = startPos;\n\tfor (const glyph of glyphs) {\n\t\twhile (\n\t\t\tpos >= 0 &&\n\t\t\tshouldSkipGlyph(font, buffer.infos[pos]?.glyphId, lookupFlag)\n\t\t) {\n\t\t\tpos--;\n\t\t}\n\t\tif (pos < 0) return false;\n\t\tif (buffer.infos[pos]?.glyphId !== glyph) return false;\n\t\tpos--;\n\t}\n\treturn true;\n}\n\n/** Match a sequence of classes forward */\nfunction matchClassSequence(\n\tfont: Font,\n\tbuffer: GlyphBuffer,\n\tstartPos: number,\n\tclasses: number[],\n\tclassDef: ClassDef,\n\tlookupFlag: number,\n): boolean {\n\tlet pos = startPos;\n\tfor (const cls of classes) {\n\t\twhile (\n\t\t\tpos < buffer.infos.length &&\n\t\t\tshouldSkipGlyph(font, buffer.infos[pos]?.glyphId, lookupFlag)\n\t\t) {\n\t\t\tpos++;\n\t\t}\n\t\tif (pos >= buffer.infos.length) return false;\n\t\tif (classDef.get(buffer.infos[pos]?.glyphId) !== cls) return false;\n\t\tpos++;\n\t}\n\treturn true;\n}\n\n/** Match a sequence of classes backward */\nfunction matchClassSequenceBackward(\n\tfont: Font,\n\tbuffer: GlyphBuffer,\n\tstartPos: number,\n\tclasses: number[],\n\tclassDef: ClassDef,\n\tlookupFlag: number,\n): boolean {\n\tlet pos = startPos;\n\tfor (const cls of classes) {\n\t\twhile (\n\t\t\tpos >= 0 &&\n\t\t\tshouldSkipGlyph(font, buffer.infos[pos]?.glyphId, lookupFlag)\n\t\t) {\n\t\t\tpos--;\n\t\t}\n\t\tif (pos < 0) return false;\n\t\tif (classDef.get(buffer.infos[pos]?.glyphId) !== cls) return false;\n\t\tpos--;\n\t}\n\treturn true;\n}\n\n// Utility\n\nfunction shouldSkipGlyph(\n\tfont: Font,\n\tglyphId: GlyphId,\n\tlookupFlag: number,\n): boolean {\n\tconst gdef = font.gdef;\n\tif (!gdef) return false;\n\n\tconst glyphClass = getGlyphClass(gdef, glyphId);\n\n\tif (\n\t\tlookupFlag & LookupFlag.IgnoreBaseGlyphs &&\n\t\tglyphClass === GlyphClass.Base\n\t)\n\t\treturn true;\n\tif (\n\t\tlookupFlag & LookupFlag.IgnoreLigatures &&\n\t\tglyphClass === GlyphClass.Ligature\n\t)\n\t\treturn true;\n\tif (lookupFlag & LookupFlag.IgnoreMarks && glyphClass === GlyphClass.Mark)\n\t\treturn true;\n\n\tconst markAttachmentType = getMarkAttachmentType(lookupFlag);\n\tif (markAttachmentType !== 0 && glyphClass === GlyphClass.Mark) {\n\t\tconst glyphMarkClass = gdef.markAttachClassDef.get(glyphId);\n\t\tif (glyphMarkClass !== markAttachmentType) return true;\n\t}\n\n\treturn false;\n}\n\n// AAT morx substitution\n\nfunction applyMorx(font: Font, buffer: GlyphBuffer): void {\n\tconst morx = font.morx;\n\tif (!morx) return;\n\n\tfor (const chain of morx.chains) {\n\t\tfor (const subtable of chain.subtables) {\n\t\t\t// Apply if subFeatureFlags match (default: all enabled)\n\t\t\tif ((chain.defaultFlags & subtable.subFeatureFlags) === 0) continue;\n\n\t\t\tswitch (subtable.type) {\n\t\t\t\tcase MorxSubtableType.NonContextual:\n\t\t\t\t\t// Simple substitution (Type 4)\n\t\t\t\t\tfor (const info of buffer.infos) {\n\t\t\t\t\t\tconst replacement = applyNonContextual(\n\t\t\t\t\t\t\tsubtable as MorxNonContextualSubtable,\n\t\t\t\t\t\t\tinfo.glyphId,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tif (replacement !== null) {\n\t\t\t\t\t\t\tinfo.glyphId = replacement;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase MorxSubtableType.Rearrangement:\n\t\t\t\t\t// Rearrangement (Type 0) - reorder glyphs\n\t\t\t\t\tprocessRearrangement(\n\t\t\t\t\t\tsubtable as MorxRearrangementSubtable,\n\t\t\t\t\t\tbuffer.infos,\n\t\t\t\t\t);\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase MorxSubtableType.Contextual:\n\t\t\t\t\t// Contextual substitution (Type 1)\n\t\t\t\t\tprocessContextual(subtable as MorxContextualSubtable, buffer.infos);\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase MorxSubtableType.Ligature: {\n\t\t\t\t\t// Ligature (Type 2)\n\t\t\t\t\tconst newInfos = processLigature(\n\t\t\t\t\t\tsubtable as MorxLigatureSubtable,\n\t\t\t\t\t\tbuffer.infos,\n\t\t\t\t\t);\n\t\t\t\t\t// Update buffer with new infos (may be shorter due to ligatures)\n\t\t\t\t\tif (newInfos.length !== buffer.infos.length) {\n\t\t\t\t\t\tbuffer.initFromInfos(newInfos);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tcase MorxSubtableType.Insertion: {\n\t\t\t\t\t// Insertion (Type 5)\n\t\t\t\t\tconst newInfos = processInsertion(\n\t\t\t\t\t\tsubtable as MorxInsertionSubtable,\n\t\t\t\t\t\tbuffer.infos,\n\t\t\t\t\t);\n\t\t\t\t\t// Update buffer with new infos (may be longer due to insertions)\n\t\t\t\t\tif (newInfos.length !== buffer.infos.length) {\n\t\t\t\t\t\tbuffer.initFromInfos(newInfos);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n",
99
- "// Bidi character types data, auto generated\nexport default {\n\tR: \"13k,1a,2,3,3,2+1j,ch+16,a+1,5+2,2+n,5,a,4,6+16,4+3,h+1b,4mo,179q,2+9,2+11,2i9+7y,2+68,4,3+4,5+13,4+3,2+4k,3+29,8+cf,1t+7z,w+17,3+3m,1t+3z,16o1+5r,8+30,8+mc,29+1r,29+4v,75+73\",\n\tEN: \"1c+9,3d+1,6,187+9,513,4+5,7+9,sf+j,175h+9,qw+q,161f+1d,4xt+a,25i+9\",\n\tES: \"17,2,6dp+1,f+1,av,16vr,mx+1,4o,2\",\n\tET: \"z+2,3h+3,b+1,ym,3e+1,2o,p4+1,8,6u,7c,g6,1wc,1n9+4,30+1b,2n,6d,qhx+1,h0m,a+1,49+2,63+1,4+1,6bb+3,12jj\",\n\tAN: \"16o+5,2j+9,2+1,35,ed,1ff2+9,87+u\",\n\tCS: \"18,2+1,b,2u,12k,55v,l,17v0,2,3,53,2+1,b\",\n\tB: \"a,3,f+2,2v,690\",\n\tS: \"9,2,k\",\n\tWS: \"c,k,4f4,1vk+a,u,1j,335\",\n\tON: \"x+1,4+4,h+5,r+5,r+3,z,5+3,2+1,2+1,5,2+2,3+4,o,w,ci+1,8+d,3+d,6+8,2+g,39+1,9,6+1,2,33,b8,3+1,3c+1,7+1,5r,b,7h+3,sa+5,2,3i+6,jg+3,ur+9,2v,ij+1,9g+9,7+a,8m,4+1,49+x,14u,2+2,c+2,e+2,e+2,e+1,i+n,e+e,2+p,u+2,e+2,36+1,2+3,2+1,b,2+2,6+5,2,2,2,h+1,5+4,6+3,3+f,16+2,5+3l,3+81,1y+p,2+40,q+a,m+13,2r+ch,2+9e,75+hf,3+v,2+2w,6e+5,f+6,75+2a,1a+p,2+2g,d+5x,r+b,6+3,4+o,g,6+1,6+2,2k+1,4,2j,5h+z,1m+1,1e+f,t+2,1f+e,d+3,4o+3,2s+1,w,535+1r,h3l+1i,93+2,2s,b+1,3l+x,2v,4g+3,21+3,kz+1,g5v+1,5a,j+9,n+v,2,3,2+8,2+1,3+2,2,3,46+1,4+4,h+5,r+5,r+a,3h+2,4+6,b+4,78,1r+24,4+c,4,1hb,ey+6,103+j,16j+c,1ux+7,5+g,fsh,jdq+1t,4,57+2e,p1,1m,1m,1m,1m,4kt+1,7j+17,5+2r,d+e,3+e,2+e,2+10,m+4,w,1n+5,1q,4z+5,4b+rb,9+c,4+c,4+37,d+2g,8+b,l+b,5+1j,9+9,7+13,9+t,3+1,27+3c,2+29,2+3q,d+d,3+4,4+2,6+6,a+o,8+6,a+2,e+6,16+42,2+1i\",\n\tBN: \"0+8,6+d,2s+5,2+p,e,4m9,1kt+2,2b+5,5+5,17q9+v,7k,6p+8,6+1,119d+3,440+7,96s+1,1ekf+1,1ekf+1,1ekf+1,1ekf+1,1ekf+1,1ekf+1,1ekf+1,1ekf+1,1ekf+1,1ekf+1,1ekf+1,1ekf+75,6p+2rz,1ben+1,1ekf+1,1ekf+1\",\n\tNSM: \"lc+33,7o+6,7c+18,2,2+1,2+1,2,21+a,1d+k,h,2u+6,3+5,3+1,2+3,10,v+q,2k+a,1n+8,a,p+3,2+8,2+2,2+4,18+2,3c+e,2+v,1k,2,5+7,5,4+6,b+1,u,1n,5+3,9,l+1,r,3+1,1m,5+1,5+1,3+2,4,v+1,4,c+1,1m,5+4,2+1,5,l+1,n+5,2,1n,3,2+3,9,8+1,c+1,v,1q,d,1f,4,1m+2,6+2,2+3,8+1,c+1,u,1n,g+1,l+1,t+1,1m+1,5+3,9,l+1,u,21,8+2,2,2j,3+6,d+7,2r,3+8,c+5,23+1,s,2,2,1k+d,2+4,2+1,6+a,2+z,a,2v+3,2+5,2+1,3+1,q+1,5+2,h+3,e,3+1,7,g,jk+2,qb+2,u+2,u+1,v+1,1t+1,2+6,9,3+a,a,1a+2,3c+1,z,3b+2,5+1,a,7+2,64+1,3,1n,2+6,2,2,3+7,7+9,3,1d+g,1s+3,1d,2+4,2,6,15+8,d+1,x+3,3+1,2+2,1l,2+1,4,2+2,1n+7,3+1,49+2,2+c,2+6,5,7,4+1,5j+1l,2+4,k1+w,2db+2,3y,2p+v,ff+3,30+1,n9x+3,2+9,x+1,29+1,7l,4,5,q+1,6,48+1,r+h,e,13+7,q+a,1b+2,1d,3+3,3+1,14,1w+5,3+1,3+1,d,9,1c,1g,2+2,3+1,6+1,2,17+1,9,6n,3,5,fn5,ki+f,h+f,r2,6b,46+4,1af+2,2+1,6+3,15+2,5,4m+1,fy+3,as+1,4a+a,4x,1j+e,1l+2,1e+3,3+1,1y+2,11+4,2+7,1r,d+1,1h+8,b+3,3,2o+2,3,2+1,7,4h,4+7,m+1,1m+1,4,12+6,4+4,5g+7,3+2,2,o,2d+5,2,5+1,2+1,6n+3,7+1,2+1,s+1,2e+7,3,2+1,2z,2,3+5,2,2u+2,3+3,2+4,78+8,2+1,75+1,2,5,41+3,3+1,5,x+5,3+1,15+5,3+3,9,a+5,3+2,1b+c,2+1,bb+6,2+5,2d+l,3+6,2+1,2+1,3f+5,4,2+1,2+6,2,21+1,4,2,9o+1,f0c+4,1o+6,t5,1s+3,2a,f5l+1,43t+2,i+7,3+6,v+3,45+2,1j0+1i,5+1d,9,f,n+4,2+e,11t+6,2+g,3+6,2+1,2+4,7a+6,c6+3,15t+6,32+6,gzhy+6n\",\n\tAL: \"16w,3,2,e+1b,z+2,2+2s,g+1,8+1,b+m,2+t,s+2i,c+e,4h+f,1d+1e,1bwe+dp,3+3z,x+c,2+1,35+3y,2rm+z,5+7,b+5,dt+l,c+u,17nl+27,1t+27,4x+6n,3+d\",\n\tLRO: \"6ct\",\n\tRLO: \"6cu\",\n\tLRE: \"6cq\",\n\tRLE: \"6cr\",\n\tPDF: \"6cs\",\n\tLRI: \"6ee\",\n\tRLI: \"6ef\",\n\tFSI: \"6eg\",\n\tPDI: \"6eh\",\n};\n",
100
- "/**\n * Bidi character type detection\n * Port of bidi-js charTypes.js\n */\n\nimport DATA from \"./char-types.gen.ts\";\n\nexport const TYPES: Record<string, number> = {};\nexport const TYPES_TO_NAMES: Record<number, string> = {};\nTYPES.L = 1; // L is the default\nTYPES_TO_NAMES[1] = \"L\";\n\nObject.keys(DATA).forEach((type, i) => {\n\tTYPES[type] = 1 << (i + 1);\n\tconst typeVal = TYPES[type];\n\tif (typeVal !== undefined) {\n\t\tTYPES_TO_NAMES[typeVal] = type;\n\t}\n});\n\nObject.freeze(TYPES);\n\n// Helper to get type value with fallback\nfunction getType(name: string): number {\n\treturn TYPES[name] ?? 0;\n}\n\nexport const ISOLATE_INIT_TYPES =\n\tgetType(\"LRI\") | getType(\"RLI\") | getType(\"FSI\");\nexport const STRONG_TYPES = getType(\"L\") | getType(\"R\") | getType(\"AL\");\nexport const NEUTRAL_ISOLATE_TYPES =\n\tgetType(\"B\") |\n\tgetType(\"S\") |\n\tgetType(\"WS\") |\n\tgetType(\"ON\") |\n\tgetType(\"FSI\") |\n\tgetType(\"LRI\") |\n\tgetType(\"RLI\") |\n\tgetType(\"PDI\");\nexport const BN_LIKE_TYPES =\n\tgetType(\"BN\") |\n\tgetType(\"RLE\") |\n\tgetType(\"LRE\") |\n\tgetType(\"RLO\") |\n\tgetType(\"LRO\") |\n\tgetType(\"PDF\");\nexport const TRAILING_TYPES =\n\tgetType(\"S\") |\n\tgetType(\"WS\") |\n\tgetType(\"B\") |\n\tISOLATE_INIT_TYPES |\n\tgetType(\"PDI\") |\n\tBN_LIKE_TYPES;\n\nlet map: Map<number, number> | null = null;\n\nfunction parseData(): void {\n\tif (!map) {\n\t\tmap = new Map();\n\t\tlet start = 0;\n\t\tfor (const type in DATA) {\n\t\t\tif (Object.hasOwn(DATA, type)) {\n\t\t\t\tconst segments = DATA[type as keyof typeof DATA];\n\t\t\t\tlet temp = \"\";\n\t\t\t\tlet end = 0;\n\t\t\t\tlet state = false;\n\t\t\t\tlet lastCode = 0; // Reset for each type - data is encoded relative to 0\n\t\t\t\tfor (let i = 0; i <= segments.length + 1; i += 1) {\n\t\t\t\t\tconst char = segments[i];\n\t\t\t\t\tif (char !== \",\" && i !== segments.length) {\n\t\t\t\t\t\tif (char === \"+\") {\n\t\t\t\t\t\t\tstate = true;\n\t\t\t\t\t\t\tlastCode = start = lastCode + parseInt(temp, 36);\n\t\t\t\t\t\t\ttemp = \"\";\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\ttemp += char;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (!state) {\n\t\t\t\t\t\t\tlastCode = start = lastCode + parseInt(temp, 36);\n\t\t\t\t\t\t\tend = start;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tend = start + parseInt(temp, 36);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tstate = false;\n\t\t\t\t\t\ttemp = \"\";\n\t\t\t\t\t\tlastCode = end;\n\t\t\t\t\t\tconst typeVal = getType(type);\n\t\t\t\t\t\tfor (let j = start; j < end + 1; j += 1) {\n\t\t\t\t\t\t\tmap.set(j, typeVal);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Get the bidi character type for a character\n */\nexport function getBidiCharType(char: string): number {\n\tparseData();\n\tconst codepoint = char.codePointAt(0);\n\tif (codepoint === undefined) return getType(\"L\");\n\treturn map?.get(codepoint) ?? getType(\"L\");\n}\n\n/**\n * Get the name of a bidi character type\n */\nexport function getBidiCharTypeName(char: string): string {\n\treturn TYPES_TO_NAMES[getBidiCharType(char)] ?? \"L\";\n}\n",
101
- "/**\n * Bidi embedding levels calculation (UAX #9)\n * Port of bidi-js embeddingLevels.js\n */\n\nimport {\n\tclosingToOpeningBracket,\n\tgetCanonicalBracket,\n\topeningToClosingBracket,\n} from \"./brackets.ts\";\nimport {\n\tBN_LIKE_TYPES,\n\tgetBidiCharType,\n\tISOLATE_INIT_TYPES,\n\tNEUTRAL_ISOLATE_TYPES,\n\tSTRONG_TYPES,\n\tTRAILING_TYPES,\n\tTYPES,\n} from \"./char-types.ts\";\n\n// Local type aliases\nconst TYPE_L = TYPES.L ?? 1;\nconst TYPE_R = TYPES.R ?? 2;\nconst TYPE_EN = TYPES.EN ?? 4;\nconst TYPE_ES = TYPES.ES ?? 8;\nconst TYPE_ET = TYPES.ET ?? 16;\nconst TYPE_AN = TYPES.AN ?? 32;\nconst TYPE_CS = TYPES.CS ?? 64;\nconst TYPE_B = TYPES.B ?? 128;\nconst TYPE_S = TYPES.S ?? 256;\nconst TYPE_ON = TYPES.ON ?? 512;\nconst TYPE_BN = TYPES.BN ?? 1024;\nconst TYPE_NSM = TYPES.NSM ?? 2048;\nconst TYPE_AL = TYPES.AL ?? 4096;\nconst TYPE_LRO = TYPES.LRO ?? 8192;\nconst TYPE_RLO = TYPES.RLO ?? 16384;\nconst TYPE_LRE = TYPES.LRE ?? 32768;\nconst TYPE_RLE = TYPES.RLE ?? 65536;\nconst TYPE_PDF = TYPES.PDF ?? 131072;\nconst TYPE_LRI = TYPES.LRI ?? 262144;\nconst TYPE_RLI = TYPES.RLI ?? 524288;\nconst TYPE_FSI = TYPES.FSI ?? 1048576;\nconst TYPE_PDI = TYPES.PDI ?? 2097152;\n\nexport interface EmbeddingLevelsResult {\n\tparagraphs: Array<{ start: number; end: number; level: number }>;\n\tlevels: Uint8Array;\n}\n\ninterface StatusStackEntry {\n\t_level: number;\n\t_override: number;\n\t_isolate: number;\n\t_isolInitIndex?: number;\n}\n\ninterface LevelRun {\n\t_start: number;\n\t_end: number;\n\t_level: number;\n\t_startsWithPDI: boolean;\n\t_endsWithIsolInit: boolean;\n}\n\ninterface IsolatingRunSeq {\n\t_seqIndices: number[];\n\t_sosType: number;\n\t_eosType: number;\n}\n\nfunction getCharType(charTypes: Uint32Array, i: number): number {\n\treturn charTypes[i] ?? 0;\n}\n\nfunction getSeqIndex(seqIndices: number[], i: number): number {\n\treturn seqIndices[i] ?? 0;\n}\n\nfunction getCharAt(s: string, i: number): string {\n\treturn s[i] ?? \"\";\n}\n\n/**\n * This function applies the Bidirectional Algorithm to a string, returning the resolved embedding levels\n * in a single Uint8Array plus a list of objects holding each paragraph's start and end indices and resolved\n * base embedding level.\n */\nexport function getEmbeddingLevels(\n\tstring: string,\n\tbaseDirection?: \"ltr\" | \"rtl\" | \"auto\",\n): EmbeddingLevelsResult {\n\tconst MAX_DEPTH = 125;\n\n\t// Start by mapping all characters to their unicode type, as a bitmask integer\n\tconst charTypes = new Uint32Array(string.length);\n\tfor (let i = 0; i < string.length; i++) {\n\t\tcharTypes[i] = getBidiCharType(getCharAt(string, i));\n\t}\n\n\tconst charTypeCounts = new Map<number, number>();\n\n\tfunction changeCharType(i: number, type: number): void {\n\t\tconst oldType = getCharType(charTypes, i);\n\t\tcharTypes[i] = type;\n\t\tcharTypeCounts.set(oldType, (charTypeCounts.get(oldType) ?? 0) - 1);\n\t\tif (oldType & NEUTRAL_ISOLATE_TYPES) {\n\t\t\tcharTypeCounts.set(\n\t\t\t\tNEUTRAL_ISOLATE_TYPES,\n\t\t\t\t(charTypeCounts.get(NEUTRAL_ISOLATE_TYPES) ?? 0) - 1,\n\t\t\t);\n\t\t}\n\t\tcharTypeCounts.set(type, (charTypeCounts.get(type) ?? 0) + 1);\n\t\tif (type & NEUTRAL_ISOLATE_TYPES) {\n\t\t\tcharTypeCounts.set(\n\t\t\t\tNEUTRAL_ISOLATE_TYPES,\n\t\t\t\t(charTypeCounts.get(NEUTRAL_ISOLATE_TYPES) ?? 0) + 1,\n\t\t\t);\n\t\t}\n\t}\n\n\tconst embedLevels = new Uint8Array(string.length);\n\tconst isolationPairs = new Map<number, number>();\n\n\tconst paragraphs: Array<{ start: number; end: number; level: number }> = [];\n\tlet paragraph: { start: number; end: number; level: number } | null = null;\n\n\tfunction determineAutoEmbedLevel(start: number, isFSI: boolean): number {\n\t\tfor (let i = start; i < string.length; i++) {\n\t\t\tconst charType = getCharType(charTypes, i);\n\t\t\tif (charType & (TYPE_R | TYPE_AL)) {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\tif (charType & (TYPE_B | TYPE_L) || (isFSI && charType === TYPE_PDI)) {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tif (charType & ISOLATE_INIT_TYPES) {\n\t\t\t\tconst pdi = indexOfMatchingPDI(i);\n\t\t\t\ti = pdi === -1 ? string.length : pdi;\n\t\t\t}\n\t\t}\n\t\treturn 0;\n\t}\n\n\tfunction indexOfMatchingPDI(isolateStart: number): number {\n\t\tlet isolationLevel = 1;\n\t\tfor (let i = isolateStart + 1; i < string.length; i++) {\n\t\t\tconst charType = getCharType(charTypes, i);\n\t\t\tif (charType & TYPE_B) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (charType & TYPE_PDI) {\n\t\t\t\tif (--isolationLevel === 0) {\n\t\t\t\t\treturn i;\n\t\t\t\t}\n\t\t\t} else if (charType & ISOLATE_INIT_TYPES) {\n\t\t\t\tisolationLevel++;\n\t\t\t}\n\t\t}\n\t\treturn -1;\n\t}\n\n\tfor (let i = 0; i < string.length; i++) {\n\t\tif (!paragraph) {\n\t\t\tparagraph = {\n\t\t\t\tstart: i,\n\t\t\t\tend: string.length - 1,\n\t\t\t\tlevel:\n\t\t\t\t\tbaseDirection === \"rtl\"\n\t\t\t\t\t\t? 1\n\t\t\t\t\t\t: baseDirection === \"ltr\"\n\t\t\t\t\t\t\t? 0\n\t\t\t\t\t\t\t: determineAutoEmbedLevel(i, false),\n\t\t\t};\n\t\t\tparagraphs.push(paragraph);\n\t\t}\n\t\tif (getCharType(charTypes, i) & TYPE_B) {\n\t\t\tparagraph.end = i;\n\t\t\tparagraph = null;\n\t\t}\n\t}\n\n\tconst FORMATTING_TYPES =\n\t\tTYPE_RLE |\n\t\tTYPE_LRE |\n\t\tTYPE_RLO |\n\t\tTYPE_LRO |\n\t\tISOLATE_INIT_TYPES |\n\t\tTYPE_PDI |\n\t\tTYPE_PDF |\n\t\tTYPE_B;\n\tconst nextEven = (n: number): number => n + (n & 1 ? 1 : 2);\n\tconst nextOdd = (n: number): number => n + (n & 1 ? 2 : 1);\n\n\tfor (let paraIdx = 0; paraIdx < paragraphs.length; paraIdx++) {\n\t\tconst para = paragraphs[paraIdx];\n\t\tif (!para) continue;\n\t\tparagraph = para;\n\n\t\tconst statusStack: StatusStackEntry[] = [\n\t\t\t{\n\t\t\t\t_level: paragraph.level,\n\t\t\t\t_override: 0,\n\t\t\t\t_isolate: 0,\n\t\t\t},\n\t\t];\n\n\t\tlet overflowIsolateCount = 0;\n\t\tlet overflowEmbeddingCount = 0;\n\t\tlet validIsolateCount = 0;\n\t\tcharTypeCounts.clear();\n\n\t\tfor (let i = paragraph.start; i <= paragraph.end; i++) {\n\t\t\tlet charType = getCharType(charTypes, i);\n\t\t\tlet stackTop = statusStack[statusStack.length - 1];\n\t\t\tif (!stackTop) continue;\n\n\t\t\tcharTypeCounts.set(charType, (charTypeCounts.get(charType) ?? 0) + 1);\n\t\t\tif (charType & NEUTRAL_ISOLATE_TYPES) {\n\t\t\t\tcharTypeCounts.set(\n\t\t\t\t\tNEUTRAL_ISOLATE_TYPES,\n\t\t\t\t\t(charTypeCounts.get(NEUTRAL_ISOLATE_TYPES) ?? 0) + 1,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (charType & FORMATTING_TYPES) {\n\t\t\t\tif (charType & (TYPE_RLE | TYPE_LRE)) {\n\t\t\t\t\tembedLevels[i] = stackTop._level;\n\t\t\t\t\tconst level = (charType === TYPE_RLE ? nextOdd : nextEven)(\n\t\t\t\t\t\tstackTop._level,\n\t\t\t\t\t);\n\t\t\t\t\tif (\n\t\t\t\t\t\tlevel <= MAX_DEPTH &&\n\t\t\t\t\t\t!overflowIsolateCount &&\n\t\t\t\t\t\t!overflowEmbeddingCount\n\t\t\t\t\t) {\n\t\t\t\t\t\tstatusStack.push({\n\t\t\t\t\t\t\t_level: level,\n\t\t\t\t\t\t\t_override: 0,\n\t\t\t\t\t\t\t_isolate: 0,\n\t\t\t\t\t\t});\n\t\t\t\t\t} else if (!overflowIsolateCount) {\n\t\t\t\t\t\toverflowEmbeddingCount++;\n\t\t\t\t\t}\n\t\t\t\t} else if (charType & (TYPE_RLO | TYPE_LRO)) {\n\t\t\t\t\tembedLevels[i] = stackTop._level;\n\t\t\t\t\tconst level = (charType === TYPE_RLO ? nextOdd : nextEven)(\n\t\t\t\t\t\tstackTop._level,\n\t\t\t\t\t);\n\t\t\t\t\tif (\n\t\t\t\t\t\tlevel <= MAX_DEPTH &&\n\t\t\t\t\t\t!overflowIsolateCount &&\n\t\t\t\t\t\t!overflowEmbeddingCount\n\t\t\t\t\t) {\n\t\t\t\t\t\tstatusStack.push({\n\t\t\t\t\t\t\t_level: level,\n\t\t\t\t\t\t\t_override: charType & TYPE_RLO ? TYPE_R : TYPE_L,\n\t\t\t\t\t\t\t_isolate: 0,\n\t\t\t\t\t\t});\n\t\t\t\t\t} else if (!overflowIsolateCount) {\n\t\t\t\t\t\toverflowEmbeddingCount++;\n\t\t\t\t\t}\n\t\t\t\t} else if (charType & ISOLATE_INIT_TYPES) {\n\t\t\t\t\tif (charType & TYPE_FSI) {\n\t\t\t\t\t\tcharType =\n\t\t\t\t\t\t\tdetermineAutoEmbedLevel(i + 1, true) === 1 ? TYPE_RLI : TYPE_LRI;\n\t\t\t\t\t}\n\n\t\t\t\t\tembedLevels[i] = stackTop._level;\n\t\t\t\t\tif (stackTop._override) {\n\t\t\t\t\t\tchangeCharType(i, stackTop._override);\n\t\t\t\t\t}\n\t\t\t\t\tconst level = (charType === TYPE_RLI ? nextOdd : nextEven)(\n\t\t\t\t\t\tstackTop._level,\n\t\t\t\t\t);\n\t\t\t\t\tif (\n\t\t\t\t\t\tlevel <= MAX_DEPTH &&\n\t\t\t\t\t\toverflowIsolateCount === 0 &&\n\t\t\t\t\t\toverflowEmbeddingCount === 0\n\t\t\t\t\t) {\n\t\t\t\t\t\tvalidIsolateCount++;\n\t\t\t\t\t\tstatusStack.push({\n\t\t\t\t\t\t\t_level: level,\n\t\t\t\t\t\t\t_override: 0,\n\t\t\t\t\t\t\t_isolate: 1,\n\t\t\t\t\t\t\t_isolInitIndex: i,\n\t\t\t\t\t\t});\n\t\t\t\t\t} else {\n\t\t\t\t\t\toverflowIsolateCount++;\n\t\t\t\t\t}\n\t\t\t\t} else if (charType & TYPE_PDI) {\n\t\t\t\t\tif (overflowIsolateCount > 0) {\n\t\t\t\t\t\toverflowIsolateCount--;\n\t\t\t\t\t} else if (validIsolateCount > 0) {\n\t\t\t\t\t\toverflowEmbeddingCount = 0;\n\t\t\t\t\t\twhile (statusStack.length > 0) {\n\t\t\t\t\t\t\tconst top = statusStack[statusStack.length - 1];\n\t\t\t\t\t\t\tif (top?._isolate) break;\n\t\t\t\t\t\t\tstatusStack.pop();\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst top = statusStack[statusStack.length - 1];\n\t\t\t\t\t\tconst isolInitIndex = top?._isolInitIndex;\n\t\t\t\t\t\tif (isolInitIndex != null) {\n\t\t\t\t\t\t\tisolationPairs.set(isolInitIndex, i);\n\t\t\t\t\t\t\tisolationPairs.set(i, isolInitIndex);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tstatusStack.pop();\n\t\t\t\t\t\tvalidIsolateCount--;\n\t\t\t\t\t}\n\t\t\t\t\tstackTop = statusStack[statusStack.length - 1];\n\t\t\t\t\tif (!stackTop) continue;\n\t\t\t\t\tembedLevels[i] = stackTop._level;\n\t\t\t\t\tif (stackTop._override) {\n\t\t\t\t\t\tchangeCharType(i, stackTop._override);\n\t\t\t\t\t}\n\t\t\t\t} else if (charType & TYPE_PDF) {\n\t\t\t\t\tif (overflowIsolateCount === 0) {\n\t\t\t\t\t\tif (overflowEmbeddingCount > 0) {\n\t\t\t\t\t\t\toverflowEmbeddingCount--;\n\t\t\t\t\t\t} else if (!stackTop._isolate && statusStack.length > 1) {\n\t\t\t\t\t\t\tstatusStack.pop();\n\t\t\t\t\t\t\tstackTop = statusStack[statusStack.length - 1];\n\t\t\t\t\t\t\tif (!stackTop) continue;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tembedLevels[i] = stackTop._level;\n\t\t\t\t} else if (charType & TYPE_B) {\n\t\t\t\t\tembedLevels[i] = paragraph.level;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tembedLevels[i] = stackTop._level;\n\t\t\t\tif (stackTop._override && charType !== TYPE_BN) {\n\t\t\t\t\tchangeCharType(i, stackTop._override);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst levelRuns: LevelRun[] = [];\n\t\tlet currentRun: LevelRun | null = null;\n\t\tfor (let i = paragraph.start; i <= paragraph.end; i++) {\n\t\t\tconst charType = getCharType(charTypes, i);\n\t\t\tif (!(charType & BN_LIKE_TYPES)) {\n\t\t\t\tconst lvl = embedLevels[i] ?? 0;\n\t\t\t\tconst isIsolInit = !!(charType & ISOLATE_INIT_TYPES);\n\t\t\t\tconst isPDI = charType === TYPE_PDI;\n\t\t\t\tif (currentRun && lvl === currentRun._level) {\n\t\t\t\t\tcurrentRun._end = i;\n\t\t\t\t\tcurrentRun._endsWithIsolInit = isIsolInit;\n\t\t\t\t} else {\n\t\t\t\t\tcurrentRun = {\n\t\t\t\t\t\t_start: i,\n\t\t\t\t\t\t_end: i,\n\t\t\t\t\t\t_level: lvl,\n\t\t\t\t\t\t_startsWithPDI: isPDI,\n\t\t\t\t\t\t_endsWithIsolInit: isIsolInit,\n\t\t\t\t\t};\n\t\t\t\t\tlevelRuns.push(currentRun);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst isolatingRunSeqs: IsolatingRunSeq[] = [];\n\n\t\tfor (let runIdx = 0; runIdx < levelRuns.length; runIdx++) {\n\t\t\tconst run = levelRuns[runIdx];\n\t\t\tif (!run) continue;\n\t\t\tif (\n\t\t\t\t!run._startsWithPDI ||\n\t\t\t\t(run._startsWithPDI && !isolationPairs.has(run._start))\n\t\t\t) {\n\t\t\t\tcurrentRun = run;\n\t\t\t\tconst seqRuns: LevelRun[] = [run];\n\n\t\t\t\twhile (currentRun?._endsWithIsolInit) {\n\t\t\t\t\tconst pdiIndex = isolationPairs.get(currentRun._end);\n\t\t\t\t\tif (pdiIndex == null) break;\n\t\t\t\t\tlet found = false;\n\t\t\t\t\tfor (let i = runIdx + 1; i < levelRuns.length; i++) {\n\t\t\t\t\t\tconst nextRun = levelRuns[i];\n\t\t\t\t\t\tif (nextRun?._start === pdiIndex) {\n\t\t\t\t\t\t\tcurrentRun = nextRun;\n\t\t\t\t\t\t\tseqRuns.push(nextRun);\n\t\t\t\t\t\t\tfound = true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (!found) break;\n\t\t\t\t}\n\n\t\t\t\tconst seqIndices: number[] = [];\n\t\t\t\tfor (const seqRun of seqRuns) {\n\t\t\t\t\tfor (let j = seqRun._start; j <= seqRun._end; j++) {\n\t\t\t\t\t\tseqIndices.push(j);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst firstIdx = seqIndices[0] ?? 0;\n\t\t\t\tconst firstLevel = embedLevels[firstIdx] ?? 0;\n\t\t\t\tlet prevLevel = paragraph.level;\n\t\t\t\tfor (let i = firstIdx - 1; i >= 0; i--) {\n\t\t\t\t\tif (!(getCharType(charTypes, i) & BN_LIKE_TYPES)) {\n\t\t\t\t\t\tprevLevel = embedLevels[i] ?? 0;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconst lastIndex = seqIndices[seqIndices.length - 1] ?? 0;\n\t\t\t\tconst lastLevel = embedLevels[lastIndex] ?? 0;\n\t\t\t\tlet nextLevel = paragraph.level;\n\t\t\t\tif (!(getCharType(charTypes, lastIndex) & ISOLATE_INIT_TYPES)) {\n\t\t\t\t\tfor (let i = lastIndex + 1; i <= paragraph.end; i++) {\n\t\t\t\t\t\tif (!(getCharType(charTypes, i) & BN_LIKE_TYPES)) {\n\t\t\t\t\t\t\tnextLevel = embedLevels[i] ?? 0;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tisolatingRunSeqs.push({\n\t\t\t\t\t_seqIndices: seqIndices,\n\t\t\t\t\t_sosType: Math.max(prevLevel, firstLevel) % 2 ? TYPE_R : TYPE_L,\n\t\t\t\t\t_eosType: Math.max(nextLevel, lastLevel) % 2 ? TYPE_R : TYPE_L,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tfor (const seq of isolatingRunSeqs) {\n\t\t\tconst {\n\t\t\t\t_seqIndices: seqIndices,\n\t\t\t\t_sosType: sosType,\n\t\t\t\t_eosType: eosType,\n\t\t\t} = seq;\n\t\t\tconst firstSeqIdx = seqIndices[0] ?? 0;\n\t\t\tconst embedDirection =\n\t\t\t\t(embedLevels[firstSeqIdx] ?? 0) & 1 ? TYPE_R : TYPE_L;\n\n\t\t\t// W1\n\t\t\tif (charTypeCounts.get(TYPE_NSM)) {\n\t\t\t\tfor (let si = 0; si < seqIndices.length; si++) {\n\t\t\t\t\tconst i = getSeqIndex(seqIndices, si);\n\t\t\t\t\tif (getCharType(charTypes, i) & TYPE_NSM) {\n\t\t\t\t\t\tlet prevType = sosType;\n\t\t\t\t\t\tfor (let sj = si - 1; sj >= 0; sj--) {\n\t\t\t\t\t\t\tconst sjIdx = getSeqIndex(seqIndices, sj);\n\t\t\t\t\t\t\tif (!(getCharType(charTypes, sjIdx) & BN_LIKE_TYPES)) {\n\t\t\t\t\t\t\t\tprevType = getCharType(charTypes, sjIdx);\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tchangeCharType(\n\t\t\t\t\t\t\ti,\n\t\t\t\t\t\t\tprevType & (ISOLATE_INIT_TYPES | TYPE_PDI) ? TYPE_ON : prevType,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// W2\n\t\t\tif (charTypeCounts.get(TYPE_EN)) {\n\t\t\t\tfor (let si = 0; si < seqIndices.length; si++) {\n\t\t\t\t\tconst i = getSeqIndex(seqIndices, si);\n\t\t\t\t\tif (getCharType(charTypes, i) & TYPE_EN) {\n\t\t\t\t\t\tfor (let sj = si - 1; sj >= -1; sj--) {\n\t\t\t\t\t\t\tconst prevCharType =\n\t\t\t\t\t\t\t\tsj === -1\n\t\t\t\t\t\t\t\t\t? sosType\n\t\t\t\t\t\t\t\t\t: getCharType(charTypes, getSeqIndex(seqIndices, sj));\n\t\t\t\t\t\t\tif (prevCharType & STRONG_TYPES) {\n\t\t\t\t\t\t\t\tif (prevCharType === TYPE_AL) {\n\t\t\t\t\t\t\t\t\tchangeCharType(i, TYPE_AN);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// W3\n\t\t\tif (charTypeCounts.get(TYPE_AL)) {\n\t\t\t\tfor (let si = 0; si < seqIndices.length; si++) {\n\t\t\t\t\tconst i = getSeqIndex(seqIndices, si);\n\t\t\t\t\tif (getCharType(charTypes, i) & TYPE_AL) {\n\t\t\t\t\t\tchangeCharType(i, TYPE_R);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// W4\n\t\t\tif (charTypeCounts.get(TYPE_ES) || charTypeCounts.get(TYPE_CS)) {\n\t\t\t\tfor (let si = 1; si < seqIndices.length - 1; si++) {\n\t\t\t\t\tconst i = getSeqIndex(seqIndices, si);\n\t\t\t\t\tif (getCharType(charTypes, i) & (TYPE_ES | TYPE_CS)) {\n\t\t\t\t\t\tlet prevType = 0;\n\t\t\t\t\t\tlet nextType = 0;\n\t\t\t\t\t\tfor (let sj = si - 1; sj >= 0; sj--) {\n\t\t\t\t\t\t\tprevType = getCharType(charTypes, getSeqIndex(seqIndices, sj));\n\t\t\t\t\t\t\tif (!(prevType & BN_LIKE_TYPES)) break;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfor (let sj = si + 1; sj < seqIndices.length; sj++) {\n\t\t\t\t\t\t\tnextType = getCharType(charTypes, getSeqIndex(seqIndices, sj));\n\t\t\t\t\t\t\tif (!(nextType & BN_LIKE_TYPES)) break;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tprevType === nextType &&\n\t\t\t\t\t\t\t(getCharType(charTypes, i) === TYPE_ES\n\t\t\t\t\t\t\t\t? prevType === TYPE_EN\n\t\t\t\t\t\t\t\t: prevType & (TYPE_EN | TYPE_AN))\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tchangeCharType(i, prevType);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// W5\n\t\t\tif (charTypeCounts.get(TYPE_EN)) {\n\t\t\t\tfor (let si = 0; si < seqIndices.length; si++) {\n\t\t\t\t\tconst i = getSeqIndex(seqIndices, si);\n\t\t\t\t\tif (getCharType(charTypes, i) & TYPE_EN) {\n\t\t\t\t\t\tfor (let sj = si - 1; sj >= 0; sj--) {\n\t\t\t\t\t\t\tconst sjIdx = getSeqIndex(seqIndices, sj);\n\t\t\t\t\t\t\tif (!(getCharType(charTypes, sjIdx) & (TYPE_ET | BN_LIKE_TYPES)))\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tchangeCharType(sjIdx, TYPE_EN);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfor (si++; si < seqIndices.length; si++) {\n\t\t\t\t\t\t\tconst siIdx = getSeqIndex(seqIndices, si);\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t!(\n\t\t\t\t\t\t\t\t\tgetCharType(charTypes, siIdx) &\n\t\t\t\t\t\t\t\t\t(TYPE_ET | BN_LIKE_TYPES | TYPE_EN)\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tif (getCharType(charTypes, siIdx) !== TYPE_EN) {\n\t\t\t\t\t\t\t\tchangeCharType(siIdx, TYPE_EN);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// W6\n\t\t\tif (\n\t\t\t\tcharTypeCounts.get(TYPE_ET) ||\n\t\t\t\tcharTypeCounts.get(TYPE_ES) ||\n\t\t\t\tcharTypeCounts.get(TYPE_CS)\n\t\t\t) {\n\t\t\t\tfor (let si = 0; si < seqIndices.length; si++) {\n\t\t\t\t\tconst i = getSeqIndex(seqIndices, si);\n\t\t\t\t\tif (getCharType(charTypes, i) & (TYPE_ET | TYPE_ES | TYPE_CS)) {\n\t\t\t\t\t\tchangeCharType(i, TYPE_ON);\n\t\t\t\t\t\tfor (let sj = si - 1; sj >= 0; sj--) {\n\t\t\t\t\t\t\tconst sjIdx = getSeqIndex(seqIndices, sj);\n\t\t\t\t\t\t\tif (!(getCharType(charTypes, sjIdx) & BN_LIKE_TYPES)) break;\n\t\t\t\t\t\t\tchangeCharType(sjIdx, TYPE_ON);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfor (let sj = si + 1; sj < seqIndices.length; sj++) {\n\t\t\t\t\t\t\tconst sjIdx = getSeqIndex(seqIndices, sj);\n\t\t\t\t\t\t\tif (!(getCharType(charTypes, sjIdx) & BN_LIKE_TYPES)) break;\n\t\t\t\t\t\t\tchangeCharType(sjIdx, TYPE_ON);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// W7\n\t\t\tif (charTypeCounts.get(TYPE_EN)) {\n\t\t\t\tlet prevStrongType = sosType;\n\t\t\t\tfor (let si = 0; si < seqIndices.length; si++) {\n\t\t\t\t\tconst i = getSeqIndex(seqIndices, si);\n\t\t\t\t\tconst type = getCharType(charTypes, i);\n\t\t\t\t\tif (type & TYPE_EN) {\n\t\t\t\t\t\tif (prevStrongType === TYPE_L) {\n\t\t\t\t\t\t\tchangeCharType(i, TYPE_L);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (type & STRONG_TYPES) {\n\t\t\t\t\t\tprevStrongType = type;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// N0-N2\n\t\t\tif (charTypeCounts.get(NEUTRAL_ISOLATE_TYPES)) {\n\t\t\t\tconst R_TYPES_FOR_N_STEPS = TYPE_R | TYPE_EN | TYPE_AN;\n\t\t\t\tconst STRONG_TYPES_FOR_N_STEPS = R_TYPES_FOR_N_STEPS | TYPE_L;\n\n\t\t\t\tconst bracketPairs: Array<[number, number]> = [];\n\t\t\t\tconst openerStack: Array<{ char: string; seqIndex: number }> = [];\n\n\t\t\t\tfor (let si = 0; si < seqIndices.length; si++) {\n\t\t\t\t\tconst siIdx = getSeqIndex(seqIndices, si);\n\t\t\t\t\tif (getCharType(charTypes, siIdx) & NEUTRAL_ISOLATE_TYPES) {\n\t\t\t\t\t\tconst char = getCharAt(string, siIdx);\n\t\t\t\t\t\tconst closingBracket = openingToClosingBracket(char);\n\t\t\t\t\t\tif (closingBracket !== null) {\n\t\t\t\t\t\t\tif (openerStack.length < 63) {\n\t\t\t\t\t\t\t\topenerStack.push({ char, seqIndex: si });\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tconst oppositeBracket = closingToOpeningBracket(char);\n\t\t\t\t\t\t\tif (oppositeBracket !== null) {\n\t\t\t\t\t\t\t\tfor (\n\t\t\t\t\t\t\t\t\tlet stackIdx = openerStack.length - 1;\n\t\t\t\t\t\t\t\t\tstackIdx >= 0;\n\t\t\t\t\t\t\t\t\tstackIdx--\n\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\tconst opener = openerStack[stackIdx];\n\t\t\t\t\t\t\t\t\tif (!opener) continue;\n\t\t\t\t\t\t\t\t\tconst stackChar = opener.char;\n\t\t\t\t\t\t\t\t\tconst canonicalChar = getCanonicalBracket(char);\n\t\t\t\t\t\t\t\t\tconst canonicalStack = getCanonicalBracket(stackChar);\n\t\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\t\tstackChar === oppositeBracket ||\n\t\t\t\t\t\t\t\t\t\t(canonicalChar &&\n\t\t\t\t\t\t\t\t\t\t\tstackChar === closingToOpeningBracket(canonicalChar)) ||\n\t\t\t\t\t\t\t\t\t\t(canonicalStack &&\n\t\t\t\t\t\t\t\t\t\t\topeningToClosingBracket(canonicalStack) === char)\n\t\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\t\tbracketPairs.push([opener.seqIndex, si]);\n\t\t\t\t\t\t\t\t\t\topenerStack.length = stackIdx;\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbracketPairs.sort((a, b) => a[0] - b[0]);\n\n\t\t\t\tfor (const pair of bracketPairs) {\n\t\t\t\t\tconst [openSeqIdx, closeSeqIdx] = pair;\n\t\t\t\t\tlet foundStrongType = false;\n\t\t\t\t\tlet useStrongType = 0;\n\n\t\t\t\t\tfor (let si = openSeqIdx + 1; si < closeSeqIdx; si++) {\n\t\t\t\t\t\tconst i = getSeqIndex(seqIndices, si);\n\t\t\t\t\t\tconst ct = getCharType(charTypes, i);\n\t\t\t\t\t\tif (ct & STRONG_TYPES_FOR_N_STEPS) {\n\t\t\t\t\t\t\tfoundStrongType = true;\n\t\t\t\t\t\t\tconst lr = ct & R_TYPES_FOR_N_STEPS ? TYPE_R : TYPE_L;\n\t\t\t\t\t\t\tif (lr === embedDirection) {\n\t\t\t\t\t\t\t\tuseStrongType = lr;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (foundStrongType && !useStrongType) {\n\t\t\t\t\t\tuseStrongType = sosType;\n\t\t\t\t\t\tfor (let si = openSeqIdx - 1; si >= 0; si--) {\n\t\t\t\t\t\t\tconst i = getSeqIndex(seqIndices, si);\n\t\t\t\t\t\t\tconst ct = getCharType(charTypes, i);\n\t\t\t\t\t\t\tif (ct & STRONG_TYPES_FOR_N_STEPS) {\n\t\t\t\t\t\t\t\tconst lr = ct & R_TYPES_FOR_N_STEPS ? TYPE_R : TYPE_L;\n\t\t\t\t\t\t\t\tuseStrongType = lr !== embedDirection ? lr : embedDirection;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (useStrongType) {\n\t\t\t\t\t\tcharTypes[getSeqIndex(seqIndices, openSeqIdx)] = useStrongType;\n\t\t\t\t\t\tcharTypes[getSeqIndex(seqIndices, closeSeqIdx)] = useStrongType;\n\n\t\t\t\t\t\tif (useStrongType !== embedDirection) {\n\t\t\t\t\t\t\tfor (let si = openSeqIdx + 1; si < seqIndices.length; si++) {\n\t\t\t\t\t\t\t\tconst siIdx = getSeqIndex(seqIndices, si);\n\t\t\t\t\t\t\t\tif (!(getCharType(charTypes, siIdx) & BN_LIKE_TYPES)) {\n\t\t\t\t\t\t\t\t\tif (getBidiCharType(getCharAt(string, siIdx)) & TYPE_NSM) {\n\t\t\t\t\t\t\t\t\t\tcharTypes[siIdx] = useStrongType;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tfor (let si = closeSeqIdx + 1; si < seqIndices.length; si++) {\n\t\t\t\t\t\t\t\tconst siIdx = getSeqIndex(seqIndices, si);\n\t\t\t\t\t\t\t\tif (!(getCharType(charTypes, siIdx) & BN_LIKE_TYPES)) {\n\t\t\t\t\t\t\t\t\tif (getBidiCharType(getCharAt(string, siIdx)) & TYPE_NSM) {\n\t\t\t\t\t\t\t\t\t\tcharTypes[siIdx] = useStrongType;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// N1/N2\n\t\t\t\tfor (let si = 0; si < seqIndices.length; si++) {\n\t\t\t\t\tconst siIdx = getSeqIndex(seqIndices, si);\n\t\t\t\t\tif (getCharType(charTypes, siIdx) & NEUTRAL_ISOLATE_TYPES) {\n\t\t\t\t\t\tlet niRunStart = si;\n\t\t\t\t\t\tlet niRunEnd = si;\n\t\t\t\t\t\tlet prevType = sosType;\n\n\t\t\t\t\t\tfor (let si2 = si - 1; si2 >= 0; si2--) {\n\t\t\t\t\t\t\tconst si2Idx = getSeqIndex(seqIndices, si2);\n\t\t\t\t\t\t\tif (getCharType(charTypes, si2Idx) & BN_LIKE_TYPES) {\n\t\t\t\t\t\t\t\tniRunStart = si2;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tprevType =\n\t\t\t\t\t\t\t\t\tgetCharType(charTypes, si2Idx) & R_TYPES_FOR_N_STEPS\n\t\t\t\t\t\t\t\t\t\t? TYPE_R\n\t\t\t\t\t\t\t\t\t\t: TYPE_L;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tlet nextType = eosType;\n\t\t\t\t\t\tfor (let si2 = si + 1; si2 < seqIndices.length; si2++) {\n\t\t\t\t\t\t\tconst si2Idx = getSeqIndex(seqIndices, si2);\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tgetCharType(charTypes, si2Idx) &\n\t\t\t\t\t\t\t\t(NEUTRAL_ISOLATE_TYPES | BN_LIKE_TYPES)\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tniRunEnd = si2;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tnextType =\n\t\t\t\t\t\t\t\t\tgetCharType(charTypes, si2Idx) & R_TYPES_FOR_N_STEPS\n\t\t\t\t\t\t\t\t\t\t? TYPE_R\n\t\t\t\t\t\t\t\t\t\t: TYPE_L;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tfor (let sj = niRunStart; sj <= niRunEnd; sj++) {\n\t\t\t\t\t\t\tcharTypes[getSeqIndex(seqIndices, sj)] =\n\t\t\t\t\t\t\t\tprevType === nextType ? prevType : embedDirection;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsi = niRunEnd;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Resolving Implicit Levels\n\t\tfor (let i = paragraph.start; i <= paragraph.end; i++) {\n\t\t\tconst level = embedLevels[i] ?? 0;\n\t\t\tconst type = getCharType(charTypes, i);\n\n\t\t\tif (level & 1) {\n\t\t\t\tif (type & (TYPE_L | TYPE_EN | TYPE_AN)) {\n\t\t\t\t\tembedLevels[i]++;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (type & TYPE_R) {\n\t\t\t\t\tembedLevels[i]++;\n\t\t\t\t} else if (type & (TYPE_AN | TYPE_EN)) {\n\t\t\t\t\tembedLevels[i] += 2;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (type & BN_LIKE_TYPES) {\n\t\t\t\tembedLevels[i] =\n\t\t\t\t\ti === 0 ? paragraph.level : (embedLevels[i - 1] ?? paragraph.level);\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\ti === paragraph.end ||\n\t\t\t\tgetBidiCharType(getCharAt(string, i)) & (TYPE_S | TYPE_B)\n\t\t\t) {\n\t\t\t\tfor (\n\t\t\t\t\tlet j = i;\n\t\t\t\t\tj >= 0 && getBidiCharType(getCharAt(string, j)) & TRAILING_TYPES;\n\t\t\t\t\tj--\n\t\t\t\t) {\n\t\t\t\t\tembedLevels[j] = paragraph.level;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\tlevels: embedLevels,\n\t\tparagraphs,\n\t};\n}\n",
102
- "/**\n * Texture atlas generator for GPU font rendering\n *\n * Packs multiple glyph bitmaps into a single texture atlas\n * using shelf/skyline bin packing algorithm.\n */\n\nimport type { Font } from \"../font/font.ts\";\nimport { rasterizeGlyph } from \"./rasterize.ts\";\nimport {\n\ttype AtlasOptions,\n\ttype Bitmap,\n\tcreateBitmap,\n\ttype GlyphAtlas,\n\ttype GlyphMetrics,\n\tPixelMode,\n} from \"./types.ts\";\n\n/**\n * Shelf packing node\n */\ninterface Shelf {\n\ty: number;\n\theight: number;\n\twidth: number;\n}\n\n/**\n * Build a texture atlas from a set of glyphs\n */\nexport function buildAtlas(\n\tfont: Font,\n\tglyphIds: number[],\n\toptions: AtlasOptions,\n): GlyphAtlas {\n\tconst {\n\t\tfontSize,\n\t\tpadding = 1,\n\t\tmaxWidth = 2048,\n\t\tmaxHeight = 2048,\n\t\tpixelMode = PixelMode.Gray,\n\t} = options;\n\n\t// First pass: rasterize all glyphs and collect sizes\n\tconst glyphData: Array<{\n\t\tglyphId: number;\n\t\tbitmap: Bitmap;\n\t\tbearingX: number;\n\t\tbearingY: number;\n\t\tadvance: number;\n\t}> = [];\n\n\tconst scale = fontSize / font.unitsPerEm;\n\n\tfor (const glyphId of glyphIds) {\n\t\tconst result = rasterizeGlyph(font, glyphId, fontSize, {\n\t\t\tpadding: 0,\n\t\t\tpixelMode,\n\t\t});\n\t\tif (!result) continue;\n\n\t\tconst advance = font.advanceWidth(glyphId) * scale;\n\n\t\tglyphData.push({\n\t\t\tglyphId,\n\t\t\tbitmap: result.bitmap,\n\t\t\tbearingX: result.bearingX,\n\t\t\tbearingY: result.bearingY,\n\t\t\tadvance,\n\t\t});\n\t}\n\n\t// Sort by height (descending) for better packing\n\tglyphData.sort((a, b) => b.bitmap.rows - a.bitmap.rows);\n\n\t// Calculate required atlas size\n\tconst {\n\t\twidth: atlasWidth,\n\t\theight: atlasHeight,\n\t\tplacements,\n\t} = packGlyphs(\n\t\tglyphData.map((g) => ({\n\t\t\twidth: g.bitmap.width + padding * 2,\n\t\t\theight: g.bitmap.rows + padding * 2,\n\t\t})),\n\t\tmaxWidth,\n\t\tmaxHeight,\n\t);\n\n\t// Create atlas bitmap\n\tconst atlas = createBitmap(atlasWidth, atlasHeight, pixelMode);\n\n\t// Copy glyphs into atlas and build metrics map\n\tconst glyphMetrics = new Map<number, GlyphMetrics>();\n\n\tfor (let i = 0; i < glyphData.length; i++) {\n\t\tconst glyph = glyphData[i];\n\t\tconst placement = placements[i];\n\n\t\tif (!placement.placed) continue;\n\n\t\t// Copy glyph bitmap into atlas\n\t\tcopyBitmap(\n\t\t\tglyph.bitmap,\n\t\t\tatlas,\n\t\t\tplacement.x + padding,\n\t\t\tplacement.y + padding,\n\t\t);\n\n\t\t// Store metrics\n\t\tglyphMetrics.set(glyph.glyphId, {\n\t\t\tglyphId: glyph.glyphId,\n\t\t\tatlasX: placement.x + padding,\n\t\t\tatlasY: placement.y + padding,\n\t\t\twidth: glyph.bitmap.width,\n\t\t\theight: glyph.bitmap.rows,\n\t\t\tbearingX: glyph.bearingX,\n\t\t\tbearingY: glyph.bearingY,\n\t\t\tadvance: glyph.advance,\n\t\t});\n\t}\n\n\treturn {\n\t\tbitmap: atlas,\n\t\tglyphs: glyphMetrics,\n\t\tfontSize,\n\t};\n}\n\n/**\n * Build atlas for ASCII printable characters (32-126)\n */\nexport function buildAsciiAtlas(font: Font, options: AtlasOptions): GlyphAtlas {\n\tconst glyphIds: number[] = [];\n\n\tfor (let codepoint = 32; codepoint <= 126; codepoint++) {\n\t\tconst glyphId = font.glyphId(codepoint);\n\t\tif (glyphId !== undefined && glyphId !== 0) {\n\t\t\tglyphIds.push(glyphId);\n\t\t}\n\t}\n\n\treturn buildAtlas(font, glyphIds, options);\n}\n\n/**\n * Build atlas for a specific string (including all unique glyphs)\n */\nexport function buildStringAtlas(\n\tfont: Font,\n\ttext: string,\n\toptions: AtlasOptions,\n): GlyphAtlas {\n\tconst glyphIdSet = new Set<number>();\n\n\tfor (const char of text) {\n\t\tconst codepoint = char.codePointAt(0);\n\t\tif (codepoint === undefined) continue;\n\n\t\tconst glyphId = font.glyphId(codepoint);\n\t\tif (glyphId !== undefined && glyphId !== 0) {\n\t\t\tglyphIdSet.add(glyphId);\n\t\t}\n\t}\n\n\treturn buildAtlas(font, Array.from(glyphIdSet), options);\n}\n\n/**\n * Placement result for a glyph\n */\ninterface Placement {\n\tx: number;\n\ty: number;\n\tplaced: boolean;\n}\n\n/**\n * Pack rectangles using shelf algorithm\n */\nfunction packGlyphs(\n\tsizes: Array<{ width: number; height: number }>,\n\tmaxWidth: number,\n\tmaxHeight: number,\n): { width: number; height: number; placements: Placement[] } {\n\tconst shelves: Shelf[] = [];\n\tconst placements: Placement[] = [];\n\n\tlet atlasWidth = 0;\n\tlet atlasHeight = 0;\n\n\tfor (const size of sizes) {\n\t\tlet placed = false;\n\t\tlet bestShelf = -1;\n\t\tlet bestY = maxHeight;\n\n\t\t// Try to find an existing shelf\n\t\tfor (let i = 0; i < shelves.length; i++) {\n\t\t\tconst shelf = shelves[i];\n\n\t\t\t// Check if glyph fits in this shelf\n\t\t\tif (shelf.width + size.width <= maxWidth && size.height <= shelf.height) {\n\t\t\t\tif (shelf.y < bestY) {\n\t\t\t\t\tbestShelf = i;\n\t\t\t\t\tbestY = shelf.y;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (bestShelf >= 0) {\n\t\t\t// Place in existing shelf\n\t\t\tconst shelf = shelves[bestShelf];\n\t\t\tplacements.push({\n\t\t\t\tx: shelf.width,\n\t\t\t\ty: shelf.y,\n\t\t\t\tplaced: true,\n\t\t\t});\n\t\t\tshelf.width += size.width;\n\t\t\tatlasWidth = Math.max(atlasWidth, shelf.width);\n\t\t\tplaced = true;\n\t\t} else {\n\t\t\t// Create new shelf\n\t\t\tconst newY = atlasHeight;\n\n\t\t\tif (newY + size.height <= maxHeight && size.width <= maxWidth) {\n\t\t\t\tshelves.push({\n\t\t\t\t\ty: newY,\n\t\t\t\t\theight: size.height,\n\t\t\t\t\twidth: size.width,\n\t\t\t\t});\n\t\t\t\tplacements.push({\n\t\t\t\t\tx: 0,\n\t\t\t\t\ty: newY,\n\t\t\t\t\tplaced: true,\n\t\t\t\t});\n\t\t\t\tatlasHeight = newY + size.height;\n\t\t\t\tatlasWidth = Math.max(atlasWidth, size.width);\n\t\t\t\tplaced = true;\n\t\t\t}\n\t\t}\n\n\t\tif (!placed) {\n\t\t\tplacements.push({ x: 0, y: 0, placed: false });\n\t\t}\n\t}\n\n\t// Round up to power of 2 for GPU compatibility\n\tconst finalWidth = nextPowerOf2(atlasWidth);\n\tconst finalHeight = nextPowerOf2(atlasHeight);\n\n\treturn {\n\t\twidth: Math.min(finalWidth, maxWidth),\n\t\theight: Math.min(finalHeight, maxHeight),\n\t\tplacements,\n\t};\n}\n\n/**\n * Copy source bitmap into destination at specified position\n */\nfunction copyBitmap(\n\tsrc: Bitmap,\n\tdst: Bitmap,\n\tdstX: number,\n\tdstY: number,\n): void {\n\tconst bytesPerPixel = src.pixelMode === PixelMode.LCD ? 3 : 1;\n\n\tfor (let y = 0; y < src.rows; y++) {\n\t\tconst srcRow = y * src.pitch;\n\t\tconst dstRow = (dstY + y) * dst.pitch + dstX * bytesPerPixel;\n\n\t\tfor (let x = 0; x < src.width * bytesPerPixel; x++) {\n\t\t\tdst.buffer[dstRow + x] = src.buffer[srcRow + x];\n\t\t}\n\t}\n}\n\n/**\n * Get next power of 2 >= n\n */\nfunction nextPowerOf2(n: number): number {\n\tif (n <= 0) return 1;\n\tn--;\n\tn |= n >> 1;\n\tn |= n >> 2;\n\tn |= n >> 4;\n\tn |= n >> 8;\n\tn |= n >> 16;\n\treturn n + 1;\n}\n\n/**\n * Export atlas to formats suitable for GPU upload\n */\nexport function atlasToRGBA(atlas: GlyphAtlas): Uint8Array {\n\tconst { bitmap } = atlas;\n\tconst rgba = new Uint8Array(bitmap.width * bitmap.rows * 4);\n\n\tfor (let y = 0; y < bitmap.rows; y++) {\n\t\tfor (let x = 0; x < bitmap.width; x++) {\n\t\t\tconst srcIdx = y * bitmap.pitch + x;\n\t\t\tconst dstIdx = (y * bitmap.width + x) * 4;\n\n\t\t\tconst alpha = bitmap.buffer[srcIdx] ?? 0;\n\n\t\t\t// White text on transparent background\n\t\t\trgba[dstIdx] = 255;\n\t\t\trgba[dstIdx + 1] = 255;\n\t\t\trgba[dstIdx + 2] = 255;\n\t\t\trgba[dstIdx + 3] = alpha;\n\t\t}\n\t}\n\n\treturn rgba;\n}\n\n/**\n * Export atlas as single-channel alpha texture\n */\nexport function atlasToAlpha(atlas: GlyphAtlas): Uint8Array {\n\tconst { bitmap } = atlas;\n\n\tif (bitmap.pitch === bitmap.width) {\n\t\treturn bitmap.buffer;\n\t}\n\n\t// Copy without padding\n\tconst alpha = new Uint8Array(bitmap.width * bitmap.rows);\n\tfor (let y = 0; y < bitmap.rows; y++) {\n\t\tfor (let x = 0; x < bitmap.width; x++) {\n\t\t\talpha[y * bitmap.width + x] = bitmap.buffer[y * bitmap.pitch + x];\n\t\t}\n\t}\n\n\treturn alpha;\n}\n\n/**\n * Get UV coordinates for a glyph in the atlas\n */\nexport function getGlyphUV(\n\tatlas: GlyphAtlas,\n\tglyphId: number,\n): { u0: number; v0: number; u1: number; v1: number } | null {\n\tconst metrics = atlas.glyphs.get(glyphId);\n\tif (!metrics) return null;\n\n\tconst { bitmap } = atlas;\n\n\treturn {\n\t\tu0: metrics.atlasX / bitmap.width,\n\t\tv0: metrics.atlasY / bitmap.rows,\n\t\tu1: (metrics.atlasX + metrics.width) / bitmap.width,\n\t\tv1: (metrics.atlasY + metrics.height) / bitmap.rows,\n\t};\n}\n",
103
- "/**\n * CPU Performance Tests for comparison with GPU implementations\n */\n\nimport { benchmark, PerformanceResult, BenchmarkOptions } from '../utils/perf-utils.js';\nimport * as shaper from '../../../src/index.ts';\nimport { rasterizeGlyph } from '../../../src/raster/rasterize.ts';\nimport { renderSdf } from '../../../src/raster/sdf.ts';\nimport { getGlyphPath } from '../../../src/render/path.ts';\nimport { buildAsciiAtlas, buildStringAtlas } from '../../../src/raster/atlas.ts';\n\nlet testFont: shaper.Font | null = null;\n\n/**\n * Initialize test font\n */\nexport async function initTestFont(): Promise<shaper.Font> {\n if (testFont) return testFont;\n \n // Use the same font path as in the examples\n const fontPath = new URL('../../../tests/fonts/STIXTwoMath-Regular.otf', import.meta.url).pathname;\n testFont = await shaper.Font.fromFile(fontPath);\n return testFont;\n}\n\n/**\n * CPU Rasterization Performance Test\n */\nexport async function benchmarkCPURasterization(\n options: BenchmarkOptions = {}\n): Promise<PerformanceResult> {\n const font = await initTestFont();\n const glyphId = font.glyphId('A'.codePointAt(0)!);\n\n return benchmark('CPU Rasterization', () => {\n rasterizeGlyph(font, glyphId, 32, {\n pixelMode: 'Gray' as any,\n hinting: false\n });\n }, options);\n}\n\n/**\n * CPU SDF Generation Performance Test\n */\nexport async function benchmarkCPUSDF(\n options: BenchmarkOptions = {}\n): Promise<PerformanceResult> {\n const font = await initTestFont();\n const glyphId = font.glyphId('A'.codePointAt(0)!);\n const path = getGlyphPath(font, glyphId);\n \n if (!path) throw new Error('Could not get glyph path');\n\n return benchmark('CPU SDF Generation', () => {\n renderSdf(path, {\n width: 64,\n height: 64,\n scale: 32 / font.unitsPerEm!,\n spread: 8\n });\n }, options);\n}\n\n/**\n * CPU Atlas Generation Performance Test\n */\nexport async function benchmarkCPUAtlas(\n options: BenchmarkOptions = {}\n): Promise<PerformanceResult> {\n const font = await initTestFont();\n\n return benchmark('CPU Atlas Generation', () => {\n buildAsciiAtlas(font, { fontSize: 32 });\n }, options);\n}\n\n/**\n * CPU Text Shaping Performance Test\n */\nexport async function benchmarkCPUTextShaping(\n options: BenchmarkOptions = {}\n): Promise<PerformanceResult> {\n const font = await initTestFont();\n const text = 'The quick brown fox jumps over the lazy dog.'.repeat(20);\n\n return benchmark('CPU Text Shaping', () => {\n const buffer = new shaper.UnicodeBuffer().addStr(text);\n shaper.shape(font, buffer);\n }, options);\n}\n\n/**\n * CPU String Atlas Performance Test\n */\nexport async function benchmarkCPUStringAtlas(\n options: BenchmarkOptions = {}\n): Promise<PerformanceResult> {\n const font = await initTestFont();\n const text = 'The quick brown fox jumps over the lazy dog.'.repeat(20);\n\n return benchmark('CPU String Atlas', () => {\n buildStringAtlas(font, text, { fontSize: 32 });\n }, options);\n}\n\n/**\n * CPU Path Rendering Performance Test\n */\nexport async function benchmarkCPUPathRendering(\n options: BenchmarkOptions = {}\n): Promise<PerformanceResult> {\n const font = await initTestFont();\n const glyphId = font.glyphId('A'.codePointAt(0)!);\n const path = getGlyphPath(font, glyphId);\n \n if (!path) throw new Error('Could not get glyph path');\n\n return benchmark('CPU Path Rendering', () => {\n // Create a simple mock canvas for Node.js compatibility\n const canvas = {\n width: 64,\n height: 64,\n getContext: (type: string) => {\n if (type === '2d') {\n return {\n clearRect: () => {},\n fillStyle: '',\n beginPath: () => {},\n moveTo: () => {},\n lineTo: () => {},\n quadraticCurveTo: () => {},\n bezierCurveTo: () => {},\n closePath: () => {},\n fill: () => {}\n };\n }\n return null;\n }\n } as any;\n \n const ctx = canvas.getContext('2d')!;\n \n ctx.clearRect(0, 0, 64, 64);\n ctx.fillStyle = 'black';\n \n // Simple path rendering simulation\n ctx.beginPath();\n for (const cmd of path.commands) {\n switch (cmd.type) {\n case 'M':\n ctx.moveTo(cmd.x, cmd.y);\n break;\n case 'L':\n ctx.lineTo(cmd.x, cmd.y);\n break;\n case 'Q':\n ctx.quadraticCurveTo(cmd.x1!, cmd.y1!, cmd.x, cmd.y);\n break;\n case 'C':\n ctx.bezierCurveTo(cmd.x1!, cmd.y1!, cmd.x2!, cmd.y2!, cmd.x, cmd.y);\n break;\n case 'Z':\n ctx.closePath();\n break;\n }\n }\n ctx.fill();\n }, options);\n}\n\n/**\n * CPU Bitmap Operations Performance Test\n */\nexport async function benchmarkCPUBitmapOps(\n options: BenchmarkOptions = {}\n): Promise<PerformanceResult> {\n const bitmap = new Uint8Array(64 * 64);\n \n // Fill with some test data\n for (let i = 0; i < bitmap.length; i++) {\n const x = i % 64;\n const y = Math.floor(i / 64);\n bitmap[i] = (x + y) % 256;\n }\n\n return benchmark('CPU Bitmap Operations', () => {\n // Simulate various bitmap operations\n const result = new Uint8Array(64 * 64);\n \n // Blur operation\n for (let y = 1; y < 63; y++) {\n for (let x = 1; x < 63; x++) {\n let sum = 0;\n for (let dy = -1; dy <= 1; dy++) {\n for (let dx = -1; dx <= 1; dx++) {\n sum += bitmap[(y + dy) * 64 + (x + dx)];\n }\n }\n result[y * 64 + x] = sum / 9;\n }\n }\n \n // Threshold operation\n for (let i = 0; i < result.length; i++) {\n result[i] = result[i] > 128 ? 255 : 0;\n }\n }, options);\n}\n\n/**\n * CPU Parallel-like Processing (simulated)\n */\nexport async function benchmarkCPUParallel(\n options: BenchmarkOptions = {}\n): Promise<PerformanceResult> {\n const dataSize = 10000;\n const data = new Float32Array(dataSize);\n \n // Initialize with random data\n for (let i = 0; i < dataSize; i++) {\n data[i] = Math.random() * 100;\n }\n\n return benchmark('CPU Parallel Processing', () => {\n const result = new Float32Array(dataSize);\n \n // Simulate parallel processing with multiple passes\n for (let pass = 0; pass < 5; pass++) {\n for (let i = 0; i < dataSize; i++) {\n // Complex calculation\n let value = data[i];\n value = Math.sin(value) * Math.cos(value);\n value = Math.sqrt(Math.abs(value));\n result[i] = value * 255;\n }\n \n // Copy result back for next pass\n data.set(result);\n }\n }, options);\n}\n\n/**\n * CPU Memory-intensive Operations\n */\nexport async function benchmarkCPUMemoryOps(\n options: BenchmarkOptions = {}\n): Promise<PerformanceResult> {\n return benchmark('CPU Memory Operations', () => {\n // Allocate multiple large arrays\n const arrays: Float32Array[] = [];\n \n for (let i = 0; i < 10; i++) {\n arrays.push(new Float32Array(10000));\n }\n \n // Perform memory-intensive operations\n for (let arr of arrays) {\n for (let j = 0; j < arr.length; j++) {\n arr[j] = Math.sin(j * 0.01) * Math.cos(j * 0.02);\n }\n }\n \n // Combine arrays\n const result = new Float32Array(10000);\n for (let i = 0; i < result.length; i++) {\n let sum = 0;\n for (let arr of arrays) {\n sum += arr[i];\n }\n result[i] = sum / arrays.length;\n }\n }, options);\n}\n\n/**\n * Run all CPU benchmarks\n */\nexport async function runAllCPUBenchmarks(\n options: BenchmarkOptions = {}\n): Promise<PerformanceResult[]> {\n const results: PerformanceResult[] = [];\n \n console.log('Running CPU benchmarks...');\n \n results.push(await benchmarkCPURasterization(options));\n results.push(await benchmarkCPUSDF(options));\n results.push(await benchmarkCPUAtlas(options));\n results.push(await benchmarkCPUTextShaping(options));\n results.push(await benchmarkCPUStringAtlas(options));\n results.push(await benchmarkCPUPathRendering(options));\n results.push(await benchmarkCPUBitmapOps(options));\n results.push(await benchmarkCPUParallel(options));\n results.push(await benchmarkCPUMemoryOps(options));\n \n return results;\n}",
104
- "/**\n * WebGPU Performance Tests\n */\n\nimport { benchmark, PerformanceResult, BenchmarkOptions } from '../utils/perf-utils.js';\n\nexport interface WebGPUTestContext {\n adapter: GPUAdapter;\n device: GPUDevice;\n commandEncoder?: GPUCommandEncoder;\n}\n\n/**\n * Initialize WebGPU context\n */\nexport async function initWebGPU(): Promise<WebGPUTestContext | null> {\n if (!navigator.gpu) {\n console.warn('WebGPU not supported');\n return null;\n }\n\n try {\n const adapter = await navigator.gpu.requestAdapter();\n if (!adapter) {\n console.warn('No WebGPU adapter found');\n return null;\n }\n\n const device = await adapter.requestDevice();\n return { adapter, device };\n } catch (error) {\n console.error('WebGPU initialization failed:', error);\n return null;\n }\n}\n\n/**\n * WebGPU SDF Generation Performance Test\n */\nexport async function benchmarkWebGPUSDF(\n context: WebGPUTestContext,\n options: BenchmarkOptions = {}\n): Promise<PerformanceResult> {\n const { device } = context;\n const size = 64;\n\n // Create compute shader for SDF generation\n const shaderCode = `\n @group(0) @binding(0) var<storage, read_write> distances: array<f32>;\n @group(0) @binding(1) var<uniform> params: vec4<f32>;\n @group(0) @binding(2) var<storage, read> edges: array<vec4<f32>>;\n\n @compute @workgroup_size(8, 8)\n fn main(@builtin(global_invocation_id) id: vec3<u32>) {\n let x = id.x;\n let y = id.y;\n let width = u32(params.x);\n let height = u32(params.y);\n\n if (x >= width || y >= height) { return; }\n\n let px = f32(x) + 0.5;\n let py = f32(y) + 0.5;\n var minDist = 1000000.0;\n\n // Simple point-to-edge distance calculation\n for (var i = 0u; i < arrayLength(&edges); i = i + 1u) {\n let edge = edges[i];\n let dx = px - edge.x;\n let dy = py - edge.y;\n let dist = sqrt(dx * dx + dy * dy);\n minDist = min(minDist, dist);\n }\n\n distances[y * width + x] = minDist / params.z; // Normalize by spread\n }\n `;\n\n const shaderModule = device.createShaderModule({ code: shaderCode });\n const computePipeline = device.createComputePipeline({\n layout: 'auto',\n compute: { module: shaderModule, entryPoint: 'main' }\n });\n\n // Create buffers\n const distanceBuffer = device.createBuffer({\n size: size * size * 4,\n usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC\n });\n\n const uniformBuffer = device.createBuffer({\n size: 16,\n usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST\n });\n\n // Sample edge data (simplified)\n const edgeBuffer = device.createBuffer({\n size: 100 * 16, // 100 edges * vec4<f32>\n usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST\n });\n\n const bindGroup = device.createBindGroup({\n layout: computePipeline.getBindGroupLayout(0),\n entries: [\n { binding: 0, resource: { buffer: distanceBuffer } },\n { binding: 1, resource: { buffer: uniformBuffer } },\n { binding: 2, resource: { buffer: edgeBuffer } }\n ]\n });\n\n // Upload uniform data\n device.queue.writeBuffer(uniformBuffer, 0, new Float32Array([size, size, 8.0, 0.0]));\n\n return benchmark('WebGPU SDF Generation', async () => {\n const commandEncoder = device.createCommandEncoder();\n const computePass = commandEncoder.beginComputePass();\n \n computePass.setPipeline(computePipeline);\n computePass.setBindGroup(0, bindGroup);\n computePass.dispatchWorkgroups(Math.ceil(size / 8), Math.ceil(size / 8));\n computePass.end();\n\n device.queue.submit([commandEncoder.finish()]);\n }, options);\n}\n\n/**\n * WebGPU Texture Atlas Packing Performance Test\n */\nexport async function benchmarkWebGPUAtlasPacking(\n context: WebGPUTestContext,\n options: BenchmarkOptions = {}\n): Promise<PerformanceResult> {\n const { device } = context;\n const atlasSize = 512;\n const glyphCount = 256;\n\n const shaderCode = `\n struct Rect {\n x: f32,\n y: f32,\n width: f32,\n height: f32,\n placed: u32\n };\n\n @group(0) @binding(0) var<storage, read_write> rects: array<Rect>;\n @group(0) @binding(1) var<storage, read_write> atlas: array<u32>;\n @group(0) @binding(2) var<uniform> params: vec4<u32>;\n\n @compute @workgroup_size(16, 16)\n fn main(@builtin(global_invocation_id) id: vec3<u32>) {\n let rectIndex = id.x;\n let attempt = id.y;\n \n if (rectIndex >= params.x) { return; }\n \n let rect = &rects[rectIndex];\n if (rect.placed != 0u) { return; }\n\n // Simple packing algorithm - try different positions\n let x = (rectIndex * 7u + attempt * 13u) % (params.y - u32(rect.width));\n let y = (rectIndex * 11u + attempt * 17u) % (params.z - u32(rect.height));\n\n // Check if position is available (simplified)\n var canPlace = true;\n for (var dy = 0u; dy < u32(rect.height); dy = dy + 1u) {\n for (var dx = 0u; dx < u32(rect.width); dx = dx + 1u) {\n let atlasIdx = (y + dy) * params.y + (x + dx);\n if (atlas[atlasIdx] != 0u) {\n canPlace = false;\n break;\n }\n }\n if (!canPlace) { break; }\n }\n\n if (canPlace) {\n rect.x = f32(x);\n rect.y = f32(y);\n rect.placed = 1u;\n \n // Mark atlas positions as used\n for (var dy = 0u; dy < u32(rect.height); dy = dy + 1u) {\n for (var dx = 0u; dx < u32(rect.width); dx = dx + 1u) {\n let atlasIdx = (y + dy) * params.y + (x + dx);\n atlas[atlasIdx] = 1u;\n }\n }\n }\n }\n `;\n\n const shaderModule = device.createShaderModule({ code: shaderCode });\n const computePipeline = device.createComputePipeline({\n layout: 'auto',\n compute: { module: shaderModule, entryPoint: 'main' }\n });\n\n // Create buffers\n const rectBuffer = device.createBuffer({\n size: glyphCount * 20, // sizeof(Rect)\n usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST\n });\n\n const atlasBuffer = device.createBuffer({\n size: atlasSize * atlasSize * 4,\n usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST\n });\n\n const uniformBuffer = device.createBuffer({\n size: 16,\n usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST\n });\n\n const bindGroup = device.createBindGroup({\n layout: computePipeline.getBindGroupLayout(0),\n entries: [\n { binding: 0, resource: { buffer: rectBuffer } },\n { binding: 1, resource: { buffer: atlasBuffer } },\n { binding: 2, resource: { buffer: uniformBuffer } }\n ]\n });\n\n // Initialize data\n const rects = new ArrayBuffer(glyphCount * 20);\n const rectView = new DataView(rects);\n for (let i = 0; i < glyphCount; i++) {\n rectView.setFloat32(i * 20 + 0, 0, true); // x\n rectView.setFloat32(i * 20 + 4, 0, true); // y\n rectView.setFloat32(i * 20 + 8, 16 + (i % 32), true); // width\n rectView.setFloat32(i * 20 + 12, 16 + (i % 16), true); // height\n rectView.setUint32(i * 20 + 16, 0, true); // placed\n }\n\n device.queue.writeBuffer(rectBuffer, 0, rects);\n device.queue.writeBuffer(uniformBuffer, 0, new Uint32Array([glyphCount, atlasSize, atlasSize, 0]));\n\n return benchmark('WebGPU Atlas Packing', async () => {\n const commandEncoder = device.createCommandEncoder();\n const computePass = commandEncoder.beginComputePass();\n \n computePass.setPipeline(computePipeline);\n computePass.setBindGroup(0, bindGroup);\n computePass.dispatchWorkgroups(Math.ceil(glyphCount / 16), 32);\n computePass.end();\n\n device.queue.submit([commandEncoder.finish()]);\n }, options);\n}\n\n/**\n * WebGPU Parallel Glyph Rendering Performance Test\n */\nexport async function benchmarkWebGPUGlyphRendering(\n context: WebGPUTestContext,\n options: BenchmarkOptions = {}\n): Promise<PerformanceResult> {\n const { device } = context;\n const glyphCount = 128;\n const glyphSize = 32;\n\n const shaderCode = `\n @group(0) @binding(0) var<storage, read> glyphData: array<vec4<f32>>;\n @group(0) @binding(1) var<storage, read_write> outputAtlas: array<vec4<f32>>;\n @group(0) @binding(2) var<uniform> params: vec4<u32>;\n\n fn drawPixel(x: u32, y: u32, glyphIndex: u32, color: vec4<f32>) {\n let atlasX = (glyphIndex % params.z) * params.x + x;\n let atlasY = (glyphIndex / params.z) * params.y + y;\n let atlasIndex = atlasY * (params.z * params.x) + atlasX;\n \n if (atlasIndex < arrayLength(&outputAtlas)) {\n outputAtlas[atlasIndex] = color;\n }\n }\n\n @compute @workgroup_size(8, 8)\n fn main(@builtin(global_invocation_id) id: vec3<u32>) {\n let x = id.x;\n let y = id.y;\n let glyphIndex = id.z;\n \n if (glyphIndex >= params.w) { return; }\n if (x >= params.x || y >= params.y) { return; }\n\n // Simple circle glyph simulation\n let center = vec2<f32>(f32(params.x) / 2.0, f32(params.y) / 2.0);\n let pos = vec2<f32>(f32(x), f32(y));\n let dist = distance(pos, center);\n \n if (dist < f32(params.x) / 2.0) {\n let alpha = 1.0 - (dist / (f32(params.x) / 2.0));\n drawPixel(x, y, glyphIndex, vec4<f32>(1.0, 1.0, 1.0, alpha));\n }\n }\n `;\n\n const shaderModule = device.createShaderModule({ code: shaderCode });\n const computePipeline = device.createComputePipeline({\n layout: 'auto',\n compute: { module: shaderModule, entryPoint: 'main' }\n });\n\n // Create buffers\n const glyphBuffer = device.createBuffer({\n size: glyphCount * 16,\n usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST\n });\n\n const atlasSize = Math.ceil(Math.sqrt(glyphCount)) * glyphSize;\n const outputBuffer = device.createBuffer({\n size: atlasSize * atlasSize * 16, // vec4<f32>\n usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC\n });\n\n const uniformBuffer = device.createBuffer({\n size: 16,\n usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST\n });\n\n const bindGroup = device.createBindGroup({\n layout: computePipeline.getBindGroupLayout(0),\n entries: [\n { binding: 0, resource: { buffer: glyphBuffer } },\n { binding: 1, resource: { buffer: outputBuffer } },\n { binding: 2, resource: { buffer: uniformBuffer } }\n ]\n });\n\n // Initialize uniform data\n const glyphsPerRow = Math.ceil(Math.sqrt(glyphCount));\n device.queue.writeBuffer(uniformBuffer, 0, new Uint32Array([\n glyphSize, glyphSize, glyphsPerRow, glyphCount\n ]));\n\n return benchmark('WebGPU Parallel Glyph Rendering', async () => {\n const commandEncoder = device.createCommandEncoder();\n const computePass = commandEncoder.beginComputePass();\n \n computePass.setPipeline(computePipeline);\n computePass.setBindGroup(0, bindGroup);\n computePass.dispatchWorkgroups(\n Math.ceil(glyphSize / 8),\n Math.ceil(glyphSize / 8),\n glyphCount\n );\n computePass.end();\n\n device.queue.submit([commandEncoder.finish()]);\n }, options);\n}",
105
- "/**\n * WebGL Performance Tests\n */\n\nimport { benchmark, PerformanceResult, BenchmarkOptions } from '../utils/perf-utils.js';\n\nexport interface WebGLTestContext {\n canvas: HTMLCanvasElement;\n gl: WebGL2RenderingContext | WebGLRenderingContext;\n program?: WebGLProgram;\n framebuffer?: WebGLFramebuffer;\n}\n\n/**\n * Initialize WebGL context\n */\nexport function initWebGL(): WebGLTestContext | null {\n const canvas = document.createElement('canvas');\n canvas.width = 512;\n canvas.height = 512;\n \n const gl = canvas.getContext('webgl2') || canvas.getContext('webgl');\n if (!gl) {\n console.warn('WebGL not supported');\n return null;\n }\n\n return { canvas, gl };\n}\n\n/**\n * Compile shader\n */\nfunction compileShader(gl: WebGLRenderingContext, type: number, source: string): WebGLShader | null {\n const shader = gl.createShader(type);\n if (!shader) return null;\n\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n console.error('Shader compilation error:', gl.getShaderInfoLog(shader));\n gl.deleteShader(shader);\n return null;\n }\n\n return shader;\n}\n\n/**\n * Create shader program\n */\nfunction createProgram(gl: WebGLRenderingContext, vertexSource: string, fragmentSource: string): WebGLProgram | null {\n const vertexShader = compileShader(gl, gl.VERTEX_SHADER, vertexSource);\n const fragmentShader = compileShader(gl, gl.FRAGMENT_SHADER, fragmentSource);\n\n if (!vertexShader || !fragmentShader) return null;\n\n const program = gl.createProgram();\n if (!program) return null;\n\n gl.attachShader(program, vertexShader);\n gl.attachShader(program, fragmentShader);\n gl.linkProgram(program);\n\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n console.error('Program linking error:', gl.getProgramInfoLog(program));\n gl.deleteProgram(program);\n return null;\n }\n\n return program;\n}\n\n/**\n * WebGL Texture Atlas Rendering Performance Test\n */\nexport async function benchmarkWebGLAtlasRendering(\n context: WebGLTestContext,\n options: BenchmarkOptions = {}\n): Promise<PerformanceResult> {\n const { gl } = context;\n\n // Vertex shader for texture rendering\n const vertexShaderSource = `\n attribute vec2 a_position;\n attribute vec2 a_texCoord;\n uniform mat3 u_matrix;\n varying vec2 v_texCoord;\n\n void main() {\n gl_Position = vec4((u_matrix * vec3(a_position, 1.0)).xy, 0.0, 1.0);\n v_texCoord = a_texCoord;\n }\n `;\n\n // Fragment shader for texture rendering\n const fragmentShaderSource = `\n precision mediump float;\n uniform sampler2D u_texture;\n uniform vec4 u_color;\n varying vec2 v_texCoord;\n\n void main() {\n vec4 texColor = texture2D(u_texture, v_texCoord);\n gl_FragColor = vec4(texColor.rgb * u_color.rgb, texColor.a * u_color.a);\n }\n `;\n\n const program = createProgram(gl, vertexShaderSource, fragmentShaderSource);\n if (!program) throw new Error('Failed to create shader program');\n\n context.program = program;\n gl.useProgram(program);\n\n // Create vertices for multiple quads (simulating glyph rendering)\n const quadCount = 100;\n const vertices: number[] = [];\n const texCoords: number[] = [];\n\n for (let i = 0; i < quadCount; i++) {\n const x = (i % 10) * 0.2 - 0.9;\n const y = Math.floor(i / 10) * 0.2 - 0.9;\n const size = 0.15;\n\n // Quad vertices\n vertices.push(\n x, y,\n x + size, y,\n x, y + size,\n x + size, y,\n x + size, y + size,\n x, y + size\n );\n\n // Texture coordinates\n const u = (i % 16) / 16;\n const v = Math.floor(i / 16) / 16;\n const texSize = 1.0 / 16;\n\n texCoords.push(\n u, v,\n u + texSize, v,\n u, v + texSize,\n u + texSize, v,\n u + texSize, v + texSize,\n u, v + texSize\n );\n }\n\n // Create buffers\n const positionBuffer = gl.createBuffer();\n gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);\n gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);\n\n const texCoordBuffer = gl.createBuffer();\n gl.bindBuffer(gl.ARRAY_BUFFER, texCoordBuffer);\n gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(texCoords), gl.STATIC_DRAW);\n\n // Create texture atlas\n const texture = gl.createTexture();\n gl.bindTexture(gl.TEXTURE_2D, texture);\n \n const atlasData = new Uint8Array(256 * 256 * 4);\n for (let i = 0; i < atlasData.length; i += 4) {\n atlasData[i] = 255; // R\n atlasData[i + 1] = 255; // G\n atlasData[i + 2] = 255; // B\n atlasData[i + 3] = 255; // A\n }\n\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 256, 256, 0, gl.RGBA, gl.UNSIGNED_BYTE, atlasData);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n\n // Set up attributes\n const positionLocation = gl.getAttribLocation(program, 'a_position');\n const texCoordLocation = gl.getAttribLocation(program, 'a_texCoord');\n\n gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);\n gl.enableVertexAttribArray(positionLocation);\n gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);\n\n gl.bindBuffer(gl.ARRAY_BUFFER, texCoordBuffer);\n gl.enableVertexAttribArray(texCoordLocation);\n gl.vertexAttribPointer(texCoordLocation, 2, gl.FLOAT, false, 0, 0);\n\n // Set uniforms\n const matrixLocation = gl.getUniformLocation(program, 'u_matrix');\n const colorLocation = gl.getUniformLocation(program, 'u_color');\n const textureLocation = gl.getUniformLocation(program, 'u_texture');\n\n gl.uniformMatrix3fv(matrixLocation, false, [\n 1, 0, 0,\n 0, 1, 0,\n 0, 0, 1\n ]);\n gl.uniform4fv(colorLocation, [1, 1, 1, 1]);\n gl.uniform1i(textureLocation, 0);\n\n return benchmark('WebGL Atlas Rendering', () => {\n gl.clear(gl.COLOR_BUFFER_BIT);\n gl.drawArrays(gl.TRIANGLES, 0, quadCount * 6);\n }, options);\n}\n\n/**\n * WebGL SDF Generation Performance Test\n */\nexport async function benchmarkWebGLSDF(\n context: WebGLTestContext,\n options: BenchmarkOptions = {}\n): Promise<PerformanceResult> {\n const { gl, canvas } = context;\n const size = 64;\n\n // Create framebuffer for offscreen rendering\n const framebuffer = gl.createFramebuffer();\n context.framebuffer = framebuffer;\n\n // Create texture for SDF output\n const sdfTexture = gl.createTexture();\n gl.bindTexture(gl.TEXTURE_2D, sdfTexture);\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, size, size, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\n\n // Attach texture to framebuffer\n gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);\n gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, sdfTexture, 0);\n\n if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) !== gl.FRAMEBUFFER_COMPLETE) {\n throw new Error('Framebuffer not complete');\n }\n\n // SDF generation shader\n const vertexShaderSource = `\n attribute vec2 a_position;\n void main() {\n gl_Position = vec4(a_position, 0.0, 1.0);\n }\n `;\n\n const fragmentShaderSource = `\n precision mediump float;\n uniform vec2 u_resolution;\n uniform vec2 u_center;\n uniform float u_radius;\n\n void main() {\n vec2 coord = gl_FragCoord.xy;\n float dist = distance(coord, u_center);\n float sdf = (dist - u_radius) / u_resolution.x;\n float alpha = 0.5 + 0.5 * sdf;\n gl_FragColor = vec4(alpha, alpha, alpha, 1.0);\n }\n `;\n\n const program = createProgram(gl, vertexShaderSource, fragmentShaderSource);\n if (!program) throw new Error('Failed to create SDF shader program');\n\n gl.useProgram(program);\n\n // Create full-screen quad\n const vertices = new Float32Array([\n -1, -1,\n 1, -1,\n -1, 1,\n 1, -1,\n 1, 1,\n -1, 1\n ]);\n\n const buffer = gl.createBuffer();\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);\n\n const positionLocation = gl.getAttribLocation(program, 'a_position');\n gl.enableVertexAttribArray(positionLocation);\n gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);\n\n // Set uniforms\n const resolutionLocation = gl.getUniformLocation(program, 'u_resolution');\n const centerLocation = gl.getUniformLocation(program, 'u_center');\n const radiusLocation = gl.getUniformLocation(program, 'u_radius');\n\n gl.uniform2f(resolutionLocation, size, size);\n gl.uniform2f(centerLocation, size / 2, size / 2);\n gl.uniform1f(radiusLocation, size / 3);\n\n gl.viewport(0, 0, size, size);\n\n return benchmark('WebGL SDF Generation', () => {\n gl.clear(gl.COLOR_BUFFER_BIT);\n gl.drawArrays(gl.TRIANGLES, 0, 6);\n }, options);\n}\n\n/**\n * WebGL Glyph Blitting Performance Test\n */\nexport async function benchmarkWebGLGlyphBlitting(\n context: WebGLTestContext,\n options: BenchmarkOptions = {}\n): Promise<PerformanceResult> {\n const { gl } = context;\n\n // Simple blitting shader\n const vertexShaderSource = `\n attribute vec2 a_position;\n attribute vec2 a_texCoord;\n uniform vec2 u_offset;\n uniform vec2 u_scale;\n varying vec2 v_texCoord;\n\n void main() {\n vec2 pos = (a_position * u_scale) + u_offset;\n gl_Position = vec4(pos, 0.0, 1.0);\n v_texCoord = a_texCoord;\n }\n `;\n\n const fragmentShaderSource = `\n precision mediump float;\n uniform sampler2D u_texture;\n uniform float u_alpha;\n varying vec2 v_texCoord;\n\n void main() {\n vec4 color = texture2D(u_texture, v_texCoord);\n gl_FragColor = vec4(color.rgb, color.a * u_alpha);\n }\n `;\n\n const program = createProgram(gl, vertexShaderSource, fragmentShaderSource);\n if (!program) throw new Error('Failed to create blitting program');\n\n gl.useProgram(program);\n\n // Create glyph texture (simulating font atlas)\n const glyphTexture = gl.createTexture();\n gl.bindTexture(gl.TEXTURE_2D, glyphTexture);\n \n const glyphData = new Uint8Array(32 * 32 * 4);\n for (let i = 0; i < glyphData.length; i += 4) {\n const x = (i / 4) % 32;\n const y = Math.floor((i / 4) / 32);\n const dist = Math.sqrt((x - 16) ** 2 + (y - 16) ** 2);\n const alpha = Math.max(0, 255 - dist * 8);\n \n glyphData[i] = 255; // R\n glyphData[i + 1] = 255; // G\n glyphData[i + 2] = 255; // B\n glyphData[i + 3] = alpha; // A\n }\n\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 32, 32, 0, gl.RGBA, gl.UNSIGNED_BYTE, glyphData);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n\n // Create quad for rendering\n const vertices = new Float32Array([\n // Position, TexCoord\n -1, -1, 0, 0,\n 1, -1, 1, 0,\n -1, 1, 0, 1,\n 1, -1, 1, 0,\n 1, 1, 1, 1,\n -1, 1, 0, 1\n ]);\n\n const buffer = gl.createBuffer();\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);\n\n const positionLocation = gl.getAttribLocation(program, 'a_position');\n const texCoordLocation = gl.getAttribLocation(program, 'a_texCoord');\n\n gl.enableVertexAttribArray(positionLocation);\n gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 16, 0);\n gl.enableVertexAttribArray(texCoordLocation);\n gl.vertexAttribPointer(texCoordLocation, 2, gl.FLOAT, false, 16, 8);\n\n // Set uniforms\n const offsetLocation = gl.getUniformLocation(program, 'u_offset');\n const scaleLocation = gl.getUniformLocation(program, 'u_scale');\n const alphaLocation = gl.getUniformLocation(program, 'u_alpha');\n const textureLocation = gl.getUniformLocation(program, 'u_texture');\n\n gl.uniform1i(textureLocation, 0);\n\n const glyphCount = 50;\n return benchmark('WebGL Glyph Blitting', () => {\n gl.clear(gl.COLOR_BUFFER_BIT);\n \n for (let i = 0; i < glyphCount; i++) {\n const x = (i % 10) * 0.2 - 0.9;\n const y = Math.floor(i / 10) * 0.2 - 0.9;\n const scale = 0.03;\n \n gl.uniform2f(offsetLocation, x, y);\n gl.uniform2f(scaleLocation, scale, scale);\n gl.uniform1f(alphaLocation, 1.0);\n \n gl.drawArrays(gl.TRIANGLES, 0, 6);\n }\n }, options);\n}",
106
- "/**\n * CPU vs GPU Performance Comparison Tests\n */\n\nimport { benchmark, comparePerformance, PerformanceResult, BenchmarkOptions } from './utils/perf-utils.js';\nimport { \n benchmarkWebGPUSDF, \n benchmarkWebGPUAtlasPacking, \n benchmarkWebGPUGlyphRendering,\n initWebGPU \n} from './gpu/webgpu-perf.js';\nimport { \n benchmarkWebGLAtlasRendering, \n benchmarkWebGLSDF, \n benchmarkWebGLGlyphBlitting,\n initWebGL \n} from './gpu/webgl-perf.js';\nimport { \n benchmarkCPUSDF, \n benchmarkCPUAtlas,\n benchmarkCPUPathRendering,\n initTestFont \n} from './cpu/cpu-perf.js';\n\nexport interface ComparisonResult {\n cpu: PerformanceResult;\n webgpu?: PerformanceResult;\n webgl?: PerformanceResult;\n speedupWebGPU?: number;\n speedupWebGL?: number;\n winner: 'cpu' | 'webgpu' | 'webgl';\n}\n\n/**\n * Compare SDF generation performance\n */\nexport async function compareSDFGeneration(\n options: BenchmarkOptions = {}\n): Promise<ComparisonResult> {\n console.log('Comparing SDF generation performance...');\n \n const result: ComparisonResult = {\n cpu: await benchmarkCPUSDF(options),\n winner: 'cpu'\n };\n\n // Test WebGPU\n try {\n const webgpuContext = await initWebGPU();\n if (webgpuContext) {\n result.webgpu = await benchmarkWebGPUSDF(webgpuContext, options);\n result.speedupWebGPU = result.cpu.avgTime / result.webgpu.avgTime;\n console.log(`WebGPU SDF speedup: ${result.speedupWebGPU.toFixed(2)}x`);\n }\n } catch (error) {\n console.warn('WebGPU SDF test failed:', error);\n }\n\n // Test WebGL\n try {\n const webglContext = initWebGL();\n if (webglContext) {\n result.webgl = await benchmarkWebGLSDF(webglContext, options);\n result.speedupWebGL = result.cpu.avgTime / result.webgl.avgTime;\n console.log(`WebGL SDF speedup: ${result.speedupWebGL.toFixed(2)}x`);\n }\n } catch (error) {\n console.warn('WebGL SDF test failed:', error);\n }\n\n // Determine winner\n const speedups = [\n { name: 'cpu', speedup: 1 },\n { name: 'webgpu', speedup: result.speedupWebGPU || 0 },\n { name: 'webgl', speedup: result.speedupWebGL || 0 }\n ];\n\n const winner = speedups.reduce((prev, current) => \n current.speedup > prev.speedup ? current : prev\n );\n \n result.winner = winner.name as 'cpu' | 'webgpu' | 'webgl';\n \n return result;\n}\n\n/**\n * Compare atlas generation/packing performance\n */\nexport async function compareAtlasGeneration(\n options: BenchmarkOptions = {}\n): Promise<ComparisonResult> {\n console.log('Comparing atlas generation performance...');\n \n const result: ComparisonResult = {\n cpu: await benchmarkCPUAtlas(options),\n winner: 'cpu'\n };\n\n // Test WebGPU\n try {\n const webgpuContext = await initWebGPU();\n if (webgpuContext) {\n result.webgpu = await benchmarkWebGPUAtlasPacking(webgpuContext, options);\n result.speedupWebGPU = result.cpu.avgTime / result.webgpu.avgTime;\n console.log(`WebGPU atlas speedup: ${result.speedupWebGPU.toFixed(2)}x`);\n }\n } catch (error) {\n console.warn('WebGPU atlas test failed:', error);\n }\n\n // Test WebGL (using atlas rendering as approximation)\n try {\n const webglContext = initWebGL();\n if (webglContext) {\n result.webgl = await benchmarkWebGLAtlasRendering(webglContext, options);\n result.speedupWebGL = result.cpu.avgTime / result.webgl.avgTime;\n console.log(`WebGL atlas speedup: ${result.speedupWebGL.toFixed(2)}x`);\n }\n } catch (error) {\n console.warn('WebGL atlas test failed:', error);\n }\n\n // Determine winner\n const speedups = [\n { name: 'cpu', speedup: 1 },\n { name: 'webgpu', speedup: result.speedupWebGPU || 0 },\n { name: 'webgl', speedup: result.speedupWebGL || 0 }\n ];\n\n const winner = speedups.reduce((prev, current) => \n current.speedup > prev.speedup ? current : prev\n );\n \n result.winner = winner.name as 'cpu' | 'webgpu' | 'webgl';\n \n return result;\n}\n\n/**\n * Compare glyph rendering performance\n */\nexport async function compareGlyphRendering(\n options: BenchmarkOptions = {}\n): Promise<ComparisonResult> {\n console.log('Comparing glyph rendering performance...');\n \n const result: ComparisonResult = {\n cpu: await benchmarkCPUPathRendering(options),\n winner: 'cpu'\n };\n\n // Test WebGPU\n try {\n const webgpuContext = await initWebGPU();\n if (webgpuContext) {\n result.webgpu = await benchmarkWebGPUGlyphRendering(webgpuContext, options);\n result.speedupWebGPU = result.cpu.avgTime / result.webgpu.avgTime;\n console.log(`WebGPU glyph rendering speedup: ${result.speedupWebGPU.toFixed(2)}x`);\n }\n } catch (error) {\n console.warn('WebGPU glyph rendering test failed:', error);\n }\n\n // Test WebGL\n try {\n const webglContext = initWebGL();\n if (webglContext) {\n result.webgl = await benchmarkWebGLGlyphBlitting(webglContext, options);\n result.speedupWebGL = result.cpu.avgTime / result.webgl.avgTime;\n console.log(`WebGL glyph rendering speedup: ${result.speedupWebGL.toFixed(2)}x`);\n }\n } catch (error) {\n console.warn('WebGL glyph rendering test failed:', error);\n }\n\n // Determine winner\n const speedups = [\n { name: 'cpu', speedup: 1 },\n { name: 'webgpu', speedup: result.speedupWebGPU || 0 },\n { name: 'webgl', speedup: result.speedupWebGL || 0 }\n ];\n\n const winner = speedups.reduce((prev, current) => \n current.speedup > prev.speedup ? current : prev\n );\n \n result.winner = winner.name as 'cpu' | 'webgpu' | 'webgl';\n \n return result;\n}\n\n/**\n * Comprehensive performance comparison\n */\nexport async function runComprehensiveComparison(\n options: BenchmarkOptions = {}\n): Promise<{\n sdf: ComparisonResult;\n atlas: ComparisonResult;\n rendering: ComparisonResult;\n summary: {\n totalTests: number;\n gpuWins: number;\n cpuWins: number;\n averageSpeedup: number;\n bestGPU: 'webgpu' | 'webgl';\n };\n}> {\n console.log('Running comprehensive performance comparison...');\n \n const [sdf, atlas, rendering] = await Promise.all([\n compareSDFGeneration(options),\n compareAtlasGeneration(options),\n compareGlyphRendering(options)\n ]);\n\n // Generate summary\n const results = [sdf, atlas, rendering];\n let gpuWins = 0;\n let totalSpeedup = 0;\n let webgpuWins = 0;\n let webglWins = 0;\n\n results.forEach(result => {\n if (result.winner !== 'cpu') {\n gpuWins++;\n if (result.winner === 'webgpu') webgpuWins++;\n if (result.winner === 'webgl') webglWins++;\n }\n \n totalSpeedup += Math.max(\n result.speedupWebGPU || 0,\n result.speedupWebGL || 0,\n 1\n );\n });\n\n const summary = {\n totalTests: results.length,\n gpuWins,\n cpuWins: results.length - gpuWins,\n averageSpeedup: totalSpeedup / results.length,\n bestGPU: webgpuWins >= webglWins ? 'webgpu' : 'webgl'\n };\n\n return { sdf, atlas, rendering, summary };\n}\n\n/**\n * Create comparison report\n */\nexport function createComparisonReport(results: {\n sdf: ComparisonResult;\n atlas: ComparisonResult;\n rendering: ComparisonResult;\n summary: any;\n}): string {\n const report: string[] = [];\n \n report.push('=== CPU vs GPU Performance Comparison Report ===');\n report.push(`Generated: ${new Date().toISOString()}`);\n report.push('');\n\n // SDF Results\n report.push('SDF Generation:');\n report.push(` CPU: ${results.sdf.cpu.avgTime.toFixed(3)} ms`);\n if (results.sdf.webgpu) {\n report.push(` WebGPU: ${results.sdf.webgpu.avgTime.toFixed(3)} ms (${results.sdf.speedupWebGPU!.toFixed(2)}x speedup)`);\n }\n if (results.sdf.webgl) {\n report.push(` WebGL: ${results.sdf.webgl.avgTime.toFixed(3)} ms (${results.sdf.speedupWebGL!.toFixed(2)}x speedup)`);\n }\n report.push(` Winner: ${results.sdf.winner.toUpperCase()}`);\n report.push('');\n\n // Atlas Results\n report.push('Atlas Generation:');\n report.push(` CPU: ${results.atlas.cpu.avgTime.toFixed(3)} ms`);\n if (results.atlas.webgpu) {\n report.push(` WebGPU: ${results.atlas.webgpu.avgTime.toFixed(3)} ms (${results.atlas.speedupWebGPU!.toFixed(2)}x speedup)`);\n }\n if (results.atlas.webgl) {\n report.push(` WebGL: ${results.atlas.webgl.avgTime.toFixed(3)} ms (${results.atlas.speedupWebGL!.toFixed(2)}x speedup)`);\n }\n report.push(` Winner: ${results.atlas.winner.toUpperCase()}`);\n report.push('');\n\n // Rendering Results\n report.push('Glyph Rendering:');\n report.push(` CPU: ${results.rendering.cpu.avgTime.toFixed(3)} ms`);\n if (results.rendering.webgpu) {\n report.push(` WebGPU: ${results.rendering.webgpu.avgTime.toFixed(3)} ms (${results.rendering.speedupWebGPU!.toFixed(2)}x speedup)`);\n }\n if (results.rendering.webgl) {\n report.push(` WebGL: ${results.rendering.webgl.avgTime.toFixed(3)} ms (${results.rendering.speedupWebGL!.toFixed(2)}x speedup)`);\n }\n report.push(` Winner: ${results.rendering.winner.toUpperCase()}`);\n report.push('');\n\n // Summary\n report.push('=== Summary ===');\n report.push(`Total Tests: ${results.summary.totalTests}`);\n report.push(`GPU Wins: ${results.summary.gpuWins}`);\n report.push(`CPU Wins: ${results.summary.cpuWins}`);\n report.push(`Average Speedup: ${results.summary.averageSpeedup.toFixed(2)}x`);\n report.push(`Best GPU Technology: ${results.summary.bestGPU.toUpperCase()}`);\n\n return report.join('\\n');\n}"
107
- ],
108
- "mappings": ";;;;;;;;;;;;;IAMa,gBAqGA;AAAA;AAAA,EArGA,iBAAiB,IAAI,WAAW;AAAA,IAG5C;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAC3E;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IACzE;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IACxE;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IACxE;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IACxE;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IACxE;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAEhB;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAC3E;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAC3E;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAEjC;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAC3E;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAC3E;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAGjC;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAC3E;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAC3E;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAC3E;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAC3E;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAErE;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAC3E;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAC3E;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAC3E;AAAA,IAAG;AAAA,IAEH;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAC3E;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAE/D;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAC3E;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAC3E;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAC3E;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAC3E;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAC3E;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAC3E;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAC3E;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAC3E;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAC3E;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAE/D;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IACxE;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IACxE;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IACxE;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IACxE;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IACxE;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IACxE;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IACxE;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IACxE;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IACxE;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IACxE;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IACxE;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IACxE;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IACxE;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAEhB;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAC1E;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IACxE;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IACxE;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAC1E;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IACxE;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IACxE;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAC1E;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IACxE;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IACxE;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAC3E;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IACxE;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IACxE;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAE5D;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAC3E;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAC1E;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IACxE;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IACxE;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IACxE;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IACxE;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IACxE;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IACxE;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IACxE;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IACxE;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IACxE;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IACxE;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAEhE;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAC3E;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAC3E;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAC3E;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAC3E;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAC3E;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAC3E;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAC3E;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAC3E;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAC3E;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG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AAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;A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,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EAEzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EAEzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,KAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EAEzB,CAAC,MAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,MAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,MAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,MAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,MAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,MAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,MAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,MAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,MAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,MAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,MAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,MAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,MAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,MAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,MAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,MAAQ,CAAC,KAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,MAAQ,CAAC,IAAQ,GAAM,CAAC;AAAA,EACzB,CAAC,MAAQ,CAAC,KAAQ,GAAM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Q,OAAO;AAAA,EAC1B,IAAI,OAAO;AAAA,IAAQ,OAAO;AAAA,EAC1B,IAAI,OAAO;AAAA,IAAQ,OAAO;AAAA,EAC1B,IAAI,OAAO;AAAA,IAAQ,OAAO;AAAA,EAC1B,IAAI,OAAO;AAAA,IAAQ,OAAO;AAAA,EAC1B,IAAI,OAAO;AAAA,IAAQ,OAAO;AAAA,EAC1B,IAAI,OAAO;AAAA,IAAQ,OAAO;AAAA,EAC1B,IAAI,OAAO;AAAA,IAAQ,OAAO;AAAA,EAC1B,IAAI,OAAO;AAAA,IAAQ,OAAO;AAAA,EAC1B,IAAI,OAAO;AAAA,IAAQ,OAAO;AAAA,EAC1B,IAAI,OAAO;AAAA,IAAQ,OAAO;AAAA,EAC1B,IAAI,OAAO;AAAA,IAAQ,OAAO;AAAA,EAC1B,IAAI,OAAO;AAAA,IAAQ,OAAO;AAAA,EAC1B,IAAI,OAAO;AAAA,IAAQ,OAAO;AAAA,EAC1B,IAAI,MAAM,QAAU,MAAM;AAAA,IAAQ,OAAO;AAAA,EACzC,IAAI,OAAO;AAAA,IAAQ,OAAO;AAAA,EAC1B,IAAI,OAAO;AAAA,IAAQ,OAAO;AAAA,EAC1B,IAAI,OAAO;AAAA,IAAQ,OAAO;AAAA,EAC1B,IAAI,OAAO;AAAA,IAAQ,OAAO;AAAA,EAC1B,IAAI,OAAO;AAAA,IAAQ,OAAO;AAAA,EAC1B,IAAI,OAAO;AAAA,IAAQ,OAAO;AAAA,EAC1B,IAAI,OAAO;AAAA,IAAQ,OAAO;AAAA,EAC1B,IAAI,OAAO;AAAA,IAAQ,OAAO;AAAA,EAC1B,IAAI,OAAO;AAAA,IAAQ,OAAO;AAAA,EAC1B,IAAI,MAAM,QAAU,MAAM;AAAA,IAAQ,OAAO;AAAA,EACzC,IAAI,MAAM,QAAU,MAAM;AAAA,IAAQ,OAAO;AAAA,EACzC,IAAI,MAAM,QAAU,MAAM;AAAA,IAAQ,OAAO;AAAA,EACzC,IAAI,MAAM,QAAU,MAAM;AAAA,IAAQ,OAAO;AAAA,EACzC,IAAI,OAAO;AAAA,IAAQ,OAAO;AAAA,EAC1B,IAAI,MAAM,QAAU,MAAM;AAAA,IAAQ,OAAO;AAAA,EACzC,IAAI,OAAO;AAAA,IAAQ,OAAO;AAAA,EAC1B,IAAI,MAAM,QAAU,MAAM;AAAA,IAAQ,OAAO;AAAA,EA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",
109
- "debugId": "2CD0CEBD6834CC0A64756E2164756E21",
110
- "names": []
111
- }