Pure MoonBit FreeType-compatible font engine
Dependencies
| Format | Extension | Status | Driver |
|---|---|---|---|
| TrueType | .ttf | Full | truetype/ — glyph loading, bytecode interpreter |
| OpenType/CFF (CFF1) | .otf | Full | cff/ — CFF INDEX/DICT parsing, Type 2 charstrings |
| OpenType/CFF2 | .otf | Full | cff/ + sfnt/ — pure MoonBit CFF2 parsing, charstrings, variations, and SFNT integration |
| TrueType Collection | .ttc | Full | sfnt/ — collection header, per-face loading |
| WOFF1 | .woff | Full | sfnt/woff.mbt — zlib decompression via bikallem/compress |
| WOFF2 | .woff2 | Full | sfnt/woff2.mbt — Brotli decompression, glyf/loca + hmtx transform reconstruction, collections |
| Standalone CFF | .cff | Full | cff_loader.mbt — bare CFF without SFNT container, PS hinting |
| Type 1 (PFB/PFA) | .pfb .pfa | Full | type1/ — pure MoonBit single-master + Multiple Master parsing, hinting, and AFM/PFM-backed metrics/kerning |
| BDF (bitmap) | .bdf | Full | bdf/ — header + glyph bitmap extraction |
| PCF (bitmap) | .pcf | Full | pcf/ — TOC, properties, metrics, encodings, bitmaps |
| Color glyphs | COLR/CPAL, sbix, CBDT/CBLC | Full | color/ — MoonBit COLR/sbix/CBDT path |
| Subsystem | Reason |
|---|---|
| File I/O (ftsystem.c file operations) | Accepts Bytes instead of file paths; no I/O or OS dependency |
| FT_Library global state | Eliminated — API is stateless, no initialization needed |
| Memory allocator (FT_ALLOC/FT_FREE/FT_Memory) | Eliminated — GC handles memory |
| FT_Generic (user data hooks) | Omitted — users wrap Face in their own struct |
| OT-SVG renderer (SVG table rendering) | Not implemented — the runtime exposes SVG table metadata but does not ship an SVG rasterizer |
let font_data : Bytes = ... // font file contents
let face = @freetype.from_bytes(font_data)
// Face metadata
println(face.family_name()) // "DejaVu Sans"
println(face.num_glyphs()) // 6253
println(face.units_per_em()) // 2048
println(face.is_scalable()) // true
println(face.has_kerning()) // truelet glyph_index = @freetype.get_char_index(face, 65U) // 'A' → glyph index// Font units (no scaling)
@freetype.load_glyph(face, glyph_index, load_flags=@base.LOAD_NO_SCALE)
let outline = face.glyph().outline()
println(outline.n_points()) // number of outline points
println(outline.n_contours()) // number of contours
println(outline.points()[0].x()) // first point x coordinate
// Scaled to pixel size
@freetype.set_pixel_sizes(face, 0U, 16U) // 16 ppem
@freetype.load_glyph(face, glyph_index)
println(face.glyph().metrics().hori_advance()) // advance width in 26.6@freetype.set_pixel_sizes(face, 0U, 16U)
@freetype.load_glyph(face, glyph_index, load_flags=@base.LOAD_RENDER)
println(face.glyph().bitmap().width())
println(face.glyph().bitmap().rows())
// Or render after a separate load_glyph call.
@freetype.load_glyph(face, glyph_index, load_flags=@base.LOAD_NO_HINTING)
@freetype.render_glyph(face)
println(face.glyph().bitmap_left())
println(face.glyph().bitmap_top())
// Explicit render modes.
@freetype.render_glyph(face, mode=Mono)
@freetype.render_glyph(face, mode=Lcd)
@freetype.render_glyph(face, mode=Sdf)
// LOAD_RENDER also honors FreeType-style load targets.
@freetype.load_glyph(
face,
glyph_index,
load_flags=@base.LOAD_RENDER | @base.LOAD_TARGET_LCD,
)
// Color glyphs opt in through LOAD_COLOR and render to BGRA.
@freetype.load_glyph(face, glyph_index, load_flags=@base.LOAD_COLOR)
println(face.glyph().bitmap().pixel_mode()) // Bgralet (kern_x, kern_y) = @freetype.get_kerning(face, glyph_a, glyph_v)let format = @base.detect_format(data)
// Returns: TrueType, CffOpenType, TrueTypeCollection, Woff1, Woff2,
// Type1Pfb, Type1Pfa, CffStandalone, Bdf, Pcf, WindowsFnt, Pfr, Unknownsrc/
lib.mbt # Public API: from_bytes, get_char_index, load_glyph,
# set_pixel_sizes, get_kerning
error/ # FTError enum (~80 error codes)
fixed/ # Fixed-point math: 16.16, 26.6, 2.14, CORDIC trig, matrix ops
types/ # Shared types: Vector, BBox, Outline, Bitmap, GlyphMetrics, tags
stream/ # ByteReader: position-tracked Bytes reader
base/ # FaceRec, GlyphSlot, GlyphLoader, outline ops, format detection
smooth/ # Outline rasterizer: gray, mono, LCD, LCD_V bitmap emission
color/ # Color font table parsing, BGRA surfaces, bitmap decode helpers
sdf/ # Signed-distance-field rasterization
nativeft/ # Legacy native bridge experiments (not used by the public runtime)
sfnt/ # SFNT parsing: table directory, head, hhea, maxp, hmtx, name,
# OS/2, post, cmap (formats 0/2/4/6/8/10/12/13/14), kern,
# WOFF1, WOFF2
truetype/ # TrueType: glyph loading, loca, bytecode interpreter
cff/ # CFF: INDEX/DICT parsing, charstring loading
psaux/ # PostScript charstring interpreter (Type 2)
pshinter/ # PostScript hinting: stem alignment, blue zones
psnames/ # Glyph name ↔ Unicode mapping
type1/ # Type 1 PFB: segment parsing, eexec decryption
autofit/ # Auto-hinter: script detection, segment/edge analysis
bdf/, pcf/ # Bitmap font drivers
cache/ # Glyph/charmap LRU cache
otvalid/, gxvalid/ # OpenType and GX/AAT table validation
parity/ # Parity tests (read fonts from disk, compare with C FreeType)
bench/ # C FreeType comparison benchmark + report
benchmarks/ # MoonBit benchmarks (moon bench)
blit/ # Fast byte-level blit operations (memcpy/memset FFI)make build # Compile
make test # Run unit tests
make parity # Run parity tests against C FreeType golden data
make fmt # Format code + regenerate .mbti files
make bench # Run C vs MoonBit benchmark comparison
make clean # Remove build artifacts
make all # build + fmt + test + parity| Font | Format | Glyphs | Source |
|---|---|---|---|
| DejaVu Sans | TrueType | 6,253 | dejavu-fonts |
| Roboto Variable | TrueType | 1,326 | Google Fonts |
| Source Code Pro | CFF/OpenType | 1,568 | Adobe |
| Noto Sans JP | CFF/OpenType | 17,936 | Google Noto |
| DejaVu Sans | TTC | 6,253 × 2 | Converted from TTF |
| DejaVu Sans | WOFF1 | 6,253 | Converted from TTF |
| Source Code Pro | WOFF1 | 1,568 | Converted from OTF |
| DejaVu Sans | WOFF2 | 6,253 | Converted from TTF |
| minimal | WOFF2 (CFF) | 3 | Converted from OTF |
| minimal collection | WOFF2 TTC | 3 × 2 | Synthetic collection reconstruction fixture |
| Source Code Pro | Standalone CFF | 1,568 | Extracted CFF table |
| minimal | Standalone CFF | 3 | Extracted CFF table |
| Nimbus Sans | Type 1 PFB | 855 | URW base35 |
| GNU Unifont | BDF | 57,087 | unifoundry.com |
| Nabla | TrueType / COLR v1 | 3,655 | Google Fonts real-world COLR v1 gradient fixture |
| minimal SBIX / CBDT / COLR | Color TrueType | 3-6 | Synthetic BGRA, COLR v0/v1, and bitmap-format edge-case fixtures |
| uvs / mvar | TrueType | 4-5 | Synthetic UVS and metric-variation fixtures |
$ make parity
PARITY REPORT: MoonBit FreeType Port vs C FreeType
Total: 536 tests, 536 passed, 0 failed
Format coverage:
FULL TrueType .ttf
FULL CFF/OpenType .otf
FULL TrueType Collection .ttc
FULL WOFF1 .woff
FULL WOFF2 .woff2
FULL Standalone CFF .cff
FULL Type 1 PFB .pfb
FULL BDF Bitmap .bdf
FULL PCF Bitmap .pcf| Font | Format | MoonBit / C Ratio |
|---|---|---|
| DejaVuSans.ttf | TrueType | 0.5x (faster) |
| DejaVuSans.ttc | TrueType Collection | 0.8x (faster) |
| SourceCodePro-Regular.otf | CFF/OpenType | 0.7x (faster) |
| NotoSansJP-Regular.otf | CFF/OpenType CJK | 0.1x (faster) |
| NimbusSans-Regular.pfb | Type 1 PFB | 0.5x (faster) |
| Roboto[wdth,wght].ttf | Variable TrueType | 1.5x |
| unifont.bdf | BDF Bitmap | 2.3x |
| DejaVuSans.woff | WOFF1 | 9.9x (zlib overhead) |
make bench # Runs C FreeType + MoonBit benchmarks and generates comparison report| C FreeType | MoonBit Port |
|---|---|
| FT_Library (global state) | Eliminated — stateless API |
| FT_ALLOC/FT_FREE | GC handles memory |
| FT_Stream (file I/O) | ByteReader over Bytes |
| FT_Fixed (32-bit signed long) | Int64 newtype (avoids overflow) |
| FT_ListRec (linked list) | Array[T] |
| FT_Hash | Map[K, V] |
| FT_Driver_ClassRec (fn ptr table) | Closure-based SfntOps / Type1Ops |
| FT_CMap_ClassRec (fn ptr table) | CmapLookup enum with per-format structs |
| FT_Generic (user data) | Omitted — users wrap Face |
| src/gzip/, src/bzip2/, Brotli | bikallem/compress (zlib + brotli) |
Pure MoonBit FreeType-compatible font engine
Dependencies