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