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>>(&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 kerx(&self) -> Result<tables::kerx::Kerx<'a>, ReadError> {
177 self.expect_table()
178 }
179
180 fn kern(&self) -> Result<tables::kern::Kern<'a>, ReadError> {
181 self.expect_table()
182 }
183
184 fn colr(&self) -> Result<tables::colr::Colr<'a>, ReadError> {
185 self.expect_table()
186 }
187
188 fn cpal(&self) -> Result<tables::cpal::Cpal<'a>, ReadError> {
189 self.expect_table()
190 }
191
192 fn cblc(&self) -> Result<tables::cblc::Cblc<'a>, ReadError> {
193 self.expect_table()
194 }
195
196 fn cbdt(&self) -> Result<tables::cbdt::Cbdt<'a>, ReadError> {
197 self.expect_table()
198 }
199
200 fn eblc(&self) -> Result<tables::eblc::Eblc<'a>, ReadError> {
201 self.expect_table()
202 }
203
204 fn ebdt(&self) -> Result<tables::ebdt::Ebdt<'a>, ReadError> {
205 self.expect_table()
206 }
207
208 fn sbix(&self) -> Result<tables::sbix::Sbix<'a>, ReadError> {
209 let num_glyphs = self.maxp().map(|maxp| maxp.num_glyphs())?;
211 let data = self.expect_data_for_tag(tables::sbix::Sbix::TAG)?;
212 tables::sbix::Sbix::read(data, num_glyphs)
213 }
214
215 fn stat(&self) -> Result<tables::stat::Stat<'a>, ReadError> {
216 self.expect_table()
217 }
218
219 fn svg(&self) -> Result<tables::svg::Svg<'a>, ReadError> {
220 self.expect_table()
221 }
222
223 fn varc(&self) -> Result<tables::varc::Varc<'a>, ReadError> {
224 self.expect_table()
225 }
226
227 #[cfg(feature = "ift")]
228 fn ift(&self) -> Result<tables::ift::Ift<'a>, ReadError> {
229 self.expect_data_for_tag(tables::ift::IFT_TAG)
230 .and_then(FontRead::read)
231 }
232
233 #[cfg(feature = "ift")]
234 fn iftx(&self) -> Result<tables::ift::Ift<'a>, ReadError> {
235 self.expect_data_for_tag(tables::ift::IFTX_TAG)
236 .and_then(FontRead::read)
237 }
238
239 fn meta(&self) -> Result<tables::meta::Meta<'a>, ReadError> {
240 self.expect_table()
241 }
242
243 fn base(&self) -> Result<tables::base::Base<'a>, ReadError> {
244 self.expect_table()
245 }
246
247 fn dsig(&self) -> Result<tables::dsig::Dsig<'a>, ReadError> {
248 self.expect_table()
249 }
250}
251
252#[cfg(test)]
253mod tests {
254
255 use super::*;
256
257 #[test]
259 fn bug_105() {
260 struct DummyProvider;
264 impl TableProvider<'static> for DummyProvider {
265 fn data_for_tag(&self, tag: Tag) -> Option<FontData<'static>> {
266 if tag == Tag::new(b"maxp") {
267 Some(FontData::new(&[
268 0, 0, 0x50, 0, 0, 3, ]))
271 } else if tag == Tag::new(b"hhea") {
272 Some(FontData::new(&[
273 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, ]))
283 } else if tag == Tag::new(b"hmtx") {
284 Some(FontData::new(&[
285 0, 4, 0, 6, 0, 30, 0, 111, ]))
288 } else {
289 None
290 }
291 }
292 }
293
294 let number_of_h_metrics = DummyProvider.hhea().unwrap().number_of_h_metrics();
295 let num_glyphs = DummyProvider.maxp().unwrap().num_glyphs();
296 let hmtx = DummyProvider.hmtx().unwrap();
297
298 assert_eq!(number_of_h_metrics, 1);
299 assert_eq!(num_glyphs, 3);
300 assert_eq!(hmtx.h_metrics().len(), 1);
301 assert_eq!(hmtx.left_side_bearings().len(), 2);
302 }
303}