raster

package
v0.24.0 Latest Latest
Warning

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

Go to latest
Published: Feb 5, 2026 License: MIT Imports: 1 Imported by: 0

Documentation

Overview

Package raster provides scanline rasterization for 2D paths. This file implements AlphaRuns for RLE-encoded alpha (coverage) values. Based on tiny-skia's alpha_runs.rs (Android/Skia heritage).

Package raster provides scanline rasterization for 2D paths. This file implements the anti-aliased hairline rendering algorithm. Based on tiny-skia's hairline_aa.rs (Android/Skia heritage).

The algorithm uses fixed-point arithmetic for precision: - FDot6: 26.6 fixed-point for pixel coordinates (64 subpixel positions) - FDot16: 16.16 fixed-point for slopes and interpolation

The key insight is that for hairlines (stroke width <= 1px after transform), we can directly compute per-pixel coverage without expanding to a fill path. This produces smoother results for thin lines, especially dashed lines.

Package raster provides scanline rasterization for 2D paths. This file implements blitters for anti-aliased hairline rendering. Based on tiny-skia's blitter.rs (Android/Skia heritage).

Package raster provides scanline rasterization for 2D paths. This file implements line cap handling for hairline rendering.

Package raster provides scanline rasterization for 2D paths. This file implements fixed-point types for anti-aliased hairline rendering. Based on tiny-skia's fixed_point.rs (Android/Skia heritage).

Package raster provides scanline rasterization for 2D paths.

Package raster provides scanline rasterization for 2D paths. This file implements anti-aliased filling using 4x supersampling.

Package raster provides scanline rasterization for 2D paths. This file implements SuperBlitter for anti-aliased rendering via 4x supersampling. Based on tiny-skia's path_aa.rs (Android/Skia heritage).

Index

Constants

View Source
const (
	// FDot6Shift is the number of fractional bits in FDot6.
	FDot6Shift = 6
	// FDot6One represents 1.0 in FDot6 format (64).
	FDot6One FDot6 = 1 << FDot6Shift
	// FDot6Mask is used to extract the fractional part.
	FDot6Mask = FDot6One - 1
)

Fixed-point constants for FDot6 (26.6 format).

View Source
const SupersampleMask = SupersampleScale - 1

SupersampleMask is used to extract subpixel coordinates.

View Source
const SupersampleScale = 1 << SupersampleShift

SupersampleScale is the number of subpixels per pixel (4 for 2-bit shift).

View Source
const SupersampleShift = 2

SupersampleShift controls supersampling level: 2 means 4x (1 << 2 = 4).

Variables

This section is empty.

Functions

func CatchOverflow added in v0.19.0

func CatchOverflow(alpha uint16) uint8

CatchOverflow converts 0-256 to 0-255 safely. Input value 256 maps to 255 (handles overflow from accumulation).

func FDot6Ceil added in v0.21.2

func FDot6Ceil(f FDot6) int

FDot6Ceil returns the ceiling of an FDot6 value as an integer.

func FDot6Floor added in v0.21.2

func FDot6Floor(f FDot6) int

FDot6Floor returns the floor of an FDot6 value as an integer.

func FDot6Round added in v0.21.2

func FDot6Round(f FDot6) int

FDot6Round returns the rounded value of an FDot6 as an integer.

func FDot6SmallScale added in v0.21.2

func FDot6SmallScale(value uint8, dot6 FDot6) uint8

FDot6SmallScale scales a uint8 value by an FDot6 value in range [0, 64]. This is used to compute partial pixel coverage. Result is always in [0, 255] since: max(uint8)*64/64 = 255.

func FDot6ToFloat added in v0.21.2

func FDot6ToFloat(f FDot6) float64

FDot6ToFloat converts FDot6 to float64.

func FDot16Ceil added in v0.21.2

func FDot16Ceil(f FDot16) int

FDot16Ceil returns the ceiling of an FDot16 value as an integer.

