Documentation
¶
Overview ¶
Package raster turns a vtengine frame snapshot into RGBA pixels: HarfBuzz shaping in style runs (ligature clusters anchored to their origin cell), FreeType glyph rendering with an atlas cache, synthesized sprites for box-drawing/blocks/braille (sprites.go — cell-exact tiling, like every real terminal), color emoji (CBDT strikes), kitty graphics compositing by z-layer, cursor and decorations, at 1x or 2x. Quality is pinned by the typographic golden suite (byte-exact frames).
DETERMINISM RULE: frames must be byte-identical across OS and CPU architecture (the PRD's north metric). Blending and span math stay integer-only. Any float expression shaped like c + a*b in the render path must round the product through an explicit conversion — e.g. c + float32(a*b), see mask() in text.go — because on arm64 the Go compiler otherwise fuses it into a single-rounding FMA and coverage can drift by one alpha step relative to amd64 (found empirically: one pixel in the first cross-arch CI run, bisected with -d=fmahash).
Index ¶
- func DownscaleHalf(dst, src *image.RGBA) *image.RGBA
- func KeysBandFor(capCell int) int
- type BarStyle
- type CameraTrack
- func (ct *CameraTrack) Breakpoints(from, to time.Duration) []time.Duration
- func (ct *CameraTrack) MoveTo(target image.Rectangle, at, dur time.Duration)
- func (ct *CameraTrack) Reset(at, dur time.Duration)
- func (ct *CameraTrack) SetTime(t time.Duration)
- func (ct *CameraTrack) Viewport() image.Rectangle
- type Fill
- type HighlightSpec
- type HighlightTrack
- func (ht *HighlightTrack) Activate(spec HighlightSpec, at time.Duration)
- func (ht *HighlightTrack) Breakpoints(from, to time.Duration) []time.Duration
- func (ht *HighlightTrack) Clear(at time.Duration)
- func (ht *HighlightTrack) ClearNamed(name string, at time.Duration)
- func (ht *HighlightTrack) SetTime(t time.Duration)
- type ImageSource
- type KeysNotation
- type KeysStyle
- type KeysTrack
- type Options
- type Rasterizer
- func (r *Rasterizer) CellSize() (w, h int)
- func (r *Rasterizer) Composite(master *image.RGBA, vp image.Rectangle, dst *image.RGBA) *image.RGBA
- func (r *Rasterizer) LogicalCellSize() (w, h int)
- func (r *Rasterizer) Render(f *vtengine.Frame, src ImageSource, dst *image.RGBA) (*image.RGBA, error)
- func (r *Rasterizer) SuperSample() int
- func (r *Rasterizer) Warnings() []string
- func (r *Rasterizer) WorldRect() image.Rectangle
- func (r *Rasterizer) ZoomTarget(col, row, w, h int) (image.Rectangle, error)
- type TitleAlign
- type UserFonts
- type Window
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func DownscaleHalf ¶
DownscaleHalf shrinks src into dst at exactly 2:1 with the integer area mean — the output-scale knob's final pass (this file's scaler: deterministic by construction). dst is reallocated when it does not match; the result is returned either way.
func KeysBandFor ¶
KeysBandFor is the band's logical height for a cap cell height (the grid cell scaled by the chosen size): matte above, the strip — a frame row between two sprocket rows — and matte below.
Types ¶
type BarStyle ¶
type BarStyle uint8
BarStyle is a WindowBar variant. The zero value means no bar.
const ( BarNone BarStyle = iota BarColorful // macOS traffic lights, left BarColorfulRight // macOS traffic lights, right BarRings BarRingsRight BarLinuxControls // minimize/maximize/close strokes, right BarGnomeCSD // a close button in a circle, right (CSD-like) )
The window bar styles: VHS's four, plus foley's genre controls (dress-reachable; a tape using them still degrades in VHS, which silently draws no bar for unknown styles).
type CameraTrack ¶
type CameraTrack struct {
// contains filtered or unexported fields
}
CameraTrack holds the camera's movements and serves the driver's Overlay contract (SetTime/Breakpoints). Like HighlightTrack it is mutated by the recording goroutine while realtime's loop reads it — mutex; single-goroutine and contention-free in deterministic mode.
func NewCameraTrack ¶
func NewCameraTrack(world image.Rectangle) *CameraTrack
NewCameraTrack returns a camera at identity over the given world.
func (*CameraTrack) Breakpoints ¶
func (ct *CameraTrack) Breakpoints(from, to time.Duration) []time.Duration
Breakpoints reports the animation instants in [from, to): each move's quantized steps plus its exact end.
func (*CameraTrack) MoveTo ¶
func (ct *CameraTrack) MoveTo(target image.Rectangle, at, dur time.Duration)
MoveTo animates the camera to target starting at the given instant. The departure point is the camera's state AT that instant — never a teleport. A move to where the camera already rests is a no-op: it must not emit a transition's worth of identical frames (`zoom off` at identity, re-zooming the same rect).
func (*CameraTrack) Reset ¶
func (ct *CameraTrack) Reset(at, dur time.Duration)
Reset animates back to identity — `zoom off`, reversible by construction.
func (*CameraTrack) SetTime ¶
func (ct *CameraTrack) SetTime(t time.Duration)
SetTime fixes the camera clock for the next render.
func (*CameraTrack) Viewport ¶
func (ct *CameraTrack) Viewport() image.Rectangle
Viewport reports the camera rect at the track's current clock.
type Fill ¶
Fill is a margin fill: a solid color, or an image file already decoded by the caller (scaled to the canvas here). Image wins when non-nil.
type HighlightSpec ¶
type HighlightSpec struct {
Pattern *regexp.Regexp
Col, Row, W, H int
Rect bool
Occurrence int
Pick bool
Name string
}
HighlightSpec is one highlight: a regex over each row's text, or a cell rectangle (Col,Row,W,H). Exactly one form is set. With Pick, Occurrence narrows a pattern to that match of the FRAME — 0-based in screen order, the same standard as the rect's cells. Name lets a targeted off close just this highlight.
type HighlightTrack ¶
type HighlightTrack struct {
// contains filtered or unexported fields
}
HighlightTrack holds the active highlights and serves the driver's Overlay contract (SetTime/Breakpoints — snap on/off, no fades). Unlike KeysTrack (fed by OnKey ON the driver's goroutine), this one is mutated by the RECORDING goroutine while realtime's loop reads it at render — hence the mutex; in deterministic mode everything is one goroutine and it never contends.
func NewHighlightTrack ¶
func NewHighlightTrack() *HighlightTrack
NewHighlightTrack returns an empty track.
func (*HighlightTrack) Activate ¶
func (ht *HighlightTrack) Activate(spec HighlightSpec, at time.Duration)
Activate turns a highlight on from the given virtual instant.
func (*HighlightTrack) Breakpoints ¶
func (ht *HighlightTrack) Breakpoints(from, to time.Duration) []time.Duration
Breakpoints reports the on/off instants in [from, to) — highlights snap, so those are the only frames they need.
func (*HighlightTrack) Clear ¶
func (ht *HighlightTrack) Clear(at time.Duration)
Clear turns every open highlight off at the given virtual instant.
func (*HighlightTrack) ClearNamed ¶
func (ht *HighlightTrack) ClearNamed(name string, at time.Duration)
ClearNamed turns off every open highlight carrying the name.
func (*HighlightTrack) SetTime ¶
func (ht *HighlightTrack) SetTime(t time.Duration)
SetTime fixes the overlay clock for the next render.
type ImageSource ¶
ImageSource resolves kitty-graphics pixels for placements in a frame. vtengine.Engine satisfies it; so does the test fake.
type KeysNotation ¶
type KeysNotation uint8
KeysNotation is the cap vocabulary.
const ( // KeysKeycap prints what a real keycap prints: lowercase words in // the grid font, drawn arrows, a blank spacebar. KeysKeycap KeysNotation = iota // KeysIcons swaps the words for compact drawn symbols (enter, tab, // bksp, del) — esc stays a word: keyboards never icon it. KeysIcons )
type KeysStyle ¶
type KeysStyle struct {
// Notation picks the cap vocabulary.
Notation KeysNotation
// Accent overrides the special-cap color; nil keeps the theme's
// bright magenta. AccentOff mutes the hierarchy entirely.
Accent *color.RGBA
AccentOff bool
// Plain drops the celluloid: caps float straight on the margin.
Plain bool
}
KeysStyle is the band's styling knobs: notation, accent override, and the plain (stripless) variant.
type KeysTrack ¶
type KeysTrack struct {
// contains filtered or unexported fields
}
KeysTrack accumulates the injected input track and serves the driver's overlay contract structurally (SetTime/Breakpoints) — the driver stays raster-agnostic, the raster driver-agnostic. Chips are a pure function of the track and the render time.
func NewKeysTrack ¶
func NewKeysTrack(notation KeysNotation) *KeysTrack
NewKeysTrack returns an empty input track speaking the given notation (the cap face derives at AddKey time — coalescing compares faces, so the vocabulary is fixed per recording).
func (*KeysTrack) AddKey ¶
AddKey records one injected keystroke. Hidden input is dropped: if the setup is not shown, its typing must not leak either.
func (*KeysTrack) Breakpoints ¶
Breakpoints reports every overlay-state change taking effect in [from, to): cap births, phrase reveals, fade steps. The driver splits time advances there so the animation lands on exact frames.
type Options ¶
type Options struct {
Pack *fontpack.Pack
// UserFonts loads a user primary font over the pack.
UserFonts UserFonts
// FontSizePx is the glyph size in pixels at Scale 1.
FontSizePx int
// Scale multiplies every metric (2 = native supersampling).
Scale int
// SuperSample renders the frame at N× the output for the camera's
// master; 0/1 = none. Cell METRICS still derive at the
// base Scale and multiply exactly — the logical grid (and so the
// footage) is identical with or without a camera.
SuperSample int
// Window configures the chrome around the grid (VHS parity: margin,
// window bar, padding, rounded corners). Zero value = no chrome, the
// canvas is exactly the grid.
Window Window
// Keys is the injected input track for the keys band;
// nil = no chips. Window.KeysBand sizes the band itself.
Keys *KeysTrack
// KeysFontPx is the cap label size in logical px (the reel's
// small/medium/large); zero = FontSizePx.
KeysFontPx int
// KeysStyle tunes the band's look and vocabulary:
// accent override and the plain (stripless) variant. The notation
// lives on the KeysTrack — cap faces derive as keys arrive.
KeysStyle KeysStyle
// Highlights is the highlight track; nil = none.
// SelectionColor paints the matches — the theme's Selection.
Highlights *HighlightTrack
SelectionColor color.RGBA
}
Options configures a Rasterizer.
type Rasterizer ¶
type Rasterizer struct {
// contains filtered or unexported fields
}
Rasterizer turns engine frames into RGBA images. It caches parsed faces, glyph masks and decoded images; it is not safe for concurrent use (one rasterizer per recording, like the engine).
func New ¶
func New(opts Options) (*Rasterizer, error)
New parses the pack's faces and computes the cell metrics that the engine geometry must match (Geometry.CellW/CellH = CellSize()).
func (*Rasterizer) CellSize ¶
func (r *Rasterizer) CellSize() (w, h int)
CellSize returns the cell size in output pixels (already scaled).
func (*Rasterizer) Composite ¶
Composite develops the master through the camera: the WORLD part of the frame is the viewport downscaled into the output; the HUD band (the keys reel) is glued under it at a fixed 2:1 — pinned to the camera glass, never zoomed (stratification). dst is reused when it already has the output size.
func (*Rasterizer) LogicalCellSize ¶
func (r *Rasterizer) LogicalCellSize() (w, h int)
LogicalCellSize returns the cell size in LOGICAL pixels — the values the engine geometry and the pty winsize must use (kitty-graphics math happens in logical space; Render multiplies by Scale).
func (*Rasterizer) Render ¶
func (r *Rasterizer) Render(f *vtengine.Frame, src ImageSource, dst *image.RGBA) (*image.RGBA, error)
Render draws the frame into dst (reused when it has the right bounds, reallocated otherwise) and returns the image.
func (*Rasterizer) SuperSample ¶
func (r *Rasterizer) SuperSample() int
SuperSample reports the master's supersample factor (1 = no camera).
func (*Rasterizer) Warnings ¶
func (r *Rasterizer) Warnings() []string
Warnings reports assembly findings for the recorder to surface. The slice is a copy — callers cannot corrupt the rasterizer's record.
func (*Rasterizer) WorldRect ¶
func (r *Rasterizer) WorldRect() image.Rectangle
WorldRect is the camera's world on the master: the canvas minus the keys band — the HUD stays glued to the camera glass.
func (*Rasterizer) ZoomTarget ¶
func (r *Rasterizer) ZoomTarget(col, row, w, h int) (image.Rectangle, error)
ZoomTarget maps a CELL rect (0-based, the house standard) to a master viewport: expanded to the world's aspect around its center, capped at the supersample's sharp limit — beyond it foley would ship a blurry frame, and blurry never ships silently: it refuses with the recipe — then clamped inside the world.
type TitleAlign ¶
type TitleAlign uint8
TitleAlign positions the window title inside the bar.
const ( TitleCenter TitleAlign = iota TitleLeft )
Title alignments.
type UserFonts ¶
type UserFonts struct {
// Label names the font in errors and warnings (a file path or a
// catalog family name).
Label string
Regular, Bold, Italic, BoldItalic []byte
}
UserFonts is a user-supplied primary font. A single file fills Regular and serves every style; a family gives styles their own files — absent styles fall back to the Regular face, keeping the grid metrics whole. The primary drives cell metrics and titles the window bar; the pack stays as per-cell coverage fallback, emoji stay Noto, and block sprites stay synthesized.
type Window ¶
type Window struct {
// CanvasW, CanvasH are the final output size in logical pixels.
// Zero means "grid only" (no chrome).
CanvasW, CanvasH int
// Padding is the inner border between the terminal background and
// the grid, painted in the theme background.
Padding int
// Margin is the border outside the window block, painted MarginFill.
Margin int
// MarginFill paints the margin band (and the corner reveals).
MarginFill Fill
// Bar selects the window bar style; BarSize its height; BarColor its
// background.
Bar BarStyle
BarSize int
BarColor color.RGBA
// Title is drawn inside the bar (static text: recordings must not
// leak hostnames — determinism). TitleAlign positions it.
Title string
TitleAlign TitleAlign
// TitleFollow lets the bar follow the title the APPLICATION
// declares via OSC 0/2 (Frame.Title), falling back to Title while
// none is set. Footage, not host state: deterministic.
TitleFollow bool
// KeysBand is the height of the input-caption band under the
// window; zero = no band. The canvas GROWS by it — a cue
// never eats grid rows and the footage is never covered.
KeysBand int
// Radius rounds the window block's corners, revealing MarginFill.
Radius int
}
Window configures the chrome. Zero value = no chrome at all: the canvas is exactly the grid (every pre-chrome recording and golden).