Documentation
¶
Overview ¶
The CSS box primitives: per-corner rounded fills, rounded border rings with per-side widths and colors, angled multi-stop linear gradients, and box shadows with offset, spread, blur, and inset — everything a CSS box paints behind its content. Every primitive is a per-pixel signed-distance coverage pass at the device scale and blends through the single blend site, so PushAlpha and PushBrightness apply by construction.
Package render holds pure drawing and damage primitives. Nothing in here touches Wayland; everything is unit-testable.
The shadow raster cache. Canvas.Shadow paints a blurred rounded-rect silhouette; the expensive half of that is the coverage field - the Gaussian kernel and the per-pixel signed-distance sweep - and it depends only on (rect size, corner radius, blur, device scale), never on the color or what is underneath. This file builds each field once and hands the cached raster back, so a hover twitch that repaints the same floating surface every frame re-blends the ring but never re-Gaussians it. The counters double as the paint-count proof: a second identical Shadow must be a hit, not a rebuild.
Index ¶
- Constants
- Variables
- func AlignedPen(sh *ShapedText, box Rect, h Alignment, d text.Direction) (x, baseline int)
- func DecodeImage(data []byte) (image.Image, error)
- func EllipsizeText(f Font, text string, mode EllipsizeMode, maxWidth, px float64) string
- func FixtureFontData() []byte
- func FixtureHebrewFontData() []byte
- func NRGBA(data []byte, stride, width, height int) *image.NRGBA
- func Resample(src image.Image, srcRect image.Rectangle, dstW, dstH int) *image.RGBA
- func ScaleRect(srcW, srcH, boxW, boxH int, s ImageScale) (src image.Rectangle, dstW, dstH int)
- func Stride(widthPx int) int
- func WrapText(f Font, text string, maxWidth, px float64) []string
- type Affine
- type Alignment
- type Animation
- type BoxShadow
- type Canvas
- func (c *Canvas) Arc(cx, cy, radius, width, start, sweep float64, col Color)
- func (c *Canvas) BeginOverlays()
- func (c *Canvas) BorderRect(r Rect, width int, col Color)
- func (c *Canvas) BoxShadow(r Rect, radii Corners, s BoxShadow)
- func (c *Canvas) Clear(r Rect, col Color)
- func (c *Canvas) ClearDevice(r Rect, col Color)
- func (c *Canvas) Composite(l *Layer, src Rect, m Affine, alpha float64)
- func (c *Canvas) DeviceScale() (num, denom int)
- func (c *Canvas) DrawImage(img image.Image, x, y int)
- func (c *Canvas) DrawImageCover(img image.Image, r Rect, radii Corners)
- func (c *Canvas) DrawImageCoverImage(ic *Icon, r Rect, radii Corners)
- func (c *Canvas) DrawImageDevice(img image.Image, x, y int)
- func (c *Canvas) FillPath(p *Path, col Color)
- func (c *Canvas) FillRect(r Rect, col Color)
- func (c *Canvas) FillRectDevice(r Rect, col Color)
- func (c *Canvas) FinishFocus()
- func (c *Canvas) FlushOverlays()
- func (c *Canvas) Layer(old *Layer, region Rect) *Layer
- func (c *Canvas) Line(x0, y0, x1, y1, width int, col Color)
- func (c *Canvas) MapRect(r Rect) Rect
- func (c *Canvas) MarkFocus(key any, paint func(*Canvas))
- func (c *Canvas) Overlay(paint func(*Canvas))
- func (c *Canvas) PaintGradient(r Rect, radii Corners, g Gradient)
- func (c *Canvas) Painted(w any)
- func (c *Canvas) PopAlpha(prev float64)
- func (c *Canvas) PopBrightness(prev float64)
- func (c *Canvas) PopClip(prev Rect)
- func (c *Canvas) PushAlpha(a float64) float64
- func (c *Canvas) PushBrightness(f float64) float64
- func (c *Canvas) PushClip(r Rect) Rect
- func (c *Canvas) PushClipDevice(r Rect) Rect
- func (c *Canvas) Rect() Rect
- func (c *Canvas) ResetTouched() int
- func (c *Canvas) RoundedBorder(r Rect, radii Corners, widths Insets, col Color)
- func (c *Canvas) RoundedBorderSides(r Rect, radii Corners, widths Insets, cols [4]Color)
- func (c *Canvas) RoundedRect(r Rect, radius int, col Color)
- func (c *Canvas) RoundedRectCorners(r Rect, radii Corners, col Color)
- func (c *Canvas) Shadow(r Rect, cornerRadius, blur int, col Color)
- func (c *Canvas) Touched() int
- type Chain
- func (c *Chain) Draw(cv *Canvas, s *ShapedText, x, baselineY int, col Color)
- func (c *Chain) DrawAligned(cv *Canvas, s string, box Rect, px float64, col Color, h Alignment) *ShapedText
- func (c *Chain) DrawAlignedDir(cv *Canvas, s string, box Rect, px float64, col Color, h Alignment, ...) *ShapedText
- func (c *Chain) Ellipsize(text string, maxWidth, px float64) string
- func (c *Chain) Face(r rune) *Typeface
- func (c *Chain) Primary() *Typeface
- func (c *Chain) Shape(s string, px float64) *ShapedText
- func (c *Chain) ShapeDir(s string, px float64, d text.Direction) *ShapedText
- func (c *Chain) ShapeRune(r rune, px float64) *ShapedText
- func (c *Chain) Spaced(px float64) *Chain
- func (c *Chain) Tabular() *Chain
- func (c *Chain) Weighted(w int) *Chain
- func (c *Chain) WithResolver(resolve func(rune) *Typeface) *Chain
- func (c *Chain) WithVariations(vs ...Variation) *Chain
- func (c *Chain) Wrap(text string, maxWidth, px float64) []string
- type Color
- type Corners
- type Decoration
- type DecorationLine
- type DecorationStyle
- type EllipsizeMode
- type Extend
- type Font
- type Gradient
- type GradientKind
- type GradientStop
- type Icon
- type ImageScale
- type Insets
- type Layer
- type Path
- type RadialSize
- type Rect
- type ShapedText
- func (s *ShapedText) Advance() float64
- func (s *ShapedText) AppendCaretBands(buf [][2]float64, start, end int) [][2]float64
- func (s *ShapedText) Ascent() float64
- func (s *ShapedText) CaretAt(x float64) int
- func (s *ShapedText) CaretPositions() []float64
- func (s *ShapedText) CaretX(caret int) float64
- func (s *ShapedText) Descent() float64
- func (s *ShapedText) Draw(cv *Canvas, x, baselineY int, col Color)
- func (s *ShapedText) DrawDecoration(cv *Canvas, x, baseline int, d Decoration, col Color)
- func (s *ShapedText) LineHeight() int
- func (s *ShapedText) NotDefCount() int
- func (s *ShapedText) Runs() int
- func (s *ShapedText) Text() string
- type Typeface
- func (t *Typeface) Covers(r rune) bool
- func (t *Typeface) Describe() font.Description
- func (t *Typeface) Draw(cv *Canvas, s *ShapedText, x, baselineY int, col Color)
- func (t *Typeface) DrawAligned(cv *Canvas, s string, box Rect, px float64, col Color, h Alignment) *ShapedText
- func (t *Typeface) DrawAlignedDir(cv *Canvas, s string, box Rect, px float64, col Color, h Alignment, ...) *ShapedText
- func (t *Typeface) Ellipsize(text string, maxWidth, px float64) string
- func (t *Typeface) Family() string
- func (t *Typeface) HasAxis(tag string) bool
- func (t *Typeface) IsMonospace() bool
- func (t *Typeface) Shape(s string, px float64) *ShapedText
- func (t *Typeface) ShapeDir(s string, px float64, d text.Direction) *ShapedText
- func (t *Typeface) ShapeRune(r rune, px float64) *ShapedText
- func (t *Typeface) Spaced(px float64) *Typeface
- func (t *Typeface) Tabular() *Typeface
- func (t *Typeface) Variations() []Variation
- func (t *Typeface) Weighted(w int) *Typeface
- func (t *Typeface) WithVariations(vs ...Variation) *Typeface
- func (t *Typeface) Wrap(text string, maxWidth, px float64) []string
- type Variation
Constants ¶
const Ellipsis = "…"
Ellipsis is the mark a truncated text carries where it was cut.
Variables ¶
var Identity = Affine{A: 1, D: 1}
Identity is the affine map that moves nothing.
Functions ¶
func AlignedPen ¶
AlignedPen is where an aligned draw puts sh's pen inside box: the alignment mirrored for a right-to-left line, the line centered vertically on its baseline. Decorations and carets drawn after a DrawAligned use it to land on the painted text.
func DecodeImage ¶
DecodeImage decodes image bytes: an animated GIF or APNG to an *Animation, anything else (PNG, JPEG, GIF, still WebP) to a still image. Animated WebP is not decoded: golang.org/x/image/webp, the pure-Go decoder, reads still images only.
func EllipsizeText ¶
func EllipsizeText(f Font, text string, mode EllipsizeMode, maxWidth, px float64) string
EllipsizeText shortens text so its advance fits maxWidth, cutting at mode and inserting an ellipsis; see Typeface.Ellipsize. Package-level so any Font - a lone typeface or a fallback chain - truncates through the same code path the methods use.
func FixtureFontData ¶
func FixtureFontData() []byte
FixtureFontData returns the bytes of the bundled Cantarell Regular fixture font (SIL Open Font License 1.1; the license text ships in testdata/LICENSE-Cantarell.txt). It is the single face every golden snapshot is shaped with.
func FixtureHebrewFontData ¶
func FixtureHebrewFontData() []byte
FixtureHebrewFontData returns the bytes of the bundled Hebrew fixture face; see render/testdata/README.md for why a second face exists.
func NRGBA ¶
NRGBA converts a Canvas-format pixel buffer — ARGB8888 premultiplied in wl_shm byte order — into a straight-alpha image.NRGBA: exactly the pixel representation the PNG goldens store, so encode, decode, and compare all see the same bytes and the comparison is exact. stride is in bytes; the returned image's rows are tight.
func Resample ¶
Resample scales srcRect of src into a fresh dstW x dstH RGBA with the CatmullRom kernel. Cubic resampling is what keeps fractional and non-integer down- and upscales from the blockiness of a nearest-neighbor pass (stubbedev/gelm#14); the canvas's own image drawing is nearest-neighbor and must never see unresampled pixels.
func ScaleRect ¶
func ScaleRect(srcW, srcH, boxW, boxH int, s ImageScale) (src image.Rectangle, dstW, dstH int)
ScaleRect resolves a scaling policy for a srcW x srcH image into a boxW x boxH box. Both sizes are in the same units - widget.Image feeds device pixels so the result stays crisp at fractional scales. It returns the source rectangle to sample and the size to resample it into; drawing that resample centered in the box is the whole policy. An empty result means a zero-sized input.
Types ¶
type Affine ¶
type Affine struct{ A, B, C, D, E, F float64 }
Affine is a 2-D affine map in device pixels: (x, y) goes to (A·x + C·y + E, B·x + D·y + F). The zero value maps everything to the origin; Identity leaves points where they are.
func Rotate ¶
Rotate is the map rotating about the origin by deg degrees, clockwise on screen (y grows downward), as a GSK snapshot rotation does.
type Alignment ¶
type Alignment uint8
Alignment selects how a drawn run is positioned inside its box.
type Animation ¶
Animation is a decoded animated image (GIF, APNG): every frame fully composited over the canvas, how long each shows, and how many times the sequence plays (0: forever). It is an image.Image as its first frame, so every still-image path - sizing, a static paint, a cache - takes it unchanged; an animating painter steps through Frames.
func (*Animation) ColorModel ¶
ColorModel implements image.Image (the first frame's).
func (*Animation) PixelBytes ¶
PixelBytes is the frames' combined pixel cost, what a byte-budget cache charges for the animation.
type BoxShadow ¶
BoxShadow is one CSS box-shadow layer: an offset, a blur radius (the Gaussian spans two sigmas of it, CSS's convention), a spread, and whether it paints inside the box instead of outside.
type Canvas ¶
type Canvas struct {
// contains filtered or unexported fields
}
Canvas paints into a raw ARGB8888 premultiplied pixel buffer: the exact format of a wl_shm buffer at any scale. All drawing clips to the intersection of the requested rect, the canvas bounds, and any clip set with PushClip, and blends through the opacity set with PushAlpha.
The canvas carries a device scale: a rational number of device (buffer) pixels per logical pixel - 240/120 is 2x, 150/120 is the fractional 1.25x. Primitive arguments (FillRect, RoundedRect, text, ...) are in logical pixels and land on device pixels rounded outward, so a logical rect fully covers the device area it spans; text is shaped at its logical size and rasterized at the device scale, which keeps it crisp at any factor. PushClip takes a logical rect like every primitive; the bounds returned by Rect and the explicit device bridge (MapRect, ClearDevice, FillRectDevice, PushClipDevice) are in device pixels.
func New ¶
New returns a canvas over data: height rows of stride bytes holding width ARGB8888 pixels each, at device scale 1 (one device pixel per logical pixel).
func NewScaled ¶
NewScaled returns a canvas over data at the given device scale: num device pixels per denom logical pixels (240/120 doubles). width and height are the buffer's device size. It panics on a non-positive scale, which is a programming error, not a runtime condition.
func (*Canvas) Arc ¶
Arc strokes a circular arc of the logical circle centered at (cx, cy) with the given radius (to the stroke's middle) and stroke width, clockwise from start through sweep radians (0 is three o'clock, -π/2 is twelve). Caps are round, like cairo's LINE_CAP_ROUND; a sweep of 2π or more is the whole circle. Anti-aliased by per-pixel signed distance at the device scale.
func (*Canvas) BeginOverlays ¶
func (c *Canvas) BeginOverlays()
BeginOverlays arms the frame's top layer: until FlushOverlays, Overlay defers its paints instead of running them in place. A window arms it around painting its tree, so a widget that hangs content outside its own bounds (an open dropdown list) paints above every later sibling, as a popover would.
func (*Canvas) BorderRect ¶
BorderRect blends col over a hollow rect of the given logical thickness. The stroke grows inward from the rect edges.
func (*Canvas) BoxShadow ¶
BoxShadow paints one CSS box-shadow layer for the box r with the given corner radii. An outer shadow is the box offset and grown by the spread, blurred, and clipped to outside the box itself (so a translucent box never shows its own shadow through); an inset shadow fills the box's inside except the offset, spread-shrunk hole, blurred at the hole's edge. The blur is Gaussian with sigma half the blur radius, evaluated per pixel from the silhouette's signed distance.
func (*Canvas) Clear ¶
Clear overwrites the logical rect with col, ignoring what is underneath. ClearDevice is the device-space counterpart for callers that already hold mapped rects.
func (*Canvas) ClearDevice ¶
ClearDevice overwrites the device-pixel rect r with col, ignoring what is underneath. Unlike Clear it applies no logical mapping: it is the bridge for frame pipelines that track damage in device pixels.
func (*Canvas) Composite ¶
Composite draws the src device rect of l onto c through m (layer device pixels to canvas device pixels), bilinearly filtered, blended through c's opacity times alpha and clipped to c's clip. Pixels of l outside src count as transparent, so the drawn edge antialiases. A whole-pixel translation copies without filtering.
func (*Canvas) DeviceScale ¶
DeviceScale returns the canvas's device scale as a rational: num device pixels per denom logical pixels.
func (*Canvas) DrawImage ¶
DrawImage blends img onto the canvas, scaled from its natural (logical) size to the device rect its logical placement spans.
func (*Canvas) DrawImageCover ¶
DrawImageCover blends img onto the canvas scaled to COVER r: the image scales uniformly until it fills the rect, centered, the overflow cropped (CSS background-size: cover), the whole masked by the rounded rect.
func (*Canvas) DrawImageCoverImage ¶
DrawImageCoverImage is DrawImageCover for an Icon's pixels.
func (*Canvas) DrawImageDevice ¶
DrawImageDevice blends img onto the canvas one-to-one in device pixels, its top-left corner at (x, y). It is the device-space counterpart of DrawImage: rasters that were already resampled for the device rect they cover - widget.Image's cache - must land without a second scale, which DrawImage's nearest-neighbor logical mapping would apply at any device scale other than 1.
Opacity (PushAlpha) modulates here, at blit time, and nowhere earlier: the cached rasters are premultiplied and shared by every consumer, so baking a factor into them would double-multiply the next frame and bleed into widgets fading independently. Multiplying the premultiplied channels together (blend then modulate) keeps a modulated raster premultiplied, exactly like the AA coverage ramps.
func (*Canvas) FillPath ¶
FillPath fills the path's subpaths with col, anti-aliased, under the clip and the pushed opacity. Overlapping subpaths fill once.
func (*Canvas) FillRectDevice ¶
FillRectDevice blends col over the device-pixel rect with source-over compositing; the device counterpart of FillRect.
func (*Canvas) FinishFocus ¶
func (c *Canvas) FinishFocus()
FinishFocus draws the focus ring if no container reached its widget (a container defined outside the kit, a subtree composited from a layer) and disarms it.
func (*Canvas) FlushOverlays ¶
func (c *Canvas) FlushOverlays()
FlushOverlays runs the deferred top-layer paints in queue order (one queued while flushing runs too) and disarms the frame.
func (*Canvas) Layer ¶
Layer returns a layer the size and scale of c whose region (device pixels) is transparent and is the layer's clip; drawing lands only there. old's buffer is reused when it is the right size, so a layer kept across frames allocates once.
func (*Canvas) Line ¶
Line blends col along the segment from logical (x0, y0) to (x1, y1) with the given thickness in logical pixels, anti-aliased with per-pixel signed-distance coverage at the device scale. Caps are round.
func (*Canvas) MarkFocus ¶
MarkFocus arms the frame's focus ring: Painted draws it the moment key's widget finishes painting, so everything painted after it in tree order (a card over a list, a later sibling) covers it, as a widget's own outline would be covered. A nil key clears it.
func (*Canvas) Overlay ¶
Overlay paints on the frame's top layer: deferred to FlushOverlays while a frame is armed, in place otherwise (a subtree painted on its own has no later siblings to escape). The deferred paint runs under the frame's clip, not the caller's, so a scrolled container does not cut it, with the opacity in force now.
func (*Canvas) PaintGradient ¶
PaintGradient fills r with g, clipped to its rounded outline (radii in logical pixels). Colors interpolate premultiplied between the stops. A linear gradient's line spans the box's corners along its angle, CSS's rule; radial and conic geometry sizes against the box.
func (*Canvas) Painted ¶
Painted reports that w finished painting: the containers call it after each child, drawing the armed focus ring after its widget.
func (*Canvas) PopBrightness ¶
PopBrightness restores a factor returned by PushBrightness.
func (*Canvas) PushAlpha ¶
PushAlpha scales the opacity of everything painted until the matching PopAlpha: every blended primitive (FillRect, RoundedRect, gradients, Line, text, images) has its premultiplied color channels - color with the alpha, never the alpha alone - multiplied by a. It is the subtree-opacity primitive fades hang off: nested pushes multiply, and a zero push makes every blend a no-op without touching a pixel. a clamps to [0, 1], so a spring tween's overshoot saturates instead of over-brightening.
It returns the previous opacity; restore it with PopAlpha, the same save-and-restore shape as PushClip. Clear and ClearDevice are the one exception: they overwrite pixels rather than blend, so a faded subtree cannot punch transparent holes in its background.
func (*Canvas) PushBrightness ¶
PushBrightness multiplies the color channels of everything painted until the matching PopBrightness by f: CSS's filter: brightness(). Nested pushes multiply. Channels clamp at the pixel's alpha, so the result stays a valid premultiplied color. It returns the previous factor; restore it with PopBrightness.
func (*Canvas) PushClip ¶
PushClip narrows subsequent drawing to the intersection of the logical rect r, mapped to device pixels the way FillRect maps, and the current clip. It returns the previous clip; restore it with PopClip.
func (*Canvas) PushClipDevice ¶
PushClipDevice is PushClip for a rect already in device pixels (a damage region, a layer's rect).
func (*Canvas) ResetTouched ¶
ResetTouched zeroes the drawn-pixel counter and returns the previous value.
func (*Canvas) RoundedBorder ¶
RoundedBorder strokes the ring between r's rounded outline and its inner edge, inset per side by widths: a CSS border. The inner corner radii shrink by the adjacent widths.
func (*Canvas) RoundedBorderSides ¶
RoundedBorderSides is RoundedBorder with a color per side (top, right, bottom, left). A ring pixel takes the color of the side it is relatively closest to, which splits the corners along their diagonals the way CSS borders join.
func (*Canvas) RoundedRect ¶
RoundedRect blends col over a filled logical rect with corners rounded by radius logical pixels, anti-aliased with per-pixel signed-distance coverage. The rasterization runs at the device scale.
func (*Canvas) RoundedRectCorners ¶
RoundedRectCorners blends col over r with each corner rounded by its own radius, anti-aliased. Radii that overlap scale down together, per CSS.
func (*Canvas) Shadow ¶
Shadow blends a box shadow for the logical rect: the blurred silhouette of a rounded rect, centered on r (no spread), falling off with a precomputed Gaussian kernel. blur is the falloff radius in logical pixels. The shadow paints OUTSIDE r - full strength at the edges, tail gone past blur - so callers keep layout and hit-testing on r itself and owe the ring only damage. The coverage raster is cached per (rect size, radius, blur, device scale) in shadowRasterFor, so a hover twitch that repaints the same shadow re-blends the pixels but never re-Gaussians. Per-pixel coverage scales all four premultiplied channels exactly as RoundedRect's AA, and the draw blends through the PushAlpha stack like every primitive, so a fading surface fades its shadow with it.
type Chain ¶
type Chain struct {
// contains filtered or unexported fields
}
Chain shapes mixed-script text across faces: every rune goes to the first face that covers it, so a line mixing latin, CJK, and emoji renders instead of drawing .notdef boxes. The picks cache per rune, so repeated shapes pay one lookup per distinct rune. Like Typeface, a chain is not safe for concurrent use.
func FixtureChain ¶
FixtureChain returns a fresh fallback chain over the two bundled fixture faces — Latin and digits from Cantarell, Hebrew from Noto Sans Hebrew — the shape mixed-direction goldens pin.
func NewChain ¶
NewChain returns a chain shaping with primary and, for runes it lacks, the first covering face of fallback. A nil primary panics here, naming the argument — the same nil-face contract the widget constructors enforce — instead of failing on the first Shape.
func (*Chain) Draw ¶
func (c *Chain) Draw(cv *Canvas, s *ShapedText, x, baselineY int, col Color)
Draw paints a shaped line; see ShapedText.Draw.
func (*Chain) DrawAligned ¶
func (c *Chain) DrawAligned(cv *Canvas, s string, box Rect, px float64, col Color, h Alignment) *ShapedText
DrawAligned draws text inside box with the given alignment; see Typeface.DrawAligned.
func (*Chain) DrawAlignedDir ¶
func (c *Chain) DrawAlignedDir(cv *Canvas, s string, box Rect, px float64, col Color, h Alignment, d text.Direction) *ShapedText
DrawAlignedDir draws text inside box under base direction d; start and end mirror for a right-to-left base. See text.Direction.
func (*Chain) Face ¶
Face returns the face rune r shapes with: the diagnostic view of the fallback decision, and a way for tests to pin which family a rune lands on.
func (*Chain) Shape ¶
func (c *Chain) Shape(s string, px float64) *ShapedText
Shape splits text into runs of consecutive runes sharing a face and shapes each with it, on one shared baseline, serving repeats from the process-wide shaping cache like Typeface.Shape. Within that, the line resolves into directional runs (internal/text.BidiRuns) laid out in visual order, so mixed Hebrew/Arabic + Latin lines render reading-correct. The chain is the key: a chain held by the app reuses its entries across frames, and two chains over the same faces never collide. Empty text still shapes one primary run, so its metrics reserve the font's line height.
func (*Chain) ShapeDir ¶
ShapeDir shapes under base direction d; see Chain.Shape and text.Direction.
func (*Chain) ShapeRune ¶
func (c *Chain) ShapeRune(r rune, px float64) *ShapedText
ShapeRune shapes one rune; see Font.ShapeRune and Chain.Shape.
func (*Chain) Spaced ¶
Spaced returns the chain shaping with px of letter spacing after every cluster, whichever face a rune lands on (see Typeface.Spaced).
func (*Chain) Tabular ¶
Tabular returns the chain shaping with each face's tnum twin: digits on a uniform advance grid, what a clock or a numeric column wants. The variant keeps its own rune picks, so it never rewrites the base chain's.
func (*Chain) WithResolver ¶
WithResolver installs a store-backed face picker consulted for runes neither the primary nor the fallback list covers, and returns the chain. internal/sysfont.Fallback wires one to the system font store.
func (*Chain) WithVariations ¶
WithVariations returns the chain shaping with every face instantiated at vs (each face ignores axes it lacks); faces the store resolves for uncovered runes shape at their defaults.
type Color ¶
type Color uint32
Color is a premultiplied ARGB8888 pixel value, laid out as 0xAARRGGBB. Premultiplied is the native format of both the wl_shm buffers and Go's image.RGBA, so colors pass through blending without conversion.
func ColorFromBytes ¶
ColorFromBytes decodes a premultiplied color from the wl_shm byte order: little-endian ARGB8888, that is bytes B, G, R, A.
type Corners ¶
type Corners struct {
TopLeft, TopRight, BottomRight, BottomLeft int
}
Corners is a per-corner radius set in logical pixels, clockwise from the top-left.
type Decoration ¶
type Decoration struct {
Lines DecorationLine
Style DecorationStyle
Color Color
}
Decoration is a text decoration: its lines, their style, and their color (zero: the text's).
type DecorationLine ¶
type DecorationLine uint8
DecorationLine is a set of text decoration lines (CSS text-decoration-line).
const ( Underline DecorationLine = 1 << iota Overline LineThrough )
Decoration lines.
type DecorationStyle ¶
type DecorationStyle uint8
DecorationStyle is how decoration lines are drawn (CSS text-decoration-style).
const ( DecorationSolid DecorationStyle = iota DecorationDouble DecorationDotted DecorationDashed DecorationWavy )
Decoration styles.
type EllipsizeMode ¶
type EllipsizeMode uint8
EllipsizeMode selects which end of an overflowing line the ellipsis replaces.
const ( // EllipsizeNone never truncates: long text overflows and clips. EllipsizeNone EllipsizeMode = iota // EllipsizeStart cuts from the front: "…cated text". EllipsizeStart // EllipsizeMiddle keeps the head and the tail: "trunc…text" - the // mode for paths and filenames, whose both halves identify them. EllipsizeMiddle // EllipsizeEnd cuts from the back: "truncated te…". EllipsizeEnd )
type Font ¶
type Font interface {
// Shape lays text out at the given pixel size, resolving the base
// paragraph direction from the text's first strong character.
Shape(s string, px float64) *ShapedText
// ShapeDir is Shape under an explicit base direction; see
// text.Direction.
ShapeDir(s string, px float64, d text.Direction) *ShapedText
// ShapeRune shapes one rune at the pixel size - the per-rune probe
// wrap measurement and advance math use. Rune-keyed in the caches,
// so a probe never builds a one-rune string per call.
ShapeRune(r rune, px float64) *ShapedText
// Draw paints a shaped line with its baseline at logical
// (x, baselineY).
Draw(cv *Canvas, s *ShapedText, x, baselineY int, col Color)
// DrawAligned draws text inside box with the given alignment; start
// and end mirror for a right-to-left paragraph.
DrawAligned(cv *Canvas, s string, box Rect, px float64, col Color, h Alignment) *ShapedText
// DrawAlignedDir is DrawAligned under an explicit base direction.
DrawAlignedDir(cv *Canvas, s string, box Rect, px float64, col Color, h Alignment, d text.Direction) *ShapedText
}
Font shapes and paints text: a single Typeface, or a Chain that falls back across faces for runes the primary face lacks. Widgets take a Font, so either works at every text call site.
type Gradient ¶
type Gradient struct {
Kind GradientKind
Stops []GradientStop
Extend Extend
// Angle is the linear direction, or the conic start, in degrees on
// CSS's compass: 0 up, 90 right, clockwise.
Angle float64
// CenterX and CenterY place a radial or conic center as fractions
// of the box (0.5 is its middle).
CenterX, CenterY float64
// Circle makes a radial gradient's ending shape a circle instead
// of an ellipse.
Circle bool
// Size picks the radial ending shape's size; RadiusX and RadiusY
// are its explicit radii in logical pixels under RadiusExplicit (a
// circle takes RadiusX).
Size RadialSize
RadiusX, RadiusY float64
}
Gradient is one gradient fill: its geometry, its stops (sorted by position; positions may repeat for a hard stop), and its extend mode. The zero value is a padded linear gradient pointing up; build one with Linear, Radial or Conic.
func Conic ¶
func Conic(from float64, stops ...GradientStop) Gradient
Conic is a centered conic gradient starting at from (CSS degrees).
func Linear ¶
func Linear(angle float64, stops ...GradientStop) Gradient
Linear is a linear gradient at angle (CSS degrees).
func Radial ¶
func Radial(stops ...GradientStop) Gradient
Radial is a centered farthest-corner ellipse.
type GradientKind ¶
type GradientKind uint8
GradientKind is a gradient's geometry.
const ( // GradientLinear runs along a line at an angle (CSS linear-gradient). GradientLinear GradientKind = iota // GradientRadial grows from a center out to an ellipse or circle // (CSS radial-gradient). GradientRadial // GradientConic sweeps around a center (CSS conic-gradient). GradientConic )
type GradientStop ¶
GradientStop is one color stop of a gradient: Pos is the fraction of the gradient line (or ray, or turn), 0 at its start and 1 at its end.
type Icon ¶
type Icon struct {
// contains filtered or unexported fields
}
Icon is a rasterized icon ready to blend onto a canvas.
func IconFromARGB32 ¶
IconFromARGB32 decodes a width x height raster of 32-bit ARGB pixels in network byte order (A, R, G, B per pixel, straight alpha, rows top to bottom with no padding) and scales it to w x h pixels. This is the StatusNotifierItem IconPixmap wire format (also the _NET_WM_ICON payload once byte-swapped to big-endian). data shorter than width*height*4 is an error, not a partial icon; trailing bytes past the raster are ignored.
func IconFromImage ¶
IconFromImage scales any decoded image to w x h pixels, the same resampling LoadPNG applies. It is the entry point for pixels that did not come from a file: a decoded image the caller already holds, or a raster protocol payload converted to an image.
func LoadSVG ¶
LoadSVG rasterizes SVG icon data at w x h pixels. The icon's viewBox is scaled to fit inside that box with its aspect ratio kept and centered; the rest stays transparent. Unsupported SVG elements are an error, not silently dropped.
func (*Icon) DrawRotated ¶
DrawRotated blends the icon turned deg degrees clockwise about its center, the center staying where the unrotated draw's center is. Destination pixels inverse-map into the icon with nearest sampling; the corners past the rotated bounds stay transparent.
func (*Icon) DrawXformed ¶
DrawXformed blends the icon through the affine m, applied about the icon's center: destination pixels inverse-map into the icon with nearest sampling; corners past the transformed bounds stay transparent. The identity draws straight.
func (*Icon) Tint ¶
Tint returns a copy of the icon recolored to tint: every pixel keeps its alpha (anti-aliasing, opacity) and takes tint's color, so the source works as a mask. This is how symbolic icons follow the theme accent. The limits are the mask approach's limits: ink comes out one flat color, gradient hue variation collapses to its alpha ramp, and multi-color art goes monochrome - which is the symbolic-icon contract. A translucent tint yields a translucent result.
type ImageScale ¶
type ImageScale uint8
ImageScale picks how an image fills the box its widget was arranged into.
const ( // ImageFit scales the image to the largest size that fits the box // with the aspect ratio kept (contain); the rest of the box stays // transparent. The default. ImageFit ImageScale = iota // ImageCover scales the image until it fills the box completely, // aspect ratio kept, cropping the overflow: the largest centered // crop of the source with the box's aspect ratio, resampled to the // full box. ImageCover // ImageNone draws the image at its natural size, one source pixel // per device pixel, centered in the box and clipped to it. Nothing // is resampled, so the pixels stay exactly as decoded - at a 2x // device scale an image covers half the logical size it would at // 1x. ImageNone // ImageStretch resamples the whole image to exactly the box, // ignoring the aspect ratio. ImageStretch // ImageScaleDown is ImageNone for an image that fits the box and // ImageFit for one that does not: never enlarged, only shrunk (aspect // kept) until it fits - GTK's ContentFit.SCALE_DOWN, with the natural // size measured in device pixels like ImageNone. ImageScaleDown )
type Insets ¶
type Insets struct {
Top, Right, Bottom, Left int
}
Insets is a per-side length set in logical pixels, in CSS order.
type Layer ¶
type Layer struct {
// contains filtered or unexported fields
}
Layer is an offscreen buffer shaped like a canvas: the same device size and scale, so a widget subtree paints into it exactly as it would onto the canvas, to be drawn back transformed by Composite.
type Path ¶
type Path struct {
// contains filtered or unexported fields
}
Path is an outline in logical pixels for FillPath: straight and cubic Bézier segments in subpaths, each closed when filled (cairo's move_to / line_to / curve_to / close_path).
type RadialSize ¶
type RadialSize uint8
RadialSize is a radial gradient's ending-shape size, the CSS keywords plus explicit radii.
const ( // FarthestCorner reaches the farthest corner (the CSS default). FarthestCorner RadialSize = iota // ClosestSide touches the nearest side. ClosestSide // ClosestCorner reaches the nearest corner. ClosestCorner // FarthestSide touches the farthest side. FarthestSide // RadiusExplicit uses Gradient.RadiusX and RadiusY. RadiusExplicit )
type Rect ¶
type Rect struct {
X, Y, W, H int
}
Rect is an axis-aligned rectangle in buffer pixel coordinates. A Rect with a non-positive width or height is empty and covers no pixels.
func MapRect ¶
MapRect maps the logical rect r into device pixels at scale num/denom, rounding the origin down and the far edge up so the device rect fully covers everything r spans. Package-level so the frame pipeline can map damage without a canvas instance.
func UnionAll ¶
UnionAll returns the bounding box of all rects. Nil and empty inputs yield an empty Rect.
func (Rect) Contains ¶
Contains reports whether the pixel (x, y) lies inside r. Empty rects contain nothing.
func (Rect) Intersect ¶
Intersect returns the overlap of r and o. Disjoint or empty inputs yield an empty Rect.
type ShapedText ¶
type ShapedText struct {
// contains filtered or unexported fields
}
ShapedText is one line of text shaped at a fixed pixel size: a sequence of runs, each shaped with its own face and embedding direction, sharing one baseline, laid out in visual left-to-right order (the directional runs internal/text resolves). Glyph positions are relative to the line origin. A single face and direction produce a single run; fallback chains produce one run per face change.
ShapedText is immutable once built - the process-wide shaping cache shares one instance between every caller that shapes the same (font, size, string) - so readers may hold and consult it freely but never write it.
func (*ShapedText) Advance ¶
func (s *ShapedText) Advance() float64
Advance returns the line width in pixels: the sum over the runs.
func (*ShapedText) AppendCaretBands ¶
func (s *ShapedText) AppendCaretBands(buf [][2]float64, start, end int) [][2]float64
AppendCaretBands appends the x spans covering the selected rune range [start, end) to buf and returns it: one span per visual run the range touches, left to right, so a selection across mixed-direction text highlights disjoint spans instead of spanning the middle. Spans are line-relative; callers offset them. The buffer is the caller's, kept across frames, so the render path stays allocation-free in the steady state.
func (*ShapedText) Ascent ¶
func (s *ShapedText) Ascent() float64
Ascent returns the line's ascent above the baseline in pixels: the maximum over the runs, so a taller fallback face grows the line.
func (*ShapedText) CaretAt ¶
func (s *ShapedText) CaretAt(x float64) int
CaretAt returns the rune boundary nearest x: the inverse of CaretX for hit-testing clicks in a text field, direction-agnostic because the table already follows the line visually.
func (*ShapedText) CaretPositions ¶
func (s *ShapedText) CaretPositions() []float64
CaretPositions returns the caret x for every rune boundary 0..n at once - the table CaretX indexes, shared with every other reader of this line: read it, never modify it. Callers composing several runs into one line (rich labels) offset each run's table by its line x.
func (*ShapedText) CaretX ¶
func (s *ShapedText) CaretX(caret int) float64
CaretX returns the x offset of the caret placed before rune index caret, clamped to [0, rune count]. The x follows the line visually: before an RTL run's first rune it sits at that run's right edge.
func (*ShapedText) Descent ¶
func (s *ShapedText) Descent() float64
Descent returns the line's descent below the baseline in pixels (positive): the maximum over the runs.
func (*ShapedText) Draw ¶
func (s *ShapedText) Draw(cv *Canvas, x, baselineY int, col Color)
Draw paints the line with its baseline at logical (x, baselineY), clipped to the canvas like every other primitive. Each run draws with its own face; every run was shaped at the logical pixel size and rasterizes at the canvas's device scale, so text stays crisp at any factor no matter which face supplied the glyph.
func (*ShapedText) DrawDecoration ¶
func (s *ShapedText) DrawDecoration(cv *Canvas, x, baseline int, d Decoration, col Color)
DrawDecoration draws d along the line s, drawn with its pen at x and baseline: each line spans the shaped advance - the line's visual extent, whatever its runs' directions - at the font's own underline, strikethrough, and ascent metrics (post and OS/2, variable-font deltas included), in d.Color or else col. Every text widget and a rich label's runs paint decorations through it.
func (*ShapedText) LineHeight ¶
func (s *ShapedText) LineHeight() int
LineHeight returns the rounded line height: the smallest integer box height that fits the line's ascent and descent. Measure and drawing guards must both use this so a label's natural height is never smaller than the height its own painter requires.
func (*ShapedText) NotDefCount ¶
func (s *ShapedText) NotDefCount() int
NotDefCount returns how many shaped glyphs are the .notdef box (glyph 0), i.e. runes no face in the chain could render. Fallback chains aim for zero on scripts the system covers.
func (*ShapedText) Runs ¶
func (s *ShapedText) Runs() int
Runs returns how many faces the line was shaped across. A single typeface always returns 1.
func (*ShapedText) Text ¶
func (s *ShapedText) Text() string
Text returns the string the run was shaped from.
type Typeface ¶
type Typeface struct {
// contains filtered or unexported fields
}
Typeface is a loaded font plus the machinery to shape and rasterize it. One instance per font family; it is not safe for concurrent use.
func NewFixtureHebrewTypeface ¶
NewFixtureHebrewTypeface parses the bundled Hebrew fixture into a fresh Typeface, one per caller like NewFixtureTypeface.
func NewFixtureTypeface ¶
NewFixtureTypeface parses the bundled fixture font into a fresh Typeface. One per caller: a Typeface is stateful and not safe for concurrent use, so tests never share one.
func NewTypeface ¶
NewTypeface wraps an already-resolved face, as returned by a font matcher.
func (*Typeface) Covers ¶
Covers reports whether the face has a glyph for r. Fallback chains consult it per rune to decide where a glyph comes from.
func (*Typeface) Describe ¶
func (t *Typeface) Describe() font.Description
Describe returns the face's font description: family, style, weight, and stretch. Callers compare it to pin which variant a request resolved to.
func (*Typeface) Draw ¶
func (t *Typeface) Draw(cv *Canvas, s *ShapedText, x, baselineY int, col Color)
Draw paints a shaped line; see ShapedText.Draw.
func (*Typeface) DrawAligned ¶
func (t *Typeface) DrawAligned(cv *Canvas, s string, box Rect, px float64, col Color, h Alignment) *ShapedText
DrawAligned draws text inside box with the given alignment, skipping it entirely when the box cannot hold one line of the font. The guard uses the same rounded LineHeight the measurement reports.
func (*Typeface) DrawAlignedDir ¶
func (t *Typeface) DrawAlignedDir(cv *Canvas, s string, box Rect, px float64, col Color, h Alignment, d text.Direction) *ShapedText
DrawAlignedDir draws text inside box under base direction d; start and end mirror for a right-to-left base. See text.Direction.
func (*Typeface) Ellipsize ¶
Ellipsize shortens text to fit maxWidth, replacing the cut remainder with an ellipsis. Text that already fits is returned unchanged. For the other cut points use EllipsizeText.
func (*Typeface) HasAxis ¶
HasAxis reports whether the face is variable along tag: setting the axis to its two extremes yields different coordinates.
func (*Typeface) IsMonospace ¶
IsMonospace reports whether the face's glyphs are fixed-width (its post table's flag), what a monospace filter asks.
func (*Typeface) Shape ¶
func (t *Typeface) Shape(s string, px float64) *ShapedText
Shape lays text out at the given pixel size, resolving the base direction from the text's first strong character. Results are served from the process-wide shaping cache: the second Shape of the same (face, size, string) is a map hit returning the identical ShapedText, so per-frame re-shapes - Entry's selection band, text, and caret, or a per-event click mapping - cost a lookup.
func (*Typeface) ShapeDir ¶
ShapeDir lays text out under base direction d; see Shape and text.Direction.
func (*Typeface) ShapeRune ¶
func (t *Typeface) ShapeRune(r rune, px float64) *ShapedText
ShapeRune shapes one rune; see Font.ShapeRune. Identical result to Shape(string(r)) - the fill goes through the same uncached path - but the cache keys on the rune, so per-rune probes (wrap measurement walks one rune at a time) stay allocation-free in the steady state.
func (*Typeface) Spaced ¶
Spaced returns the face shaping with px of letter spacing after every cluster (CSS letter-spacing): the advances themselves carry it, so measuring, caret placement, and painting agree. Memoized; zero returns the face itself.
func (*Typeface) Tabular ¶
Tabular returns the face shaping with the tnum OpenType feature on: digits on a uniform advance grid, what a clock or a numeric column wants. Memoized; the twin shares nothing the lazy caches fill, so the two entries never contend.
func (*Typeface) Variations ¶
Variations reports the settings this face was instantiated at; nil for a face at its default instance.
func (*Typeface) Weighted ¶
Weighted is the face at CSS weight w along its wght axis - a variable family's real weight rather than its default instance; a face without the axis returns itself.
func (*Typeface) WithVariations ¶
WithVariations returns the face instantiated at vs (CSS font-variation-settings, a named instance's coordinates): axes the font lacks are ignored, values clamp to each axis's range, and unnamed axes keep their defaults - settings apply over the default instance, not over t's own. A face with none of the axes, or empty vs, returns the default face. Instances are memoized per setting.
func (*Typeface) Wrap ¶
Wrap breaks text into lines of at most maxWidth pixels, filling greedily along Unicode UAX #14 break opportunities: each line takes as much as fits before the first opportunity that overflows. Breaks land where real typesetting puts them - at spaces, after hyphens, inside CJK runs - not only at ASCII spaces. A run with no break opportunity before the width, an unbreakable token, stays whole on its own line and overflows. Hard newlines split unconditionally; trailing spaces at a break and leading spaces of a continuation are dropped.
type Variation ¶
Variation is one setting of a variable font's design axis: an OpenType axis tag ("wght", "wdth", "slnt", "ital", "opsz", or a font's own) and a value in that axis's design units (wght 100-900).
func ParseVariations ¶
ParseVariations parses a CSS font-variation-settings value - "normal", or comma-separated quoted four-letter tags and numbers ("wght" 650, "wdth" 80).