Documentation
¶
Overview ¶
Package shape is a HarfBuzz-lite complex-text shaper for the go-opentype stack. It turns a run of Unicode text into positioned glyphs in visual (left-to-right) order, ready to blit, applying the three things a naive cmap-then-GSUB pass gets wrong for real text:
- Bidirectional reordering (via github.com/go-opentype/bidi): resolve the UAX #9 embedding levels and lay the glyphs out left-to-right, so a right-to-left Arabic run is emitted in the order it is drawn.
- Arabic cursive joining: each letter's Unicode joining form (isolated, initial, medial, final) is resolved, then the font's isol/init/medi/fina GSUB features are applied positionally — each only at the glyphs in that form — via opentype's ApplyMasked. Without this, Arabic renders as disconnected isolated letters.
- Ligatures, mark attachment and kerning: GSUB ccmp/rlig/liga/calt then GPOS kern/mark/mkmk/curs, so diacritics sit on their base and pairs kern.
Usage ¶
face := font.NewFace(32)
glyphs := shape.Shape(face, "بيت", shape.Options{})
for _, g := range glyphs {
// g.GID is the glyph to draw; advance the pen by g.XAdvance,
// offset the glyph by (g.XOffset, g.YOffset). All in pixels.
}
The base direction defaults to Auto (derived from the first strong character); the script is auto-detected from the text (any Arabic-block rune selects the Arabic shaper) unless Options.Script forces it.
Scope ¶
Arabic and Latin/default (Latin, Cyrillic, Greek, CJK, ...) shaping are implemented. Scripts that need glyph reordering or a state machine — Indic (Devanagari, ...), Thai/Lao, Khmer, Myanmar and the Universal Shaping Engine — are out of scope and shape as the default path (no reordering); they are future work. Cluster indices are exact for one-to-one substitutions (the Arabic positional forms) and best-effort, monotonic, when a substitution changes the run length (ligatures, decomposition).
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Glyph ¶
type Glyph struct {
GID opentype.GlyphIndex
Cluster int
XAdvance int
YAdvance int
XOffset int
YOffset int
}
Glyph is one positioned glyph of a shaped run, in visual (left-to-right) order. GID is the glyph to draw; Cluster is the logical (rune) index in the source text the glyph derives from; the advances move the pen after drawing and the offsets place the glyph relative to the pen — all in whole pixels at the face's size.
func Shape ¶
Shape turns text into a positioned glyph run in visual order. It resolves the bidirectional embedding levels, maps each rune to a glyph, applies GSUB (positionally for Arabic cursive joining, whole-run for ligatures and contextual alternates), positions the result with GPOS (kerning and mark attachment), and emits the glyphs left-to-right with per-glyph advances and offsets in pixels. An empty text, or a face whose font lacks GSUB/GPOS, simply skips the corresponding stage.
type Options ¶
type Options struct {
// Direction is the base paragraph direction (bidi.LeftToRight,
// bidi.RightToLeft or bidi.Auto). The zero value is bidi.LeftToRight.
Direction bidi.Direction
// Script forces the shaping script: "arab" for Arabic, "latn"/"dflt" (or
// any other value) for the default shaper. Empty auto-detects: any
// Arabic-block rune selects "arab", otherwise "dflt".
Script string
// Features lists extra OpenType feature tags to activate, applied over the
// whole run in both the substitution and positioning stages (a tag with no
// matching lookups is a no-op).
Features []string
}
Options configures a Shape call. The zero value shapes with an automatic base direction (from the first strong character), a script auto-detected from the text, and no extra features.