1use types::{BigEndian, Tag};
4
5use crate::{tables, FontData, FontRead, ReadError};
6
7pub trait TopLevelTable {
11 const TAG: Tag;
13}
14
15pub trait TableProvider<'a> {
17 fn data_for_tag(&self, tag: Tag) -> Option<FontData<'a>>;
18
19 fn expect_data_for_tag(&self, tag: Tag) -> Result<FontData<'a>, ReadError> {
20 self.data_for_tag(tag).ok_or(ReadError::TableIsMissing(tag))
21 }
22
23 fn expect_table<T: TopLevelTable + FontRead<'a, Args = ()>>(&self) -> Result<T, ReadError> {
24 self.expect_data_for_tag(T::TAG).and_then(FontRead::read)
25 }
26
27 fn head(&self) -> Result<tables::head::Head<'a>, ReadError> {
28 self.expect_table()
29 }
30
31 fn name(&self) -> Result<tables::name::Name<'a>, ReadError> {
32 self.expect_table()
33 }
34
35 fn hhea(&self) -> Result<tables::hhea::Hhea<'a>, ReadError> {
36 self.expect_table()
37 }
38
39 fn vhea(&self) -> Result<tables::vhea::Vhea<'a>, ReadError> {
40 self.expect_table()
41 }
42
43 fn hmtx(&self) -> Result<tables::hmtx::Hmtx<'a>, ReadError> {
44 let number_of_h_metrics = self.hhea().map(|hhea| hhea.number_of_h_metrics())?;
46 let data = self.expect_data_for_tag(tables::hmtx::Hmtx::TAG)?;
47 tables::hmtx::Hmtx::read(data, number_of_h_metrics)
48 }
49
50 fn hdmx(&self) -> Result<tables::hdmx::Hdmx<'a>, ReadError> {
51 let num_glyphs = self.maxp().map(|maxp| maxp.num_glyphs())?;
52 let data = self.expect_data_for_tag(tables::hdmx::Hdmx::TAG)?;
53 tables::hdmx::Hdmx::read(data, num_glyphs)
54 }
55
56 fn vmtx(&self) -> Result<tables::vmtx::Vmtx<'a>, ReadError> {
57 let number_of_v_metrics = self.vhea().map(|vhea| vhea.number_of_long_ver_metrics())?;
59 let data = self.expect_data_for_tag(tables::vmtx::Vmtx::TAG)?;
60 tables::vmtx::Vmtx::read(data, number_of_v_metrics)
61 }
62
63 fn vorg(&self) -> Result<tables::vorg::Vorg<'a>, ReadError> {
64 self.expect_table()
65 }
66
67 fn fvar(&self) -> Result<tables::fvar::Fvar<'a>, ReadError> {
68 self.expect_table()
69 }
70
71 fn avar(&self) -> Result<tables::avar::Avar<'a>, ReadError> {
72 self.expect_table()
73 }
74
75 fn hvar(&self) -> Result<tables::hvar::Hvar<'a>, ReadError> {
76 self.expect_table()
77 }
78
79 fn vvar(&self) -> Result<tables::vvar::Vvar<'a>, ReadError> {
80 self.expect_table()
81 }
82
83 fn mvar(&self) -> Result<tables::mvar::Mvar<'a>, ReadError> {
84 self.expect_table()
85 }
86
87 fn maxp(&self) -> Result<tables::maxp::Maxp<'a>, ReadError> {
88 self.expect_table()
89 }
90
91 fn os2(&self) -> Result<tables::os2::Os2<'a>, ReadError> {
92 self.expect_table()
93 }
94
95 fn post(&self) -> Result<tables::post::Post<'a>, ReadError> {
96 self.expect_table()
97 }
98
99 fn gasp(&self) -> Result<tables::gasp::Gasp<'a>, ReadError> {
100 self.expect_table()
101 }
102
103 fn loca(&self, is_long: impl Into<Option<bool>>) -> Result<tables::loca::Loca<'a>, ReadError> {
105 let is_long = match is_long.into() {
106 Some(val) => val,
107 None => self.head()?.index_to_loc_format() == 1,
108 };
109 let data = self.expect_data_for_tag(tables::loca::Loca::TAG)?;
110 tables::loca::Loca::read(data, is_long)
111 }
112
113 fn glyf(&self) -> Result<tables::glyf::Glyf<'a>, ReadError> {
114 self.expect_table()
115 }
116
117 fn gvar(&self) -> Result<tables::gvar::Gvar<'a>, ReadError> {
118 self.expect_table()
119 }
120
121 fn cvt(&self) -> Result<&'a [BigEndian<i16>], ReadError> {
124 let table_data = self.expect_data_for_tag(Tag::new(b"cvt "))?;
125 table_data.read_array(0..table_data.len())
126 }
127
128 fn cvar(&self) -> Result<tables::cvar::Cvar<'a>, ReadError> {
129 self.expect_table()
130 }
131
132 fn cff(&self) -> Result<tables::cff::Cff<'a>, ReadError> {
133 self.expect_table()
134 }
135
136 fn cff2(&self) -> Result<tables::cff2::Cff2<'a>, ReadError> {
137 self.expect_table()
138 }
139
140 fn cmap(&self) -> Result<tables::cmap::Cmap<'a>, ReadError> {
141 self.expect_table()
142 }
143
144 fn gdef(&self) -> Result<tables::gdef::Gdef<'a>, ReadError> {
145 self.expect_table()
146 }
147
148 fn gpos(&self) -> Result<tables::gpos::Gpos<'a>, ReadError> {
149 self.expect_table()
150 }
151
152 fn gsub(&self) -> Result<tables::gsub::Gsub<'a>, ReadError> {
153 self.expect_table()
154 }
155
156 fn feat(&self) -> Result<tables::feat::Feat<'a>, ReadError> {
157 self.expect_table()
158 }
159
160 fn ltag(&self) -> Result<tables::ltag::Ltag<'a>, ReadError> {
161 self.expect_table()
162 }
163
164 fn ankr(&self) -> Result<tables::ankr::Ankr<'a>, ReadError> {
165 self.expect_table()
166 }
167
168 fn trak(&self) -> Result<tables::trak::Trak<'a>, ReadError> {
169 self.expect_table()
170 }
171
172 fn morx(&self) -> Result<tables::morx::Morx<'a>, ReadError> {
173 self.expect_table()
174 }
175
176 fn mort(&self) -> Result<tables::mort::Mort<'a>, ReadError> {
177 self.expect_table()
178 }
179
180 fn kerx(&self) -> Result<tables::kerx::Kerx<'a>, ReadError> {
181 self.expect_table()
182 }
183
184 fn kern(&self) -> Result<tables::kern::Kern<'a>, ReadError> {
185 self.expect_table()
186 }
187
188 fn colr(&self) -> Result<tables::colr::Colr<'a>, ReadError> {
189 self.expect_table()
190 }
191
192 fn cpal(&self) -> Result<tables::cpal::Cpal<'a>, ReadError> {
193 self.expect_table()
194 }
195
196 fn cblc(&self) -> Result<tables::cblc::Cblc<'a>, ReadError> {
197 self.expect_table()
198 }
199
200 fn cbdt(&self) -> Result<tables::cbdt::Cbdt<'a>, ReadError> {
201 self.expect_table()
202 }
203
204 fn eblc(&self) -> Result<tables::eblc::Eblc<'a>, ReadError> {
205 self.expect_table()
206 }
207
208 fn ebdt(&self) -> Result<tables::ebdt::Ebdt<'a>, ReadError> {
209 self.expect_table()
210 }
211
212 fn sbix(&self) -> Result<tables::sbix::Sbix<'a>, ReadError> {
213 let num_glyphs = self.maxp().map(|maxp| maxp.num_glyphs())?;
215 let data = self.expect_data_for_tag(tables::sbix::Sbix::TAG)?;
216 tables::sbix::Sbix::read(data, num_glyphs)
217 }
218
219 fn stat(&self) -> Result<tables::stat::Stat<'a>, ReadError> {
220 self.expect_table()
221 }
222
223 fn svg(&self) -> Result<tables::svg::Svg<'a>, ReadError> {
224 self.expect_table()
225 }
226
227 fn varc(&self) -> Result<tables::varc::Varc<'a>, ReadError> {
228 self.expect_table()
229 }
230
231 #[cfg(feature = "ift")]
232 fn ift(&self) -> Result<tables::ift::IftPatchMap<'a>, ReadError> {
233 self.expect_data_for_tag(tables::ift::IFT_TAG)
234 .and_then(FontRead::read)
235 }
236
237 #[cfg(feature = "ift")]
238 fn iftx(&self) -> Result<tables::ift::IftPatchMap<'a>, ReadError> {
239 self.expect_data_for_tag(tables::ift::IFTX_TAG)
240 .and_then(FontRead::read)
241 }
242
243 fn meta(&self) -> Result<tables::meta::Meta<'a>, ReadError> {
244 self.expect_table()
245 }
246
247 fn base(&self) -> Result<tables::base::Base<'a>, ReadError> {
248 self.expect_table()
249 }
250
251 fn dsig(&self) -> Result<tables::dsig::Dsig<'a>, ReadError> {
252 self.expect_table()
253 }
254
255 fn math(&self) -> Result<tables::math::Math<'a>, ReadError> {
256 self.expect_table()
257 }
258}
259
260#[cfg(test)]
261mod tests {
262
263 use super::*;
264
265 #[test]
267 fn bug_105() {
268 struct DummyProvider;
272 impl TableProvider<'static> for DummyProvider {
273 fn data_for_tag(&self, tag: Tag) -> Option<FontData<'static>> {
274 if tag == Tag::new(b"maxp") {
275 Some(FontData::new(&[
276 0, 0, 0x50, 0, 0, 3, ]))
279 } else if tag == Tag::new(b"hhea") {
280 Some(FontData::new(&[
281 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, ]))
291 } else if tag == Tag::new(b"hmtx") {
292 Some(FontData::new(&[
293 0, 4, 0, 6, 0, 30, 0, 111, ]))
296 } else {
297 None
298 }
299 }
300 }
301
302 let number_of_h_metrics = DummyProvider.hhea().unwrap().number_of_h_metrics();
303 let num_glyphs = DummyProvider.maxp().unwrap().num_glyphs();
304 let hmtx = DummyProvider.hmtx().unwrap();
305
306 assert_eq!(number_of_h_metrics, 1);
307 assert_eq!(num_glyphs, 3);
308 assert_eq!(hmtx.h_metrics().len(), 1);
309 assert_eq!(hmtx.left_side_bearings().len(), 2);
310 }
311}