recording

package
v0.33.0 Latest Latest
Warning

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

Go to latest
Published: Mar 3, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package recording provides types for recording drawing operations.

The recording system enables vector export (PDF, SVG) by capturing drawing operations as typed command structures instead of immediate rasterization. Commands are stored in a Recording and can be replayed to any backend.

Design follows Cairo's approach of typed command structs for inspectability and debuggability, rather than Skia's binary serialization format.

Architecture

Commands capture all drawing operations:

  • State commands (Save, Restore, SetTransform, SetClip)
  • Drawing commands (FillPath, StrokePath, FillRect, DrawImage, DrawText)
  • Style commands (SetFillStyle, SetStrokeStyle, SetLineWidth, etc.)

Resources (paths, brushes, images) are stored in a ResourcePool and referenced by typed handles (PathRef, BrushRef, ImageRef) to enable deduplication and efficient memory usage.

Example

// Record drawing operations
rec := recording.NewRecorder(800, 600)
rec.Save()
rec.SetTransform(matrix)
rec.FillPath(pathRef, brushRef, FillRuleNonZero)
rec.Restore()
r := rec.Finish()

// Replay to a backend
r.Playback(pdfBackend)

Package recording provides a command-based drawing recording system for gg.

The recording system captures drawing operations as commands that can be played back to different backends, enabling vector export (PDF, SVG) and other transformations of 2D graphics.

Architecture

The system follows a Command Pattern with three main components:

  • Recorder: Captures drawing operations as commands
  • Recording: Stores commands and resources for playback
  • Backend: Renders commands to a specific output format

This design is inspired by Skia's SkPicture and Cairo's recording surface.

Basic Usage

Record drawing operations using a Recorder:

rec := recording.NewRecorder(800, 600)

// Draw using the familiar Context-like API
rec.SetFillRGBA(1, 0, 0, 1) // Red
rec.DrawRectangle(100, 100, 200, 150)
rec.Fill()

rec.SetStrokeRGBA(0, 0, 1, 1) // Blue
rec.SetLineWidth(2)
rec.DrawCircle(400, 300, 50)
rec.Stroke()

// Finish recording
r := rec.FinishRecording()

Playback to Backends

Play back recordings to different output formats:

// PDF output (requires github.com/gogpu/gg-pdf)
import _ "github.com/gogpu/gg-pdf"

pdfBackend, _ := recording.NewBackend("pdf")
r.Playback(pdfBackend)
pdfBackend.(recording.FileBackend).SaveToFile("output.pdf")

// SVG output (requires github.com/gogpu/gg-svg)
import _ "github.com/gogpu/gg-svg"

svgBackend, _ := recording.NewBackend("svg")
r.Playback(svgBackend)
svgBackend.(recording.FileBackend).SaveToFile("output.svg")

// Raster output (built-in)
rasterBackend, _ := recording.NewBackend("raster")
r.Playback(rasterBackend)
rasterBackend.(recording.PixmapBackend).Pixmap() // Get pixel data

Backend Registration

Backends are registered using the database/sql driver pattern. Import a backend package with a blank identifier to automatically register it:

import (
    "github.com/gogpu/gg/recording"
    _ "github.com/gogpu/gg-pdf"  // Registers "pdf" backend
    _ "github.com/gogpu/gg-svg"  // Registers "svg" backend
)

The built-in "raster" backend is always available via:

import _ "github.com/gogpu/gg/recording/backends/raster"

Resource Management

The recording system uses reference-based resource pooling for efficient storage and playback:

  • Paths are cloned and stored with PathRef references
  • Brushes (solid colors, gradients) are stored with BrushRef references
  • Images are stored with ImageRef references
  • Fonts are stored with FontRef references

This ensures recordings are immutable and can be safely played back multiple times to different backends.

Supported Operations

The Recorder supports the full gg drawing API:

  • Path operations: MoveTo, LineTo, QuadraticTo, CubicTo, ClosePath
  • Shape helpers: DrawRectangle, DrawRoundedRectangle, DrawCircle, DrawEllipse, DrawArc, DrawEllipticalArc
  • Fill and stroke with solid colors and gradients
  • Line styles: width, cap, join, miter limit, dash patterns
  • Transformations: Translate, Rotate, Scale, matrix operations
  • Clipping: path-based clipping with fill rules
  • State management: Push/Pop (Save/Restore)
  • Text rendering (font-dependent)
  • Image drawing

Brushes

The recording system supports multiple brush types for fills and strokes:

  • SolidBrush: Single solid color
  • LinearGradientBrush: Linear color gradient
  • RadialGradientBrush: Radial color gradient
  • SweepGradientBrush: Angular/conic gradient

Example gradient usage:

grad := recording.NewLinearGradientBrush(0, 0, 200, 200).
    AddColorStop(0, gg.RGBA{R: 1, G: 0, B: 0, A: 1}).
    AddColorStop(1, gg.RGBA{R: 0, G: 0, B: 1, A: 1})

rec.SetFillStyle(grad)
rec.Fill()

Custom Backends

Implement the Backend interface to create custom output formats:

type Backend interface {
    Begin(width, height int) error
    End() error
    Save()
    Restore()
    SetTransform(m Matrix)
    SetClip(path *gg.Path, rule FillRule)
    ClearClip()
    FillPath(path *gg.Path, brush Brush, rule FillRule)
    StrokePath(path *gg.Path, brush Brush, stroke Stroke)
    FillRect(rect Rect, brush Brush)
    DrawImage(img image.Image, src, dst Rect, opts ImageOptions)
    DrawText(s string, x, y float64, face text.Face, brush Brush)
}

Register custom backends with Register:

func init() {
    recording.Register("myformat", func() recording.Backend {
        return NewMyBackend()
    })
}

Thread Safety

Recorder is NOT safe for concurrent use. Each goroutine should use its own Recorder instance. However, Recording objects are immutable after Finish() and can be safely shared and played back from multiple goroutines.

Performance Considerations

The recording system is optimized for:

  • Minimal allocations during recording (pre-allocated slices)
  • Efficient resource deduplication via pooling
  • Fast playback with direct command dispatch

For real-time rendering, prefer direct gg.Context usage. Use recording when you need vector export or command inspection.

Index

Constants

