M4: text on a path takes a fill binding made through fills

The bindings that move with the path's fills and effects are now found with list_binding, which reads `fills` as the first fill's color, as style_sets in cmd/styles.rs does.
This commit is contained in:
dotCooCoo
2026-10-24 14:02:50 -07:00
parent 949d6c2830
commit 0978b44385
2 changed files with 19 additions and 1 deletions
+5 -1
View File
@@ -148,7 +148,11 @@ fn on_path(s: &mut Session, p: &Value) -> Result<Value> {
let (transform, w, h) = (pn.transform, pn.width, pn.height);
let fills = pn.fills.iter().any(|f| f.visible).then(|| (pn.fills.clone(), pn.styles.fill.clone()));
let effects = (!pn.effects.is_empty()).then(|| (pn.effects.clone(), pn.styles.effect.clone()));
let moved = |k: &str| (fills.is_some() && (k == "fill" || k.starts_with("fills/"))) || (effects.is_some() && k.starts_with("effects/"));
let moved = |k: &str| match super::lists::list_binding(k) {
Some((super::lists::BoundList::Fills, ..)) => fills.is_some(),
Some((super::lists::BoundList::Effects, ..)) => effects.is_some(),
_ => false,
};
let bound: Vec<(String, VariableId)> = pn.bound.iter().filter(|(k, _)| moved(k)).map(|(k, v)| (k.clone(), v.clone())).collect();
let mut tp = TextPath::new(&geom);
tp.start = num(p, "start").filter(|v| v.is_finite()).unwrap_or(0.0).clamp(0.0, 1.0);
+14
View File
@@ -142,6 +142,20 @@ fn text_put_on_a_path_with_an_empty_effect_style_keeps_its_own_effects() {
assert_eq!((&n.effects, &n.styles.effect), (&text.effects, &text.styles.effect), "a path whose effect style draws no effects");
}
#[test]
fn text_put_on_a_path_takes_a_fill_binding_made_through_fills() {
let mut s = Session::new();
let (t, v) = text_and_curve(&mut s, json!({"fill": "#FF0000"}));
s.execute("variable.bind", &json!({"ids": [v], "field": "fills", "variable": "shadow"})).unwrap();
s.execute("variable.bind", &json!({"ids": [t], "field": "fills", "variable": "ink"})).unwrap();
let path = s.doc().unwrap().node(v).unwrap().clone();
assert!(path.bound.contains_key("fills"));
s.execute("text.onPath", &json!({"ids": [t, v]})).unwrap();
let n = s.doc().unwrap().node(t).unwrap();
assert_eq!(n.bound, path.bound, "the path's `fills` binding replaces the text's");
assert_eq!(n.fills, path.fills);
}
#[test]
fn pattern_fills_tile_their_source_live() {
let mut s = Session::new();