Skip to main content

read_fonts/generated/
generated_os2.rs

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