diff --git a/crates/engine/src/extra_cmds.rs b/crates/engine/src/extra_cmds.rs index 91c9a9bc1a..c291862167 100644 --- a/crates/engine/src/extra_cmds.rs +++ b/crates/engine/src/extra_cmds.rs @@ -930,7 +930,13 @@ pub fn specs() -> Vec { for id in ids { let l = doc.layer_mut(id).ok_or(EngineError::NoLayer(id))?; l.effects = fx.clone(); - l.blend = style.blend; + // Pass Through is a group's mode: a group's style pastes onto other layers as + // Normal, as a merged group's Pass Through becomes Normal. + l.blend = if style.blend == photocraft_color::BlendMode::PassThrough && !l.is_group() { + photocraft_color::BlendMode::Normal + } else { + style.blend + }; l.fill_opacity = style.fill; l.advanced = style.advanced; l.blend_if = blend_if.clone(); diff --git a/crates/engine/src/lib.rs b/crates/engine/src/lib.rs index 2e0684de12..ba618f6ac8 100644 --- a/crates/engine/src/lib.rs +++ b/crates/engine/src/lib.rs @@ -432,8 +432,8 @@ pub struct Session { coalesce_request: Option, /// Pixels copied with Edit › Copy / Cut (shared by all documents, like Photoshop). pub clipboard: Option, - /// Layer › Layer Style › Copy Layer Style: effects, blend mode, fill opacity and the Advanced - /// Blending switches. + /// Layer › Layer Style › Copy Layer Style: the effects and the Blending Options + /// ([`CopiedStyle`]: blend mode, fill opacity, Advanced Blending, Blend If, channels). pub style_clipboard: Option, /// Shape path context menu: copied vector fill and stroke styles. pub path_fill_clipboard: Option, diff --git a/crates/engine/tests/style_and_align.rs b/crates/engine/tests/style_and_align.rs index ad17330507..9af9bed0fa 100644 --- a/crates/engine/tests/style_and_align.rs +++ b/crates/engine/tests/style_and_align.rs @@ -97,3 +97,19 @@ fn several_layers_align_to_an_active_selection() { assert_eq!(x0, 40, "layer {id} aligned to the selection's left edge"); } } + +#[test] +fn a_groups_pass_through_pastes_onto_a_pixel_layer_as_normal() { + let mut s = Session::new(); + let (a, _) = new_doc(&mut s, "rgb"); + let g = s.execute("layer.new.group", json!({})).unwrap()["layer"].as_u64().unwrap(); + assert_eq!(layer(&s, g).blend, photocraft_color::BlendMode::PassThrough); + s.execute("layer.layerStyle.copyLayerStyle", json!({"layer": g})).unwrap(); + s.execute("layer.layerStyle.pasteLayerStyle", json!({"layer": a})).unwrap(); + assert_eq!(layer(&s, a).blend, photocraft_color::BlendMode::Normal, "Pass Through isn't a pixel layer's mode"); + // Onto another group it stays Pass Through. + let g2 = s.execute("layer.new.group", json!({})).unwrap()["layer"].as_u64().unwrap(); + s.execute("layer.setProps", json!({"layer": g2, "blend": "Multiply"})).unwrap(); + s.execute("layer.layerStyle.pasteLayerStyle", json!({"layer": g2})).unwrap(); + assert_eq!(layer(&s, g2).blend, photocraft_color::BlendMode::PassThrough); +}