text/msdf/types.go

Functions Structs

Functions

func Add

Add returns p + q.

func (p Point) Add(q Point) Point {
	return Point{p.X + q.X, p.Y + q.Y}
}

func Angle

Angle returns the angle of the vector in radians (-pi, pi].

func (p Point) Angle() float64 {
	return math.Atan2(p.Y, p.X)
}

func AngleBetween

AngleBetween returns the angle between two vectors in radians [0, pi].

func AngleBetween(a, b Point) float64 {
	dot := a.Dot(b)
	lenA := a.Length()
	lenB := b.Length()
	if lenA == 0 || lenB == 0 {
		return 0
	}
	cosAngle := dot / (lenA * lenB)
	// Clamp to [-1, 1] to handle floating point errors
	if cosAngle > 1 {
		cosAngle = 1
	}
	if cosAngle < -1 {
		cosAngle = -1
	}
	return math.Acos(cosAngle)
}

func Center

Center returns the center point of the rectangle.

func (r Rect) Center() Point {
	return Point{
		(r.MinX + r.MaxX) / 2,
		(r.MinY + r.MaxY) / 2,
	}
}

func Combine

Combine returns the closer distance of the two.

func (d SignedDistance) Combine(other SignedDistance) SignedDistance {
	if d.IsCloserThan(other) {
		return d
	}
	return other
}

func Contains

Contains returns true if the point is inside the rectangle.

func (r Rect) Contains(p Point) bool {
	return p.X >= r.MinX && p.X <= r.MaxX && p.Y >= r.MinY && p.Y <= r.MaxY
}

func Cross

Cross returns the 2D cross product (z-component of 3D cross).

func (p Point) Cross(q Point) float64 {
	return p.X*q.Y - p.Y*q.X
}

func DefaultConfig

DefaultConfig returns the default MSDF configuration.

These values work well for most text rendering scenarios.

func DefaultConfig() Config {
	return Config{
		Size:		32,
		Range:		4.0,
		AngleThreshold:	math.Pi / 3,	// 60 degrees
		EdgeThreshold:	1.001,
	}
}

func Dot

Dot returns the dot product of p and q.

func (p Point) Dot(q Point) float64 {
	return p.X*q.X + p.Y*q.Y
}

func Error

func (e *ConfigError) Error() string {
	return "msdf: invalid config." + e.Field + ": " + e.Reason
}

func Expand

Expand returns a rectangle expanded by the given margin on all sides.

func (r Rect) Expand(margin float64) Rect {
	return Rect{
		MinX:	r.MinX - margin,
		MinY:	r.MinY - margin,
		MaxX:	r.MaxX + margin,
		MaxY:	r.MaxY + margin,
	}
}

func GetPixel

GetPixel returns the RGB values at (x, y).

func (m *MSDF) GetPixel(x, y int) (r, g, b byte) {
	offset := m.PixelOffset(x, y)
	return m.Data[offset], m.Data[offset+1], m.Data[offset+2]
}

func Height

Height returns the height of the rectangle.

func (r Rect) Height() float64 {
	return r.MaxY - r.MinY
}

func Infinite

Infinite returns a signed distance representing infinity.

func Infinite() SignedDistance {
	return SignedDistance{Distance: math.MaxFloat64, Dot: 0}
}

func IsCloserThan

IsCloserThan returns true if d is closer to the edge than other.

func (d SignedDistance) IsCloserThan(other SignedDistance) bool {
	absD := math.Abs(d.Distance)
	absO := math.Abs(other.Distance)
	if absD < absO {
		return true
	}
	if absD > absO {
		return false
	}
	// Equal absolute distance - use dot product to break ties
	return d.Dot < other.Dot
}

func IsEmpty

IsEmpty returns true if the rectangle has zero or negative area.

func (r Rect) IsEmpty() bool {
	return r.MinX >= r.MaxX || r.MinY >= r.MaxY
}

func Length

Length returns the Euclidean length of the vector.

func (p Point) Length() float64 {
	return math.Sqrt(p.X*p.X + p.Y*p.Y)
}

func LengthSquared

LengthSquared returns the squared length (avoids sqrt).

func (p Point) LengthSquared() float64 {
	return p.X*p.X + p.Y*p.Y
}

func Lerp

Lerp returns linear interpolation between p and q: p + t*(q-p).

func (p Point) Lerp(q Point, t float64) Point {
	return Point{
		p.X + t*(q.X-p.X),
		p.Y + t*(q.Y-p.Y),
	}
}

func Mul

Mul returns p * scalar.

func (p Point) Mul(s float64) Point {
	return Point{p.X * s, p.Y * s}
}

func NewSignedDistance

NewSignedDistance creates a new signed distance.

func NewSignedDistance(distance, dot float64) SignedDistance {
	return SignedDistance{Distance: distance, Dot: dot}
}

func Normalized

Normalized returns a unit vector in the same direction.

Returns zero vector if length is zero.

func (p Point) Normalized() Point {
	length := p.Length()
	if length == 0 {
		return Point{}
	}
	return Point{p.X / length, p.Y / length}
}

