Symbols: Reset Transformation keeps the art's size when the stored size is not positive

This commit is contained in:
dotCooCoo
2026-11-08 12:21:14 +07:00
committed by bflatastic
parent 98265b7435
commit 1cd607f596
3 changed files with 24 additions and 2 deletions
+2 -2
View File
@@ -710,8 +710,8 @@ pub fn reset_transformation(boxes: &vectorcraft_doc::SymbolBoxes, n: &Node) -> O
if n.extras().perspective.is_some() || !d.symbols.iter().any(|s| s.name == *symbol) {
return None;
}
let (w, h) = natural_size(d, symbol);
let scale = Affine::scale_non_uniform(w / (2.0 * HALF), h / (2.0 * HALF));
// The symbol's stored natural size, or the art unscaled when that size is not positive and finite.
let scale = d.symbol_natural_xf(symbol);
// The art's box in symbol space (the ±HALF square when the art cannot be measured): its
// center keeps its place on the page.
let art = boxes.art_bounds(symbol).unwrap_or_else(|| vectorcraft_geom::Rect::new(-HALF, -HALF, HALF, HALF));
+21
View File
@@ -1422,6 +1422,27 @@ fn reset_transformation_keeps_the_center_of_art_away_from_the_origin() {
assert!((after.width() - 20.0).abs() < 1e-9 && (after.height() - 20.0).abs() < 1e-9, "{after:?}");
}
/// A stored natural size that is not positive (from a damaged file) does not flatten the instance:
/// Reset Transformation gives it the art's own size, as drawing the symbol does.
#[test]
fn reset_transformation_ignores_a_stored_size_that_is_not_positive() {
let mut s = session();
let r = rect(&mut s, 0.0, 0.0, 20.0, 20.0);
let art = node(&s, r);
s.execute("edit.clear", &json!({"ids": [r.0]})).unwrap();
let st = s.doc_mut().unwrap();
let d = std::sync::Arc::make_mut(&mut st.doc);
d.symbols.push(vectorcraft_doc::Symbol { dynamic: false, name: "Flat".into(), art: std::sync::Arc::new(art) });
d.unknown.insert(vectorcraft_doc::SYMBOL_SIZES.to_string(), json!({"Flat": [0.0, 20.0]}));
let layer = d.layers[0].id;
let id = d.alloc_id();
let xf = vectorcraft_geom::Affine::translate((100.0, 100.0)) * vectorcraft_geom::Affine::rotate(0.5);
d.insert(Some(layer), usize::MAX, Node::new(id, NodeKind::SymbolInstance { symbol: "Flat".into(), xf })).unwrap();
assert_eq!(s.execute("symbol.instance.resetTransform", &json!({"ids": [id.0]})).unwrap()["ids"], json!([id.0]));
let after = s.doc().unwrap().doc.bounds_of(&[id], false).unwrap();
assert!((after.width() - 20.0).abs() < 1e-9 && (after.height() - 20.0).abs() < 1e-9, "{after:?}");
}
/// Reset Transformation adds no undo step for an instance already at its symbol's scale or for
/// one in perspective, and refuses an id naming no object and objects without an instance,
/// changing nothing.