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
256#[cfg(test)]
257mod tests {
258
259 use super::*;
260
261 #[test]
263 fn bug_105() {
264 struct DummyProvider;
268 impl TableProvider<'static> for DummyProvider {
269 fn data_for_tag(&self, tag: Tag) -> Option<FontData<'static>> {
270 if tag == Tag::new(b"maxp") {
271 Some(FontData::new(&[
272 0, 0, 0x50, 0, 0, 3, ]))
275 } else if tag == Tag::new(b"hhea") {
276 Some(FontData::new(&[
277 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, ]))
287 } else if tag == Tag::new(b"hmtx") {
288 Some(FontData::new(&[
289 0, 4, 0, 6, 0, 30, 0, 111, ]))
292 } else {
293 None
294 }
295 }
296 }
297
298 let number_of_h_metrics = DummyProvider.hhea().unwrap().number_of_h_metrics();
299 let num_glyphs = DummyProvider.maxp().unwrap().num_glyphs();
300 let hmtx = DummyProvider.hmtx().unwrap();
301
302 assert_eq!(number_of_h_metrics, 1);
303 assert_eq!(num_glyphs, 3);
304 assert_eq!(hmtx.h_metrics().len(), 1);
305 assert_eq!(hmtx.left_side_bearings().len(), 2);
306 }
307}