Merge pull request #76 from lrbalt/tri-color
Enable drawing in three colors for epd2in13 with TriColor thanks to @lrbaltmain
commit
253cc101fd
|
|
@ -11,7 +11,7 @@ use embedded_hal::prelude::*;
|
||||||
use epd_waveshare::{
|
use epd_waveshare::{
|
||||||
color::*,
|
color::*,
|
||||||
epd2in13bc::{Display2in13bc, Epd2in13bc},
|
epd2in13bc::{Display2in13bc, Epd2in13bc},
|
||||||
graphics::{Display, DisplayRotation},
|
graphics::{DisplayRotation, TriDisplay},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
use linux_embedded_hal::{
|
use linux_embedded_hal::{
|
||||||
|
|
@ -77,7 +77,7 @@ fn main() -> Result<(), std::io::Error> {
|
||||||
|
|
||||||
println!("Test all the rotations");
|
println!("Test all the rotations");
|
||||||
let mut display = Display2in13bc::default();
|
let mut display = Display2in13bc::default();
|
||||||
let mut display_chromatic = Display2in13bc::default();
|
display.clear_buffer(TriColor::White);
|
||||||
|
|
||||||
display.set_rotation(DisplayRotation::Rotate0);
|
display.set_rotation(DisplayRotation::Rotate0);
|
||||||
draw_text(&mut display, "Rotation 0!", 5, 50);
|
draw_text(&mut display, "Rotation 0!", 5, 50);
|
||||||
|
|
@ -91,59 +91,62 @@ fn main() -> Result<(), std::io::Error> {
|
||||||
display.set_rotation(DisplayRotation::Rotate270);
|
display.set_rotation(DisplayRotation::Rotate270);
|
||||||
draw_text(&mut display, "Rotation 270!", 5, 50);
|
draw_text(&mut display, "Rotation 270!", 5, 50);
|
||||||
|
|
||||||
|
// Since we only used black and white, we can resort to updating only
|
||||||
|
// the bw-buffer of this tri-color screen
|
||||||
|
|
||||||
epd2in13
|
epd2in13
|
||||||
.update_and_display_frame(&mut spi, &display.buffer(), &mut delay)
|
.update_and_display_frame(&mut spi, &display.bw_buffer(), &mut delay)
|
||||||
.expect("display frame new graphics");
|
.expect("display frame new graphics");
|
||||||
|
|
||||||
println!("First frame done. Waiting 5s");
|
println!("First frame done. Waiting 5s");
|
||||||
delay.delay_ms(5000u16);
|
delay.delay_ms(5000u16);
|
||||||
|
|
||||||
println!("Now test new graphics with default rotation:");
|
println!("Now test new graphics with default rotation and three colors:");
|
||||||
display.clear_buffer(Color::White);
|
display.clear_buffer(TriColor::White);
|
||||||
display_chromatic.clear_buffer(Color::White);
|
|
||||||
// keep both displays on same rotation
|
|
||||||
display_chromatic.set_rotation(DisplayRotation::Rotate270);
|
|
||||||
|
|
||||||
// draw a analog clock
|
// draw a analog clock in black
|
||||||
let _ = Circle::new(Point::new(64, 64), 40)
|
let _ = Circle::new(Point::new(64, 64), 40)
|
||||||
.into_styled(PrimitiveStyle::with_stroke(Black, 1))
|
.into_styled(PrimitiveStyle::with_stroke(TriColor::Black, 1))
|
||||||
.draw(&mut display);
|
.draw(&mut display);
|
||||||
let _ = Line::new(Point::new(64, 64), Point::new(30, 40))
|
let _ = Line::new(Point::new(64, 64), Point::new(30, 40))
|
||||||
.into_styled(PrimitiveStyle::with_stroke(Black, 4))
|
.into_styled(PrimitiveStyle::with_stroke(TriColor::Black, 4))
|
||||||
.draw(&mut display);
|
.draw(&mut display);
|
||||||
let _ = Line::new(Point::new(64, 64), Point::new(80, 40))
|
let _ = Line::new(Point::new(64, 64), Point::new(80, 40))
|
||||||
.into_styled(PrimitiveStyle::with_stroke(Black, 1))
|
.into_styled(PrimitiveStyle::with_stroke(TriColor::Black, 1))
|
||||||
.draw(&mut display);
|
.draw(&mut display);
|
||||||
|
|
||||||
// draw text white on Red background by using the chromatic buffer
|
// draw text white on chromatic (red or yellow) background
|
||||||
|
|
||||||
let _ = Text::new("It's working-WoB!", Point::new(90, 10))
|
let _ = Text::new("It's working-WoB!", Point::new(90, 10))
|
||||||
.into_styled(text_style!(
|
.into_styled(text_style!(
|
||||||
font = Font6x8,
|
font = Font6x8,
|
||||||
text_color = White,
|
text_color = TriColor::White,
|
||||||
background_color = Black
|
background_color = TriColor::Chromatic
|
||||||
))
|
))
|
||||||
.draw(&mut display_chromatic);
|
.draw(&mut display);
|
||||||
|
|
||||||
// use bigger/different font
|
// use bigger/different font
|
||||||
let _ = Text::new("It's working-WoB!", Point::new(90, 40))
|
let _ = Text::new("It's working-WoB!", Point::new(90, 40))
|
||||||
.into_styled(text_style!(
|
.into_styled(text_style!(
|
||||||
font = Font12x16,
|
font = Font12x16,
|
||||||
text_color = White,
|
text_color = TriColor::White,
|
||||||
background_color = Black
|
background_color = TriColor::Chromatic
|
||||||
))
|
))
|
||||||
.draw(&mut display_chromatic);
|
.draw(&mut display);
|
||||||
|
|
||||||
epd2in13.update_color_frame(&mut spi, &display.buffer(), &display_chromatic.buffer())?;
|
// we used three colors, so we need to update both bw-buffer and chromatic-buffer
|
||||||
|
|
||||||
|
epd2in13.update_color_frame(&mut spi, display.bw_buffer(), display.chromatic_buffer())?;
|
||||||
epd2in13
|
epd2in13
|
||||||
.display_frame(&mut spi, &mut delay)
|
.display_frame(&mut spi, &mut delay)
|
||||||
.expect("display frame new graphics");
|
.expect("display frame new graphics");
|
||||||
|
|
||||||
println!("Second frame done. Waiting 5s");
|
println!("Second frame done. Waiting 5s");
|
||||||
delay.delay_ms(5000u16);
|
delay.delay_ms(5000u16);
|
||||||
|
|
||||||
display.clear_buffer(Color::White);
|
// clear both bw buffer and chromatic buffer
|
||||||
display_chromatic.clear_buffer(Color::White);
|
display.clear_buffer(TriColor::White);
|
||||||
epd2in13.update_color_frame(&mut spi, &display.buffer(), &display_chromatic.buffer())?;
|
epd2in13.update_color_frame(&mut spi, display.bw_buffer(), display.chromatic_buffer())?;
|
||||||
epd2in13.display_frame(&mut spi, &mut delay)?;
|
epd2in13.display_frame(&mut spi, &mut delay)?;
|
||||||
|
|
||||||
println!("Finished tests - going to sleep");
|
println!("Finished tests - going to sleep");
|
||||||
|
|
@ -154,8 +157,8 @@ fn draw_text(display: &mut Display2in13bc, text: &str, x: i32, y: i32) {
|
||||||
let _ = Text::new(text, Point::new(x, y))
|
let _ = Text::new(text, Point::new(x, y))
|
||||||
.into_styled(text_style!(
|
.into_styled(text_style!(
|
||||||
font = Font6x8,
|
font = Font6x8,
|
||||||
text_color = Black,
|
text_color = TriColor::Black,
|
||||||
background_color = White
|
background_color = TriColor::White
|
||||||
))
|
))
|
||||||
.draw(display);
|
.draw(display);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
23
src/color.rs
23
src/color.rs
|
|
@ -169,6 +169,29 @@ impl From<u8> for Color {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl TriColor {
|
||||||
|
/// Get the color encoding of the color for one bit
|
||||||
|
pub fn get_bit_value(self) -> u8 {
|
||||||
|
match self {
|
||||||
|
TriColor::White => 1u8,
|
||||||
|
TriColor::Black | TriColor::Chromatic => 0u8,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets a full byte of black or white pixels
|
||||||
|
pub fn get_byte_value(self) -> u8 {
|
||||||
|
match self {
|
||||||
|
TriColor::White => 0xff,
|
||||||
|
TriColor::Black | TriColor::Chromatic => 0x00,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "graphics")]
|
||||||
|
impl PixelColor for TriColor {
|
||||||
|
type Raw = ();
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
|
||||||
|
|
@ -1,30 +1,33 @@
|
||||||
|
use crate::color::TriColor;
|
||||||
use crate::epd2in13bc::{DEFAULT_BACKGROUND_COLOR, HEIGHT, NUM_DISPLAY_BITS, WIDTH};
|
use crate::epd2in13bc::{DEFAULT_BACKGROUND_COLOR, HEIGHT, NUM_DISPLAY_BITS, WIDTH};
|
||||||
use crate::graphics::{Display, DisplayRotation};
|
use crate::graphics::{DisplayRotation, TriDisplay};
|
||||||
use embedded_graphics::pixelcolor::BinaryColor;
|
|
||||||
use embedded_graphics::prelude::*;
|
use embedded_graphics::prelude::*;
|
||||||
|
|
||||||
/// Full size buffer for use with the 2in13b/c EPD
|
/// Full size buffer for use with the 2.13" b/c EPD
|
||||||
///
|
///
|
||||||
/// Can also be manually constructed and be used together with VarDisplay
|
/// Can also be manually constructed and be used together with VarDisplay
|
||||||
pub struct Display2in13bc {
|
pub struct Display2in13bc {
|
||||||
buffer: [u8; NUM_DISPLAY_BITS as usize],
|
// one buffer for both b/w and for chromatic:
|
||||||
|
// * &buffer[0..NUM_DISPLAY_BITS] for b/w buffer and
|
||||||
|
// * &buffer[NUM_DISPLAY_BITS..2*NUM_DISPLAY_BITS] for chromatic buffer
|
||||||
|
buffer: [u8; 2 * NUM_DISPLAY_BITS as usize],
|
||||||
rotation: DisplayRotation,
|
rotation: DisplayRotation,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Display2in13bc {
|
impl Default for Display2in13bc {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Display2in13bc {
|
Display2in13bc {
|
||||||
buffer: [DEFAULT_BACKGROUND_COLOR.get_byte_value(); NUM_DISPLAY_BITS as usize],
|
buffer: [DEFAULT_BACKGROUND_COLOR.get_byte_value(); 2 * NUM_DISPLAY_BITS as usize],
|
||||||
rotation: DisplayRotation::default(),
|
rotation: DisplayRotation::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DrawTarget<BinaryColor> for Display2in13bc {
|
impl DrawTarget<TriColor> for Display2in13bc {
|
||||||
type Error = core::convert::Infallible;
|
type Error = core::convert::Infallible;
|
||||||
|
|
||||||
fn draw_pixel(&mut self, pixel: Pixel<BinaryColor>) -> Result<(), Self::Error> {
|
fn draw_pixel(&mut self, pixel: Pixel<TriColor>) -> Result<(), Self::Error> {
|
||||||
self.draw_helper(WIDTH, HEIGHT, pixel)
|
self.draw_helper_tri(WIDTH, HEIGHT, pixel)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn size(&self) -> Size {
|
fn size(&self) -> Size {
|
||||||
|
|
@ -32,7 +35,7 @@ impl DrawTarget<BinaryColor> for Display2in13bc {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for Display2in13bc {
|
impl TriDisplay for Display2in13bc {
|
||||||
fn buffer(&self) -> &[u8] {
|
fn buffer(&self) -> &[u8] {
|
||||||
&self.buffer
|
&self.buffer
|
||||||
}
|
}
|
||||||
|
|
@ -48,4 +51,16 @@ impl Display for Display2in13bc {
|
||||||
fn rotation(&self) -> DisplayRotation {
|
fn rotation(&self) -> DisplayRotation {
|
||||||
self.rotation
|
self.rotation
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn chromatic_offset(&self) -> usize {
|
||||||
|
NUM_DISPLAY_BITS as usize
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bw_buffer(&self) -> &[u8] {
|
||||||
|
&self.buffer[0..self.chromatic_offset()]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn chromatic_buffer(&self) -> &[u8] {
|
||||||
|
&self.buffer[self.chromatic_offset()..]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,8 @@
|
||||||
//!```rust, no_run
|
//!```rust, no_run
|
||||||
//!# use embedded_hal_mock::*;
|
//!# use embedded_hal_mock::*;
|
||||||
//!# fn main() -> Result<(), MockError> {
|
//!# fn main() -> Result<(), MockError> {
|
||||||
//!use embedded_graphics::{
|
//!use embedded_graphics::{prelude::*, primitives::Line, style::PrimitiveStyle};
|
||||||
//! pixelcolor::BinaryColor::On as Black, prelude::*, primitives::Line, style::PrimitiveStyle,
|
//!use epd_waveshare::{epd2in13bc::*, prelude::*, color::TriColor};
|
||||||
//!};
|
|
||||||
//!use epd_waveshare::{epd2in13bc::*, prelude::*};
|
|
||||||
//!#
|
//!#
|
||||||
//!# let expectations = [];
|
//!# let expectations = [];
|
||||||
//!# let mut spi = spi::Mock::new(&expectations);
|
//!# let mut spi = spi::Mock::new(&expectations);
|
||||||
|
|
@ -25,28 +23,24 @@
|
||||||
//!let mut epd = Epd2in13bc::new(&mut spi, cs_pin, busy_in, dc, rst, &mut delay)?;
|
//!let mut epd = Epd2in13bc::new(&mut spi, cs_pin, busy_in, dc, rst, &mut delay)?;
|
||||||
//!
|
//!
|
||||||
//!// Use display graphics from embedded-graphics
|
//!// Use display graphics from embedded-graphics
|
||||||
//!// This display is for the black/white pixels
|
//!// This display is for the black/white/chromatic pixels
|
||||||
//!let mut mono_display = Display2in13bc::default();
|
//!let mut tricolor_display = Display2in13bc::default();
|
||||||
//!
|
//!
|
||||||
//!// Use embedded graphics for drawing
|
//!// Use embedded graphics for drawing a black line
|
||||||
//!// A black line
|
|
||||||
//!let _ = Line::new(Point::new(0, 120), Point::new(0, 200))
|
//!let _ = Line::new(Point::new(0, 120), Point::new(0, 200))
|
||||||
//! .into_styled(PrimitiveStyle::with_stroke(Black, 1))
|
//! .into_styled(PrimitiveStyle::with_stroke(TriColor::Black, 1))
|
||||||
//! .draw(&mut mono_display);
|
//! .draw(&mut tricolor_display);
|
||||||
//!
|
//!
|
||||||
//!// Use a second display for red/yellow
|
//!// We use `chromatic` but it will be shown as red/yellow
|
||||||
//!let mut chromatic_display = Display2in13bc::default();
|
|
||||||
//!
|
|
||||||
//!// We use `Black` but it will be shown as red/yellow
|
|
||||||
//!let _ = Line::new(Point::new(15, 120), Point::new(15, 200))
|
//!let _ = Line::new(Point::new(15, 120), Point::new(15, 200))
|
||||||
//! .into_styled(PrimitiveStyle::with_stroke(Black, 1))
|
//! .into_styled(PrimitiveStyle::with_stroke(TriColor::Chromatic, 1))
|
||||||
//! .draw(&mut chromatic_display);
|
//! .draw(&mut tricolor_display);
|
||||||
//!
|
//!
|
||||||
//!// Display updated frame
|
//!// Display updated frame
|
||||||
//!epd.update_color_frame(
|
//!epd.update_color_frame(
|
||||||
//! &mut spi,
|
//! &mut spi,
|
||||||
//! &mono_display.buffer(),
|
//! &tricolor_display.bw_buffer(),
|
||||||
//! &chromatic_display.buffer()
|
//! &tricolor_display.chromatic_buffer()
|
||||||
//!)?;
|
//!)?;
|
||||||
//!epd.display_frame(&mut spi, &mut delay)?;
|
//!epd.display_frame(&mut spi, &mut delay)?;
|
||||||
//!
|
//!
|
||||||
|
|
@ -70,8 +64,9 @@ pub const WIDTH: u32 = 104;
|
||||||
/// Height of epd2in13bc in pixels
|
/// Height of epd2in13bc in pixels
|
||||||
pub const HEIGHT: u32 = 212;
|
pub const HEIGHT: u32 = 212;
|
||||||
/// Default background color (white) of epd2in13bc display
|
/// Default background color (white) of epd2in13bc display
|
||||||
pub const DEFAULT_BACKGROUND_COLOR: Color = Color::White;
|
pub const DEFAULT_BACKGROUND_COLOR: TriColor = TriColor::White;
|
||||||
|
|
||||||
|
/// Number of bits for b/w buffer and same for chromatic buffer
|
||||||
const NUM_DISPLAY_BITS: u32 = WIDTH * HEIGHT / 8;
|
const NUM_DISPLAY_BITS: u32 = WIDTH * HEIGHT / 8;
|
||||||
|
|
||||||
const IS_BUSY_LOW: bool = true;
|
const IS_BUSY_LOW: bool = true;
|
||||||
|
|
@ -81,7 +76,7 @@ const BLACK_BORDER: u8 = 0x30;
|
||||||
const CHROMATIC_BORDER: u8 = 0xb0;
|
const CHROMATIC_BORDER: u8 = 0xb0;
|
||||||
const FLOATING_BORDER: u8 = 0xF0;
|
const FLOATING_BORDER: u8 = 0xF0;
|
||||||
|
|
||||||
use crate::color::{Color, TriColor};
|
use crate::color::TriColor;
|
||||||
|
|
||||||
pub(crate) mod command;
|
pub(crate) mod command;
|
||||||
use self::command::Command;
|
use self::command::Command;
|
||||||
|
|
@ -91,10 +86,10 @@ mod graphics;
|
||||||
#[cfg(feature = "graphics")]
|
#[cfg(feature = "graphics")]
|
||||||
pub use self::graphics::Display2in13bc;
|
pub use self::graphics::Display2in13bc;
|
||||||
|
|
||||||
/// Epd2in9bc driver
|
/// Epd2in13bc driver
|
||||||
pub struct Epd2in13bc<SPI, CS, BUSY, DC, RST, DELAY> {
|
pub struct Epd2in13bc<SPI, CS, BUSY, DC, RST, DELAY> {
|
||||||
interface: DisplayInterface<SPI, CS, BUSY, DC, RST, DELAY>,
|
interface: DisplayInterface<SPI, CS, BUSY, DC, RST, DELAY>,
|
||||||
color: Color,
|
color: TriColor,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<SPI, CS, BUSY, DC, RST, DELAY> InternalWiAdditions<SPI, CS, BUSY, DC, RST, DELAY>
|
impl<SPI, CS, BUSY, DC, RST, DELAY> InternalWiAdditions<SPI, CS, BUSY, DC, RST, DELAY>
|
||||||
|
|
@ -196,7 +191,7 @@ where
|
||||||
RST: OutputPin,
|
RST: OutputPin,
|
||||||
DELAY: DelayMs<u8>,
|
DELAY: DelayMs<u8>,
|
||||||
{
|
{
|
||||||
type DisplayColor = Color;
|
type DisplayColor = TriColor;
|
||||||
fn new(
|
fn new(
|
||||||
spi: &mut SPI,
|
spi: &mut SPI,
|
||||||
cs: CS,
|
cs: CS,
|
||||||
|
|
@ -236,11 +231,11 @@ where
|
||||||
self.init(spi, delay)
|
self.init(spi, delay)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_background_color(&mut self, color: Color) {
|
fn set_background_color(&mut self, color: TriColor) {
|
||||||
self.color = color;
|
self.color = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn background_color(&self) -> &Color {
|
fn background_color(&self) -> &TriColor {
|
||||||
&self.color
|
&self.color
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
//! Graphics Support for EPDs
|
//! Graphics Support for EPDs
|
||||||
|
|
||||||
use crate::buffer_len;
|
use crate::buffer_len;
|
||||||
use crate::color::{Color, OctColor};
|
use crate::color::{Color, OctColor, TriColor};
|
||||||
use embedded_graphics::{pixelcolor::BinaryColor, prelude::*};
|
use embedded_graphics::{pixelcolor::BinaryColor, prelude::*};
|
||||||
|
|
||||||
/// Displayrotation
|
/// Displayrotation
|
||||||
|
|
@ -85,6 +85,89 @@ pub trait Display: DrawTarget<BinaryColor> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Necessary traits for all displays to implement for drawing
|
||||||
|
///
|
||||||
|
/// Adds support for:
|
||||||
|
/// - Drawing (With the help of DrawTarget/Embedded Graphics)
|
||||||
|
/// - Rotations
|
||||||
|
/// - Clearing
|
||||||
|
pub trait TriDisplay: DrawTarget<TriColor> {
|
||||||
|
/// Clears the buffer of the display with the chosen background color
|
||||||
|
fn clear_buffer(&mut self, background_color: TriColor) {
|
||||||
|
for elem in self.get_mut_buffer().iter_mut() {
|
||||||
|
*elem = background_color.get_byte_value();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the buffer
|
||||||
|
fn buffer(&self) -> &[u8];
|
||||||
|
|
||||||
|
/// Returns a mutable buffer
|
||||||
|
fn get_mut_buffer(&mut self) -> &mut [u8];
|
||||||
|
|
||||||
|
/// Sets the rotation of the display
|
||||||
|
fn set_rotation(&mut self, rotation: DisplayRotation);
|
||||||
|
|
||||||
|
/// Get the current rotation of the display
|
||||||
|
fn rotation(&self) -> DisplayRotation;
|
||||||
|
|
||||||
|
/// Get the offset into buffer where chromatic data starts
|
||||||
|
fn chromatic_offset(&self) -> usize;
|
||||||
|
|
||||||
|
/// return the b/w part of the buffer
|
||||||
|
fn bw_buffer(&self) -> &[u8];
|
||||||
|
|
||||||
|
/// return the chromatic part of the buffer
|
||||||
|
fn chromatic_buffer(&self) -> &[u8];
|
||||||
|
|
||||||
|
/// Helperfunction for the Embedded Graphics draw trait
|
||||||
|
///
|
||||||
|
/// Becomes uneccesary when const_generics become stablised
|
||||||
|
fn draw_helper_tri(
|
||||||
|
&mut self,
|
||||||
|
width: u32,
|
||||||
|
height: u32,
|
||||||
|
pixel: Pixel<TriColor>,
|
||||||
|
) -> Result<(), Self::Error> {
|
||||||
|
let rotation = self.rotation();
|
||||||
|
|
||||||
|
let Pixel(point, color) = pixel;
|
||||||
|
if outside_display(point, width, height, rotation) {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Give us index inside the buffer and the bit-position in that u8 which needs to be changed
|
||||||
|
let (index, bit) = find_position(point.x as u32, point.y as u32, width, height, rotation);
|
||||||
|
let index = index as usize;
|
||||||
|
let offset = self.chromatic_offset();
|
||||||
|
|
||||||
|
let buffer = self.get_mut_buffer();
|
||||||
|
|
||||||
|
// "Draw" the Pixel on that bit
|
||||||
|
match color {
|
||||||
|
TriColor::Black => {
|
||||||
|
// clear bit in bw-buffer -> black
|
||||||
|
buffer[index] &= !bit;
|
||||||
|
// set bit in chromatic-buffer -> white
|
||||||
|
buffer[index + offset] |= bit;
|
||||||
|
}
|
||||||
|
TriColor::White => {
|
||||||
|
// set bit in bw-buffer -> white
|
||||||
|
buffer[index] |= bit;
|
||||||
|
// set bit in chromatic-buffer -> white
|
||||||
|
buffer[index + offset] |= bit;
|
||||||
|
}
|
||||||
|
TriColor::Chromatic => {
|
||||||
|
// set bit in b/w buffer (white)
|
||||||
|
buffer[index] |= bit;
|
||||||
|
// clear bit in chromatic buffer -> chromatic
|
||||||
|
buffer[index + offset] &= !bit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Necessary traits for all displays to implement for drawing
|
/// Necessary traits for all displays to implement for drawing
|
||||||
///
|
///
|
||||||
/// Adds support for:
|
/// Adds support for:
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,7 @@ pub mod prelude {
|
||||||
pub use crate::SPI_MODE;
|
pub use crate::SPI_MODE;
|
||||||
|
|
||||||
#[cfg(feature = "graphics")]
|
#[cfg(feature = "graphics")]
|
||||||
pub use crate::graphics::{Display, DisplayRotation, OctDisplay};
|
pub use crate::graphics::{Display, DisplayRotation, OctDisplay, TriDisplay};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the needed buffer length. Takes care of rounding up in case width
|
/// Computes the needed buffer length. Takes care of rounding up in case width
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue