Merge #629: Fix pasted type losing its layout bounds cache
# Conflicts: # crates/engine/src/cmd/edit.rs
This commit is contained in:
commit
9e2fb37f3a
|
|
@ -259,6 +259,26 @@ mod tests {
|
|||
assert!((b.width() - 30.0).abs() < 1e-6 && (b.height() - 40.0).abs() < 1e-6);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pasted_type_gets_its_layout_bounds_cache() {
|
||||
// Reported from Illustrator: pasted type kept no layout bounds, so its box (and alignment)
|
||||
// fell back to the rough estimate until the file was saved and reopened.
|
||||
let mut s = session();
|
||||
let svg = r#"<svg xmlns="http://www.w3.org/2000/svg" width="500" height="120"><text x="0" y="80" font-family="Source Sans 3" font-size="40">WWWWWWWW</text></svg>"#;
|
||||
s.execute("clipboard.importSvg", &json!({"svg": svg})).unwrap();
|
||||
s.execute("edit.paste", &json!({})).unwrap();
|
||||
let mut checked = 0;
|
||||
s.doc().unwrap().doc.walk(|n| {
|
||||
let vectorcraft_doc::NodeKind::Text(t) = &n.kind else { return };
|
||||
let cached = t.cached_bounds.expect("pasted type computed its bounds");
|
||||
let real = vectorcraft_text::layout(vectorcraft_text::FontDb::global(), t).bounds;
|
||||
assert!((cached.width() - real.width()).abs() < 1e-6, "{cached:?} {real:?}");
|
||||
assert!(cached.width() > t.estimate_bounds().width() + 1.0, "{cached:?} is just the estimate");
|
||||
checked += 1;
|
||||
});
|
||||
assert_eq!(checked, 1, "one text object pasted");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn paste_never_lands_in_an_object_that_reused_an_undone_layers_id() {
|
||||
// Found by the model-based test: undo restores the id counter, so a compound path made
|
||||
|
|
|
|||
|
|
@ -381,6 +381,9 @@ fn paste_clip(s: &mut Session, p: &Value, mode: PasteMode, clip: &Clipboard, cho
|
|||
}
|
||||
}
|
||||
sel.set(new_ids.iter().copied());
|
||||
// Pasted type arrives without the layout bounds cache: fill it so boxes and alignment are
|
||||
// right away (opening the file later would, but paste must not depend on a reopen).
|
||||
super::typecmd::refresh_bounds_of(d, &new_ids);
|
||||
Ok((new_ids, imported, artboard))
|
||||
})?;
|
||||
// The Artboard tool takes the pasted artboard.
|
||||
|
|
|
|||
|
|
@ -187,6 +187,20 @@ fn auto_height(t: &mut TextObject) -> bool {
|
|||
true
|
||||
}
|
||||
|
||||
/// Recompute the layout bounds cache for the text among `ids` (and their descendants) that lacks
|
||||
/// it. Pasted or imported type arrives without the cache (not serialized), so selection boxes, the
|
||||
/// Transform panel and hit testing would fall back to [`TextObject::estimate_bounds`] (a rough
|
||||
/// 0.55 em per character) until the text is edited — the box comes up short and alignment looks off.
|
||||
pub(crate) fn refresh_bounds_of(d: &mut Document, ids: &[NodeId]) {
|
||||
for id in text_ids(d, ids) {
|
||||
if let Some(NodeKind::Text(t)) = d.node_mut(id).map(|n| &mut n.kind)
|
||||
&& t.cached_bounds.is_none()
|
||||
{
|
||||
refresh_bounds(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Text objects among `ids` and their descendants.
|
||||
fn text_ids(d: &Document, ids: &[NodeId]) -> Vec<NodeId> {
|
||||
let mut out = vec![];
|
||||
|
|
|
|||
Loading…
Reference in New Issue