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"); | 
