glyph

package module
v1.9.0 Latest Latest
Warning

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

Go to latest
Published: Jun 3, 2026 License: MIT Imports: 12 Imported by: 0

README

Go-Glyph

Go version License Ask DeepWiki

High-performance text rendering library for Go. Uses Pango, FreeType, and FontConfig on Linux/macOS; native GDI on Windows; CoreText on iOS. Provides text shaping, layout, rasterization, and editing with pluggable rendering backends.

screenshot

Features

  • Text shaping via Pango - full Unicode, BiDi, complex scripts
  • Glyph rasterization via FreeType2 with subpixel positioning
  • Multi-page glyph atlas with automatic packing and eviction
  • Layout caching for efficient per-frame rendering
  • Rich text - mixed fonts, sizes, colors, and styles in one block
  • Pango markup support for inline styling
  • Text decorations - underline, strikethrough, stroke/outline
  • Gradient text - horizontal and vertical color gradients
  • Word wrapping with word, character, and word-char modes
  • Text alignment - left, center, right
  • Affine transforms - rotation, skew, scale, translation
  • Glyph placements - per-glyph positioning (text on a path)
  • Hit testing and cursor position queries
  • Text mutation - insert, delete, selection, undo/redo
  • IME support with composition/preedit rendering
  • Accessibility - screen reader announcements, text field nodes
  • Pluggable backends - Ebitengine, SDL2, GPU (Metal/OpenGL)

Prerequisites

Go-Glyph uses CGo bindings to the following C libraries:

  • Pango (+ PangoFT2)
  • FreeType2
  • FontConfig
  • GLib
  • SDL2 (for SDL2 and GPU backends)
Windows (MSYS2)

The root package and Ebitengine backend require no native libraries on Windows (CGO_ENABLED=0). The SDL2 and GPU backends need SDL2 via MSYS2:

pacman -S mingw-w64-x86_64-SDL2 mingw-w64-x86_64-pkg-config

Build from an MSYS2 MinGW 64-bit shell, or add the MinGW bin/ directory to PATH so pkg-config and the SDL2 DLL are found.

macOS (Homebrew)
brew install pango freetype fontconfig glib sdl2
Ubuntu / Debian
sudo apt install libpango1.0-dev libfreetype-dev \
    libfontconfig1-dev libglib2.0-dev libsdl2-dev
Fedora
sudo dnf install pango-devel freetype-devel \
    fontconfig-devel glib2-devel SDL2-devel

Installation

go get github.com/go-gui-org/go-glyph@latest

Quick Start

Minimal Ebitengine example:

package main

import (
    "log"

    "github.com/hajimehoshi/ebiten/v2"
    "github.com/go-gui-org/go-glyph"
    glyphebi "github.com/go-gui-org/go-glyph/backend/ebitengine"
)

type Game struct {
    ts      *glyph.TextSystem
    backend *glyphebi.Backend
}

func (g *Game) Update() error { return nil }

func (g *Game) Draw(screen *ebiten.Image) {
    g.backend.SetTarget(screen)

    _ = g.ts.DrawText(20, 20, "Hello, World!", glyph.TextConfig{
        Style: glyph.TextStyle{
            FontName: "Sans 24",
            Color:    glyph.Color{A: 255},
        },
    })

    g.ts.Commit()
}

func (g *Game) Layout(w, h int) (int, int) { return w, h }

func main() {
    scale := ebiten.Monitor().DeviceScaleFactor()
    backend := glyphebi.New(nil, float32(scale))

    ts, err := glyph.NewTextSystem(backend)
    if err != nil {
        log.Fatal(err)
    }
    defer ts.Free()

    ebiten.SetWindowSize(800, 600)
    if err := ebiten.RunGame(&Game{ts: ts, backend: backend}); err != nil {
        log.Fatal(err)
    }
}

Core Concepts

screenshot

TextSystem

The main entry point. Manages a Context (Pango/FreeType state), a Renderer (glyph atlas + draw calls), and a layout cache.

ts, err := glyph.NewTextSystem(backend)
defer ts.Free()

// Simple rendering (uses cache automatically):
ts.DrawText(x, y, "text", cfg)
ts.Commit() // Upload atlas textures, call once per frame.

For pre-computed layouts:

layout, err := ts.LayoutText("text", cfg)
ts.DrawLayout(layout, x, y)
TextConfig

Controls all aspects of text rendering:

cfg := glyph.TextConfig{
    Style: glyph.TextStyle{
        FontName:      "Sans 16",       // Pango font description
        Typeface:      glyph.TypefaceBold,
        Color:         glyph.Color{R: 255, A: 255},
        Underline:     true,
        Strikethrough:  false,
        LetterSpacing: 2.0,             // Extra spacing (points)
        StrokeWidth:   1.5,             // Outline width (points)
        StrokeColor:   glyph.Color{A: 255},
    },
    Block: glyph.BlockStyle{
        Wrap:   glyph.WrapWord,
        Width:  400,                    // Wrap width (-1 = none)
        Align:  glyph.AlignCenter,
        Indent: 20,                     // First-line indent
    },
    UseMarkup: false,
    Gradient:  nil,
}
Layout

A computed text layout containing glyph positions, line breaks, character rectangles, and logical attributes. Created by LayoutText, LayoutRichText, or LayoutTextCached.

DrawBackend

Interface for plugging in a rendering framework:

type DrawBackend interface {
    NewTexture(width, height int) TextureID
    UpdateTexture(id TextureID, data []byte)
    DeleteTexture(id TextureID)
    DrawTexturedQuad(id TextureID, src, dst Rect, c Color)
    DrawFilledRect(dst Rect, c Color)
    DrawTexturedQuadTransformed(
        id TextureID, src, dst Rect, c Color, t AffineTransform,
    )
    DPIScale() float32
}

Backends

Backend Package Notes
Ebitengine go-glyph/backend/ebitengine Pure Go game engine
SDL2 go-glyph/backend/sdl2 SDL2 renderer
GPU go-glyph/backend/gpu Metal (macOS), OpenGL 3.3 (Linux/Windows)

Each backend has its own go.mod with framework-specific dependencies. Import the one matching the target framework.

Ebitengine
import glyphebi "github.com/go-gui-org/go-glyph/backend/ebitengine"

backend := glyphebi.New(nil, float32(dpiScale))
// Call backend.SetTarget(screen) each frame before drawing.
SDL2
import glyphsdl "github.com/go-gui-org/go-glyph/backend/sdl2"

backend := glyphsdl.New(sdlRenderer, float32(dpiScale))
defer backend.Destroy()
GPU (Metal / OpenGL)

Uses Metal on macOS and OpenGL 3.3 on Linux. The API is identical on both platforms:

import glyphgpu "github.com/go-gui-org/go-glyph/backend/gpu"

// Create window with gpu.WindowFlag() (Metal or OpenGL).
window, _ := sdl.CreateWindow("demo",
    sdl.WINDOWPOS_CENTERED, sdl.WINDOWPOS_CENTERED,
    800, 600, sdl.WINDOW_SHOWN|gpu.WindowFlag())

backend, err := glyphgpu.New(sdlWindow, float32(dpiScale))
defer backend.Destroy()

// Per frame:
backend.BeginFrame()
// ... draw text ...
backend.EndFrame(0.96, 0.96, 0.96, 1.0, logicalW, logicalH)

Text Styling

screenshot

