Custom surfaces
Draw the widget tree with something other than Skia.
Layout, hit-testing, animation and reconciliation don't depend on a renderer. Only painting goes through a trait:
pub trait Surface {
fn draw(&mut self, ui: &mut UI);
}
A surface walks the laid-out tree and paints through a RenderContext, which has primitives such as fill_rect, fill_corners_rect, draw_border and draw_image. All coordinates are logical, before DPI scaling, and the backend applies its own scale.
The Skia backend in the crate is the reference implementation. Read it alongside this page.
Host-painted canvases
To paint part of the UI yourself, such as a game viewport or a waveform, place a Canvas widget in the document. It takes part in layout like any other widget, and your code paints its rectangle.
TODO: a worked example of a minimal non-Skia surface.