go-opentype is a family of pure-Go, standard-library-only packages that
together read a font file, lay out Unicode text โ including mixed-direction and Arabic script โ and
rasterise the result, with zero third-party dependencies anywhere in the stack.
import (
"github.com/go-opentype/opentype"
"github.com/go-opentype/shape"
)
f, _ := opentype.Parse(ttf) // ttf is a []byte TrueType/OpenType blob
face := f.NewFace(32) // 32px per em
for _, g := range shape.Shape(face, "ุจูุช", shape.Options{}) {
// g.GID glyph to draw
// g.XAdvance, g.YAdvance advance to move the pen by (px)
// g.XOffset, g.YOffset placement relative to the pen (px)
}
bounds, mask, maskp, advance, ok := face.GlyphMask('H', penX, baselineY)
// mask is an *image.Alpha coverage mask, ready to composite
The engine: a pure-Go, stdlib-only sfnt parser and anti-aliased rasteriser. TrueType glyf + CFF + CFF2 outlines; all cmap formats (0/2/4/6/8/10/12/13/14 + variation selectors); every GSUB and GPOS lookup type with GDEF + lookup flags (mark filtering); variable fonts (fvar/avar/gvar + IUP, plus HVAR/VVAR/MVAR metric variation); the full TrueType instruction hinter and a CFF/Type 2 stem grid-fitter (blue zones, counter control, stem darkening); vertical metrics; the OpenType MATH table; and font subsetting + instancing (SubsetTrueType/SubsetCFF, Instance) plus OS/2 font-descriptor accessors for PDF/CSS embedding. Feature parity with FreeType on the outline + hinting paths.
A pure-Go, stdlib-only implementation of the Unicode Bidirectional Algorithm (UAX #9) for mixed left-to-right / right-to-left text. Bidi_Class and paired-bracket properties are compiled into generated lookup tables โ no golang.org/x/text dependency. ResolveLevels, Reorder and a VisualOrder convenience wrapper.
A HarfBuzz-lite complex-text shaper composing the two siblings above: bidi reordering from bidi and the font’s substitution/positioning tables from opentype. Dedicated shapers for Arabic (cursive joining), the Indic scripts (Devanagari, Bengali, Tamil, โฆ โ two-pass reordering, reph modes, split matras, dotted-circle), the Universal Shaping Engine (Thai/Lao, Khmer, Myanmar, Tibetan and ~100 more โ sakot, split vowels, feature-driven reorder), Egyptian hieroglyph quadrats, Hangul jamo composition, vertical writing mode, and Latin/default (ligatures, marks, kerning) โ all to positioned glyphs in visual order. Validated on real Noto fonts.
46 legible, permissively-licensed families โ Atkinson Hyperlegible, Inter, Lora, JetBrains Mono, the Go pair, dozens of Noto faces, and non-Latin scripts (Arabic, Hebrew, Devanagari, Thai, Egyptian Hieroglyphs, plus CJK via Noto Sans SC, JP and KR) โ each its own subpackage embedded via go:embed, so a binary links only the faces it imports. fonts.MostLegible() returns Atkinson Hyperlegible, designed by the Braille Institute to maximise character distinction for low-vision readers.
What it replaces: the narrow slice of golang.org/x/image/font +
font/opentype a glyph-blitting UI needs, and golang.org/x/text/unicode/bidi โ
both dropped in favour of a smaller, purpose-built, dependency-free stack โ reaching
functional parity with the HarfBuzz + FreeType pair for anti-aliased rendering and
OpenType shaping: TrueType + CFF + CFF2 outlines, all cmap formats, every GSUB/GPOS lookup with
GDEF + lookup flags, variable fonts with metric variation, full TrueType + CFF hinting, the
OpenType MATH table, UAX #9 bidi, and complex-script shaping for Arabic, the Indic scripts, the
Universal Shaping Engine (Thai/Khmer/Myanmar/โฆ), Egyptian hieroglyphs, Hangul and vertical text.
Every package in the stack ships with a
100 % statement coverage gate, tested against synthesised in-memory fonts so no
package depends on an external .ttf to run its suite. The whole stack is pure Go with cgo
disabled โ no C toolchain, no runtime fetch, no vendored assets โ and cross-compiles trivially,
including to GOOS=js GOARCH=wasm. Everything is BSD-3-Clause.