Bold, Italic
glyph.TextStyle{FontName: "Sans 18", Typeface: glyph.TypefaceBold}
glyph.TextStyle{FontName: "Sans 18", Typeface: glyph.TypefaceItalic}
glyph.TextStyle{FontName: "Sans 18", Typeface: glyph.TypefaceBoldItalic}
Underline and Strikethrough
glyph.TextStyle{FontName: "Sans 16", Underline: true}
glyph.TextStyle{FontName: "Sans 16", Strikethrough: true}
Letter Spacing
glyph.TextStyle{FontName: "Sans 16", LetterSpacing: 3.0}  // wider
glyph.TextStyle{FontName: "Sans 16", LetterSpacing: -1.0}  // tighter
Stroke / Outline
glyph.TextStyle{
    FontName:    "Sans 28",
    Color:       glyph.Color{R: 255, G: 255, B: 255, A: 255},
    StrokeWidth: 2.0,
    StrokeColor: glyph.Color{A: 255},
}
Gradients
cfg := glyph.TextConfig{
    Style: glyph.TextStyle{FontName: "Sans 28"},
    Gradient: &glyph.GradientConfig{
        Direction: glyph.GradientHorizontal,
        Stops: []glyph.GradientStop{
            {Color: glyph.Color{R: 255, A: 255}, Position: 0},
            {Color: glyph.Color{B: 255, A: 255}, Position: 1},
        },
    },
}

Layout Features

Word Wrapping
glyph.BlockStyle{Wrap: glyph.WrapWord, Width: 300}
glyph.BlockStyle{Wrap: glyph.WrapChar, Width: 300}
glyph.BlockStyle{Wrap: glyph.WrapWordChar, Width: 300}
Alignment
glyph.BlockStyle{Width: 400, Align: glyph.AlignLeft}
glyph.BlockStyle{Width: 400, Align: glyph.AlignCenter}
glyph.BlockStyle{Width: 400, Align: glyph.AlignRight}
Indentation
glyph.BlockStyle{Width: 400, Indent: 30}   // first-line indent
glyph.BlockStyle{Width: 400, Indent: -30}  // hanging indent
Rich Text

Render multiple styles in a single layout:

rt := glyph.RichText{
    Runs: []glyph.StyleRun{
        {Text: "Bold ", Style: glyph.TextStyle{
            FontName: "Sans 16",
            Typeface: glyph.TypefaceBold,
            Color:    glyph.Color{A: 255},
        }},
        {Text: "and italic", Style: glyph.TextStyle{
            FontName: "Sans 16",
            Typeface: glyph.TypefaceItalic,
            Color:    glyph.Color{R: 200, A: 255},
        }},
    },
}
layout, err := ts.LayoutRichText(rt, cfg)
ts.DrawLayout(layout, x, y)
Pango Markup
cfg := glyph.TextConfig{
    Style:     glyph.TextStyle{FontName: "Sans 16"},
    UseMarkup: true,
}
ts.DrawText(x, y, "<b>Bold</b> and <i>italic</i>", cfg)

Text Queries

All query methods operate on a pre-computed Layout:

layout, _ := ts.LayoutText(text, cfg)

// Hit testing: byte index at screen coordinates.
idx := layout.HitTest(mouseX-originX, mouseY-originY)

// Character bounding box.
rect, ok := layout.GetCharRect(byteIndex)

// Cursor position geometry.
cursor, ok := layout.GetCursorPos(byteIndex)

// Closest byte index (clamps to text bounds).
idx = layout.GetClosestOffset(localX, localY)

// Selection rectangles.
rects := layout.GetSelectionRects(start, end)

// Cursor navigation.
next := layout.MoveCursorRight(byteIndex)
prev := layout.MoveCursorLeft(byteIndex)
wordNext := layout.MoveCursorWordRight(byteIndex)
wordPrev := layout.MoveCursorWordLeft(byteIndex)
lineStart := layout.MoveCursorLineStart(byteIndex)
lineEnd := layout.MoveCursorLineEnd(byteIndex)
up := layout.MoveCursorUp(byteIndex, preferredX)
down := layout.MoveCursorDown(byteIndex, preferredX)

// Word / paragraph boundaries.
start, end := layout.GetWordAtIndex(byteIndex)
pStart, pEnd := layout.GetParagraphAtIndex(byteIndex, text)

Text Mutation

Package-level functions for editing text:

// Insert and delete.
result := glyph.InsertText(text, cursor, "hello")
result = glyph.DeleteBackward(text, layout, cursor)
result = glyph.DeleteForward(text, layout, cursor)

// Word/line deletion.
result = glyph.DeleteToWordBoundary(text, layout, cursor)
result = glyph.DeleteToWordEnd(text, layout, cursor)
result = glyph.DeleteToLineStart(text, layout, cursor)
result = glyph.DeleteToLineEnd(text, layout, cursor)

// Selection operations.
result = glyph.DeleteSelection(text, cursor, anchor)
result = glyph.InsertReplacingSelection(text, cursor, anchor, "new")
selected := glyph.GetSelectedText(text, cursor, anchor)
clipboard, result := glyph.CutSelection(text, cursor, anchor)
Undo / Redo
um := glyph.NewUndoManager(100)

// After each mutation:
um.RecordMutation(result, insertedText, cursorBefore, anchorBefore)

// Undo / redo:
if undoResult := um.Undo(currentText); undoResult != nil {
    text = undoResult.Text
    cursor = undoResult.Cursor
}
if redoResult := um.Redo(currentText); redoResult != nil {
    text = redoResult.Text
    cursor = redoResult.Cursor
}

Advanced Rendering

Affine Transforms
transform := glyph.AffineRotation(0.3).
    Multiply(glyph.AffineSkew(0.2, 0))

ts.DrawLayoutTransformed(layout, x, y, transform)
Rotated Text
ts.DrawLayoutRotated(layout, x, y, angleRadians)
Glyph Placements (Text on a Path)

Position each glyph independently:

glyphs := layout.GlyphPositions()
placements := make([]glyph.GlyphPlacement, len(glyphs))
for i, g := range glyphs {
    t := float64(g.X) / totalWidth
    placements[i] = glyph.GlyphPlacement{
        X:     pathX(t),
        Y:     pathY(t),
        Angle: pathAngle(t),
    }
}
ts.DrawLayoutPlaced(layout, placements)
Subpixel Rendering

Glyph positions use subpixel offsets for smooth text at all sizes. The renderer quantizes to 4 horizontal subpixel bins.

Subsystems

IME (Input Method Editor)

The ime package provides a Bridge interface for platform-native IME integration. Composition state (preedit text, clause styling, cursor offset) is tracked in CompositionState and rendered with clause underlines and cursor feedback.

Accessibility

The accessibility package provides a Manager for building an accessibility tree with text nodes and text field nodes. An Announcer handles screen reader announcements (character echo, word echo, line changes, selection changes) with debouncing.

Examples

Example Description
examples/demo Ebitengine demo - basic text, styles, wrapping, emoji, CJK, RTL
examples/demo_sdl2 Same demo using SDL2 backend
examples/demo_gpu Same demo using GPU backend (Metal/OpenGL)
examples/showcase_gpu Feature gallery (22 sections)

Run an example:

cd examples/demo && go run .

Architecture

TextSystem
  +-- Context (platform text engine)
  |     +-- Text shaping and layout computation
  |     +-- Font resolution and metrics
  +-- Renderer
  |     +-- GlyphAtlas (multi-page, shelf-packed)
  |     +-- Glyph rasterization and caching
  |     +-- Draw call emission (5-pass pipeline)
  +-- Layout cache (hash-keyed, time-based eviction)
  +-- DrawBackend (interface)
        +-- Ebitengine / SDL2 / GPU implementations

