diff --git a/crates/paint/src/retouch.rs b/crates/paint/src/retouch.rs index 30a27836d7..0129c31638 100644 --- a/crates/paint/src/retouch.rs +++ b/crates/paint/src/retouch.rs @@ -423,6 +423,7 @@ fn premultiply(px: &mut [f32], alpha: Option) { mod tests { use super::*; use crate::{BrushSettings, StrokePoint}; + use photocraft_geom::Point; fn stroke(points: &[(f64, f64)], size: f32, hardness: f32) -> Stroke { Stroke { @@ -551,4 +552,39 @@ mod tests { mix_premultiplied(&mut d, &[1.0, 1.0], 7, 0.5); assert_eq!(d, [0.5, 0.5]); } + + #[test] + fn footprint_stays_inside_the_full_size_ring() { + let radius = 10.5f32; + for hardness in [1.0, 0.5, 0.0] { + let dab = Dab::round(Point::new(32.0, 32.0), radius, 1.0); + let fp = footprint(&dab, 0, hardness); + let mut painted = 0usize; + let mut farthest = 0.0f64; + for y in fp.rect.y0..fp.rect.y1 { + for x in fp.rect.x0..fp.rect.x1 { + let dist = ((x as f64 + 0.5 - dab.center.x).powi(2) + (y as f64 + 0.5 - dab.center.y).powi(2)).sqrt(); + if fp.at(x, y) <= 0.0 { + continue; + } + painted += 1; + farthest = farthest.max(dist); + assert!( + dist < radius as f64 + 0.5, + "hardness {hardness}: pixel ({x}, {y}) at {dist} px from \ + the centre is painted past the Full Size ring of \ + {radius} px" + ); + } + } + assert!(painted > 0, "hardness {hardness}: nothing painted"); + if hardness == 1.0 { + assert!( + farthest > radius as f64, + "a hard tip painted only {farthest} px out, so the Full \ + Size ring at {radius} px is never reached" + ); + } + } + } }