diff --git a/src/draw_target.rs b/src/draw_target.rs index eb8ac5e..624ab2f 100644 --- a/src/draw_target.rs +++ b/src/draw_target.rs @@ -657,7 +657,7 @@ impl + AsMut<[u32]>> DrawTarget { /// Draws `src` through an untransformed `mask` positioned at `x`, `y` in device space pub fn mask(&mut self, src: &Source, x: i32, y: i32, mask: &Mask) { - self.composite(src, Some(&mask.data), intrect(x, y, mask.width, mask.height), intrect(x, y, mask.width, mask.height), BlendMode::SrcOver, 1.); + self.composite(src, Some(&mask.data), intrect(x, y, x + mask.width, y + mask.height), intrect(x, y, x + mask.width, y + mask.height), BlendMode::SrcOver, 1.); } /// Strokes `path` with `style` and fills the result with `src` diff --git a/src/tests.rs b/src/tests.rs index 8afa395..fb50ba1 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -956,4 +956,60 @@ mod tests { &checkerboard[..] ); } + + #[test] + fn mask_composite_position() { + let mask = Mask { + width: 2, + height: 2, + data: vec![0xff, 0xff, 0xff, 0xff], + }; + let source = Source::Solid(SolidSource { + r: 0xff, + g: 0, + b: 0, + a: 0xff, + }); + let zeros = SolidSource { + r: 0, + g: 0, + b: 0, + a: 0, + }; + let red = 0xffff0000; + let width: i32 = 4; + let height: i32 = 4; + + let mut dt = DrawTarget::new(width, height); + let pos = |offset: (usize, usize), (x, y): (usize, usize)| { + offset.0 + x + (offset.1 + y) * width as usize + }; + + dt.mask(&source, 0, 0, &mask); + assert_eq!(dt.get_data()[pos((0, 0), (0, 0))], red); + assert_eq!(dt.get_data()[pos((0, 0), (0, 1))], red); + assert_eq!(dt.get_data()[pos((0, 0), (1, 0))], red); + assert_eq!(dt.get_data()[pos((0, 0), (1, 1))], red); + + dt.clear(zeros); + dt.mask(&source, 1, 0, &mask); + assert_eq!(dt.get_data()[pos((1, 0), (0, 0))], red); + assert_eq!(dt.get_data()[pos((1, 0), (0, 1))], red); + assert_eq!(dt.get_data()[pos((1, 0), (1, 0))], red); + assert_eq!(dt.get_data()[pos((1, 0), (1, 1))], red); + + dt.clear(zeros); + dt.mask(&source, 0, 1, &mask); + assert_eq!(dt.get_data()[pos((0, 1), (0, 0))], red); + assert_eq!(dt.get_data()[pos((0, 1), (0, 1))], red); + assert_eq!(dt.get_data()[pos((0, 1), (1, 0))], red); + assert_eq!(dt.get_data()[pos((0, 1), (1, 1))], red); + + dt.clear(zeros); + dt.mask(&source, 1, 1, &mask); + assert_eq!(dt.get_data()[pos((1, 1), (0, 0))], red); + assert_eq!(dt.get_data()[pos((1, 1), (0, 1))], red); + assert_eq!(dt.get_data()[pos((1, 1), (1, 0))], red); + assert_eq!(dt.get_data()[pos((1, 1), (1, 1))], red); + } }