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