From 8d08bef233f92efc5490df39b374d74a1342aac2 Mon Sep 17 00:00:00 2001 From: caemor Date: Sun, 14 Oct 2018 12:36:54 +0200 Subject: [PATCH 01/75] add embedded_graphics --- Cargo.toml | 2 ++ src/lib.rs | 2 ++ 2 files changed, 4 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index 346ea63..fc9e5d3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,6 +29,8 @@ epd4in2_fast_update = [] [dependencies] +embedded-graphics = "0.4.1" + [dependencies.embedded-hal] features = ["unproven"] diff --git a/src/lib.rs b/src/lib.rs index 6492411..93c7c39 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -78,6 +78,8 @@ pub use epd2in9::EPD2in9; #[cfg(any(feature = "epd1in54", feature = "epd2in9"))] pub(crate) mod type_a; +use embedded_graphics; + //TODO: test spi mode /// SPI mode - /// For more infos see [Requirements: SPI](index.html#spi) From c16e136d094b9f4423be3dec626517c6f2c97af9 Mon Sep 17 00:00:00 2001 From: caemor Date: Sun, 14 Oct 2018 12:38:11 +0200 Subject: [PATCH 02/75] fix --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 93c7c39..7be71ec 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -78,7 +78,7 @@ pub use epd2in9::EPD2in9; #[cfg(any(feature = "epd1in54", feature = "epd2in9"))] pub(crate) mod type_a; -use embedded_graphics; +use embedded-graphics; //TODO: test spi mode /// SPI mode - From 3196c4b38759d0e39c0d2a0a89b5ace86fb44d22 Mon Sep 17 00:00:00 2001 From: caemor Date: Sun, 14 Oct 2018 12:38:56 +0200 Subject: [PATCH 03/75] fix embedded_graphics include --- src/lib.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 7be71ec..fb9c8dc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -78,7 +78,8 @@ pub use epd2in9::EPD2in9; #[cfg(any(feature = "epd1in54", feature = "epd2in9"))] pub(crate) mod type_a; -use embedded-graphics; +extern crate embedded_graphics; +use embedded_graphics; //TODO: test spi mode /// SPI mode - From e30cb6f7e85c9c4af6f061a5a3eb807bc5f452de Mon Sep 17 00:00:00 2001 From: caemor Date: Sun, 14 Oct 2018 23:18:47 +0200 Subject: [PATCH 04/75] Make Enum DisplayRotation, impl Buffer and Drawing for 4in2 display --- src/drawing.rs | 173 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 173 insertions(+) create mode 100644 src/drawing.rs diff --git a/src/drawing.rs b/src/drawing.rs new file mode 100644 index 0000000..e1e6542 --- /dev/null +++ b/src/drawing.rs @@ -0,0 +1,173 @@ +use color::Color; + +/// Displayrotation +#[derive(Clone, Copy)] +pub enum DisplayRotation { + /// No rotation + Rotate0, + /// Rotate by 90 degrees clockwise + Rotate90, + /// Rotate by 180 degrees clockwise + Rotate180, + /// Rotate 270 degrees clockwise + Rotate270, +} +impl Default for Displayorientation { + fn default() -> Self { + Displayorientation::Rotate0 + } +} + +pub enum Display { + Eink42BlackWhite, +} +impl Display { + /// Gets the Dimensions of a dipslay in the following order: + /// - Width + /// - Height + /// - Neccessary Buffersize + pub fn get_dimensions(&self) -> (u16, u16, u16) { + match self { + Display::Eink42BlackWhite => (400, 300, 15000), + } + } +} + +pub trait Buffer { + fn get_buffer(&self) -> &[u8]; +} + +pub struct DisplayEink42BlackWhite { + buffer: [u8; 400 * 300 / 8], + rotation: Displayorientation, //TODO: check embedded_graphics for orientation +} +impl Default for DisplayEink42BlackWhite { + fn default() -> Self { + use epd4in2::constants::*; + DisplayEink42BlackWhite { + buffer: [ + DEFAULT_BACKGROUND_COLOR.get_full_byte(), + WIDTH * HEIGHT / 8 + ], + rotation: DisplayRotation::default() + } + } +} +impl Buffer for DisplayEink42BlackWhite { + fn get_buffer(&self) -> &[u8] { + &self.buffer + } +} +impl Drawing for DisplayEink42BlackWhite { + fn draw(&mut self, item_pixels: T) + where + T: Iterator> + { + for Pixel(UnsignedCoord(x,y), color) in item_pixels { + let (idx, bit) = match self.rotation { + Displayorientation::Rotate0 | Displayorientation::Rotate180 => ( + (x as usize / 8 + (self.width as usize / 8) * y as usize), + 0x80 >> (x % 8), + ), + Displayorientation::Rotate90 | Displayorientation::Rotate270 => ( + y as usize / 8 * self.width as usize + x as usize, + 0x80 >> (y % 8), + ), + }; + + if idx >= self.buffer.len() { + return; + } + + match color { + Color::Black => { + self.buffer[idx] &= !bit; + } + Color::White => { + self.buffer[idx] |= bit; + } + } + } + } +} + +// impl Drawing for DisplayRibbonLeft { +// fn draw(&mut self, item_pixels: T) +// where +// T: Iterator>, +// { +// for Pixel(UnsignedCoord(x, y), color) in item_pixels { +// if y > 127 || x > 295 { +// continue; +// } +// let cell = &mut self.0[y as usize / 8 + (295 - x as usize) * 128 / 8]; +// let bit = 7 - y % 8; +// if color != 0 { +// *cell &= !(1 << bit); +// } else { +// *cell |= 1 << bit; +// } +// } +// } +// } + + + + // /// Draw a single Pixel with `color` + // /// + // /// limited to i16::max images (buffer_size) at the moment + // pub fn draw_pixel(&mut self, x: u16, y: u16, color: &Color) { + // let (idx, bit) = match self.rotation { + // Displayorientation::Rotate0 | Displayorientation::Rotate180 => ( + // (x as usize / 8 + (self.width as usize / 8) * y as usize), + // 0x80 >> (x % 8), + // ), + // Displayorientation::Rotate90 | Displayorientation::Rotate270 => ( + // y as usize / 8 * self.width as usize + x as usize, + // 0x80 >> (y % 8), + // ), + // }; + + // if idx >= self.buffer.len() { + // return; + // } + + // match color { + // Color::Black => { + // self.buffer[idx] &= !bit; + // } + // Color::White => { + // self.buffer[idx] |= bit; + // } + // } + // } + + // /// Draw a single Pixel with `color` + // /// + // /// limited to i16::max images (buffer_size) at the moment + // #[allow(dead_code)] + // fn draw_byte(&mut self, x: u16, y: u16, filling: u8, color: &Color) { + // let idx = match self.rotation { + // Displayorientation::Rotate0 | Displayorientation::Rotate180 => { + // x as usize / 8 + (self.width as usize / 8) * y as usize + // }, + // Displayorientation::Rotate90 | Displayorientation::Rotate270 => { + // y as usize / 8 + (self.width as usize / 8) * x as usize + // }, + // }; + + // if idx >= self.buffer.len() { + // return; + // } + + // match color { + // Color::Black => { + // self.buffer[idx] = !filling; + // }, + // Color::White => { + // self.buffer[idx] = filling; + // } + // } + // } + +//TODO: write tests \ No newline at end of file From 8a7309cfc8a8ba56dcef3d9264f1847f500d6c36 Mon Sep 17 00:00:00 2001 From: Chris Date: Mon, 15 Oct 2018 15:51:36 +0200 Subject: [PATCH 05/75] Renamed old drawing mod to drawing_old --- src/{drawing => drawing_old}/font.rs | 0 src/{drawing => drawing_old}/mod.rs | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename src/{drawing => drawing_old}/font.rs (100%) rename src/{drawing => drawing_old}/mod.rs (100%) diff --git a/src/drawing/font.rs b/src/drawing_old/font.rs similarity index 100% rename from src/drawing/font.rs rename to src/drawing_old/font.rs diff --git a/src/drawing/mod.rs b/src/drawing_old/mod.rs similarity index 100% rename from src/drawing/mod.rs rename to src/drawing_old/mod.rs From 29b798684805c0dcffb2b1954fd7e83b3da5bb7d Mon Sep 17 00:00:00 2001 From: Chris Date: Mon, 15 Oct 2018 15:52:20 +0200 Subject: [PATCH 06/75] Add from_u8 to color, finish drawing for 4in2 --- src/color.rs | 53 ++++++++++++++++++++++++++++++++++++++++++++++ src/drawing.rs | 24 +++++++++++---------- src/epd4in2/mod.rs | 2 +- src/lib.rs | 3 ++- 4 files changed, 69 insertions(+), 13 deletions(-) diff --git a/src/color.rs b/src/color.rs index edee7e8..fdab855 100644 --- a/src/color.rs +++ b/src/color.rs @@ -1,3 +1,6 @@ + +use embedded_graphics::prelude::*; + /// Only for the B/W Displays atm #[derive(Clone, Copy, PartialEq, Debug)] pub enum Color { @@ -22,6 +25,14 @@ impl Color { } } + fn from_u8(val: u8) -> Self { + match val { + 0 => Color::Black, + 1 => Color::White, + e => panic!("DisplayColor only parses 0 and 1 (Black and White) and not `{}`", e), + } + } + /// Get the color encoding of a specific bit in a byte /// /// input is the byte where one bit is gonna be selected @@ -73,3 +84,45 @@ impl Color { } } } + +impl PixelColor for Color {} + +impl From for Color { + fn from(value: u8) -> Self { + Color::from_u8(value) + } +} + + + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn from_u8() { + assert_eq!(Color::Black, Color::from(0u8)); + assert_eq!(Color::White, Color::from(1u8)); + } + + // test all values aside from 0 and 1 which all should panic + #[test] + fn from_u8_panic() { + for val in 2..=u8::max_value() { + let result = std::panic::catch_unwind(|| Color::from(val)); + assert!(result.is_err()); + } + } + + #[test] + fn u8_conversion_black() { + assert_eq!(Color::from(Color::Black.get_bit_value()), Color::Black); + assert_eq!(Color::from(0u8).get_bit_value(), 0u8); + } + + #[test] + fn u8_conversion_white() { + assert_eq!(Color::from(Color::White.get_bit_value()), Color::White); + assert_eq!(Color::from(1u8).get_bit_value(), 1u8); + } +} diff --git a/src/drawing.rs b/src/drawing.rs index e1e6542..97c3ef7 100644 --- a/src/drawing.rs +++ b/src/drawing.rs @@ -1,4 +1,5 @@ use color::Color; +use embedded_graphics::prelude::*; /// Displayrotation #[derive(Clone, Copy)] @@ -12,9 +13,9 @@ pub enum DisplayRotation { /// Rotate 270 degrees clockwise Rotate270, } -impl Default for Displayorientation { +impl Default for DisplayRotation { fn default() -> Self { - Displayorientation::Rotate0 + DisplayRotation::Rotate0 } } @@ -39,15 +40,15 @@ pub trait Buffer { pub struct DisplayEink42BlackWhite { buffer: [u8; 400 * 300 / 8], - rotation: Displayorientation, //TODO: check embedded_graphics for orientation + rotation: DisplayRotation, //TODO: check embedded_graphics for orientation } impl Default for DisplayEink42BlackWhite { fn default() -> Self { - use epd4in2::constants::*; + use epd4in2::constants::{DEFAULT_BACKGROUND_COLOR, WIDTH, HEIGHT}; DisplayEink42BlackWhite { buffer: [ - DEFAULT_BACKGROUND_COLOR.get_full_byte(), - WIDTH * HEIGHT / 8 + DEFAULT_BACKGROUND_COLOR.get_byte_value(); + WIDTH as usize * HEIGHT as usize / 8 ], rotation: DisplayRotation::default() } @@ -63,14 +64,15 @@ impl Drawing for DisplayEink42BlackWhite { where T: Iterator> { + use epd4in2::constants::{DEFAULT_BACKGROUND_COLOR, WIDTH, HEIGHT}; for Pixel(UnsignedCoord(x,y), color) in item_pixels { let (idx, bit) = match self.rotation { - Displayorientation::Rotate0 | Displayorientation::Rotate180 => ( - (x as usize / 8 + (self.width as usize / 8) * y as usize), + DisplayRotation::Rotate0 | DisplayRotation::Rotate180 => ( + (x as usize / 8 + (WIDTH as usize / 8) * y as usize), 0x80 >> (x % 8), ), - Displayorientation::Rotate90 | Displayorientation::Rotate270 => ( - y as usize / 8 * self.width as usize + x as usize, + DisplayRotation::Rotate90 | DisplayRotation::Rotate270 => ( + y as usize / 8 * WIDTH as usize + x as usize, 0x80 >> (y % 8), ), }; @@ -79,7 +81,7 @@ impl Drawing for DisplayEink42BlackWhite { return; } - match color { + match Color::from(color) { Color::Black => { self.buffer[idx] &= !bit; } diff --git a/src/epd4in2/mod.rs b/src/epd4in2/mod.rs index 640fa6f..4d6dd53 100644 --- a/src/epd4in2/mod.rs +++ b/src/epd4in2/mod.rs @@ -55,7 +55,7 @@ use traits::{WaveshareDisplay, InternalWiAdditions}; use interface::DisplayInterface; //The Lookup Tables for the Display -mod constants; +pub(crate) mod constants; //TODO: Limit to crate::drawing use self::constants::*; use color::Color; diff --git a/src/lib.rs b/src/lib.rs index fb9c8dc..3c9623b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -50,6 +50,8 @@ use hal::spi::{Mode, Phase, Polarity}; #[cfg(feature = "graphics")] pub mod drawing; +pub(crate) mod drawing_old; + mod traits; pub use traits::{WaveshareDisplay}; @@ -79,7 +81,6 @@ pub use epd2in9::EPD2in9; pub(crate) mod type_a; extern crate embedded_graphics; -use embedded_graphics; //TODO: test spi mode /// SPI mode - From 98a9b1c0edf077a5a159535ffbcd2c2242c3563b Mon Sep 17 00:00:00 2001 From: Chris Date: Mon, 15 Oct 2018 15:54:59 +0200 Subject: [PATCH 07/75] Fix examples --- examples/embedded_linux_epd1in54/src/main.rs | 2 +- examples/embedded_linux_epd4in2/src/main.rs | 2 +- examples/stm32f3discovery/src/main.rs | 2 +- src/lib.rs | 4 +++- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/examples/embedded_linux_epd1in54/src/main.rs b/examples/embedded_linux_epd1in54/src/main.rs index 11c94c6..b2bd427 100644 --- a/examples/embedded_linux_epd1in54/src/main.rs +++ b/examples/embedded_linux_epd1in54/src/main.rs @@ -7,7 +7,7 @@ extern crate eink_waveshare_rs; use eink_waveshare_rs::{ EPD1in54, - //drawing::{Graphics}, + //drawing_old::{Graphics}, color::Color, WaveshareDisplay, }; diff --git a/examples/embedded_linux_epd4in2/src/main.rs b/examples/embedded_linux_epd4in2/src/main.rs index 25d2489..922cf67 100644 --- a/examples/embedded_linux_epd4in2/src/main.rs +++ b/examples/embedded_linux_epd4in2/src/main.rs @@ -7,7 +7,7 @@ extern crate eink_waveshare_rs; use eink_waveshare_rs::{ EPD4in2, - drawing::{Graphics}, + drawing_old::{Graphics}, color::Color, WaveshareDisplay, }; diff --git a/examples/stm32f3discovery/src/main.rs b/examples/stm32f3discovery/src/main.rs index ded3f40..29989b7 100644 --- a/examples/stm32f3discovery/src/main.rs +++ b/examples/stm32f3discovery/src/main.rs @@ -28,7 +28,7 @@ extern crate eink_waveshare_rs; use eink_waveshare_rs::{ EPD1in54, SPI_MODE, - //drawing::{Graphics}, + //drawing_old::{Graphics}, color::Color, WaveshareDisplay, }; diff --git a/src/lib.rs b/src/lib.rs index 3c9623b..23d6745 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -50,7 +50,9 @@ use hal::spi::{Mode, Phase, Polarity}; #[cfg(feature = "graphics")] pub mod drawing; -pub(crate) mod drawing_old; +//TODO: remove old drawing support +#[cfg(feature = "graphics")] +pub mod drawing_old; mod traits; pub use traits::{WaveshareDisplay}; From 2bab732b6fa89fb59cb79db06f8fd7658c0e5e3f Mon Sep 17 00:00:00 2001 From: Chris Date: Tue, 16 Oct 2018 18:08:43 +0200 Subject: [PATCH 08/75] use new graphics in example --- examples/embedded_linux_epd4in2/src/main.rs | 48 +++++++++++++++++++-- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/examples/embedded_linux_epd4in2/src/main.rs b/examples/embedded_linux_epd4in2/src/main.rs index 922cf67..8e61235 100644 --- a/examples/embedded_linux_epd4in2/src/main.rs +++ b/examples/embedded_linux_epd4in2/src/main.rs @@ -8,6 +8,7 @@ extern crate eink_waveshare_rs; use eink_waveshare_rs::{ EPD4in2, drawing_old::{Graphics}, + drawing::DisplayEink42BlackWhite, color::Color, WaveshareDisplay, }; @@ -136,6 +137,8 @@ fn run() -> Result<(), std::io::Error> { epd4in2.clear_frame(&mut spi).expect("clear frame error"); epd4in2.update_frame(&mut spi, graphics.get_buffer()).expect("update frame error"); epd4in2.display_frame(&mut spi)?; + + println!("Finished basic old graphics test"); delay.delay_ms(3000u16); @@ -158,6 +161,8 @@ fn run() -> Result<(), std::io::Error> { epd4in2.update_partial_frame(&mut spi, circle_graphics.get_buffer(), 160,240, 32, 32).expect("update partial frame error"); epd4in2.display_frame(&mut spi)?; + println!("Finished partial update test"); + delay.delay_ms(3000u16); @@ -170,7 +175,44 @@ fn run() -> Result<(), std::io::Error> { epd4in2.update_frame(&mut spi, graphics.get_buffer())?; epd4in2.display_frame(&mut spi)?; - delay.delay_ms(3000u16); + println!("Finished draw string test"); - epd4in2.sleep(&mut spi) -} + delay.delay_ms(3000u16); + println!("Now test new graphics:"); + + let mut i = 0; + loop { + println!("Loop {}", i); + i += 1; + let mut display = DisplayEink42BlackWhite::default(); + display.draw( + Circle::new(Coord::new(64, 64), 64) + .with_stroke(Some(1u8.into())) + .into_iter(), + ); + display.draw( + Line::new(Coord::new(64, 64), Coord::new(0, 64)) + .with_stroke(Some(1u8.into())) + .into_iter(), + ); + display.draw( + Line::new(Coord::new(64, 64), Coord::new(80, 80)) + .with_stroke(Some(1u8.into())) + .into_iter(), + ); + display.draw( + Font6x8::render_str("Hello World!") + .with_stroke(Some(1u8.into())) + .translate(Coord::new(5 + i, 50)) + .into_iter(), + ); + + epd4in2.update_frame(&mut spi, &display.get_buffer()).unwrap(); + epd4in2.display_frame(&mut spi); + if i > 296 { + epd4in2.sleep(&mut spi)?; + return; + } + delay.delay_ms(1_000u16); + } +} From fe97740f0414cf9ef133b80fd3c5dc3577eba3be Mon Sep 17 00:00:00 2001 From: Chris Date: Tue, 16 Oct 2018 18:13:43 +0200 Subject: [PATCH 09/75] Fix example --- examples/embedded_linux_epd4in2/Cargo.toml | 2 ++ examples/embedded_linux_epd4in2/src/main.rs | 18 +++++++++++++----- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/examples/embedded_linux_epd4in2/Cargo.toml b/examples/embedded_linux_epd4in2/Cargo.toml index 5bb31a6..cf2e8f9 100644 --- a/examples/embedded_linux_epd4in2/Cargo.toml +++ b/examples/embedded_linux_epd4in2/Cargo.toml @@ -11,4 +11,6 @@ eink_waveshare_rs = { path = "../../", default-features = false, features = ["ep linux-embedded-hal = "0.2.0" +embedded-graphics = "0.4.1" + embedded-hal = { version = "0.2.1", features = ["unproven"] } diff --git a/examples/embedded_linux_epd4in2/src/main.rs b/examples/embedded_linux_epd4in2/src/main.rs index 8e61235..ebf93a7 100644 --- a/examples/embedded_linux_epd4in2/src/main.rs +++ b/examples/embedded_linux_epd4in2/src/main.rs @@ -8,11 +8,17 @@ extern crate eink_waveshare_rs; use eink_waveshare_rs::{ EPD4in2, drawing_old::{Graphics}, - drawing::DisplayEink42BlackWhite, + drawing::{DisplayEink42BlackWhite, Buffer}, color::Color, WaveshareDisplay, }; +extern crate embedded_graphics; +use embedded_graphics::coord::Coord; +use embedded_graphics::fonts::Font6x8; +use embedded_graphics::prelude::*; +use embedded_graphics::primitives::{Circle, Line}; + use lin_hal::spidev::{self, SpidevOptions}; use lin_hal::{Pin, Spidev}; use lin_hal::sysfs_gpio::Direction; @@ -63,7 +69,7 @@ impl<'a> InputPin for HackInputPin<'a> { * */ fn main() { - run().map_err(|e| println!("{}", e.to_string())); + run().map_err(|e| println!("{}", e.to_string())).unwrap(); } @@ -208,11 +214,13 @@ fn run() -> Result<(), std::io::Error> { ); epd4in2.update_frame(&mut spi, &display.get_buffer()).unwrap(); - epd4in2.display_frame(&mut spi); + epd4in2.display_frame(&mut spi).expect("display frame new graphics"); if i > 296 { - epd4in2.sleep(&mut spi)?; - return; + + break; } delay.delay_ms(1_000u16); } + println!("Finished tests - going to sleep"); + epd4in2.sleep(&mut spi) } From 533cb841236171abc69b6e64a88afcb1bfa5379e Mon Sep 17 00:00:00 2001 From: Chris Date: Tue, 16 Oct 2018 18:24:14 +0200 Subject: [PATCH 10/75] Make lines visible --- examples/embedded_linux_epd4in2/src/main.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/embedded_linux_epd4in2/src/main.rs b/examples/embedded_linux_epd4in2/src/main.rs index ebf93a7..be268a7 100644 --- a/examples/embedded_linux_epd4in2/src/main.rs +++ b/examples/embedded_linux_epd4in2/src/main.rs @@ -193,29 +193,29 @@ fn run() -> Result<(), std::io::Error> { let mut display = DisplayEink42BlackWhite::default(); display.draw( Circle::new(Coord::new(64, 64), 64) - .with_stroke(Some(1u8.into())) + .with_stroke(Color::Black)) .into_iter(), ); display.draw( Line::new(Coord::new(64, 64), Coord::new(0, 64)) - .with_stroke(Some(1u8.into())) + .with_stroke(Color::Black)) .into_iter(), ); display.draw( Line::new(Coord::new(64, 64), Coord::new(80, 80)) - .with_stroke(Some(1u8.into())) + .with_stroke(Color::Black)) .into_iter(), ); display.draw( Font6x8::render_str("Hello World!") .with_stroke(Some(1u8.into())) - .translate(Coord::new(5 + i, 50)) + .translate(Coord::new(5 + i*5, 50)) .into_iter(), ); epd4in2.update_frame(&mut spi, &display.get_buffer()).unwrap(); epd4in2.display_frame(&mut spi).expect("display frame new graphics"); - if i > 296 { + if i > 60 { break; } From e92af2198a3651050950404984331998e713886d Mon Sep 17 00:00:00 2001 From: Chris Date: Tue, 16 Oct 2018 18:26:29 +0200 Subject: [PATCH 11/75] Fix previous commit --- examples/embedded_linux_epd4in2/src/main.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/embedded_linux_epd4in2/src/main.rs b/examples/embedded_linux_epd4in2/src/main.rs index be268a7..2f30b63 100644 --- a/examples/embedded_linux_epd4in2/src/main.rs +++ b/examples/embedded_linux_epd4in2/src/main.rs @@ -193,29 +193,29 @@ fn run() -> Result<(), std::io::Error> { let mut display = DisplayEink42BlackWhite::default(); display.draw( Circle::new(Coord::new(64, 64), 64) - .with_stroke(Color::Black)) + .with_stroke(Color::Black) .into_iter(), ); display.draw( Line::new(Coord::new(64, 64), Coord::new(0, 64)) - .with_stroke(Color::Black)) + .with_stroke(Color::Black) .into_iter(), ); display.draw( Line::new(Coord::new(64, 64), Coord::new(80, 80)) - .with_stroke(Color::Black)) + .with_stroke(Color::Black) .into_iter(), ); display.draw( Font6x8::render_str("Hello World!") - .with_stroke(Some(1u8.into())) - .translate(Coord::new(5 + i*5, 50)) + .with_stroke(Color::Black) + .translate(Coord::new(5 + i*10, 50)) .into_iter(), ); epd4in2.update_frame(&mut spi, &display.get_buffer()).unwrap(); epd4in2.display_frame(&mut spi).expect("display frame new graphics"); - if i > 60 { + if i > 20 { break; } From ff21d6e611e9617bb6abbbf1e54981ef0aded171 Mon Sep 17 00:00:00 2001 From: Chris Date: Tue, 16 Oct 2018 18:33:06 +0200 Subject: [PATCH 12/75] add impl Drawing for DisplayEink42BlackWhite fix error by using option for style --- examples/embedded_linux_epd4in2/src/main.rs | 8 ++--- src/drawing.rs | 34 +++++++++++++++++++++ 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/examples/embedded_linux_epd4in2/src/main.rs b/examples/embedded_linux_epd4in2/src/main.rs index 2f30b63..3097018 100644 --- a/examples/embedded_linux_epd4in2/src/main.rs +++ b/examples/embedded_linux_epd4in2/src/main.rs @@ -193,22 +193,22 @@ fn run() -> Result<(), std::io::Error> { let mut display = DisplayEink42BlackWhite::default(); display.draw( Circle::new(Coord::new(64, 64), 64) - .with_stroke(Color::Black) + .with_stroke(Some(Color::Black)) .into_iter(), ); display.draw( Line::new(Coord::new(64, 64), Coord::new(0, 64)) - .with_stroke(Color::Black) + .with_stroke(Some(Color::Black)) .into_iter(), ); display.draw( Line::new(Coord::new(64, 64), Coord::new(80, 80)) - .with_stroke(Color::Black) + .with_stroke(Some(Color::Black)) .into_iter(), ); display.draw( Font6x8::render_str("Hello World!") - .with_stroke(Color::Black) + .with_stroke(Some(Color::Black)) .translate(Coord::new(5 + i*10, 50)) .into_iter(), ); diff --git a/src/drawing.rs b/src/drawing.rs index 97c3ef7..28b81e5 100644 --- a/src/drawing.rs +++ b/src/drawing.rs @@ -93,6 +93,40 @@ impl Drawing for DisplayEink42BlackWhite { } } +impl Drawing for DisplayEink42BlackWhite { + fn draw(&mut self, item_pixels: T) + where + T: Iterator> + { + use epd4in2::constants::{DEFAULT_BACKGROUND_COLOR, WIDTH, HEIGHT}; + for Pixel(UnsignedCoord(x,y), color) in item_pixels { + let (idx, bit) = match self.rotation { + DisplayRotation::Rotate0 | DisplayRotation::Rotate180 => ( + (x as usize / 8 + (WIDTH as usize / 8) * y as usize), + 0x80 >> (x % 8), + ), + DisplayRotation::Rotate90 | DisplayRotation::Rotate270 => ( + y as usize / 8 * WIDTH as usize + x as usize, + 0x80 >> (y % 8), + ), + }; + + if idx >= self.buffer.len() { + return; + } + + match color { + Color::Black => { + self.buffer[idx] &= !bit; + } + Color::White => { + self.buffer[idx] |= bit; + } + } + } + } +} + // impl Drawing for DisplayRibbonLeft { // fn draw(&mut self, item_pixels: T) // where From 8904066de615aae3e6cea8e3ee07ef302be2117f Mon Sep 17 00:00:00 2001 From: Chris Date: Tue, 16 Oct 2018 21:43:27 +0200 Subject: [PATCH 13/75] Moved constants of type_a to its own file --- src/epd1in54/mod.rs | 5 ++++- src/epd2in9/mod.rs | 5 ++++- src/type_a/constants.rs | 14 ++++++++++++++ src/type_a/mod.rs | 16 +--------------- 4 files changed, 23 insertions(+), 17 deletions(-) create mode 100644 src/type_a/constants.rs diff --git a/src/epd1in54/mod.rs b/src/epd1in54/mod.rs index 99732d1..a4c625f 100644 --- a/src/epd1in54/mod.rs +++ b/src/epd1in54/mod.rs @@ -29,7 +29,10 @@ use hal::{ digital::*, }; -use type_a::{command::Command, LUT_FULL_UPDATE, LUT_PARTIAL_UPDATE}; +use type_a::{ + command::Command, + constants::{LUT_FULL_UPDATE, LUT_PARTIAL_UPDATE} +}; use color::Color; diff --git a/src/epd2in9/mod.rs b/src/epd2in9/mod.rs index 1110d11..4fd3b2a 100644 --- a/src/epd2in9/mod.rs +++ b/src/epd2in9/mod.rs @@ -28,7 +28,10 @@ use hal::{ digital::*, }; -use type_a::{command::Command, LUT_FULL_UPDATE, LUT_PARTIAL_UPDATE}; +use type_a::{ + command::Command, + constants::{LUT_FULL_UPDATE, LUT_PARTIAL_UPDATE} +}; use color::Color; diff --git a/src/type_a/constants.rs b/src/type_a/constants.rs new file mode 100644 index 0000000..63de296 --- /dev/null +++ b/src/type_a/constants.rs @@ -0,0 +1,14 @@ +// Original Waveforms from Waveshare +pub(crate) const LUT_FULL_UPDATE: [u8; 30] =[ + 0x02, 0x02, 0x01, 0x11, 0x12, 0x12, 0x22, 0x22, + 0x66, 0x69, 0x69, 0x59, 0x58, 0x99, 0x99, 0x88, + 0x00, 0x00, 0x00, 0x00, 0xF8, 0xB4, 0x13, 0x51, + 0x35, 0x51, 0x51, 0x19, 0x01, 0x00 +]; + +pub(crate) const LUT_PARTIAL_UPDATE: [u8; 30] =[ + 0x10, 0x18, 0x18, 0x08, 0x18, 0x18, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x13, 0x14, 0x44, 0x12, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +]; \ No newline at end of file diff --git a/src/type_a/mod.rs b/src/type_a/mod.rs index 987a032..11b59c7 100644 --- a/src/type_a/mod.rs +++ b/src/type_a/mod.rs @@ -1,16 +1,2 @@ pub(crate) mod command; - -// Original Waveforms from Waveshare -pub(crate) const LUT_FULL_UPDATE: [u8; 30] =[ - 0x02, 0x02, 0x01, 0x11, 0x12, 0x12, 0x22, 0x22, - 0x66, 0x69, 0x69, 0x59, 0x58, 0x99, 0x99, 0x88, - 0x00, 0x00, 0x00, 0x00, 0xF8, 0xB4, 0x13, 0x51, - 0x35, 0x51, 0x51, 0x19, 0x01, 0x00 -]; - -pub(crate) const LUT_PARTIAL_UPDATE: [u8; 30] =[ - 0x10, 0x18, 0x18, 0x08, 0x18, 0x18, 0x08, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x13, 0x14, 0x44, 0x12, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -]; +pub(crate) mod constants; \ No newline at end of file From d2a47eb05c22b4da1fb35bbea63d73bbf586bb00 Mon Sep 17 00:00:00 2001 From: Chris Date: Tue, 16 Oct 2018 22:11:25 +0200 Subject: [PATCH 14/75] Rename Buffer Trait to Display and add a Rotation Function to it --- examples/embedded_linux_epd4in2/src/main.rs | 57 +++++--- src/drawing.rs | 140 ++------------------ 2 files changed, 50 insertions(+), 147 deletions(-) diff --git a/examples/embedded_linux_epd4in2/src/main.rs b/examples/embedded_linux_epd4in2/src/main.rs index 3097018..84090c1 100644 --- a/examples/embedded_linux_epd4in2/src/main.rs +++ b/examples/embedded_linux_epd4in2/src/main.rs @@ -8,7 +8,7 @@ extern crate eink_waveshare_rs; use eink_waveshare_rs::{ EPD4in2, drawing_old::{Graphics}, - drawing::{DisplayEink42BlackWhite, Buffer}, + drawing::{DisplayEink42BlackWhite, Display}, color::Color, WaveshareDisplay, }; @@ -184,34 +184,51 @@ fn run() -> Result<(), std::io::Error> { println!("Finished draw string test"); delay.delay_ms(3000u16); + println!("Now test new graphics:"); + let mut display = DisplayEink42BlackWhite::default(); + display.draw( + Circle::new(Coord::new(64, 64), 64) + .with_stroke(Some(Color::Black)) + .into_iter(), + ); + display.draw( + Line::new(Coord::new(64, 64), Coord::new(0, 64)) + .with_stroke(Some(Color::Black)) + .into_iter(), + ); + display.draw( + Line::new(Coord::new(64, 64), Coord::new(80, 80)) + .with_stroke(Some(Color::Black)) + .into_iter(), + ); + display.draw( + Font6x8::render_str("It's working!") + // Using Style here + .with_style(Style { + fill_color: Some(Color::Black), + stroke_color: Some(Color::White), + stroke_width: 0u8, // Has no effect on fonts + }) + .translate(Coord::new(175, 250)) + .into_iter(), + ); + + //display.clear(); + //display.set_rotation(Rotation) let mut i = 0; loop { - println!("Loop {}", i); i += 1; - let mut display = DisplayEink42BlackWhite::default(); - display.draw( - Circle::new(Coord::new(64, 64), 64) - .with_stroke(Some(Color::Black)) - .into_iter(), - ); - display.draw( - Line::new(Coord::new(64, 64), Coord::new(0, 64)) - .with_stroke(Some(Color::Black)) - .into_iter(), - ); - display.draw( - Line::new(Coord::new(64, 64), Coord::new(80, 80)) - .with_stroke(Some(Color::Black)) - .into_iter(), - ); + println!("Moving Hello World. Loop {} from 20", i); + display.draw( Font6x8::render_str("Hello World!") .with_stroke(Some(Color::Black)) + .with_fill(Some(Color::White)) .translate(Coord::new(5 + i*10, 50)) .into_iter(), - ); + ); epd4in2.update_frame(&mut spi, &display.get_buffer()).unwrap(); epd4in2.display_frame(&mut spi).expect("display frame new graphics"); @@ -221,6 +238,8 @@ fn run() -> Result<(), std::io::Error> { } delay.delay_ms(1_000u16); } + + println!("Finished tests - going to sleep"); epd4in2.sleep(&mut spi) } diff --git a/src/drawing.rs b/src/drawing.rs index 28b81e5..9bf4600 100644 --- a/src/drawing.rs +++ b/src/drawing.rs @@ -19,29 +19,18 @@ impl Default for DisplayRotation { } } -pub enum Display { - Eink42BlackWhite, -} -impl Display { - /// Gets the Dimensions of a dipslay in the following order: - /// - Width - /// - Height - /// - Neccessary Buffersize - pub fn get_dimensions(&self) -> (u16, u16, u16) { - match self { - Display::Eink42BlackWhite => (400, 300, 15000), - } - } -} - -pub trait Buffer { +pub trait Display { fn get_buffer(&self) -> &[u8]; + fn set_rotation(&mut self, rotation: DisplayRotation); + fn rotation(&self) -> DisplayRotation; } + pub struct DisplayEink42BlackWhite { buffer: [u8; 400 * 300 / 8], rotation: DisplayRotation, //TODO: check embedded_graphics for orientation } + impl Default for DisplayEink42BlackWhite { fn default() -> Self { use epd4in2::constants::{DEFAULT_BACKGROUND_COLOR, WIDTH, HEIGHT}; @@ -54,42 +43,16 @@ impl Default for DisplayEink42BlackWhite { } } } -impl Buffer for DisplayEink42BlackWhite { + +impl Display for DisplayEink42BlackWhite { fn get_buffer(&self) -> &[u8] { &self.buffer } -} -impl Drawing for DisplayEink42BlackWhite { - fn draw(&mut self, item_pixels: T) - where - T: Iterator> - { - use epd4in2::constants::{DEFAULT_BACKGROUND_COLOR, WIDTH, HEIGHT}; - for Pixel(UnsignedCoord(x,y), color) in item_pixels { - let (idx, bit) = match self.rotation { - DisplayRotation::Rotate0 | DisplayRotation::Rotate180 => ( - (x as usize / 8 + (WIDTH as usize / 8) * y as usize), - 0x80 >> (x % 8), - ), - DisplayRotation::Rotate90 | DisplayRotation::Rotate270 => ( - y as usize / 8 * WIDTH as usize + x as usize, - 0x80 >> (y % 8), - ), - }; - - if idx >= self.buffer.len() { - return; - } - - match Color::from(color) { - Color::Black => { - self.buffer[idx] &= !bit; - } - Color::White => { - self.buffer[idx] |= bit; - } - } - } + fn set_rotation(&mut self, rotation: DisplayRotation) { + self.rotation = rotation; + } + fn rotation(&self) -> DisplayRotation { + self.rotation } } @@ -127,83 +90,4 @@ impl Drawing for DisplayEink42BlackWhite { } } -// impl Drawing for DisplayRibbonLeft { -// fn draw(&mut self, item_pixels: T) -// where -// T: Iterator>, -// { -// for Pixel(UnsignedCoord(x, y), color) in item_pixels { -// if y > 127 || x > 295 { -// continue; -// } -// let cell = &mut self.0[y as usize / 8 + (295 - x as usize) * 128 / 8]; -// let bit = 7 - y % 8; -// if color != 0 { -// *cell &= !(1 << bit); -// } else { -// *cell |= 1 << bit; -// } -// } -// } -// } - - - - // /// Draw a single Pixel with `color` - // /// - // /// limited to i16::max images (buffer_size) at the moment - // pub fn draw_pixel(&mut self, x: u16, y: u16, color: &Color) { - // let (idx, bit) = match self.rotation { - // Displayorientation::Rotate0 | Displayorientation::Rotate180 => ( - // (x as usize / 8 + (self.width as usize / 8) * y as usize), - // 0x80 >> (x % 8), - // ), - // Displayorientation::Rotate90 | Displayorientation::Rotate270 => ( - // y as usize / 8 * self.width as usize + x as usize, - // 0x80 >> (y % 8), - // ), - // }; - - // if idx >= self.buffer.len() { - // return; - // } - - // match color { - // Color::Black => { - // self.buffer[idx] &= !bit; - // } - // Color::White => { - // self.buffer[idx] |= bit; - // } - // } - // } - - // /// Draw a single Pixel with `color` - // /// - // /// limited to i16::max images (buffer_size) at the moment - // #[allow(dead_code)] - // fn draw_byte(&mut self, x: u16, y: u16, filling: u8, color: &Color) { - // let idx = match self.rotation { - // Displayorientation::Rotate0 | Displayorientation::Rotate180 => { - // x as usize / 8 + (self.width as usize / 8) * y as usize - // }, - // Displayorientation::Rotate90 | Displayorientation::Rotate270 => { - // y as usize / 8 + (self.width as usize / 8) * x as usize - // }, - // }; - - // if idx >= self.buffer.len() { - // return; - // } - - // match color { - // Color::Black => { - // self.buffer[idx] = !filling; - // }, - // Color::White => { - // self.buffer[idx] = filling; - // } - // } - // } - //TODO: write tests \ No newline at end of file From 2fb19b2df9b366b8e609d8cbfa457c87c83e3c93 Mon Sep 17 00:00:00 2001 From: Chris Date: Tue, 16 Oct 2018 23:28:39 +0200 Subject: [PATCH 15/75] added many tests to drawing --- src/drawing.rs | 124 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 121 insertions(+), 3 deletions(-) diff --git a/src/drawing.rs b/src/drawing.rs index 9bf4600..7747908 100644 --- a/src/drawing.rs +++ b/src/drawing.rs @@ -20,7 +20,7 @@ impl Default for DisplayRotation { } pub trait Display { - fn get_buffer(&self) -> &[u8]; + fn buffer(&self) -> &[u8]; fn set_rotation(&mut self, rotation: DisplayRotation); fn rotation(&self) -> DisplayRotation; } @@ -45,7 +45,7 @@ impl Default for DisplayEink42BlackWhite { } impl Display for DisplayEink42BlackWhite { - fn get_buffer(&self) -> &[u8] { + fn buffer(&self) -> &[u8] { &self.buffer } fn set_rotation(&mut self, rotation: DisplayRotation) { @@ -90,4 +90,122 @@ impl Drawing for DisplayEink42BlackWhite { } } -//TODO: write tests \ No newline at end of file +//TODO: write tests +#[cfg(test)] +mod tests { + use super::*; + use epd4in2; + use embedded_graphics::coord::Coord; + use embedded_graphics::fonts::Font6x8; + use embedded_graphics::prelude::*; + use embedded_graphics::primitives::{Circle, Line}; + + #[test] + fn from_u8() { + assert_eq!(Color::Black, Color::from(0u8)); + assert_eq!(Color::White, Color::from(1u8)); + } + + // test all values aside from 0 and 1 which all should panic + #[test] + fn from_u8_panic() { + for val in 2..=u8::max_value() { + let result = std::panic::catch_unwind(|| Color::from(val)); + assert!(result.is_err()); + } + } + + // test buffer length + #[test] + fn graphics_4in2_size() { + let display = DisplayEink42BlackWhite::default(); + assert_eq!(display.buffer().len(), 15000); + } + + // test default background color on all bytes + #[test] + fn graphics_4in2_default() { + let display = DisplayEink42BlackWhite::default(); + use epd4in2; + for &byte in display.buffer() { + assert_eq!(byte, epd4in2::constants::DEFAULT_BACKGROUND_COLOR.get_byte_value()); + } + } + + #[test] + fn graphics_4in2_rotation_0() { + let mut display = DisplayEink42BlackWhite::default(); + display.draw( + Line::new(Coord::new(0, 0), Coord::new(7, 0)) + .with_stroke(Some(Color::Black)) + .into_iter(), + ); + + let buffer = display.buffer(); + + assert_eq!(buffer[0], Color::Black.get_byte_value()); + + for &byte in buffer.iter().skip(1) { + assert_eq!(byte, epd4in2::constants::DEFAULT_BACKGROUND_COLOR.get_byte_value()); + } + } + + #[test] + fn graphics_4in2_rotation_90() { + let mut display = DisplayEink42BlackWhite::default(); + display.set_rotation(DisplayRotation::Rotate90); + display.draw( + Line::new(Coord::new(0, 392), Coord::new(0, 399)) + .with_stroke(Some(Color::Black)) + .into_iter(), + ); + + let buffer = display.buffer(); + + assert_eq!(buffer[0], Color::Black.get_byte_value()); + + for &byte in buffer.iter().skip(1) { + assert_eq!(byte, epd4in2::constants::DEFAULT_BACKGROUND_COLOR.get_byte_value()); + } + } + + #[test] + fn graphics_4in2_rotation_180() { + let mut display = DisplayEink42BlackWhite::default(); + display.set_rotation(DisplayRotation::Rotate180); + display.draw( + Line::new(Coord::new(392, 299), Coord::new(399, 299)) + .with_stroke(Some(Color::Black)) + .into_iter(), + ); + + let buffer = display.buffer(); + + assert_eq!(buffer[0], Color::Black.get_byte_value()); + + for &byte in buffer.iter().skip(1) { + assert_eq!(byte, epd4in2::constants::DEFAULT_BACKGROUND_COLOR.get_byte_value()); + } + + } + + #[test] + fn graphics_4in2_rotation_270() { + let mut display = DisplayEink42BlackWhite::default(); + display.set_rotation(DisplayRotation::Rotate270); + display.draw( + Line::new(Coord::new(299, 0), Coord::new(299, 0)) + .with_stroke(Some(Color::Black)) + .into_iter(), + ); + + let buffer = display.buffer(); + + assert_eq!(buffer[0], Color::Black.get_byte_value()); + + for &byte in buffer.iter().skip(1) { + assert_eq!(byte, epd4in2::constants::DEFAULT_BACKGROUND_COLOR.get_byte_value()); + } + + } +} \ No newline at end of file From 4ca0321573f6d7e4d981d56d21b218d0f8b54a2a Mon Sep 17 00:00:00 2001 From: Chris Date: Tue, 16 Oct 2018 23:28:51 +0200 Subject: [PATCH 16/75] added rotation examples --- examples/embedded_linux_epd4in2/src/main.rs | 52 +++++++++++++++++++-- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/examples/embedded_linux_epd4in2/src/main.rs b/examples/embedded_linux_epd4in2/src/main.rs index 84090c1..a9cb102 100644 --- a/examples/embedded_linux_epd4in2/src/main.rs +++ b/examples/embedded_linux_epd4in2/src/main.rs @@ -8,7 +8,7 @@ extern crate eink_waveshare_rs; use eink_waveshare_rs::{ EPD4in2, drawing_old::{Graphics}, - drawing::{DisplayEink42BlackWhite, Display}, + drawing::{DisplayEink42BlackWhite, Display, DisplayRotation}, color::Color, WaveshareDisplay, }; @@ -186,6 +186,51 @@ fn run() -> Result<(), std::io::Error> { delay.delay_ms(3000u16); println!("Now test new graphics:"); + + println!("Now test new graphics with rotate90:"); + let mut display = DisplayEink42BlackWhite::default(); + display.set_rotation(DisplayRotation::Rotate90); + display.draw( + Font6x8::render_str("Rotate 90!") + .with_stroke(Some(Color::Black)) + .with_fill(Some(Color::White)) + .translate(Coord::new(5, 50)) + .into_iter(), + ); + epd4in2.update_frame(&mut spi, &display.buffer()).unwrap(); + epd4in2.display_frame(&mut spi).expect("display frame new graphics"); + delay.delay_ms(2000u16); + + println!("Now test new graphics with rotate180:"); + let mut display = DisplayEink42BlackWhite::default(); + display.set_rotation(DisplayRotation::Rotate180); + display.draw( + Font6x8::render_str("Rotate 180!") + .with_stroke(Some(Color::Black)) + .with_fill(Some(Color::White)) + .translate(Coord::new(5, 50)) + .into_iter(), + ); + epd4in2.update_frame(&mut spi, &display.buffer()).unwrap(); + epd4in2.display_frame(&mut spi).expect("display frame new graphics"); + delay.delay_ms(2000u16); + + println!("Now test new graphics with rotate270:"); + let mut display = DisplayEink42BlackWhite::default(); + display.set_rotation(DisplayRotation::Rotate270); + display.draw( + Font6x8::render_str("Rotate 270!") + .with_stroke(Some(Color::Black)) + .with_fill(Some(Color::White)) + .translate(Coord::new(5, 50)) + .into_iter(), + ); + epd4in2.update_frame(&mut spi, &display.buffer()).unwrap(); + epd4in2.display_frame(&mut spi).expect("display frame new graphics"); + delay.delay_ms(2000u16); + + + println!("Now test new graphics with default rotation and some special stuff:"); let mut display = DisplayEink42BlackWhite::default(); display.draw( Circle::new(Coord::new(64, 64), 64) @@ -214,8 +259,7 @@ fn run() -> Result<(), std::io::Error> { .into_iter(), ); - //display.clear(); - //display.set_rotation(Rotation) + let mut i = 0; loop { @@ -230,7 +274,7 @@ fn run() -> Result<(), std::io::Error> { .into_iter(), ); - epd4in2.update_frame(&mut spi, &display.get_buffer()).unwrap(); + epd4in2.update_frame(&mut spi, &display.buffer()).unwrap(); epd4in2.display_frame(&mut spi).expect("display frame new graphics"); if i > 20 { From dd70d02eb7ef1bf566c73ed34e6319733aa84708 Mon Sep 17 00:00:00 2001 From: Chris Date: Tue, 16 Oct 2018 23:36:17 +0200 Subject: [PATCH 17/75] use style instead of with_stroke --- examples/embedded_linux_epd4in2/src/main.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/examples/embedded_linux_epd4in2/src/main.rs b/examples/embedded_linux_epd4in2/src/main.rs index a9cb102..ba2089c 100644 --- a/examples/embedded_linux_epd4in2/src/main.rs +++ b/examples/embedded_linux_epd4in2/src/main.rs @@ -268,8 +268,11 @@ fn run() -> Result<(), std::io::Error> { display.draw( Font6x8::render_str("Hello World!") - .with_stroke(Some(Color::Black)) - .with_fill(Some(Color::White)) + .with_style(Style { + fill_color: Some(Color::White), + stroke_color: Some(Color::Black), + stroke_width: 0u8, // Has no effect on fonts + }) .translate(Coord::new(5 + i*10, 50)) .into_iter(), ); From cc2d09f4aa9a543c94fb67f255af50f9cd19b81d Mon Sep 17 00:00:00 2001 From: Chris Date: Tue, 16 Oct 2018 23:49:21 +0200 Subject: [PATCH 18/75] try fixed embedded_graphics version --- examples/embedded_linux_epd4in2/Cargo.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/embedded_linux_epd4in2/Cargo.toml b/examples/embedded_linux_epd4in2/Cargo.toml index cf2e8f9..237f292 100644 --- a/examples/embedded_linux_epd4in2/Cargo.toml +++ b/examples/embedded_linux_epd4in2/Cargo.toml @@ -11,6 +11,7 @@ eink_waveshare_rs = { path = "../../", default-features = false, features = ["ep linux-embedded-hal = "0.2.0" -embedded-graphics = "0.4.1" +#embedded-graphics = "0.4.1" +embedded-graphics = {git = "https://github.com/Caemor/embedded-graphics", branch = "patch-1"} embedded-hal = { version = "0.2.1", features = ["unproven"] } From d37ffd5489580e67278886a9030190d432438e42 Mon Sep 17 00:00:00 2001 From: Chris Date: Tue, 16 Oct 2018 23:55:27 +0200 Subject: [PATCH 19/75] test patch --- Cargo.toml | 3 ++- examples/embedded_linux_epd4in2/Cargo.toml | 2 +- examples/embedded_linux_epd4in2/src/main.rs | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index fc9e5d3..cb92be1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,7 +29,8 @@ epd4in2_fast_update = [] [dependencies] -embedded-graphics = "0.4.1" +#embedded-graphics = "0.4.1" +embedded-graphics = {git = "https://github.com/caemor/embedded-graphics", branch = "patch-1"} [dependencies.embedded-hal] diff --git a/examples/embedded_linux_epd4in2/Cargo.toml b/examples/embedded_linux_epd4in2/Cargo.toml index 237f292..3940b13 100644 --- a/examples/embedded_linux_epd4in2/Cargo.toml +++ b/examples/embedded_linux_epd4in2/Cargo.toml @@ -12,6 +12,6 @@ eink_waveshare_rs = { path = "../../", default-features = false, features = ["ep linux-embedded-hal = "0.2.0" #embedded-graphics = "0.4.1" -embedded-graphics = {git = "https://github.com/Caemor/embedded-graphics", branch = "patch-1"} +embedded-graphics = {git = "https://github.com/caemor/embedded-graphics", branch = "patch-1"} embedded-hal = { version = "0.2.1", features = ["unproven"] } diff --git a/examples/embedded_linux_epd4in2/src/main.rs b/examples/embedded_linux_epd4in2/src/main.rs index ba2089c..06d9312 100644 --- a/examples/embedded_linux_epd4in2/src/main.rs +++ b/examples/embedded_linux_epd4in2/src/main.rs @@ -18,6 +18,7 @@ use embedded_graphics::coord::Coord; use embedded_graphics::fonts::Font6x8; use embedded_graphics::prelude::*; use embedded_graphics::primitives::{Circle, Line}; +use embedded_graphics::Drawing; use lin_hal::spidev::{self, SpidevOptions}; use lin_hal::{Pin, Spidev}; From e17697cfb18c3e5847bac9dfe52b64b56575fb7c Mon Sep 17 00:00:00 2001 From: Chris Date: Thu, 18 Oct 2018 16:09:23 +0200 Subject: [PATCH 20/75] Fix missing std-lib in a test --- src/color.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/color.rs b/src/color.rs index fdab855..7a83d44 100644 --- a/src/color.rs +++ b/src/color.rs @@ -109,6 +109,7 @@ mod tests { #[test] fn from_u8_panic() { for val in 2..=u8::max_value() { + extern crate std; let result = std::panic::catch_unwind(|| Color::from(val)); assert!(result.is_err()); } From 08457e503d301d5043520b23ac49024764f07f4f Mon Sep 17 00:00:00 2001 From: Chris Date: Thu, 18 Oct 2018 16:20:39 +0200 Subject: [PATCH 21/75] Use the fixed embedded graphics lib once more --- Cargo.toml | 4 ++-- examples/embedded_linux_epd4in2/Cargo.toml | 4 ++-- src/drawing.rs | 1 + 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index cb92be1..ee10123 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,8 +29,8 @@ epd4in2_fast_update = [] [dependencies] -#embedded-graphics = "0.4.1" -embedded-graphics = {git = "https://github.com/caemor/embedded-graphics", branch = "patch-1"} +embedded-graphics = "0.4.2" +#embedded-graphics = {git = "https://github.com/caemor/embedded-graphics", branch = "patch-1"} [dependencies.embedded-hal] diff --git a/examples/embedded_linux_epd4in2/Cargo.toml b/examples/embedded_linux_epd4in2/Cargo.toml index 3940b13..f12dbbd 100644 --- a/examples/embedded_linux_epd4in2/Cargo.toml +++ b/examples/embedded_linux_epd4in2/Cargo.toml @@ -11,7 +11,7 @@ eink_waveshare_rs = { path = "../../", default-features = false, features = ["ep linux-embedded-hal = "0.2.0" -#embedded-graphics = "0.4.1" -embedded-graphics = {git = "https://github.com/caemor/embedded-graphics", branch = "patch-1"} +embedded-graphics = "0.4.2" +#embedded-graphics = {git = "https://github.com/caemor/embedded-graphics", branch = "patch-1"} embedded-hal = { version = "0.2.1", features = ["unproven"] } diff --git a/src/drawing.rs b/src/drawing.rs index 7747908..a610a1e 100644 --- a/src/drawing.rs +++ b/src/drawing.rs @@ -110,6 +110,7 @@ mod tests { #[test] fn from_u8_panic() { for val in 2..=u8::max_value() { + extern crate std; let result = std::panic::catch_unwind(|| Color::from(val)); assert!(result.is_err()); } From dbdb8912a85a9bdd71a7578cac0a308be3453df3 Mon Sep 17 00:00:00 2001 From: Chris Date: Thu, 18 Oct 2018 16:22:44 +0200 Subject: [PATCH 22/75] cleanup --- Cargo.toml | 2 -- examples/embedded_linux_epd4in2/Cargo.toml | 1 - src/drawing.rs | 6 ++---- 3 files changed, 2 insertions(+), 7 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ee10123..eb2cd11 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,8 +30,6 @@ epd4in2_fast_update = [] [dependencies] embedded-graphics = "0.4.2" -#embedded-graphics = {git = "https://github.com/caemor/embedded-graphics", branch = "patch-1"} - [dependencies.embedded-hal] features = ["unproven"] diff --git a/examples/embedded_linux_epd4in2/Cargo.toml b/examples/embedded_linux_epd4in2/Cargo.toml index f12dbbd..845ff86 100644 --- a/examples/embedded_linux_epd4in2/Cargo.toml +++ b/examples/embedded_linux_epd4in2/Cargo.toml @@ -12,6 +12,5 @@ eink_waveshare_rs = { path = "../../", default-features = false, features = ["ep linux-embedded-hal = "0.2.0" embedded-graphics = "0.4.2" -#embedded-graphics = {git = "https://github.com/caemor/embedded-graphics", branch = "patch-1"} embedded-hal = { version = "0.2.1", features = ["unproven"] } diff --git a/src/drawing.rs b/src/drawing.rs index a610a1e..ccc0c4e 100644 --- a/src/drawing.rs +++ b/src/drawing.rs @@ -61,7 +61,7 @@ impl Drawing for DisplayEink42BlackWhite { where T: Iterator> { - use epd4in2::constants::{DEFAULT_BACKGROUND_COLOR, WIDTH, HEIGHT}; + use epd4in2::constants::WIDTH; for Pixel(UnsignedCoord(x,y), color) in item_pixels { let (idx, bit) = match self.rotation { DisplayRotation::Rotate0 | DisplayRotation::Rotate180 => ( @@ -96,9 +96,7 @@ mod tests { use super::*; use epd4in2; use embedded_graphics::coord::Coord; - use embedded_graphics::fonts::Font6x8; - use embedded_graphics::prelude::*; - use embedded_graphics::primitives::{Circle, Line}; + use embedded_graphics::primitives::Line; #[test] fn from_u8() { From 2a3b10ba948407609f68b4a1f9519d7c66233461 Mon Sep 17 00:00:00 2001 From: Chris Date: Thu, 18 Oct 2018 17:02:55 +0200 Subject: [PATCH 23/75] Don't make expensive calculations if pixel is outside the display and return early --- src/drawing.rs | 44 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/src/drawing.rs b/src/drawing.rs index ccc0c4e..08b195c 100644 --- a/src/drawing.rs +++ b/src/drawing.rs @@ -56,28 +56,46 @@ impl Display for DisplayEink42BlackWhite { } } +//TODO: add more tests for the rotation maybe? or test it at least once in real! impl Drawing for DisplayEink42BlackWhite { fn draw(&mut self, item_pixels: T) where T: Iterator> { - use epd4in2::constants::WIDTH; + use epd4in2::constants::{WIDTH, HEIGHT}; 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; + } + } + } + let (idx, bit) = match self.rotation { - DisplayRotation::Rotate0 | DisplayRotation::Rotate180 => ( - (x as usize / 8 + (WIDTH as usize / 8) * y as usize), + DisplayRotation::Rotate0 => ( + x as usize / 8 + (WIDTH as usize / 8) * y as usize, 0x80 >> (x % 8), ), - DisplayRotation::Rotate90 | DisplayRotation::Rotate270 => ( - y as usize / 8 * WIDTH as usize + x as usize, + 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), ), }; - if idx >= self.buffer.len() { - return; - } - match color { Color::Black => { self.buffer[idx] &= !bit; @@ -180,6 +198,9 @@ mod tests { let buffer = display.buffer(); + extern crate std; + std::println!("{:?}", buffer); + assert_eq!(buffer[0], Color::Black.get_byte_value()); for &byte in buffer.iter().skip(1) { @@ -193,13 +214,16 @@ mod tests { let mut display = DisplayEink42BlackWhite::default(); display.set_rotation(DisplayRotation::Rotate270); display.draw( - Line::new(Coord::new(299, 0), Coord::new(299, 0)) + Line::new(Coord::new(299, 0), Coord::new(299, 7)) .with_stroke(Some(Color::Black)) .into_iter(), ); let buffer = display.buffer(); + extern crate std; + std::println!("{:?}", buffer); + assert_eq!(buffer[0], Color::Black.get_byte_value()); for &byte in buffer.iter().skip(1) { From 90ff5234111e75889d01267389b8d18fa72681e9 Mon Sep 17 00:00:00 2001 From: Chris Date: Thu, 18 Oct 2018 21:17:56 +0200 Subject: [PATCH 24/75] simplify example --- examples/embedded_linux_epd4in2/src/main.rs | 86 ++++++++++----------- 1 file changed, 40 insertions(+), 46 deletions(-) diff --git a/examples/embedded_linux_epd4in2/src/main.rs b/examples/embedded_linux_epd4in2/src/main.rs index 06d9312..a1ded8f 100644 --- a/examples/embedded_linux_epd4in2/src/main.rs +++ b/examples/embedded_linux_epd4in2/src/main.rs @@ -122,69 +122,69 @@ fn run() -> Result<(), std::io::Error> { //fixed currently with the HackInputPin, see further above let mut epd4in2 = EPD4in2::new(&mut spi, cs, busy_in, dc, rst, &mut delay).expect("eink initalize error"); - //let mut buffer = [0u8, epd4in2.get_width() / 8 * epd4in2.get_height()]; - let mut buffer = [0u8; 15000]; + // //let mut buffer = [0u8, epd4in2.get_width() / 8 * epd4in2.get_height()]; + // let mut buffer = [0u8; 15000]; - // draw something - let mut graphics = Graphics::new(400, 300, &mut buffer); - graphics.clear(&Color::White); - graphics.draw_line(0,0,400,300, &Color::Black); + // // draw something + // let mut graphics = Graphics::new(400, 300, &mut buffer); + // graphics.clear(&Color::White); + // graphics.draw_line(0,0,400,300, &Color::Black); - graphics.draw_filled_rectangle(200,200, 230, 230, &Color::Black); - graphics.draw_line(202,202,218,228, &Color::White); + // graphics.draw_filled_rectangle(200,200, 230, 230, &Color::Black); + // graphics.draw_line(202,202,218,228, &Color::White); - graphics.draw_circle(200, 150, 130, &Color::Black); + // graphics.draw_circle(200, 150, 130, &Color::Black); - graphics.draw_pixel(390, 290, &Color::Black); + // graphics.draw_pixel(390, 290, &Color::Black); - graphics.draw_horizontal_line(0, 150, 400, &Color::Black); + // graphics.draw_horizontal_line(0, 150, 400, &Color::Black); - graphics.draw_vertical_line(200, 50, 200, &Color::Black); + // graphics.draw_vertical_line(200, 50, 200, &Color::Black); - epd4in2.clear_frame(&mut spi).expect("clear frame error"); - epd4in2.update_frame(&mut spi, graphics.get_buffer()).expect("update frame error"); - epd4in2.display_frame(&mut spi)?; + // epd4in2.clear_frame(&mut spi).expect("clear frame error"); + // epd4in2.update_frame(&mut spi, graphics.get_buffer()).expect("update frame error"); + // epd4in2.display_frame(&mut spi)?; - println!("Finished basic old graphics test"); + // println!("Finished basic old graphics test"); - delay.delay_ms(3000u16); + // delay.delay_ms(3000u16); - epd4in2.clear_frame(&mut spi)?; + // epd4in2.clear_frame(&mut spi)?; - //Test fast updating a bit more - let mut small_buffer = [0x00; 128]; - let mut circle_graphics = Graphics::new(32,32, &mut small_buffer); - circle_graphics.draw_circle(16,16, 10, &Color::Black); + // //Test fast updating a bit more + // let mut small_buffer = [0x00; 128]; + // let mut circle_graphics = Graphics::new(32,32, &mut small_buffer); + // circle_graphics.draw_circle(16,16, 10, &Color::Black); - epd4in2.update_partial_frame(&mut spi, circle_graphics.get_buffer(), 16,16, 32, 32).expect("update frame error"); - epd4in2.display_frame(&mut spi)?; + // epd4in2.update_partial_frame(&mut spi, circle_graphics.get_buffer(), 16,16, 32, 32).expect("update frame error"); + // epd4in2.display_frame(&mut spi)?; - epd4in2.update_partial_frame(&mut spi, circle_graphics.get_buffer(), 128,64, 32, 32).expect("update partial frame error"); - epd4in2.display_frame(&mut spi)?; + // epd4in2.update_partial_frame(&mut spi, circle_graphics.get_buffer(), 128,64, 32, 32).expect("update partial frame error"); + // epd4in2.display_frame(&mut spi)?; - epd4in2.update_partial_frame(&mut spi, circle_graphics.get_buffer(), 320,24, 32, 32).expect("update partial frame error"); - epd4in2.display_frame(&mut spi)?; + // epd4in2.update_partial_frame(&mut spi, circle_graphics.get_buffer(), 320,24, 32, 32).expect("update partial frame error"); + // epd4in2.display_frame(&mut spi)?; - epd4in2.update_partial_frame(&mut spi, circle_graphics.get_buffer(), 160,240, 32, 32).expect("update partial frame error"); - epd4in2.display_frame(&mut spi)?; + // epd4in2.update_partial_frame(&mut spi, circle_graphics.get_buffer(), 160,240, 32, 32).expect("update partial frame error"); + // epd4in2.display_frame(&mut spi)?; - println!("Finished partial update test"); + // println!("Finished partial update test"); - delay.delay_ms(3000u16); + // delay.delay_ms(3000u16); - //pub fn draw_string_8x8(&self, buffer: &mut[u8], x0: u16, y0: u16, input: &str, color: &Color) { - graphics.draw_string_8x8(16, 16, "hello", &Color::Black); - graphics.draw_char_8x8(250, 250, '#', &Color::Black); - graphics.draw_char_8x8(300, 16, '7', &Color::Black); - epd4in2.update_frame(&mut spi, graphics.get_buffer())?; - epd4in2.display_frame(&mut spi)?; + // //pub fn draw_string_8x8(&self, buffer: &mut[u8], x0: u16, y0: u16, input: &str, color: &Color) { + // graphics.draw_string_8x8(16, 16, "hello", &Color::Black); + // graphics.draw_char_8x8(250, 250, '#', &Color::Black); + // graphics.draw_char_8x8(300, 16, '7', &Color::Black); + // epd4in2.update_frame(&mut spi, graphics.get_buffer())?; + // epd4in2.display_frame(&mut spi)?; - println!("Finished draw string test"); + // println!("Finished draw string test"); - delay.delay_ms(3000u16); + //delay.delay_ms(3000u16); println!("Now test new graphics:"); @@ -193,8 +193,6 @@ fn run() -> Result<(), std::io::Error> { display.set_rotation(DisplayRotation::Rotate90); display.draw( Font6x8::render_str("Rotate 90!") - .with_stroke(Some(Color::Black)) - .with_fill(Some(Color::White)) .translate(Coord::new(5, 50)) .into_iter(), ); @@ -207,8 +205,6 @@ fn run() -> Result<(), std::io::Error> { display.set_rotation(DisplayRotation::Rotate180); display.draw( Font6x8::render_str("Rotate 180!") - .with_stroke(Some(Color::Black)) - .with_fill(Some(Color::White)) .translate(Coord::new(5, 50)) .into_iter(), ); @@ -221,8 +217,6 @@ fn run() -> Result<(), std::io::Error> { display.set_rotation(DisplayRotation::Rotate270); display.draw( Font6x8::render_str("Rotate 270!") - .with_stroke(Some(Color::Black)) - .with_fill(Some(Color::White)) .translate(Coord::new(5, 50)) .into_iter(), ); From 8db42f7ec7bcd1032624a301d7fbb03842222c25 Mon Sep 17 00:00:00 2001 From: Chris Date: Thu, 18 Oct 2018 21:39:33 +0200 Subject: [PATCH 25/75] find error --- examples/embedded_linux_epd4in2/src/main.rs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/examples/embedded_linux_epd4in2/src/main.rs b/examples/embedded_linux_epd4in2/src/main.rs index a1ded8f..84d3312 100644 --- a/examples/embedded_linux_epd4in2/src/main.rs +++ b/examples/embedded_linux_epd4in2/src/main.rs @@ -188,6 +188,27 @@ fn run() -> Result<(), std::io::Error> { println!("Now test new graphics:"); + println!("Now test new graphics with rotate0:"); + let mut display = DisplayEink42BlackWhite::default(); + display.set_rotation(DisplayRotation::Rotate0); + display.draw( + Font6x8::render_str("Rotate 0!") + .with_fill(Some(Color::White)) + .with_stroke(Some(Color::Black)) + .translate(Coord::new(5, 50)) + .into_iter(), + ); + display.draw( + Font6x8::render_str("Rotate 0 - inverse!") + .with_fill(Some(Color::Black)) + .with_stroke(Some(Color::White)) + .translate(Coord::new(50, 70)) + .into_iter(), + ); + epd4in2.update_frame(&mut spi, &display.buffer()).unwrap(); + epd4in2.display_frame(&mut spi).expect("display frame new graphics"); + delay.delay_ms(2000u16); + println!("Now test new graphics with rotate90:"); let mut display = DisplayEink42BlackWhite::default(); display.set_rotation(DisplayRotation::Rotate90); From a68ddb673a78eb8635de76736a3506ded9fc7c32 Mon Sep 17 00:00:00 2001 From: Chris Date: Thu, 18 Oct 2018 21:54:52 +0200 Subject: [PATCH 26/75] add some lines to the rotations --- examples/embedded_linux_epd4in2/src/main.rs | 23 +++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/examples/embedded_linux_epd4in2/src/main.rs b/examples/embedded_linux_epd4in2/src/main.rs index 84d3312..b825f3c 100644 --- a/examples/embedded_linux_epd4in2/src/main.rs +++ b/examples/embedded_linux_epd4in2/src/main.rs @@ -205,6 +205,14 @@ fn run() -> Result<(), std::io::Error> { .translate(Coord::new(50, 70)) .into_iter(), ); + + display.draw( + Line::new(Coord::new(5, 5), Coord::new(15, 15)) + .with_stroke(Some(Color::Black)) + .into_iter(), + ); + + epd4in2.update_frame(&mut spi, &display.buffer()).unwrap(); epd4in2.display_frame(&mut spi).expect("display frame new graphics"); delay.delay_ms(2000u16); @@ -217,6 +225,11 @@ fn run() -> Result<(), std::io::Error> { .translate(Coord::new(5, 50)) .into_iter(), ); + display.draw( + Line::new(Coord::new(5, 5), Coord::new(15, 15)) + .with_stroke(Some(Color::Black)) + .into_iter(), + ); epd4in2.update_frame(&mut spi, &display.buffer()).unwrap(); epd4in2.display_frame(&mut spi).expect("display frame new graphics"); delay.delay_ms(2000u16); @@ -229,6 +242,11 @@ fn run() -> Result<(), std::io::Error> { .translate(Coord::new(5, 50)) .into_iter(), ); + display.draw( + Line::new(Coord::new(5, 5), Coord::new(15, 15)) + .with_stroke(Some(Color::Black)) + .into_iter(), + ); epd4in2.update_frame(&mut spi, &display.buffer()).unwrap(); epd4in2.display_frame(&mut spi).expect("display frame new graphics"); delay.delay_ms(2000u16); @@ -241,6 +259,11 @@ fn run() -> Result<(), std::io::Error> { .translate(Coord::new(5, 50)) .into_iter(), ); + display.draw( + Line::new(Coord::new(5, 5), Coord::new(15, 15)) + .with_stroke(Some(Color::Black)) + .into_iter(), + ); epd4in2.update_frame(&mut spi, &display.buffer()).unwrap(); epd4in2.display_frame(&mut spi).expect("display frame new graphics"); delay.delay_ms(2000u16); From 4ff373f512bf885b7cab4fdf36f9b2731fa4fc08 Mon Sep 17 00:00:00 2001 From: Chris Date: Thu, 18 Oct 2018 22:06:47 +0200 Subject: [PATCH 27/75] add different style to rotate90 in example --- examples/embedded_linux_epd4in2/src/main.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/embedded_linux_epd4in2/src/main.rs b/examples/embedded_linux_epd4in2/src/main.rs index b825f3c..158d141 100644 --- a/examples/embedded_linux_epd4in2/src/main.rs +++ b/examples/embedded_linux_epd4in2/src/main.rs @@ -222,6 +222,8 @@ fn run() -> Result<(), std::io::Error> { display.set_rotation(DisplayRotation::Rotate90); display.draw( Font6x8::render_str("Rotate 90!") + .with_stroke(Some(Color::Black)) + .with_fill(Some(Color::White)) .translate(Coord::new(5, 50)) .into_iter(), ); From 73115fd0f327efd210309163d8c333f9a9a4a698 Mon Sep 17 00:00:00 2001 From: Chris Date: Thu, 18 Oct 2018 22:19:36 +0200 Subject: [PATCH 28/75] tes --- examples/embedded_linux_epd4in2/src/main.rs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/examples/embedded_linux_epd4in2/src/main.rs b/examples/embedded_linux_epd4in2/src/main.rs index 158d141..6ce118e 100644 --- a/examples/embedded_linux_epd4in2/src/main.rs +++ b/examples/embedded_linux_epd4in2/src/main.rs @@ -15,7 +15,7 @@ use eink_waveshare_rs::{ extern crate embedded_graphics; use embedded_graphics::coord::Coord; -use embedded_graphics::fonts::Font6x8; +use embedded_graphics::fonts::{Font6x8, Font12x16}; use embedded_graphics::prelude::*; use embedded_graphics::primitives::{Circle, Line}; use embedded_graphics::Drawing; @@ -289,7 +289,7 @@ fn run() -> Result<(), std::io::Error> { .into_iter(), ); display.draw( - Font6x8::render_str("It's working!") + Font6x8::render_str("It's working-WoB!") // Using Style here .with_style(Style { fill_color: Some(Color::Black), @@ -300,6 +300,18 @@ fn run() -> Result<(), std::io::Error> { .into_iter(), ); + display.draw( + Font6x8::render_str("It's working-BoW!") + // Using Style here + .with_style(Style { + fill_color: Some(Color::White), + stroke_color: Some(Color::Black), + stroke_width: 0u8, // Has no effect on fonts + }) + .translate(Coord::new(50, 50)) + .into_iter(), + ); + let mut i = 0; From 967c67f9a6a901cacc168edb1e2923ecb8a69be0 Mon Sep 17 00:00:00 2001 From: Chris Date: Thu, 18 Oct 2018 22:21:44 +0200 Subject: [PATCH 29/75] position font elsewhere --- examples/embedded_linux_epd4in2/src/main.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/examples/embedded_linux_epd4in2/src/main.rs b/examples/embedded_linux_epd4in2/src/main.rs index 6ce118e..8638386 100644 --- a/examples/embedded_linux_epd4in2/src/main.rs +++ b/examples/embedded_linux_epd4in2/src/main.rs @@ -302,13 +302,25 @@ fn run() -> Result<(), std::io::Error> { display.draw( Font6x8::render_str("It's working-BoW!") + // Using Style here + .with_style(Style { + fill_color: Some(Color::Black), + stroke_color: Some(Color::Black), + stroke_width: 0u8, // Has no effect on fonts + }) + .translate(Coord::new(50, 200)) + .into_iter(), + ); + + display.draw( + Font12x16::render_str("It's working-BoW!") // Using Style here .with_style(Style { fill_color: Some(Color::White), stroke_color: Some(Color::Black), stroke_width: 0u8, // Has no effect on fonts }) - .translate(Coord::new(50, 50)) + .translate(Coord::new(50, 22)) .into_iter(), ); From 7dd826795ac8b74e82afe3996d5005d4c188469e Mon Sep 17 00:00:00 2001 From: Chris Date: Thu, 18 Oct 2018 22:27:13 +0200 Subject: [PATCH 30/75] inverse the colors --- src/color.rs | 12 ++++++------ src/drawing.rs | 6 ++++-- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/color.rs b/src/color.rs index 7a83d44..93c9506 100644 --- a/src/color.rs +++ b/src/color.rs @@ -12,23 +12,23 @@ impl Color { /// Get the color encoding of the color for one bit pub fn get_bit_value(&self) -> u8 { match self { - Color::White => 1u8, - Color::Black => 0u8, + Color::White => 0u8, + Color::Black => 1u8, } } /// Gets a full byte of black or white pixels pub fn get_byte_value(&self) -> u8 { match self { - Color::White => 0xff, - Color::Black => 0x00, + Color::White => 0x00, + Color::Black => 0xff, } } fn from_u8(val: u8) -> Self { match val { - 0 => Color::Black, - 1 => Color::White, + 1 => Color::Black, + 0 => Color::White, e => panic!("DisplayColor only parses 0 and 1 (Black and White) and not `{}`", e), } } diff --git a/src/drawing.rs b/src/drawing.rs index 08b195c..98b7236 100644 --- a/src/drawing.rs +++ b/src/drawing.rs @@ -98,10 +98,12 @@ impl Drawing for DisplayEink42BlackWhite { match color { Color::Black => { - self.buffer[idx] &= !bit; + //self.buffer[idx] &= !bit; + self.buffer[idx] |= bit; } Color::White => { - self.buffer[idx] |= bit; + //self.buffer[idx] |= bit; + self.buffer[idx] &= !bit; } } } From b9a833ec5f1c550db1edc84e0b6c411cd2a77d31 Mon Sep 17 00:00:00 2001 From: Chris Date: Thu, 18 Oct 2018 22:30:49 +0200 Subject: [PATCH 31/75] Revert "inverse the colors" This reverts commit 7dd826795ac8b74e82afe3996d5005d4c188469e. --- src/color.rs | 12 ++++++------ src/drawing.rs | 6 ++---- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/color.rs b/src/color.rs index 93c9506..7a83d44 100644 --- a/src/color.rs +++ b/src/color.rs @@ -12,23 +12,23 @@ impl Color { /// Get the color encoding of the color for one bit pub fn get_bit_value(&self) -> u8 { match self { - Color::White => 0u8, - Color::Black => 1u8, + Color::White => 1u8, + Color::Black => 0u8, } } /// Gets a full byte of black or white pixels pub fn get_byte_value(&self) -> u8 { match self { - Color::White => 0x00, - Color::Black => 0xff, + Color::White => 0xff, + Color::Black => 0x00, } } fn from_u8(val: u8) -> Self { match val { - 1 => Color::Black, - 0 => Color::White, + 0 => Color::Black, + 1 => Color::White, e => panic!("DisplayColor only parses 0 and 1 (Black and White) and not `{}`", e), } } diff --git a/src/drawing.rs b/src/drawing.rs index 98b7236..08b195c 100644 --- a/src/drawing.rs +++ b/src/drawing.rs @@ -98,12 +98,10 @@ impl Drawing for DisplayEink42BlackWhite { match color { Color::Black => { - //self.buffer[idx] &= !bit; - self.buffer[idx] |= bit; + self.buffer[idx] &= !bit; } Color::White => { - //self.buffer[idx] |= bit; - self.buffer[idx] &= !bit; + self.buffer[idx] |= bit; } } } From 1acdd8d10770fc77e7d0d8da7df03ef3612dae50 Mon Sep 17 00:00:00 2001 From: Chris Date: Thu, 18 Oct 2018 22:44:03 +0200 Subject: [PATCH 32/75] add a line through the big font --- examples/embedded_linux_epd4in2/src/main.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/examples/embedded_linux_epd4in2/src/main.rs b/examples/embedded_linux_epd4in2/src/main.rs index 8638386..8780160 100644 --- a/examples/embedded_linux_epd4in2/src/main.rs +++ b/examples/embedded_linux_epd4in2/src/main.rs @@ -305,14 +305,14 @@ fn run() -> Result<(), std::io::Error> { // Using Style here .with_style(Style { fill_color: Some(Color::Black), - stroke_color: Some(Color::Black), + stroke_color: Some(Color::White), stroke_width: 0u8, // Has no effect on fonts }) .translate(Coord::new(50, 200)) .into_iter(), ); - display.draw( + display.draw( Font12x16::render_str("It's working-BoW!") // Using Style here .with_style(Style { @@ -324,6 +324,12 @@ fn run() -> Result<(), std::io::Error> { .into_iter(), ); + display.draw( + Line::new(Coord::new(60, 28), Coord::new(120, 28)) + .with_stroke(Some(Color::White)) + .into_iter(), + ); + let mut i = 0; From dadc302945b71bc33e0436079708a7bbe9fcee48 Mon Sep 17 00:00:00 2001 From: Chris Date: Thu, 18 Oct 2018 22:52:54 +0200 Subject: [PATCH 33/75] test inverse color matching once more --- src/drawing.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/drawing.rs b/src/drawing.rs index 08b195c..98b7236 100644 --- a/src/drawing.rs +++ b/src/drawing.rs @@ -98,10 +98,12 @@ impl Drawing for DisplayEink42BlackWhite { match color { Color::Black => { - self.buffer[idx] &= !bit; + //self.buffer[idx] &= !bit; + self.buffer[idx] |= bit; } Color::White => { - self.buffer[idx] |= bit; + //self.buffer[idx] |= bit; + self.buffer[idx] &= !bit; } } } From b5dcbb0454322c5ffc2c5d444727f6b01c20c572 Mon Sep 17 00:00:00 2001 From: Chris Date: Thu, 18 Oct 2018 22:53:41 +0200 Subject: [PATCH 34/75] fix example --- examples/embedded_linux_epd4in2/src/main.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/embedded_linux_epd4in2/src/main.rs b/examples/embedded_linux_epd4in2/src/main.rs index 8780160..615e297 100644 --- a/examples/embedded_linux_epd4in2/src/main.rs +++ b/examples/embedded_linux_epd4in2/src/main.rs @@ -304,8 +304,8 @@ fn run() -> Result<(), std::io::Error> { Font6x8::render_str("It's working-BoW!") // Using Style here .with_style(Style { - fill_color: Some(Color::Black), - stroke_color: Some(Color::White), + fill_color: Some(Color::White), + stroke_color: Some(Color::Black), stroke_width: 0u8, // Has no effect on fonts }) .translate(Coord::new(50, 200)) From 33ebb1e4f7872914ea0532e41cec8dec6155e056 Mon Sep 17 00:00:00 2001 From: Chris Date: Thu, 18 Oct 2018 22:54:57 +0200 Subject: [PATCH 35/75] reduce loop --- examples/embedded_linux_epd4in2/src/main.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/embedded_linux_epd4in2/src/main.rs b/examples/embedded_linux_epd4in2/src/main.rs index 615e297..7f535f5 100644 --- a/examples/embedded_linux_epd4in2/src/main.rs +++ b/examples/embedded_linux_epd4in2/src/main.rs @@ -333,9 +333,10 @@ fn run() -> Result<(), std::io::Error> { let mut i = 0; + let mut limit = 2 loop { i += 1; - println!("Moving Hello World. Loop {} from 20", i); + println!("Moving Hello World. Loop {} from {}", i, limit); display.draw( Font6x8::render_str("Hello World!") @@ -350,7 +351,7 @@ fn run() -> Result<(), std::io::Error> { epd4in2.update_frame(&mut spi, &display.buffer()).unwrap(); epd4in2.display_frame(&mut spi).expect("display frame new graphics"); - if i > 20 { + if i >= 20 { break; } From 9d6a009f497af8b75714b8d0f1c6744a56127f2f Mon Sep 17 00:00:00 2001 From: Chris Date: Thu, 18 Oct 2018 22:55:42 +0200 Subject: [PATCH 36/75] forgot semicolon --- examples/embedded_linux_epd4in2/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/embedded_linux_epd4in2/src/main.rs b/examples/embedded_linux_epd4in2/src/main.rs index 7f535f5..6fff958 100644 --- a/examples/embedded_linux_epd4in2/src/main.rs +++ b/examples/embedded_linux_epd4in2/src/main.rs @@ -333,7 +333,7 @@ fn run() -> Result<(), std::io::Error> { let mut i = 0; - let mut limit = 2 + let mut limit = 2; loop { i += 1; println!("Moving Hello World. Loop {} from {}", i, limit); From 591d25f74a95736e27f41a896b3ff50b91b1ef3f Mon Sep 17 00:00:00 2001 From: Chris Date: Thu, 18 Oct 2018 22:58:34 +0200 Subject: [PATCH 37/75] reverse color change --- examples/embedded_linux_epd4in2/src/main.rs | 2 +- src/drawing.rs | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/examples/embedded_linux_epd4in2/src/main.rs b/examples/embedded_linux_epd4in2/src/main.rs index 6fff958..df77102 100644 --- a/examples/embedded_linux_epd4in2/src/main.rs +++ b/examples/embedded_linux_epd4in2/src/main.rs @@ -351,7 +351,7 @@ fn run() -> Result<(), std::io::Error> { epd4in2.update_frame(&mut spi, &display.buffer()).unwrap(); epd4in2.display_frame(&mut spi).expect("display frame new graphics"); - if i >= 20 { + if i >= limit { break; } diff --git a/src/drawing.rs b/src/drawing.rs index 98b7236..08b195c 100644 --- a/src/drawing.rs +++ b/src/drawing.rs @@ -98,12 +98,10 @@ impl Drawing for DisplayEink42BlackWhite { match color { Color::Black => { - //self.buffer[idx] &= !bit; - self.buffer[idx] |= bit; + self.buffer[idx] &= !bit; } Color::White => { - //self.buffer[idx] |= bit; - self.buffer[idx] &= !bit; + self.buffer[idx] |= bit; } } } From a75a9b74bdd3a5b01910fc23bba35dea07be6208 Mon Sep 17 00:00:00 2001 From: Chris Date: Thu, 18 Oct 2018 22:59:53 +0200 Subject: [PATCH 38/75] add anotherline to example --- examples/embedded_linux_epd4in2/src/main.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/examples/embedded_linux_epd4in2/src/main.rs b/examples/embedded_linux_epd4in2/src/main.rs index df77102..5088139 100644 --- a/examples/embedded_linux_epd4in2/src/main.rs +++ b/examples/embedded_linux_epd4in2/src/main.rs @@ -330,6 +330,12 @@ fn run() -> Result<(), std::io::Error> { .into_iter(), ); + display.draw( + Line::new(Coord::new(90, 14), Coord::new(90, 42)) + .with_stroke(Some(Color::Black)) + .into_iter(), + ); + let mut i = 0; From e1b76c73a38e29c78b0dd8f3475869344d4256c7 Mon Sep 17 00:00:00 2001 From: Chris Date: Thu, 18 Oct 2018 23:15:14 +0200 Subject: [PATCH 39/75] test branch of embedded-graphics --- Cargo.toml | 3 ++- examples/embedded_linux_epd4in2/Cargo.toml | 3 ++- examples/embedded_linux_epd4in2/src/main.rs | 8 ++++++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index eb2cd11..ee18ca5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,7 +29,8 @@ epd4in2_fast_update = [] [dependencies] -embedded-graphics = "0.4.2" +# embedded-graphics = "0.4.2" +embedded-graphics = {git = "https://github.com/caemor/embedded-graphics", branch = "test-change"} [dependencies.embedded-hal] features = ["unproven"] diff --git a/examples/embedded_linux_epd4in2/Cargo.toml b/examples/embedded_linux_epd4in2/Cargo.toml index 845ff86..19b3912 100644 --- a/examples/embedded_linux_epd4in2/Cargo.toml +++ b/examples/embedded_linux_epd4in2/Cargo.toml @@ -11,6 +11,7 @@ eink_waveshare_rs = { path = "../../", default-features = false, features = ["ep linux-embedded-hal = "0.2.0" -embedded-graphics = "0.4.2" +# embedded-graphics = "0.4.2" +embedded-graphics = {git = "https://github.com/caemor/embedded-graphics", branch = "test-change"} embedded-hal = { version = "0.2.1", features = ["unproven"] } diff --git a/examples/embedded_linux_epd4in2/src/main.rs b/examples/embedded_linux_epd4in2/src/main.rs index 5088139..43358c2 100644 --- a/examples/embedded_linux_epd4in2/src/main.rs +++ b/examples/embedded_linux_epd4in2/src/main.rs @@ -193,15 +193,15 @@ fn run() -> Result<(), std::io::Error> { display.set_rotation(DisplayRotation::Rotate0); display.draw( Font6x8::render_str("Rotate 0!") - .with_fill(Some(Color::White)) .with_stroke(Some(Color::Black)) + .with_fill(Some(Color::White)) .translate(Coord::new(5, 50)) .into_iter(), ); display.draw( Font6x8::render_str("Rotate 0 - inverse!") - .with_fill(Some(Color::Black)) .with_stroke(Some(Color::White)) + .with_fill(Some(Color::Black)) .translate(Coord::new(50, 70)) .into_iter(), ); @@ -241,6 +241,8 @@ fn run() -> Result<(), std::io::Error> { display.set_rotation(DisplayRotation::Rotate180); display.draw( Font6x8::render_str("Rotate 180!") + .with_stroke(Some(Color::Black)) + .with_fill(Some(Color::White)) .translate(Coord::new(5, 50)) .into_iter(), ); @@ -258,6 +260,8 @@ fn run() -> Result<(), std::io::Error> { display.set_rotation(DisplayRotation::Rotate270); display.draw( Font6x8::render_str("Rotate 270!") + .with_stroke(Some(Color::Black)) + .with_fill(Some(Color::White)) .translate(Coord::new(5, 50)) .into_iter(), ); From 529b58cd748058d015e21fbb62a63e4a927c6ebe Mon Sep 17 00:00:00 2001 From: Chris Date: Thu, 18 Oct 2018 23:47:12 +0200 Subject: [PATCH 40/75] test if there was really a change or if the upload to crates.io was broken --- Cargo.toml | 2 +- examples/embedded_linux_epd4in2/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ee18ca5..b9e7869 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,7 +30,7 @@ epd4in2_fast_update = [] [dependencies] # embedded-graphics = "0.4.2" -embedded-graphics = {git = "https://github.com/caemor/embedded-graphics", branch = "test-change"} +embedded-graphics = {git = "https://github.com/caemor/embedded-graphics", branch = "master"} [dependencies.embedded-hal] features = ["unproven"] diff --git a/examples/embedded_linux_epd4in2/Cargo.toml b/examples/embedded_linux_epd4in2/Cargo.toml index 19b3912..10e110f 100644 --- a/examples/embedded_linux_epd4in2/Cargo.toml +++ b/examples/embedded_linux_epd4in2/Cargo.toml @@ -12,6 +12,6 @@ eink_waveshare_rs = { path = "../../", default-features = false, features = ["ep linux-embedded-hal = "0.2.0" # embedded-graphics = "0.4.2" -embedded-graphics = {git = "https://github.com/caemor/embedded-graphics", branch = "test-change"} +embedded-graphics = {git = "https://github.com/caemor/embedded-graphics", branch = "master"} embedded-hal = { version = "0.2.1", features = ["unproven"] } From a29e6530b4c4236373a4cf0c37a5e8f54525bf22 Mon Sep 17 00:00:00 2001 From: Chris Date: Thu, 18 Oct 2018 23:49:41 +0200 Subject: [PATCH 41/75] check upstream/master --- Cargo.toml | 3 ++- examples/embedded_linux_epd4in2/Cargo.toml | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b9e7869..deb8a35 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,7 +30,8 @@ epd4in2_fast_update = [] [dependencies] # embedded-graphics = "0.4.2" -embedded-graphics = {git = "https://github.com/caemor/embedded-graphics", branch = "master"} +# embedded-graphics = {git = "https://github.com/caemor/embedded-graphics", branch = "master"} +embedded-graphics = {git = "https://github.com/jamwaffles/embedded-graphics", branch = "master"} [dependencies.embedded-hal] features = ["unproven"] diff --git a/examples/embedded_linux_epd4in2/Cargo.toml b/examples/embedded_linux_epd4in2/Cargo.toml index 10e110f..bb36b1a 100644 --- a/examples/embedded_linux_epd4in2/Cargo.toml +++ b/examples/embedded_linux_epd4in2/Cargo.toml @@ -12,6 +12,9 @@ eink_waveshare_rs = { path = "../../", default-features = false, features = ["ep linux-embedded-hal = "0.2.0" # embedded-graphics = "0.4.2" -embedded-graphics = {git = "https://github.com/caemor/embedded-graphics", branch = "master"} +# embedded-graphics = {git = "https://github.com/caemor/embedded-graphics", branch = "master"} +embedded-graphics = {git = "https://github.com/jamwaffles/embedded-graphics", branch = "master"} + + embedded-hal = { version = "0.2.1", features = ["unproven"] } From c145300c5dac5ef68c3c225b9b0ba04bb2207418 Mon Sep 17 00:00:00 2001 From: Chris Date: Thu, 18 Oct 2018 23:51:37 +0200 Subject: [PATCH 42/75] try crates.io version once more --- Cargo.toml | 4 ++-- examples/embedded_linux_epd4in2/Cargo.toml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index deb8a35..38e174b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,9 +29,9 @@ epd4in2_fast_update = [] [dependencies] -# embedded-graphics = "0.4.2" +embedded-graphics = "0.4.2" # embedded-graphics = {git = "https://github.com/caemor/embedded-graphics", branch = "master"} -embedded-graphics = {git = "https://github.com/jamwaffles/embedded-graphics", branch = "master"} +# embedded-graphics = {git = "https://github.com/jamwaffles/embedded-graphics", branch = "master"} [dependencies.embedded-hal] features = ["unproven"] diff --git a/examples/embedded_linux_epd4in2/Cargo.toml b/examples/embedded_linux_epd4in2/Cargo.toml index bb36b1a..d27968d 100644 --- a/examples/embedded_linux_epd4in2/Cargo.toml +++ b/examples/embedded_linux_epd4in2/Cargo.toml @@ -11,9 +11,9 @@ eink_waveshare_rs = { path = "../../", default-features = false, features = ["ep linux-embedded-hal = "0.2.0" -# embedded-graphics = "0.4.2" +embedded-graphics = "0.4.2" # embedded-graphics = {git = "https://github.com/caemor/embedded-graphics", branch = "master"} -embedded-graphics = {git = "https://github.com/jamwaffles/embedded-graphics", branch = "master"} +# embedded-graphics = {git = "https://github.com/jamwaffles/embedded-graphics", branch = "master"} From 5fbf91216cb843def2151fbb07b458625ef3e434 Mon Sep 17 00:00:00 2001 From: Chris Date: Fri, 19 Oct 2018 07:59:53 +0200 Subject: [PATCH 43/75] embedded graphics should be fixed now --- Cargo.toml | 2 +- examples/embedded_linux_epd4in2/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 38e174b..34de391 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,7 +29,7 @@ epd4in2_fast_update = [] [dependencies] -embedded-graphics = "0.4.2" +embedded-graphics = "0.4.3" # embedded-graphics = {git = "https://github.com/caemor/embedded-graphics", branch = "master"} # embedded-graphics = {git = "https://github.com/jamwaffles/embedded-graphics", branch = "master"} diff --git a/examples/embedded_linux_epd4in2/Cargo.toml b/examples/embedded_linux_epd4in2/Cargo.toml index d27968d..1731f4a 100644 --- a/examples/embedded_linux_epd4in2/Cargo.toml +++ b/examples/embedded_linux_epd4in2/Cargo.toml @@ -11,7 +11,7 @@ eink_waveshare_rs = { path = "../../", default-features = false, features = ["ep linux-embedded-hal = "0.2.0" -embedded-graphics = "0.4.2" +embedded-graphics = "0.4.3" # embedded-graphics = {git = "https://github.com/caemor/embedded-graphics", branch = "master"} # embedded-graphics = {git = "https://github.com/jamwaffles/embedded-graphics", branch = "master"} From e21dbfb7e342374102ec8c84819d6ac8ff0ddfcc Mon Sep 17 00:00:00 2001 From: Chris Date: Fri, 19 Oct 2018 08:21:59 +0200 Subject: [PATCH 44/75] Removed duplicate test (from color) --- src/drawing.rs | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/drawing.rs b/src/drawing.rs index 08b195c..f46595c 100644 --- a/src/drawing.rs +++ b/src/drawing.rs @@ -122,15 +122,7 @@ mod tests { assert_eq!(Color::White, Color::from(1u8)); } - // test all values aside from 0 and 1 which all should panic - #[test] - fn from_u8_panic() { - for val in 2..=u8::max_value() { - extern crate std; - let result = std::panic::catch_unwind(|| Color::from(val)); - assert!(result.is_err()); - } - } + // test buffer length #[test] From 0fc3b5da188beb0f77cdbdd4d516c15e2e6f69fa Mon Sep 17 00:00:00 2001 From: Chris Date: Fri, 19 Oct 2018 08:46:15 +0200 Subject: [PATCH 45/75] 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 From b3c41b0e7f76c74881ac616335790f7127333818 Mon Sep 17 00:00:00 2001 From: Chris Date: Fri, 19 Oct 2018 09:17:37 +0200 Subject: [PATCH 46/75] improve example --- examples/embedded_linux_epd4in2/src/main.rs | 163 ++------------------ 1 file changed, 15 insertions(+), 148 deletions(-) diff --git a/examples/embedded_linux_epd4in2/src/main.rs b/examples/embedded_linux_epd4in2/src/main.rs index 43358c2..74cfece 100644 --- a/examples/embedded_linux_epd4in2/src/main.rs +++ b/examples/embedded_linux_epd4in2/src/main.rs @@ -122,73 +122,7 @@ fn run() -> Result<(), std::io::Error> { //fixed currently with the HackInputPin, see further above let mut epd4in2 = EPD4in2::new(&mut spi, cs, busy_in, dc, rst, &mut delay).expect("eink initalize error"); - // //let mut buffer = [0u8, epd4in2.get_width() / 8 * epd4in2.get_height()]; - // let mut buffer = [0u8; 15000]; - - // // draw something - // let mut graphics = Graphics::new(400, 300, &mut buffer); - // graphics.clear(&Color::White); - // graphics.draw_line(0,0,400,300, &Color::Black); - - // graphics.draw_filled_rectangle(200,200, 230, 230, &Color::Black); - // graphics.draw_line(202,202,218,228, &Color::White); - - // graphics.draw_circle(200, 150, 130, &Color::Black); - - // graphics.draw_pixel(390, 290, &Color::Black); - - // graphics.draw_horizontal_line(0, 150, 400, &Color::Black); - - // graphics.draw_vertical_line(200, 50, 200, &Color::Black); - - // epd4in2.clear_frame(&mut spi).expect("clear frame error"); - // epd4in2.update_frame(&mut spi, graphics.get_buffer()).expect("update frame error"); - // epd4in2.display_frame(&mut spi)?; - - // println!("Finished basic old graphics test"); - - // delay.delay_ms(3000u16); - - // epd4in2.clear_frame(&mut spi)?; - - // //Test fast updating a bit more - // let mut small_buffer = [0x00; 128]; - // let mut circle_graphics = Graphics::new(32,32, &mut small_buffer); - // circle_graphics.draw_circle(16,16, 10, &Color::Black); - - // epd4in2.update_partial_frame(&mut spi, circle_graphics.get_buffer(), 16,16, 32, 32).expect("update frame error"); - // epd4in2.display_frame(&mut spi)?; - - // epd4in2.update_partial_frame(&mut spi, circle_graphics.get_buffer(), 128,64, 32, 32).expect("update partial frame error"); - // epd4in2.display_frame(&mut spi)?; - - // epd4in2.update_partial_frame(&mut spi, circle_graphics.get_buffer(), 320,24, 32, 32).expect("update partial frame error"); - // epd4in2.display_frame(&mut spi)?; - - // epd4in2.update_partial_frame(&mut spi, circle_graphics.get_buffer(), 160,240, 32, 32).expect("update partial frame error"); - // epd4in2.display_frame(&mut spi)?; - - // println!("Finished partial update test"); - - // delay.delay_ms(3000u16); - - - - - // //pub fn draw_string_8x8(&self, buffer: &mut[u8], x0: u16, y0: u16, input: &str, color: &Color) { - // graphics.draw_string_8x8(16, 16, "hello", &Color::Black); - // graphics.draw_char_8x8(250, 250, '#', &Color::Black); - // graphics.draw_char_8x8(300, 16, '7', &Color::Black); - // epd4in2.update_frame(&mut spi, graphics.get_buffer())?; - // epd4in2.display_frame(&mut spi)?; - - // println!("Finished draw string test"); - - //delay.delay_ms(3000u16); - - println!("Now test new graphics:"); - - println!("Now test new graphics with rotate0:"); + println!("Test all the rotations"); let mut display = DisplayEink42BlackWhite::default(); display.set_rotation(DisplayRotation::Rotate0); display.draw( @@ -198,27 +132,7 @@ fn run() -> Result<(), std::io::Error> { .translate(Coord::new(5, 50)) .into_iter(), ); - display.draw( - Font6x8::render_str("Rotate 0 - inverse!") - .with_stroke(Some(Color::White)) - .with_fill(Some(Color::Black)) - .translate(Coord::new(50, 70)) - .into_iter(), - ); - display.draw( - Line::new(Coord::new(5, 5), Coord::new(15, 15)) - .with_stroke(Some(Color::Black)) - .into_iter(), - ); - - - epd4in2.update_frame(&mut spi, &display.buffer()).unwrap(); - epd4in2.display_frame(&mut spi).expect("display frame new graphics"); - delay.delay_ms(2000u16); - - println!("Now test new graphics with rotate90:"); - let mut display = DisplayEink42BlackWhite::default(); display.set_rotation(DisplayRotation::Rotate90); display.draw( Font6x8::render_str("Rotate 90!") @@ -227,17 +141,7 @@ fn run() -> Result<(), std::io::Error> { .translate(Coord::new(5, 50)) .into_iter(), ); - display.draw( - Line::new(Coord::new(5, 5), Coord::new(15, 15)) - .with_stroke(Some(Color::Black)) - .into_iter(), - ); - epd4in2.update_frame(&mut spi, &display.buffer()).unwrap(); - epd4in2.display_frame(&mut spi).expect("display frame new graphics"); - delay.delay_ms(2000u16); - println!("Now test new graphics with rotate180:"); - let mut display = DisplayEink42BlackWhite::default(); display.set_rotation(DisplayRotation::Rotate180); display.draw( Font6x8::render_str("Rotate 180!") @@ -246,17 +150,7 @@ fn run() -> Result<(), std::io::Error> { .translate(Coord::new(5, 50)) .into_iter(), ); - display.draw( - Line::new(Coord::new(5, 5), Coord::new(15, 15)) - .with_stroke(Some(Color::Black)) - .into_iter(), - ); - epd4in2.update_frame(&mut spi, &display.buffer()).unwrap(); - epd4in2.display_frame(&mut spi).expect("display frame new graphics"); - delay.delay_ms(2000u16); - println!("Now test new graphics with rotate270:"); - let mut display = DisplayEink42BlackWhite::default(); display.set_rotation(DisplayRotation::Rotate270); display.draw( Font6x8::render_str("Rotate 270!") @@ -265,18 +159,17 @@ fn run() -> Result<(), std::io::Error> { .translate(Coord::new(5, 50)) .into_iter(), ); - display.draw( - Line::new(Coord::new(5, 5), Coord::new(15, 15)) - .with_stroke(Some(Color::Black)) - .into_iter(), - ); + + epd4in2.update_frame(&mut spi, &display.buffer()).unwrap(); epd4in2.display_frame(&mut spi).expect("display frame new graphics"); - delay.delay_ms(2000u16); + delay.delay_ms(5000u16); println!("Now test new graphics with default rotation and some special stuff:"); let mut display = DisplayEink42BlackWhite::default(); + + // draw a analog clock display.draw( Circle::new(Coord::new(64, 64), 64) .with_stroke(Some(Color::Black)) @@ -292,6 +185,8 @@ fn run() -> Result<(), std::io::Error> { .with_stroke(Some(Color::Black)) .into_iter(), ); + + // draw white on black background display.draw( Font6x8::render_str("It's working-WoB!") // Using Style here @@ -304,18 +199,7 @@ fn run() -> Result<(), std::io::Error> { .into_iter(), ); - display.draw( - Font6x8::render_str("It's working-BoW!") - // Using Style here - .with_style(Style { - fill_color: Some(Color::White), - stroke_color: Some(Color::Black), - stroke_width: 0u8, // Has no effect on fonts - }) - .translate(Coord::new(50, 200)) - .into_iter(), - ); - + // use bigger/different font display.draw( Font12x16::render_str("It's working-BoW!") // Using Style here @@ -324,32 +208,18 @@ fn run() -> Result<(), std::io::Error> { stroke_color: Some(Color::Black), stroke_width: 0u8, // Has no effect on fonts }) - .translate(Coord::new(50, 22)) - .into_iter(), - ); - - display.draw( - Line::new(Coord::new(60, 28), Coord::new(120, 28)) - .with_stroke(Some(Color::White)) - .into_iter(), - ); - - display.draw( - Line::new(Coord::new(90, 14), Coord::new(90, 42)) - .with_stroke(Some(Color::Black)) + .translate(Coord::new(50, 200)) .into_iter(), ); - - let mut i = 0; - let mut limit = 2; - loop { - i += 1; + // a moving `Hello World!` + let limit = 10; + for i in 0..limit { println!("Moving Hello World. Loop {} from {}", i, limit); display.draw( - Font6x8::render_str("Hello World!") + Font6x8::render_str(" Hello World! ") .with_style(Style { fill_color: Some(Color::White), stroke_color: Some(Color::Black), @@ -361,10 +231,7 @@ fn run() -> Result<(), std::io::Error> { epd4in2.update_frame(&mut spi, &display.buffer()).unwrap(); epd4in2.display_frame(&mut spi).expect("display frame new graphics"); - if i >= limit { - - break; - } + delay.delay_ms(1_000u16); } From 0b77b069a4d1d737fcec5f189d9a37dce6aa1ea3 Mon Sep 17 00:00:00 2001 From: Chris Date: Fri, 19 Oct 2018 09:19:36 +0200 Subject: [PATCH 47/75] improve moving hello world in example --- examples/embedded_linux_epd4in2/src/main.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/embedded_linux_epd4in2/src/main.rs b/examples/embedded_linux_epd4in2/src/main.rs index 74cfece..871aef0 100644 --- a/examples/embedded_linux_epd4in2/src/main.rs +++ b/examples/embedded_linux_epd4in2/src/main.rs @@ -219,13 +219,13 @@ fn run() -> Result<(), std::io::Error> { println!("Moving Hello World. Loop {} from {}", i, limit); display.draw( - Font6x8::render_str(" Hello World! ") + Font6x8::render_str(" Hello World! ") .with_style(Style { fill_color: Some(Color::White), stroke_color: Some(Color::Black), stroke_width: 0u8, // Has no effect on fonts }) - .translate(Coord::new(5 + i*10, 50)) + .translate(Coord::new(5 + i*12, 50)) .into_iter(), ); From bbdecdb6f7e54cf952fd02e1e8dd7c0b906550a0 Mon Sep 17 00:00:00 2001 From: Chris Date: Fri, 19 Oct 2018 09:47:36 +0200 Subject: [PATCH 48/75] Update documenatation --- README.md | 15 +++------------ examples/embedded_linux_epd1in54/src/main.rs | 9 ++------- examples/embedded_linux_epd4in2/src/main.rs | 8 +------- 3 files changed, 6 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 80aaa30..cea48e0 100644 --- a/README.md +++ b/README.md @@ -60,24 +60,15 @@ They are also called A and B, but you shouldn't get confused and mix it with the ## TODO's -- [ ] add more examples (e.g. for f3) - [ ] improve the partial drawing/check the timings/timing improvements/.... -- [ ] for later: add support for the smaller waveshare epds +- [ ] for later: add support for more waveshare epds - [ ] License: Stay with ISC (=MIT) or go to the Apache+MIT Dual License as used in many other projects? ## Graphics/Drawing -Supports: -- Lines -- Squares -- Circles -- Pixels -- Chars -- Strings +It is recommended to use the [embedded graphics](https://crates.io/crates/embedded-graphics) library. -Chars and Strings work with a 8x8-Font. - -Support for bigger sized/independent Fonts is in work. +Even though any u8-slice works, it is not recommended! ## Examples diff --git a/examples/embedded_linux_epd1in54/src/main.rs b/examples/embedded_linux_epd1in54/src/main.rs index b2bd427..aa850b9 100644 --- a/examples/embedded_linux_epd1in54/src/main.rs +++ b/examples/embedded_linux_epd1in54/src/main.rs @@ -55,13 +55,8 @@ impl<'a> InputPin for HackInputPin<'a> { } } - -/* -* -* BE CAREFUL: this wasn't tested yet, and the pins are also not choosen correctly (just some random ones atm) -* -*/ - +//TODO: Test this implemenation +//BE CAREFUL: this wasn't tested yet fn main() { run().unwrap(); diff --git a/examples/embedded_linux_epd4in2/src/main.rs b/examples/embedded_linux_epd4in2/src/main.rs index 871aef0..f3a5426 100644 --- a/examples/embedded_linux_epd4in2/src/main.rs +++ b/examples/embedded_linux_epd4in2/src/main.rs @@ -51,8 +51,6 @@ impl<'a> HackInputPin<'a> { } } -//TODO: make it safer?? or handle the errors better? -// now it defaults to is_low if an error appears impl<'a> InputPin for HackInputPin<'a> { fn is_low(&self) -> bool { self.pin.get_value().unwrap_or(0) == 0 @@ -64,11 +62,7 @@ impl<'a> InputPin for HackInputPin<'a> { } -/* -* -* BE CAREFUL: this wasn't tested yet, and the pins are also not choosen correctly (just some random ones atm) -* -*/ + fn main() { run().map_err(|e| println!("{}", e.to_string())).unwrap(); } From a52237569571731af3bd96043cbfc6c6432bc4a3 Mon Sep 17 00:00:00 2001 From: Chris Date: Fri, 19 Oct 2018 09:58:52 +0200 Subject: [PATCH 49/75] Clean up and removal of a few fixed todos --- src/drawing.rs | 5 ++--- src/epd4in2/mod.rs | 21 +++------------------ src/lib.rs | 1 - src/traits.rs | 4 ++-- 4 files changed, 7 insertions(+), 24 deletions(-) diff --git a/src/drawing.rs b/src/drawing.rs index a2fe671..d4278b1 100644 --- a/src/drawing.rs +++ b/src/drawing.rs @@ -28,7 +28,7 @@ pub trait Display { pub struct DisplayEink42BlackWhite { buffer: [u8; 400 * 300 / 8], - rotation: DisplayRotation, //TODO: check embedded_graphics for orientation + rotation: DisplayRotation, } impl Default for DisplayEink42BlackWhite { @@ -56,7 +56,7 @@ impl Display for DisplayEink42BlackWhite { } } -//TODO: add more tests for the rotation maybe? or test it at least once in real! + impl Drawing for DisplayEink42BlackWhite { fn draw(&mut self, item_pixels: T) where @@ -126,7 +126,6 @@ fn rotation(x: u32, y: u32, width: u32, height: u32, rotation: DisplayRotation) -//TODO: write tests #[cfg(test)] mod tests { use super::*; diff --git a/src/epd4in2/mod.rs b/src/epd4in2/mod.rs index 4d6dd53..2802672 100644 --- a/src/epd4in2/mod.rs +++ b/src/epd4in2/mod.rs @@ -158,23 +158,16 @@ where self.init(spi, delay) } - //TODO: is such a long delay really needed inbetween? fn sleep(&mut self, spi: &mut SPI) -> Result<(), SPI::Error> { self.interface.cmd_with_data(spi, Command::VCOM_AND_DATA_INTERVAL_SETTING, &[0x17])?; //border floating self.command(spi, Command::VCM_DC_SETTING)?; // VCOM to 0V self.command(spi, Command::PANEL_SETTING)?; - //TODO: Removal of delay. TEST! - //self.delay_ms(100); - self.command(spi, Command::POWER_SETTING)?; //VG&VS to 0V fast for _ in 0..4 { self.send_data(spi, &[0x00])?; } - //TODO: Removal of delay. TEST! - //self.delay_ms(100); - self.command(spi, Command::POWER_OFF)?; self.wait_until_idle(); self.interface.cmd_with_data(spi, Command::DEEP_SLEEP, &[0xA5]) @@ -187,19 +180,11 @@ where self.interface.cmd_with_data(spi, Command::VCM_DC_SETTING, &[0x12])?; - //TODO: this was a send_command instead of a send_data. check if it's alright and doing what it should do (setting the default values) - //self.send_command_u8(0x97)?; //VBDF 17|D7 VBDW 97 VBDB 57 VBDF F7 VBDW 77 VBDB 37 VBDR B7 + //VBDF 17|D7 VBDW 97 VBDB 57 VBDF F7 VBDW 77 VBDB 37 VBDR B7 self.interface.cmd_with_data(spi, Command::VCOM_AND_DATA_INTERVAL_SETTING, &[0x97])?; - - self.command(spi, Command::DATA_START_TRANSMISSION_1)?; - self.send_data(spi, &[color_value; WIDTH as usize / 8 * HEIGHT as usize])?; - //for _ in 0..buffer.len() { - // self.send_data(spi, &[color_value])?; - //} - - //TODO: Removal of delay. TEST! - //self.delay_ms(2); + //TODO: compare with using a loop instead of the full buffer + self.interface.cmd_with_data(spi, Command::DATA_START_TRANSMISSION_1, &[color_value; WIDTH as usize / 8 * HEIGHT as usize])?; self.interface.cmd_with_data(spi, Command::DATA_START_TRANSMISSION_2, buffer) } diff --git a/src/lib.rs b/src/lib.rs index 23d6745..f2f24df 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -84,7 +84,6 @@ pub(crate) mod type_a; extern crate embedded_graphics; -//TODO: test spi mode /// SPI mode - /// For more infos see [Requirements: SPI](index.html#spi) pub const SPI_MODE: Mode = Mode { diff --git a/src/traits.rs b/src/traits.rs index 8e95745..b8f55a8 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -17,8 +17,8 @@ pub(crate) trait Command { } -//TODO: add LUT trait with set_fast_lut and set_manual_lut and set_normal_lut or sth like that? -// for partial updates +// Trait for using various Waveforms from different LUTs +// E.g. for partial updates trait LUTSupport { fn set_lut(&mut self) -> Result<(), ERR>; fn set_lut_quick(&mut self) -> Result<(), ERR>; From b7275198e10a4e828c529cb788cbac7c1848bfc1 Mon Sep 17 00:00:00 2001 From: Chris Date: Fri, 19 Oct 2018 10:14:36 +0200 Subject: [PATCH 50/75] remove another dublicate test case --- src/drawing.rs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/drawing.rs b/src/drawing.rs index d4278b1..a77dc29 100644 --- a/src/drawing.rs +++ b/src/drawing.rs @@ -133,12 +133,6 @@ mod tests { use embedded_graphics::coord::Coord; use embedded_graphics::primitives::Line; - #[test] - fn from_u8() { - assert_eq!(Color::Black, Color::from(0u8)); - assert_eq!(Color::White, Color::from(1u8)); - } - #[test] fn rotation_overflow() { use epd4in2::constants::{WIDTH, HEIGHT}; @@ -165,8 +159,6 @@ mod tests { } } - - // test buffer length #[test] fn graphics_4in2_size() { From 8922707bac6135e77711bd10f1e689b240520de1 Mon Sep 17 00:00:00 2001 From: Chris Date: Fri, 19 Oct 2018 10:59:26 +0200 Subject: [PATCH 51/75] Renamed drawing to graphics and extracted display-specific stuff into the display folders --- examples/embedded_linux_epd4in2/src/main.rs | 6 +- src/{drawing.rs => epd4in2/graphics.rs} | 115 +++----------------- src/epd4in2/mod.rs | 5 +- src/graphics.rs | 95 ++++++++++++++++ src/lib.rs | 4 +- src/traits.rs | 2 - 6 files changed, 120 insertions(+), 107 deletions(-) rename src/{drawing.rs => epd4in2/graphics.rs} (59%) create mode 100644 src/graphics.rs diff --git a/examples/embedded_linux_epd4in2/src/main.rs b/examples/embedded_linux_epd4in2/src/main.rs index f3a5426..d064359 100644 --- a/examples/embedded_linux_epd4in2/src/main.rs +++ b/examples/embedded_linux_epd4in2/src/main.rs @@ -6,9 +6,9 @@ extern crate eink_waveshare_rs; use eink_waveshare_rs::{ - EPD4in2, - drawing_old::{Graphics}, - drawing::{DisplayEink42BlackWhite, Display, DisplayRotation}, + EPD4in2, + DisplayEink42BlackWhite, + graphics::{Display, DisplayRotation}, color::Color, WaveshareDisplay, }; diff --git a/src/drawing.rs b/src/epd4in2/graphics.rs similarity index 59% rename from src/drawing.rs rename to src/epd4in2/graphics.rs index a77dc29..7650b85 100644 --- a/src/drawing.rs +++ b/src/epd4in2/graphics.rs @@ -1,39 +1,21 @@ +use graphics::{ + outside_display, + rotation, + DisplayRotation, + Display +}; use color::Color; use embedded_graphics::prelude::*; -/// Displayrotation -#[derive(Clone, Copy)] -pub enum DisplayRotation { - /// No rotation - Rotate0, - /// Rotate by 90 degrees clockwise - Rotate90, - /// Rotate by 180 degrees clockwise - Rotate180, - /// Rotate 270 degrees clockwise - Rotate270, -} -impl Default for DisplayRotation { - fn default() -> Self { - DisplayRotation::Rotate0 - } -} +use epd4in2::constants::{DEFAULT_BACKGROUND_COLOR, WIDTH, HEIGHT}; -pub trait Display { - fn buffer(&self) -> &[u8]; - fn set_rotation(&mut self, rotation: DisplayRotation); - fn rotation(&self) -> DisplayRotation; -} - - -pub struct DisplayEink42BlackWhite { - buffer: [u8; 400 * 300 / 8], +pub struct DisplayEink42BlackWhite { + buffer: [u8; WIDTH as usize * HEIGHT as usize / 8], rotation: DisplayRotation, } impl Default for DisplayEink42BlackWhite { fn default() -> Self { - use epd4in2::constants::{DEFAULT_BACKGROUND_COLOR, WIDTH, HEIGHT}; DisplayEink42BlackWhite { buffer: [ DEFAULT_BACKGROUND_COLOR.get_byte_value(); @@ -62,8 +44,6 @@ impl Drawing for DisplayEink42BlackWhite { where T: Iterator> { - use epd4in2::constants::{WIDTH, HEIGHT}; - let width = WIDTH as u32; let height = HEIGHT as u32; @@ -87,45 +67,6 @@ 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), - ), - } -} - - - #[cfg(test)] mod tests { use super::*; @@ -133,42 +74,16 @@ mod tests { use embedded_graphics::coord::Coord; use embedded_graphics::primitives::Line; - #[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 #[test] - fn graphics_4in2_size() { + fn graphics_size() { let display = DisplayEink42BlackWhite::default(); assert_eq!(display.buffer().len(), 15000); } // test default background color on all bytes #[test] - fn graphics_4in2_default() { + fn graphics_default() { let display = DisplayEink42BlackWhite::default(); use epd4in2; for &byte in display.buffer() { @@ -177,7 +92,7 @@ mod tests { } #[test] - fn graphics_4in2_rotation_0() { + fn graphics_rotation_0() { let mut display = DisplayEink42BlackWhite::default(); display.draw( Line::new(Coord::new(0, 0), Coord::new(7, 0)) @@ -195,7 +110,7 @@ mod tests { } #[test] - fn graphics_4in2_rotation_90() { + fn graphics_rotation_90() { let mut display = DisplayEink42BlackWhite::default(); display.set_rotation(DisplayRotation::Rotate90); display.draw( @@ -214,7 +129,7 @@ mod tests { } #[test] - fn graphics_4in2_rotation_180() { + fn graphics_rotation_180() { let mut display = DisplayEink42BlackWhite::default(); display.set_rotation(DisplayRotation::Rotate180); display.draw( @@ -237,7 +152,7 @@ mod tests { } #[test] - fn graphics_4in2_rotation_270() { + fn graphics_rotation_270() { let mut display = DisplayEink42BlackWhite::default(); display.set_rotation(DisplayRotation::Rotate270); display.draw( diff --git a/src/epd4in2/mod.rs b/src/epd4in2/mod.rs index 2802672..8e9306c 100644 --- a/src/epd4in2/mod.rs +++ b/src/epd4in2/mod.rs @@ -60,9 +60,12 @@ use self::constants::*; use color::Color; -pub mod command; +pub(crate) mod command; use self::command::Command; +pub mod graphics; + + /// EPD4in2 driver /// pub struct EPD4in2 { diff --git a/src/graphics.rs b/src/graphics.rs new file mode 100644 index 0000000..eff4641 --- /dev/null +++ b/src/graphics.rs @@ -0,0 +1,95 @@ +/// Displayrotation +#[derive(Clone, Copy)] +pub enum DisplayRotation { + /// No rotation + Rotate0, + /// Rotate by 90 degrees clockwise + Rotate90, + /// Rotate by 180 degrees clockwise + Rotate180, + /// Rotate 270 degrees clockwise + Rotate270, +} + +impl Default for DisplayRotation { + fn default() -> Self { + DisplayRotation::Rotate0 + } +} + +pub trait Display { + fn buffer(&self) -> &[u8]; + fn set_rotation(&mut self, rotation: DisplayRotation); + fn rotation(&self) -> DisplayRotation; +} + + +pub(crate) 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 +} + +pub(crate) 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), + ), + } +} + + + +#[cfg(test)] +mod tests { + use super::{DisplayRotation, outside_display, rotation}; + + #[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); + } + } + } + } +} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index f2f24df..310749f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -48,7 +48,7 @@ extern crate embedded_hal as hal; use hal::spi::{Mode, Phase, Polarity}; #[cfg(feature = "graphics")] -pub mod drawing; +pub mod graphics; //TODO: remove old drawing support #[cfg(feature = "graphics")] @@ -66,6 +66,8 @@ mod interface; mod epd4in2; #[cfg(feature = "epd4in2")] pub use epd4in2::EPD4in2; +#[cfg(feature = "epd4in2")] +pub use epd4in2::graphics::DisplayEink42BlackWhite; #[cfg(feature = "epd1in54")] mod epd1in54; diff --git a/src/traits.rs b/src/traits.rs index b8f55a8..a8537a4 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -56,8 +56,6 @@ where DC: OutputPin, RST: OutputPin, { - - /// Creates a new driver from a SPI peripheral, CS Pin, Busy InputPin, DC /// /// This already initialises the device. That means [init()](WaveshareInterface::init()) isn't needed directly afterwards From 9289d689b7b8af2578881cbaf44d1ccc58d44da6 Mon Sep 17 00:00:00 2001 From: Chris Date: Fri, 19 Oct 2018 11:27:16 +0200 Subject: [PATCH 52/75] Fix epd1in54 example, test if old bugs are fixed --- examples/embedded_linux_epd1in54/Cargo.toml | 4 +- examples/embedded_linux_epd1in54/src/main.rs | 77 +++++--- src/epd1in54/graphics.rs | 175 +++++++++++++++++++ src/epd1in54/mod.rs | 2 + src/lib.rs | 3 + 5 files changed, 235 insertions(+), 26 deletions(-) create mode 100644 src/epd1in54/graphics.rs diff --git a/examples/embedded_linux_epd1in54/Cargo.toml b/examples/embedded_linux_epd1in54/Cargo.toml index 052c45b..d51c42e 100644 --- a/examples/embedded_linux_epd1in54/Cargo.toml +++ b/examples/embedded_linux_epd1in54/Cargo.toml @@ -7,8 +7,10 @@ authors = ["Christoph Groß "] #eink_waveshare_rs = { git = "https://github.com/Caemor/eink-waveshare-rs"} #eink_waveshare_rs = { path = "../../"} -eink_waveshare_rs = { path = "../../", default-features = false, features = ["epd1in54"]} +eink_waveshare_rs = { path = "../../", default-features = false, features = ["epd1in54", "graphics"]} linux-embedded-hal = "0.2.0" +embedded-graphics = "0.4.3" + embedded-hal = { version = "0.2.1", features = ["unproven"] } diff --git a/examples/embedded_linux_epd1in54/src/main.rs b/examples/embedded_linux_epd1in54/src/main.rs index aa850b9..86b19e2 100644 --- a/examples/embedded_linux_epd1in54/src/main.rs +++ b/examples/embedded_linux_epd1in54/src/main.rs @@ -7,7 +7,8 @@ extern crate eink_waveshare_rs; use eink_waveshare_rs::{ EPD1in54, - //drawing_old::{Graphics}, + DisplayEink1in54BlackWhite, + graphics::{Display, DisplayRotation}, color::Color, WaveshareDisplay, }; @@ -17,6 +18,16 @@ use lin_hal::{Pin, Spidev}; use lin_hal::sysfs_gpio::Direction; use lin_hal::Delay; +extern crate embedded_graphics; +use embedded_graphics::coord::Coord; +use embedded_graphics::fonts::{Font6x8}; +use embedded_graphics::prelude::*; +//use embedded_graphics::primitives::{Circle, Line}; +use embedded_graphics::Drawing; + +extern crate embedded_hal; +use embedded_hal::prelude::*; + // activate spi, gpio in raspi-config // needs to be run with sudo because of some sysfs_gpio permission problems and follow-up timing problems // see https://github.com/rust-embedded/rust-sysfs-gpio/issues/5 and follow-up issues @@ -25,7 +36,6 @@ use lin_hal::Delay; // DigitalIn Hack as long as it's not in the linux_embedded_hal // from https://github.com/rudihorn/max31865/blob/extra_examples/examples/rpi.rs // (slightly changed now as OutputPin doesn't provide is_high and is_low anymore) -extern crate embedded_hal; use embedded_hal::digital::{InputPin}; //TODO: Remove when linux_embedded_hal implements InputPin @@ -114,31 +124,48 @@ fn run() -> Result<(), std::io::Error> { epd.clear_frame(&mut spi).expect("clear frame 1"); epd.display_frame(&mut spi).expect("disp 1"); - // Speeddemo - let small_buffer = [Color::Black.get_byte_value(); 32];//16x16 - let number_of_runs = 1; - for i in 0..number_of_runs { - let offset = i * 8 % 150; - epd.update_partial_frame(&mut spi, &small_buffer, 25 + offset, 25 + offset, 16, 16).expect("partial frame"); - epd.display_frame(&mut spi).expect("disp 2"); - } - - // Clear the full screen - epd.clear_frame(&mut spi).expect("clear frame 2"); - epd.display_frame(&mut spi).expect("disp 3"); - - // Draw some squares - let small_buffer = [Color::Black.get_byte_value(); 3200]; //160x160 - epd.update_partial_frame(&mut spi, &small_buffer, 20, 20, 160, 160)?; - - let small_buffer = [Color::White.get_byte_value(); 800]; //80x80 - epd.update_partial_frame(&mut spi, &small_buffer, 60, 60, 80, 80)?; - - let small_buffer = [Color::Black.get_byte_value(); 8]; //8x8 - epd.update_partial_frame(&mut spi, &small_buffer, 96, 96, 8, 8).expect("partial frame 2"); + println!("Test all the rotations"); + let mut display = DisplayEink1in54BlackWhite::default(); + display.set_rotation(DisplayRotation::Rotate0); + display.draw( + Font6x8::render_str("Rotate 0!") + .with_stroke(Some(Color::Black)) + .with_fill(Some(Color::White)) + .translate(Coord::new(5, 50)) + .into_iter(), + ); + + display.set_rotation(DisplayRotation::Rotate90); + display.draw( + Font6x8::render_str("Rotate 90!") + .with_stroke(Some(Color::Black)) + .with_fill(Some(Color::White)) + .translate(Coord::new(5, 50)) + .into_iter(), + ); + + display.set_rotation(DisplayRotation::Rotate180); + display.draw( + Font6x8::render_str("Rotate 180!") + .with_stroke(Some(Color::Black)) + .with_fill(Some(Color::White)) + .translate(Coord::new(5, 50)) + .into_iter(), + ); + + display.set_rotation(DisplayRotation::Rotate270); + display.draw( + Font6x8::render_str("Rotate 270!") + .with_stroke(Some(Color::Black)) + .with_fill(Some(Color::White)) + .translate(Coord::new(5, 50)) + .into_iter(), + ); // Display updated frame - epd.display_frame(&mut spi).expect("disp 4"); + epd.update_frame(&mut spi, &display.buffer()).unwrap(); + epd.display_frame(&mut spi).expect("display frame new graphics"); + delay.delay_ms(5000u16); // Set the EPD to sleep epd.sleep(&mut spi).expect("sleep"); diff --git a/src/epd1in54/graphics.rs b/src/epd1in54/graphics.rs new file mode 100644 index 0000000..79f5622 --- /dev/null +++ b/src/epd1in54/graphics.rs @@ -0,0 +1,175 @@ +use graphics::{ + outside_display, + rotation, + DisplayRotation, + Display +}; +use color::Color; +use embedded_graphics::prelude::*; + +use epd1in54::{DEFAULT_BACKGROUND_COLOR, WIDTH, HEIGHT}; + +pub struct DisplayEink1in54BlackWhite { + buffer: [u8; WIDTH as usize * HEIGHT as usize / 8], + rotation: DisplayRotation, +} + +impl Default for DisplayEink1in54BlackWhite { + fn default() -> Self { + DisplayEink1in54BlackWhite { + buffer: [ + DEFAULT_BACKGROUND_COLOR.get_byte_value(); + WIDTH as usize * HEIGHT as usize / 8 + ], + rotation: DisplayRotation::default() + } + } +} + +impl Display for DisplayEink1in54BlackWhite { + fn buffer(&self) -> &[u8] { + &self.buffer + } + fn set_rotation(&mut self, rotation: DisplayRotation) { + self.rotation = rotation; + } + fn rotation(&self) -> DisplayRotation { + self.rotation + } +} + + +impl Drawing for DisplayEink1in54BlackWhite { + fn draw(&mut self, item_pixels: T) + where + T: Iterator> + { + let width = WIDTH as u32; + let height = HEIGHT as u32; + + for Pixel(UnsignedCoord(x,y), color) in item_pixels { + if outside_display(x, y, width, height, self.rotation) { + return; + } + + let (idx, bit) = rotation(x, y, width, height, self.rotation); + + let idx = idx as usize; + match color { + Color::Black => { + self.buffer[idx] &= !bit; + } + Color::White => { + self.buffer[idx] |= bit; + } + } + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use epd1in54::{DEFAULT_BACKGROUND_COLOR}; + use embedded_graphics::coord::Coord; + use embedded_graphics::primitives::Line; + + // test buffer length + #[test] + fn graphics_size() { + let display = DisplayEink1in54BlackWhite::default(); + assert_eq!(display.buffer().len(), 5000); + } + + // test default background color on all bytes + #[test] + fn graphics_default() { + let display = DisplayEink1in54BlackWhite::default(); + for &byte in display.buffer() { + assert_eq!(byte, DEFAULT_BACKGROUND_COLOR.get_byte_value()); + } + } + + #[test] + fn graphics_rotation_0() { + let mut display = DisplayEink1in54BlackWhite::default(); + display.draw( + Line::new(Coord::new(0, 0), Coord::new(7, 0)) + .with_stroke(Some(Color::Black)) + .into_iter(), + ); + + let buffer = display.buffer(); + + assert_eq!(buffer[0], Color::Black.get_byte_value()); + + for &byte in buffer.iter().skip(1) { + assert_eq!(byte, DEFAULT_BACKGROUND_COLOR.get_byte_value()); + } + } + + #[test] + fn graphics_rotation_90() { + let mut display = DisplayEink1in54BlackWhite::default(); + display.set_rotation(DisplayRotation::Rotate90); + display.draw( + Line::new(Coord::new(0, 192), Coord::new(0, 199)) + .with_stroke(Some(Color::Black)) + .into_iter(), + ); + + let buffer = display.buffer(); + + assert_eq!(buffer[0], Color::Black.get_byte_value()); + + for &byte in buffer.iter().skip(1) { + assert_eq!(byte, DEFAULT_BACKGROUND_COLOR.get_byte_value()); + } + } + + #[test] + fn graphics_rotation_180() { + let mut display = DisplayEink1in54BlackWhite::default(); + display.set_rotation(DisplayRotation::Rotate180); + display.draw( + Line::new(Coord::new(192, 199), Coord::new(199, 199)) + .with_stroke(Some(Color::Black)) + .into_iter(), + ); + + let buffer = display.buffer(); + + extern crate std; + std::println!("{:?}", buffer); + + assert_eq!(buffer[0], Color::Black.get_byte_value()); + + for &byte in buffer.iter().skip(1) { + assert_eq!(byte, DEFAULT_BACKGROUND_COLOR.get_byte_value()); + } + + } + + #[test] + fn graphics_rotation_270() { + let mut display = DisplayEink1in54BlackWhite::default(); + display.set_rotation(DisplayRotation::Rotate270); + display.draw( + Line::new(Coord::new(199, 0), Coord::new(199, 7)) + .with_stroke(Some(Color::Black)) + .into_iter(), + ); + + let buffer = display.buffer(); + + extern crate std; + std::println!("{:?}", buffer); + + assert_eq!(buffer[0], Color::Black.get_byte_value()); + + for &byte in buffer.iter().skip(1) { + assert_eq!(byte, DEFAULT_BACKGROUND_COLOR.get_byte_value()); + } + + } +} \ No newline at end of file diff --git a/src/epd1in54/mod.rs b/src/epd1in54/mod.rs index a4c625f..2d9d6ec 100644 --- a/src/epd1in54/mod.rs +++ b/src/epd1in54/mod.rs @@ -40,6 +40,8 @@ use traits::{WaveshareDisplay}; use interface::DisplayInterface; +pub mod graphics; + /// EPD1in54 driver /// pub struct EPD1in54 { diff --git a/src/lib.rs b/src/lib.rs index 310749f..d23d6b5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -73,6 +73,9 @@ pub use epd4in2::graphics::DisplayEink42BlackWhite; mod epd1in54; #[cfg(feature = "epd1in54")] pub use epd1in54::EPD1in54; +#[cfg(feature = "epd1in54")] +pub use epd1in54::graphics::DisplayEink1in54BlackWhite; + #[cfg(feature = "epd2in9")] mod epd2in9; From 139096297ba5dbb727fa2cf574553fac71075ef6 Mon Sep 17 00:00:00 2001 From: Chris Date: Fri, 19 Oct 2018 14:36:43 +0200 Subject: [PATCH 53/75] Generalise graphics once more Change u16 positions to u32 to adapt to embedded graphics unsigned coordinates Furthermore added epd4in2 defaults graphics buffer --- src/drawing_old/mod.rs | 2 +- src/epd1in54/mod.rs | 26 +++++++------- src/epd2in9/mod.rs | 26 +++++++------- src/epd4in2/constants.rs | 4 +-- src/epd4in2/graphics.rs | 75 ++++++++++++---------------------------- src/epd4in2/mod.rs | 4 +-- src/graphics.rs | 63 +++++++++++++++++++++++++++++++++ src/interface.rs | 2 +- src/lib.rs | 2 +- src/traits.rs | 12 +++---- 10 files changed, 124 insertions(+), 92 deletions(-) diff --git a/src/drawing_old/mod.rs b/src/drawing_old/mod.rs index 979f8e7..a9149b3 100644 --- a/src/drawing_old/mod.rs +++ b/src/drawing_old/mod.rs @@ -44,7 +44,7 @@ impl Display { } } -#[allow(dead_code)] + pub struct Graphics<'a> { width: u16, height: u16, diff --git a/src/epd1in54/mod.rs b/src/epd1in54/mod.rs index 2d9d6ec..5a61fbb 100644 --- a/src/epd1in54/mod.rs +++ b/src/epd1in54/mod.rs @@ -19,8 +19,8 @@ //! epd4in2.sleep(); //! ``` -const WIDTH: u16 = 200; -const HEIGHT: u16 = 200; +const WIDTH: u32 = 200; +const HEIGHT: u32 = 200; //const DPI: u16 = 184; const DEFAULT_BACKGROUND_COLOR: Color = Color::White; @@ -109,11 +109,11 @@ where DC: OutputPin, RST: OutputPin, { - fn width(&self) -> u16 { + fn width(&self) -> u32 { WIDTH } - fn height(&self) -> u16 { + fn height(&self) -> u32 { HEIGHT } @@ -157,10 +157,10 @@ where &mut self, spi: &mut SPI, buffer: &[u8], - x: u16, - y: u16, - width: u16, - height: u16, + x: u32, + y: u32, + width: u32, + height: u32, ) -> Result<(), SPI::Error> { self.set_ram_area(spi, x, y, x + width, y + height)?; self.set_ram_counter(spi, x, y)?; @@ -227,10 +227,10 @@ where pub(crate) fn set_ram_area( &mut self, spi: &mut SPI, - start_x: u16, - start_y: u16, - end_x: u16, - end_y: u16, + start_x: u32, + start_y: u32, + end_x: u32, + end_y: u32, ) -> Result<(), SPI::Error> { assert!(start_x < end_x); assert!(start_y < end_y); @@ -251,7 +251,7 @@ where ) } - pub(crate) fn set_ram_counter(&mut self, spi: &mut SPI, x: u16, y: u16) -> Result<(), SPI::Error> { + pub(crate) fn set_ram_counter(&mut self, spi: &mut SPI, x: u32, y: u32) -> Result<(), SPI::Error> { // x is positioned in bytes, so the last 3 bits which show the position inside a byte in the ram // aren't relevant self.interface.cmd_with_data(spi, Command::SET_RAM_X_ADDRESS_COUNTER, &[(x >> 3) as u8])?; diff --git a/src/epd2in9/mod.rs b/src/epd2in9/mod.rs index 4fd3b2a..7e877db 100644 --- a/src/epd2in9/mod.rs +++ b/src/epd2in9/mod.rs @@ -19,8 +19,8 @@ //! epd4in2.sleep(); //! ``` -const WIDTH: u16 = 128; -const HEIGHT: u16 = 296; +const WIDTH: u32 = 128; +const HEIGHT: u32 = 296; const DEFAULT_BACKGROUND_COLOR: Color = Color::White; use hal::{ @@ -102,11 +102,11 @@ where DC: OutputPin, RST: OutputPin, { - fn width(&self) -> u16 { + fn width(&self) -> u32 { WIDTH } - fn height(&self) -> u16 { + fn height(&self) -> u32 { HEIGHT } @@ -151,10 +151,10 @@ where &mut self, spi: &mut SPI, buffer: &[u8], - x: u16, - y: u16, - width: u16, - height: u16, + x: u32, + y: u32, + width: u32, + height: u32, ) -> Result<(), SPI::Error> { self.set_ram_area(spi, x, y, x + width, y + height)?; self.set_ram_counter(spi, x, y)?; @@ -220,10 +220,10 @@ where pub(crate) fn set_ram_area( &mut self, spi: &mut SPI, - start_x: u16, - start_y: u16, - end_x: u16, - end_y: u16, + start_x: u32, + start_y: u32, + end_x: u32, + end_y: u32, ) -> Result<(), SPI::Error> { assert!(start_x < end_x); assert!(start_y < end_y); @@ -242,7 +242,7 @@ where ) } - pub(crate) fn set_ram_counter(&mut self, spi: &mut SPI, x: u16, y: u16) -> Result<(), SPI::Error> { + pub(crate) fn set_ram_counter(&mut self, spi: &mut SPI, x: u32, y: u32) -> Result<(), SPI::Error> { // x is positioned in bytes, so the last 3 bits which show the position inside a byte in the ram // aren't relevant self.interface.cmd_with_data(spi, Command::SET_RAM_X_ADDRESS_COUNTER, &[(x >> 3) as u8])?; diff --git a/src/epd4in2/constants.rs b/src/epd4in2/constants.rs index 2e484a4..47bf5f7 100644 --- a/src/epd4in2/constants.rs +++ b/src/epd4in2/constants.rs @@ -1,7 +1,7 @@ use color::Color; -pub(crate) const WIDTH: u16 = 400; -pub(crate) const HEIGHT: u16 = 300; +pub(crate) const WIDTH: u32 = 400; +pub(crate) const HEIGHT: u32 = 300; pub(crate) const DEFAULT_BACKGROUND_COLOR: Color = Color::White; pub(crate) const LUT_VCOM0: [u8; 44] = [ diff --git a/src/epd4in2/graphics.rs b/src/epd4in2/graphics.rs index 7650b85..9980867 100644 --- a/src/epd4in2/graphics.rs +++ b/src/epd4in2/graphics.rs @@ -7,84 +7,48 @@ use graphics::{ use color::Color; use embedded_graphics::prelude::*; +use graphics::Graphics; + use epd4in2::constants::{DEFAULT_BACKGROUND_COLOR, WIDTH, HEIGHT}; -pub struct DisplayEink42BlackWhite { - buffer: [u8; WIDTH as usize * HEIGHT as usize / 8], - rotation: DisplayRotation, +pub struct DisplayEink4in2BlackWhite { + pub buffer: [u8; WIDTH as usize * HEIGHT as usize / 8], } -impl Default for DisplayEink42BlackWhite { +impl Default for DisplayEink4in2BlackWhite { fn default() -> Self { - DisplayEink42BlackWhite { + DisplayEink4in2BlackWhite { buffer: [ DEFAULT_BACKGROUND_COLOR.get_byte_value(); WIDTH as usize * HEIGHT as usize / 8 - ], - rotation: DisplayRotation::default() + ] } } } -impl Display for DisplayEink42BlackWhite { - fn buffer(&self) -> &[u8] { - &self.buffer - } - fn set_rotation(&mut self, rotation: DisplayRotation) { - self.rotation = rotation; - } - fn rotation(&self) -> DisplayRotation { - self.rotation - } -} -impl Drawing for DisplayEink42BlackWhite { - fn draw(&mut self, item_pixels: T) - where - T: Iterator> - { - let width = WIDTH as u32; - let height = HEIGHT as u32; - - for Pixel(UnsignedCoord(x,y), color) in item_pixels { - if outside_display(x, y, width, height, self.rotation) { - return; - } - - let (idx, bit) = rotation(x, y, width, height, self.rotation); - - let idx = idx as usize; - match color { - Color::Black => { - self.buffer[idx] &= !bit; - } - Color::White => { - self.buffer[idx] |= bit; - } - } - } - } -} - #[cfg(test)] mod tests { use super::*; use epd4in2; + use graphics::Graphics; use embedded_graphics::coord::Coord; use embedded_graphics::primitives::Line; // test buffer length #[test] fn graphics_size() { - let display = DisplayEink42BlackWhite::default(); + let mut display4in2 = DisplayEink4in2BlackWhite::default(); + let display = Graphics::new(WIDTH, HEIGHT, &mut display4in2.buffer); assert_eq!(display.buffer().len(), 15000); } // test default background color on all bytes #[test] fn graphics_default() { - let display = DisplayEink42BlackWhite::default(); + let mut display4in2 = DisplayEink4in2BlackWhite::default(); + let mut display = Graphics::new(WIDTH, HEIGHT, &mut display4in2.buffer); use epd4in2; for &byte in display.buffer() { assert_eq!(byte, epd4in2::constants::DEFAULT_BACKGROUND_COLOR.get_byte_value()); @@ -93,7 +57,8 @@ mod tests { #[test] fn graphics_rotation_0() { - let mut display = DisplayEink42BlackWhite::default(); + let mut display4in2 = DisplayEink4in2BlackWhite::default(); + let mut display = Graphics::new(WIDTH, HEIGHT, &mut display4in2.buffer); display.draw( Line::new(Coord::new(0, 0), Coord::new(7, 0)) .with_stroke(Some(Color::Black)) @@ -111,7 +76,8 @@ mod tests { #[test] fn graphics_rotation_90() { - let mut display = DisplayEink42BlackWhite::default(); + let mut display4in2 = DisplayEink4in2BlackWhite::default(); + let mut display = Graphics::new(WIDTH, HEIGHT, &mut display4in2.buffer); display.set_rotation(DisplayRotation::Rotate90); display.draw( Line::new(Coord::new(0, 392), Coord::new(0, 399)) @@ -130,7 +96,8 @@ mod tests { #[test] fn graphics_rotation_180() { - let mut display = DisplayEink42BlackWhite::default(); + let mut display4in2 = DisplayEink4in2BlackWhite::default(); + let mut display = Graphics::new(WIDTH, HEIGHT, &mut display4in2.buffer); display.set_rotation(DisplayRotation::Rotate180); display.draw( Line::new(Coord::new(392, 299), Coord::new(399, 299)) @@ -153,7 +120,8 @@ mod tests { #[test] fn graphics_rotation_270() { - let mut display = DisplayEink42BlackWhite::default(); + let mut display4in2 = DisplayEink4in2BlackWhite::default(); + let mut display = Graphics::new(WIDTH, HEIGHT, &mut display4in2.buffer); display.set_rotation(DisplayRotation::Rotate270); display.draw( Line::new(Coord::new(299, 0), Coord::new(299, 7)) @@ -173,4 +141,5 @@ mod tests { } } -} \ No newline at end of file +} + diff --git a/src/epd4in2/mod.rs b/src/epd4in2/mod.rs index 8e9306c..fbddc57 100644 --- a/src/epd4in2/mod.rs +++ b/src/epd4in2/mod.rs @@ -278,11 +278,11 @@ where &self.color } - fn width(&self) -> u16 { + fn width(&self) -> u32 { WIDTH } - fn height(&self) -> u16 { + fn height(&self) -> u32 { HEIGHT } } diff --git a/src/graphics.rs b/src/graphics.rs index eff4641..a477985 100644 --- a/src/graphics.rs +++ b/src/graphics.rs @@ -1,3 +1,6 @@ +use color::Color; +use embedded_graphics::prelude::*; + /// Displayrotation #[derive(Clone, Copy)] pub enum DisplayRotation { @@ -16,6 +19,7 @@ impl Default for DisplayRotation { DisplayRotation::Rotate0 } } +use epd4in2::constants::{DEFAULT_BACKGROUND_COLOR, WIDTH, HEIGHT}; pub trait Display { fn buffer(&self) -> &[u8]; @@ -23,6 +27,65 @@ pub trait Display { fn rotation(&self) -> DisplayRotation; } +pub struct Graphics<'a> { + pub(crate) width: u32, + pub(crate) height: u32, + pub(crate) rotation: DisplayRotation, + pub(crate) buffer: &'a mut [u8], //buffer: Box//[u8; 15000] +} + +impl<'a> Graphics<'a> { + pub fn new(width: u32, height: u32, buffer: &'a mut [u8]) -> Graphics<'a> { + let len = buffer.len() as u32; + assert!(width / 8 * height >= len); + Graphics { + width, + height, + rotation: DisplayRotation::default(), + buffer, + } + } + + pub fn buffer(&self) -> &[u8] { + &self.buffer + } + pub fn set_rotation(&mut self, rotation: DisplayRotation) { + self.rotation = rotation; + } + pub fn rotation(&self) -> DisplayRotation { + self.rotation + } +} + + +impl<'a> Drawing for Graphics<'a> { + fn draw(&mut self, item_pixels: T) + where + T: Iterator> + { + let width = WIDTH as u32; + let height = HEIGHT as u32; + + for Pixel(UnsignedCoord(x,y), color) in item_pixels { + if outside_display(x, y, width, height, self.rotation) { + return; + } + + let (idx, bit) = rotation(x, y, width, height, self.rotation); + + let idx = idx as usize; + match color { + Color::Black => { + self.buffer[idx] &= !bit; + } + Color::White => { + self.buffer[idx] |= bit; + } + } + } + } +} + pub(crate) fn outside_display(x: u32, y: u32, width: u32, height: u32, rotation: DisplayRotation) -> bool { match rotation { diff --git a/src/interface.rs b/src/interface.rs index 4e07baf..dd8a5da 100644 --- a/src/interface.rs +++ b/src/interface.rs @@ -84,7 +84,7 @@ where &mut self, spi: &mut SPI, val: u8, - repetitions: u16, + repetitions: u32, ) -> Result<(), SPI::Error> { // high for data self.dc.set_high(); diff --git a/src/lib.rs b/src/lib.rs index d23d6b5..359b05d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -67,7 +67,7 @@ mod epd4in2; #[cfg(feature = "epd4in2")] pub use epd4in2::EPD4in2; #[cfg(feature = "epd4in2")] -pub use epd4in2::graphics::DisplayEink42BlackWhite; +pub use epd4in2::graphics::DisplayEink4in2BlackWhite; #[cfg(feature = "epd1in54")] mod epd1in54; diff --git a/src/traits.rs b/src/traits.rs index a8537a4..be64cb6 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -83,10 +83,10 @@ where fn background_color(&self) -> &Color; /// Get the width of the display - fn width(&self) -> u16; + fn width(&self) -> u32; /// Get the height of the display - fn height(&self) -> u16; + fn height(&self) -> u32; /// Transmit a full frame to the SRAM of the EPD fn update_frame(&mut self, spi: &mut SPI, buffer: &[u8]) -> Result<(), SPI::Error>; @@ -98,10 +98,10 @@ where &mut self, spi: &mut SPI, buffer: &[u8], - x: u16, - y: u16, - width: u16, - height: u16, + x: u32, + y: u32, + width: u32, + height: u32, ) -> Result<(), SPI::Error>; /// Displays the frame data from SRAM From 1baf35c1a4fc7c56202c0635081e79f3a6459b63 Mon Sep 17 00:00:00 2001 From: Chris Date: Fri, 19 Oct 2018 14:37:41 +0200 Subject: [PATCH 54/75] Forgotten files in previous commit --- src/epd4in2/mod.rs | 10 +++++----- src/graphics.rs | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/epd4in2/mod.rs b/src/epd4in2/mod.rs index fbddc57..d8dbdf3 100644 --- a/src/epd4in2/mod.rs +++ b/src/epd4in2/mod.rs @@ -196,12 +196,12 @@ where &mut self, spi: &mut SPI, buffer: &[u8], - x: u16, - y: u16, - width: u16, - height: u16, + x: u32, + y: u32, + width: u32, + height: u32, ) -> Result<(), SPI::Error> { - if buffer.len() as u16 != width / 8 * height { + if buffer.len() as u32 != width / 8 * height { //TODO: panic!! or sth like that //return Err("Wrong buffersize"); } diff --git a/src/graphics.rs b/src/graphics.rs index a477985..10fc30d 100644 --- a/src/graphics.rs +++ b/src/graphics.rs @@ -28,10 +28,10 @@ pub trait Display { } pub struct Graphics<'a> { - pub(crate) width: u32, - pub(crate) height: u32, - pub(crate) rotation: DisplayRotation, - pub(crate) buffer: &'a mut [u8], //buffer: Box//[u8; 15000] + width: u32, + height: u32, + rotation: DisplayRotation, + buffer: &'a mut [u8], //buffer: Box//[u8; 15000] } impl<'a> Graphics<'a> { From f6a894c5a38c2c3498832135c8596e7c37bb52c9 Mon Sep 17 00:00:00 2001 From: Chris Date: Fri, 19 Oct 2018 15:55:18 +0200 Subject: [PATCH 55/75] use generalised graphics with new specialised buffers --- src/epd1in54/graphics.rs | 83 ++++++++++------------------------------ src/epd4in2/graphics.rs | 17 ++------ src/graphics.rs | 9 ++--- src/lib.rs | 4 +- 4 files changed, 29 insertions(+), 84 deletions(-) diff --git a/src/epd1in54/graphics.rs b/src/epd1in54/graphics.rs index 79f5622..8c7c773 100644 --- a/src/epd1in54/graphics.rs +++ b/src/epd1in54/graphics.rs @@ -1,17 +1,7 @@ -use graphics::{ - outside_display, - rotation, - DisplayRotation, - Display -}; -use color::Color; -use embedded_graphics::prelude::*; - -use epd1in54::{DEFAULT_BACKGROUND_COLOR, WIDTH, HEIGHT}; - -pub struct DisplayEink1in54BlackWhite { - buffer: [u8; WIDTH as usize * HEIGHT as usize / 8], - rotation: DisplayRotation, +use epd4in2::constants::{DEFAULT_BACKGROUND_COLOR, WIDTH, HEIGHT}; + +pub struct DisplayEink1in54BlackWhite { + pub buffer: [u8; WIDTH as usize * HEIGHT as usize / 8], } impl Default for DisplayEink1in54BlackWhite { @@ -20,71 +10,34 @@ impl Default for DisplayEink1in54BlackWhite { buffer: [ DEFAULT_BACKGROUND_COLOR.get_byte_value(); WIDTH as usize * HEIGHT as usize / 8 - ], - rotation: DisplayRotation::default() + ] } } } -impl Display for DisplayEink1in54BlackWhite { - fn buffer(&self) -> &[u8] { - &self.buffer - } - fn set_rotation(&mut self, rotation: DisplayRotation) { - self.rotation = rotation; - } - fn rotation(&self) -> DisplayRotation { - self.rotation - } -} - - -impl Drawing for DisplayEink1in54BlackWhite { - fn draw(&mut self, item_pixels: T) - where - T: Iterator> - { - let width = WIDTH as u32; - let height = HEIGHT as u32; - - for Pixel(UnsignedCoord(x,y), color) in item_pixels { - if outside_display(x, y, width, height, self.rotation) { - return; - } - - let (idx, bit) = rotation(x, y, width, height, self.rotation); - - let idx = idx as usize; - match color { - Color::Black => { - self.buffer[idx] &= !bit; - } - Color::White => { - self.buffer[idx] |= bit; - } - } - } - } -} #[cfg(test)] mod tests { use super::*; - use epd1in54::{DEFAULT_BACKGROUND_COLOR}; + use graphics::{DisplayRotation, Graphics}; use embedded_graphics::coord::Coord; use embedded_graphics::primitives::Line; + use color::Color; + use embedded_graphics::prelude::*; // test buffer length #[test] fn graphics_size() { - let display = DisplayEink1in54BlackWhite::default(); + let mut display1in54 = DisplayEink1in54BlackWhite::default(); + let display = Graphics::new(WIDTH, HEIGHT, &mut display1in54.buffer); assert_eq!(display.buffer().len(), 5000); } // test default background color on all bytes #[test] fn graphics_default() { - let display = DisplayEink1in54BlackWhite::default(); + let mut display1in54 = DisplayEink1in54BlackWhite::default(); + let display = Graphics::new(WIDTH, HEIGHT, &mut display1in54.buffer); for &byte in display.buffer() { assert_eq!(byte, DEFAULT_BACKGROUND_COLOR.get_byte_value()); } @@ -92,7 +45,8 @@ mod tests { #[test] fn graphics_rotation_0() { - let mut display = DisplayEink1in54BlackWhite::default(); + let mut display1in54 = DisplayEink1in54BlackWhite::default(); + let mut display = Graphics::new(WIDTH, HEIGHT, &mut display1in54.buffer); display.draw( Line::new(Coord::new(0, 0), Coord::new(7, 0)) .with_stroke(Some(Color::Black)) @@ -110,7 +64,8 @@ mod tests { #[test] fn graphics_rotation_90() { - let mut display = DisplayEink1in54BlackWhite::default(); + let mut display1in54 = DisplayEink1in54BlackWhite::default(); + let mut display = Graphics::new(WIDTH, HEIGHT, &mut display1in54.buffer); display.set_rotation(DisplayRotation::Rotate90); display.draw( Line::new(Coord::new(0, 192), Coord::new(0, 199)) @@ -129,7 +84,8 @@ mod tests { #[test] fn graphics_rotation_180() { - let mut display = DisplayEink1in54BlackWhite::default(); + let mut display1in54 = DisplayEink1in54BlackWhite::default(); + let mut display = Graphics::new(WIDTH, HEIGHT, &mut display1in54.buffer); display.set_rotation(DisplayRotation::Rotate180); display.draw( Line::new(Coord::new(192, 199), Coord::new(199, 199)) @@ -152,7 +108,8 @@ mod tests { #[test] fn graphics_rotation_270() { - let mut display = DisplayEink1in54BlackWhite::default(); + let mut display1in54 = DisplayEink1in54BlackWhite::default(); + let mut display = Graphics::new(WIDTH, HEIGHT, &mut display1in54.buffer); display.set_rotation(DisplayRotation::Rotate270); display.draw( Line::new(Coord::new(199, 0), Coord::new(199, 7)) diff --git a/src/epd4in2/graphics.rs b/src/epd4in2/graphics.rs index 9980867..af7d3c0 100644 --- a/src/epd4in2/graphics.rs +++ b/src/epd4in2/graphics.rs @@ -1,14 +1,3 @@ -use graphics::{ - outside_display, - rotation, - DisplayRotation, - Display -}; -use color::Color; -use embedded_graphics::prelude::*; - -use graphics::Graphics; - use epd4in2::constants::{DEFAULT_BACKGROUND_COLOR, WIDTH, HEIGHT}; pub struct DisplayEink4in2BlackWhite { @@ -32,9 +21,11 @@ impl Default for DisplayEink4in2BlackWhite { mod tests { use super::*; use epd4in2; - use graphics::Graphics; + use graphics::{DisplayRotation, Graphics}; use embedded_graphics::coord::Coord; use embedded_graphics::primitives::Line; + use color::Color; + use embedded_graphics::prelude::*; // test buffer length #[test] @@ -48,7 +39,7 @@ mod tests { #[test] fn graphics_default() { let mut display4in2 = DisplayEink4in2BlackWhite::default(); - let mut display = Graphics::new(WIDTH, HEIGHT, &mut display4in2.buffer); + let display = Graphics::new(WIDTH, HEIGHT, &mut display4in2.buffer); use epd4in2; for &byte in display.buffer() { assert_eq!(byte, epd4in2::constants::DEFAULT_BACKGROUND_COLOR.get_byte_value()); diff --git a/src/graphics.rs b/src/graphics.rs index 10fc30d..b9a7530 100644 --- a/src/graphics.rs +++ b/src/graphics.rs @@ -19,7 +19,7 @@ impl Default for DisplayRotation { DisplayRotation::Rotate0 } } -use epd4in2::constants::{DEFAULT_BACKGROUND_COLOR, WIDTH, HEIGHT}; +//use epd4in2::constants::{DEFAULT_BACKGROUND_COLOR, WIDTH, HEIGHT}; pub trait Display { fn buffer(&self) -> &[u8]; @@ -63,15 +63,12 @@ impl<'a> Drawing for Graphics<'a> { where T: Iterator> { - let width = WIDTH as u32; - let height = HEIGHT as u32; - for Pixel(UnsignedCoord(x,y), color) in item_pixels { - if outside_display(x, y, width, height, self.rotation) { + if outside_display(x, y, self.width, self.height, self.rotation) { return; } - let (idx, bit) = rotation(x, y, width, height, self.rotation); + let (idx, bit) = rotation(x, y, self.width, self.height, self.rotation); let idx = idx as usize; match color { diff --git a/src/lib.rs b/src/lib.rs index 359b05d..36e54b8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -67,14 +67,14 @@ mod epd4in2; #[cfg(feature = "epd4in2")] pub use epd4in2::EPD4in2; #[cfg(feature = "epd4in2")] -pub use epd4in2::graphics::DisplayEink4in2BlackWhite; +pub use epd4in2::graphics::DisplayEink4in2BlackWhite as Buffer4in2; #[cfg(feature = "epd1in54")] mod epd1in54; #[cfg(feature = "epd1in54")] pub use epd1in54::EPD1in54; #[cfg(feature = "epd1in54")] -pub use epd1in54::graphics::DisplayEink1in54BlackWhite; +pub use epd1in54::graphics::DisplayEink1in54BlackWhite as Buffer1in54; #[cfg(feature = "epd2in9")] From a832ab9fedaf2aa3c27e022ec2d06eed6c50ac6a Mon Sep 17 00:00:00 2001 From: Chris Date: Fri, 19 Oct 2018 16:12:22 +0200 Subject: [PATCH 56/75] add more changes --- examples/embedded_linux_epd1in54/src/main.rs | 5 +-- src/epd1in54/graphics.rs | 37 +++++++++++++++----- src/epd4in2/graphics.rs | 31 ++++++++++++---- src/graphics.rs | 18 +++++----- 4 files changed, 64 insertions(+), 27 deletions(-) diff --git a/examples/embedded_linux_epd1in54/src/main.rs b/examples/embedded_linux_epd1in54/src/main.rs index 86b19e2..45cfb7c 100644 --- a/examples/embedded_linux_epd1in54/src/main.rs +++ b/examples/embedded_linux_epd1in54/src/main.rs @@ -7,7 +7,7 @@ extern crate eink_waveshare_rs; use eink_waveshare_rs::{ EPD1in54, - DisplayEink1in54BlackWhite, + Buffer1in54, graphics::{Display, DisplayRotation}, color::Color, WaveshareDisplay, @@ -125,7 +125,8 @@ fn run() -> Result<(), std::io::Error> { epd.display_frame(&mut spi).expect("disp 1"); println!("Test all the rotations"); - let mut display = DisplayEink1in54BlackWhite::default(); + let mut buffer = Buffer1in54::default(); + let mut display = Display::new(buffer.width, buffer.height, &mut buffer.buffer); display.set_rotation(DisplayRotation::Rotate0); display.draw( Font6x8::render_str("Rotate 0!") diff --git a/src/epd1in54/graphics.rs b/src/epd1in54/graphics.rs index 8c7c773..05ed250 100644 --- a/src/epd1in54/graphics.rs +++ b/src/epd1in54/graphics.rs @@ -1,12 +1,19 @@ -use epd4in2::constants::{DEFAULT_BACKGROUND_COLOR, WIDTH, HEIGHT}; +use epd1in54::{DEFAULT_BACKGROUND_COLOR, WIDTH, HEIGHT}; +use graphics::DisplayDimension; pub struct DisplayEink1in54BlackWhite { - pub buffer: [u8; WIDTH as usize * HEIGHT as usize / 8], + width: u32, + height: u32, + buffer: [u8; WIDTH as usize * HEIGHT as usize / 8], } + + impl Default for DisplayEink1in54BlackWhite { fn default() -> Self { DisplayEink1in54BlackWhite { + width: WIDTH, + height: HEIGHT, buffer: [ DEFAULT_BACKGROUND_COLOR.get_byte_value(); WIDTH as usize * HEIGHT as usize / 8 @@ -15,11 +22,23 @@ impl Default for DisplayEink1in54BlackWhite { } } +impl DisplayDimension for DisplayEink1in54BlackWhite { + fn buffer(&self) -> &[u8] { + &self.buffer + } + fn width(&self) -> u32 { + self.width + } + fn height(&self) -> u32 { + self.height + } +} + #[cfg(test)] mod tests { use super::*; - use graphics::{DisplayRotation, Graphics}; + use graphics::{DisplayRotation, Display}; use embedded_graphics::coord::Coord; use embedded_graphics::primitives::Line; use color::Color; @@ -29,7 +48,7 @@ mod tests { #[test] fn graphics_size() { let mut display1in54 = DisplayEink1in54BlackWhite::default(); - let display = Graphics::new(WIDTH, HEIGHT, &mut display1in54.buffer); + let display = Display::new(WIDTH, HEIGHT, &mut display1in54.buffer); assert_eq!(display.buffer().len(), 5000); } @@ -37,7 +56,7 @@ mod tests { #[test] fn graphics_default() { let mut display1in54 = DisplayEink1in54BlackWhite::default(); - let display = Graphics::new(WIDTH, HEIGHT, &mut display1in54.buffer); + let display = Display::new(WIDTH, HEIGHT, &mut display1in54.buffer); for &byte in display.buffer() { assert_eq!(byte, DEFAULT_BACKGROUND_COLOR.get_byte_value()); } @@ -46,7 +65,7 @@ mod tests { #[test] fn graphics_rotation_0() { let mut display1in54 = DisplayEink1in54BlackWhite::default(); - let mut display = Graphics::new(WIDTH, HEIGHT, &mut display1in54.buffer); + let mut display = Display::new(WIDTH, HEIGHT, &mut display1in54.buffer); display.draw( Line::new(Coord::new(0, 0), Coord::new(7, 0)) .with_stroke(Some(Color::Black)) @@ -65,7 +84,7 @@ mod tests { #[test] fn graphics_rotation_90() { let mut display1in54 = DisplayEink1in54BlackWhite::default(); - let mut display = Graphics::new(WIDTH, HEIGHT, &mut display1in54.buffer); + let mut display = Display::new(WIDTH, HEIGHT, &mut display1in54.buffer); display.set_rotation(DisplayRotation::Rotate90); display.draw( Line::new(Coord::new(0, 192), Coord::new(0, 199)) @@ -85,7 +104,7 @@ mod tests { #[test] fn graphics_rotation_180() { let mut display1in54 = DisplayEink1in54BlackWhite::default(); - let mut display = Graphics::new(WIDTH, HEIGHT, &mut display1in54.buffer); + let mut display = Display::new(WIDTH, HEIGHT, &mut display1in54.buffer); display.set_rotation(DisplayRotation::Rotate180); display.draw( Line::new(Coord::new(192, 199), Coord::new(199, 199)) @@ -109,7 +128,7 @@ mod tests { #[test] fn graphics_rotation_270() { let mut display1in54 = DisplayEink1in54BlackWhite::default(); - let mut display = Graphics::new(WIDTH, HEIGHT, &mut display1in54.buffer); + let mut display = Display::new(WIDTH, HEIGHT, &mut display1in54.buffer); display.set_rotation(DisplayRotation::Rotate270); display.draw( Line::new(Coord::new(199, 0), Coord::new(199, 7)) diff --git a/src/epd4in2/graphics.rs b/src/epd4in2/graphics.rs index af7d3c0..22ffdcf 100644 --- a/src/epd4in2/graphics.rs +++ b/src/epd4in2/graphics.rs @@ -1,12 +1,17 @@ use epd4in2::constants::{DEFAULT_BACKGROUND_COLOR, WIDTH, HEIGHT}; +use graphics::DisplayDimension; pub struct DisplayEink4in2BlackWhite { + width: u32, + height: u32, pub buffer: [u8; WIDTH as usize * HEIGHT as usize / 8], } impl Default for DisplayEink4in2BlackWhite { fn default() -> Self { DisplayEink4in2BlackWhite { + width: WIDTH, + height: HEIGHT, buffer: [ DEFAULT_BACKGROUND_COLOR.get_byte_value(); WIDTH as usize * HEIGHT as usize / 8 @@ -15,13 +20,25 @@ impl Default for DisplayEink4in2BlackWhite { } } +impl DisplayDimension for DisplayEink4in2BlackWhite { + fn buffer(&self) -> &[u8] { + &self.buffer + } + fn width(&self) -> u32 { + self.width + } + fn height(&self) -> u32 { + self.height + } +} + #[cfg(test)] mod tests { use super::*; use epd4in2; - use graphics::{DisplayRotation, Graphics}; + use graphics::{DisplayRotation, Display}; use embedded_graphics::coord::Coord; use embedded_graphics::primitives::Line; use color::Color; @@ -31,7 +48,7 @@ mod tests { #[test] fn graphics_size() { let mut display4in2 = DisplayEink4in2BlackWhite::default(); - let display = Graphics::new(WIDTH, HEIGHT, &mut display4in2.buffer); + let display = Display::new(WIDTH, HEIGHT, &mut display4in2.buffer); assert_eq!(display.buffer().len(), 15000); } @@ -39,7 +56,7 @@ mod tests { #[test] fn graphics_default() { let mut display4in2 = DisplayEink4in2BlackWhite::default(); - let display = Graphics::new(WIDTH, HEIGHT, &mut display4in2.buffer); + let display = Display::new(WIDTH, HEIGHT, &mut display4in2.buffer); use epd4in2; for &byte in display.buffer() { assert_eq!(byte, epd4in2::constants::DEFAULT_BACKGROUND_COLOR.get_byte_value()); @@ -49,7 +66,7 @@ mod tests { #[test] fn graphics_rotation_0() { let mut display4in2 = DisplayEink4in2BlackWhite::default(); - let mut display = Graphics::new(WIDTH, HEIGHT, &mut display4in2.buffer); + let mut display = Display::new(WIDTH, HEIGHT, &mut display4in2.buffer); display.draw( Line::new(Coord::new(0, 0), Coord::new(7, 0)) .with_stroke(Some(Color::Black)) @@ -68,7 +85,7 @@ mod tests { #[test] fn graphics_rotation_90() { let mut display4in2 = DisplayEink4in2BlackWhite::default(); - let mut display = Graphics::new(WIDTH, HEIGHT, &mut display4in2.buffer); + let mut display = Display::new(WIDTH, HEIGHT, &mut display4in2.buffer); display.set_rotation(DisplayRotation::Rotate90); display.draw( Line::new(Coord::new(0, 392), Coord::new(0, 399)) @@ -88,7 +105,7 @@ mod tests { #[test] fn graphics_rotation_180() { let mut display4in2 = DisplayEink4in2BlackWhite::default(); - let mut display = Graphics::new(WIDTH, HEIGHT, &mut display4in2.buffer); + let mut display = Display::new(WIDTH, HEIGHT, &mut display4in2.buffer); display.set_rotation(DisplayRotation::Rotate180); display.draw( Line::new(Coord::new(392, 299), Coord::new(399, 299)) @@ -112,7 +129,7 @@ mod tests { #[test] fn graphics_rotation_270() { let mut display4in2 = DisplayEink4in2BlackWhite::default(); - let mut display = Graphics::new(WIDTH, HEIGHT, &mut display4in2.buffer); + let mut display = Display::new(WIDTH, HEIGHT, &mut display4in2.buffer); display.set_rotation(DisplayRotation::Rotate270); display.draw( Line::new(Coord::new(299, 0), Coord::new(299, 7)) diff --git a/src/graphics.rs b/src/graphics.rs index b9a7530..92d6c6f 100644 --- a/src/graphics.rs +++ b/src/graphics.rs @@ -19,26 +19,26 @@ impl Default for DisplayRotation { DisplayRotation::Rotate0 } } -//use epd4in2::constants::{DEFAULT_BACKGROUND_COLOR, WIDTH, HEIGHT}; -pub trait Display { +pub trait DisplayDimension { fn buffer(&self) -> &[u8]; - fn set_rotation(&mut self, rotation: DisplayRotation); - fn rotation(&self) -> DisplayRotation; + fn width(&self) -> u32; + fn height(&self) -> u32; } -pub struct Graphics<'a> { + +pub struct Display<'a> { width: u32, height: u32, rotation: DisplayRotation, buffer: &'a mut [u8], //buffer: Box//[u8; 15000] } -impl<'a> Graphics<'a> { - pub fn new(width: u32, height: u32, buffer: &'a mut [u8]) -> Graphics<'a> { +impl<'a> Display<'a> { + pub fn new(width: u32, height: u32, buffer: &'a mut [u8]) -> Display<'a> { let len = buffer.len() as u32; assert!(width / 8 * height >= len); - Graphics { + Display { width, height, rotation: DisplayRotation::default(), @@ -58,7 +58,7 @@ impl<'a> Graphics<'a> { } -impl<'a> Drawing for Graphics<'a> { +impl<'a> Drawing for Display<'a> { fn draw(&mut self, item_pixels: T) where T: Iterator> From a1adeb77a45c1b580b573dec1ea5eb02a4995050 Mon Sep 17 00:00:00 2001 From: Chris Date: Fri, 19 Oct 2018 16:16:43 +0200 Subject: [PATCH 57/75] more changes to the displaydimension trait --- examples/embedded_linux_epd1in54/src/main.rs | 4 ++-- src/epd1in54/graphics.rs | 6 +++--- src/epd4in2/graphics.rs | 4 ++-- src/graphics.rs | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/embedded_linux_epd1in54/src/main.rs b/examples/embedded_linux_epd1in54/src/main.rs index 45cfb7c..d3fe524 100644 --- a/examples/embedded_linux_epd1in54/src/main.rs +++ b/examples/embedded_linux_epd1in54/src/main.rs @@ -8,7 +8,7 @@ extern crate eink_waveshare_rs; use eink_waveshare_rs::{ EPD1in54, Buffer1in54, - graphics::{Display, DisplayRotation}, + graphics::{Display, DisplayRotation, DisplayDimension}, color::Color, WaveshareDisplay, }; @@ -126,7 +126,7 @@ fn run() -> Result<(), std::io::Error> { println!("Test all the rotations"); let mut buffer = Buffer1in54::default(); - let mut display = Display::new(buffer.width, buffer.height, &mut buffer.buffer); + let mut display = Display::new(buffer.width(), buffer.height(), &mut buffer.buffer); display.set_rotation(DisplayRotation::Rotate0); display.draw( Font6x8::render_str("Rotate 0!") diff --git a/src/epd1in54/graphics.rs b/src/epd1in54/graphics.rs index 05ed250..d71b9dd 100644 --- a/src/epd1in54/graphics.rs +++ b/src/epd1in54/graphics.rs @@ -4,7 +4,7 @@ use graphics::DisplayDimension; pub struct DisplayEink1in54BlackWhite { width: u32, height: u32, - buffer: [u8; WIDTH as usize * HEIGHT as usize / 8], + pub buffer: [u8; WIDTH as usize * HEIGHT as usize / 8], } @@ -23,8 +23,8 @@ impl Default for DisplayEink1in54BlackWhite { } impl DisplayDimension for DisplayEink1in54BlackWhite { - fn buffer(&self) -> &[u8] { - &self.buffer + fn buffer(&mut self) -> &mut [u8] { + &mut self.buffer } fn width(&self) -> u32 { self.width diff --git a/src/epd4in2/graphics.rs b/src/epd4in2/graphics.rs index 22ffdcf..ac0f788 100644 --- a/src/epd4in2/graphics.rs +++ b/src/epd4in2/graphics.rs @@ -21,8 +21,8 @@ impl Default for DisplayEink4in2BlackWhite { } impl DisplayDimension for DisplayEink4in2BlackWhite { - fn buffer(&self) -> &[u8] { - &self.buffer + fn buffer(&mut self) -> &mut [u8] { + &mut self.buffer } fn width(&self) -> u32 { self.width diff --git a/src/graphics.rs b/src/graphics.rs index 92d6c6f..fd8b85d 100644 --- a/src/graphics.rs +++ b/src/graphics.rs @@ -21,7 +21,7 @@ impl Default for DisplayRotation { } pub trait DisplayDimension { - fn buffer(&self) -> &[u8]; + fn buffer(&mut self) -> &mut [u8]; fn width(&self) -> u32; fn height(&self) -> u32; } From 3b0b5962ec92d2167aab801bbf8fae053010e3c5 Mon Sep 17 00:00:00 2001 From: Chris Date: Fri, 19 Oct 2018 16:26:31 +0200 Subject: [PATCH 58/75] Streamline a few things --- examples/embedded_linux_epd1in54/src/main.rs | 4 +-- examples/embedded_linux_epd4in2/src/main.rs | 5 +-- src/epd1in54/graphics.rs | 37 +++++--------------- src/epd4in2/graphics.rs | 36 +++++-------------- src/graphics.rs | 9 ++--- src/lib.rs | 4 +-- 6 files changed, 27 insertions(+), 68 deletions(-) diff --git a/examples/embedded_linux_epd1in54/src/main.rs b/examples/embedded_linux_epd1in54/src/main.rs index d3fe524..1bafd82 100644 --- a/examples/embedded_linux_epd1in54/src/main.rs +++ b/examples/embedded_linux_epd1in54/src/main.rs @@ -8,7 +8,7 @@ extern crate eink_waveshare_rs; use eink_waveshare_rs::{ EPD1in54, Buffer1in54, - graphics::{Display, DisplayRotation, DisplayDimension}, + graphics::{Display, DisplayRotation}, color::Color, WaveshareDisplay, }; @@ -126,7 +126,7 @@ fn run() -> Result<(), std::io::Error> { println!("Test all the rotations"); let mut buffer = Buffer1in54::default(); - let mut display = Display::new(buffer.width(), buffer.height(), &mut buffer.buffer); + let mut display = Display::new(epd.width(), epd.height(), &mut buffer.buffer); display.set_rotation(DisplayRotation::Rotate0); display.draw( Font6x8::render_str("Rotate 0!") diff --git a/examples/embedded_linux_epd4in2/src/main.rs b/examples/embedded_linux_epd4in2/src/main.rs index d064359..17d2714 100644 --- a/examples/embedded_linux_epd4in2/src/main.rs +++ b/examples/embedded_linux_epd4in2/src/main.rs @@ -7,7 +7,7 @@ extern crate eink_waveshare_rs; use eink_waveshare_rs::{ EPD4in2, - DisplayEink42BlackWhite, + Buffer4in2, graphics::{Display, DisplayRotation}, color::Color, WaveshareDisplay, @@ -117,7 +117,8 @@ fn run() -> Result<(), std::io::Error> { let mut epd4in2 = EPD4in2::new(&mut spi, cs, busy_in, dc, rst, &mut delay).expect("eink initalize error"); println!("Test all the rotations"); - let mut display = DisplayEink42BlackWhite::default(); + let mut buffer = Buffer4in2::default(); + let mut display = Display::new(epd4in2.width(), epd4in2.height(), &mut buffer.buffer); display.set_rotation(DisplayRotation::Rotate0); display.draw( Font6x8::render_str("Rotate 0!") diff --git a/src/epd1in54/graphics.rs b/src/epd1in54/graphics.rs index d71b9dd..010b974 100644 --- a/src/epd1in54/graphics.rs +++ b/src/epd1in54/graphics.rs @@ -1,19 +1,12 @@ use epd1in54::{DEFAULT_BACKGROUND_COLOR, WIDTH, HEIGHT}; -use graphics::DisplayDimension; -pub struct DisplayEink1in54BlackWhite { - width: u32, - height: u32, +pub struct Buffer1in54BlackWhite { pub buffer: [u8; WIDTH as usize * HEIGHT as usize / 8], } - - -impl Default for DisplayEink1in54BlackWhite { +impl Default for Buffer1in54BlackWhite { fn default() -> Self { - DisplayEink1in54BlackWhite { - width: WIDTH, - height: HEIGHT, + Buffer1in54BlackWhite { buffer: [ DEFAULT_BACKGROUND_COLOR.get_byte_value(); WIDTH as usize * HEIGHT as usize / 8 @@ -22,18 +15,6 @@ impl Default for DisplayEink1in54BlackWhite { } } -impl DisplayDimension for DisplayEink1in54BlackWhite { - fn buffer(&mut self) -> &mut [u8] { - &mut self.buffer - } - fn width(&self) -> u32 { - self.width - } - fn height(&self) -> u32 { - self.height - } -} - #[cfg(test)] mod tests { @@ -47,7 +28,7 @@ mod tests { // test buffer length #[test] fn graphics_size() { - let mut display1in54 = DisplayEink1in54BlackWhite::default(); + let mut display1in54 = Buffer1in54BlackWhite::default(); let display = Display::new(WIDTH, HEIGHT, &mut display1in54.buffer); assert_eq!(display.buffer().len(), 5000); } @@ -55,7 +36,7 @@ mod tests { // test default background color on all bytes #[test] fn graphics_default() { - let mut display1in54 = DisplayEink1in54BlackWhite::default(); + let mut display1in54 = Buffer1in54BlackWhite::default(); let display = Display::new(WIDTH, HEIGHT, &mut display1in54.buffer); for &byte in display.buffer() { assert_eq!(byte, DEFAULT_BACKGROUND_COLOR.get_byte_value()); @@ -64,7 +45,7 @@ mod tests { #[test] fn graphics_rotation_0() { - let mut display1in54 = DisplayEink1in54BlackWhite::default(); + let mut display1in54 = Buffer1in54BlackWhite::default(); let mut display = Display::new(WIDTH, HEIGHT, &mut display1in54.buffer); display.draw( Line::new(Coord::new(0, 0), Coord::new(7, 0)) @@ -83,7 +64,7 @@ mod tests { #[test] fn graphics_rotation_90() { - let mut display1in54 = DisplayEink1in54BlackWhite::default(); + let mut display1in54 = Buffer1in54BlackWhite::default(); let mut display = Display::new(WIDTH, HEIGHT, &mut display1in54.buffer); display.set_rotation(DisplayRotation::Rotate90); display.draw( @@ -103,7 +84,7 @@ mod tests { #[test] fn graphics_rotation_180() { - let mut display1in54 = DisplayEink1in54BlackWhite::default(); + let mut display1in54 = Buffer1in54BlackWhite::default(); let mut display = Display::new(WIDTH, HEIGHT, &mut display1in54.buffer); display.set_rotation(DisplayRotation::Rotate180); display.draw( @@ -127,7 +108,7 @@ mod tests { #[test] fn graphics_rotation_270() { - let mut display1in54 = DisplayEink1in54BlackWhite::default(); + let mut display1in54 = Buffer1in54BlackWhite::default(); let mut display = Display::new(WIDTH, HEIGHT, &mut display1in54.buffer); display.set_rotation(DisplayRotation::Rotate270); display.draw( diff --git a/src/epd4in2/graphics.rs b/src/epd4in2/graphics.rs index ac0f788..586234d 100644 --- a/src/epd4in2/graphics.rs +++ b/src/epd4in2/graphics.rs @@ -1,17 +1,12 @@ use epd4in2::constants::{DEFAULT_BACKGROUND_COLOR, WIDTH, HEIGHT}; -use graphics::DisplayDimension; -pub struct DisplayEink4in2BlackWhite { - width: u32, - height: u32, +pub struct Buffer4in2 { pub buffer: [u8; WIDTH as usize * HEIGHT as usize / 8], } -impl Default for DisplayEink4in2BlackWhite { +impl Default for Buffer4in2 { fn default() -> Self { - DisplayEink4in2BlackWhite { - width: WIDTH, - height: HEIGHT, + Buffer4in2 { buffer: [ DEFAULT_BACKGROUND_COLOR.get_byte_value(); WIDTH as usize * HEIGHT as usize / 8 @@ -20,19 +15,6 @@ impl Default for DisplayEink4in2BlackWhite { } } -impl DisplayDimension for DisplayEink4in2BlackWhite { - fn buffer(&mut self) -> &mut [u8] { - &mut self.buffer - } - fn width(&self) -> u32 { - self.width - } - fn height(&self) -> u32 { - self.height - } -} - - #[cfg(test)] mod tests { @@ -47,7 +29,7 @@ mod tests { // test buffer length #[test] fn graphics_size() { - let mut display4in2 = DisplayEink4in2BlackWhite::default(); + let mut display4in2 = Buffer4in2::default(); let display = Display::new(WIDTH, HEIGHT, &mut display4in2.buffer); assert_eq!(display.buffer().len(), 15000); } @@ -55,7 +37,7 @@ mod tests { // test default background color on all bytes #[test] fn graphics_default() { - let mut display4in2 = DisplayEink4in2BlackWhite::default(); + let mut display4in2 = Buffer4in2::default(); let display = Display::new(WIDTH, HEIGHT, &mut display4in2.buffer); use epd4in2; for &byte in display.buffer() { @@ -65,7 +47,7 @@ mod tests { #[test] fn graphics_rotation_0() { - let mut display4in2 = DisplayEink4in2BlackWhite::default(); + let mut display4in2 = Buffer4in2::default(); let mut display = Display::new(WIDTH, HEIGHT, &mut display4in2.buffer); display.draw( Line::new(Coord::new(0, 0), Coord::new(7, 0)) @@ -84,7 +66,7 @@ mod tests { #[test] fn graphics_rotation_90() { - let mut display4in2 = DisplayEink4in2BlackWhite::default(); + let mut display4in2 = Buffer4in2::default(); let mut display = Display::new(WIDTH, HEIGHT, &mut display4in2.buffer); display.set_rotation(DisplayRotation::Rotate90); display.draw( @@ -104,7 +86,7 @@ mod tests { #[test] fn graphics_rotation_180() { - let mut display4in2 = DisplayEink4in2BlackWhite::default(); + let mut display4in2 = Buffer4in2::default(); let mut display = Display::new(WIDTH, HEIGHT, &mut display4in2.buffer); display.set_rotation(DisplayRotation::Rotate180); display.draw( @@ -128,7 +110,7 @@ mod tests { #[test] fn graphics_rotation_270() { - let mut display4in2 = DisplayEink4in2BlackWhite::default(); + let mut display4in2 = Buffer4in2::default(); let mut display = Display::new(WIDTH, HEIGHT, &mut display4in2.buffer); display.set_rotation(DisplayRotation::Rotate270); display.draw( diff --git a/src/graphics.rs b/src/graphics.rs index fd8b85d..55672b8 100644 --- a/src/graphics.rs +++ b/src/graphics.rs @@ -20,13 +20,6 @@ impl Default for DisplayRotation { } } -pub trait DisplayDimension { - fn buffer(&mut self) -> &mut [u8]; - fn width(&self) -> u32; - fn height(&self) -> u32; -} - - pub struct Display<'a> { width: u32, height: u32, @@ -49,9 +42,11 @@ impl<'a> Display<'a> { pub fn buffer(&self) -> &[u8] { &self.buffer } + pub fn set_rotation(&mut self, rotation: DisplayRotation) { self.rotation = rotation; } + pub fn rotation(&self) -> DisplayRotation { self.rotation } diff --git a/src/lib.rs b/src/lib.rs index 36e54b8..37d9980 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -67,14 +67,14 @@ mod epd4in2; #[cfg(feature = "epd4in2")] pub use epd4in2::EPD4in2; #[cfg(feature = "epd4in2")] -pub use epd4in2::graphics::DisplayEink4in2BlackWhite as Buffer4in2; +pub use epd4in2::graphics::Buffer4in2; #[cfg(feature = "epd1in54")] mod epd1in54; #[cfg(feature = "epd1in54")] pub use epd1in54::EPD1in54; #[cfg(feature = "epd1in54")] -pub use epd1in54::graphics::DisplayEink1in54BlackWhite as Buffer1in54; +pub use epd1in54::graphics::Buffer1in54BlackWhite as Buffer1in54; #[cfg(feature = "epd2in9")] From 520317f3519e394de13e6d070afd0ed26f8fe458 Mon Sep 17 00:00:00 2001 From: Chris Date: Fri, 19 Oct 2018 17:00:15 +0200 Subject: [PATCH 59/75] Fixed examples and more small improvements --- examples/embedded_linux_epd1in54/src/main.rs | 6 ++-- examples/embedded_linux_epd4in2/src/main.rs | 8 ++++-- src/color.rs | 2 +- src/epd1in54/mod.rs | 3 +- src/epd2in9/mod.rs | 6 ++-- src/epd4in2/constants.rs | 6 ++-- src/epd4in2/mod.rs | 5 ++-- src/graphics.rs | 30 ++++++++++++++++++-- src/lib.rs | 19 ++----------- 9 files changed, 52 insertions(+), 33 deletions(-) diff --git a/examples/embedded_linux_epd1in54/src/main.rs b/examples/embedded_linux_epd1in54/src/main.rs index 1bafd82..93380bd 100644 --- a/examples/embedded_linux_epd1in54/src/main.rs +++ b/examples/embedded_linux_epd1in54/src/main.rs @@ -6,8 +6,10 @@ extern crate eink_waveshare_rs; use eink_waveshare_rs::{ - EPD1in54, - Buffer1in54, + epd1in54::{ + EPD1in54, + Buffer1in54, + }, graphics::{Display, DisplayRotation}, color::Color, WaveshareDisplay, diff --git a/examples/embedded_linux_epd4in2/src/main.rs b/examples/embedded_linux_epd4in2/src/main.rs index 17d2714..f14dcdb 100644 --- a/examples/embedded_linux_epd4in2/src/main.rs +++ b/examples/embedded_linux_epd4in2/src/main.rs @@ -6,8 +6,10 @@ extern crate eink_waveshare_rs; use eink_waveshare_rs::{ - EPD4in2, - Buffer4in2, + epd4in2::{ + EPD4in2, + Buffer4in2, + }, graphics::{Display, DisplayRotation}, color::Color, WaveshareDisplay, @@ -162,7 +164,7 @@ fn run() -> Result<(), std::io::Error> { println!("Now test new graphics with default rotation and some special stuff:"); - let mut display = DisplayEink42BlackWhite::default(); + display.clear_buffer(Color::White); // draw a analog clock display.draw( diff --git a/src/color.rs b/src/color.rs index 7a83d44..f825949 100644 --- a/src/color.rs +++ b/src/color.rs @@ -48,7 +48,7 @@ impl Color { } // Inverses the given color from Black to White or from White to Black - fn inverse_color(color: &Color) -> Color { + pub(crate) fn inverse_color(color: &Color) -> Color { match color { Color::White => Color::Black, Color::Black => Color::White, diff --git a/src/epd1in54/mod.rs b/src/epd1in54/mod.rs index 5a61fbb..ce59f51 100644 --- a/src/epd1in54/mod.rs +++ b/src/epd1in54/mod.rs @@ -40,7 +40,8 @@ use traits::{WaveshareDisplay}; use interface::DisplayInterface; -pub mod graphics; +mod graphics; +pub use epd1in54::graphics::Buffer1in54BlackWhite as Buffer1in54; /// EPD1in54 driver /// diff --git a/src/epd2in9/mod.rs b/src/epd2in9/mod.rs index 7e877db..163b655 100644 --- a/src/epd2in9/mod.rs +++ b/src/epd2in9/mod.rs @@ -19,9 +19,9 @@ //! epd4in2.sleep(); //! ``` -const WIDTH: u32 = 128; -const HEIGHT: u32 = 296; -const DEFAULT_BACKGROUND_COLOR: Color = Color::White; +pub const WIDTH: u32 = 128; +pub const HEIGHT: u32 = 296; +pub const DEFAULT_BACKGROUND_COLOR: Color = Color::White; use hal::{ blocking::{delay::*, spi::Write}, diff --git a/src/epd4in2/constants.rs b/src/epd4in2/constants.rs index 47bf5f7..9e019cc 100644 --- a/src/epd4in2/constants.rs +++ b/src/epd4in2/constants.rs @@ -1,8 +1,8 @@ use color::Color; -pub(crate) const WIDTH: u32 = 400; -pub(crate) const HEIGHT: u32 = 300; -pub(crate) const DEFAULT_BACKGROUND_COLOR: Color = Color::White; +pub const WIDTH: u32 = 400; +pub const HEIGHT: u32 = 300; +pub const DEFAULT_BACKGROUND_COLOR: Color = Color::White; pub(crate) const LUT_VCOM0: [u8; 44] = [ 0x00, 0x17, 0x00, 0x00, 0x00, 0x02, diff --git a/src/epd4in2/mod.rs b/src/epd4in2/mod.rs index d8dbdf3..bbea54f 100644 --- a/src/epd4in2/mod.rs +++ b/src/epd4in2/mod.rs @@ -56,14 +56,15 @@ use interface::DisplayInterface; //The Lookup Tables for the Display pub(crate) mod constants; //TODO: Limit to crate::drawing -use self::constants::*; +pub use self::constants::*; use color::Color; pub(crate) mod command; use self::command::Command; -pub mod graphics; +mod graphics; +pub use self::graphics::Buffer4in2; /// EPD4in2 driver diff --git a/src/graphics.rs b/src/graphics.rs index 55672b8..32b4e53 100644 --- a/src/graphics.rs +++ b/src/graphics.rs @@ -43,10 +43,16 @@ impl<'a> Display<'a> { &self.buffer } + pub fn clear_buffer(&mut self, background_color: Color) { + for elem in &mut self.buffer.iter_mut() { + *elem = background_color.get_byte_value(); + } + } + pub fn set_rotation(&mut self, rotation: DisplayRotation) { self.rotation = rotation; } - + pub fn rotation(&self) -> DisplayRotation { self.rotation } @@ -120,7 +126,27 @@ pub(crate) fn rotation(x: u32, y: u32, width: u32, height: u32, rotation: Displa #[cfg(test)] mod tests { - use super::{DisplayRotation, outside_display, rotation}; + use super::{DisplayRotation, outside_display, rotation, Display}; + use color::Color; + + #[test] + fn buffer_clear() { + use epd4in2::constants::{WIDTH, HEIGHT}; + + let mut buffer = [Color::Black.get_byte_value(); WIDTH as usize / 8 * HEIGHT as usize]; + let mut display = Display::new(WIDTH, HEIGHT, &mut buffer); + + for &byte in display.buffer.iter() { + assert_eq!(byte, Color::Black.get_byte_value()); + } + + display.clear_buffer(Color::White); + + for &byte in display.buffer.iter() { + assert_eq!(byte, Color::White.get_byte_value()); + } + } + #[test] fn rotation_overflow() { diff --git a/src/lib.rs b/src/lib.rs index 37d9980..736ffa0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -63,26 +63,13 @@ pub mod color; mod interface; #[cfg(feature = "epd4in2")] -mod epd4in2; -#[cfg(feature = "epd4in2")] -pub use epd4in2::EPD4in2; -#[cfg(feature = "epd4in2")] -pub use epd4in2::graphics::Buffer4in2; +pub mod epd4in2; #[cfg(feature = "epd1in54")] -mod epd1in54; -#[cfg(feature = "epd1in54")] -pub use epd1in54::EPD1in54; -#[cfg(feature = "epd1in54")] -pub use epd1in54::graphics::Buffer1in54BlackWhite as Buffer1in54; - +pub mod epd1in54; #[cfg(feature = "epd2in9")] -mod epd2in9; -///2in9 eink -#[cfg(feature = "epd2in9")] -///2in9 eink -pub use epd2in9::EPD2in9; +pub mod epd2in9; #[cfg(any(feature = "epd1in54", feature = "epd2in9"))] pub(crate) mod type_a; From 824735fb642f0630c158e31d715c300358f06358 Mon Sep 17 00:00:00 2001 From: Chris Date: Mon, 22 Oct 2018 13:06:24 +0200 Subject: [PATCH 60/75] Fix error where pixel outside display lead to early return instead of just skipping that pixel --- src/graphics.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/graphics.rs b/src/graphics.rs index 32b4e53..d06e82f 100644 --- a/src/graphics.rs +++ b/src/graphics.rs @@ -20,22 +20,22 @@ impl Default for DisplayRotation { } } -pub struct Display<'a> { +pub struct Display { width: u32, height: u32, rotation: DisplayRotation, - buffer: &'a mut [u8], //buffer: Box//[u8; 15000] + buffer: [u8; 15000], //buffer: Box//[u8; 15000] } -impl<'a> Display<'a> { - pub fn new(width: u32, height: u32, buffer: &'a mut [u8]) -> Display<'a> { +impl Display { + pub fn new(width: u32, height: u32, buffer: & mut [u8]) -> Display { let len = buffer.len() as u32; assert!(width / 8 * height >= len); Display { width, height, rotation: DisplayRotation::default(), - buffer, + buffer: [0u8; 15000], } } @@ -59,7 +59,7 @@ impl<'a> Display<'a> { } -impl<'a> Drawing for Display<'a> { +impl Drawing for Display { fn draw(&mut self, item_pixels: T) where T: Iterator> From efa55917889861d37a59fb334efc7b367ef5da1f Mon Sep 17 00:00:00 2001 From: Chris Date: Mon, 22 Oct 2018 13:10:24 +0200 Subject: [PATCH 61/75] Added some comments to the previous commit --- src/graphics.rs | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/graphics.rs b/src/graphics.rs index d06e82f..1342dba 100644 --- a/src/graphics.rs +++ b/src/graphics.rs @@ -20,22 +20,22 @@ impl Default for DisplayRotation { } } -pub struct Display { +pub struct Display<'a> { width: u32, height: u32, rotation: DisplayRotation, - buffer: [u8; 15000], //buffer: Box//[u8; 15000] + buffer: &'a mut [u8], //buffer: Box//[u8; 15000] } -impl Display { - pub fn new(width: u32, height: u32, buffer: & mut [u8]) -> Display { +impl<'a> Display<'a> { + pub fn new(width: u32, height: u32, buffer: &'a mut [u8]) -> Display<'a> { let len = buffer.len() as u32; assert!(width / 8 * height >= len); Display { width, height, rotation: DisplayRotation::default(), - buffer: [0u8; 15000], + buffer, } } @@ -59,25 +59,28 @@ impl Display { } -impl Drawing for Display { +impl<'a> Drawing for Display<'a> { fn draw(&mut self, item_pixels: T) where T: Iterator> { for Pixel(UnsignedCoord(x,y), color) in item_pixels { + if outside_display(x, y, self.width, self.height, self.rotation) { - return; + continue; } - let (idx, bit) = rotation(x, y, self.width, self.height, self.rotation); + // Give us index inside the buffer and the bit-position in that u8 which needs to be changed + let (index, bit) = rotation(x, y, self.width, self.height, self.rotation); + let index = index as usize; - let idx = idx as usize; + // "Draw" the Pixel on that bit match color { Color::Black => { - self.buffer[idx] &= !bit; + self.buffer[index] &= !bit; } Color::White => { - self.buffer[idx] |= bit; + self.buffer[index] |= bit; } } } @@ -85,7 +88,7 @@ impl Drawing for Display { } -pub(crate) fn outside_display(x: u32, y: u32, width: u32, height: u32, rotation: DisplayRotation) -> bool { +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 { @@ -101,7 +104,7 @@ pub(crate) fn outside_display(x: u32, y: u32, width: u32, height: u32, rotation: false } -pub(crate) fn rotation(x: u32, y: u32, width: u32, height: u32, rotation: DisplayRotation) -> (u32, u8) { +fn rotation(x: u32, y: u32, width: u32, height: u32, rotation: DisplayRotation) -> (u32, u8) { match rotation { DisplayRotation::Rotate0 => ( x / 8 + (width / 8) * y, From 4fefe40b8210a24d53dcc0ea8e74149d0cfc65a4 Mon Sep 17 00:00:00 2001 From: Chris Date: Mon, 22 Oct 2018 14:45:12 +0200 Subject: [PATCH 62/75] Adapt stm32 example to changes to fix build errors --- examples/stm32f3discovery/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/stm32f3discovery/src/main.rs b/examples/stm32f3discovery/src/main.rs index 29989b7..c4614f4 100644 --- a/examples/stm32f3discovery/src/main.rs +++ b/examples/stm32f3discovery/src/main.rs @@ -26,7 +26,7 @@ extern crate eink_waveshare_rs; use eink_waveshare_rs::{ - EPD1in54, + epd1in54::EPD1in54, SPI_MODE, //drawing_old::{Graphics}, color::Color, From 8f0a2a98adb9ac18d8340af68b1221ced5a9303a Mon Sep 17 00:00:00 2001 From: Chris Date: Mon, 22 Oct 2018 15:42:08 +0200 Subject: [PATCH 63/75] Update Readme --- README.md | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index cea48e0..796202b 100644 --- a/README.md +++ b/README.md @@ -2,18 +2,16 @@ This library contains a driver for E-Paper Modules from Waveshare. -Support for more than the 4.2in EPD (especially the smaller and faster ones) is in the work. - -The 2.9in (A) and 1.54 (A) variant should both work but aren't tested yet. +It uses the [embedded graphics](https://crates.io/crates/embedded-graphics) library for the optional graphics support. ## (Supported) Devices | Device (with Link) | Colors | Flexible Display | Partial Refresh | Supported | Tested | | :---: | --- | :---: | :---: | :---: | :---: | | [4.2 Inch B/W (A)](https://www.waveshare.com/product/4.2inch-e-paper-module.htm) | Black, White | ✕ | Not officially [[1](#42-inch-e-ink-blackwhite)] | ✔ | ✔ | -| [1.54 Inch B/W (A)](https://www.waveshare.com/1.54inch-e-Paper-Module.htm) | Black, White | ✕ | ✔ | ✔ | | +| [1.54 Inch B/W (A)](https://www.waveshare.com/1.54inch-e-Paper-Module.htm) | Black, White | ✕ | ✔ | ✔ | ✔ | | [2.13 Inch B/W (A)](https://www.waveshare.com/product/2.13inch-e-paper-hat.htm) | Black, White | ✕ | ✔ | | | -| [2.9 Inch B/W (A)](https://www.waveshare.com/product/2.9inch-e-paper-module.htm) | Black, White | ✕ | ✔ | ✔ | | +| [2.9 Inch B/W (A)](https://www.waveshare.com/product/2.9inch-e-paper-module.htm) | Black, White | ✕ | ✔ | ✔ | ✔ | ### 4.2 Inch E-Ink Black/White @@ -61,14 +59,6 @@ They are also called A and B, but you shouldn't get confused and mix it with the ## TODO's - [ ] improve the partial drawing/check the timings/timing improvements/.... -- [ ] for later: add support for more waveshare epds -- [ ] License: Stay with ISC (=MIT) or go to the Apache+MIT Dual License as used in many other projects? - -## Graphics/Drawing - -It is recommended to use the [embedded graphics](https://crates.io/crates/embedded-graphics) library. - -Even though any u8-slice works, it is not recommended! ## Examples From 697a781ff2aff78af357d460522c32f6016a7b91 Mon Sep 17 00:00:00 2001 From: Chris Date: Mon, 22 Oct 2018 15:43:50 +0200 Subject: [PATCH 64/75] Remove more or less duplicate test cases for 2in9 buffer --- Cargo.toml | 8 +++--- src/color.rs | 5 +++- src/epd1in54/graphics.rs | 2 +- src/epd1in54/mod.rs | 6 ++--- src/epd2in9/graphics.rs | 41 ++++++++++++++++++++++++++++ src/epd2in9/mod.rs | 3 +++ src/graphics.rs | 58 ++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 5 +++- 8 files changed, 118 insertions(+), 10 deletions(-) create mode 100644 src/epd2in9/graphics.rs diff --git a/Cargo.toml b/Cargo.toml index 34de391..ffe9c4e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,16 +20,16 @@ travis-ci = { repository = "Caemor/eink-waveshare-rs" } [features] default = ["epd1in54", "epd2in9", "epd4in2", "graphics"] -graphics = [] +graphics = ["embedded-graphics"] epd1in54 = [] epd2in9 = [] epd4in2 = [] # Activates the fast LUT for EPD4in2 epd4in2_fast_update = [] -[dependencies] - -embedded-graphics = "0.4.3" +[dependencies.embedded-graphics] +optional = true +version = "0.4.3" # embedded-graphics = {git = "https://github.com/caemor/embedded-graphics", branch = "master"} # embedded-graphics = {git = "https://github.com/jamwaffles/embedded-graphics", branch = "master"} diff --git a/src/color.rs b/src/color.rs index f825949..07a9f47 100644 --- a/src/color.rs +++ b/src/color.rs @@ -1,5 +1,5 @@ -use embedded_graphics::prelude::*; + /// Only for the B/W Displays atm #[derive(Clone, Copy, PartialEq, Debug)] @@ -85,6 +85,9 @@ impl Color { } } +#[cfg(feature = "graphics")] +use embedded_graphics::prelude::*; +#[cfg(feature = "graphics")] impl PixelColor for Color {} impl From for Color { diff --git a/src/epd1in54/graphics.rs b/src/epd1in54/graphics.rs index 010b974..2604645 100644 --- a/src/epd1in54/graphics.rs +++ b/src/epd1in54/graphics.rs @@ -12,7 +12,7 @@ impl Default for Buffer1in54BlackWhite { WIDTH as usize * HEIGHT as usize / 8 ] } - } + } } diff --git a/src/epd1in54/mod.rs b/src/epd1in54/mod.rs index ce59f51..2bb8eea 100644 --- a/src/epd1in54/mod.rs +++ b/src/epd1in54/mod.rs @@ -19,10 +19,10 @@ //! epd4in2.sleep(); //! ``` -const WIDTH: u32 = 200; -const HEIGHT: u32 = 200; +pub const WIDTH: u32 = 200; +pub const HEIGHT: u32 = 200; //const DPI: u16 = 184; -const DEFAULT_BACKGROUND_COLOR: Color = Color::White; +pub const DEFAULT_BACKGROUND_COLOR: Color = Color::White; use hal::{ blocking::{delay::*, spi::Write}, diff --git a/src/epd2in9/graphics.rs b/src/epd2in9/graphics.rs new file mode 100644 index 0000000..45e17d9 --- /dev/null +++ b/src/epd2in9/graphics.rs @@ -0,0 +1,41 @@ +use epd2in9::{DEFAULT_BACKGROUND_COLOR, WIDTH, HEIGHT}; + +pub struct Buffer2in9 { + pub buffer: [u8; WIDTH as usize * HEIGHT as usize / 8], +} + +impl Default for Buffer2in9 { + fn default() -> Self { + Buffer2in9 { + buffer: [ + DEFAULT_BACKGROUND_COLOR.get_byte_value(); + WIDTH as usize * HEIGHT as usize / 8 + ] + } + } +} + + +#[cfg(test)] +mod tests { + use super::*; + use graphics::Display; + + // test buffer length + #[test] + fn graphics_size() { + let mut buffer = Buffer2in9::default(); + let display = Display::new(WIDTH, HEIGHT, &mut buffer.buffer); + assert_eq!(display.buffer().len(), 4736); + } + + // test default background color on all bytes + #[test] + fn graphics_default() { + let mut buffer = Buffer2in9::default(); + let display = Display::new(WIDTH, HEIGHT, &mut buffer.buffer); + for &byte in display.buffer() { + assert_eq!(byte, DEFAULT_BACKGROUND_COLOR.get_byte_value()); + } + } +} \ No newline at end of file diff --git a/src/epd2in9/mod.rs b/src/epd2in9/mod.rs index 163b655..9da3e14 100644 --- a/src/epd2in9/mod.rs +++ b/src/epd2in9/mod.rs @@ -39,6 +39,9 @@ use traits::*; use interface::DisplayInterface; +mod graphics; +pub use epd2in9::graphics::Buffer2in9; + /// EPD2in9 driver /// pub struct EPD2in9 { diff --git a/src/graphics.rs b/src/graphics.rs index 1342dba..2cbd3ff 100644 --- a/src/graphics.rs +++ b/src/graphics.rs @@ -131,6 +131,9 @@ fn rotation(x: u32, y: u32, width: u32, height: u32, rotation: DisplayRotation) mod tests { use super::{DisplayRotation, outside_display, rotation, Display}; use color::Color; + use embedded_graphics::coord::Coord; + use embedded_graphics::primitives::Line; + use embedded_graphics::prelude::*; #[test] fn buffer_clear() { @@ -176,4 +179,59 @@ mod tests { } } } + + + + #[test] + fn graphics_rotation_0() { + use epd2in9::{DEFAULT_BACKGROUND_COLOR}; + let width = 128; + let height = 296; + + let mut buffer = [DEFAULT_BACKGROUND_COLOR.get_byte_value(); 128 / 8 * 296]; + let mut display = Display::new(width, height, &mut buffer); + + display.draw( + Line::new(Coord::new(0, 0), Coord::new(7, 0)) + .with_stroke(Some(Color::Black)) + .into_iter(), + ); + + let buffer = display.buffer(); + + assert_eq!(buffer[0], Color::Black.get_byte_value()); + + for &byte in buffer.iter().skip(1) { + assert_eq!(byte, DEFAULT_BACKGROUND_COLOR.get_byte_value()); + } + } + + #[test] + fn graphics_rotation_90() { + use epd2in9::{DEFAULT_BACKGROUND_COLOR}; + let width = 128; + let height = 296; + + let mut buffer = [DEFAULT_BACKGROUND_COLOR.get_byte_value(); 128 / 8 * 296]; + let mut display = Display::new(width, height, &mut buffer); + + display.set_rotation(DisplayRotation::Rotate90); + + display.draw( + Line::new(Coord::new(0, 120), Coord::new(0, 295)) + .with_stroke(Some(Color::Black)) + .into_iter(), + ); + + let buffer = display.buffer(); + + extern crate std; + std::println!("{:?}", buffer); + + assert_eq!(buffer[0], Color::Black.get_byte_value()); + + for &byte in buffer.iter().skip(1) { + assert_eq!(byte, DEFAULT_BACKGROUND_COLOR.get_byte_value()); + } + } } \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 736ffa0..6268ff6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -47,6 +47,9 @@ extern crate embedded_hal as hal; use hal::spi::{Mode, Phase, Polarity}; +#[cfg(feature = "graphics")] +extern crate embedded_graphics; + #[cfg(feature = "graphics")] pub mod graphics; @@ -74,7 +77,7 @@ pub mod epd2in9; #[cfg(any(feature = "epd1in54", feature = "epd2in9"))] pub(crate) mod type_a; -extern crate embedded_graphics; + /// SPI mode - /// For more infos see [Requirements: SPI](index.html#spi) From 598a6924ea829d7c78d85fd8c86887b7a7d12e23 Mon Sep 17 00:00:00 2001 From: Chris Date: Mon, 22 Oct 2018 15:55:52 +0200 Subject: [PATCH 65/75] Cleanup of color-module and removal of old drawing module --- src/color.rs | 52 +-- src/drawing_old/font.rs | 759 ---------------------------------------- src/drawing_old/mod.rs | 622 -------------------------------- src/lib.rs | 14 +- 4 files changed, 8 insertions(+), 1439 deletions(-) delete mode 100644 src/drawing_old/font.rs delete mode 100644 src/drawing_old/mod.rs diff --git a/src/color.rs b/src/color.rs index 07a9f47..7f2f8f9 100644 --- a/src/color.rs +++ b/src/color.rs @@ -25,6 +25,7 @@ impl Color { } } + /// Parses fn from_u8(val: u8) -> Self { match val { 0 => Color::Black, @@ -33,56 +34,15 @@ impl Color { } } - /// Get the color encoding of a specific bit in a byte - /// - /// input is the byte where one bit is gonna be selected - /// pos is counted from the left (highest value) from 0 to 7 - /// remember: 1 is white, 0 is black - /// Color is the color you want to draw with in the foreground - pub(crate) fn get_color(input: u8, pos: u8, color: &Color) -> Color { - if Color::is_drawable_pixel(input, pos) { - Color::normal_color(color) - } else { - Color::inverse_color(color) - } - } - - // Inverses the given color from Black to White or from White to Black - pub(crate) fn inverse_color(color: &Color) -> Color { - match color { + /// Returns the inverse of the given color. + /// + /// Black returns White and White returns Black + pub fn inverse(&self) -> Color { + match self { Color::White => Color::Black, Color::Black => Color::White, } } - - // Gives you a new owned copy of the color - //TODO: just use clone? - fn normal_color(color: &Color) -> Color { - match color { - Color::White => Color::White, - Color::Black => Color::Black, - } - } - - //position counted from the left (highest value) from 0 to 7 - //remember: 1 is white, 0 is black - pub(crate) fn is_drawable_pixel(input: u8, pos: u8) -> bool { - ((input >> (7 - pos)) & 1u8) > 0u8 - } - - //TODO: does basically the same as get_color, so remove one of them? - pub(crate) fn convert_color(input: u8, pos: u8, foreground_color: &Color) -> Color { - //match color: - // - white for "nothing to draw"/background drawing - // - black for pixel to draw - // - //foreground color is the color you want to have in the foreground - if Color::is_drawable_pixel(input, pos) { - Color::normal_color(foreground_color) - } else { - Color::inverse_color(foreground_color) - } - } } #[cfg(feature = "graphics")] diff --git a/src/drawing_old/font.rs b/src/drawing_old/font.rs deleted file mode 100644 index a63bf37..0000000 --- a/src/drawing_old/font.rs +++ /dev/null @@ -1,759 +0,0 @@ -//width must be multiple of 8 -// -//chars are build in the bitmap like this example of a width 16, height 2 font: -//12 -//34 -// first char is the first ascii letter you want -#[allow(dead_code)] -pub struct Font<'a> { - width: u8, - height: u8, - first_char: u8, - last_char: u8, - bitmap: &'a [u8], - widthmap: &'a [u8], -} - -impl<'a> Font<'a> { - /// Panics if either Bitmap or Widthmap of the Font are to small for the amount and size of chars - pub fn new( - width: u8, - height: u8, - first_char: u8, - last_char: u8, - bitmap: &'a [u8], - widthmap: &'a [u8], - ) -> Font<'a> { - //Assertion so it shouldn't be able to panic later - let length_of_char = width as usize / 8 * height as usize; - let amount_of_chars = last_char as usize - first_char as usize + 1; - assert!(bitmap.len() >= amount_of_chars * length_of_char); - assert!(widthmap.len() >= amount_of_chars); - - Font { - width, - height, - first_char, - last_char, - bitmap, - widthmap, - } - } - - fn get_length_of_char(&self) -> usize { - self.width as usize / 8 * self.height as usize - } - - fn get_char_pos(&self, input: char) -> usize { - (input as usize - self.first_char as usize) - } - - /// Can panic, when end_pos > bitmap.len, should be caught in Font::new already - pub(crate) fn get_char(&'a self, input: char) -> &'a [u8] { - let start_pos = self.get_char_pos(input) * self.get_length_of_char(); - let end_pos = start_pos + self.get_length_of_char(); - - &self.bitmap[start_pos..end_pos] - } - - /// Can panic, when get_char_pos > widthmap.len(), should be caught in Font::new already - pub(crate) fn get_char_width(&self, input: char) -> u8 { - self.widthmap[self.get_char_pos(input)] - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn fonts_test() { - // don#t draw this, as it's just a test and not thought for drawing - // because the bitmap has column-bytes here, which is not what we use - // and you will get not get what you expect on your eink-screen - // but that doesn't change the "value" of the test - let bitmap = [ - 0x00, 0x00, 0x5F, 0x00, 0x00, 0x00, 0x00, 0x00, // '!' - 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, // '"' - 0x14, 0x7F, 0x14, 0x7F, 0x14, 0x00, 0x00, 0x00, // '#' - 0x14, 0x7F, 0x14, 0x7F, 0x14, 0x00, 0x00, 0x00, // '$' - ]; - - let widthmap = [8, 8, 8, 8]; - - let font = Font::new(8, 8, '!' as u8, '$' as u8, &bitmap, &widthmap); - - let hashtag = [0x14, 0x7F, 0x14, 0x7F, 0x14, 0x00, 0x00, 0x00]; - - assert_eq!(font.get_char('#'), hashtag); - - assert_eq!(font.get_char('$')[7], 0x00); - - assert_eq!(font.get_char_width('#'), widthmap[2]); - assert_eq!(font.get_char_width('$'), widthmap[3]); - } - - #[test] - fn bitmap_8x8_test() { - let and = [0x36, 0x49, 0x55, 0x22, 0x50, 0x00, 0x00, 0x00]; - let zero = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; - let first_value = [0x00, 0x00, 0x5F, 0x00, 0x00, 0x00, 0x00, 0x00]; - let last_value = [0x00, 0x41, 0x36, 0x08, 0x00, 0x00, 0x00, 0x00]; - - assert_eq!(bitmap_8x8('&'), and); - - assert_eq!(bitmap_8x8('ß'), zero); - assert_eq!(bitmap_8x8('°'), zero); - - assert_eq!(bitmap_8x8('!'), first_value); - assert_eq!(bitmap_8x8('}'), last_value); - - assert_eq!(bitmap_8x8('0')[1], 0x3E); - } -} - -//bad font as the order is not the one we want to use -//goes from bottom left -> up -> right -pub(crate) fn bitmap_8x8(input: char) -> [u8; 8] { - // Populate the array with the data from the character array at the right index - match input { - '!' => [0x00, 0x00, 0x5F, 0x00, 0x00, 0x00, 0x00, 0x00], - '"' => [0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00], - '#' => [0x14, 0x7F, 0x14, 0x7F, 0x14, 0x00, 0x00, 0x00], - '$' => [0x24, 0x2A, 0x7F, 0x2A, 0x12, 0x00, 0x00, 0x00], - '%' => [0x23, 0x13, 0x08, 0x64, 0x62, 0x00, 0x00, 0x00], - '&' => [0x36, 0x49, 0x55, 0x22, 0x50, 0x00, 0x00, 0x00], - '\'' => [0x00, 0x05, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00], - '(' => [0x00, 0x1C, 0x22, 0x41, 0x00, 0x00, 0x00, 0x00], - ')' => [0x00, 0x41, 0x22, 0x1C, 0x00, 0x00, 0x00, 0x00], - '*' => [0x08, 0x2A, 0x1C, 0x2A, 0x08, 0x00, 0x00, 0x00], - '+' => [0x08, 0x08, 0x3E, 0x08, 0x08, 0x00, 0x00, 0x00], - ',' => [0x00, 0x50, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00], - '-' => [0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00], - '.' => [0x00, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00], - '/' => [0x20, 0x10, 0x08, 0x04, 0x02, 0x00, 0x00, 0x00], - '0' => [0x1C, 0x3E, 0x61, 0x41, 0x43, 0x3E, 0x1C, 0x00], - '1' => [0x40, 0x42, 0x7F, 0x7F, 0x40, 0x40, 0x00, 0x00], - '2' => [0x62, 0x73, 0x79, 0x59, 0x5D, 0x4F, 0x46, 0x00], - '3' => [0x20, 0x61, 0x49, 0x4D, 0x4F, 0x7B, 0x31, 0x00], - '4' => [0x18, 0x1C, 0x16, 0x13, 0x7F, 0x7F, 0x10, 0x00], - '5' => [0x27, 0x67, 0x45, 0x45, 0x45, 0x7D, 0x38, 0x00], - '6' => [0x3C, 0x7E, 0x4B, 0x49, 0x49, 0x79, 0x30, 0x00], - '7' => [0x03, 0x03, 0x71, 0x79, 0x0D, 0x07, 0x03, 0x00], - '8' => [0x36, 0x7F, 0x49, 0x49, 0x49, 0x7F, 0x36, 0x00], - '9' => [0x06, 0x4F, 0x49, 0x49, 0x69, 0x3F, 0x1E, 0x00], - ':' => [0x00, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00], - ';' => [0x00, 0x56, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00], - '<' => [0x00, 0x08, 0x14, 0x22, 0x41, 0x00, 0x00, 0x00], - '=' => [0x14, 0x14, 0x14, 0x14, 0x14, 0x00, 0x00, 0x00], - '>' => [0x41, 0x22, 0x14, 0x08, 0x00, 0x00, 0x00, 0x00], - '?' => [0x02, 0x01, 0x51, 0x09, 0x06, 0x00, 0x00, 0x00], - '@' => [0x32, 0x49, 0x79, 0x41, 0x3E, 0x00, 0x00, 0x00], - 'A' => [0x7E, 0x11, 0x11, 0x11, 0x7E, 0x00, 0x00, 0x00], - 'B' => [0x7F, 0x49, 0x49, 0x49, 0x36, 0x00, 0x00, 0x00], - 'C' => [0x3E, 0x41, 0x41, 0x41, 0x22, 0x00, 0x00, 0x00], - 'D' => [0x7F, 0x7F, 0x41, 0x41, 0x63, 0x3E, 0x1C, 0x00], - 'E' => [0x7F, 0x49, 0x49, 0x49, 0x41, 0x00, 0x00, 0x00], - 'F' => [0x7F, 0x09, 0x09, 0x01, 0x01, 0x00, 0x00, 0x00], - 'G' => [0x3E, 0x41, 0x41, 0x51, 0x32, 0x00, 0x00, 0x00], - 'H' => [0x7F, 0x08, 0x08, 0x08, 0x7F, 0x00, 0x00, 0x00], - 'I' => [0x00, 0x41, 0x7F, 0x41, 0x00, 0x00, 0x00, 0x00], - 'J' => [0x20, 0x40, 0x41, 0x3F, 0x01, 0x00, 0x00, 0x00], - 'K' => [0x7F, 0x08, 0x14, 0x22, 0x41, 0x00, 0x00, 0x00], - 'L' => [0x7F, 0x7F, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00], - 'M' => [0x7F, 0x02, 0x04, 0x02, 0x7F, 0x00, 0x00, 0x00], - 'N' => [0x7F, 0x04, 0x08, 0x10, 0x7F, 0x00, 0x00, 0x00], - 'O' => [0x3E, 0x7F, 0x41, 0x41, 0x41, 0x7F, 0x3E, 0x00], - 'P' => [0x7F, 0x09, 0x09, 0x09, 0x06, 0x00, 0x00, 0x00], - 'Q' => [0x3E, 0x41, 0x51, 0x21, 0x5E, 0x00, 0x00, 0x00], - 'R' => [0x7F, 0x7F, 0x11, 0x31, 0x79, 0x6F, 0x4E, 0x00], - 'S' => [0x46, 0x49, 0x49, 0x49, 0x31, 0x00, 0x00, 0x00], - 'T' => [0x01, 0x01, 0x7F, 0x01, 0x01, 0x00, 0x00, 0x00], - 'U' => [0x3F, 0x40, 0x40, 0x40, 0x3F, 0x00, 0x00, 0x00], - 'V' => [0x1F, 0x20, 0x40, 0x20, 0x1F, 0x00, 0x00, 0x00], - 'W' => [0x7F, 0x7F, 0x38, 0x1C, 0x38, 0x7F, 0x7F, 0x00], - 'X' => [0x63, 0x14, 0x08, 0x14, 0x63, 0x00, 0x00, 0x00], - 'Y' => [0x03, 0x04, 0x78, 0x04, 0x03, 0x00, 0x00, 0x00], - 'Z' => [0x61, 0x51, 0x49, 0x45, 0x43, 0x00, 0x00, 0x00], - '[' => [0x00, 0x00, 0x7F, 0x41, 0x41, 0x00, 0x00, 0x00], - '\\' => [0x02, 0x04, 0x08, 0x10, 0x20, 0x00, 0x00, 0x00], - ']' => [0x41, 0x41, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00], - '^' => [0x04, 0x02, 0x01, 0x02, 0x04, 0x00, 0x00, 0x00], - '_' => [0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00], - '`' => [0x00, 0x01, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00], - 'a' => [0x20, 0x54, 0x54, 0x54, 0x78, 0x00, 0x00, 0x00], - 'b' => [0x7F, 0x48, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00], - 'c' => [0x38, 0x44, 0x44, 0x44, 0x20, 0x00, 0x00, 0x00], - 'd' => [0x38, 0x44, 0x44, 0x48, 0x7F, 0x00, 0x00, 0x00], - 'e' => [0x38, 0x54, 0x54, 0x54, 0x18, 0x00, 0x00, 0x00], - 'f' => [0x08, 0x7E, 0x09, 0x01, 0x02, 0x00, 0x00, 0x00], - 'g' => [0x08, 0x14, 0x54, 0x54, 0x3C, 0x00, 0x00, 0x00], - 'h' => [0x7F, 0x08, 0x04, 0x04, 0x78, 0x00, 0x00, 0x00], - 'i' => [0x00, 0x44, 0x7D, 0x40, 0x00, 0x00, 0x00, 0x00], - 'j' => [0x20, 0x40, 0x44, 0x3D, 0x00, 0x00, 0x00, 0x00], - 'k' => [0x00, 0x7F, 0x10, 0x28, 0x44, 0x00, 0x00, 0x00], - 'l' => [0x00, 0x41, 0x7F, 0x40, 0x00, 0x00, 0x00, 0x00], - 'm' => [0x7C, 0x04, 0x18, 0x04, 0x78, 0x00, 0x00, 0x00], - 'n' => [0x7C, 0x08, 0x04, 0x04, 0x78, 0x00, 0x00, 0x00], - 'o' => [0x38, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00], - 'p' => [0x7C, 0x14, 0x14, 0x14, 0x08, 0x00, 0x00, 0x00], - 'q' => [0x08, 0x14, 0x14, 0x18, 0x7C, 0x00, 0x00, 0x00], - 'r' => [0x7C, 0x08, 0x04, 0x04, 0x08, 0x00, 0x00, 0x00], - 's' => [0x48, 0x54, 0x54, 0x54, 0x20, 0x00, 0x00, 0x00], - 't' => [0x04, 0x3F, 0x44, 0x40, 0x20, 0x00, 0x00, 0x00], - 'u' => [0x3C, 0x40, 0x40, 0x20, 0x7C, 0x00, 0x00, 0x00], - 'v' => [0x1C, 0x20, 0x40, 0x20, 0x1C, 0x00, 0x00, 0x00], - 'w' => [0x3C, 0x40, 0x30, 0x40, 0x3C, 0x00, 0x00, 0x00], - 'x' => [0x00, 0x44, 0x28, 0x10, 0x28, 0x44, 0x00, 0x00], - 'y' => [0x0C, 0x50, 0x50, 0x50, 0x3C, 0x00, 0x00, 0x00], - 'z' => [0x44, 0x64, 0x54, 0x4C, 0x44, 0x00, 0x00, 0x00], - '{' => [0x00, 0x08, 0x36, 0x41, 0x00, 0x00, 0x00, 0x00], - '|' => [0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00], - '}' => [0x00, 0x41, 0x36, 0x08, 0x00, 0x00, 0x00, 0x00], - _ => [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], - } -} -/* -pub(crate) const VCR_OSD_MONO_Bitmap = [ -af afa 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, - 0xFF, 0xFF, 0xFC, 0x3F, 0xFC, 0x3F, 0xFC, 0x3F, 0xFC, 0x3F, 0xFC, 0x3F, - 0xFC, 0x3F, 0x30, 0x0C, 0x30, 0x0C, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x0F, - aaa 0x0F, 0x00, 0xF0, 0xF0, 0x0F, 0x0F, 0xF0, 0xF0, 0xFF, 0x0F, 0xFF, 0xF0, - 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xF0, 0xFF, 0x0F, 0x0F, 0xF0, 0xF0, - 0x0F, 0x0F, 0x00, 0xF0, 0xF0, 0x0F, 0x0F, 0xF0, 0xF0, 0xFF, 0x0F, 0xFF, - 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xF0, 0xFF, 0x0F, 0x0F, 0xF0, - 0xF0, 0x0F, 0x0F, 0x00, 0xF0, 0xF0, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x00, - 0xF0, 0x00, 0x0F, 0x00, 0x0F, 0xFF, 0x00, 0xFF, 0xF0, 0x3F, 0xFF, 0xC3, - 0xFF, 0xFC, 0xFC, 0xF3, 0xFF, 0xCF, 0x3F, 0xF0, 0xF0, 0xFF, 0x0F, 0x0F, - 0xFC, 0xF0, 0x0F, 0xCF, 0x00, 0x3F, 0xFF, 0x03, 0xFF, 0xF0, 0x0F, 0xFF, - 0xC0, 0xFF, 0xFC, 0x00, 0xF3, 0xF0, 0x0F, 0x3F, 0xF0, 0xF0, 0xFF, 0x0F, - 0x0F, 0xFC, 0xF3, 0xFF, 0xCF, 0x3F, 0x3F, 0xFF, 0xC3, 0xFF, 0xFC, 0x0F, - 0xFF, 0x00, 0xFF, 0xF0, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x3F, 0x00, 0xF3, - 0xF0, 0x0F, 0xFF, 0xC0, 0xFF, 0xFC, 0x0F, 0xF3, 0xC0, 0xFF, 0x3C, 0x0F, - 0xF3, 0xC3, 0xFF, 0x3C, 0x3F, 0xFF, 0xCF, 0xCF, 0xFC, 0xFC, 0x3F, 0x3F, - 0x03, 0xF3, 0xF0, 0x00, 0xFC, 0x00, 0x0F, 0xC0, 0x03, 0xF0, 0x00, 0x3F, - 0x00, 0x0F, 0xCF, 0xC0, 0xFC, 0xFC, 0x3F, 0x3F, 0xF3, 0xF3, 0xFF, 0xFC, - 0x3C, 0xFF, 0xC3, 0xCF, 0xF0, 0x3C, 0xFF, 0x03, 0xCF, 0xF0, 0x3F, 0xFF, - 0x03, 0xFF, 0xF0, 0x0F, 0xCF, 0x00, 0xFC, 0x03, 0xF0, 0x00, 0x3F, 0x00, - 0x0F, 0xFC, 0x00, 0xFF, 0xC0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, - 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, - 0xF0, 0x0F, 0x3C, 0x00, 0xF3, 0xC0, 0x0F, 0xFC, 0x00, 0xFF, 0xC0, 0x3F, - 0xF0, 0x03, 0xFF, 0x00, 0xFF, 0xF0, 0x0F, 0xFF, 0x00, 0xF0, 0xFC, 0xFF, - 0x0F, 0xCF, 0xF0, 0x3F, 0xFF, 0x03, 0xFF, 0xF0, 0x0F, 0xCF, 0x00, 0xFC, - 0xFC, 0x0F, 0xCF, 0xC0, 0xFC, 0x3F, 0xFF, 0xF3, 0xFF, 0xFF, 0x0F, 0xFC, - 0xF0, 0xFF, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF3, 0x0C, 0x03, 0xC0, 0xF0, - 0xF0, 0x3C, 0x3C, 0x0F, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, - 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, - 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x03, 0xC0, 0xF0, 0x0F, 0x03, 0xC0, 0x3C, - 0x0F, 0xF0, 0x3C, 0x03, 0xC0, 0xF0, 0x0F, 0x03, 0xC0, 0x3C, 0x0F, 0x03, - 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, - 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0xF0, 0x3C, - 0x3C, 0x0F, 0x0F, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0xC3, 0xC3, 0xC3, - 0xC3, 0xF3, 0xCF, 0xF3, 0xCF, 0x3F, 0xFC, 0x3F, 0xFC, 0x0F, 0xF0, 0x0F, - 0xF0, 0x3F, 0xFC, 0x3F, 0xFC, 0xF3, 0xCF, 0xF3, 0xCF, 0xC3, 0xC3, 0xC3, - 0xC3, 0x03, 0xC0, 0x03, 0xC0, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, - 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, - 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, - 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, - 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x0F, 0x0F, 0x0F, 0x0F, 0x3C, - 0x3C, 0xF0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, - 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x03, 0xF0, 0x00, 0x3F, 0x00, 0x0F, 0xC0, - 0x00, 0xFC, 0x00, 0x3F, 0x00, 0x03, 0xF0, 0x00, 0xFC, 0x00, 0x0F, 0xC0, - 0x03, 0xF0, 0x00, 0x3F, 0x00, 0x0F, 0xC0, 0x00, 0xFC, 0x00, 0x3F, 0x00, - 0x03, 0xF0, 0x00, 0xFC, 0x00, 0x0F, 0xC0, 0x00, 0xF0, 0x00, 0x0F, 0x00, - 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0x0F, - 0xFF, 0x00, 0xFF, 0xF0, 0x3F, 0xFF, 0xC3, 0xFF, 0xFC, 0xFC, 0x03, 0xFF, - 0xC0, 0x3F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x0F, 0xFF, 0x00, 0xFF, - 0xF0, 0x3F, 0xFF, 0x03, 0xFF, 0xF0, 0xFC, 0xFF, 0x0F, 0xCF, 0xF3, 0xF0, - 0xFF, 0x3F, 0x0F, 0xFF, 0xC0, 0xFF, 0xFC, 0x0F, 0xFF, 0x00, 0xFF, 0xF0, - 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xFC, 0x03, 0xFF, 0xC0, 0x3F, 0x3F, - 0xFF, 0xC3, 0xFF, 0xFC, 0x0F, 0xFF, 0x00, 0xFF, 0xF0, 0x0F, 0x00, 0xF0, - 0x3F, 0x03, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0x0F, 0x00, 0xF0, - 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, - 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0x00, 0xFF, 0xF0, 0x3F, 0xFF, 0xC3, 0xFF, - 0xFC, 0xFC, 0x03, 0xFF, 0xC0, 0x3F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0x00, - 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x03, 0xF0, 0x00, 0x3F, 0x0F, 0xFF, 0xC0, - 0xFF, 0xFC, 0x3F, 0xFF, 0x03, 0xFF, 0xF0, 0xFC, 0x00, 0x0F, 0xC0, 0x00, - 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, - 0x0F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0x0F, 0xFF, 0x00, 0xFF, 0xF0, 0x3F, 0xFF, 0xC3, 0xFF, 0xFC, 0xFC, - 0x03, 0xFF, 0xC0, 0x3F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0x00, 0x00, 0xF0, - 0x00, 0x0F, 0x00, 0x03, 0xF0, 0x00, 0x3F, 0x00, 0xFF, 0xC0, 0x0F, 0xFC, - 0x00, 0xFF, 0xC0, 0x0F, 0xFC, 0x00, 0x03, 0xF0, 0x00, 0x3F, 0x00, 0x00, - 0xF0, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xFC, 0x03, 0xFF, 0xC0, - 0x3F, 0x3F, 0xFF, 0xC3, 0xFF, 0xFC, 0x0F, 0xFF, 0x00, 0xFF, 0xF0, 0x00, - 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x3F, 0x00, 0x03, 0xF0, 0x00, 0xFF, 0x00, - 0x0F, 0xF0, 0x03, 0xFF, 0x00, 0x3F, 0xF0, 0x0F, 0xCF, 0x00, 0xFC, 0xF0, - 0x3F, 0x0F, 0x03, 0xF0, 0xF0, 0xFC, 0x0F, 0x0F, 0xC0, 0xF0, 0xF0, 0x0F, - 0x0F, 0x00, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, - 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x0F, 0x00, 0x00, - 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xFF, 0xFF, 0x0F, 0xFF, 0xF0, 0xFF, 0xFF, - 0xCF, 0xFF, 0xFC, 0x00, 0x03, 0xF0, 0x00, 0x3F, 0x00, 0x00, 0xF0, 0x00, - 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0xF0, - 0x00, 0xFF, 0x00, 0x0F, 0xFC, 0x03, 0xFF, 0xC0, 0x3F, 0x3F, 0xFF, 0xC3, - 0xFF, 0xFC, 0x0F, 0xFF, 0x00, 0xFF, 0xF0, 0x0F, 0xFF, 0x00, 0xFF, 0xF0, - 0x3F, 0xFF, 0xC3, 0xFF, 0xFC, 0xFC, 0x03, 0xFF, 0xC0, 0x3F, 0xF0, 0x00, - 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, - 0x00, 0xFF, 0xFF, 0x0F, 0xFF, 0xF0, 0xFF, 0xFF, 0xCF, 0xFF, 0xFC, 0xF0, - 0x03, 0xFF, 0x00, 0x3F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, - 0x00, 0x0F, 0xFC, 0x03, 0xFF, 0xC0, 0x3F, 0x3F, 0xFF, 0xC3, 0xFF, 0xFC, - 0x0F, 0xFF, 0x00, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, - 0x0F, 0x00, 0x03, 0xF0, 0x00, 0x3F, 0x00, 0x0F, 0xC0, 0x00, 0xFC, 0x00, - 0x3F, 0x00, 0x03, 0xF0, 0x00, 0xFC, 0x00, 0x0F, 0xC0, 0x00, 0xF0, 0x00, - 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, - 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, - 0x00, 0x0F, 0x00, 0x0F, 0xFF, 0x00, 0xFF, 0xF0, 0x3F, 0xFF, 0xC3, 0xFF, - 0xFC, 0xFC, 0x03, 0xFF, 0xC0, 0x3F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, - 0x00, 0xFF, 0x00, 0x0F, 0xFC, 0x03, 0xFF, 0xC0, 0x3F, 0x3F, 0xFF, 0xC3, - 0xFF, 0xFC, 0x3F, 0xFF, 0xC3, 0xFF, 0xFC, 0xFC, 0x03, 0xFF, 0xC0, 0x3F, - 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xFC, 0x03, - 0xFF, 0xC0, 0x3F, 0x3F, 0xFF, 0xC3, 0xFF, 0xFC, 0x0F, 0xFF, 0x00, 0xFF, - 0xF0, 0x0F, 0xFF, 0x00, 0xFF, 0xF0, 0x3F, 0xFF, 0xC3, 0xFF, 0xFC, 0xFC, - 0x03, 0xFF, 0xC0, 0x3F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, - 0x00, 0x0F, 0xFC, 0x00, 0xFF, 0xC0, 0x0F, 0x3F, 0xFF, 0xF3, 0xFF, 0xFF, - 0x0F, 0xFF, 0xF0, 0xFF, 0xFF, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, - 0xF0, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xFC, 0x03, 0xFF, 0xC0, - 0x3F, 0x3F, 0xFF, 0xC3, 0xFF, 0xFC, 0x0F, 0xFF, 0x00, 0xFF, 0xF0, 0xFF, - 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x0F, 0x0F, 0x0F, 0x0F, 0x3C, 0x3C, 0xF0, 0xF0, 0x00, 0x0F, 0x00, - 0x0F, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0xFC, 0x00, 0xFC, 0x03, 0xF0, 0x03, - 0xF0, 0x0F, 0xC0, 0x0F, 0xC0, 0x3F, 0x00, 0x3F, 0x00, 0xFC, 0x00, 0xFC, - 0x00, 0xF0, 0x00, 0xF0, 0x00, 0xFC, 0x00, 0xFC, 0x00, 0x3F, 0x00, 0x3F, - 0x00, 0x0F, 0xC0, 0x0F, 0xC0, 0x03, 0xF0, 0x03, 0xF0, 0x00, 0xFC, 0x00, - 0xFC, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x0F, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xF0, 0x00, 0xFC, 0x00, 0xFC, 0x00, 0x3F, - 0x00, 0x3F, 0x00, 0x0F, 0xC0, 0x0F, 0xC0, 0x03, 0xF0, 0x03, 0xF0, 0x00, - 0xFC, 0x00, 0xFC, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x0F, 0x00, 0x0F, 0x00, - 0x3F, 0x00, 0x3F, 0x00, 0xFC, 0x00, 0xFC, 0x03, 0xF0, 0x03, 0xF0, 0x0F, - 0xC0, 0x0F, 0xC0, 0x3F, 0x00, 0x3F, 0x00, 0xFC, 0x00, 0xFC, 0x00, 0xF0, - 0x00, 0xF0, 0x00, 0x0F, 0xFF, 0x00, 0xFF, 0xF0, 0x3F, 0xFF, 0xC3, 0xFF, - 0xFC, 0xFC, 0x03, 0xFF, 0xC0, 0x3F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0x00, - 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x03, 0xF0, 0x00, 0x3F, 0x00, 0x0F, 0xC0, - 0x00, 0xFC, 0x00, 0x3F, 0x00, 0x03, 0xF0, 0x00, 0xFC, 0x00, 0x0F, 0xC0, - 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, - 0x00, 0x0F, 0xFF, 0x00, 0xFF, 0xF0, 0x3C, 0x03, 0xC3, 0xC0, 0x3C, 0xF0, - 0x00, 0xFF, 0x00, 0x0F, 0xC3, 0xCC, 0x3C, 0x3C, 0xC3, 0xCF, 0x3C, 0x3C, - 0xF3, 0xC3, 0xCF, 0x3C, 0x3C, 0xF3, 0xC3, 0xCF, 0x3C, 0x3C, 0xF3, 0xC3, - 0xCF, 0x3C, 0xFC, 0xF3, 0xCF, 0xC3, 0xF3, 0xCC, 0x3F, 0x3C, 0xF0, 0x00, - 0x0F, 0x00, 0x00, 0x3C, 0x03, 0xC3, 0xC0, 0x3C, 0x0F, 0xFF, 0x00, 0xFF, - 0xF0, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x03, 0xFC, 0x00, 0x3F, 0xC0, 0x0F, - 0xFF, 0x00, 0xFF, 0xF0, 0x3F, 0x0F, 0xC3, 0xF0, 0xFC, 0xFC, 0x03, 0xFF, - 0xC0, 0x3F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, - 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, - 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xFF, - 0xFF, 0x0F, 0xFF, 0xF0, 0xFF, 0xFF, 0xCF, 0xFF, 0xFC, 0xF0, 0x03, 0xFF, - 0x00, 0x3F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, - 0xF0, 0x03, 0xFF, 0x00, 0x3F, 0xFF, 0xFF, 0xCF, 0xFF, 0xFC, 0xFF, 0xFF, - 0xCF, 0xFF, 0xFC, 0xF0, 0x03, 0xFF, 0x00, 0x3F, 0xF0, 0x00, 0xFF, 0x00, - 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x03, 0xFF, 0x00, 0x3F, 0xFF, - 0xFF, 0xCF, 0xFF, 0xFC, 0xFF, 0xFF, 0x0F, 0xFF, 0xF0, 0x0F, 0xFF, 0x00, - 0xFF, 0xF0, 0x3F, 0xFF, 0xC3, 0xFF, 0xFC, 0xFC, 0x03, 0xFF, 0xC0, 0x3F, - 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, - 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, - 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, - 0x00, 0xFF, 0x00, 0x0F, 0xFC, 0x03, 0xFF, 0xC0, 0x3F, 0x3F, 0xFF, 0xC3, - 0xFF, 0xFC, 0x0F, 0xFF, 0x00, 0xFF, 0xF0, 0xFF, 0xFF, 0x0F, 0xFF, 0xF0, - 0xFF, 0xFF, 0xCF, 0xFF, 0xFC, 0xF0, 0x03, 0xFF, 0x00, 0x3F, 0xF0, 0x00, - 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, - 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, - 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, - 0x00, 0x0F, 0xF0, 0x03, 0xFF, 0x00, 0x3F, 0xFF, 0xFF, 0xCF, 0xFF, 0xFC, - 0xFF, 0xFF, 0x0F, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, - 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xFF, - 0xFF, 0x0F, 0xFF, 0xF0, 0xFF, 0xFF, 0x0F, 0xFF, 0xF0, 0xF0, 0x00, 0x0F, - 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, - 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, - 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xFF, 0xFF, 0x0F, - 0xFF, 0xF0, 0xFF, 0xFF, 0x0F, 0xFF, 0xF0, 0xF0, 0x00, 0x0F, 0x00, 0x00, - 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, - 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, - 0x00, 0x0F, 0xFF, 0x00, 0xFF, 0xF0, 0x3F, 0xFF, 0xC3, 0xFF, 0xFC, 0xFC, - 0x03, 0xFF, 0xC0, 0x3F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0x0F, - 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x3F, 0xFF, 0x03, 0xFF, - 0xF0, 0x3F, 0xFF, 0x03, 0xFF, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, - 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xFC, 0x03, 0xFF, 0xC0, - 0x3F, 0x3F, 0xFF, 0xC3, 0xFF, 0xFC, 0x0F, 0xFF, 0x00, 0xFF, 0xF0, 0xF0, - 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, - 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, - 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, - 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, - 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, - 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, - 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xF0, 0x0F, 0xFF, 0x00, 0xFF, 0xF0, 0x0F, - 0xFF, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, - 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, - 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, - 0x00, 0x0F, 0x00, 0x00, 0xF0, 0xF0, 0x0F, 0x0F, 0x00, 0xF0, 0xFC, 0x3F, - 0x0F, 0xC3, 0xF0, 0x3F, 0xFC, 0x03, 0xFF, 0xC0, 0x0F, 0xF0, 0x00, 0xFF, - 0x00, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x03, 0xFF, 0x00, 0x3F, 0xF0, - 0x0F, 0xCF, 0x00, 0xFC, 0xF0, 0x3F, 0x0F, 0x03, 0xF0, 0xF0, 0xFC, 0x0F, - 0x0F, 0xC0, 0xF3, 0xF0, 0x0F, 0x3F, 0x00, 0xFF, 0xC0, 0x0F, 0xFC, 0x00, - 0xFF, 0xC0, 0x0F, 0xFC, 0x00, 0xF3, 0xF0, 0x0F, 0x3F, 0x00, 0xF0, 0xFC, - 0x0F, 0x0F, 0xC0, 0xF0, 0x3F, 0x0F, 0x03, 0xF0, 0xF0, 0x0F, 0xCF, 0x00, - 0xFC, 0xF0, 0x03, 0xFF, 0x00, 0x3F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, - 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, - 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, - 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, - 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, - 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, - 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xFC, 0x03, 0xFF, 0xC0, 0x3F, - 0xFF, 0x0F, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF3, 0xFC, - 0xFF, 0x3F, 0xCF, 0xF0, 0xF0, 0xFF, 0x0F, 0x0F, 0xF0, 0xF0, 0xFF, 0x0F, - 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, - 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, - 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, - 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xFC, 0x00, - 0xFF, 0xC0, 0x0F, 0xFF, 0x00, 0xFF, 0xF0, 0x0F, 0xFF, 0xC0, 0xFF, 0xFC, - 0x0F, 0xF3, 0xF0, 0xFF, 0x3F, 0x0F, 0xF0, 0xFC, 0xFF, 0x0F, 0xCF, 0xF0, - 0x3F, 0xFF, 0x03, 0xFF, 0xF0, 0x0F, 0xFF, 0x00, 0xFF, 0xF0, 0x03, 0xFF, - 0x00, 0x3F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, - 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0x0F, 0xFF, 0x00, 0xFF, 0xF0, 0x3F, 0xFF, - 0xC3, 0xFF, 0xFC, 0xFC, 0x03, 0xFF, 0xC0, 0x3F, 0xF0, 0x00, 0xFF, 0x00, - 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, - 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, - 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, - 0xFC, 0x03, 0xFF, 0xC0, 0x3F, 0x3F, 0xFF, 0xC3, 0xFF, 0xFC, 0x0F, 0xFF, - 0x00, 0xFF, 0xF0, 0xFF, 0xFF, 0x0F, 0xFF, 0xF0, 0xFF, 0xFF, 0xCF, 0xFF, - 0xFC, 0xF0, 0x03, 0xFF, 0x00, 0x3F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, - 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x03, 0xFF, 0x00, 0x3F, 0xFF, 0xFF, 0xCF, - 0xFF, 0xFC, 0xFF, 0xFF, 0x0F, 0xFF, 0xF0, 0xF0, 0x00, 0x0F, 0x00, 0x00, - 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, - 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, - 0x00, 0x0F, 0xFF, 0x00, 0xFF, 0xF0, 0x3F, 0xFF, 0xC3, 0xFF, 0xFC, 0xFC, - 0x03, 0xFF, 0xC0, 0x3F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, - 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, - 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0xF0, 0xFF, 0x0F, 0x0F, 0xF0, 0xFC, - 0xFF, 0x0F, 0xCF, 0xF0, 0x3F, 0xFF, 0x03, 0xFF, 0xFC, 0x0F, 0xCF, 0xC0, - 0xFC, 0x3F, 0xFF, 0xF3, 0xFF, 0xFF, 0x0F, 0xF0, 0xF0, 0xFF, 0x0F, 0xFF, - 0xFF, 0x0F, 0xFF, 0xF0, 0xFF, 0xFF, 0xCF, 0xFF, 0xFC, 0xF0, 0x03, 0xFF, - 0x00, 0x3F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, - 0xF0, 0x03, 0xFF, 0x00, 0x3F, 0xFF, 0xFF, 0xCF, 0xFF, 0xFC, 0xFF, 0xFF, - 0x0F, 0xFF, 0xF0, 0xF3, 0xF0, 0x0F, 0x3F, 0x00, 0xF0, 0xFC, 0x0F, 0x0F, - 0xC0, 0xF0, 0x3F, 0x0F, 0x03, 0xF0, 0xF0, 0x0F, 0xCF, 0x00, 0xFC, 0xF0, - 0x03, 0xFF, 0x00, 0x3F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0x0F, 0xFF, 0x00, - 0xFF, 0xF0, 0x3F, 0xFF, 0xC3, 0xFF, 0xFC, 0xFC, 0x03, 0xFF, 0xC0, 0x3F, - 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xFC, 0x00, - 0x0F, 0xC0, 0x00, 0x3F, 0xFF, 0x03, 0xFF, 0xF0, 0x0F, 0xFF, 0xC0, 0xFF, - 0xFC, 0x00, 0x03, 0xF0, 0x00, 0x3F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0xF0, - 0x00, 0xFF, 0x00, 0x0F, 0xFC, 0x03, 0xFF, 0xC0, 0x3F, 0x3F, 0xFF, 0xC3, - 0xFF, 0xFC, 0x0F, 0xFF, 0x00, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, - 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, - 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, - 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, - 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, - 0x00, 0xF0, 0x00, 0x0F, 0x00, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, - 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, - 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, - 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, - 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, - 0xFC, 0x03, 0xFF, 0xC0, 0x3F, 0x3F, 0xFF, 0xC3, 0xFF, 0xFC, 0x0F, 0xFF, - 0x00, 0xFF, 0xF0, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, - 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, - 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, - 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, - 0xFC, 0x03, 0xFF, 0xC0, 0x3F, 0x3F, 0x0F, 0xC3, 0xF0, 0xFC, 0x0F, 0xFF, - 0x00, 0xFF, 0xF0, 0x03, 0xFC, 0x00, 0x3F, 0xC0, 0x00, 0xF0, 0x00, 0x0F, - 0x00, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, - 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, - 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0xF0, 0xFF, 0x0F, 0x0F, - 0xF0, 0xF0, 0xFF, 0x0F, 0x0F, 0xF0, 0xF0, 0xFF, 0x0F, 0x0F, 0xF0, 0xF0, - 0xFF, 0x0F, 0x0F, 0xF0, 0xF0, 0xFF, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0x3F, 0xFF, 0xC3, 0xFF, 0xFC, 0x0F, 0x0F, 0x00, 0xF0, 0xF0, 0xF0, - 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, - 0x00, 0x0F, 0xFC, 0x03, 0xFF, 0xC0, 0x3F, 0x3F, 0x0F, 0xC3, 0xF0, 0xFC, - 0x0F, 0xFF, 0x00, 0xFF, 0xF0, 0x03, 0xFC, 0x00, 0x3F, 0xC0, 0x03, 0xFC, - 0x00, 0x3F, 0xC0, 0x0F, 0xFF, 0x00, 0xFF, 0xF0, 0x3F, 0x0F, 0xC3, 0xF0, - 0xFC, 0xFC, 0x03, 0xFF, 0xC0, 0x3F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, - 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, - 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, - 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xFC, 0x03, - 0xFF, 0xC0, 0x3F, 0x3F, 0x0F, 0xC3, 0xF0, 0xFC, 0x0F, 0xFF, 0x00, 0xFF, - 0xF0, 0x03, 0xFC, 0x00, 0x3F, 0xC0, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, - 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, - 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x03, - 0xF0, 0x00, 0x3F, 0x00, 0x0F, 0xC0, 0x00, 0xFC, 0x00, 0x3F, 0x00, 0x03, - 0xF0, 0x00, 0xFC, 0x00, 0x0F, 0xC0, 0x03, 0xF0, 0x00, 0x3F, 0x00, 0x0F, - 0xC0, 0x00, 0xFC, 0x00, 0x3F, 0x00, 0x03, 0xF0, 0x00, 0xFC, 0x00, 0x0F, - 0xC0, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, - 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, - 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, - 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, - 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xFC, 0x00, 0x0F, 0xC0, - 0x00, 0x3F, 0x00, 0x03, 0xF0, 0x00, 0x0F, 0xC0, 0x00, 0xFC, 0x00, 0x03, - 0xF0, 0x00, 0x3F, 0x00, 0x00, 0xFC, 0x00, 0x0F, 0xC0, 0x00, 0x3F, 0x00, - 0x03, 0xF0, 0x00, 0x0F, 0xC0, 0x00, 0xFC, 0x00, 0x03, 0xF0, 0x00, 0x3F, - 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, - 0xF0, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xF0, 0x0F, - 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, - 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, - 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x03, 0xFC, 0x00, 0x3F, - 0xC0, 0x0F, 0xFF, 0x00, 0xFF, 0xF0, 0x3F, 0x0F, 0xC3, 0xF0, 0xFC, 0xFC, - 0x03, 0xFF, 0xC0, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x3F, 0x03, 0xF0, 0xFC, 0x03, 0xC0, 0xF0, - 0x0F, 0xFF, 0x00, 0xFF, 0xF0, 0x0F, 0xFF, 0xC0, 0xFF, 0xFC, 0x00, 0x03, - 0xF0, 0x00, 0x3F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x0F, 0xFC, 0xF0, 0xFF, - 0xCF, 0x3F, 0xFF, 0xF3, 0xFF, 0xFF, 0xFC, 0x03, 0xFF, 0xC0, 0x3F, 0xF0, - 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xFC, 0x03, 0xFF, - 0xC0, 0x3F, 0x3F, 0xFF, 0xF3, 0xFF, 0xFF, 0x0F, 0xFC, 0xF0, 0xFF, 0xCF, - 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, - 0x0F, 0x00, 0x00, 0xF0, 0xFC, 0x0F, 0x0F, 0xC0, 0xF3, 0xFF, 0x0F, 0x3F, - 0xF0, 0xFF, 0xCF, 0xCF, 0xFC, 0xFC, 0xFF, 0x03, 0xFF, 0xF0, 0x3F, 0xFC, - 0x00, 0xFF, 0xC0, 0x0F, 0xFC, 0x00, 0xFF, 0xC0, 0x0F, 0xFC, 0x00, 0xFF, - 0xC0, 0x0F, 0xFF, 0x03, 0xFF, 0xF0, 0x3F, 0xFF, 0xCF, 0xCF, 0xFC, 0xFC, - 0xF3, 0xFF, 0x0F, 0x3F, 0xF0, 0xF0, 0xFC, 0x0F, 0x0F, 0xC0, 0x0F, 0xFF, - 0x00, 0xFF, 0xF0, 0x3F, 0xFF, 0xC3, 0xFF, 0xFC, 0xFC, 0x03, 0xFF, 0xC0, - 0x3F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, - 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0xFF, - 0x00, 0x0F, 0xFC, 0x03, 0xFF, 0xC0, 0x3F, 0x3F, 0xFF, 0xC3, 0xFF, 0xFC, - 0x0F, 0xFF, 0x00, 0xFF, 0xF0, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, - 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x03, 0xF0, 0xF0, 0x3F, - 0x0F, 0x0F, 0xFC, 0xF0, 0xFF, 0xCF, 0x3F, 0x3F, 0xF3, 0xF3, 0xFF, 0xFC, - 0x0F, 0xFF, 0xC0, 0xFF, 0xF0, 0x03, 0xFF, 0x00, 0x3F, 0xF0, 0x03, 0xFF, - 0x00, 0x3F, 0xF0, 0x03, 0xFF, 0x00, 0x3F, 0xFC, 0x0F, 0xFF, 0xC0, 0xFF, - 0x3F, 0x3F, 0xF3, 0xF3, 0xFF, 0x0F, 0xFC, 0xF0, 0xFF, 0xCF, 0x03, 0xF0, - 0xF0, 0x3F, 0x0F, 0x0F, 0xFF, 0x00, 0xFF, 0xF0, 0x3F, 0xFF, 0xC3, 0xFF, - 0xFC, 0xFC, 0x03, 0xFF, 0xC0, 0x3F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xFF, 0xFC, 0xF0, 0x00, 0x0F, - 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xFC, 0x03, 0xFF, 0xC0, 0x3F, - 0x3F, 0xFF, 0xC3, 0xFF, 0xFC, 0x0F, 0xFF, 0x00, 0xFF, 0xF0, 0x00, 0xFF, - 0x00, 0xFF, 0x03, 0xFF, 0x03, 0xFF, 0x03, 0xC0, 0x03, 0xC0, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, - 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, - 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, - 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x0F, 0xFF, 0x00, 0xFF, 0xF0, 0x3F, - 0xFF, 0xC3, 0xFF, 0xFC, 0xFC, 0x03, 0xFF, 0xC0, 0x3F, 0xF0, 0x00, 0xFF, - 0x00, 0x0F, 0xFC, 0x03, 0xFF, 0xC0, 0x3F, 0x3F, 0xFF, 0xF3, 0xFF, 0xFF, - 0x0F, 0xFC, 0xF0, 0xFF, 0xCF, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, - 0xF0, 0x00, 0x0F, 0x3C, 0x03, 0xF3, 0xC0, 0x3F, 0x3F, 0xFF, 0xC3, 0xFF, - 0xFC, 0x0F, 0xFF, 0x00, 0xFF, 0xF0, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, - 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0xFC, 0x0F, - 0x0F, 0xC0, 0xF3, 0xFF, 0x0F, 0x3F, 0xF0, 0xFF, 0xCF, 0xCF, 0xFC, 0xFC, - 0xFF, 0x03, 0xFF, 0xF0, 0x3F, 0xFC, 0x00, 0xFF, 0xC0, 0x0F, 0xF0, 0x00, - 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, - 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, - 0x00, 0xFF, 0x00, 0x0F, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0x0F, 0x00, - 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0xC0, - 0xFC, 0x03, 0xF0, 0x3F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, - 0xFF, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, - 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x03, 0xF0, 0x3F, 0xFF, 0xCF, - 0xFC, 0xFF, 0x0F, 0xF0, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, - 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0xFF, 0x00, 0x0F, - 0xF0, 0x03, 0xFF, 0x00, 0x3F, 0xF0, 0x0F, 0xCF, 0x00, 0xFC, 0xF0, 0x3F, - 0x0F, 0x03, 0xF0, 0xF0, 0xFC, 0x0F, 0x0F, 0xC0, 0xF3, 0xF0, 0x0F, 0x3F, - 0x00, 0xFF, 0xFC, 0x0F, 0xFF, 0xC0, 0xFF, 0x3F, 0x0F, 0xF3, 0xF0, 0xFC, - 0x0F, 0xCF, 0xC0, 0xFC, 0xF0, 0x03, 0xFF, 0x00, 0x3F, 0xF0, 0x00, 0xFF, - 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xF3, 0xFF, 0x0F, 0x3F, 0xF0, 0xFF, 0xFF, 0xCF, - 0xFF, 0xFC, 0xFC, 0xF3, 0xFF, 0xCF, 0x3F, 0xF0, 0xF0, 0xFF, 0x0F, 0x0F, - 0xF0, 0xF0, 0xFF, 0x0F, 0x0F, 0xF0, 0xF0, 0xFF, 0x0F, 0x0F, 0xF0, 0xF0, - 0xFF, 0x0F, 0x0F, 0xF0, 0xF0, 0xFF, 0x0F, 0x0F, 0xF0, 0xF0, 0xFF, 0x0F, - 0x0F, 0xF0, 0xF0, 0xFF, 0x0F, 0x0F, 0xF0, 0xF0, 0xFF, 0x0F, 0x0F, 0xF3, - 0xFF, 0x0F, 0x3F, 0xF0, 0xFF, 0xFF, 0xCF, 0xFF, 0xFC, 0xFC, 0x03, 0xFF, - 0xC0, 0x3F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, - 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, - 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, - 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0x0F, 0xFF, 0x00, 0xFF, 0xF0, 0x3F, - 0xFF, 0xC3, 0xFF, 0xFC, 0xFC, 0x03, 0xFF, 0xC0, 0x3F, 0xF0, 0x00, 0xFF, - 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, - 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xFC, 0x03, - 0xFF, 0xC0, 0x3F, 0x3F, 0xFF, 0xC3, 0xFF, 0xFC, 0x0F, 0xFF, 0x00, 0xFF, - 0xF0, 0xF3, 0xFF, 0x0F, 0x3F, 0xF0, 0xFF, 0xFF, 0xCF, 0xFF, 0xFC, 0xFF, - 0x03, 0xFF, 0xF0, 0x3F, 0xFC, 0x00, 0xFF, 0xC0, 0x0F, 0xFC, 0x00, 0xFF, - 0xC0, 0x0F, 0xFC, 0x00, 0xFF, 0xC0, 0x0F, 0xFF, 0x03, 0xFF, 0xF0, 0x3F, - 0xFF, 0xFF, 0xCF, 0xFF, 0xFC, 0xF3, 0xFF, 0x0F, 0x3F, 0xF0, 0xF0, 0x00, - 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, - 0x00, 0x0F, 0xFC, 0xF0, 0xFF, 0xCF, 0x3F, 0xFF, 0xF3, 0xFF, 0xFF, 0xFC, - 0x0F, 0xFF, 0xC0, 0xFF, 0xF0, 0x03, 0xFF, 0x00, 0x3F, 0xF0, 0x03, 0xFF, - 0x00, 0x3F, 0xF0, 0x03, 0xFF, 0x00, 0x3F, 0xFC, 0x0F, 0xFF, 0xC0, 0xFF, - 0x3F, 0xFF, 0xF3, 0xFF, 0xFF, 0x0F, 0xF3, 0xF0, 0xFF, 0x3F, 0x00, 0x00, - 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, - 0x0F, 0xF0, 0xFF, 0x0F, 0x0F, 0xF0, 0xF3, 0xFF, 0xCF, 0x3F, 0xFC, 0xFF, - 0xC3, 0xFF, 0xFC, 0x3F, 0xFF, 0x00, 0xFF, 0xF0, 0x0F, 0xFC, 0x00, 0x0F, - 0xC0, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, - 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, - 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0x0F, 0xFF, 0x00, 0xFF, - 0xF0, 0x3F, 0xFF, 0xC3, 0xFF, 0xFC, 0xFC, 0x03, 0xFF, 0xC0, 0x3F, 0xFC, - 0x00, 0xFF, 0xC0, 0x0F, 0x3F, 0xF0, 0x03, 0xFF, 0x00, 0x03, 0xFF, 0x00, - 0x3F, 0xF0, 0x00, 0x3F, 0xC0, 0x03, 0xFC, 0xF0, 0x03, 0xFF, 0x00, 0x3F, - 0xFC, 0x03, 0xFF, 0xC0, 0x3F, 0x3F, 0xFF, 0xC3, 0xFF, 0xFC, 0x0F, 0xFF, - 0x00, 0xFF, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, - 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, - 0x0F, 0xC0, 0xFC, 0x03, 0xF0, 0x3F, 0x00, 0xF0, 0x0F, 0xF0, 0x00, 0xFF, - 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, - 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, - 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, - 0x0F, 0xFC, 0x03, 0xFF, 0xC0, 0x3F, 0x3F, 0xFF, 0xC3, 0xFF, 0xFC, 0x0F, - 0xFF, 0x00, 0xFF, 0xF0, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, - 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, - 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xFC, 0x03, - 0xFF, 0xC0, 0x3F, 0x3F, 0x0F, 0xC3, 0xF0, 0xFC, 0x0F, 0xFF, 0x00, 0xFF, - 0xF0, 0x03, 0xFC, 0x00, 0x3F, 0xC0, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0xF0, - 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, - 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0xF0, 0xFF, 0x0F, 0x0F, - 0xF0, 0xF0, 0xFF, 0x0F, 0x0F, 0xF0, 0xF0, 0xFF, 0x0F, 0x0F, 0xF0, 0xF0, - 0xFF, 0x0F, 0x0F, 0xFC, 0xF3, 0xFF, 0xCF, 0x3F, 0x3F, 0xFF, 0xC3, 0xFF, - 0xFC, 0x0F, 0x0F, 0x00, 0xF0, 0xF0, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xFC, - 0x03, 0xFF, 0xC0, 0x3F, 0x3F, 0x0F, 0xC3, 0xF0, 0xFC, 0x0F, 0xFF, 0x00, - 0xFF, 0xF0, 0x03, 0xFC, 0x00, 0x3F, 0xC0, 0x00, 0xF0, 0x00, 0x0F, 0x00, - 0x03, 0xFC, 0x00, 0x3F, 0xC0, 0x0F, 0xFF, 0x00, 0xFF, 0xF0, 0x3F, 0x0F, - 0xC3, 0xF0, 0xFC, 0xFC, 0x03, 0xFF, 0xC0, 0x3F, 0xF0, 0x00, 0xFF, 0x00, - 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, - 0x03, 0xFF, 0x00, 0x3F, 0xF0, 0x03, 0xFF, 0x00, 0x3F, 0xF0, 0x0F, 0xFF, - 0x00, 0xFF, 0xFC, 0x3F, 0xFF, 0xC3, 0xFF, 0x3F, 0xFC, 0xF3, 0xFF, 0xCF, - 0x0F, 0xF0, 0xF0, 0xFF, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x03, - 0xF0, 0x00, 0x3F, 0x0F, 0xFF, 0xC0, 0xFF, 0xFC, 0x0F, 0xFF, 0x00, 0xFF, - 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, - 0x03, 0xF0, 0x00, 0x3F, 0x00, 0x0F, 0xC0, 0x00, 0xFC, 0x00, 0x3F, 0x00, - 0x03, 0xF0, 0x00, 0xFC, 0x00, 0x0F, 0xC0, 0x03, 0xF0, 0x00, 0x3F, 0x00, - 0x0F, 0xC0, 0x00, 0xFC, 0x00, 0x3F, 0x00, 0x03, 0xF0, 0x00, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xF0, 0x3F, 0x03, - 0xF0, 0x3F, 0x0F, 0xF0, 0xFF, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, - 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0xFC, 0x0F, 0xC0, 0xFC, 0x0F, 0xC0, 0x0F, - 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, - 0xF0, 0xFF, 0x03, 0xF0, 0x3F, 0x03, 0xF0, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFC, 0x0F, 0xC0, 0xFC, 0x0F, 0xC0, 0xFF, 0x0F, 0xF0, 0x0F, 0x00, 0xF0, - 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x03, 0xF0, 0x3F, - 0x03, 0xF0, 0x3F, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, - 0x0F, 0x00, 0xF0, 0xFF, 0x0F, 0xF0, 0xFC, 0x0F, 0xC0, 0xFC, 0x0F, 0xC0, - 0x0F, 0xC0, 0x30, 0xFC, 0x03, 0x3F, 0xF0, 0xF3, 0xFF, 0x0F, 0xF0, 0xFF, - 0xCF, 0x0F, 0xFC, 0xC0, 0x3F, 0x0C, 0x03, 0xF0 ]; - -// uint16_t bitmapOffset; // Pointer into GFXfont->bitmap -// uint8_t width, height; // Bitmap dimensions in pixels -// uint8_t xAdvance; // Distance to advance cursor (x axis) -//int8_t xOffset, yOffset; // Dist from cursor pos to UL corner -pub(crate) const VCR_OSD_MONO_Glyphs = [ //: [u8; 44] = [ - [ 0, 0, 0, 24, 0, 1 ], // 0x20 ' ' - [ 0, 4, 28, 24, 8, -29 ], // 0x21 '!' - [ 14, 16, 8, 24, 4, -29 ], // 0x22 '"' - [ 30, 20, 26, 24, 2, -29 ], // 0x23 '#' - [ 95, 20, 28, 24, 2, -29 ], // 0x24 '$' - [ 165, 20, 28, 24, 2, -29 ], // 0x25 '%' - [ 235, 20, 32, 24, 2, -33 ], // 0x26 '&' - [ 315, 6, 8, 24, 8, -29 ], // 0x27 ''' - [ 321, 10, 32, 24, 6, -33 ], // 0x28 '(' - [ 361, 10, 32, 24, 8, -33 ], // 0x29 ')' - [ 401, 16, 18, 24, 4, -31 ], // 0x2A '*' - [ 437, 20, 20, 24, 2, -25 ], // 0x2B '+' - [ 487, 8, 8, 24, 6, -9 ], // 0x2C ',' - [ 495, 16, 4, 24, 4, -17 ], // 0x2D '-' - [ 503, 4, 4, 24, 8, -5 ], // 0x2E '.' - [ 505, 20, 28, 24, 2, -29 ], // 0x2F '/' - [ 575, 20, 28, 24, 2, -29 ], // 0x30 '0' - [ 645, 12, 28, 24, 6, -29 ], // 0x31 '1' - [ 687, 20, 28, 24, 2, -29 ], // 0x32 '2' - [ 757, 20, 28, 24, 2, -29 ], // 0x33 '3' - [ 827, 20, 28, 24, 2, -29 ], // 0x34 '4' - [ 897, 20, 28, 24, 2, -29 ], // 0x35 '5' - [ 967, 20, 28, 24, 2, -29 ], // 0x36 '6' - [ 1037, 20, 28, 24, 2, -29 ], // 0x37 '7' - [ 1107, 20, 28, 24, 2, -29 ], // 0x38 '8' - [ 1177, 20, 28, 24, 2, -29 ], // 0x39 '9' - [ 1247, 4, 20, 24, 8, -25 ], // 0x3A ':' - [ 1257, 8, 24, 24, 4, -25 ], // 0x3B ';' - [ 1281, 16, 30, 24, 4, -31 ], // 0x3C '<' - [ 1341, 20, 12, 24, 2, -21 ], // 0x3D '=' - [ 1371, 16, 30, 24, 4, -31 ], // 0x3E '>' - [ 1431, 20, 28, 24, 2, -29 ], // 0x3F '?' - [ 1501, 20, 24, 24, 2, -27 ], // 0x40 '@' - [ 1561, 20, 28, 24, 2, -29 ], // 0x41 'A' - [ 1631, 20, 28, 24, 2, -29 ], // 0x42 'B' - [ 1701, 20, 28, 24, 2, -29 ], // 0x43 'C' - [ 1771, 20, 28, 24, 2, -29 ], // 0x44 'D' - [ 1841, 20, 28, 24, 2, -29 ], // 0x45 'E' - [ 1911, 20, 28, 24, 2, -29 ], // 0x46 'F' - [ 1981, 20, 28, 24, 2, -29 ], // 0x47 'G' - [ 2051, 20, 28, 24, 2, -29 ], // 0x48 'H' - [ 2121, 12, 28, 24, 6, -29 ], // 0x49 'I' - [ 2163, 20, 28, 24, 2, -29 ], // 0x4A 'J' - [ 2233, 20, 28, 24, 2, -29 ], // 0x4B 'K' - [ 2303, 20, 28, 24, 2, -29 ], // 0x4C 'L' - [ 2373, 20, 28, 24, 2, -29 ], // 0x4D 'M' - [ 2443, 20, 28, 24, 2, -29 ], // 0x4E 'N' - [ 2513, 20, 28, 24, 2, -29 ], // 0x4F 'O' - [ 2583, 20, 28, 24, 2, -29 ], // 0x50 'P' - [ 2653, 20, 28, 24, 2, -29 ], // 0x51 'Q' - [ 2723, 20, 28, 24, 2, -29 ], // 0x52 'R' - [ 2793, 20, 28, 24, 2, -29 ], // 0x53 'S' - [ 2863, 20, 28, 24, 2, -29 ], // 0x54 'T' - [ 2933, 20, 28, 24, 2, -29 ], // 0x55 'U' - [ 3003, 20, 28, 24, 2, -29 ], // 0x56 'V' - [ 3073, 20, 28, 24, 2, -29 ], // 0x57 'W' - [ 3143, 20, 28, 24, 2, -29 ], // 0x58 'X' - [ 3213, 20, 28, 24, 2, -29 ], // 0x59 'Y' - [ 3283, 20, 28, 24, 2, -29 ], // 0x5A 'Z' - [ 3353, 12, 32, 24, 8, -33 ], // 0x5B '[' - [ 3401, 20, 28, 24, 2, -29 ], // 0x5C '\' - [ 3471, 12, 32, 24, 4, -33 ], // 0x5D ']' - [ 3519, 20, 10, 24, 2, -29 ], // 0x5E '^' - [ 3544, 24, 4, 24, 0, -3 ], // 0x5F '_' - [ 3556, 10, 6, 24, 6, -29 ], // 0x60 '`' - [ 3564, 20, 24, 24, 2, -25 ], // 0x61 'a' - [ 3624, 20, 28, 24, 2, -29 ], // 0x62 'b' - [ 3694, 20, 22, 24, 2, -23 ], // 0x63 'c' - [ 3749, 20, 28, 24, 2, -29 ], // 0x64 'd' - [ 3819, 20, 22, 24, 2, -23 ], // 0x65 'e' - [ 3874, 16, 28, 24, 4, -29 ], // 0x66 'f' - [ 3930, 20, 24, 24, 2, -25 ], // 0x67 'g' - [ 3990, 20, 28, 24, 2, -29 ], // 0x68 'h' - [ 4060, 12, 26, 24, 6, -27 ], // 0x69 'i' - [ 4099, 12, 30, 24, 6, -31 ], // 0x6A 'j' - [ 4144, 20, 28, 24, 2, -29 ], // 0x6B 'k' - [ 4214, 4, 28, 24, 10, -29 ], // 0x6C 'l' - [ 4228, 20, 22, 24, 2, -23 ], // 0x6D 'm' - [ 4283, 20, 22, 24, 2, -23 ], // 0x6E 'n' - [ 4338, 20, 22, 24, 2, -23 ], // 0x6F 'o' - [ 4393, 20, 24, 24, 2, -25 ], // 0x70 'p' - [ 4453, 20, 24, 24, 2, -25 ], // 0x71 'q' - [ 4513, 20, 22, 24, 2, -23 ], // 0x72 'r' - [ 4568, 20, 22, 24, 2, -23 ], // 0x73 's' - [ 4623, 12, 28, 24, 6, -29 ], // 0x74 't' - [ 4665, 20, 22, 24, 2, -23 ], // 0x75 'u' - [ 4720, 20, 22, 24, 2, -23 ], // 0x76 'v' - [ 4775, 20, 22, 24, 2, -23 ], // 0x77 'w' - [ 4830, 20, 22, 24, 2, -23 ], // 0x78 'x' - [ 4885, 20, 24, 24, 2, -25 ], // 0x79 'y' - [ 4945, 20, 22, 24, 2, -23 ], // 0x7A 'z' - [ 5000, 12, 32, 24, 6, -33 ], // 0x7B '[' - [ 5048, 4, 32, 24, 10, -33 ], // 0x7C '|' - [ 5064, 12, 32, 24, 6, -33 ], // 0x7D ']' - [ 5112, 20, 8, 24, 2, -19 ] ]; // 0x7E '~' - - -*/ -/* -pub(crate) const LUT_VCOM0_QUICK: [u8; 44] = [ -0x00, 0x0E, 0x00, 0x00, 0x00, 0x01, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -];*/ diff --git a/src/drawing_old/mod.rs b/src/drawing_old/mod.rs deleted file mode 100644 index a9149b3..0000000 --- a/src/drawing_old/mod.rs +++ /dev/null @@ -1,622 +0,0 @@ -pub mod font; -use self::font::Font; - -use color::Color; - -#[derive(Clone, Copy)] -pub enum Displayorientation { - /// No rotation - Rotate0, - /// Rotate by 90 degrees clockwise - Rotate90, - /// Rotate by 180 degrees clockwise - Rotate180, - /// Rotate 270 degrees clockwise - Rotate270, -} - -//WARNING: Adapt for bigger sized displays! -// pub struct DisplayDescription { -// width: u16, -// height: u16, -// buffer_size: u16 -// } - -// impl Display_Description { -// pub fn new(width: u16, height: u16, buffer_size: u16) -> Display_Description { - -// } -// } - -pub enum Display { - Eink42BlackWhite, -} - -impl Display { - /// Gets the Dimensions of a dipslay in the following order: - /// - Width - /// - Height - /// - Neccessary Buffersize - pub fn get_dimensions(&self) -> (u16, u16, u16) { - match self { - Display::Eink42BlackWhite => (400, 300, 15000), - } - } -} - - -pub struct Graphics<'a> { - width: u16, - height: u16, - rotation: Displayorientation, - buffer: &'a mut [u8], //buffer: Box//[u8; 15000] -} - -impl<'a> Graphics<'a> { - /// width needs to be a multiple of 8! - pub fn new(width: u16, height: u16, buffer: &'a mut [u8]) -> Graphics<'a> { - let len = buffer.len(); - assert!(width / 8 * height >= len as u16); - Graphics { - width, - height, - rotation: Displayorientation::Rotate0, - buffer, - } - } - - /// Clears/Fills the full buffer with `color` - pub fn clear(&mut self, color: &Color) { - for elem in self.buffer.iter_mut() { - *elem = color.get_byte_value(); - } - } - - pub fn get_buffer(&'a self) -> &'a [u8] { - self.buffer - } - - /// Draw a single Pixel with `color` - /// - /// limited to i16::max images (buffer_size) at the moment - pub fn draw_pixel(&mut self, x: u16, y: u16, color: &Color) { - let (idx, bit) = match self.rotation { - Displayorientation::Rotate0 | Displayorientation::Rotate180 => ( - (x as usize / 8 + (self.width as usize / 8) * y as usize), - 0x80 >> (x % 8), - ), - Displayorientation::Rotate90 | Displayorientation::Rotate270 => ( - y as usize / 8 * self.width as usize + x as usize, - 0x80 >> (y % 8), - ), - }; - - if idx >= self.buffer.len() { - return; - } - - match color { - Color::Black => { - self.buffer[idx] &= !bit; - } - Color::White => { - self.buffer[idx] |= bit; - } - } - } - - /// Draw a single Pixel with `color` - /// - /// limited to i16::max images (buffer_size) at the moment - #[allow(dead_code)] - fn draw_byte(&mut self, x: u16, y: u16, filling: u8, color: &Color) { - let idx = match self.rotation { - Displayorientation::Rotate0 | Displayorientation::Rotate180 => { - x as usize / 8 + (self.width as usize / 8) * y as usize - }, - Displayorientation::Rotate90 | Displayorientation::Rotate270 => { - y as usize / 8 + (self.width as usize / 8) * x as usize - }, - }; - - if idx >= self.buffer.len() { - return; - } - - match color { - Color::Black => { - self.buffer[idx] = !filling; - }, - Color::White => { - self.buffer[idx] = filling; - } - } - } - - ///TODO: test! - pub fn draw_char(&mut self, x0: u16, y0: u16, input: char, font: &Font, color: &Color) { - self.draw_char_helper(x0, y0, input, font, color); - } - - ///TODO: test! - /// no autobreak line yet - pub fn draw_string(&mut self, x0: u16, y0: u16, input: &str, font: &Font, color: &Color) { - let mut counter = 0; - for input_char in input.chars() { - self.draw_char(x0 + counter, y0, input_char, font, color); - counter += u16::from(font.get_char_width(input_char)); - } - } - - //TODO: add support for font_height = 0 - //TODO: add support for char offset in y direction to reduce font file size - fn draw_char_helper(&mut self, x0: u16, y0: u16, input: char, font: &Font, color: &Color) { - //width: u8, height: u8, charbuffer: &[u8] - //TODO: font.get_char(input) -> FontChar {width, height, [u8]} - //TODO: font.get_char_offset(input) -> u16 - - let buff = font.get_char(input); - let char_width = font.get_char_width(input); - - let mut row_counter = 0; - let mut width_counter = 0u8; - for &elem in buff.iter() { - for _ in 0..8 { - self.draw_pixel( - x0 + u16::from(width_counter), - y0 + row_counter, - &Color::get_color(elem, width_counter % 8, color), - ); - - //Widthcounter shows how far we are in x direction - width_counter += 1; - // if we have reached - if width_counter >= char_width { - width_counter = 0; - row_counter += 1; - break; - } - } - } - } - - /// Draws a single 8x8 Char somewhere (1 pixel padding included) - pub fn draw_char_8x8(&mut self, x0: u16, y0: u16, input: char, color: &Color) { - let mut counter = 0; - // includes special draw_char instructions as this one is ordered columnwise and not rowwise (first byte == first 8 pixel columnwise) - for &elem in (&font::bitmap_8x8(input)).iter() { - for i in 0..8u8 { - self.draw_pixel( - x0 + counter, - y0 + 7 - u16::from(i), - &Color::convert_color(elem, i, color), - ) - } - counter += 1; - } - } - - /// Draws Strings with 8x8 Chars (1 pixel padding included) - /// - /// Is quite small for the 400x300 E-Ink - /// - /// no autobreak line yet - pub fn draw_string_8x8(&mut self, x0: u16, y0: u16, input: &str, color: &Color) { - for (counter, input_char) in input.chars().enumerate() { - self.draw_char_8x8( - x0 + counter as u16 * 8, - y0, - input_char, - color, - ); - } - } - - // void plotLine(int x0, int y0, int x1, int y1) - // { - // int dx = abs(x1-x0), sx = x0= dy) { err += dy; x0 += sx; } /* e_xy+e_x > 0 */ - // if (e2 <= dx) { err += dx; y0 += sy; } /* e_xy+e_y < 0 */ - // } - // } - //bresenham algorithm for lines - /// draw line - pub fn draw_line(&mut self, x0: u16, y0: u16, x1: u16, y1: u16, color: &Color) { - let mut x0 = x0 as i16; - let x1 = x1 as i16; - let mut y0 = y0 as i16; - let y1 = y1 as i16; - - let dx = i16::abs(x1 - x0); - let sx = if x0 < x1 { 1 } else { -1 }; - - let dy = -i16::abs(y1 - y0); - let sy = if y0 < y1 { 1 } else { -1 }; - - let mut err = dx + dy; - - loop { - self.draw_pixel(x0 as u16, y0 as u16, color); - - if x0 == x1 && y0 == y1 { - break; - } - - let e2 = 2 * err; - - if e2 >= dy { - err += dy; - x0 += sx; - } - - if e2 <= dx { - err += dx; - y0 += sy; - } - } - } - - /// Draw a horizontal line - /// TODO: maybe optimize by grouping up the bytes? But is it worth the longer and more complicated function? is it even faster? - pub fn draw_horizontal_line(&mut self, x: u16, y: u16, length: u16, color: &Color) { - for i in 0..length { - self.draw_pixel(x + i, y, color); - } - } - - /// Draws a vertical line - pub fn draw_vertical_line(&mut self, x: u16, y: u16, length: u16, color: &Color) { - for i in 0..length { - self.draw_pixel(x, y + i, color); - } - } - - /// Draws a rectangle. (x0,y0) is top left corner, (x1,y1) bottom right - pub fn draw_rectangle(&mut self, x0: u16, y0: u16, x1: u16, y1: u16, color: &Color) { - let (min_x, max_x) = if x0 <= x1 { (x0, x1) } else { (x1, x0) }; - let (min_y, max_y) = if y0 <= y1 { (y0, y1) } else { (y1, y0) }; - let x_len = max_x - min_x; - let y_len = max_y - min_y; - self.draw_horizontal_line(min_x, min_y, x_len, color); - self.draw_horizontal_line(min_x, max_y, x_len, color); - self.draw_vertical_line(min_x, min_y, y_len, color); - self.draw_vertical_line(max_x, min_y, y_len, color); - } - - /// Draws a filled rectangle. For more info see draw_rectangle - pub fn draw_filled_rectangle(&mut self, x0: u16, y0: u16, x1: u16, y1: u16, color: &Color) { - let (min_x, max_x) = if x0 <= x1 { (x0, x1) } else { (x1, x0) }; - let (min_y, max_y) = if y0 <= y1 { (y0, y1) } else { (y1, y0) }; - let x_len = max_x - min_x; - let y_len = max_y - min_y; - for i in 0..y_len { - self.draw_horizontal_line(min_x, min_y + i, x_len, color); - } - } - - fn draw_pixel_helper(&mut self, x: i16, y: i16, color: &Color) { - if x >= 0 && y >= 0 { - self.draw_pixel(x as u16, y as u16, color); - } - } - - fn draw_circle_helper(&mut self, x0: u16, y0: u16, radius: u16, filled: bool, color: &Color) { - let mut x = radius - 1; - let mut y = 0; - let mut dx = 1; - let mut dy = 1; - let mut err: i16 = dx - 2 * radius as i16; - - while x >= y { - if filled { - self.circle_helper_filled_putpixel(x0, y0, x, y, color); - } else { - self.circle_helper_putpixel(x0, y0, x, y, color); - } - - if err <= 0 { - y += 1; - err += dy; - dy += 2; - } - - if err > 0 { - x -= 1; - dx += 2; - err += dx - 2 * radius as i16; - } - } - } - - fn circle_helper_putpixel(&mut self, x0: u16, y0: u16, x: u16, y: u16, color: &Color) { - self.draw_horizontal_line(x0 - x, y0 + y, 2 * x, color); - // self.draw_pixel(buffer, x0 + x, y0 + y, color); - // self.draw_pixel(buffer, x0 - x, y0 + y, color); - - self.draw_horizontal_line(x0 - y, y0 + x, 2 * y, color); - // self.draw_pixel(buffer, x0 + y, y0 + x, color); - // self.draw_pixel(buffer, x0 - y, y0 + x, color); - - self.draw_horizontal_line(x0 - x, y0 - y, 2 * x, color); - // self.draw_pixel(buffer, x0 - x, y0 - y, color); - // self.draw_pixel(buffer, x0 + x, y0 - y, color); - - self.draw_horizontal_line(x0 - y, y0 - y, 2 * y, color); - // self.draw_pixel(buffer, x0 - y, y0 - x, color); - // self.draw_pixel(buffer, x0 + y, y0 - x, color); - } - - //TODO: Test - fn circle_helper_filled_putpixel(&mut self, x0: u16, y0: u16, x: u16, y: u16, color: &Color) { - self.draw_pixel(x0 + x, y0 + y, color); - self.draw_pixel(x0 + y, y0 + x, color); - self.draw_pixel(x0 - y, y0 + x, color); - self.draw_pixel(x0 - x, y0 + y, color); - self.draw_pixel(x0 - x, y0 - y, color); - self.draw_pixel(x0 - y, y0 - x, color); - self.draw_pixel(x0 + y, y0 - x, color); - self.draw_pixel(x0 + x, y0 - y, color); - } - - ///TODO: test if circle looks good - /// Draws a circle - pub fn draw_circle(&mut self, x0: u16, y0: u16, radius: u16, color: &Color) { - self.draw_circle_helper(x0, y0, radius, false, color); - } - - ///TODO: test if circle looks good - /// Draws a circle - pub fn draw_circle2(&mut self, x: u16, y: u16, radius: u16, color: &Color) { - let radius = radius as i16; - let x_mid = x as i16; - let y_mid = y as i16; - let mut x_pos: i16 = 0 - radius; - let mut y_pos = 0; - let mut err: i16 = 2 - 2 * radius; - - loop { - self.draw_pixel_helper(x_mid - x_pos, y_mid + y_pos, color); - self.draw_pixel_helper(x_mid - y_pos, y_mid - x_pos, color); - self.draw_pixel_helper(x_mid + x_pos, y_mid - y_pos, color); - self.draw_pixel_helper(x_mid + y_pos, y_mid + x_pos, color); - - let radius = err; - - if radius <= y_pos { - y_pos += 1; - err += y_pos * 2 + 1; - } - - if radius > x_pos || err > y_pos { - x_pos += 1; - err += x_pos * 2 + 1; - } - - if x_pos >= 0 { - break; - } - } - } - - ///TODO: test! - pub fn draw_filled_circle(&mut self, x0: u16, y0: u16, radius: u16, color: &Color) { - self.draw_circle_helper(x0, y0, radius, true, color); - } -} - -/* - -############ ############ ############ ############ - ## ## # ## - ## ## # ## - ## ###### ##### ## - ## ###### ##### ## - ## ## # ## - ## ## # ## - ## ############ ############ ## - -*/ - -#[cfg(test)] -mod graphics { - use super::*; - - #[test] - fn test_filled_rectangle() { - let mut buffer = [Color::White.get_byte_value(); 150]; - let mut graphics = Graphics::new(40, 30, &mut buffer); - graphics.draw_filled_rectangle(0, 0, 40, 30, &Color::Black); - - assert_eq!(graphics.buffer[0], Color::Black.get_byte_value()); - - for &elem in graphics.buffer.iter() { - assert_eq!(elem, Color::Black.get_byte_value()); - } - } - - /// draw a 4x4 in the top left corner - #[test] - fn test_filled_rectangle2() { - let mut buffer = [Color::White.get_byte_value(); 8]; - let mut graphics = Graphics::new(8, 8, &mut buffer); - graphics.draw_filled_rectangle(0, 0, 4, 4, &Color::Black); - - assert_eq!(graphics.buffer[0], 0x0f); - - let mut counter = 0; - for &elem in graphics.buffer.iter() { - counter += 1; - - if counter <= 4 { - assert_eq!(elem, 0x0f); - } else { - assert_eq!(elem, Color::White.get_byte_value()); - } - } - } - - #[test] - fn test_horizontal_line() { - let mut buffer = [Color::White.get_byte_value(); 4]; - let mut graphics = Graphics::new(16, 2, &mut buffer); - graphics.draw_horizontal_line(1, 0, 14, &Color::Black); - - assert_eq!(graphics.buffer[0], 0x80); - assert_eq!(graphics.buffer[1], 0x01); - assert_eq!(graphics.buffer[2], Color::White.get_byte_value()); - assert_eq!(graphics.buffer[3], Color::White.get_byte_value()); - } - - #[test] - fn test_vertical_line() { - let mut buffer = [Color::White.get_byte_value(); 8]; - let mut graphics = Graphics::new(8, 8, &mut buffer); - graphics.draw_vertical_line(0, 0, 8, &Color::Black); - - graphics.draw_vertical_line(5, 0, 8, &Color::Black); - - assert_eq!(graphics.buffer[0], 0x7b); - - for &elem in graphics.buffer.iter() { - assert_eq!(elem, 0x7bu8); - } - } - - //test draw_line for compatibility with draw_vertical_line - #[test] - fn draw_line_1() { - let mut buffer = [Color::White.get_byte_value(); 8]; - let mut graphics = Graphics::new(8, 8, &mut buffer); - - graphics.draw_vertical_line(5, 0, 8, &Color::Black); - - let mut buffer2 = [Color::White.get_byte_value(); 8]; - let mut graphics2 = Graphics::new(8, 8, &mut buffer2); - - graphics2.draw_line(5, 0, 5, 8, &Color::Black); - - for i in 0..graphics.buffer.len() { - assert_eq!(graphics.buffer[i], graphics2.buffer[i]); - } - } - - //test draw_line for compatibility with draw_horizontal_line - #[test] - fn draw_line_2() { - let mut buffer = [Color::White.get_byte_value(); 4]; - let mut graphics = Graphics::new(16, 2, &mut buffer); - graphics.draw_horizontal_line(1, 0, 14, &Color::Black); - - let mut buffer2 = [Color::White.get_byte_value(); 4]; - let mut graphics2 = Graphics::new(16, 2, &mut buffer2); - graphics2.draw_line(1, 0, 14, 0, &Color::Black); - - for i in 0..graphics.buffer.len() { - assert_eq!(graphics.buffer[i], graphics2.buffer[i]); - } - } - - //test draw_line for diago - #[test] - fn draw_line_3() { - let mut buffer = [Color::White.get_byte_value(); 8]; - let mut graphics = Graphics::new(8, 8, &mut buffer); - - graphics.draw_line(0, 0, 16, 16, &Color::Black); - - for i in 0..graphics.buffer.len() { - assert_eq!(graphics.buffer[i], !(0x80 >> i % 8)); - } - } - - #[test] - fn test_pixel() { - let mut buffer = [Color::White.get_byte_value(); 8]; - let mut graphics = Graphics::new(8, 8, &mut buffer); - graphics.draw_pixel(1, 0, &Color::Black); - - assert_eq!(graphics.buffer[0], !0x40); - - let mut buffer = [Color::White.get_byte_value(); 16]; - let mut graphics = Graphics::new(16, 8, &mut buffer); - graphics.draw_pixel(9, 0, &Color::Black); - assert_eq!(graphics.buffer[0], Color::White.get_byte_value()); - assert_eq!(graphics.buffer[1], !0x40); - } - - #[test] - fn test_byte() { - let mut buffer = [Color::White.get_byte_value(); 8]; - let mut graphics = Graphics::new(8, 8, &mut buffer); - graphics.draw_byte(0, 0, 0xff, &Color::Black); - - assert_eq!(graphics.buffer[0], Color::Black.get_byte_value()); - - for i in 1..graphics.buffer.len() { - assert_eq!(graphics.buffer[i], Color::White.get_byte_value()); - } - - graphics.draw_byte(0, 0, 0x5A, &Color::Black); - assert_eq!(graphics.buffer[0], !0x5A); - } - - #[test] - fn test_char_with_8x8_font() { - // Test ! - let mut buffer = [Color::White.get_byte_value(); 8]; - let mut graphics = Graphics::new(8, 8, &mut buffer); - graphics.draw_char_8x8(0, 0, '!', &Color::Black); - - for i in 0..5 { - assert_eq!(graphics.buffer[i], !0x20); - } - assert_eq!(graphics.buffer[5], Color::White.get_byte_value()); - assert_eq!(graphics.buffer[6], !0x20); - assert_eq!(graphics.buffer[7], Color::White.get_byte_value()); - - // Test H - let mut buffer = [Color::White.get_byte_value(); 8]; - let mut graphics = Graphics::new(8, 8, &mut buffer); - graphics.draw_char_8x8(0, 0, 'H', &Color::Black); - - for i in 0..3 { - assert_eq!(graphics.buffer[i], !0x88); - } - assert_eq!(graphics.buffer[3], !0xF8); - for i in 4..7 { - assert_eq!(graphics.buffer[i], !0x88); - } - assert_eq!(graphics.buffer[7], Color::White.get_byte_value()); - } - - #[test] - fn test_string_with_8x8_font() { - // Test !H - let mut buffer = [Color::White.get_byte_value(); 16]; - let mut graphics = Graphics::new(16, 8, &mut buffer); - graphics.draw_string_8x8(0, 0, "!H", &Color::Black); - - for i in 0..5 { - assert_eq!(graphics.buffer[i * 2], !0x20); - } - assert_eq!(graphics.buffer[5 * 2], Color::White.get_byte_value()); - assert_eq!(graphics.buffer[6 * 2], !0x20); - assert_eq!(graphics.buffer[7 * 2], Color::White.get_byte_value()); - - for i in 0..3 { - assert_eq!(graphics.buffer[i * 2 + 1], !0x88); - } - assert_eq!(graphics.buffer[3 * 2 + 1], !0xF8); - for i in 4..7 { - assert_eq!(graphics.buffer[i * 2 + 1], !0x88); - } - assert_eq!(graphics.buffer[7 * 2 + 1], Color::White.get_byte_value()); - } -} diff --git a/src/lib.rs b/src/lib.rs index 6268ff6..a115add 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -41,22 +41,12 @@ //! #![no_std] -//TODO: Make more assertions about buffersizes? - -extern crate embedded_hal as hal; - -use hal::spi::{Mode, Phase, Polarity}; - #[cfg(feature = "graphics")] extern crate embedded_graphics; #[cfg(feature = "graphics")] pub mod graphics; -//TODO: remove old drawing support -#[cfg(feature = "graphics")] -pub mod drawing_old; - mod traits; pub use traits::{WaveshareDisplay}; @@ -77,10 +67,10 @@ pub mod epd2in9; #[cfg(any(feature = "epd1in54", feature = "epd2in9"))] pub(crate) mod type_a; - - /// SPI mode - /// For more infos see [Requirements: SPI](index.html#spi) +extern crate embedded_hal as hal; +use hal::spi::{Mode, Phase, Polarity}; pub const SPI_MODE: Mode = Mode { phase: Phase::CaptureOnFirstTransition, polarity: Polarity::IdleLow, From f039b1f6a45d78a70decf4589403fcb41d60f3a4 Mon Sep 17 00:00:00 2001 From: Chris Date: Mon, 22 Oct 2018 16:16:48 +0200 Subject: [PATCH 66/75] Improve documentation --- examples/stm32f3discovery/src/main.rs | 3 +-- src/color.rs | 10 +++++++--- src/graphics.rs | 2 ++ src/lib.rs | 13 ++++++++++--- src/traits.rs | 10 ++++------ 5 files changed, 24 insertions(+), 14 deletions(-) diff --git a/examples/stm32f3discovery/src/main.rs b/examples/stm32f3discovery/src/main.rs index c4614f4..1a00c40 100644 --- a/examples/stm32f3discovery/src/main.rs +++ b/examples/stm32f3discovery/src/main.rs @@ -29,8 +29,7 @@ use eink_waveshare_rs::{ epd1in54::EPD1in54, SPI_MODE, //drawing_old::{Graphics}, - color::Color, - WaveshareDisplay, + prelude::*, }; diff --git a/src/color.rs b/src/color.rs index 7f2f8f9..611965e 100644 --- a/src/color.rs +++ b/src/color.rs @@ -1,13 +1,17 @@ +//! B/W Color for EPDs - -/// Only for the B/W Displays atm +/// Only for the Black/White-Displays #[derive(Clone, Copy, PartialEq, Debug)] pub enum Color { + /// Black color Black, + /// White color White, } +//TODO: Rename get_bit_value to bit() and get_byte_value to byte() ? + impl Color { /// Get the color encoding of the color for one bit pub fn get_bit_value(&self) -> u8 { @@ -25,7 +29,7 @@ impl Color { } } - /// Parses + /// Parses from u8 to Color fn from_u8(val: u8) -> Self { match val { 0 => Color::Black, diff --git a/src/graphics.rs b/src/graphics.rs index 2cbd3ff..5f42e6a 100644 --- a/src/graphics.rs +++ b/src/graphics.rs @@ -1,3 +1,5 @@ +//! Graphics Support for EPDs + use color::Color; use embedded_graphics::prelude::*; diff --git a/src/lib.rs b/src/lib.rs index a115add..1d5ea1f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -48,7 +48,6 @@ extern crate embedded_graphics; pub mod graphics; mod traits; -pub use traits::{WaveshareDisplay}; pub mod color; @@ -67,10 +66,18 @@ pub mod epd2in9; #[cfg(any(feature = "epd1in54", feature = "epd2in9"))] pub(crate) mod type_a; -/// SPI mode - -/// For more infos see [Requirements: SPI](index.html#spi) +pub mod prelude { + pub use traits::{WaveshareDisplay}; + pub use color::Color; + pub use SPI_MODE; +} + + extern crate embedded_hal as hal; use hal::spi::{Mode, Phase, Polarity}; + +/// SPI mode - +/// For more infos see [Requirements: SPI](index.html#spi) pub const SPI_MODE: Mode = Mode { phase: Phase::CaptureOnFirstTransition, polarity: Polarity::IdleLow, diff --git a/src/traits.rs b/src/traits.rs index be64cb6..fb395e9 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -3,20 +3,15 @@ use hal::{ blocking::{delay::*, spi::Write}, digital::*, }; - use color::Color; - - - /// All commands need to have this trait which gives the address of the command /// which needs to be send via SPI with activated CommandsPin (Data/Command Pin in CommandMode) pub(crate) trait Command { fn address(self) -> u8; } - // Trait for using various Waveforms from different LUTs // E.g. for partial updates trait LUTSupport { @@ -25,7 +20,6 @@ trait LUTSupport { fn set_lut_manual(&mut self, data: &[u8]) -> Result<(), ERR>; } - pub(crate) trait InternalWiAdditions where SPI: Write, @@ -48,6 +42,9 @@ where } +/// All the functions to interact with the EPDs +/// +/// This trait includes all public functions to use the EPDS pub trait WaveshareDisplay where SPI: Write, @@ -73,6 +70,7 @@ where /// and initialising which already contains the reset fn sleep(&mut self, spi: &mut SPI) -> Result<(), SPI::Error>; + /// Wakes the device up from sleep fn wake_up>(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error>; From e51406b05f1d392ea4c5436614c879fe0a26ad49 Mon Sep 17 00:00:00 2001 From: Chris Date: Mon, 22 Oct 2018 16:17:53 +0200 Subject: [PATCH 67/75] use prelude in examples --- examples/embedded_linux_epd1in54/src/main.rs | 3 +-- examples/embedded_linux_epd4in2/src/main.rs | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/examples/embedded_linux_epd1in54/src/main.rs b/examples/embedded_linux_epd1in54/src/main.rs index 93380bd..d3319ae 100644 --- a/examples/embedded_linux_epd1in54/src/main.rs +++ b/examples/embedded_linux_epd1in54/src/main.rs @@ -11,8 +11,7 @@ use eink_waveshare_rs::{ Buffer1in54, }, graphics::{Display, DisplayRotation}, - color::Color, - WaveshareDisplay, + prelude::*, }; use lin_hal::spidev::{self, SpidevOptions}; diff --git a/examples/embedded_linux_epd4in2/src/main.rs b/examples/embedded_linux_epd4in2/src/main.rs index f14dcdb..7ff7599 100644 --- a/examples/embedded_linux_epd4in2/src/main.rs +++ b/examples/embedded_linux_epd4in2/src/main.rs @@ -11,8 +11,7 @@ use eink_waveshare_rs::{ Buffer4in2, }, graphics::{Display, DisplayRotation}, - color::Color, - WaveshareDisplay, + prelude::*, }; extern crate embedded_graphics; From 3fc25d71e5bdf0628f60281df94bd1ac0122e884 Mon Sep 17 00:00:00 2001 From: Chris Date: Tue, 23 Oct 2018 16:41:59 +0200 Subject: [PATCH 68/75] Improved Documentation --- Cargo.toml | 2 -- src/epd1in54/graphics.rs | 4 ++++ src/epd1in54/mod.rs | 37 ++++++++++++++++++++++++++----------- src/epd2in9/graphics.rs | 4 ++++ src/epd4in2/graphics.rs | 4 ++++ 5 files changed, 38 insertions(+), 13 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ffe9c4e..0e7779a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,8 +30,6 @@ epd4in2_fast_update = [] [dependencies.embedded-graphics] optional = true version = "0.4.3" -# embedded-graphics = {git = "https://github.com/caemor/embedded-graphics", branch = "master"} -# embedded-graphics = {git = "https://github.com/jamwaffles/embedded-graphics", branch = "master"} [dependencies.embedded-hal] features = ["unproven"] diff --git a/src/epd1in54/graphics.rs b/src/epd1in54/graphics.rs index 2604645..1a9d620 100644 --- a/src/epd1in54/graphics.rs +++ b/src/epd1in54/graphics.rs @@ -1,5 +1,9 @@ use epd1in54::{DEFAULT_BACKGROUND_COLOR, WIDTH, HEIGHT}; +/// Full size buffer for use with the 1in54 EPD +/// +/// Can also be manuall constructed: +/// `buffer: [DEFAULT_BACKGROUND_COLOR.get_byte_value(); WIDTH / 8 * HEIGHT]` pub struct Buffer1in54BlackWhite { pub buffer: [u8; WIDTH as usize * HEIGHT as usize / 8], } diff --git a/src/epd1in54/mod.rs b/src/epd1in54/mod.rs index 2bb8eea..80e1a3c 100644 --- a/src/epd1in54/mod.rs +++ b/src/epd1in54/mod.rs @@ -4,19 +4,34 @@ //! # Examples from the 4.2" Display. It should work the same for the 1.54" one. //! //! ```ignore -//! let mut epd4in2 = EPD4in2::new(spi, cs, busy, dc, rst, delay).unwrap(); +//! use eink_waveshare_rs::{ +//! epd1in54::{EPD1in54, Buffer1in54}, +//! graphics::{Display, DisplayRotation}, +//! prelude::*, +//! }; +//! +//! // Setup EPD +//! let mut epd = EPD1in54::new(&mut spi, cs_pin, busy_in, dc, rst, &mut delay)?; //! -//! let mut buffer = [0u8, epd4in2.get_width() / 8 * epd4in2.get_height()]; +//! // Use display graphics +//! let mut buffer = Buffer1in54::default(); +//! let mut display = Display::new(epd.width(), epd.height(), &mut buffer.buffer); +//! +//! // Write some hello world in the screenbuffer +//! display.draw( +//! Font6x8::render_str("Hello World!") +//! .with_stroke(Some(Color::Black)) +//! .with_fill(Some(Color::White)) +//! .translate(Coord::new(5, 50)) +//! .into_iter(), +//! ); //! -//! // draw something into the buffer -//! -//! epd4in2.display_and_transfer_buffer(buffer, None); -//! -//! // wait and look at the image -//! -//! epd4in2.clear_frame(None); -//! -//! epd4in2.sleep(); +//! // Display updated frame +//! epd.update_frame(&mut spi, &display.buffer()).unwrap(); +//! epd.display_frame(&mut spi).expect("display frame new graphics"); +//! +//! // Set the EPD to sleep +//! epd.sleep(&mut spi).expect("sleep"); //! ``` pub const WIDTH: u32 = 200; diff --git a/src/epd2in9/graphics.rs b/src/epd2in9/graphics.rs index 45e17d9..2e6c31d 100644 --- a/src/epd2in9/graphics.rs +++ b/src/epd2in9/graphics.rs @@ -1,5 +1,9 @@ use epd2in9::{DEFAULT_BACKGROUND_COLOR, WIDTH, HEIGHT}; +/// Full size buffer for use with the 2in9 EPD +/// +/// Can also be manuall constructed: +/// `buffer: [DEFAULT_BACKGROUND_COLOR.get_byte_value(); WIDTH / 8 * HEIGHT]` pub struct Buffer2in9 { pub buffer: [u8; WIDTH as usize * HEIGHT as usize / 8], } diff --git a/src/epd4in2/graphics.rs b/src/epd4in2/graphics.rs index 586234d..601459a 100644 --- a/src/epd4in2/graphics.rs +++ b/src/epd4in2/graphics.rs @@ -1,5 +1,9 @@ use epd4in2::constants::{DEFAULT_BACKGROUND_COLOR, WIDTH, HEIGHT}; +/// Full size buffer for use with the 4in2 EPD +/// +/// Can also be manuall constructed: +/// `buffer: [DEFAULT_BACKGROUND_COLOR.get_byte_value(); WIDTH / 8 * HEIGHT]` pub struct Buffer4in2 { pub buffer: [u8; WIDTH as usize * HEIGHT as usize / 8], } From ea1843f506b9fdfe805e6cf93d51cdccf6441da5 Mon Sep 17 00:00:00 2001 From: Chris Date: Tue, 23 Oct 2018 16:42:14 +0200 Subject: [PATCH 69/75] Add a quick lut example --- examples/embedded_linux_epd1in54/src/main.rs | 23 ++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/examples/embedded_linux_epd1in54/src/main.rs b/examples/embedded_linux_epd1in54/src/main.rs index d3319ae..6e53781 100644 --- a/examples/embedded_linux_epd1in54/src/main.rs +++ b/examples/embedded_linux_epd1in54/src/main.rs @@ -169,6 +169,29 @@ fn run() -> Result<(), std::io::Error> { epd.display_frame(&mut spi).expect("display frame new graphics"); delay.delay_ms(5000u16); + // a moving `Hello World!` + epd.set_lut_quick(&mut spi).expect("SET LUT QUICK error"); + let limit = 20; + for i in 0..limit { + println!("Moving Hello World. Loop {} from {}", i, limit); + + display.draw( + Font6x8::render_str(" Hello World! ") + .with_style(Style { + fill_color: Some(Color::White), + stroke_color: Some(Color::Black), + stroke_width: 0u8, // Has no effect on fonts + }) + .translate(Coord::new(5 + i*6, 50)) + .into_iter(), + ); + + epd.update_frame(&mut spi, &display.buffer()).unwrap(); + epd.display_frame(&mut spi).expect("display frame new graphics"); + + delay.delay_ms(1_000u16); + } + // Set the EPD to sleep epd.sleep(&mut spi).expect("sleep"); From bfafb8b05881df28b76b37bb65504b1cb74dc4fc Mon Sep 17 00:00:00 2001 From: Chris Date: Tue, 23 Oct 2018 16:47:00 +0200 Subject: [PATCH 70/75] make the quick example faster --- examples/embedded_linux_epd1in54/src/main.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/examples/embedded_linux_epd1in54/src/main.rs b/examples/embedded_linux_epd1in54/src/main.rs index 6e53781..aef8786 100644 --- a/examples/embedded_linux_epd1in54/src/main.rs +++ b/examples/embedded_linux_epd1in54/src/main.rs @@ -169,11 +169,12 @@ fn run() -> Result<(), std::io::Error> { epd.display_frame(&mut spi).expect("display frame new graphics"); delay.delay_ms(5000u16); - // a moving `Hello World!` + // a quickly moving `Hello World!` + display.set_rotation(DisplayRotation::Rotate0); epd.set_lut_quick(&mut spi).expect("SET LUT QUICK error"); let limit = 20; for i in 0..limit { - println!("Moving Hello World. Loop {} from {}", i, limit); + println!("Moving Hello World. Loop {} from {}", (i+1), limit); display.draw( Font6x8::render_str(" Hello World! ") @@ -188,8 +189,6 @@ fn run() -> Result<(), std::io::Error> { epd.update_frame(&mut spi, &display.buffer()).unwrap(); epd.display_frame(&mut spi).expect("display frame new graphics"); - - delay.delay_ms(1_000u16); } // Set the EPD to sleep From 0204e72cb564bbbfb4918a8c1bac333fb035d729 Mon Sep 17 00:00:00 2001 From: Chris Date: Tue, 23 Oct 2018 22:14:11 +0200 Subject: [PATCH 71/75] Some last doc changes --- examples/embedded_linux_epd4in2/src/main.rs | 2 +- src/epd1in54/mod.rs | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/examples/embedded_linux_epd4in2/src/main.rs b/examples/embedded_linux_epd4in2/src/main.rs index 7ff7599..8306cf4 100644 --- a/examples/embedded_linux_epd4in2/src/main.rs +++ b/examples/embedded_linux_epd4in2/src/main.rs @@ -212,7 +212,7 @@ fn run() -> Result<(), std::io::Error> { // a moving `Hello World!` let limit = 10; for i in 0..limit { - println!("Moving Hello World. Loop {} from {}", i, limit); + println!("Moving Hello World. Loop {} from {}", (i+1), limit); display.draw( Font6x8::render_str(" Hello World! ") diff --git a/src/epd1in54/mod.rs b/src/epd1in54/mod.rs index 80e1a3c..019ca79 100644 --- a/src/epd1in54/mod.rs +++ b/src/epd1in54/mod.rs @@ -1,8 +1,7 @@ //! A simple Driver for the Waveshare 1.54" E-Ink Display via SPI -//! -//! -//! # Examples from the 4.2" Display. It should work the same for the 1.54" one. -//! +//! +//! # Example for the 1.54 in E-Ink Display +//! //! ```ignore //! use eink_waveshare_rs::{ //! epd1in54::{EPD1in54, Buffer1in54}, From c98c058c5a1a81ee46b7fbff63d7a8b4324e481e Mon Sep 17 00:00:00 2001 From: Chris Date: Tue, 23 Oct 2018 23:15:23 +0200 Subject: [PATCH 72/75] Add 2in9 example --- examples/embedded_linux_epd2in9/Cargo.toml | 14 ++ examples/embedded_linux_epd2in9/src/main.rs | 198 ++++++++++++++++++++ 2 files changed, 212 insertions(+) create mode 100644 examples/embedded_linux_epd2in9/Cargo.toml create mode 100644 examples/embedded_linux_epd2in9/src/main.rs diff --git a/examples/embedded_linux_epd2in9/Cargo.toml b/examples/embedded_linux_epd2in9/Cargo.toml new file mode 100644 index 0000000..b5eba5c --- /dev/null +++ b/examples/embedded_linux_epd2in9/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "embedded_linux_eink_example" +version = "0.1.0" +authors = ["Christoph Groß "] + +[dependencies] + +eink_waveshare_rs = { path = "../../", default-features = false, features = ["epd2in9", "graphics"]} + +linux-embedded-hal = "0.2.0" + +embedded-graphics = "0.4.3" + +embedded-hal = { version = "0.2.1", features = ["unproven"] } diff --git a/examples/embedded_linux_epd2in9/src/main.rs b/examples/embedded_linux_epd2in9/src/main.rs new file mode 100644 index 0000000..291787d --- /dev/null +++ b/examples/embedded_linux_epd2in9/src/main.rs @@ -0,0 +1,198 @@ +// the library for the embedded linux device +extern crate linux_embedded_hal as lin_hal; + +// the eink library +extern crate eink_waveshare_rs; + + +use eink_waveshare_rs::{ + epd2in9::{ + EPD2in9, + Buffer2in9, + }, + graphics::{Display, DisplayRotation}, + prelude::*, +}; + +use lin_hal::spidev::{self, SpidevOptions}; +use lin_hal::{Pin, Spidev}; +use lin_hal::sysfs_gpio::Direction; +use lin_hal::Delay; + +extern crate embedded_graphics; +use embedded_graphics::coord::Coord; +use embedded_graphics::fonts::{Font6x8}; +use embedded_graphics::prelude::*; +//use embedded_graphics::primitives::{Circle, Line}; +use embedded_graphics::Drawing; + +extern crate embedded_hal; +use embedded_hal::prelude::*; + +// activate spi, gpio in raspi-config +// needs to be run with sudo because of some sysfs_gpio permission problems and follow-up timing problems +// see https://github.com/rust-embedded/rust-sysfs-gpio/issues/5 and follow-up issues + + +// DigitalIn Hack as long as it's not in the linux_embedded_hal +// from https://github.com/rudihorn/max31865/blob/extra_examples/examples/rpi.rs +// (slightly changed now as OutputPin doesn't provide is_high and is_low anymore) +use embedded_hal::digital::{InputPin}; + +//TODO: Remove when linux_embedded_hal implements InputPin +struct HackInputPin<'a> { + pin: &'a Pin +} + +//TODO: Remove when linux_embedded_hal implements InputPin +impl<'a> HackInputPin<'a> { + fn new(p : &'a Pin) -> HackInputPin { + HackInputPin { + pin: p + } + } +} + +//TODO: Remove when linux_embedded_hal implements InputPin +// for now it defaults to is_low if an error appears +// could be handled better! +impl<'a> InputPin for HackInputPin<'a> { + fn is_low(&self) -> bool { + self.pin.get_value().unwrap_or(0) == 0 + } + + fn is_high(&self) -> bool { + !self.is_low() + } +} + +//TODO: Test this implemenation +//BE CAREFUL: this wasn't tested yet +fn main() { + + run().unwrap(); +} + +fn run() -> Result<(), std::io::Error> { + // Configure SPI + // SPI settings are from eink-waveshare-rs documenation + let mut spi = Spidev::open("/dev/spidev0.0").expect("spidev directory"); + let options = SpidevOptions::new() + .bits_per_word(8) + .max_speed_hz(4_000_000) + .mode(spidev::SPI_MODE_0) + .build(); + spi.configure(&options).expect("spi configuration"); + + // Configure Digital I/O Pin to be used as Chip Select for SPI + let cs_pin = Pin::new(26);//BCM7 CE0 + cs_pin.export().expect("cs_pin export"); + while !cs_pin.is_exported() {} + cs_pin.set_direction(Direction::Out).expect("cs_pin Direction"); + cs_pin.set_value(1).expect("cs_pin Value set to 1"); + + // Configure Busy Input Pin + let busy = Pin::new(5);//pin 29 + busy.export().expect("busy export"); + while !busy.is_exported() {} + busy.set_direction(Direction::In).expect("busy Direction"); + //busy.set_value(1).expect("busy Value set to 1"); + let busy_in = HackInputPin::new(&busy); + + // Configure Data/Command OutputPin + let dc = Pin::new(6); //pin 31 //bcm6 + dc.export().expect("dc export"); + while !dc.is_exported() {} + dc.set_direction(Direction::Out).expect("dc Direction"); + dc.set_value(1).expect("dc Value set to 1"); + + // Configure Reset OutputPin + let rst = Pin::new(16); //pin 36 //bcm16 + rst.export().expect("rst export"); + while !rst.is_exported() {} + rst.set_direction(Direction::Out).expect("rst Direction"); + rst.set_value(1).expect("rst Value set to 1"); + + // Configure Delay + let mut delay = Delay {}; + + + // Setup of the needed pins is finished here + // Now the "real" usage of the eink-waveshare-rs crate begins + let mut epd = EPD2in9::new(&mut spi, cs_pin, busy_in, dc, rst, &mut delay)?; + + // Clear the full screen + epd.clear_frame(&mut spi).expect("clear frame 1"); + epd.display_frame(&mut spi).expect("disp 1"); + + println!("Test all the rotations"); + let mut buffer = Buffer2in9::default(); + let mut display = Display::new(epd.width(), epd.height(), &mut buffer.buffer); + display.set_rotation(DisplayRotation::Rotate0); + display.draw( + Font6x8::render_str("Rotate 0!") + .with_stroke(Some(Color::Black)) + .with_fill(Some(Color::White)) + .translate(Coord::new(5, 50)) + .into_iter(), + ); + + display.set_rotation(DisplayRotation::Rotate90); + display.draw( + Font6x8::render_str("Rotate 90!") + .with_stroke(Some(Color::Black)) + .with_fill(Some(Color::White)) + .translate(Coord::new(5, 50)) + .into_iter(), + ); + + display.set_rotation(DisplayRotation::Rotate180); + display.draw( + Font6x8::render_str("Rotate 180!") + .with_stroke(Some(Color::Black)) + .with_fill(Some(Color::White)) + .translate(Coord::new(5, 50)) + .into_iter(), + ); + + display.set_rotation(DisplayRotation::Rotate270); + display.draw( + Font6x8::render_str("Rotate 270!") + .with_stroke(Some(Color::Black)) + .with_fill(Some(Color::White)) + .translate(Coord::new(5, 50)) + .into_iter(), + ); + + // Display updated frame + epd.update_frame(&mut spi, &display.buffer()).unwrap(); + epd.display_frame(&mut spi).expect("display frame new graphics"); + delay.delay_ms(5000u16); + + // a quickly moving `Hello World!` + display.set_rotation(DisplayRotation::Rotate0); + epd.set_lut_quick(&mut spi).expect("SET LUT QUICK error"); + let limit = 20; + for i in 0..limit { + println!("Moving Hello World. Loop {} from {}", (i+1), limit); + + display.draw( + Font6x8::render_str(" Hello World! ") + .with_style(Style { + fill_color: Some(Color::White), + stroke_color: Some(Color::Black), + stroke_width: 0u8, // Has no effect on fonts + }) + .translate(Coord::new(5 + i*6, 50)) + .into_iter(), + ); + + epd.update_frame(&mut spi, &display.buffer()).unwrap(); + epd.display_frame(&mut spi).expect("display frame new graphics"); + } + + // Set the EPD to sleep + epd.sleep(&mut spi).expect("sleep"); + + Ok(()) +} From f06b672899c9440ced193642ca9fc42c705139bb Mon Sep 17 00:00:00 2001 From: Chris Date: Wed, 24 Oct 2018 08:11:10 +0200 Subject: [PATCH 73/75] add a empty screen first --- examples/embedded_linux_epd2in9/src/main.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/examples/embedded_linux_epd2in9/src/main.rs b/examples/embedded_linux_epd2in9/src/main.rs index 291787d..65a3c45 100644 --- a/examples/embedded_linux_epd2in9/src/main.rs +++ b/examples/embedded_linux_epd2in9/src/main.rs @@ -128,6 +128,9 @@ fn run() -> Result<(), std::io::Error> { println!("Test all the rotations"); let mut buffer = Buffer2in9::default(); let mut display = Display::new(epd.width(), epd.height(), &mut buffer.buffer); + epd.update_frame(&mut spi, display.buffer()).unwrap(); + epd.display_frame(&mut spi); + display.set_rotation(DisplayRotation::Rotate0); display.draw( Font6x8::render_str("Rotate 0!") From 91d7a7862af7a6a8ebd0c6bbf00c1ca95708759b Mon Sep 17 00:00:00 2001 From: Chris Date: Wed, 24 Oct 2018 14:07:35 +0200 Subject: [PATCH 74/75] improved docs for 2in9 --- README.md | 10 +++++++--- src/epd2in9/mod.rs | 42 +++++++++++++++++++++++++++++------------- 2 files changed, 36 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 796202b..62ff176 100644 --- a/README.md +++ b/README.md @@ -11,16 +11,20 @@ It uses the [embedded graphics](https://crates.io/crates/embedded-graphics) libr | [4.2 Inch B/W (A)](https://www.waveshare.com/product/4.2inch-e-paper-module.htm) | Black, White | ✕ | Not officially [[1](#42-inch-e-ink-blackwhite)] | ✔ | ✔ | | [1.54 Inch B/W (A)](https://www.waveshare.com/1.54inch-e-Paper-Module.htm) | Black, White | ✕ | ✔ | ✔ | ✔ | | [2.13 Inch B/W (A)](https://www.waveshare.com/product/2.13inch-e-paper-hat.htm) | Black, White | ✕ | ✔ | | | -| [2.9 Inch B/W (A)](https://www.waveshare.com/product/2.9inch-e-paper-module.htm) | Black, White | ✕ | ✔ | ✔ | ✔ | +| [2.9 Inch B/W (A)](https://www.waveshare.com/product/2.9inch-e-paper-module.htm) | Black, White | ✕ | ✔ | ✔ | ✔ [[2](#)] | -### 4.2 Inch E-Ink Black/White +### [1]: 4.2 Inch E-Ink Black/White - Partial Refresh Out of the Box the original driver from Waveshare only supports full updates. -- [1]: Be careful with the quick refresh updates:
+That means: Be careful with the quick refresh updates:
It's possible with this driver but might lead to ghosting / burn-in effects therefore it's hidden behind a feature. +### [2]: 2.9 Inch E-Ink Black/White - Tests + +Since my 2.9 Inch-Display has some blurring issues I am not absolutly sure if everything was working correctly + ### Interface | Interface | Description | diff --git a/src/epd2in9/mod.rs b/src/epd2in9/mod.rs index 9da3e14..dcdf1a7 100644 --- a/src/epd2in9/mod.rs +++ b/src/epd2in9/mod.rs @@ -1,22 +1,38 @@ //! A simple Driver for the Waveshare 2.9" E-Ink Display via SPI //! +//! Untested! //! -//! # Examples from the 4.2" Display. It should work the same for the 2.9" one. -//! +//! # Example for the 2.9 in E-Ink Display +//! //! ```ignore -//! let mut epd4in2 = EPD4in2::new(spi, cs, busy, dc, rst, delay).unwrap(); -//! -//! let mut buffer = [0u8, epd4in2.get_width() / 8 * epd4in2.get_height()]; -//! -//! // draw something into the buffer -//! -//! epd4in2.display_and_transfer_buffer(buffer, None); -//! -//! // wait and look at the image +//! use eink_waveshare_rs::{ +//! epd2in9::{EPD2in9, Buffer2in9}, +//! graphics::{Display, DisplayRotation}, +//! prelude::*, +//! }; +//! +//! // Setup EPD +//! let mut epd = EPD2in9::new(&mut spi, cs_pin, busy_in, dc, rst, &mut delay)?; //! -//! epd4in2.clear_frame(None); +//! // Use display graphics +//! let mut buffer = Buffer2in9::default(); +//! let mut display = Display::new(epd.width(), epd.height(), &mut buffer.buffer); +//! +//! // Write some hello world in the screenbuffer +//! display.draw( +//! Font6x8::render_str("Hello World!") +//! .with_stroke(Some(Color::Black)) +//! .with_fill(Some(Color::White)) +//! .translate(Coord::new(5, 50)) +//! .into_iter(), +//! ); //! -//! epd4in2.sleep(); +//! // Display updated frame +//! epd.update_frame(&mut spi, &display.buffer()).unwrap(); +//! epd.display_frame(&mut spi).expect("display frame new graphics"); +//! +//! // Set the EPD to sleep +//! epd.sleep(&mut spi).expect("sleep"); //! ``` pub const WIDTH: u32 = 128; From 5b2996d73a3f94a7c3c821da946453ee29107d5b Mon Sep 17 00:00:00 2001 From: Chris Date: Wed, 24 Oct 2018 14:09:39 +0200 Subject: [PATCH 75/75] Fixed broken link --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 62ff176..5762069 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ It uses the [embedded graphics](https://crates.io/crates/embedded-graphics) libr | [4.2 Inch B/W (A)](https://www.waveshare.com/product/4.2inch-e-paper-module.htm) | Black, White | ✕ | Not officially [[1](#42-inch-e-ink-blackwhite)] | ✔ | ✔ | | [1.54 Inch B/W (A)](https://www.waveshare.com/1.54inch-e-Paper-Module.htm) | Black, White | ✕ | ✔ | ✔ | ✔ | | [2.13 Inch B/W (A)](https://www.waveshare.com/product/2.13inch-e-paper-hat.htm) | Black, White | ✕ | ✔ | | | -| [2.9 Inch B/W (A)](https://www.waveshare.com/product/2.9inch-e-paper-module.htm) | Black, White | ✕ | ✔ | ✔ | ✔ [[2](#)] | +| [2.9 Inch B/W (A)](https://www.waveshare.com/product/2.9inch-e-paper-module.htm) | Black, White | ✕ | ✔ | ✔ | ✔ [[2](#2-29-inch-e-ink-blackwhite---tests)] | ### [1]: 4.2 Inch E-Ink Black/White - Partial Refresh @@ -23,7 +23,7 @@ It's possible with this driver but might lead to ghosting / burn-in effects ther ### [2]: 2.9 Inch E-Ink Black/White - Tests -Since my 2.9 Inch-Display has some blurring issues I am not absolutly sure if everything was working correctly +Since my 2.9 Inch Display has some blurring issues I am not absolutly sure if everything was working correctly as it should :-) ### Interface