diff --git a/pico-st7789/src/canvas.rs b/pico-st7789/src/canvas.rs index cb2d05b..7a16821 100644 --- a/pico-st7789/src/canvas.rs +++ b/pico-st7789/src/canvas.rs @@ -8,118 +8,55 @@ // e c // d d d -use alloc::collections::btree_map::BTreeMap; +use crate::font::{Font, Glyph}; -/* -*/ - -pub struct RGB { pub r: u8, pub g: u8, pub b: u8 } +pub struct RGB { + pub r: u8, + pub g: u8, + pub b: u8, +} pub trait Canvas { fn set_pixel(&mut self, x: usize, y: usize, color: &RGB); + fn fill(&mut self, x1: usize, y1: usize, x2: usize, y2: usize, color: &RGB) { + for x in x1..x2 + 1 { + for y in y1..y2 + 1 { + self.set_pixel(x, y, color); + } + } + } + fn square(&mut self, x1: usize, y1: usize, x2: usize, y2: usize, color: &RGB) { - for x in x1..x2+1 { + for x in x1..x2 + 1 { self.set_pixel(x, y1, color); } - for x in x1..x2+1 { + for x in x1..x2 + 1 { self.set_pixel(x, y2, color); } - for y in y1..y2+1 { + for y in y1..y2 + 1 { self.set_pixel(x1, y, color); } - for y in y1..y2+1 { + for y in y1..y2 + 1 { self.set_pixel(x2, y, color); } } } -/* -pub const DIGIT_WIDTH: usize = 5; -pub const DIGIT_HEIGHT: usize = 9; - -pub const ZERO_SEVEN_SEGMENT: [bool; 7] = [true, true, true, true, true, true, false]; - -pub const ONE_SEVEN_SEGMENT: [bool; 7] = [false, true, true, false, false, false, false]; - -pub const TWO_SEVEN_SEGMENT: [bool; 7] = [true, true, false, true, true, false, true]; - -pub const THREE_SEVEN_SEGMENT: [bool; 7] = [true, true, true, true, false, false, true]; - -pub const FOUR_SEVEN_SEGMENT: [bool; 7] = [false, true, true, false, false, true, true]; - -pub const FIVE_SEVEN_SEGMENT: [bool; 7] = [true, false, true, true, false, true, true]; - -pub const SIX_SEVEN_SEGMENT: [bool; 7] = [true, false, true, true, true, true, true]; - -pub const SEVEN_SEVEN_SEGMENT: [bool; 7] = [true, true, true, false, false, false, false]; - -pub const EIGHT_SEVEN_SEGMENT: [bool; 7] = [true, true, true, true, true, true, true]; - -pub const NINE_SEVEN_SEGMENT: [bool; 7] = [true, true, true, false, false, true, true]; - -pub const SEVEN_SEGMENT_FONT: [[bool; 7]; 10] = [ - ZERO_SEVEN_SEGMENT, - ONE_SEVEN_SEGMENT, - TWO_SEVEN_SEGMENT, - THREE_SEVEN_SEGMENT, - FOUR_SEVEN_SEGMENT, - FIVE_SEVEN_SEGMENT, - SIX_SEVEN_SEGMENT, - SEVEN_SEVEN_SEGMENT, - EIGHT_SEVEN_SEGMENT, - NINE_SEVEN_SEGMENT, -]; - -pub fn write_pixel(framebuf: &mut [u8], width: usize, x: usize, y: usize, color: (u8, u8, u8)) { - framebuf[(y * width + x) * 3 + 0] = color.0 << 2; - framebuf[(y * width + x) * 3 + 1] = color.1 << 2; - framebuf[(y * width + x) * 3 + 2] = color.2 << 2; -} - -pub fn draw_seven_segment( - digit: u8, - frame: &mut [u8], - width: usize, - x: usize, - y: usize, - color: (u8, u8, u8), -) { - let segments = SEVEN_SEGMENT_FONT[digit as usize]; - if segments[0] { - write_pixel(frame, width, x + 1, y, color); - write_pixel(frame, width, x + 2, y, color); - write_pixel(frame, width, x + 3, y, color); - } - if segments[1] { - write_pixel(frame, width, x + 4, y + 1, color); - write_pixel(frame, width, x + 4, y + 2, color); - write_pixel(frame, width, x + 4, y + 3, color); - } - if segments[2] { - write_pixel(frame, width, x + 4, y + 5, color); - write_pixel(frame, width, x + 4, y + 6, color); - write_pixel(frame, width, x + 4, y + 7, color); - } - if segments[3] { - write_pixel(frame, width, x + 1, y + 8, color); - write_pixel(frame, width, x + 2, y + 8, color); - write_pixel(frame, width, x + 3, y + 8, color); - } - if segments[4] { - write_pixel(frame, width, x, y + 5, color); - write_pixel(frame, width, x, y + 6, color); - write_pixel(frame, width, x, y + 7, color); - } - if segments[5] { - write_pixel(frame, width, x, y + 1, color); - write_pixel(frame, width, x, y + 2, color); - write_pixel(frame, width, x, y + 3, color); - } - if segments[6] { - write_pixel(frame, width, x + 1, y + 4, color); - write_pixel(frame, width, x + 2, y + 4, color); - write_pixel(frame, width, x + 3, y + 4, color); +pub fn print<A>( + canvas: &mut impl Canvas, + font: &impl Font<A>, + sx: usize, + sy: usize, + text: &str, + color: &RGB, +) where + A: Glyph, +{ + let mut x = sx; + for c in text.chars().map(|c| font.glyph(c)) { + c.draw(canvas, x, sy, color); + let (dx, _) = c.extents(); + x = x + dx + 1; } } -*/ diff --git a/pico-st7789/src/font/bits_5_8.rs b/pico-st7789/src/font/bits_5_8.rs new file mode 100644 index 0000000..ecada60 --- /dev/null +++ b/pico-st7789/src/font/bits_5_8.rs @@ -0,0 +1,513 @@ +use alloc::collections::btree_map::BTreeMap; + +use crate::canvas::{Canvas, RGB}; + +use super::{Font, Glyph}; + +pub struct BitmapGlyph([u8; 7]); + +pub struct BitmapFont(BTreeMap<char, BitmapGlyph>); + +impl BitmapFont { + pub fn new() -> Self { + let mut font = BTreeMap::new(); + font.insert(' ', BitmapGlyph([ + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + ])); + font.insert( + ':', + BitmapGlyph([ + 0b00000, + 0b00100, + 0b00100, + 0b00000, + 0b00100, + 0b00100, + 0b00000, + ]), + ); + font.insert( + '/', + BitmapGlyph([ + 0b00001, + 0b00010, + 0b00010, + 0b00100, + 0b01000, + 0b01000, + 0b10000, + ]), + ); + font.insert( + '0', + BitmapGlyph([ + 0b01110, + 0b10001, + 0b10001, + 0b10101, + 0b10001, + 0b10001, + 0b01110, + ]), + ); + font.insert( + '1', + BitmapGlyph([ + 0b00001, + 0b00011, + 0b00101, + 0b00001, + 0b00001, + 0b00001, + 0b00001, + ]), + ); + font.insert( + '2', + BitmapGlyph([ + 0b01110, + 0b10001, + 0b00001, + 0b00010, + 0b00100, + 0b01000, + 0b11111, + ]), + ); + font.insert( + '3', + BitmapGlyph([ + 0b01110, + 0b10001, + 0b00001, + 0b01110, + 0b00001, + 0b10001, + 0b01110, + ]), + ); + font.insert( + '4', + BitmapGlyph([ + 0b10001, + 0b10001, + 0b10001, + 0b11111, + 0b00001, + 0b00001, + 0b00001, + ]), + ); + font.insert( + '5', + BitmapGlyph([ + 0b11111, + 0b10000, + 0b10000, + 0b11111, + 0b00001, + 0b10001, + 0b01110, + ]), + ); + font.insert( + '6', + BitmapGlyph([ + 0b01110, + 0b10001, + 0b10000, + 0b11110, + 0b10001, + 0b10001, + 0b01110, + ]), + ); + font.insert( + '7', + BitmapGlyph([ + 0b11111, + 0b00001, + 0b00010, + 0b00110, + 0b00100, + 0b01000, + 0b01000, + ]), + ); + font.insert( + '8', + BitmapGlyph([ + 0b01110, + 0b10001, + 0b10001, + 0b01110, + 0b10001, + 0b10001, + 0b01110, + ]), + ); + font.insert( + '9', + BitmapGlyph([ + 0b01110, + 0b10001, + 0b10001, + 0b01111, + 0b00001, + 0b00001, + 0b01110, + ]), + ); + font.insert( + 'A', + BitmapGlyph([ + 0b00100, + 0b01010, + 0b01010, + 0b10001, + 0b11111, + 0b10001, + 0b10001, + ]), + ); + font.insert( + 'B', + BitmapGlyph([ + 0b11110, + 0b10001, + 0b10001, + 0b1111 , + 0b10001, + 0b10001, + 0b11110, + ]), + ); + font.insert( + 'C', + BitmapGlyph([ + 0b01110, + 0b10001, + 0b10000, + 0b10000, + 0b10000, + 0b10001, + 0b01110, + ]), + ); + font.insert( + 'D', + BitmapGlyph([ + 0b11110, + 0b10001, + 0b10001, + 0b10001, + 0b10001, + 0b10001, + 0b11110, + ]), + ); + font.insert( + 'E', + BitmapGlyph([ + 0b11111, + 0b10000, + 0b10000, + 0b11111, + 0b10000, + 0b10000, + 0b11111, + ]), + ); + font.insert( + 'F', + BitmapGlyph([ + 0b11111, + 0b10000, + 0b10000, + 0b11110, + 0b10000, + 0b10000, + 0b10000, + ]), + ); + font.insert( + 'G', + BitmapGlyph([ + 0b01110, + 0b10001, + 0b10000, + 0b10011, + 0b10001, + 0b10001, + 0b01110, + ]), + ); + font.insert( + 'H', + BitmapGlyph([ + 0b10001, + 0b10001, + 0b10001, + 0b11111, + 0b10001, + 0b10001, + 0b10001, + ]), + ); + font.insert( + 'I', + BitmapGlyph([ + 0b11111, + 0b00100, + 0b00100, + 0b00100, + 0b00100, + 0b00100, + 0b11111, + ]), + ); + font.insert( + 'J', + BitmapGlyph([ + 0b00111, + 0b00001, + 0b00001, + 0b00001, + 0b00001, + 0b10001, + 0b01110, + ]), + ); + font.insert( + 'K', + BitmapGlyph([ + 0b10001, + 0b10010, + 0b10100, + 0b11000, + 0b10100, + 0b10010, + 0b10001, + ]), + ); + font.insert( + 'L', + BitmapGlyph([ + 0b10000, + 0b10000, + 0b10000, + 0b10000, + 0b10000, + 0b10000, + 0b11111, + ]), + ); + font.insert( + 'M', + BitmapGlyph([ + 0b10001, + 0b11011, + 0b10101, + 0b10001, + 0b10001, + 0b10001, + 0b10001, + ]), + ); + font.insert( + 'N', + BitmapGlyph([ + 0b10001, + 0b11001, + 0b11001, + 0b10101, + 0b10011, + 0b10011, + 0b10001, + ]), + ); + font.insert( + 'O', + BitmapGlyph([ + 0b01110, + 0b10001, + 0b10001, + 0b10001, + 0b10001, + 0b10001, + 0b01110, + ]), + ); + font.insert( + 'P', + BitmapGlyph([ + 0b11110, + 0b10001, + 0b10001, + 0b11110, + 0b10000, + 0b10000, + 0b10000, + ]), + ); + font.insert( + 'Q', + BitmapGlyph([ + 0b01110, + 0b10001, + 0b10001, + 0b10001, + 0b10101, + 0b10011, + 0b01110, + ]), + ); + font.insert( + 'R', + BitmapGlyph([ + 0b11110, + 0b10001, + 0b10001, + 0b11110, + 0b10100, + 0b10010, + 0b10001, + ]), + ); + font.insert( + 'S', + BitmapGlyph([ + 0b01110, + 0b10001, + 0b10000, + 0b01110, + 0b00001, + 0b10001, + 0b01110, + ]), + ); + font.insert( + 'T', + BitmapGlyph([ + 0b11111, + 0b00100, + 0b00100, + 0b00100, + 0b00100, + 0b00100, + 0b00100, + ]), + ); + font.insert( + 'U', + BitmapGlyph([ + 0b10001, + 0b10001, + 0b10001, + 0b10001, + 0b10001, + 0b10001, + 0b01110, + ]), + ); + font.insert( + 'V', + BitmapGlyph([ + 0b10001, + 0b10001, + 0b10001, + 0b10001, + 0b01010, + 0b01010, + 0b00100, + ]), + ); + font.insert( + 'W', + BitmapGlyph([ + 0b10001, + 0b10001, + 0b10001, + 0b10001, + 0b10101, + 0b10101, + 0b01010, + ]), + ); + font.insert( + 'X', + BitmapGlyph([ + 0b10001, + 0b10001, + 0b01010, + 0b00100, + 0b01010, + 0b10001, + 0b10001, + ]), + ); + font.insert( + 'Y', + BitmapGlyph([ + 0b10001, + 0b10001, + 0b01010, + 0b00100, + 0b00100, + 0b00100, + 0b00100, + ]), + ); + font.insert( + 'Z', + BitmapGlyph([ + 0b11111, + 0b00001, + 0b00010, + 0b00100, + 0b01000, + 0b10000, + 0b11111, + ]), + ); + Self(font) + } +} + +impl Font<BitmapGlyph> for BitmapFont { + fn glyph(&self, c: char) -> &BitmapGlyph { + self.0.get(&c).unwrap_or(self.0.get(&' ').unwrap()) + } +} + +impl Glyph for BitmapGlyph { + fn draw(&self, canvas: &mut impl Canvas, x: usize, y: usize, color: &RGB) { + for row in 0..7 { + if self.0[row] & (1 << 4) > 0 { + canvas.set_pixel(x, y + row, color); + } + if self.0[row] & (1 << 3) > 0 { + canvas.set_pixel(x + 1, y + row, color); + } + if self.0[row] & (1 << 2) > 0 { + canvas.set_pixel(x + 2, y + row, color); + } + if self.0[row] & (1 << 1) > 0 { + canvas.set_pixel(x + 3, y + row, color); + } + if self.0[row] & 1 > 0 { + canvas.set_pixel(x + 4, y + row, color); + } + } + } + + fn extents(&self) -> (usize, usize) { + (5, 7) + } +} diff --git a/pico-st7789/src/font/mod.rs b/pico-st7789/src/font/mod.rs index 126176d..f20065b 100644 --- a/pico-st7789/src/font/mod.rs +++ b/pico-st7789/src/font/mod.rs @@ -1,5 +1,11 @@ use crate::canvas::{Canvas, RGB}; +mod bits_5_8; +pub use bits_5_8::BitmapFont; + +mod seven_segment; +pub use seven_segment::SevenSegmentFont; + mod sixteen_segment; pub use sixteen_segment::SixteenSegmentFont; @@ -9,5 +15,6 @@ pub trait Font<A> { pub trait Glyph { fn draw(&self, canvas: &mut impl Canvas, x: usize, y: usize, color: &RGB); + fn extents(&self) -> (usize, usize); } diff --git a/pico-st7789/src/font/seven_segment.rs b/pico-st7789/src/font/seven_segment.rs new file mode 100644 index 0000000..94dd8cd --- /dev/null +++ b/pico-st7789/src/font/seven_segment.rs @@ -0,0 +1,211 @@ +use alloc::collections::btree_map::BTreeMap; +use bitflags::bitflags; + +use crate::canvas::{Canvas, RGB}; + +use super::{Font, Glyph}; + +// Seven Segments +// +// a a a +// f b +// f b +// f b +// g g g +// e c +// e c +// e c +// d d d + +bitflags! { + pub struct SevenSegmentGlyph: u8 { + const NONE = 0; + const A = 0x01; + const B = 0x01 << 1; + const C = 0x01 << 2; + const D = 0x01 << 3; + const E = 0x01 << 4; + const F = 0x01 << 5; + const G = 0x01 << 6; + const DOT = 0x01 << 7; + } +} + +pub struct SevenSegmentFont(BTreeMap<char, SevenSegmentGlyph>); + +impl SevenSegmentFont { + pub fn new() -> Self { + let mut font = BTreeMap::new(); + font.insert(' ', SevenSegmentGlyph::NONE); + font.insert( + '0', + SevenSegmentGlyph::A + | SevenSegmentGlyph::B + | SevenSegmentGlyph::C + | SevenSegmentGlyph::D + | SevenSegmentGlyph::E + | SevenSegmentGlyph::F, + ); + font.insert('1', SevenSegmentGlyph::B | SevenSegmentGlyph::C); + font.insert( + '2', + SevenSegmentGlyph::A + | SevenSegmentGlyph::B + | SevenSegmentGlyph::D + | SevenSegmentGlyph::E + | SevenSegmentGlyph::G, + ); + font.insert( + '3', + SevenSegmentGlyph::A + | SevenSegmentGlyph::B + | SevenSegmentGlyph::C + | SevenSegmentGlyph::G + | SevenSegmentGlyph::D, + ); + font.insert( + '4', + SevenSegmentGlyph::B + | SevenSegmentGlyph::C + | SevenSegmentGlyph::F + | SevenSegmentGlyph::G, + ); + font.insert( + '5', + SevenSegmentGlyph::A + | SevenSegmentGlyph::C + | SevenSegmentGlyph::D + | SevenSegmentGlyph::F + | SevenSegmentGlyph::G, + ); + font.insert( + '6', + SevenSegmentGlyph::A + | SevenSegmentGlyph::E + | SevenSegmentGlyph::F + | SevenSegmentGlyph::G + | SevenSegmentGlyph::C + | SevenSegmentGlyph::D, + ); + font.insert( + '7', + SevenSegmentGlyph::A | SevenSegmentGlyph::B | SevenSegmentGlyph::C, + ); + font.insert( + '8', + SevenSegmentGlyph::A + | SevenSegmentGlyph::B + | SevenSegmentGlyph::C + | SevenSegmentGlyph::D + | SevenSegmentGlyph::E + | SevenSegmentGlyph::F + | SevenSegmentGlyph::G, + ); + font.insert( + '9', + SevenSegmentGlyph::A + | SevenSegmentGlyph::B + | SevenSegmentGlyph::C + | SevenSegmentGlyph::F + | SevenSegmentGlyph::G, + ); + font.insert( + 'A', + SevenSegmentGlyph::A + | SevenSegmentGlyph::B + | SevenSegmentGlyph::C + | SevenSegmentGlyph::E + | SevenSegmentGlyph::F + | SevenSegmentGlyph::G, + ); + font.insert( + 'B', + SevenSegmentGlyph::C + | SevenSegmentGlyph::D + | SevenSegmentGlyph::E + | SevenSegmentGlyph::F + | SevenSegmentGlyph::G, + ); + font.insert( + 'C', + SevenSegmentGlyph::A + | SevenSegmentGlyph::D + | SevenSegmentGlyph::E + | SevenSegmentGlyph::F, + ); + font.insert( + 'D', + SevenSegmentGlyph::B + | SevenSegmentGlyph::C + | SevenSegmentGlyph::D + | SevenSegmentGlyph::E + | SevenSegmentGlyph::G, + ); + font.insert( + 'E', + SevenSegmentGlyph::A + | SevenSegmentGlyph::D + | SevenSegmentGlyph::E + | SevenSegmentGlyph::F + | SevenSegmentGlyph::G, + ); + font.insert( + 'F', + SevenSegmentGlyph::A + | SevenSegmentGlyph::E + | SevenSegmentGlyph::F + | SevenSegmentGlyph::G, + ); + Self(font) + } +} + +impl Font<SevenSegmentGlyph> for SevenSegmentFont { + fn glyph(&self, c: char) -> &SevenSegmentGlyph { + self.0.get(&c).unwrap() + } +} + +impl Glyph for SevenSegmentGlyph { + fn draw(&self, canvas: &mut impl Canvas, x: usize, y: usize, color: &RGB) { + if self.contains(SevenSegmentGlyph::A) { + canvas.set_pixel(x + 1, y, color); + canvas.set_pixel(x + 2, y, color); + canvas.set_pixel(x + 3, y, color); + } + if self.contains(SevenSegmentGlyph::B) { + canvas.set_pixel(x + 4, y + 1, color); + canvas.set_pixel(x + 4, y + 2, color); + canvas.set_pixel(x + 4, y + 3, color); + } + if self.contains(SevenSegmentGlyph::C) { + canvas.set_pixel(x + 4, y + 5, color); + canvas.set_pixel(x + 4, y + 6, color); + canvas.set_pixel(x + 4, y + 7, color); + } + if self.contains(SevenSegmentGlyph::D) { + canvas.set_pixel(x + 1, y + 8, color); + canvas.set_pixel(x + 2, y + 8, color); + canvas.set_pixel(x + 3, y + 8, color); + } + if self.contains(SevenSegmentGlyph::E) { + canvas.set_pixel(x, y + 5, color); + canvas.set_pixel(x, y + 6, color); + canvas.set_pixel(x, y + 7, color); + } + if self.contains(SevenSegmentGlyph::F) { + canvas.set_pixel(x, y + 1, color); + canvas.set_pixel(x, y + 2, color); + canvas.set_pixel(x, y + 3, color); + } + if self.contains(SevenSegmentGlyph::G) { + canvas.set_pixel(x + 1, y + 4, color); + canvas.set_pixel(x + 2, y + 4, color); + canvas.set_pixel(x + 3, y + 4, color); + } + } + + fn extents(&self) -> (usize, usize) { + (5, 8) + } +} diff --git a/pico-st7789/src/font/sixteen_segment.rs b/pico-st7789/src/font/sixteen_segment.rs index fe021ff..eb8cb29 100644 --- a/pico-st7789/src/font/sixteen_segment.rs +++ b/pico-st7789/src/font/sixteen_segment.rs @@ -396,13 +396,182 @@ impl SixteenSegmentFont { | SixteenSegmentGlyph::J | SixteenSegmentGlyph::K, ); + + font.insert( + 'a', + SixteenSegmentGlyph::D1 + | SixteenSegmentGlyph::D2 + | SixteenSegmentGlyph::E + | SixteenSegmentGlyph::G1 + | SixteenSegmentGlyph::L, + ); + font.insert( + 'b', + SixteenSegmentGlyph::D1 + | SixteenSegmentGlyph::E + | SixteenSegmentGlyph::F + | SixteenSegmentGlyph::G1 + | SixteenSegmentGlyph::L, + ); + font.insert( + 'c', + SixteenSegmentGlyph::D1 | SixteenSegmentGlyph::E | SixteenSegmentGlyph::G1, + ); + font.insert( + 'd', + SixteenSegmentGlyph::B + | SixteenSegmentGlyph::C + | SixteenSegmentGlyph::D2 + | SixteenSegmentGlyph::G2 + | SixteenSegmentGlyph::L, + ); + font.insert( + 'e', + SixteenSegmentGlyph::D1 + | SixteenSegmentGlyph::E + | SixteenSegmentGlyph::G1 + | SixteenSegmentGlyph::K, + ); + font.insert( + 'f', + SixteenSegmentGlyph::A2 + | SixteenSegmentGlyph::G1 + | SixteenSegmentGlyph::G2 + | SixteenSegmentGlyph::I + | SixteenSegmentGlyph::L, + ); + font.insert( + 'g', + SixteenSegmentGlyph::A1 + | SixteenSegmentGlyph::D1 + | SixteenSegmentGlyph::F + | SixteenSegmentGlyph::G1 + | SixteenSegmentGlyph::I + | SixteenSegmentGlyph::L, + ); + font.insert( + 'h', + SixteenSegmentGlyph::E + | SixteenSegmentGlyph::F + | SixteenSegmentGlyph::G1 + | SixteenSegmentGlyph::L, + ); + font.insert('i', SixteenSegmentGlyph::L); + font.insert( + 'j', + SixteenSegmentGlyph::D1 + | SixteenSegmentGlyph::E + | SixteenSegmentGlyph::I + | SixteenSegmentGlyph::L, + ); + font.insert( + 'k', + SixteenSegmentGlyph::I + | SixteenSegmentGlyph::J + | SixteenSegmentGlyph::L + | SixteenSegmentGlyph::M, + ); + font.insert('l', SixteenSegmentGlyph::E | SixteenSegmentGlyph::F); + font.insert( + 'm', + SixteenSegmentGlyph::C + | SixteenSegmentGlyph::E + | SixteenSegmentGlyph::L + | SixteenSegmentGlyph::G1 + | SixteenSegmentGlyph::G2, + ); + font.insert( + 'n', + SixteenSegmentGlyph::E | SixteenSegmentGlyph::L | SixteenSegmentGlyph::G1, + ); + font.insert( + 'o', + SixteenSegmentGlyph::D1 + | SixteenSegmentGlyph::E + | SixteenSegmentGlyph::G1 + | SixteenSegmentGlyph::L, + ); + font.insert( + 'p', + SixteenSegmentGlyph::A1 + | SixteenSegmentGlyph::E + | SixteenSegmentGlyph::F + | SixteenSegmentGlyph::G1 + | SixteenSegmentGlyph::I, + ); + font.insert( + 'q', + SixteenSegmentGlyph::A1 + | SixteenSegmentGlyph::F + | SixteenSegmentGlyph::G1 + | SixteenSegmentGlyph::I + | SixteenSegmentGlyph::L, + ); + font.insert('r', SixteenSegmentGlyph::E | SixteenSegmentGlyph::G1); + font.insert( + 's', + SixteenSegmentGlyph::A1 + | SixteenSegmentGlyph::D1 + | SixteenSegmentGlyph::F + | SixteenSegmentGlyph::G1 + | SixteenSegmentGlyph::L, + ); + font.insert( + 't', + SixteenSegmentGlyph::D1 + | SixteenSegmentGlyph::E + | SixteenSegmentGlyph::F + | SixteenSegmentGlyph::G1, + ); + font.insert( + 'u', + SixteenSegmentGlyph::D1 | SixteenSegmentGlyph::E | SixteenSegmentGlyph::L, + ); + font.insert('v', SixteenSegmentGlyph::E | SixteenSegmentGlyph::K); + font.insert( + 'w', + SixteenSegmentGlyph::C + | SixteenSegmentGlyph::E + | SixteenSegmentGlyph::K + | SixteenSegmentGlyph::M, + ); + font.insert( + 'x', + SixteenSegmentGlyph::H + | SixteenSegmentGlyph::J + | SixteenSegmentGlyph::K + | SixteenSegmentGlyph::M, + ); + font.insert( + 'y', + SixteenSegmentGlyph::B + | SixteenSegmentGlyph::C + | SixteenSegmentGlyph::I + | SixteenSegmentGlyph::D2 + | SixteenSegmentGlyph::G2, + ); + font.insert( + 'z', + SixteenSegmentGlyph::D1 | SixteenSegmentGlyph::G1 | SixteenSegmentGlyph::K, + ); + font.insert( + '@', + SixteenSegmentGlyph::A1 + | SixteenSegmentGlyph::A2 + | SixteenSegmentGlyph::B + | SixteenSegmentGlyph::D1 + | SixteenSegmentGlyph::D2 + | SixteenSegmentGlyph::E + | SixteenSegmentGlyph::F + | SixteenSegmentGlyph::G2, + ); Self(font) } } impl Font<SixteenSegmentGlyph> for SixteenSegmentFont { fn glyph(&self, c: char) -> &SixteenSegmentGlyph { - self.0.get(&c).unwrap() + self.0.get(&c).unwrap_or(&SixteenSegmentGlyph::NONE) } } @@ -513,5 +682,8 @@ impl Glyph for SixteenSegmentGlyph { canvas.set_pixel(x + 7, y + 11, color); } } -} + fn extents(&self) -> (usize, usize) { + (9, 13) + } +} diff --git a/pico-st7789/src/main.rs b/pico-st7789/src/main.rs index e404ba7..ad3a90f 100644 --- a/pico-st7789/src/main.rs +++ b/pico-st7789/src/main.rs @@ -3,6 +3,7 @@ extern crate alloc; +use alloc::fmt::format; use embedded_alloc::LlffHeap as Heap; use embedded_hal::{delay::DelayNs, digital::OutputPin}; use fugit::RateExtU32; @@ -14,10 +15,10 @@ use rp_pico::{ }; mod canvas; -use canvas::{Canvas, RGB}; +use canvas::{Canvas, RGB, print}; mod font; -use font::{Font, Glyph, SixteenSegmentFont}; +use font::{BitmapFont, Font, Glyph, SevenSegmentFont, SixteenSegmentFont}; mod st7789; use st7789::{ST7789Display, SETUP_PROGRAM}; @@ -59,12 +60,12 @@ impl Canvas for FrameBuf { unsafe fn main() -> ! { { use core::mem::MaybeUninit; - const HEAP_SIZE: usize = 1024; + const HEAP_SIZE: usize = 64 * 1024; static mut HEAP_MEM: [MaybeUninit<u8>; HEAP_SIZE] = [MaybeUninit::uninit(); HEAP_SIZE]; unsafe { HEAP.init(HEAP_MEM.as_ptr() as usize, HEAP_SIZE) } } - let font_sixteen = SixteenSegmentFont::new(); + let font_bitmap = BitmapFont::new(); // rp_pico::pac::Peripherals is a reference to physical hardware defined on the Pico. let mut peripherals = pac::Peripherals::take().unwrap(); @@ -148,136 +149,19 @@ unsafe fn main() -> ! { */ let mut canvas = FrameBuf::new(); let white = RGB { r: 63, g: 63, b: 63 }; + let mut count = 0; loop { - /* - draw_seven_segment(0, &mut frame, 0, 0, (255, 255, 255)); - draw_seven_segment(1, &mut frame, 7, 0, (255, 255, 255)); - draw_seven_segment(2, &mut frame, 14, 0, (255, 255, 255)); - draw_seven_segment(3, &mut frame, 21, 0, (255, 255, 255)); - draw_seven_segment(4, &mut frame, 28, 0, (255, 255, 255)); - draw_seven_segment(5, &mut frame, 35, 0, (255, 255, 255)); - draw_seven_segment(6, &mut frame, 42, 0, (255, 255, 255)); - draw_seven_segment(7, &mut frame, 49, 0, (255, 255, 255)); - draw_seven_segment(8, &mut frame, 56, 0, (255, 255, 255)); - draw_seven_segment(9, &mut frame, 63, 0, (255, 255, 255)); - */ + canvas.fill(0, 10, 170, 20, &RGB{r: 0, g: 0, b: 0 }); + print(&mut canvas, &font_bitmap, 1, 10, &format(format_args!("COUNT: {:03}", count)), &RGB{ r: 32, g: 32, b: 63 }); + print(&mut canvas, &font_bitmap, 1, 200, " !\"#$%&'<>*+,-./", &RGB{ r: 63, g: 63, b: 63 }); + print(&mut canvas, &font_bitmap, 1, 220, "0123456789|: = ?", &RGB{ r: 63, g: 63, b: 63 }); + print(&mut canvas, &font_bitmap, 1, 240, "@ABCDEFGHIJKLMNO", &RGB{ r: 63, g: 63, b: 63 }); + print(&mut canvas, &font_bitmap, 1, 260, "PQRSTUVWXYZ[\\]^_", &RGB{ r: 63, g: 63, b: 63 }); + print(&mut canvas, &font_bitmap, 1, 280, "`abcdefghijklmno", &RGB{ r: 63, g: 63, b: 63 }); + print(&mut canvas, &font_bitmap, 1, 300, "pqrstuvwxyz{|}", &RGB{ r: 63, g: 63, b: 63 }); - font_sixteen - .glyph(' ') - .draw(&mut canvas, 0, 0, &white); - font_sixteen - .glyph('0') - .draw(&mut canvas, 11, 0, &white); - font_sixteen - .glyph('1') - .draw(&mut canvas, 22, 0, &white); - font_sixteen - .glyph('2') - .draw(&mut canvas, 33, 0, &white); - font_sixteen - .glyph('3') - .draw(&mut canvas, 44, 0, &white); - font_sixteen - .glyph('4') - .draw(&mut canvas, 55, 0, &white); - font_sixteen - .glyph('5') - .draw(&mut canvas, 66, 0, &white); - font_sixteen - .glyph('6') - .draw(&mut canvas, 77, 0, &white); - font_sixteen - .glyph('7') - .draw(&mut canvas, 88, 0, &white); - font_sixteen - .glyph('8') - .draw(&mut canvas, 99, 0, &white); - font_sixteen - .glyph('9') - .draw(&mut canvas, 110, 0, &white); - - font_sixteen - .glyph('A') - .draw(&mut canvas, 0, 20, &white); - font_sixteen - .glyph('B') - .draw(&mut canvas, 11, 20, &white); - font_sixteen - .glyph('C') - .draw(&mut canvas, 22, 20, &white); - font_sixteen - .glyph('D') - .draw(&mut canvas, 33, 20, &white); - font_sixteen - .glyph('E') - .draw(&mut canvas, 44, 20, &white); - font_sixteen - .glyph('F') - .draw(&mut canvas, 55, 20, &white); - font_sixteen - .glyph('G') - .draw(&mut canvas, 66, 20, &white); - font_sixteen - .glyph('H') - .draw(&mut canvas, 77, 20, &white); - font_sixteen - .glyph('I') - .draw(&mut canvas, 88, 20, &white); - font_sixteen - .glyph('J') - .draw(&mut canvas, 99, 20, &white); - font_sixteen - .glyph('K') - .draw(&mut canvas, 110, 20, &white); - font_sixteen - .glyph('L') - .draw(&mut canvas, 121, 20, &white); - font_sixteen - .glyph('M') - .draw(&mut canvas, 132, 20, &white); - font_sixteen - .glyph('N') - .draw(&mut canvas, 143, 20, &white); - font_sixteen - .glyph('O') - .draw(&mut canvas, 154, 20, &white); - - font_sixteen - .glyph('P') - .draw(&mut canvas, 0, 40, &white); - font_sixteen - .glyph('Q') - .draw(&mut canvas, 11, 40, &white); - font_sixteen - .glyph('R') - .draw(&mut canvas, 22, 40, &white); - font_sixteen - .glyph('S') - .draw(&mut canvas, 33, 40, &white); - font_sixteen - .glyph('T') - .draw(&mut canvas, 44, 40, &white); - font_sixteen - .glyph('U') - .draw(&mut canvas, 55, 40, &white); - font_sixteen - .glyph('V') - .draw(&mut canvas, 66, 40, &white); - font_sixteen - .glyph('W') - .draw(&mut canvas, 77, 40, &white); - font_sixteen - .glyph('X') - .draw(&mut canvas, 88, 40, &white); - font_sixteen - .glyph('Y') - .draw(&mut canvas, 99, 40, &white); - font_sixteen - .glyph('Z') - .draw(&mut canvas, 110, 40, &white); - - canvas.square(10, 70, 160, 310, &white); + // canvas.square(10, 70, 160, 310, &white); { let display = display.acquire(); @@ -286,6 +170,7 @@ unsafe fn main() -> ! { display.send_buf(canvas.buf); let _ = led.set_low(); } + count = count + 1; /* for x in 80..90 { for y in 155..165 {