View Source
const InvalidRef = ^uint32(0)

InvalidRef is the sentinel value for an invalid reference. Use this to indicate that a reference does not point to a valid resource.

Variables

This section is empty.

Functions

func Backends

func Backends() []string

Backends returns a sorted list of registered backend names. The list is sorted alphabetically for consistent output.

func Count

func Count() int

Count returns the number of registered backends.

func IsRegistered

func IsRegistered(name string) bool

IsRegistered checks if a backend with the given name is registered.

func Register

func Register(name string, factory BackendFactory)

Register registers a backend factory with the given name. This function is typically called from init() in backend packages, following the database/sql driver pattern:

func init() {
    recording.Register("pdf", func() recording.Backend {
        return NewPDFBackend()
    })
}

Register panics if:

  • factory is nil
  • a backend with the same name is already registered

This ensures that duplicate registrations are caught early during program initialization rather than silently overwriting backends.

func Unregister

func Unregister(name string)

Unregister removes a backend from the registry. This is primarily useful for testing to clean up between tests. If the backend is not registered, this is a no-op.

Types

type Backend

type Backend interface {

	// Begin initializes the backend for rendering at the given dimensions.
	// This must be called before any drawing operations.
	// Returns an error if initialization fails.
	Begin(width, height int) error

	// End finalizes the rendering and prepares the output.
	// After End is called, output methods (WriteTo, SaveToFile) can be used.
	// Returns an error if finalization fails.
	End() error

	// Save saves the current graphics state (transform, clip) onto a stack.
	// The state can be restored with Restore.
	Save()

	// Restore restores the graphics state from the stack.
	// If the stack is empty, this is a no-op.
	Restore()

	// SetTransform sets the current transformation matrix.
	// This replaces any existing transform.
	SetTransform(m Matrix)

	// SetClip sets the clipping region to the given path.
	// Only pixels inside the path (according to the fill rule) will be drawn.
	// The clip is intersected with any existing clip.
	SetClip(path *gg.Path, rule FillRule)

	// ClearClip removes any clipping region.
	ClearClip()

	// FillPath fills the given path with the brush color/pattern.
	// The rule determines how to handle self-intersecting paths.
	FillPath(path *gg.Path, brush Brush, rule FillRule)

	// StrokePath strokes the given path with the brush and stroke style.
	StrokePath(path *gg.Path, brush Brush, stroke Stroke)

	// FillRect is an optimized method for filling axis-aligned rectangles.
	// Backends may implement this more efficiently than FillPath with a rect path.
	FillRect(rect Rect, brush Brush)

	// DrawImage draws an image from the source rectangle to the destination rectangle.
	// The opts parameter specifies interpolation quality and alpha.
	DrawImage(img image.Image, src, dst Rect, opts ImageOptions)

	// DrawText draws text at the given position with the specified font face and brush.
	// The position (x, y) is the baseline origin of the text.
	DrawText(s string, x, y float64, face text.Face, brush Brush)
}

Backend is the interface that all export backends must implement. Backends receive high-level drawing commands and translate them to their output format (raster pixels, PDF content streams, SVG elements, etc.).

A Backend manages its own state stack for Save/Restore operations and handles coordinate transformations as needed (e.g., PDF Y-flip).

Backends are created via the registry using NewBackend(name) and registered via Register() in their init() functions.

Implementation Contract

Each backend must:

  1. Register in init() using recording.Register()
  2. Handle all Backend methods (even if no-op for some)
  3. Manage own state stack for Save/Restore
  4. Translate coordinates if needed (e.g., PDF Y-flip)

Example Backend Registration

func init() {
    recording.Register("pdf", func() recording.Backend {
        return NewPDFBackend()
    })
}

func MustBackend

func MustBackend(name string) Backend

MustBackend creates a new backend instance by name, panicking on error. This is useful when backend availability is guaranteed.

Example:

backend := recording.MustBackend("raster")

func NewBackend

func NewBackend(name string) (Backend, error)

NewBackend creates a new backend instance by name. The name must match a previously registered backend.

Example:

import _ "github.com/gogpu/gg-pdf" // Register PDF backend

backend, err := recording.NewBackend("pdf")
if err != nil {
    // Handle error - backend not registered
}

Returns an error if the backend is not registered. The error message includes a hint about forgotten imports.

type BackendFactory

type BackendFactory func() Backend

BackendFactory is a function that creates a new backend instance. Factories are registered via Register() and called by NewBackend().

type Brush

type Brush interface {
	// contains filtered or unexported methods
}

Brush represents a fill/stroke style for recording commands. This is a sealed interface - only types in this package implement it.

Unlike gg.Brush which is designed for immediate-mode rendering with ColorAt, recording.Brush stores the brush definition for later playback to different backends (raster, PDF, SVG).

func BrushFromGG

func BrushFromGG(b gg.Brush) Brush

BrushFromGG converts a gg.Brush to a recording.Brush. This extracts the brush definition for storage in a recording.

type BrushRef

type BrushRef uint32

BrushRef is a reference to a brush in the resource pool. The zero value is a valid reference to the first brush (if any).

func (BrushRef) IsValid

func (r BrushRef) IsValid() bool

IsValid returns true if the reference points to a valid brush.

type ClearClipCommand

type ClearClipCommand struct{}

ClearClipCommand clears the clipping region to the full canvas.

func (ClearClipCommand) Type

Type implements Command.

type Command

type Command interface {
	// Type returns the CommandType for this command.
	Type() CommandType
}

Command is the interface implemented by all command types. Commands represent individual drawing operations that can be serialized and replayed to different backends.

type CommandType

type CommandType uint8

CommandType identifies the type of a command. Each command type corresponds to a specific drawing operation.

const (
	// State commands
	CmdSave         CommandType = iota // Save current state
	CmdRestore                         // Restore previous state
	CmdSetTransform                    // Set transformation matrix
	CmdSetClip                         // Set clipping region
	CmdClearClip                       // Clear clipping region

	// Drawing commands
	CmdFillPath   // Fill a path
	CmdStrokePath // Stroke a path
	CmdFillRect   // Fill a rectangle (optimized)
	CmdStrokeRect // Stroke a rectangle
	CmdDrawImage  // Draw an image
	CmdDrawText   // Draw text

	// Style commands
	CmdSetFillStyle   // Set fill brush
	CmdSetStrokeStyle // Set stroke brush
	CmdSetLineWidth   // Set stroke line width
	CmdSetLineCap     // Set stroke line cap
	CmdSetLineJoin    // Set stroke line join
	CmdSetMiterLimit  // Set miter limit
	CmdSetDash        // Set dash pattern
	CmdSetFillRule    // Set fill rule
)

