Fix designCraft 0.18.0: arrowheads point the wrong way on curves whose (#2515)

Fixes #2514.

- crates/doc/src/arrow.rs
- crates/doc/tests/autocraft_regression_2514.rs

Co-authored-by: autocraft-bot[bot] <354215646+autocraft-bot[bot]@users.noreply.github.com>
This commit is contained in:
autocraft-bot[bot] authored and GitHub committed 2026-11-09 12:53:59 +00:00
1 parent bb54c44ad9
commit 57e68009da
2 files changed
+34 -1

No files matched your search

+6 -1
View File
@@ -75,7 +75,12 @@ fn end_of(seg: &PathSeg, at_start: bool) -> (Point, Vec2) {
let mut d = match seg {
PathSeg::Line(l) => l.p1 - l.p0,
PathSeg::Quad(q) => q.deriv().eval(t).to_vec2(),
PathSeg::Cubic(c) => c.deriv().eval(t).to_vec2(),
PathSeg::Cubic(c) => {
// A handle sitting on its anchor has no direction: the tangent then points at the next
// control point of the segment that differs from the end point.
let pts = if at_start { [c.p1 - c.p0, c.p2 - c.p0, c.p3 - c.p0] } else { [c.p3 - c.p2, c.p3 - c.p1, c.p3 - c.p0] };
pts.into_iter().find(|v| v.hypot() >= 1e-9).unwrap_or(Vec2::ZERO)
}
};
if d.hypot() < 1e-9 {
d = seg.end() - seg.start();
@@ -0,0 +1,28 @@
use designcraft_doc::arrow::apply;
use designcraft_doc::geom::BezPath;
use designcraft_doc::geom::kurbo::Shape;
use designcraft_doc::{Arrowhead, Stroke};
#[test]
fn start_head_follows_tangent_when_start_handle_is_missing() {
let mut bp = BezPath::new();
bp.move_to((0.0, 0.0));
bp.curve_to((0.0, 0.0), (100.0, 0.0), (100.0, 100.0));
let st = Stroke { weight: 1.0, start: Arrowhead::Bar, ..Stroke::default() };
let (_, heads) = apply(&bp, &st, false).unwrap();
// The curve leaves heading along +x, so the bar at the start stands upright.
let b = heads[0].path.bounding_box();
assert!(b.height() > b.width() * 3.0, "{b:?}");
}
#[test]
fn end_head_follows_tangent_when_end_handle_is_missing() {
let mut bp = BezPath::new();
bp.move_to((0.0, 0.0));
bp.curve_to((100.0, 0.0), (100.0, 100.0), (100.0, 100.0));
let st = Stroke { weight: 1.0, end: Arrowhead::Bar, ..Stroke::default() };
let (_, heads) = apply(&bp, &st, false).unwrap();
// The curve arrives heading along +y, so the bar at the end lies across, horizontally.
let b = heads[0].path.bounding_box();
assert!(b.width() > b.height() * 3.0, "{b:?}");
}