font

    TrueType/OTF(CFF)/WOFF/WOFF2 font parser for MoonBit

    font
    ttf
    woff
    woff2
    opentype
    otf
    cff
    Download zip
    Author
    Version
    0.7.4
    License
    Apache-2.0
    Last updated
    last month
    Downloads
    30K

    #mizchi/font

    TrueType/OTF(CFF)/WOFF/WOFF2 font parser written in MoonBit.

    Parses font binary data and converts glyph outlines to @svg.PathCommand (from mizchi/svg).

    #Usage

    let data : Bytes = ... // TTF, OTF, WOFF, WOFF2, or TTC file bytes
    let font = @font.parse_font(data).unwrap()

    // Get glyph outline as SVG path commands
    let cmds = font.scaled_outline('A'.to_int(), 48.0)

    // Get glyph metrics
    let gid = font.glyph_index('A'.to_int())
    let metrics = font.glyph_metrics(gid)

    // Text layout with kerning
    let positions = font.layout_text("Hello", 48.0)
    let width = font.measure_text("Hello", 48.0)

    // Variable font with axis values
    let cmds = font.char_outline_at('A'.to_int(), { "wght": 700.0 })

    // Vertical text layout
    let vpositions = font.layout_text_vertical("縦書き", 48.0)
    let vheight = font.measure_text_vertical("縦書き", 48.0)

    // Font subsetting (glyf-based TrueType only)
    let subset = @font.subset_font(data, [0x41, 0x42, 0x43]) // A, B, C

    #Supported Specifications

    This library covers the core OpenType tables needed for glyph rendering, metrics, variable fonts, and text layout (horizontal and vertical). Latin, CJK, and other scripts that don't require complex shaping work well out of the box.

    #Font Formats

    FormatNotes
    TTF (TrueType)✅sfnt flavor 0x00010000 and 0x74727565
    OTF (OpenType/CFF)✅sfnt flavor OTTO
    WOFF1✅zlib decompression
    WOFF2✅Brotli decompression with glyf/loca/hmtx transforms
    TTC/OTC (Font Collections)✅Index-based or first-font access

    #OpenType Tables

    #✅ Parsed

    TableDescription
    headunits_per_em, indexToLocFormat
    maxpnumGlyphs
    hheaascent, descent, lineGap, numOfLongHorMetrics
    hmtxadvanceWidth, leftSideBearing per glyph
    cmapFormat 0, 4 (BMP), 6, and 12 (full Unicode)
    locaShort and long formats
    glyfSimple and compound glyphs
    CFF Type 2 charstrings with subroutines
    CFF2Variable font support with blend/vsindex
    fvarAxis definitions (wght, wdth, opsz, etc.)
    avarPiecewise linear axis value mapping
    gvarTrueType delta interpolation with IUP
    kernFormat 0 horizontal pairs
    nameWindows Unicode, Unicode platform, Mac Roman
    OS/2Weight/width class, PANOSE, x-height, cap-height
    postItalic angle, fixed pitch, glyph names (v2.0)
    vhea/vmtxVertical metrics — advance heights and top side bearings
    gaspGrid-fitting and scan-conversion ranges
    VORGVertical origin Y coordinates for CFF glyphs

    #❌ Not Parsed

    The tables below are not parsed. Most of them are only needed for advanced use cases.

    🔤 Complex Text Shaping — Required for scripts with context-dependent glyph forms: Arabic, Hebrew, Devanagari, Thai, etc. Also needed for OpenType features like ligatures (fi → fi), stylistic alternates, and advanced kerning. Latin and CJK text renders correctly without these.

    TableDescription
    GSUBGlyph substitution — ligatures, contextual alternates, localized forms
    GPOSGlyph positioning — pair adjustment, mark-to-base, mark-to-mark
    GDEFGlyph definition — glyph classes, ligature caret positions, mark sets
    BASEBaseline offsets for mixing scripts (e.g. Latin + CJK in one line)
    JSTFJustification alternatives for full-justified text

    🎨 Color & Emoji — Required for rendering color emoji and multi-color glyphs. Not needed for monochrome text rendering.

    TableDescription
    COLR/CPALColor layers with palettes (COLRv0/v1 color fonts)
    SVG SVG glyph documents (SVG-in-OpenType color fonts)
    CBDT/CBLCColor bitmap glyphs (Google/Android emoji)
    sbixApple bitmap glyphs (Apple emoji)
    EBDT/EBLCMonochrome/grayscale embedded bitmaps (legacy low-res screens)

    📐 Specialized Rendering — Needed only for specific rendering scenarios.

    TableDescription
    MATHMath layout constants and glyph assembly — only for TeX-like math typesetting engines
    cvt/fpgm/prepTrueType hinting programs — grid-fitting instructions for low-DPI rasterization. Irrelevant for SVG/vector output
    hdmxPre-computed device widths for specific PPEMs — legacy optimization for bitmap rendering

    🍎 Apple AAT — Apple-proprietary layout system. Most modern fonts use OpenType (GSUB/GPOS) instead. Only found in macOS system fonts and some legacy fonts.

    TableDescription
    morx/mortApple Advanced Typography — state-machine-based shaping

    🔒 Other — Rarely needed for rendering or layout.

    TableDescription
    DSIGDigital signature — font authenticity verification, does not affect rendering
    cvarCVT variations — hinting value adjustments in variable fonts, only relevant if hinting is executed

    #CFF / CFF2 Charstring Operators

    All standard operators for outline extraction are supported:

    CategoryOperators
    Move✅rmoveto, hmoveto, vmoveto
    Line✅rlineto, hlineto, vlineto
    Curve✅rrcurveto, hhcurveto, vvcurveto, hvcurveto, vhcurveto
    Mixed✅rcurveline, rlinecurve
    Flex✅flex, hflex, vflex, hflex1, flex1
    Hint✅hstem, vstem, hstemhm, vstemhm, hintmask, cntrmask
    Subroutine✅callsubr, callgsubr, return
    Arithmetic✅add, sub, mul, div, neg, abs, sqrt, eq
    Logic✅and, or, not, ifelse
    Stack✅dup, exch, drop, index, roll, put, get
    CFF2 Variation✅blend, vsindex
    Control✅endchar
    Deprecated➖seac, dotsection — removed from modern specs

    #Glyph Outlines

    FeatureNotes
    Simple glyphs (TrueType)✅
    Compound glyphs (TrueType)✅Scale, 2x2 matrix, XY offset transforms
    CFF1 charstrings✅Local/global subroutines
    CFF2 charstrings✅Blend interpolation
    TrueType variations (gvar)✅Shared tuples, IUP, delta unpacking
    CFF2 variations (ItemVariationStore)✅Region scalars, blend deltas
    Hinting / instruction execution❌Not needed for vector/SVG output

    #cmap Formats

    Formats 0, 4, 6, and 12 cover virtually all modern fonts. The unsupported formats are legacy or niche:

    FormatCoverage
    Format 0✅Mac Roman 256-char
    Format 4✅BMP (U+0000–U+FFFF)
    Format 6✅Trimmed table
    Format 12✅Full Unicode (preferred when available)
    Format 2❌CJK mixed 8/16-bit — obsolete encoding, replaced by Format 12
    Format 14❌Unicode Variation Sequences — needed for CJK glyph variants (e.g. JP vs CN forms)

    #Kerning

    The kern table Format 0 covers most Latin fonts. GPOS-based kerning requires the OpenType layout engine (GSUB/GPOS), which is a significantly larger scope:

    FeatureNotes
    kern table Format 0 (flat pairs)✅Covers most Latin fonts
    kern table Format 1 (Apple state machine)❌Apple-only, rare in cross-platform fonts
    GPOS pair adjustment (PairPos)❌More precise than kern, used by modern fonts
    GPOS contextual kerning❌Context-dependent spacing adjustments

    #Font Subsetting

    Subsetting extracts only the glyphs you need, reducing file size for web delivery:

    FeatureNotes
    Glyf-based TrueType subsetting✅
    Compound glyph dependency resolution✅
    Glyph ID remapping✅
    cmap Format 12 rebuild✅
    Table copy (head, hhea, hmtx, maxp, name, OS/2, post)✅
    CFF/CFF2 subsetting❌CFF charstring rewriting is complex
    WOFF/WOFF2 output❌Outputs raw sfnt — wrap with external compressor
    Layout table subsetting (GSUB/GPOS)❌Requires lookup/coverage rewriting

    #Text Layout

    Horizontal LTR text with kerning and vertical top-to-bottom text are fully supported. The unsupported features represent a full text shaping engine (like HarfBuzz), which is a separate domain:

    FeatureNotes
    Horizontal advance widths✅
    Pair kerning (kern table)✅
    UTF-16 surrogate pair handling✅
    Text width measurement✅
    OpenType shaping (GSUB/GPOS)❌Full shaping engine — needed for Arabic, Devanagari, ligatures
    Bidirectional text❌Unicode BiDi algorithm — needed for mixed LTR/RTL text
    Vertical layout✅Top-to-bottom CJK typesetting (vhea/vmtx/VORG)
    Line breaking❌Text wrapping — typically handled by the application layer

    #JS Bindings (Wasm)

    13 exported functions:

    FunctionReturnsDescription
    loadFont(data)JSON stringParse font, return metrics
    getFontInfo()JSON stringGet cached font info
    glyphToSvgPath(codepoint, fontSize)SVG path stringScaled glyph outline
    glyphAdvance(codepoint, fontSize)DoubleScaled advance width
    fontName(nameId)StringName table lookup
    kernAdvance(cp1, cp2, fontSize)DoubleScaled kerning value
    layoutText(text, fontSize)JSON stringGlyph positions with kerning
    measureText(text, fontSize)DoubleTotal text width
    fontWeightClass()IntOS/2 weight class
    isFixedPitch()Int (0/1)Post table fixed-pitch flag
    codepointCoverage()JSON stringAll supported codepoints
    glyphIds()JSON stringAll glyph IDs (0 to numGlyphs-1)
    tableSizes()JSON stringTable tag to byte size

    #Development

    # Download test fixtures and run tests just test # Or manually bash scripts/download-fixtures.sh moon test # Type check just check # Format code just fmt

    NotoSans font files are not committed to the repository. They are downloaded from GitHub Releases on first run.

    #Dependencies

    #Test Fonts

    fixtures/NotoSansMono-Regular.ttf is licensed under the SIL Open Font License.

    #License

    Apache-2.0

    AtlasPageInfo

    pub(all) struct AtlasPageInfo {
    page_id : Int
    width : Int
    height : Int
    dirty : Bool
    }

    BinaryReader

    pub(all) struct BinaryReader {
    data : Bytes
    pos : Int
    }

    BinaryReader::at

    fn BinaryReader::at(data : Bytes, pos : Int) -> BinaryReader

    BinaryReader::new

    fn BinaryReader::new(data : Bytes) -> BinaryReader

    BinaryReader::peek_int16_at

    fn BinaryReader::peek_int16_at(self : BinaryReader, offset : Int) -> Int

    BinaryReader::peek_uint16_at

    fn BinaryReader::peek_uint16_at(self : BinaryReader, offset : Int) -> Int

    BinaryReader::peek_uint32_at

    fn BinaryReader::peek_uint32_at(self : BinaryReader, offset : Int) -> Int

    BinaryReader::position

    fn BinaryReader::position(self : BinaryReader) -> Int

    BinaryReader::read_f16dot16

    fn BinaryReader::read_f16dot16(self : BinaryReader) -> Double

    BinaryReader::read_f2dot14

    fn BinaryReader::read_f2dot14(self : BinaryReader) -> Double

    BinaryReader::read_int16

    fn BinaryReader::read_int16(self : BinaryReader) -> Int

    BinaryReader::read_int8

    fn BinaryReader::read_int8(self : BinaryReader) -> Int

    BinaryReader::read_tag

    fn BinaryReader::read_tag(self : BinaryReader) -> String

    BinaryReader::read_uint16

    fn BinaryReader::read_uint16(self : BinaryReader) -> Int

    BinaryReader::read_uint32

    fn BinaryReader::read_uint32(self : BinaryReader) -> Int

    BinaryReader::read_uint8

    fn BinaryReader::read_uint8(self : BinaryReader) -> Int

    BinaryReader::seek

    fn BinaryReader::seek(self : BinaryReader, pos : Int) -> Unit

    BinaryReader::skip

    fn BinaryReader::skip(self : BinaryReader, n : Int) -> Unit

    CFFData

    pub(all) struct CFFData {
    charstrings : CFFIndex
    global_subrs : CFFIndex
    local_subrs : CFFIndex
    default_width_x : Int
    nominal_width_x : Int
    is_cff2 : Bool
    ivs : ItemVariationStore?
    }

    CFFIndex

    pub(all) struct CFFIndex {
    data_offset : Int
    offsets : Array[Int]
    }

    FontFormat

    pub enum FontFormat {
    TrueType
    OpenType
    Woff1
    Woff2
    TrueTypeCollection
    Unknown
    } derive(Eq)

    impl Show for FontFormat

    FontKey

    pub(all) struct FontKey {
    family : String
    weight : Int
    italic : Bool
    }

    impl Show for FontKey

    GaspRange

    pub(all) struct GaspRange {
    max_ppem : Int
    behavior : Int
    }

    Glyph

    pub(all) struct Glyph {
    glyph_id : Int
    metrics : GlyphMetrics
    outline : Array[
    PathCommand
    ]
    }

    GlyphAtlas

    pub struct GlyphAtlas {
    cache : GlyphCache
    width : Int
    height : Int
    pixels : Array[Int]
    dirty : Bool
    last_used_generation : Int
    }

    GlyphAtlas::deserialize

    fn GlyphAtlas::deserialize(data : Array[Int]) -> GlyphAtlas?

    Deserialize a GlyphAtlas from a flat Int array.

    GlyphAtlas::get_cache

    fn GlyphAtlas::get_cache(self : GlyphAtlas) -> GlyphCache

    GlyphAtlas::get_pixels

    fn GlyphAtlas::get_pixels(self : GlyphAtlas) -> Array[Int]

    GlyphAtlas::new

    fn GlyphAtlas::new(width : Int, height : Int, page_id : Int) -> GlyphAtlas

    GlyphAtlas::rasterize_glyph

    fn GlyphAtlas::rasterize_glyph(self : GlyphAtlas, font : TTFont, codepoint : Int, size_px : Double) -> GlyphCacheEntry?

    Rasterize a single glyph and place it into the atlas.

    GlyphAtlas::serialize

    fn GlyphAtlas::serialize(self : GlyphAtlas) -> Array[Int]

    Serialize a GlyphAtlas to a flat Int array for persistent caching.

    GlyphBBox

    pub(all) struct GlyphBBox {
    x_min : Int
    y_min : Int
    x_max : Int
    y_max : Int
    }

    GlyphBitmap

    pub struct GlyphBitmap {
    width : Int
    height : Int
    pixels : Array[Int]
    }

    Rasterized glyph pixel data (RGBA8 flat array: [r,g,b,a, r,g,b,a, ...]).
    impl Show for GlyphBitmap

    GlyphCache

    pub struct GlyphCache {
    entries : Map[Int, GlyphCacheEntry]
    next_x : Double
    next_y : Double
    row_height : Double
    atlas_width : Double
    atlas_height : Double
    atlas_page_id : Int
    }

    GlyphCache::allocate

    fn GlyphCache::allocate(self : GlyphCache, glyph_id : Int, width : Double, height : Double) -> GlyphCacheEntry?

    Allocate space in the atlas for a glyph. Returns the cache entry, or None if the atlas is full.

    GlyphCache::clear

    fn GlyphCache::clear(self : GlyphCache) -> Unit

    GlyphCache::entry_count

    fn GlyphCache::entry_count(self : GlyphCache) -> Int

    GlyphCache::get

    fn GlyphCache::get(self : GlyphCache, glyph_id : Int) -> GlyphCacheEntry?

    GlyphCache::new

    fn GlyphCache::new(atlas_width : Double, atlas_height : Double, atlas_page_id : Int) -> GlyphCache

    GlyphCacheEntry

    pub(all) struct GlyphCacheEntry {
    glyph_id : Int
    atlas_x : Double
    atlas_y : Double
    atlas_w : Double
    atlas_h : Double
    atlas_page_id : Int
    }

    GlyphMetrics

    pub(all) struct GlyphMetrics {
    advance_width : Int
    left_side_bearing : Int
    bbox : GlyphBBox
    }

    GlyphPosition

    pub(all) struct GlyphPosition {
    codepoint : Int
    glyph_id : Int
    x_offset : Double
    y_offset : Double
    x_advance : Double
    }

    GlyphQuad

    pub(all) struct GlyphQuad {
    glyph_id : Int
    atlas_x : Double
    atlas_y : Double
    atlas_w : Double
    atlas_h : Double
    dst_x : Double
    dst_y : Double
    dst_w : Double
    dst_h : Double
    }

    impl Show for GlyphQuad

    GvarData

    pub(all) struct GvarData {
    axis_count : Int
    shared_tuples : Array[Array[Double]]
    gvar_offset : Int
    glyph_var_data_offset : Int
    glyph_offsets : Array[Int]
    }

    ItemVariationData

    pub(all) struct ItemVariationData {
    region_indices : Array[Int]
    delta_sets : Array[Array[Int]]
    }

    ItemVariationStore

    pub(all) struct ItemVariationStore {
    regions : Array[VarRegion]
    data : Array[ItemVariationData]
    }

    OS2Table

    pub(all) struct OS2Table {
    version : Int
    us_weight_class : Int
    us_width_class : Int
    fs_type : Int
    panose : FixedArray[Int]
    ul_unicode_range1 : Int
    ul_unicode_range2 : Int
    ul_unicode_range3 : Int
    ul_unicode_range4 : Int
    fs_selection : Int
    s_typo_ascender : Int
    s_typo_descender : Int
    s_typo_line_gap : Int
    us_win_ascent : Int
    us_win_descent : Int
    sx_height : Int
    s_cap_height : Int
    }

    PostTable

    pub(all) struct PostTable {
    italic_angle : Double
    underline_position : Int
    underline_thickness : Int
    is_fixed_pitch : Bool
    glyph_names : Array[String]
    }

    TTFont

    pub(all) struct TTFont {
    units_per_em : Int
    index_to_loc_format : Int
    num_glyphs : Int
    ascent : Int
    descent : Int
    line_gap : Int
    num_h_metrics : Int
    glyf_offset : Int
    data : Bytes
    cmap : Map[Int, Int]
    loca : Array[Int]
    advance_widths : Array[Int]
    left_side_bearings : Array[Int]
    cff : CFFData?
    gvar : GvarData?
    var_axes : Array[VarAxis]
    kern_pairs : Map[Int, Int]
    avar_segments : Array[Array[(Double, Double)]]
    name_records : Map[Int, String]
    os2 : OS2Table?
    post : PostTable?
    vertical : VerticalMetrics?
    gasp : Array[GaspRange]
    vorg : VorgData?
    }

    TTFont::cap_height

    fn TTFont::cap_height(self : TTFont) -> Int

    Get cap-height from OS/2 table

    TTFont::char_outline

    fn TTFont::char_outline(self : TTFont, codepoint : Int) -> Array[
    PathCommand
    ]

    TTFont::char_outline_at

    fn TTFont::char_outline_at(self : TTFont, codepoint : Int, axis_values : Map[String, Double]) -> Array[
    PathCommand
    ]

    TTFont::codepoint_coverage

    fn TTFont::codepoint_coverage(self : TTFont) -> Array[Int]

    Get all codepoints covered by the font's cmap

    TTFont::font_name

    fn TTFont::font_name(self : TTFont, name_id : Int) -> String?

    Get font name by nameID (1=family, 2=subfamily, 4=full name, 6=postscript name)

    TTFont::get_glyph

    fn TTFont::get_glyph(self : TTFont, codepoint : Int) -> Glyph

    TTFont::glyph_ids

    fn TTFont::glyph_ids(self : TTFont) -> Array[Int]

    Get all glyph IDs in the font (0 to num_glyphs-1)

    TTFont::glyph_index

    fn TTFont::glyph_index(self : TTFont, codepoint : Int) -> Int

    TTFont::glyph_metrics

    fn TTFont::glyph_metrics(self : TTFont, glyph_id : Int) -> GlyphMetrics

    TTFont::glyph_metrics_at

    fn TTFont::glyph_metrics_at(self : TTFont, glyph_id : Int, axis_values : Map[String, Double]) -> GlyphMetrics

    Get glyph metrics with variable font interpolation. For glyf+gvar fonts, advance width is interpolated via phantom points. For CFF2 fonts, bbox is computed from the variable outline (advance uses static value).

    TTFont::glyph_name

    fn TTFont::glyph_name(self : TTFont, glyph_id : Int) -> String

    Get glyph name from post table

    TTFont::glyph_outline

    fn TTFont::glyph_outline(self : TTFont, glyph_id : Int) -> Array[
    PathCommand
    ]

    TTFont::glyph_outline_at

    fn TTFont::glyph_outline_at(self : TTFont, glyph_id : Int, axis_values : Map[String, Double]) -> Array[
    PathCommand
    ]

    TTFont::is_fixed_pitch

    fn TTFont::is_fixed_pitch(self : TTFont) -> Bool

    Check if font is fixed-pitch from post table

    TTFont::italic_angle

    fn TTFont::italic_angle(self : TTFont) -> Double

    Get italic angle from post table

    TTFont::kern_pair

    fn TTFont::kern_pair(self : TTFont, left_gid : Int, right_gid : Int) -> Int

    Get kerning value for a pair of glyph IDs

    TTFont::layout_text

    fn TTFont::layout_text(self : TTFont, text : String, font_size : Double) -> Array[GlyphPosition]

    Layout text into positioned glyphs with kerning

    TTFont::layout_text_vertical

    fn TTFont::layout_text_vertical(self : TTFont, text : String, font_size : Double) -> Array[GlyphPosition]

    Layout text vertically (top-to-bottom) into positioned glyphs

    TTFont::measure_text

    fn TTFont::measure_text(self : TTFont, text : String, font_size : Double) -> Double

    Measure total text width

    TTFont::measure_text_vertical

    fn TTFont::measure_text_vertical(self : TTFont, text : String, font_size : Double) -> Double

    Measure total text height for vertical layout

    TTFont::scaled_outline

    fn TTFont::scaled_outline(self : TTFont, codepoint : Int, font_size : Double) -> Array[
    PathCommand
    ]

    TTFont::vert_origin_y

    fn TTFont::vert_origin_y(self : TTFont, glyph_id : Int) -> Int

    Get vertical origin Y for a glyph (design units)

    TTFont::weight_class

    fn TTFont::weight_class(self : TTFont) -> Int

    Get weight class from OS/2 table (400=Regular, 700=Bold)

    TTFont::x_height

    fn TTFont::x_height(self : TTFont) -> Int

    Get x-height from OS/2 table

    TableInfo

    pub(all) struct TableInfo {
    tag : String
    offset : Int
    length : Int
    }

    TextMetrics

    pub(all) struct TextMetrics {
    width : Double
    height : Double
    baseline : Double
    }

    impl Show for TextMetrics

    TextRenderer

    pub struct TextRenderer {
    pages : Array[GlyphAtlas]
    font : TTFont
    pipeline_id : Int
    atlas_size : Int
    base_page_id : Int
    max_pages : Int
    generation : Int
    }

    TextRenderer::clear

    fn TextRenderer::clear(self : TextRenderer) -> Unit

    TextRenderer::ensure_glyph

    fn TextRenderer::ensure_glyph(self : TextRenderer, codepoint : Int, size_px : Double) -> (Int, GlyphCacheEntry)?

    Ensure a glyph is rasterized and cached. Returns the page index and cache entry. Used by GPU renderers to build draw commands.

    TextRenderer::flush_dirty_pages

    fn TextRenderer::flush_dirty_pages(self : TextRenderer) -> Array[AtlasPageInfo]

    TextRenderer::get_atlas

    fn TextRenderer::get_atlas(self : TextRenderer) -> GlyphAtlas

    TextRenderer::get_page

    fn TextRenderer::get_page(self : TextRenderer, index : Int) -> GlyphAtlas

    TextRenderer::get_page_id

    fn TextRenderer::get_page_id(self : TextRenderer) -> Int

    TextRenderer::get_page_ids

    fn TextRenderer::get_page_ids(self : TextRenderer) -> Array[Int]

    TextRenderer::glyph_count

    fn TextRenderer::glyph_count(self : TextRenderer) -> Int

    TextRenderer::load_cache

    fn TextRenderer::load_cache(self : TextRenderer, pages_data : Array[Array[Int]]) -> Int

    Restore atlas pages from serialized data. Returns number of pages loaded.

    TextRenderer::measure

    fn TextRenderer::measure(self : TextRenderer, text : String, size_px : Double) -> TextMetrics

    TextRenderer::new

    fn TextRenderer::new(font : TTFont, atlas_size : Int, base_page_id : Int, pipeline_id : Int) -> TextRenderer

    TextRenderer::new_with_options

    fn TextRenderer::new_with_options(font : TTFont, atlas_size : Int, base_page_id : Int, pipeline_id : Int, max_pages : Int) -> TextRenderer

    TextRenderer::page_count

    fn TextRenderer::page_count(self : TextRenderer) -> Int

    TextRenderer::serialize_cache

    fn TextRenderer::serialize_cache(self : TextRenderer) -> Array[Array[Int]]

    Serialize all pages of a TextRenderer.

    TextRun

    pub(all) struct TextRun {
    text : String
    style : TextStyle
    }

    impl Show for TextRun

    TextStyle

    pub(all) struct TextStyle {
    font : FontKey
    size_px : Double
    line_height : Double
    letter_spacing : Double
    }

    impl Show for TextStyle

    VarAxis

    pub(all) struct VarAxis {
    tag : String
    min_value : Double
    default_value : Double
    max_value : Double
    }

    VarRegion

    pub(all) struct VarRegion {
    axes : Array[VarRegionAxis]
    }

    VarRegionAxis

    pub(all) struct VarRegionAxis {
    start_coord : Double
    peak_coord : Double
    end_coord : Double
    }

    VerticalMetrics

    pub(all) struct VerticalMetrics {
    v_ascent : Int
    v_descent : Int
    advance_heights : Array[Int]
    top_side_bearings : Array[Int]
    }

    VorgData

    pub(all) struct VorgData {
    default_vert_origin_y : Int
    vert_origins : Map[Int, Int]
    }

    analyze_tables

    fn analyze_tables(data : Bytes) -> Array[TableInfo]?

    Analyze sfnt table directory without full parsing

    blit_to_atlas

    fn blit_to_atlas(atlas_pixels : Array[Int], atlas_width : Int, src : GlyphBitmap, dst_x : Int, dst_y : Int) -> Unit

    Copy a GlyphBitmap into a larger pixel array at the given position.

    bytes_slice

    fn bytes_slice(data : Bytes, offset : Int, length : Int) -> Bytes

    Copy a slice of Bytes

    calc_table_checksum

    fn calc_table_checksum(data : Bytes) -> Int

    Calculate table checksum per OpenType spec

    compute_path_bbox

    fn compute_path_bbox(cmds : Array[
    PathCommand
    ]) -> GlyphBBox

    Compute bounding box from path commands. Calculates exact bounds including cubic/quadratic bezier curve extrema.

    default_text_style

    fn default_text_style(family : String, size_px : Double) -> TextStyle

    detect_font_format

    fn detect_font_format(data : Bytes) -> FontFormat

    log2_floor

    fn log2_floor(n : Int) -> Int

    Floor of log2(n), minimum 0

    make_glyph_cache_key

    fn make_glyph_cache_key(glyph_id : Int, size_px : Double) -> Int

    Create a composite cache key from glyph_id and size_px. Quantizes size to 0.1px precision (supports sizes 0-4095px, glyph IDs 0-524287).

    new_text_run

    fn new_text_run(text : String, style : TextStyle) -> TextRun

    outline_bbox

    fn outline_bbox(commands : Array[
    PathCommand
    ]) -> (Double, Double, Double, Double)

    Compute bounding box from outline path commands.

    pad4

    fn pad4(n : Int) -> Int

    Round up to next multiple of 4

    parse_avar

    fn parse_avar(reader : BinaryReader, offset : Int, axis_count : Int) -> Array[Array[(Double, Double)]]

    Parse avar table: returns per-axis segment maps

    parse_cmap

    fn parse_cmap(reader : BinaryReader, offset : Int) -> Map[Int, Int]

    Parse cmap table: returns Map[codepoint -> glyph_id] Prefers Format 12 (full Unicode) over Format 4 (BMP only)

    parse_font

    fn parse_font(data : Bytes) -> TTFont?

    Parse a font from raw bytes, auto-detecting format (TTF, OTF, or WOFF1)

    parse_font_at

    fn parse_font_at(data : Bytes, index : Int) -> TTFont?

    Parse a single font from a TTC/OTC collection by index

    parse_font_collection

    fn parse_font_collection(data : Bytes) -> Array[TTFont]?

    Parse a TTC/OTC font collection, returning all fonts

    parse_fvar

    fn parse_fvar(reader : BinaryReader, offset : Int) -> Array[VarAxis]

    Parse fvar table: returns array of variation axes

    parse_gasp

    fn parse_gasp(reader : BinaryReader, offset : Int) -> Array[GaspRange]

    Parse gasp table: returns array of GaspRange records

    parse_head

    fn parse_head(reader : BinaryReader, offset : Int) -> (Int, Int)

    Parse head table: returns (units_per_em, index_to_loc_format)

    parse_hhea

    fn parse_hhea(reader : BinaryReader, offset : Int) -> (Int, Int, Int, Int)

    Parse hhea table: returns (ascent, descent, line_gap, num_h_metrics)

    parse_hmtx

    fn parse_hmtx(reader : BinaryReader, offset : Int, num_glyphs : Int, num_h_metrics : Int) -> (Array[Int], Array[Int])

    Parse hmtx table: returns (advance_widths, left_side_bearings)

    parse_kern

    fn parse_kern(reader : BinaryReader, offset : Int) -> Map[Int, Int]

    Parse kern table (format 0, horizontal only): returns Map[key -> value] Key = (left_gid << 16) | right_gid

    parse_loca

    fn parse_loca(reader : BinaryReader, offset : Int, num_glyphs : Int, format : Int) -> Array[Int]

    Parse loca table: returns array of glyph offsets into glyf table

    parse_maxp

    fn parse_maxp(reader : BinaryReader, offset : Int) -> Int

    Parse maxp table: returns num_glyphs

    parse_name

    fn parse_name(reader : BinaryReader, offset : Int) -> Map[Int, String]

    Parse name table: returns Map[nameID -> string] Prefers platformID=3/encodingID=1 (Windows Unicode BMP, UTF-16BE)

    parse_os2

    fn parse_os2(reader : BinaryReader, offset : Int) -> OS2Table

    Parse OS/2 table

    parse_post

    fn parse_post(reader : BinaryReader, offset : Int, num_glyphs : Int) -> PostTable

    Parse post table

    parse_ttf

    fn parse_ttf(data : Bytes) -> TTFont?

    Parse a TrueType/OpenType font from raw bytes

    parse_vhea

    fn parse_vhea(reader : BinaryReader, offset : Int) -> (Int, Int, Int)

    Parse vhea table: returns (v_ascent, v_descent, num_v_metrics)

    parse_vmtx

    fn parse_vmtx(reader : BinaryReader, offset : Int, num_glyphs : Int, num_v_metrics : Int) -> (Array[Int], Array[Int])

    Parse vmtx table: returns (advance_heights, top_side_bearings)

    parse_vorg

    fn parse_vorg(reader : BinaryReader, offset : Int) -> VorgData

    Parse VORG table: returns VorgData with default origin and per-glyph overrides

    parse_woff1

    fn parse_woff1(data : Bytes) -> TTFont?

    Parse a WOFF1 font, decompress tables, rebuild sfnt, and delegate to parse_ttf

    parse_woff2

    fn parse_woff2(data : Bytes) -> TTFont?

    Parse a WOFF2 font, decompress tables, reconstruct transforms, and delegate to parse_ttf

    path_commands_to_svg_d

    fn path_commands_to_svg_d(commands : Array[
    PathCommand
    ]) -> String

    Convert font outline PathCommands to SVG path d attribute string.

    rasterize_glyph

    fn rasterize_glyph(font : TTFont, codepoint : Int, size_px : Double) -> GlyphBitmap?

    Rasterize a glyph outline to a pixel bitmap using SVG rendering. Returns None for glyphs with no outline (e.g., space).

    rebuild_sfnt

    fn rebuild_sfnt(flavor : Int, tables : Array[(String, Bytes)]) -> Bytes

    Rebuild an sfnt (TrueType/OpenType) binary from individual table data. Produces: Offset Table (12 bytes) + Table Records (16 bytes x n) + Table Data (4-byte aligned)

    scale_commands

    fn scale_commands(commands : Array[
    PathCommand
    ], scale : Double, flip_y : Bool) -> Array[
    PathCommand
    ]

    subset_font

    fn subset_font(data : Bytes, codepoints : Array[Int]) -> Bytes?

    Subset a TrueType font to include only the given codepoints. Returns a new sfnt binary containing only the required glyphs. Only supports glyf-based TrueType fonts (not CFF/CFF2).

    write_be16

    fn write_be16(out : Array[Byte], offset : Int, value : Int) -> Unit

    Write a big-endian uint16 into Array[Byte]

    write_be32

    fn write_be32(out : Array[Byte], offset : Int, value : Int) -> Unit

    Write a big-endian uint32 into Array[Byte]