func FDot16Floor added in v0.21.2

func FDot16Floor(f FDot16) int

FDot16Floor returns the floor of an FDot16 value as an integer.

func FDot16ToFloat added in v0.21.2

func FDot16ToFloat(f FDot16) float64

FDot16ToFloat converts FDot16 to float64.

func StrokeHairlineAA added in v0.21.2

func StrokeHairlineAA(blitter HairlineBlitter, points []HairlinePoint, lineCap HairlineLineCap, coverage float64)

StrokeHairlineAA draws an anti-aliased hairline path. The path is a sequence of points representing line segments. Coverage controls the global opacity (0.0 to 1.0).

Types

type AAPixmap added in v0.19.0

type AAPixmap interface {
	Pixmap
	// BlendPixelAlpha blends a color with the existing pixel using given alpha.
	// alpha is in range 0-255.
	BlendPixelAlpha(x, y int, c RGBA, alpha uint8)
}

AAPixmap extends Pixmap with alpha-blended pixel writing.

type AAPixmapAdapter added in v0.19.0

type AAPixmapAdapter struct {
	Pixmap Pixmap
}

AAPixmapAdapter wraps a basic Pixmap to provide BlendPixelAlpha for AA rendering. This allows non-AA pixmaps to work with the AA rasterizer.

func (*AAPixmapAdapter) BlendPixelAlpha added in v0.19.0

func (a *AAPixmapAdapter) BlendPixelAlpha(x, y int, c RGBA, alpha uint8)

BlendPixelAlpha blends a color with the existing pixel using given alpha. This is a simple implementation that uses alpha to modulate the color.

func (*AAPixmapAdapter) Height added in v0.19.0

func (a *AAPixmapAdapter) Height() int

Height returns the height of the pixmap.

func (*AAPixmapAdapter) SetPixel added in v0.19.0

func (a *AAPixmapAdapter) SetPixel(x, y int, c RGBA)

SetPixel sets a pixel color.

func (*AAPixmapAdapter) Width added in v0.19.0

func (a *AAPixmapAdapter) Width() int

Width returns the width of the pixmap.

type AAPixmapBatch added in v0.19.0

type AAPixmapBatch interface {
	AAPixmap
	// BlendSpanAlpha blends a solid color over a horizontal span with constant alpha.
	// Parameters:
	//   - x, y: starting pixel coordinates
	//   - count: number of pixels to blend
	//   - r, g, b, a: source color (premultiplied alpha, 0-255)
	//   - alpha: coverage alpha (0-255)
	BlendSpanAlpha(x, y, count int, r, g, b, a, alpha uint8)
}

AAPixmapBatch is an optional interface for pixmaps that support batch AA blending. Pixmaps implementing this interface can benefit from SIMD-optimized processing for runs of 16+ pixels with the same coverage alpha.

type ActiveEdge

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

ActiveEdge is an edge being processed by the rasterizer.

type ActiveEdgeTable

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

ActiveEdgeTable represents edges active at a scanline.

func NewActiveEdgeTable

func NewActiveEdgeTable() *ActiveEdgeTable

NewActiveEdgeTable creates a new active edge table.

func (*ActiveEdgeTable) Add

func (aet *ActiveEdgeTable) Add(edge Edge)

Add adds an edge to the active edge table.

func (*ActiveEdgeTable) AddAtY added in v0.19.0

func (aet *ActiveEdgeTable) AddAtY(edge Edge, y float64)

AddAtY adds an edge to the active edge table with x computed for the given y.

func (*ActiveEdgeTable) Clear

func (aet *ActiveEdgeTable) Clear()

Clear clears all edges.

func (*ActiveEdgeTable) Edges

func (aet *ActiveEdgeTable) Edges() []ActiveEdge

Edges returns the active edges.

func (*ActiveEdgeTable) Remove

func (aet *ActiveEdgeTable) Remove(y float64)

Remove removes inactive edges for the given scanline.

