Merge pull request #2510 from vangel76/fix/2426-innerglow-pattern

Render: Inner Glow on a pattern fill draws along the edges, not at the top left (#2426)
This commit is contained in:
BFlat
2026-10-17 13:44:51 +07:00
committed by GitHub
2 changed files with 25 additions and 0 deletions
+22
View File
@@ -587,3 +587,25 @@ fn picking_another_pattern_swatch_keeps_the_pattern_transform() {
assert_eq!(pattern, "Dots");
assert_eq!(xf.as_coeffs(), [2.0, 0.0, 0.0, 2.0, 15.0, 10.0]);
}
#[test]
fn inner_glow_on_a_pattern_fill_stays_inside_the_object_on_the_threaded_renderer() {
// #2426: the glow's pixmap was drawn with the pattern's paint transform, so it landed
// scaled at the top left instead of along the object's edges.
let mut s = session();
make_dots(&mut s);
let bg = rect(&mut s, 0.0, 0.0, 400.0, 400.0);
s.execute("paint.setFill", &json!({"ids": [bg.0], "color": "#223344"})).unwrap();
let big = rect(&mut s, 100.0, 100.0, 150.0, 150.0);
s.execute("paint.setFill", &json!({"ids": [big.0], "swatch": "Dots"})).unwrap();
sel(&mut s, &[big]);
s.execute("effect.apply", &json!({"effect": "stylize.innerGlow", "params": {"blur": 10}})).unwrap();
let mut r = vectorcraft_render::Renderer::new();
r.threads = 2;
let view = Affine::scale(1.5) * Affine::translate((-20.0, -30.0));
let out = r.render(&s.doc().unwrap().doc, 400, 400, view, &Default::default());
let [red, ..] = out.pixel(110, 100);
assert!(red < 0x30, "glow outside the object: red {red}");
let [red, ..] = out.pixel(123, 200);
assert!(red > 0x40, "no glow along the edge: red {red}");
}
+3
View File
@@ -274,6 +274,9 @@ pub(crate) fn draw_pixmap(ctx: &mut RenderContext, pm: Arc<Pixmap>, at: (f64, f6
#[cfg(test)]
PIXELS_DRAWN.with(|n| n.set(n.get() + u64::from(pm.width()) * u64::from(pm.height())));
ctx.set_transform(Affine::translate(at));
// The pixmap maps 1:1 onto the rect: a paint transform left by an earlier fill (a pattern,
// radial or freeform gradient) would resample it (#2426).
ctx.reset_paint_transform();
ctx.set_paint(vello_cpu::Image { image: vello_cpu::ImageSource::Pixmap(pm), sampler: peniko::ImageSampler::default() });
ctx.fill_rect(&Rect::new(0.0, 0.0, w, h));
ctx.set_transform(Affine::IDENTITY);