diff --git a/crates/engine/src/cmd/layer/create.rs b/crates/engine/src/cmd/layer/create.rs index 64b850558..621ae866b 100644 --- a/crates/engine/src/cmd/layer/create.rs +++ b/crates/engine/src/cmd/layer/create.rs @@ -279,6 +279,7 @@ fn anchor_param(p: &Value, cmd: &str) -> Result> { None | Some(Value::Null) => Ok(None), Some(v) => v .as_array() + .filter(|a| a.len() == 2) .and_then(|a| Some([a.first()?.as_f64()?, a.get(1)?.as_f64()?])) .filter(|c| c.iter().all(|x| x.is_finite() && x.abs() <= MAX_PLACEMENT)) .map(Some) @@ -361,12 +362,13 @@ pub(super) fn add_item(s: &mut Session, p: &Value) -> Result { l.out_point = fr.snap_nearest(end).max(start + fr.frame_duration()); // `in` / `out` are comp times like `layer.timing`'s; each keeps at least one frame. let fd = fr.frame_duration(); - if let Some(o) = out_p { - l.out_point = fr.snap_nearest(o).max(l.in_point + fd); - } + // In first, as `layer.timing` does, so an `out` before the layer's start still lands. if let Some(i) = in_p { l.in_point = fr.snap_nearest(i).min(l.out_point - fd); } + if let Some(o) = out_p { + l.out_point = fr.snap_nearest(o).max(l.in_point + fd); + } place(&mut l, position); set_anchor(&mut l, anchor); insert_layer_at(proj, st, cid, l, index) diff --git a/crates/engine/src/tests/add_item_options.rs b/crates/engine/src/tests/add_item_options.rs index 76e27c65c..b21e863b0 100644 --- a/crates/engine/src/tests/add_item_options.rs +++ b/crates/engine/src/tests/add_item_options.rs @@ -82,3 +82,12 @@ fn invalid_values_are_errors_and_change_nothing() { } assert_eq!(s.active_comp().unwrap().layers.len(), n); } + +/// `in` applies before `out` (as `layer.timing`), so a range before the layer's start lands as asked. +#[test] +fn in_and_out_before_the_start_land_and_a_three_value_anchor_is_refused() { + let (mut s, item, _) = setup(); + let id = s.execute_checked("layer.addItem", json!({"item": item, "time": 5.0, "in": 1.0, "out": 2.0})).unwrap()["layer"].as_u64().unwrap(); + assert_eq!((secs(layer(&s, id).in_point), secs(layer(&s, id).out_point)), (1.0, 2.0)); + assert!(s.execute_checked("layer.addItem", json!({"item": item, "anchor": [1.0, 2.0, 3.0]})).is_err()); +}