agb/agb-image-converter/src/font_loader.rs

69 lines
1.8 KiB
Rust
Raw Normal View History

2022-04-05 07:06:08 +10:00
use crate::ByteString;
use quote::quote;
use proc_macro2::TokenStream;
struct LetterData {
width: usize,
2022-04-06 07:32:11 +10:00
height: usize,
xmin: i32,
ymin: i32,
advance_width: f32,
2022-04-05 07:06:08 +10:00
rendered: Vec<u8>,
}
pub fn load_font(font_data: &[u8], pixels_per_em: f32) -> TokenStream {
2022-04-06 07:32:11 +10:00
let font = fontdue::Font::from_bytes(
font_data,
fontdue::FontSettings {
collection_index: 0,
scale: pixels_per_em,
},
)
.expect("Invalid font data");
2022-04-05 07:06:08 +10:00
2022-04-06 07:44:32 +10:00
let line_metrics = font.horizontal_line_metrics(pixels_per_em).unwrap();
let line_height = line_metrics.new_line_size as i32;
let ascent = line_metrics.ascent as i32;
2022-04-05 07:06:08 +10:00
let font = (0..128)
.map(|i| font.rasterize(char::from_u32(i).unwrap(), pixels_per_em))
.map(|(metrics, bitmap)| {
let width = metrics.width;
2022-04-06 07:32:11 +10:00
let height = metrics.height;
2022-04-06 07:44:32 +10:00
2022-04-05 07:06:08 +10:00
LetterData {
width,
2022-04-06 07:32:11 +10:00
height,
2022-04-05 07:06:08 +10:00
rendered: bitmap,
2022-04-06 07:32:11 +10:00
xmin: metrics.xmin,
ymin: metrics.ymin,
advance_width: metrics.advance_width,
2022-04-05 07:06:08 +10:00
}
})
.map(|letter_data| {
let data_raw = ByteString(&letter_data.rendered);
2022-04-06 07:32:11 +10:00
let height = letter_data.height as u8;
2022-04-05 07:06:08 +10:00
let width = letter_data.width as u8;
2022-04-06 07:32:11 +10:00
let xmin = letter_data.xmin as i8;
let ymin = letter_data.ymin as i8;
let advance_width = letter_data.advance_width as u8;
2022-04-05 07:06:08 +10:00
2022-04-06 07:32:11 +10:00
quote!(
agb::display::FontLetter::new(
#width,
#height,
#data_raw,
#xmin,
#ymin,
#advance_width,
)
)
2022-04-05 07:06:08 +10:00
});
quote![
2022-04-06 07:44:32 +10:00
agb::display::Font::new(&[#(#font),*], #line_height, #ascent)
2022-04-05 07:06:08 +10:00
]
}