Expand description
valo-text — typographer + paragraph layout, no GPU. The pipeline: style spans → per-character font fallback → bidi levels → harfrust shaping (endless line) → greedy wrapping with UAX #14 opportunities → per-line UAX #9 visual reorder → placed glyph runs. Glyph raster (swash alpha masks, SDF distance fields, skrifa outline paths) also lives here — CPU-only; the renderer’s atlas calls in.
Structs§
- Decoration
- An underline / strike-through / overline, drawn from the font’s own decoration metrics (post/OS2 tables; skparagraph’s Decorations.cpp).
- FaceSet
- The host’s registered fonts: families for styles to name, plus a global
fallback chain consulted per character. Immutable once built —
register everything, then
Arcit for builders and the renderer. - Font
- Font
Attrs - One registered font: immutable bytes + the metrics every layout needs. Shaping (harfrust), outlines (skrifa), and raster (swash) all re-read the same bytes — no parsed state is shared across those seams. A variant’s place in its family — CSS-style matching picks by these.
- Font
Collection - Faces plus the sources that can find more — Skia’s
FontCollection(skparagraph FontCollection.h: the asset/dynamic/defaultSkFontMgrs live INSIDE the collection, andfindTypefaces/defaultFallbackare its methods). Shaping consults this at every miss; what no source can answer accumulates as thedemanda host fetches asynchronously (Flutter web’s_unprocessedCodePoints). - Font
Demand - What shaping could not resolve — the host’s font-loading demand signal
(Flutter web’s missing-font detection reshaped as an API).
families: requested names the collection has NO face for at all.codepoints: chars NO present face covers, each with the attrs of the span that wanted it — a bold span’s missing glyph should be answered with a bold face (for subset-chunk families this doubles as “which chunk is missing”). valo detects; the host owns the loading policy — Google, a mirror, bundled files, the OS, anything. - FontId
- Index into a
FontCollection— stable for the collection’s lifetime. - Glyph
Image - A rasterized glyph: A8 coverage (or normalized distance for SDF), plus
the placement of the bitmap’s top-left relative to the glyph origin
(
leftright of origin,topabove the baseline — swash conventions). - Glyph
Stroke - The stroke a glyph raster can carry:
valo_geometry::Strokewithout its dashes, which a fixed-size atlas key has nowhere to put. Impeller’sStrokeParameterscarries the same four fields for the same reason.widthis in the raster’s own pixels, likepx. - Line
- Line
Metrics - Per-line metrics for caret/selection UIs (skparagraph’s LineMetrics).
- Paragraph
- The retained paragraph, with Skia’s state tiers made explicit (SkParagraph’s kShaped/kWrapped/kFormatted ladder):
- Paragraph
Builder - Collects styled spans;
build()runs fallback segmentation + shaping once and hands back the retainedParagraph. - Paragraph
Style - Paragraph-level knobs, fixed at
build(Flutter’s ParagraphStyle). - Placed
Glyph - One positioned glyph:
x/yin paragraph-local px,yon the baseline. - Placed
Run - A line’s worth of one font+size+color — exactly what one
GlyphRundisplay-list op carries. - Position
With Affinity - A byte offset plus which side of it the position leans (SkParagraph’s
PositionWithAffinity):
downstream= the caret belongs to the glyph AFTER the offset. - Rasterizer
- CPU glyph rasterization, on swash. One per renderer — swash’s context caches scaling state, and the stroker its segment buffers.
- Shadow
- One text shadow: an offset, optionally blurred copy in
color. - Text
Style - How one span of text looks (skparagraph’s TextStyle, the subset valo implements).
Families are tried in order per character (then the collection’s fallback
chain);
weight/italicpick within a family’s variants.
Enums§
- Decoration
Kind - Text
Align - Paragraph-level horizontal alignment (needs a finite layout width).
- Text
Direction - Which way the paragraph reads before its content gets a say.
- Variant
Caps - CSS
font-variant-caps, lowered to the OpenType features a shaper understands. Every variant here is a font capability: a face without the feature renders unchanged rather than synthesizing small capitals, which is what browsers do forfont-synthesis: noneand what valo always does.
Constants§
- SDF_PAD
- SDF spread in texels: distance saturates ±this many pixels from the edge (0.5 = on the edge). Also the raster padding so the field has room.
Traits§
- Font
Source - Somewhere fonts can come FROM when the collection lacks them — the
pluggable half of the demand loop. Implementations only
locate and parse (an installed-fonts scan today; a platform-native
CoreText/DirectWrite lookup can replace it without touching policy);
the growth policy itself lives in
FaceSet::grown_by.
Functions§
- glyph_
path - The glyph as a valo
Pathatpx, baseline-origin, y-down — the huge- text tier: stencil-then-cover handles it like any shape.
Type Aliases§
- Font
Data - Font file bytes however the host owns them: an owned buffer, or a memory-mapped file from a system-font source — faces only ever read.