The rendering pipeline per layout:

  1. Background rectangles
  2. Stroke setup
  3. Stroke outlines
  4. Fill glyphs (with subpixel positioning, emoji scaling, gradients)
  5. Decorations (underline, strikethrough)

Wiki Documentation

https://deepwiki.com/mike-ward/go-glyph/8-glossary

License

See LICENSE for details.

Documentation

Overview

Package glyph provides high-quality text shaping, layout, and rendering for GPU-accelerated applications. It wraps Pango (for Unicode layout, bidirectional text, and complex script support) and FreeType (for glyph rasterization with subpixel positioning) behind a backend-agnostic DrawBackend interface.

Quick start

ctx, err := glyph.NewContext(2.0) // 2× Retina scale
if err != nil {
    log.Fatal(err)
}

layout, err := ctx.LayoutText("Hello, world!", glyph.TextConfig{
    Style: glyph.TextStyle{FontName: "Sans 18"},
    Block: glyph.DefaultBlockStyle(),
})

renderer := glyph.NewRenderer(backend, ctx)
renderer.DrawLayout(layout, 10, 10)

Architecture

Context owns FreeType and Pango state. Renderer draws shaped layouts through a DrawBackend. Two backends are provided:

Thread Safety

Context, Renderer, TextSystem, and GlyphAtlas are not safe for concurrent use. In a typical application, call all glyph methods from the main/render goroutine.

Sub-packages

Index

Constants

View Source
const (
	FTPixelModeNone = 0
	FTPixelModeMono = 1
	FTPixelModeGray = 2
	FTPixelModeLCD  = 5
	FTPixelModeBGRA = 7
	FTPixelModeLCDV = 6
)

FreeType pixel modes.

View Source
const (
	FTLoadDefault       = 0
	FTLoadNoScale       = 1 << 0
	FTLoadNoHinting     = 1 << 1
	FTLoadRender        = 1 << 2
	FTLoadNoBitmap      = 1 << 3
	FTLoadForceAutohint = 1 << 5
	FTLoadMonochrome    = 1 << 12
	FTLoadNoAutohint    = 1 << 15
	FTLoadTargetNormal  = 0
	FTLoadTargetLight   = 1 << 16
	FTLoadTargetMono    = 2 << 16
	FTLoadTargetLCD     = 3 << 16
)

FreeType load flags.

View Source
const (
	FTRenderModeNormal = 0
	FTRenderModeLight  = 1
	FTRenderModeMono   = 2
	FTRenderModeLCD    = 3
)

FreeType render modes.

View Source
const (
	FTStrokerLineCapRound  = 1
	FTStrokerLineJoinRound = 1
)

FreeType stroker constants.

View Source
const (
	FTFixedPointShift = 6
	FTFixedPointUnit  = 64
	FTSubpixelUnit    = 16
)

FreeType 26.6 fixed-point constants.

View Source
const (
	// MaxTextLength is the maximum text input length (10KB) for
	// DoS prevention.
	MaxTextLength = 10240
	// MaxTextureDimension is the maximum texture size in pixels.
	MaxTextureDimension = 16384
	// MinFontSize is the minimum font size in points.
	MinFontSize = float32(0.1)
	// MaxFontSize is the maximum font size in points.
	MaxFontSize = float32(500.0)
)
View Source
const FTFaceFlagColor = 1 << 13

FreeType face flags.

View Source
const MaxGlyphSize = 256

MaxGlyphSize caps individual glyph bitmaps to 256x256 pixels. This prevents a single oversized color emoji (some CBDT fonts ship 128px strikes) from consuming a disproportionate fraction of the atlas page. 256 supports up to ~256pt at 1x DPI; at 2x Retina the effective limit is ~128pt, which covers all practical UI sizes.

View Source
const PangoGlyphUnknownFlag = 0x10000000

PangoGlyphUnknownFlag is the flag bit set on glyph indices that Pango could not map to the font.

View Source
const PangoScale = 1024

Pango constants.

View Source
const SubpixelBins = 4

Subpixel positioning constants.

Variables

This section is empty.

Functions

func GetSelectedText

func GetSelectedText(text string, cursor, anchor int) string

GetSelectedText returns the text between cursor and anchor.

func IsDeadKey

func IsDeadKey(r rune) bool

IsDeadKey returns true if the rune is a dead key accent starter.

func ScaleBitmapBicubic

func ScaleBitmapBicubic(src []byte, srcW, srcH, dstW, dstH int) []byte

ScaleBitmapBicubic scales an RGBA bitmap using bicubic (Catmull-Rom) interpolation with premultiplied alpha.

func SetDPIAwareWindows

func SetDPIAwareWindows()

SetDPIAwareWindows is a no-op on non-Windows platforms. On Windows it marks the process as per-monitor DPI aware v2 so windows render at native physical resolution. See dpi_windows.go.

func ValidateDimension

func ValidateDimension(dim int, name, location string) error

ValidateDimension validates an integer dimension (width/height).

func ValidateFontPath

func ValidateFontPath(_ string, _ string) error

ValidateFontPath is a no-op under WASM (no filesystem).

func ValidateSize

func ValidateSize(size, minVal, maxVal float32,
	name, location string) error

ValidateSize validates a numeric size against min/max bounds.

func ValidateTextInput

func ValidateTextInput(text string, maxLen int, location string) error

ValidateTextInput validates text for UTF-8, non-empty, and length.

Types

type AffineTransform

type AffineTransform struct {
	XX float32
	XY float32
	YX float32
	YY float32
	X0 float32
	Y0 float32
}

AffineTransform encodes a 2D affine transform matrix:

[ XX  XY  X0 ]
[ YX  YY  Y0 ]
[  0   0   1 ]

func AffineIdentity

func AffineIdentity() AffineTransform

AffineIdentity returns an identity transform.

func AffineRotation

func AffineRotation(angle float32) AffineTransform

AffineRotation returns a rotation transform in radians around origin.

func AffineSkew

func AffineSkew(skewX, skewY float32) AffineTransform

AffineSkew returns a shear transform with direct skew factors.

func AffineTranslation

func AffineTranslation(dx, dy float32) AffineTransform

AffineTranslation returns a translation transform.

func (AffineTransform) Apply

func (t AffineTransform) Apply(x, y float32) (float32, float32)

Apply maps a point through the affine transform.

func (AffineTransform) Multiply

Multiply returns the composition of two transforms: a then b. Result maps point p as: Multiply(a, b).Apply(p) == a.Apply(b.Apply(p)).

type Alignment

type Alignment int

Alignment specifies horizontal text alignment within the layout box.

const (
	AlignLeft   Alignment = iota // Left-aligned (default).
	AlignCenter                  // Center-aligned.
	AlignRight                   // Right-aligned.
)

type AtlasPage

type AtlasPage struct {
	Shelves      []Shelf
	StagingFront []byte // GPU upload source.
	StagingBack  []byte // CPU rasterization target.
	TextureID    TextureID
	Width        int
	Height       int
	Age          uint64 // Frame counter when last used.
	UsedPixels   int64
	Dirty        bool
}

AtlasPage is a single texture page in a multi-page glyph atlas.

type Bitmap

type Bitmap struct {
	Data     []byte
	Width    int
	Height   int
	Channels int // Always 4 (RGBA).
}

