Skip to main content

widgetkit_render/
surface.rs

1use crate::{Canvas, raw::{Frame, Rasterizer}};
2use widgetkit_core::{Color, Error, Result};
3
4pub trait RenderSurface {
5    fn size(&self) -> (u32, u32);
6    fn present(&mut self, pixels: &[Color]) -> Result<()>;
7}
8
9pub trait Renderer: Send {
10    fn render_canvas(&mut self, canvas: Canvas, surface: &mut dyn RenderSurface) -> Result<()>;
11}
12
13pub struct SoftwareRenderer {
14    pixels: Vec<Color>,
15}
16
17impl SoftwareRenderer {
18    pub fn new() -> Self {
19        Self { pixels: Vec::new() }
20    }
21
22    fn ensure_buffer(&mut self, width: u32, height: u32) -> Result<()> {
23        let len = usize::try_from(width)
24            .ok()
25            .and_then(|w| usize::try_from(height).ok().map(|h| w.saturating_mul(h)))
26            .ok_or_else(|| Error::render("surface dimensions exceed addressable memory"))?;
27        if self.pixels.len() != len {
28            self.pixels.resize(len, Color::TRANSPARENT);
29        }
30        Ok(())
31    }
32}
33
34impl Default for SoftwareRenderer {
35    fn default() -> Self {
36        Self::new()
37    }
38}
39
40impl Renderer for SoftwareRenderer {
41    fn render_canvas(&mut self, canvas: Canvas, surface: &mut dyn RenderSurface) -> Result<()> {
42        let (width, height) = surface.size();
43        self.ensure_buffer(width, height)?;
44        let scene = canvas.into_scene();
45        let frame = Frame::new(width, height, &mut self.pixels);
46        let mut raster = Rasterizer::new(frame);
47        raster.execute(scene);
48        drop(raster);
49        surface.present(&self.pixels)
50    }
51}