mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-31 15:48:33 +00:00
Transform: Fit to Comp refuses a scale that overflows (#2198)
A shape's painted bounds can be tiny enough (a 1e-305 px rectangle) that the fit scale overflows to infinity. Non-finite bounds are skipped and a non-finite scale returns an error before anything is written, instead of storing infinity in the document. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
a3a72d48aa
commit
5224414d28
2 files changed
+14
-1
No files matched your search
@@ -89,7 +89,7 @@ pub(super) fn transform_op(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
.map(|l| {
|
||||
let (w, h) = effectcraft_render::source_size(&s.project, l);
|
||||
if fitting && (w == 0 || h == 0) {
|
||||
match effectcraft_render::content_bounds(&ectx, l).filter(|b| b[2] > b[0] && b[3] > b[1]) {
|
||||
match effectcraft_render::content_bounds(&ectx, l).filter(|b| b.iter().all(|v| v.is_finite()) && b[2] > b[0] && b[3] > b[1]) {
|
||||
Some(b) => (l.id, [b[2] - b[0], b[3] - b[1]], [(b[0] + b[2]) / 2.0, (b[1] + b[3]) / 2.0]),
|
||||
None => (l.id, [0.0; 2], [0.0; 2]),
|
||||
}
|
||||
@@ -127,6 +127,10 @@ pub(super) fn transform_op(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
"fitHeight" => (ch / h, ch / h),
|
||||
_ => (cw / w, ch / h),
|
||||
};
|
||||
// A tiny shape's bounds can overflow the scale; refuse rather than write infinity.
|
||||
if !(sx * 100.0).is_finite() || !(sy * 100.0).is_finite() {
|
||||
return Err(EngineError::Other(format!("layer {} is too small to fit to the composition", lid.0)));
|
||||
}
|
||||
let z = |m: &str, d: f64| tr.get(m).map(|p| p.value_at(lt).as_vec3()[2]).unwrap_or(d);
|
||||
let (sz, az) = (z("scale", 100.0), z("anchor", 0.0));
|
||||
set(tr, "scale", KV::Vec3([sx * 100.0, sy * 100.0, sz]));
|
||||
|
||||
@@ -1154,6 +1154,15 @@ fn fit_to_comp_fills_the_comp_with_shape_and_text_bounds() {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fit_to_comp_refuses_a_scale_that_overflows() {
|
||||
let mut s = comp();
|
||||
let a = s.execute("layer.newShape", json!({"kind": "rect", "size": [1e-305, 80]})).unwrap()["layer"].as_u64().unwrap();
|
||||
let before = s.project.clone();
|
||||
assert!(s.execute("layer.transform", json!({"layers": [a], "op": "fit"})).is_err(), "an infinite scale is refused");
|
||||
assert_eq!(s.project, before, "nothing was written");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn duplicated_and_pasted_layers_keep_their_links() {
|
||||
let mut s = comp();
|
||||
|
||||
Reference in new issue
Block a user