Bitmap holds RGBA pixel data for a rasterized glyph.

type BlockStyle

type BlockStyle struct {
	Tabs  []int
	Align Alignment
	Wrap  WrapMode
	// Width is the wrapping width. -1 = no wrapping.
	Width float32
	// Indent determines first-line indentation. Negative = hanging indent.
	Indent float32
	// LineSpacing adds extra vertical space after each line except the last.
	LineSpacing float32
}

BlockStyle defines paragraph-level layout properties.

func DefaultBlockStyle

func DefaultBlockStyle() BlockStyle

DefaultBlockStyle returns a BlockStyle with standard defaults.

type CachedGlyph

type CachedGlyph struct {
	X      int
	Y      int
	Width  int
	Height int
	Left   int // Bitmap left bearing.
	Top    int // Bitmap top bearing.
	Page   int // Atlas page index.
}

CachedGlyph stores atlas coordinates and bearing info for a rasterized glyph.

type CharRect

type CharRect struct {
	Rect  Rect
	Index int // Byte index in the original text.
}

CharRect maps a character byte index to its bounding rectangle.

type Clause

type Clause struct {
	Start  int
	Length int
	Style  ClauseStyle
}

Clause represents a segment in multi-clause CJK composition.

type ClauseRects

type ClauseRects struct {
	Rects     []Rect
	ClauseIdx int
	Style     ClauseStyle
}

ClauseRects holds clause index, rects, and style for rendering.

type ClauseStyle

type ClauseStyle int

ClauseStyle identifies the visual style of an IME clause.

const (
	ClauseRaw       ClauseStyle = iota // Unconverted input.
	ClauseConverted                    // Converted but not selected.
	ClauseSelected                     // Currently selected clause.
)

type Color

type Color struct {
	R, G, B, A uint8
}

Color is an RGBA color with 8-bit channels.

func GradientColorAt

func GradientColorAt(stops []GradientStop, t float32) Color

GradientColorAt samples the gradient at normalized position t.

func LerpColor

func LerpColor(a, b Color, t float32) Color

LerpColor linearly interpolates between two colors. t is clamped to [0,1].

type CompositionPhase

type CompositionPhase int

CompositionPhase tracks IME preedit state.

const (
	CompositionNone CompositionPhase = iota
	CompositionStarted
	CompositionUpdating
	CompositionCommitted
)

type CompositionState

type CompositionState struct {
	PreeditText    string
	Clauses        []Clause
	Phase          CompositionPhase
	PreeditStart   int
	CursorOffset   int
	SelectedClause int
}

CompositionState tracks IME composition for preedit display.

func NewCompositionState

func NewCompositionState() CompositionState

NewCompositionState returns an initialized CompositionState.

func (*CompositionState) ClearClauses

func (cs *CompositionState) ClearClauses()

ClearClauses resets clause array for fresh enumeration.

func (*CompositionState) Commit

func (cs *CompositionState) Commit() string

Commit finalizes composition, returns text to insert.

func (*CompositionState) CompositionBounds

func (cs *CompositionState) CompositionBounds(layout Layout) (Rect, bool)

CompositionBounds returns bounding rect covering entire preedit. Returns ok=false if not composing.

func (*CompositionState) DocumentCursorPos

func (cs *CompositionState) DocumentCursorPos() int

DocumentCursorPos returns absolute cursor position in document.

func (*CompositionState) GetClauseRects

func (cs *CompositionState) GetClauseRects(layout Layout) []ClauseRects

GetClauseRects returns selection rects for each clause.

func (*CompositionState) HandleClause

func (cs *CompositionState) HandleClause(start, length, style int)

HandleClause processes clause info from IME overlay.

func (*CompositionState) HandleInsertText

func (cs *CompositionState) HandleInsertText(text string) string

HandleInsertText processes insertText from IME overlay.

func (*CompositionState) HandleMarkedText

func (cs *CompositionState) HandleMarkedText(text string,
	cursorInPreedit, documentCursor int)

HandleMarkedText processes setMarkedText from IME overlay.

func (*CompositionState) HandleUnmarkText

func (cs *CompositionState) HandleUnmarkText()

HandleUnmarkText cancels composition without committing.

func (*CompositionState) IsComposing

func (cs *CompositionState) IsComposing() bool

IsComposing returns true if composition is active.

func (*CompositionState) PreeditEnd

func (cs *CompositionState) PreeditEnd() int

PreeditEnd returns byte offset where preedit ends in document.

func (*CompositionState) Reset

func (cs *CompositionState) Reset()

Reset discards composition without inserting text.

func (*CompositionState) SetClauses

func (cs *CompositionState) SetClauses(clauses []Clause, selected int)

SetClauses updates clause segmentation from IME attributes.

func (*CompositionState) SetMarkedText

func (cs *CompositionState) SetMarkedText(text string, cursorInPreedit int)

SetMarkedText updates preedit from IME.

func (*CompositionState) Start

func (cs *CompositionState) Start(cursorPos int)

Start begins composition at document cursor position.

type Context

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

Context holds a Canvas2D context for text measurement in WASM.

Not safe for concurrent use.

func NewContext

func NewContext(scaleFactor float32) (*Context, error)

NewContext creates a WASM text context using an offscreen canvas for measureText calls.

func (*Context) AddFontFile

func (ctx *Context) AddFontFile(_ string) error

AddFontFile is a no-op under WASM. Use FontFace API to load fonts before creating the TextSystem.

func (*Context) FontHeight

func (ctx *Context) FontHeight(cfg TextConfig) (float32, error)

FontHeight returns ascent + descent in logical pixels.

func (*Context) FontMetrics

func (ctx *Context) FontMetrics(cfg TextConfig) (TextMetrics, error)

FontMetrics returns detailed font metrics.

func (*Context) Free

func (ctx *Context) Free()

Free releases resources.

func (*Context) LayoutRichText

func (ctx *Context) LayoutRichText(rt RichText, cfg TextConfig) (Layout, error)

LayoutRichText shapes multi-styled text.

func (*Context) LayoutText

func (ctx *Context) LayoutText(text string, cfg TextConfig) (Layout, error)

LayoutText shapes and wraps text using Canvas2D measureText.

func (*Context) ResolveFontName

func (ctx *Context) ResolveFontName(name string) (string, error)

ResolveFontName returns the input name unchanged under WASM.

func (*Context) ScaleFactor

func (ctx *Context) ScaleFactor() float32

ScaleFactor returns the DPI scale factor.

type CursorPosition

type CursorPosition struct {
	X      float32
	Y      float32
	Height float32
}

CursorPosition represents the geometry for rendering a text cursor.

type DeadKeyState

type DeadKeyState struct {
	Pending    rune
	HasPending bool
	PendingPos int
}

DeadKeyState tracks pending dead key for accent composition.

func (*DeadKeyState) Clear

func (dks *DeadKeyState) Clear()

Clear cancels pending dead key.

func (*DeadKeyState) Reset

func (dks *DeadKeyState) Reset()

Reset zeros all fields.

func (*DeadKeyState) StartDeadKey

func (dks *DeadKeyState) StartDeadKey(dead rune, pos int)

StartDeadKey records a dead key press.

func (*DeadKeyState) TryCombine

func (dks *DeadKeyState) TryCombine(base rune) (string, bool)

TryCombine attempts to combine pending dead key with base char. Returns (result, wasCombined). If invalid: returns both chars.

type DrawBackend

