mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-13 08:29:14 +00:00
Merge pull request #6937 from dotCooCoo/fix/artboard-new-subpoint-sides
Artboards: artboard.new keeps a side below 1 pt as given
This commit is contained in:
@@ -850,14 +850,23 @@ fn move_node(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
ok()
|
||||
}
|
||||
|
||||
fn rect_from(p: &Value, default: Rect) -> Rect {
|
||||
/// The rectangle from `x`, `y`, `width` and `height`, each defaulting to `default`'s. Sides are kept as given.
|
||||
fn rect_unclamped(p: &Value, default: Rect) -> Rect {
|
||||
let x = f64_or(p, "x", default.x0);
|
||||
let y = f64_or(p, "y", default.y0);
|
||||
let w = f64_or(p, "width", default.width()).max(1.0);
|
||||
let h = f64_or(p, "height", default.height()).max(1.0);
|
||||
let w = f64_or(p, "width", default.width());
|
||||
let h = f64_or(p, "height", default.height());
|
||||
Rect::new(x, y, x + w, y + h)
|
||||
}
|
||||
|
||||
/// [`rect_unclamped`] with each supplied side raised to at least 1 pt, as `artboard.setProps` uses it.
|
||||
/// A side left out keeps `default`'s, even below 1 pt.
|
||||
fn rect_from(p: &Value, default: Rect) -> Rect {
|
||||
let r = rect_unclamped(p, default);
|
||||
let floor = |key: &str, side: f64| if p.get(key).and_then(Value::as_f64).is_some() { side.max(1.0) } else { side };
|
||||
Rect::new(r.x0, r.y0, r.x0 + floor("width", r.width()), r.y0 + floor("height", r.height()))
|
||||
}
|
||||
|
||||
/// An artboard command's `color` param, its background color: None when absent, `Some(None)` for
|
||||
/// null (no color), else `Some(Some(color))`.
|
||||
fn artboard_color(p: &Value, cmd: &str) -> Result<Option<Option<vectorcraft_color::Color>>> {
|
||||
@@ -942,7 +951,7 @@ fn artboard_new(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
src + side.offset(src)
|
||||
}
|
||||
None if p.get("beside").is_some_and(|v| !v.is_null()) => return Err(bad("artboard.new", "`beside` needs `side`")),
|
||||
None => rect_from(p, def),
|
||||
None => rect_unclamped(p, def),
|
||||
};
|
||||
// A size taken from another artboard (`side`, or width or height left out) keeps to the limit too.
|
||||
if !super::newdoc::side_in_range(r.width()) || !super::newdoc::side_in_range(r.height()) {
|
||||
|
||||
@@ -291,6 +291,20 @@ fn file_new_and_artboard_new_take_the_same_largest_side() {
|
||||
assert!(err.contains(in_meters), "{p}: {err}");
|
||||
}
|
||||
assert_eq!(boards(&s).len(), 2);
|
||||
|
||||
// A side below 1 pt is kept as given, as file.new keeps it, and a size taken from such an artboard keeps it too.
|
||||
let mut s = new_doc(json!({"width": 0.5, "height": 0.25}));
|
||||
assert_eq!(boards(&s), [Rect::new(0.0, 0.0, 0.5, 0.25)]);
|
||||
s.execute("artboard.new", &json!({"x": 0, "y": 10, "width": 0.5, "height": 0.75})).unwrap();
|
||||
s.execute("artboard.new", &json!({"x": 0, "y": 20})).unwrap();
|
||||
assert_eq!(boards(&s)[1..], [Rect::new(0.0, 10.0, 0.5, 10.75), Rect::new(0.0, 20.0, 0.5, 20.75)]);
|
||||
// artboard.setProps keeps such sides when it changes something else, on a locked artboard too,
|
||||
// and still raises a supplied side to 1 pt.
|
||||
s.execute("artboard.setProps", &json!({"index": 1, "name": "Small"})).unwrap();
|
||||
s.execute("artboard.setProps", &json!({"index": 2, "locked": true})).unwrap();
|
||||
s.execute("artboard.setProps", &json!({"index": 2, "name": "Small locked"})).unwrap();
|
||||
s.execute("artboard.setProps", &json!({"index": 0, "height": 0.5})).unwrap();
|
||||
assert_eq!(boards(&s), [Rect::new(0.0, 0.0, 0.5, 1.0), Rect::new(0.0, 10.0, 0.5, 10.75), Rect::new(0.0, 20.0, 0.5, 20.75)]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user