text

package
v0.7.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 9, 2026 License: GPL-3.0 Imports: 26 Imported by: 0

Documentation

Overview

Package text implements CPU-side font selection, shaping, measurement and grayscale glyph preparation. Catalog and Engine are not safe for concurrent use (go-text faces cache mutable state).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func VariationHash

func VariationHash(v []font.Variation) [32]byte

VariationHash hashes the axis coordinates without allocating for up to 16 axes (fonts rarely have more).

Types

type Atlas

type Atlas struct {
	Size, MaxPages int
	// contains filtered or unexported fields
}

Atlas owns fixed-size monochrome pages. One pixel padding isolates bilinear samples. It is not concurrent-safe; call BeginFrame before inserting a new frame and drain Uploads before displaying that frame. An active page is never evicted within the same frame. Placements expire when their page is evicted; the caller must only retain them for its current frame. Drain Uploads once per frame; undrained changes are coalesced, never discarded. At most one pending upload per page (bounding union of all dirty rects) uses at most MaxPages*Size*Size pending bytes.

func NewAtlas

func NewAtlas(size, maxPages int) (*Atlas, error)

func (*Atlas) BeginFrame

func (a *Atlas) BeginFrame()

func (*Atlas) Insert

func (a *Atlas) Insert(k Key, m Mask) (Placement, error)

func (*Atlas) Lookup

func (a *Atlas) Lookup(k Key) (Placement, bool)

Lookup only updates the page generation; a hit neither rasterizes nor uploads.

func (*Atlas) MarkAllDirty

func (a *Atlas) MarkAllDirty()

MarkAllDirty restores the GPU mirror after a failed upload or atlas recreation. Existing pending changes are subsumed by the full-page rectangles.

func (*Atlas) PagesUsed

func (a *Atlas) PagesUsed() int

PagesUsed reports the number of allocated atlas pages.

func (*Atlas) Uploads

func (a *Atlas) Uploads() []Upload

Uploads returns a snapshot of all pending page changes, then clears the pending set. Call once per frame before submitting the renderer uploads.

type Catalog

type Catalog struct {
	Faces []*Face

	Diagnostics []error
	// contains filtered or unexported fields
}

func Load

func Load(source FontSource) (*Catalog, error)

type DirectorySource

type DirectorySource string

DirectorySource reads font files recursively; paths are sorted before parsing.

func (DirectorySource) Fonts

func (d DirectorySource) Fonts() (map[string][]byte, error)

type Engine

type Engine struct {
	// contains filtered or unexported fields
}

Engine is single-goroutine only: Measure and EndFrame are not synchronized. Its catalog is fixed at NewEngine and must not change afterwards, because cached measurements depend on its faces.

func NewEngine

func NewEngine(c *Catalog) *Engine

func (*Engine) EndFrame

func (e *Engine) EndFrame()

EndFrame evicts measurements not used during the last two frames. Call it once after each frame that may have measured text.

func (*Engine) Measure

func (e *Engine) Measure(s string, r Request, width float64) (Layout, error)