type DrawBackend interface {
	// NewTexture allocates a new RGBA texture of the given size.
	NewTexture(width, height int) TextureID

	// UpdateTexture uploads RGBA pixel data to an existing texture.
	// data must be width*height*4 bytes.
	UpdateTexture(id TextureID, data []byte)

	// DeleteTexture releases a texture.
	DeleteTexture(id TextureID)

	// DrawTexturedQuad draws a textured rectangle with color tinting.
	DrawTexturedQuad(id TextureID, src, dst Rect, c Color)

	// DrawFilledRect draws an untextured filled rectangle.
	DrawFilledRect(dst Rect, c Color)

	// DrawTexturedQuadTransformed draws a textured quad with an
	// affine transform applied.
	DrawTexturedQuadTransformed(id TextureID, src, dst Rect, c Color, t AffineTransform)

	// DPIScale returns the display DPI scale factor.
	DPIScale() float32
}

DrawBackend abstracts the GPU rendering backend. Implementations provide texture management and drawing primitives. The Renderer calls only these methods — never a specific backend directly.

type FTFace

type FTFace struct{}

FTFace is a no-op stub.

func (*FTFace) FacePtr

func (f *FTFace) FacePtr() unsafe.Pointer

type FTLibrary

type FTLibrary struct{}

FTLibrary is a no-op stub.

func InitFreeType

func InitFreeType() (FTLibrary, error)

func (*FTLibrary) Close

func (l *FTLibrary) Close()

type FTStroker

type FTStroker struct{}

FTStroker is a no-op stub.

func NewFTStroker

func NewFTStroker(_ FTLibrary) (FTStroker, error)

func (*FTStroker) Close

func (s *FTStroker) Close()

type FontAxis

type FontAxis struct {
	Tag   string
	Value float32
}

FontAxis represents a variable font axis tag and value.

type FontFeature

type FontFeature struct {
	Tag   string
	Value int
}

FontFeature represents an OpenType feature tag and value.

type FontFeatures

type FontFeatures struct {
	OpenTypeFeatures []FontFeature
	VariationAxes    []FontAxis
}

FontFeatures holds OpenType features and variable font axes.

type Glyph

type Glyph struct {
	Index     uint32
	XOffset   float64
	YOffset   float64
	XAdvance  float64
	YAdvance  float64
	Codepoint uint32 // Cluster byte length (use with Index as byte offset).
	GlyphID   uint16 // Resolved CGGlyph/HB glyph ID (0 = unknown, use text).
}

Glyph holds a shaped glyph index and its positioning offsets.

type GlyphAtlas

type GlyphAtlas struct {
	Backend           DrawBackend
	Pages             []AtlasPage
	Garbage           []TextureID // Textures pending deletion.
	MaxPages          int
	CurrentPage       int
	FrameCounter      uint64
	MaxGlyphDimension int
	LastFrame         uint64
}

GlyphAtlas manages a multi-page texture atlas for glyph bitmaps.

Not safe for concurrent use. Accessed only through Renderer.

func NewGlyphAtlas

func NewGlyphAtlas(backend DrawBackend, w, h int) (*GlyphAtlas, error)

NewGlyphAtlas creates a new glyph atlas with one initial page. Dimensions are rounded up to the next power of two to satisfy GPU texture alignment requirements (most drivers silently round up non-power-of-two textures, wasting VRAM). Dimensions below 64 are clamped to 64.

func (*GlyphAtlas) Cleanup

func (atlas *GlyphAtlas) Cleanup(frame uint64)

Cleanup removes stale textures from previous frames.

func (*GlyphAtlas) Free

func (atlas *GlyphAtlas) Free()

Free releases all atlas textures.

func (*GlyphAtlas) InsertBitmap

func (atlas *GlyphAtlas) InsertBitmap(bmp Bitmap, left, top int) (CachedGlyph, bool, int, error)

InsertBitmap places a bitmap into the atlas using shelf-based best-height-fit with multi-page support. Returns the CachedGlyph, whether a page reset occurred, and the index of the reset page.

func (*GlyphAtlas) SwapAndUpload

func (atlas *GlyphAtlas) SwapAndUpload()

SwapAndUpload swaps staging buffers and uploads dirty pages to the GPU.

type GlyphInfo

type GlyphInfo struct {
	X       float32
	Y       float32 // Baseline y.
	Advance float32
	Index   int // Index into Layout.Glyphs.
}

GlyphInfo provides the absolute position and advance of a glyph within a Layout. Returned by GlyphPositions.

type GlyphPlacement

type GlyphPlacement struct {
	X     float32 // Absolute screen x.
	Y     float32 // Absolute screen y (baseline).
	Angle float32 // Rotation in radians, 0 = upright.
}

GlyphPlacement specifies absolute screen position and rotation for a single glyph. Used with DrawLayoutPlaced for text-on-curve.

type GradientConfig

type GradientConfig struct {
	Stops     []GradientStop
	Direction GradientDirection
}

GradientConfig defines an N-stop gradient for text rendering. Stops must be sorted by position in ascending order.

type GradientDirection

type GradientDirection int

GradientDirection controls the axis of color interpolation.

const (
	GradientHorizontal GradientDirection = iota // Left to right.
	GradientVertical                            // Top to bottom.
)

type GradientStop

type GradientStop struct {
	Color    Color
	Position float32
}

GradientStop defines a color at a normalized position (0.0–1.0).

type InlineObject

type InlineObject struct {
	ID     string
	Width  float32 // Points.
	Height float32
	Offset float32 // Baseline offset.
}

InlineObject represents an embedded non-text element in a layout.

type Item

type Item struct {
	Style TextStyle

	FTFace   unsafe.Pointer // *C.FT_FaceRec, set during layout.
	RunText  string
	ObjectID string

	CSSFont string // WASM only: CSS font string for glyph rasterization.

	Width   float64
	X       float64 // Run position relative to layout.
	Y       float64 // Baseline y relative to layout.
	Ascent  float64
	Descent float64

	GlyphStart int
	GlyphCount int
	StartIndex int
	Length     int

	// Decoration metrics.
	UnderlineOffset        float64
	UnderlineThickness     float64
	StrikethroughOffset    float64
	StrikethroughThickness float64

	StrokeWidth float32

	Color   Color
	BgColor Color

	StrokeColor Color

	HasUnderline     bool
	HasStrikethrough bool
	HasBgColor       bool
	HasStroke        bool
	UseOriginalColor bool // True for emoji — skip tinting.
	IsObject         bool
}

Item is a run of glyphs sharing the same font and attributes.

type Layout

type Layout struct {
	CharRectByIndex map[int]int // byte index → CharRects index
	LogAttrByIndex  map[int]int // byte index → LogAttrs index
	Text            string
	ClonedObjectIDs []string
	Items           []Item
	Glyphs          []Glyph
	CharRects       []CharRect
	Lines           []Line
	LogAttrs        []LogAttr

	Width        float32 // Logical width.
	Height       float32 // Logical height.
	VisualWidth  float32 // Ink width.
	VisualHeight float32 // Ink height.
	// contains filtered or unexported fields
}

Layout is the result of text shaping. It contains positioned glyph runs, hit-test rectangles, line boundaries, and cursor attributes.

func (*Layout) GetCharRect

func (l *Layout) GetCharRect(index int) (Rect, bool)

GetCharRect returns the bounding box for a character at byte index. Returns ok=false if index is not a valid character position.

func (*Layout) GetClosestOffset

