From 549ebdc37c83b17af1e62365d5bd4632759c8f1a Mon Sep 17 00:00:00 2001 From: Sofia Date: Sat, 13 Sep 2025 14:46:14 +0300 Subject: [PATCH] Add alphabet --- src/display.rs | 8 +++ src/font.rs | 167 ++++++++++++++++++++++++++++++++++++++++++++++++ src/graphics.rs | 7 +- src/main.rs | 25 +++++--- 4 files changed, 193 insertions(+), 14 deletions(-) diff --git a/src/display.rs b/src/display.rs index ce852e1..43fd0ba 100644 --- a/src/display.rs +++ b/src/display.rs @@ -43,6 +43,14 @@ impl Rgb565 { Rgb565(0, 255, 255) } + pub fn black() -> Rgb565 { + Rgb565(0, 0, 0) + } + + pub fn white() -> Rgb565 { + Rgb565(255, 255, 255) + } + pub fn qoi_hash(&self) -> usize { ((self.0 as u32 * 3 + self.1 as u32 * 5 + self.2 as u32 * 7 + 255 * 11) % 64) as usize } diff --git a/src/font.rs b/src/font.rs index 13f7837..41130b3 100644 --- a/src/font.rs +++ b/src/font.rs @@ -1,9 +1,176 @@ +use atmega_hal::port::PinOps; +use embedded_hal::delay::DelayNs; + +use crate::{ + display::{Display, Rgb565, Vec2}, + graphics::draw_stream, +}; + fn letter(character: char) -> [u8; 8] { match character { 'a' => [ 0b01111110, 0b01000010, 0b10000001, 0b11111111, 0b10000001, 0b10000001, 0b10000001, 0b10000001, ], + 'b' => [ + 0b11111100, 0b10000010, 0b10000010, 0b10001100, 0b10000010, 0b10000001, 0b10000001, + 0b11111110, + ], + 'c' => [ + 0b11111110, 0b10000001, 0b10000000, 0b10000000, 0b10000000, 0b10000000, 0b10000001, + 0b11111110, + ], + 'd' => [ + 0b11111100, 0b10000010, 0b10000010, 0b10000001, 0b10000001, 0b10000010, 0b10000010, + 0b11111100, + ], + 'e' => [ + 0b11111111, 0b10000000, 0b10000000, 0b11111000, 0b10000000, 0b10000000, 0b10000000, + 0b11111111, + ], + 'f' => [ + 0b11111111, 0b10000000, 0b10000000, 0b11111000, 0b10000000, 0b10000000, 0b10000000, + 0b10000000, + ], + 'g' => [ + 0b11111110, 0b10000001, 0b10000000, 0b10000000, 0b10011111, 0b10010001, 0b01000010, + 0b00111100, + ], + 'h' => [ + 0b10000001, 0b10000001, 0b10000001, 0b11111111, 0b10000001, 0b10000001, 0b10000001, + 0b10000001, + ], + 'i' => [ + 0b00111000, 0b00011000, 0b00011000, 0b00011000, 0b00011000, 0b00011000, 0b00011000, + 0b00111000, + ], + 'j' => [ + 0b00001110, 0b00000010, 0b00000010, 0b00000010, 0b00000010, 0b10000010, 0b10000010, + 0b01111100, + ], + 'k' => [ + 0b01000010, 0b01000100, 0b01001000, 0b01110000, 0b01001000, 0b01000100, 0b01000010, + 0b01000001, + ], + 'l' => [ + 0b10000000, 0b10000000, 0b10000000, 0b10000000, 0b10000000, 0b10000000, 0b10000000, + 0b11111111, + ], + 'm' => [ + 0b01100110, 0b10011001, 0b10010001, 0b10010001, 0b10010001, 0b10000001, 0b10000001, + 0b10000001, + ], + 'n' => [ + 0b11000001, 0b10100001, 0b10010001, 0b10001001, 0b10001001, 0b10000101, 0b10000111, + 0b10000011, + ], + 'o' => [ + 0b11111111, 0b10000001, 0b10000001, 0b10000001, 0b10000001, 0b10000001, 0b10000001, + 0b11111111, + ], + 'p' => [ + 0b11111111, 0b10000001, 0b10000001, 0b11111111, 0b10000000, 0b10000000, 0b10000000, + 0b00000000, + ], + 'q' => [ + 0b01111110, 0b10000001, 0b10000001, 0b10000001, 0b10001001, 0b10000101, 0b10000011, + 0b01111111, + ], + 'r' => [ + 0b11111111, 0b10000001, 0b10000001, 0b11111111, 0b11111100, 0b10000010, 0b10000001, + 0b00000001, + ], + 's' => [ + 0b01111111, 0b10000000, 0b10000000, 0b01111110, 0b00000001, 0b00000001, 0b00000001, + 0b11111110, + ], + 't' => [ + 0b11111111, 0b00010000, 0b00010000, 0b00010000, 0b00010000, 0b00010000, 0b00010000, + 0b00010000, + ], + 'u' => [ + 0b10000001, 0b10000001, 0b10000001, 0b10000001, 0b10000001, 0b10000001, 0b10000001, + 0b01111110, + ], + 'v' => [ + 0b10000001, 0b10000001, 0b01000010, 0b01000010, 0b00100100, 0b00100100, 0b00100100, + 0b00011000, + ], + 'w' => [ + 0b10000001, 0b10000001, 0b10000001, 0b10000001, 0b10011001, 0b01011010, 0b00100100, + 0b00100100, + ], + 'x' => [ + 0b10000001, 0b01000010, 0b00100100, 0b00011000, 0b00011000, 0b00100100, 0b01000010, + 0b10000001, + ], + 'y' => [ + 0b10000001, 0b10000001, 0b01000010, 0b00111100, 0b00011000, 0b00011000, 0b00011000, + 0b00011000, + ], + 'z' => [ + 0b11111111, 0b00000111, 0b00001100, 0b00011000, 0b00110000, 0b01100000, 0b11000000, + 0b11111111, + ], _ => [0; 8], } } + +pub struct Letter { + base: [u8; 8], + pub fg: Rgb565, + pub bg: Rgb565, +} + +impl Letter { + pub fn from(character: char, fg: Rgb565, bg: Rgb565) -> Letter { + Letter { + base: letter(character), + fg, + bg, + } + } + + pub fn iter<'a>(&'a self) -> LetterIter<'a> { + LetterIter { + letter: &self, + idx: 0, + } + } +} + +pub struct LetterIter<'a> { + letter: &'a Letter, + idx: usize, +} + +impl<'a> LetterIter<'a> { + pub fn draw( + mut self, + display: &mut Display, + position: Vec2, + scale: u16, + ) { + draw_stream(&mut self, display, position, Vec2 { x: 8, y: 8 }, scale); + } +} + +impl<'a> Iterator for LetterIter<'a> { + type Item = Rgb565; + + fn next(&mut self) -> Option { + let byte_idx = self.idx / 8; + let bit_idx = self.idx % 8; + if byte_idx >= 8 { + None + } else { + self.idx += 1; + let flag = (self.letter.base[byte_idx] & (1 << bit_idx)) >> bit_idx; + if flag == 1 { + Some(self.letter.fg) + } else { + Some(self.letter.bg) + } + } + } +} diff --git a/src/graphics.rs b/src/graphics.rs index 4730323..4d2b708 100644 --- a/src/graphics.rs +++ b/src/graphics.rs @@ -108,7 +108,8 @@ pub fn draw_image( y: height, }, scale_factor, - ) + ); + Ok(()) } else { Err(QoiErr::InvalidMagicNumber) } @@ -120,7 +121,7 @@ pub fn draw_stream( position: Vec2, scale: Vec2, scale_factor: u16, -) -> Result<(), QoiErr> { +) { let scale_iter = ScaleIterator { iter: stream, last_row: [Rgb565::yellow(); 120], @@ -142,8 +143,6 @@ pub fn draw_stream( let [c1, c2] = pixel.as_color().bytes; display.write(Writeable::Data(&[c1, c2])); } - - Ok(()) } struct ScaleIterator<'a> { iter: &'a mut dyn Iterator, diff --git a/src/main.rs b/src/main.rs index e4f234f..9758871 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,7 +18,8 @@ use atmega_hal::{ use panic_halt as _; use crate::{ - display::{Display, Vec2}, + display::{Display, Rgb565, Vec2}, + font::Letter, graphics::{Image, LARGE_CAT_UNSAFE, PRESS_BTN_UNSAFE, draw_image}, peripherals::Button, }; @@ -81,15 +82,19 @@ fn main() -> ! { let images = [Image::from(addr_of!(LARGE_CAT_UNSAFE))]; let len = images.len(); - match draw_image( - &mut serial, - &mut Image::from(addr_of!(PRESS_BTN_UNSAFE)).iter(), - &mut display, - Vec2 { x: 0, y: 0 }, - ) { - Ok(_) => ufmt::uwriteln!(serial, "Successfully read QOI").unwrap(), - Err(e) => ufmt::uwriteln!(serial, "Error: {:?}", e).unwrap(), - } + // match draw_image( + // &mut serial, + // &mut Image::from(addr_of!(PRESS_BTN_UNSAFE)).iter(), + // &mut display, + // Vec2 { x: 0, y: 0 }, + // ) { + // Ok(_) => ufmt::uwriteln!(serial, "Successfully read QOI").unwrap(), + // Err(e) => ufmt::uwriteln!(serial, "Error: {:?}", e).unwrap(), + // } + + let letter = Letter::from('h', Rgb565::white(), Rgb565::black()); + + letter.iter().draw(&mut display, Vec2 { x: 10, y: 10 }, 4); loop { if button.poll() {