func (*ActiveEdgeTable) Sort

func (aet *ActiveEdgeTable) Sort()

Sort sorts edges by x coordinate (insertion sort for small lists).

func (*ActiveEdgeTable) Update

func (aet *ActiveEdgeTable) Update()

Update updates x positions for the next scanline.

type AlphaRuns added in v0.19.0

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

AlphaRuns stores run-length-encoded alpha (supersampling coverage) values. Sparseness allows independent composition of several paths into the same buffer.

func NewAlphaRuns added in v0.19.0

func NewAlphaRuns(width int) *AlphaRuns

NewAlphaRuns creates a new AlphaRuns buffer for the given width.

func (*AlphaRuns) Add added in v0.19.0

func (ar *AlphaRuns) Add(x int, startAlpha uint8, middleCount int, stopAlpha uint8, maxValue uint8, offsetX int) int

Add inserts a run into the buffer. Parameters:

  • x: starting x coordinate
  • startAlpha: alpha for first pixel (if non-zero)
  • middleCount: number of full-coverage pixels
  • stopAlpha: alpha for last pixel (if non-zero)
  • maxValue: maximum alpha value for middle pixels
  • offsetX: hint for where to start searching in runs array

Returns the new offsetX value for the next call on the same scanline.

func (*AlphaRuns) Alpha added in v0.19.0

func (ar *AlphaRuns) Alpha() []uint8

Alpha returns the alpha slice.

func (*AlphaRuns) IsEmpty added in v0.19.0

func (ar *AlphaRuns) IsEmpty() bool

IsEmpty returns true if the scanline contains only a single run of alpha 0.

func (*AlphaRuns) Reset added in v0.19.0

func (ar *AlphaRuns) Reset(width int)

Reset reinitializes the buffer for a new scanline.

func (*AlphaRuns) Runs added in v0.19.0

func (ar *AlphaRuns) Runs() []uint16

Runs returns the runs slice.

type Blitter added in v0.19.0

type Blitter interface {
	// BlitH blits a horizontal span at supersampled coordinates.
	BlitH(x, y uint32, width int)
}

Blitter is an interface for receiving horizontal spans.

type Edge

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

Edge represents a line segment for scanline rasterization.

func NewEdge

func NewEdge(p0, p1 Point) Edge

NewEdge creates a new edge from two points.

func (*Edge) XAtY

func (e *Edge) XAtY(y float64) float64

XAtY calculates the x coordinate at the given y coordinate.

type FDot6 added in v0.21.2

type FDot6 int32

FDot6 is a 26.6 fixed-point type for pixel coordinates. The 6-bit fractional part provides 64 subpixel positions per pixel.

func Abs6 added in v0.21.2

func Abs6(f FDot6) FDot6

Abs6 returns the absolute value of an FDot6.

func Contribution64 added in v0.21.2

func Contribution64(ordinate FDot6) FDot6

Contribution64 returns the fractional part of an FDot6 ordinate, but returns 64 for exact integer positions instead of 0. This is used for calculating partial pixel coverage at endpoints.

func FloatToFDot6 added in v0.21.2

func FloatToFDot6(f float64) FDot6

FloatToFDot6 converts a float64 to FDot6 fixed-point.

func Max6 added in v0.21.2

func Max6(a, b FDot6) FDot6

Max6 returns the maximum of two FDot6 values.

func Min6 added in v0.21.2

func Min6(a, b FDot6) FDot6

Min6 returns the minimum of two FDot6 values.

type FDot16 added in v0.21.2

type FDot16 int32

FDot16 is a 16.16 fixed-point type for slopes and interpolation. Used for precise calculations that need more fractional bits.

const (
	// FDot16Shift is the number of fractional bits in FDot16.
	FDot16Shift = 16
	// FDot16One represents 1.0 in FDot16 format (65536).
	FDot16One FDot16 = 1 << FDot16Shift
	// FDot16Half represents 0.5 in FDot16 format.
	FDot16Half FDot16 = FDot16One / 2
)

