From 5100b5d0a1f654ec1254b7765ceadfb9091d6939 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Fri, 24 Feb 2023 23:24:48 +0100 Subject: Introduce `iced_renderer` subcrate featuring runtime renderer fallback --- renderer/src/backend.rs | 94 ++++++++++++++++++++++++++++++++++++++ renderer/src/lib.rs | 17 +++++++ renderer/src/settings.rs | 30 ++++++++++++ renderer/src/window.rs | 3 ++ renderer/src/window/compositor.rs | 96 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 240 insertions(+) create mode 100644 renderer/src/backend.rs create mode 100644 renderer/src/lib.rs create mode 100644 renderer/src/settings.rs create mode 100644 renderer/src/window.rs create mode 100644 renderer/src/window/compositor.rs (limited to 'renderer/src') diff --git a/renderer/src/backend.rs b/renderer/src/backend.rs new file mode 100644 index 00000000..a9a09593 --- /dev/null +++ b/renderer/src/backend.rs @@ -0,0 +1,94 @@ +use crate::{Font, Point, Size}; + +use iced_graphics::backend; +use iced_graphics::text; + +use std::borrow::Cow; + +pub enum Backend { + Wgpu(iced_wgpu::Backend), +} + +impl iced_graphics::Backend for Backend {} + +impl backend::Text for Backend { + const ICON_FONT: Font = Font::Name("Iced-Icons"); + const CHECKMARK_ICON: char = '\u{f00c}'; + const ARROW_DOWN_ICON: char = '\u{e800}'; + + fn default_font(&self) -> Font { + match self { + Self::Wgpu(backend) => backend.default_font(), + } + } + + fn default_size(&self) -> f32 { + match self { + Self::Wgpu(backend) => backend.default_size(), + } + } + + fn measure( + &self, + contents: &str, + size: f32, + font: Font, + bounds: Size, + ) -> (f32, f32) { + match self { + Self::Wgpu(backend) => { + backend.measure(contents, size, font, bounds) + } + } + } + + fn hit_test( + &self, + contents: &str, + size: f32, + font: Font, + bounds: Size, + position: Point, + nearest_only: bool, + ) -> Option { + match self { + Self::Wgpu(backend) => backend.hit_test( + contents, + size, + font, + bounds, + position, + nearest_only, + ), + } + } + + fn load_font(&mut self, font: Cow<'static, [u8]>) { + match self { + Self::Wgpu(backend) => { + backend.load_font(font); + } + } + } +} + +#[cfg(feature = "image")] +impl backend::Image for Backend { + fn dimensions(&self, handle: &iced_native::image::Handle) -> Size { + match self { + Self::Wgpu(backend) => backend.dimensions(handle), + } + } +} + +#[cfg(feature = "svg")] +impl backend::Svg for Backend { + fn viewport_dimensions( + &self, + handle: &iced_native::svg::Handle, + ) -> Size { + match self { + Self::Wgpu(backend) => backend.viewport_dimensions(handle), + } + } +} diff --git a/renderer/src/lib.rs b/renderer/src/lib.rs new file mode 100644 index 00000000..d0ba6793 --- /dev/null +++ b/renderer/src/lib.rs @@ -0,0 +1,17 @@ +pub mod window; + +mod backend; +mod settings; + +pub use backend::Backend; +pub use settings::Settings; + +pub use iced_graphics::{ + Antialiasing, Color, Error, Font, Point, Size, Viewport, +}; + +/// The default graphics renderer for [`iced`]. +/// +/// [`iced`]: https://github.com/iced-rs/iced +pub type Renderer = + iced_graphics::Renderer; diff --git a/renderer/src/settings.rs b/renderer/src/settings.rs new file mode 100644 index 00000000..c4dc248b --- /dev/null +++ b/renderer/src/settings.rs @@ -0,0 +1,30 @@ +use crate::{Antialiasing, Font}; + +/// The settings of a [`Backend`]. +/// +/// [`Backend`]: crate::Backend +#[derive(Debug, Clone, Copy, PartialEq)] +pub struct Settings { + /// The default [`Font`] to use. + pub default_font: Font, + + /// The default size of text. + /// + /// By default, it will be set to `16.0`. + pub default_text_size: f32, + + /// The antialiasing strategy that will be used for triangle primitives. + /// + /// By default, it is `None`. + pub antialiasing: Option, +} + +impl Default for Settings { + fn default() -> Settings { + Settings { + default_font: Font::SansSerif, + default_text_size: 16.0, + antialiasing: None, + } + } +} diff --git a/renderer/src/window.rs b/renderer/src/window.rs new file mode 100644 index 00000000..a7c8911b --- /dev/null +++ b/renderer/src/window.rs @@ -0,0 +1,3 @@ +mod compositor; + +pub use compositor::Compositor; diff --git a/renderer/src/window/compositor.rs b/renderer/src/window/compositor.rs new file mode 100644 index 00000000..ad78d8bf --- /dev/null +++ b/renderer/src/window/compositor.rs @@ -0,0 +1,96 @@ +use crate::{Backend, Color, Error, Renderer, Settings, Viewport}; + +use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle}; + +pub use iced_graphics::window::compositor::{Information, SurfaceError}; + +pub enum Compositor { + Wgpu(iced_wgpu::window::Compositor), +} + +pub enum Surface { + Wgpu(iced_wgpu::window::Surface), +} + +impl iced_graphics::window::Compositor for Compositor { + type Settings = Settings; + type Renderer = Renderer; + type Surface = Surface; + + fn new( + settings: Self::Settings, + compatible_window: Option<&W>, + ) -> Result<(Self, Self::Renderer), Error> { + let (compositor, backend) = iced_wgpu::window::compositor::new( + iced_wgpu::Settings { + default_font: settings.default_font, + default_text_size: settings.default_text_size, + antialiasing: settings.antialiasing, + ..iced_wgpu::Settings::from_env() + }, + compatible_window, + )?; + + Ok(( + Self::Wgpu(compositor), + Renderer::new(Backend::Wgpu(backend)), + )) + } + + fn create_surface( + &mut self, + window: &W, + ) -> Surface { + match self { + Self::Wgpu(compositor) => { + Surface::Wgpu(compositor.create_surface(window)) + } + } + } + + fn configure_surface( + &mut self, + surface: &mut Surface, + width: u32, + height: u32, + ) { + match (self, surface) { + (Self::Wgpu(compositor), Surface::Wgpu(surface)) => { + compositor.configure_surface(surface, width, height); + } + } + } + + fn fetch_information(&self) -> Information { + match self { + Self::Wgpu(compositor) => compositor.fetch_information(), + } + } + + fn present>( + &mut self, + renderer: &mut Self::Renderer, + surface: &mut Self::Surface, + viewport: &Viewport, + background_color: Color, + overlay: &[T], + ) -> Result<(), SurfaceError> { + renderer.with_primitives(|backend, primitives| { + match (self, backend, surface) { + ( + Self::Wgpu(compositor), + Backend::Wgpu(backend), + Surface::Wgpu(surface), + ) => iced_wgpu::window::compositor::present( + compositor, + backend, + surface, + primitives, + viewport, + background_color, + overlay, + ), + } + }) + } +} -- cgit