use super::Tables;
use crate::ps::cff::CffFontRef;
use crate::tables::{glyf::Glyf, gvar::Gvar, hvar::Hvar, loca::Loca, vorg::Vorg, vvar::Vvar};
use crate::TableProvider;
use alloc::sync::Arc;
use yoke::{Yoke, Yokeable};
pub(crate) struct TableCache<Y: for<'a> Yokeable<'a>>(Yoke<Y, Arc<Tables>>);
impl<Y: for<'a> Yokeable<'a>> TableCache<Y> {
pub(crate) fn read<F>(tables: Arc<Tables>, read: F) -> Self
where
F: for<'a> FnOnce(&'a Tables) -> <Y as Yokeable<'a>>::Output,
{
Self(Yoke::attach_to_cart(tables, read))
}
#[inline]
pub(crate) fn get(&self) -> &<Y as Yokeable<'_>>::Output {
self.0.get()
}
}
#[derive(Clone, Default, Yokeable)]
pub(crate) struct GlyfLoca<'a>(pub(crate) Option<(Glyf<'a>, Loca<'a>)>);
impl<'a> GlyfLoca<'a> {
pub(crate) fn read(tables: &impl TableProvider<'a>) -> Self {
Self(tables.glyf().ok().zip(tables.loca(None).ok()))
}
}
#[derive(Clone, Default, Yokeable)]
pub(crate) struct HvarTable<'a>(pub(crate) Option<Hvar<'a>>);
impl<'a> HvarTable<'a> {
pub(crate) fn read(tables: &impl TableProvider<'a>) -> Self {
Self(tables.hvar().ok())
}
}
#[derive(Clone, Default, Yokeable)]
pub(crate) struct VvarTable<'a>(pub(crate) Option<Vvar<'a>>);
impl<'a> VvarTable<'a> {
pub(crate) fn read(tables: &impl TableProvider<'a>) -> Self {
Self(tables.vvar().ok())
}
}
#[derive(Clone, Default, Yokeable)]
pub(crate) struct GvarTable<'a>(pub(crate) Option<Gvar<'a>>);
impl<'a> GvarTable<'a> {
pub(crate) fn read(tables: &impl TableProvider<'a>) -> Self {
Self(tables.gvar().ok())
}
}
#[derive(Clone, Default, Yokeable)]
pub(crate) struct CffFont<'a>(pub(crate) Option<CffFontRef<'a>>);
impl<'a> CffFont<'a> {
pub(crate) fn read(tables: &impl TableProvider<'a>) -> Self {
let upem = tables.head().ok().map(|head| head.units_per_em() as i32);
let data = tables
.cff2()
.ok()
.map(|cff2| cff2.offset_data().as_bytes())
.or_else(|| tables.cff().ok().map(|cff| cff.offset_data().as_bytes()));
Self(data.and_then(|data| CffFontRef::new(data, 0, upem).ok()))
}
}
#[derive(Clone, Default, Yokeable)]
pub(crate) struct VorgTable<'a>(pub(crate) Option<Vorg<'a>>);
impl<'a> VorgTable<'a> {
pub(crate) fn read(tables: &impl TableProvider<'a>) -> Self {
Self(tables.vorg().ok())
}
}