diff --git a/crates/io/src/comps_map.rs b/crates/io/src/comps_map.rs index 8d0c78f3b0..da33624b30 100644 --- a/crates/io/src/comps_map.rs +++ b/crates/io/src/comps_map.rs @@ -215,33 +215,37 @@ pub(crate) fn decode_comps(resource: Option<&[u8]>, doc: &Document) -> (Vec { - let p = offset_position(h, o); - if p.is_none() { - warnings.push(format!( - "layer \"{}\": layer comp position offset ({}, {}) is out of range; that position was not imported", - l.name, o.0, o.1 - )); - } - p + let position = match (here, s.offset) { + (Some(h), Some(o)) => { + let p = offset_position(h, o); + if p.is_none() { + warnings.push(format!( + "layer \"{}\": layer comp position offset ({}, {}) is out of range; that position was not imported", + l.name, o.0, o.1 + )); } - _ => None, - }, - appearance: None, + p + } + _ => None, }; for id in &s.comps { let target = if *id == 0 { Some(&mut last) } else { comps.iter_mut().find(|c| c.id == *id) }; - if let Some(c) = target { - c.states.push(state.clone()); + let Some(c) = target else { continue }; + let visible = if *id != 0 && c.apply_visibility { Some(resolved) } else { s.visible }; + if visible.is_none() && s.offset.is_none() { + continue; } + c.states.push(CompLayerState { layer: l.id, visible, position, appearance: None }); } } } diff --git a/crates/io/tests/comps_artboards.rs b/crates/io/tests/comps_artboards.rs index 346d7cc06a..a5b553f5a8 100644 --- a/crates/io/tests/comps_artboards.rs +++ b/crates/io/tests/comps_artboards.rs @@ -182,7 +182,15 @@ fn synthetic_psd_roundtrip_all_depths() { v.sort_by(|x, y| x.0.cmp(&y.0)); v }; - assert_eq!(named(&d, a), named(&back, b), "{depth:?} comp {}", a.name); + let mut want = named(&d, a); + if a.name == "One" { + // "One" records nothing for Board 1. A PSD can't say "leaves it alone": its entry + // has no `enab`, which Photoshop reads as the previous comp's visibility (Both: + // shown), and so does the import now (#8093). + want.push(("Board 1".to_string(), Some(true), None)); + want.sort_by(|x, y| x.0.cmp(&y.0)); + } + assert_eq!(want, named(&back, b), "{depth:?} comp {}", a.name); } // Re-exporting the imported document is byte-stable for comps and artboards. let f1 = PsdFile::from_bytes(&to_psd(&back)).unwrap();