diff --git a/crates/engine/src/tests_opacitymask.rs b/crates/engine/src/tests_opacitymask.rs index eb80dae29..96a418405 100644 --- a/crates/engine/src/tests_opacitymask.rs +++ b/crates/engine/src/tests_opacitymask.rs @@ -3,6 +3,8 @@ //! report mixed values, and saves and exports never carry the editing layer. use serde_json::{Value, json}; +use vectorcraft_geom::Affine; +use vectorcraft_render::{RenderOptions, Renderer}; use super::*; use crate::cmd::maskedit::MASK_EDIT_LAYER; @@ -46,6 +48,21 @@ fn data(v: &Value) -> Vec { vectorcraft_format::base64_decode(v["dataBase64"].as_str().unwrap()).unwrap() } +/// #2727: the canvas passes `isolation` while mask art is edited; the editing layer is not drawn on +/// the page, so isolation dimming must not run or the artwork washes out. +#[test] +fn mask_editing_does_not_dim_the_canvas() { + let mut s = session(); + editing_mask(&mut s); + let st = s.doc().unwrap(); + let layer = st.isolation.expect("mask editing isolates the temporary layer"); + let render = |opts: &RenderOptions| Renderer::new().render(&st.doc, 300, 300, Affine::IDENTITY, opts); + let plain = render(&RenderOptions::default()); + let canvas = render(&RenderOptions { isolated: Some(layer), ..Default::default() }); + assert_eq!(plain.pixel(50, 100), canvas.pixel(50, 100), "inside the mask"); + assert_eq!(plain.pixel(250, 100), canvas.pixel(250, 100), "outside the mask"); +} + #[test] fn mask_options_act_on_the_masked_object_while_editing() { let mut s = session(); diff --git a/crates/render/src/lib.rs b/crates/render/src/lib.rs index 059989c8c..0169a3593 100644 --- a/crates/render/src/lib.rs +++ b/crates/render/src/lib.rs @@ -1222,7 +1222,9 @@ impl Renderer { /// In isolation mode, while drawing outside the isolated container and the art dimmed around /// it: the isolated container and its layers and groups, from the top layer down to it. fn isolation_path(&mut self, f: &Frame) -> Option<(NodeId, Vec)> { - let isolated = f.opts.isolated.filter(|_| !self.isolation_settled)?; + // Opacity-mask editing isolates the temporary layer for tools; that layer is not painted on + // the page (the mask applies on the object), so canvas dimming would wash out everything. + let isolated = f.opts.isolated.filter(|_| f.doc.mask_edit.is_none() && !self.isolation_settled)?; let doc = std::ptr::from_ref(f.doc) as usize; if self.isolation.as_ref().is_none_or(|(stamp, d, id, _)| (*stamp, *d, *id) != (self.stamp, doc, isolated)) { self.isolation = Some((self.stamp, doc, isolated, f.doc.ancestry(isolated).unwrap_or_default()));