Expand description
The renderer boundary: a flat list of quads in physical pixels.
A backend needs exactly two abilities: draw these quads, and mirror the
glyph atlas to a texture. Everything else (layout, shaping, styling)
happened already. Core::output hands out the
finished frame’s DisplayList together with the window’s
GlyphAtlas.
Consuming one frame:
use kui_core::{Color, Core, NodeSpec, QuadKind, Size};
let mut core = Core::new();
let mut ui = core.frame(Size::new(200.0, 100.0), 2.0);
ui.leaf(NodeSpec::row().size(50.0, 20.0).bg(Color::WHITE));
ui.finish();
let (list, atlas) = core.output();
if atlas.dirty {
// Upload `atlas.pixels` (RGBA, `atlas.size` square). When
// `atlas.epoch` moved, the page was replaced: re-create the texture.
atlas.dirty = false;
}
for quad in &list.quads {
let clip = list.clip_of(quad); // physical px, like `quad.rect`
match quad.kind {
QuadKind::Solid => { /* rounded rect, optional border */ }
QuadKind::GlyphMask | QuadKind::GlyphColor | QuadKind::GlyphSubpixel => {
/* sample the atlas at the texel rect in `quad.uv` */
}
_ => { /* see each variant's doc */ }
}
let _ = clip;
}
assert_eq!(list.scale, 2.0);
// 50 logical px at scale 2.
assert!(list.quads.iter().any(|q| q.kind == QuadKind::Solid && q.rect.w == 100.0));Quads are in paint order. Every quad names an entry of
DisplayList::clips; a QuadKind::Fragment or
QuadKind::Texture quad also names an entry of
DisplayList::fragments or DisplayList::textures through
uv[0], and the list carries what a backend needs to compile or upload
those the first time it meets them.
Structs§
- Clip
- The clip a node inherits: a rect, and the radii to round its corners by.
- Display
List - Fragment
Draw - What a
QuadKind::Fragmentquad points at: which registered WGSL paints it, and the sixteen numbers that frame passes it. - Quad
- Texture
Draw - What a
QuadKind::Texturequad points at: which registered image, and the texel rect of it to show (the whole image, or the crop afit="cover"made). Beside the quads for the reasonFragmentDrawis: a handle and a rect on every quad would be paid by the 20,000 that are not one. A frame that draws no texture-backed image leaves the vector empty. - Texture
Pixels - A texture-backed image’s pixels as a frame hands them to a backend;
see
DisplayList::texture_pixels.
Enums§
- Fragment
Image - Where a fragment’s
imagerow lands for one frame: nowhere, in the glyph atlas the fragment pipeline already has bound, or in a texture of the image’s own that the backend binds in the atlas’s place for that one quad — the same swap aQuadKind::Texturequad asks for. The core decides between the last two on the image’s backing, so a backend meets the same two cases it already draws. - Quad
Kind
Constants§
- NO_CLIP
- A clip that clips nothing.
- NO_
CLIP_ ID - The entry every frame’s clip table starts with:
Clip::NONEin physical pixels. Emission seeds it before any quad is made, so a quad that is clipped by nothing — most quads of most frames — names this without interning anything. - SQUARE
- Radii that round nothing.
Functions§
- intern_
clip - Interns a clip into a frame’s table and returns the index a quad names.
Type Aliases§
- ClipId
- An index into
DisplayList::clips. Every quad has one; there is no “no clip” value, because a frame that clips nothing still names an entry —Clip::NONEscaled — and a backend that reads it needs no special case.