mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-24 09:46:59 -06:00
#2558: a coarser glow kept whole draws after a pan as made again
A test for review: an Outer Glow made coarser over its whole reach is kept for any pan, since its grid starts at the reach's first whole device pixel, which a whole-pixel pan moves with the art. After pans that aren't multiples of its scale (2 and 3), the kept raster draws exactly what a fresh renderer draws. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
committed by
bflatastic
co-authored by
Claude Opus 5.5
parent
be7fd07562
commit
7dc0c034d8
@@ -2492,6 +2492,43 @@ mod tests {
|
||||
assert!(r.render(&d, 400, 400, Affine::scale(2.0), &opts).pixels == first.pixels, "made again alike");
|
||||
}
|
||||
|
||||
/// An Outer Glow whose whole reach is over the budget is made coarser over that whole reach and
|
||||
/// kept for any pan: its grid starts at the reach's first whole device pixel, which a pan by whole
|
||||
/// pixels moves with the art, so the raster drawn after the pan is the one a fresh renderer makes,
|
||||
/// also for pans that aren't multiples of the raster's scale. Here a 100 pt glow at 500% (scale
|
||||
/// 2) and a 2 pt glow round the page at 800% (scale 3, near the narrowest blur made coarser).
|
||||
#[test]
|
||||
fn a_coarser_glow_kept_whole_draws_after_a_pan_as_made_again() {
|
||||
let size = (640, 360);
|
||||
for (rect, blur, zoom, center, scale) in [
|
||||
(Rect::new(200.0, 300.0, 400.0, 500.0), 100.0, 5.0, (440.0, 400.0), 2.0),
|
||||
(Rect::new(0.0, 0.0, 595.0, 842.0), 2.0, 8.0, (595.0, 421.0), 3.0),
|
||||
] {
|
||||
let mut d = Document::new(595.0, 842.0);
|
||||
let layer = d.layers[0].id;
|
||||
let mut n =
|
||||
Node::path(d.alloc_id(), shapes::rectangle(rect), Appearance::basic(Paint::solid(Color::rgb(0.1, 0.3, 0.9)), Paint::None, 0.0));
|
||||
n.appearance.effects = vec![Effect { id: "stylize.outerGlow".into(), params: json!({"blur": blur}), visible: true }];
|
||||
d.insert(Some(layer), 0, n).unwrap();
|
||||
let base = Affine::translate((320.0, 180.0)) * Affine::scale(zoom) * Affine::translate((-center.0, -center.1));
|
||||
let opts = RenderOptions { background: Some([255, 255, 255, 255]), ..Default::default() };
|
||||
let mut r = Renderer::new();
|
||||
r.threads = 2;
|
||||
r.render(&d, size.0, size.1, base, &opts);
|
||||
let image = |r: &Renderer| r.shadows.values().map(|e| std::sync::Arc::as_ptr(&e.image)).collect::<Vec<_>>();
|
||||
let kept = image(&r);
|
||||
assert!(r.shadows.values().all(|e| e.scale == scale && e.view.is_none()), "blur {blur}: coarser, over the whole reach");
|
||||
for pan in [(37.0, -21.0), (1.0, 0.0), (-3.0, 5.0)] {
|
||||
let xf = Affine::translate(pan) * base;
|
||||
let panned = r.render(&d, size.0, size.1, xf, &opts);
|
||||
assert_eq!(image(&r), kept, "blur {blur}, pan {pan:?}: the raster kept is drawn");
|
||||
let mut fresh = Renderer::new();
|
||||
fresh.threads = 2;
|
||||
assert!(panned.pixels == fresh.render(&d, size.0, size.1, xf, &opts).pixels, "blur {blur}, pan {pan:?}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The multithreaded rasterizer draws the same pixels with any number of workers, so the
|
||||
/// automatic thread count can follow the machine.
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user