use crate::gfx::lcd::LcdSize;
use std::collections::HashMap;
mod font_5x8;
pub(crate) use font_5x8::FONT_5X8;
mod font_16x16;
pub(crate) use font_16x16::FONT_16X16;
pub struct Font {
pub name: &'static str,
pub glyph_size: LcdSize,
pub stride: usize,
pub data: &'static [u8],
}
impl Font {
pub(crate) fn glyph(&self, mut ch: char) -> &'static [u8] {
if !(' '..='~').contains(&ch) {
ch = '?';
}
let height = self.glyph_size.height * self.stride;
let offset = ((ch as usize) - (' ' as usize)) * height;
debug_assert!(offset < (self.data.len() + height));
&self.data[offset..offset + height]
}
}
pub type Fonts = HashMap<&'static str, &'static Font>;
pub fn all_fonts() -> Fonts {
let mut fonts = Fonts::default();
fonts.insert(FONT_5X8.name, &FONT_5X8);
fonts.insert(FONT_16X16.name, &FONT_16X16);
fonts
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_font_glyph_printable() {
let font = &FONT_5X8;
let offset = (usize::from(b'a') - usize::from(b' ')) * 8;
let expected = &font.data[offset..offset + 8];
let data = font.glyph('a');
assert_eq!(expected, data);
}
#[test]
fn test_font_glyph_non_printable() {
let font = &FONT_5X8;
let offset = (usize::from(b'?') - usize::from(b' ')) * 8;
let expected = &font.data[offset..offset + 8];
let data = font.glyph(char::from(30));
assert_eq!(expected, data);
}
}