func (CommandType) String

func (c CommandType) String() string

String returns the string representation of a CommandType.

type DrawImageCommand

type DrawImageCommand struct {
	// Image references the image in the resource pool.
	Image ImageRef
	// SrcRect is the source rectangle in image coordinates.
	// If zero, uses the entire image.
	SrcRect Rect
	// DstRect is the destination rectangle in canvas coordinates.
	DstRect Rect
	// Options contains rendering options (interpolation, etc.).
	Options ImageOptions
}

DrawImageCommand draws an image.

func (DrawImageCommand) Type

Type implements Command.

type DrawTextCommand

type DrawTextCommand struct {
	// Text is the string to render.
	Text string
	// X is the horizontal position.
	X float64
	// Y is the vertical position (baseline).
	Y float64
	// FontSize is the size of the font in points.
	FontSize float64
	// FontFamily is the name of the font family.
	FontFamily string
	// Brush references the text color/brush in the resource pool.
	Brush BrushRef
}

DrawTextCommand draws text at a specified position.

func (DrawTextCommand) Type

Type implements Command.

type ExtendMode

type ExtendMode int

ExtendMode defines how gradients extend beyond their defined bounds.

const (
	// ExtendPad extends edge colors beyond bounds (default behavior).
	ExtendPad ExtendMode = iota
	// ExtendRepeat repeats the gradient pattern.
	ExtendRepeat
	// ExtendReflect mirrors the gradient pattern.
	ExtendReflect
)

type FileBackend

type FileBackend interface {
	Backend

	// SaveToFile saves the rendered content to a file at the given path.
	// This should only be called after End().
	// Returns an error if the file cannot be written.
	SaveToFile(path string) error
}

FileBackend extends Backend with the ability to save output directly to a file. This is a convenience interface for backends that can optimize file output.

type FillPathCommand

type FillPathCommand struct {
	// Path references the path to fill in the resource pool.
	Path PathRef
	// Brush references the fill brush in the resource pool.
	Brush BrushRef
	// Rule specifies the fill rule (non-zero or even-odd).
	Rule FillRule
}

FillPathCommand fills a path with a brush.

func (FillPathCommand) Type

Type implements Command.

type FillRectCommand

type FillRectCommand struct {
	// Rect is the rectangle to fill.
	Rect Rect
	// Brush references the fill brush in the resource pool.
	Brush BrushRef
}

FillRectCommand fills a rectangle with a brush. This is an optimization for the common case of axis-aligned rectangles.

func (FillRectCommand) Type

Type implements Command.

type FillRule

type FillRule uint8

FillRule specifies how to determine which areas are inside a path.

const (
	// FillRuleNonZero uses the non-zero winding rule.
	FillRuleNonZero FillRule = iota
	// FillRuleEvenOdd uses the even-odd rule.
	FillRuleEvenOdd
)

type FontRef

type FontRef uint32

FontRef is a reference to a pooled font face. The zero value is a valid reference to the first font (if any).

func (FontRef) IsValid

func (r FontRef) IsValid() bool

IsValid returns true if the reference is valid (not InvalidRef).

type GradientStop

type GradientStop struct {
	Offset float64 // Position in gradient, 0.0 to 1.0
	Color  gg.RGBA // Color at this position
}

GradientStop defines a color stop in a gradient.

type ImageOptions

type ImageOptions struct {
	// Interpolation specifies the interpolation mode.
	Interpolation InterpolationMode
	// Alpha is the opacity (0.0 to 1.0).
	Alpha float64
}

ImageOptions contains options for image rendering.

func DefaultImageOptions

func DefaultImageOptions() ImageOptions

DefaultImageOptions returns ImageOptions with default settings.

type ImageRef

type ImageRef uint32

ImageRef is a reference to an image in the resource pool. The zero value is a valid reference to the first image (if any).

func (ImageRef) IsValid

func (r ImageRef) IsValid() bool

IsValid returns true if the reference points to a valid image.

type InterpolationMode

type InterpolationMode uint8

InterpolationMode specifies how to interpolate between pixels.

const (
	// InterpolationNearest uses nearest-neighbor interpolation.
	InterpolationNearest InterpolationMode = iota
	// InterpolationBilinear uses bilinear interpolation.
	InterpolationBilinear
)

type LineCap

type LineCap uint8

LineCap specifies the shape of line endpoints.

const (
	// LineCapButt specifies a flat line cap.
	LineCapButt LineCap = iota
	// LineCapRound specifies a rounded line cap.
	LineCapRound
	// LineCapSquare specifies a square line cap.
	LineCapSquare
)

type LineJoin

type LineJoin uint8

LineJoin specifies the shape of line joins.

const (
	// LineJoinMiter specifies a sharp (mitered) join.
	LineJoinMiter LineJoin = iota
	// LineJoinRound specifies a rounded join.
	LineJoinRound
	// LineJoinBevel specifies a beveled join.
	LineJoinBevel
)

type LinearGradientBrush

type LinearGradientBrush struct {
	Start  gg.Point       // Start point of the gradient
	End    gg.Point       // End point of the gradient
	Stops  []GradientStop // Color stops defining the gradient
	Extend ExtendMode     // How gradient extends beyond bounds
}

LinearGradientBrush is a linear gradient brush. Colors transition linearly from Start to End.

func NewLinearGradientBrush

func NewLinearGradientBrush(x0, y0, x1, y1 float64) *LinearGradientBrush

NewLinearGradientBrush creates a new linear gradient brush.

func (*LinearGradientBrush) AddColorStop

func (g *LinearGradientBrush) AddColorStop(offset float64, color gg.RGBA) *LinearGradientBrush

AddColorStop adds a color stop at the specified offset. Offset should be in the range [0, 1]. Returns the gradient for method chaining.

func (*LinearGradientBrush) SetExtend

SetExtend sets the extend mode for the gradient. Returns the gradient for method chaining.

