diff options
| author | 2024-03-22 01:35:14 +0100 | |
|---|---|---|
| committer | 2024-03-22 01:35:14 +0100 | |
| commit | 53a183fe0d6aed460fbb8155ac9541757277aab3 (patch) | |
| tree | 449574ac4d2d14a146db74a1fd96e8075a394db4 /renderer/src | |
| parent | b972ebca8f8c23d2df1b45bb26038789766a5a65 (diff) | |
| download | iced-53a183fe0d6aed460fbb8155ac9541757277aab3.tar.gz iced-53a183fe0d6aed460fbb8155ac9541757277aab3.tar.bz2 iced-53a183fe0d6aed460fbb8155ac9541757277aab3.zip | |
Restore `canvas::Frame` API
Diffstat (limited to '')
| -rw-r--r-- | renderer/src/fallback.rs | 20 | ||||
| -rw-r--r-- | renderer/src/geometry.rs | 236 | ||||
| -rw-r--r-- | renderer/src/geometry/cache.rs | 137 | 
3 files changed, 7 insertions, 386 deletions
| diff --git a/renderer/src/fallback.rs b/renderer/src/fallback.rs index a4c725c0..659f253d 100644 --- a/renderer/src/fallback.rs +++ b/renderer/src/fallback.rs @@ -459,10 +459,10 @@ mod geometry {          Right(R),      } -    impl<L, R> geometry::Frame for Frame<L, R> +    impl<L, R> geometry::frame::Backend for Frame<L, R>      where -        L: geometry::Frame, -        R: geometry::Frame, +        L: geometry::frame::Backend, +        R: geometry::frame::Backend,      {          type Geometry = Geometry<L::Geometry, R::Geometry>; @@ -545,17 +545,11 @@ mod geometry {          fn scale_nonuniform(&mut self, scale: impl Into<Vector>) {              delegate!(self, frame, frame.scale_nonuniform(scale));          } -    } -    impl<L, R> From<Frame<L, R>> for Geometry<L::Geometry, R::Geometry> -    where -        L: geometry::Frame, -        R: geometry::Frame, -    { -        fn from(frame: Frame<L, R>) -> Self { -            match frame { -                Frame::Left(frame) => Self::Left(frame.into()), -                Frame::Right(frame) => Self::Right(frame.into()), +        fn into_geometry(self) -> Self::Geometry { +            match self { +                Frame::Left(frame) => Geometry::Left(frame.into_geometry()), +                Frame::Right(frame) => Geometry::Right(frame.into_geometry()),              }          }      } diff --git a/renderer/src/geometry.rs b/renderer/src/geometry.rs deleted file mode 100644 index a16cecd5..00000000 --- a/renderer/src/geometry.rs +++ /dev/null @@ -1,236 +0,0 @@ -mod cache; - -pub use cache::Cache; - -use crate::core::{Point, Radians, Rectangle, Size, Transformation, Vector}; -use crate::graphics::geometry::{Fill, Path, Stroke, Text}; -use crate::Renderer; - -macro_rules! delegate { -    ($frame:expr, $name:ident, $body:expr) => { -        match $frame { -            Self::TinySkia($name) => $body, -            #[cfg(feature = "wgpu")] -            Self::Wgpu($name) => $body, -            #[cfg(feature = "custom")] -            Self::Custom($name) => $body, -        } -    }; -} - -pub enum Geometry { -    TinySkia(iced_tiny_skia::Primitive), -    #[cfg(feature = "wgpu")] -    Wgpu(iced_wgpu::Primitive), -    #[cfg(feature = "custom")] -    Custom(Box<dyn crate::custom::Geometry>), -} - -impl Geometry { -    pub fn transform(self, transformation: Transformation) -> Self { -        match self { -            Self::TinySkia(primitive) => { -                Self::TinySkia(primitive.transform(transformation)) -            } -            #[cfg(feature = "wgpu")] -            Self::Wgpu(primitive) => { -                Self::Wgpu(primitive.transform(transformation)) -            } -            #[cfg(feature = "custom")] -            Self::Custom(geometry) => { -                Self::Custom(geometry.transform(transformation)) -            } -        } -    } -} - -pub enum Frame { -    TinySkia(iced_tiny_skia::geometry::Frame), -    #[cfg(feature = "wgpu")] -    Wgpu(iced_wgpu::geometry::Frame), -    #[cfg(feature = "custom")] -    Custom(Box<dyn crate::custom::Frame>), -} - -impl Frame { -    pub fn new(renderer: &Renderer, size: Size) -> Self { -        match renderer { -            Renderer::TinySkia(_) => { -                Frame::TinySkia(iced_tiny_skia::geometry::Frame::new(size)) -            } -            #[cfg(feature = "wgpu")] -            Renderer::Wgpu(_) => { -                Frame::Wgpu(iced_wgpu::geometry::Frame::new(size)) -            } -            #[cfg(feature = "custom")] -            Renderer::Custom(renderer) => { -                Frame::Custom(renderer.new_frame(size)) -            } -        } -    } - -    /// Returns the width of the [`Frame`]. -    #[inline] -    pub fn width(&self) -> f32 { -        delegate!(self, frame, frame.width()) -    } - -    /// Returns the height of the [`Frame`]. -    #[inline] -    pub fn height(&self) -> f32 { -        delegate!(self, frame, frame.height()) -    } - -    /// Returns the dimensions of the [`Frame`]. -    #[inline] -    pub fn size(&self) -> Size { -        delegate!(self, frame, frame.size()) -    } - -    /// Returns the coordinate of the center of the [`Frame`]. -    #[inline] -    pub fn center(&self) -> Point { -        delegate!(self, frame, frame.center()) -    } - -    /// 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.into())); -    } - -    /// Draws an axis-aligned rectangle given its top-left corner coordinate and -    /// its `Size` on the [`Frame`] by filling it with the provided style. -    pub fn fill_rectangle( -        &mut self, -        top_left: Point, -        size: Size, -        fill: impl Into<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.into())); -    } - -    /// Draws the characters of the given [`Text`] on the [`Frame`], filling -    /// them with the given color. -    /// -    /// __Warning:__ Text currently does not work well with rotations and scale -    /// transforms! The position will be correctly transformed, but the -    /// resulting glyphs will not be rotated or scaled properly. -    /// -    /// Additionally, all text will be rendered on top of all the layers of -    /// a `Canvas`. Therefore, it is currently only meant to be used for -    /// overlays, which is the most common use case. -    /// -    /// 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.into())); -    } - -    /// Stores the current transform of the [`Frame`] and executes the given -    /// drawing operations, restoring the transform afterwards. -    /// -    /// This method is useful to compose transforms and perform drawing -    /// operations in different coordinate systems. -    #[inline] -    pub fn with_save<R>(&mut self, f: impl FnOnce(&mut Frame) -> R) -> R { -        delegate!(self, frame, frame.push_transform()); - -        let result = f(self); - -        delegate!(self, frame, frame.pop_transform()); - -        result -    } - -    /// Executes the given drawing operations within a [`Rectangle`] region, -    /// clipping any geometry that overflows its bounds. Any transformations -    /// performed are local to the provided closure. -    /// -    /// This method is useful to perform drawing operations that need to be -    /// clipped. -    #[inline] -    pub fn with_clip<R>( -        &mut self, -        region: Rectangle, -        f: impl FnOnce(&mut Frame) -> R, -    ) -> R { -        let mut frame = match self { -            Self::TinySkia(_) => Self::TinySkia( -                iced_tiny_skia::geometry::Frame::new(region.size()), -            ), -            #[cfg(feature = "wgpu")] -            Self::Wgpu(_) => { -                Self::Wgpu(iced_wgpu::geometry::Frame::new(region.size())) -            } -            #[cfg(feature = "custom")] -            Self::Custom(frame) => Self::Custom(frame.new(region.size())), -        }; - -        let result = f(&mut frame); - -        let origin = Point::new(region.x, region.y); - -        match (self, frame) { -            (Self::TinySkia(target), Self::TinySkia(frame)) => { -                target.clip(frame, origin); -            } -            #[cfg(feature = "wgpu")] -            (Self::Wgpu(target), Self::Wgpu(frame)) => { -                target.clip(frame, origin); -            } -            #[cfg(feature = "custom")] -            (Self::Custom(target), Self::Custom(frame)) => { -                target.clip(frame, origin); -            } -            #[allow(unreachable_patterns)] -            _ => unreachable!(), -        }; - -        result -    } - -    /// Applies a translation to the current transform of the [`Frame`]. -    #[inline] -    pub fn translate(&mut self, translation: Vector) { -        delegate!(self, frame, frame.translate(translation)); -    } - -    /// 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.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.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.into())); -    } - -    pub fn into_geometry(self) -> Geometry { -        match self { -            Self::TinySkia(frame) => Geometry::TinySkia(frame.into_primitive()), -            #[cfg(feature = "wgpu")] -            Self::Wgpu(frame) => Geometry::Wgpu(frame.into_primitive()), -            #[cfg(feature = "custom")] -            Self::Custom(frame) => Geometry::Custom(frame.into_geometry()), -        } -    } -} diff --git a/renderer/src/geometry/cache.rs b/renderer/src/geometry/cache.rs deleted file mode 100644 index 20f73f22..00000000 --- a/renderer/src/geometry/cache.rs +++ /dev/null @@ -1,137 +0,0 @@ -use crate::core::Size; -use crate::geometry::{Frame, Geometry}; -use crate::Renderer; - -use std::cell::RefCell; -use std::sync::Arc; - -/// A simple cache that stores generated [`Geometry`] to avoid recomputation. -/// -/// A [`Cache`] will not redraw its geometry unless the dimensions of its layer -/// change or it is explicitly cleared. -#[derive(Debug, Default)] -pub struct Cache { -    state: RefCell<State>, -} - -#[derive(Debug, Default)] -enum State { -    #[default] -    Empty, -    Filled { -        bounds: Size, -        primitive: Internal, -    }, -} - -#[derive(Debug, Clone)] -enum Internal { -    TinySkia(Arc<iced_tiny_skia::Primitive>), -    #[cfg(feature = "wgpu")] -    Wgpu(Arc<iced_wgpu::Primitive>), -    #[cfg(feature = "custom")] -    Custom(Arc<dyn crate::custom::Geometry>), -} - -impl Cache { -    /// Creates a new empty [`Cache`]. -    pub fn new() -> Self { -        Cache { -            state: RefCell::default(), -        } -    } - -    /// Clears the [`Cache`], forcing a redraw the next time it is used. -    pub fn clear(&self) { -        *self.state.borrow_mut() = State::Empty; -    } - -    /// Draws [`Geometry`] using the provided closure and stores it in the -    /// [`Cache`]. -    /// -    /// The closure will only be called when -    /// - the bounds have changed since the previous draw call. -    /// - the [`Cache`] is empty or has been explicitly cleared. -    /// -    /// Otherwise, the previously stored [`Geometry`] will be returned. The -    /// [`Cache`] is not cleared in this case. In other words, it will keep -    /// returning the stored [`Geometry`] if needed. -    pub fn draw( -        &self, -        renderer: &Renderer, -        bounds: Size, -        draw_fn: impl FnOnce(&mut Frame), -    ) -> Geometry { -        use std::ops::Deref; - -        if let State::Filled { -            bounds: cached_bounds, -            primitive, -        } = self.state.borrow().deref() -        { -            if *cached_bounds == bounds { -                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(), -                        }); -                    } -                    #[cfg(feature = "custom")] -                    Internal::Custom(geometry) => { -                        return Geometry::Custom(geometry.clone().load()) -                    } -                } -            } -        } - -        let mut frame = Frame::new(renderer, bounds); -        draw_fn(&mut frame); - -        let primitive = { -            let geometry = frame.into_geometry(); - -            match geometry { -                Geometry::TinySkia(primitive) => { -                    Internal::TinySkia(Arc::new(primitive)) -                } -                #[cfg(feature = "wgpu")] -                Geometry::Wgpu(primitive) => { -                    Internal::Wgpu(Arc::new(primitive)) -                } -                #[cfg(feature = "custom")] -                Geometry::Custom(geometry) => { -                    Internal::Custom(geometry.cache()) -                } -            } -        }; - -        *self.state.borrow_mut() = State::Filled { -            bounds, -            primitive: primitive.clone(), -        }; - -        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, -                }) -            } -            #[cfg(feature = "custom")] -            Internal::Custom(geometry) => Geometry::Custom(geometry.load()), -        } -    } -} | 
