use nanoserde::DeRon;
use super::{Loadable, sprite::Sprite};
use crate::{
assets::{Id, loader::ron::RonLoader},
context::ContextInner,
};
pub(crate) struct Font {
pub(crate) sprites: Vec<Sprite>,
pub(crate) metadata: FontMetadata,
}
impl Loadable for Font {
fn load_if_exists(id: &Id, ctx: &mut ContextInner) -> Option<Self> {
let base = Sprite::load_if_exists_without_metadata(id, ctx)?;
let metadata = FontMetadata::load_if_exists(id, ctx).unwrap_or_default();
let sprites = base.horizontal_parts(metadata.glyph_width);
assert_eq!(
metadata.last_char - metadata.first_char,
sprites.len() - 1,
"Font not properly defined, last char does not match length of parsed glyphs"
);
Some(Self { sprites, metadata })
}
}
#[derive(Debug, Clone, Copy, DeRon)]
pub struct FontMetadata {
pub(crate) glyph_width: f32,
pub(crate) glyph_height: f32,
#[nserde(default = "'!' as usize")]
pub(crate) first_char: usize,
#[nserde(default = "'~' as usize")]
pub(crate) last_char: usize,
}
impl Loadable for FontMetadata {
fn load_if_exists(id: &Id, ctx: &mut ContextInner) -> Option<Self> {
ctx.asset_source.load_if_exists::<RonLoader, Self>(id)
}
}
impl Default for FontMetadata {
fn default() -> Self {
Self {
glyph_width: 8.0,
glyph_height: 8.0,
first_char: '!' as usize,
last_char: '~' as usize,
}
}
}