type Matrix

type Matrix struct {
	A, B, C float64
	D, E, F float64
}

Matrix represents a 2D affine transformation matrix. It uses a 2x3 matrix in row-major order:

| A  B  C |
| D  E  F |

This represents the transformation:

x' = A*x + B*y + C
y' = D*x + E*y + F

The Matrix type is designed to be compatible with gg.Matrix for seamless integration with the gg graphics library.

func Identity

func Identity() Matrix

Identity returns the identity transformation matrix. The identity matrix performs no transformation.

func Rotate

func Rotate(angle float64) Matrix

Rotate creates a rotation matrix (angle in radians).

func Scale

func Scale(sx, sy float64) Matrix

Scale creates a scaling matrix.

func Shear

func Shear(x, y float64) Matrix

Shear creates a shear matrix.

func Translate

func Translate(x, y float64) Matrix

Translate creates a translation matrix.

func (Matrix) Determinant

func (m Matrix) Determinant() float64

Determinant returns the determinant of the 2x2 part of the matrix. A determinant of zero means the matrix is not invertible. A negative determinant means the transformation flips orientation.

func (Matrix) Invert

func (m Matrix) Invert() Matrix

Invert returns the inverse matrix. Returns the identity matrix if the matrix is not invertible.

func (Matrix) IsIdentity

func (m Matrix) IsIdentity() bool

IsIdentity returns true if the matrix is the identity matrix.

func (Matrix) IsTranslation

func (m Matrix) IsTranslation() bool

IsTranslation returns true if the matrix is only a translation.

func (Matrix) Multiply

func (m Matrix) Multiply(other Matrix) Matrix

Multiply multiplies two matrices (m * other). This applies the transformation of `other` after `m`.

func (Matrix) ScaleFactor

func (m Matrix) ScaleFactor() float64

ScaleFactor returns the maximum scale factor of the transformation. This is useful for determining effective stroke width after transform.

func (Matrix) TransformPoint

func (m Matrix) TransformPoint(x, y float64) (float64, float64)

TransformPoint applies the transformation to a point.

func (Matrix) TransformVector

func (m Matrix) TransformVector(x, y float64) (float64, float64)

TransformVector applies the transformation to a vector (no translation).

func (Matrix) Translation

func (m Matrix) Translation() (x, y float64)

Translation returns the translation components of the matrix.

type PathRef

type PathRef uint32

PathRef is a reference to a path in the resource pool. The zero value is a valid reference to the first path (if any).

func (PathRef) IsValid

func (r PathRef) IsValid() bool

IsValid returns true if the reference points to a valid path.

type PatternBrush

type PatternBrush struct {
	Image     ImageRef   // Reference to the pattern image in the pool
	Repeat    RepeatMode // How the pattern repeats
	Transform gg.Matrix  // Transform applied to the pattern
}

PatternBrush is an image pattern brush. The pattern can be repeated, reflected, or clamped.

func NewPatternBrush

func NewPatternBrush(imageRef ImageRef) *PatternBrush

NewPatternBrush creates a new pattern brush with the given image reference.

func (*PatternBrush) SetRepeat

func (b *PatternBrush) SetRepeat(mode RepeatMode) *PatternBrush

SetRepeat sets the repeat mode for the pattern. Returns the brush for method chaining.

func (*PatternBrush) SetTransform

func (b *PatternBrush) SetTransform(m gg.Matrix) *PatternBrush

SetTransform sets the transform matrix for the pattern. Returns the brush for method chaining.

type PixmapBackend

type PixmapBackend interface {
	Backend

	// Pixmap returns the rendered pixmap.
	// This should only be called after End().
	// Returns nil if no pixmap is available.
	Pixmap() *gg.Pixmap
}

PixmapBackend extends Backend with access to a rasterized pixmap. This is implemented by the raster backend and allows direct pixel access.

type RadialGradientBrush

type RadialGradientBrush struct {
	Center      gg.Point       // Center of the gradient circle
	Focus       gg.Point       // Focal point (can differ from center)
	StartRadius float64        // Inner radius where gradient begins (t=0)
	EndRadius   float64        // Outer radius where gradient ends (t=1)
	Stops       []GradientStop // Color stops defining the gradient
	Extend      ExtendMode     // How gradient extends beyond bounds
}

RadialGradientBrush is a radial gradient brush. Colors radiate from Focus within a circle defined by Center and EndRadius.

func NewRadialGradientBrush

func NewRadialGradientBrush(cx, cy, startRadius, endRadius float64) *RadialGradientBrush

NewRadialGradientBrush creates a new radial gradient brush. The gradient transitions from startRadius to endRadius around (cx, cy). Focus defaults to center.

func (*RadialGradientBrush) AddColorStop

func (g *RadialGradientBrush) AddColorStop(offset float64, color gg.RGBA) *RadialGradientBrush

AddColorStop adds a color stop at the specified offset. Offset should be in the range [0, 1]. Returns the gradient for method chaining.

func (*RadialGradientBrush) SetExtend

SetExtend sets the extend mode for the gradient. Returns the gradient for method chaining.

func (*RadialGradientBrush) SetFocus

func (g *RadialGradientBrush) SetFocus(fx, fy float64) *RadialGradientBrush

SetFocus sets the focal point of the gradient. Returns the gradient for method chaining.

type Recorder

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

Recorder captures drawing operations as commands. It mirrors the gg.Context drawing API but generates commands instead of rasterizing pixels. Use FinishRecording to obtain an immutable Recording that can be replayed to different backends.

Example:

rec := recording.NewRecorder(800, 600)
rec.SetRGB(1, 0, 0)
rec.DrawCircle(100, 100, 50)
rec.Fill()
recording := rec.FinishRecording()

The Recorder is not safe for concurrent use.

func NewRecorder

func NewRecorder(width, height int) *Recorder

NewRecorder creates a new Recorder for the given dimensions. The Recorder starts with default state: black fill/stroke, 1px line width, butt caps, miter joins, non-zero fill rule, and identity transform.

func (*Recorder) Clear

func (r *Recorder) Clear()

Clear fills the entire canvas with the current fill color. This is equivalent to drawing a rectangle covering the entire canvas.

func (*Recorder) ClearDash

func (r *Recorder) ClearDash()

