diff --git a/crates/engine/src/cmd/paths/closed.rs b/crates/engine/src/cmd/paths/closed.rs index 12ccb10ac..5689020d3 100644 --- a/crates/engine/src/cmd/paths/closed.rs +++ b/crates/engine/src/cmd/paths/closed.rs @@ -120,6 +120,8 @@ pub(super) fn toggle_closed(s: &mut Session, _: &Value) -> Result { if path.closed == closed { continue; } + // As `mask.setClosed`: a path read from a file may have fewer tangents than vertices (#1250). + path.fit_tangents(); path.closed = closed; if roto { super::roto_smooth(&mut path); diff --git a/crates/engine/src/tests/viewer.rs b/crates/engine/src/tests/viewer.rs index 45517e3cd..19d96a75e 100644 --- a/crates/engine/src/tests/viewer.rs +++ b/crates/engine/src/tests/viewer.rs @@ -527,6 +527,25 @@ fn toggle_closed_recomputes_roto_bezier_tangents() { assert_eq!(path(&s), closed, "reclosing restores the closed RotoBezier tangents"); } +#[test] +fn toggle_closed_fits_short_tangent_lists_like_set_closed() { + let mut s = comp(); + let lid = s.execute("layer.newSolid", json!({})).unwrap()["layer"].as_u64().unwrap(); + let uid = s.execute("mask.new", json!({"layer": lid, "vertices": [[0, 0], [100, 0], [100, 100]], "closed": true})).unwrap()["mask"].as_u64().unwrap(); + let cid = s.active_comp_id().unwrap(); + let layer_mut = std::sync::Arc::make_mut(&mut s.project).comp_mut(cid).unwrap().layer_mut(LayerId(lid)).unwrap(); + let prop = layer_mut.props.find_group_mut(uid).unwrap().get_mut("path").unwrap(); + let KV::Path(path) = &mut prop.value else { panic!("not a path") }; + // A file can store fewer tangents than vertices (#1250). + path.in_tangents.clear(); + path.out_tangents.truncate(1); + s.state.selected_props = vec![(LayerId(lid), uid)]; + s.execute("path.toggleClosed", json!({})).unwrap(); + let path = layer(&s, lid).props.find_group(uid).unwrap().get("path").unwrap().value.as_path().unwrap().clone(); + assert!(!path.closed); + assert_eq!((path.in_tangents.len(), path.out_tangents.len()), (3, 3)); +} + #[test] fn toggle_closed_edits_layer_time_and_roundtrips() { use effectcraft_keyframe::Keyframe;