diff options
| author | 2024-06-21 10:41:17 +0100 | |
|---|---|---|
| committer | 2024-09-10 23:44:04 +0200 | |
| commit | ec39390c23cd46a115bb0528abdb2c5527f1272a (patch) | |
| tree | 104c7209bc2c37cdd332b31d8308237461a22a63 | |
| parent | abd323181d613f1dc69b6cbe885dce556f427de2 (diff) | |
| download | iced-ec39390c23cd46a115bb0528abdb2c5527f1272a.tar.gz iced-ec39390c23cd46a115bb0528abdb2c5527f1272a.tar.bz2 iced-ec39390c23cd46a115bb0528abdb2c5527f1272a.zip  | |
Add stroke_rectangle
This method should be able to leverage performance improvements in lyon's
`tessellate_rectangle` over `tessellate_path`.
| -rw-r--r-- | graphics/src/geometry/frame.rs | 24 | ||||
| -rw-r--r-- | renderer/src/fallback.rs | 13 | ||||
| -rw-r--r-- | tiny_skia/src/geometry.rs | 25 | ||||
| -rw-r--r-- | wgpu/src/geometry.rs | 38 | 
4 files changed, 100 insertions, 0 deletions
diff --git a/graphics/src/geometry/frame.rs b/graphics/src/geometry/frame.rs index b5f2f139..3dee7e75 100644 --- a/graphics/src/geometry/frame.rs +++ b/graphics/src/geometry/frame.rs @@ -65,6 +65,17 @@ where          self.raw.stroke(path, stroke);      } +    /// Draws the stroke of an axis-aligned rectangle with the provided style +    /// given its top-left corner coordinate and its `Size` on the [`Frame`] . +    pub fn stroke_rectangle<'a>( +        &mut self, +        top_left: Point, +        size: Size, +        stroke: impl Into<Stroke<'a>>, +    ) { +        self.raw.stroke_rectangle(top_left, size, stroke); +    } +      /// Draws the characters of the given [`Text`] on the [`Frame`], filling      /// them with the given color.      /// @@ -200,6 +211,12 @@ pub trait Backend: Sized {      fn paste(&mut self, frame: Self);      fn stroke<'a>(&mut self, path: &Path, stroke: impl Into<Stroke<'a>>); +    fn stroke_rectangle<'a>( +        &mut self, +        top_left: Point, +        size: Size, +        stroke: impl Into<Stroke<'a>>, +    );      fn fill(&mut self, path: &Path, fill: impl Into<Fill>);      fn fill_text(&mut self, text: impl Into<Text>); @@ -248,6 +265,13 @@ impl Backend for () {      fn paste(&mut self, _frame: Self) {}      fn stroke<'a>(&mut self, _path: &Path, _stroke: impl Into<Stroke<'a>>) {} +    fn stroke_rectangle<'a>( +        &mut self, +        _top_left: Point, +        _size: Size, +        _stroke: impl Into<Stroke<'a>>, +    ) { +    }      fn fill(&mut self, _path: &Path, _fill: impl Into<Fill>) {}      fn fill_text(&mut self, _text: impl Into<Text>) {} diff --git a/renderer/src/fallback.rs b/renderer/src/fallback.rs index fbd285db..8cb18bde 100644 --- a/renderer/src/fallback.rs +++ b/renderer/src/fallback.rs @@ -540,6 +540,19 @@ mod geometry {              delegate!(self, frame, frame.stroke(path, stroke));          } +        fn stroke_rectangle<'a>( +            &mut self, +            top_left: Point, +            size: Size, +            stroke: impl Into<Stroke<'a>>, +        ) { +            delegate!( +                self, +                frame, +                frame.stroke_rectangle(top_left, size, stroke) +            ); +        } +          fn fill_text(&mut self, text: impl Into<Text>) {              delegate!(self, frame, frame.fill_text(text));          } diff --git a/tiny_skia/src/geometry.rs b/tiny_skia/src/geometry.rs index 659612d1..532a53cd 100644 --- a/tiny_skia/src/geometry.rs +++ b/tiny_skia/src/geometry.rs @@ -168,6 +168,31 @@ impl geometry::frame::Backend for Frame {          });      } +    fn stroke_rectangle<'a>( +        &mut self, +        top_left: Point, +        size: Size, +        stroke: impl Into<Stroke<'a>>, +    ) { +        let Some(path) = convert_path(&Path::rectangle(top_left, size)) +            .and_then(|path| path.transform(self.transform)) +        else { +            return; +        }; + +        let stroke = stroke.into(); +        let skia_stroke = into_stroke(&stroke); + +        let mut paint = into_paint(stroke.style); +        paint.shader.transform(self.transform); + +        self.primitives.push(Primitive::Stroke { +            path, +            paint, +            stroke: skia_stroke, +        }); +    } +      fn fill_text(&mut self, text: impl Into<geometry::Text>) {          let text = text.into(); diff --git a/wgpu/src/geometry.rs b/wgpu/src/geometry.rs index be65ba36..8e6f77d7 100644 --- a/wgpu/src/geometry.rs +++ b/wgpu/src/geometry.rs @@ -253,6 +253,44 @@ impl geometry::frame::Backend for Frame {          .expect("Stroke path");      } +    fn stroke_rectangle<'a>( +        &mut self, +        top_left: Point, +        size: Size, +        stroke: impl Into<Stroke<'a>>, +    ) { +        let stroke = stroke.into(); + +        let mut buffer = self +            .buffers +            .get_stroke(&self.transforms.current.transform_style(stroke.style)); + +        let top_left = self +            .transforms +            .current +            .0 +            .transform_point(lyon::math::Point::new(top_left.x, top_left.y)); + +        let size = +            self.transforms.current.0.transform_vector( +                lyon::math::Vector::new(size.width, size.height), +            ); + +        let mut options = tessellation::StrokeOptions::default(); +        options.line_width = stroke.width; +        options.start_cap = into_line_cap(stroke.line_cap); +        options.end_cap = into_line_cap(stroke.line_cap); +        options.line_join = into_line_join(stroke.line_join); + +        self.stroke_tessellator +            .tessellate_rectangle( +                &lyon::math::Box2D::new(top_left, top_left + size), +                &options, +                buffer.as_mut(), +            ) +            .expect("Stroke rectangle"); +    } +      fn fill_text(&mut self, text: impl Into<geometry::Text>) {          let text = text.into();  | 
