use crate::GlyphId;
use crate::conv::{DPU, LineMetrics};
use ttf_parser::Face;
#[derive(Copy, Clone, Debug)]
pub struct FaceRef<'a>(pub(crate) &'a Face<'a>);
impl<'a> FaceRef<'a> {
#[inline]
pub fn glyph_index(&self, c: char) -> GlyphId {
GlyphId(self.0.glyph_index(c).map(|id| id.0).unwrap_or(0))
}
#[inline]
pub fn dpu(self, dpem: f32) -> DPU {
DPU(dpem / f32::from(self.0.units_per_em()))
}
#[inline]
pub fn scale_by_dpem(self, dpem: f32) -> ScaledFaceRef<'a> {
ScaledFaceRef(self.0, self.dpu(dpem))
}
#[inline]
pub fn scale_by_dpu(self, dpu: DPU) -> ScaledFaceRef<'a> {
ScaledFaceRef(self.0, dpu)
}
}
#[derive(Copy, Clone, Debug)]
pub struct ScaledFaceRef<'a>(&'a Face<'a>, DPU);
impl<'a> ScaledFaceRef<'a> {
#[inline]
pub fn face(&self) -> FaceRef<'_> {
FaceRef(self.0)
}
#[inline]
pub fn dpu(&self) -> DPU {
self.1
}
#[inline]
pub fn h_advance(&self, id: GlyphId) -> f32 {
let x = self.0.glyph_hor_advance(id.into()).unwrap();
self.1.u16_to_px(x)
}
#[inline]
pub fn h_side_bearing(&self, id: GlyphId) -> f32 {
let x = self.0.glyph_hor_side_bearing(id.into()).unwrap_or(0);
self.1.i16_to_px(x)
}
#[inline]
pub fn ascent(&self) -> f32 {
self.1.i16_to_px(self.0.ascender())
}
#[inline]
pub fn descent(&self) -> f32 {
self.1.i16_to_px(self.0.descender())
}
#[inline]
pub fn line_gap(&self) -> f32 {
self.1.i16_to_px(self.0.line_gap())
}
#[inline]
pub fn height(&self) -> f32 {
self.1.i16_to_px(self.0.height())
}
#[inline]
pub fn underline_metrics(&self) -> Option<LineMetrics> {
self.0
.underline_metrics()
.map(|m| self.1.to_line_metrics(m))
}
#[inline]
pub fn strikethrough_metrics(&self) -> Option<LineMetrics> {
self.0
.strikeout_metrics()
.map(|m| self.1.to_line_metrics(m))
}
}