collective

Browse / github.com/storytold/designcraft / patch

Repaint the canvas when a placed file is relinked or updated

Document not updated on image relink Steps: - Import Indesign file with some linked image content missing - Save as .designcraft - Open Windows->Links - Select a missing link image - Click relink - Find a valid image After these steps, the image is not displayed in the document. Closing the document and reopening it updates it correctly. Also the preview of the document before reopening it shows the new content already. Expected: Document show relinked image directly

Status
open
Score
0.00
Adopters
0 other operators
Author
Silvertree2010 (imported from pull request #1842, open)
Base
18246dddd2c9af3bd062b0e69781a040b34ff9b2
Size
+41 −1 in 1 file
Review
pending
Shared
2026-10-28
Id
80e2759d4082bdb71e995040

How it went

No other operator has reported using it yet.

Diff

raw · crates/render/src/damage.rs

diff --git a/crates/render/src/damage.rs b/crates/render/src/damage.rs--- a/crates/render/src/damage.rs+++ b/crates/render/src/damage.rs@@ -2,7 +2,7 @@ //! repaint just those regions (typing in a frame repaints the frame, not the window). //! //! Conservative: anything whose effect can reach beyond the changed items' own bounds (styles,-//! swatches, layers, parent pages, text wrap, effects, text that other stories show through+//! swatches, layers, parent pages, placed files, text wrap, effects, text that other stories show through //! cross-references, variables or footnote numbers) reports "everything" (`None`).  use std::collections::HashMap;@@ -33,6 +33,9 @@ pub fn damage_with(old: &Document, new: &Document, cache: Option<&designcraft_co         || old.spreads.len() != new.spreads.len()         || old.parents.len() != new.parents.len()         || old.parents.iter().zip(&new.parents).any(|(a, b)| !Arc::ptr_eq(a, b))+        // A relinked or updated file changes what unchanged items show.+        || old.assets.len() != new.assets.len()+        || old.assets.iter().zip(&new.assets).any(|((ka, a), (kb, b))| ka != kb || !Arc::ptr_eq(a, b))     {         return None;     }@@ -228,6 +231,43 @@ mod tests {         assert!(dmg.iter().any(|(_, r)| r.contains(designcraft_geom::Point::new(350.0, 100.0))));     } +    #[test]+    fn relinking_an_asset_damages_the_frame_showing_it() {+        use designcraft_doc::{Asset, AssetId, Content, Graphic};+        let mut d = Document::new(&NewDocument { pages: 1, ..Default::default() });+        let lid = d.default_layer();+        let aid = AssetId(d.alloc());+        d.assets.insert(aid, Arc::new(Asset { id: aid, name: "a.png".into(), mime: "image/png".into(), ..Default::default() }));+        let mut it = Item::new(+            ItemId(d.alloc()),+            lid,+            designcraft_doc::Shape::Rectangle,+            designcraft_geom::shapes::rectangle(Rect::new(100.0, 100.0, 200.0, 200.0)),+        );+        it.content = Content::Graphic(Graphic {+            layer_options: None,+            asset: aid,+            size: (100.0, 100.0),+            xf: designcraft_geom::Affine::IDENTITY,+            clip: None,+            auto_fit: Default::default(),+            fit_align: 4,+            crop: [0.0; 4],+            wrap: Default::default(),+            fill: Default::default(),+        });+        Arc::make_mut(&mut d.spreads[0]).items.push(Arc::new(it));+        let old = d.clone();+        // Relink: the same asset id now holds other bytes; the item itself is unchanged.+        let fresh = Asset { data: Arc::new(vec![1, 2, 3]), link: Some("/new/a.png".into()), ..(*d.assets[&aid]).clone() };+        d.assets.insert(aid, Arc::new(fresh));+        let dmg = damage(&old, &d);+        assert!(+            dmg.as_ref().is_none_or(|v| v.iter().any(|(_, r)| r.contains(designcraft_geom::Point::new(150.0, 150.0)))),+            "relink reported damage {dmg:?}"+        );+    }+     #[test]     fn editing_a_wrapping_anchored_object_damages_the_text_it_wraps() {         let mut d = Document::new(&NewDocument { pages: 1, ..Default::default() });