func OutlineToPixel

OutlineToPixel converts outline coordinates to pixel coordinates.

func (m *MSDF) OutlineToPixel(ox, oy float64) (px, py float64) {
	px = (ox-m.Bounds.MinX)*m.Scale + m.TranslateX
	py = (oy-m.Bounds.MinY)*m.Scale + m.TranslateY
	return
}

func Perpendicular

Perpendicular returns a perpendicular vector (rotated 90 degrees CCW).

func (p Point) Perpendicular() Point {
	return Point{-p.Y, p.X}
}

func PixelOffset

PixelOffset returns the byte offset for pixel (x, y).

func (m *MSDF) PixelOffset(x, y int) int {
	return (y*m.Width + x) * 3
}

func PixelToOutline

PixelToOutline converts pixel coordinates to outline coordinates.

func (m *MSDF) PixelToOutline(px, py float64) (ox, oy float64) {
	ox = (px-m.TranslateX)/m.Scale + m.Bounds.MinX
	oy = (py-m.TranslateY)/m.Scale + m.Bounds.MinY
	return
}

func SetPixel

SetPixel sets the RGB values at (x, y).

func (m *MSDF) SetPixel(x, y int, r, g, b byte) {
	offset := m.PixelOffset(x, y)
	m.Data[offset] = r
	m.Data[offset+1] = g
	m.Data[offset+2] = b
}

func Sub

Sub returns p - q.

func (p Point) Sub(q Point) Point {
	return Point{p.X - q.X, p.Y - q.Y}
}

func Union

Union returns the smallest rectangle containing both r and s.

func (r Rect) Union(s Rect) Rect {
	return Rect{
		MinX:	min(r.MinX, s.MinX),
		MinY:	min(r.MinY, s.MinY),
		MaxX:	max(r.MaxX, s.MaxX),
		MaxY:	max(r.MaxY, s.MaxY),
	}
}

func Validate

Validate checks if the configuration is valid and returns an error if not.

func (c *Config) Validate() error {
	if c.Size < 8 {
		return &ConfigError{Field: "Size", Reason: "must be at least 8"}
	}
	if c.Size > 4096 {
		return &ConfigError{Field: "Size", Reason: "must be at most 4096"}
	}
	if c.Range <= 0 {
		return &ConfigError{Field: "Range", Reason: "must be positive"}
	}
	if c.AngleThreshold <= 0 || c.AngleThreshold > math.Pi {
		return &ConfigError{Field: "AngleThreshold", Reason: "must be in (0, pi]"}
	}
	if c.EdgeThreshold < 1 {
		return &ConfigError{Field: "EdgeThreshold", Reason: "must be at least 1.0"}
	}
	return nil
}

func Width

Width returns the width of the rectangle.

func (r Rect) Width() float64 {
	return r.MaxX - r.MinX
}

Structs

type Config struct

Config holds MSDF generation parameters.

type Config struct {
	// Size is the output texture size (width = height).
	// Typical values: 32, 48, 64.
	// Default: 32
	Size	int

	// Range is the distance range in pixels.
	// This controls how far from the edge the distance field extends.
	// Larger values = softer edges, smaller = sharper but less scalable.
	// Default: 4.0
	Range	float64

	// AngleThreshold is the minimum angle (in radians) to consider a corner sharp.
	// Corners sharper than this get different channel colors to preserve them.
	// Default: pi/3 (60 degrees)
	AngleThreshold	float64

	// EdgeThreshold is the minimum pseudo-distance for edge detection.
	// Used in edge coloring algorithm.
	// Default: 1.001
	EdgeThreshold	float64
}

type ConfigError struct

ConfigError represents a configuration validation error.

type ConfigError struct {
	Field	string
	Reason	string
}

type MSDF struct

MSDF holds the generated multi-channel signed distance field.

type MSDF struct {
	// Data is the RGB pixel data (3 bytes per pixel, row-major order).
	// Red, Green, Blue channels encode directional distance.
	// The median of RGB gives the actual signed distance.
	Data	[]byte

	// Width of the texture in pixels.
	Width	int

	// Height of the texture in pixels.
	Height	int

	// Bounds is the expanded bounding box (shape bounds + pxRange padding)
	// in the original outline coordinate space.
	Bounds	Rect

	// Scale is the scaling factor from outline coordinates to pixel coordinates.
	Scale	float64

	// Translation offset from outline to texture coordinates.
	TranslateX, TranslateY	float64
}

type Point struct

Point represents a 2D point with float64 precision.

Used internally for distance calculations.

type Point struct {
	X, Y float64
}

type Rect struct

Rect represents a 2D rectangle.

type Rect struct {
	MinX, MinY	float64
	MaxX, MaxY	float64
}

type SignedDistance struct

SignedDistance represents a signed distance with additional metadata.

type SignedDistance struct {
	// Distance is the signed Euclidean distance.
	// Negative = inside, Positive = outside.
	Distance	float64

	// Dot is the dot product used for resolving ambiguities.
	// Used when distances are equal.
	Dot	float64
}