text

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Sep 30, 2026 License: GPL-3.0 Imports: 25 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

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. MinContent is the largest unbreakable UAX#14 segment; max-content ignores soft breaks. 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, MinContent, MaxContent, 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 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) Open

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

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