mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-11 16:33:22 -06:00
G4: Scale Text Attributes bakes transform scale into type sizes
After scaling groups, type.scaleTextAttributes matches panel sizes to what draws on canvas without leaving scale in the affine. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
committed by
bflatastic
co-authored by
Cursor
parent
240d8d4891
commit
07a49d447d
@@ -34,6 +34,15 @@ pub fn specs() -> Vec<CommandSpec> {
|
||||
has_selection,
|
||||
create_outlines
|
||||
),
|
||||
cmd!(
|
||||
"type.scaleTextAttributes",
|
||||
"Scale Text Attributes",
|
||||
["Type"],
|
||||
None,
|
||||
"{ids?|id?} bake each selected type object's transform scale into its character sizes (leading, baseline shift and horizontal scale included), leaving rotation and position in the affine → {ids, changed}",
|
||||
scale_text_attributes_enabled,
|
||||
scale_text_attributes
|
||||
),
|
||||
cmd!(
|
||||
"type.opticalMarginAlignment",
|
||||
"Optical Margin Alignment",
|
||||
@@ -386,6 +395,42 @@ fn text_ids(d: &Document, ids: &[NodeId]) -> Vec<NodeId> {
|
||||
out
|
||||
}
|
||||
|
||||
fn scale_text_attributes_enabled(s: &Session) -> std::result::Result<(), String> {
|
||||
has_selection(s)?;
|
||||
let st = s.active().ok_or("no document open")?;
|
||||
let ids = text_ids(&st.doc, &st.selection.objects);
|
||||
if ids.iter().any(|id| {
|
||||
st.doc.node(*id).is_some_and(|n| {
|
||||
let NodeKind::Text(t) = &n.kind else { return false };
|
||||
t.style_scale().is_some_and(|sc| (sc.points - 1.0).abs() > 1e-12 || (sc.horizontal - 1.0).abs() > 1e-12)
|
||||
})
|
||||
}) {
|
||||
Ok(())
|
||||
} else {
|
||||
Err("Scale Text Attributes: selected type has no scale to bake".into())
|
||||
}
|
||||
}
|
||||
|
||||
fn scale_text_attributes(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
const C: &str = "type.scaleTextAttributes";
|
||||
let ids = text_targets(s, p, C)?;
|
||||
let changed = s.edit("Scale Text Attributes", |d, _| {
|
||||
let mut n = 0usize;
|
||||
for id in &ids {
|
||||
let Some(NodeKind::Text(t)) = d.node_mut(*id).map(|node| &mut node.kind) else { continue };
|
||||
if t.scale_text_attributes() {
|
||||
refresh_bounds(t);
|
||||
n += 1;
|
||||
}
|
||||
}
|
||||
if n == 0 {
|
||||
return Err(EngineError::Other("Scale Text Attributes: selected type has no scale to bake".into()));
|
||||
}
|
||||
Ok(n)
|
||||
})?;
|
||||
Ok(json!({ "ids": ids.iter().map(|i| i.0).collect::<Vec<_>>(), "changed": changed }))
|
||||
}
|
||||
|
||||
fn create_outlines(s: &mut Session, _: &Value) -> Result<Value> {
|
||||
let roots = selected_roots(s)?;
|
||||
let ids = s.edit("Create Outlines", |d, sel| {
|
||||
|
||||
Reference in New Issue
Block a user