From a61fe79a6f15debb1ced9e0c3bf6dad22dd6ab26 Mon Sep 17 00:00:00 2001 From: Gwilym Inzani Date: Wed, 27 Mar 2024 09:21:06 +0000 Subject: [PATCH] Allow any character supported by the font --- agb-image-converter/src/font_loader.rs | 14 +++++++++++--- agb/src/display/font.rs | 16 +++++++++++++--- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/agb-image-converter/src/font_loader.rs b/agb-image-converter/src/font_loader.rs index d8f8177c..c63e09eb 100644 --- a/agb-image-converter/src/font_loader.rs +++ b/agb-image-converter/src/font_loader.rs @@ -4,6 +4,7 @@ use quote::quote; use proc_macro2::TokenStream; struct LetterData { + character: char, width: usize, height: usize, xmin: i32, @@ -27,9 +28,11 @@ pub fn load_font(font_data: &[u8], pixels_per_em: f32) -> TokenStream { let line_height = line_metrics.new_line_size as i32; let mut ascent = line_metrics.ascent as i32; - let letters: Vec<_> = (0..128) - .map(|i| font.rasterize(char::from_u32(i).unwrap(), pixels_per_em)) - .map(|(metrics, bitmap)| { + let mut letters: Vec<_> = font + .chars() + .iter() + .map(|(&c, _)| (c, font.rasterize(c, pixels_per_em))) + .map(|(c, (metrics, bitmap))| { let width = metrics.width; let height = metrics.height; @@ -48,6 +51,7 @@ pub fn load_font(font_data: &[u8], pixels_per_em: f32) -> TokenStream { .collect(); LetterData { + character: c, width, height, rendered, @@ -58,6 +62,8 @@ pub fn load_font(font_data: &[u8], pixels_per_em: f32) -> TokenStream { }) .collect(); + letters.sort_unstable_by_key(|letter| letter.character); + let maximum_above_line = letters .iter() .map(|x| (x.height as i32 + x.ymin)) @@ -69,6 +75,7 @@ pub fn load_font(font_data: &[u8], pixels_per_em: f32) -> TokenStream { } let font = letters.iter().map(|letter_data| { + let character = letter_data.character; let data_raw = ByteString(&letter_data.rendered); let height = letter_data.height as u8; let width = letter_data.width as u8; @@ -78,6 +85,7 @@ pub fn load_font(font_data: &[u8], pixels_per_em: f32) -> TokenStream { quote!( display::FontLetter::new( + #character, #width, #height, #data_raw, diff --git a/agb/src/display/font.rs b/agb/src/display/font.rs index 54b3078f..cb0c7a04 100644 --- a/agb/src/display/font.rs +++ b/agb/src/display/font.rs @@ -10,6 +10,7 @@ use super::tiled::{DynamicTile, RegularMap, VRamManager}; /// Does not support any unicode features. /// For usage see the `text_render.rs` example pub struct FontLetter { + pub(crate) character: char, pub(crate) width: u8, pub(crate) height: u8, pub(crate) data: &'static [u8], @@ -21,6 +22,7 @@ pub struct FontLetter { impl FontLetter { #[must_use] pub const fn new( + character: char, width: u8, height: u8, data: &'static [u8], @@ -29,6 +31,7 @@ impl FontLetter { advance_width: u8, ) -> Self { Self { + character, width, height, data, @@ -47,14 +50,14 @@ impl FontLetter { } pub struct Font { - letters: &'static [FontLetter; 128], + letters: &'static [FontLetter], line_height: i32, ascent: i32, } impl Font { #[must_use] - pub const fn new(letters: &'static [FontLetter; 128], line_height: i32, ascent: i32) -> Self { + pub const fn new(letters: &'static [FontLetter], line_height: i32, ascent: i32) -> Self { Self { letters, line_height, @@ -63,7 +66,14 @@ impl Font { } pub(crate) fn letter(&self, letter: char) -> &'static FontLetter { - &self.letters[letter as usize & (128 - 1)] + let letter = self + .letters + .binary_search_by_key(&letter, |letter| letter.character); + + match letter { + Ok(index) => &self.letters[index], + Err(_) => &self.letters[0], + } } pub(crate) fn ascent(&self) -> i32 {