use std::marker::PhantomData;
use super::{
Context,
extensions::{Empty, camera::MainCamera, pivot::Pivoting},
load::FromMemory,
sprite::SpriteContext,
text::TextContext,
};
use crate::assets::loadable::sprite::SpritePivot;
pub struct FontContext<'font, 'ctx> {
pub(crate) font: &'font str,
pub(crate) ctx: &'ctx Context,
}
impl<'font, 'ctx> FontContext<'font, 'ctx> {
#[inline]
#[must_use]
pub fn glyph(
&self,
glyph: impl Into<usize>,
) -> SpriteContext<'_, FromMemory, Empty, Empty, Empty, Empty, Pivoting, Empty, MainCamera>
{
fn inner<'ctx>(
this: &FontContext<'_, 'ctx>,
glyph: usize,
) -> SpriteContext<'ctx, FromMemory, Empty, Empty, Empty, Empty, Pivoting, Empty, MainCamera>
{
let sprite = this.ctx.write(|ctx| {
let font = ctx.font(this.font);
let char_offset = glyph - font.metadata.first_char;
font.sprites[char_offset]
});
SpriteContext {
load: FromMemory::new(sprite),
ctx: this.ctx,
translation: Empty,
previous_translation: Empty,
rotation: Empty,
scaling: Empty,
pivot: Pivoting::new(SpritePivot::Center, SpritePivot::Center),
shader: Empty,
phantom: PhantomData,
}
}
inner(self, glyph.into())
}
#[inline(always)]
#[must_use]
pub const fn text<'text>(
self,
text: &'text str,
) -> TextContext<'font, 'text, 'ctx, Empty, Empty, MainCamera> {
TextContext {
font: self.font,
ctx: self.ctx,
text,
translation: Empty,
previous_translation: Empty,
phantom: PhantomData,
}
}
#[inline]
#[must_use]
pub fn glyph_size(&self) -> (f32, f32) {
self.ctx.write(|ctx| {
let metadata = ctx.font(self.font).metadata;
(metadata.glyph_width, metadata.glyph_height)
})
}
#[inline]
#[must_use]
pub fn glyph_width(&self) -> f32 {
self.ctx
.write(|ctx| ctx.font(self.font).metadata.glyph_width)
}
#[inline]
#[must_use]
pub fn glyph_height(&self) -> f32 {
self.ctx
.write(|ctx| ctx.font(self.font).metadata.glyph_height)
}
#[inline]
#[must_use]
pub fn first_char(&self) -> usize {
self.ctx
.write(|ctx| ctx.font(self.font).metadata.first_char)
}
#[inline]
#[must_use]
pub fn last_char(&self) -> usize {
self.ctx.write(|ctx| ctx.font(self.font).metadata.last_char)
}
#[inline]
#[must_use]
pub fn chars(&self) -> usize {
self.ctx.write(|ctx| {
let metadata = ctx.font(self.font).metadata;
metadata.last_char - metadata.first_char
})
}
}
impl Context {
#[inline(always)]
#[must_use]
pub const fn font<'font>(&self, font: &'font str) -> FontContext<'font, '_> {
FontContext { font, ctx: self }
}
}