Phase 2: Pure Rust Font Engine#
Implement a scanline rasterizer that converts glyph outlines (from the glyf table) into grayscale bitmaps suitable for rendering.
Depends on: Parse glyf and OS/2 tables (glyph outline extraction)
Outline processing#
- Convert TrueType quadratic bezier curves to monotonic segments
- Flatten bezier curves into line segments at a given resolution (adaptive or fixed subdivision)
- Scale outline coordinates from font units (units per em from head table) to target pixel size
Scanline rasterizer#
- Use a coverage-based approach: for each pixel row, compute horizontal intersections with the outline
- Apply the even-odd or non-zero winding rule to determine inside/outside
- Produce anti-aliased output: compute sub-pixel coverage as a grayscale value (0-255)
- Handle overlapping contours correctly
Output format#
GlyphBitmap { width: u32, height: u32, bearing_x: i32, bearing_y: i32, data: Vec<u8> }- Each byte is a grayscale alpha value (0 = transparent, 255 = fully opaque)
- bearing_x/bearing_y specify the offset from the glyph origin to the bitmap top-left
Public API#
Font::rasterize_glyph(glyph_id: u16, size_px: f32) -> Option<GlyphBitmap>- Scale factor:
size_px / units_per_em
Acceptance criteria#
- Rasterize basic Latin glyphs (A-Z, a-z, 0-9) at multiple sizes
- Anti-aliased output (not just binary black/white)
- Correct bearing/positioning values
- Compound glyphs rasterize correctly
- All existing tests continue to pass
-
cargo clippy --workspace -- -D warningspasses -
cargo fmt --all --checkpasses