func (l *Layout) GetClosestOffset(x, y float32) int

GetClosestOffset returns the byte index of the character closest to (x, y). Handles clicks outside bounds.

func (*Layout) GetCursorPos

func (l *Layout) GetCursorPos(byteIndex int) (CursorPosition, bool)

GetCursorPos returns cursor geometry at byte_index. Returns ok=false if not a valid cursor position.

func (*Layout) GetFontNameAtIndex

func (l *Layout) GetFontNameAtIndex(index int) string

GetFontNameAtIndex returns the font family name at byte index.

func (*Layout) GetParagraphAtIndex

func (l *Layout) GetParagraphAtIndex(byteIndex int, text string) (int, int)

GetParagraphAtIndex returns (start, end) byte indices for paragraph containing index. Paragraph = text between \n\n.

func (*Layout) GetSelectionRects

func (l *Layout) GetSelectionRects(start, end int) []Rect

GetSelectionRects returns rectangles covering [start, end).

func (*Layout) GetValidCursorPositions

func (l *Layout) GetValidCursorPositions() []int

GetValidCursorPositions returns sorted byte indices that are valid cursor positions. Uses pre-built cache.

func (*Layout) GetWordAtIndex

func (l *Layout) GetWordAtIndex(byteIndex int) (int, int)

GetWordAtIndex returns (start, end) byte indices for word containing index. Returns (index, index) if not in a word.

func (*Layout) GlyphPositions

func (l *Layout) GlyphPositions() []GlyphInfo

GlyphPositions returns the absolute position, advance, and index of every glyph in the layout.

func (*Layout) HitTest

func (l *Layout) HitTest(x, y float32) int

HitTest returns the byte index of the character at (x, y) relative to origin. Returns -1 if no character is found.

func (*Layout) HitTestRect

func (l *Layout) HitTestRect(x, y float32) (Rect, bool)

HitTestRect returns the bounding box of the character at (x, y) relative to the layout origin. Returns ok=false if no character is found.

func (*Layout) MoveCursorDown

func (l *Layout) MoveCursorDown(byteIndex int, preferredX float32) int

MoveCursorDown returns byte index on next line at similar x.

func (*Layout) MoveCursorLeft

func (l *Layout) MoveCursorLeft(byteIndex int) int

MoveCursorLeft returns the previous valid cursor position.

func (*Layout) MoveCursorLineEnd

func (l *Layout) MoveCursorLineEnd(byteIndex int) int

MoveCursorLineEnd returns the end of the current line. At a soft-wrap boundary the later line is preferred.

func (*Layout) MoveCursorLineStart

func (l *Layout) MoveCursorLineStart(byteIndex int) int

MoveCursorLineStart returns the start of the current line. At a soft-wrap boundary the later line is preferred.

func (*Layout) MoveCursorRight

func (l *Layout) MoveCursorRight(byteIndex int) int

MoveCursorRight returns the next valid cursor position.

func (*Layout) MoveCursorUp

func (l *Layout) MoveCursorUp(byteIndex int, preferredX float32) int

MoveCursorUp returns byte index on previous line at similar x. Pass preferredX < 0 to use cursor's current x.

func (*Layout) MoveCursorWordLeft

func (l *Layout) MoveCursorWordLeft(byteIndex int) int

MoveCursorWordLeft returns the previous word start.

func (*Layout) MoveCursorWordRight

func (l *Layout) MoveCursorWordRight(byteIndex int) int

MoveCursorWordRight returns the next word start.

type Line

type Line struct {
	StartIndex       int
	Length           int
	Rect             Rect // Logical bounding box relative to layout.
	IsParagraphStart bool
}

Line describes one line of a laid-out paragraph.

type LoadGlyphConfig

type LoadGlyphConfig struct {
	Index        uint32
	Codepoint    uint32
	TargetHeight int
	SubpixelBin  int
	CSSFont      string
}

LoadGlyphConfig holds parameters for WASM glyph rasterization.

type LoadGlyphResult

type LoadGlyphResult struct {
	Cached        CachedGlyph
	ResetOccurred bool
	ResetPage     int
}

LoadGlyphResult holds the output of a glyph load operation.

type LogAttr

type LogAttr struct {
	IsCursorPosition bool
	IsWordStart      bool
	IsWordEnd        bool
	IsLineBreak      bool
}

LogAttr holds character classification for cursor/word boundaries.

type MutationResult

type MutationResult struct {
	NewText     string
	DeletedText string
	CursorPos   int
	RangeStart  int
	RangeEnd    int
}

MutationResult contains the result of applying a text mutation.

func CutSelection

func CutSelection(text string, cursor, anchor int) (string, MutationResult)

CutSelection removes selected text and returns it for clipboard.

func DeleteBackward

func DeleteBackward(text string, layout Layout, cursor int) MutationResult

DeleteBackward removes one grapheme cluster before cursor (Backspace). Uses layout.MoveCursorLeft for grapheme boundary.

func DeleteForward

func DeleteForward(text string, layout Layout, cursor int) MutationResult

DeleteForward removes one grapheme cluster after cursor (Delete).

func DeleteSelection

func DeleteSelection(text string, cursor, anchor int) MutationResult

DeleteSelection removes text between cursor and anchor.

func DeleteToLineEnd

func DeleteToLineEnd(text string, layout Layout, cursor int) MutationResult

DeleteToLineEnd removes text from cursor to line end (Cmd+Delete).

func DeleteToLineStart

func DeleteToLineStart(text string, layout Layout, cursor int) MutationResult

DeleteToLineStart removes text from cursor to line start (Cmd+Backspace).

func DeleteToWordBoundary

func DeleteToWordBoundary(text string, layout Layout, cursor int) MutationResult

DeleteToWordBoundary removes text from cursor to previous word boundary (Option+Backspace).

func DeleteToWordEnd

func DeleteToWordEnd(text string, layout Layout, cursor int) MutationResult

DeleteToWordEnd removes text from cursor to next word boundary (Option+Delete).

func InsertReplacingSelection

func InsertReplacingSelection(text string, cursor, anchor int, insert string) MutationResult

InsertReplacingSelection inserts text, replacing any selection.

func InsertText

func InsertText(text string, cursor int, insert string) MutationResult

InsertText inserts a string at cursor position.

func (MutationResult) ToChange

func (m MutationResult) ToChange(inserted string) TextChange

ToChange converts a MutationResult to a TextChange.

type OperationType

type OperationType int

OperationType identifies the kind of undo operation.

const (
	OpInsert OperationType = iota
	OpDelete
	OpReplace
)

type PangoAttrListW

type PangoAttrListW struct{}

PangoAttrListW is a no-op stub.

func NewPangoAttrList

func NewPangoAttrList() PangoAttrListW

func (*PangoAttrListW) Close

func (a *PangoAttrListW) Close()

type PangoContextW

type PangoContextW struct{}

PangoContextW is a no-op stub.

func (*PangoContextW) Close

func (c *PangoContextW) Close()

type PangoFontDescW

type PangoFontDescW struct{}

PangoFontDescW is a no-op stub.

func (*PangoFontDescW) Close

func (d *PangoFontDescW) Close()

func (PangoFontDescW) SetSize

func (d PangoFontDescW) SetSize(_ int)

func (PangoFontDescW) SetStyle

func (d PangoFontDescW) SetStyle(_ int)

func (PangoFontDescW) SetVariations

func (d PangoFontDescW) SetVariations(_ string)

func (PangoFontDescW) SetWeight

