Integration: #819 a pasted missing graphic always gets a fresh asset id from the target

This commit is contained in:
aiongg
2026-10-13 19:06:46 +00:00
parent 0016b8260e
commit 5917b24aaa
2 changed files with 38 additions and 8 deletions
+34
View File
@@ -615,6 +615,40 @@ mod shared_asset_tests {
assert_ne!(g.asset, missing);
assert!(!dst.assets.contains_key(&g.asset));
}
#[test]
fn pasted_missing_graphic_never_takes_an_asset_placed_later() {
use designcraft_doc::build::NewDocument;
use designcraft_doc::{Graphic, Item, ItemId, Shape, SpreadRef};
let mut src = Document::new(&NewDocument::default());
let mut dst = Document::new(&NewDocument::default());
// The source's missing id is ahead of the target's counter: the target would allocate it to its next image.
for _ in 0..50 {
src.alloc();
}
let missing = AssetId(src.alloc());
let iid = ItemId(src.alloc());
let mut it = Item::new(
iid,
src.default_layer(),
Shape::Rectangle,
designcraft_geom::shapes::rectangle(designcraft_geom::Rect::new(0.0, 0.0, 9.0, 9.0)),
);
it.content = Content::Graphic(Graphic {
asset: missing,
size: (4.0, 4.0),
xf: designcraft_geom::Affine::IDENTITY,
clip: None,
auto_fit: Default::default(),
fit_align: 4,
crop: [1.0; 4],
wrap: Default::default(),
});
src.insert_item(SpreadRef::Doc(0), it, None).unwrap();
let ids = super::super::object::duplicate_from(&mut dst, &src, &[iid], SpreadRef::Doc(0), designcraft_geom::Vec2::ZERO).unwrap();
let g = dst.item(ids[0]).and_then(|i| i.graphic()).unwrap().asset;
assert!((0..100).all(|_| AssetId(dst.alloc()) != g), "a later image in the target takes the pasted graphic's id");
}
}
#[cfg(test)]
+4 -8
View File
@@ -948,15 +948,11 @@ pub fn duplicate_from(dst: &mut Document, src: &Document, ids: &[ItemId], to: Sp
Ok(out)
}
/// The id to reference in `dst` for asset `id` of `src`. When `src` lacks the asset (a missing graphic), an id that `dst`
/// already uses for a different asset is swapped for a fresh unused one so the reference stays missing instead of showing
/// an unrelated image.
/// The id to reference in `dst` for asset `id` of `src`. When `src` lacks the asset (a missing graphic), the reference
/// gets a fresh id from `dst`, so it stays missing: `src`'s id may already name, or later be allocated to, another
/// image in `dst`.
fn adopt_or_dangle(dst: &mut Document, src: &Document, id: AssetId) -> AssetId {
match dst.adopt_asset(src, id) {
Some(a) => a,
None if dst.assets.contains_key(&id) => AssetId(dst.alloc()),
None => id,
}
dst.adopt_asset(src, id).unwrap_or_else(|| AssetId(dst.alloc()))
}
fn renumber(dst: &mut Document, src: &Document, it: &mut Item, stories: &mut HashMap<StoryId, StoryId>) {