Documentation
¶
Overview ¶
Package paint rasterises a laid-out box tree onto an *image.RGBA using go-opentype for anti-aliased text, go-widgets/painter for backgrounds and go-gfx-decoded bitmaps for <img>. It also provides the Measurer the layout package needs (advances + vertical metrics from real font faces).
Index ¶
- func FontFamilyOf(g css.Generic) css.FontFamily
- func Paint(dst *image.RGBA, box *layout.Box, f *Fonts, imgs map[*dom.Node]image.Image)
- func PaintFull(dst *image.RGBA, box *layout.Box, f *Fonts, imgs map[*dom.Node]image.Image, ...)
- type Fonts
- func (f *Fonts) Measure(text string, fam css.FontFamily, sizePx float64, weight int, italic bool) float64
- func (f *Fonts) Metrics(fam css.FontFamily, sizePx float64, weight int, italic bool) (ascent, lineHeight float64)
- func (f *Fonts) Register(family string, weight int, italic bool, sfnt []byte) error
- func (f *Fonts) RegisterFont(family string, weight int, italic bool, ft *opentype.Font) error
- func (f *Fonts) Registered(family string) bool
- func (f *Fonts) Runs(s string, fam css.FontFamily, weight int, italic bool) []Run
- type Run
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func FontFamilyOf ¶ added in v0.4.0
func FontFamilyOf(g css.Generic) css.FontFamily
FontFamilyOf is the bare generic bucket as a FontFamily — the key the bundled families are registered under.
func Paint ¶
Paint draws the box tree onto dst. imgs supplies decoded <img> bitmaps keyed by node (already scaled to the layout size); a missing entry is skipped. The caller owns clearing dst to its base (e.g. white) beforehand. It is equivalent to PaintFull with no background-image bitmaps.
func PaintFull ¶
func PaintFull(dst *image.RGBA, box *layout.Box, f *Fonts, imgs map[*dom.Node]image.Image, bgImgs map[string]image.Image)
PaintFull draws the box tree onto dst, additionally painting CSS background-image layers (gradients and url() bitmaps). bgImgs supplies decoded background bitmaps keyed by their raw url() token; gradients need no bitmap.
Types ¶
type Fonts ¶
type Fonts struct {
// contains filtered or unexported fields
}
Fonts is a registry of parsed font families (per family × bold × italic) with a per-size Face cache. It is not safe for concurrent use (Faces cache glyphs); build one per render.
func NewFonts ¶
func NewFonts() *Fonts
NewFonts parses the bundled families in all four styles: sans = Inter, serif = Lora (both with real Bold/Italic/BoldItalic), mono = Go Mono (Regular only — bold/italic fall back to it, as the family ships no other styles). It panics only if a bundled font fails to parse, which would be a build-time defect in the fonts module, not a runtime condition.
The bundled files are parsed once per process and the parsed fonts shared by every Fonts: an *opentype.Font is read-only once parsed (a Face, which caches glyphs, is what is per-registry). Parsing them per registry — once per render — was most of the time and allocation of rendering a small page.
func (*Fonts) Measure ¶
func (f *Fonts) Measure(text string, fam css.FontFamily, sizePx float64, weight int, italic bool) float64
Measure returns the advance width of text in CSS px at the exact size asked: the shaped glyphs' advances in font units scaled to sizePx, unrounded, for the family's face and for the fallback face on the runs that need it (see Runs). The raster painter still draws with a face at the nearest whole-pixel size and whole-pixel advances, so its glyphs sit on the pixel grid; layout, though, measures the truth — a consumer that draws at the true size (a PDF) then finds the words where the layout put them. Before this, a 14.4 px bold word was measured with a 14 px face, 2.8 % short, and printed at 14.4 px it ran into the space after it.
Shaping (see requiredLigatureFeature) runs per Run, after Runs has already split the text by cmap coverage: a ligature never spans a fallback-font boundary, matching how a real text shaper only ever merges glyphs within one already-selected face.
func (*Fonts) Metrics ¶
func (f *Fonts) Metrics(fam css.FontFamily, sizePx float64, weight int, italic bool) (ascent, lineHeight float64)
Metrics implements layout.Measurer: ascent and line height.
func (*Fonts) Register ¶ added in v0.4.0
Register adds a face a document's own @font-face rule brought, parsed from SFNT bytes, under family (matched case-insensitively against the names a `font-family` declaration gives) at the weight and slant the rule declared.
The slot it occupies is the one the layout will ask for: bold is weight >= 600, the same threshold styleFace applies to a CSS weight, so a 600 and a 700 face compete for one slot and the one nearer 700 keeps it. Registering invalidates the face cache, since a cached Face was built from whichever font answered before.
func (*Fonts) RegisterFont ¶ added in v0.8.0
RegisterFont is Register for a font already parsed, which a caller that parsed it to validate it, or keeps parsed fonts across renders, passes instead of the bytes. The font is only read, never modified, so one *opentype.Font may be registered with any number of registries, concurrently.
func (*Fonts) Registered ¶ added in v0.4.0
Registered reports whether any face has been registered for a family.
func (*Fonts) Runs ¶ added in v0.4.0
Runs splits s into the runs the family's face and the fallback face set between them: a character goes to the fallback exactly when the family has no glyph for it and the fallback has; one neither covers stays with the family. A space or other whitespace joins whichever run it is in, so "① ②" is one fallback run rather than three. Measure and the painter walk these runs, and a consumer that sets the same text elsewhere (a PDF exporter embedding both fonts) must walk them too, so its glyphs come from the faces the layout measured with.