diff --git a/crates/engine/src/cmd/pathops.rs b/crates/engine/src/cmd/pathops.rs index e399d5390..7173e3245 100644 --- a/crates/engine/src/cmd/pathops.rs +++ b/crates/engine/src/cmd/pathops.rs @@ -720,17 +720,18 @@ pub(crate) fn outlined_stroke( /// stroke's own geometry effects then shape the path that stroke outlines; [`outlined_stroke`] /// gets the stroke without them. A fill with a random Transform effect paints the outline its /// geometry effects make of the path, on a copy of its own. A path whose Transform effect copies -/// it with a gradient becomes the art the canvas draws for it, each copy with its own gradient and -/// its strokes outlined before the art gets new ids. Random in a Transform effect takes its seed +/// it with a gradient, or has Scale Strokes & Effects or Transform Patterns on, becomes the art the +/// canvas draws for it, each copy with its own gradient, stroke width and pattern, and its strokes +/// outlined before the art gets new ids. Random in a Transform effect takes its seed /// from the object's id, so these effects give the outline the values the canvas drew. /// `None` when `l` has no stroke to outline. pub(crate) fn outline_strokes(d: &mut Document, brushes: &[vectorcraft_brush::Brush], l: &Node) -> Option { - use vectorcraft_render::effects::{GeomContext, apply_geometry_with, has_geometry, has_gradient_copies, is_geometry, reshape}; + use vectorcraft_render::effects::{GeomContext, apply_geometry_with, has_geometry, has_transform_art, is_geometry, reshape}; if !l.appearance.items.iter().any(|i| matches!(i, AppearanceItem::Stroke(st) if outlinable(st))) { return None; } - if has_gradient_copies(l) { - let mut art = reshape(l, None)?; + if has_transform_art(l) { + let mut art = reshape(Some(&*d), l, None)?; outline_member_strokes(d, brushes, &mut art); return Some(d.reid(&art)); } diff --git a/crates/engine/src/tests_outlinestroke.rs b/crates/engine/src/tests_outlinestroke.rs index 84428432a..7ea96d375 100644 --- a/crates/engine/src/tests_outlinestroke.rs +++ b/crates/engine/src/tests_outlinestroke.rs @@ -303,6 +303,23 @@ fn each_transform_copy_keeps_its_own_gradient() { assert_eq!(differ, none_differ); } +/// With Scale Strokes & Effects on, the canvas draws the stroke of a solid square that its +/// Transform effect scales to 200% at 8 pt; the outlined result draws the same. +#[test] +fn a_transform_that_scales_strokes_outlines_the_scaled_stroke() { + let scale = json!({"scaleH": 200, "scaleV": 200, "strokes": true}); + let mut differ = vec![]; + for (command, p) in outlining() { + let mut s = session(); + square_with(&mut s, json!({"color": "#33aa55"}), Value::Null, &[("distort.transform", scale.clone())]); + let before = render(&s); + outlined_by(&mut s, command, &p); + differ.push((command, differing(&before, &render(&s), 64))); + } + let none_differ: Vec<_> = outlining().map(|(command, _)| (command, 0)).into_iter().collect(); + assert_eq!(differ, none_differ); +} + /// Random in a Transform effect takes its seed from the object's id. The outline draws as the /// canvas drew the object with Random in a Transform effect that copies a gradient square, in a /// Transform effect on the stroke of such a square, and in a Transform effect on the fill of a