diff options
author | 2022-01-27 09:40:52 -0800 | |
---|---|---|
committer | 2022-01-27 09:40:52 -0800 | |
commit | e835cea03c5d6eeba2d76b52206516dcc2a6b628 (patch) | |
tree | b54e2c27925284e16230f5d1eaf76ea9afe86860 /graphics | |
parent | 4aa943cbc63230dfcb995c469ceec9f74e6132e1 (diff) | |
download | iced-e835cea03c5d6eeba2d76b52206516dcc2a6b628.tar.gz iced-e835cea03c5d6eeba2d76b52206516dcc2a6b628.tar.bz2 iced-e835cea03c5d6eeba2d76b52206516dcc2a6b628.zip |
Add line dash API
Diffstat (limited to 'graphics')
-rw-r--r-- | graphics/Cargo.toml | 6 | ||||
-rw-r--r-- | graphics/src/widget/canvas.rs | 2 | ||||
-rw-r--r-- | graphics/src/widget/canvas/frame.rs | 9 | ||||
-rw-r--r-- | graphics/src/widget/canvas/path.rs | 44 | ||||
-rw-r--r-- | graphics/src/widget/canvas/stroke.rs | 14 |
5 files changed, 72 insertions, 3 deletions
diff --git a/graphics/Cargo.toml b/graphics/Cargo.toml index 12f38cce..07a19807 100644 --- a/graphics/Cargo.toml +++ b/graphics/Cargo.toml @@ -11,7 +11,7 @@ keywords = ["gui", "ui", "graphics", "interface", "widgets"] categories = ["gui"] [features] -canvas = ["lyon"] +canvas = ["lyon", "lyon_algorithms"] qr_code = ["qrcode", "canvas"] font-source = ["font-kit"] font-fallback = [] @@ -39,6 +39,10 @@ path = "../style" version = "0.17" optional = true +[dependencies.lyon_algorithms] +version = "0.17" +optional = true + [dependencies.qrcode] version = "0.12" optional = true diff --git a/graphics/src/widget/canvas.rs b/graphics/src/widget/canvas.rs index f9722f33..1016bbe3 100644 --- a/graphics/src/widget/canvas.rs +++ b/graphics/src/widget/canvas.rs @@ -35,7 +35,7 @@ pub use frame::Frame; pub use geometry::Geometry; pub use path::Path; pub use program::Program; -pub use stroke::{LineCap, LineJoin, Stroke}; +pub use stroke::{LineCap, LineDash, LineJoin, Stroke}; pub use text::Text; /// A widget capable of drawing 2D graphics. diff --git a/graphics/src/widget/canvas/frame.rs b/graphics/src/widget/canvas/frame.rs index 4873e7fb..b98c3002 100644 --- a/graphics/src/widget/canvas/frame.rs +++ b/graphics/src/widget/canvas/frame.rs @@ -1,6 +1,9 @@ +use std::borrow::Cow; + use iced_native::{Point, Rectangle, Size, Vector}; use crate::{ + canvas::path, canvas::{Fill, Geometry, Path, Stroke, Text}, triangle, Primitive, }; @@ -164,6 +167,12 @@ impl Frame { options.end_cap = stroke.line_cap.into(); options.line_join = stroke.line_join.into(); + let path = if stroke.line_dash.segments.is_empty() { + Cow::Borrowed(path) + } else { + Cow::Owned(path::dashed(path, stroke.line_dash)) + }; + let result = if self.transforms.current.is_identity { self.stroke_tessellator.tessellate_path( path.raw(), diff --git a/graphics/src/widget/canvas/path.rs b/graphics/src/widget/canvas/path.rs index 4e4fd734..b52c1f90 100644 --- a/graphics/src/widget/canvas/path.rs +++ b/graphics/src/widget/canvas/path.rs @@ -7,7 +7,11 @@ mod builder; pub use arc::Arc; pub use builder::Builder; +use crate::canvas::LineDash; + use iced_native::{Point, Size}; +use lyon::path::iterator::PathIterator; +use lyon_algorithms::walk::{walk_along_path, RepeatedPattern}; /// An immutable set of points that may or may not be connected. /// @@ -66,3 +70,43 @@ impl Path { } } } + +pub(super) fn dashed(path: &Path, line_dash: LineDash) -> Path { + let segments_odd = line_dash.segments.len() % 2 == 1; + + let segments = segments_odd + .then(|| [&line_dash.segments[..], &line_dash.segments[..]].concat()) + .unwrap_or(line_dash.segments); + + let mut points = vec![]; + + walk_along_path( + path.raw().iter().flattened(0.01), + 0.0, + &mut RepeatedPattern { + callback: |position: lyon_algorithms::math::Point, + _tangent, + _distance| { + points.push(Point { + x: position.x, + y: position.y, + }); + true + }, + index: line_dash.offset, + intervals: &segments, + }, + ); + + Path::new(|builder| { + for (idx, point) in points.into_iter().enumerate() { + let is_even = idx % 2 == 0; + + if is_even { + builder.move_to(point); + } else { + builder.line_to(point); + } + } + }) +} diff --git a/graphics/src/widget/canvas/stroke.rs b/graphics/src/widget/canvas/stroke.rs index 9f0449d0..5c20405e 100644 --- a/graphics/src/widget/canvas/stroke.rs +++ b/graphics/src/widget/canvas/stroke.rs @@ -1,7 +1,7 @@ use iced_native::Color; /// The style of a stroke. -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone)] pub struct Stroke { /// The color of the stroke. pub color: Color, @@ -12,6 +12,8 @@ pub struct Stroke { /// The shape to be used at the corners of paths or basic shapes when they /// are stroked. pub line_join: LineJoin, + /// The dash pattern used when stroking the line. + pub line_dash: LineDash, } impl Stroke { @@ -43,6 +45,7 @@ impl Default for Stroke { width: 1.0, line_cap: LineCap::default(), line_join: LineJoin::default(), + line_dash: LineDash::default(), } } } @@ -103,3 +106,12 @@ impl From<LineJoin> for lyon::tessellation::LineJoin { } } } + +/// The dash pattern used when stroking the line. +#[derive(Debug, Clone, Default)] +pub struct LineDash { + /// The alternating lengths of lines and gaps which describe the pattern. + pub segments: Vec<f32>, + /// The offset of [`LineDash::segments`] to start the pattern. + pub offset: usize, +} |