use crate::{
primitives::{Interpolate, Point, geometry::Rectangle},
surface::Surface,
};
mod character_buffer_font;
pub use character_buffer_font::CharacterBufferFont;
#[cfg(feature = "embedded-graphics")]
mod embedded_mono_font;
#[cfg(feature = "embedded-graphics")]
mod rusttype;
#[cfg(feature = "embedded-graphics")]
mod u8g2;
pub trait Font {
type Attributes: Default + Interpolate + Clone;
fn metrics(&self, attributes: &Self::Attributes) -> impl FontMetrics;
}
pub(crate) trait Sealed {}
#[expect(private_bounds)]
pub trait FontRender<Color>: Font + Sealed {
fn draw(
&self,
character: char,
offset: Point,
color: Color,
background_color: Option<Color>,
attributes: &Self::Attributes,
surface: &mut impl Surface<Color = Color>,
);
}
pub trait FontMetrics {
#[must_use]
fn rendered_size(&self, character: char) -> Option<Rectangle>;
#[must_use]
fn vertical_metrics(&self) -> VMetrics;
#[must_use]
fn advance(&self, character: char) -> u32;
}
impl<T: FontMetrics> FontMetrics for &T {
fn rendered_size(&self, character: char) -> Option<Rectangle> {
(*self).rendered_size(character)
}
fn vertical_metrics(&self) -> VMetrics {
(*self).vertical_metrics()
}
fn advance(&self, character: char) -> u32 {
(*self).advance(character)
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct VMetrics {
pub ascent: i32,
pub descent: i32,
pub line_spacing: i32,
}
impl VMetrics {
#[must_use]
pub fn line_height(&self) -> u32 {
(self.ascent - self.descent + self.line_spacing).max(0) as u32
}
}
pub trait CustomSize {
#[must_use]
fn with_size(self, size: u32) -> Self;
}