Comments (3)
That sounds like a bug in the path sampler. I'll try to have a look soon-ish (no promises, I'm very short on spare time these days).
from lyon.
Just chiming back in to report that the workaround has worked: now I create a new path for every discontinuous segment and sample that (accumulating the results in a single builder) and this seems to be working. Something around these lines:
fn apply_dashes<B: lyon::path::builder::PathBuilder>(
builder: &mut B,
path: lyon::path::Path,
dashes: &Vec<Dash>,
line_width: f32,
) {
use lyon_algorithms::measure::{PathMeasurements, SampleType};
let measurements = PathMeasurements::from_path(&path, 0.001);
let mut sampler = measurements.create_sampler(&path, SampleType::Distance);
let length = sampler.length();
let mut pos = 0.0;
while pos < length {
for dash in dashes {
sampler.split_range(pos..(pos + dash.length * line_width), builder);
pos += dash.length * line_width + dash.gap * line_width;
}
}
}
Which is used like this:
let path = if has_dashes(&r.line_style.dashes) {
let mut dashed = Path::builder();
for shape in r.shapes {
let mut builder = Path::svg_builder();
draw_shape(&mut builder, shape);
apply_dashes(
&mut dashed,
builder.build(),
&r.line_style.dashes,
line_width,
);
}
dashed.build()
} else {
let mut builder = Path::svg_builder();
for shape in r.shapes {
draw_shape(&mut builder, shape);
}
builder.build()
};
from lyon.
A (currently failing) test case for this issue:
#[test]
fn multiple_sub_paths() {
let mut path = Path::builder();
path.begin(point(0.0, 0.0));
path.line_to(point(10.0, 0.0));
path.end(false);
path.begin(point(10.0, 10.0));
path.line_to(point(20.0, 10.0));
path.end(false);
let path = path.build();
let measure = PathMeasurements::from_path(&path, 0.01);
let mut sampler = measure.create_sampler(&path, SampleType::Normalized);
let mut dashes = Path::builder();
sampler.split_range(0.0 .. 0.25, &mut dashes);
sampler.split_range(0.25 .. 0.5, &mut dashes);
sampler.split_range(0.5 .. 0.75, &mut dashes);
sampler.split_range(0.75 .. 1.0, &mut dashes);
let dashes = dashes.build();
let mut iter = dashes.iter();
use crate::path::geom::euclid::approxeq::ApproxEq;
fn expect_begin(event: Option<path::PathEvent>, pos: Point) {
println!("- {:?}", event);
if let Some(path::PathEvent::Begin { at }) = event {
assert!(at.approx_eq(&pos), "Expected Begin {:?}, got {:?}", pos, at);
} else {
panic!("Expected begin, got {:?}", event);
}
}
fn expect_end(event: Option<path::PathEvent>, pos: Point) {
println!("- {:?}", event);
if let Some(path::PathEvent::End { last, .. }) = event {
assert!(last.approx_eq(&pos), "Expected End {:?}, got {:?}", pos, last);
} else {
panic!("Expected end, got {:?}", event);
}
}
fn expect_line(event: Option<path::PathEvent>, expect_from: Point, expect_to: Point) {
println!("- {:?}", event);
if let Some(path::PathEvent::Line { from, to }) = event {
assert!(from.approx_eq(&expect_from), "Expected line {:?} {:?}, got {:?} {:?}", expect_from, expect_to, from, to);
assert!(to.approx_eq(&expect_to), "Expected line {:?} {:?}, got {:?} {:?}", expect_from, expect_to, from, to);
} else {
panic!("Expected a line {:?} {:?}, got {:?}", expect_from, expect_to, event);
}
}
expect_begin(iter.next(), point(0.0, 0.0));
expect_line(iter.next(), point(0.0, 0.0), point(5.0, 0.0));
expect_end(iter.next(), point(5.0, 0.0));
expect_begin(iter.next(), point(5.0, 0.0));
expect_line(iter.next(), point(5.0, 0.0), point(10.0, 0.0));
expect_end(iter.next(), point(10.0, 0.0));
expect_begin(iter.next(), point(10.0, 10.0));
expect_line(iter.next(), point(10.0, 10.0), point(15.0, 10.0));
expect_end(iter.next(), point(15.0, 10.0));
expect_begin(iter.next(), point(15.0, 10.0));
expect_line(iter.next(), point(15.0, 10.0), point(20.0, 10.0));
expect_end(iter.next(), point(20.0, 10.0));
}
from lyon.
Related Issues (20)
- Eliminate internal vertices with `FillRule::NonZero` HOT 1
- hatching error HOT 1
- Help a noob draw a circle on the GPU HOT 2
- Using custom vertex attributes with rounded rectangles. HOT 3
- Finding close point on CubicBezierSegment HOT 3
- Cubic Bezier Segment not matching SVG? HOT 1
- Create git tags (and GitHub releases?) for crates.io releases HOT 6
- hit_test_path seems to report incorrect result with FillRule::EvenOdd HOT 1
- Update wgpu dependency in the examples HOT 2
- debug_assert can panic while not being necessarily justififed HOT 1
- Tesselator doesn't handle intersections between different paths very well HOT 4
- Add `offset` parameter to `HatchingOptions`
- Stroke tessellator seems to produce wrong results for some rounded path types HOT 5
- Lifetime issue when storing Tesselator::builder() in a struct and later resetting it HOT 4
- Stroke tessellator bad triangle HOT 1
- PathParser: can't parse path using scientific notation for numbers.
- (breaking change) Typo "InvalidParamater" in lyon_tessellation
- Is there an example of using custom attributes? HOT 2
- `end_cap` seems to have no effect if its `LineCap::Square` HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from lyon.