diff options
Diffstat (limited to '')
| -rw-r--r-- | wgpu/src/widget/canvas/frame.rs | 102 | ||||
| -rw-r--r-- | wgpu/src/widget/canvas/path.rs | 10 | 
2 files changed, 105 insertions, 7 deletions
| diff --git a/wgpu/src/widget/canvas/frame.rs b/wgpu/src/widget/canvas/frame.rs index 3c667426..687f6c37 100644 --- a/wgpu/src/widget/canvas/frame.rs +++ b/wgpu/src/widget/canvas/frame.rs @@ -1,4 +1,4 @@ -use iced_native::Point; +use iced_native::{Point, Size, Vector};  use crate::{      canvas::{Fill, Path, Stroke}, @@ -10,6 +10,20 @@ pub struct Frame {      width: f32,      height: f32,      buffers: lyon::tessellation::VertexBuffers<triangle::Vertex2D, u16>, + +    transforms: Transforms, +} + +#[derive(Debug)] +struct Transforms { +    previous: Vec<Transform>, +    current: Transform, +} + +#[derive(Debug, Clone, Copy)] +struct Transform { +    raw: lyon::math::Transform, +    is_identity: bool,  }  impl Frame { @@ -18,17 +32,32 @@ impl Frame {              width,              height,              buffers: lyon::tessellation::VertexBuffers::new(), +            transforms: Transforms { +                previous: Vec::new(), +                current: Transform { +                    raw: lyon::math::Transform::identity(), +                    is_identity: true, +                }, +            },          }      } +    #[inline]      pub fn width(&self) -> f32 {          self.width      } +    #[inline]      pub fn height(&self) -> f32 {          self.height      } +    #[inline] +    pub fn size(&self) -> Size { +        Size::new(self.width, self.height) +    } + +    #[inline]      pub fn center(&self) -> Point {          Point::new(self.width / 2.0, self.height / 2.0)      } @@ -47,9 +76,23 @@ impl Frame {          let mut tessellator = FillTessellator::new(); -        let _ = tessellator -            .tessellate_path(path.raw(), &FillOptions::default(), &mut buffers) -            .expect("Tessellate path"); +        let result = if self.transforms.current.is_identity { +            tessellator.tessellate_path( +                path.raw(), +                &FillOptions::default(), +                &mut buffers, +            ) +        } else { +            let path = path.transformed(&self.transforms.current.raw); + +            tessellator.tessellate_path( +                path.raw(), +                &FillOptions::default(), +                &mut buffers, +            ) +        }; + +        let _ = result.expect("Tessellate path");      }      pub fn stroke(&mut self, path: &Path, stroke: Stroke) { @@ -70,9 +113,54 @@ impl Frame {          options.end_cap = stroke.line_cap.into();          options.line_join = stroke.line_join.into(); -        let _ = tessellator -            .tessellate_path(path.raw(), &options, &mut buffers) -            .expect("Stroke path"); +        let result = if self.transforms.current.is_identity { +            tessellator.tessellate_path(path.raw(), &options, &mut buffers) +        } else { +            let path = path.transformed(&self.transforms.current.raw); + +            tessellator.tessellate_path(path.raw(), &options, &mut buffers) +        }; + +        let _ = result.expect("Stroke path"); +    } + +    #[inline] +    pub fn with_save(&mut self, f: impl FnOnce(&mut Frame)) { +        self.transforms.previous.push(self.transforms.current); + +        f(self); + +        self.transforms.current = self.transforms.previous.pop().unwrap(); +    } + +    #[inline] +    pub fn translate(&mut self, translation: Vector) { +        self.transforms.current.raw = self +            .transforms +            .current +            .raw +            .pre_translate(lyon::math::Vector::new( +                translation.x, +                translation.y, +            )); +        self.transforms.current.is_identity = false; +    } + +    #[inline] +    pub fn rotate(&mut self, angle: f32) { +        self.transforms.current.raw = self +            .transforms +            .current +            .raw +            .pre_rotate(lyon::math::Angle::radians(-angle)); +        self.transforms.current.is_identity = false; +    } + +    #[inline] +    pub fn scale(&mut self, scale: f32) { +        self.transforms.current.raw = +            self.transforms.current.raw.pre_scale(scale, scale); +        self.transforms.current.is_identity = false;      }      pub fn into_mesh(self) -> triangle::Mesh2D { diff --git a/wgpu/src/widget/canvas/path.rs b/wgpu/src/widget/canvas/path.rs index 8847ea29..b70d0aef 100644 --- a/wgpu/src/widget/canvas/path.rs +++ b/wgpu/src/widget/canvas/path.rs @@ -21,6 +21,16 @@ impl Path {      pub(crate) fn raw(&self) -> &lyon::path::Path {          &self.raw      } + +    #[inline] +    pub(crate) fn transformed( +        &self, +        transform: &lyon::math::Transform, +    ) -> Path { +        Path { +            raw: self.raw.transformed(transform), +        } +    }  }  #[allow(missing_debug_implementations)] | 
