Skip to content

OxideAV/oxideav-otf

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

oxideav-otf

Pure-Rust OpenType / CFF font parser for the oxideav framework. Sibling to oxideav-ttf: TTF handles TrueType outlines (quadratic Beziers); OTF handles CFF outlines (Type 2 charstrings → cubic Beziers).

Round-1 scope (this release)

  • sfnt + table directory walker (recognises OTTO, 0x00010000, true).
  • CFF (Adobe TN5176, version 1):
    • Header + Name INDEX + Top DICT + String INDEX + Global Subrs INDEX.
    • Charset formats 0 / 1 / 2 (predefined ISOAdobe also recognised).
    • Encoding formats 0 / 1 (predefined Standard / Expert noted but not used — real lookup goes through the sfnt cmap table).
    • Private DICT including defaultWidthX / nominalWidthX and the Local Subrs INDEX offset.
  • Type 2 charstring interpreter (Adobe TN5177):
    • Path: rmoveto, hmoveto, vmoveto, rlineto, hlineto, vlineto, rrcurveto, hhcurveto, hvcurveto, vvcurveto, vhcurveto, rcurveline, rlinecurve.
    • Flex: flex, hflex, hflex1, flex1.
    • Subroutines: callsubr, callgsubr, return, endchar with correct 107 / 1131 / 32768 bias formula.
    • Hints: hstem, vstem, hstemhm, vstemhm, hintmask, cntrmask — recorded for stack accounting; not enforced.
    • Width handling per TN5177 §4.7 (optional first-operand width delta vs nominalWidthX / defaultWidthX).
  • Selected sfnt tables for metadata: head, hhea, maxp, hmtx, cmap (formats 0/4/6/12), name.

Public API

use oxideav_otf::Font;

let bytes = std::fs::read("SourceSans3-Regular.otf")?;
let font  = Font::from_bytes(&bytes)?;

// Metadata.
let _ = font.family_name();         // Some("Source Sans 3")
let _ = font.full_name();
let _ = font.units_per_em();        // 1000 (CFF default)
let _ = font.glyph_count();
let _ = font.ps_name();             // PostScript name from CFF Name INDEX
let _ = font.ascent();
let _ = font.descent();
let _ = font.line_gap();

// Glyph lookup.
let gid = font.glyph_index('A').unwrap();
let _ = font.glyph_advance(gid);    // i16 advance width in font units
let _ = font.glyph_lsb(gid);
let _ = font.glyph_name(gid);       // "A" (via CFF charset → Strings)
let outline = font.glyph_outline(gid)?;

for contour in &outline.contours {
    for seg in &contour.segments {
        // CubicSegment::MoveTo / LineTo / CurveTo / ClosePath
        let _ = seg;
    }
}

Out of scope (round 2+)

  • CFF2 (OpenType 1.8+ variation-aware variant — Adobe TN5174). Detected at parse time and reported as Error::Cff2NotImplemented.
  • CIDFonts (FDArray / FDSelect / ROS) — detected and rejected.
  • Hint enforcement (we anti-alias at >= 16 px, so hints are noise).
  • Predefined Standard / Expert encoding lookup tables (legacy PostScript path; modern OpenType callers use the sfnt cmap table that we already implement).
  • The Adobe Glyph List string → codepoint mapping (round 2 if any consumer needs it).

Test fixture

tests/fixtures/SourceSans3-Regular.otf is Adobe Source Sans 3 Regular under the SIL Open Font License v1.1 (see tests/fixtures/SOURCE-SANS-LICENSE). 335 KB, ~1900 glyphs, exercises every common Type 2 operator including flex.

License

MIT — see LICENSE.

About

Pure-Rust OpenType/CFF font parser for the oxideav framework — sfnt + CFF + Type 2 charstrings (cubic-Bezier outlines)

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages