#[cfg(all(feature = "libm", not(feature = "std")))]
use crate::nostd_float::FloatExt;
use crate::{Font, Glyph, GlyphId, OutlinedGlyph, Rect};
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
pub struct PxScale {
pub x: f32,
pub y: f32,
}
impl PxScale {
#[inline]
pub fn round(self) -> Self {
Self {
x: self.x.round(),
y: self.y.round(),
}
}
}
impl From<f32> for PxScale {
#[inline]
fn from(s: f32) -> Self {
PxScale { x: s, y: s }
}
}
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
pub struct PxScaleFactor {
pub horizontal: f32,
pub vertical: f32,
}
pub trait ScaleFont<F: Font> {
fn scale(&self) -> PxScale;
fn font(&self) -> &F;
#[inline]
fn h_scale_factor(&self) -> f32 {
self.scale().x / self.font().height_unscaled()
}
#[inline]
fn v_scale_factor(&self) -> f32 {
self.scale().y / self.font().height_unscaled()
}
#[inline]
fn scale_factor(&self) -> PxScaleFactor {
PxScaleFactor {
horizontal: self.h_scale_factor(),
vertical: self.v_scale_factor(),
}
}
#[inline]
fn ascent(&self) -> f32 {
self.v_scale_factor() * self.font().ascent_unscaled()
}
#[inline]
fn descent(&self) -> f32 {
self.v_scale_factor() * self.font().descent_unscaled()
}
#[inline]
fn height(&self) -> f32 {
self.scale().y
}
#[inline]
fn line_gap(&self) -> f32 {
self.v_scale_factor() * self.font().line_gap_unscaled()
}
#[inline]
fn glyph_id(&self, c: char) -> GlyphId {
self.font().glyph_id(c)
}
#[inline]
fn scaled_glyph(&self, c: char) -> Glyph {
self.font().glyph_id(c).with_scale(self.scale())
}
#[inline]
fn h_advance(&self, id: GlyphId) -> f32 {
self.h_scale_factor() * self.font().h_advance_unscaled(id)
}
#[inline]
fn h_side_bearing(&self, id: GlyphId) -> f32 {
self.h_scale_factor() * self.font().h_side_bearing_unscaled(id)
}
#[inline]
fn v_advance(&self, id: GlyphId) -> f32 {
self.v_scale_factor() * self.font().v_advance_unscaled(id)
}
#[inline]
fn v_side_bearing(&self, id: GlyphId) -> f32 {
self.v_scale_factor() * self.font().v_side_bearing_unscaled(id)
}
#[inline]
fn kern(&self, first: GlyphId, second: GlyphId) -> f32 {
self.h_scale_factor() * self.font().kern_unscaled(first, second)
}
#[inline]
fn glyph_bounds(&self, glyph: &Glyph) -> Rect {
self.font().glyph_bounds(glyph)
}
#[inline]
fn glyph_count(&self) -> usize {
self.font().glyph_count()
}
fn codepoint_ids(&self) -> crate::CodepointIdIter<'_>;
#[inline]
fn outline_glyph(&self, glyph: Glyph) -> Option<OutlinedGlyph> {
self.font().outline_glyph(glyph)
}
}
impl<F: Font, SF: ScaleFont<F>> ScaleFont<F> for &SF {
#[inline]
fn scale(&self) -> PxScale {
(*self).scale()
}
#[inline]
fn font(&self) -> &F {
(*self).font()
}
#[inline]
fn codepoint_ids(&self) -> crate::CodepointIdIter<'_> {
(*self).codepoint_ids()
}
}
#[derive(Clone, Copy, Debug)]
pub struct PxScaleFont<F> {
pub font: F,
pub scale: PxScale,
}
impl<F> PxScaleFont<F> {
#[inline]
pub fn with_scale<S: Into<PxScale>>(mut self, scale: S) -> Self {
self.scale = scale.into();
self
}
}
impl<F: Font> ScaleFont<F> for PxScaleFont<F> {
#[inline]
fn scale(&self) -> PxScale {
self.scale
}
#[inline]
fn font(&self) -> &F {
&self.font
}
#[inline]
fn codepoint_ids(&self) -> crate::CodepointIdIter<'_> {
self.font.codepoint_ids()
}
}