read_fonts/model/font/
cache.rs1use super::Tables;
14use crate::model::glyph::outline::varc;
15use crate::ps::cff::CffFontRef;
16use crate::tables::{
17 cbdt::Cbdt,
18 cblc::Cblc,
19 colr::Colr,
20 cpal::Cpal,
21 ebdt::Ebdt,
22 eblc::Eblc,
23 glyf::Glyf,
24 gvar::SelectedGvar,
25 hmtx::GlyphMetricRecords,
26 hvar::Hvar,
27 loca::Loca,
28 sbix::Sbix,
29 variations::{DeltaSetIndexMap, ItemVariationStore},
30 vorg::Vorg,
31 vvar::Vvar,
32};
33use crate::TableProvider;
34
35use alloc::sync::Arc;
36use yoke::{Yoke, Yokeable};
37
38fn units_per_em<'a>(tables: &impl TableProvider<'a>) -> u16 {
40 crate::model::metrics::units_per_em(tables.head().map_or(0, |head| head.units_per_em()))
41}
42
43pub(crate) struct TableCache<Y: for<'a> Yokeable<'a>>(Yoke<Y, Arc<Tables>>);
45
46impl<Y: for<'a> Yokeable<'a>> TableCache<Y> {
47 pub(crate) fn read<F>(tables: Arc<Tables>, read: F) -> Self
49 where
50 F: for<'a> FnOnce(&'a Tables) -> <Y as Yokeable<'a>>::Output,
51 {
52 Self(Yoke::attach_to_cart(tables, read))
53 }
54
55 #[inline]
57 pub(crate) fn get(&self) -> &<Y as Yokeable<'_>>::Output {
58 self.0.get()
59 }
60}
61
62#[derive(Clone, Default, Yokeable)]
67pub(crate) struct GlyfLoca<'a>(pub(crate) Option<(Glyf<'a>, Loca<'a>)>);
68
69impl<'a> GlyfLoca<'a> {
70 pub(crate) fn read(tables: &impl TableProvider<'a>) -> Self {
71 Self(tables.selected_glyf_loca(None).ok())
72 }
73}
74
75#[derive(Clone, Default, Yokeable)]
77pub(crate) struct MetricsTable<'a>(pub(crate) GlyphMetricRecords<'a>);
78
79#[derive(Clone, Default, Yokeable)]
81pub(crate) struct HvarTable<'a>(pub(crate) Option<Hvar<'a>>);
82
83impl<'a> HvarTable<'a> {
84 pub(crate) fn read(tables: &impl TableProvider<'a>) -> Self {
85 Self(tables.hvar().ok())
86 }
87}
88
89#[derive(Clone, Default, Yokeable)]
91pub(crate) struct VvarTable<'a>(pub(crate) Option<Vvar<'a>>);
92
93impl<'a> VvarTable<'a> {
94 pub(crate) fn read(tables: &impl TableProvider<'a>) -> Self {
95 Self(tables.vvar().ok())
96 }
97}
98
99#[derive(Clone, Default, Yokeable)]
104pub(crate) struct GvarTable<'a>(pub(crate) Option<SelectedGvar<'a>>);
105
106impl<'a> GvarTable<'a> {
107 pub(crate) fn read(tables: &impl TableProvider<'a>) -> Self {
108 Self(tables.selected_gvar().ok())
109 }
110}
111
112#[derive(Clone, Default, Yokeable)]
114pub(crate) struct Cff2Font<'a>(pub(crate) Option<CffFontRef<'a>>);
115
116impl<'a> Cff2Font<'a> {
117 pub(crate) fn read(tables: &impl TableProvider<'a>) -> Self {
118 let upem = Some(units_per_em(tables) as i32);
119 Self(
120 tables
121 .cff2()
122 .ok()
123 .and_then(|cff2| CffFontRef::new(cff2.offset_data().as_bytes(), 0, upem).ok()),
124 )
125 }
126}
127
128#[derive(Clone, Default, Yokeable)]
133pub(crate) struct CffFont<'a>(pub(crate) Option<CffFontRef<'a>>);
134
135impl<'a> CffFont<'a> {
136 pub(crate) fn read(tables: &impl TableProvider<'a>) -> Self {
137 let upem = Some(units_per_em(tables) as i32);
138 Self(
139 tables
140 .cff()
141 .ok()
142 .and_then(|cff| CffFontRef::new(cff.offset_data().as_bytes(), 0, upem).ok()),
143 )
144 }
145}
146
147#[derive(Clone, Default, Yokeable)]
152pub(crate) struct VorgTable<'a>(pub(crate) Option<Vorg<'a>>);
153
154impl<'a> VorgTable<'a> {
155 pub(crate) fn read(tables: &impl TableProvider<'a>) -> Self {
156 Self(tables.vorg().ok())
157 }
158}
159
160impl<'a> varc::Outlines<'a> {
161 pub(crate) fn read(tables: &impl TableProvider<'a>) -> Option<Self> {
166 let varc = tables.varc().ok()?;
167 let upem = units_per_em(tables);
168 let mut axis_count = tables
171 .fvar()
172 .map(|fvar| fvar.axis_count() as usize)
173 .unwrap_or_default();
174 if let Ok(gvar) = tables.gvar() {
175 axis_count = axis_count.max(gvar.axis_count() as usize);
176 }
177 if let Ok(gvar) = tables.gvar_extended() {
178 axis_count = axis_count.max(gvar.axis_count() as usize);
179 }
180 if let Some(count) = tables
181 .cff2()
182 .ok()
183 .and_then(|cff2| CffFontRef::new(cff2.offset_data().as_bytes(), 0, None).ok())
184 .and_then(|cff| cff.var_store()?.variation_region_list().ok())
185 .map(|regions| regions.axis_count() as usize)
186 {
187 axis_count = axis_count.max(count);
188 }
189 varc::Outlines::new(varc, upem, axis_count).ok()
190 }
191}
192
193#[derive(Clone, Yokeable)]
195pub(crate) struct ColrTables<'a> {
196 pub(crate) colr: Colr<'a>,
197 pub(crate) index_map: Option<DeltaSetIndexMap<'a>>,
198 pub(crate) var_store: Option<ItemVariationStore<'a>>,
199}
200
201impl<'a> ColrTables<'a> {
202 pub(crate) fn read(tables: &impl TableProvider<'a>) -> Option<Self> {
204 tables.colr().ok().map(Self::new)
205 }
206
207 pub(crate) fn new(colr: Colr<'a>) -> Self {
208 Self {
209 index_map: colr.var_index_map().and_then(|map| map.ok()),
210 var_store: colr.item_variation_store().and_then(|store| store.ok()),
211 colr,
212 }
213 }
214}
215
216#[derive(Clone, Default, Yokeable)]
218pub(crate) struct CpalTable<'a>(pub(crate) Option<Cpal<'a>>);
219
220impl<'a> CpalTable<'a> {
221 pub(crate) fn read(tables: &impl TableProvider<'a>) -> Self {
222 Self(tables.cpal().ok())
223 }
224}
225
226#[derive(Clone, Default, Yokeable)]
228pub(crate) struct SbixTable<'a>(pub(crate) Option<Sbix<'a>>);
229
230impl<'a> SbixTable<'a> {
231 pub(crate) fn read(tables: &impl TableProvider<'a>) -> Self {
232 Self(tables.sbix().ok())
233 }
234}
235
236#[derive(Clone, Default, Yokeable)]
238pub(crate) struct CbdtTables<'a>(pub(crate) Option<(Cblc<'a>, Cbdt<'a>)>);
239
240impl<'a> CbdtTables<'a> {
241 pub(crate) fn read(tables: &impl TableProvider<'a>) -> Self {
242 Self(tables.cblc().ok().zip(tables.cbdt().ok()))
243 }
244}
245
246#[derive(Clone, Default, Yokeable)]
249pub(crate) struct EbdtTables<'a>(pub(crate) Option<(Eblc<'a>, Ebdt<'a>)>);
250
251impl<'a> EbdtTables<'a> {
252 pub(crate) fn read(tables: &impl TableProvider<'a>) -> Self {
253 Self(tables.eblc().ok().zip(tables.ebdt().ok()))
254 }
255}