Merge pull request #379 from hecrj/canvas-fill-rule
Introduce fill rule setting in `canvas`
This commit is contained in:
commit
e7f0d3809b
@ -29,7 +29,7 @@ mod text;
|
|||||||
pub use cache::Cache;
|
pub use cache::Cache;
|
||||||
pub use cursor::Cursor;
|
pub use cursor::Cursor;
|
||||||
pub use event::Event;
|
pub use event::Event;
|
||||||
pub use fill::Fill;
|
pub use fill::{Fill, FillRule};
|
||||||
pub use frame::Frame;
|
pub use frame::Frame;
|
||||||
pub use geometry::Geometry;
|
pub use geometry::Geometry;
|
||||||
pub use path::Path;
|
pub use path::Path;
|
||||||
@ -84,7 +84,7 @@ pub use text::Text;
|
|||||||
/// let circle = Path::circle(frame.center(), self.radius);
|
/// let circle = Path::circle(frame.center(), self.radius);
|
||||||
///
|
///
|
||||||
/// // And fill it with some color
|
/// // And fill it with some color
|
||||||
/// frame.fill(&circle, Fill::Color(Color::BLACK));
|
/// frame.fill(&circle, Color::BLACK);
|
||||||
///
|
///
|
||||||
/// // Finally, we produce the geometry
|
/// // Finally, we produce the geometry
|
||||||
/// vec![frame.into_geometry()]
|
/// vec![frame.into_geometry()]
|
||||||
|
@ -2,19 +2,59 @@ use iced_native::Color;
|
|||||||
|
|
||||||
/// The style used to fill geometry.
|
/// The style used to fill geometry.
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum Fill {
|
pub struct Fill {
|
||||||
/// Fill with a color.
|
/// The color used to fill geometry.
|
||||||
Color(Color),
|
///
|
||||||
|
/// 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 {
|
impl Default for Fill {
|
||||||
fn default() -> Fill {
|
fn default() -> Fill {
|
||||||
Fill::Color(Color::BLACK)
|
Fill {
|
||||||
|
color: Color::BLACK,
|
||||||
|
rule: FillRule::NonZero,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Color> for Fill {
|
impl From<Color> for Fill {
|
||||||
fn from(color: Color) -> 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,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,29 +92,22 @@ impl Frame {
|
|||||||
BuffersBuilder, FillOptions, FillTessellator,
|
BuffersBuilder, FillOptions, FillTessellator,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let Fill { color, rule } = fill.into();
|
||||||
|
|
||||||
let mut buffers = BuffersBuilder::new(
|
let mut buffers = BuffersBuilder::new(
|
||||||
&mut self.buffers,
|
&mut self.buffers,
|
||||||
FillVertex(match fill.into() {
|
FillVertex(color.into_linear()),
|
||||||
Fill::Color(color) => color.into_linear(),
|
|
||||||
}),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut tessellator = FillTessellator::new();
|
let mut tessellator = FillTessellator::new();
|
||||||
|
let options = FillOptions::default().with_fill_rule(rule.into());
|
||||||
|
|
||||||
let result = if self.transforms.current.is_identity {
|
let result = if self.transforms.current.is_identity {
|
||||||
tessellator.tessellate_path(
|
tessellator.tessellate_path(path.raw(), &options, &mut buffers)
|
||||||
path.raw(),
|
|
||||||
&FillOptions::default(),
|
|
||||||
&mut buffers,
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
let path = path.transformed(&self.transforms.current.raw);
|
let path = path.transformed(&self.transforms.current.raw);
|
||||||
|
|
||||||
tessellator.tessellate_path(
|
tessellator.tessellate_path(path.raw(), &options, &mut buffers)
|
||||||
path.raw(),
|
|
||||||
&FillOptions::default(),
|
|
||||||
&mut buffers,
|
|
||||||
)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let _ = result.expect("Tessellate path");
|
let _ = result.expect("Tessellate path");
|
||||||
@ -132,11 +125,11 @@ impl Frame {
|
|||||||
) {
|
) {
|
||||||
use lyon::tessellation::{BuffersBuilder, FillOptions};
|
use lyon::tessellation::{BuffersBuilder, FillOptions};
|
||||||
|
|
||||||
|
let Fill { color, rule } = fill.into();
|
||||||
|
|
||||||
let mut buffers = BuffersBuilder::new(
|
let mut buffers = BuffersBuilder::new(
|
||||||
&mut self.buffers,
|
&mut self.buffers,
|
||||||
FillVertex(match fill.into() {
|
FillVertex(color.into_linear()),
|
||||||
Fill::Color(color) => color.into_linear(),
|
|
||||||
}),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
let top_left =
|
let top_left =
|
||||||
@ -151,7 +144,7 @@ impl Frame {
|
|||||||
|
|
||||||
let _ = lyon::tessellation::basic_shapes::fill_rectangle(
|
let _ = lyon::tessellation::basic_shapes::fill_rectangle(
|
||||||
&lyon::math::Rect::new(top_left, size.into()),
|
&lyon::math::Rect::new(top_left, size.into()),
|
||||||
&FillOptions::default(),
|
&FillOptions::default().with_fill_rule(rule.into()),
|
||||||
&mut buffers,
|
&mut buffers,
|
||||||
)
|
)
|
||||||
.expect("Fill rectangle");
|
.expect("Fill rectangle");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user