ClearDash removes the dash pattern, returning to solid lines.

func (*Recorder) ClearPath

func (r *Recorder) ClearPath()

ClearPath clears the current path.

func (*Recorder) ClearWithColor

func (r *Recorder) ClearWithColor(c gg.RGBA)

ClearWithColor fills the entire canvas with a specific color.

func (*Recorder) Clip

func (r *Recorder) Clip()

Clip sets the current path as the clipping region and clears the path.

func (*Recorder) ClipPreserve

func (r *Recorder) ClipPreserve()

ClipPreserve sets the current path as the clipping region but keeps the path.

func (*Recorder) ClosePath

func (r *Recorder) ClosePath()

ClosePath closes the current subpath.

func (*Recorder) CubicTo

func (r *Recorder) CubicTo(c1x, c1y, c2x, c2y, x, y float64)

CubicTo adds a cubic Bezier curve to the current path.

func (*Recorder) DrawArc

func (r *Recorder) DrawArc(x, y, radius, angle1, angle2 float64)

DrawArc draws a circular arc.

func (*Recorder) DrawCircle

func (r *Recorder) DrawCircle(x, y, radius float64)

DrawCircle draws a circle.

func (*Recorder) DrawEllipse

func (r *Recorder) DrawEllipse(x, y, rx, ry float64)

DrawEllipse draws an ellipse.

func (*Recorder) DrawEllipticalArc

func (r *Recorder) DrawEllipticalArc(x, y, rx, ry, angle1, angle2 float64)

DrawEllipticalArc draws an elliptical arc.

func (*Recorder) DrawImage

func (r *Recorder) DrawImage(img image.Image, x, y int)

DrawImage draws an image at the specified position.

func (*Recorder) DrawImageAnchored

func (r *Recorder) DrawImageAnchored(img image.Image, x, y int, ax, ay float64)

DrawImageAnchored draws an image with an anchor point.

func (*Recorder) DrawImageScaled

func (r *Recorder) DrawImageScaled(img image.Image, x, y, w, h float64)

DrawImageScaled draws an image scaled to fit the specified rectangle.

func (*Recorder) DrawLine

func (r *Recorder) DrawLine(x1, y1, x2, y2 float64)

DrawLine draws a line between two points.

func (*Recorder) DrawPoint

func (r *Recorder) DrawPoint(x, y, radius float64)

DrawPoint draws a single point at the given coordinates.

func (*Recorder) DrawRectangle

func (r *Recorder) DrawRectangle(x, y, w, h float64)

DrawRectangle draws a rectangle.

func (*Recorder) DrawRoundedRectangle

func (r *Recorder) DrawRoundedRectangle(x, y, w, h, radius float64)

DrawRoundedRectangle draws a rectangle with rounded corners.

func (*Recorder) DrawString

func (r *Recorder) DrawString(s string, x, y float64)

DrawString draws text at position (x, y) where y is the baseline.

func (*Recorder) DrawStringAnchored

func (r *Recorder) DrawStringAnchored(s string, x, y, ax, ay float64)

DrawStringAnchored draws text with an anchor point. The anchor point is specified by ax and ay, which are in the range [0, 1].

func (*Recorder) DrawStringWrapped added in v0.31.0

func (r *Recorder) DrawStringWrapped(s string, x, y, ax, ay, width, lineSpacing float64, align text.Alignment)

DrawStringWrapped wraps text to the given width and draws it with alignment. Each wrapped line is recorded as a separate DrawText command.

func (*Recorder) Fill

func (r *Recorder) Fill()

Fill fills the current path and clears it.

func (*Recorder) FillPreserve

func (r *Recorder) FillPreserve()

FillPreserve fills the current path without clearing it.

func (*Recorder) FillRectangle

func (r *Recorder) FillRectangle(x, y, w, h float64)

FillRectangle fills a rectangle without adding it to the path. This is an optimized operation for the common case of axis-aligned rectangles.

func (*Recorder) FillStroke

func (r *Recorder) FillStroke()

FillStroke fills and then strokes the current path, then clears it.

func (*Recorder) FinishRecording

func (r *Recorder) FinishRecording() *Recording

FinishRecording returns an immutable Recording containing all recorded commands. After calling FinishRecording, the Recorder should not be used again.

func (*Recorder) GetCurrentPoint

func (r *Recorder) GetCurrentPoint() (x, y float64, ok bool)

GetCurrentPoint returns the current point of the path. Returns (0, 0, false) if there is no current point.

func (*Recorder) GetTransform

func (r *Recorder) GetTransform() Matrix

GetTransform returns a copy of the current transformation matrix.

func (*Recorder) Height

func (r *Recorder) Height() int

Height returns the height of the recording canvas.

func (*Recorder) Identity

func (r *Recorder) Identity()

Identity resets the transformation matrix to identity.

func (*Recorder) InvertY

func (r *Recorder) InvertY()

InvertY inverts the Y axis (useful for coordinate system changes).

func (*Recorder) LineTo

func (r *Recorder) LineTo(x, y float64)

LineTo adds a line to the current path.

func (*Recorder) MeasureMultilineString added in v0.31.0

func (r *Recorder) MeasureMultilineString(s string, lineSpacing float64) (width, height float64)

MeasureMultilineString measures text that may contain newlines. Returns (width, height) where width is the maximum line width. If no font face is set, returns (0, 0).

func (*Recorder) MeasureString

func (r *Recorder) MeasureString(s string) (w, h float64)

MeasureString returns approximate dimensions of text. Note: Actual measurement depends on the backend and font. Returns (0, 0) if no font is set.

func (*Recorder) MoveTo

func (r *Recorder) MoveTo(x, y float64)

MoveTo starts a new subpath at the given point.

func (*Recorder) NewSubPath

func (r *Recorder) NewSubPath()

NewSubPath starts a new subpath without closing the previous one. This is a no-op as MoveTo already creates a new subpath.

func (*Recorder) Pop

func (r *Recorder) Pop()

Pop is an alias for Restore, matching gg.Context API.

func (*Recorder) Push

func (r *Recorder) Push()

Push is an alias for Save, matching gg.Context API.

func (*Recorder) QuadraticTo

func (r *Recorder) QuadraticTo(cx, cy, x, y float64)

