use crate::prelude::{FullFont, PrintableFont};
pub mod full;
pub mod printable;
pub trait AgbFont {
fn char_widths(&self) -> &[u8];
#[inline]
fn char_width(&self, c: u8) -> u8 {
self.char_widths()[c as usize - self.char_offset()]
}
fn char_offset(&self) -> usize;
fn data(&self) -> &[u32];
fn glyph_height(&self) -> u32;
fn glyph_size(&self) -> usize;
fn row_u32s(&self) -> usize;
fn glyph(&self, c: u8) -> &[u32] {
if cfg!(debug_assertions) && self.char_offset() != 0 && !(32..=126).contains(&c) {
panic!("glyph {c} out of printable bounds");
}
let idx = c as usize - self.char_offset();
let offset = idx * self.glyph_size();
unsafe {
self.data()
.get_unchecked(offset..offset + self.glyph_size())
}
}
fn size_of(&self, text: &[u8], wrap_at: u8) -> (u8, u8) {
let max_width = wrap_at as u32;
if text.is_empty() {
return (0, 0);
}
let mut max_encountered_width: u32 = 0;
let mut current_line_width: u32 = 0;
let mut total_height: u32 = self.glyph_height();
for &c in text {
if c == b'\n' {
if current_line_width > max_encountered_width {
max_encountered_width = current_line_width;
}
current_line_width = 0;
total_height += self.glyph_height();
} else {
let char_w = self.char_width(c) as u32;
if current_line_width + char_w > max_width {
if current_line_width > max_encountered_width {
max_encountered_width = current_line_width;
}
current_line_width = char_w;
total_height += self.glyph_height();
} else {
current_line_width += char_w;
}
}
}
if current_line_width > max_encountered_width {
max_encountered_width = current_line_width;
}
(max_encountered_width as u8, total_height as u8)
}
}
macro_rules! impl_agb_font {
($font_class:ident, $offset: expr) => {
impl AgbFont for $font_class {
#[inline]
fn char_widths(&self) -> &[u8] {
&self.char_widths
}
#[inline]
fn char_offset(&self) -> usize {
$offset
}
#[inline]
fn data(&self) -> &[u32] {
&self.data
}
#[inline]
fn glyph_height(&self) -> u32 {
self.glyph_height
}
#[inline]
fn glyph_size(&self) -> usize {
self.glyph_size
}
#[inline]
fn row_u32s(&self) -> usize {
self.row_u32s
}
}
};
}
impl_agb_font!(PrintableFont, 32);
impl_agb_font!(FullFont, 0);