mirror of
https://github.com/lisk77/comet.git
synced 2025-10-23 21:38:50 +00:00
80 lines
No EOL
1.8 KiB
Rust
80 lines
No EOL
1.8 KiB
Rust
use image::{DynamicImage, Rgba, RgbaImage};
|
|
use ab_glyph::{FontArc, PxScale, ScaleFont, Glyph, point, Font as AbFont};
|
|
use crate::texture_atlas::{TextureAtlas, TextureRegion};
|
|
|
|
pub struct Font {
|
|
name: String,
|
|
glyphs: TextureAtlas,
|
|
}
|
|
|
|
impl Font {
|
|
pub fn new(path: &str, size: f32) -> Self {
|
|
Font {
|
|
name: path.to_string(),
|
|
glyphs: Self::generate_atlas(path, size)
|
|
}
|
|
}
|
|
|
|
pub fn name(&self) -> &str {
|
|
&self.name
|
|
}
|
|
|
|
pub fn glyphs(&self) -> &TextureAtlas {
|
|
&self.glyphs
|
|
}
|
|
|
|
pub fn get_glyph(&self, ch: char) -> Option<&TextureRegion> {
|
|
self.glyphs.textures().get(&ch.to_string())
|
|
}
|
|
|
|
fn generate_atlas(path: &str, size: f32) -> TextureAtlas {
|
|
let font_data = std::fs::read(path).expect("Failed to read font file");
|
|
let font = FontArc::try_from_vec(font_data).expect("Failed to load font");
|
|
|
|
let scale = PxScale::from(size);
|
|
let scaled_font = font.as_scaled(scale);
|
|
|
|
let mut names = Vec::new();
|
|
let mut images = Vec::new();
|
|
|
|
for code_point in 0x0020..=0x007E {
|
|
if let Some(ch) = std::char::from_u32(code_point) {
|
|
if font.glyph_id(ch).0 == 0 {
|
|
continue;
|
|
}
|
|
|
|
names.push(ch.to_string());
|
|
|
|
let glyph = Glyph {
|
|
id: font.glyph_id(ch),
|
|
scale,
|
|
position: point(0.0, 0.0),
|
|
};
|
|
|
|
if let Some(outline) = scaled_font.outline_glyph(glyph) {
|
|
let bounds = outline.px_bounds();
|
|
let width = bounds.width().ceil() as u32;
|
|
let height = bounds.height().ceil() as u32;
|
|
|
|
if width == 0 || height == 0 {
|
|
continue;
|
|
}
|
|
|
|
let mut image = RgbaImage::new(width, height);
|
|
for pixel in image.pixels_mut() {
|
|
*pixel = Rgba([0, 0, 0, 0]);
|
|
}
|
|
|
|
outline.draw(|x, y, v| {
|
|
let alpha = (v * 255.0) as u8;
|
|
image.put_pixel(x, y, Rgba([255, 255, 255, alpha]));
|
|
});
|
|
|
|
images.push(DynamicImage::ImageRgba8(image));
|
|
}
|
|
}
|
|
}
|
|
|
|
TextureAtlas::from_textures(names, images)
|
|
}
|
|
} |