use crate::renderer::Renderer;
use crate::widget::{Color, Rect};
pub struct BitmapFont {
pub glyph_width: u8,
pub glyph_height: u8,
pub scale: u8,
pub data: &'static [u8],
}
impl BitmapFont {
pub fn scaled_width(&self) -> i32 {
self.glyph_width as i32 * self.scale as i32
}
pub fn scaled_height(&self) -> i32 {
self.glyph_height as i32 * self.scale as i32
}
pub fn draw_char(&self, renderer: &mut dyn Renderer, x: i32, y: i32, ch: char, color: Color) {
let idx = if (0x20..=0x7E).contains(&(ch as u32)) {
(ch as u32 - 0x20) as usize
} else {
return; };
let bits_per_glyph = self.glyph_width as usize * self.glyph_height as usize;
let bit_offset = idx * bits_per_glyph;
let s = self.scale as i32;
for row in 0..self.glyph_height as usize {
for col in 0..self.glyph_width as usize {
let bit = bit_offset + row * self.glyph_width as usize + col;
let byte_idx = bit / 8;
let bit_idx = 7 - (bit % 8); if byte_idx < self.data.len() && (self.data[byte_idx] >> bit_idx) & 1 != 0 {
renderer.fill_rect(
Rect {
x: x + col as i32 * s,
y: y + row as i32 * s,
width: s,
height: s,
},
color,
);
}
}
}
}
pub fn draw_str(&self, renderer: &mut dyn Renderer, x: i32, y: i32, text: &str, color: Color) {
let advance = self.scaled_width() + self.scale as i32;
let mut cx = x;
for ch in text.chars() {
self.draw_char(renderer, cx, y, ch, color);
cx += advance;
}
}
pub fn draw_str_y(
&self,
renderer: &mut dyn Renderer,
x: i32,
y: i32,
text: &str,
color: Color,
) {
let advance = self.scaled_width() + self.scale as i32;
let mut cy = y;
for ch in text.chars() {
self.draw_char(renderer, x, cy, ch, color);
cy += advance;
}
}
}
pub static FONT_6X10: BitmapFont = BitmapFont {
glyph_width: 6,
glyph_height: 10,
scale: 2,
data: &FONT_6X10_DATA,
};
static FONT_6X10_DATA: [u8; 713] = {
*include_bytes!("bitmap_font_6x10.bin")
};