mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-15 12:24:19 +00:00
Merge pull request #7223 from dotCooCoo/fix/inline-graphics-in-symbol-art
Type: inline graphics in symbol, mask and pattern art follow their symbols
This commit is contained in:
@@ -1136,37 +1136,6 @@ fn font_list(_: &mut Session, p: &Value) -> Result<Value> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Gives the inline graphics in the type of [`art_texts_of`] the current bounds of their symbols'
|
||||
/// art, and lays out again the type whose inline graphics changed. A symbol drawn inline in the
|
||||
/// art of another symbol takes one more round, so there is at most one round per symbol.
|
||||
fn resolve_art_inline(doc: &mut Document) {
|
||||
for _ in 0..=doc.symbols.len() {
|
||||
let names: BTreeSet<String> =
|
||||
art_texts_of(doc).iter().flat_map(|(_, t, _)| t.runs.iter().filter_map(|r| r.inline.as_ref().map(|a| a.symbol.clone()))).collect();
|
||||
let bounds: BTreeMap<String, Option<Rect>> = names
|
||||
.into_iter()
|
||||
.map(|name| {
|
||||
let b = doc.symbol_art_bounds(&name);
|
||||
(name, b)
|
||||
})
|
||||
.collect();
|
||||
let stale = |t: &TextObject| t.runs.iter().any(|r| r.inline.as_ref().is_some_and(|a| bounds.get(&a.symbol).is_some_and(|b| *b != a.bounds)));
|
||||
let mut changed = false;
|
||||
edit_art_texts_of(doc, &stale, &mut |t| {
|
||||
for a in t.runs.iter_mut().filter_map(|r| r.inline.as_mut()) {
|
||||
if let Some(b) = bounds.get(&a.symbol) {
|
||||
a.bounds = *b;
|
||||
}
|
||||
}
|
||||
refresh_bounds(t);
|
||||
changed = true;
|
||||
});
|
||||
if !changed {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn rescan(s: &mut Session, _: &Value) -> Result<Value> {
|
||||
let db = vectorcraft_text::FontDb::global();
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
@@ -1188,8 +1157,7 @@ pub(crate) fn rescan(s: &mut Session, _: &Value) -> Result<Value> {
|
||||
d.change_unsaved(|doc| {
|
||||
let doc = std::sync::Arc::make_mut(doc);
|
||||
edit_art_texts_of(doc, &|_| true, &mut refresh_bounds);
|
||||
resolve_art_inline(doc);
|
||||
doc.resolve_inline_art();
|
||||
doc.resolve_inline_art_with(&mut refresh_bounds);
|
||||
for id in texts {
|
||||
if let Some(NodeKind::Text(t)) = doc.node_mut(id).map(|n| &mut n.kind) {
|
||||
refresh_bounds(t);
|
||||
|
||||
@@ -22,16 +22,14 @@ pub fn specs() -> Vec<CommandSpec> {
|
||||
}
|
||||
|
||||
/// Inline graphics follow their symbols: after an edit of a document that has (or had) symbols,
|
||||
/// resolve the inline art of every text again (only texts whose art changed are touched).
|
||||
/// resolve the inline art of every text again, in the layers and in the art of symbols, graph
|
||||
/// designs, pattern tiles and opacity masks, and lay out again the texts whose art changed (a
|
||||
/// symbol's type before the type that shows that symbol inline).
|
||||
pub(crate) fn refresh(before: &Document, d: &mut Document) {
|
||||
if before.symbols.is_empty() && d.symbols.is_empty() {
|
||||
return;
|
||||
}
|
||||
for id in d.resolve_inline_art() {
|
||||
if let Some(NodeKind::Text(t)) = d.node_mut(id).map(|n| &mut n.kind) {
|
||||
refresh_bounds(t);
|
||||
}
|
||||
}
|
||||
d.resolve_inline_art_with(&mut refresh_bounds);
|
||||
}
|
||||
|
||||
fn insert_inline(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
@@ -85,7 +83,7 @@ fn insert_inline(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
}
|
||||
let caret = s.edit("Insert Inline Symbol", |d, _| {
|
||||
let mut art = InlineArt { scale, baseline_shift: shift, ..InlineArt::new(symbol.clone()) };
|
||||
art.bounds = d.symbol_art_bounds(&symbol);
|
||||
art.bounds = d.inline_art_bounds(&symbol);
|
||||
let Some(NodeKind::Text(t)) = d.node_mut(id).map(|n| &mut n.kind) else { return Err(EngineError::NoNode(id)) };
|
||||
let style = edit::insertion_style(&t.runs, a, b);
|
||||
let caret = edit::replace_range_styled(&mut t.runs, a, b, &[TextRun::inline(art, style)]);
|
||||
|
||||
Reference in New Issue
Block a user