diff --git a/crates/doc/src/blend.rs b/crates/doc/src/blend.rs index d25be2c41..5ea0ff9bd 100644 --- a/crates/doc/src/blend.rs +++ b/crates/doc/src/blend.rs @@ -904,12 +904,16 @@ pub struct Spine { cum: Vec, anchors: Vec, closed: bool, - path: PathData, + /// The subpath the spine was flattened from, kept so [`Spine::at_length`] can read the + /// original curves' tangents. Only the first subpath is stored: the others never affect a + /// spine. + subpath: SubPath, } impl Spine { /// Build a spine from the first subpath of `path`: flatten it to a polyline, record cumulative - /// arc lengths, and the arc length at each anchor. + /// arc lengths, and the arc length at each anchor. `None` when `path` has no subpath, or when + /// the first one flattens to fewer than two points (so it has no length to walk). pub fn new(path: &PathData) -> Option { let sp = path.subpaths.first()?; let mut pts: Vec = Vec::new(); @@ -946,7 +950,7 @@ impl Spine { if pts.len() < 2 { return None; } - Some(Self { pts, cum, anchors, closed: sp.closed, path: path.clone() }) + Some(Self { pts, cum, anchors, closed: sp.closed, subpath: sp.clone() }) } /// The spine's flattened length in arc length. pub fn length(&self) -> f64 { @@ -1012,7 +1016,7 @@ impl Spine { /// `Align to Path` jump between chords instead of following the curve smoothly. pub fn at_length(&self, s: f64) -> (Point, f64) { let s = if s.is_finite() { s.clamp(0.0, self.length()) } else { 0.0 }; - let Some(sp) = self.path.subpaths.first() else { return (self.pts.first().copied().unwrap_or_default(), 0.0) }; + let sp = &self.subpath; let n = sp.segment_count(); let mut start = 0.0; for i in 0..n {