use std::collections::BTreeMap;
use std::path::Path;
use log::debug;
use rocketsplash_formats::{read_font_atlas, AllocationTracker, GlyphData, GlyphVariants};
use super::cls_font::{Font, RuntimeGlyph, RuntimeGlyphVariants};
use super::fnc_convert_glyph::convert_glyph;
use crate::Error;
impl Font {
pub fn load(path: impl AsRef<Path>) -> Result<Self, Error> {
let bytes = std::fs::read(path)?;
load_font_from_bytes(&bytes)
}
pub fn from_bytes(bytes: &[u8]) -> Result<Self, Error> {
load_font_from_bytes(bytes)
}
}
pub fn load_font_from_bytes(bytes: &[u8]) -> Result<Font, Error> {
let atlas = read_font_atlas(bytes)?;
let mut tracker = AllocationTracker::new();
let mut glyphs = BTreeMap::new();
for (ch, variants) in atlas.glyphs {
let runtime_variants = convert_variants(&mut tracker, variants)?;
glyphs.insert(ch, runtime_variants);
}
debug!("Loaded font atlas with {} glyphs", glyphs.len());
Ok(Font {
meta: atlas.meta,
line_height: atlas.line_height,
mode: atlas.mode,
available_styles: atlas.available_styles,
glyphs,
})
}
fn convert_variants(
tracker: &mut AllocationTracker,
variants: GlyphVariants,
) -> Result<RuntimeGlyphVariants, Error> {
Ok(RuntimeGlyphVariants {
base: convert_glyph(tracker, variants.base)?,
bold: convert_optional(tracker, variants.bold)?,
italic: convert_optional(tracker, variants.italic)?,
bold_italic: convert_optional(tracker, variants.bold_italic)?,
reverse: convert_optional(tracker, variants.reverse)?,
})
}
fn convert_optional(
tracker: &mut AllocationTracker,
glyph: Option<GlyphData>,
) -> Result<Option<RuntimeGlyph>, Error> {
glyph.map(|value| convert_glyph(tracker, value)).transpose()
}