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 num_glyphs = self.maxp().map(|maxp| maxp.num_glyphs())?;
46 let number_of_h_metrics = self.hhea().map(|hhea| hhea.number_of_h_metrics())?;
47 let data = self.expect_data_for_tag(tables::hmtx::Hmtx::TAG)?;
48 tables::hmtx::Hmtx::read(data, number_of_h_metrics, num_glyphs)
49 }
50
51 fn hdmx(&self) -> Result<tables::hdmx::Hdmx<'a>, ReadError> {
52 let num_glyphs = self.maxp().map(|maxp| maxp.num_glyphs())?;
53 let data = self.expect_data_for_tag(tables::hdmx::Hdmx::TAG)?;
54 tables::hdmx::Hdmx::read(data, num_glyphs)
55 }
56
57 fn vmtx(&self) -> Result<tables::vmtx::Vmtx<'a>, ReadError> {
58 let num_glyphs = self.maxp().map(|maxp| maxp.num_glyphs())?;
60 let number_of_v_metrics = self.vhea().map(|vhea| vhea.number_of_long_ver_metrics())?;
61 let data = self.expect_data_for_tag(tables::vmtx::Vmtx::TAG)?;
62 tables::vmtx::Vmtx::read(data, number_of_v_metrics, num_glyphs)
63 }
64
65 fn vorg(&self) -> Result<tables::vorg::Vorg<'a>, ReadError> {
66 self.expect_table()
67 }
68
69 fn fvar(&self) -> Result<tables::fvar::Fvar<'a>, ReadError> {
70 self.expect_table()
71 }
72
73 fn avar(&self) -> Result<tables::avar::Avar<'a>, ReadError> {
74 self.expect_table()
75 }
76
77 fn hvar(&self) -> Result<tables::hvar::Hvar<'a>, ReadError> {
78 self.expect_table()
79 }
80
81 fn vvar(&self) -> Result<tables::vvar::Vvar<'a>, ReadError> {
82 self.expect_table()
83 }
84
85 fn mvar(&self) -> Result<tables::mvar::Mvar<'a>, ReadError> {
86 self.expect_table()
87 }
88
89 fn maxp(&self) -> Result<tables::maxp::Maxp<'a>, ReadError> {
90 self.expect_table()
91 }
92
93 fn os2(&self) -> Result<tables::os2::Os2<'a>, ReadError> {
94 self.expect_table()
95 }
96
97 fn post(&self) -> Result<tables::post::Post<'a>, ReadError> {
98 self.expect_table()
99 }
100
101 fn gasp(&self) -> Result<tables::gasp::Gasp<'a>, ReadError> {
102 self.expect_table()
103 }
104
105 fn loca(&self, is_long: impl Into<Option<bool>>) -> Result<tables::loca::Loca<'a>, ReadError> {
107 let is_long = match is_long.into() {
108 Some(val) => val,
109 None => self.head()?.index_to_loc_format() == 1,
110 };
111 let data = self.expect_data_for_tag(tables::loca::Loca::TAG)?;
112 tables::loca::Loca::read(data, is_long)
113 }
114
115 fn glyf(&self) -> Result<tables::glyf::Glyf<'a>, ReadError> {
116 self.expect_table()
117 }
118
119 fn gvar(&self) -> Result<tables::gvar::Gvar<'a>, ReadError> {
120 self.expect_table()
121 }
122
123 fn cvt(&self) -> Result<&'a [BigEndian<i16>], ReadError> {
126 let table_data = self.expect_data_for_tag(Tag::new(b"cvt "))?;
127 table_data.read_array(0..table_data.len())
128 }
129
130 fn cvar(&self) -> Result<tables::cvar::Cvar<'a>, ReadError> {
131 self.expect_table()
132 }
133
134 fn cff(&self) -> Result<tables::cff::Cff<'a>, ReadError> {
135 self.expect_table()
136 }
137
138 fn cff2(&self) -> Result<tables::cff2::Cff2<'a>, ReadError> {
139 self.expect_table()
140 }
141
142 fn cmap(&self) -> Result<tables::cmap::Cmap<'a>, ReadError> {
143 self.expect_table()
144 }
145
146 fn gdef(&self) -> Result<tables::gdef::Gdef<'a>, ReadError> {
147 self.expect_table()
148 }
149
150 fn gpos(&self) -> Result<tables::gpos::Gpos<'a>, ReadError> {
151 self.expect_table()
152 }
153
154 fn gsub(&self) -> Result<tables::gsub::Gsub<'a>, ReadError> {
155 self.expect_table()
156 }
157
158 fn feat(&self) -> Result<tables::feat::Feat<'a>, ReadError> {
159 self.expect_table()
160 }
161
162 fn ltag(&self) -> Result<tables::ltag::Ltag<'a>, ReadError> {
163 self.expect_table()
164 }
165
166 fn ankr(&self) -> Result<tables::ankr::Ankr<'a>, ReadError> {
167 self.expect_table()
168 }
169
170 fn trak(&self) -> Result<tables::trak::Trak<'a>, ReadError> {
171 self.expect_table()
172 }
173
174 fn morx(&self) -> Result<tables::morx::Morx<'a>, ReadError> {
175 self.expect_table()
176 }
177
178 fn kerx(&self) -> Result<tables::kerx::Kerx<'a>, ReadError> {
179 self.expect_table()
180 }
181
182 fn kern(&self) -> Result<tables::kern::Kern<'a>, ReadError> {
183 self.expect_table()
184 }
185
186 fn colr(&self) -> Result<tables::colr::Colr<'a>, ReadError> {
187 self.expect_table()
188 }
189
190 fn cpal(&self) -> Result<tables::cpal::Cpal<'a>, ReadError> {
191 self.expect_table()
192 }
193
194 fn cblc(&self) -> Result<tables::cblc::Cblc<'a>, ReadError> {
195 self.expect_table()
196 }
197
198 fn cbdt(&self) -> Result<tables::cbdt::Cbdt<'a>, ReadError> {
199 self.expect_table()
200 }
201
202 fn eblc(&self) -> Result<tables::eblc::Eblc<'a>, ReadError> {
203 self.expect_table()
204 }
205
206 fn ebdt(&self) -> Result<tables::ebdt::Ebdt<'a>, ReadError> {
207 self.expect_table()
208 }
209
210 fn sbix(&self) -> Result<tables::sbix::Sbix<'a>, ReadError> {
211 let num_glyphs = self.maxp().map(|maxp| maxp.num_glyphs())?;
213 let data = self.expect_data_for_tag(tables::sbix::Sbix::TAG)?;
214 tables::sbix::Sbix::read(data, num_glyphs)
215 }
216
217 fn stat(&self) -> Result<tables::stat::Stat<'a>, ReadError> {
218 self.expect_table()
219 }
220
221 fn svg(&self) -> Result<tables::svg::Svg<'a>, ReadError> {
222 self.expect_table()
223 }
224
225 fn varc(&self) -> Result<tables::varc::Varc<'a>, ReadError> {
226 self.expect_table()
227 }
228
229 #[cfg(feature = "ift")]
230 fn ift(&self) -> Result<tables::ift::Ift<'a>, ReadError> {
231 self.expect_data_for_tag(tables::ift::IFT_TAG)
232 .and_then(FontRead::read)
233 }
234
235 #[cfg(feature = "ift")]
236 fn iftx(&self) -> Result<tables::ift::Ift<'a>, ReadError> {
237 self.expect_data_for_tag(tables::ift::IFTX_TAG)
238 .and_then(FontRead::read)
239 }
240
241 fn meta(&self) -> Result<tables::meta::Meta<'a>, ReadError> {
242 self.expect_table()
243 }
244
245 fn base(&self) -> Result<tables::base::Base<'a>, ReadError> {
246 self.expect_table()
247 }
248}
249
250#[cfg(test)]
251mod tests {
252
253 use super::*;
254
255 #[test]
257 fn bug_105() {
258 struct DummyProvider;
262 impl TableProvider<'static> for DummyProvider {
263 fn data_for_tag(&self, tag: Tag) -> Option<FontData<'static>> {
264 if tag == Tag::new(b"maxp") {
265 Some(FontData::new(&[
266 0, 0, 0x50, 0, 0, 3, ]))
269 } else if tag == Tag::new(b"hhea") {
270 Some(FontData::new(&[
271 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, ]))
281 } else if tag == Tag::new(b"hmtx") {
282 Some(FontData::new(&[
283 0, 4, 0, 6, 0, 30, 0, 111, ]))
286 } else {
287 None
288 }
289 }
290 }
291
292 let number_of_h_metrics = DummyProvider.hhea().unwrap().number_of_h_metrics();
293 let num_glyphs = DummyProvider.maxp().unwrap().num_glyphs();
294 let hmtx = DummyProvider.hmtx().unwrap();
295
296 assert_eq!(number_of_h_metrics, 1);
297 assert_eq!(num_glyphs, 3);
298 assert_eq!(hmtx.h_metrics().len(), 1);
299 assert_eq!(hmtx.left_side_bearings().len(), 2);
300 }
301}