2024-05-18 17:20:30 +02:00
|
|
|
use std::sync::Arc;
|
|
|
|
|
2024-05-16 17:24:41 +02:00
|
|
|
use font_kit::canvas::{Canvas, Format, RasterizationOptions};
|
2024-05-18 17:20:30 +02:00
|
|
|
use font_kit::font::Font;
|
2024-05-10 18:24:26 +02:00
|
|
|
use font_kit::hinting::HintingOptions;
|
|
|
|
use pathfinder_geometry::transform2d::Transform2F;
|
|
|
|
use pathfinder_geometry::vector::{vec2f, vec2i};
|
2024-05-26 15:24:44 +02:00
|
|
|
use servicepoint::{Grid, PixelGrid, TILE_SIZE};
|
2024-05-10 18:24:26 +02:00
|
|
|
|
2024-05-18 17:20:30 +02:00
|
|
|
const DEFAULT_FONT_FILE: &[u8] = include_bytes!("../Web437_IBM_BIOS.woff");
|
|
|
|
|
2024-05-10 18:24:26 +02:00
|
|
|
pub struct BitmapFont {
|
|
|
|
bitmaps: [PixelGrid; u8::MAX as usize],
|
|
|
|
}
|
|
|
|
|
|
|
|
impl BitmapFont {
|
2024-05-18 17:20:30 +02:00
|
|
|
pub fn load(font: Font) -> BitmapFont {
|
2024-05-11 23:29:25 +02:00
|
|
|
let mut bitmaps = core::array::from_fn(|_| {
|
2024-05-26 10:50:29 +02:00
|
|
|
PixelGrid::new(TILE_SIZE, TILE_SIZE)
|
2024-05-11 23:29:25 +02:00
|
|
|
});
|
2024-05-10 18:24:26 +02:00
|
|
|
|
|
|
|
for char_code in u8::MIN..u8::MAX {
|
|
|
|
let char = char_code as char;
|
|
|
|
let glyph_id = match font.glyph_for_char(char) {
|
|
|
|
None => continue,
|
|
|
|
Some(val) => val,
|
|
|
|
};
|
|
|
|
|
|
|
|
let size = 8f32;
|
|
|
|
let transform = Transform2F::default();
|
2024-05-11 23:29:25 +02:00
|
|
|
let mut canvas =
|
|
|
|
Canvas::new(vec2i(size as i32, size as i32), Format::A8);
|
2024-05-10 18:24:26 +02:00
|
|
|
font.rasterize_glyph(
|
|
|
|
&mut canvas,
|
|
|
|
glyph_id,
|
|
|
|
size,
|
|
|
|
Transform2F::from_translation(vec2f(0f32, size)) * transform,
|
|
|
|
HintingOptions::None,
|
|
|
|
RasterizationOptions::GrayscaleAa,
|
|
|
|
)
|
2024-05-16 17:24:41 +02:00
|
|
|
.unwrap();
|
2024-05-10 18:24:26 +02:00
|
|
|
|
|
|
|
assert_eq!(canvas.pixels.len(), 64);
|
|
|
|
assert_eq!(canvas.stride, 8);
|
|
|
|
|
2024-05-26 10:50:29 +02:00
|
|
|
for y in 0..TILE_SIZE {
|
|
|
|
for x in 0..TILE_SIZE {
|
|
|
|
let index = x + y * TILE_SIZE;
|
2024-05-10 18:24:26 +02:00
|
|
|
let canvas_val = canvas.pixels[index] != 0;
|
|
|
|
bitmaps[char_code as usize].set(x, y, canvas_val);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-05-16 17:22:47 +02:00
|
|
|
BitmapFont { bitmaps }
|
2024-05-10 18:24:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_bitmap(&self, char_code: u8) -> &PixelGrid {
|
|
|
|
&self.bitmaps[char_code as usize]
|
|
|
|
}
|
|
|
|
}
|
2024-05-18 17:20:30 +02:00
|
|
|
|
|
|
|
impl Default for BitmapFont {
|
|
|
|
fn default() -> Self {
|
|
|
|
let font = Font::from_bytes(Arc::new(DEFAULT_FONT_FILE.to_vec()), 0)
|
|
|
|
.expect("could not load included font");
|
|
|
|
Self::load(font)
|
|
|
|
}
|
|
|
|
}
|