Measure shapes, wraps (UAX#14) and positions runs. Width <= 0 means unbounded. Every UAX#9 paragraph resolves its own direction; line baselines stack in logical px.

Results are cached per (text, request, width) until EndFrame evicts them. The returned Lines, Runs and Glyphs are shared with the cache: treat them as immutable and copy before changing positions (see Layout.Clone).

type Face

type Face struct {
	ID         string
	Family     string
	Aspect     font.Aspect
	Shape      *font.Face
	Raster     *sfnt.Font
	Data       []byte
	Variations []font.Variation // immutable after construction; use WithVariations to clone
	Variable   bool             // fvar table present
	// contains filtered or unexported fields
}

Face is a parsed font, paired with its bytes for static TrueType rasterization.

func (*Face) WithVariations

func (f *Face) WithVariations(v []font.Variation) *Face

WithVariations clones a face, preserving the font bytes and sfnt handle while configuring go-text's variation-aware outline and shaping caches independently.

type FontFile

type FontFile struct {
	Path          string
	Family        string
	Aspect        font.Aspect
	Index         int
	UnicodeRanges [4]uint32 // OS/2 ulUnicodeRange; zero means unknown
}

type FontSource

type FontSource interface {
	Fonts() (map[string][]byte, error)
}

FontSource is the only external boundary: it provides files, not font matching policy. Implementations must return a stable snapshot. Corrupt files are reported, not silently accepted.

type Glyph

type Glyph struct {
	ID      font.GID
	X, Y    float64
	Advance float64
	// Cluster is the rune index, in the original Measure input, of the first
	// rune of the glyph's cluster. It is not a UTF-8 byte offset.
	Cluster int
	Missing bool
}

Glyph contains a positioned glyph in logical pixels, with its original shaping metrics.

type IndexSource

type IndexSource interface {
	Index() ([]FontFile, error)
	Open(path string) (io.ReadCloser, error)
}

IndexSource supplies metadata without retaining font bytes. Open is invoked only when a face is selected. Sources must keep paths stable during the catalog lifetime.

type Key

type Key struct {
	FaceID     string
	Glyph      font.GID
	Size       fixed.Int26_6
	Variations [32]byte
	Phase      uint8
}

Key identifies a grayscale glyph mask. Size is physical px in 26.6 units; Phase is one of four horizontal quarter-pixel origins (vertical phase is zero).

func GlyphKey

func GlyphKey(face *Face, id font.GID, physicalSize, originX float64, variations []font.Variation) (Key, error)

type Layout

type Layout struct {
	Lines                               []Line
	Direction                           di.Direction // paragraph basis, auto resolved by bidi analysis
	Width, Height, Baseline, LineHeight float64
}

func (Layout) Clone

func (l Layout) Clone() Layout

Clone deep-copies lines, runs and glyphs so positions can be adjusted without changing a cached measurement.

type LazySource added in v0.7.1

type LazySource interface {
	FontSource
	IndexSource
	Paths() ([]string, error)
	IndexFiles(paths []string) ([]FontFile, error)
}

LazySource lists font files cheaply and indexes chosen ones on demand, so a catalog reads only the files a request needs. Paths fixes the catalog order; IndexFiles returns entries in the order of its paths.

type Line

type Line struct {
	Runs                    []Run
	Direction               di.Direction // resolved paragraph base direction
	Width, Baseline, Height float64
}

type Mask

type Mask struct {
	Alpha  *image.Alpha
	Origin image.Point
}

func Rasterize

func Rasterize(face *Face, key Key) (Mask, error)

Rasterize uses sfnt for static faces and go-text outlines for variable faces. Neither path hints glyphs. Masks have one pixel of transparent padding for filtering.

type Placement

type Placement struct {
	Page   int
	Rect   image.Rectangle
	Origin image.Point
}

type Request

type Request struct {
	Direction bidi.BaseDirection // Auto (default), LTR, or RTL
	Families  []string
	Weight    float32
	Stretch   float32
	Italic    bool
	Size      float64
	// LetterSpacing is the signed logical-pixel spacing between shaped clusters.
	LetterSpacing float64
	Variations    []font.Variation
}

Request specifies CSS font selection. Weight defaults to 400, Stretch to 1, Style normal.

type Run

type Run struct {
	Face      *Face
	Direction di.Direction
	Level     uint8 // resolved embedding level after L1
	// Start and End are rune indices in the original Measure input; End is
	// exclusive. A CRLF separator counts as two runes.
	Start, End    int
	X, Y, Advance float64
	Glyphs        []Glyph
}

Run is a shaped span with one face, direction and embedding level.

type SystemSource

type SystemSource struct{}

SystemSource searches XDG user and system font directories without fontconfig/cgo. Earlier locations win identical family/aspect ties.

func (SystemSource) Fonts

func (s SystemSource) Fonts() (map[string][]byte, error)

Fonts remains available for callers that explicitly need byte snapshots; Load uses Index instead.

func (SystemSource) Index

func (s SystemSource) Index() ([]FontFile, error)

func (SystemSource) IndexFiles added in v0.7.1

func (SystemSource) IndexFiles(paths []string) ([]FontFile, error)

IndexFiles reads the metadata of paths in parallel and returns the entries in path order. Every worker ends before it returns.

func (SystemSource) Open

func (SystemSource) Open(path string) (io.ReadCloser, error)

func (SystemSource) Paths added in v0.7.1

func (s SystemSource) Paths() ([]string, error)

Paths lists the font files in catalog order without reading them.

type Upload

type Upload struct {
	Page  int
	Rect  image.Rectangle
	Bytes []byte
}

Upload is an immutable tightly packed grayscale rectangle, for the future renderer. It contains the latest pixels for Rect, including zeroed areas after eviction.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL