3.4 KiB
OpenSpec Change: enterprise-font-compress-btf
- Change ID: enterprise-font-compress-btf
- Package:
@suaveplan/font-compress - Category: universal
- Target path:
universal/compression/font-compress - Status: PROPOSED
- Date: 2026-04-25
- Reference source:
/mnt/s/web/suaveplan/packages/universal/font-compress/src/packer/
Summary
Deliver @suaveplan/font-compress on the genesis branch from scratch at enterprise quality. The package implements BTF (Binary TypeFace) binary packing: takes a TypefaceFont JSON (from @suaveplan/font-convert) and produces a compact Uint8Array using dictionary-based compression with @suaveplan/bitpacker. Also provides BinaryFontUnpacker which reverses the process (BTF binary → TypefaceFont JSON).
Current-state audit (genesis)
The package does not exist on genesis. The original logic was split across @suaveplan/font-compress (packing) and @suaveplan/font-decompress (unpacking) on main. In genesis we co-locate packer and unpacker here since they share the binary format and dictionary logic.
BTF binary format
[metadata: familyName string][cssFontWeight string][cssFontStyle string]
[reversed: 1 byte]
[dictLen: uint32][dictionary: Int16Array × dictLen]
[metrics: 9 × uint16 (indexes into dictionary)]
[glyphCount: uint32]
[per glyph: char codepoint uint32][ha/x_min/x_max: 3 × uint16][cmdCount: uint16]
[per cmd: type byte + coord indexes uint16 × 2|4|0]
String encoding: [length: uint16][utf8 bytes]
Available workspace deps on genesis
| Package | Role |
|---|---|
@suaveplan/error (workspace:^) |
Base class for FontCompressError; FONT_COMPRESS.* codes |
@suaveplan/types (workspace:^) |
LoggerLike, Clock |
@suaveplan/font-convert (workspace:^) |
TypefaceFont, TypefaceGlyph, PathCommand types |
@suaveplan/bitpacker (workspace:^) |
BitWriter/BitReader for bit-packed command encoding |
zod (catalog:forms) |
Option schemas |
@opentelemetry/api (catalog:observability) |
Spans + metrics |
Public API
class FontCompressError extends SuaveplanError<FontCompressErrorCode>
type FontCompressErrorCode =
| 'FONT_COMPRESS_PACK_FAILED'
| 'FONT_COMPRESS_UNPACK_FAILED'
| 'FONT_COMPRESS_INVALID_DATA'
class BinaryFontPacker {
pack(font: TypefaceFont): Uint8Array
}
class BinaryFontUnpacker {
unpack(data: Uint8Array): TypefaceFont
}
function createBinaryFontPacker(): BinaryFontPacker
function createBinaryFontUnpacker(): BinaryFontUnpacker
File layout
universal/compression/font-compress/
package.json
tsconfig.lib.json
vitest.config.ts
vite.config.ts
src/
index.ts
error-codes.ts
constants/
index.ts
packer/
binary-font-packer/
binary-font-packer.ts
binary-font-packer.md
binary-font-packer.test.ts
index.ts
unpacker/
binary-font-unpacker/
binary-font-unpacker.ts
binary-font-unpacker.md
binary-font-unpacker.test.ts
index.ts
utils/
encode-string.ts
encode-string.md
encode-string.test.ts
parse-path.ts
parse-path.md
parse-path.test.ts
__benchmarks__/
font-compress.bench.ts
tests/
roundtrip.test.ts
property.test.ts
Impact
Downstream: Three.js font loading pipelines.
Prerequisites: @suaveplan/font-convert, @suaveplan/bitpacker.