mirror of
https://github.com/storytold/deckcraft.git
synced 2026-10-24 10:37:03 -06:00
Limit shape.setBounds, shape.resize and shape.move size and position
Found while testing crates/engine/src/cmd/shape.rs:215 (set_bounds; shape.resize at :~183 and shape.move at :~171 have the same problem) Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com> Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com> Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Haiku 5.5
parent
22db9261f9
commit
3e729bbf08
@@ -169,13 +169,23 @@ pub fn specs() -> Vec<CommandSpec> {
|
||||
]
|
||||
}
|
||||
|
||||
/// Keeps a side length in `0..=MAX_PT` so a huge value cannot exhaust memory when rendering.
|
||||
fn clamp_side(v: f64) -> f64 {
|
||||
if v.is_finite() { v.clamp(0.0, MAX_PT) } else { 0.0 }
|
||||
}
|
||||
|
||||
/// Keeps a coordinate within `±POS_LIMIT`.
|
||||
fn clamp_pos(v: f64) -> f64 {
|
||||
if v.is_finite() { v.clamp(-POS_LIMIT, POS_LIMIT) } else { 0.0 }
|
||||
}
|
||||
|
||||
fn move_by(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
let (dx, dy) = (f64_param(p, "dx"), f64_param(p, "dy"));
|
||||
let (ax, ay) = (f64_param(p, "x"), f64_param(p, "y"));
|
||||
edit_geometry(s, p, "shape.move", |sh| {
|
||||
if let Some(x) = sh.xfrm.as_mut() {
|
||||
x.x = ax.unwrap_or(x.x) + dx.unwrap_or(0.0);
|
||||
x.y = ay.unwrap_or(x.y) + dy.unwrap_or(0.0);
|
||||
x.x = clamp_pos(ax.unwrap_or(x.x) + dx.unwrap_or(0.0));
|
||||
x.y = clamp_pos(ay.unwrap_or(x.y) + dy.unwrap_or(0.0));
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
@@ -202,6 +212,8 @@ fn resize(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
x.h = h.unwrap_or(x.h);
|
||||
}
|
||||
}
|
||||
x.w = clamp_side(x.w);
|
||||
x.h = clamp_side(x.h);
|
||||
// Rotated shapes resize about their centre; others keep the top-left.
|
||||
if x.rot != 0.0 {
|
||||
x.x = cx - x.w / 2.0;
|
||||
@@ -215,10 +227,10 @@ fn resize(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
fn set_bounds(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
edit_geometry(s, p, "shape.setBounds", |sh| {
|
||||
if let Some(x) = sh.xfrm.as_mut() {
|
||||
x.x = f64_param(p, "x").unwrap_or(x.x);
|
||||
x.y = f64_param(p, "y").unwrap_or(x.y);
|
||||
x.w = f64_param(p, "w").unwrap_or(x.w).max(0.0);
|
||||
x.h = f64_param(p, "h").unwrap_or(x.h).max(0.0);
|
||||
x.x = clamp_pos(f64_param(p, "x").unwrap_or(x.x));
|
||||
x.y = clamp_pos(f64_param(p, "y").unwrap_or(x.y));
|
||||
x.w = clamp_side(f64_param(p, "w").unwrap_or(x.w));
|
||||
x.h = clamp_side(f64_param(p, "h").unwrap_or(x.h));
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
|
||||
@@ -3623,3 +3623,28 @@ fn table_column_width_of_a_huge_column_is_ignored() {
|
||||
assert_eq!(table_of(&s, id).cols, vec![100.0, 100.0], "no column changes");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shape_geometry_commands_limit_size_and_position() {
|
||||
let mut s = Session::with_new();
|
||||
s.execute("slide.new", &json!({"layout": "blank"})).unwrap();
|
||||
s.execute("shape.insert", &json!({"preset": "moon", "rect": [100, 100, 200, 100]})).unwrap();
|
||||
let xfrm = |s: &Session| s.doc().unwrap().selected_shapes()[0].xfrm.unwrap();
|
||||
let within = |s: &Session| {
|
||||
let x = xfrm(s);
|
||||
[x.w, x.h].iter().all(|v| v.is_finite() && (0.0..=15_840.0).contains(v)) && [x.x, x.y].iter().all(|v| v.is_finite() && v.abs() <= 100_000.0)
|
||||
};
|
||||
s.execute("shape.setBounds", &json!({"x": 1e100, "y": -1e100, "w": 100000, "h": 1e100})).unwrap();
|
||||
let x = xfrm(&s);
|
||||
assert!(within(&s), "setBounds stored {x:?}");
|
||||
s.execute("shape.resize", &json!({"w": 10, "h": 10})).unwrap();
|
||||
s.execute("shape.resize", &json!({"h": 1e100})).unwrap();
|
||||
let x = xfrm(&s);
|
||||
assert!(within(&s), "resize stored {x:?}");
|
||||
s.execute("shape.resize", &json!({"h": 1e100, "lockAspect": true})).unwrap();
|
||||
let x = xfrm(&s);
|
||||
assert!(within(&s), "locked resize stored {x:?}");
|
||||
s.execute("shape.move", &json!({"x": 1e100, "y": -1e100})).unwrap();
|
||||
let x = xfrm(&s);
|
||||
assert!(within(&s), "move stored {x:?}");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user