QuadraticTo adds a quadratic Bezier curve to the current path.

func (*Recorder) ResetClip

func (r *Recorder) ResetClip()

ResetClip removes all clipping regions.

func (*Recorder) Restore

func (r *Recorder) Restore()

Restore restores the previously saved graphics state. If the state stack is empty, this is a no-op.

func (*Recorder) Rotate

func (r *Recorder) Rotate(angle float64)

Rotate applies a rotation (angle in radians).

func (*Recorder) RotateAbout

func (r *Recorder) RotateAbout(angle, x, y float64)

RotateAbout rotates around a specific point.

func (*Recorder) Save

func (r *Recorder) Save()

Save saves the current graphics state to the stack. The state includes transform, fill style, stroke style, and line properties.

func (*Recorder) Scale

func (r *Recorder) Scale(sx, sy float64)

Scale applies a scaling transformation.

func (*Recorder) SetColor

func (r *Recorder) SetColor(c gg.RGBA)

SetColor sets both fill and stroke color from a color.Color.

func (*Recorder) SetDash

func (r *Recorder) SetDash(lengths ...float64)

SetDash sets the dash pattern for stroking. Pass alternating dash and gap lengths. Passing no arguments clears the dash pattern (returns to solid lines).

func (*Recorder) SetDashOffset

func (r *Recorder) SetDashOffset(offset float64)

SetDashOffset sets the starting offset into the dash pattern.

func (*Recorder) SetFillBrush

func (r *Recorder) SetFillBrush(brush gg.Brush)

SetFillBrush sets the fill brush from a gg.Brush.

func (*Recorder) SetFillRGB

func (r *Recorder) SetFillRGB(red, green, blue float64)

SetFillRGB sets the fill color using RGB values (0-1).

func (*Recorder) SetFillRGBA

func (r *Recorder) SetFillRGBA(red, green, blue, alpha float64)

SetFillRGBA sets the fill color using RGBA values (0-1).

func (*Recorder) SetFillRule

func (r *Recorder) SetFillRule(rule FillRule)

SetFillRule sets the fill rule.

func (*Recorder) SetFillRuleGG

func (r *Recorder) SetFillRuleGG(rule gg.FillRule)

SetFillRuleGG sets the fill rule from gg.FillRule.

func (*Recorder) SetFillStyle

func (r *Recorder) SetFillStyle(brush Brush)

SetFillStyle sets the fill brush.

func (*Recorder) SetFont

func (r *Recorder) SetFont(face text.Face)

SetFont sets the current font face for text drawing.

func (*Recorder) SetFontFamily

func (r *Recorder) SetFontFamily(family string)

SetFontFamily sets the current font family name.

func (*Recorder) SetFontSize

func (r *Recorder) SetFontSize(size float64)

SetFontSize sets the current font size in points.

func (*Recorder) SetHexColor

func (r *Recorder) SetHexColor(hex string)

SetHexColor sets both fill and stroke color using a hex string.

func (*Recorder) SetLineCap

func (r *Recorder) SetLineCap(lc LineCap)

SetLineCap sets the line cap style.

func (*Recorder) SetLineCapGG

func (r *Recorder) SetLineCapGG(lc gg.LineCap)

SetLineCapGG sets the line cap style from gg.LineCap.

func (*Recorder) SetLineJoin

func (r *Recorder) SetLineJoin(join LineJoin)

SetLineJoin sets the line join style.

func (*Recorder) SetLineJoinGG

func (r *Recorder) SetLineJoinGG(join gg.LineJoin)

SetLineJoinGG sets the line join style from gg.LineJoin.

func (*Recorder) SetLineWidth

func (r *Recorder) SetLineWidth(width float64)

SetLineWidth sets the line width for stroking.

func (*Recorder) SetMiterLimit

func (r *Recorder) SetMiterLimit(limit float64)

SetMiterLimit sets the miter limit for line joins.

func (*Recorder) SetRGB

func (r *Recorder) SetRGB(red, green, blue float64)

SetRGB sets both fill and stroke color using RGB values (0-1).

func (*Recorder) SetRGBA

func (r *Recorder) SetRGBA(red, green, blue, alpha float64)

SetRGBA sets both fill and stroke color using RGBA values (0-1).

func (*Recorder) SetStrokeBrush

func (r *Recorder) SetStrokeBrush(brush gg.Brush)

SetStrokeBrush sets the stroke brush from a gg.Brush.

func (*Recorder) SetStrokeRGB

func (r *Recorder) SetStrokeRGB(red, green, blue float64)

SetStrokeRGB sets the stroke color using RGB values (0-1).

func (*Recorder) SetStrokeRGBA

func (r *Recorder) SetStrokeRGBA(red, green, blue, alpha float64)

SetStrokeRGBA sets the stroke color using RGBA values (0-1).

func (*Recorder) SetStrokeStyle

func (r *Recorder) SetStrokeStyle(brush Brush)

SetStrokeStyle sets the stroke brush.

func (*Recorder) SetTransform

func (r *Recorder) SetTransform(m Matrix)

SetTransform replaces the current transformation matrix.

func (*Recorder) Shear

func (r *Recorder) Shear(x, y float64)

Shear applies a shear transformation.

func (*Recorder) Stroke

func (r *Recorder) Stroke()

Stroke strokes the current path and clears it.

func (*Recorder) StrokePreserve

func (r *Recorder) StrokePreserve()

StrokePreserve strokes the current path without clearing it.

func (*Recorder) StrokeRectangle

func (r *Recorder) StrokeRectangle(x, y, w, h float64)

StrokeRectangle strokes a rectangle without adding it to the path.

func (*Recorder) Transform

func (r *Recorder) Transform(m Matrix)

Transform multiplies the current transformation matrix by the given matrix.

func (*Recorder) TransformPoint

func (r *Recorder) TransformPoint(x, y float64) (float64, float64)

TransformPoint transforms a point by the current matrix.

func (*Recorder) Translate

func (r *Recorder) Translate(x, y float64)

Translate applies a translation to the transformation matrix.

func (*Recorder) Width

func (r *Recorder) Width() int

Width returns the width of the recording canvas.

func (*Recorder) WordWrap added in v0.31.0

func (r *Recorder) WordWrap(s string, w float64) []string

