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
- func Backends() []string
- func Count() int
- func IsRegistered(name string) bool
- func Register(name string, factory BackendFactory)
- func Unregister(name string)
- type Backend
- type BackendFactory
- type Brush
- type BrushRef
- type ClearClipCommand
- type Command
- type CommandType
- type DrawImageCommand
- type DrawTextCommand
- type ExtendMode
- type FileBackend
- type FillPathCommand
- type FillRectCommand
- type FillRule
- type FontRef
- type GradientStop
- type ImageOptions
- type ImageRef
- type InterpolationMode
- type LineCap
- type LineJoin
- type LinearGradientBrush
- type Matrix
- func (m Matrix) Determinant() float64
- func (m Matrix) Invert() Matrix
- func (m Matrix) IsIdentity() bool
- func (m Matrix) IsTranslation() bool
- func (m Matrix) Multiply(other Matrix) Matrix
- func (m Matrix) ScaleFactor() float64
- func (m Matrix) TransformPoint(x, y float64) (float64, float64)
- func (m Matrix) TransformVector(x, y float64) (float64, float64)
- func (m Matrix) Translation() (x, y float64)
- type PathRef
- type PatternBrush
- type PixmapBackend
- type RadialGradientBrush
- type Recorder
- func (r *Recorder) Clear()
- func (r *Recorder) ClearDash()
- func (r *Recorder) ClearPath()
- func (r *Recorder) ClearWithColor(c gg.RGBA)
- func (r *Recorder) Clip()
- func (r *Recorder) ClipPreserve()
- func (r *Recorder) ClosePath()
- func (r *Recorder) CubicTo(c1x, c1y, c2x, c2y, x, y float64)
- func (r *Recorder) DrawArc(x, y, radius, angle1, angle2 float64)
- func (r *Recorder) DrawCircle(x, y, radius float64)
- func (r *Recorder) DrawEllipse(x, y, rx, ry float64)
- func (r *Recorder) DrawEllipticalArc(x, y, rx, ry, angle1, angle2 float64)
- func (r *Recorder) DrawImage(img image.Image, x, y int)
- func (r *Recorder) DrawImageAnchored(img image.Image, x, y int, ax, ay float64)
- func (r *Recorder) DrawImageScaled(img image.Image, x, y, w, h float64)
- func (r *Recorder) DrawLine(x1, y1, x2, y2 float64)
- func (r *Recorder) DrawPoint(x, y, radius float64)
- func (r *Recorder) DrawRectangle(x, y, w, h float64)
- func (r *Recorder) DrawRoundedRectangle(x, y, w, h, radius float64)
- func (r *Recorder) DrawString(s string, x, y float64)
- func (r *Recorder) DrawStringAnchored(s string, x, y, ax, ay float64)
- func (r *Recorder) DrawStringWrapped(s string, x, y, ax, ay, width, lineSpacing float64, align text.Alignment)
- func (r *Recorder) Fill()
- func (r *Recorder) FillPreserve()
- func (r *Recorder) FillRectangle(x, y, w, h float64)
- func (r *Recorder) FillStroke()
- func (r *Recorder) FinishRecording() *Recording
- func (r *Recorder) GetCurrentPoint() (x, y float64, ok bool)
- func (r *Recorder) GetTransform() Matrix
- func (r *Recorder) Height() int
- func (r *Recorder) Identity()
- func (r *Recorder) InvertY()
- func (r *Recorder) LineTo(x, y float64)
- func (r *Recorder) MeasureMultilineString(s string, lineSpacing float64) (width, height float64)
- func (r *Recorder) MeasureString(s string) (w, h float64)
- func (r *Recorder) MoveTo(x, y float64)
- func (r *Recorder) NewSubPath()
- func (r *Recorder) Pop()
- func (r *Recorder) Push()
- func (r *Recorder) QuadraticTo(cx, cy, x, y float64)
- func (r *Recorder) ResetClip()
- func (r *Recorder) Restore()
- func (r *Recorder) Rotate(angle float64)
- func (r *Recorder) RotateAbout(angle, x, y float64)
- func (r *Recorder) Save()
- func (r *Recorder) Scale(sx, sy float64)
- func (r *Recorder) SetColor(c gg.RGBA)
- func (r *Recorder) SetDash(lengths ...float64)
- func (r *Recorder) SetDashOffset(offset float64)
- func (r *Recorder) SetFillBrush(brush gg.Brush)
- func (r *Recorder) SetFillRGB(red, green, blue float64)
- func (r *Recorder) SetFillRGBA(red, green, blue, alpha float64)
- func (r *Recorder) SetFillRule(rule FillRule)
- func (r *Recorder) SetFillRuleGG(rule gg.FillRule)
- func (r *Recorder) SetFillStyle(brush Brush)
- func (r *Recorder) SetFont(face text.Face)
- func (r *Recorder) SetFontFamily(family string)
- func (r *Recorder) SetFontSize(size float64)
- func (r *Recorder) SetHexColor(hex string)
- func (r *Recorder) SetLineCap(lc LineCap)
- func (r *Recorder) SetLineCapGG(lc gg.LineCap)
- func (r *Recorder) SetLineJoin(join LineJoin)
- func (r *Recorder) SetLineJoinGG(join gg.LineJoin)
- func (r *Recorder) SetLineWidth(width float64)
- func (r *Recorder) SetMiterLimit(limit float64)
- func (r *Recorder) SetRGB(red, green, blue float64)
- func (r *Recorder) SetRGBA(red, green, blue, alpha float64)
- func (r *Recorder) SetStrokeBrush(brush gg.Brush)
- func (r *Recorder) SetStrokeRGB(red, green, blue float64)
- func (r *Recorder) SetStrokeRGBA(red, green, blue, alpha float64)
- func (r *Recorder) SetStrokeStyle(brush Brush)
- func (r *Recorder) SetTransform(m Matrix)
- func (r *Recorder) Shear(x, y float64)
- func (r *Recorder) Stroke()
- func (r *Recorder) StrokePreserve()
- func (r *Recorder) StrokeRectangle(x, y, w, h float64)
- func (r *Recorder) Transform(m Matrix)
- func (r *Recorder) TransformPoint(x, y float64) (float64, float64)
- func (r *Recorder) Translate(x, y float64)
- func (r *Recorder) Width() int
- func (r *Recorder) WordWrap(s string, w float64) []string
- type Recording
- type Rect
- func (r Rect) Contains(x, y float64) bool
- func (r Rect) Height() float64
- func (r Rect) Inset(dx, dy float64) Rect
- func (r Rect) Intersect(other Rect) Rect
- func (r Rect) IsEmpty() bool
- func (r Rect) Offset(dx, dy float64) Rect
- func (r Rect) Union(other Rect) Rect
- func (r Rect) Width() float64
- func (r Rect) X() float64
- func (r Rect) Y() float64
- type RepeatMode
- type ResourcePool
- func (p *ResourcePool) AddBrush(brush Brush) BrushRef
- func (p *ResourcePool) AddFont(face text.Face) FontRef
- func (p *ResourcePool) AddImage(img image.Image) ImageRef
- func (p *ResourcePool) AddPath(path *gg.Path) PathRef
- func (p *ResourcePool) BrushCount() int
- func (p *ResourcePool) Clear()
- func (p *ResourcePool) Clone() *ResourcePool
- func (p *ResourcePool) FontCount() int
- func (p *ResourcePool) GetBrush(ref BrushRef) Brush
- func (p *ResourcePool) GetFont(ref FontRef) text.Face
- func (p *ResourcePool) GetImage(ref ImageRef) image.Image
- func (p *ResourcePool) GetPath(ref PathRef) *gg.Path
- func (p *ResourcePool) ImageCount() int
- func (p *ResourcePool) PathCount() int
- type RestoreCommand
- type SaveCommand
- type SetClipCommand
- type SetDashCommand
- type SetFillRuleCommand
- type SetFillStyleCommand
- type SetLineCapCommand
- type SetLineJoinCommand
- type SetLineWidthCommand
- type SetMiterLimitCommand
- type SetStrokeStyleCommand
- type SetTransformCommand
- type SolidBrush
- type Stroke
- type StrokePathCommand
- type StrokeRectCommand
- type SweepGradientBrush
- type WriterBackend
Constants ¶
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 IsRegistered ¶
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:
- Register in init() using recording.Register()
- Handle all Backend methods (even if no-op for some)
- Manage own state stack for Save/Restore
- Translate coordinates if needed (e.g., PDF Y-flip)
Example Backend Registration ¶
func init() {
recording.Register("pdf", func() recording.Backend {
return NewPDFBackend()
})
}
func MustBackend ¶
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 ¶
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 ¶
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).
type ClearClipCommand ¶
type ClearClipCommand struct{}
ClearClipCommand clears the clipping region to the full canvas.
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.
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.
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.
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.
type FillRule ¶
type FillRule uint8
FillRule specifies how to determine which areas are inside a path.
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).
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).
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 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 ¶
func (g *LinearGradientBrush) SetExtend(mode ExtendMode) *LinearGradientBrush
SetExtend sets the extend mode for the gradient. Returns the gradient for method chaining.
type Matrix ¶
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 (Matrix) Determinant ¶
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 ¶
Invert returns the inverse matrix. Returns the identity matrix if the matrix is not invertible.
func (Matrix) IsIdentity ¶
IsIdentity returns true if the matrix is the identity matrix.
func (Matrix) IsTranslation ¶
IsTranslation returns true if the matrix is only a translation.
func (Matrix) Multiply ¶
Multiply multiplies two matrices (m * other). This applies the transformation of `other` after `m`.
func (Matrix) ScaleFactor ¶
ScaleFactor returns the maximum scale factor of the transformation. This is useful for determining effective stroke width after transform.
func (Matrix) TransformPoint ¶
TransformPoint applies the transformation to a point.
func (Matrix) TransformVector ¶
TransformVector applies the transformation to a vector (no translation).
func (Matrix) Translation ¶
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).
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 ¶
func (g *RadialGradientBrush) SetExtend(mode ExtendMode) *RadialGradientBrush
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 ¶
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) ClearWithColor ¶
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) DrawCircle ¶
DrawCircle draws a circle.
func (*Recorder) DrawEllipse ¶
DrawEllipse draws an ellipse.
func (*Recorder) DrawEllipticalArc ¶
DrawEllipticalArc draws an elliptical arc.
func (*Recorder) DrawImageAnchored ¶
DrawImageAnchored draws an image with an anchor point.
func (*Recorder) DrawImageScaled ¶
DrawImageScaled draws an image scaled to fit the specified rectangle.
func (*Recorder) DrawRectangle ¶
DrawRectangle draws a rectangle.
func (*Recorder) DrawRoundedRectangle ¶
DrawRoundedRectangle draws a rectangle with rounded corners.
func (*Recorder) DrawString ¶
DrawString draws text at position (x, y) where y is the baseline.
func (*Recorder) DrawStringAnchored ¶
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) FillPreserve ¶
func (r *Recorder) FillPreserve()
FillPreserve fills the current path without clearing it.
func (*Recorder) FillRectangle ¶
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 ¶
FinishRecording returns an immutable Recording containing all recorded commands. After calling FinishRecording, the Recorder should not be used again.
func (*Recorder) GetCurrentPoint ¶
GetCurrentPoint returns the current point of the path. Returns (0, 0, false) if there is no current point.
func (*Recorder) GetTransform ¶
GetTransform returns a copy of the current transformation matrix.
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) MeasureMultilineString ¶ added in v0.31.0
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 ¶
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) 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 ¶
QuadraticTo adds a quadratic Bezier curve to the current path.
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) RotateAbout ¶
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) SetDash ¶
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 ¶
SetDashOffset sets the starting offset into the dash pattern.
func (*Recorder) SetFillBrush ¶
SetFillBrush sets the fill brush from a gg.Brush.
func (*Recorder) SetFillRGB ¶
SetFillRGB sets the fill color using RGB values (0-1).
func (*Recorder) SetFillRGBA ¶
SetFillRGBA sets the fill color using RGBA values (0-1).
func (*Recorder) SetFillRule ¶
SetFillRule sets the fill rule.
func (*Recorder) SetFillRuleGG ¶
SetFillRuleGG sets the fill rule from gg.FillRule.
func (*Recorder) SetFillStyle ¶
SetFillStyle sets the fill brush.
func (*Recorder) SetFontFamily ¶
SetFontFamily sets the current font family name.
func (*Recorder) SetFontSize ¶
SetFontSize sets the current font size in points.
func (*Recorder) SetHexColor ¶
SetHexColor sets both fill and stroke color using a hex string.
func (*Recorder) SetLineCap ¶
SetLineCap sets the line cap style.
func (*Recorder) SetLineCapGG ¶
SetLineCapGG sets the line cap style from gg.LineCap.
func (*Recorder) SetLineJoin ¶
SetLineJoin sets the line join style.
func (*Recorder) SetLineJoinGG ¶
SetLineJoinGG sets the line join style from gg.LineJoin.
func (*Recorder) SetLineWidth ¶
SetLineWidth sets the line width for stroking.
func (*Recorder) SetMiterLimit ¶
SetMiterLimit sets the miter limit for line joins.
func (*Recorder) SetStrokeBrush ¶
SetStrokeBrush sets the stroke brush from a gg.Brush.
func (*Recorder) SetStrokeRGB ¶
SetStrokeRGB sets the stroke color using RGB values (0-1).
func (*Recorder) SetStrokeRGBA ¶
SetStrokeRGBA sets the stroke color using RGBA values (0-1).
func (*Recorder) SetStrokeStyle ¶
SetStrokeStyle sets the stroke brush.
func (*Recorder) SetTransform ¶
SetTransform replaces the current transformation matrix.
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 ¶
StrokeRectangle strokes a rectangle without adding it to the path.
func (*Recorder) Transform ¶
Transform multiplies the current transformation matrix by the given matrix.
func (*Recorder) TransformPoint ¶
TransformPoint transforms a point by the current matrix.
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) Resources ¶
func (r *Recording) Resources() *ResourcePool
Resources returns the resource pool.
type Rect ¶
Rect represents an axis-aligned rectangle. Min is the top-left corner (minimum coordinates). Max is the bottom-right corner (maximum coordinates).
func NewRectFromPoints ¶
NewRectFromPoints creates a rectangle from two corner points. The points are normalized so Min <= Max.
func (Rect) Inset ¶
Inset returns a new rectangle inset by the given amounts. Positive values shrink the rectangle, negative values expand it.
func (Rect) Intersect ¶
Intersect returns the intersection of r and other. Returns an empty rectangle if they don't intersect.
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.
type SaveCommand ¶
type SaveCommand struct{}
SaveCommand saves the current graphics state. The state includes transform, clip, fill style, stroke style, and line properties.
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.
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.
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 ¶
func (SetFillRuleCommand) Type() CommandType
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 ¶
func (SetFillStyleCommand) Type() CommandType
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 ¶
func (SetLineCapCommand) Type() CommandType
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 ¶
func (SetLineJoinCommand) Type() CommandType
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 ¶
func (SetLineWidthCommand) Type() CommandType
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 ¶
func (SetMiterLimitCommand) Type() CommandType
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 ¶
func (SetStrokeStyleCommand) Type() CommandType
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 ¶
func (SetTransformCommand) Type() CommandType
Type implements Command.
type SolidBrush ¶
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.
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 ¶
func (StrokePathCommand) Type() CommandType
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 ¶
func (StrokeRectCommand) Type() CommandType
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.