resonance 0.1.0

A modular game engine. Heavy work in progress.
Documentation

use crate::assets::loader::{AssetLoader, LoadError};
use ab_glyph::{Font, FontArc, ScaleFont};
use std::path::Path;

#[derive(Clone)]
pub struct FontData {
    pub font: FontArc,
    pub family_name: String,
}

impl FontData {
    pub fn new(font: FontArc) -> Self {

        let family_name = "Unknown".to_string();

        Self { font, family_name }
    }

    pub fn ascent(&self, size: f32) -> f32 {
        self.font.as_scaled(size).ascent()
    }

    pub fn descent(&self, size: f32) -> f32 {
        self.font.as_scaled(size).descent()
    }

    pub fn line_gap(&self, size: f32) -> f32 {
        self.font.as_scaled(size).line_gap()
    }

    pub fn height(&self, size: f32) -> f32 {
        let scaled = self.font.as_scaled(size);
        scaled.ascent() - scaled.descent() + scaled.line_gap()
    }
}

pub struct TtfLoader;

impl AssetLoader for TtfLoader {
    type Asset = FontData;

    fn load(&self, path: &Path) -> Result<Self::Asset, LoadError> {
        let bytes = std::fs::read(path)
            .map_err(|e| LoadError::LoadFailed(format!("Failed to read font file: {}", e)))?;

        let font = FontArc::try_from_vec(bytes)
            .map_err(|e| LoadError::LoadFailed(format!("Failed to parse TTF font: {:?}", e)))?;

        log::info!("Loaded TTF font from {:?}", path);

        Ok(FontData::new(font))
    }

    fn extensions(&self) -> &[&str] {
        &["ttf", "otf"]
    }
}

pub fn load_font_from_bytes(bytes: &[u8]) -> Result<FontData, LoadError> {
    let font = FontArc::try_from_vec(bytes.to_vec())
        .map_err(|e| LoadError::LoadFailed(format!("Failed to parse font: {:?}", e)))?;

    Ok(FontData::new(font))
}