diff options
author | 2020-06-02 02:21:07 +0200 | |
---|---|---|
committer | 2020-06-02 02:21:07 +0200 | |
commit | ede4440e997191c947697ee7aab89f32b9d0b2ea (patch) | |
tree | 166eac740a736d3effbd4054509a61ee12f58666 /graphics | |
parent | b96d87ff6917e7dc75178e4c623d20d577ef583f (diff) | |
download | iced-ede4440e997191c947697ee7aab89f32b9d0b2ea.tar.gz iced-ede4440e997191c947697ee7aab89f32b9d0b2ea.tar.bz2 iced-ede4440e997191c947697ee7aab89f32b9d0b2ea.zip |
Introduce fill rule setting in `canvas`
Diffstat (limited to 'graphics')
-rw-r--r-- | graphics/src/widget/canvas.rs | 4 | ||||
-rw-r--r-- | graphics/src/widget/canvas/fill.rs | 50 | ||||
-rw-r--r-- | graphics/src/widget/canvas/frame.rs | 27 |
3 files changed, 57 insertions, 24 deletions
diff --git a/graphics/src/widget/canvas.rs b/graphics/src/widget/canvas.rs index d393a5c5..b8466239 100644 --- a/graphics/src/widget/canvas.rs +++ b/graphics/src/widget/canvas.rs @@ -29,7 +29,7 @@ mod text; pub use cache::Cache; pub use cursor::Cursor; pub use event::Event; -pub use fill::Fill; +pub use fill::{Fill, FillRule}; pub use frame::Frame; pub use geometry::Geometry; pub use path::Path; @@ -84,7 +84,7 @@ pub use text::Text; /// let circle = Path::circle(frame.center(), self.radius); /// /// // And fill it with some color -/// frame.fill(&circle, Fill::Color(Color::BLACK)); +/// frame.fill(&circle, Color::BLACK); /// /// // Finally, we produce the geometry /// vec![frame.into_geometry()] diff --git a/graphics/src/widget/canvas/fill.rs b/graphics/src/widget/canvas/fill.rs index a2010e45..56495435 100644 --- a/graphics/src/widget/canvas/fill.rs +++ b/graphics/src/widget/canvas/fill.rs @@ -2,19 +2,59 @@ use iced_native::Color; /// The style used to fill geometry. #[derive(Debug, Clone, Copy)] -pub enum Fill { - /// Fill with a color. - Color(Color), +pub struct Fill { + /// The color used to fill geometry. + /// + /// By default, it is set to `BLACK`. + pub color: Color, + + /// The fill rule defines how to determine what is inside and what is + /// outside of a shape. + /// + /// See the [SVG specification][1] for more details. + /// + /// By default, it is set to `NonZero`. + /// + /// [1]: https://www.w3.org/TR/SVG/painting.html#FillRuleProperty + pub rule: FillRule, } impl Default for Fill { fn default() -> Fill { - Fill::Color(Color::BLACK) + Fill { + color: Color::BLACK, + rule: FillRule::NonZero, + } } } impl From<Color> for Fill { fn from(color: Color) -> Fill { - Fill::Color(color) + Fill { + color, + ..Fill::default() + } + } +} + +/// The fill rule defines how to determine what is inside and what is outside of +/// a shape. +/// +/// See the [SVG specification][1]. +/// +/// [1]: https://www.w3.org/TR/SVG/painting.html#FillRuleProperty +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[allow(missing_docs)] +pub enum FillRule { + NonZero, + EvenOdd, +} + +impl From<FillRule> for lyon::tessellation::FillRule { + fn from(rule: FillRule) -> lyon::tessellation::FillRule { + match rule { + FillRule::NonZero => lyon::tessellation::FillRule::NonZero, + FillRule::EvenOdd => lyon::tessellation::FillRule::EvenOdd, + } } } diff --git a/graphics/src/widget/canvas/frame.rs b/graphics/src/widget/canvas/frame.rs index 48d28d95..b5c6a2b1 100644 --- a/graphics/src/widget/canvas/frame.rs +++ b/graphics/src/widget/canvas/frame.rs @@ -92,29 +92,22 @@ impl Frame { BuffersBuilder, FillOptions, FillTessellator, }; + let Fill { color, rule } = fill.into(); + let mut buffers = BuffersBuilder::new( &mut self.buffers, - FillVertex(match fill.into() { - Fill::Color(color) => color.into_linear(), - }), + FillVertex(color.into_linear()), ); let mut tessellator = FillTessellator::new(); + let options = FillOptions::default().with_fill_rule(rule.into()); let result = if self.transforms.current.is_identity { - tessellator.tessellate_path( - path.raw(), - &FillOptions::default(), - &mut buffers, - ) + tessellator.tessellate_path(path.raw(), &options, &mut buffers) } else { let path = path.transformed(&self.transforms.current.raw); - tessellator.tessellate_path( - path.raw(), - &FillOptions::default(), - &mut buffers, - ) + tessellator.tessellate_path(path.raw(), &options, &mut buffers) }; let _ = result.expect("Tessellate path"); @@ -132,11 +125,11 @@ impl Frame { ) { use lyon::tessellation::{BuffersBuilder, FillOptions}; + let Fill { color, rule } = fill.into(); + let mut buffers = BuffersBuilder::new( &mut self.buffers, - FillVertex(match fill.into() { - Fill::Color(color) => color.into_linear(), - }), + FillVertex(color.into_linear()), ); let top_left = @@ -151,7 +144,7 @@ impl Frame { let _ = lyon::tessellation::basic_shapes::fill_rectangle( &lyon::math::Rect::new(top_left, size.into()), - &FillOptions::default(), + &FillOptions::default().with_fill_rule(rule.into()), &mut buffers, ) .expect("Fill rectangle"); |