Fixed-point constants for FDot16 (16.16 format).

func Abs16 added in v0.21.2

func Abs16(f FDot16) FDot16

Abs16 returns the absolute value of an FDot16.

func FDot6ToFDot16 added in v0.21.2

func FDot6ToFDot16(f FDot6) FDot16

FDot6ToFDot16 converts FDot6 to FDot16 (shifts left by 10 bits).

func FDot16FastDiv added in v0.21.2

func FDot16FastDiv(a, b FDot6) FDot16

FDot16FastDiv computes (a << 16) / b for fixed-point division. Used for computing slopes. Requires b != 0. The result is always valid FDot16 since inputs are bounded by design.

func FloatToFDot16 added in v0.21.2

func FloatToFDot16(f float64) FDot16

FloatToFDot16 converts a float64 to FDot16 fixed-point.

type FillRule

type FillRule int

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 HairlineBlitter added in v0.21.2

type HairlineBlitter interface {
	// BlitH blits a horizontal span at the given coordinates with coverage alpha.
	// The span covers [x, x+width) at row y.
	BlitH(x, y, width int, alpha uint8)

	// BlitV blits a vertical span at the given coordinates with coverage alpha.
	// The span covers [y, y+height) at column x.
	BlitV(x, y, height int, alpha uint8)

	// BlitAntiH2 blits two horizontal pixels with different alpha values.
	// Used for anti-aliased line drawing where coverage varies.
	BlitAntiH2(x, y int, alpha0, alpha1 uint8)

	// BlitAntiV2 blits two vertical pixels with different alpha values.
	// Used for anti-aliased line drawing where coverage varies.
	BlitAntiV2(x, y int, alpha0, alpha1 uint8)
}

HairlineBlitter blits anti-aliased hairline pixels. This interface is optimized for hairline rendering where pixels are written in specific patterns (horizontal, vertical, or diagonal).

type HairlineLineCap added in v0.21.2

type HairlineLineCap int

HairlineLineCap specifies the shape of hairline endpoints.

const (
	// HairlineCapButt specifies a flat line cap.
	HairlineCapButt HairlineLineCap = iota
	// HairlineCapRound specifies a rounded line cap.
	HairlineCapRound
	// HairlineCapSquare specifies a square line cap.
	HairlineCapSquare
)

type HairlinePixmap added in v0.21.2

type HairlinePixmap interface {
	Width() int
	Height() int
	BlendPixelAlpha(x, y int, c RGBA, alpha uint8)
}

HairlinePixmap extends the Pixmap interface with methods needed for hairline blitting.

type HairlinePoint added in v0.21.2

type HairlinePoint struct {
	X, Y float64
}

HairlinePoint represents a point for hairline rendering.

type PathEdge added in v0.21.1

type PathEdge struct {
	P0, P1 Point
}

PathEdge represents an edge from external path processing. This is used to receive edges from path.EdgeIter which correctly handles subpath boundaries.

type Pixmap

type Pixmap interface {
	Width() int
	Height() int
	SetPixel(x, y int, c RGBA)
}

Pixmap is an interface for writing pixels (avoids import cycle).

type Point

type Point struct {
	X, Y float64
}

Point represents a 2D point (internal copy to avoid import cycle).

type RGBA

type RGBA struct {
	R, G, B, A float64
}

RGBA represents a color (internal copy to avoid import cycle).

type RGBAHairlineBlitter added in v0.21.2

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

RGBAHairlineBlitter implements HairlineBlitter for RGBA pixmaps. It handles bounds checking and alpha blending.

func NewRGBAHairlineBlitter added in v0.21.2

func NewRGBAHairlineBlitter(pixmap HairlinePixmap, color RGBA) *RGBAHairlineBlitter

NewRGBAHairlineBlitter creates a new hairline blitter for the given pixmap and color.

