diff options
Diffstat (limited to '')
| -rw-r--r-- | renderer/src/compositor.rs | 25 | ||||
| -rw-r--r-- | renderer/src/custom.rs | 164 | ||||
| -rw-r--r-- | renderer/src/geometry.rs | 33 | ||||
| -rw-r--r-- | renderer/src/geometry/cache.rs | 9 | ||||
| -rw-r--r-- | renderer/src/lib.rs | 74 | 
5 files changed, 289 insertions, 16 deletions
| diff --git a/renderer/src/compositor.rs b/renderer/src/compositor.rs index c23a814c..058fa36d 100644 --- a/renderer/src/compositor.rs +++ b/renderer/src/compositor.rs @@ -1,4 +1,5 @@  use crate::core::Color; +use crate::custom;  use crate::graphics::compositor::{Information, SurfaceError, Window};  use crate::graphics::{Error, Viewport};  use crate::{Renderer, Settings}; @@ -10,12 +11,14 @@ pub enum Compositor {      TinySkia(iced_tiny_skia::window::Compositor),      #[cfg(feature = "wgpu")]      Wgpu(iced_wgpu::window::Compositor), +    Custom(Box<dyn custom::Compositor>),  }  pub enum Surface {      TinySkia(iced_tiny_skia::window::Surface),      #[cfg(feature = "wgpu")]      Wgpu(iced_wgpu::window::Surface<'static>), +    Custom(Box<dyn custom::Surface>),  }  impl crate::graphics::Compositor for Compositor { @@ -56,6 +59,9 @@ impl crate::graphics::Compositor for Compositor {              Compositor::Wgpu(compositor) => {                  Renderer::Wgpu(compositor.create_renderer())              } +            Compositor::Custom(compositor) => { +                Renderer::Custom(compositor.create_renderer()) +            }          }      } @@ -73,6 +79,9 @@ impl crate::graphics::Compositor for Compositor {              Self::Wgpu(compositor) => {                  Surface::Wgpu(compositor.create_surface(window, width, height))              } +            Self::Custom(compositor) => Surface::Custom( +                compositor.create_surface(Box::new(window), width, height), +            ),          }      } @@ -90,6 +99,9 @@ impl crate::graphics::Compositor for Compositor {              (Self::Wgpu(compositor), Surface::Wgpu(surface)) => {                  compositor.configure_surface(surface, width, height);              } +            (Self::Custom(compositor), Surface::Custom(surface)) => { +                compositor.configure_surface(surface, width, height); +            }              #[allow(unreachable_patterns)]              _ => panic!(                  "The provided surface is not compatible with the compositor." @@ -102,6 +114,7 @@ impl crate::graphics::Compositor for Compositor {              Self::TinySkia(compositor) => compositor.fetch_information(),              #[cfg(feature = "wgpu")]              Self::Wgpu(compositor) => compositor.fetch_information(), +            Self::Custom(compositor) => compositor.fetch_information(),          }      } @@ -144,6 +157,18 @@ impl crate::graphics::Compositor for Compositor {                      overlay,                  )              }), + +            #[cfg(feature = "wgpu")] +            ( +                Self::Custom(compositor), +                crate::Renderer::Custom(renderer), +                Surface::Custom(surface), +            ) => renderer.present( +                surface.as_mut(), +                viewport, +                background_color, +                compositor.as_mut(), +            ),              #[allow(unreachable_patterns)]              _ => panic!(                  "The provided renderer or surface are not compatible \ diff --git a/renderer/src/custom.rs b/renderer/src/custom.rs new file mode 100644 index 00000000..680aa0b5 --- /dev/null +++ b/renderer/src/custom.rs @@ -0,0 +1,164 @@ +use crate::core::image; +use crate::core::renderer; +use crate::core::svg; +use crate::core::text::Text; +use crate::core::{ +    Background, Color, Font, Pixels, Point, Rectangle, Size, Transformation, +}; +use crate::graphics::compositor; +use crate::graphics::text::{Editor, Paragraph}; +use crate::graphics::{Mesh, Viewport}; + +#[cfg(feature = "geometry")] +use crate::graphics::geometry::{self, Fill, Path, Stroke}; + +use std::borrow::Cow; + +pub trait Renderer { +    fn draw_mesh(&mut self, mesh: Mesh); + +    fn start_layer(&mut self); + +    fn end_layer(&mut self, bounds: Rectangle); + +    fn start_transformation(&mut self); + +    fn end_transformation(&mut self, transformation: Transformation); + +    fn fill_quad(&mut self, quad: renderer::Quad, background: Background); + +    fn clear(&mut self); + +    fn default_font(&self) -> Font; + +    fn default_size(&self) -> Pixels; + +    fn load_font(&mut self, bytes: Cow<'static, [u8]>); + +    fn fill_paragraph( +        &mut self, +        paragraph: &Paragraph, +        position: Point, +        color: Color, +        clip_bounds: Rectangle, +    ); + +    fn fill_editor( +        &mut self, +        editor: &Editor, +        position: Point, +        color: Color, +        clip_bounds: Rectangle, +    ); + +    fn fill_text( +        &mut self, +        text: Text<'_, Font>, +        position: Point, +        color: Color, +        clip_bounds: Rectangle, +    ); + +    fn measure_image(&self, handle: &image::Handle) -> Size<u32>; + +    fn draw_image( +        &mut self, +        handle: image::Handle, +        filter_method: image::FilterMethod, +        bounds: Rectangle, +    ); + +    fn measure_svg(&self, handle: &svg::Handle) -> Size<u32>; + +    fn draw_svg( +        &mut self, +        handle: crate::core::svg::Handle, +        color: Option<crate::core::Color>, +        bounds: Rectangle, +    ); + +    #[cfg(feature = "geometry")] +    fn new_frame(&self, size: Size) -> Box<dyn Frame>; + +    #[cfg(feature = "geometry")] +    fn draw_geometry(&mut self, geometry: Box<dyn Geometry>); + +    fn present( +        &mut self, +        surface: &mut dyn Surface, +        viewport: &Viewport, +        background_color: Color, +        compositor: &mut dyn Compositor, +    ) -> Result<(), compositor::SurfaceError>; +} + +#[cfg(feature = "geometry")] +pub trait Frame: std::any::Any { +    fn new(&self, size: Size) -> Box<dyn Frame>; + +    fn width(&self) -> f32; + +    fn height(&self) -> f32; + +    fn size(&self) -> Size; + +    fn center(&self) -> Point; + +    fn fill(&mut self, path: &Path, fill: Fill); + +    fn fill_rectangle(&mut self, top_left: Point, size: Size, fill: Fill); + +    fn stroke<'a>(&mut self, path: &Path, stroke: Stroke<'a>); + +    fn fill_text(&mut self, text: geometry::Text); + +    fn translate(&mut self, translation: crate::core::Vector); + +    fn rotate(&mut self, angle: crate::core::Radians); + +    fn scale(&mut self, scale: f32); + +    fn scale_nonuniform(&mut self, scale: crate::core::Vector); + +    fn push_transform(&mut self); + +    fn pop_transform(&mut self); + +    fn clip(&mut self, frame: Box<dyn Frame>, origin: Point); + +    fn into_geometry(self: Box<Self>) -> Box<dyn Geometry>; +} + +#[cfg(feature = "geometry")] +pub trait Geometry: std::any::Any + std::fmt::Debug { +    fn transform( +        self: Box<Self>, +        transformation: Transformation, +    ) -> Box<dyn Geometry>; + +    fn cache(self: Box<Self>) -> std::sync::Arc<dyn Geometry>; + +    fn load(self: std::sync::Arc<Self>) -> Box<dyn Geometry>; +} + +pub trait Compositor: std::any::Any { +    fn create_renderer(&self) -> Box<dyn Renderer>; + +    fn create_surface( +        &mut self, +        window: Box<dyn compositor::Window>, +        width: u32, +        height: u32, +    ) -> Box<dyn Surface>; + +    fn configure_surface( +        &mut self, +        surface: &mut Box<dyn Surface>, +        width: u32, +        height: u32, +    ); + +    fn fetch_information(&self) -> compositor::Information; +} + +pub trait Surface: std::any::Any {} diff --git a/renderer/src/geometry.rs b/renderer/src/geometry.rs index 36435148..bf70c7fa 100644 --- a/renderer/src/geometry.rs +++ b/renderer/src/geometry.rs @@ -3,6 +3,7 @@ mod cache;  pub use cache::Cache;  use crate::core::{Point, Radians, Rectangle, Size, Transformation, Vector}; +use crate::custom;  use crate::graphics::geometry::{Fill, Path, Stroke, Text};  use crate::Renderer; @@ -12,6 +13,7 @@ macro_rules! delegate {              Self::TinySkia($name) => $body,              #[cfg(feature = "wgpu")]              Self::Wgpu($name) => $body, +            Self::Custom($name) => $body,          }      };  } @@ -20,6 +22,7 @@ pub enum Geometry {      TinySkia(iced_tiny_skia::Primitive),      #[cfg(feature = "wgpu")]      Wgpu(iced_wgpu::Primitive), +    Custom(Box<dyn custom::Geometry>),  }  impl Geometry { @@ -32,6 +35,9 @@ impl Geometry {              Self::Wgpu(primitive) => {                  Self::Wgpu(primitive.transform(transformation))              } +            Self::Custom(geometry) => { +                Self::Custom(geometry.transform(transformation)) +            }          }      }  } @@ -40,6 +46,7 @@ pub enum Frame {      TinySkia(iced_tiny_skia::geometry::Frame),      #[cfg(feature = "wgpu")]      Wgpu(iced_wgpu::geometry::Frame), +    Custom(Box<dyn custom::Frame>),  }  impl Frame { @@ -52,6 +59,9 @@ impl Frame {              Renderer::Wgpu(_) => {                  Frame::Wgpu(iced_wgpu::geometry::Frame::new(size))              } +            Renderer::Custom(renderer) => { +                Frame::Custom(renderer.new_frame(size)) +            }          }      } @@ -82,7 +92,7 @@ impl Frame {      /// Draws the given [`Path`] on the [`Frame`] by filling it with the      /// provided style.      pub fn fill(&mut self, path: &Path, fill: impl Into<Fill>) { -        delegate!(self, frame, frame.fill(path, fill)); +        delegate!(self, frame, frame.fill(path, fill.into()));      }      /// Draws an axis-aligned rectangle given its top-left corner coordinate and @@ -93,13 +103,17 @@ impl Frame {          size: Size,          fill: impl Into<Fill>,      ) { -        delegate!(self, frame, frame.fill_rectangle(top_left, size, fill)); +        delegate!( +            self, +            frame, +            frame.fill_rectangle(top_left, size, fill.into()) +        );      }      /// Draws the stroke of the given [`Path`] on the [`Frame`] with the      /// provided style.      pub fn stroke<'a>(&mut self, path: &Path, stroke: impl Into<Stroke<'a>>) { -        delegate!(self, frame, frame.stroke(path, stroke)); +        delegate!(self, frame, frame.stroke(path, stroke.into()));      }      /// Draws the characters of the given [`Text`] on the [`Frame`], filling @@ -116,7 +130,7 @@ impl Frame {      /// Support for vectorial text is planned, and should address all these      /// limitations.      pub fn fill_text(&mut self, text: impl Into<Text>) { -        delegate!(self, frame, frame.fill_text(text)); +        delegate!(self, frame, frame.fill_text(text.into()));      }      /// Stores the current transform of the [`Frame`] and executes the given @@ -155,6 +169,7 @@ impl Frame {              Self::Wgpu(_) => {                  Self::Wgpu(iced_wgpu::geometry::Frame::new(region.size()))              } +            Self::Custom(frame) => Self::Custom(frame.new(region.size())),          };          let result = f(&mut frame); @@ -169,6 +184,9 @@ impl Frame {              (Self::Wgpu(target), Self::Wgpu(frame)) => {                  target.clip(frame, origin);              } +            (Self::Custom(target), Self::Custom(frame)) => { +                target.clip(frame, origin); +            }              #[allow(unreachable_patterns)]              _ => unreachable!(),          }; @@ -185,19 +203,19 @@ impl Frame {      /// Applies a rotation in radians to the current transform of the [`Frame`].      #[inline]      pub fn rotate(&mut self, angle: impl Into<Radians>) { -        delegate!(self, frame, frame.rotate(angle)); +        delegate!(self, frame, frame.rotate(angle.into()));      }      /// Applies a uniform scaling to the current transform of the [`Frame`].      #[inline]      pub fn scale(&mut self, scale: impl Into<f32>) { -        delegate!(self, frame, frame.scale(scale)); +        delegate!(self, frame, frame.scale(scale.into()));      }      /// Applies a non-uniform scaling to the current transform of the [`Frame`].      #[inline]      pub fn scale_nonuniform(&mut self, scale: impl Into<Vector>) { -        delegate!(self, frame, frame.scale_nonuniform(scale)); +        delegate!(self, frame, frame.scale_nonuniform(scale.into()));      }      pub fn into_geometry(self) -> Geometry { @@ -205,6 +223,7 @@ impl Frame {              Self::TinySkia(frame) => Geometry::TinySkia(frame.into_primitive()),              #[cfg(feature = "wgpu")]              Self::Wgpu(frame) => Geometry::Wgpu(frame.into_primitive()), +            Self::Custom(frame) => Geometry::Custom(frame.into_geometry()),          }      }  } diff --git a/renderer/src/geometry/cache.rs b/renderer/src/geometry/cache.rs index 3aff76b9..6a43ddb6 100644 --- a/renderer/src/geometry/cache.rs +++ b/renderer/src/geometry/cache.rs @@ -1,4 +1,5 @@  use crate::core::Size; +use crate::custom;  use crate::geometry::{Frame, Geometry};  use crate::Renderer; @@ -29,6 +30,7 @@ enum Internal {      TinySkia(Arc<iced_tiny_skia::Primitive>),      #[cfg(feature = "wgpu")]      Wgpu(Arc<iced_wgpu::Primitive>), +    Custom(Arc<dyn custom::Geometry>),  }  impl Cache { @@ -82,6 +84,9 @@ impl Cache {                              content: primitive.clone(),                          });                      } +                    Internal::Custom(geometry) => { +                        return Geometry::Custom(geometry.clone().load()) +                    }                  }              }          } @@ -100,6 +105,9 @@ impl Cache {                  Geometry::Wgpu(primitive) => {                      Internal::Wgpu(Arc::new(primitive))                  } +                Geometry::Custom(geometry) => { +                    Internal::Custom(geometry.cache()) +                }              }          }; @@ -120,6 +128,7 @@ impl Cache {                      content: primitive,                  })              } +            Internal::Custom(geometry) => Geometry::Custom(geometry.load()),          }      }  } diff --git a/renderer/src/lib.rs b/renderer/src/lib.rs index 757c264d..70741356 100644 --- a/renderer/src/lib.rs +++ b/renderer/src/lib.rs @@ -5,6 +5,7 @@  pub use iced_wgpu as wgpu;  pub mod compositor; +pub mod custom;  #[cfg(feature = "geometry")]  pub mod geometry; @@ -38,6 +39,7 @@ pub enum Renderer {      TinySkia(iced_tiny_skia::Renderer),      #[cfg(feature = "wgpu")]      Wgpu(iced_wgpu::Renderer), +    Custom(Box<dyn custom::Renderer>),  }  macro_rules! delegate { @@ -46,6 +48,7 @@ macro_rules! delegate {              Self::TinySkia($name) => $body,              #[cfg(feature = "wgpu")]              Self::Wgpu($name) => $body, +            Self::Custom($name) => $body,          }      };  } @@ -62,6 +65,9 @@ impl Renderer {                      iced_wgpu::primitive::Custom::Mesh(mesh),                  ));              } +            Self::Custom(renderer) => { +                renderer.draw_mesh(mesh); +            }          }      }  } @@ -96,6 +102,18 @@ impl core::Renderer for Renderer {                      _ => unreachable!(),                  }              } +            Self::Custom(renderer) => { +                renderer.start_layer(); + +                f(self); + +                match self { +                    Self::Custom(renderer) => { +                        renderer.end_layer(bounds); +                    } +                    _ => unreachable!(), +                } +            }          }      } @@ -132,6 +150,18 @@ impl core::Renderer for Renderer {                      _ => unreachable!(),                  }              } +            Self::Custom(renderer) => { +                renderer.start_transformation(); + +                f(self); + +                match self { +                    Self::Custom(renderer) => { +                        renderer.end_transformation(transformation); +                    } +                    _ => unreachable!(), +                } +            }          }      } @@ -140,7 +170,7 @@ impl core::Renderer for Renderer {          quad: renderer::Quad,          background: impl Into<Background>,      ) { -        delegate!(self, renderer, renderer.fill_quad(quad, background)); +        delegate!(self, renderer, renderer.fill_quad(quad, background.into()));      }      fn clear(&mut self) { @@ -216,36 +246,43 @@ impl text::Renderer for Renderer {  impl crate::core::image::Renderer for Renderer {      type Handle = crate::core::image::Handle; -    fn dimensions( +    fn measure_image(          &self,          handle: &crate::core::image::Handle,      ) -> core::Size<u32> { -        delegate!(self, renderer, renderer.dimensions(handle)) +        delegate!(self, renderer, renderer.measure_image(handle))      } -    fn draw( +    fn draw_image(          &mut self,          handle: crate::core::image::Handle,          filter_method: crate::core::image::FilterMethod,          bounds: Rectangle,      ) { -        delegate!(self, renderer, renderer.draw(handle, filter_method, bounds)); +        delegate!( +            self, +            renderer, +            renderer.draw_image(handle, filter_method, bounds) +        );      }  }  #[cfg(feature = "svg")]  impl crate::core::svg::Renderer for Renderer { -    fn dimensions(&self, handle: &crate::core::svg::Handle) -> core::Size<u32> { -        delegate!(self, renderer, renderer.dimensions(handle)) +    fn measure_svg( +        &self, +        handle: &crate::core::svg::Handle, +    ) -> core::Size<u32> { +        delegate!(self, renderer, renderer.measure_svg(handle))      } -    fn draw( +    fn draw_svg(          &mut self,          handle: crate::core::svg::Handle,          color: Option<crate::core::Color>,          bounds: Rectangle,      ) { -        delegate!(self, renderer, renderer.draw(handle, color, bounds)); +        delegate!(self, renderer, renderer.draw_svg(handle, color, bounds));      }  } @@ -263,6 +300,7 @@ impl crate::graphics::geometry::Renderer for Renderer {                          }                          #[cfg(feature = "wgpu")]                          crate::Geometry::Wgpu(_) => unreachable!(), +                        crate::Geometry::Custom(_) => unreachable!(),                      }                  }              } @@ -274,6 +312,19 @@ impl crate::graphics::geometry::Renderer for Renderer {                              renderer.draw_primitive(primitive);                          }                          crate::Geometry::TinySkia(_) => unreachable!(), +                        crate::Geometry::Custom(_) => unreachable!(), +                    } +                } +            } +            Self::Custom(renderer) => { +                for layer in layers { +                    match layer { +                        crate::Geometry::Custom(geometry) => { +                            renderer.draw_geometry(geometry); +                        } +                        crate::Geometry::TinySkia(_) => unreachable!(), +                        #[cfg(feature = "wgpu")] +                        crate::Geometry::Wgpu(_) => unreachable!(),                      }                  }              } @@ -297,6 +348,11 @@ impl iced_wgpu::primitive::pipeline::Renderer for Renderer {              Self::Wgpu(renderer) => {                  renderer.draw_pipeline_primitive(bounds, primitive);              } +            Self::Custom(_renderer) => { +                log::warn!( +                    "Custom shader primitive is unavailable with custom renderer." +                ); +            }          }      }  } | 
