Allow any character supported by the font

This commit is contained in:
Gwilym Inzani 2024-03-27 09:21:06 +00:00
parent dc8a6e3884
commit a61fe79a6f
2 changed files with 24 additions and 6 deletions

View file

@ -4,6 +4,7 @@ use quote::quote;
use proc_macro2::TokenStream; use proc_macro2::TokenStream;
struct LetterData { struct LetterData {
character: char,
width: usize, width: usize,
height: usize, height: usize,
xmin: i32, 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 line_height = line_metrics.new_line_size as i32;
let mut ascent = line_metrics.ascent as i32; let mut ascent = line_metrics.ascent as i32;
let letters: Vec<_> = (0..128) let mut letters: Vec<_> = font
.map(|i| font.rasterize(char::from_u32(i).unwrap(), pixels_per_em)) .chars()
.map(|(metrics, bitmap)| { .iter()
.map(|(&c, _)| (c, font.rasterize(c, pixels_per_em)))
.map(|(c, (metrics, bitmap))| {
let width = metrics.width; let width = metrics.width;
let height = metrics.height; let height = metrics.height;
@ -48,6 +51,7 @@ pub fn load_font(font_data: &[u8], pixels_per_em: f32) -> TokenStream {
.collect(); .collect();
LetterData { LetterData {
character: c,
width, width,
height, height,
rendered, rendered,
@ -58,6 +62,8 @@ pub fn load_font(font_data: &[u8], pixels_per_em: f32) -> TokenStream {
}) })
.collect(); .collect();
letters.sort_unstable_by_key(|letter| letter.character);
let maximum_above_line = letters let maximum_above_line = letters
.iter() .iter()
.map(|x| (x.height as i32 + x.ymin)) .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 font = letters.iter().map(|letter_data| {
let character = letter_data.character;
let data_raw = ByteString(&letter_data.rendered); let data_raw = ByteString(&letter_data.rendered);
let height = letter_data.height as u8; let height = letter_data.height as u8;
let width = letter_data.width 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!( quote!(
display::FontLetter::new( display::FontLetter::new(
#character,
#width, #width,
#height, #height,
#data_raw, #data_raw,

View file

@ -10,6 +10,7 @@ use super::tiled::{DynamicTile, RegularMap, VRamManager};
/// Does not support any unicode features. /// Does not support any unicode features.
/// For usage see the `text_render.rs` example /// For usage see the `text_render.rs` example
pub struct FontLetter { pub struct FontLetter {
pub(crate) character: char,
pub(crate) width: u8, pub(crate) width: u8,
pub(crate) height: u8, pub(crate) height: u8,
pub(crate) data: &'static [u8], pub(crate) data: &'static [u8],
@ -21,6 +22,7 @@ pub struct FontLetter {
impl FontLetter { impl FontLetter {
#[must_use] #[must_use]
pub const fn new( pub const fn new(
character: char,
width: u8, width: u8,
height: u8, height: u8,
data: &'static [u8], data: &'static [u8],
@ -29,6 +31,7 @@ impl FontLetter {
advance_width: u8, advance_width: u8,
) -> Self { ) -> Self {
Self { Self {
character,
width, width,
height, height,
data, data,
@ -47,14 +50,14 @@ impl FontLetter {
} }
pub struct Font { pub struct Font {
letters: &'static [FontLetter; 128], letters: &'static [FontLetter],
line_height: i32, line_height: i32,
ascent: i32, ascent: i32,
} }
impl Font { impl Font {
#[must_use] #[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 { Self {
letters, letters,
line_height, line_height,
@ -63,7 +66,14 @@ impl Font {
} }
pub(crate) fn letter(&self, letter: char) -> &'static FontLetter { 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 { pub(crate) fn ascent(&self) -> i32 {