func (d PangoFontDescW) SetWeight(_ int)

type PangoFontMapW

type PangoFontMapW struct{}

PangoFontMapW is a no-op stub.

func NewPangoFT2FontMap

func NewPangoFT2FontMap() PangoFontMapW

func (*PangoFontMapW) Close

func (m *PangoFontMapW) Close()

func (PangoFontMapW) CreateContext

func (m PangoFontMapW) CreateContext() PangoContextW

func (PangoFontMapW) SetResolution

func (m PangoFontMapW) SetResolution(_, _ float64)

type PangoFontMetricsW

type PangoFontMetricsW struct{}

PangoFontMetricsW is a no-op stub.

func (*PangoFontMetricsW) Close

func (m *PangoFontMetricsW) Close()

type PangoFontW

type PangoFontW struct{}

PangoFontW is a no-op stub.

func (*PangoFontW) Close

func (f *PangoFontW) Close()

type PangoLayoutIterW

type PangoLayoutIterW struct{}

PangoLayoutIterW is a no-op stub.

func (*PangoLayoutIterW) Close

func (it *PangoLayoutIterW) Close()

type PangoLayoutW

type PangoLayoutW struct{}

PangoLayoutW is a no-op stub.

func (*PangoLayoutW) Close

func (l *PangoLayoutW) Close()

type PangoTabArrayW

type PangoTabArrayW struct{}

PangoTabArrayW is a no-op stub.

func NewPangoTabArray

func NewPangoTabArray(_ int) PangoTabArrayW

func (*PangoTabArrayW) Close

func (t *PangoTabArrayW) Close()

func (PangoTabArrayW) SetTab

func (t PangoTabArrayW) SetTab(_, _ int)

type Rect

type Rect struct {
	X, Y, Width, Height float32
}

Rect is an axis-aligned rectangle.

type Renderer

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

Renderer rasterizes glyphs via Canvas2D fillText, manages the glyph cache and atlas, and emits draw calls through DrawBackend.

Not safe for concurrent use. All methods must be called from a single goroutine (typically the render/GL thread).

func NewRenderer

func NewRenderer(backend DrawBackend, scaleFactor float32) (*Renderer, error)

func NewRendererWithConfig

func NewRendererWithConfig(backend DrawBackend, scaleFactor float32,
	atlasW, atlasH int, cfg RendererConfig) (*Renderer, error)

func (*Renderer) Atlas

func (r *Renderer) Atlas() *GlyphAtlas

func (*Renderer) Commit

func (r *Renderer) Commit()

func (*Renderer) DrawComposition

func (r *Renderer) DrawComposition(layout Layout, x, y float32,
	cs *CompositionState, cursorColor Color)

DrawComposition renders IME preedit visual feedback: clause underlines and preedit cursor. Call after DrawLayout when composition is active.

func (*Renderer) DrawLayout

func (r *Renderer) DrawLayout(layout Layout, x, y float32)

func (*Renderer) DrawLayoutPlaced

func (r *Renderer) DrawLayoutPlaced(layout Layout,
	placements []GlyphPlacement)

func (*Renderer) DrawLayoutRotated

func (r *Renderer) DrawLayoutRotated(layout Layout, x, y, angle float32)

func (*Renderer) DrawLayoutTransformed

func (r *Renderer) DrawLayoutTransformed(layout Layout, x, y float32,
	transform AffineTransform)

func (*Renderer) DrawLayoutTransformedWithGradient

func (r *Renderer) DrawLayoutTransformedWithGradient(layout Layout,
	x, y float32, transform AffineTransform, gradient *GradientConfig)

func (*Renderer) DrawLayoutWithComposition

func (r *Renderer) DrawLayoutWithComposition(layout Layout, x, y float32,
	cs *CompositionState)

DrawLayoutWithComposition renders a layout with preedit text. Currently draws normally; opacity reduction deferred to future.

func (*Renderer) DrawLayoutWithGradient

func (r *Renderer) DrawLayoutWithGradient(layout Layout, x, y float32,
	gradient *GradientConfig)

func (*Renderer) Free

func (r *Renderer) Free()

type RendererConfig

type RendererConfig struct {
	MaxGlyphCacheEntries int
}

RendererConfig configures the Renderer.

type RichText

type RichText struct {
	Runs []StyleRun
}

RichText is a sequence of styled runs.

type Shelf

type Shelf struct {
	Y       int // Vertical position of shelf top.
	Height  int // Shelf height (fixed at creation).
	CursorX int // Next free x position.
	Width   int // Shelf width (page width).
}

Shelf is a horizontal strip within an atlas page.

type StyleRun

type StyleRun struct {
	Style TextStyle
	Text  string
}

StyleRun is a text segment with its own style.

type TextChange

type TextChange struct {
	NewText    string
	OldText    string
	RangeStart int
	RangeEnd   int
}

TextChange captures mutation info for undo support and events.

type TextConfig

type TextConfig struct {
	Style        TextStyle
	Gradient     *GradientConfig // nil = no gradient.
	Block        BlockStyle
	Orientation  TextOrientation
	UseMarkup    bool
	NoHitTesting bool
}

TextConfig holds configuration for text layout and rendering.

type TextMetrics

type TextMetrics struct {
	Ascender  float32
	Descender float32
	Height    float32
	LineGap   float32
}

TextMetrics contains metrics for a specific font configuration. All values are in pixels.

type TextOrientation

type TextOrientation int

TextOrientation defines the flow direction of text.

const (
	OrientationHorizontal TextOrientation = iota
	OrientationVertical                   // Vertical flow, upright chars (CJK).
)

type TextStyle

type TextStyle struct {
	Features *FontFeatures
	Object   *InlineObject
	// FontName is a Pango font description string, e.g. "Sans Italic Light 15".
	FontName string
	// Typeface overrides weight/style in FontName when not TypefaceRegular.
	Typeface Typeface
	// Size overrides the size in FontName (points). 0 = use FontName.
	Size float32
	// LetterSpacing is extra spacing between characters (points).
	LetterSpacing float32

	// StrokeWidth is outline width in points (0 = no stroke).
	StrokeWidth float32
	Color       Color
	// BgColor is the background highlight color behind the text run.
	BgColor Color

	StrokeColor Color

	Underline     bool
	Strikethrough bool
}

TextStyle represents the visual style of a run of text.

type TextSystem

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

TextSystem is the main entry point for text rendering. It owns the Context, Renderer, and a layout cache.

Not safe for concurrent use. Callers must serialize access externally if shared across goroutines.

func NewTextSystem

func NewTextSystem(backend DrawBackend) (*TextSystem, error)

NewTextSystem creates a TextSystem with default atlas size (1024x1024).

func NewTextSystemAtlasSize

func NewTextSystemAtlasSize(backend DrawBackend, atlasW, atlasH int) (*TextSystem, error)

NewTextSystemAtlasSize creates a TextSystem with custom atlas dimensions.

func (*TextSystem) AddFontFile

func (ts *TextSystem) AddFontFile(path string) error

AddFontFile registers a font file (TTF/OTF). Clears the layout cache to prevent stale FT_Face pointers.

func (*TextSystem) Commit

func (ts *TextSystem) Commit()

Commit uploads atlas textures and prunes the layout cache. Call once per frame after all draw calls.

func (*TextSystem) Context

func (ts *TextSystem) Context() *Context

Context returns the underlying Context for advanced usage.

func (*TextSystem) DrawLayout

