address review: drop media copied by a rolled-back diagram fallback or parent drawing

This commit is contained in:
Dylan M. Taylor
2026-11-11 15:11:54 +00:00
parent 96c6b5da4c
commit 64c89064ea
2 changed files with 13 additions and 2 deletions
+9
View File
@@ -76,6 +76,15 @@ impl Imp<'_> {
self.media_by_part.insert(key, id);
Some(id)
}
/// Drop the media copied since the list was `len` long, with their part-cache entries: used when
/// the content that read them is discarded, so they are neither kept nor reused uncharged.
pub fn forget_media_from(&mut self, len: usize) {
if self.media.len() > len {
let gone: std::collections::HashSet<MediaId> = self.media[len..].iter().map(|m| m.id).collect();
self.media.truncate(len);
self.media_by_part.retain(|_, id| !gone.contains(id));
}
}
/// Media item for an external link.
pub fn media_link(&mut self, url: &str) -> MediaId {
if let Some(m) = self.media.iter().find(|m| m.link.as_deref() == Some(url)) {
+4 -2
View File
@@ -471,7 +471,7 @@ fn frame(imp: &mut Imp, part: &Part, ctx: &mut IdCtx, e: &El, depth: usize) -> S
};
// Keep the parts it points to so a save writes it back whole (#203). A part with relationships
// of its own, or an external link, can't be carried: the save then falls back to the preview.
let xml_before = imp.diagram_xml_bytes;
let (xml_before, media_before) = (imp.diagram_xml_bytes, imp.media.len());
let parts = super::rel_refs(e)
.into_iter()
.map(|id| {
@@ -496,6 +496,7 @@ fn frame(imp: &mut Imp, part: &Part, ctx: &mut IdCtx, e: &El, depth: usize) -> S
// A fallback that drops its parts does not keep their bytes charged.
if parts.is_none() {
imp.diagram_xml_bytes = xml_before;
imp.forget_media_from(media_before);
}
let parts = parts.unwrap_or_default();
s.kind = ShapeKind::Opaque { xml: part.keep(e), preview, label, parts };
@@ -601,7 +602,7 @@ fn smartart(imp: &mut Imp, part: &Part, gd: &El, frame: &Shape, depth: usize) ->
let tree = d.root.child("spTree")?;
let mut sub = IdCtx { fresh: true, ..Default::default() };
let before = imp.smartart_shapes;
let xml_before = imp.diagram_xml_bytes;
let (xml_before, media_before) = (imp.diagram_xml_bytes, imp.media.len());
let children = sp_tree(imp, &dpart, &mut sub, tree, depth + 1);
if children.is_empty() {
return None;
@@ -612,6 +613,7 @@ fn smartart(imp: &mut Imp, part: &Part, gd: &El, frame: &Shape, depth: usize) ->
// Over the presentation's remaining budget: a placeholder, and nothing charged, nested SmartArt included.
imp.smartart_shapes = before;
imp.diagram_xml_bytes = xml_before;
imp.forget_media_from(media_before);
return None;
}
imp.smartart_shapes = total;