| 1 |
|
- |
# Copilot Instructions — Font |
| 2 |
|
- |
|
| 3 |
|
- |
## Build & Check |
| 4 |
|
- |
|
| 5 |
|
- |
```bash |
| 6 |
|
- |
# Type-check the package (it's a library, no entry point) |
| 7 |
|
- |
odin check . -no-entry-point |
| 8 |
|
- |
|
| 9 |
|
- |
# Type-check with vet warnings (stricter) |
| 10 |
|
- |
odin check . -vet -no-entry-point |
| 11 |
|
- |
|
| 12 |
|
- |
# Run oracle comparison tests |
| 13 |
|
- |
./tests/run_tests.sh |
| 14 |
|
- |
|
| 15 |
|
- |
# Build and run a single test (e.g. the harness) |
| 16 |
|
- |
odin build tests/harness -out:tests/harness/test_harness |
| 17 |
|
- |
./tests/harness/test_harness tests/fonts/AdwaitaSans-Regular.ttf |
| 18 |
|
- |
``` |
| 19 |
|
- |
|
| 20 |
|
- |
## Architecture |
| 21 |
|
- |
|
| 22 |
|
- |
An Odin library in the `font` package, split across per-concern files. Parses and rasterizes TrueType (.ttf) and OpenType/CFF (.otf) fonts including variable fonts. Built from stb_truetype's design with coverage-accumulation rasterizer, Raph Levien's analytical Bézier flattening, and multi-channel SDF generation. |
| 23 |
|
- |
|
| 24 |
|
- |
### Source files |
| 25 |
|
- |
|
| 26 |
|
- |
- `types.odin` — structs, constants, inline big-endian readers |
| 27 |
|
- |
- `parser.odin` — font init, table lookup, CFF/buf utilities, cmap, metrics |
| 28 |
|
- |
- `shapes.odin` — glyph shape extraction (TrueType contours + CFF charstrings) |
| 29 |
|
- |
- `raster.odin` — curve flattening, scanline rasterizer, bitmap API |
| 30 |
|
- |
- `sdf.odin` — signed distance field generation |
| 31 |
|
- |
- `msdf.odin` — multi-channel SDF with edge coloring |
| 32 |
|
- |
- `svg.odin` — SVG glyph lookup |
| 33 |
|
- |
- `packing.odin` — font atlas packing, baking, oversampling |
| 34 |
|
- |
- `kern.odin` — kerning (kern table + GPOS pair adjustment) |
| 35 |
|
- |
- `gsub.odin` — OpenType GSUB glyph substitution (types 1/2/4/6/7) |
| 36 |
|
- |
- `layout.odin` — text layout engine (positioning, wrapping, alignment) |
| 37 |
|
- |
- `variations.odin` — variable font support (fvar/avar axis parsing) |
| 38 |
|
- |
- `gvar.odin` — glyph variation deltas for variable fonts |
| 39 |
|
- |
- `autohint.odin` — lightweight metrics-driven grid-fitting |
| 40 |
|
- |
- `color.odin` — COLR/CPAL color font support |
| 41 |
|
- |
- `os2_post.odin` — OS/2 metrics (weight, width, x-height) and post glyph names |
| 42 |
|
- |
- `names.odin` — font name API, UTF conversion, font matching |
| 43 |
|
- |
|
| 44 |
|
- |
### Rendering pipeline |
| 45 |
|
- |
|
| 46 |
|
- |
1. **Font init** — `init_font` parses font tables, caches offsets, detects CFF vs TrueType (stored in `is_cff` flag for dispatch throughout) |
| 47 |
|
- |
2. **Glyph lookup** — `find_glyph_index` maps Unicode codepoints → glyph indices via cmap table formats (0/2/4/6/10/12/13) |
| 48 |
|
- |
3. **GSUB** — `apply_gsub_default` / `apply_gsub_feature` apply glyph substitutions (ligatures, contextual alternates, etc.) |
| 49 |
|
- |
4. **Shape extraction** — `get_glyph_shape_tt` (TrueType contours) or `get_glyph_shape_t2`/`run_charstring` (CFF CharString interpreter) produce `Vertex` arrays |
| 50 |
|
- |
5. **Curve flattening** — `flatten_curves` dispatches to `tesselate_curve` (quadratic, uses Raph Levien analytical approach) and `tesselate_cubic` (cubic, recursive subdivision). The analytical path maps curves to canonical parabola form via `map_to_basic` |
| 51 |
|
- |
6. **Rasterization** — `rasterize` → `rasterize_sorted_edges` uses scanline active-edge with anti-aliasing |
| 52 |
|
- |
7. **SDF** — `get_glyph_sdf` generates signed distance fields via ray-intersection against Bézier curves |
| 53 |
|
- |
8. **Text layout** — `layout_text` positions glyphs with metrics, kerning, wrapping, and alignment |
| 54 |
|
- |
|
| 55 |
|
- |
### API layering |
| 56 |
|
- |
|
| 57 |
|
- |
Most functionality has two levels: a `get_codepoint_*` wrapper that calls `find_glyph_index` then delegates to the corresponding `get_glyph_*` function. When adding new features, follow this pattern. |
| 58 |
|
- |
|
| 59 |
|
- |
### Reference sources |
| 60 |
|
- |
|
| 61 |
|
- |
`ref/` contains cleaned source-only copies of related projects for reference: stb_truetype.h, fontdue (Rust), ttf-parser (Rust), msdfgen (C++), harfbuzz (C++). |
| 62 |
|
- |
|
| 63 |
|
- |
## Conventions |
| 64 |
|
- |
|
| 65 |
|
- |
- **Visibility**: Internal helpers use `@(private)`. Public API has no annotation. |
| 66 |
|
- |
- **Performance-critical helpers**: Big-endian readers (`ttBYTE`, `ttUSHORT`, `ttULONG`, etc.) and small hot-path functions use `#force_inline`. |
| 67 |
|
- |
- **Naming**: Types are `Title_Snake_Case`, procedures are `snake_case`, constants are `UPPER_SNAKE_CASE`. The `tt*` prefixed reader functions retain stb_truetype naming heritage. |
| 68 |
|
- |
- **Memory**: Public allocation functions accept `allocator := context.allocator`. Use `mem.free` for cleanup. Font data is accessed via raw pointers (`[^]u8`). |
| 69 |
|
- |
- **Error handling**: Functions return `bool` for success/failure or use sentinel values (e.g., negative offsets). No exceptions or error union types. |
| 70 |
|
- |
- **Font data**: All font data is big-endian; the `tt*` inline helpers handle byte-order conversion. |