func (ts *TextSystem) DrawLayout(l Layout, x, y float32)

DrawLayout renders a pre-computed Layout at (x, y).

func (*TextSystem) DrawLayoutPlaced

func (ts *TextSystem) DrawLayoutPlaced(l Layout, placements []GlyphPlacement)

DrawLayoutPlaced renders glyphs at individual placements.

func (*TextSystem) DrawLayoutRotated

func (ts *TextSystem) DrawLayoutRotated(l Layout, x, y, angle float32)

DrawLayoutRotated renders rotated by angle (radians).

func (*TextSystem) DrawLayoutTransformed

func (ts *TextSystem) DrawLayoutTransformed(l Layout, x, y float32,
	transform AffineTransform)

DrawLayoutTransformed renders with an affine transform.

func (*TextSystem) DrawLayoutTransformedWithGradient

func (ts *TextSystem) DrawLayoutTransformedWithGradient(
	l Layout,
	x, y float32,
	transform AffineTransform,
	gradient *GradientConfig,
)

DrawLayoutTransformedWithGradient renders with both an affine transform and gradient colors.

func (*TextSystem) DrawLayoutWithGradient

func (ts *TextSystem) DrawLayoutWithGradient(l Layout, x, y float32,
	gradient *GradientConfig)

DrawLayoutWithGradient renders with gradient colors.

func (*TextSystem) DrawText

func (ts *TextSystem) DrawText(x, y float32, text string, cfg TextConfig) error

DrawText renders text at (x, y) using configuration. Uses layout cache for repeated calls.

func (*TextSystem) FontHeight

func (ts *TextSystem) FontHeight(cfg TextConfig) (float32, error)

FontHeight returns the font height (ascent + descent) in pixels.

func (*TextSystem) FontMetrics

func (ts *TextSystem) FontMetrics(cfg TextConfig) (TextMetrics, error)

FontMetrics returns detailed font metrics.

func (*TextSystem) Free

func (ts *TextSystem) Free()

Free releases all TextSystem resources.

func (*TextSystem) LayoutRichText

func (ts *TextSystem) LayoutRichText(rt RichText, cfg TextConfig) (Layout, error)

LayoutRichText computes a Layout for multi-styled text.

func (*TextSystem) LayoutText

func (ts *TextSystem) LayoutText(text string, cfg TextConfig) (Layout, error)

LayoutText computes a new Layout (bypasses cache).

func (*TextSystem) LayoutTextCached

func (ts *TextSystem) LayoutTextCached(text string, cfg TextConfig) (Layout, error)

LayoutTextCached retrieves a cached layout or creates a new one.

func (*TextSystem) Renderer

func (ts *TextSystem) Renderer() *Renderer

Renderer returns the underlying Renderer for advanced usage.

func (*TextSystem) ResolveFontName

func (ts *TextSystem) ResolveFontName(name string) (string, error)

ResolveFontName returns the actual font family name that Pango resolves for the given description string.

func (*TextSystem) TextHeight

func (ts *TextSystem) TextHeight(text string, cfg TextConfig) (float32, error)

TextHeight returns the visual height (pixels) of text.

func (*TextSystem) TextWidth

func (ts *TextSystem) TextWidth(text string, cfg TextConfig) (float32, error)

TextWidth returns the width (pixels) of text if rendered with cfg.

type TextureID

type TextureID uint64

TextureID is an opaque handle to a GPU texture managed by a DrawBackend.

type Typeface

type Typeface int

Typeface specifies bold/italic style programmatically.

const (
	TypefaceRegular    Typeface = iota // Default — preserves font_name style.
	TypefaceBold                       // Override to bold.
	TypefaceItalic                     // Override to italic.
	TypefaceBoldItalic                 // Override to bold+italic.
)

type UndoManager

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

UndoManager tracks undo/redo stacks with coalescing.

func NewUndoManager

func NewUndoManager(maxHistory int) *UndoManager

NewUndoManager creates an UndoManager with specified history limit.

func (*UndoManager) BreakCoalescing

func (um *UndoManager) BreakCoalescing()

BreakCoalescing flushes pending operation on cursor navigation.

func (*UndoManager) CanRedo

func (um *UndoManager) CanRedo() bool

CanRedo returns true if redo is possible.

func (*UndoManager) CanUndo

func (um *UndoManager) CanUndo() bool

CanUndo returns true if undo is possible.

func (*UndoManager) Clear

func (um *UndoManager) Clear()

Clear resets all undo/redo state.

func (*UndoManager) FlushPending

func (um *UndoManager) FlushPending()

FlushPending pushes pending coalescable op to undo stack.

func (*UndoManager) RecordMutation

func (um *UndoManager) RecordMutation(result MutationResult,
	inserted string, cursorBefore, anchorBefore int)

RecordMutation tracks a mutation for undo support.

func (*UndoManager) Redo

func (um *UndoManager) Redo(text string) *UndoResult

Redo reapplies an undone operation. Returns nil if nothing to redo.

func (*UndoManager) Undo

func (um *UndoManager) Undo(text string) *UndoResult

Undo reverses the last operation. Returns nil if nothing to undo.

func (*UndoManager) UndoDepth

func (um *UndoManager) UndoDepth() int

UndoDepth returns count of operations available for undo.

type UndoOperation

type UndoOperation struct {
	DeletedText  string
	InsertedText string
	OpType       OperationType
	CursorBefore int
	AnchorBefore int
	RangeStart   int
	RangeEnd     int
	CursorAfter  int
	AnchorAfter  int
}

UndoOperation stores inverse operation data for undo/redo.

func MutationToUndoOp

func MutationToUndoOp(result MutationResult, inserted string,
	cursorBefore, anchorBefore int) UndoOperation

MutationToUndoOp converts a MutationResult to an UndoOperation.

type UndoResult

type UndoResult struct {
	Text   string
	Cursor int
	Anchor int
}

UndoResult holds the result of an undo/redo operation.

type WrapMode

type WrapMode int

WrapMode defines how text wraps when exceeding max width.

const (
	WrapNone     WrapMode = -1 // Do not wrap, even when a width is set.
	WrapWord     WrapMode = 0  // Wrap at word boundaries (PANGO_WRAP_WORD).
	WrapChar     WrapMode = 1  // Wrap at character boundaries (PANGO_WRAP_CHAR).
	WrapWordChar WrapMode = 2  // Wrap at word, fallback to char (PANGO_WRAP_WORD_CHAR).
)

Directories

Path Synopsis
Package accessibility provides screen reader support for the glyph text rendering library.
Package accessibility provides screen reader support for the glyph text rendering library.
backend
ebitengine
Package ebitengine provides an Ebitengine DrawBackend for the glyph text rendering library.
Package ebitengine provides an Ebitengine DrawBackend for the glyph text rendering library.
gpu
Package gpu provides a raw Metal DrawBackend for the glyph text rendering library.
Package gpu provides a raw Metal DrawBackend for the glyph text rendering library.
sdl2
Package sdl2 provides an SDL2 DrawBackend for the glyph text rendering library.
Package sdl2 provides an SDL2 DrawBackend for the glyph text rendering library.
web
Package web provides a Canvas2D DrawBackend for browser-based rendering of go-glyph text.
Package web provides a Canvas2D DrawBackend for browser-based rendering of go-glyph text.
Package ime provides platform-specific IME (Input Method Editor) bridges.
Package ime provides platform-specific IME (Input Method Editor) bridges.

Jump to

Keyboard shortcuts

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