mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-31 05:27:08 -06:00
Draw a line to the end point of degenerate SVG arcs
Found while testing crates/svg/src/pathdata.rs:228-233 Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Haiku 5.5
parent
0871135a6b
commit
58fbda40b4
@@ -226,9 +226,16 @@ fn segment(l: &mut Lex, c: u8, base: Vec2, p: &mut BezPath, cur: &mut Point, las
|
||||
let sweep = l.flag()?;
|
||||
let e = pt(l)?;
|
||||
let arc = SvgArc { from: *cur, to: e, radii: Vec2::new(rx, ry), x_rotation: rot.to_radians(), large_arc: large, sweep };
|
||||
match kurbo::Arc::from_svg_arc(&arc) {
|
||||
Some(a) => a.to_cubic_beziers(0.1, |c1, c2, end| p.curve_to(c1, c2, end)),
|
||||
None => p.line_to(e),
|
||||
let mut last_end = None;
|
||||
if let Some(a) = kurbo::Arc::from_svg_arc(&arc) {
|
||||
a.to_cubic_beziers(0.1, |c1, c2, end| {
|
||||
p.curve_to(c1, c2, end);
|
||||
last_end = Some(end);
|
||||
});
|
||||
}
|
||||
// Degenerate arcs (e.g. huge radii) may emit nothing or stop short of the end point.
|
||||
if last_end.is_none_or(|q| (q - e).hypot() > 1e-3 * (1.0 + e.to_vec2().hypot())) {
|
||||
p.line_to(e);
|
||||
}
|
||||
*cur = e;
|
||||
*last_cubic = None;
|
||||
@@ -294,6 +301,18 @@ mod tests {
|
||||
assert!(parse_path_data("M0 0 L10 0 z 9 9").elements().len() <= 4);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn huge_radius_arc_still_reaches_end_point() {
|
||||
for d in ["M0 0 A1e20 1e20 0 0 1 10 0 L10 10", "M0 0 A1e20 1e20 0 1 1 10 0 L10 10", "M0 0 a1e20 1e20 0 0 1 10 0 L10 10"] {
|
||||
let p = parse_path_data(d);
|
||||
let reaches = p.elements().iter().any(|e| match e {
|
||||
PathEl::LineTo(q) | PathEl::CurveTo(_, _, q) => (q.x - 10.0).abs() < 1e-6 && q.y.abs() < 1e-6,
|
||||
_ => false,
|
||||
});
|
||||
assert!(reaches, "{d}: {:?}", p.elements());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn number_lists() {
|
||||
assert_eq!(numbers("0 0,100 50"), vec![0.0, 0.0, 100.0, 50.0]);
|
||||
|
||||
Reference in New Issue
Block a user