diff options
Diffstat (limited to '')
| -rw-r--r-- | renderer/src/compositor.rs | 80 | ||||
| -rw-r--r-- | renderer/src/geometry.rs | 24 | ||||
| -rw-r--r-- | renderer/src/geometry/cache.rs | 52 | ||||
| -rw-r--r-- | renderer/src/lib.rs | 248 | 
4 files changed, 356 insertions, 48 deletions
| diff --git a/renderer/src/compositor.rs b/renderer/src/compositor.rs index 57317b28..8b17a4b0 100644 --- a/renderer/src/compositor.rs +++ b/renderer/src/compositor.rs @@ -100,26 +100,28 @@ impl<Theme> crate::graphics::Compositor for Compositor<Theme> {          background_color: Color,          overlay: &[T],      ) -> Result<(), SurfaceError> { -        renderer.with_primitives(|backend, primitives| { -            match (self, backend, surface) { -                ( -                    Self::TinySkia(_compositor), -                    crate::Backend::TinySkia(backend), -                    Surface::TinySkia(surface), -                ) => iced_tiny_skia::window::compositor::present( +        match (self, renderer, surface) { +            ( +                Self::TinySkia(_compositor), +                crate::Renderer::TinySkia(renderer), +                Surface::TinySkia(surface), +            ) => renderer.with_primitives(|backend, primitives| { +                iced_tiny_skia::window::compositor::present(                      backend,                      surface,                      primitives,                      viewport,                      background_color,                      overlay, -                ), -                #[cfg(feature = "wgpu")] -                ( -                    Self::Wgpu(compositor), -                    crate::Backend::Wgpu(backend), -                    Surface::Wgpu(surface), -                ) => iced_wgpu::window::compositor::present( +                ) +            }), +            #[cfg(feature = "wgpu")] +            ( +                Self::Wgpu(compositor), +                crate::Renderer::Wgpu(renderer), +                Surface::Wgpu(surface), +            ) => renderer.with_primitives(|backend, primitives| { +                iced_wgpu::window::compositor::present(                      compositor,                      backend,                      surface, @@ -127,14 +129,14 @@ impl<Theme> crate::graphics::Compositor for Compositor<Theme> {                      viewport,                      background_color,                      overlay, -                ), -                #[allow(unreachable_patterns)] -                _ => panic!( -                    "The provided renderer or surface are not compatible \ +                ) +            }), +            #[allow(unreachable_patterns)] +            _ => panic!( +                "The provided renderer or surface are not compatible \                      with the compositor." -                ), -            } -        }) +            ), +        }      }      fn screenshot<T: AsRef<str>>( @@ -145,12 +147,27 @@ impl<Theme> crate::graphics::Compositor for Compositor<Theme> {          background_color: Color,          overlay: &[T],      ) -> Vec<u8> { -        renderer.with_primitives(|backend, primitives| match (self, backend, surface) { -            (Self::TinySkia(_compositor), crate::Backend::TinySkia(backend), Surface::TinySkia(surface)) => { -                iced_tiny_skia::window::compositor::screenshot(surface, backend, primitives, viewport, background_color, overlay) -            }, +        match (self, renderer, surface) { +            ( +                Self::TinySkia(_compositor), +                Renderer::TinySkia(renderer), +                Surface::TinySkia(surface), +            ) => renderer.with_primitives(|backend, primitives| { +                iced_tiny_skia::window::compositor::screenshot( +                    surface, +                    backend, +                    primitives, +                    viewport, +                    background_color, +                    overlay, +                ) +            }),              #[cfg(feature = "wgpu")] -            (Self::Wgpu(compositor), crate::Backend::Wgpu(backend), Surface::Wgpu(_)) => { +            ( +                Self::Wgpu(compositor), +                Renderer::Wgpu(renderer), +                Surface::Wgpu(_), +            ) => renderer.with_primitives(|backend, primitives| {                  iced_wgpu::window::compositor::screenshot(                      compositor,                      backend, @@ -159,12 +176,13 @@ impl<Theme> crate::graphics::Compositor for Compositor<Theme> {                      background_color,                      overlay,                  ) -            }, +            }),              #[allow(unreachable_patterns)]              _ => panic!( -                "The provided renderer or backend are not compatible with the compositor." +                "The provided renderer or backend are not compatible \ +                with the compositor."              ), -        }) +        }      }  } @@ -215,7 +233,7 @@ impl Candidate {                  Ok((                      Compositor::TinySkia(compositor), -                    Renderer::new(crate::Backend::TinySkia(backend)), +                    Renderer::TinySkia(iced_tiny_skia::Renderer::new(backend)),                  ))              }              #[cfg(feature = "wgpu")] @@ -232,7 +250,7 @@ impl Candidate {                  Ok((                      Compositor::Wgpu(compositor), -                    Renderer::new(crate::Backend::Wgpu(backend)), +                    Renderer::Wgpu(iced_wgpu::Renderer::new(backend)),                  ))              }              #[cfg(not(feature = "wgpu"))] diff --git a/renderer/src/geometry.rs b/renderer/src/geometry.rs index 26e2fed0..04b5d9e6 100644 --- a/renderer/src/geometry.rs +++ b/renderer/src/geometry.rs @@ -3,8 +3,8 @@ mod cache;  pub use cache::Cache;  use crate::core::{Point, Rectangle, Size, Vector}; -use crate::graphics::geometry::{Fill, Geometry, Path, Stroke, Text}; -use crate::Backend; +use crate::graphics::geometry::{Fill, Path, Stroke, Text}; +use crate::Renderer;  pub enum Frame {      TinySkia(iced_tiny_skia::geometry::Frame), @@ -12,6 +12,12 @@ pub enum Frame {      Wgpu(iced_wgpu::geometry::Frame),  } +pub enum Geometry { +    TinySkia(iced_tiny_skia::Primitive), +    #[cfg(feature = "wgpu")] +    Wgpu(iced_wgpu::Primitive), +} +  macro_rules! delegate {      ($frame:expr, $name:ident, $body:expr) => {          match $frame { @@ -23,13 +29,13 @@ macro_rules! delegate {  }  impl Frame { -    pub fn new<Theme>(renderer: &crate::Renderer<Theme>, size: Size) -> Self { -        match renderer.backend() { -            Backend::TinySkia(_) => { +    pub fn new<Theme>(renderer: &Renderer<Theme>, size: Size) -> Self { +        match renderer { +            Renderer::TinySkia(_) => {                  Frame::TinySkia(iced_tiny_skia::geometry::Frame::new(size))              }              #[cfg(feature = "wgpu")] -            Backend::Wgpu(_) => { +            Renderer::Wgpu(_) => {                  Frame::Wgpu(iced_wgpu::geometry::Frame::new(size))              }          } @@ -169,6 +175,10 @@ impl Frame {      }      pub fn into_geometry(self) -> Geometry { -        Geometry(delegate!(self, frame, frame.into_primitive())) +        match self { +            Self::TinySkia(frame) => Geometry::TinySkia(frame.into_primitive()), +            #[cfg(feature = "wgpu")] +            Self::Wgpu(frame) => Geometry::Wgpu(frame.into_primitive()), +        }      }  } diff --git a/renderer/src/geometry/cache.rs b/renderer/src/geometry/cache.rs index 2a3534d0..d82e7f69 100644 --- a/renderer/src/geometry/cache.rs +++ b/renderer/src/geometry/cache.rs @@ -1,6 +1,5 @@  use crate::core::Size;  use crate::geometry::{Frame, Geometry}; -use crate::graphics::Primitive;  use crate::Renderer;  use std::cell::RefCell; @@ -21,10 +20,17 @@ enum State {      Empty,      Filled {          bounds: Size, -        primitive: Arc<Primitive>, +        primitive: Internal,      },  } +#[derive(Debug, Clone)] +enum Internal { +    TinySkia(Arc<iced_tiny_skia::Primitive>), +    #[cfg(feature = "wgpu")] +    Wgpu(Arc<iced_wgpu::Primitive>), +} +  impl Cache {      /// Creates a new empty [`Cache`].      pub fn new() -> Self { @@ -62,9 +68,21 @@ impl Cache {          } = self.state.borrow().deref()          {              if *cached_bounds == bounds { -                return Geometry(Primitive::Cache { -                    content: primitive.clone(), -                }); +                match primitive { +                    Internal::TinySkia(primitive) => { +                        return Geometry::TinySkia( +                            iced_tiny_skia::Primitive::Cache { +                                content: primitive.clone(), +                            }, +                        ); +                    } +                    #[cfg(feature = "wgpu")] +                    Internal::Wgpu(primitive) => { +                        return Geometry::Wgpu(iced_wgpu::Primitive::Cache { +                            content: primitive.clone(), +                        }); +                    } +                }              }          } @@ -74,7 +92,15 @@ impl Cache {          let primitive = {              let geometry = frame.into_geometry(); -            Arc::new(geometry.0) +            match geometry { +                Geometry::TinySkia(primitive) => { +                    Internal::TinySkia(Arc::new(primitive)) +                } +                #[cfg(feature = "wgpu")] +                Geometry::Wgpu(primitive) => { +                    Internal::Wgpu(Arc::new(primitive)) +                } +            }          };          *self.state.borrow_mut() = State::Filled { @@ -82,6 +108,18 @@ impl Cache {              primitive: primitive.clone(),          }; -        Geometry(Primitive::Cache { content: primitive }) +        match primitive { +            Internal::TinySkia(primitive) => { +                Geometry::TinySkia(iced_tiny_skia::Primitive::Cache { +                    content: primitive, +                }) +            } +            #[cfg(feature = "wgpu")] +            Internal::Wgpu(primitive) => { +                Geometry::Wgpu(iced_wgpu::Primitive::Cache { +                    content: primitive, +                }) +            } +        }      }  } diff --git a/renderer/src/lib.rs b/renderer/src/lib.rs index 22ec7bd1..89b8f4c6 100644 --- a/renderer/src/lib.rs +++ b/renderer/src/lib.rs @@ -3,17 +3,259 @@ pub mod compositor;  #[cfg(feature = "geometry")]  pub mod geometry; -mod backend;  mod settings;  pub use iced_graphics as graphics;  pub use iced_graphics::core; -pub use backend::Backend;  pub use compositor::Compositor;  pub use settings::Settings; +#[cfg(feature = "geometry")] +pub use geometry::Geometry; + +use crate::core::renderer; +use crate::core::text::{self, Text}; +use crate::core::{Background, Font, Point, Rectangle, Size, Vector}; + +use std::borrow::Cow; +  /// The default graphics renderer for [`iced`].  ///  /// [`iced`]: https://github.com/iced-rs/iced -pub type Renderer<Theme> = iced_graphics::Renderer<Backend, Theme>; +pub enum Renderer<Theme> { +    TinySkia(iced_tiny_skia::Renderer<Theme>), +    #[cfg(feature = "wgpu")] +    Wgpu(iced_wgpu::Renderer<Theme>), +} + +macro_rules! delegate { +    ($renderer:expr, $name:ident, $body:expr) => { +        match $renderer { +            Self::TinySkia($name) => $body, +            #[cfg(feature = "wgpu")] +            Self::Wgpu($name) => $body, +        } +    }; +} + +impl<T> Renderer<T> { +    #[cfg(feature = "wgpu")] +    pub fn draw_with_wgpu(&mut self, primitive: iced_wgpu::Primitive) { +        if let Self::Wgpu(renderer) = self { +            renderer.draw_primitive(primitive); +        } +    } +} + +impl<T> core::Renderer for Renderer<T> { +    type Theme = T; + +    fn with_layer(&mut self, bounds: Rectangle, f: impl FnOnce(&mut Self)) { +        match self { +            Self::TinySkia(renderer) => { +                let primitives = renderer.start_layer(); + +                f(self); + +                match self { +                    Self::TinySkia(renderer) => { +                        renderer.end_layer(primitives, bounds); +                    } +                    #[cfg(feature = "wgpu")] +                    _ => unreachable!(), +                } +            } +            #[cfg(feature = "wgpu")] +            Self::Wgpu(renderer) => { +                let primitives = renderer.start_layer(); + +                f(self); + +                match self { +                    #[cfg(feature = "wgpu")] +                    Self::Wgpu(renderer) => { +                        renderer.end_layer(primitives, bounds); +                    } +                    _ => unreachable!(), +                } +            } +        } +    } + +    fn with_translation( +        &mut self, +        translation: Vector, +        f: impl FnOnce(&mut Self), +    ) { +        match self { +            Self::TinySkia(renderer) => { +                let primitives = renderer.start_translation(); + +                f(self); + +                match self { +                    Self::TinySkia(renderer) => { +                        renderer.end_translation(primitives, translation); +                    } +                    #[cfg(feature = "wgpu")] +                    _ => unreachable!(), +                } +            } +            #[cfg(feature = "wgpu")] +            Self::Wgpu(renderer) => { +                let primitives = renderer.start_translation(); + +                f(self); + +                match self { +                    #[cfg(feature = "wgpu")] +                    Self::Wgpu(renderer) => { +                        renderer.end_translation(primitives, translation); +                    } +                    _ => unreachable!(), +                } +            } +        } +    } + +    fn fill_quad( +        &mut self, +        quad: renderer::Quad, +        background: impl Into<Background>, +    ) { +        delegate!(self, renderer, renderer.fill_quad(quad, background)); +    } + +    fn clear(&mut self) { +        delegate!(self, renderer, renderer.clear()); +    } +} + +impl<T> text::Renderer for Renderer<T> { +    type Font = Font; + +    const ICON_FONT: Font = iced_tiny_skia::Renderer::<T>::ICON_FONT; +    const CHECKMARK_ICON: char = iced_tiny_skia::Renderer::<T>::CHECKMARK_ICON; +    const ARROW_DOWN_ICON: char = +        iced_tiny_skia::Renderer::<T>::ARROW_DOWN_ICON; + +    fn default_font(&self) -> Self::Font { +        delegate!(self, renderer, renderer.default_font()) +    } + +    fn default_size(&self) -> f32 { +        delegate!(self, renderer, renderer.default_size()) +    } + +    fn measure( +        &self, +        content: &str, +        size: f32, +        line_height: text::LineHeight, +        font: Font, +        bounds: Size, +        shaping: text::Shaping, +    ) -> Size { +        delegate!( +            self, +            renderer, +            renderer.measure(content, size, line_height, font, bounds, shaping) +        ) +    } + +    fn hit_test( +        &self, +        content: &str, +        size: f32, +        line_height: text::LineHeight, +        font: Font, +        bounds: Size, +        shaping: text::Shaping, +        point: Point, +        nearest_only: bool, +    ) -> Option<text::Hit> { +        delegate!( +            self, +            renderer, +            renderer.hit_test( +                content, +                size, +                line_height, +                font, +                bounds, +                shaping, +                point, +                nearest_only +            ) +        ) +    } + +    fn load_font(&mut self, bytes: Cow<'static, [u8]>) { +        delegate!(self, renderer, renderer.load_font(bytes)); +    } + +    fn fill_text(&mut self, text: Text<'_, Self::Font>) { +        delegate!(self, renderer, renderer.fill_text(text)); +    } +} + +#[cfg(feature = "image")] +impl<T> crate::core::image::Renderer for Renderer<T> { +    type Handle = crate::core::image::Handle; + +    fn dimensions(&self, handle: &crate::core::image::Handle) -> Size<u32> { +        delegate!(self, renderer, renderer.dimensions(handle)) +    } + +    fn draw(&mut self, handle: crate::core::image::Handle, bounds: Rectangle) { +        delegate!(self, renderer, renderer.draw(handle, bounds)); +    } +} + +#[cfg(feature = "svg")] +impl<T> crate::core::svg::Renderer for Renderer<T> { +    fn dimensions(&self, handle: &crate::core::svg::Handle) -> Size<u32> { +        delegate!(self, renderer, renderer.dimensions(handle)) +    } + +    fn draw( +        &mut self, +        handle: crate::core::svg::Handle, +        color: Option<crate::core::Color>, +        bounds: Rectangle, +    ) { +        delegate!(self, renderer, renderer.draw(handle, color, bounds)) +    } +} + +#[cfg(feature = "geometry")] +impl<T> crate::graphics::geometry::Renderer for Renderer<T> { +    type Geometry = crate::Geometry; + +    fn draw(&mut self, layers: Vec<Self::Geometry>) { +        match self { +            Self::TinySkia(renderer) => { +                for layer in layers { +                    match layer { +                        crate::Geometry::TinySkia(primitive) => { +                            renderer.draw_primitive(primitive); +                        } +                        _ => unreachable!(), +                    } +                } +            } +            #[cfg(feature = "wgpu")] +            Self::Wgpu(renderer) => { +                for layer in layers { +                    match layer { +                        crate::Geometry::Wgpu(primitive) => { +                            renderer.draw_primitive(primitive); +                        } +                        _ => unreachable!(), +                    } +                } +            } +        } +    } +} | 
