Clamp overflowing geometry to the limit and keep rotated resizes in range

An overflow to infinity (move x=1e308 dx=1e308) now lands on the limit
instead of resetting to 0, and a rotated shape re-centred after a capped
resize stays within POS_LIMIT (CodeRabbit review).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Brandon Thomas
2026-10-18 11:18:16 -04:00
co-authored by Claude Opus 5.5
parent 3e729bbf08
commit efc279d6f2
2 changed files with 14 additions and 4 deletions
+5 -4
View File
@@ -170,13 +170,14 @@ pub fn specs() -> Vec<CommandSpec> {
}
/// Keeps a side length in `0..=MAX_PT` so a huge value cannot exhaust memory when rendering.
/// An overflow to infinity lands on the limit; NaN becomes 0.
fn clamp_side(v: f64) -> f64 {
if v.is_finite() { v.clamp(0.0, MAX_PT) } else { 0.0 }
if v.is_nan() { 0.0 } else { v.clamp(0.0, MAX_PT) }
}
/// 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 }
if v.is_nan() { 0.0 } else { v.clamp(-POS_LIMIT, POS_LIMIT) }
}
fn move_by(s: &mut Session, p: &Value) -> Result<Value> {
@@ -216,8 +217,8 @@ fn resize(s: &mut Session, p: &Value) -> Result<Value> {
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;
x.y = cy - x.h / 2.0;
x.x = clamp_pos(cx - x.w / 2.0);
x.y = clamp_pos(cy - x.h / 2.0);
}
}
Ok(())
+9
View File
@@ -3647,4 +3647,13 @@ fn shape_geometry_commands_limit_size_and_position() {
s.execute("shape.move", &json!({"x": 1e100, "y": -1e100})).unwrap();
let x = xfrm(&s);
assert!(within(&s), "move stored {x:?}");
// A move that overflows to infinity lands on the limit, not back at 0.
s.execute("shape.move", &json!({"x": 1e308, "dx": 1e308})).unwrap();
assert_eq!(xfrm(&s).x, 100_000.0);
// A rotated shape resizes about its centre and still stays inside the limit.
s.execute("shape.setBounds", &json!({"x": 99_000, "y": 0, "w": 10, "h": 10})).unwrap();
s.execute("shape.rotate", &json!({"deg": 45})).unwrap();
s.execute("shape.resize", &json!({"w": 1e100})).unwrap();
let x = xfrm(&s);
assert!(within(&s), "rotated resize stored {x:?}");
}