first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,90 @@
---
name: sp-font-convert
description: Converts TTF/OTF/WOFF/WOFF2 font files to typeface.js JSON format. Defines canonical TypefaceFont, TypefaceGlyph, and PathCommand types.
---
# Font-Convert for Suaveplan
Converts TTF/OTF/WOFF/WOFF2 font files to the [typeface.js](https://gero3.github.io/facetype.js/)
JSON format used by Three.js `FontLoader`. Defines the canonical `TypefaceFont`,
`TypefaceGlyph`, and `PathCommand` types consumed by `@suaveplan/font-compress`
and `@suaveplan/font-decompress`.
## Architecture
| Component | Responsibility |
|-----------|---------------|
| `FontConverter` | Parses font binaries via `opentype.js` and converts to `TypefaceFont` with configurable character restrictions and winding reversal. |
| `BatchConverter` | Converts multiple font buffers in one call using a shared `FontConverter` instance. |
| `TypefaceFont` / `TypefaceGlyph` / `PathCommand` | Canonical shared types for the typeface.js JSON shape. |
| `outlineToString` | Serialises `PathCommand[]` back to the space-separated outline string. |
| `reverseWinding` | Reverses glyph path winding order for Three.js compatibility. |
| `FontConvertError` | Typed error carrying `FONT_CONVERT_CODES.*` via `defineCodes`. |
## File Structure
```
media/fonts/font-convert/
src/core/font-converter/ # FontConverter class + factory
src/core/batch-converter/ # BatchConverter for multi-file conversion
src/types/typeface.ts # TypefaceFont, TypefaceGlyph, PathCommand types
src/utils/outline-to-string.ts # PathCommand[] → outline string
src/utils/reverse-winding.ts # Winding order reversal
src/constants/index.ts # UPM defaults, scale factors, resolution
src/error-codes.ts # FONT_CONVERT_CODES + FontConvertError
```
Sibling packages:
- `@suaveplan/font-compress` — typeface.js JSON → BTF binary packing
- `@suaveplan/font-decompress` — BTF binary → typeface.js JSON unpacking
- `@suaveplan/font-subset` — Unicode subsetting and compression pipeline
## Patterns
### Quick Start — convert a single font
```typescript
import { createFontConverter } from "@suaveplan/font-convert";
import { readFileSync } from "node:fs";
const converter = createFontConverter();
const font = converter.convert(readFileSync("MyFont.ttf"));
console.log(font.familyName); // "MyFont"
console.log(font.cssFontWeight); // "normal" | "bold"
```
### Batch conversion
```typescript
import { BatchConverter } from "@suaveplan/font-convert";
const batch = new BatchConverter();
const results = batch.convertAll([
{ name: "Inter-Regular", data: await Bun.file("Inter.ttf").bytes() },
{ name: "Inter-Bold", data: await Bun.file("Inter-Bold.ttf").bytes() },
]);
```
### Subpath imports for tree-shaking
```typescript
import { FontConverter } from "@suaveplan/font-convert/core/font-converter";
import { BatchConverter } from "@suaveplan/font-convert/core/batch-converter";
import type { TypefaceFont, PathCommand } from "@suaveplan/font-convert/types/typeface";
```
## Constraints
- **Uses `opentype.js`** — the parser dependency is the only external runtime dep beyond `@suaveplan/*` packages.
- **Injectable `parse` function** — `FontConverter` accepts `options.parse` so tests can stub `opentype.parse` without monkey-patching.
- **Scales to resolution 1000** — all glyph coordinates and metrics are scaled from the font's UPM to a fixed resolution of 1000.
- **`reverseTypeface` option** — reverses glyph winding order via `reverseWinding` for Three.js counter-clockwise expectations.
- **Error codes go through `defineCodes`** — `FONT_CONVERT_CODES` is produced by `defineCodes("FONT_CONVERT", [...])`; never hand-write the string literal.
## Checklist
1. Use `createFontConverter` for single-font conversion; use `BatchConverter` for build pipelines that process many fonts.
2. Import `TypefaceFont` and `PathCommand` types from `@suaveplan/font-convert` when building tools that consume or produce typeface.js JSON.
3. Pass `reverseTypeface: true` when the output is destined for Three.js `FontLoader`.
4. Import from subpath exports rather than deep `src/` paths for tree-shakeability.