diff options
author | 2020-02-12 07:08:49 +0100 | |
---|---|---|
committer | 2020-02-12 07:08:49 +0100 | |
commit | f34407bfdaf06c4bf204dc31b152be9451c243b8 (patch) | |
tree | aa9c48f24c9babb5722c2a7cdc098365b010796c /wgpu/src | |
parent | 74dd79e97f83d3e9e13d87444740edeb353f9be8 (diff) | |
download | iced-f34407bfdaf06c4bf204dc31b152be9451c243b8.tar.gz iced-f34407bfdaf06c4bf204dc31b152be9451c243b8.tar.bz2 iced-f34407bfdaf06c4bf204dc31b152be9451c243b8.zip |
Implement `Frame::fill` and `Frame::stroke`
Diffstat (limited to '')
-rw-r--r-- | wgpu/src/widget/canvas.rs | 20 | ||||
-rw-r--r-- | wgpu/src/widget/canvas/frame.rs | 76 | ||||
-rw-r--r-- | wgpu/src/widget/canvas/path.rs | 6 |
3 files changed, 100 insertions, 2 deletions
diff --git a/wgpu/src/widget/canvas.rs b/wgpu/src/widget/canvas.rs index 7b84f36c..6bfeed9a 100644 --- a/wgpu/src/widget/canvas.rs +++ b/wgpu/src/widget/canvas.rs @@ -133,6 +133,16 @@ impl Default for LineCap { } } +impl From<LineCap> for lyon::tessellation::LineCap { + fn from(line_cap: LineCap) -> lyon::tessellation::LineCap { + match line_cap { + LineCap::Butt => lyon::tessellation::LineCap::Butt, + LineCap::Square => lyon::tessellation::LineCap::Square, + LineCap::Round => lyon::tessellation::LineCap::Round, + } + } +} + #[derive(Debug, Clone, Copy)] pub enum LineJoin { Miter, @@ -146,6 +156,16 @@ impl Default for LineJoin { } } +impl From<LineJoin> for lyon::tessellation::LineJoin { + fn from(line_join: LineJoin) -> lyon::tessellation::LineJoin { + match line_join { + LineJoin::Miter => lyon::tessellation::LineJoin::Miter, + LineJoin::Round => lyon::tessellation::LineJoin::Round, + LineJoin::Bevel => lyon::tessellation::LineJoin::Bevel, + } + } +} + #[derive(Debug, Clone, Copy)] pub enum Fill { Color(Color), diff --git a/wgpu/src/widget/canvas/frame.rs b/wgpu/src/widget/canvas/frame.rs index e5daeedb..82ff526b 100644 --- a/wgpu/src/widget/canvas/frame.rs +++ b/wgpu/src/widget/canvas/frame.rs @@ -33,7 +33,79 @@ impl Frame { Point::new(self.width as f32 / 2.0, self.height as f32 / 2.0) } - pub fn fill(&mut self, path: &Path, fill: Fill) {} + pub fn fill(&mut self, path: &Path, fill: Fill) { + use lyon::tessellation::{ + BuffersBuilder, FillOptions, FillTessellator, + }; - pub fn stroke(&mut self, path: &Path, stroke: Stroke) {} + let mut buffers = BuffersBuilder::new( + &mut self.buffers, + FillVertex(match fill { + Fill::Color(color) => color.into_linear(), + }), + ); + + let mut tessellator = FillTessellator::new(); + + let _ = tessellator + .tessellate_path(path.raw(), &FillOptions::default(), &mut buffers) + .expect("Tessellate path"); + } + + pub fn stroke(&mut self, path: &Path, stroke: Stroke) { + use lyon::tessellation::{ + BuffersBuilder, StrokeOptions, StrokeTessellator, + }; + + let mut buffers = BuffersBuilder::new( + &mut self.buffers, + StrokeVertex(stroke.color.into_linear()), + ); + + let mut tessellator = StrokeTessellator::new(); + + let mut options = StrokeOptions::default(); + options.line_width = stroke.width; + options.start_cap = stroke.line_cap.into(); + 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"); + } +} + +struct FillVertex([f32; 4]); + +impl lyon::tessellation::FillVertexConstructor<triangle::Vertex2D> + for FillVertex +{ + fn new_vertex( + &mut self, + position: lyon::math::Point, + _attributes: lyon::tessellation::FillAttributes<'_>, + ) -> triangle::Vertex2D { + triangle::Vertex2D { + position: [position.x, position.y], + color: self.0, + } + } +} + +struct StrokeVertex([f32; 4]); + +impl lyon::tessellation::StrokeVertexConstructor<triangle::Vertex2D> + for StrokeVertex +{ + fn new_vertex( + &mut self, + position: lyon::math::Point, + _attributes: lyon::tessellation::StrokeAttributes<'_, '_>, + ) -> triangle::Vertex2D { + triangle::Vertex2D { + position: [position.x, position.y], + color: self.0, + } + } } diff --git a/wgpu/src/widget/canvas/path.rs b/wgpu/src/widget/canvas/path.rs index 86326e8e..96206256 100644 --- a/wgpu/src/widget/canvas/path.rs +++ b/wgpu/src/widget/canvas/path.rs @@ -9,10 +9,16 @@ impl Path { pub fn new(f: impl FnOnce(&mut Builder)) -> Self { let mut builder = Builder::new(); + // TODO: Make it pure instead of side-effect-based (?) f(&mut builder); builder.build() } + + #[inline] + pub(crate) fn raw(&self) -> &lyon::path::Path { + &self.raw + } } #[allow(missing_debug_implementations)] |