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