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 /// OS/2 [selection flags](https://learn.microsoft.com/en-us/typography/opentype/spec/os2#fsselection)
9 #[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
10 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
11 pub struct SelectionFlags {
12     bits: u16,
13 }
14 
15 impl SelectionFlags {
16     /// Bit 0: Font contains italic or oblique glyphs, otherwise they are
17     /// upright.
18     pub const ITALIC: Self = Self { bits: 0x0001 };
19 
20     /// Bit 1: Glyphs are underscored.
21     pub const UNDERSCORE: Self = Self { bits: 0x0002 };
22 
23     /// Bit 2: Glyphs have their foreground and background reversed.
24     pub const NEGATIVE: Self = Self { bits: 0x0004 };
25 
26     /// Bit 3: Outline (hollow) glyphs, otherwise they are solid.
27     pub const OUTLINED: Self = Self { bits: 0x0008 };
28 
29     /// Bit 4: Glyphs are overstruck.
30     pub const STRIKEOUT: Self = Self { bits: 0x0010 };
31 
32     /// Bit 5: Glyphs are emboldened.
33     pub const BOLD: Self = Self { bits: 0x0020 };
34 
35     /// Bit 6: Glyphs are in the standard weight/style for the font.
36     pub const REGULAR: Self = Self { bits: 0x0040 };
37 
38     /// Bit 7: If set, it is strongly recommended that applications use
39     /// OS/2.sTypoAscender - OS/2.sTypoDescender + OS/2.sTypoLineGap as
40     /// the default line spacing for this font.
41     pub const USE_TYPO_METRICS: Self = Self { bits: 0x0080 };
42 
43     /// Bit 8: The font has 'name' table strings consistent with a
44     /// weight/width/slope family without requiring use of name IDs 21 and 22.
45     pub const WWS: Self = Self { bits: 0x0100 };
46 
47     /// Bit 9: Font contains oblique glyphs.
48     pub const OBLIQUE: Self = Self { bits: 0x0200 };
49 }
50 
51 impl SelectionFlags {
52     ///  Returns an empty set of flags.
53     #[inline]
empty() -> Self54     pub const fn empty() -> Self {
55         Self { bits: 0 }
56     }
57 
58     /// Returns the set containing all flags.
59     #[inline]
all() -> Self60     pub const fn all() -> Self {
61         Self {
62             bits: Self::ITALIC.bits
63                 | Self::UNDERSCORE.bits
64                 | Self::NEGATIVE.bits
65                 | Self::OUTLINED.bits
66                 | Self::STRIKEOUT.bits
67                 | Self::BOLD.bits
68                 | Self::REGULAR.bits
69                 | Self::USE_TYPO_METRICS.bits
70                 | Self::WWS.bits
71                 | Self::OBLIQUE.bits,
72         }
73     }
74 
75     /// Returns the raw value of the flags currently stored.
76     #[inline]
bits(&self) -> u1677     pub const fn bits(&self) -> u16 {
78         self.bits
79     }
80 
81     /// Convert from underlying bit representation, unless that
82     /// representation contains bits that do not correspond to a flag.
83     #[inline]
from_bits(bits: u16) -> Option<Self>84     pub const fn from_bits(bits: u16) -> Option<Self> {
85         if (bits & !Self::all().bits()) == 0 {
86             Some(Self { bits })
87         } else {
88             None
89         }
90     }
91 
92     /// Convert from underlying bit representation, dropping any bits
93     /// that do not correspond to flags.
94     #[inline]
from_bits_truncate(bits: u16) -> Self95     pub const fn from_bits_truncate(bits: u16) -> Self {
96         Self {
97             bits: bits & Self::all().bits,
98         }
99     }
100 
101     /// Returns `true` if no flags are currently stored.
102     #[inline]
is_empty(&self) -> bool103     pub const fn is_empty(&self) -> bool {
104         self.bits() == Self::empty().bits()
105     }
106 
107     /// Returns `true` if there are flags common to both `self` and `other`.
108     #[inline]
intersects(&self, other: Self) -> bool109     pub const fn intersects(&self, other: Self) -> bool {
110         !(Self {
111             bits: self.bits & other.bits,
112         })
113         .is_empty()
114     }
115 
116     /// Returns `true` if all of the flags in `other` are contained within `self`.
117     #[inline]
contains(&self, other: Self) -> bool118     pub const fn contains(&self, other: Self) -> bool {
119         (self.bits & other.bits) == other.bits
120     }
121 
122     /// Inserts the specified flags in-place.
123     #[inline]
insert(&mut self, other: Self)124     pub fn insert(&mut self, other: Self) {
125         self.bits |= other.bits;
126     }
127 
128     /// Removes the specified flags in-place.
129     #[inline]
remove(&mut self, other: Self)130     pub fn remove(&mut self, other: Self) {
131         self.bits &= !other.bits;
132     }
133 
134     /// Toggles the specified flags in-place.
135     #[inline]
toggle(&mut self, other: Self)136     pub fn toggle(&mut self, other: Self) {
137         self.bits ^= other.bits;
138     }
139 
140     /// Returns the intersection between the flags in `self` and
141     /// `other`.
142     ///
143     /// Specifically, the returned set contains only the flags which are
144     /// present in *both* `self` *and* `other`.
145     ///
146     /// This is equivalent to using the `&` operator (e.g.
147     /// [`ops::BitAnd`]), as in `flags & other`.
148     ///
149     /// [`ops::BitAnd`]: https://doc.rust-lang.org/std/ops/trait.BitAnd.html
150     #[inline]
151     #[must_use]
intersection(self, other: Self) -> Self152     pub const fn intersection(self, other: Self) -> Self {
153         Self {
154             bits: self.bits & other.bits,
155         }
156     }
157 
158     /// Returns the union of between the flags in `self` and `other`.
159     ///
160     /// Specifically, the returned set contains all flags which are
161     /// present in *either* `self` *or* `other`, including any which are
162     /// present in both.
163     ///
164     /// This is equivalent to using the `|` operator (e.g.
165     /// [`ops::BitOr`]), as in `flags | other`.
166     ///
167     /// [`ops::BitOr`]: https://doc.rust-lang.org/std/ops/trait.BitOr.html
168     #[inline]
169     #[must_use]
union(self, other: Self) -> Self170     pub const fn union(self, other: Self) -> Self {
171         Self {
172             bits: self.bits | other.bits,
173         }
174     }
175 
176     /// Returns the difference between the flags in `self` and `other`.
177     ///
178     /// Specifically, the returned set contains all flags present in
179     /// `self`, except for the ones present in `other`.
180     ///
181     /// It is also conceptually equivalent to the "bit-clear" operation:
182     /// `flags & !other` (and this syntax is also supported).
183     ///
184     /// This is equivalent to using the `-` operator (e.g.
185     /// [`ops::Sub`]), as in `flags - other`.
186     ///
187     /// [`ops::Sub`]: https://doc.rust-lang.org/std/ops/trait.Sub.html
188     #[inline]
189     #[must_use]
difference(self, other: Self) -> Self190     pub const fn difference(self, other: Self) -> Self {
191         Self {
192             bits: self.bits & !other.bits,
193         }
194     }
195 }
196 
197 impl std::ops::BitOr for SelectionFlags {
198     type Output = Self;
199 
200     /// Returns the union of the two sets of flags.
201     #[inline]
bitor(self, other: SelectionFlags) -> Self202     fn bitor(self, other: SelectionFlags) -> Self {
203         Self {
204             bits: self.bits | other.bits,
205         }
206     }
207 }
208 
209 impl std::ops::BitOrAssign for SelectionFlags {
210     /// Adds the set of flags.
211     #[inline]
bitor_assign(&mut self, other: Self)212     fn bitor_assign(&mut self, other: Self) {
213         self.bits |= other.bits;
214     }
215 }
216 
217 impl std::ops::BitXor for SelectionFlags {
218     type Output = Self;
219 
220     /// Returns the left flags, but with all the right flags toggled.
221     #[inline]
bitxor(self, other: Self) -> Self222     fn bitxor(self, other: Self) -> Self {
223         Self {
224             bits: self.bits ^ other.bits,
225         }
226     }
227 }
228 
229 impl std::ops::BitXorAssign for SelectionFlags {
230     /// Toggles the set of flags.
231     #[inline]
bitxor_assign(&mut self, other: Self)232     fn bitxor_assign(&mut self, other: Self) {
233         self.bits ^= other.bits;
234     }
235 }
236 
237 impl std::ops::BitAnd for SelectionFlags {
238     type Output = Self;
239 
240     /// Returns the intersection between the two sets of flags.
241     #[inline]
bitand(self, other: Self) -> Self242     fn bitand(self, other: Self) -> Self {
243         Self {
244             bits: self.bits & other.bits,
245         }
246     }
247 }
248 
249 impl std::ops::BitAndAssign for SelectionFlags {
250     /// Disables all flags disabled in the set.
251     #[inline]
bitand_assign(&mut self, other: Self)252     fn bitand_assign(&mut self, other: Self) {
253         self.bits &= other.bits;
254     }
255 }
256 
257 impl std::ops::Sub for SelectionFlags {
258     type Output = Self;
259 
260     /// Returns the set difference of the two sets of flags.
261     #[inline]
sub(self, other: Self) -> Self262     fn sub(self, other: Self) -> Self {
263         Self {
264             bits: self.bits & !other.bits,
265         }
266     }
267 }
268 
269 impl std::ops::SubAssign for SelectionFlags {
270     /// Disables all flags enabled in the set.
271     #[inline]
sub_assign(&mut self, other: Self)272     fn sub_assign(&mut self, other: Self) {
273         self.bits &= !other.bits;
274     }
275 }
276 
277 impl std::ops::Not for SelectionFlags {
278     type Output = Self;
279 
280     /// Returns the complement of this set of flags.
281     #[inline]
not(self) -> Self282     fn not(self) -> Self {
283         Self { bits: !self.bits } & Self::all()
284     }
285 }
286 
287 impl std::fmt::Debug for SelectionFlags {
fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result288     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
289         let members: &[(&str, Self)] = &[
290             ("ITALIC", Self::ITALIC),
291             ("UNDERSCORE", Self::UNDERSCORE),
292             ("NEGATIVE", Self::NEGATIVE),
293             ("OUTLINED", Self::OUTLINED),
294             ("STRIKEOUT", Self::STRIKEOUT),
295             ("BOLD", Self::BOLD),
296             ("REGULAR", Self::REGULAR),
297             ("USE_TYPO_METRICS", Self::USE_TYPO_METRICS),
298             ("WWS", Self::WWS),
299             ("OBLIQUE", Self::OBLIQUE),
300         ];
301         let mut first = true;
302         for (name, value) in members {
303             if self.contains(*value) {
304                 if !first {
305                     f.write_str(" | ")?;
306                 }
307                 first = false;
308                 f.write_str(name)?;
309             }
310         }
311         if first {
312             f.write_str("(empty)")?;
313         }
314         Ok(())
315     }
316 }
317 
318 impl std::fmt::Binary for SelectionFlags {
fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result319     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
320         std::fmt::Binary::fmt(&self.bits, f)
321     }
322 }
323 
324 impl std::fmt::Octal for SelectionFlags {
fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result325     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
326         std::fmt::Octal::fmt(&self.bits, f)
327     }
328 }
329 
330 impl std::fmt::LowerHex for SelectionFlags {
fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result331     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
332         std::fmt::LowerHex::fmt(&self.bits, f)
333     }
334 }
335 
336 impl std::fmt::UpperHex for SelectionFlags {
fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result337     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
338         std::fmt::UpperHex::fmt(&self.bits, f)
339     }
340 }
341 
342 impl font_types::Scalar for SelectionFlags {
343     type Raw = <u16 as font_types::Scalar>::Raw;
to_raw(self) -> Self::Raw344     fn to_raw(self) -> Self::Raw {
345         self.bits().to_raw()
346     }
from_raw(raw: Self::Raw) -> Self347     fn from_raw(raw: Self::Raw) -> Self {
348         let t = <u16>::from_raw(raw);
349         Self::from_bits_truncate(t)
350     }
351 }
352 
353 #[cfg(feature = "traversal")]
354 impl<'a> From<SelectionFlags> for FieldType<'a> {
from(src: SelectionFlags) -> FieldType<'a>355     fn from(src: SelectionFlags) -> FieldType<'a> {
356         src.bits().into()
357     }
358 }
359 
360 /// [`OS/2`](https://docs.microsoft.com/en-us/typography/opentype/spec/os2)
361 #[derive(Debug, Clone, Copy)]
362 #[doc(hidden)]
363 pub struct Os2Marker {
364     panose_10_byte_len: usize,
365     ul_code_page_range_1_byte_start: Option<usize>,
366     ul_code_page_range_2_byte_start: Option<usize>,
367     sx_height_byte_start: Option<usize>,
368     s_cap_height_byte_start: Option<usize>,
369     us_default_char_byte_start: Option<usize>,
370     us_break_char_byte_start: Option<usize>,
371     us_max_context_byte_start: Option<usize>,
372     us_lower_optical_point_size_byte_start: Option<usize>,
373     us_upper_optical_point_size_byte_start: Option<usize>,
374 }
375 
376 impl Os2Marker {
version_byte_range(&self) -> Range<usize>377     fn version_byte_range(&self) -> Range<usize> {
378         let start = 0;
379         start..start + u16::RAW_BYTE_LEN
380     }
x_avg_char_width_byte_range(&self) -> Range<usize>381     fn x_avg_char_width_byte_range(&self) -> Range<usize> {
382         let start = self.version_byte_range().end;
383         start..start + i16::RAW_BYTE_LEN
384     }
us_weight_class_byte_range(&self) -> Range<usize>385     fn us_weight_class_byte_range(&self) -> Range<usize> {
386         let start = self.x_avg_char_width_byte_range().end;
387         start..start + u16::RAW_BYTE_LEN
388     }
us_width_class_byte_range(&self) -> Range<usize>389     fn us_width_class_byte_range(&self) -> Range<usize> {
390         let start = self.us_weight_class_byte_range().end;
391         start..start + u16::RAW_BYTE_LEN
392     }
fs_type_byte_range(&self) -> Range<usize>393     fn fs_type_byte_range(&self) -> Range<usize> {
394         let start = self.us_width_class_byte_range().end;
395         start..start + u16::RAW_BYTE_LEN
396     }
y_subscript_x_size_byte_range(&self) -> Range<usize>397     fn y_subscript_x_size_byte_range(&self) -> Range<usize> {
398         let start = self.fs_type_byte_range().end;
399         start..start + i16::RAW_BYTE_LEN
400     }
y_subscript_y_size_byte_range(&self) -> Range<usize>401     fn y_subscript_y_size_byte_range(&self) -> Range<usize> {
402         let start = self.y_subscript_x_size_byte_range().end;
403         start..start + i16::RAW_BYTE_LEN
404     }
y_subscript_x_offset_byte_range(&self) -> Range<usize>405     fn y_subscript_x_offset_byte_range(&self) -> Range<usize> {
406         let start = self.y_subscript_y_size_byte_range().end;
407         start..start + i16::RAW_BYTE_LEN
408     }
y_subscript_y_offset_byte_range(&self) -> Range<usize>409     fn y_subscript_y_offset_byte_range(&self) -> Range<usize> {
410         let start = self.y_subscript_x_offset_byte_range().end;
411         start..start + i16::RAW_BYTE_LEN
412     }
y_superscript_x_size_byte_range(&self) -> Range<usize>413     fn y_superscript_x_size_byte_range(&self) -> Range<usize> {
414         let start = self.y_subscript_y_offset_byte_range().end;
415         start..start + i16::RAW_BYTE_LEN
416     }
y_superscript_y_size_byte_range(&self) -> Range<usize>417     fn y_superscript_y_size_byte_range(&self) -> Range<usize> {
418         let start = self.y_superscript_x_size_byte_range().end;
419         start..start + i16::RAW_BYTE_LEN
420     }
y_superscript_x_offset_byte_range(&self) -> Range<usize>421     fn y_superscript_x_offset_byte_range(&self) -> Range<usize> {
422         let start = self.y_superscript_y_size_byte_range().end;
423         start..start + i16::RAW_BYTE_LEN
424     }
y_superscript_y_offset_byte_range(&self) -> Range<usize>425     fn y_superscript_y_offset_byte_range(&self) -> Range<usize> {
426         let start = self.y_superscript_x_offset_byte_range().end;
427         start..start + i16::RAW_BYTE_LEN
428     }
y_strikeout_size_byte_range(&self) -> Range<usize>429     fn y_strikeout_size_byte_range(&self) -> Range<usize> {
430         let start = self.y_superscript_y_offset_byte_range().end;
431         start..start + i16::RAW_BYTE_LEN
432     }
y_strikeout_position_byte_range(&self) -> Range<usize>433     fn y_strikeout_position_byte_range(&self) -> Range<usize> {
434         let start = self.y_strikeout_size_byte_range().end;
435         start..start + i16::RAW_BYTE_LEN
436     }
s_family_class_byte_range(&self) -> Range<usize>437     fn s_family_class_byte_range(&self) -> Range<usize> {
438         let start = self.y_strikeout_position_byte_range().end;
439         start..start + i16::RAW_BYTE_LEN
440     }
panose_10_byte_range(&self) -> Range<usize>441     fn panose_10_byte_range(&self) -> Range<usize> {
442         let start = self.s_family_class_byte_range().end;
443         start..start + self.panose_10_byte_len
444     }
ul_unicode_range_1_byte_range(&self) -> Range<usize>445     fn ul_unicode_range_1_byte_range(&self) -> Range<usize> {
446         let start = self.panose_10_byte_range().end;
447         start..start + u32::RAW_BYTE_LEN
448     }
ul_unicode_range_2_byte_range(&self) -> Range<usize>449     fn ul_unicode_range_2_byte_range(&self) -> Range<usize> {
450         let start = self.ul_unicode_range_1_byte_range().end;
451         start..start + u32::RAW_BYTE_LEN
452     }
ul_unicode_range_3_byte_range(&self) -> Range<usize>453     fn ul_unicode_range_3_byte_range(&self) -> Range<usize> {
454         let start = self.ul_unicode_range_2_byte_range().end;
455         start..start + u32::RAW_BYTE_LEN
456     }
ul_unicode_range_4_byte_range(&self) -> Range<usize>457     fn ul_unicode_range_4_byte_range(&self) -> Range<usize> {
458         let start = self.ul_unicode_range_3_byte_range().end;
459         start..start + u32::RAW_BYTE_LEN
460     }
ach_vend_id_byte_range(&self) -> Range<usize>461     fn ach_vend_id_byte_range(&self) -> Range<usize> {
462         let start = self.ul_unicode_range_4_byte_range().end;
463         start..start + Tag::RAW_BYTE_LEN
464     }
fs_selection_byte_range(&self) -> Range<usize>465     fn fs_selection_byte_range(&self) -> Range<usize> {
466         let start = self.ach_vend_id_byte_range().end;
467         start..start + SelectionFlags::RAW_BYTE_LEN
468     }
us_first_char_index_byte_range(&self) -> Range<usize>469     fn us_first_char_index_byte_range(&self) -> Range<usize> {
470         let start = self.fs_selection_byte_range().end;
471         start..start + u16::RAW_BYTE_LEN
472     }
us_last_char_index_byte_range(&self) -> Range<usize>473     fn us_last_char_index_byte_range(&self) -> Range<usize> {
474         let start = self.us_first_char_index_byte_range().end;
475         start..start + u16::RAW_BYTE_LEN
476     }
s_typo_ascender_byte_range(&self) -> Range<usize>477     fn s_typo_ascender_byte_range(&self) -> Range<usize> {
478         let start = self.us_last_char_index_byte_range().end;
479         start..start + i16::RAW_BYTE_LEN
480     }
s_typo_descender_byte_range(&self) -> Range<usize>481     fn s_typo_descender_byte_range(&self) -> Range<usize> {
482         let start = self.s_typo_ascender_byte_range().end;
483         start..start + i16::RAW_BYTE_LEN
484     }
s_typo_line_gap_byte_range(&self) -> Range<usize>485     fn s_typo_line_gap_byte_range(&self) -> Range<usize> {
486         let start = self.s_typo_descender_byte_range().end;
487         start..start + i16::RAW_BYTE_LEN
488     }
us_win_ascent_byte_range(&self) -> Range<usize>489     fn us_win_ascent_byte_range(&self) -> Range<usize> {
490         let start = self.s_typo_line_gap_byte_range().end;
491         start..start + u16::RAW_BYTE_LEN
492     }
us_win_descent_byte_range(&self) -> Range<usize>493     fn us_win_descent_byte_range(&self) -> Range<usize> {
494         let start = self.us_win_ascent_byte_range().end;
495         start..start + u16::RAW_BYTE_LEN
496     }
ul_code_page_range_1_byte_range(&self) -> Option<Range<usize>>497     fn ul_code_page_range_1_byte_range(&self) -> Option<Range<usize>> {
498         let start = self.ul_code_page_range_1_byte_start?;
499         Some(start..start + u32::RAW_BYTE_LEN)
500     }
ul_code_page_range_2_byte_range(&self) -> Option<Range<usize>>501     fn ul_code_page_range_2_byte_range(&self) -> Option<Range<usize>> {
502         let start = self.ul_code_page_range_2_byte_start?;
503         Some(start..start + u32::RAW_BYTE_LEN)
504     }
sx_height_byte_range(&self) -> Option<Range<usize>>505     fn sx_height_byte_range(&self) -> Option<Range<usize>> {
506         let start = self.sx_height_byte_start?;
507         Some(start..start + i16::RAW_BYTE_LEN)
508     }
s_cap_height_byte_range(&self) -> Option<Range<usize>>509     fn s_cap_height_byte_range(&self) -> Option<Range<usize>> {
510         let start = self.s_cap_height_byte_start?;
511         Some(start..start + i16::RAW_BYTE_LEN)
512     }
us_default_char_byte_range(&self) -> Option<Range<usize>>513     fn us_default_char_byte_range(&self) -> Option<Range<usize>> {
514         let start = self.us_default_char_byte_start?;
515         Some(start..start + u16::RAW_BYTE_LEN)
516     }
us_break_char_byte_range(&self) -> Option<Range<usize>>517     fn us_break_char_byte_range(&self) -> Option<Range<usize>> {
518         let start = self.us_break_char_byte_start?;
519         Some(start..start + u16::RAW_BYTE_LEN)
520     }
us_max_context_byte_range(&self) -> Option<Range<usize>>521     fn us_max_context_byte_range(&self) -> Option<Range<usize>> {
522         let start = self.us_max_context_byte_start?;
523         Some(start..start + u16::RAW_BYTE_LEN)
524     }
us_lower_optical_point_size_byte_range(&self) -> Option<Range<usize>>525     fn us_lower_optical_point_size_byte_range(&self) -> Option<Range<usize>> {
526         let start = self.us_lower_optical_point_size_byte_start?;
527         Some(start..start + u16::RAW_BYTE_LEN)
528     }
us_upper_optical_point_size_byte_range(&self) -> Option<Range<usize>>529     fn us_upper_optical_point_size_byte_range(&self) -> Option<Range<usize>> {
530         let start = self.us_upper_optical_point_size_byte_start?;
531         Some(start..start + u16::RAW_BYTE_LEN)
532     }
533 }
534 
535 impl TopLevelTable for Os2<'_> {
536     /// `OS/2`
537     const TAG: Tag = Tag::new(b"OS/2");
538 }
539 
540 impl<'a> FontRead<'a> for Os2<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>541     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
542         let mut cursor = data.cursor();
543         let version: u16 = cursor.read()?;
544         cursor.advance::<i16>();
545         cursor.advance::<u16>();
546         cursor.advance::<u16>();
547         cursor.advance::<u16>();
548         cursor.advance::<i16>();
549         cursor.advance::<i16>();
550         cursor.advance::<i16>();
551         cursor.advance::<i16>();
552         cursor.advance::<i16>();
553         cursor.advance::<i16>();
554         cursor.advance::<i16>();
555         cursor.advance::<i16>();
556         cursor.advance::<i16>();
557         cursor.advance::<i16>();
558         cursor.advance::<i16>();
559         let panose_10_byte_len = 10_usize * u8::RAW_BYTE_LEN;
560         cursor.advance_by(panose_10_byte_len);
561         cursor.advance::<u32>();
562         cursor.advance::<u32>();
563         cursor.advance::<u32>();
564         cursor.advance::<u32>();
565         cursor.advance::<Tag>();
566         cursor.advance::<SelectionFlags>();
567         cursor.advance::<u16>();
568         cursor.advance::<u16>();
569         cursor.advance::<i16>();
570         cursor.advance::<i16>();
571         cursor.advance::<i16>();
572         cursor.advance::<u16>();
573         cursor.advance::<u16>();
574         let ul_code_page_range_1_byte_start = version
575             .compatible(1)
576             .then(|| cursor.position())
577             .transpose()?;
578         version.compatible(1).then(|| cursor.advance::<u32>());
579         let ul_code_page_range_2_byte_start = version
580             .compatible(1)
581             .then(|| cursor.position())
582             .transpose()?;
583         version.compatible(1).then(|| cursor.advance::<u32>());
584         let sx_height_byte_start = version
585             .compatible(2)
586             .then(|| cursor.position())
587             .transpose()?;
588         version.compatible(2).then(|| cursor.advance::<i16>());
589         let s_cap_height_byte_start = version
590             .compatible(2)
591             .then(|| cursor.position())
592             .transpose()?;
593         version.compatible(2).then(|| cursor.advance::<i16>());
594         let us_default_char_byte_start = version
595             .compatible(2)
596             .then(|| cursor.position())
597             .transpose()?;
598         version.compatible(2).then(|| cursor.advance::<u16>());
599         let us_break_char_byte_start = version
600             .compatible(2)
601             .then(|| cursor.position())
602             .transpose()?;
603         version.compatible(2).then(|| cursor.advance::<u16>());
604         let us_max_context_byte_start = version
605             .compatible(2)
606             .then(|| cursor.position())
607             .transpose()?;
608         version.compatible(2).then(|| cursor.advance::<u16>());
609         let us_lower_optical_point_size_byte_start = version
610             .compatible(5)
611             .then(|| cursor.position())
612             .transpose()?;
613         version.compatible(5).then(|| cursor.advance::<u16>());
614         let us_upper_optical_point_size_byte_start = version
615             .compatible(5)
616             .then(|| cursor.position())
617             .transpose()?;
618         version.compatible(5).then(|| cursor.advance::<u16>());
619         cursor.finish(Os2Marker {
620             panose_10_byte_len,
621             ul_code_page_range_1_byte_start,
622             ul_code_page_range_2_byte_start,
623             sx_height_byte_start,
624             s_cap_height_byte_start,
625             us_default_char_byte_start,
626             us_break_char_byte_start,
627             us_max_context_byte_start,
628             us_lower_optical_point_size_byte_start,
629             us_upper_optical_point_size_byte_start,
630         })
631     }
632 }
633 
634 /// [`OS/2`](https://docs.microsoft.com/en-us/typography/opentype/spec/os2)
635 pub type Os2<'a> = TableRef<'a, Os2Marker>;
636 
637 impl<'a> Os2<'a> {
version(&self) -> u16638     pub fn version(&self) -> u16 {
639         let range = self.shape.version_byte_range();
640         self.data.read_at(range.start).unwrap()
641     }
642 
643     /// [Average weighted escapement](https://learn.microsoft.com/en-us/typography/opentype/spec/os2#xavgcharwidth).
644     ///
645     /// The Average Character Width parameter specifies the arithmetic average
646     /// of the escapement (width) of all non-zero width glyphs in the font.
x_avg_char_width(&self) -> i16647     pub fn x_avg_char_width(&self) -> i16 {
648         let range = self.shape.x_avg_char_width_byte_range();
649         self.data.read_at(range.start).unwrap()
650     }
651 
652     /// [Weight class](https://learn.microsoft.com/en-us/typography/opentype/spec/os2#usweightclass).
653     ///
654     /// Indicates the visual weight (degree of blackness or thickness of
655     /// strokes) of the characters in the font. Values from 1 to 1000 are valid.
us_weight_class(&self) -> u16656     pub fn us_weight_class(&self) -> u16 {
657         let range = self.shape.us_weight_class_byte_range();
658         self.data.read_at(range.start).unwrap()
659     }
660 
661     /// [Width class](https://learn.microsoft.com/en-us/typography/opentype/spec/os2#uswidthclass).
662     ///
663     /// Indicates a relative change from the normal aspect ratio (width to height
664     /// ratio) as specified by a font designer for the glyphs in a font.
us_width_class(&self) -> u16665     pub fn us_width_class(&self) -> u16 {
666         let range = self.shape.us_width_class_byte_range();
667         self.data.read_at(range.start).unwrap()
668     }
669 
670     /// [Type flags](https://learn.microsoft.com/en-us/typography/opentype/spec/os2#fstype).
671     ///
672     /// Indicates font embedding licensing rights for the font.
fs_type(&self) -> u16673     pub fn fs_type(&self) -> u16 {
674         let range = self.shape.fs_type_byte_range();
675         self.data.read_at(range.start).unwrap()
676     }
677 
678     /// The recommended horizontal size in font design units for subscripts for
679     /// this font.
y_subscript_x_size(&self) -> i16680     pub fn y_subscript_x_size(&self) -> i16 {
681         let range = self.shape.y_subscript_x_size_byte_range();
682         self.data.read_at(range.start).unwrap()
683     }
684 
685     /// The recommended vertical size in font design units for subscripts for
686     /// this font.
y_subscript_y_size(&self) -> i16687     pub fn y_subscript_y_size(&self) -> i16 {
688         let range = self.shape.y_subscript_y_size_byte_range();
689         self.data.read_at(range.start).unwrap()
690     }
691 
692     /// The recommended horizontal offset in font design units for subscripts
693     /// for this font.
y_subscript_x_offset(&self) -> i16694     pub fn y_subscript_x_offset(&self) -> i16 {
695         let range = self.shape.y_subscript_x_offset_byte_range();
696         self.data.read_at(range.start).unwrap()
697     }
698 
699     /// The recommended vertical offset in font design units for subscripts
700     /// for this font.
y_subscript_y_offset(&self) -> i16701     pub fn y_subscript_y_offset(&self) -> i16 {
702         let range = self.shape.y_subscript_y_offset_byte_range();
703         self.data.read_at(range.start).unwrap()
704     }
705 
706     /// The recommended horizontal size in font design units for superscripts
707     /// for this font.
y_superscript_x_size(&self) -> i16708     pub fn y_superscript_x_size(&self) -> i16 {
709         let range = self.shape.y_superscript_x_size_byte_range();
710         self.data.read_at(range.start).unwrap()
711     }
712 
713     /// The recommended vertical size in font design units for superscripts
714     /// for this font.
y_superscript_y_size(&self) -> i16715     pub fn y_superscript_y_size(&self) -> i16 {
716         let range = self.shape.y_superscript_y_size_byte_range();
717         self.data.read_at(range.start).unwrap()
718     }
719 
720     /// The recommended horizontal offset in font design units for superscripts
721     /// for this font.
y_superscript_x_offset(&self) -> i16722     pub fn y_superscript_x_offset(&self) -> i16 {
723         let range = self.shape.y_superscript_x_offset_byte_range();
724         self.data.read_at(range.start).unwrap()
725     }
726 
727     /// The recommended vertical offset in font design units for superscripts
728     /// for this font.
y_superscript_y_offset(&self) -> i16729     pub fn y_superscript_y_offset(&self) -> i16 {
730         let range = self.shape.y_superscript_y_offset_byte_range();
731         self.data.read_at(range.start).unwrap()
732     }
733 
734     /// Thickness of the strikeout stroke in font design units.
y_strikeout_size(&self) -> i16735     pub fn y_strikeout_size(&self) -> i16 {
736         let range = self.shape.y_strikeout_size_byte_range();
737         self.data.read_at(range.start).unwrap()
738     }
739 
740     /// The position of the top of the strikeout stroke relative to the
741     /// baseline in font design units.
y_strikeout_position(&self) -> i16742     pub fn y_strikeout_position(&self) -> i16 {
743         let range = self.shape.y_strikeout_position_byte_range();
744         self.data.read_at(range.start).unwrap()
745     }
746 
747     /// [Font-family class and subclass](https://learn.microsoft.com/en-us/typography/opentype/spec/os2#sfamilyclass).
748     /// This parameter is a classification of font-family design.
s_family_class(&self) -> i16749     pub fn s_family_class(&self) -> i16 {
750         let range = self.shape.s_family_class_byte_range();
751         self.data.read_at(range.start).unwrap()
752     }
753 
754     /// [PANOSE classification number](https://learn.microsoft.com/en-us/typography/opentype/spec/os2#panose).
755     ///
756     /// Additional specifications are required for PANOSE to classify non-Latin
757     /// character sets.
panose_10(&self) -> &'a [u8]758     pub fn panose_10(&self) -> &'a [u8] {
759         let range = self.shape.panose_10_byte_range();
760         self.data.read_array(range).unwrap()
761     }
762 
763     /// [Unicode Character Range](https://learn.microsoft.com/en-us/typography/opentype/spec/os2#ulunicoderange1-bits-031ulunicoderange2-bits-3263ulunicoderange3-bits-6495ulunicoderange4-bits-96127).
764     ///
765     /// Unicode Character Range (bits 0-31).
ul_unicode_range_1(&self) -> u32766     pub fn ul_unicode_range_1(&self) -> u32 {
767         let range = self.shape.ul_unicode_range_1_byte_range();
768         self.data.read_at(range.start).unwrap()
769     }
770 
771     /// Unicode Character Range (bits 32-63).
ul_unicode_range_2(&self) -> u32772     pub fn ul_unicode_range_2(&self) -> u32 {
773         let range = self.shape.ul_unicode_range_2_byte_range();
774         self.data.read_at(range.start).unwrap()
775     }
776 
777     /// Unicode Character Range (bits 64-95).
ul_unicode_range_3(&self) -> u32778     pub fn ul_unicode_range_3(&self) -> u32 {
779         let range = self.shape.ul_unicode_range_3_byte_range();
780         self.data.read_at(range.start).unwrap()
781     }
782 
783     /// Unicode Character Range (bits 96-127).
ul_unicode_range_4(&self) -> u32784     pub fn ul_unicode_range_4(&self) -> u32 {
785         let range = self.shape.ul_unicode_range_4_byte_range();
786         self.data.read_at(range.start).unwrap()
787     }
788 
789     /// [Font Vendor Identification](https://learn.microsoft.com/en-us/typography/opentype/spec/os2#achvendid).
790     ///
791     /// The four-character identifier for the vendor of the given type face.
ach_vend_id(&self) -> Tag792     pub fn ach_vend_id(&self) -> Tag {
793         let range = self.shape.ach_vend_id_byte_range();
794         self.data.read_at(range.start).unwrap()
795     }
796 
797     /// [Font selection flags](https://learn.microsoft.com/en-us/typography/opentype/spec/os2#fsselection).
798     ///
799     /// Contains information concerning the nature of the font patterns.
fs_selection(&self) -> SelectionFlags800     pub fn fs_selection(&self) -> SelectionFlags {
801         let range = self.shape.fs_selection_byte_range();
802         self.data.read_at(range.start).unwrap()
803     }
804 
805     /// The minimum Unicode index (character code) in this font.
us_first_char_index(&self) -> u16806     pub fn us_first_char_index(&self) -> u16 {
807         let range = self.shape.us_first_char_index_byte_range();
808         self.data.read_at(range.start).unwrap()
809     }
810 
811     /// The maximum Unicode index (character code) in this font.
us_last_char_index(&self) -> u16812     pub fn us_last_char_index(&self) -> u16 {
813         let range = self.shape.us_last_char_index_byte_range();
814         self.data.read_at(range.start).unwrap()
815     }
816 
817     /// The typographic ascender for this font.
s_typo_ascender(&self) -> i16818     pub fn s_typo_ascender(&self) -> i16 {
819         let range = self.shape.s_typo_ascender_byte_range();
820         self.data.read_at(range.start).unwrap()
821     }
822 
823     /// The typographic descender for this font.
s_typo_descender(&self) -> i16824     pub fn s_typo_descender(&self) -> i16 {
825         let range = self.shape.s_typo_descender_byte_range();
826         self.data.read_at(range.start).unwrap()
827     }
828 
829     /// The typographic line gap for this font.
s_typo_line_gap(&self) -> i16830     pub fn s_typo_line_gap(&self) -> i16 {
831         let range = self.shape.s_typo_line_gap_byte_range();
832         self.data.read_at(range.start).unwrap()
833     }
834 
835     /// The “Windows ascender” metric.
836     ///
837     /// This should be used to specify the height above the baseline for a
838     /// clipping region.
us_win_ascent(&self) -> u16839     pub fn us_win_ascent(&self) -> u16 {
840         let range = self.shape.us_win_ascent_byte_range();
841         self.data.read_at(range.start).unwrap()
842     }
843 
844     /// The “Windows descender” metric.
845     ///
846     /// This should be used to specify the vertical extent below the baseline
847     /// for a clipping region.
us_win_descent(&self) -> u16848     pub fn us_win_descent(&self) -> u16 {
849         let range = self.shape.us_win_descent_byte_range();
850         self.data.read_at(range.start).unwrap()
851     }
852 
853     /// Code page character range bits 0-31.
ul_code_page_range_1(&self) -> Option<u32>854     pub fn ul_code_page_range_1(&self) -> Option<u32> {
855         let range = self.shape.ul_code_page_range_1_byte_range()?;
856         Some(self.data.read_at(range.start).unwrap())
857     }
858 
859     /// Code page character range bits 32-63.
ul_code_page_range_2(&self) -> Option<u32>860     pub fn ul_code_page_range_2(&self) -> Option<u32> {
861         let range = self.shape.ul_code_page_range_2_byte_range()?;
862         Some(self.data.read_at(range.start).unwrap())
863     }
864 
865     /// This metric specifies the distance between the baseline and the
866     /// approximate height of non-ascending lowercase letters measured in
867     /// FUnits.
sx_height(&self) -> Option<i16>868     pub fn sx_height(&self) -> Option<i16> {
869         let range = self.shape.sx_height_byte_range()?;
870         Some(self.data.read_at(range.start).unwrap())
871     }
872 
873     /// This metric specifies the distance between the baseline and the
874     /// approximate height of uppercase letters measured in FUnits.
s_cap_height(&self) -> Option<i16>875     pub fn s_cap_height(&self) -> Option<i16> {
876         let range = self.shape.s_cap_height_byte_range()?;
877         Some(self.data.read_at(range.start).unwrap())
878     }
879 
880     /// This is the Unicode code point, in UTF-16 encoding, of a character that
881     /// can be used for a default glyph.
us_default_char(&self) -> Option<u16>882     pub fn us_default_char(&self) -> Option<u16> {
883         let range = self.shape.us_default_char_byte_range()?;
884         Some(self.data.read_at(range.start).unwrap())
885     }
886 
887     /// his is the Unicode code point, in UTF-16 encoding, of a character that
888     /// can be used as a default break character.
us_break_char(&self) -> Option<u16>889     pub fn us_break_char(&self) -> Option<u16> {
890         let range = self.shape.us_break_char_byte_range()?;
891         Some(self.data.read_at(range.start).unwrap())
892     }
893 
894     /// This field is used for fonts with multiple optical styles.
us_max_context(&self) -> Option<u16>895     pub fn us_max_context(&self) -> Option<u16> {
896         let range = self.shape.us_max_context_byte_range()?;
897         Some(self.data.read_at(range.start).unwrap())
898     }
899 
900     /// This field is used for fonts with multiple optical styles.
us_lower_optical_point_size(&self) -> Option<u16>901     pub fn us_lower_optical_point_size(&self) -> Option<u16> {
902         let range = self.shape.us_lower_optical_point_size_byte_range()?;
903         Some(self.data.read_at(range.start).unwrap())
904     }
905 
906     /// This field is used for fonts with multiple optical styles.
us_upper_optical_point_size(&self) -> Option<u16>907     pub fn us_upper_optical_point_size(&self) -> Option<u16> {
908         let range = self.shape.us_upper_optical_point_size_byte_range()?;
909         Some(self.data.read_at(range.start).unwrap())
910     }
911 }
912 
913 #[cfg(feature = "traversal")]
914 impl<'a> SomeTable<'a> for Os2<'a> {
type_name(&self) -> &str915     fn type_name(&self) -> &str {
916         "Os2"
917     }
get_field(&self, idx: usize) -> Option<Field<'a>>918     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
919         let version = self.version();
920         match idx {
921             0usize => Some(Field::new("version", self.version())),
922             1usize => Some(Field::new("x_avg_char_width", self.x_avg_char_width())),
923             2usize => Some(Field::new("us_weight_class", self.us_weight_class())),
924             3usize => Some(Field::new("us_width_class", self.us_width_class())),
925             4usize => Some(Field::new("fs_type", self.fs_type())),
926             5usize => Some(Field::new("y_subscript_x_size", self.y_subscript_x_size())),
927             6usize => Some(Field::new("y_subscript_y_size", self.y_subscript_y_size())),
928             7usize => Some(Field::new(
929                 "y_subscript_x_offset",
930                 self.y_subscript_x_offset(),
931             )),
932             8usize => Some(Field::new(
933                 "y_subscript_y_offset",
934                 self.y_subscript_y_offset(),
935             )),
936             9usize => Some(Field::new(
937                 "y_superscript_x_size",
938                 self.y_superscript_x_size(),
939             )),
940             10usize => Some(Field::new(
941                 "y_superscript_y_size",
942                 self.y_superscript_y_size(),
943             )),
944             11usize => Some(Field::new(
945                 "y_superscript_x_offset",
946                 self.y_superscript_x_offset(),
947             )),
948             12usize => Some(Field::new(
949                 "y_superscript_y_offset",
950                 self.y_superscript_y_offset(),
951             )),
952             13usize => Some(Field::new("y_strikeout_size", self.y_strikeout_size())),
953             14usize => Some(Field::new(
954                 "y_strikeout_position",
955                 self.y_strikeout_position(),
956             )),
957             15usize => Some(Field::new("s_family_class", self.s_family_class())),
958             16usize => Some(Field::new("panose_10", self.panose_10())),
959             17usize => Some(Field::new("ul_unicode_range_1", self.ul_unicode_range_1())),
960             18usize => Some(Field::new("ul_unicode_range_2", self.ul_unicode_range_2())),
961             19usize => Some(Field::new("ul_unicode_range_3", self.ul_unicode_range_3())),
962             20usize => Some(Field::new("ul_unicode_range_4", self.ul_unicode_range_4())),
963             21usize => Some(Field::new("ach_vend_id", self.ach_vend_id())),
964             22usize => Some(Field::new("fs_selection", self.fs_selection())),
965             23usize => Some(Field::new(
966                 "us_first_char_index",
967                 self.us_first_char_index(),
968             )),
969             24usize => Some(Field::new("us_last_char_index", self.us_last_char_index())),
970             25usize => Some(Field::new("s_typo_ascender", self.s_typo_ascender())),
971             26usize => Some(Field::new("s_typo_descender", self.s_typo_descender())),
972             27usize => Some(Field::new("s_typo_line_gap", self.s_typo_line_gap())),
973             28usize => Some(Field::new("us_win_ascent", self.us_win_ascent())),
974             29usize => Some(Field::new("us_win_descent", self.us_win_descent())),
975             30usize if version.compatible(1) => Some(Field::new(
976                 "ul_code_page_range_1",
977                 self.ul_code_page_range_1().unwrap(),
978             )),
979             31usize if version.compatible(1) => Some(Field::new(
980                 "ul_code_page_range_2",
981                 self.ul_code_page_range_2().unwrap(),
982             )),
983             32usize if version.compatible(2) => {
984                 Some(Field::new("sx_height", self.sx_height().unwrap()))
985             }
986             33usize if version.compatible(2) => {
987                 Some(Field::new("s_cap_height", self.s_cap_height().unwrap()))
988             }
989             34usize if version.compatible(2) => Some(Field::new(
990                 "us_default_char",
991                 self.us_default_char().unwrap(),
992             )),
993             35usize if version.compatible(2) => {
994                 Some(Field::new("us_break_char", self.us_break_char().unwrap()))
995             }
996             36usize if version.compatible(2) => {
997                 Some(Field::new("us_max_context", self.us_max_context().unwrap()))
998             }
999             37usize if version.compatible(5) => Some(Field::new(
1000                 "us_lower_optical_point_size",
1001                 self.us_lower_optical_point_size().unwrap(),
1002             )),
1003             38usize if version.compatible(5) => Some(Field::new(
1004                 "us_upper_optical_point_size",
1005                 self.us_upper_optical_point_size().unwrap(),
1006             )),
1007             _ => None,
1008         }
1009     }
1010 }
1011 
1012 #[cfg(feature = "traversal")]
1013 impl<'a> std::fmt::Debug for Os2<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1014     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1015         (self as &dyn SomeTable<'a>).fmt(f)
1016     }
1017 }
1018