use st7735::gfx::PrimitveGFX; pub struct FontGlyph { pub bitmap_offset: usize, // Offset in glyph bitmap pub width: u8, // Size of glyph pub height: u8, pub x_advance: u8, // Distance to advance along x-axis pub x_offset: i8, // Distance to upper left coner from cursor pos pub y_offset: i8, } pub struct Font { pub bitmap: &'static [u8], // Glyph bitmaps, concatenated pub glyphs: &'static [FontGlyph], // Array of glyph metadata pub first: u8, // Start of ASCII extend pub last: u8, // End of ASCII extend pub y_advance: u8, // Line height } pub trait FontRenderer: PrimitveGFX { fn draw_glyph(&mut self, x: u8, y: u8, glyph: &FontGlyph, font: &Font, size: u8, color: u16) { if size == 0 { return; } // Any clipping should be done by draw_rect let x = x as i16; let y = y as i16; let size = size as i16; let mut bo = glyph.bitmap_offset; let mut set_pixels: i16 = 0; let mut bits: u8 = 0; let mut bit: u8 = 0; for cur_y in 0..(glyph.height as i16) { for cur_x in 0..(glyph.width as i16) { if bit == 0 { bits = font.bitmap[bo]; bo += 1; bit = 0x80; } if bit & bits != 0 { set_pixels += 1; } else if set_pixels > 0 { let start_x = (x + ((glyph.x_offset as i16) + cur_x - set_pixels) * size) as u8; let start_y = (y + ((glyph.y_offset as i16) + cur_y) * size) as u8; let w = (set_pixels * size) as u8; let h = size as u8; self.fill_rect(start_x, start_y, w, h, color); set_pixels = 0; } bit >>= 1; } if set_pixels > 0 { let start_x = (x + ((glyph.x_offset as i16) + (glyph.width as i16) - set_pixels) * size) as u8; let start_y = (y + ((glyph.y_offset as i16) + cur_y) * size) as u8; let w = (set_pixels * size) as u8; let h = size as u8; self.fill_rect(start_x, start_y, w, h, color); set_pixels = 0; } } } fn draw_text(&mut self, x: u8, y: u8, text: &str, font: &Font, size: u8, color: u16) { let mut cursor_x = x; let mut cursor_y = y; for text_char in text.chars() { let c = if text_char.is_ascii() { text_char as u8 } else { '?' as u8 }; if c == '\n' as u8 { cursor_x = x; cursor_y += font.y_advance * size; } else if c >= font.first && c <= font.last && c != '\r' as u8 { let pos = (c - font.first) as usize; let glyph = &font.glyphs[pos]; self.draw_glyph(cursor_x, cursor_y, glyph, &font, size, color); cursor_x += glyph.x_advance * size; } } } }