# 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:

```rust
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.
