mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-08 07:11:31 +00:00
Symbols: Reset Transformation's enabled check does not measure the symbol's art
This commit is contained in:
@@ -722,9 +722,9 @@ pub use pathops::shape_count;
|
||||
/// The gaps View › Show Live Paint Gaps shows on a Live Paint group.
|
||||
pub use buildcmds::live_paint_gaps;
|
||||
|
||||
/// The transform Reset Transformation gives a symbol instance (the Symbols panel menu and the
|
||||
/// Control bar enable it when there is one).
|
||||
pub use brushsym::reset_transformation;
|
||||
/// Whether Reset Transformation changes a symbol instance (the Symbols panel menu and the
|
||||
/// Control bar enable it when it changes one).
|
||||
pub use brushsym::reset_transformation_changes;
|
||||
|
||||
/// Command ids kept only so older scripts keep working: `(alias, the command it duplicates)`.
|
||||
/// They run as before but the command palette leaves them out (it lists the command once).
|
||||
|
||||
@@ -24,8 +24,8 @@ use super::{
|
||||
};
|
||||
use crate::EngineError;
|
||||
|
||||
/// The transform Reset Transformation gives a symbol instance.
|
||||
pub use symbols::reset_transformation;
|
||||
/// Whether Reset Transformation changes a symbol instance.
|
||||
pub use symbols::reset_transformation_changes;
|
||||
|
||||
mod brushes;
|
||||
mod dynamic;
|
||||
|
||||
@@ -702,22 +702,32 @@ const RESET_TOLERANCE: f64 = 1e-9;
|
||||
|
||||
/// The transform Reset Transformation gives instance `n` of the document of `boxes`: its symbol's
|
||||
/// own scale, without rotation, shear or reflection, with the center of its art's bounding box
|
||||
/// where it is. `None` when `n` is not an instance of a symbol the document holds, is in
|
||||
/// perspective, or already has that transform.
|
||||
pub fn reset_transformation(boxes: &vectorcraft_doc::SymbolBoxes, n: &Node) -> Option<Affine> {
|
||||
/// where it is. `None` when [`reset_transformation_changes`] is false for `n`.
|
||||
fn reset_transformation(boxes: &vectorcraft_doc::SymbolBoxes, n: &Node) -> Option<Affine> {
|
||||
let d = boxes.document();
|
||||
let NodeKind::SymbolInstance { symbol, xf } = &n.kind else { return None };
|
||||
if n.extras().perspective.is_some() || !d.symbols.iter().any(|s| s.name == *symbol) {
|
||||
if !reset_transformation_changes(d, n) {
|
||||
return None;
|
||||
}
|
||||
// The symbol's stored natural size, or the art unscaled when that size is not positive and finite.
|
||||
let NodeKind::SymbolInstance { symbol, xf } = &n.kind else { return None };
|
||||
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));
|
||||
let center = xf.transform_rect_bbox(art).center();
|
||||
let new = Affine::translate(center - scale * art.center()) * scale;
|
||||
xf.as_coeffs().iter().zip(new.as_coeffs()).any(|(a, b)| (a - b).abs() > RESET_TOLERANCE).then_some(new)
|
||||
Some(Affine::translate(center - scale * art.center()) * scale)
|
||||
}
|
||||
|
||||
/// Does Reset Transformation change `n`? True for an instance of a symbol `d` holds, not in
|
||||
/// perspective, whose scale, rotation, shear or reflection differs from the symbol's own scale
|
||||
/// (its stored natural size, or the art unscaled when that size is not positive and finite).
|
||||
/// It does not measure the art.
|
||||
pub fn reset_transformation_changes(d: &Document, n: &Node) -> bool {
|
||||
let NodeKind::SymbolInstance { symbol, xf } = &n.kind else { return false };
|
||||
if n.extras().perspective.is_some() || !d.symbols.iter().any(|s| s.name == *symbol) {
|
||||
return false;
|
||||
}
|
||||
let natural = d.symbol_natural_xf(symbol).as_coeffs();
|
||||
xf.as_coeffs()[..4].iter().zip(&natural[..4]).any(|(a, b)| (a - b).abs() > RESET_TOLERANCE)
|
||||
}
|
||||
|
||||
pub(super) fn symbol_instance_reset_transform(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
|
||||
@@ -164,8 +164,7 @@ pub(crate) fn changed_instances_selected(app: &VectorcraftApp) -> bool {
|
||||
/// symbol's, which Reset Transformation restores?
|
||||
fn transformed_instances_selected(app: &VectorcraftApp) -> bool {
|
||||
let Some(doc) = app.session.active().map(|st| st.doc.clone()) else { return false };
|
||||
let boxes = doc.symbol_boxes();
|
||||
instance_selected(app, |c| vectorcraft_engine::cmd::reset_transformation(&boxes, c).is_some())
|
||||
instance_selected(app, |c| vectorcraft_engine::cmd::reset_transformation_changes(&doc, c))
|
||||
}
|
||||
|
||||
/// The symbols of the selected objects when every one is a symbol instance; `None` otherwise.
|
||||
|
||||
Reference in New Issue
Block a user