diff --git a/crates/engine/src/graphics.rs b/crates/engine/src/graphics.rs index b7e57625a..6a69369ac 100644 --- a/crates/engine/src/graphics.rs +++ b/crates/engine/src/graphics.rs @@ -124,13 +124,15 @@ pub(crate) fn place_video_clip( (q.settings.width, q.settings.height, q.settings.frame_rate) }; let (src, dur) = source(pr, (w, h, rate)); + // an imported picture (`graphics.newFromFile`) keeps its own size: centre its anchor in it + let src_size = pr.source_size(src).unwrap_or((w, h)); let t = rate.snap(t); let dur = dur.max(rate.frame_duration()); let mut ti = pr.make_track_item(src, TrackKind::Video, t, TimeRange::new(Tick::ZERO, dur), rate).ok_or_else(|| bad("graphics.newText", "bad item"))?; ti.name = name; ti.effects.extend(extra); for e in &mut ti.effects { - filmcraft_project::resolve_auto_points(e, (w, h), (w, h)); + filmcraft_project::resolve_auto_points(e, (w, h), src_size); } let id = ti.id; let track_id = filmcraft_project::TrackId(pr.alloc_id()); diff --git a/crates/engine/src/graphics_tests.rs b/crates/engine/src/graphics_tests.rs index 10ae78527..33fe00947 100644 --- a/crates/engine/src/graphics_tests.rs +++ b/crates/engine/src/graphics_tests.rs @@ -369,6 +369,9 @@ fn new_layer_from_file_places_the_image_above() { assert_eq!(it.start, q.settings.frame_rate.snap(t)); let ti = q.video_tracks.iter().position(|tr| tr.id == tid).unwrap(); assert!(q.video_tracks[..ti].iter().any(|tr| tr.item_at(t).is_some()), "above the footage"); + // the anchor is the picture's centre, not the frame's, so `position` places the picture + let anchor = it.effect("motion").unwrap().vec2_at("anchor", Tick::ZERO); + assert_eq!((anchor.x, anchor.y), (w as f64 / 2.0, h as f64 / 2.0)); assert_eq!(s.state.selection, vec![clip]); assert!(s.execute("graphics.newFromFile", json!({})).is_err()); let _ = std::fs::remove_dir_all(&dir);