1 // THIS FILE IS AUTOGENERATED.
2 // Any changes to this file will be overwritten.
3 // For more information about how codegen works, see font-codegen/README.md
4 
5 #[allow(unused_imports)]
6 use crate::codegen_prelude::*;
7 
8 /// [Script List Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#script-list-table-and-script-record)
9 #[derive(Debug, Clone, Copy)]
10 #[doc(hidden)]
11 pub struct ScriptListMarker {
12     script_records_byte_len: usize,
13 }
14 
15 impl ScriptListMarker {
script_count_byte_range(&self) -> Range<usize>16     fn script_count_byte_range(&self) -> Range<usize> {
17         let start = 0;
18         start..start + u16::RAW_BYTE_LEN
19     }
script_records_byte_range(&self) -> Range<usize>20     fn script_records_byte_range(&self) -> Range<usize> {
21         let start = self.script_count_byte_range().end;
22         start..start + self.script_records_byte_len
23     }
24 }
25 
26 impl<'a> FontRead<'a> for ScriptList<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>27     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
28         let mut cursor = data.cursor();
29         let script_count: u16 = cursor.read()?;
30         let script_records_byte_len = script_count as usize * ScriptRecord::RAW_BYTE_LEN;
31         cursor.advance_by(script_records_byte_len);
32         cursor.finish(ScriptListMarker {
33             script_records_byte_len,
34         })
35     }
36 }
37 
38 /// [Script List Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#script-list-table-and-script-record)
39 pub type ScriptList<'a> = TableRef<'a, ScriptListMarker>;
40 
41 impl<'a> ScriptList<'a> {
42     /// Number of ScriptRecords
script_count(&self) -> u1643     pub fn script_count(&self) -> u16 {
44         let range = self.shape.script_count_byte_range();
45         self.data.read_at(range.start).unwrap()
46     }
47 
48     /// Array of ScriptRecords, listed alphabetically by script tag
script_records(&self) -> &'a [ScriptRecord]49     pub fn script_records(&self) -> &'a [ScriptRecord] {
50         let range = self.shape.script_records_byte_range();
51         self.data.read_array(range).unwrap()
52     }
53 }
54 
55 #[cfg(feature = "traversal")]
56 impl<'a> SomeTable<'a> for ScriptList<'a> {
type_name(&self) -> &str57     fn type_name(&self) -> &str {
58         "ScriptList"
59     }
get_field(&self, idx: usize) -> Option<Field<'a>>60     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
61         match idx {
62             0usize => Some(Field::new("script_count", self.script_count())),
63             1usize => Some(Field::new(
64                 "script_records",
65                 traversal::FieldType::array_of_records(
66                     stringify!(ScriptRecord),
67                     self.script_records(),
68                     self.offset_data(),
69                 ),
70             )),
71             _ => None,
72         }
73     }
74 }
75 
76 #[cfg(feature = "traversal")]
77 impl<'a> std::fmt::Debug for ScriptList<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result78     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
79         (self as &dyn SomeTable<'a>).fmt(f)
80     }
81 }
82 
83 /// [Script Record](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#script-list-table-and-script-record)
84 #[derive(Clone, Debug)]
85 #[repr(C)]
86 #[repr(packed)]
87 pub struct ScriptRecord {
88     /// 4-byte script tag identifier
89     pub script_tag: BigEndian<Tag>,
90     /// Offset to Script table, from beginning of ScriptList
91     pub script_offset: BigEndian<Offset16>,
92 }
93 
94 impl ScriptRecord {
95     /// 4-byte script tag identifier
script_tag(&self) -> Tag96     pub fn script_tag(&self) -> Tag {
97         self.script_tag.get()
98     }
99 
100     /// Offset to Script table, from beginning of ScriptList
script_offset(&self) -> Offset16101     pub fn script_offset(&self) -> Offset16 {
102         self.script_offset.get()
103     }
104 
105     /// Offset to Script table, from beginning of ScriptList
106     ///
107     /// The `data` argument should be retrieved from the parent table
108     /// By calling its `offset_data` method.
script<'a>(&self, data: FontData<'a>) -> Result<Script<'a>, ReadError>109     pub fn script<'a>(&self, data: FontData<'a>) -> Result<Script<'a>, ReadError> {
110         self.script_offset().resolve(data)
111     }
112 }
113 
114 impl FixedSize for ScriptRecord {
115     const RAW_BYTE_LEN: usize = Tag::RAW_BYTE_LEN + Offset16::RAW_BYTE_LEN;
116 }
117 
118 impl sealed::Sealed for ScriptRecord {}
119 
120 /// SAFETY: see the [`FromBytes`] trait documentation.
121 unsafe impl FromBytes for ScriptRecord {
this_trait_should_only_be_implemented_in_generated_code()122     fn this_trait_should_only_be_implemented_in_generated_code() {}
123 }
124 
125 #[cfg(feature = "traversal")]
126 impl<'a> SomeRecord<'a> for ScriptRecord {
traverse(self, data: FontData<'a>) -> RecordResolver<'a>127     fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
128         RecordResolver {
129             name: "ScriptRecord",
130             get_field: Box::new(move |idx, _data| match idx {
131                 0usize => Some(Field::new("script_tag", self.script_tag())),
132                 1usize => Some(Field::new(
133                     "script_offset",
134                     FieldType::offset(self.script_offset(), self.script(_data)),
135                 )),
136                 _ => None,
137             }),
138             data,
139         }
140     }
141 }
142 
143 /// [Script Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#script-table-and-language-system-record)
144 #[derive(Debug, Clone, Copy)]
145 #[doc(hidden)]
146 pub struct ScriptMarker {
147     lang_sys_records_byte_len: usize,
148 }
149 
150 impl ScriptMarker {
default_lang_sys_offset_byte_range(&self) -> Range<usize>151     fn default_lang_sys_offset_byte_range(&self) -> Range<usize> {
152         let start = 0;
153         start..start + Offset16::RAW_BYTE_LEN
154     }
lang_sys_count_byte_range(&self) -> Range<usize>155     fn lang_sys_count_byte_range(&self) -> Range<usize> {
156         let start = self.default_lang_sys_offset_byte_range().end;
157         start..start + u16::RAW_BYTE_LEN
158     }
lang_sys_records_byte_range(&self) -> Range<usize>159     fn lang_sys_records_byte_range(&self) -> Range<usize> {
160         let start = self.lang_sys_count_byte_range().end;
161         start..start + self.lang_sys_records_byte_len
162     }
163 }
164 
165 impl<'a> FontRead<'a> for Script<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>166     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
167         let mut cursor = data.cursor();
168         cursor.advance::<Offset16>();
169         let lang_sys_count: u16 = cursor.read()?;
170         let lang_sys_records_byte_len = lang_sys_count as usize * LangSysRecord::RAW_BYTE_LEN;
171         cursor.advance_by(lang_sys_records_byte_len);
172         cursor.finish(ScriptMarker {
173             lang_sys_records_byte_len,
174         })
175     }
176 }
177 
178 /// [Script Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#script-table-and-language-system-record)
179 pub type Script<'a> = TableRef<'a, ScriptMarker>;
180 
181 impl<'a> Script<'a> {
182     /// Offset to default LangSys table, from beginning of Script table
183     /// — may be NULL
default_lang_sys_offset(&self) -> Nullable<Offset16>184     pub fn default_lang_sys_offset(&self) -> Nullable<Offset16> {
185         let range = self.shape.default_lang_sys_offset_byte_range();
186         self.data.read_at(range.start).unwrap()
187     }
188 
189     /// Attempt to resolve [`default_lang_sys_offset`][Self::default_lang_sys_offset].
default_lang_sys(&self) -> Option<Result<LangSys<'a>, ReadError>>190     pub fn default_lang_sys(&self) -> Option<Result<LangSys<'a>, ReadError>> {
191         let data = self.data;
192         self.default_lang_sys_offset().resolve(data)
193     }
194 
195     /// Number of LangSysRecords for this script — excluding the
196     /// default LangSys
lang_sys_count(&self) -> u16197     pub fn lang_sys_count(&self) -> u16 {
198         let range = self.shape.lang_sys_count_byte_range();
199         self.data.read_at(range.start).unwrap()
200     }
201 
202     /// Array of LangSysRecords, listed alphabetically by LangSys tag
lang_sys_records(&self) -> &'a [LangSysRecord]203     pub fn lang_sys_records(&self) -> &'a [LangSysRecord] {
204         let range = self.shape.lang_sys_records_byte_range();
205         self.data.read_array(range).unwrap()
206     }
207 }
208 
209 #[cfg(feature = "traversal")]
210 impl<'a> SomeTable<'a> for Script<'a> {
type_name(&self) -> &str211     fn type_name(&self) -> &str {
212         "Script"
213     }
get_field(&self, idx: usize) -> Option<Field<'a>>214     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
215         match idx {
216             0usize => Some(Field::new(
217                 "default_lang_sys_offset",
218                 FieldType::offset(self.default_lang_sys_offset(), self.default_lang_sys()),
219             )),
220             1usize => Some(Field::new("lang_sys_count", self.lang_sys_count())),
221             2usize => Some(Field::new(
222                 "lang_sys_records",
223                 traversal::FieldType::array_of_records(
224                     stringify!(LangSysRecord),
225                     self.lang_sys_records(),
226                     self.offset_data(),
227                 ),
228             )),
229             _ => None,
230         }
231     }
232 }
233 
234 #[cfg(feature = "traversal")]
235 impl<'a> std::fmt::Debug for Script<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result236     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
237         (self as &dyn SomeTable<'a>).fmt(f)
238     }
239 }
240 
241 #[derive(Clone, Debug)]
242 #[repr(C)]
243 #[repr(packed)]
244 pub struct LangSysRecord {
245     /// 4-byte LangSysTag identifier
246     pub lang_sys_tag: BigEndian<Tag>,
247     /// Offset to LangSys table, from beginning of Script table
248     pub lang_sys_offset: BigEndian<Offset16>,
249 }
250 
251 impl LangSysRecord {
252     /// 4-byte LangSysTag identifier
lang_sys_tag(&self) -> Tag253     pub fn lang_sys_tag(&self) -> Tag {
254         self.lang_sys_tag.get()
255     }
256 
257     /// Offset to LangSys table, from beginning of Script table
lang_sys_offset(&self) -> Offset16258     pub fn lang_sys_offset(&self) -> Offset16 {
259         self.lang_sys_offset.get()
260     }
261 
262     /// Offset to LangSys table, from beginning of Script table
263     ///
264     /// The `data` argument should be retrieved from the parent table
265     /// By calling its `offset_data` method.
lang_sys<'a>(&self, data: FontData<'a>) -> Result<LangSys<'a>, ReadError>266     pub fn lang_sys<'a>(&self, data: FontData<'a>) -> Result<LangSys<'a>, ReadError> {
267         self.lang_sys_offset().resolve(data)
268     }
269 }
270 
271 impl FixedSize for LangSysRecord {
272     const RAW_BYTE_LEN: usize = Tag::RAW_BYTE_LEN + Offset16::RAW_BYTE_LEN;
273 }
274 
275 impl sealed::Sealed for LangSysRecord {}
276 
277 /// SAFETY: see the [`FromBytes`] trait documentation.
278 unsafe impl FromBytes for LangSysRecord {
this_trait_should_only_be_implemented_in_generated_code()279     fn this_trait_should_only_be_implemented_in_generated_code() {}
280 }
281 
282 #[cfg(feature = "traversal")]
283 impl<'a> SomeRecord<'a> for LangSysRecord {
traverse(self, data: FontData<'a>) -> RecordResolver<'a>284     fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
285         RecordResolver {
286             name: "LangSysRecord",
287             get_field: Box::new(move |idx, _data| match idx {
288                 0usize => Some(Field::new("lang_sys_tag", self.lang_sys_tag())),
289                 1usize => Some(Field::new(
290                     "lang_sys_offset",
291                     FieldType::offset(self.lang_sys_offset(), self.lang_sys(_data)),
292                 )),
293                 _ => None,
294             }),
295             data,
296         }
297     }
298 }
299 
300 /// [Language System Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#language-system-table)
301 #[derive(Debug, Clone, Copy)]
302 #[doc(hidden)]
303 pub struct LangSysMarker {
304     feature_indices_byte_len: usize,
305 }
306 
307 impl LangSysMarker {
lookup_order_offset_byte_range(&self) -> Range<usize>308     fn lookup_order_offset_byte_range(&self) -> Range<usize> {
309         let start = 0;
310         start..start + u16::RAW_BYTE_LEN
311     }
required_feature_index_byte_range(&self) -> Range<usize>312     fn required_feature_index_byte_range(&self) -> Range<usize> {
313         let start = self.lookup_order_offset_byte_range().end;
314         start..start + u16::RAW_BYTE_LEN
315     }
feature_index_count_byte_range(&self) -> Range<usize>316     fn feature_index_count_byte_range(&self) -> Range<usize> {
317         let start = self.required_feature_index_byte_range().end;
318         start..start + u16::RAW_BYTE_LEN
319     }
feature_indices_byte_range(&self) -> Range<usize>320     fn feature_indices_byte_range(&self) -> Range<usize> {
321         let start = self.feature_index_count_byte_range().end;
322         start..start + self.feature_indices_byte_len
323     }
324 }
325 
326 impl<'a> FontRead<'a> for LangSys<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>327     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
328         let mut cursor = data.cursor();
329         cursor.advance::<u16>();
330         cursor.advance::<u16>();
331         let feature_index_count: u16 = cursor.read()?;
332         let feature_indices_byte_len = feature_index_count as usize * u16::RAW_BYTE_LEN;
333         cursor.advance_by(feature_indices_byte_len);
334         cursor.finish(LangSysMarker {
335             feature_indices_byte_len,
336         })
337     }
338 }
339 
340 /// [Language System Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#language-system-table)
341 pub type LangSys<'a> = TableRef<'a, LangSysMarker>;
342 
343 impl<'a> LangSys<'a> {
344     /// Index of a feature required for this language system; if no
345     /// required features = 0xFFFF
required_feature_index(&self) -> u16346     pub fn required_feature_index(&self) -> u16 {
347         let range = self.shape.required_feature_index_byte_range();
348         self.data.read_at(range.start).unwrap()
349     }
350 
351     /// Number of feature index values for this language system —
352     /// excludes the required feature
feature_index_count(&self) -> u16353     pub fn feature_index_count(&self) -> u16 {
354         let range = self.shape.feature_index_count_byte_range();
355         self.data.read_at(range.start).unwrap()
356     }
357 
358     /// Array of indices into the FeatureList, in arbitrary order
feature_indices(&self) -> &'a [BigEndian<u16>]359     pub fn feature_indices(&self) -> &'a [BigEndian<u16>] {
360         let range = self.shape.feature_indices_byte_range();
361         self.data.read_array(range).unwrap()
362     }
363 }
364 
365 #[cfg(feature = "traversal")]
366 impl<'a> SomeTable<'a> for LangSys<'a> {
type_name(&self) -> &str367     fn type_name(&self) -> &str {
368         "LangSys"
369     }
get_field(&self, idx: usize) -> Option<Field<'a>>370     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
371         match idx {
372             0usize => Some(Field::new(
373                 "required_feature_index",
374                 self.required_feature_index(),
375             )),
376             1usize => Some(Field::new(
377                 "feature_index_count",
378                 self.feature_index_count(),
379             )),
380             2usize => Some(Field::new("feature_indices", self.feature_indices())),
381             _ => None,
382         }
383     }
384 }
385 
386 #[cfg(feature = "traversal")]
387 impl<'a> std::fmt::Debug for LangSys<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result388     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
389         (self as &dyn SomeTable<'a>).fmt(f)
390     }
391 }
392 
393 /// [Feature List Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#feature-list-table)
394 #[derive(Debug, Clone, Copy)]
395 #[doc(hidden)]
396 pub struct FeatureListMarker {
397     feature_records_byte_len: usize,
398 }
399 
400 impl FeatureListMarker {
feature_count_byte_range(&self) -> Range<usize>401     fn feature_count_byte_range(&self) -> Range<usize> {
402         let start = 0;
403         start..start + u16::RAW_BYTE_LEN
404     }
feature_records_byte_range(&self) -> Range<usize>405     fn feature_records_byte_range(&self) -> Range<usize> {
406         let start = self.feature_count_byte_range().end;
407         start..start + self.feature_records_byte_len
408     }
409 }
410 
411 impl<'a> FontRead<'a> for FeatureList<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>412     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
413         let mut cursor = data.cursor();
414         let feature_count: u16 = cursor.read()?;
415         let feature_records_byte_len = feature_count as usize * FeatureRecord::RAW_BYTE_LEN;
416         cursor.advance_by(feature_records_byte_len);
417         cursor.finish(FeatureListMarker {
418             feature_records_byte_len,
419         })
420     }
421 }
422 
423 /// [Feature List Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#feature-list-table)
424 pub type FeatureList<'a> = TableRef<'a, FeatureListMarker>;
425 
426 impl<'a> FeatureList<'a> {
427     /// Number of FeatureRecords in this table
feature_count(&self) -> u16428     pub fn feature_count(&self) -> u16 {
429         let range = self.shape.feature_count_byte_range();
430         self.data.read_at(range.start).unwrap()
431     }
432 
433     /// Array of FeatureRecords — zero-based (first feature has
434     /// FeatureIndex = 0), listed alphabetically by feature tag
feature_records(&self) -> &'a [FeatureRecord]435     pub fn feature_records(&self) -> &'a [FeatureRecord] {
436         let range = self.shape.feature_records_byte_range();
437         self.data.read_array(range).unwrap()
438     }
439 }
440 
441 #[cfg(feature = "traversal")]
442 impl<'a> SomeTable<'a> for FeatureList<'a> {
type_name(&self) -> &str443     fn type_name(&self) -> &str {
444         "FeatureList"
445     }
get_field(&self, idx: usize) -> Option<Field<'a>>446     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
447         match idx {
448             0usize => Some(Field::new("feature_count", self.feature_count())),
449             1usize => Some(Field::new(
450                 "feature_records",
451                 traversal::FieldType::array_of_records(
452                     stringify!(FeatureRecord),
453                     self.feature_records(),
454                     self.offset_data(),
455                 ),
456             )),
457             _ => None,
458         }
459     }
460 }
461 
462 #[cfg(feature = "traversal")]
463 impl<'a> std::fmt::Debug for FeatureList<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result464     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
465         (self as &dyn SomeTable<'a>).fmt(f)
466     }
467 }
468 
469 /// Part of [FeatureList]
470 #[derive(Clone, Debug)]
471 #[repr(C)]
472 #[repr(packed)]
473 pub struct FeatureRecord {
474     /// 4-byte feature identification tag
475     pub feature_tag: BigEndian<Tag>,
476     /// Offset to Feature table, from beginning of FeatureList
477     pub feature_offset: BigEndian<Offset16>,
478 }
479 
480 impl FeatureRecord {
481     /// 4-byte feature identification tag
feature_tag(&self) -> Tag482     pub fn feature_tag(&self) -> Tag {
483         self.feature_tag.get()
484     }
485 
486     /// Offset to Feature table, from beginning of FeatureList
feature_offset(&self) -> Offset16487     pub fn feature_offset(&self) -> Offset16 {
488         self.feature_offset.get()
489     }
490 
491     /// Offset to Feature table, from beginning of FeatureList
492     ///
493     /// The `data` argument should be retrieved from the parent table
494     /// By calling its `offset_data` method.
feature<'a>(&self, data: FontData<'a>) -> Result<Feature<'a>, ReadError>495     pub fn feature<'a>(&self, data: FontData<'a>) -> Result<Feature<'a>, ReadError> {
496         let args = self.feature_tag();
497         self.feature_offset().resolve_with_args(data, &args)
498     }
499 }
500 
501 impl FixedSize for FeatureRecord {
502     const RAW_BYTE_LEN: usize = Tag::RAW_BYTE_LEN + Offset16::RAW_BYTE_LEN;
503 }
504 
505 impl sealed::Sealed for FeatureRecord {}
506 
507 /// SAFETY: see the [`FromBytes`] trait documentation.
508 unsafe impl FromBytes for FeatureRecord {
this_trait_should_only_be_implemented_in_generated_code()509     fn this_trait_should_only_be_implemented_in_generated_code() {}
510 }
511 
512 #[cfg(feature = "traversal")]
513 impl<'a> SomeRecord<'a> for FeatureRecord {
traverse(self, data: FontData<'a>) -> RecordResolver<'a>514     fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
515         RecordResolver {
516             name: "FeatureRecord",
517             get_field: Box::new(move |idx, _data| match idx {
518                 0usize => Some(Field::new("feature_tag", self.feature_tag())),
519                 1usize => Some(Field::new(
520                     "feature_offset",
521                     FieldType::offset(self.feature_offset(), self.feature(_data)),
522                 )),
523                 _ => None,
524             }),
525             data,
526         }
527     }
528 }
529 
530 /// [Feature Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#feature-table)
531 #[derive(Debug, Clone, Copy)]
532 #[doc(hidden)]
533 pub struct FeatureMarker {
534     feature_tag: Tag,
535     lookup_list_indices_byte_len: usize,
536 }
537 
538 impl FeatureMarker {
feature_params_offset_byte_range(&self) -> Range<usize>539     fn feature_params_offset_byte_range(&self) -> Range<usize> {
540         let start = 0;
541         start..start + Offset16::RAW_BYTE_LEN
542     }
lookup_index_count_byte_range(&self) -> Range<usize>543     fn lookup_index_count_byte_range(&self) -> Range<usize> {
544         let start = self.feature_params_offset_byte_range().end;
545         start..start + u16::RAW_BYTE_LEN
546     }
lookup_list_indices_byte_range(&self) -> Range<usize>547     fn lookup_list_indices_byte_range(&self) -> Range<usize> {
548         let start = self.lookup_index_count_byte_range().end;
549         start..start + self.lookup_list_indices_byte_len
550     }
551 }
552 
553 impl ReadArgs for Feature<'_> {
554     type Args = Tag;
555 }
556 
557 impl<'a> FontReadWithArgs<'a> for Feature<'a> {
read_with_args(data: FontData<'a>, args: &Tag) -> Result<Self, ReadError>558     fn read_with_args(data: FontData<'a>, args: &Tag) -> Result<Self, ReadError> {
559         let feature_tag = *args;
560         let mut cursor = data.cursor();
561         cursor.advance::<Offset16>();
562         let lookup_index_count: u16 = cursor.read()?;
563         let lookup_list_indices_byte_len = lookup_index_count as usize * u16::RAW_BYTE_LEN;
564         cursor.advance_by(lookup_list_indices_byte_len);
565         cursor.finish(FeatureMarker {
566             feature_tag,
567             lookup_list_indices_byte_len,
568         })
569     }
570 }
571 
572 impl<'a> Feature<'a> {
573     /// A constructor that requires additional arguments.
574     ///
575     /// This type requires some external state in order to be
576     /// parsed.
read(data: FontData<'a>, feature_tag: Tag) -> Result<Self, ReadError>577     pub fn read(data: FontData<'a>, feature_tag: Tag) -> Result<Self, ReadError> {
578         let args = feature_tag;
579         Self::read_with_args(data, &args)
580     }
581 }
582 
583 /// [Feature Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#feature-table)
584 pub type Feature<'a> = TableRef<'a, FeatureMarker>;
585 
586 impl<'a> Feature<'a> {
587     /// Offset from start of Feature table to FeatureParams table, if defined for the feature and present, else NULL
feature_params_offset(&self) -> Nullable<Offset16>588     pub fn feature_params_offset(&self) -> Nullable<Offset16> {
589         let range = self.shape.feature_params_offset_byte_range();
590         self.data.read_at(range.start).unwrap()
591     }
592 
593     /// Attempt to resolve [`feature_params_offset`][Self::feature_params_offset].
feature_params(&self) -> Option<Result<FeatureParams<'a>, ReadError>>594     pub fn feature_params(&self) -> Option<Result<FeatureParams<'a>, ReadError>> {
595         let data = self.data;
596         let args = self.feature_tag();
597         self.feature_params_offset().resolve_with_args(data, &args)
598     }
599 
600     /// Number of LookupList indices for this feature
lookup_index_count(&self) -> u16601     pub fn lookup_index_count(&self) -> u16 {
602         let range = self.shape.lookup_index_count_byte_range();
603         self.data.read_at(range.start).unwrap()
604     }
605 
606     /// Array of indices into the LookupList — zero-based (first
607     /// lookup is LookupListIndex = 0)
lookup_list_indices(&self) -> &'a [BigEndian<u16>]608     pub fn lookup_list_indices(&self) -> &'a [BigEndian<u16>] {
609         let range = self.shape.lookup_list_indices_byte_range();
610         self.data.read_array(range).unwrap()
611     }
612 
feature_tag(&self) -> Tag613     pub(crate) fn feature_tag(&self) -> Tag {
614         self.shape.feature_tag
615     }
616 }
617 
618 #[cfg(feature = "traversal")]
619 impl<'a> SomeTable<'a> for Feature<'a> {
type_name(&self) -> &str620     fn type_name(&self) -> &str {
621         "Feature"
622     }
get_field(&self, idx: usize) -> Option<Field<'a>>623     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
624         match idx {
625             0usize => Some(Field::new(
626                 "feature_params_offset",
627                 FieldType::offset(self.feature_params_offset(), self.feature_params()),
628             )),
629             1usize => Some(Field::new("lookup_index_count", self.lookup_index_count())),
630             2usize => Some(Field::new(
631                 "lookup_list_indices",
632                 self.lookup_list_indices(),
633             )),
634             _ => None,
635         }
636     }
637 }
638 
639 #[cfg(feature = "traversal")]
640 impl<'a> std::fmt::Debug for Feature<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result641     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
642         (self as &dyn SomeTable<'a>).fmt(f)
643     }
644 }
645 
646 /// [Lookup List Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#lookup-list-table)
647 #[derive(Debug)]
648 #[doc(hidden)]
649 pub struct LookupListMarker<T = ()> {
650     lookup_offsets_byte_len: usize,
651     offset_type: std::marker::PhantomData<*const T>,
652 }
653 
654 impl<T> LookupListMarker<T> {
lookup_count_byte_range(&self) -> Range<usize>655     fn lookup_count_byte_range(&self) -> Range<usize> {
656         let start = 0;
657         start..start + u16::RAW_BYTE_LEN
658     }
lookup_offsets_byte_range(&self) -> Range<usize>659     fn lookup_offsets_byte_range(&self) -> Range<usize> {
660         let start = self.lookup_count_byte_range().end;
661         start..start + self.lookup_offsets_byte_len
662     }
663 }
664 
665 impl<T> Clone for LookupListMarker<T> {
clone(&self) -> Self666     fn clone(&self) -> Self {
667         *self
668     }
669 }
670 
671 impl<T> Copy for LookupListMarker<T> {}
672 
673 impl<'a, T> FontRead<'a> for LookupList<'a, T> {
read(data: FontData<'a>) -> Result<Self, ReadError>674     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
675         let mut cursor = data.cursor();
676         let lookup_count: u16 = cursor.read()?;
677         let lookup_offsets_byte_len = lookup_count as usize * Offset16::RAW_BYTE_LEN;
678         cursor.advance_by(lookup_offsets_byte_len);
679         cursor.finish(LookupListMarker {
680             lookup_offsets_byte_len,
681             offset_type: std::marker::PhantomData,
682         })
683     }
684 }
685 
686 impl<'a> LookupList<'a, ()> {
687     #[allow(dead_code)]
into_concrete<T>(self) -> LookupList<'a, T>688     pub(crate) fn into_concrete<T>(self) -> LookupList<'a, T> {
689         let TableRef { data, shape } = self;
690         TableRef {
691             shape: LookupListMarker {
692                 lookup_offsets_byte_len: shape.lookup_offsets_byte_len,
693                 offset_type: std::marker::PhantomData,
694             },
695             data,
696         }
697     }
698 }
699 
700 impl<'a, T> LookupList<'a, T> {
701     #[allow(dead_code)]
702     /// Replace the specific generic type on this implementation with `()`
of_unit_type(&self) -> LookupList<'a, ()>703     pub(crate) fn of_unit_type(&self) -> LookupList<'a, ()> {
704         let TableRef { data, shape } = self;
705         TableRef {
706             shape: LookupListMarker {
707                 lookup_offsets_byte_len: shape.lookup_offsets_byte_len,
708                 offset_type: std::marker::PhantomData,
709             },
710             data: *data,
711         }
712     }
713 }
714 
715 /// [Lookup List Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#lookup-list-table)
716 pub type LookupList<'a, T> = TableRef<'a, LookupListMarker<T>>;
717 
718 impl<'a, T> LookupList<'a, T> {
719     /// Number of lookups in this table
lookup_count(&self) -> u16720     pub fn lookup_count(&self) -> u16 {
721         let range = self.shape.lookup_count_byte_range();
722         self.data.read_at(range.start).unwrap()
723     }
724 
725     /// Array of offsets to Lookup tables, from beginning of LookupList
726     /// — zero based (first lookup is Lookup index = 0)
lookup_offsets(&self) -> &'a [BigEndian<Offset16>]727     pub fn lookup_offsets(&self) -> &'a [BigEndian<Offset16>] {
728         let range = self.shape.lookup_offsets_byte_range();
729         self.data.read_array(range).unwrap()
730     }
731 
732     /// A dynamically resolving wrapper for [`lookup_offsets`][Self::lookup_offsets].
lookups(&self) -> ArrayOfOffsets<'a, T, Offset16> where T: FontRead<'a>,733     pub fn lookups(&self) -> ArrayOfOffsets<'a, T, Offset16>
734     where
735         T: FontRead<'a>,
736     {
737         let data = self.data;
738         let offsets = self.lookup_offsets();
739         ArrayOfOffsets::new(offsets, data, ())
740     }
741 }
742 
743 #[cfg(feature = "traversal")]
744 impl<'a, T: FontRead<'a> + SomeTable<'a> + 'a> SomeTable<'a> for LookupList<'a, T> {
type_name(&self) -> &str745     fn type_name(&self) -> &str {
746         "LookupList"
747     }
get_field(&self, idx: usize) -> Option<Field<'a>>748     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
749         match idx {
750             0usize => Some(Field::new("lookup_count", self.lookup_count())),
751             1usize => Some({
752                 let data = self.data;
753                 Field::new(
754                     "lookup_offsets",
755                     FieldType::array_of_offsets(
756                         better_type_name::<T>(),
757                         self.lookup_offsets(),
758                         move |off| {
759                             let target = off.get().resolve::<T>(data);
760                             FieldType::offset(off.get(), target)
761                         },
762                     ),
763                 )
764             }),
765             _ => None,
766         }
767     }
768 }
769 
770 #[cfg(feature = "traversal")]
771 impl<'a, T: FontRead<'a> + SomeTable<'a> + 'a> std::fmt::Debug for LookupList<'a, T> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result772     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
773         (self as &dyn SomeTable<'a>).fmt(f)
774     }
775 }
776 
777 /// [Lookup Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#lookup-table)
778 #[derive(Debug)]
779 #[doc(hidden)]
780 pub struct LookupMarker<T = ()> {
781     subtable_offsets_byte_len: usize,
782     offset_type: std::marker::PhantomData<*const T>,
783 }
784 
785 impl<T> LookupMarker<T> {
lookup_type_byte_range(&self) -> Range<usize>786     fn lookup_type_byte_range(&self) -> Range<usize> {
787         let start = 0;
788         start..start + u16::RAW_BYTE_LEN
789     }
lookup_flag_byte_range(&self) -> Range<usize>790     fn lookup_flag_byte_range(&self) -> Range<usize> {
791         let start = self.lookup_type_byte_range().end;
792         start..start + LookupFlag::RAW_BYTE_LEN
793     }
sub_table_count_byte_range(&self) -> Range<usize>794     fn sub_table_count_byte_range(&self) -> Range<usize> {
795         let start = self.lookup_flag_byte_range().end;
796         start..start + u16::RAW_BYTE_LEN
797     }
subtable_offsets_byte_range(&self) -> Range<usize>798     fn subtable_offsets_byte_range(&self) -> Range<usize> {
799         let start = self.sub_table_count_byte_range().end;
800         start..start + self.subtable_offsets_byte_len
801     }
mark_filtering_set_byte_range(&self) -> Range<usize>802     fn mark_filtering_set_byte_range(&self) -> Range<usize> {
803         let start = self.subtable_offsets_byte_range().end;
804         start..start + u16::RAW_BYTE_LEN
805     }
806 }
807 
808 impl<T> Clone for LookupMarker<T> {
clone(&self) -> Self809     fn clone(&self) -> Self {
810         *self
811     }
812 }
813 
814 impl<T> Copy for LookupMarker<T> {}
815 
816 impl<'a, T> FontRead<'a> for Lookup<'a, T> {
read(data: FontData<'a>) -> Result<Self, ReadError>817     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
818         let mut cursor = data.cursor();
819         cursor.advance::<u16>();
820         cursor.advance::<LookupFlag>();
821         let sub_table_count: u16 = cursor.read()?;
822         let subtable_offsets_byte_len = sub_table_count as usize * Offset16::RAW_BYTE_LEN;
823         cursor.advance_by(subtable_offsets_byte_len);
824         cursor.advance::<u16>();
825         cursor.finish(LookupMarker {
826             subtable_offsets_byte_len,
827             offset_type: std::marker::PhantomData,
828         })
829     }
830 }
831 
832 impl<'a> Lookup<'a, ()> {
833     #[allow(dead_code)]
into_concrete<T>(self) -> Lookup<'a, T>834     pub(crate) fn into_concrete<T>(self) -> Lookup<'a, T> {
835         let TableRef { data, shape } = self;
836         TableRef {
837             shape: LookupMarker {
838                 subtable_offsets_byte_len: shape.subtable_offsets_byte_len,
839                 offset_type: std::marker::PhantomData,
840             },
841             data,
842         }
843     }
844 }
845 
846 impl<'a, T> Lookup<'a, T> {
847     #[allow(dead_code)]
848     /// Replace the specific generic type on this implementation with `()`
of_unit_type(&self) -> Lookup<'a, ()>849     pub(crate) fn of_unit_type(&self) -> Lookup<'a, ()> {
850         let TableRef { data, shape } = self;
851         TableRef {
852             shape: LookupMarker {
853                 subtable_offsets_byte_len: shape.subtable_offsets_byte_len,
854                 offset_type: std::marker::PhantomData,
855             },
856             data: *data,
857         }
858     }
859 }
860 
861 /// [Lookup Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#lookup-table)
862 pub type Lookup<'a, T> = TableRef<'a, LookupMarker<T>>;
863 
864 impl<'a, T> Lookup<'a, T> {
865     /// Different enumerations for GSUB and GPOS
lookup_type(&self) -> u16866     pub fn lookup_type(&self) -> u16 {
867         let range = self.shape.lookup_type_byte_range();
868         self.data.read_at(range.start).unwrap()
869     }
870 
871     /// Lookup qualifiers
lookup_flag(&self) -> LookupFlag872     pub fn lookup_flag(&self) -> LookupFlag {
873         let range = self.shape.lookup_flag_byte_range();
874         self.data.read_at(range.start).unwrap()
875     }
876 
877     /// Number of subtables for this lookup
sub_table_count(&self) -> u16878     pub fn sub_table_count(&self) -> u16 {
879         let range = self.shape.sub_table_count_byte_range();
880         self.data.read_at(range.start).unwrap()
881     }
882 
883     /// Array of offsets to lookup subtables, from beginning of Lookup
884     /// table
subtable_offsets(&self) -> &'a [BigEndian<Offset16>]885     pub fn subtable_offsets(&self) -> &'a [BigEndian<Offset16>] {
886         let range = self.shape.subtable_offsets_byte_range();
887         self.data.read_array(range).unwrap()
888     }
889 
890     /// A dynamically resolving wrapper for [`subtable_offsets`][Self::subtable_offsets].
subtables(&self) -> ArrayOfOffsets<'a, T, Offset16> where T: FontRead<'a>,891     pub fn subtables(&self) -> ArrayOfOffsets<'a, T, Offset16>
892     where
893         T: FontRead<'a>,
894     {
895         let data = self.data;
896         let offsets = self.subtable_offsets();
897         ArrayOfOffsets::new(offsets, data, ())
898     }
899 
900     /// Index (base 0) into GDEF mark glyph sets structure. This field
901     /// is only present if the USE_MARK_FILTERING_SET lookup flag is
902     /// set.
mark_filtering_set(&self) -> u16903     pub fn mark_filtering_set(&self) -> u16 {
904         let range = self.shape.mark_filtering_set_byte_range();
905         self.data.read_at(range.start).unwrap()
906     }
907 }
908 
909 #[cfg(feature = "traversal")]
910 impl<'a, T: FontRead<'a> + SomeTable<'a> + 'a> SomeTable<'a> for Lookup<'a, T> {
type_name(&self) -> &str911     fn type_name(&self) -> &str {
912         "Lookup"
913     }
get_field(&self, idx: usize) -> Option<Field<'a>>914     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
915         match idx {
916             0usize => Some(Field::new("lookup_type", self.lookup_type())),
917             1usize => Some(Field::new("lookup_flag", self.traverse_lookup_flag())),
918             2usize => Some(Field::new("sub_table_count", self.sub_table_count())),
919             3usize => Some({
920                 let data = self.data;
921                 Field::new(
922                     "subtable_offsets",
923                     FieldType::array_of_offsets(
924                         better_type_name::<T>(),
925                         self.subtable_offsets(),
926                         move |off| {
927                             let target = off.get().resolve::<T>(data);
928                             FieldType::offset(off.get(), target)
929                         },
930                     ),
931                 )
932             }),
933             4usize => Some(Field::new("mark_filtering_set", self.mark_filtering_set())),
934             _ => None,
935         }
936     }
937 }
938 
939 #[cfg(feature = "traversal")]
940 impl<'a, T: FontRead<'a> + SomeTable<'a> + 'a> std::fmt::Debug for Lookup<'a, T> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result941     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
942         (self as &dyn SomeTable<'a>).fmt(f)
943     }
944 }
945 
946 impl Format<u16> for CoverageFormat1Marker {
947     const FORMAT: u16 = 1;
948 }
949 
950 /// [Coverage Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#coverage-format-1)
951 #[derive(Debug, Clone, Copy)]
952 #[doc(hidden)]
953 pub struct CoverageFormat1Marker {
954     glyph_array_byte_len: usize,
955 }
956 
957 impl CoverageFormat1Marker {
coverage_format_byte_range(&self) -> Range<usize>958     fn coverage_format_byte_range(&self) -> Range<usize> {
959         let start = 0;
960         start..start + u16::RAW_BYTE_LEN
961     }
glyph_count_byte_range(&self) -> Range<usize>962     fn glyph_count_byte_range(&self) -> Range<usize> {
963         let start = self.coverage_format_byte_range().end;
964         start..start + u16::RAW_BYTE_LEN
965     }
glyph_array_byte_range(&self) -> Range<usize>966     fn glyph_array_byte_range(&self) -> Range<usize> {
967         let start = self.glyph_count_byte_range().end;
968         start..start + self.glyph_array_byte_len
969     }
970 }
971 
972 impl<'a> FontRead<'a> for CoverageFormat1<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>973     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
974         let mut cursor = data.cursor();
975         cursor.advance::<u16>();
976         let glyph_count: u16 = cursor.read()?;
977         let glyph_array_byte_len = glyph_count as usize * GlyphId::RAW_BYTE_LEN;
978         cursor.advance_by(glyph_array_byte_len);
979         cursor.finish(CoverageFormat1Marker {
980             glyph_array_byte_len,
981         })
982     }
983 }
984 
985 /// [Coverage Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#coverage-format-1)
986 pub type CoverageFormat1<'a> = TableRef<'a, CoverageFormat1Marker>;
987 
988 impl<'a> CoverageFormat1<'a> {
989     /// Format identifier — format = 1
coverage_format(&self) -> u16990     pub fn coverage_format(&self) -> u16 {
991         let range = self.shape.coverage_format_byte_range();
992         self.data.read_at(range.start).unwrap()
993     }
994 
995     /// Number of glyphs in the glyph array
glyph_count(&self) -> u16996     pub fn glyph_count(&self) -> u16 {
997         let range = self.shape.glyph_count_byte_range();
998         self.data.read_at(range.start).unwrap()
999     }
1000 
1001     /// Array of glyph IDs — in numerical order
glyph_array(&self) -> &'a [BigEndian<GlyphId>]1002     pub fn glyph_array(&self) -> &'a [BigEndian<GlyphId>] {
1003         let range = self.shape.glyph_array_byte_range();
1004         self.data.read_array(range).unwrap()
1005     }
1006 }
1007 
1008 #[cfg(feature = "traversal")]
1009 impl<'a> SomeTable<'a> for CoverageFormat1<'a> {
type_name(&self) -> &str1010     fn type_name(&self) -> &str {
1011         "CoverageFormat1"
1012     }
get_field(&self, idx: usize) -> Option<Field<'a>>1013     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
1014         match idx {
1015             0usize => Some(Field::new("coverage_format", self.coverage_format())),
1016             1usize => Some(Field::new("glyph_count", self.glyph_count())),
1017             2usize => Some(Field::new("glyph_array", self.glyph_array())),
1018             _ => None,
1019         }
1020     }
1021 }
1022 
1023 #[cfg(feature = "traversal")]
1024 impl<'a> std::fmt::Debug for CoverageFormat1<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1025     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1026         (self as &dyn SomeTable<'a>).fmt(f)
1027     }
1028 }
1029 
1030 impl Format<u16> for CoverageFormat2Marker {
1031     const FORMAT: u16 = 2;
1032 }
1033 
1034 /// [Coverage Format 2](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#coverage-format-2)
1035 #[derive(Debug, Clone, Copy)]
1036 #[doc(hidden)]
1037 pub struct CoverageFormat2Marker {
1038     range_records_byte_len: usize,
1039 }
1040 
1041 impl CoverageFormat2Marker {
coverage_format_byte_range(&self) -> Range<usize>1042     fn coverage_format_byte_range(&self) -> Range<usize> {
1043         let start = 0;
1044         start..start + u16::RAW_BYTE_LEN
1045     }
range_count_byte_range(&self) -> Range<usize>1046     fn range_count_byte_range(&self) -> Range<usize> {
1047         let start = self.coverage_format_byte_range().end;
1048         start..start + u16::RAW_BYTE_LEN
1049     }
range_records_byte_range(&self) -> Range<usize>1050     fn range_records_byte_range(&self) -> Range<usize> {
1051         let start = self.range_count_byte_range().end;
1052         start..start + self.range_records_byte_len
1053     }
1054 }
1055 
1056 impl<'a> FontRead<'a> for CoverageFormat2<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>1057     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
1058         let mut cursor = data.cursor();
1059         cursor.advance::<u16>();
1060         let range_count: u16 = cursor.read()?;
1061         let range_records_byte_len = range_count as usize * RangeRecord::RAW_BYTE_LEN;
1062         cursor.advance_by(range_records_byte_len);
1063         cursor.finish(CoverageFormat2Marker {
1064             range_records_byte_len,
1065         })
1066     }
1067 }
1068 
1069 /// [Coverage Format 2](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#coverage-format-2)
1070 pub type CoverageFormat2<'a> = TableRef<'a, CoverageFormat2Marker>;
1071 
1072 impl<'a> CoverageFormat2<'a> {
1073     /// Format identifier — format = 2
coverage_format(&self) -> u161074     pub fn coverage_format(&self) -> u16 {
1075         let range = self.shape.coverage_format_byte_range();
1076         self.data.read_at(range.start).unwrap()
1077     }
1078 
1079     /// Number of RangeRecords
range_count(&self) -> u161080     pub fn range_count(&self) -> u16 {
1081         let range = self.shape.range_count_byte_range();
1082         self.data.read_at(range.start).unwrap()
1083     }
1084 
1085     /// Array of glyph ranges — ordered by startGlyphID.
range_records(&self) -> &'a [RangeRecord]1086     pub fn range_records(&self) -> &'a [RangeRecord] {
1087         let range = self.shape.range_records_byte_range();
1088         self.data.read_array(range).unwrap()
1089     }
1090 }
1091 
1092 #[cfg(feature = "traversal")]
1093 impl<'a> SomeTable<'a> for CoverageFormat2<'a> {
type_name(&self) -> &str1094     fn type_name(&self) -> &str {
1095         "CoverageFormat2"
1096     }
get_field(&self, idx: usize) -> Option<Field<'a>>1097     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
1098         match idx {
1099             0usize => Some(Field::new("coverage_format", self.coverage_format())),
1100             1usize => Some(Field::new("range_count", self.range_count())),
1101             2usize => Some(Field::new(
1102                 "range_records",
1103                 traversal::FieldType::array_of_records(
1104                     stringify!(RangeRecord),
1105                     self.range_records(),
1106                     self.offset_data(),
1107                 ),
1108             )),
1109             _ => None,
1110         }
1111     }
1112 }
1113 
1114 #[cfg(feature = "traversal")]
1115 impl<'a> std::fmt::Debug for CoverageFormat2<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1116     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1117         (self as &dyn SomeTable<'a>).fmt(f)
1118     }
1119 }
1120 
1121 /// Used in [CoverageFormat2]
1122 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
1123 #[repr(C)]
1124 #[repr(packed)]
1125 pub struct RangeRecord {
1126     /// First glyph ID in the range
1127     pub start_glyph_id: BigEndian<GlyphId>,
1128     /// Last glyph ID in the range
1129     pub end_glyph_id: BigEndian<GlyphId>,
1130     /// Coverage Index of first glyph ID in range
1131     pub start_coverage_index: BigEndian<u16>,
1132 }
1133 
1134 impl RangeRecord {
1135     /// First glyph ID in the range
start_glyph_id(&self) -> GlyphId1136     pub fn start_glyph_id(&self) -> GlyphId {
1137         self.start_glyph_id.get()
1138     }
1139 
1140     /// Last glyph ID in the range
end_glyph_id(&self) -> GlyphId1141     pub fn end_glyph_id(&self) -> GlyphId {
1142         self.end_glyph_id.get()
1143     }
1144 
1145     /// Coverage Index of first glyph ID in range
start_coverage_index(&self) -> u161146     pub fn start_coverage_index(&self) -> u16 {
1147         self.start_coverage_index.get()
1148     }
1149 }
1150 
1151 impl FixedSize for RangeRecord {
1152     const RAW_BYTE_LEN: usize = GlyphId::RAW_BYTE_LEN + GlyphId::RAW_BYTE_LEN + u16::RAW_BYTE_LEN;
1153 }
1154 
1155 impl sealed::Sealed for RangeRecord {}
1156 
1157 /// SAFETY: see the [`FromBytes`] trait documentation.
1158 unsafe impl FromBytes for RangeRecord {
this_trait_should_only_be_implemented_in_generated_code()1159     fn this_trait_should_only_be_implemented_in_generated_code() {}
1160 }
1161 
1162 #[cfg(feature = "traversal")]
1163 impl<'a> SomeRecord<'a> for RangeRecord {
traverse(self, data: FontData<'a>) -> RecordResolver<'a>1164     fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
1165         RecordResolver {
1166             name: "RangeRecord",
1167             get_field: Box::new(move |idx, _data| match idx {
1168                 0usize => Some(Field::new("start_glyph_id", self.start_glyph_id())),
1169                 1usize => Some(Field::new("end_glyph_id", self.end_glyph_id())),
1170                 2usize => Some(Field::new(
1171                     "start_coverage_index",
1172                     self.start_coverage_index(),
1173                 )),
1174                 _ => None,
1175             }),
1176             data,
1177         }
1178     }
1179 }
1180 
1181 /// [Coverage Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#coverage-table)
1182 #[derive(Clone)]
1183 pub enum CoverageTable<'a> {
1184     Format1(CoverageFormat1<'a>),
1185     Format2(CoverageFormat2<'a>),
1186 }
1187 
1188 impl<'a> CoverageTable<'a> {
1189     /// Format identifier — format = 1
coverage_format(&self) -> u161190     pub fn coverage_format(&self) -> u16 {
1191         match self {
1192             Self::Format1(item) => item.coverage_format(),
1193             Self::Format2(item) => item.coverage_format(),
1194         }
1195     }
1196 }
1197 
1198 impl<'a> FontRead<'a> for CoverageTable<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>1199     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
1200         let format: u16 = data.read_at(0usize)?;
1201         match format {
1202             CoverageFormat1Marker::FORMAT => Ok(Self::Format1(FontRead::read(data)?)),
1203             CoverageFormat2Marker::FORMAT => Ok(Self::Format2(FontRead::read(data)?)),
1204             other => Err(ReadError::InvalidFormat(other.into())),
1205         }
1206     }
1207 }
1208 
1209 #[cfg(feature = "traversal")]
1210 impl<'a> CoverageTable<'a> {
dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a>1211     fn dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a> {
1212         match self {
1213             Self::Format1(table) => table,
1214             Self::Format2(table) => table,
1215         }
1216     }
1217 }
1218 
1219 #[cfg(feature = "traversal")]
1220 impl<'a> std::fmt::Debug for CoverageTable<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1221     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1222         self.dyn_inner().fmt(f)
1223     }
1224 }
1225 
1226 #[cfg(feature = "traversal")]
1227 impl<'a> SomeTable<'a> for CoverageTable<'a> {
type_name(&self) -> &str1228     fn type_name(&self) -> &str {
1229         self.dyn_inner().type_name()
1230     }
get_field(&self, idx: usize) -> Option<Field<'a>>1231     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
1232         self.dyn_inner().get_field(idx)
1233     }
1234 }
1235 
1236 impl Format<u16> for ClassDefFormat1Marker {
1237     const FORMAT: u16 = 1;
1238 }
1239 
1240 /// [Class Definition Table Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#class-definition-table-format-1)
1241 #[derive(Debug, Clone, Copy)]
1242 #[doc(hidden)]
1243 pub struct ClassDefFormat1Marker {
1244     class_value_array_byte_len: usize,
1245 }
1246 
1247 impl ClassDefFormat1Marker {
class_format_byte_range(&self) -> Range<usize>1248     fn class_format_byte_range(&self) -> Range<usize> {
1249         let start = 0;
1250         start..start + u16::RAW_BYTE_LEN
1251     }
start_glyph_id_byte_range(&self) -> Range<usize>1252     fn start_glyph_id_byte_range(&self) -> Range<usize> {
1253         let start = self.class_format_byte_range().end;
1254         start..start + GlyphId::RAW_BYTE_LEN
1255     }
glyph_count_byte_range(&self) -> Range<usize>1256     fn glyph_count_byte_range(&self) -> Range<usize> {
1257         let start = self.start_glyph_id_byte_range().end;
1258         start..start + u16::RAW_BYTE_LEN
1259     }
class_value_array_byte_range(&self) -> Range<usize>1260     fn class_value_array_byte_range(&self) -> Range<usize> {
1261         let start = self.glyph_count_byte_range().end;
1262         start..start + self.class_value_array_byte_len
1263     }
1264 }
1265 
1266 impl<'a> FontRead<'a> for ClassDefFormat1<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>1267     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
1268         let mut cursor = data.cursor();
1269         cursor.advance::<u16>();
1270         cursor.advance::<GlyphId>();
1271         let glyph_count: u16 = cursor.read()?;
1272         let class_value_array_byte_len = glyph_count as usize * u16::RAW_BYTE_LEN;
1273         cursor.advance_by(class_value_array_byte_len);
1274         cursor.finish(ClassDefFormat1Marker {
1275             class_value_array_byte_len,
1276         })
1277     }
1278 }
1279 
1280 /// [Class Definition Table Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#class-definition-table-format-1)
1281 pub type ClassDefFormat1<'a> = TableRef<'a, ClassDefFormat1Marker>;
1282 
1283 impl<'a> ClassDefFormat1<'a> {
1284     /// Format identifier — format = 1
class_format(&self) -> u161285     pub fn class_format(&self) -> u16 {
1286         let range = self.shape.class_format_byte_range();
1287         self.data.read_at(range.start).unwrap()
1288     }
1289 
1290     /// First glyph ID of the classValueArray
start_glyph_id(&self) -> GlyphId1291     pub fn start_glyph_id(&self) -> GlyphId {
1292         let range = self.shape.start_glyph_id_byte_range();
1293         self.data.read_at(range.start).unwrap()
1294     }
1295 
1296     /// Size of the classValueArray
glyph_count(&self) -> u161297     pub fn glyph_count(&self) -> u16 {
1298         let range = self.shape.glyph_count_byte_range();
1299         self.data.read_at(range.start).unwrap()
1300     }
1301 
1302     /// Array of Class Values — one per glyph ID
class_value_array(&self) -> &'a [BigEndian<u16>]1303     pub fn class_value_array(&self) -> &'a [BigEndian<u16>] {
1304         let range = self.shape.class_value_array_byte_range();
1305         self.data.read_array(range).unwrap()
1306     }
1307 }
1308 
1309 #[cfg(feature = "traversal")]
1310 impl<'a> SomeTable<'a> for ClassDefFormat1<'a> {
type_name(&self) -> &str1311     fn type_name(&self) -> &str {
1312         "ClassDefFormat1"
1313     }
get_field(&self, idx: usize) -> Option<Field<'a>>1314     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
1315         match idx {
1316             0usize => Some(Field::new("class_format", self.class_format())),
1317             1usize => Some(Field::new("start_glyph_id", self.start_glyph_id())),
1318             2usize => Some(Field::new("glyph_count", self.glyph_count())),
1319             3usize => Some(Field::new("class_value_array", self.class_value_array())),
1320             _ => None,
1321         }
1322     }
1323 }
1324 
1325 #[cfg(feature = "traversal")]
1326 impl<'a> std::fmt::Debug for ClassDefFormat1<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1327     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1328         (self as &dyn SomeTable<'a>).fmt(f)
1329     }
1330 }
1331 
1332 impl Format<u16> for ClassDefFormat2Marker {
1333     const FORMAT: u16 = 2;
1334 }
1335 
1336 /// [Class Definition Table Format 2](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#class-definition-table-format-2)
1337 #[derive(Debug, Clone, Copy)]
1338 #[doc(hidden)]
1339 pub struct ClassDefFormat2Marker {
1340     class_range_records_byte_len: usize,
1341 }
1342 
1343 impl ClassDefFormat2Marker {
class_format_byte_range(&self) -> Range<usize>1344     fn class_format_byte_range(&self) -> Range<usize> {
1345         let start = 0;
1346         start..start + u16::RAW_BYTE_LEN
1347     }
class_range_count_byte_range(&self) -> Range<usize>1348     fn class_range_count_byte_range(&self) -> Range<usize> {
1349         let start = self.class_format_byte_range().end;
1350         start..start + u16::RAW_BYTE_LEN
1351     }
class_range_records_byte_range(&self) -> Range<usize>1352     fn class_range_records_byte_range(&self) -> Range<usize> {
1353         let start = self.class_range_count_byte_range().end;
1354         start..start + self.class_range_records_byte_len
1355     }
1356 }
1357 
1358 impl<'a> FontRead<'a> for ClassDefFormat2<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>1359     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
1360         let mut cursor = data.cursor();
1361         cursor.advance::<u16>();
1362         let class_range_count: u16 = cursor.read()?;
1363         let class_range_records_byte_len =
1364             class_range_count as usize * ClassRangeRecord::RAW_BYTE_LEN;
1365         cursor.advance_by(class_range_records_byte_len);
1366         cursor.finish(ClassDefFormat2Marker {
1367             class_range_records_byte_len,
1368         })
1369     }
1370 }
1371 
1372 /// [Class Definition Table Format 2](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#class-definition-table-format-2)
1373 pub type ClassDefFormat2<'a> = TableRef<'a, ClassDefFormat2Marker>;
1374 
1375 impl<'a> ClassDefFormat2<'a> {
1376     /// Format identifier — format = 2
class_format(&self) -> u161377     pub fn class_format(&self) -> u16 {
1378         let range = self.shape.class_format_byte_range();
1379         self.data.read_at(range.start).unwrap()
1380     }
1381 
1382     /// Number of ClassRangeRecords
class_range_count(&self) -> u161383     pub fn class_range_count(&self) -> u16 {
1384         let range = self.shape.class_range_count_byte_range();
1385         self.data.read_at(range.start).unwrap()
1386     }
1387 
1388     /// Array of ClassRangeRecords — ordered by startGlyphID
class_range_records(&self) -> &'a [ClassRangeRecord]1389     pub fn class_range_records(&self) -> &'a [ClassRangeRecord] {
1390         let range = self.shape.class_range_records_byte_range();
1391         self.data.read_array(range).unwrap()
1392     }
1393 }
1394 
1395 #[cfg(feature = "traversal")]
1396 impl<'a> SomeTable<'a> for ClassDefFormat2<'a> {
type_name(&self) -> &str1397     fn type_name(&self) -> &str {
1398         "ClassDefFormat2"
1399     }
get_field(&self, idx: usize) -> Option<Field<'a>>1400     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
1401         match idx {
1402             0usize => Some(Field::new("class_format", self.class_format())),
1403             1usize => Some(Field::new("class_range_count", self.class_range_count())),
1404             2usize => Some(Field::new(
1405                 "class_range_records",
1406                 traversal::FieldType::array_of_records(
1407                     stringify!(ClassRangeRecord),
1408                     self.class_range_records(),
1409                     self.offset_data(),
1410                 ),
1411             )),
1412             _ => None,
1413         }
1414     }
1415 }
1416 
1417 #[cfg(feature = "traversal")]
1418 impl<'a> std::fmt::Debug for ClassDefFormat2<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1419     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1420         (self as &dyn SomeTable<'a>).fmt(f)
1421     }
1422 }
1423 
1424 /// Used in [ClassDefFormat2]
1425 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
1426 #[repr(C)]
1427 #[repr(packed)]
1428 pub struct ClassRangeRecord {
1429     /// First glyph ID in the range
1430     pub start_glyph_id: BigEndian<GlyphId>,
1431     /// Last glyph ID in the range
1432     pub end_glyph_id: BigEndian<GlyphId>,
1433     /// Applied to all glyphs in the range
1434     pub class: BigEndian<u16>,
1435 }
1436 
1437 impl ClassRangeRecord {
1438     /// First glyph ID in the range
start_glyph_id(&self) -> GlyphId1439     pub fn start_glyph_id(&self) -> GlyphId {
1440         self.start_glyph_id.get()
1441     }
1442 
1443     /// Last glyph ID in the range
end_glyph_id(&self) -> GlyphId1444     pub fn end_glyph_id(&self) -> GlyphId {
1445         self.end_glyph_id.get()
1446     }
1447 
1448     /// Applied to all glyphs in the range
class(&self) -> u161449     pub fn class(&self) -> u16 {
1450         self.class.get()
1451     }
1452 }
1453 
1454 impl FixedSize for ClassRangeRecord {
1455     const RAW_BYTE_LEN: usize = GlyphId::RAW_BYTE_LEN + GlyphId::RAW_BYTE_LEN + u16::RAW_BYTE_LEN;
1456 }
1457 
1458 impl sealed::Sealed for ClassRangeRecord {}
1459 
1460 /// SAFETY: see the [`FromBytes`] trait documentation.
1461 unsafe impl FromBytes for ClassRangeRecord {
this_trait_should_only_be_implemented_in_generated_code()1462     fn this_trait_should_only_be_implemented_in_generated_code() {}
1463 }
1464 
1465 #[cfg(feature = "traversal")]
1466 impl<'a> SomeRecord<'a> for ClassRangeRecord {
traverse(self, data: FontData<'a>) -> RecordResolver<'a>1467     fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
1468         RecordResolver {
1469             name: "ClassRangeRecord",
1470             get_field: Box::new(move |idx, _data| match idx {
1471                 0usize => Some(Field::new("start_glyph_id", self.start_glyph_id())),
1472                 1usize => Some(Field::new("end_glyph_id", self.end_glyph_id())),
1473                 2usize => Some(Field::new("class", self.class())),
1474                 _ => None,
1475             }),
1476             data,
1477         }
1478     }
1479 }
1480 
1481 /// A [Class Definition Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#class-definition-table)
1482 #[derive(Clone)]
1483 pub enum ClassDef<'a> {
1484     Format1(ClassDefFormat1<'a>),
1485     Format2(ClassDefFormat2<'a>),
1486 }
1487 
1488 impl<'a> ClassDef<'a> {
1489     /// Format identifier — format = 1
class_format(&self) -> u161490     pub fn class_format(&self) -> u16 {
1491         match self {
1492             Self::Format1(item) => item.class_format(),
1493             Self::Format2(item) => item.class_format(),
1494         }
1495     }
1496 }
1497 
1498 impl<'a> FontRead<'a> for ClassDef<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>1499     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
1500         let format: u16 = data.read_at(0usize)?;
1501         match format {
1502             ClassDefFormat1Marker::FORMAT => Ok(Self::Format1(FontRead::read(data)?)),
1503             ClassDefFormat2Marker::FORMAT => Ok(Self::Format2(FontRead::read(data)?)),
1504             other => Err(ReadError::InvalidFormat(other.into())),
1505         }
1506     }
1507 }
1508 
1509 #[cfg(feature = "traversal")]
1510 impl<'a> ClassDef<'a> {
dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a>1511     fn dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a> {
1512         match self {
1513             Self::Format1(table) => table,
1514             Self::Format2(table) => table,
1515         }
1516     }
1517 }
1518 
1519 #[cfg(feature = "traversal")]
1520 impl<'a> std::fmt::Debug for ClassDef<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1521     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1522         self.dyn_inner().fmt(f)
1523     }
1524 }
1525 
1526 #[cfg(feature = "traversal")]
1527 impl<'a> SomeTable<'a> for ClassDef<'a> {
type_name(&self) -> &str1528     fn type_name(&self) -> &str {
1529         self.dyn_inner().type_name()
1530     }
get_field(&self, idx: usize) -> Option<Field<'a>>1531     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
1532         self.dyn_inner().get_field(idx)
1533     }
1534 }
1535 
1536 /// [Sequence Lookup Record](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#sequence-lookup-record)
1537 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
1538 #[repr(C)]
1539 #[repr(packed)]
1540 pub struct SequenceLookupRecord {
1541     /// Index (zero-based) into the input glyph sequence
1542     pub sequence_index: BigEndian<u16>,
1543     /// Index (zero-based) into the LookupList
1544     pub lookup_list_index: BigEndian<u16>,
1545 }
1546 
1547 impl SequenceLookupRecord {
1548     /// Index (zero-based) into the input glyph sequence
sequence_index(&self) -> u161549     pub fn sequence_index(&self) -> u16 {
1550         self.sequence_index.get()
1551     }
1552 
1553     /// Index (zero-based) into the LookupList
lookup_list_index(&self) -> u161554     pub fn lookup_list_index(&self) -> u16 {
1555         self.lookup_list_index.get()
1556     }
1557 }
1558 
1559 impl FixedSize for SequenceLookupRecord {
1560     const RAW_BYTE_LEN: usize = u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN;
1561 }
1562 
1563 impl sealed::Sealed for SequenceLookupRecord {}
1564 
1565 /// SAFETY: see the [`FromBytes`] trait documentation.
1566 unsafe impl FromBytes for SequenceLookupRecord {
this_trait_should_only_be_implemented_in_generated_code()1567     fn this_trait_should_only_be_implemented_in_generated_code() {}
1568 }
1569 
1570 #[cfg(feature = "traversal")]
1571 impl<'a> SomeRecord<'a> for SequenceLookupRecord {
traverse(self, data: FontData<'a>) -> RecordResolver<'a>1572     fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
1573         RecordResolver {
1574             name: "SequenceLookupRecord",
1575             get_field: Box::new(move |idx, _data| match idx {
1576                 0usize => Some(Field::new("sequence_index", self.sequence_index())),
1577                 1usize => Some(Field::new("lookup_list_index", self.lookup_list_index())),
1578                 _ => None,
1579             }),
1580             data,
1581         }
1582     }
1583 }
1584 
1585 impl Format<u16> for SequenceContextFormat1Marker {
1586     const FORMAT: u16 = 1;
1587 }
1588 
1589 /// [Sequence Context Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#sequence-context-format-1-simple-glyph-contexts)
1590 #[derive(Debug, Clone, Copy)]
1591 #[doc(hidden)]
1592 pub struct SequenceContextFormat1Marker {
1593     seq_rule_set_offsets_byte_len: usize,
1594 }
1595 
1596 impl SequenceContextFormat1Marker {
format_byte_range(&self) -> Range<usize>1597     fn format_byte_range(&self) -> Range<usize> {
1598         let start = 0;
1599         start..start + u16::RAW_BYTE_LEN
1600     }
coverage_offset_byte_range(&self) -> Range<usize>1601     fn coverage_offset_byte_range(&self) -> Range<usize> {
1602         let start = self.format_byte_range().end;
1603         start..start + Offset16::RAW_BYTE_LEN
1604     }
seq_rule_set_count_byte_range(&self) -> Range<usize>1605     fn seq_rule_set_count_byte_range(&self) -> Range<usize> {
1606         let start = self.coverage_offset_byte_range().end;
1607         start..start + u16::RAW_BYTE_LEN
1608     }
seq_rule_set_offsets_byte_range(&self) -> Range<usize>1609     fn seq_rule_set_offsets_byte_range(&self) -> Range<usize> {
1610         let start = self.seq_rule_set_count_byte_range().end;
1611         start..start + self.seq_rule_set_offsets_byte_len
1612     }
1613 }
1614 
1615 impl<'a> FontRead<'a> for SequenceContextFormat1<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>1616     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
1617         let mut cursor = data.cursor();
1618         cursor.advance::<u16>();
1619         cursor.advance::<Offset16>();
1620         let seq_rule_set_count: u16 = cursor.read()?;
1621         let seq_rule_set_offsets_byte_len = seq_rule_set_count as usize * Offset16::RAW_BYTE_LEN;
1622         cursor.advance_by(seq_rule_set_offsets_byte_len);
1623         cursor.finish(SequenceContextFormat1Marker {
1624             seq_rule_set_offsets_byte_len,
1625         })
1626     }
1627 }
1628 
1629 /// [Sequence Context Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#sequence-context-format-1-simple-glyph-contexts)
1630 pub type SequenceContextFormat1<'a> = TableRef<'a, SequenceContextFormat1Marker>;
1631 
1632 impl<'a> SequenceContextFormat1<'a> {
1633     /// Format identifier: format = 1
format(&self) -> u161634     pub fn format(&self) -> u16 {
1635         let range = self.shape.format_byte_range();
1636         self.data.read_at(range.start).unwrap()
1637     }
1638 
1639     /// Offset to Coverage table, from beginning of
1640     /// SequenceContextFormat1 table
coverage_offset(&self) -> Offset161641     pub fn coverage_offset(&self) -> Offset16 {
1642         let range = self.shape.coverage_offset_byte_range();
1643         self.data.read_at(range.start).unwrap()
1644     }
1645 
1646     /// Attempt to resolve [`coverage_offset`][Self::coverage_offset].
coverage(&self) -> Result<CoverageTable<'a>, ReadError>1647     pub fn coverage(&self) -> Result<CoverageTable<'a>, ReadError> {
1648         let data = self.data;
1649         self.coverage_offset().resolve(data)
1650     }
1651 
1652     /// Number of SequenceRuleSet tables
seq_rule_set_count(&self) -> u161653     pub fn seq_rule_set_count(&self) -> u16 {
1654         let range = self.shape.seq_rule_set_count_byte_range();
1655         self.data.read_at(range.start).unwrap()
1656     }
1657 
1658     /// Array of offsets to SequenceRuleSet tables, from beginning of
1659     /// SequenceContextFormat1 table (offsets may be NULL)
seq_rule_set_offsets(&self) -> &'a [BigEndian<Nullable<Offset16>>]1660     pub fn seq_rule_set_offsets(&self) -> &'a [BigEndian<Nullable<Offset16>>] {
1661         let range = self.shape.seq_rule_set_offsets_byte_range();
1662         self.data.read_array(range).unwrap()
1663     }
1664 
1665     /// A dynamically resolving wrapper for [`seq_rule_set_offsets`][Self::seq_rule_set_offsets].
seq_rule_sets(&self) -> ArrayOfNullableOffsets<'a, SequenceRuleSet<'a>, Offset16>1666     pub fn seq_rule_sets(&self) -> ArrayOfNullableOffsets<'a, SequenceRuleSet<'a>, Offset16> {
1667         let data = self.data;
1668         let offsets = self.seq_rule_set_offsets();
1669         ArrayOfNullableOffsets::new(offsets, data, ())
1670     }
1671 }
1672 
1673 #[cfg(feature = "traversal")]
1674 impl<'a> SomeTable<'a> for SequenceContextFormat1<'a> {
type_name(&self) -> &str1675     fn type_name(&self) -> &str {
1676         "SequenceContextFormat1"
1677     }
get_field(&self, idx: usize) -> Option<Field<'a>>1678     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
1679         match idx {
1680             0usize => Some(Field::new("format", self.format())),
1681             1usize => Some(Field::new(
1682                 "coverage_offset",
1683                 FieldType::offset(self.coverage_offset(), self.coverage()),
1684             )),
1685             2usize => Some(Field::new("seq_rule_set_count", self.seq_rule_set_count())),
1686             3usize => Some({
1687                 let data = self.data;
1688                 Field::new(
1689                     "seq_rule_set_offsets",
1690                     FieldType::array_of_offsets(
1691                         better_type_name::<SequenceRuleSet>(),
1692                         self.seq_rule_set_offsets(),
1693                         move |off| {
1694                             let target = off.get().resolve::<SequenceRuleSet>(data);
1695                             FieldType::offset(off.get(), target)
1696                         },
1697                     ),
1698                 )
1699             }),
1700             _ => None,
1701         }
1702     }
1703 }
1704 
1705 #[cfg(feature = "traversal")]
1706 impl<'a> std::fmt::Debug for SequenceContextFormat1<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1707     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1708         (self as &dyn SomeTable<'a>).fmt(f)
1709     }
1710 }
1711 
1712 /// Part of [SequenceContextFormat1]
1713 #[derive(Debug, Clone, Copy)]
1714 #[doc(hidden)]
1715 pub struct SequenceRuleSetMarker {
1716     seq_rule_offsets_byte_len: usize,
1717 }
1718 
1719 impl SequenceRuleSetMarker {
seq_rule_count_byte_range(&self) -> Range<usize>1720     fn seq_rule_count_byte_range(&self) -> Range<usize> {
1721         let start = 0;
1722         start..start + u16::RAW_BYTE_LEN
1723     }
seq_rule_offsets_byte_range(&self) -> Range<usize>1724     fn seq_rule_offsets_byte_range(&self) -> Range<usize> {
1725         let start = self.seq_rule_count_byte_range().end;
1726         start..start + self.seq_rule_offsets_byte_len
1727     }
1728 }
1729 
1730 impl<'a> FontRead<'a> for SequenceRuleSet<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>1731     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
1732         let mut cursor = data.cursor();
1733         let seq_rule_count: u16 = cursor.read()?;
1734         let seq_rule_offsets_byte_len = seq_rule_count as usize * Offset16::RAW_BYTE_LEN;
1735         cursor.advance_by(seq_rule_offsets_byte_len);
1736         cursor.finish(SequenceRuleSetMarker {
1737             seq_rule_offsets_byte_len,
1738         })
1739     }
1740 }
1741 
1742 /// Part of [SequenceContextFormat1]
1743 pub type SequenceRuleSet<'a> = TableRef<'a, SequenceRuleSetMarker>;
1744 
1745 impl<'a> SequenceRuleSet<'a> {
1746     /// Number of SequenceRule tables
seq_rule_count(&self) -> u161747     pub fn seq_rule_count(&self) -> u16 {
1748         let range = self.shape.seq_rule_count_byte_range();
1749         self.data.read_at(range.start).unwrap()
1750     }
1751 
1752     /// Array of offsets to SequenceRule tables, from beginning of the
1753     /// SequenceRuleSet table
seq_rule_offsets(&self) -> &'a [BigEndian<Offset16>]1754     pub fn seq_rule_offsets(&self) -> &'a [BigEndian<Offset16>] {
1755         let range = self.shape.seq_rule_offsets_byte_range();
1756         self.data.read_array(range).unwrap()
1757     }
1758 
1759     /// A dynamically resolving wrapper for [`seq_rule_offsets`][Self::seq_rule_offsets].
seq_rules(&self) -> ArrayOfOffsets<'a, SequenceRule<'a>, Offset16>1760     pub fn seq_rules(&self) -> ArrayOfOffsets<'a, SequenceRule<'a>, Offset16> {
1761         let data = self.data;
1762         let offsets = self.seq_rule_offsets();
1763         ArrayOfOffsets::new(offsets, data, ())
1764     }
1765 }
1766 
1767 #[cfg(feature = "traversal")]
1768 impl<'a> SomeTable<'a> for SequenceRuleSet<'a> {
type_name(&self) -> &str1769     fn type_name(&self) -> &str {
1770         "SequenceRuleSet"
1771     }
get_field(&self, idx: usize) -> Option<Field<'a>>1772     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
1773         match idx {
1774             0usize => Some(Field::new("seq_rule_count", self.seq_rule_count())),
1775             1usize => Some({
1776                 let data = self.data;
1777                 Field::new(
1778                     "seq_rule_offsets",
1779                     FieldType::array_of_offsets(
1780                         better_type_name::<SequenceRule>(),
1781                         self.seq_rule_offsets(),
1782                         move |off| {
1783                             let target = off.get().resolve::<SequenceRule>(data);
1784                             FieldType::offset(off.get(), target)
1785                         },
1786                     ),
1787                 )
1788             }),
1789             _ => None,
1790         }
1791     }
1792 }
1793 
1794 #[cfg(feature = "traversal")]
1795 impl<'a> std::fmt::Debug for SequenceRuleSet<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1796     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1797         (self as &dyn SomeTable<'a>).fmt(f)
1798     }
1799 }
1800 
1801 /// Part of [SequenceContextFormat1]
1802 #[derive(Debug, Clone, Copy)]
1803 #[doc(hidden)]
1804 pub struct SequenceRuleMarker {
1805     input_sequence_byte_len: usize,
1806     seq_lookup_records_byte_len: usize,
1807 }
1808 
1809 impl SequenceRuleMarker {
glyph_count_byte_range(&self) -> Range<usize>1810     fn glyph_count_byte_range(&self) -> Range<usize> {
1811         let start = 0;
1812         start..start + u16::RAW_BYTE_LEN
1813     }
seq_lookup_count_byte_range(&self) -> Range<usize>1814     fn seq_lookup_count_byte_range(&self) -> Range<usize> {
1815         let start = self.glyph_count_byte_range().end;
1816         start..start + u16::RAW_BYTE_LEN
1817     }
input_sequence_byte_range(&self) -> Range<usize>1818     fn input_sequence_byte_range(&self) -> Range<usize> {
1819         let start = self.seq_lookup_count_byte_range().end;
1820         start..start + self.input_sequence_byte_len
1821     }
seq_lookup_records_byte_range(&self) -> Range<usize>1822     fn seq_lookup_records_byte_range(&self) -> Range<usize> {
1823         let start = self.input_sequence_byte_range().end;
1824         start..start + self.seq_lookup_records_byte_len
1825     }
1826 }
1827 
1828 impl<'a> FontRead<'a> for SequenceRule<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>1829     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
1830         let mut cursor = data.cursor();
1831         let glyph_count: u16 = cursor.read()?;
1832         let seq_lookup_count: u16 = cursor.read()?;
1833         let input_sequence_byte_len =
1834             transforms::subtract(glyph_count, 1_usize) * GlyphId::RAW_BYTE_LEN;
1835         cursor.advance_by(input_sequence_byte_len);
1836         let seq_lookup_records_byte_len =
1837             seq_lookup_count as usize * SequenceLookupRecord::RAW_BYTE_LEN;
1838         cursor.advance_by(seq_lookup_records_byte_len);
1839         cursor.finish(SequenceRuleMarker {
1840             input_sequence_byte_len,
1841             seq_lookup_records_byte_len,
1842         })
1843     }
1844 }
1845 
1846 /// Part of [SequenceContextFormat1]
1847 pub type SequenceRule<'a> = TableRef<'a, SequenceRuleMarker>;
1848 
1849 impl<'a> SequenceRule<'a> {
1850     /// Number of glyphs in the input glyph sequence
glyph_count(&self) -> u161851     pub fn glyph_count(&self) -> u16 {
1852         let range = self.shape.glyph_count_byte_range();
1853         self.data.read_at(range.start).unwrap()
1854     }
1855 
1856     /// Number of SequenceLookupRecords
seq_lookup_count(&self) -> u161857     pub fn seq_lookup_count(&self) -> u16 {
1858         let range = self.shape.seq_lookup_count_byte_range();
1859         self.data.read_at(range.start).unwrap()
1860     }
1861 
1862     /// Array of input glyph IDs—starting with the second glyph
input_sequence(&self) -> &'a [BigEndian<GlyphId>]1863     pub fn input_sequence(&self) -> &'a [BigEndian<GlyphId>] {
1864         let range = self.shape.input_sequence_byte_range();
1865         self.data.read_array(range).unwrap()
1866     }
1867 
1868     /// Array of Sequence lookup records
seq_lookup_records(&self) -> &'a [SequenceLookupRecord]1869     pub fn seq_lookup_records(&self) -> &'a [SequenceLookupRecord] {
1870         let range = self.shape.seq_lookup_records_byte_range();
1871         self.data.read_array(range).unwrap()
1872     }
1873 }
1874 
1875 #[cfg(feature = "traversal")]
1876 impl<'a> SomeTable<'a> for SequenceRule<'a> {
type_name(&self) -> &str1877     fn type_name(&self) -> &str {
1878         "SequenceRule"
1879     }
get_field(&self, idx: usize) -> Option<Field<'a>>1880     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
1881         match idx {
1882             0usize => Some(Field::new("glyph_count", self.glyph_count())),
1883             1usize => Some(Field::new("seq_lookup_count", self.seq_lookup_count())),
1884             2usize => Some(Field::new("input_sequence", self.input_sequence())),
1885             3usize => Some(Field::new(
1886                 "seq_lookup_records",
1887                 traversal::FieldType::array_of_records(
1888                     stringify!(SequenceLookupRecord),
1889                     self.seq_lookup_records(),
1890                     self.offset_data(),
1891                 ),
1892             )),
1893             _ => None,
1894         }
1895     }
1896 }
1897 
1898 #[cfg(feature = "traversal")]
1899 impl<'a> std::fmt::Debug for SequenceRule<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1900     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1901         (self as &dyn SomeTable<'a>).fmt(f)
1902     }
1903 }
1904 
1905 impl Format<u16> for SequenceContextFormat2Marker {
1906     const FORMAT: u16 = 2;
1907 }
1908 
1909 /// [Sequence Context Format 2](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#sequence-context-format-2-class-based-glyph-contexts)
1910 #[derive(Debug, Clone, Copy)]
1911 #[doc(hidden)]
1912 pub struct SequenceContextFormat2Marker {
1913     class_seq_rule_set_offsets_byte_len: usize,
1914 }
1915 
1916 impl SequenceContextFormat2Marker {
format_byte_range(&self) -> Range<usize>1917     fn format_byte_range(&self) -> Range<usize> {
1918         let start = 0;
1919         start..start + u16::RAW_BYTE_LEN
1920     }
coverage_offset_byte_range(&self) -> Range<usize>1921     fn coverage_offset_byte_range(&self) -> Range<usize> {
1922         let start = self.format_byte_range().end;
1923         start..start + Offset16::RAW_BYTE_LEN
1924     }
class_def_offset_byte_range(&self) -> Range<usize>1925     fn class_def_offset_byte_range(&self) -> Range<usize> {
1926         let start = self.coverage_offset_byte_range().end;
1927         start..start + Offset16::RAW_BYTE_LEN
1928     }
class_seq_rule_set_count_byte_range(&self) -> Range<usize>1929     fn class_seq_rule_set_count_byte_range(&self) -> Range<usize> {
1930         let start = self.class_def_offset_byte_range().end;
1931         start..start + u16::RAW_BYTE_LEN
1932     }
class_seq_rule_set_offsets_byte_range(&self) -> Range<usize>1933     fn class_seq_rule_set_offsets_byte_range(&self) -> Range<usize> {
1934         let start = self.class_seq_rule_set_count_byte_range().end;
1935         start..start + self.class_seq_rule_set_offsets_byte_len
1936     }
1937 }
1938 
1939 impl<'a> FontRead<'a> for SequenceContextFormat2<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>1940     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
1941         let mut cursor = data.cursor();
1942         cursor.advance::<u16>();
1943         cursor.advance::<Offset16>();
1944         cursor.advance::<Offset16>();
1945         let class_seq_rule_set_count: u16 = cursor.read()?;
1946         let class_seq_rule_set_offsets_byte_len =
1947             class_seq_rule_set_count as usize * Offset16::RAW_BYTE_LEN;
1948         cursor.advance_by(class_seq_rule_set_offsets_byte_len);
1949         cursor.finish(SequenceContextFormat2Marker {
1950             class_seq_rule_set_offsets_byte_len,
1951         })
1952     }
1953 }
1954 
1955 /// [Sequence Context Format 2](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#sequence-context-format-2-class-based-glyph-contexts)
1956 pub type SequenceContextFormat2<'a> = TableRef<'a, SequenceContextFormat2Marker>;
1957 
1958 impl<'a> SequenceContextFormat2<'a> {
1959     /// Format identifier: format = 2
format(&self) -> u161960     pub fn format(&self) -> u16 {
1961         let range = self.shape.format_byte_range();
1962         self.data.read_at(range.start).unwrap()
1963     }
1964 
1965     /// Offset to Coverage table, from beginning of
1966     /// SequenceContextFormat2 table
coverage_offset(&self) -> Offset161967     pub fn coverage_offset(&self) -> Offset16 {
1968         let range = self.shape.coverage_offset_byte_range();
1969         self.data.read_at(range.start).unwrap()
1970     }
1971 
1972     /// Attempt to resolve [`coverage_offset`][Self::coverage_offset].
coverage(&self) -> Result<CoverageTable<'a>, ReadError>1973     pub fn coverage(&self) -> Result<CoverageTable<'a>, ReadError> {
1974         let data = self.data;
1975         self.coverage_offset().resolve(data)
1976     }
1977 
1978     /// Offset to ClassDef table, from beginning of
1979     /// SequenceContextFormat2 table
class_def_offset(&self) -> Offset161980     pub fn class_def_offset(&self) -> Offset16 {
1981         let range = self.shape.class_def_offset_byte_range();
1982         self.data.read_at(range.start).unwrap()
1983     }
1984 
1985     /// Attempt to resolve [`class_def_offset`][Self::class_def_offset].
class_def(&self) -> Result<ClassDef<'a>, ReadError>1986     pub fn class_def(&self) -> Result<ClassDef<'a>, ReadError> {
1987         let data = self.data;
1988         self.class_def_offset().resolve(data)
1989     }
1990 
1991     /// Number of ClassSequenceRuleSet tables
class_seq_rule_set_count(&self) -> u161992     pub fn class_seq_rule_set_count(&self) -> u16 {
1993         let range = self.shape.class_seq_rule_set_count_byte_range();
1994         self.data.read_at(range.start).unwrap()
1995     }
1996 
1997     /// Array of offsets to ClassSequenceRuleSet tables, from beginning
1998     /// of SequenceContextFormat2 table (may be NULL)
class_seq_rule_set_offsets(&self) -> &'a [BigEndian<Nullable<Offset16>>]1999     pub fn class_seq_rule_set_offsets(&self) -> &'a [BigEndian<Nullable<Offset16>>] {
2000         let range = self.shape.class_seq_rule_set_offsets_byte_range();
2001         self.data.read_array(range).unwrap()
2002     }
2003 
2004     /// A dynamically resolving wrapper for [`class_seq_rule_set_offsets`][Self::class_seq_rule_set_offsets].
class_seq_rule_sets( &self, ) -> ArrayOfNullableOffsets<'a, ClassSequenceRuleSet<'a>, Offset16>2005     pub fn class_seq_rule_sets(
2006         &self,
2007     ) -> ArrayOfNullableOffsets<'a, ClassSequenceRuleSet<'a>, Offset16> {
2008         let data = self.data;
2009         let offsets = self.class_seq_rule_set_offsets();
2010         ArrayOfNullableOffsets::new(offsets, data, ())
2011     }
2012 }
2013 
2014 #[cfg(feature = "traversal")]
2015 impl<'a> SomeTable<'a> for SequenceContextFormat2<'a> {
type_name(&self) -> &str2016     fn type_name(&self) -> &str {
2017         "SequenceContextFormat2"
2018     }
get_field(&self, idx: usize) -> Option<Field<'a>>2019     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
2020         match idx {
2021             0usize => Some(Field::new("format", self.format())),
2022             1usize => Some(Field::new(
2023                 "coverage_offset",
2024                 FieldType::offset(self.coverage_offset(), self.coverage()),
2025             )),
2026             2usize => Some(Field::new(
2027                 "class_def_offset",
2028                 FieldType::offset(self.class_def_offset(), self.class_def()),
2029             )),
2030             3usize => Some(Field::new(
2031                 "class_seq_rule_set_count",
2032                 self.class_seq_rule_set_count(),
2033             )),
2034             4usize => Some({
2035                 let data = self.data;
2036                 Field::new(
2037                     "class_seq_rule_set_offsets",
2038                     FieldType::array_of_offsets(
2039                         better_type_name::<ClassSequenceRuleSet>(),
2040                         self.class_seq_rule_set_offsets(),
2041                         move |off| {
2042                             let target = off.get().resolve::<ClassSequenceRuleSet>(data);
2043                             FieldType::offset(off.get(), target)
2044                         },
2045                     ),
2046                 )
2047             }),
2048             _ => None,
2049         }
2050     }
2051 }
2052 
2053 #[cfg(feature = "traversal")]
2054 impl<'a> std::fmt::Debug for SequenceContextFormat2<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result2055     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2056         (self as &dyn SomeTable<'a>).fmt(f)
2057     }
2058 }
2059 
2060 /// Part of [SequenceContextFormat2]
2061 #[derive(Debug, Clone, Copy)]
2062 #[doc(hidden)]
2063 pub struct ClassSequenceRuleSetMarker {
2064     class_seq_rule_offsets_byte_len: usize,
2065 }
2066 
2067 impl ClassSequenceRuleSetMarker {
class_seq_rule_count_byte_range(&self) -> Range<usize>2068     fn class_seq_rule_count_byte_range(&self) -> Range<usize> {
2069         let start = 0;
2070         start..start + u16::RAW_BYTE_LEN
2071     }
class_seq_rule_offsets_byte_range(&self) -> Range<usize>2072     fn class_seq_rule_offsets_byte_range(&self) -> Range<usize> {
2073         let start = self.class_seq_rule_count_byte_range().end;
2074         start..start + self.class_seq_rule_offsets_byte_len
2075     }
2076 }
2077 
2078 impl<'a> FontRead<'a> for ClassSequenceRuleSet<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>2079     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
2080         let mut cursor = data.cursor();
2081         let class_seq_rule_count: u16 = cursor.read()?;
2082         let class_seq_rule_offsets_byte_len =
2083             class_seq_rule_count as usize * Offset16::RAW_BYTE_LEN;
2084         cursor.advance_by(class_seq_rule_offsets_byte_len);
2085         cursor.finish(ClassSequenceRuleSetMarker {
2086             class_seq_rule_offsets_byte_len,
2087         })
2088     }
2089 }
2090 
2091 /// Part of [SequenceContextFormat2]
2092 pub type ClassSequenceRuleSet<'a> = TableRef<'a, ClassSequenceRuleSetMarker>;
2093 
2094 impl<'a> ClassSequenceRuleSet<'a> {
2095     /// Number of ClassSequenceRule tables
class_seq_rule_count(&self) -> u162096     pub fn class_seq_rule_count(&self) -> u16 {
2097         let range = self.shape.class_seq_rule_count_byte_range();
2098         self.data.read_at(range.start).unwrap()
2099     }
2100 
2101     /// Array of offsets to ClassSequenceRule tables, from beginning of
2102     /// ClassSequenceRuleSet table
class_seq_rule_offsets(&self) -> &'a [BigEndian<Offset16>]2103     pub fn class_seq_rule_offsets(&self) -> &'a [BigEndian<Offset16>] {
2104         let range = self.shape.class_seq_rule_offsets_byte_range();
2105         self.data.read_array(range).unwrap()
2106     }
2107 
2108     /// A dynamically resolving wrapper for [`class_seq_rule_offsets`][Self::class_seq_rule_offsets].
class_seq_rules(&self) -> ArrayOfOffsets<'a, ClassSequenceRule<'a>, Offset16>2109     pub fn class_seq_rules(&self) -> ArrayOfOffsets<'a, ClassSequenceRule<'a>, Offset16> {
2110         let data = self.data;
2111         let offsets = self.class_seq_rule_offsets();
2112         ArrayOfOffsets::new(offsets, data, ())
2113     }
2114 }
2115 
2116 #[cfg(feature = "traversal")]
2117 impl<'a> SomeTable<'a> for ClassSequenceRuleSet<'a> {
type_name(&self) -> &str2118     fn type_name(&self) -> &str {
2119         "ClassSequenceRuleSet"
2120     }
get_field(&self, idx: usize) -> Option<Field<'a>>2121     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
2122         match idx {
2123             0usize => Some(Field::new(
2124                 "class_seq_rule_count",
2125                 self.class_seq_rule_count(),
2126             )),
2127             1usize => Some({
2128                 let data = self.data;
2129                 Field::new(
2130                     "class_seq_rule_offsets",
2131                     FieldType::array_of_offsets(
2132                         better_type_name::<ClassSequenceRule>(),
2133                         self.class_seq_rule_offsets(),
2134                         move |off| {
2135                             let target = off.get().resolve::<ClassSequenceRule>(data);
2136                             FieldType::offset(off.get(), target)
2137                         },
2138                     ),
2139                 )
2140             }),
2141             _ => None,
2142         }
2143     }
2144 }
2145 
2146 #[cfg(feature = "traversal")]
2147 impl<'a> std::fmt::Debug for ClassSequenceRuleSet<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result2148     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2149         (self as &dyn SomeTable<'a>).fmt(f)
2150     }
2151 }
2152 
2153 /// Part of [SequenceContextFormat2]
2154 #[derive(Debug, Clone, Copy)]
2155 #[doc(hidden)]
2156 pub struct ClassSequenceRuleMarker {
2157     input_sequence_byte_len: usize,
2158     seq_lookup_records_byte_len: usize,
2159 }
2160 
2161 impl ClassSequenceRuleMarker {
glyph_count_byte_range(&self) -> Range<usize>2162     fn glyph_count_byte_range(&self) -> Range<usize> {
2163         let start = 0;
2164         start..start + u16::RAW_BYTE_LEN
2165     }
seq_lookup_count_byte_range(&self) -> Range<usize>2166     fn seq_lookup_count_byte_range(&self) -> Range<usize> {
2167         let start = self.glyph_count_byte_range().end;
2168         start..start + u16::RAW_BYTE_LEN
2169     }
input_sequence_byte_range(&self) -> Range<usize>2170     fn input_sequence_byte_range(&self) -> Range<usize> {
2171         let start = self.seq_lookup_count_byte_range().end;
2172         start..start + self.input_sequence_byte_len
2173     }
seq_lookup_records_byte_range(&self) -> Range<usize>2174     fn seq_lookup_records_byte_range(&self) -> Range<usize> {
2175         let start = self.input_sequence_byte_range().end;
2176         start..start + self.seq_lookup_records_byte_len
2177     }
2178 }
2179 
2180 impl<'a> FontRead<'a> for ClassSequenceRule<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>2181     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
2182         let mut cursor = data.cursor();
2183         let glyph_count: u16 = cursor.read()?;
2184         let seq_lookup_count: u16 = cursor.read()?;
2185         let input_sequence_byte_len =
2186             transforms::subtract(glyph_count, 1_usize) * u16::RAW_BYTE_LEN;
2187         cursor.advance_by(input_sequence_byte_len);
2188         let seq_lookup_records_byte_len =
2189             seq_lookup_count as usize * SequenceLookupRecord::RAW_BYTE_LEN;
2190         cursor.advance_by(seq_lookup_records_byte_len);
2191         cursor.finish(ClassSequenceRuleMarker {
2192             input_sequence_byte_len,
2193             seq_lookup_records_byte_len,
2194         })
2195     }
2196 }
2197 
2198 /// Part of [SequenceContextFormat2]
2199 pub type ClassSequenceRule<'a> = TableRef<'a, ClassSequenceRuleMarker>;
2200 
2201 impl<'a> ClassSequenceRule<'a> {
2202     /// Number of glyphs to be matched
glyph_count(&self) -> u162203     pub fn glyph_count(&self) -> u16 {
2204         let range = self.shape.glyph_count_byte_range();
2205         self.data.read_at(range.start).unwrap()
2206     }
2207 
2208     /// Number of SequenceLookupRecords
seq_lookup_count(&self) -> u162209     pub fn seq_lookup_count(&self) -> u16 {
2210         let range = self.shape.seq_lookup_count_byte_range();
2211         self.data.read_at(range.start).unwrap()
2212     }
2213 
2214     /// Sequence of classes to be matched to the input glyph sequence,
2215     /// beginning with the second glyph position
input_sequence(&self) -> &'a [BigEndian<u16>]2216     pub fn input_sequence(&self) -> &'a [BigEndian<u16>] {
2217         let range = self.shape.input_sequence_byte_range();
2218         self.data.read_array(range).unwrap()
2219     }
2220 
2221     /// Array of SequenceLookupRecords
seq_lookup_records(&self) -> &'a [SequenceLookupRecord]2222     pub fn seq_lookup_records(&self) -> &'a [SequenceLookupRecord] {
2223         let range = self.shape.seq_lookup_records_byte_range();
2224         self.data.read_array(range).unwrap()
2225     }
2226 }
2227 
2228 #[cfg(feature = "traversal")]
2229 impl<'a> SomeTable<'a> for ClassSequenceRule<'a> {
type_name(&self) -> &str2230     fn type_name(&self) -> &str {
2231         "ClassSequenceRule"
2232     }
get_field(&self, idx: usize) -> Option<Field<'a>>2233     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
2234         match idx {
2235             0usize => Some(Field::new("glyph_count", self.glyph_count())),
2236             1usize => Some(Field::new("seq_lookup_count", self.seq_lookup_count())),
2237             2usize => Some(Field::new("input_sequence", self.input_sequence())),
2238             3usize => Some(Field::new(
2239                 "seq_lookup_records",
2240                 traversal::FieldType::array_of_records(
2241                     stringify!(SequenceLookupRecord),
2242                     self.seq_lookup_records(),
2243                     self.offset_data(),
2244                 ),
2245             )),
2246             _ => None,
2247         }
2248     }
2249 }
2250 
2251 #[cfg(feature = "traversal")]
2252 impl<'a> std::fmt::Debug for ClassSequenceRule<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result2253     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2254         (self as &dyn SomeTable<'a>).fmt(f)
2255     }
2256 }
2257 
2258 impl Format<u16> for SequenceContextFormat3Marker {
2259     const FORMAT: u16 = 3;
2260 }
2261 
2262 /// [Sequence Context Format 3](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#sequence-context-format-3-coverage-based-glyph-contexts)
2263 #[derive(Debug, Clone, Copy)]
2264 #[doc(hidden)]
2265 pub struct SequenceContextFormat3Marker {
2266     coverage_offsets_byte_len: usize,
2267     seq_lookup_records_byte_len: usize,
2268 }
2269 
2270 impl SequenceContextFormat3Marker {
format_byte_range(&self) -> Range<usize>2271     fn format_byte_range(&self) -> Range<usize> {
2272         let start = 0;
2273         start..start + u16::RAW_BYTE_LEN
2274     }
glyph_count_byte_range(&self) -> Range<usize>2275     fn glyph_count_byte_range(&self) -> Range<usize> {
2276         let start = self.format_byte_range().end;
2277         start..start + u16::RAW_BYTE_LEN
2278     }
seq_lookup_count_byte_range(&self) -> Range<usize>2279     fn seq_lookup_count_byte_range(&self) -> Range<usize> {
2280         let start = self.glyph_count_byte_range().end;
2281         start..start + u16::RAW_BYTE_LEN
2282     }
coverage_offsets_byte_range(&self) -> Range<usize>2283     fn coverage_offsets_byte_range(&self) -> Range<usize> {
2284         let start = self.seq_lookup_count_byte_range().end;
2285         start..start + self.coverage_offsets_byte_len
2286     }
seq_lookup_records_byte_range(&self) -> Range<usize>2287     fn seq_lookup_records_byte_range(&self) -> Range<usize> {
2288         let start = self.coverage_offsets_byte_range().end;
2289         start..start + self.seq_lookup_records_byte_len
2290     }
2291 }
2292 
2293 impl<'a> FontRead<'a> for SequenceContextFormat3<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>2294     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
2295         let mut cursor = data.cursor();
2296         cursor.advance::<u16>();
2297         let glyph_count: u16 = cursor.read()?;
2298         let seq_lookup_count: u16 = cursor.read()?;
2299         let coverage_offsets_byte_len = glyph_count as usize * Offset16::RAW_BYTE_LEN;
2300         cursor.advance_by(coverage_offsets_byte_len);
2301         let seq_lookup_records_byte_len =
2302             seq_lookup_count as usize * SequenceLookupRecord::RAW_BYTE_LEN;
2303         cursor.advance_by(seq_lookup_records_byte_len);
2304         cursor.finish(SequenceContextFormat3Marker {
2305             coverage_offsets_byte_len,
2306             seq_lookup_records_byte_len,
2307         })
2308     }
2309 }
2310 
2311 /// [Sequence Context Format 3](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#sequence-context-format-3-coverage-based-glyph-contexts)
2312 pub type SequenceContextFormat3<'a> = TableRef<'a, SequenceContextFormat3Marker>;
2313 
2314 impl<'a> SequenceContextFormat3<'a> {
2315     /// Format identifier: format = 3
format(&self) -> u162316     pub fn format(&self) -> u16 {
2317         let range = self.shape.format_byte_range();
2318         self.data.read_at(range.start).unwrap()
2319     }
2320 
2321     /// Number of glyphs in the input sequence
glyph_count(&self) -> u162322     pub fn glyph_count(&self) -> u16 {
2323         let range = self.shape.glyph_count_byte_range();
2324         self.data.read_at(range.start).unwrap()
2325     }
2326 
2327     /// Number of SequenceLookupRecords
seq_lookup_count(&self) -> u162328     pub fn seq_lookup_count(&self) -> u16 {
2329         let range = self.shape.seq_lookup_count_byte_range();
2330         self.data.read_at(range.start).unwrap()
2331     }
2332 
2333     /// Array of offsets to Coverage tables, from beginning of
2334     /// SequenceContextFormat3 subtable
coverage_offsets(&self) -> &'a [BigEndian<Offset16>]2335     pub fn coverage_offsets(&self) -> &'a [BigEndian<Offset16>] {
2336         let range = self.shape.coverage_offsets_byte_range();
2337         self.data.read_array(range).unwrap()
2338     }
2339 
2340     /// A dynamically resolving wrapper for [`coverage_offsets`][Self::coverage_offsets].
coverages(&self) -> ArrayOfOffsets<'a, CoverageTable<'a>, Offset16>2341     pub fn coverages(&self) -> ArrayOfOffsets<'a, CoverageTable<'a>, Offset16> {
2342         let data = self.data;
2343         let offsets = self.coverage_offsets();
2344         ArrayOfOffsets::new(offsets, data, ())
2345     }
2346 
2347     /// Array of SequenceLookupRecords
seq_lookup_records(&self) -> &'a [SequenceLookupRecord]2348     pub fn seq_lookup_records(&self) -> &'a [SequenceLookupRecord] {
2349         let range = self.shape.seq_lookup_records_byte_range();
2350         self.data.read_array(range).unwrap()
2351     }
2352 }
2353 
2354 #[cfg(feature = "traversal")]
2355 impl<'a> SomeTable<'a> for SequenceContextFormat3<'a> {
type_name(&self) -> &str2356     fn type_name(&self) -> &str {
2357         "SequenceContextFormat3"
2358     }
get_field(&self, idx: usize) -> Option<Field<'a>>2359     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
2360         match idx {
2361             0usize => Some(Field::new("format", self.format())),
2362             1usize => Some(Field::new("glyph_count", self.glyph_count())),
2363             2usize => Some(Field::new("seq_lookup_count", self.seq_lookup_count())),
2364             3usize => Some({
2365                 let data = self.data;
2366                 Field::new(
2367                     "coverage_offsets",
2368                     FieldType::array_of_offsets(
2369                         better_type_name::<CoverageTable>(),
2370                         self.coverage_offsets(),
2371                         move |off| {
2372                             let target = off.get().resolve::<CoverageTable>(data);
2373                             FieldType::offset(off.get(), target)
2374                         },
2375                     ),
2376                 )
2377             }),
2378             4usize => Some(Field::new(
2379                 "seq_lookup_records",
2380                 traversal::FieldType::array_of_records(
2381                     stringify!(SequenceLookupRecord),
2382                     self.seq_lookup_records(),
2383                     self.offset_data(),
2384                 ),
2385             )),
2386             _ => None,
2387         }
2388     }
2389 }
2390 
2391 #[cfg(feature = "traversal")]
2392 impl<'a> std::fmt::Debug for SequenceContextFormat3<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result2393     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2394         (self as &dyn SomeTable<'a>).fmt(f)
2395     }
2396 }
2397 
2398 #[derive(Clone)]
2399 pub enum SequenceContext<'a> {
2400     Format1(SequenceContextFormat1<'a>),
2401     Format2(SequenceContextFormat2<'a>),
2402     Format3(SequenceContextFormat3<'a>),
2403 }
2404 
2405 impl<'a> SequenceContext<'a> {
2406     /// Format identifier: format = 1
format(&self) -> u162407     pub fn format(&self) -> u16 {
2408         match self {
2409             Self::Format1(item) => item.format(),
2410             Self::Format2(item) => item.format(),
2411             Self::Format3(item) => item.format(),
2412         }
2413     }
2414 }
2415 
2416 impl<'a> FontRead<'a> for SequenceContext<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>2417     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
2418         let format: u16 = data.read_at(0usize)?;
2419         match format {
2420             SequenceContextFormat1Marker::FORMAT => Ok(Self::Format1(FontRead::read(data)?)),
2421             SequenceContextFormat2Marker::FORMAT => Ok(Self::Format2(FontRead::read(data)?)),
2422             SequenceContextFormat3Marker::FORMAT => Ok(Self::Format3(FontRead::read(data)?)),
2423             other => Err(ReadError::InvalidFormat(other.into())),
2424         }
2425     }
2426 }
2427 
2428 #[cfg(feature = "traversal")]
2429 impl<'a> SequenceContext<'a> {
dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a>2430     fn dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a> {
2431         match self {
2432             Self::Format1(table) => table,
2433             Self::Format2(table) => table,
2434             Self::Format3(table) => table,
2435         }
2436     }
2437 }
2438 
2439 #[cfg(feature = "traversal")]
2440 impl<'a> std::fmt::Debug for SequenceContext<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result2441     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2442         self.dyn_inner().fmt(f)
2443     }
2444 }
2445 
2446 #[cfg(feature = "traversal")]
2447 impl<'a> SomeTable<'a> for SequenceContext<'a> {
type_name(&self) -> &str2448     fn type_name(&self) -> &str {
2449         self.dyn_inner().type_name()
2450     }
get_field(&self, idx: usize) -> Option<Field<'a>>2451     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
2452         self.dyn_inner().get_field(idx)
2453     }
2454 }
2455 
2456 impl Format<u16> for ChainedSequenceContextFormat1Marker {
2457     const FORMAT: u16 = 1;
2458 }
2459 
2460 /// [Chained Sequence Context Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#chained-sequence-context-format-1-simple-glyph-contexts)
2461 #[derive(Debug, Clone, Copy)]
2462 #[doc(hidden)]
2463 pub struct ChainedSequenceContextFormat1Marker {
2464     chained_seq_rule_set_offsets_byte_len: usize,
2465 }
2466 
2467 impl ChainedSequenceContextFormat1Marker {
format_byte_range(&self) -> Range<usize>2468     fn format_byte_range(&self) -> Range<usize> {
2469         let start = 0;
2470         start..start + u16::RAW_BYTE_LEN
2471     }
coverage_offset_byte_range(&self) -> Range<usize>2472     fn coverage_offset_byte_range(&self) -> Range<usize> {
2473         let start = self.format_byte_range().end;
2474         start..start + Offset16::RAW_BYTE_LEN
2475     }
chained_seq_rule_set_count_byte_range(&self) -> Range<usize>2476     fn chained_seq_rule_set_count_byte_range(&self) -> Range<usize> {
2477         let start = self.coverage_offset_byte_range().end;
2478         start..start + u16::RAW_BYTE_LEN
2479     }
chained_seq_rule_set_offsets_byte_range(&self) -> Range<usize>2480     fn chained_seq_rule_set_offsets_byte_range(&self) -> Range<usize> {
2481         let start = self.chained_seq_rule_set_count_byte_range().end;
2482         start..start + self.chained_seq_rule_set_offsets_byte_len
2483     }
2484 }
2485 
2486 impl<'a> FontRead<'a> for ChainedSequenceContextFormat1<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>2487     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
2488         let mut cursor = data.cursor();
2489         cursor.advance::<u16>();
2490         cursor.advance::<Offset16>();
2491         let chained_seq_rule_set_count: u16 = cursor.read()?;
2492         let chained_seq_rule_set_offsets_byte_len =
2493             chained_seq_rule_set_count as usize * Offset16::RAW_BYTE_LEN;
2494         cursor.advance_by(chained_seq_rule_set_offsets_byte_len);
2495         cursor.finish(ChainedSequenceContextFormat1Marker {
2496             chained_seq_rule_set_offsets_byte_len,
2497         })
2498     }
2499 }
2500 
2501 /// [Chained Sequence Context Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#chained-sequence-context-format-1-simple-glyph-contexts)
2502 pub type ChainedSequenceContextFormat1<'a> = TableRef<'a, ChainedSequenceContextFormat1Marker>;
2503 
2504 impl<'a> ChainedSequenceContextFormat1<'a> {
2505     /// Format identifier: format = 1
format(&self) -> u162506     pub fn format(&self) -> u16 {
2507         let range = self.shape.format_byte_range();
2508         self.data.read_at(range.start).unwrap()
2509     }
2510 
2511     /// Offset to Coverage table, from beginning of
2512     /// ChainSequenceContextFormat1 table
coverage_offset(&self) -> Offset162513     pub fn coverage_offset(&self) -> Offset16 {
2514         let range = self.shape.coverage_offset_byte_range();
2515         self.data.read_at(range.start).unwrap()
2516     }
2517 
2518     /// Attempt to resolve [`coverage_offset`][Self::coverage_offset].
coverage(&self) -> Result<CoverageTable<'a>, ReadError>2519     pub fn coverage(&self) -> Result<CoverageTable<'a>, ReadError> {
2520         let data = self.data;
2521         self.coverage_offset().resolve(data)
2522     }
2523 
2524     /// Number of ChainedSequenceRuleSet tables
chained_seq_rule_set_count(&self) -> u162525     pub fn chained_seq_rule_set_count(&self) -> u16 {
2526         let range = self.shape.chained_seq_rule_set_count_byte_range();
2527         self.data.read_at(range.start).unwrap()
2528     }
2529 
2530     /// Array of offsets to ChainedSeqRuleSet tables, from beginning of
2531     /// ChainedSequenceContextFormat1 table (may be NULL)
chained_seq_rule_set_offsets(&self) -> &'a [BigEndian<Nullable<Offset16>>]2532     pub fn chained_seq_rule_set_offsets(&self) -> &'a [BigEndian<Nullable<Offset16>>] {
2533         let range = self.shape.chained_seq_rule_set_offsets_byte_range();
2534         self.data.read_array(range).unwrap()
2535     }
2536 
2537     /// A dynamically resolving wrapper for [`chained_seq_rule_set_offsets`][Self::chained_seq_rule_set_offsets].
chained_seq_rule_sets( &self, ) -> ArrayOfNullableOffsets<'a, ChainedSequenceRuleSet<'a>, Offset16>2538     pub fn chained_seq_rule_sets(
2539         &self,
2540     ) -> ArrayOfNullableOffsets<'a, ChainedSequenceRuleSet<'a>, Offset16> {
2541         let data = self.data;
2542         let offsets = self.chained_seq_rule_set_offsets();
2543         ArrayOfNullableOffsets::new(offsets, data, ())
2544     }
2545 }
2546 
2547 #[cfg(feature = "traversal")]
2548 impl<'a> SomeTable<'a> for ChainedSequenceContextFormat1<'a> {
type_name(&self) -> &str2549     fn type_name(&self) -> &str {
2550         "ChainedSequenceContextFormat1"
2551     }
get_field(&self, idx: usize) -> Option<Field<'a>>2552     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
2553         match idx {
2554             0usize => Some(Field::new("format", self.format())),
2555             1usize => Some(Field::new(
2556                 "coverage_offset",
2557                 FieldType::offset(self.coverage_offset(), self.coverage()),
2558             )),
2559             2usize => Some(Field::new(
2560                 "chained_seq_rule_set_count",
2561                 self.chained_seq_rule_set_count(),
2562             )),
2563             3usize => Some({
2564                 let data = self.data;
2565                 Field::new(
2566                     "chained_seq_rule_set_offsets",
2567                     FieldType::array_of_offsets(
2568                         better_type_name::<ChainedSequenceRuleSet>(),
2569                         self.chained_seq_rule_set_offsets(),
2570                         move |off| {
2571                             let target = off.get().resolve::<ChainedSequenceRuleSet>(data);
2572                             FieldType::offset(off.get(), target)
2573                         },
2574                     ),
2575                 )
2576             }),
2577             _ => None,
2578         }
2579     }
2580 }
2581 
2582 #[cfg(feature = "traversal")]
2583 impl<'a> std::fmt::Debug for ChainedSequenceContextFormat1<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result2584     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2585         (self as &dyn SomeTable<'a>).fmt(f)
2586     }
2587 }
2588 
2589 /// Part of [ChainedSequenceContextFormat1]
2590 #[derive(Debug, Clone, Copy)]
2591 #[doc(hidden)]
2592 pub struct ChainedSequenceRuleSetMarker {
2593     chained_seq_rule_offsets_byte_len: usize,
2594 }
2595 
2596 impl ChainedSequenceRuleSetMarker {
chained_seq_rule_count_byte_range(&self) -> Range<usize>2597     fn chained_seq_rule_count_byte_range(&self) -> Range<usize> {
2598         let start = 0;
2599         start..start + u16::RAW_BYTE_LEN
2600     }
chained_seq_rule_offsets_byte_range(&self) -> Range<usize>2601     fn chained_seq_rule_offsets_byte_range(&self) -> Range<usize> {
2602         let start = self.chained_seq_rule_count_byte_range().end;
2603         start..start + self.chained_seq_rule_offsets_byte_len
2604     }
2605 }
2606 
2607 impl<'a> FontRead<'a> for ChainedSequenceRuleSet<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>2608     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
2609         let mut cursor = data.cursor();
2610         let chained_seq_rule_count: u16 = cursor.read()?;
2611         let chained_seq_rule_offsets_byte_len =
2612             chained_seq_rule_count as usize * Offset16::RAW_BYTE_LEN;
2613         cursor.advance_by(chained_seq_rule_offsets_byte_len);
2614         cursor.finish(ChainedSequenceRuleSetMarker {
2615             chained_seq_rule_offsets_byte_len,
2616         })
2617     }
2618 }
2619 
2620 /// Part of [ChainedSequenceContextFormat1]
2621 pub type ChainedSequenceRuleSet<'a> = TableRef<'a, ChainedSequenceRuleSetMarker>;
2622 
2623 impl<'a> ChainedSequenceRuleSet<'a> {
2624     /// Number of ChainedSequenceRule tables
chained_seq_rule_count(&self) -> u162625     pub fn chained_seq_rule_count(&self) -> u16 {
2626         let range = self.shape.chained_seq_rule_count_byte_range();
2627         self.data.read_at(range.start).unwrap()
2628     }
2629 
2630     /// Array of offsets to ChainedSequenceRule tables, from beginning
2631     /// of ChainedSequenceRuleSet table
chained_seq_rule_offsets(&self) -> &'a [BigEndian<Offset16>]2632     pub fn chained_seq_rule_offsets(&self) -> &'a [BigEndian<Offset16>] {
2633         let range = self.shape.chained_seq_rule_offsets_byte_range();
2634         self.data.read_array(range).unwrap()
2635     }
2636 
2637     /// A dynamically resolving wrapper for [`chained_seq_rule_offsets`][Self::chained_seq_rule_offsets].
chained_seq_rules(&self) -> ArrayOfOffsets<'a, ChainedSequenceRule<'a>, Offset16>2638     pub fn chained_seq_rules(&self) -> ArrayOfOffsets<'a, ChainedSequenceRule<'a>, Offset16> {
2639         let data = self.data;
2640         let offsets = self.chained_seq_rule_offsets();
2641         ArrayOfOffsets::new(offsets, data, ())
2642     }
2643 }
2644 
2645 #[cfg(feature = "traversal")]
2646 impl<'a> SomeTable<'a> for ChainedSequenceRuleSet<'a> {
type_name(&self) -> &str2647     fn type_name(&self) -> &str {
2648         "ChainedSequenceRuleSet"
2649     }
get_field(&self, idx: usize) -> Option<Field<'a>>2650     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
2651         match idx {
2652             0usize => Some(Field::new(
2653                 "chained_seq_rule_count",
2654                 self.chained_seq_rule_count(),
2655             )),
2656             1usize => Some({
2657                 let data = self.data;
2658                 Field::new(
2659                     "chained_seq_rule_offsets",
2660                     FieldType::array_of_offsets(
2661                         better_type_name::<ChainedSequenceRule>(),
2662                         self.chained_seq_rule_offsets(),
2663                         move |off| {
2664                             let target = off.get().resolve::<ChainedSequenceRule>(data);
2665                             FieldType::offset(off.get(), target)
2666                         },
2667                     ),
2668                 )
2669             }),
2670             _ => None,
2671         }
2672     }
2673 }
2674 
2675 #[cfg(feature = "traversal")]
2676 impl<'a> std::fmt::Debug for ChainedSequenceRuleSet<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result2677     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2678         (self as &dyn SomeTable<'a>).fmt(f)
2679     }
2680 }
2681 
2682 /// Part of [ChainedSequenceContextFormat1]
2683 #[derive(Debug, Clone, Copy)]
2684 #[doc(hidden)]
2685 pub struct ChainedSequenceRuleMarker {
2686     backtrack_sequence_byte_len: usize,
2687     input_sequence_byte_len: usize,
2688     lookahead_sequence_byte_len: usize,
2689     seq_lookup_records_byte_len: usize,
2690 }
2691 
2692 impl ChainedSequenceRuleMarker {
backtrack_glyph_count_byte_range(&self) -> Range<usize>2693     fn backtrack_glyph_count_byte_range(&self) -> Range<usize> {
2694         let start = 0;
2695         start..start + u16::RAW_BYTE_LEN
2696     }
backtrack_sequence_byte_range(&self) -> Range<usize>2697     fn backtrack_sequence_byte_range(&self) -> Range<usize> {
2698         let start = self.backtrack_glyph_count_byte_range().end;
2699         start..start + self.backtrack_sequence_byte_len
2700     }
input_glyph_count_byte_range(&self) -> Range<usize>2701     fn input_glyph_count_byte_range(&self) -> Range<usize> {
2702         let start = self.backtrack_sequence_byte_range().end;
2703         start..start + u16::RAW_BYTE_LEN
2704     }
input_sequence_byte_range(&self) -> Range<usize>2705     fn input_sequence_byte_range(&self) -> Range<usize> {
2706         let start = self.input_glyph_count_byte_range().end;
2707         start..start + self.input_sequence_byte_len
2708     }
lookahead_glyph_count_byte_range(&self) -> Range<usize>2709     fn lookahead_glyph_count_byte_range(&self) -> Range<usize> {
2710         let start = self.input_sequence_byte_range().end;
2711         start..start + u16::RAW_BYTE_LEN
2712     }
lookahead_sequence_byte_range(&self) -> Range<usize>2713     fn lookahead_sequence_byte_range(&self) -> Range<usize> {
2714         let start = self.lookahead_glyph_count_byte_range().end;
2715         start..start + self.lookahead_sequence_byte_len
2716     }
seq_lookup_count_byte_range(&self) -> Range<usize>2717     fn seq_lookup_count_byte_range(&self) -> Range<usize> {
2718         let start = self.lookahead_sequence_byte_range().end;
2719         start..start + u16::RAW_BYTE_LEN
2720     }
seq_lookup_records_byte_range(&self) -> Range<usize>2721     fn seq_lookup_records_byte_range(&self) -> Range<usize> {
2722         let start = self.seq_lookup_count_byte_range().end;
2723         start..start + self.seq_lookup_records_byte_len
2724     }
2725 }
2726 
2727 impl<'a> FontRead<'a> for ChainedSequenceRule<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>2728     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
2729         let mut cursor = data.cursor();
2730         let backtrack_glyph_count: u16 = cursor.read()?;
2731         let backtrack_sequence_byte_len = backtrack_glyph_count as usize * GlyphId::RAW_BYTE_LEN;
2732         cursor.advance_by(backtrack_sequence_byte_len);
2733         let input_glyph_count: u16 = cursor.read()?;
2734         let input_sequence_byte_len =
2735             transforms::subtract(input_glyph_count, 1_usize) * GlyphId::RAW_BYTE_LEN;
2736         cursor.advance_by(input_sequence_byte_len);
2737         let lookahead_glyph_count: u16 = cursor.read()?;
2738         let lookahead_sequence_byte_len = lookahead_glyph_count as usize * GlyphId::RAW_BYTE_LEN;
2739         cursor.advance_by(lookahead_sequence_byte_len);
2740         let seq_lookup_count: u16 = cursor.read()?;
2741         let seq_lookup_records_byte_len =
2742             seq_lookup_count as usize * SequenceLookupRecord::RAW_BYTE_LEN;
2743         cursor.advance_by(seq_lookup_records_byte_len);
2744         cursor.finish(ChainedSequenceRuleMarker {
2745             backtrack_sequence_byte_len,
2746             input_sequence_byte_len,
2747             lookahead_sequence_byte_len,
2748             seq_lookup_records_byte_len,
2749         })
2750     }
2751 }
2752 
2753 /// Part of [ChainedSequenceContextFormat1]
2754 pub type ChainedSequenceRule<'a> = TableRef<'a, ChainedSequenceRuleMarker>;
2755 
2756 impl<'a> ChainedSequenceRule<'a> {
2757     /// Number of glyphs in the backtrack sequence
backtrack_glyph_count(&self) -> u162758     pub fn backtrack_glyph_count(&self) -> u16 {
2759         let range = self.shape.backtrack_glyph_count_byte_range();
2760         self.data.read_at(range.start).unwrap()
2761     }
2762 
2763     /// Array of backtrack glyph IDs
backtrack_sequence(&self) -> &'a [BigEndian<GlyphId>]2764     pub fn backtrack_sequence(&self) -> &'a [BigEndian<GlyphId>] {
2765         let range = self.shape.backtrack_sequence_byte_range();
2766         self.data.read_array(range).unwrap()
2767     }
2768 
2769     /// Number of glyphs in the input sequence
input_glyph_count(&self) -> u162770     pub fn input_glyph_count(&self) -> u16 {
2771         let range = self.shape.input_glyph_count_byte_range();
2772         self.data.read_at(range.start).unwrap()
2773     }
2774 
2775     /// Array of input glyph IDs—start with second glyph
input_sequence(&self) -> &'a [BigEndian<GlyphId>]2776     pub fn input_sequence(&self) -> &'a [BigEndian<GlyphId>] {
2777         let range = self.shape.input_sequence_byte_range();
2778         self.data.read_array(range).unwrap()
2779     }
2780 
2781     /// Number of glyphs in the lookahead sequence
lookahead_glyph_count(&self) -> u162782     pub fn lookahead_glyph_count(&self) -> u16 {
2783         let range = self.shape.lookahead_glyph_count_byte_range();
2784         self.data.read_at(range.start).unwrap()
2785     }
2786 
2787     /// Array of lookahead glyph IDs
lookahead_sequence(&self) -> &'a [BigEndian<GlyphId>]2788     pub fn lookahead_sequence(&self) -> &'a [BigEndian<GlyphId>] {
2789         let range = self.shape.lookahead_sequence_byte_range();
2790         self.data.read_array(range).unwrap()
2791     }
2792 
2793     /// Number of SequenceLookupRecords
seq_lookup_count(&self) -> u162794     pub fn seq_lookup_count(&self) -> u16 {
2795         let range = self.shape.seq_lookup_count_byte_range();
2796         self.data.read_at(range.start).unwrap()
2797     }
2798 
2799     /// Array of SequenceLookupRecords
seq_lookup_records(&self) -> &'a [SequenceLookupRecord]2800     pub fn seq_lookup_records(&self) -> &'a [SequenceLookupRecord] {
2801         let range = self.shape.seq_lookup_records_byte_range();
2802         self.data.read_array(range).unwrap()
2803     }
2804 }
2805 
2806 #[cfg(feature = "traversal")]
2807 impl<'a> SomeTable<'a> for ChainedSequenceRule<'a> {
type_name(&self) -> &str2808     fn type_name(&self) -> &str {
2809         "ChainedSequenceRule"
2810     }
get_field(&self, idx: usize) -> Option<Field<'a>>2811     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
2812         match idx {
2813             0usize => Some(Field::new(
2814                 "backtrack_glyph_count",
2815                 self.backtrack_glyph_count(),
2816             )),
2817             1usize => Some(Field::new("backtrack_sequence", self.backtrack_sequence())),
2818             2usize => Some(Field::new("input_glyph_count", self.input_glyph_count())),
2819             3usize => Some(Field::new("input_sequence", self.input_sequence())),
2820             4usize => Some(Field::new(
2821                 "lookahead_glyph_count",
2822                 self.lookahead_glyph_count(),
2823             )),
2824             5usize => Some(Field::new("lookahead_sequence", self.lookahead_sequence())),
2825             6usize => Some(Field::new("seq_lookup_count", self.seq_lookup_count())),
2826             7usize => Some(Field::new(
2827                 "seq_lookup_records",
2828                 traversal::FieldType::array_of_records(
2829                     stringify!(SequenceLookupRecord),
2830                     self.seq_lookup_records(),
2831                     self.offset_data(),
2832                 ),
2833             )),
2834             _ => None,
2835         }
2836     }
2837 }
2838 
2839 #[cfg(feature = "traversal")]
2840 impl<'a> std::fmt::Debug for ChainedSequenceRule<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result2841     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2842         (self as &dyn SomeTable<'a>).fmt(f)
2843     }
2844 }
2845 
2846 impl Format<u16> for ChainedSequenceContextFormat2Marker {
2847     const FORMAT: u16 = 2;
2848 }
2849 
2850 /// [Chained Sequence Context Format 2](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#chained-sequence-context-format-2-class-based-glyph-contexts)
2851 #[derive(Debug, Clone, Copy)]
2852 #[doc(hidden)]
2853 pub struct ChainedSequenceContextFormat2Marker {
2854     chained_class_seq_rule_set_offsets_byte_len: usize,
2855 }
2856 
2857 impl ChainedSequenceContextFormat2Marker {
format_byte_range(&self) -> Range<usize>2858     fn format_byte_range(&self) -> Range<usize> {
2859         let start = 0;
2860         start..start + u16::RAW_BYTE_LEN
2861     }
coverage_offset_byte_range(&self) -> Range<usize>2862     fn coverage_offset_byte_range(&self) -> Range<usize> {
2863         let start = self.format_byte_range().end;
2864         start..start + Offset16::RAW_BYTE_LEN
2865     }
backtrack_class_def_offset_byte_range(&self) -> Range<usize>2866     fn backtrack_class_def_offset_byte_range(&self) -> Range<usize> {
2867         let start = self.coverage_offset_byte_range().end;
2868         start..start + Offset16::RAW_BYTE_LEN
2869     }
input_class_def_offset_byte_range(&self) -> Range<usize>2870     fn input_class_def_offset_byte_range(&self) -> Range<usize> {
2871         let start = self.backtrack_class_def_offset_byte_range().end;
2872         start..start + Offset16::RAW_BYTE_LEN
2873     }
lookahead_class_def_offset_byte_range(&self) -> Range<usize>2874     fn lookahead_class_def_offset_byte_range(&self) -> Range<usize> {
2875         let start = self.input_class_def_offset_byte_range().end;
2876         start..start + Offset16::RAW_BYTE_LEN
2877     }
chained_class_seq_rule_set_count_byte_range(&self) -> Range<usize>2878     fn chained_class_seq_rule_set_count_byte_range(&self) -> Range<usize> {
2879         let start = self.lookahead_class_def_offset_byte_range().end;
2880         start..start + u16::RAW_BYTE_LEN
2881     }
chained_class_seq_rule_set_offsets_byte_range(&self) -> Range<usize>2882     fn chained_class_seq_rule_set_offsets_byte_range(&self) -> Range<usize> {
2883         let start = self.chained_class_seq_rule_set_count_byte_range().end;
2884         start..start + self.chained_class_seq_rule_set_offsets_byte_len
2885     }
2886 }
2887 
2888 impl<'a> FontRead<'a> for ChainedSequenceContextFormat2<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>2889     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
2890         let mut cursor = data.cursor();
2891         cursor.advance::<u16>();
2892         cursor.advance::<Offset16>();
2893         cursor.advance::<Offset16>();
2894         cursor.advance::<Offset16>();
2895         cursor.advance::<Offset16>();
2896         let chained_class_seq_rule_set_count: u16 = cursor.read()?;
2897         let chained_class_seq_rule_set_offsets_byte_len =
2898             chained_class_seq_rule_set_count as usize * Offset16::RAW_BYTE_LEN;
2899         cursor.advance_by(chained_class_seq_rule_set_offsets_byte_len);
2900         cursor.finish(ChainedSequenceContextFormat2Marker {
2901             chained_class_seq_rule_set_offsets_byte_len,
2902         })
2903     }
2904 }
2905 
2906 /// [Chained Sequence Context Format 2](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#chained-sequence-context-format-2-class-based-glyph-contexts)
2907 pub type ChainedSequenceContextFormat2<'a> = TableRef<'a, ChainedSequenceContextFormat2Marker>;
2908 
2909 impl<'a> ChainedSequenceContextFormat2<'a> {
2910     /// Format identifier: format = 2
format(&self) -> u162911     pub fn format(&self) -> u16 {
2912         let range = self.shape.format_byte_range();
2913         self.data.read_at(range.start).unwrap()
2914     }
2915 
2916     /// Offset to Coverage table, from beginning of
2917     /// ChainedSequenceContextFormat2 table
coverage_offset(&self) -> Offset162918     pub fn coverage_offset(&self) -> Offset16 {
2919         let range = self.shape.coverage_offset_byte_range();
2920         self.data.read_at(range.start).unwrap()
2921     }
2922 
2923     /// Attempt to resolve [`coverage_offset`][Self::coverage_offset].
coverage(&self) -> Result<CoverageTable<'a>, ReadError>2924     pub fn coverage(&self) -> Result<CoverageTable<'a>, ReadError> {
2925         let data = self.data;
2926         self.coverage_offset().resolve(data)
2927     }
2928 
2929     /// Offset to ClassDef table containing backtrack sequence context,
2930     /// from beginning of ChainedSequenceContextFormat2 table
backtrack_class_def_offset(&self) -> Offset162931     pub fn backtrack_class_def_offset(&self) -> Offset16 {
2932         let range = self.shape.backtrack_class_def_offset_byte_range();
2933         self.data.read_at(range.start).unwrap()
2934     }
2935 
2936     /// Attempt to resolve [`backtrack_class_def_offset`][Self::backtrack_class_def_offset].
backtrack_class_def(&self) -> Result<ClassDef<'a>, ReadError>2937     pub fn backtrack_class_def(&self) -> Result<ClassDef<'a>, ReadError> {
2938         let data = self.data;
2939         self.backtrack_class_def_offset().resolve(data)
2940     }
2941 
2942     /// Offset to ClassDef table containing input sequence context,
2943     /// from beginning of ChainedSequenceContextFormat2 table
input_class_def_offset(&self) -> Offset162944     pub fn input_class_def_offset(&self) -> Offset16 {
2945         let range = self.shape.input_class_def_offset_byte_range();
2946         self.data.read_at(range.start).unwrap()
2947     }
2948 
2949     /// Attempt to resolve [`input_class_def_offset`][Self::input_class_def_offset].
input_class_def(&self) -> Result<ClassDef<'a>, ReadError>2950     pub fn input_class_def(&self) -> Result<ClassDef<'a>, ReadError> {
2951         let data = self.data;
2952         self.input_class_def_offset().resolve(data)
2953     }
2954 
2955     /// Offset to ClassDef table containing lookahead sequence context,
2956     /// from beginning of ChainedSequenceContextFormat2 table
lookahead_class_def_offset(&self) -> Offset162957     pub fn lookahead_class_def_offset(&self) -> Offset16 {
2958         let range = self.shape.lookahead_class_def_offset_byte_range();
2959         self.data.read_at(range.start).unwrap()
2960     }
2961 
2962     /// Attempt to resolve [`lookahead_class_def_offset`][Self::lookahead_class_def_offset].
lookahead_class_def(&self) -> Result<ClassDef<'a>, ReadError>2963     pub fn lookahead_class_def(&self) -> Result<ClassDef<'a>, ReadError> {
2964         let data = self.data;
2965         self.lookahead_class_def_offset().resolve(data)
2966     }
2967 
2968     /// Number of ChainedClassSequenceRuleSet tables
chained_class_seq_rule_set_count(&self) -> u162969     pub fn chained_class_seq_rule_set_count(&self) -> u16 {
2970         let range = self.shape.chained_class_seq_rule_set_count_byte_range();
2971         self.data.read_at(range.start).unwrap()
2972     }
2973 
2974     /// Array of offsets to ChainedClassSequenceRuleSet tables, from
2975     /// beginning of ChainedSequenceContextFormat2 table (may be NULL)
chained_class_seq_rule_set_offsets(&self) -> &'a [BigEndian<Nullable<Offset16>>]2976     pub fn chained_class_seq_rule_set_offsets(&self) -> &'a [BigEndian<Nullable<Offset16>>] {
2977         let range = self.shape.chained_class_seq_rule_set_offsets_byte_range();
2978         self.data.read_array(range).unwrap()
2979     }
2980 
2981     /// A dynamically resolving wrapper for [`chained_class_seq_rule_set_offsets`][Self::chained_class_seq_rule_set_offsets].
chained_class_seq_rule_sets( &self, ) -> ArrayOfNullableOffsets<'a, ChainedClassSequenceRuleSet<'a>, Offset16>2982     pub fn chained_class_seq_rule_sets(
2983         &self,
2984     ) -> ArrayOfNullableOffsets<'a, ChainedClassSequenceRuleSet<'a>, Offset16> {
2985         let data = self.data;
2986         let offsets = self.chained_class_seq_rule_set_offsets();
2987         ArrayOfNullableOffsets::new(offsets, data, ())
2988     }
2989 }
2990 
2991 #[cfg(feature = "traversal")]
2992 impl<'a> SomeTable<'a> for ChainedSequenceContextFormat2<'a> {
type_name(&self) -> &str2993     fn type_name(&self) -> &str {
2994         "ChainedSequenceContextFormat2"
2995     }
get_field(&self, idx: usize) -> Option<Field<'a>>2996     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
2997         match idx {
2998             0usize => Some(Field::new("format", self.format())),
2999             1usize => Some(Field::new(
3000                 "coverage_offset",
3001                 FieldType::offset(self.coverage_offset(), self.coverage()),
3002             )),
3003             2usize => Some(Field::new(
3004                 "backtrack_class_def_offset",
3005                 FieldType::offset(
3006                     self.backtrack_class_def_offset(),
3007                     self.backtrack_class_def(),
3008                 ),
3009             )),
3010             3usize => Some(Field::new(
3011                 "input_class_def_offset",
3012                 FieldType::offset(self.input_class_def_offset(), self.input_class_def()),
3013             )),
3014             4usize => Some(Field::new(
3015                 "lookahead_class_def_offset",
3016                 FieldType::offset(
3017                     self.lookahead_class_def_offset(),
3018                     self.lookahead_class_def(),
3019                 ),
3020             )),
3021             5usize => Some(Field::new(
3022                 "chained_class_seq_rule_set_count",
3023                 self.chained_class_seq_rule_set_count(),
3024             )),
3025             6usize => Some({
3026                 let data = self.data;
3027                 Field::new(
3028                     "chained_class_seq_rule_set_offsets",
3029                     FieldType::array_of_offsets(
3030                         better_type_name::<ChainedClassSequenceRuleSet>(),
3031                         self.chained_class_seq_rule_set_offsets(),
3032                         move |off| {
3033                             let target = off.get().resolve::<ChainedClassSequenceRuleSet>(data);
3034                             FieldType::offset(off.get(), target)
3035                         },
3036                     ),
3037                 )
3038             }),
3039             _ => None,
3040         }
3041     }
3042 }
3043 
3044 #[cfg(feature = "traversal")]
3045 impl<'a> std::fmt::Debug for ChainedSequenceContextFormat2<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result3046     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3047         (self as &dyn SomeTable<'a>).fmt(f)
3048     }
3049 }
3050 
3051 /// Part of [ChainedSequenceContextFormat2]
3052 #[derive(Debug, Clone, Copy)]
3053 #[doc(hidden)]
3054 pub struct ChainedClassSequenceRuleSetMarker {
3055     chained_class_seq_rule_offsets_byte_len: usize,
3056 }
3057 
3058 impl ChainedClassSequenceRuleSetMarker {
chained_class_seq_rule_count_byte_range(&self) -> Range<usize>3059     fn chained_class_seq_rule_count_byte_range(&self) -> Range<usize> {
3060         let start = 0;
3061         start..start + u16::RAW_BYTE_LEN
3062     }
chained_class_seq_rule_offsets_byte_range(&self) -> Range<usize>3063     fn chained_class_seq_rule_offsets_byte_range(&self) -> Range<usize> {
3064         let start = self.chained_class_seq_rule_count_byte_range().end;
3065         start..start + self.chained_class_seq_rule_offsets_byte_len
3066     }
3067 }
3068 
3069 impl<'a> FontRead<'a> for ChainedClassSequenceRuleSet<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>3070     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
3071         let mut cursor = data.cursor();
3072         let chained_class_seq_rule_count: u16 = cursor.read()?;
3073         let chained_class_seq_rule_offsets_byte_len =
3074             chained_class_seq_rule_count as usize * Offset16::RAW_BYTE_LEN;
3075         cursor.advance_by(chained_class_seq_rule_offsets_byte_len);
3076         cursor.finish(ChainedClassSequenceRuleSetMarker {
3077             chained_class_seq_rule_offsets_byte_len,
3078         })
3079     }
3080 }
3081 
3082 /// Part of [ChainedSequenceContextFormat2]
3083 pub type ChainedClassSequenceRuleSet<'a> = TableRef<'a, ChainedClassSequenceRuleSetMarker>;
3084 
3085 impl<'a> ChainedClassSequenceRuleSet<'a> {
3086     /// Number of ChainedClassSequenceRule tables
chained_class_seq_rule_count(&self) -> u163087     pub fn chained_class_seq_rule_count(&self) -> u16 {
3088         let range = self.shape.chained_class_seq_rule_count_byte_range();
3089         self.data.read_at(range.start).unwrap()
3090     }
3091 
3092     /// Array of offsets to ChainedClassSequenceRule tables, from
3093     /// beginning of ChainedClassSequenceRuleSet
chained_class_seq_rule_offsets(&self) -> &'a [BigEndian<Offset16>]3094     pub fn chained_class_seq_rule_offsets(&self) -> &'a [BigEndian<Offset16>] {
3095         let range = self.shape.chained_class_seq_rule_offsets_byte_range();
3096         self.data.read_array(range).unwrap()
3097     }
3098 
3099     /// A dynamically resolving wrapper for [`chained_class_seq_rule_offsets`][Self::chained_class_seq_rule_offsets].
chained_class_seq_rules( &self, ) -> ArrayOfOffsets<'a, ChainedClassSequenceRule<'a>, Offset16>3100     pub fn chained_class_seq_rules(
3101         &self,
3102     ) -> ArrayOfOffsets<'a, ChainedClassSequenceRule<'a>, Offset16> {
3103         let data = self.data;
3104         let offsets = self.chained_class_seq_rule_offsets();
3105         ArrayOfOffsets::new(offsets, data, ())
3106     }
3107 }
3108 
3109 #[cfg(feature = "traversal")]
3110 impl<'a> SomeTable<'a> for ChainedClassSequenceRuleSet<'a> {
type_name(&self) -> &str3111     fn type_name(&self) -> &str {
3112         "ChainedClassSequenceRuleSet"
3113     }
get_field(&self, idx: usize) -> Option<Field<'a>>3114     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
3115         match idx {
3116             0usize => Some(Field::new(
3117                 "chained_class_seq_rule_count",
3118                 self.chained_class_seq_rule_count(),
3119             )),
3120             1usize => Some({
3121                 let data = self.data;
3122                 Field::new(
3123                     "chained_class_seq_rule_offsets",
3124                     FieldType::array_of_offsets(
3125                         better_type_name::<ChainedClassSequenceRule>(),
3126                         self.chained_class_seq_rule_offsets(),
3127                         move |off| {
3128                             let target = off.get().resolve::<ChainedClassSequenceRule>(data);
3129                             FieldType::offset(off.get(), target)
3130                         },
3131                     ),
3132                 )
3133             }),
3134             _ => None,
3135         }
3136     }
3137 }
3138 
3139 #[cfg(feature = "traversal")]
3140 impl<'a> std::fmt::Debug for ChainedClassSequenceRuleSet<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result3141     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3142         (self as &dyn SomeTable<'a>).fmt(f)
3143     }
3144 }
3145 
3146 /// Part of [ChainedSequenceContextFormat2]
3147 #[derive(Debug, Clone, Copy)]
3148 #[doc(hidden)]
3149 pub struct ChainedClassSequenceRuleMarker {
3150     backtrack_sequence_byte_len: usize,
3151     input_sequence_byte_len: usize,
3152     lookahead_sequence_byte_len: usize,
3153     seq_lookup_records_byte_len: usize,
3154 }
3155 
3156 impl ChainedClassSequenceRuleMarker {
backtrack_glyph_count_byte_range(&self) -> Range<usize>3157     fn backtrack_glyph_count_byte_range(&self) -> Range<usize> {
3158         let start = 0;
3159         start..start + u16::RAW_BYTE_LEN
3160     }
backtrack_sequence_byte_range(&self) -> Range<usize>3161     fn backtrack_sequence_byte_range(&self) -> Range<usize> {
3162         let start = self.backtrack_glyph_count_byte_range().end;
3163         start..start + self.backtrack_sequence_byte_len
3164     }
input_glyph_count_byte_range(&self) -> Range<usize>3165     fn input_glyph_count_byte_range(&self) -> Range<usize> {
3166         let start = self.backtrack_sequence_byte_range().end;
3167         start..start + u16::RAW_BYTE_LEN
3168     }
input_sequence_byte_range(&self) -> Range<usize>3169     fn input_sequence_byte_range(&self) -> Range<usize> {
3170         let start = self.input_glyph_count_byte_range().end;
3171         start..start + self.input_sequence_byte_len
3172     }
lookahead_glyph_count_byte_range(&self) -> Range<usize>3173     fn lookahead_glyph_count_byte_range(&self) -> Range<usize> {
3174         let start = self.input_sequence_byte_range().end;
3175         start..start + u16::RAW_BYTE_LEN
3176     }
lookahead_sequence_byte_range(&self) -> Range<usize>3177     fn lookahead_sequence_byte_range(&self) -> Range<usize> {
3178         let start = self.lookahead_glyph_count_byte_range().end;
3179         start..start + self.lookahead_sequence_byte_len
3180     }
seq_lookup_count_byte_range(&self) -> Range<usize>3181     fn seq_lookup_count_byte_range(&self) -> Range<usize> {
3182         let start = self.lookahead_sequence_byte_range().end;
3183         start..start + u16::RAW_BYTE_LEN
3184     }
seq_lookup_records_byte_range(&self) -> Range<usize>3185     fn seq_lookup_records_byte_range(&self) -> Range<usize> {
3186         let start = self.seq_lookup_count_byte_range().end;
3187         start..start + self.seq_lookup_records_byte_len
3188     }
3189 }
3190 
3191 impl<'a> FontRead<'a> for ChainedClassSequenceRule<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>3192     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
3193         let mut cursor = data.cursor();
3194         let backtrack_glyph_count: u16 = cursor.read()?;
3195         let backtrack_sequence_byte_len = backtrack_glyph_count as usize * u16::RAW_BYTE_LEN;
3196         cursor.advance_by(backtrack_sequence_byte_len);
3197         let input_glyph_count: u16 = cursor.read()?;
3198         let input_sequence_byte_len =
3199             transforms::subtract(input_glyph_count, 1_usize) * u16::RAW_BYTE_LEN;
3200         cursor.advance_by(input_sequence_byte_len);
3201         let lookahead_glyph_count: u16 = cursor.read()?;
3202         let lookahead_sequence_byte_len = lookahead_glyph_count as usize * u16::RAW_BYTE_LEN;
3203         cursor.advance_by(lookahead_sequence_byte_len);
3204         let seq_lookup_count: u16 = cursor.read()?;
3205         let seq_lookup_records_byte_len =
3206             seq_lookup_count as usize * SequenceLookupRecord::RAW_BYTE_LEN;
3207         cursor.advance_by(seq_lookup_records_byte_len);
3208         cursor.finish(ChainedClassSequenceRuleMarker {
3209             backtrack_sequence_byte_len,
3210             input_sequence_byte_len,
3211             lookahead_sequence_byte_len,
3212             seq_lookup_records_byte_len,
3213         })
3214     }
3215 }
3216 
3217 /// Part of [ChainedSequenceContextFormat2]
3218 pub type ChainedClassSequenceRule<'a> = TableRef<'a, ChainedClassSequenceRuleMarker>;
3219 
3220 impl<'a> ChainedClassSequenceRule<'a> {
3221     /// Number of glyphs in the backtrack sequence
backtrack_glyph_count(&self) -> u163222     pub fn backtrack_glyph_count(&self) -> u16 {
3223         let range = self.shape.backtrack_glyph_count_byte_range();
3224         self.data.read_at(range.start).unwrap()
3225     }
3226 
3227     /// Array of backtrack-sequence classes
backtrack_sequence(&self) -> &'a [BigEndian<u16>]3228     pub fn backtrack_sequence(&self) -> &'a [BigEndian<u16>] {
3229         let range = self.shape.backtrack_sequence_byte_range();
3230         self.data.read_array(range).unwrap()
3231     }
3232 
3233     /// Total number of glyphs in the input sequence
input_glyph_count(&self) -> u163234     pub fn input_glyph_count(&self) -> u16 {
3235         let range = self.shape.input_glyph_count_byte_range();
3236         self.data.read_at(range.start).unwrap()
3237     }
3238 
3239     /// Array of input sequence classes, beginning with the second
3240     /// glyph position
input_sequence(&self) -> &'a [BigEndian<u16>]3241     pub fn input_sequence(&self) -> &'a [BigEndian<u16>] {
3242         let range = self.shape.input_sequence_byte_range();
3243         self.data.read_array(range).unwrap()
3244     }
3245 
3246     /// Number of glyphs in the lookahead sequence
lookahead_glyph_count(&self) -> u163247     pub fn lookahead_glyph_count(&self) -> u16 {
3248         let range = self.shape.lookahead_glyph_count_byte_range();
3249         self.data.read_at(range.start).unwrap()
3250     }
3251 
3252     /// Array of lookahead-sequence classes
lookahead_sequence(&self) -> &'a [BigEndian<u16>]3253     pub fn lookahead_sequence(&self) -> &'a [BigEndian<u16>] {
3254         let range = self.shape.lookahead_sequence_byte_range();
3255         self.data.read_array(range).unwrap()
3256     }
3257 
3258     /// Number of SequenceLookupRecords
seq_lookup_count(&self) -> u163259     pub fn seq_lookup_count(&self) -> u16 {
3260         let range = self.shape.seq_lookup_count_byte_range();
3261         self.data.read_at(range.start).unwrap()
3262     }
3263 
3264     /// Array of SequenceLookupRecords
seq_lookup_records(&self) -> &'a [SequenceLookupRecord]3265     pub fn seq_lookup_records(&self) -> &'a [SequenceLookupRecord] {
3266         let range = self.shape.seq_lookup_records_byte_range();
3267         self.data.read_array(range).unwrap()
3268     }
3269 }
3270 
3271 #[cfg(feature = "traversal")]
3272 impl<'a> SomeTable<'a> for ChainedClassSequenceRule<'a> {
type_name(&self) -> &str3273     fn type_name(&self) -> &str {
3274         "ChainedClassSequenceRule"
3275     }
get_field(&self, idx: usize) -> Option<Field<'a>>3276     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
3277         match idx {
3278             0usize => Some(Field::new(
3279                 "backtrack_glyph_count",
3280                 self.backtrack_glyph_count(),
3281             )),
3282             1usize => Some(Field::new("backtrack_sequence", self.backtrack_sequence())),
3283             2usize => Some(Field::new("input_glyph_count", self.input_glyph_count())),
3284             3usize => Some(Field::new("input_sequence", self.input_sequence())),
3285             4usize => Some(Field::new(
3286                 "lookahead_glyph_count",
3287                 self.lookahead_glyph_count(),
3288             )),
3289             5usize => Some(Field::new("lookahead_sequence", self.lookahead_sequence())),
3290             6usize => Some(Field::new("seq_lookup_count", self.seq_lookup_count())),
3291             7usize => Some(Field::new(
3292                 "seq_lookup_records",
3293                 traversal::FieldType::array_of_records(
3294                     stringify!(SequenceLookupRecord),
3295                     self.seq_lookup_records(),
3296                     self.offset_data(),
3297                 ),
3298             )),
3299             _ => None,
3300         }
3301     }
3302 }
3303 
3304 #[cfg(feature = "traversal")]
3305 impl<'a> std::fmt::Debug for ChainedClassSequenceRule<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result3306     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3307         (self as &dyn SomeTable<'a>).fmt(f)
3308     }
3309 }
3310 
3311 impl Format<u16> for ChainedSequenceContextFormat3Marker {
3312     const FORMAT: u16 = 3;
3313 }
3314 
3315 /// [Chained Sequence Context Format 3](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#chained-sequence-context-format-3-coverage-based-glyph-contexts)
3316 #[derive(Debug, Clone, Copy)]
3317 #[doc(hidden)]
3318 pub struct ChainedSequenceContextFormat3Marker {
3319     backtrack_coverage_offsets_byte_len: usize,
3320     input_coverage_offsets_byte_len: usize,
3321     lookahead_coverage_offsets_byte_len: usize,
3322     seq_lookup_records_byte_len: usize,
3323 }
3324 
3325 impl ChainedSequenceContextFormat3Marker {
format_byte_range(&self) -> Range<usize>3326     fn format_byte_range(&self) -> Range<usize> {
3327         let start = 0;
3328         start..start + u16::RAW_BYTE_LEN
3329     }
backtrack_glyph_count_byte_range(&self) -> Range<usize>3330     fn backtrack_glyph_count_byte_range(&self) -> Range<usize> {
3331         let start = self.format_byte_range().end;
3332         start..start + u16::RAW_BYTE_LEN
3333     }
backtrack_coverage_offsets_byte_range(&self) -> Range<usize>3334     fn backtrack_coverage_offsets_byte_range(&self) -> Range<usize> {
3335         let start = self.backtrack_glyph_count_byte_range().end;
3336         start..start + self.backtrack_coverage_offsets_byte_len
3337     }
input_glyph_count_byte_range(&self) -> Range<usize>3338     fn input_glyph_count_byte_range(&self) -> Range<usize> {
3339         let start = self.backtrack_coverage_offsets_byte_range().end;
3340         start..start + u16::RAW_BYTE_LEN
3341     }
input_coverage_offsets_byte_range(&self) -> Range<usize>3342     fn input_coverage_offsets_byte_range(&self) -> Range<usize> {
3343         let start = self.input_glyph_count_byte_range().end;
3344         start..start + self.input_coverage_offsets_byte_len
3345     }
lookahead_glyph_count_byte_range(&self) -> Range<usize>3346     fn lookahead_glyph_count_byte_range(&self) -> Range<usize> {
3347         let start = self.input_coverage_offsets_byte_range().end;
3348         start..start + u16::RAW_BYTE_LEN
3349     }
lookahead_coverage_offsets_byte_range(&self) -> Range<usize>3350     fn lookahead_coverage_offsets_byte_range(&self) -> Range<usize> {
3351         let start = self.lookahead_glyph_count_byte_range().end;
3352         start..start + self.lookahead_coverage_offsets_byte_len
3353     }
seq_lookup_count_byte_range(&self) -> Range<usize>3354     fn seq_lookup_count_byte_range(&self) -> Range<usize> {
3355         let start = self.lookahead_coverage_offsets_byte_range().end;
3356         start..start + u16::RAW_BYTE_LEN
3357     }
seq_lookup_records_byte_range(&self) -> Range<usize>3358     fn seq_lookup_records_byte_range(&self) -> Range<usize> {
3359         let start = self.seq_lookup_count_byte_range().end;
3360         start..start + self.seq_lookup_records_byte_len
3361     }
3362 }
3363 
3364 impl<'a> FontRead<'a> for ChainedSequenceContextFormat3<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>3365     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
3366         let mut cursor = data.cursor();
3367         cursor.advance::<u16>();
3368         let backtrack_glyph_count: u16 = cursor.read()?;
3369         let backtrack_coverage_offsets_byte_len =
3370             backtrack_glyph_count as usize * Offset16::RAW_BYTE_LEN;
3371         cursor.advance_by(backtrack_coverage_offsets_byte_len);
3372         let input_glyph_count: u16 = cursor.read()?;
3373         let input_coverage_offsets_byte_len = input_glyph_count as usize * Offset16::RAW_BYTE_LEN;
3374         cursor.advance_by(input_coverage_offsets_byte_len);
3375         let lookahead_glyph_count: u16 = cursor.read()?;
3376         let lookahead_coverage_offsets_byte_len =
3377             lookahead_glyph_count as usize * Offset16::RAW_BYTE_LEN;
3378         cursor.advance_by(lookahead_coverage_offsets_byte_len);
3379         let seq_lookup_count: u16 = cursor.read()?;
3380         let seq_lookup_records_byte_len =
3381             seq_lookup_count as usize * SequenceLookupRecord::RAW_BYTE_LEN;
3382         cursor.advance_by(seq_lookup_records_byte_len);
3383         cursor.finish(ChainedSequenceContextFormat3Marker {
3384             backtrack_coverage_offsets_byte_len,
3385             input_coverage_offsets_byte_len,
3386             lookahead_coverage_offsets_byte_len,
3387             seq_lookup_records_byte_len,
3388         })
3389     }
3390 }
3391 
3392 /// [Chained Sequence Context Format 3](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#chained-sequence-context-format-3-coverage-based-glyph-contexts)
3393 pub type ChainedSequenceContextFormat3<'a> = TableRef<'a, ChainedSequenceContextFormat3Marker>;
3394 
3395 impl<'a> ChainedSequenceContextFormat3<'a> {
3396     /// Format identifier: format = 3
format(&self) -> u163397     pub fn format(&self) -> u16 {
3398         let range = self.shape.format_byte_range();
3399         self.data.read_at(range.start).unwrap()
3400     }
3401 
3402     /// Number of glyphs in the backtrack sequence
backtrack_glyph_count(&self) -> u163403     pub fn backtrack_glyph_count(&self) -> u16 {
3404         let range = self.shape.backtrack_glyph_count_byte_range();
3405         self.data.read_at(range.start).unwrap()
3406     }
3407 
3408     /// Array of offsets to coverage tables for the backtrack sequence
backtrack_coverage_offsets(&self) -> &'a [BigEndian<Offset16>]3409     pub fn backtrack_coverage_offsets(&self) -> &'a [BigEndian<Offset16>] {
3410         let range = self.shape.backtrack_coverage_offsets_byte_range();
3411         self.data.read_array(range).unwrap()
3412     }
3413 
3414     /// A dynamically resolving wrapper for [`backtrack_coverage_offsets`][Self::backtrack_coverage_offsets].
backtrack_coverages(&self) -> ArrayOfOffsets<'a, CoverageTable<'a>, Offset16>3415     pub fn backtrack_coverages(&self) -> ArrayOfOffsets<'a, CoverageTable<'a>, Offset16> {
3416         let data = self.data;
3417         let offsets = self.backtrack_coverage_offsets();
3418         ArrayOfOffsets::new(offsets, data, ())
3419     }
3420 
3421     /// Number of glyphs in the input sequence
input_glyph_count(&self) -> u163422     pub fn input_glyph_count(&self) -> u16 {
3423         let range = self.shape.input_glyph_count_byte_range();
3424         self.data.read_at(range.start).unwrap()
3425     }
3426 
3427     /// Array of offsets to coverage tables for the input sequence
input_coverage_offsets(&self) -> &'a [BigEndian<Offset16>]3428     pub fn input_coverage_offsets(&self) -> &'a [BigEndian<Offset16>] {
3429         let range = self.shape.input_coverage_offsets_byte_range();
3430         self.data.read_array(range).unwrap()
3431     }
3432 
3433     /// A dynamically resolving wrapper for [`input_coverage_offsets`][Self::input_coverage_offsets].
input_coverages(&self) -> ArrayOfOffsets<'a, CoverageTable<'a>, Offset16>3434     pub fn input_coverages(&self) -> ArrayOfOffsets<'a, CoverageTable<'a>, Offset16> {
3435         let data = self.data;
3436         let offsets = self.input_coverage_offsets();
3437         ArrayOfOffsets::new(offsets, data, ())
3438     }
3439 
3440     /// Number of glyphs in the lookahead sequence
lookahead_glyph_count(&self) -> u163441     pub fn lookahead_glyph_count(&self) -> u16 {
3442         let range = self.shape.lookahead_glyph_count_byte_range();
3443         self.data.read_at(range.start).unwrap()
3444     }
3445 
3446     /// Array of offsets to coverage tables for the lookahead sequence
lookahead_coverage_offsets(&self) -> &'a [BigEndian<Offset16>]3447     pub fn lookahead_coverage_offsets(&self) -> &'a [BigEndian<Offset16>] {
3448         let range = self.shape.lookahead_coverage_offsets_byte_range();
3449         self.data.read_array(range).unwrap()
3450     }
3451 
3452     /// A dynamically resolving wrapper for [`lookahead_coverage_offsets`][Self::lookahead_coverage_offsets].
lookahead_coverages(&self) -> ArrayOfOffsets<'a, CoverageTable<'a>, Offset16>3453     pub fn lookahead_coverages(&self) -> ArrayOfOffsets<'a, CoverageTable<'a>, Offset16> {
3454         let data = self.data;
3455         let offsets = self.lookahead_coverage_offsets();
3456         ArrayOfOffsets::new(offsets, data, ())
3457     }
3458 
3459     /// Number of SequenceLookupRecords
seq_lookup_count(&self) -> u163460     pub fn seq_lookup_count(&self) -> u16 {
3461         let range = self.shape.seq_lookup_count_byte_range();
3462         self.data.read_at(range.start).unwrap()
3463     }
3464 
3465     /// Array of SequenceLookupRecords
seq_lookup_records(&self) -> &'a [SequenceLookupRecord]3466     pub fn seq_lookup_records(&self) -> &'a [SequenceLookupRecord] {
3467         let range = self.shape.seq_lookup_records_byte_range();
3468         self.data.read_array(range).unwrap()
3469     }
3470 }
3471 
3472 #[cfg(feature = "traversal")]
3473 impl<'a> SomeTable<'a> for ChainedSequenceContextFormat3<'a> {
type_name(&self) -> &str3474     fn type_name(&self) -> &str {
3475         "ChainedSequenceContextFormat3"
3476     }
get_field(&self, idx: usize) -> Option<Field<'a>>3477     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
3478         match idx {
3479             0usize => Some(Field::new("format", self.format())),
3480             1usize => Some(Field::new(
3481                 "backtrack_glyph_count",
3482                 self.backtrack_glyph_count(),
3483             )),
3484             2usize => Some({
3485                 let data = self.data;
3486                 Field::new(
3487                     "backtrack_coverage_offsets",
3488                     FieldType::array_of_offsets(
3489                         better_type_name::<CoverageTable>(),
3490                         self.backtrack_coverage_offsets(),
3491                         move |off| {
3492                             let target = off.get().resolve::<CoverageTable>(data);
3493                             FieldType::offset(off.get(), target)
3494                         },
3495                     ),
3496                 )
3497             }),
3498             3usize => Some(Field::new("input_glyph_count", self.input_glyph_count())),
3499             4usize => Some({
3500                 let data = self.data;
3501                 Field::new(
3502                     "input_coverage_offsets",
3503                     FieldType::array_of_offsets(
3504                         better_type_name::<CoverageTable>(),
3505                         self.input_coverage_offsets(),
3506                         move |off| {
3507                             let target = off.get().resolve::<CoverageTable>(data);
3508                             FieldType::offset(off.get(), target)
3509                         },
3510                     ),
3511                 )
3512             }),
3513             5usize => Some(Field::new(
3514                 "lookahead_glyph_count",
3515                 self.lookahead_glyph_count(),
3516             )),
3517             6usize => Some({
3518                 let data = self.data;
3519                 Field::new(
3520                     "lookahead_coverage_offsets",
3521                     FieldType::array_of_offsets(
3522                         better_type_name::<CoverageTable>(),
3523                         self.lookahead_coverage_offsets(),
3524                         move |off| {
3525                             let target = off.get().resolve::<CoverageTable>(data);
3526                             FieldType::offset(off.get(), target)
3527                         },
3528                     ),
3529                 )
3530             }),
3531             7usize => Some(Field::new("seq_lookup_count", self.seq_lookup_count())),
3532             8usize => Some(Field::new(
3533                 "seq_lookup_records",
3534                 traversal::FieldType::array_of_records(
3535                     stringify!(SequenceLookupRecord),
3536                     self.seq_lookup_records(),
3537                     self.offset_data(),
3538                 ),
3539             )),
3540             _ => None,
3541         }
3542     }
3543 }
3544 
3545 #[cfg(feature = "traversal")]
3546 impl<'a> std::fmt::Debug for ChainedSequenceContextFormat3<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result3547     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3548         (self as &dyn SomeTable<'a>).fmt(f)
3549     }
3550 }
3551 
3552 #[derive(Clone)]
3553 pub enum ChainedSequenceContext<'a> {
3554     Format1(ChainedSequenceContextFormat1<'a>),
3555     Format2(ChainedSequenceContextFormat2<'a>),
3556     Format3(ChainedSequenceContextFormat3<'a>),
3557 }
3558 
3559 impl<'a> ChainedSequenceContext<'a> {
3560     /// Format identifier: format = 1
format(&self) -> u163561     pub fn format(&self) -> u16 {
3562         match self {
3563             Self::Format1(item) => item.format(),
3564             Self::Format2(item) => item.format(),
3565             Self::Format3(item) => item.format(),
3566         }
3567     }
3568 }
3569 
3570 impl<'a> FontRead<'a> for ChainedSequenceContext<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>3571     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
3572         let format: u16 = data.read_at(0usize)?;
3573         match format {
3574             ChainedSequenceContextFormat1Marker::FORMAT => Ok(Self::Format1(FontRead::read(data)?)),
3575             ChainedSequenceContextFormat2Marker::FORMAT => Ok(Self::Format2(FontRead::read(data)?)),
3576             ChainedSequenceContextFormat3Marker::FORMAT => Ok(Self::Format3(FontRead::read(data)?)),
3577             other => Err(ReadError::InvalidFormat(other.into())),
3578         }
3579     }
3580 }
3581 
3582 #[cfg(feature = "traversal")]
3583 impl<'a> ChainedSequenceContext<'a> {
dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a>3584     fn dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a> {
3585         match self {
3586             Self::Format1(table) => table,
3587             Self::Format2(table) => table,
3588             Self::Format3(table) => table,
3589         }
3590     }
3591 }
3592 
3593 #[cfg(feature = "traversal")]
3594 impl<'a> std::fmt::Debug for ChainedSequenceContext<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result3595     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3596         self.dyn_inner().fmt(f)
3597     }
3598 }
3599 
3600 #[cfg(feature = "traversal")]
3601 impl<'a> SomeTable<'a> for ChainedSequenceContext<'a> {
type_name(&self) -> &str3602     fn type_name(&self) -> &str {
3603         self.dyn_inner().type_name()
3604     }
get_field(&self, idx: usize) -> Option<Field<'a>>3605     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
3606         self.dyn_inner().get_field(idx)
3607     }
3608 }
3609 
3610 /// [Device](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#device-and-variationindex-tables)
3611 /// delta formats
3612 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash, PartialOrd, Ord)]
3613 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3614 #[repr(u16)]
3615 #[allow(clippy::manual_non_exhaustive)]
3616 pub enum DeltaFormat {
3617     /// Signed 2-bit value, 8 values per uint16
3618     #[default]
3619     Local2BitDeltas = 0x0001,
3620     /// Signed 4-bit value, 4 values per uint16
3621     Local4BitDeltas = 0x0002,
3622     /// Signed 8-bit value, 2 values per uint16
3623     Local8BitDeltas = 0x0003,
3624     /// VariationIndex table, contains a delta-set index pair.
3625     VariationIndex = 0x8000,
3626     #[doc(hidden)]
3627     /// If font data is malformed we will map unknown values to this variant
3628     Unknown,
3629 }
3630 
3631 impl DeltaFormat {
3632     /// Create from a raw scalar.
3633     ///
3634     /// This will never fail; unknown values will be mapped to the `Unknown` variant
new(raw: u16) -> Self3635     pub fn new(raw: u16) -> Self {
3636         match raw {
3637             0x0001 => Self::Local2BitDeltas,
3638             0x0002 => Self::Local4BitDeltas,
3639             0x0003 => Self::Local8BitDeltas,
3640             0x8000 => Self::VariationIndex,
3641             _ => Self::Unknown,
3642         }
3643     }
3644 }
3645 
3646 impl font_types::Scalar for DeltaFormat {
3647     type Raw = <u16 as font_types::Scalar>::Raw;
to_raw(self) -> Self::Raw3648     fn to_raw(self) -> Self::Raw {
3649         (self as u16).to_raw()
3650     }
from_raw(raw: Self::Raw) -> Self3651     fn from_raw(raw: Self::Raw) -> Self {
3652         let t = <u16>::from_raw(raw);
3653         Self::new(t)
3654     }
3655 }
3656 
3657 #[cfg(feature = "traversal")]
3658 impl<'a> From<DeltaFormat> for FieldType<'a> {
from(src: DeltaFormat) -> FieldType<'a>3659     fn from(src: DeltaFormat) -> FieldType<'a> {
3660         (src as u16).into()
3661     }
3662 }
3663 
3664 /// [Device Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#device-and-variationindex-tables)
3665 #[derive(Debug, Clone, Copy)]
3666 #[doc(hidden)]
3667 pub struct DeviceMarker {
3668     delta_value_byte_len: usize,
3669 }
3670 
3671 impl DeviceMarker {
start_size_byte_range(&self) -> Range<usize>3672     fn start_size_byte_range(&self) -> Range<usize> {
3673         let start = 0;
3674         start..start + u16::RAW_BYTE_LEN
3675     }
end_size_byte_range(&self) -> Range<usize>3676     fn end_size_byte_range(&self) -> Range<usize> {
3677         let start = self.start_size_byte_range().end;
3678         start..start + u16::RAW_BYTE_LEN
3679     }
delta_format_byte_range(&self) -> Range<usize>3680     fn delta_format_byte_range(&self) -> Range<usize> {
3681         let start = self.end_size_byte_range().end;
3682         start..start + DeltaFormat::RAW_BYTE_LEN
3683     }
delta_value_byte_range(&self) -> Range<usize>3684     fn delta_value_byte_range(&self) -> Range<usize> {
3685         let start = self.delta_format_byte_range().end;
3686         start..start + self.delta_value_byte_len
3687     }
3688 }
3689 
3690 impl<'a> FontRead<'a> for Device<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>3691     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
3692         let mut cursor = data.cursor();
3693         let start_size: u16 = cursor.read()?;
3694         let end_size: u16 = cursor.read()?;
3695         let delta_format: DeltaFormat = cursor.read()?;
3696         let delta_value_byte_len =
3697             DeltaFormat::value_count(delta_format, start_size, end_size) * u16::RAW_BYTE_LEN;
3698         cursor.advance_by(delta_value_byte_len);
3699         cursor.finish(DeviceMarker {
3700             delta_value_byte_len,
3701         })
3702     }
3703 }
3704 
3705 /// [Device Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#device-and-variationindex-tables)
3706 pub type Device<'a> = TableRef<'a, DeviceMarker>;
3707 
3708 impl<'a> Device<'a> {
3709     /// Smallest size to correct, in ppem
start_size(&self) -> u163710     pub fn start_size(&self) -> u16 {
3711         let range = self.shape.start_size_byte_range();
3712         self.data.read_at(range.start).unwrap()
3713     }
3714 
3715     /// Largest size to correct, in ppem
end_size(&self) -> u163716     pub fn end_size(&self) -> u16 {
3717         let range = self.shape.end_size_byte_range();
3718         self.data.read_at(range.start).unwrap()
3719     }
3720 
3721     /// Format of deltaValue array data: 0x0001, 0x0002, or 0x0003
delta_format(&self) -> DeltaFormat3722     pub fn delta_format(&self) -> DeltaFormat {
3723         let range = self.shape.delta_format_byte_range();
3724         self.data.read_at(range.start).unwrap()
3725     }
3726 
3727     /// Array of compressed data
delta_value(&self) -> &'a [BigEndian<u16>]3728     pub fn delta_value(&self) -> &'a [BigEndian<u16>] {
3729         let range = self.shape.delta_value_byte_range();
3730         self.data.read_array(range).unwrap()
3731     }
3732 }
3733 
3734 #[cfg(feature = "traversal")]
3735 impl<'a> SomeTable<'a> for Device<'a> {
type_name(&self) -> &str3736     fn type_name(&self) -> &str {
3737         "Device"
3738     }
get_field(&self, idx: usize) -> Option<Field<'a>>3739     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
3740         match idx {
3741             0usize => Some(Field::new("start_size", self.start_size())),
3742             1usize => Some(Field::new("end_size", self.end_size())),
3743             2usize => Some(Field::new("delta_format", self.delta_format())),
3744             3usize => Some(Field::new("delta_value", self.delta_value())),
3745             _ => None,
3746         }
3747     }
3748 }
3749 
3750 #[cfg(feature = "traversal")]
3751 impl<'a> std::fmt::Debug for Device<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result3752     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3753         (self as &dyn SomeTable<'a>).fmt(f)
3754     }
3755 }
3756 
3757 /// Variation index table
3758 #[derive(Debug, Clone, Copy)]
3759 #[doc(hidden)]
3760 pub struct VariationIndexMarker {}
3761 
3762 impl VariationIndexMarker {
delta_set_outer_index_byte_range(&self) -> Range<usize>3763     fn delta_set_outer_index_byte_range(&self) -> Range<usize> {
3764         let start = 0;
3765         start..start + u16::RAW_BYTE_LEN
3766     }
delta_set_inner_index_byte_range(&self) -> Range<usize>3767     fn delta_set_inner_index_byte_range(&self) -> Range<usize> {
3768         let start = self.delta_set_outer_index_byte_range().end;
3769         start..start + u16::RAW_BYTE_LEN
3770     }
delta_format_byte_range(&self) -> Range<usize>3771     fn delta_format_byte_range(&self) -> Range<usize> {
3772         let start = self.delta_set_inner_index_byte_range().end;
3773         start..start + DeltaFormat::RAW_BYTE_LEN
3774     }
3775 }
3776 
3777 impl<'a> FontRead<'a> for VariationIndex<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>3778     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
3779         let mut cursor = data.cursor();
3780         cursor.advance::<u16>();
3781         cursor.advance::<u16>();
3782         cursor.advance::<DeltaFormat>();
3783         cursor.finish(VariationIndexMarker {})
3784     }
3785 }
3786 
3787 /// Variation index table
3788 pub type VariationIndex<'a> = TableRef<'a, VariationIndexMarker>;
3789 
3790 impl<'a> VariationIndex<'a> {
3791     /// A delta-set outer index — used to select an item variation
3792     /// data subtable within the item variation store.
delta_set_outer_index(&self) -> u163793     pub fn delta_set_outer_index(&self) -> u16 {
3794         let range = self.shape.delta_set_outer_index_byte_range();
3795         self.data.read_at(range.start).unwrap()
3796     }
3797 
3798     /// A delta-set inner index — used to select a delta-set row
3799     /// within an item variation data subtable.
delta_set_inner_index(&self) -> u163800     pub fn delta_set_inner_index(&self) -> u16 {
3801         let range = self.shape.delta_set_inner_index_byte_range();
3802         self.data.read_at(range.start).unwrap()
3803     }
3804 
3805     /// Format, = 0x8000
delta_format(&self) -> DeltaFormat3806     pub fn delta_format(&self) -> DeltaFormat {
3807         let range = self.shape.delta_format_byte_range();
3808         self.data.read_at(range.start).unwrap()
3809     }
3810 }
3811 
3812 #[cfg(feature = "traversal")]
3813 impl<'a> SomeTable<'a> for VariationIndex<'a> {
type_name(&self) -> &str3814     fn type_name(&self) -> &str {
3815         "VariationIndex"
3816     }
get_field(&self, idx: usize) -> Option<Field<'a>>3817     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
3818         match idx {
3819             0usize => Some(Field::new(
3820                 "delta_set_outer_index",
3821                 self.delta_set_outer_index(),
3822             )),
3823             1usize => Some(Field::new(
3824                 "delta_set_inner_index",
3825                 self.delta_set_inner_index(),
3826             )),
3827             2usize => Some(Field::new("delta_format", self.delta_format())),
3828             _ => None,
3829         }
3830     }
3831 }
3832 
3833 #[cfg(feature = "traversal")]
3834 impl<'a> std::fmt::Debug for VariationIndex<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result3835     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3836         (self as &dyn SomeTable<'a>).fmt(f)
3837     }
3838 }
3839 
3840 /// Either a [Device] table (in a non-variable font) or a [VariationIndex] table (in a variable font)
3841 #[derive(Clone)]
3842 pub enum DeviceOrVariationIndex<'a> {
3843     Device(Device<'a>),
3844     VariationIndex(VariationIndex<'a>),
3845 }
3846 
3847 impl<'a> FontRead<'a> for DeviceOrVariationIndex<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>3848     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
3849         let format: DeltaFormat = data.read_at(4usize)?;
3850 
3851         #[allow(clippy::redundant_guards)]
3852         match format {
3853             format if format != DeltaFormat::VariationIndex => {
3854                 Ok(Self::Device(FontRead::read(data)?))
3855             }
3856             format if format == DeltaFormat::VariationIndex => {
3857                 Ok(Self::VariationIndex(FontRead::read(data)?))
3858             }
3859             other => Err(ReadError::InvalidFormat(other.into())),
3860         }
3861     }
3862 }
3863 
3864 #[cfg(feature = "traversal")]
3865 impl<'a> DeviceOrVariationIndex<'a> {
dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a>3866     fn dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a> {
3867         match self {
3868             Self::Device(table) => table,
3869             Self::VariationIndex(table) => table,
3870         }
3871     }
3872 }
3873 
3874 #[cfg(feature = "traversal")]
3875 impl<'a> std::fmt::Debug for DeviceOrVariationIndex<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result3876     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3877         self.dyn_inner().fmt(f)
3878     }
3879 }
3880 
3881 #[cfg(feature = "traversal")]
3882 impl<'a> SomeTable<'a> for DeviceOrVariationIndex<'a> {
type_name(&self) -> &str3883     fn type_name(&self) -> &str {
3884         self.dyn_inner().type_name()
3885     }
get_field(&self, idx: usize) -> Option<Field<'a>>3886     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
3887         self.dyn_inner().get_field(idx)
3888     }
3889 }
3890 
3891 /// [FeatureVariations Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#featurevariations-table)
3892 #[derive(Debug, Clone, Copy)]
3893 #[doc(hidden)]
3894 pub struct FeatureVariationsMarker {
3895     feature_variation_records_byte_len: usize,
3896 }
3897 
3898 impl FeatureVariationsMarker {
version_byte_range(&self) -> Range<usize>3899     fn version_byte_range(&self) -> Range<usize> {
3900         let start = 0;
3901         start..start + MajorMinor::RAW_BYTE_LEN
3902     }
feature_variation_record_count_byte_range(&self) -> Range<usize>3903     fn feature_variation_record_count_byte_range(&self) -> Range<usize> {
3904         let start = self.version_byte_range().end;
3905         start..start + u32::RAW_BYTE_LEN
3906     }
feature_variation_records_byte_range(&self) -> Range<usize>3907     fn feature_variation_records_byte_range(&self) -> Range<usize> {
3908         let start = self.feature_variation_record_count_byte_range().end;
3909         start..start + self.feature_variation_records_byte_len
3910     }
3911 }
3912 
3913 impl<'a> FontRead<'a> for FeatureVariations<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>3914     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
3915         let mut cursor = data.cursor();
3916         cursor.advance::<MajorMinor>();
3917         let feature_variation_record_count: u32 = cursor.read()?;
3918         let feature_variation_records_byte_len =
3919             feature_variation_record_count as usize * FeatureVariationRecord::RAW_BYTE_LEN;
3920         cursor.advance_by(feature_variation_records_byte_len);
3921         cursor.finish(FeatureVariationsMarker {
3922             feature_variation_records_byte_len,
3923         })
3924     }
3925 }
3926 
3927 /// [FeatureVariations Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#featurevariations-table)
3928 pub type FeatureVariations<'a> = TableRef<'a, FeatureVariationsMarker>;
3929 
3930 impl<'a> FeatureVariations<'a> {
version(&self) -> MajorMinor3931     pub fn version(&self) -> MajorMinor {
3932         let range = self.shape.version_byte_range();
3933         self.data.read_at(range.start).unwrap()
3934     }
3935 
3936     /// Number of feature variation records.
feature_variation_record_count(&self) -> u323937     pub fn feature_variation_record_count(&self) -> u32 {
3938         let range = self.shape.feature_variation_record_count_byte_range();
3939         self.data.read_at(range.start).unwrap()
3940     }
3941 
3942     /// Array of feature variation records.
feature_variation_records(&self) -> &'a [FeatureVariationRecord]3943     pub fn feature_variation_records(&self) -> &'a [FeatureVariationRecord] {
3944         let range = self.shape.feature_variation_records_byte_range();
3945         self.data.read_array(range).unwrap()
3946     }
3947 }
3948 
3949 #[cfg(feature = "traversal")]
3950 impl<'a> SomeTable<'a> for FeatureVariations<'a> {
type_name(&self) -> &str3951     fn type_name(&self) -> &str {
3952         "FeatureVariations"
3953     }
get_field(&self, idx: usize) -> Option<Field<'a>>3954     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
3955         match idx {
3956             0usize => Some(Field::new("version", self.version())),
3957             1usize => Some(Field::new(
3958                 "feature_variation_record_count",
3959                 self.feature_variation_record_count(),
3960             )),
3961             2usize => Some(Field::new(
3962                 "feature_variation_records",
3963                 traversal::FieldType::array_of_records(
3964                     stringify!(FeatureVariationRecord),
3965                     self.feature_variation_records(),
3966                     self.offset_data(),
3967                 ),
3968             )),
3969             _ => None,
3970         }
3971     }
3972 }
3973 
3974 #[cfg(feature = "traversal")]
3975 impl<'a> std::fmt::Debug for FeatureVariations<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result3976     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3977         (self as &dyn SomeTable<'a>).fmt(f)
3978     }
3979 }
3980 
3981 /// Part of [FeatureVariations]
3982 #[derive(Clone, Debug)]
3983 #[repr(C)]
3984 #[repr(packed)]
3985 pub struct FeatureVariationRecord {
3986     /// Offset to a condition set table, from beginning of
3987     /// FeatureVariations table.
3988     pub condition_set_offset: BigEndian<Nullable<Offset32>>,
3989     /// Offset to a feature table substitution table, from beginning of
3990     /// the FeatureVariations table.
3991     pub feature_table_substitution_offset: BigEndian<Nullable<Offset32>>,
3992 }
3993 
3994 impl FeatureVariationRecord {
3995     /// Offset to a condition set table, from beginning of
3996     /// FeatureVariations table.
condition_set_offset(&self) -> Nullable<Offset32>3997     pub fn condition_set_offset(&self) -> Nullable<Offset32> {
3998         self.condition_set_offset.get()
3999     }
4000 
4001     /// Offset to a condition set table, from beginning of
4002     /// FeatureVariations table.
4003     ///
4004     /// The `data` argument should be retrieved from the parent table
4005     /// By calling its `offset_data` method.
condition_set<'a>( &self, data: FontData<'a>, ) -> Option<Result<ConditionSet<'a>, ReadError>>4006     pub fn condition_set<'a>(
4007         &self,
4008         data: FontData<'a>,
4009     ) -> Option<Result<ConditionSet<'a>, ReadError>> {
4010         self.condition_set_offset().resolve(data)
4011     }
4012 
4013     /// Offset to a feature table substitution table, from beginning of
4014     /// the FeatureVariations table.
feature_table_substitution_offset(&self) -> Nullable<Offset32>4015     pub fn feature_table_substitution_offset(&self) -> Nullable<Offset32> {
4016         self.feature_table_substitution_offset.get()
4017     }
4018 
4019     /// Offset to a feature table substitution table, from beginning of
4020     /// the FeatureVariations table.
4021     ///
4022     /// The `data` argument should be retrieved from the parent table
4023     /// By calling its `offset_data` method.
feature_table_substitution<'a>( &self, data: FontData<'a>, ) -> Option<Result<FeatureTableSubstitution<'a>, ReadError>>4024     pub fn feature_table_substitution<'a>(
4025         &self,
4026         data: FontData<'a>,
4027     ) -> Option<Result<FeatureTableSubstitution<'a>, ReadError>> {
4028         self.feature_table_substitution_offset().resolve(data)
4029     }
4030 }
4031 
4032 impl FixedSize for FeatureVariationRecord {
4033     const RAW_BYTE_LEN: usize = Offset32::RAW_BYTE_LEN + Offset32::RAW_BYTE_LEN;
4034 }
4035 
4036 impl sealed::Sealed for FeatureVariationRecord {}
4037 
4038 /// SAFETY: see the [`FromBytes`] trait documentation.
4039 unsafe impl FromBytes for FeatureVariationRecord {
this_trait_should_only_be_implemented_in_generated_code()4040     fn this_trait_should_only_be_implemented_in_generated_code() {}
4041 }
4042 
4043 #[cfg(feature = "traversal")]
4044 impl<'a> SomeRecord<'a> for FeatureVariationRecord {
traverse(self, data: FontData<'a>) -> RecordResolver<'a>4045     fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
4046         RecordResolver {
4047             name: "FeatureVariationRecord",
4048             get_field: Box::new(move |idx, _data| match idx {
4049                 0usize => Some(Field::new(
4050                     "condition_set_offset",
4051                     FieldType::offset(self.condition_set_offset(), self.condition_set(_data)),
4052                 )),
4053                 1usize => Some(Field::new(
4054                     "feature_table_substitution_offset",
4055                     FieldType::offset(
4056                         self.feature_table_substitution_offset(),
4057                         self.feature_table_substitution(_data),
4058                     ),
4059                 )),
4060                 _ => None,
4061             }),
4062             data,
4063         }
4064     }
4065 }
4066 
4067 /// [ConditionSet Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#conditionset-table)
4068 #[derive(Debug, Clone, Copy)]
4069 #[doc(hidden)]
4070 pub struct ConditionSetMarker {
4071     condition_offsets_byte_len: usize,
4072 }
4073 
4074 impl ConditionSetMarker {
condition_count_byte_range(&self) -> Range<usize>4075     fn condition_count_byte_range(&self) -> Range<usize> {
4076         let start = 0;
4077         start..start + u16::RAW_BYTE_LEN
4078     }
condition_offsets_byte_range(&self) -> Range<usize>4079     fn condition_offsets_byte_range(&self) -> Range<usize> {
4080         let start = self.condition_count_byte_range().end;
4081         start..start + self.condition_offsets_byte_len
4082     }
4083 }
4084 
4085 impl<'a> FontRead<'a> for ConditionSet<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>4086     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
4087         let mut cursor = data.cursor();
4088         let condition_count: u16 = cursor.read()?;
4089         let condition_offsets_byte_len = condition_count as usize * Offset32::RAW_BYTE_LEN;
4090         cursor.advance_by(condition_offsets_byte_len);
4091         cursor.finish(ConditionSetMarker {
4092             condition_offsets_byte_len,
4093         })
4094     }
4095 }
4096 
4097 /// [ConditionSet Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#conditionset-table)
4098 pub type ConditionSet<'a> = TableRef<'a, ConditionSetMarker>;
4099 
4100 impl<'a> ConditionSet<'a> {
4101     /// Number of conditions for this condition set.
condition_count(&self) -> u164102     pub fn condition_count(&self) -> u16 {
4103         let range = self.shape.condition_count_byte_range();
4104         self.data.read_at(range.start).unwrap()
4105     }
4106 
4107     /// Array of offsets to condition tables, from beginning of the
4108     /// ConditionSet table.
condition_offsets(&self) -> &'a [BigEndian<Offset32>]4109     pub fn condition_offsets(&self) -> &'a [BigEndian<Offset32>] {
4110         let range = self.shape.condition_offsets_byte_range();
4111         self.data.read_array(range).unwrap()
4112     }
4113 
4114     /// A dynamically resolving wrapper for [`condition_offsets`][Self::condition_offsets].
conditions(&self) -> ArrayOfOffsets<'a, ConditionFormat1<'a>, Offset32>4115     pub fn conditions(&self) -> ArrayOfOffsets<'a, ConditionFormat1<'a>, Offset32> {
4116         let data = self.data;
4117         let offsets = self.condition_offsets();
4118         ArrayOfOffsets::new(offsets, data, ())
4119     }
4120 }
4121 
4122 #[cfg(feature = "traversal")]
4123 impl<'a> SomeTable<'a> for ConditionSet<'a> {
type_name(&self) -> &str4124     fn type_name(&self) -> &str {
4125         "ConditionSet"
4126     }
get_field(&self, idx: usize) -> Option<Field<'a>>4127     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
4128         match idx {
4129             0usize => Some(Field::new("condition_count", self.condition_count())),
4130             1usize => Some({
4131                 let data = self.data;
4132                 Field::new(
4133                     "condition_offsets",
4134                     FieldType::array_of_offsets(
4135                         better_type_name::<ConditionFormat1>(),
4136                         self.condition_offsets(),
4137                         move |off| {
4138                             let target = off.get().resolve::<ConditionFormat1>(data);
4139                             FieldType::offset(off.get(), target)
4140                         },
4141                     ),
4142                 )
4143             }),
4144             _ => None,
4145         }
4146     }
4147 }
4148 
4149 #[cfg(feature = "traversal")]
4150 impl<'a> std::fmt::Debug for ConditionSet<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result4151     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4152         (self as &dyn SomeTable<'a>).fmt(f)
4153     }
4154 }
4155 
4156 impl Format<u16> for ConditionFormat1Marker {
4157     const FORMAT: u16 = 1;
4158 }
4159 
4160 /// [Condition Table Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#condition-table-format-1-font-variation-axis-range): Font Variation Axis Range
4161 #[derive(Debug, Clone, Copy)]
4162 #[doc(hidden)]
4163 pub struct ConditionFormat1Marker {}
4164 
4165 impl ConditionFormat1Marker {
format_byte_range(&self) -> Range<usize>4166     fn format_byte_range(&self) -> Range<usize> {
4167         let start = 0;
4168         start..start + u16::RAW_BYTE_LEN
4169     }
axis_index_byte_range(&self) -> Range<usize>4170     fn axis_index_byte_range(&self) -> Range<usize> {
4171         let start = self.format_byte_range().end;
4172         start..start + u16::RAW_BYTE_LEN
4173     }
filter_range_min_value_byte_range(&self) -> Range<usize>4174     fn filter_range_min_value_byte_range(&self) -> Range<usize> {
4175         let start = self.axis_index_byte_range().end;
4176         start..start + F2Dot14::RAW_BYTE_LEN
4177     }
filter_range_max_value_byte_range(&self) -> Range<usize>4178     fn filter_range_max_value_byte_range(&self) -> Range<usize> {
4179         let start = self.filter_range_min_value_byte_range().end;
4180         start..start + F2Dot14::RAW_BYTE_LEN
4181     }
4182 }
4183 
4184 impl<'a> FontRead<'a> for ConditionFormat1<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>4185     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
4186         let mut cursor = data.cursor();
4187         cursor.advance::<u16>();
4188         cursor.advance::<u16>();
4189         cursor.advance::<F2Dot14>();
4190         cursor.advance::<F2Dot14>();
4191         cursor.finish(ConditionFormat1Marker {})
4192     }
4193 }
4194 
4195 /// [Condition Table Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#condition-table-format-1-font-variation-axis-range): Font Variation Axis Range
4196 pub type ConditionFormat1<'a> = TableRef<'a, ConditionFormat1Marker>;
4197 
4198 impl<'a> ConditionFormat1<'a> {
4199     /// Format, = 1
format(&self) -> u164200     pub fn format(&self) -> u16 {
4201         let range = self.shape.format_byte_range();
4202         self.data.read_at(range.start).unwrap()
4203     }
4204 
4205     /// Index (zero-based) for the variation axis within the 'fvar'
4206     /// table.
axis_index(&self) -> u164207     pub fn axis_index(&self) -> u16 {
4208         let range = self.shape.axis_index_byte_range();
4209         self.data.read_at(range.start).unwrap()
4210     }
4211 
4212     /// Minimum value of the font variation instances that satisfy this
4213     /// condition.
filter_range_min_value(&self) -> F2Dot144214     pub fn filter_range_min_value(&self) -> F2Dot14 {
4215         let range = self.shape.filter_range_min_value_byte_range();
4216         self.data.read_at(range.start).unwrap()
4217     }
4218 
4219     /// Maximum value of the font variation instances that satisfy this
4220     /// condition.
filter_range_max_value(&self) -> F2Dot144221     pub fn filter_range_max_value(&self) -> F2Dot14 {
4222         let range = self.shape.filter_range_max_value_byte_range();
4223         self.data.read_at(range.start).unwrap()
4224     }
4225 }
4226 
4227 #[cfg(feature = "traversal")]
4228 impl<'a> SomeTable<'a> for ConditionFormat1<'a> {
type_name(&self) -> &str4229     fn type_name(&self) -> &str {
4230         "ConditionFormat1"
4231     }
get_field(&self, idx: usize) -> Option<Field<'a>>4232     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
4233         match idx {
4234             0usize => Some(Field::new("format", self.format())),
4235             1usize => Some(Field::new("axis_index", self.axis_index())),
4236             2usize => Some(Field::new(
4237                 "filter_range_min_value",
4238                 self.filter_range_min_value(),
4239             )),
4240             3usize => Some(Field::new(
4241                 "filter_range_max_value",
4242                 self.filter_range_max_value(),
4243             )),
4244             _ => None,
4245         }
4246     }
4247 }
4248 
4249 #[cfg(feature = "traversal")]
4250 impl<'a> std::fmt::Debug for ConditionFormat1<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result4251     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4252         (self as &dyn SomeTable<'a>).fmt(f)
4253     }
4254 }
4255 
4256 /// [FeatureTableSubstitution Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#featuretablesubstitution-table)
4257 #[derive(Debug, Clone, Copy)]
4258 #[doc(hidden)]
4259 pub struct FeatureTableSubstitutionMarker {
4260     substitutions_byte_len: usize,
4261 }
4262 
4263 impl FeatureTableSubstitutionMarker {
version_byte_range(&self) -> Range<usize>4264     fn version_byte_range(&self) -> Range<usize> {
4265         let start = 0;
4266         start..start + MajorMinor::RAW_BYTE_LEN
4267     }
substitution_count_byte_range(&self) -> Range<usize>4268     fn substitution_count_byte_range(&self) -> Range<usize> {
4269         let start = self.version_byte_range().end;
4270         start..start + u16::RAW_BYTE_LEN
4271     }
substitutions_byte_range(&self) -> Range<usize>4272     fn substitutions_byte_range(&self) -> Range<usize> {
4273         let start = self.substitution_count_byte_range().end;
4274         start..start + self.substitutions_byte_len
4275     }
4276 }
4277 
4278 impl<'a> FontRead<'a> for FeatureTableSubstitution<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>4279     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
4280         let mut cursor = data.cursor();
4281         cursor.advance::<MajorMinor>();
4282         let substitution_count: u16 = cursor.read()?;
4283         let substitutions_byte_len =
4284             substitution_count as usize * FeatureTableSubstitutionRecord::RAW_BYTE_LEN;
4285         cursor.advance_by(substitutions_byte_len);
4286         cursor.finish(FeatureTableSubstitutionMarker {
4287             substitutions_byte_len,
4288         })
4289     }
4290 }
4291 
4292 /// [FeatureTableSubstitution Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#featuretablesubstitution-table)
4293 pub type FeatureTableSubstitution<'a> = TableRef<'a, FeatureTableSubstitutionMarker>;
4294 
4295 impl<'a> FeatureTableSubstitution<'a> {
4296     /// Major & minor version of the table: (1, 0)
version(&self) -> MajorMinor4297     pub fn version(&self) -> MajorMinor {
4298         let range = self.shape.version_byte_range();
4299         self.data.read_at(range.start).unwrap()
4300     }
4301 
4302     /// Number of feature table substitution records.
substitution_count(&self) -> u164303     pub fn substitution_count(&self) -> u16 {
4304         let range = self.shape.substitution_count_byte_range();
4305         self.data.read_at(range.start).unwrap()
4306     }
4307 
4308     /// Array of feature table substitution records.
substitutions(&self) -> &'a [FeatureTableSubstitutionRecord]4309     pub fn substitutions(&self) -> &'a [FeatureTableSubstitutionRecord] {
4310         let range = self.shape.substitutions_byte_range();
4311         self.data.read_array(range).unwrap()
4312     }
4313 }
4314 
4315 #[cfg(feature = "traversal")]
4316 impl<'a> SomeTable<'a> for FeatureTableSubstitution<'a> {
type_name(&self) -> &str4317     fn type_name(&self) -> &str {
4318         "FeatureTableSubstitution"
4319     }
get_field(&self, idx: usize) -> Option<Field<'a>>4320     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
4321         match idx {
4322             0usize => Some(Field::new("version", self.version())),
4323             1usize => Some(Field::new("substitution_count", self.substitution_count())),
4324             2usize => Some(Field::new(
4325                 "substitutions",
4326                 traversal::FieldType::array_of_records(
4327                     stringify!(FeatureTableSubstitutionRecord),
4328                     self.substitutions(),
4329                     self.offset_data(),
4330                 ),
4331             )),
4332             _ => None,
4333         }
4334     }
4335 }
4336 
4337 #[cfg(feature = "traversal")]
4338 impl<'a> std::fmt::Debug for FeatureTableSubstitution<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result4339     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4340         (self as &dyn SomeTable<'a>).fmt(f)
4341     }
4342 }
4343 
4344 /// Used in [FeatureTableSubstitution]
4345 #[derive(Clone, Debug)]
4346 #[repr(C)]
4347 #[repr(packed)]
4348 pub struct FeatureTableSubstitutionRecord {
4349     /// The feature table index to match.
4350     pub feature_index: BigEndian<u16>,
4351     /// Offset to an alternate feature table, from start of the
4352     /// FeatureTableSubstitution table.
4353     pub alternate_feature_offset: BigEndian<Offset32>,
4354 }
4355 
4356 impl FeatureTableSubstitutionRecord {
4357     /// The feature table index to match.
feature_index(&self) -> u164358     pub fn feature_index(&self) -> u16 {
4359         self.feature_index.get()
4360     }
4361 
4362     /// Offset to an alternate feature table, from start of the
4363     /// FeatureTableSubstitution table.
alternate_feature_offset(&self) -> Offset324364     pub fn alternate_feature_offset(&self) -> Offset32 {
4365         self.alternate_feature_offset.get()
4366     }
4367 }
4368 
4369 impl FixedSize for FeatureTableSubstitutionRecord {
4370     const RAW_BYTE_LEN: usize = u16::RAW_BYTE_LEN + Offset32::RAW_BYTE_LEN;
4371 }
4372 
4373 impl sealed::Sealed for FeatureTableSubstitutionRecord {}
4374 
4375 /// SAFETY: see the [`FromBytes`] trait documentation.
4376 unsafe impl FromBytes for FeatureTableSubstitutionRecord {
this_trait_should_only_be_implemented_in_generated_code()4377     fn this_trait_should_only_be_implemented_in_generated_code() {}
4378 }
4379 
4380 #[cfg(feature = "traversal")]
4381 impl<'a> SomeRecord<'a> for FeatureTableSubstitutionRecord {
traverse(self, data: FontData<'a>) -> RecordResolver<'a>4382     fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
4383         RecordResolver {
4384             name: "FeatureTableSubstitutionRecord",
4385             get_field: Box::new(move |idx, _data| match idx {
4386                 0usize => Some(Field::new("feature_index", self.feature_index())),
4387                 1usize => Some(Field::new(
4388                     "alternate_feature_offset",
4389                     FieldType::offset(
4390                         self.alternate_feature_offset(),
4391                         self.alternate_feature(_data),
4392                     ),
4393                 )),
4394                 _ => None,
4395             }),
4396             data,
4397         }
4398     }
4399 }
4400 
4401 #[derive(Debug, Clone, Copy)]
4402 #[doc(hidden)]
4403 pub struct SizeParamsMarker {}
4404 
4405 impl SizeParamsMarker {
design_size_byte_range(&self) -> Range<usize>4406     fn design_size_byte_range(&self) -> Range<usize> {
4407         let start = 0;
4408         start..start + u16::RAW_BYTE_LEN
4409     }
identifier_byte_range(&self) -> Range<usize>4410     fn identifier_byte_range(&self) -> Range<usize> {
4411         let start = self.design_size_byte_range().end;
4412         start..start + u16::RAW_BYTE_LEN
4413     }
name_entry_byte_range(&self) -> Range<usize>4414     fn name_entry_byte_range(&self) -> Range<usize> {
4415         let start = self.identifier_byte_range().end;
4416         start..start + u16::RAW_BYTE_LEN
4417     }
range_start_byte_range(&self) -> Range<usize>4418     fn range_start_byte_range(&self) -> Range<usize> {
4419         let start = self.name_entry_byte_range().end;
4420         start..start + u16::RAW_BYTE_LEN
4421     }
range_end_byte_range(&self) -> Range<usize>4422     fn range_end_byte_range(&self) -> Range<usize> {
4423         let start = self.range_start_byte_range().end;
4424         start..start + u16::RAW_BYTE_LEN
4425     }
4426 }
4427 
4428 impl<'a> FontRead<'a> for SizeParams<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>4429     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
4430         let mut cursor = data.cursor();
4431         cursor.advance::<u16>();
4432         cursor.advance::<u16>();
4433         cursor.advance::<u16>();
4434         cursor.advance::<u16>();
4435         cursor.advance::<u16>();
4436         cursor.finish(SizeParamsMarker {})
4437     }
4438 }
4439 
4440 pub type SizeParams<'a> = TableRef<'a, SizeParamsMarker>;
4441 
4442 impl<'a> SizeParams<'a> {
4443     /// The first value represents the design size in 720/inch units (decipoints).
4444     ///
4445     /// The design size entry must be non-zero. When there is a design size but
4446     /// no recommended size range, the rest of the array will consist of zeros.
design_size(&self) -> u164447     pub fn design_size(&self) -> u16 {
4448         let range = self.shape.design_size_byte_range();
4449         self.data.read_at(range.start).unwrap()
4450     }
4451 
4452     /// The second value has no independent meaning, but serves as an identifier that associates fonts in a subfamily.
4453     ///
4454     /// All fonts which share a Typographic or Font Family name and which differ
4455     /// only by size range shall have the same subfamily value, and no fonts
4456     /// which differ in weight or style shall have the same subfamily value.
4457     /// If this value is zero, the remaining fields in the array will be ignored.
identifier(&self) -> u164458     pub fn identifier(&self) -> u16 {
4459         let range = self.shape.identifier_byte_range();
4460         self.data.read_at(range.start).unwrap()
4461     }
4462 
4463     /// The third value enables applications to use a single name for the subfamily identified by the second value.
4464     ///
4465     /// If the preceding value is non-zero, this value must be set in the range
4466     /// 256 – 32767 (inclusive). It records the value of a field in the 'name'
4467     /// table, which must contain English-language strings encoded in Windows
4468     /// Unicode and Macintosh Roman, and may contain additional strings localized
4469     /// to other scripts and languages. Each of these strings is the name
4470     /// an application should use, in combination with the family name, to
4471     /// represent the subfamily in a menu. Applications will choose the
4472     /// appropriate version based on their selection criteria.
name_entry(&self) -> u164473     pub fn name_entry(&self) -> u16 {
4474         let range = self.shape.name_entry_byte_range();
4475         self.data.read_at(range.start).unwrap()
4476     }
4477 
4478     /// The fourth and fifth values represent the small end of the recommended
4479     /// usage range (exclusive) and the large end of the recommended usage range
4480     /// (inclusive), stored in 720/inch units (decipoints).
4481     ///
4482     /// Ranges must not overlap, and should generally be contiguous.
range_start(&self) -> u164483     pub fn range_start(&self) -> u16 {
4484         let range = self.shape.range_start_byte_range();
4485         self.data.read_at(range.start).unwrap()
4486     }
4487 
range_end(&self) -> u164488     pub fn range_end(&self) -> u16 {
4489         let range = self.shape.range_end_byte_range();
4490         self.data.read_at(range.start).unwrap()
4491     }
4492 }
4493 
4494 #[cfg(feature = "traversal")]
4495 impl<'a> SomeTable<'a> for SizeParams<'a> {
type_name(&self) -> &str4496     fn type_name(&self) -> &str {
4497         "SizeParams"
4498     }
get_field(&self, idx: usize) -> Option<Field<'a>>4499     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
4500         match idx {
4501             0usize => Some(Field::new("design_size", self.design_size())),
4502             1usize => Some(Field::new("identifier", self.identifier())),
4503             2usize => Some(Field::new("name_entry", self.name_entry())),
4504             3usize => Some(Field::new("range_start", self.range_start())),
4505             4usize => Some(Field::new("range_end", self.range_end())),
4506             _ => None,
4507         }
4508     }
4509 }
4510 
4511 #[cfg(feature = "traversal")]
4512 impl<'a> std::fmt::Debug for SizeParams<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result4513     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4514         (self as &dyn SomeTable<'a>).fmt(f)
4515     }
4516 }
4517 
4518 #[derive(Debug, Clone, Copy)]
4519 #[doc(hidden)]
4520 pub struct StylisticSetParamsMarker {}
4521 
4522 impl StylisticSetParamsMarker {
version_byte_range(&self) -> Range<usize>4523     fn version_byte_range(&self) -> Range<usize> {
4524         let start = 0;
4525         start..start + u16::RAW_BYTE_LEN
4526     }
ui_name_id_byte_range(&self) -> Range<usize>4527     fn ui_name_id_byte_range(&self) -> Range<usize> {
4528         let start = self.version_byte_range().end;
4529         start..start + NameId::RAW_BYTE_LEN
4530     }
4531 }
4532 
4533 impl<'a> FontRead<'a> for StylisticSetParams<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>4534     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
4535         let mut cursor = data.cursor();
4536         cursor.advance::<u16>();
4537         cursor.advance::<NameId>();
4538         cursor.finish(StylisticSetParamsMarker {})
4539     }
4540 }
4541 
4542 pub type StylisticSetParams<'a> = TableRef<'a, StylisticSetParamsMarker>;
4543 
4544 impl<'a> StylisticSetParams<'a> {
version(&self) -> u164545     pub fn version(&self) -> u16 {
4546         let range = self.shape.version_byte_range();
4547         self.data.read_at(range.start).unwrap()
4548     }
4549 
4550     /// The 'name' table name ID that specifies a string (or strings, for
4551     /// multiple languages) for a user-interface label for this feature.
4552     ///
4553     /// The value of uiLabelNameId is expected to be in the font-specific name
4554     /// ID range (256-32767), though that is not a requirement in this Feature
4555     /// Parameters specification. The user-interface label for the feature can
4556     /// be provided in multiple languages. An English string should be included
4557     /// as a fallback. The string should be kept to a minimal length to fit
4558     /// comfortably with different application interfaces.
ui_name_id(&self) -> NameId4559     pub fn ui_name_id(&self) -> NameId {
4560         let range = self.shape.ui_name_id_byte_range();
4561         self.data.read_at(range.start).unwrap()
4562     }
4563 }
4564 
4565 #[cfg(feature = "traversal")]
4566 impl<'a> SomeTable<'a> for StylisticSetParams<'a> {
type_name(&self) -> &str4567     fn type_name(&self) -> &str {
4568         "StylisticSetParams"
4569     }
get_field(&self, idx: usize) -> Option<Field<'a>>4570     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
4571         match idx {
4572             0usize => Some(Field::new("version", self.version())),
4573             1usize => Some(Field::new("ui_name_id", self.ui_name_id())),
4574             _ => None,
4575         }
4576     }
4577 }
4578 
4579 #[cfg(feature = "traversal")]
4580 impl<'a> std::fmt::Debug for StylisticSetParams<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result4581     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4582         (self as &dyn SomeTable<'a>).fmt(f)
4583     }
4584 }
4585 
4586 impl Format<u16> for CharacterVariantParamsMarker {
4587     const FORMAT: u16 = 0;
4588 }
4589 
4590 /// featureParams for ['cv01'-'cv99'](https://docs.microsoft.com/en-us/typography/opentype/spec/features_ae#cv01-cv99)
4591 #[derive(Debug, Clone, Copy)]
4592 #[doc(hidden)]
4593 pub struct CharacterVariantParamsMarker {
4594     character_byte_len: usize,
4595 }
4596 
4597 impl CharacterVariantParamsMarker {
format_byte_range(&self) -> Range<usize>4598     fn format_byte_range(&self) -> Range<usize> {
4599         let start = 0;
4600         start..start + u16::RAW_BYTE_LEN
4601     }
feat_ui_label_name_id_byte_range(&self) -> Range<usize>4602     fn feat_ui_label_name_id_byte_range(&self) -> Range<usize> {
4603         let start = self.format_byte_range().end;
4604         start..start + NameId::RAW_BYTE_LEN
4605     }
feat_ui_tooltip_text_name_id_byte_range(&self) -> Range<usize>4606     fn feat_ui_tooltip_text_name_id_byte_range(&self) -> Range<usize> {
4607         let start = self.feat_ui_label_name_id_byte_range().end;
4608         start..start + NameId::RAW_BYTE_LEN
4609     }
sample_text_name_id_byte_range(&self) -> Range<usize>4610     fn sample_text_name_id_byte_range(&self) -> Range<usize> {
4611         let start = self.feat_ui_tooltip_text_name_id_byte_range().end;
4612         start..start + NameId::RAW_BYTE_LEN
4613     }
num_named_parameters_byte_range(&self) -> Range<usize>4614     fn num_named_parameters_byte_range(&self) -> Range<usize> {
4615         let start = self.sample_text_name_id_byte_range().end;
4616         start..start + u16::RAW_BYTE_LEN
4617     }
first_param_ui_label_name_id_byte_range(&self) -> Range<usize>4618     fn first_param_ui_label_name_id_byte_range(&self) -> Range<usize> {
4619         let start = self.num_named_parameters_byte_range().end;
4620         start..start + NameId::RAW_BYTE_LEN
4621     }
char_count_byte_range(&self) -> Range<usize>4622     fn char_count_byte_range(&self) -> Range<usize> {
4623         let start = self.first_param_ui_label_name_id_byte_range().end;
4624         start..start + u16::RAW_BYTE_LEN
4625     }
character_byte_range(&self) -> Range<usize>4626     fn character_byte_range(&self) -> Range<usize> {
4627         let start = self.char_count_byte_range().end;
4628         start..start + self.character_byte_len
4629     }
4630 }
4631 
4632 impl<'a> FontRead<'a> for CharacterVariantParams<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>4633     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
4634         let mut cursor = data.cursor();
4635         cursor.advance::<u16>();
4636         cursor.advance::<NameId>();
4637         cursor.advance::<NameId>();
4638         cursor.advance::<NameId>();
4639         cursor.advance::<u16>();
4640         cursor.advance::<NameId>();
4641         let char_count: u16 = cursor.read()?;
4642         let character_byte_len = char_count as usize * Uint24::RAW_BYTE_LEN;
4643         cursor.advance_by(character_byte_len);
4644         cursor.finish(CharacterVariantParamsMarker { character_byte_len })
4645     }
4646 }
4647 
4648 /// featureParams for ['cv01'-'cv99'](https://docs.microsoft.com/en-us/typography/opentype/spec/features_ae#cv01-cv99)
4649 pub type CharacterVariantParams<'a> = TableRef<'a, CharacterVariantParamsMarker>;
4650 
4651 impl<'a> CharacterVariantParams<'a> {
4652     /// Format number is set to 0.
format(&self) -> u164653     pub fn format(&self) -> u16 {
4654         let range = self.shape.format_byte_range();
4655         self.data.read_at(range.start).unwrap()
4656     }
4657 
4658     /// The 'name' table name ID that specifies a string (or strings,
4659     /// for multiple languages) for a user-interface label for this
4660     /// feature. (May be NULL.)
feat_ui_label_name_id(&self) -> NameId4661     pub fn feat_ui_label_name_id(&self) -> NameId {
4662         let range = self.shape.feat_ui_label_name_id_byte_range();
4663         self.data.read_at(range.start).unwrap()
4664     }
4665 
4666     /// The 'name' table name ID that specifies a string (or strings,
4667     /// for multiple languages) that an application can use for tooltip
4668     /// text for this feature. (May be NULL.)
feat_ui_tooltip_text_name_id(&self) -> NameId4669     pub fn feat_ui_tooltip_text_name_id(&self) -> NameId {
4670         let range = self.shape.feat_ui_tooltip_text_name_id_byte_range();
4671         self.data.read_at(range.start).unwrap()
4672     }
4673 
4674     /// The 'name' table name ID that specifies sample text that
4675     /// illustrates the effect of this feature. (May be NULL.)
sample_text_name_id(&self) -> NameId4676     pub fn sample_text_name_id(&self) -> NameId {
4677         let range = self.shape.sample_text_name_id_byte_range();
4678         self.data.read_at(range.start).unwrap()
4679     }
4680 
4681     /// Number of named parameters. (May be zero.)
num_named_parameters(&self) -> u164682     pub fn num_named_parameters(&self) -> u16 {
4683         let range = self.shape.num_named_parameters_byte_range();
4684         self.data.read_at(range.start).unwrap()
4685     }
4686 
4687     /// The first 'name' table name ID used to specify strings for
4688     /// user-interface labels for the feature parameters. (Must be zero
4689     /// if numParameters is zero.)
first_param_ui_label_name_id(&self) -> NameId4690     pub fn first_param_ui_label_name_id(&self) -> NameId {
4691         let range = self.shape.first_param_ui_label_name_id_byte_range();
4692         self.data.read_at(range.start).unwrap()
4693     }
4694 
4695     /// The count of characters for which this feature provides glyph
4696     /// variants. (May be zero.)
char_count(&self) -> u164697     pub fn char_count(&self) -> u16 {
4698         let range = self.shape.char_count_byte_range();
4699         self.data.read_at(range.start).unwrap()
4700     }
4701 
4702     /// The Unicode Scalar Value of the characters for which this
4703     /// feature provides glyph variants.
character(&self) -> &'a [BigEndian<Uint24>]4704     pub fn character(&self) -> &'a [BigEndian<Uint24>] {
4705         let range = self.shape.character_byte_range();
4706         self.data.read_array(range).unwrap()
4707     }
4708 }
4709 
4710 #[cfg(feature = "traversal")]
4711 impl<'a> SomeTable<'a> for CharacterVariantParams<'a> {
type_name(&self) -> &str4712     fn type_name(&self) -> &str {
4713         "CharacterVariantParams"
4714     }
get_field(&self, idx: usize) -> Option<Field<'a>>4715     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
4716         match idx {
4717             0usize => Some(Field::new("format", self.format())),
4718             1usize => Some(Field::new(
4719                 "feat_ui_label_name_id",
4720                 self.feat_ui_label_name_id(),
4721             )),
4722             2usize => Some(Field::new(
4723                 "feat_ui_tooltip_text_name_id",
4724                 self.feat_ui_tooltip_text_name_id(),
4725             )),
4726             3usize => Some(Field::new(
4727                 "sample_text_name_id",
4728                 self.sample_text_name_id(),
4729             )),
4730             4usize => Some(Field::new(
4731                 "num_named_parameters",
4732                 self.num_named_parameters(),
4733             )),
4734             5usize => Some(Field::new(
4735                 "first_param_ui_label_name_id",
4736                 self.first_param_ui_label_name_id(),
4737             )),
4738             6usize => Some(Field::new("char_count", self.char_count())),
4739             7usize => Some(Field::new("character", self.character())),
4740             _ => None,
4741         }
4742     }
4743 }
4744 
4745 #[cfg(feature = "traversal")]
4746 impl<'a> std::fmt::Debug for CharacterVariantParams<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result4747     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4748         (self as &dyn SomeTable<'a>).fmt(f)
4749     }
4750 }
4751