Embedder primitives: placed-child clipping, offscreen RGBA readback, standalone text measurement
Three additions an embedder needs to drive ltk as the render backend for a retained, externally-owned widget tree, each kept general rather than tied to one consumer. Stack placed-child clipping. `Stack::push_placed_clipped(e, rect, clip)` places a child at an exact rect like `push_placed` but clips its subtree's drawing to `clip` (in the Stack's coordinate space) — Android's clipChildren: content that overflows, such as a scrolled list row reaching above the list or an inner card past a rounded bubble, is not painted. The Stack child tuple grows an 8th `Option<Rect>` for the clip, and `layout_and_draw` brackets a clipped child with `set_clip_rects`/restore around the recursion. The clip is shifted by the Stack's own origin to match the placed rect (which `Stack::layout` already offsets), so a Stack laid out at a non-zero origin clips in the right place rather than off by that origin. Offscreen RGBA readback. `Canvas::read_rgba_pixels(out)` reads any canvas into tightly packed straight-alpha RGBA8, top-left row first. Unlike `read_gles_rgba_pixels` it also serves the software backend, un-premultiplying its pixmap, so an offscreen software canvas (an embedder's scratch bitmap) can be read back into a straight-alpha buffer. `Canvas::is_software()` lets a caller branch on the backend — e.g. to honour a real path clip on software but only a bounding rect on GLES. Standalone text measurement. `measure_text(text, size)`, re-exported at the crate root, measures one line with the default UI font and the system fallback chain, returning `(width, line_height)` in pixels without a live `Canvas` — for an embedder's measure pass that must produce the same metrics the renderer will later use. It is backed by `system_fonts::primary_handle()`, a process-wide cached handle for the primary UI font (the same default a canvas loads, with the bundled-font fallback), which widens `render::helpers::load_default_font_bytes` to `pub(crate)`.
This commit is contained in:
+18
-1
@@ -53,7 +53,24 @@ pub( crate ) fn layout_and_draw<Msg: Clone>(
|
||||
let mut idx = flat_idx;
|
||||
for ( child_rect, child_i ) in child_rects
|
||||
{
|
||||
idx = layout_and_draw::<Msg>( &s.children[ child_i ].0, canvas, child_rect, ctx, idx );
|
||||
let child = &s.children[ child_i ];
|
||||
// A placed child may carry a clip rect (Android clipChildren): clip the
|
||||
// canvas to it for the child's subtree, then restore the prior clip.
|
||||
// The clip is in the Stack's coordinate space (like the placed rect),
|
||||
// so it is shifted by the Stack's origin to match — otherwise a Stack
|
||||
// laid out at a non-zero origin clips in the wrong place.
|
||||
if let Some( clip ) = child.7
|
||||
{
|
||||
let saved = canvas.clip_bounds();
|
||||
let clip = Rect { x: rect.x + clip.x, y: rect.y + clip.y, width: clip.width, height: clip.height };
|
||||
canvas.set_clip_rects( &[ clip ] );
|
||||
idx = layout_and_draw::<Msg>( &child.0, canvas, child_rect, ctx, idx );
|
||||
canvas.set_clip_rects( &saved );
|
||||
}
|
||||
else
|
||||
{
|
||||
idx = layout_and_draw::<Msg>( &child.0, canvas, child_rect, ctx, idx );
|
||||
}
|
||||
}
|
||||
idx
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user