feat: ttf fonts are now loadable

This commit is contained in:
lisk77 2025-03-16 20:07:05 +01:00
parent 9e16179df3
commit 0507703284
4 changed files with 136 additions and 54 deletions

View file

@ -1,16 +1,17 @@
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: Vec<DynamicImage>,
glyphs: TextureAtlas,
}
impl Font {
pub fn new(path: &str, size: f32) -> Self {
Font {
name: path.to_string(),
glyphs: Self::generate_images(path, size),
glyphs: Self::generate_atlas(path, size)
}
}
@ -18,31 +19,22 @@ impl Font {
&self.name
}
pub fn names(&self) -> Vec<String> {
let mut names = Vec::new();
for code_point in 0x0020..=0x007E {
if let Some(ch) = std::char::from_u32(code_point) {
names.push(ch.to_string());
}
}
names
pub fn glyphs(&self) -> &TextureAtlas {
&self.glyphs
}
pub fn glyph(&self, index: usize) -> &DynamicImage {
&self.glyphs[index]
pub fn get_glyph(&self, ch: char) -> Option<&TextureRegion> {
self.glyphs.textures().get(&ch.to_string())
}
pub fn glyphs(&self) -> Vec<DynamicImage> {
self.glyphs.clone()
}
fn generate_images(path: &str, size: f32) -> Vec<DynamicImage> {
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 {
@ -51,6 +43,8 @@ impl Font {
continue;
}
names.push(ch.to_string());
let glyph = Glyph {
id: font.glyph_id(ch),
scale,
@ -80,6 +74,7 @@ impl Font {
}
}
}
images
TextureAtlas::from_textures(names, images)
}
}

View file

@ -4,12 +4,14 @@ use std::{
use wgpu::{naga, Device, FilterMode, Queue, ShaderModule, TextureFormat, TextureUsages};
use wgpu::naga::ShaderStage;
use comet_log::info;
use crate::{font, texture, Texture};
use crate::font::Font;
use crate::texture_atlas::{TextureAtlas, TextureRegion};
pub struct GraphicResourceManager {
texture_atlas: TextureAtlas,
fonts: HashMap<String, TextureAtlas>,
fonts: Vec<Font>,
data_files: HashMap<String, String>,
shaders: HashMap<String, ShaderModule>
}
@ -18,7 +20,7 @@ impl GraphicResourceManager {
pub fn new() -> Self {
Self {
texture_atlas: TextureAtlas::empty(),
fonts: HashMap::new(),
fonts: Vec::new(),
data_files: HashMap::new(),
shaders: HashMap::new()
}
@ -36,6 +38,14 @@ impl GraphicResourceManager {
&self.data_files
}
pub fn fonts(&self) -> &Vec<Font> {
&self.fonts
}
pub fn get_glyph(&self, font: &str, ch: char) -> Option<&TextureRegion> {
self.fonts.iter().find(|f| f.name() == font).and_then(|f| f.get_glyph(ch))
}
pub fn set_texture_atlas(&mut self, texture_atlas: TextureAtlas) {
self.texture_atlas = texture_atlas;
@ -122,9 +132,10 @@ impl GraphicResourceManager {
}
pub fn load_font(&mut self, path: &str, size: f32) {
let font = font::Font::new(path, size);
let atlas = TextureAtlas::from_textures(font.glyphs(), font.names());
self.fonts.insert(font.name().to_string(), atlas);
info!("Loading font: {}", path);
let font = Font::new(path, size);
info!("Font {} loaded!", font.name());
self.fonts.push(font);
}
/*pub async fn load_model(

View file

@ -166,8 +166,8 @@ impl TextureAtlas {
}
pub fn from_textures(
textures: Vec<DynamicImage>,
names: Vec<String>,
textures: Vec<DynamicImage>,
) -> Self {
let mut regions: HashMap<String, TextureRegion> = HashMap::new();