A text's path becomes construction (#1119)

sketch.text and sketch.edit_text make the curve a text follows construction in the same undo step, so it no longer cuts the letters into pieces; the reply names the curve as guide.
This commit is contained in:
phanoob authored and GitHub committed 2026-10-14 13:24:23 -04:00
1 parent ed943a74e6
commit 6ebfcd16b6
3 files changed
+63 -3

No files matched your search

+21 -3
View File
@@ -8,7 +8,7 @@ use solidcraft_sketch::{ConstraintKind, CurveKind, LinkKind, LinkSource, Sketch,
/// The style parameters of `sketch.text` and `sketch.edit_text`.
macro_rules! text_style_doc {
() => {
"bold?, italic?: bool (an installed family's bold or italic face; italic without one is slanted), align?: left|center|right (the lines against `at`, or along the path), letter_spacing?: extra mm between letters, line_spacing?: times the font's line distance (default 1), path?: a curve id of the sketch the baseline follows (\"\": none; `at` and `angle` then do not place the text), reverse?: bool (the other way along the path)"
"bold?, italic?: bool (an installed family's bold or italic face; italic without one is slanted), align?: left|center|right (the lines against `at`, or along the path), letter_spacing?: extra mm between letters, line_spacing?: times the font's line distance (default 1), path?: a curve id of the sketch the baseline follows (\"\": none; `at` and `angle` then do not place the text; the curve becomes construction, a guide the letters stand on), reverse?: bool (the other way along the path)"
};
}
@@ -209,11 +209,28 @@ fn text(s: &mut Session, p: &Value) -> Result<Value> {
if geom.is_empty() {
return Err(bad(cmd, "the text makes no outline"));
}
let guide = guide(&mut sk, &src);
let l = sk.add_link(LinkKind::Text, src, &geom)?;
let curves = ids_of(&sk, &sk.link_curves(&l));
*doc.sketch_mut(id)? = sk;
*s.doc_mut() = doc;
Ok(json!({"link": l, "curves": curves}))
Ok(json!({"link": l, "curves": curves, "guide": guide}))
}
/// A text's path is its guide: the curve it follows becomes construction. Left as it was, it
/// would cut the letters standing on it (and the ones hanging below it) into pieces, each
/// profile a piece of a letter and of the curve, and picking the text would pick those pieces.
/// Taking the text off the curve leaves the curve as it is. The curve made construction, if any.
fn guide(sk: &mut Sketch, src: &LinkSource) -> Option<String> {
let LinkSource::Text { style, .. } = src else { return None };
let id = style.path.as_ref()?;
let curve = sk.curve_index(id).and_then(|c| sk.curves.get_mut(c))?;
if curve.construction {
return None;
}
curve.construction = true;
curve.centerline = false;
Some(id.clone())
}
/// The text source owning an outline or one of its linked points.
@@ -290,10 +307,11 @@ fn apply_text_edit(sk: &mut Sketch, p: &Value) -> Result<Value> {
if geom.is_empty() {
return Err(bad(cmd, "the text makes no outline"));
}
let guide = guide(sk, &src);
sk.set_link_source(&l, src.clone());
sk.update_link(&l, &geom)?;
let curves = ids_of(sk, &sk.link_curves(&l));
Ok(json!({"link": l, "curves": curves}))
Ok(json!({"link": l, "curves": curves, "guide": guide}))
}
/// The curve ending at point `pi` and the direction leaving it there.