From 0ae1baa37bd7b6607f79b33b8a6d8c5daafde0b2 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 22 Jun 2023 00:38:36 +0200 Subject: Introduce custom backend-specific primitives --- renderer/src/lib.rs | 248 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 245 insertions(+), 3 deletions(-) (limited to 'renderer/src/lib.rs') 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 = iced_graphics::Renderer; +pub enum Renderer { + TinySkia(iced_tiny_skia::Renderer), + #[cfg(feature = "wgpu")] + Wgpu(iced_wgpu::Renderer), +} + +macro_rules! delegate { + ($renderer:expr, $name:ident, $body:expr) => { + match $renderer { + Self::TinySkia($name) => $body, + #[cfg(feature = "wgpu")] + Self::Wgpu($name) => $body, + } + }; +} + +impl Renderer { + #[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 core::Renderer for Renderer { + 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, + ) { + delegate!(self, renderer, renderer.fill_quad(quad, background)); + } + + fn clear(&mut self) { + delegate!(self, renderer, renderer.clear()); + } +} + +impl text::Renderer for Renderer { + type Font = Font; + + const ICON_FONT: Font = iced_tiny_skia::Renderer::::ICON_FONT; + const CHECKMARK_ICON: char = iced_tiny_skia::Renderer::::CHECKMARK_ICON; + const ARROW_DOWN_ICON: char = + iced_tiny_skia::Renderer::::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 { + 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 crate::core::image::Renderer for Renderer { + type Handle = crate::core::image::Handle; + + fn dimensions(&self, handle: &crate::core::image::Handle) -> Size { + 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 crate::core::svg::Renderer for Renderer { + fn dimensions(&self, handle: &crate::core::svg::Handle) -> Size { + delegate!(self, renderer, renderer.dimensions(handle)) + } + + fn draw( + &mut self, + handle: crate::core::svg::Handle, + color: Option, + bounds: Rectangle, + ) { + delegate!(self, renderer, renderer.draw(handle, color, bounds)) + } +} + +#[cfg(feature = "geometry")] +impl crate::graphics::geometry::Renderer for Renderer { + type Geometry = crate::Geometry; + + fn draw(&mut self, layers: Vec) { + 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!(), + } + } + } + } + } +} -- cgit From fa5650cfd1115e6ccec2ad795cf58fd970d5b43c Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 29 Jun 2023 07:48:03 +0200 Subject: Decouple `Mesh` primitives from main `Primitive` type --- renderer/src/lib.rs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'renderer/src/lib.rs') diff --git a/renderer/src/lib.rs b/renderer/src/lib.rs index 89b8f4c6..7d1a02c2 100644 --- a/renderer/src/lib.rs +++ b/renderer/src/lib.rs @@ -17,6 +17,7 @@ pub use geometry::Geometry; use crate::core::renderer; use crate::core::text::{self, Text}; use crate::core::{Background, Font, Point, Rectangle, Size, Vector}; +use crate::graphics::Mesh; use std::borrow::Cow; @@ -40,10 +41,17 @@ macro_rules! delegate { } impl Renderer { - #[cfg(feature = "wgpu")] - pub fn draw_with_wgpu(&mut self, primitive: iced_wgpu::Primitive) { - if let Self::Wgpu(renderer) = self { - renderer.draw_primitive(primitive); + pub fn draw_mesh(&mut self, mesh: Mesh) { + match self { + Self::TinySkia(_) => { + log::warn!("Unsupported mesh primitive: {:?}", mesh) + } + #[cfg(feature = "wgpu")] + Self::Wgpu(renderer) => { + renderer.draw_primitive(iced_wgpu::Primitive::Custom( + iced_wgpu::primitive::Custom::Mesh(mesh), + )); + } } } } -- cgit