From 0fc3b5da188beb0f77cdbdd4d516c15e2e6f69fa Mon Sep 17 00:00:00 2001 From: Chris Date: Fri, 19 Oct 2018 08:46:15 +0200 Subject: [PATCH] seperate drawing impl in multiple functions for better test coverage --- src/drawing.rs | 102 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 73 insertions(+), 29 deletions(-) diff --git a/src/drawing.rs b/src/drawing.rs index f46595c..a2fe671 100644 --- a/src/drawing.rs +++ b/src/drawing.rs @@ -63,39 +63,18 @@ impl Drawing for DisplayEink42BlackWhite { T: Iterator> { use epd4in2::constants::{WIDTH, HEIGHT}; + + let width = WIDTH as u32; + let height = HEIGHT as u32; + for Pixel(UnsignedCoord(x,y), color) in item_pixels { - match self.rotation { - DisplayRotation::Rotate0 | DisplayRotation::Rotate180 => { - if x >= WIDTH as u32 || y >= HEIGHT as u32 { - return; - } - }, - DisplayRotation::Rotate90 | DisplayRotation::Rotate270 => { - if y >= WIDTH as u32 || x >= HEIGHT as u32 { - return; - } - } + if outside_display(x, y, width, height, self.rotation) { + return; } - let (idx, bit) = match self.rotation { - DisplayRotation::Rotate0 => ( - x as usize / 8 + (WIDTH as usize / 8) * y as usize, - 0x80 >> (x % 8), - ), - DisplayRotation::Rotate90 => ( - (WIDTH as usize - 1 - y as usize) / 8 + (WIDTH as usize / 8) * x as usize, - 0x01 << (y % 8), - ), - DisplayRotation::Rotate180 => ( - ((WIDTH as usize / 8) * HEIGHT as usize - 1) - (x as usize / 8 + (WIDTH as usize / 8) * y as usize), - 0x01 << (x % 8), - ), - DisplayRotation::Rotate270 => ( - y as usize / 8 + (HEIGHT as usize - 1 - x as usize) * (WIDTH as usize / 8), - 0x80 >> (y % 8), - ), - }; + let (idx, bit) = rotation(x, y, width, height, self.rotation); + let idx = idx as usize; match color { Color::Black => { self.buffer[idx] &= !bit; @@ -108,6 +87,45 @@ impl Drawing for DisplayEink42BlackWhite { } } +fn outside_display(x: u32, y: u32, width: u32, height: u32, rotation: DisplayRotation) -> bool { + match rotation { + DisplayRotation::Rotate0 | DisplayRotation::Rotate180 => { + if x >= width || y >= height { + return true; + } + }, + DisplayRotation::Rotate90 | DisplayRotation::Rotate270 => { + if y >= width || x >= height { + return true; + } + } + } + false +} + +fn rotation(x: u32, y: u32, width: u32, height: u32, rotation: DisplayRotation) -> (u32, u8) { + match rotation { + DisplayRotation::Rotate0 => ( + x / 8 + (width / 8) * y, + 0x80 >> (x % 8), + ), + DisplayRotation::Rotate90 => ( + (width - 1 - y) / 8 + (width / 8) * x, + 0x01 << (y % 8), + ), + DisplayRotation::Rotate180 => ( + ((width / 8) * height - 1) - (x / 8 + (width / 8) * y), + 0x01 << (x % 8), + ), + DisplayRotation::Rotate270 => ( + y / 8 + (height - 1 - x) * (width / 8), + 0x80 >> (y % 8), + ), + } +} + + + //TODO: write tests #[cfg(test)] mod tests { @@ -122,6 +140,32 @@ mod tests { assert_eq!(Color::White, Color::from(1u8)); } + #[test] + fn rotation_overflow() { + use epd4in2::constants::{WIDTH, HEIGHT}; + let width = WIDTH as u32; + let height = HEIGHT as u32; + test_rotation_overflow(width, height, DisplayRotation::Rotate0); + test_rotation_overflow(width, height, DisplayRotation::Rotate90); + test_rotation_overflow(width, height, DisplayRotation::Rotate180); + test_rotation_overflow(width, height, DisplayRotation::Rotate270); + + } + + fn test_rotation_overflow(width: u32, height: u32, rotation2: DisplayRotation) { + let max_value = width / 8 * height; + for x in 0..(width + height) { //limit x because it runs too long + for y in 0..(u32::max_value()) { + if outside_display(x, y, width, height, rotation2) { + break; + } else { + let (idx, _) = rotation(x, y, width, height, rotation2); + assert!(idx < max_value); + } + } + } + } + // test buffer length