Better handling for screen size not divisible by 8
Screen with width not divisible by 8 require special care when allocating the buffer and when handling rotation. Define a function for getting the needed buffer size (round up to next byte). Change how rotation is done by changing coordinates instead of direct pixel access.embedded-hal-1.0
parent
22f16eaa05
commit
82b8c98538
|
|
@ -1,5 +1,6 @@
|
|||
//! Graphics Support for EPDs
|
||||
|
||||
use crate::buffer_len;
|
||||
use crate::color::Color;
|
||||
use embedded_graphics::{pixelcolor::BinaryColor, prelude::*};
|
||||
|
||||
|
|
@ -88,6 +89,7 @@ pub trait Display: DrawTarget<BinaryColor> {
|
|||
///
|
||||
/// The buffer can be created as following:
|
||||
/// buffer: [DEFAULT_BACKGROUND_COLOR.get_byte_value(); WIDTH / 8 * HEIGHT]
|
||||
/// If WIDTH is not a multiple of 8, don't forget to round it up (ie. (WIDTH + 7) / 8)
|
||||
///
|
||||
/// Example:
|
||||
/// ```rust,no_run
|
||||
|
|
@ -120,10 +122,10 @@ pub struct VarDisplay<'a> {
|
|||
impl<'a> VarDisplay<'a> {
|
||||
/// Create a new variable sized display.
|
||||
///
|
||||
/// Buffersize must be at least width / 8 * height bytes.
|
||||
/// Buffersize must be at least (width + 7) / 8 * height bytes.
|
||||
pub fn new(width: u32, height: u32, buffer: &'a mut [u8]) -> VarDisplay<'a> {
|
||||
let len = buffer.len() as u32;
|
||||
assert!(width / 8 * height >= len);
|
||||
assert!(buffer_len(width as usize, height as usize) >= len as usize);
|
||||
VarDisplay {
|
||||
width,
|
||||
height,
|
||||
|
|
@ -187,29 +189,36 @@ fn outside_display(p: Point, width: u32, height: u32, rotation: DisplayRotation)
|
|||
#[rustfmt::skip]
|
||||
//returns index position in the u8-slice and the bit-position inside that u8
|
||||
fn find_position(x: u32, y: u32, width: u32, height: u32, rotation: DisplayRotation) -> (u32, u8) {
|
||||
let nx;
|
||||
let ny;
|
||||
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),
|
||||
),
|
||||
DisplayRotation::Rotate0 => {
|
||||
nx = x;
|
||||
ny = y;
|
||||
},
|
||||
DisplayRotation::Rotate90 => {
|
||||
nx = width - 1 - y;
|
||||
ny = x;
|
||||
} ,
|
||||
DisplayRotation::Rotate180 => {
|
||||
nx = width - 1 - x;
|
||||
ny = height - 1 - y;
|
||||
},
|
||||
DisplayRotation::Rotate270 => {
|
||||
nx = y;
|
||||
ny = height - 1 - x;
|
||||
},
|
||||
}
|
||||
|
||||
(
|
||||
nx / 8 + ((width + 7) / 8) * ny,
|
||||
0x80 >> (nx % 8),
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{find_position, outside_display, Display, DisplayRotation, VarDisplay};
|
||||
use super::{buffer_len, find_position, outside_display, Display, DisplayRotation, VarDisplay};
|
||||
use crate::color::Black;
|
||||
use crate::color::Color;
|
||||
use embedded_graphics::{prelude::*, primitives::Line, style::PrimitiveStyle};
|
||||
|
|
@ -218,7 +227,8 @@ mod tests {
|
|||
fn buffer_clear() {
|
||||
use crate::epd4in2::{HEIGHT, WIDTH};
|
||||
|
||||
let mut buffer = [Color::Black.get_byte_value(); WIDTH as usize / 8 * HEIGHT as usize];
|
||||
let mut buffer =
|
||||
[Color::Black.get_byte_value(); buffer_len(WIDTH as usize, HEIGHT as usize)];
|
||||
let mut display = VarDisplay::new(WIDTH, HEIGHT, &mut buffer);
|
||||
|
||||
for &byte in display.buffer.iter() {
|
||||
|
|
|
|||
13
src/lib.rs
13
src/lib.rs
|
|
@ -92,6 +92,19 @@ pub mod prelude {
|
|||
pub use crate::graphics::{Display, DisplayRotation};
|
||||
}
|
||||
|
||||
/// Computes the needed buffer length. Takes care of rounding up in case width
|
||||
/// is not divisible by 8.
|
||||
///
|
||||
/// unused
|
||||
/// bits width
|
||||
/// <----><------------------------>
|
||||
/// [XXXXX210][76543210]...[76543210] ^
|
||||
/// [XXXXX210][76543210]...[76543210] | height
|
||||
/// [XXXXX210][76543210]...[76543210] v
|
||||
pub const fn buffer_len(width: usize, height: usize) -> usize {
|
||||
(width + 7) / 8 * height
|
||||
}
|
||||
|
||||
use embedded_hal::spi::{Mode, Phase, Polarity};
|
||||
|
||||
/// SPI mode -
|
||||
|
|
|
|||
Loading…
Reference in New Issue