WordWrap wraps text to fit within the given width using word boundaries. Uses the current font face for text measurement. If no font face is set, returns the input string as a single-element slice.

type Recording

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

Recording is an immutable container for recorded drawing commands. It can be replayed to any Backend implementation.

func (*Recording) Commands

func (r *Recording) Commands() []Command

Commands returns the recorded commands.

func (*Recording) Height

func (r *Recording) Height() int

Height returns the height of the recording canvas.

func (*Recording) Playback

func (r *Recording) Playback(backend Backend) error

Playback replays the recording to the given backend.

func (*Recording) Resources

func (r *Recording) Resources() *ResourcePool

Resources returns the resource pool.

func (*Recording) Width

func (r *Recording) Width() int

Width returns the width of the recording canvas.

type Rect

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

Rect represents an axis-aligned rectangle. Min is the top-left corner (minimum coordinates). Max is the bottom-right corner (maximum coordinates).

func NewRect

func NewRect(x, y, width, height float64) Rect

NewRect creates a rectangle from position and size.

func NewRectFromPoints

func NewRectFromPoints(x1, y1, x2, y2 float64) Rect

NewRectFromPoints creates a rectangle from two corner points. The points are normalized so Min <= Max.

func (Rect) Contains

func (r Rect) Contains(x, y float64) bool

Contains returns true if the point is inside the rectangle.

func (Rect) Height

func (r Rect) Height() float64

Height returns the height of the rectangle.

func (Rect) Inset

func (r Rect) Inset(dx, dy float64) Rect

Inset returns a new rectangle inset by the given amounts. Positive values shrink the rectangle, negative values expand it.

func (Rect) Intersect

func (r Rect) Intersect(other Rect) Rect

Intersect returns the intersection of r and other. Returns an empty rectangle if they don't intersect.

func (Rect) IsEmpty

func (r Rect) IsEmpty() bool

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

func (Rect) Offset

func (r Rect) Offset(dx, dy float64) Rect

Offset returns a new rectangle offset by the given amounts.

func (Rect) Union

func (r Rect) Union(other Rect) Rect

Union returns the smallest rectangle containing both r and other.

func (Rect) Width

func (r Rect) Width() float64

Width returns the width of the rectangle.

func (Rect) X

func (r Rect) X() float64

X returns the left edge of the rectangle.

func (Rect) Y

func (r Rect) Y() float64

Y returns the top edge of the rectangle.

type RepeatMode

type RepeatMode int

RepeatMode defines how patterns repeat.

const (
	// RepeatBoth repeats in both X and Y directions.
	RepeatBoth RepeatMode = iota
	// RepeatX repeats only in X direction.
	RepeatX
	// RepeatY repeats only in Y direction.
	RepeatY
	// RepeatNone does not repeat (clamps to edge).
	RepeatNone
)

type ResourcePool

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

ResourcePool stores resources referenced by recording commands. Resources are stored in slices indexed by their reference types. Each Add operation clones mutable resources to ensure immutability.

ResourcePool is not safe for concurrent use. If concurrent access is needed, external synchronization must be provided.

func NewResourcePool

func NewResourcePool() *ResourcePool

NewResourcePool creates an empty resource pool with pre-allocated capacity.

func (*ResourcePool) AddBrush

func (p *ResourcePool) AddBrush(brush Brush) BrushRef

AddBrush adds a brush to the pool and returns its reference. Brushes are stored directly as they are typically immutable value types.

func (*ResourcePool) AddFont

func (p *ResourcePool) AddFont(face text.Face) FontRef

AddFont adds a font face to the pool and returns its reference. Font faces are stored directly as they are already immutable and safe to share.

func (*ResourcePool) AddImage

func (p *ResourcePool) AddImage(img image.Image) ImageRef

AddImage adds an image to the pool and returns its reference. Images are stored directly as Go's image.Image is already immutable.

func (*ResourcePool) AddPath

func (p *ResourcePool) AddPath(path *gg.Path) PathRef

AddPath adds a path to the pool and returns its reference. The path is cloned to ensure immutability of the recording.

func (*ResourcePool) BrushCount

func (p *ResourcePool) BrushCount() int

BrushCount returns the number of brushes in the pool.

func (*ResourcePool) Clear

func (p *ResourcePool) Clear()

Clear removes all resources from the pool. This does not release the underlying memory; use NewResourcePool for that.

func (*ResourcePool) Clone

func (p *ResourcePool) Clone() *ResourcePool

Clone creates a deep copy of the resource pool. Paths are cloned; other resources are copied by reference (they are immutable).

func (*ResourcePool) FontCount

func (p *ResourcePool) FontCount() int

FontCount returns the number of font faces in the pool.

func (*ResourcePool) GetBrush

func (p *ResourcePool) GetBrush(ref BrushRef) Brush

GetBrush returns the brush for the given reference. Returns nil if the reference is invalid.

func (*ResourcePool) GetFont

func (p *ResourcePool) GetFont(ref FontRef) text.Face

GetFont returns the font face for the given reference. Returns nil if the reference is invalid.

func (*ResourcePool) GetImage

func (p *ResourcePool) GetImage(ref ImageRef) image.Image

GetImage returns the image for the given reference. Returns nil if the reference is invalid.

func (*ResourcePool) GetPath

func (p *ResourcePool) GetPath(ref PathRef) *gg.Path

GetPath returns the path for the given reference. Returns nil if the reference is invalid.

func (*ResourcePool) ImageCount

func (p *ResourcePool) ImageCount() int

ImageCount returns the number of images in the pool.

func (*ResourcePool) PathCount

func (p *ResourcePool) PathCount() int

PathCount returns the number of paths in the pool.

type RestoreCommand

type RestoreCommand struct{}

RestoreCommand restores the previously saved graphics state.

func (RestoreCommand) Type

func (RestoreCommand) Type() CommandType

Type implements Command.

type SaveCommand

type SaveCommand struct{}

SaveCommand saves the current graphics state. The state includes transform, clip, fill style, stroke style, and line properties.

func (SaveCommand) Type

func (SaveCommand) Type() CommandType

Type implements Command.

type SetClipCommand

type SetClipCommand struct {
	// Path references the clip path in the resource pool.
	Path PathRef
	// Rule specifies the fill rule for determining inside/outside.
	Rule FillRule
}

