mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-09 00:17:42 +00:00
Text styles: loading uses a loop the document has under the names found for it
When the document has a loop of styles and patterns under one set of names, its styles were still matched one by one, so a style could be matched to another copy with the same attributes and the pattern then compared with the wrong style name. Each definition of such a loop is now the document's under the name found for it.
This commit is contained in:
@@ -1044,24 +1044,38 @@ impl Clipboard {
|
||||
// In a loop the document does not have all at once, every definition uses one that is
|
||||
// added under a free name, so each one is added too.
|
||||
let mut fresh = false;
|
||||
// The names in the document of the loop being placed, when it has them all at once.
|
||||
let mut matched: BTreeMap<(Res, String), String> = BTreeMap::new();
|
||||
for (def, looped, starts) in steps {
|
||||
fresh &= looped;
|
||||
if !looped {
|
||||
matched.clear();
|
||||
}
|
||||
// A loop of uses that the document has all at once is known under those names before
|
||||
// its definitions are compared.
|
||||
if let Some(group) = starts {
|
||||
matched.clear();
|
||||
match names_of_loop(d, group, &out.relink) {
|
||||
Some(names) => {
|
||||
for (def, name) in group.iter().zip(names) {
|
||||
let (res, own) = def.key();
|
||||
if own != name {
|
||||
out.relink.renames.entry(res).or_default().insert(own.to_string(), name);
|
||||
out.relink.renames.entry(res).or_default().insert(own.to_string(), name.clone());
|
||||
}
|
||||
matched.insert((res, own.to_string()), name);
|
||||
}
|
||||
fresh = false;
|
||||
}
|
||||
None => fresh = true,
|
||||
}
|
||||
}
|
||||
// A definition of such a loop is the document's under the name found for it.
|
||||
let (res, own) = def.key();
|
||||
if let Some(name) = matched.get(&(res, own.to_string())) {
|
||||
let p = if name == own { Placed::Existing } else { Placed::Reused(name.clone()) };
|
||||
out.placed(res, own, &p);
|
||||
continue;
|
||||
}
|
||||
match def {
|
||||
Def::Style(r, def) => {
|
||||
let mut s = def.clone();
|
||||
|
||||
@@ -945,7 +945,8 @@ fn a_style_and_the_pattern_that_uses_it_load_together() {
|
||||
|
||||
/// A style and the pattern it paints with, whose type is set in that style, are both added when
|
||||
/// the document has a style of that name and attributes but another pattern of that name: the
|
||||
/// copy of the style paints with the copy of the pattern, and a second load adds nothing.
|
||||
/// copy of the style paints with the copy of the pattern, and a second load adds nothing. A loop the
|
||||
/// document has is used under the names it has together.
|
||||
#[test]
|
||||
fn a_style_in_a_loop_is_not_matched_to_a_style_that_paints_with_another_pattern() {
|
||||
let (mut src, id) = session_with_text("Tile");
|
||||
@@ -977,6 +978,20 @@ fn a_style_in_a_loop_is_not_matched_to_a_style_that_paints_with_another_pattern(
|
||||
let r = s.execute("charStyle.load", &load).unwrap();
|
||||
assert_eq!(r["added"], json!([]), "{r}");
|
||||
assert_eq!(s.doc().unwrap().doc, d);
|
||||
// With the loop's style renamed "Accent 3" and an "Accent 2" listed before it that also paints
|
||||
// with "Dots 2", the loop is still found as "Accent 3" and "Dots 2", the names it has together.
|
||||
let doc = std::sync::Arc::make_mut(&mut s.doc_mut().unwrap().doc);
|
||||
let at = doc.char_styles.iter().position(|c| c.name == "Accent 2").unwrap();
|
||||
doc.char_styles[at].name = "Accent 3".into();
|
||||
let copy = TextStyleDef { name: "Accent 2".into(), attrs: doc.char_styles[at].attrs.clone() };
|
||||
doc.char_styles.insert(at, copy);
|
||||
let tile = doc.patterns.iter_mut().find(|p| p.name == "Dots 2").unwrap();
|
||||
let NodeKind::Text(text) = &mut std::sync::Arc::make_mut(&mut tile.art[0]).kind else { panic!("pattern art should be type") };
|
||||
text.runs[0].style.style_name = Some("Accent 3".into());
|
||||
let d = s.doc().unwrap().doc.clone();
|
||||
let r = s.execute("charStyle.load", &load).unwrap();
|
||||
assert_eq!(r, json!({"added": [], "existing": ["Accent 3"], "skipped": []}));
|
||||
assert_eq!(s.doc().unwrap().doc, d);
|
||||
}
|
||||
|
||||
/// A brush in a loaded style's pattern whose art sets type in a style renamed on the way in
|
||||
|
||||
Reference in New Issue
Block a user