func (*RGBAHairlineBlitter) BlitAntiH2 added in v0.21.2

func (b *RGBAHairlineBlitter) BlitAntiH2(x, y int, alpha0, alpha1 uint8)

BlitAntiH2 blits two horizontal pixels with different alpha values. This is the core operation for mostly-vertical lines where coverage is distributed between two adjacent horizontal pixels.

func (*RGBAHairlineBlitter) BlitAntiV2 added in v0.21.2

func (b *RGBAHairlineBlitter) BlitAntiV2(x, y int, alpha0, alpha1 uint8)

BlitAntiV2 blits two vertical pixels with different alpha values. This is the core operation for mostly-horizontal lines where coverage is distributed between two adjacent vertical pixels.

func (*RGBAHairlineBlitter) BlitH added in v0.21.2

func (b *RGBAHairlineBlitter) BlitH(x, y, width int, alpha uint8)

BlitH blits a horizontal span with the given alpha coverage.

func (*RGBAHairlineBlitter) BlitV added in v0.21.2

func (b *RGBAHairlineBlitter) BlitV(x, y, height int, alpha uint8)

BlitV blits a vertical span with the given alpha coverage.

type Rasterizer

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

Rasterizer performs scanline rasterization.

func NewRasterizer

func NewRasterizer(width, height int) *Rasterizer

NewRasterizer creates a new rasterizer for the given dimensions.

func (*Rasterizer) Fill

func (r *Rasterizer) Fill(pixmap Pixmap, points []Point, fillRule FillRule, color RGBA)

Fill rasterizes a filled path onto a pixmap.

func (*Rasterizer) FillAA deprecated added in v0.19.0

func (r *Rasterizer) FillAA(pixmap AAPixmap, points []Point, fillRule FillRule, color RGBA)

FillAA rasterizes a filled path with anti-aliasing onto a pixmap. Uses 4x supersampling for smooth edges.

Deprecated: This function creates edges from consecutive point pairs, which incorrectly connects separate subpaths. Use FillAAFromEdges with path.EdgeIter for correct subpath handling.

func (*Rasterizer) FillAAFromEdges added in v0.21.1

func (r *Rasterizer) FillAAFromEdges(pixmap AAPixmap, pathEdges []PathEdge, fillRule FillRule, color RGBA)

FillAAFromEdges rasterizes edges with anti-aliasing onto a pixmap. This function accepts pre-computed edges from path.EdgeIter, which correctly handles subpath boundaries (no connecting edges between subpaths). Uses 4x supersampling for smooth edges.

func (*Rasterizer) Stroke

func (r *Rasterizer) Stroke(pixmap Pixmap, points []Point, lineWidth float64, color RGBA)

Stroke rasterizes a stroked path.

type SpanFiller added in v0.5.0

type SpanFiller interface {
	FillSpan(x1, x2, y int, c RGBA)
}

SpanFiller is an optional interface that pixmaps can implement for optimized span filling.

type SuperBlitter added in v0.19.0

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

SuperBlitter accumulates supersampled coverage and blits AA pixels.

func NewSuperBlitter added in v0.19.0

func NewSuperBlitter(
	pixmap AAPixmap,
	color RGBA,
	boundsLeft, boundsTop, boundsRight, boundsBottom int,
	clipLeft, clipTop, clipRight, clipBottom int,
) *SuperBlitter

NewSuperBlitter creates a new SuperBlitter for AA rendering. bounds defines the pixel-space bounding box of the path. clipLeft, clipTop, clipRight, clipBottom define the clipping region.

func (*SuperBlitter) BlitH added in v0.19.0

func (sb *SuperBlitter) BlitH(x, y uint32, width int)

BlitH implements Blitter interface for receiving supersampled spans.

func (*SuperBlitter) Flush added in v0.19.0

func (sb *SuperBlitter) Flush()

Flush writes the accumulated coverage to the pixmap.

Jump to

Keyboard shortcuts

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