SetClipCommand sets the clipping region.

func (SetClipCommand) Type

func (SetClipCommand) Type() CommandType

Type implements Command.

type SetDashCommand

type SetDashCommand struct {
	// Pattern is the dash pattern (alternating dash and gap lengths).
	// Nil or empty means solid line.
	Pattern []float64
	// Offset is the starting offset into the pattern.
	Offset float64
}

SetDashCommand sets the dash pattern for stroking.

func (SetDashCommand) Type

func (SetDashCommand) Type() CommandType

Type implements Command.

type SetFillRuleCommand

type SetFillRuleCommand struct {
	// Rule is the fill rule (non-zero or even-odd).
	Rule FillRule
}

SetFillRuleCommand sets the fill rule.

func (SetFillRuleCommand) Type

Type implements Command.

type SetFillStyleCommand

type SetFillStyleCommand struct {
	// Brush references the fill brush in the resource pool.
	Brush BrushRef
}

SetFillStyleCommand sets the fill brush.

func (SetFillStyleCommand) Type

Type implements Command.

type SetLineCapCommand

type SetLineCapCommand struct {
	// Cap is the line cap style.
	Cap LineCap
}

SetLineCapCommand sets the stroke line cap style.

func (SetLineCapCommand) Type

Type implements Command.

type SetLineJoinCommand

type SetLineJoinCommand struct {
	// Join is the line join style.
	Join LineJoin
}

SetLineJoinCommand sets the stroke line join style.

func (SetLineJoinCommand) Type

Type implements Command.

type SetLineWidthCommand

type SetLineWidthCommand struct {
	// Width is the line width in pixels.
	Width float64
}

SetLineWidthCommand sets the stroke line width.

func (SetLineWidthCommand) Type

Type implements Command.

type SetMiterLimitCommand

type SetMiterLimitCommand struct {
	// Limit is the miter limit value.
	Limit float64
}

SetMiterLimitCommand sets the miter limit for line joins.

func (SetMiterLimitCommand) Type

Type implements Command.

type SetStrokeStyleCommand

type SetStrokeStyleCommand struct {
	// Brush references the stroke brush in the resource pool.
	Brush BrushRef
}

SetStrokeStyleCommand sets the stroke brush.

func (SetStrokeStyleCommand) Type

Type implements Command.

type SetTransformCommand

type SetTransformCommand struct {
	// Matrix is the new transformation matrix.
	Matrix Matrix
}

SetTransformCommand sets the current transformation matrix.

func (SetTransformCommand) Type

Type implements Command.

type SolidBrush

type SolidBrush struct {
	Color gg.RGBA
}

SolidBrush is a solid color brush.

func NewSolidBrush

func NewSolidBrush(color gg.RGBA) SolidBrush

NewSolidBrush creates a solid color brush.

type Stroke

type Stroke struct {
	// Width is the line width in pixels.
	Width float64
	// Cap is the shape of line endpoints.
	Cap LineCap
	// Join is the shape of line joins.
	Join LineJoin
	// MiterLimit is the limit for miter joins.
	MiterLimit float64
	// DashPattern is the dash pattern (nil for solid line).
	DashPattern []float64
	// DashOffset is the starting offset into the dash pattern.
	DashOffset float64
}

Stroke defines the style for stroking paths.

func DefaultStroke

func DefaultStroke() Stroke

DefaultStroke returns a Stroke with default settings.

func (Stroke) Clone

func (s Stroke) Clone() Stroke

Clone creates a deep copy of the Stroke.

type StrokePathCommand

type StrokePathCommand struct {
	// Path references the path to stroke in the resource pool.
	Path PathRef
	// Brush references the stroke brush in the resource pool.
	Brush BrushRef
	// Stroke contains the stroke style (width, cap, join, dash).
	Stroke Stroke
}

StrokePathCommand strokes a path with a brush.

func (StrokePathCommand) Type

Type implements Command.

type StrokeRectCommand

type StrokeRectCommand struct {
	// Rect is the rectangle to stroke.
	Rect Rect
	// Brush references the stroke brush in the resource pool.
	Brush BrushRef
	// Stroke contains the stroke style.
	Stroke Stroke
}

StrokeRectCommand strokes a rectangle with a brush.

func (StrokeRectCommand) Type

Type implements Command.

type SweepGradientBrush

type SweepGradientBrush struct {
	Center     gg.Point       // Center of the sweep
	StartAngle float64        // Start angle in radians
	EndAngle   float64        // End angle in radians
	Stops      []GradientStop // Color stops defining the gradient
	Extend     ExtendMode     // How gradient extends beyond bounds
}

SweepGradientBrush is an angular (conic) gradient brush. Colors sweep from StartAngle to EndAngle around Center.

func NewSweepGradientBrush

func NewSweepGradientBrush(cx, cy, startAngle float64) *SweepGradientBrush

NewSweepGradientBrush creates a new sweep (conic) gradient brush. The gradient sweeps a full 360 degrees by default.

func (*SweepGradientBrush) AddColorStop

func (g *SweepGradientBrush) AddColorStop(offset float64, color gg.RGBA) *SweepGradientBrush

AddColorStop adds a color stop at the specified offset. Offset should be in the range [0, 1]. Returns the gradient for method chaining.

func (*SweepGradientBrush) SetEndAngle

func (g *SweepGradientBrush) SetEndAngle(endAngle float64) *SweepGradientBrush

SetEndAngle sets the end angle of the sweep. Returns the gradient for method chaining.

func (*SweepGradientBrush) SetExtend

func (g *SweepGradientBrush) SetExtend(mode ExtendMode) *SweepGradientBrush

SetExtend sets the extend mode for the gradient. Returns the gradient for method chaining.

type WriterBackend

type WriterBackend interface {
	Backend

	// WriteTo writes the rendered content to the given writer.
	// This should only be called after End().
	// Returns the number of bytes written and any error.
	WriteTo(w io.Writer) (int64, error)
}

WriterBackend extends Backend with the ability to write output to an io.Writer. This is useful for streaming output or writing to network connections.

Directories

Path Synopsis
backends
raster
Package raster provides a raster backend for the recording system.
Package raster provides a raster backend for the recording system.

Jump to

Keyboard shortcuts

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