nihpod/demo/src/console.rs

103 lines
2.6 KiB
Rust

use embedded_graphics::{
Drawable,
geometry::{Point, Size},
mono_font::{ascii::FONT_6X10, MonoTextStyle},
prelude::{RgbColor},
primitives::rectangle::Rectangle,
text::{Text, Baseline},
draw_target::DrawTarget,
};
pub struct Console<const W: usize, const H: usize> {
array: [[char; W]; H],
dirty: [bool; H],
curline: usize,
curcol: usize,
}
impl<const W: usize, const H: usize> Console<W, H> {
const FONT_H: i32 = 12;
const FONT_W: i32 = 6;
pub fn new() -> Self {
Self {
array: [[' '; W]; H],
dirty: [true; H],
curline: 0,
curcol: 0,
}
}
pub fn write_char(&mut self, c: char) {
let mut wrapped = false;
if self.curcol >= W {
self.curcol = 0;
self.curline += 1;
}
if self.curline >= H {
self.curline = 0;
for i in 0..W {
self.array[0][i] = ' ';
}
wrapped = true;
}
if c == '\n' {
self.curline += 1;
self.curcol = 0;
} else {
self.array[self.curline][self.curcol] = c;
self.curcol += 1;
self.dirty[self.curline] = true;
}
if wrapped {
//self.array.rotate_left(1);
for i in 0..H {
self.dirty[i] = true;
}
for i in 1..H {
for j in 0..W {
self.array[i][j] = ' ';
}
}
}
}
pub fn blit<D, C: RgbColor>(&mut self, target: &mut D)
where
D: DrawTarget<Color=C>,
{
let style = MonoTextStyle::new(&FONT_6X10, C::WHITE);
for (i, dirty) in self.dirty.iter().enumerate() {
if !dirty {
continue
}
let mut s = heapless::String::<W>::new();
for c in self.array[i] {
s.push(c);
}
let tl = Point::new(0, Self::FONT_H * (i as i32));
let sz = Size::new((Self::FONT_W * (W as i32)) as u32, Self::FONT_H as u32);
let rect = Rectangle::new(tl, sz);
target.fill_solid(&rect, C::BLACK);
Text::with_baseline(&s, tl, style, Baseline::Top).draw(target);
}
for i in 0..H {
self.dirty[i] = false;
}
}
}
impl<const W: usize, const H: usize> core::fmt::Write for Console<W, H> {
fn write_str(&mut self, text: &str) -> core::fmt::Result {
for c in text.chars() {
self.write_char(c);
}
Ok(())
}
}