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
354impl<'a> MinByteRange<'a> for Os2<'a> {
355    fn min_byte_range(&self) -> Range<usize> {
356        0..self.us_win_descent_byte_range().end
357    }
358    fn min_table_bytes(&self) -> &'a [u8] {
359        let range = self.min_byte_range();
360        self.offset_data().as_bytes().get(range).unwrap_or_default()
361    }
362}
363
364impl TopLevelTable for Os2<'_> {
365    /// `OS/2`
366    const TAG: Tag = Tag::new(b"OS/2");
367}
368
369impl ReadArgs for Os2<'_> {
370    type Args = ();
371}
372
373impl<'a> FontRead<'a> for Os2<'a> {
374    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
375        #[allow(clippy::absurd_extreme_comparisons)]
376        if data.len() < Self::MIN_SIZE {
377            return Err(ReadError::OutOfBounds);
378        }
379        let Some(data) = TableDataRef::new(data.as_bytes()) else {
380            return Err(ReadError::OutOfBounds);
381        };
382        Ok(Self { data })
383    }
384}
385
386/// The fields at the start of the table, which are read directly.
387#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
388#[repr(C, packed)]
389#[doc(hidden)]
390pub struct Os2FixedHeader {
391    pub version: BigEndian<u16>,
392    pub x_avg_char_width: BigEndian<i16>,
393    pub us_weight_class: BigEndian<u16>,
394    pub us_width_class: BigEndian<u16>,
395    pub fs_type: BigEndian<u16>,
396    pub y_subscript_x_size: BigEndian<i16>,
397    pub y_subscript_y_size: BigEndian<i16>,
398    pub y_subscript_x_offset: BigEndian<i16>,
399    pub y_subscript_y_offset: BigEndian<i16>,
400    pub y_superscript_x_size: BigEndian<i16>,
401    pub y_superscript_y_size: BigEndian<i16>,
402    pub y_superscript_x_offset: BigEndian<i16>,
403    pub y_superscript_y_offset: BigEndian<i16>,
404    pub y_strikeout_size: BigEndian<i16>,
405    pub y_strikeout_position: BigEndian<i16>,
406    pub s_family_class: BigEndian<i16>,
407}
408
409#[allow(clippy::absurd_extreme_comparisons)]
410const _: () = assert!(std::mem::size_of::<Os2FixedHeader>() <= Os2::MIN_SIZE);
411
412/// [`OS/2`](https://docs.microsoft.com/en-us/typography/opentype/spec/os2)
413#[derive(Clone)]
414pub struct Os2<'a> {
415    data: TableDataRef<'a, Os2FixedHeader>,
416}
417
418#[allow(clippy::needless_lifetimes)]
419impl<'a> Os2<'a> {
420    pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN
421        + i16::RAW_BYTE_LEN
422        + u16::RAW_BYTE_LEN
423        + u16::RAW_BYTE_LEN
424        + u16::RAW_BYTE_LEN
425        + i16::RAW_BYTE_LEN
426        + i16::RAW_BYTE_LEN
427        + i16::RAW_BYTE_LEN
428        + i16::RAW_BYTE_LEN
429        + i16::RAW_BYTE_LEN
430        + i16::RAW_BYTE_LEN
431        + i16::RAW_BYTE_LEN
432        + i16::RAW_BYTE_LEN
433        + i16::RAW_BYTE_LEN
434        + i16::RAW_BYTE_LEN
435        + i16::RAW_BYTE_LEN
436        + u8::RAW_BYTE_LEN * 10_usize
437        + u32::RAW_BYTE_LEN
438        + u32::RAW_BYTE_LEN
439        + u32::RAW_BYTE_LEN
440        + u32::RAW_BYTE_LEN
441        + Tag::RAW_BYTE_LEN
442        + SelectionFlags::RAW_BYTE_LEN
443        + u16::RAW_BYTE_LEN
444        + u16::RAW_BYTE_LEN
445        + i16::RAW_BYTE_LEN
446        + i16::RAW_BYTE_LEN
447        + i16::RAW_BYTE_LEN
448        + u16::RAW_BYTE_LEN
449        + u16::RAW_BYTE_LEN);
450    basic_table_impls!(impl_the_methods);
451
452    pub fn version(&self) -> u16 {
453        self.data.header().version.get()
454    }
455
456    /// [Average weighted escapement](https://learn.microsoft.com/en-us/typography/opentype/spec/os2#xavgcharwidth).
457    ///
458    /// The Average Character Width parameter specifies the arithmetic average
459    /// of the escapement (width) of all non-zero width glyphs in the font.
460    pub fn x_avg_char_width(&self) -> i16 {
461        self.data.header().x_avg_char_width.get()
462    }
463
464    /// [Weight class](https://learn.microsoft.com/en-us/typography/opentype/spec/os2#usweightclass).
465    ///
466    /// Indicates the visual weight (degree of blackness or thickness of
467    /// strokes) of the characters in the font. Values from 1 to 1000 are valid.
468    pub fn us_weight_class(&self) -> u16 {
469        self.data.header().us_weight_class.get()
470    }
471
472    /// [Width class](https://learn.microsoft.com/en-us/typography/opentype/spec/os2#uswidthclass).
473    ///
474    /// Indicates a relative change from the normal aspect ratio (width to height
475    /// ratio) as specified by a font designer for the glyphs in a font.
476    pub fn us_width_class(&self) -> u16 {
477        self.data.header().us_width_class.get()
478    }
479
480    /// [Type flags](https://learn.microsoft.com/en-us/typography/opentype/spec/os2#fstype).
481    ///
482    /// Indicates font embedding licensing rights for the font.
483    pub fn fs_type(&self) -> u16 {
484        self.data.header().fs_type.get()
485    }
486
487    /// The recommended horizontal size in font design units for subscripts for
488    /// this font.
489    pub fn y_subscript_x_size(&self) -> i16 {
490        self.data.header().y_subscript_x_size.get()
491    }
492
493    /// The recommended vertical size in font design units for subscripts for
494    /// this font.
495    pub fn y_subscript_y_size(&self) -> i16 {
496        self.data.header().y_subscript_y_size.get()
497    }
498
499    /// The recommended horizontal offset in font design units for subscripts
500    /// for this font.
501    pub fn y_subscript_x_offset(&self) -> i16 {
502        self.data.header().y_subscript_x_offset.get()
503    }
504
505    /// The recommended vertical offset in font design units for subscripts
506    /// for this font.
507    pub fn y_subscript_y_offset(&self) -> i16 {
508        self.data.header().y_subscript_y_offset.get()
509    }
510
511    /// The recommended horizontal size in font design units for superscripts
512    /// for this font.
513    pub fn y_superscript_x_size(&self) -> i16 {
514        self.data.header().y_superscript_x_size.get()
515    }
516
517    /// The recommended vertical size in font design units for superscripts
518    /// for this font.
519    pub fn y_superscript_y_size(&self) -> i16 {
520        self.data.header().y_superscript_y_size.get()
521    }
522
523    /// The recommended horizontal offset in font design units for superscripts
524    /// for this font.
525    pub fn y_superscript_x_offset(&self) -> i16 {
526        self.data.header().y_superscript_x_offset.get()
527    }
528
529    /// The recommended vertical offset in font design units for superscripts
530    /// for this font.
531    pub fn y_superscript_y_offset(&self) -> i16 {
532        self.data.header().y_superscript_y_offset.get()
533    }
534
535    /// Thickness of the strikeout stroke in font design units.
536    pub fn y_strikeout_size(&self) -> i16 {
537        self.data.header().y_strikeout_size.get()
538    }
539
540    /// The position of the top of the strikeout stroke relative to the
541    /// baseline in font design units.
542    pub fn y_strikeout_position(&self) -> i16 {
543        self.data.header().y_strikeout_position.get()
544    }
545
546    /// [Font-family class and subclass](https://learn.microsoft.com/en-us/typography/opentype/spec/os2#sfamilyclass).
547    /// This parameter is a classification of font-family design.
548    pub fn s_family_class(&self) -> i16 {
549        self.data.header().s_family_class.get()
550    }
551
552    /// [PANOSE classification number](https://learn.microsoft.com/en-us/typography/opentype/spec/os2#panose).
553    ///
554    /// Additional specifications are required for PANOSE to classify non-Latin
555    /// character sets.
556    pub fn panose_10(&self) -> &'a [u8] {
557        let range = self.panose_10_byte_range();
558        self.offset_data()
559            .read_array(range)
560            .ok()
561            .unwrap_or_default()
562    }
563
564    /// [Unicode Character Range](https://learn.microsoft.com/en-us/typography/opentype/spec/os2#ulunicoderange1-bits-031ulunicoderange2-bits-3263ulunicoderange3-bits-6495ulunicoderange4-bits-96127).
565    ///
566    /// Unicode Character Range (bits 0-31).
567    pub fn ul_unicode_range_1(&self) -> u32 {
568        let range = self.ul_unicode_range_1_byte_range();
569        self.offset_data()
570            .read_at(range.start)
571            .ok()
572            .unwrap_or_default()
573    }
574
575    /// Unicode Character Range (bits 32-63).
576    pub fn ul_unicode_range_2(&self) -> u32 {
577        let range = self.ul_unicode_range_2_byte_range();
578        self.offset_data()
579            .read_at(range.start)
580            .ok()
581            .unwrap_or_default()
582    }
583
584    /// Unicode Character Range (bits 64-95).
585    pub fn ul_unicode_range_3(&self) -> u32 {
586        let range = self.ul_unicode_range_3_byte_range();
587        self.offset_data()
588            .read_at(range.start)
589            .ok()
590            .unwrap_or_default()
591    }
592
593    /// Unicode Character Range (bits 96-127).
594    pub fn ul_unicode_range_4(&self) -> u32 {
595        let range = self.ul_unicode_range_4_byte_range();
596        self.offset_data()
597            .read_at(range.start)
598            .ok()
599            .unwrap_or_default()
600    }
601
602    /// [Font Vendor Identification](https://learn.microsoft.com/en-us/typography/opentype/spec/os2#achvendid).
603    ///
604    /// The four-character identifier for the vendor of the given type face.
605    pub fn ach_vend_id(&self) -> Tag {
606        let range = self.ach_vend_id_byte_range();
607        self.offset_data()
608            .read_at(range.start)
609            .ok()
610            .unwrap_or_default()
611    }
612
613    /// [Font selection flags](https://learn.microsoft.com/en-us/typography/opentype/spec/os2#fsselection).
614    ///
615    /// Contains information concerning the nature of the font patterns.
616    pub fn fs_selection(&self) -> SelectionFlags {
617        let range = self.fs_selection_byte_range();
618        self.offset_data()
619            .read_at(range.start)
620            .ok()
621            .unwrap_or_default()
622    }
623
624    /// The minimum Unicode index (character code) in this font.
625    pub fn us_first_char_index(&self) -> u16 {
626        let range = self.us_first_char_index_byte_range();
627        self.offset_data()
628            .read_at(range.start)
629            .ok()
630            .unwrap_or_default()
631    }
632
633    /// The maximum Unicode index (character code) in this font.
634    pub fn us_last_char_index(&self) -> u16 {
635        let range = self.us_last_char_index_byte_range();
636        self.offset_data()
637            .read_at(range.start)
638            .ok()
639            .unwrap_or_default()
640    }
641
642    /// The typographic ascender for this font.
643    pub fn s_typo_ascender(&self) -> i16 {
644        let range = self.s_typo_ascender_byte_range();
645        self.offset_data()
646            .read_at(range.start)
647            .ok()
648            .unwrap_or_default()
649    }
650
651    /// The typographic descender for this font.
652    pub fn s_typo_descender(&self) -> i16 {
653        let range = self.s_typo_descender_byte_range();
654        self.offset_data()
655            .read_at(range.start)
656            .ok()
657            .unwrap_or_default()
658    }
659
660    /// The typographic line gap for this font.
661    pub fn s_typo_line_gap(&self) -> i16 {
662        let range = self.s_typo_line_gap_byte_range();
663        self.offset_data()
664            .read_at(range.start)
665            .ok()
666            .unwrap_or_default()
667    }
668
669    /// The “Windows ascender” metric.
670    ///
671    /// This should be used to specify the height above the baseline for a
672    /// clipping region.
673    pub fn us_win_ascent(&self) -> u16 {
674        let range = self.us_win_ascent_byte_range();
675        self.offset_data()
676            .read_at(range.start)
677            .ok()
678            .unwrap_or_default()
679    }
680
681    /// The “Windows descender” metric.
682    ///
683    /// This should be used to specify the vertical extent below the baseline
684    /// for a clipping region.
685    pub fn us_win_descent(&self) -> u16 {
686        let range = self.us_win_descent_byte_range();
687        self.offset_data()
688            .read_at(range.start)
689            .ok()
690            .unwrap_or_default()
691    }
692
693    /// Code page character range bits 0-31.
694    pub fn ul_code_page_range_1(&self) -> Option<u32> {
695        let range = self.ul_code_page_range_1_byte_range();
696        (!range.is_empty())
697            .then(|| self.offset_data().read_at(range.start).ok())
698            .flatten()
699    }
700
701    /// Code page character range bits 32-63.
702    pub fn ul_code_page_range_2(&self) -> Option<u32> {
703        let range = self.ul_code_page_range_2_byte_range();
704        (!range.is_empty())
705            .then(|| self.offset_data().read_at(range.start).ok())
706            .flatten()
707    }
708
709    /// This metric specifies the distance between the baseline and the
710    /// approximate height of non-ascending lowercase letters measured in
711    /// FUnits.
712    pub fn sx_height(&self) -> Option<i16> {
713        let range = self.sx_height_byte_range();
714        (!range.is_empty())
715            .then(|| self.offset_data().read_at(range.start).ok())
716            .flatten()
717    }
718
719    /// This metric specifies the distance between the baseline and the
720    /// approximate height of uppercase letters measured in FUnits.
721    pub fn s_cap_height(&self) -> Option<i16> {
722        let range = self.s_cap_height_byte_range();
723        (!range.is_empty())
724            .then(|| self.offset_data().read_at(range.start).ok())
725            .flatten()
726    }
727
728    /// This is the Unicode codepoint, in UTF-16 encoding, of a character that
729    /// can be used for a default glyph.
730    pub fn us_default_char(&self) -> Option<u16> {
731        let range = self.us_default_char_byte_range();
732        (!range.is_empty())
733            .then(|| self.offset_data().read_at(range.start).ok())
734            .flatten()
735    }
736
737    /// This is the Unicode codepoint, in UTF-16 encoding, of a character that
738    /// can be used as a default break character.
739    pub fn us_break_char(&self) -> Option<u16> {
740        let range = self.us_break_char_byte_range();
741        (!range.is_empty())
742            .then(|| self.offset_data().read_at(range.start).ok())
743            .flatten()
744    }
745
746    /// This field is used for fonts with multiple optical styles.
747    pub fn us_max_context(&self) -> Option<u16> {
748        let range = self.us_max_context_byte_range();
749        (!range.is_empty())
750            .then(|| self.offset_data().read_at(range.start).ok())
751            .flatten()
752    }
753
754    /// This field is used for fonts with multiple optical styles.
755    pub fn us_lower_optical_point_size(&self) -> Option<u16> {
756        let range = self.us_lower_optical_point_size_byte_range();
757        (!range.is_empty())
758            .then(|| self.offset_data().read_at(range.start).ok())
759            .flatten()
760    }
761
762    /// This field is used for fonts with multiple optical styles.
763    pub fn us_upper_optical_point_size(&self) -> Option<u16> {
764        let range = self.us_upper_optical_point_size_byte_range();
765        (!range.is_empty())
766            .then(|| self.offset_data().read_at(range.start).ok())
767            .flatten()
768    }
769
770    pub fn version_byte_range(&self) -> Range<usize> {
771        let start = 0;
772        let end = start + u16::RAW_BYTE_LEN;
773        start..end
774    }
775
776    pub fn x_avg_char_width_byte_range(&self) -> Range<usize> {
777        let start = self.version_byte_range().end;
778        let end = start + i16::RAW_BYTE_LEN;
779        start..end
780    }
781
782    pub fn us_weight_class_byte_range(&self) -> Range<usize> {
783        let start = self.x_avg_char_width_byte_range().end;
784        let end = start + u16::RAW_BYTE_LEN;
785        start..end
786    }
787
788    pub fn us_width_class_byte_range(&self) -> Range<usize> {
789        let start = self.us_weight_class_byte_range().end;
790        let end = start + u16::RAW_BYTE_LEN;
791        start..end
792    }
793
794    pub fn fs_type_byte_range(&self) -> Range<usize> {
795        let start = self.us_width_class_byte_range().end;
796        let end = start + u16::RAW_BYTE_LEN;
797        start..end
798    }
799
800    pub fn y_subscript_x_size_byte_range(&self) -> Range<usize> {
801        let start = self.fs_type_byte_range().end;
802        let end = start + i16::RAW_BYTE_LEN;
803        start..end
804    }
805
806    pub fn y_subscript_y_size_byte_range(&self) -> Range<usize> {
807        let start = self.y_subscript_x_size_byte_range().end;
808        let end = start + i16::RAW_BYTE_LEN;
809        start..end
810    }
811
812    pub fn y_subscript_x_offset_byte_range(&self) -> Range<usize> {
813        let start = self.y_subscript_y_size_byte_range().end;
814        let end = start + i16::RAW_BYTE_LEN;
815        start..end
816    }
817
818    pub fn y_subscript_y_offset_byte_range(&self) -> Range<usize> {
819        let start = self.y_subscript_x_offset_byte_range().end;
820        let end = start + i16::RAW_BYTE_LEN;
821        start..end
822    }
823
824    pub fn y_superscript_x_size_byte_range(&self) -> Range<usize> {
825        let start = self.y_subscript_y_offset_byte_range().end;
826        let end = start + i16::RAW_BYTE_LEN;
827        start..end
828    }
829
830    pub fn y_superscript_y_size_byte_range(&self) -> Range<usize> {
831        let start = self.y_superscript_x_size_byte_range().end;
832        let end = start + i16::RAW_BYTE_LEN;
833        start..end
834    }
835
836    pub fn y_superscript_x_offset_byte_range(&self) -> Range<usize> {
837        let start = self.y_superscript_y_size_byte_range().end;
838        let end = start + i16::RAW_BYTE_LEN;
839        start..end
840    }
841
842    pub fn y_superscript_y_offset_byte_range(&self) -> Range<usize> {
843        let start = self.y_superscript_x_offset_byte_range().end;
844        let end = start + i16::RAW_BYTE_LEN;
845        start..end
846    }
847
848    pub fn y_strikeout_size_byte_range(&self) -> Range<usize> {
849        let start = self.y_superscript_y_offset_byte_range().end;
850        let end = start + i16::RAW_BYTE_LEN;
851        start..end
852    }
853
854    pub fn y_strikeout_position_byte_range(&self) -> Range<usize> {
855        let start = self.y_strikeout_size_byte_range().end;
856        let end = start + i16::RAW_BYTE_LEN;
857        start..end
858    }
859
860    pub fn s_family_class_byte_range(&self) -> Range<usize> {
861        let start = self.y_strikeout_position_byte_range().end;
862        let end = start + i16::RAW_BYTE_LEN;
863        start..end
864    }
865
866    pub fn panose_10_byte_range(&self) -> Range<usize> {
867        let start = self.s_family_class_byte_range().end;
868        let end = start + (10_usize).saturating_mul(u8::RAW_BYTE_LEN);
869        start..end
870    }
871
872    pub fn ul_unicode_range_1_byte_range(&self) -> Range<usize> {
873        let start = self.panose_10_byte_range().end;
874        let end = start + u32::RAW_BYTE_LEN;
875        start..end
876    }
877
878    pub fn ul_unicode_range_2_byte_range(&self) -> Range<usize> {
879        let start = self.ul_unicode_range_1_byte_range().end;
880        let end = start + u32::RAW_BYTE_LEN;
881        start..end
882    }
883
884    pub fn ul_unicode_range_3_byte_range(&self) -> Range<usize> {
885        let start = self.ul_unicode_range_2_byte_range().end;
886        let end = start + u32::RAW_BYTE_LEN;
887        start..end
888    }
889
890    pub fn ul_unicode_range_4_byte_range(&self) -> Range<usize> {
891        let start = self.ul_unicode_range_3_byte_range().end;
892        let end = start + u32::RAW_BYTE_LEN;
893        start..end
894    }
895
896    pub fn ach_vend_id_byte_range(&self) -> Range<usize> {
897        let start = self.ul_unicode_range_4_byte_range().end;
898        let end = start + Tag::RAW_BYTE_LEN;
899        start..end
900    }
901
902    pub fn fs_selection_byte_range(&self) -> Range<usize> {
903        let start = self.ach_vend_id_byte_range().end;
904        let end = start + SelectionFlags::RAW_BYTE_LEN;
905        start..end
906    }
907
908    pub fn us_first_char_index_byte_range(&self) -> Range<usize> {
909        let start = self.fs_selection_byte_range().end;
910        let end = start + u16::RAW_BYTE_LEN;
911        start..end
912    }
913
914    pub fn us_last_char_index_byte_range(&self) -> Range<usize> {
915        let start = self.us_first_char_index_byte_range().end;
916        let end = start + u16::RAW_BYTE_LEN;
917        start..end
918    }
919
920    pub fn s_typo_ascender_byte_range(&self) -> Range<usize> {
921        let start = self.us_last_char_index_byte_range().end;
922        let end = start + i16::RAW_BYTE_LEN;
923        start..end
924    }
925
926    pub fn s_typo_descender_byte_range(&self) -> Range<usize> {
927        let start = self.s_typo_ascender_byte_range().end;
928        let end = start + i16::RAW_BYTE_LEN;
929        start..end
930    }
931
932    pub fn s_typo_line_gap_byte_range(&self) -> Range<usize> {
933        let start = self.s_typo_descender_byte_range().end;
934        let end = start + i16::RAW_BYTE_LEN;
935        start..end
936    }
937
938    pub fn us_win_ascent_byte_range(&self) -> Range<usize> {
939        let start = self.s_typo_line_gap_byte_range().end;
940        let end = start + u16::RAW_BYTE_LEN;
941        start..end
942    }
943
944    pub fn us_win_descent_byte_range(&self) -> Range<usize> {
945        let start = self.us_win_ascent_byte_range().end;
946        let end = start + u16::RAW_BYTE_LEN;
947        start..end
948    }
949
950    pub fn ul_code_page_range_1_byte_range(&self) -> Range<usize> {
951        let start = self.us_win_descent_byte_range().end;
952        let end = if self.version().compatible(1u16) {
953            start + u32::RAW_BYTE_LEN
954        } else {
955            start
956        };
957        start..end
958    }
959
960    pub fn ul_code_page_range_2_byte_range(&self) -> Range<usize> {
961        let start = self.ul_code_page_range_1_byte_range().end;
962        let end = if self.version().compatible(1u16) {
963            start + u32::RAW_BYTE_LEN
964        } else {
965            start
966        };
967        start..end
968    }
969
970    pub fn sx_height_byte_range(&self) -> Range<usize> {
971        let start = self.ul_code_page_range_2_byte_range().end;
972        let end = if self.version().compatible(2u16) {
973            start + i16::RAW_BYTE_LEN
974        } else {
975            start
976        };
977        start..end
978    }
979
980    pub fn s_cap_height_byte_range(&self) -> Range<usize> {
981        let start = self.sx_height_byte_range().end;
982        let end = if self.version().compatible(2u16) {
983            start + i16::RAW_BYTE_LEN
984        } else {
985            start
986        };
987        start..end
988    }
989
990    pub fn us_default_char_byte_range(&self) -> Range<usize> {
991        let start = self.s_cap_height_byte_range().end;
992        let end = if self.version().compatible(2u16) {
993            start + u16::RAW_BYTE_LEN
994        } else {
995            start
996        };
997        start..end
998    }
999
1000    pub fn us_break_char_byte_range(&self) -> Range<usize> {
1001        let start = self.us_default_char_byte_range().end;
1002        let end = if self.version().compatible(2u16) {
1003            start + u16::RAW_BYTE_LEN
1004        } else {
1005            start
1006        };
1007        start..end
1008    }
1009
1010    pub fn us_max_context_byte_range(&self) -> Range<usize> {
1011        let start = self.us_break_char_byte_range().end;
1012        let end = if self.version().compatible(2u16) {
1013            start + u16::RAW_BYTE_LEN
1014        } else {
1015            start
1016        };
1017        start..end
1018    }
1019
1020    pub fn us_lower_optical_point_size_byte_range(&self) -> Range<usize> {
1021        let start = self.us_max_context_byte_range().end;
1022        let end = if self.version().compatible(5u16) {
1023            start + u16::RAW_BYTE_LEN
1024        } else {
1025            start
1026        };
1027        start..end
1028    }
1029
1030    pub fn us_upper_optical_point_size_byte_range(&self) -> Range<usize> {
1031        let start = self.us_lower_optical_point_size_byte_range().end;
1032        let end = if self.version().compatible(5u16) {
1033            start + u16::RAW_BYTE_LEN
1034        } else {
1035            start
1036        };
1037        start..end
1038    }
1039}
1040
1041const _: () = assert!(FontData::default_data_long_enough(Os2::MIN_SIZE));
1042
1043impl Default for Os2<'_> {
1044    fn default() -> Self {
1045        Self {
1046            data: TableDataRef::new(FontData::default_table_data().as_bytes())
1047                .unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
1048        }
1049    }
1050}