use crate::error::{FontMeshError, Result};
use skrifa::{
instance::{LocationRef, Size},
metrics::Metrics,
FontRef, GlyphId, MetadataProvider,
};
pub fn parse_font(data: &[u8]) -> Result<FontRef<'_>> {
FontRef::from_index(data, 0)
.map_err(|e| FontMeshError::ParseError(format!("Failed to parse font: {e:?}")))
}
#[inline]
fn em_scale(font: &FontRef) -> f32 {
let upem = font
.metrics(Size::unscaled(), LocationRef::default())
.units_per_em
.max(1);
1.0 / upem as f32
}
#[inline]
fn metrics(font: &FontRef) -> Metrics {
font.metrics(Size::unscaled(), LocationRef::default())
}
#[inline]
pub fn glyph_id(font: &FontRef, character: char) -> Option<GlyphId> {
font.charmap().map(character)
}
#[inline]
pub fn ascender(font: &FontRef) -> f32 {
metrics(font).ascent * em_scale(font)
}
#[inline]
pub fn descender(font: &FontRef) -> f32 {
metrics(font).descent * em_scale(font)
}
#[inline]
pub fn line_gap(font: &FontRef) -> f32 {
metrics(font).leading * em_scale(font)
}
#[inline]
pub fn advance(font: &FontRef, glyph_id: GlyphId) -> Option<f32> {
let scale = em_scale(font);
font.glyph_metrics(Size::unscaled(), LocationRef::default())
.advance_width(glyph_id)
.map(|adv| adv * scale)
}
#[inline]
pub fn glyph_advance(font: &FontRef, character: char) -> Option<f32> {
advance(font, glyph_id(font, character)?)
}