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
248#[cfg(test)]
249mod tests {
250
251 use super::*;
252
253 #[test]
255 fn bug_105() {
256 struct DummyProvider;
260 impl TableProvider<'static> for DummyProvider {
261 fn data_for_tag(&self, tag: Tag) -> Option<FontData<'static>> {
262 if tag == Tag::new(b"maxp") {
263 Some(FontData::new(&[
264 0, 0, 0x50, 0, 0, 3, ]))
267 } else if tag == Tag::new(b"hhea") {
268 Some(FontData::new(&[
269 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, ]))
279 } else if tag == Tag::new(b"hmtx") {
280 Some(FontData::new(&[
281 0, 4, 0, 6, 0, 30, 0, 111, ]))
284 } else {
285 None
286 }
287 }
288 }
289
290 let number_of_h_metrics = DummyProvider.hhea().unwrap().number_of_h_metrics();
291 let num_glyphs = DummyProvider.maxp().unwrap().num_glyphs();
292 let hmtx = DummyProvider.hmtx().unwrap();
293
294 assert_eq!(number_of_h_metrics, 1);
295 assert_eq!(num_glyphs, 3);
296 assert_eq!(hmtx.h_metrics().len(), 1);
297 assert_eq!(hmtx.left_side_bearings().len(), 2);
298 }
299}