Coverage Report

Created: 2026-10-24 07:19

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/read-fonts-0.46.0/generated/generated_os2.rs
Line
Count
Source
1
// THIS FILE IS AUTOGENERATED.
2
// Any changes to this file will be overwritten.
3
// For more information about how codegen works, see font-codegen/README.md
4
5
#[allow(unused_imports)]
6
use crate::codegen_prelude::*;
7
8
/// OS/2 [selection flags](https://learn.microsoft.com/en-us/typography/opentype/spec/os2#fsselection)
9
#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash, bytemuck :: AnyBitPattern)]
10
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
11
#[repr(transparent)]
12
pub struct SelectionFlags {
13
    bits: u16,
14
}
15
16
impl 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
52
impl SelectionFlags {
53
    ///  Returns an empty set of flags.
54
    #[inline]
55
0
    pub const fn empty() -> Self {
56
0
        Self { bits: 0 }
57
0
    }
58
59
    /// Returns the set containing all flags.
60
    #[inline]
61
945
    pub const fn all() -> Self {
62
945
        Self {
63
945
            bits: Self::ITALIC.bits
64
945
                | Self::UNDERSCORE.bits
65
945
                | Self::NEGATIVE.bits
66
945
                | Self::OUTLINED.bits
67
945
                | Self::STRIKEOUT.bits
68
945
                | Self::BOLD.bits
69
945
                | Self::REGULAR.bits
70
945
                | Self::USE_TYPO_METRICS.bits
71
945
                | Self::WWS.bits
72
945
                | Self::OBLIQUE.bits,
73
945
        }
74
945
    }
75
76
    /// Returns the raw value of the flags currently stored.
77
    #[inline]
78
0
    pub const fn bits(&self) -> u16 {
79
0
        self.bits
80
0
    }
81
82
    /// Convert from underlying bit representation, unless that
83
    /// representation contains bits that do not correspond to a flag.
84
    #[inline]
85
0
    pub const fn from_bits(bits: u16) -> Option<Self> {
86
0
        if (bits & !Self::all().bits()) == 0 {
87
0
            Some(Self { bits })
88
        } else {
89
0
            None
90
        }
91
0
    }
92
93
    /// Convert from underlying bit representation, dropping any bits
94
    /// that do not correspond to flags.
95
    #[inline]
96
945
    pub const fn from_bits_truncate(bits: u16) -> Self {
97
945
        Self {
98
945
            bits: bits & Self::all().bits,
99
945
        }
100
945
    }
101
102
    /// Returns `true` if no flags are currently stored.
103
    #[inline]
104
0
    pub const fn is_empty(&self) -> bool {
105
0
        self.bits() == Self::empty().bits()
106
0
    }
107
108
    /// Returns `true` if there are flags common to both `self` and `other`.
109
    #[inline]
110
0
    pub const fn intersects(&self, other: Self) -> bool {
111
0
        !(Self {
112
0
            bits: self.bits & other.bits,
113
0
        })
114
0
        .is_empty()
115
0
    }
116
117
    /// Returns `true` if all of the flags in `other` are contained within `self`.
118
    #[inline]
119
945
    pub const fn contains(&self, other: Self) -> bool {
120
945
        (self.bits & other.bits) == other.bits
121
945
    }
122
123
    /// Inserts the specified flags in-place.
124
    #[inline]
125
0
    pub fn insert(&mut self, other: Self) {
126
0
        self.bits |= other.bits;
127
0
    }
128
129
    /// Removes the specified flags in-place.
130
    #[inline]
131
0
    pub fn remove(&mut self, other: Self) {
132
0
        self.bits &= !other.bits;
133
0
    }
134
135
    /// Toggles the specified flags in-place.
136
    #[inline]
137
0
    pub fn toggle(&mut self, other: Self) {
138
0
        self.bits ^= other.bits;
139
0
    }
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
0
    pub const fn intersection(self, other: Self) -> Self {
154
0
        Self {
155
0
            bits: self.bits & other.bits,
156
0
        }
157
0
    }
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
0
    pub const fn union(self, other: Self) -> Self {
172
0
        Self {
173
0
            bits: self.bits | other.bits,
174
0
        }
175
0
    }
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
0
    pub const fn difference(self, other: Self) -> Self {
192
0
        Self {
193
0
            bits: self.bits & !other.bits,
194
0
        }
195
0
    }
196
}
197
198
impl std::ops::BitOr for SelectionFlags {
199
    type Output = Self;
200
201
    /// Returns the union of the two sets of flags.
202
    #[inline]
203
0
    fn bitor(self, other: SelectionFlags) -> Self {
204
0
        Self {
205
0
            bits: self.bits | other.bits,
206
0
        }
207
0
    }
208
}
209
210
impl std::ops::BitOrAssign for SelectionFlags {
211
    /// Adds the set of flags.
212
    #[inline]
213
0
    fn bitor_assign(&mut self, other: Self) {
214
0
        self.bits |= other.bits;
215
0
    }
216
}
217
218
impl 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
0
    fn bitxor(self, other: Self) -> Self {
224
0
        Self {
225
0
            bits: self.bits ^ other.bits,
226
0
        }
227
0
    }
228
}
229
230
impl std::ops::BitXorAssign for SelectionFlags {
231
    /// Toggles the set of flags.
232
    #[inline]
233
0
    fn bitxor_assign(&mut self, other: Self) {
234
0
        self.bits ^= other.bits;
235
0
    }
236
}
237
238
impl std::ops::BitAnd for SelectionFlags {
239
    type Output = Self;
240
241
    /// Returns the intersection between the two sets of flags.
242
    #[inline]
243
0
    fn bitand(self, other: Self) -> Self {
244
0
        Self {
245
0
            bits: self.bits & other.bits,
246
0
        }
247
0
    }
248
}
249
250
impl std::ops::BitAndAssign for SelectionFlags {
251
    /// Disables all flags disabled in the set.
252
    #[inline]
253
0
    fn bitand_assign(&mut self, other: Self) {
254
0
        self.bits &= other.bits;
255
0
    }
256
}
257
258
impl std::ops::Sub for SelectionFlags {
259
    type Output = Self;
260
261
    /// Returns the set difference of the two sets of flags.
262
    #[inline]
263
0
    fn sub(self, other: Self) -> Self {
264
0
        Self {
265
0
            bits: self.bits & !other.bits,
266
0
        }
267
0
    }
268
}
269
270
impl std::ops::SubAssign for SelectionFlags {
271
    /// Disables all flags enabled in the set.
272
    #[inline]
273
0
    fn sub_assign(&mut self, other: Self) {
274
0
        self.bits &= !other.bits;
275
0
    }
276
}
277
278
impl std::ops::Not for SelectionFlags {
279
    type Output = Self;
280
281
    /// Returns the complement of this set of flags.
282
    #[inline]
283
0
    fn not(self) -> Self {
284
0
        Self { bits: !self.bits } & Self::all()
285
0
    }
286
}
287
288
impl std::fmt::Debug for SelectionFlags {
289
0
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
290
0
        let members: &[(&str, Self)] = &[
291
0
            ("ITALIC", Self::ITALIC),
292
0
            ("UNDERSCORE", Self::UNDERSCORE),
293
0
            ("NEGATIVE", Self::NEGATIVE),
294
0
            ("OUTLINED", Self::OUTLINED),
295
0
            ("STRIKEOUT", Self::STRIKEOUT),
296
0
            ("BOLD", Self::BOLD),
297
0
            ("REGULAR", Self::REGULAR),
298
0
            ("USE_TYPO_METRICS", Self::USE_TYPO_METRICS),
299
0
            ("WWS", Self::WWS),
300
0
            ("OBLIQUE", Self::OBLIQUE),
301
0
        ];
302
0
        let mut first = true;
303
0
        for (name, value) in members {
304
0
            if self.contains(*value) {
305
0
                if !first {
306
0
                    f.write_str(" | ")?;
307
0
                }
308
0
                first = false;
309
0
                f.write_str(name)?;
310
0
            }
311
        }
312
0
        if first {
313
0
            f.write_str("(empty)")?;
314
0
        }
315
0
        Ok(())
316
0
    }
317
}
318
319
impl std::fmt::Binary for SelectionFlags {
320
0
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
321
0
        std::fmt::Binary::fmt(&self.bits, f)
322
0
    }
323
}
324
325
impl std::fmt::Octal for SelectionFlags {
326
0
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
327
0
        std::fmt::Octal::fmt(&self.bits, f)
328
0
    }
329
}
330
331
impl std::fmt::LowerHex for SelectionFlags {
332
0
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
333
0
        std::fmt::LowerHex::fmt(&self.bits, f)
334
0
    }
335
}
336
337
impl std::fmt::UpperHex for SelectionFlags {
338
0
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
339
0
        std::fmt::UpperHex::fmt(&self.bits, f)
340
0
    }
341
}
342
343
impl font_types::Scalar for SelectionFlags {
344
    type Raw = <u16 as font_types::Scalar>::Raw;
345
0
    fn to_raw(self) -> Self::Raw {
346
0
        self.bits().to_raw()
347
0
    }
348
945
    fn from_raw(raw: Self::Raw) -> Self {
349
945
        let t = <u16>::from_raw(raw);
350
945
        Self::from_bits_truncate(t)
351
945
    }
352
}
353
354
impl<'a> MinByteRange<'a> for Os2<'a> {
355
0
    fn min_byte_range(&self) -> Range<usize> {
356
0
        0..self.us_win_descent_byte_range().end
357
0
    }
358
0
    fn min_table_bytes(&self) -> &'a [u8] {
359
0
        let range = self.min_byte_range();
360
0
        self.offset_data().as_bytes().get(range).unwrap_or_default()
361
0
    }
362
}
363
364
impl TopLevelTable for Os2<'_> {
365
    /// `OS/2`
366
    const TAG: Tag = Tag::new(b"OS/2");
367
}
368
369
impl ReadArgs for Os2<'_> {
370
    type Args = ();
371
}
372
373
impl<'a> FontRead<'a> for Os2<'a> {
374
961
    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
375
        #[allow(clippy::absurd_extreme_comparisons)]
376
961
        if data.len() < Self::MIN_SIZE {
377
13
            return Err(ReadError::OutOfBounds);
378
948
        }
379
948
        let Some(data) = TableDataRef::new(data.as_bytes()) else {
380
0
            return Err(ReadError::OutOfBounds);
381
        };
382
948
        Ok(Self { data })
383
961
    }
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)]
390
pub 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)]
410
const _: () = 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)]
414
pub struct Os2<'a> {
415
    data: TableDataRef<'a, Os2FixedHeader>,
416
}
417
418
#[allow(clippy::needless_lifetimes)]
419
impl<'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
6.61k
    pub fn version(&self) -> u16 {
453
6.61k
        self.data.header().version.get()
454
6.61k
    }
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
945
    pub fn x_avg_char_width(&self) -> i16 {
461
945
        self.data.header().x_avg_char_width.get()
462
945
    }
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
0
    pub fn us_weight_class(&self) -> u16 {
469
0
        self.data.header().us_weight_class.get()
470
0
    }
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
0
    pub fn us_width_class(&self) -> u16 {
477
0
        self.data.header().us_width_class.get()
478
0
    }
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
0
    pub fn fs_type(&self) -> u16 {
484
0
        self.data.header().fs_type.get()
485
0
    }
486
487
    /// The recommended horizontal size in font design units for subscripts for
488
    /// this font.
489
0
    pub fn y_subscript_x_size(&self) -> i16 {
490
0
        self.data.header().y_subscript_x_size.get()
491
0
    }
492
493
    /// The recommended vertical size in font design units for subscripts for
494
    /// this font.
495
0
    pub fn y_subscript_y_size(&self) -> i16 {
496
0
        self.data.header().y_subscript_y_size.get()
497
0
    }
498
499
    /// The recommended horizontal offset in font design units for subscripts
500
    /// for this font.
501
0
    pub fn y_subscript_x_offset(&self) -> i16 {
502
0
        self.data.header().y_subscript_x_offset.get()
503
0
    }
504
505
    /// The recommended vertical offset in font design units for subscripts
506
    /// for this font.
507
0
    pub fn y_subscript_y_offset(&self) -> i16 {
508
0
        self.data.header().y_subscript_y_offset.get()
509
0
    }
510
511
    /// The recommended horizontal size in font design units for superscripts
512
    /// for this font.
513
0
    pub fn y_superscript_x_size(&self) -> i16 {
514
0
        self.data.header().y_superscript_x_size.get()
515
0
    }
516
517
    /// The recommended vertical size in font design units for superscripts
518
    /// for this font.
519
0
    pub fn y_superscript_y_size(&self) -> i16 {
520
0
        self.data.header().y_superscript_y_size.get()
521
0
    }
522
523
    /// The recommended horizontal offset in font design units for superscripts
524
    /// for this font.
525
0
    pub fn y_superscript_x_offset(&self) -> i16 {
526
0
        self.data.header().y_superscript_x_offset.get()
527
0
    }
528
529
    /// The recommended vertical offset in font design units for superscripts
530
    /// for this font.
531
0
    pub fn y_superscript_y_offset(&self) -> i16 {
532
0
        self.data.header().y_superscript_y_offset.get()
533
0
    }
534
535
    /// Thickness of the strikeout stroke in font design units.
536
0
    pub fn y_strikeout_size(&self) -> i16 {
537
0
        self.data.header().y_strikeout_size.get()
538
0
    }
539
540
    /// The position of the top of the strikeout stroke relative to the
541
    /// baseline in font design units.
542
0
    pub fn y_strikeout_position(&self) -> i16 {
543
0
        self.data.header().y_strikeout_position.get()
544
0
    }
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
0
    pub fn s_family_class(&self) -> i16 {
549
0
        self.data.header().s_family_class.get()
550
0
    }
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
0
    pub fn panose_10(&self) -> &'a [u8] {
557
0
        let range = self.panose_10_byte_range();
558
0
        self.offset_data()
559
0
            .read_array(range)
560
0
            .ok()
561
0
            .unwrap_or_default()
562
0
    }
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
0
    pub fn ul_unicode_range_1(&self) -> u32 {
568
0
        let range = self.ul_unicode_range_1_byte_range();
569
0
        self.offset_data()
570
0
            .read_at(range.start)
571
0
            .ok()
572
0
            .unwrap_or_default()
573
0
    }
574
575
    /// Unicode Character Range (bits 32-63).
576
0
    pub fn ul_unicode_range_2(&self) -> u32 {
577
0
        let range = self.ul_unicode_range_2_byte_range();
578
0
        self.offset_data()
579
0
            .read_at(range.start)
580
0
            .ok()
581
0
            .unwrap_or_default()
582
0
    }
583
584
    /// Unicode Character Range (bits 64-95).
585
0
    pub fn ul_unicode_range_3(&self) -> u32 {
586
0
        let range = self.ul_unicode_range_3_byte_range();
587
0
        self.offset_data()
588
0
            .read_at(range.start)
589
0
            .ok()
590
0
            .unwrap_or_default()
591
0
    }
592
593
    /// Unicode Character Range (bits 96-127).
594
0
    pub fn ul_unicode_range_4(&self) -> u32 {
595
0
        let range = self.ul_unicode_range_4_byte_range();
596
0
        self.offset_data()
597
0
            .read_at(range.start)
598
0
            .ok()
599
0
            .unwrap_or_default()
600
0
    }
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
0
    pub fn ach_vend_id(&self) -> Tag {
606
0
        let range = self.ach_vend_id_byte_range();
607
0
        self.offset_data()
608
0
            .read_at(range.start)
609
0
            .ok()
610
0
            .unwrap_or_default()
611
0
    }
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
945
    pub fn fs_selection(&self) -> SelectionFlags {
617
945
        let range = self.fs_selection_byte_range();
618
945
        self.offset_data()
619
945
            .read_at(range.start)
620
945
            .ok()
621
945
            .unwrap_or_default()
622
945
    }
623
624
    /// The minimum Unicode index (character code) in this font.
625
0
    pub fn us_first_char_index(&self) -> u16 {
626
0
        let range = self.us_first_char_index_byte_range();
627
0
        self.offset_data()
628
0
            .read_at(range.start)
629
0
            .ok()
630
0
            .unwrap_or_default()
631
0
    }
632
633
    /// The maximum Unicode index (character code) in this font.
634
0
    pub fn us_last_char_index(&self) -> u16 {
635
0
        let range = self.us_last_char_index_byte_range();
636
0
        self.offset_data()
637
0
            .read_at(range.start)
638
0
            .ok()
639
0
            .unwrap_or_default()
640
0
    }
641
642
    /// The typographic ascender for this font.
643
945
    pub fn s_typo_ascender(&self) -> i16 {
644
945
        let range = self.s_typo_ascender_byte_range();
645
945
        self.offset_data()
646
945
            .read_at(range.start)
647
945
            .ok()
648
945
            .unwrap_or_default()
649
945
    }
650
651
    /// The typographic descender for this font.
652
945
    pub fn s_typo_descender(&self) -> i16 {
653
945
        let range = self.s_typo_descender_byte_range();
654
945
        self.offset_data()
655
945
            .read_at(range.start)
656
945
            .ok()
657
945
            .unwrap_or_default()
658
945
    }
659
660
    /// The typographic line gap for this font.
661
945
    pub fn s_typo_line_gap(&self) -> i16 {
662
945
        let range = self.s_typo_line_gap_byte_range();
663
945
        self.offset_data()
664
945
            .read_at(range.start)
665
945
            .ok()
666
945
            .unwrap_or_default()
667
945
    }
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
945
    pub fn us_win_ascent(&self) -> u16 {
674
945
        let range = self.us_win_ascent_byte_range();
675
945
        self.offset_data()
676
945
            .read_at(range.start)
677
945
            .ok()
678
945
            .unwrap_or_default()
679
945
    }
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
945
    pub fn us_win_descent(&self) -> u16 {
686
945
        let range = self.us_win_descent_byte_range();
687
945
        self.offset_data()
688
945
            .read_at(range.start)
689
945
            .ok()
690
945
            .unwrap_or_default()
691
945
    }
692
693
    /// Code page character range bits 0-31.
694
0
    pub fn ul_code_page_range_1(&self) -> Option<u32> {
695
0
        let range = self.ul_code_page_range_1_byte_range();
696
0
        (!range.is_empty())
697
0
            .then(|| self.offset_data().read_at(range.start).ok())
698
0
            .flatten()
699
0
    }
700
701
    /// Code page character range bits 32-63.
702
0
    pub fn ul_code_page_range_2(&self) -> Option<u32> {
703
0
        let range = self.ul_code_page_range_2_byte_range();
704
0
        (!range.is_empty())
705
0
            .then(|| self.offset_data().read_at(range.start).ok())
706
0
            .flatten()
707
0
    }
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
945
    pub fn sx_height(&self) -> Option<i16> {
713
945
        let range = self.sx_height_byte_range();
714
945
        (!range.is_empty())
715
945
            .then(|| self.offset_data().read_at(range.start).ok())
716
945
            .flatten()
717
945
    }
718
719
    /// This metric specifies the distance between the baseline and the
720
    /// approximate height of uppercase letters measured in FUnits.
721
945
    pub fn s_cap_height(&self) -> Option<i16> {
722
945
        let range = self.s_cap_height_byte_range();
723
945
        (!range.is_empty())
724
945
            .then(|| self.offset_data().read_at(range.start).ok())
725
945
            .flatten()
726
945
    }
727
728
    /// This is the Unicode codepoint, in UTF-16 encoding, of a character that
729
    /// can be used for a default glyph.
730
0
    pub fn us_default_char(&self) -> Option<u16> {
731
0
        let range = self.us_default_char_byte_range();
732
0
        (!range.is_empty())
733
0
            .then(|| self.offset_data().read_at(range.start).ok())
734
0
            .flatten()
735
0
    }
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
0
    pub fn us_break_char(&self) -> Option<u16> {
740
0
        let range = self.us_break_char_byte_range();
741
0
        (!range.is_empty())
742
0
            .then(|| self.offset_data().read_at(range.start).ok())
743
0
            .flatten()
744
0
    }
745
746
    /// This field is used for fonts with multiple optical styles.
747
0
    pub fn us_max_context(&self) -> Option<u16> {
748
0
        let range = self.us_max_context_byte_range();
749
0
        (!range.is_empty())
750
0
            .then(|| self.offset_data().read_at(range.start).ok())
751
0
            .flatten()
752
0
    }
753
754
    /// This field is used for fonts with multiple optical styles.
755
0
    pub fn us_lower_optical_point_size(&self) -> Option<u16> {
756
0
        let range = self.us_lower_optical_point_size_byte_range();
757
0
        (!range.is_empty())
758
0
            .then(|| self.offset_data().read_at(range.start).ok())
759
0
            .flatten()
760
0
    }
761
762
    /// This field is used for fonts with multiple optical styles.
763
0
    pub fn us_upper_optical_point_size(&self) -> Option<u16> {
764
0
        let range = self.us_upper_optical_point_size_byte_range();
765
0
        (!range.is_empty())
766
0
            .then(|| self.offset_data().read_at(range.start).ok())
767
0
            .flatten()
768
0
    }
769
770
7.56k
    pub fn version_byte_range(&self) -> Range<usize> {
771
7.56k
        let start = 0;
772
7.56k
        let end = start + u16::RAW_BYTE_LEN;
773
7.56k
        start..end
774
7.56k
    }
775
776
7.56k
    pub fn x_avg_char_width_byte_range(&self) -> Range<usize> {
777
7.56k
        let start = self.version_byte_range().end;
778
7.56k
        let end = start + i16::RAW_BYTE_LEN;
779
7.56k
        start..end
780
7.56k
    }
781
782
7.56k
    pub fn us_weight_class_byte_range(&self) -> Range<usize> {
783
7.56k
        let start = self.x_avg_char_width_byte_range().end;
784
7.56k
        let end = start + u16::RAW_BYTE_LEN;
785
7.56k
        start..end
786
7.56k
    }
787
788
7.56k
    pub fn us_width_class_byte_range(&self) -> Range<usize> {
789
7.56k
        let start = self.us_weight_class_byte_range().end;
790
7.56k
        let end = start + u16::RAW_BYTE_LEN;
791
7.56k
        start..end
792
7.56k
    }
793
794
7.56k
    pub fn fs_type_byte_range(&self) -> Range<usize> {
795
7.56k
        let start = self.us_width_class_byte_range().end;
796
7.56k
        let end = start + u16::RAW_BYTE_LEN;
797
7.56k
        start..end
798
7.56k
    }
799
800
7.56k
    pub fn y_subscript_x_size_byte_range(&self) -> Range<usize> {
801
7.56k
        let start = self.fs_type_byte_range().end;
802
7.56k
        let end = start + i16::RAW_BYTE_LEN;
803
7.56k
        start..end
804
7.56k
    }
805
806
7.56k
    pub fn y_subscript_y_size_byte_range(&self) -> Range<usize> {
807
7.56k
        let start = self.y_subscript_x_size_byte_range().end;
808
7.56k
        let end = start + i16::RAW_BYTE_LEN;
809
7.56k
        start..end
810
7.56k
    }
811
812
7.56k
    pub fn y_subscript_x_offset_byte_range(&self) -> Range<usize> {
813
7.56k
        let start = self.y_subscript_y_size_byte_range().end;
814
7.56k
        let end = start + i16::RAW_BYTE_LEN;
815
7.56k
        start..end
816
7.56k
    }
817
818
7.56k
    pub fn y_subscript_y_offset_byte_range(&self) -> Range<usize> {
819
7.56k
        let start = self.y_subscript_x_offset_byte_range().end;
820
7.56k
        let end = start + i16::RAW_BYTE_LEN;
821
7.56k
        start..end
822
7.56k
    }
823
824
7.56k
    pub fn y_superscript_x_size_byte_range(&self) -> Range<usize> {
825
7.56k
        let start = self.y_subscript_y_offset_byte_range().end;
826
7.56k
        let end = start + i16::RAW_BYTE_LEN;
827
7.56k
        start..end
828
7.56k
    }
829
830
7.56k
    pub fn y_superscript_y_size_byte_range(&self) -> Range<usize> {
831
7.56k
        let start = self.y_superscript_x_size_byte_range().end;
832
7.56k
        let end = start + i16::RAW_BYTE_LEN;
833
7.56k
        start..end
834
7.56k
    }
835
836
7.56k
    pub fn y_superscript_x_offset_byte_range(&self) -> Range<usize> {
837
7.56k
        let start = self.y_superscript_y_size_byte_range().end;
838
7.56k
        let end = start + i16::RAW_BYTE_LEN;
839
7.56k
        start..end
840
7.56k
    }
841
842
7.56k
    pub fn y_superscript_y_offset_byte_range(&self) -> Range<usize> {
843
7.56k
        let start = self.y_superscript_x_offset_byte_range().end;
844
7.56k
        let end = start + i16::RAW_BYTE_LEN;
845
7.56k
        start..end
846
7.56k
    }
847
848
7.56k
    pub fn y_strikeout_size_byte_range(&self) -> Range<usize> {
849
7.56k
        let start = self.y_superscript_y_offset_byte_range().end;
850
7.56k
        let end = start + i16::RAW_BYTE_LEN;
851
7.56k
        start..end
852
7.56k
    }
853
854
7.56k
    pub fn y_strikeout_position_byte_range(&self) -> Range<usize> {
855
7.56k
        let start = self.y_strikeout_size_byte_range().end;
856
7.56k
        let end = start + i16::RAW_BYTE_LEN;
857
7.56k
        start..end
858
7.56k
    }
859
860
7.56k
    pub fn s_family_class_byte_range(&self) -> Range<usize> {
861
7.56k
        let start = self.y_strikeout_position_byte_range().end;
862
7.56k
        let end = start + i16::RAW_BYTE_LEN;
863
7.56k
        start..end
864
7.56k
    }
865
866
7.56k
    pub fn panose_10_byte_range(&self) -> Range<usize> {
867
7.56k
        let start = self.s_family_class_byte_range().end;
868
7.56k
        let end = start + (10_usize).saturating_mul(u8::RAW_BYTE_LEN);
869
7.56k
        start..end
870
7.56k
    }
871
872
7.56k
    pub fn ul_unicode_range_1_byte_range(&self) -> Range<usize> {
873
7.56k
        let start = self.panose_10_byte_range().end;
874
7.56k
        let end = start + u32::RAW_BYTE_LEN;
875
7.56k
        start..end
876
7.56k
    }
877
878
7.56k
    pub fn ul_unicode_range_2_byte_range(&self) -> Range<usize> {
879
7.56k
        let start = self.ul_unicode_range_1_byte_range().end;
880
7.56k
        let end = start + u32::RAW_BYTE_LEN;
881
7.56k
        start..end
882
7.56k
    }
883
884
7.56k
    pub fn ul_unicode_range_3_byte_range(&self) -> Range<usize> {
885
7.56k
        let start = self.ul_unicode_range_2_byte_range().end;
886
7.56k
        let end = start + u32::RAW_BYTE_LEN;
887
7.56k
        start..end
888
7.56k
    }
889
890
7.56k
    pub fn ul_unicode_range_4_byte_range(&self) -> Range<usize> {
891
7.56k
        let start = self.ul_unicode_range_3_byte_range().end;
892
7.56k
        let end = start + u32::RAW_BYTE_LEN;
893
7.56k
        start..end
894
7.56k
    }
895
896
7.56k
    pub fn ach_vend_id_byte_range(&self) -> Range<usize> {
897
7.56k
        let start = self.ul_unicode_range_4_byte_range().end;
898
7.56k
        let end = start + Tag::RAW_BYTE_LEN;
899
7.56k
        start..end
900
7.56k
    }
901
902
7.56k
    pub fn fs_selection_byte_range(&self) -> Range<usize> {
903
7.56k
        let start = self.ach_vend_id_byte_range().end;
904
7.56k
        let end = start + SelectionFlags::RAW_BYTE_LEN;
905
7.56k
        start..end
906
7.56k
    }
907
908
6.61k
    pub fn us_first_char_index_byte_range(&self) -> Range<usize> {
909
6.61k
        let start = self.fs_selection_byte_range().end;
910
6.61k
        let end = start + u16::RAW_BYTE_LEN;
911
6.61k
        start..end
912
6.61k
    }
913
914
6.61k
    pub fn us_last_char_index_byte_range(&self) -> Range<usize> {
915
6.61k
        let start = self.us_first_char_index_byte_range().end;
916
6.61k
        let end = start + u16::RAW_BYTE_LEN;
917
6.61k
        start..end
918
6.61k
    }
919
920
6.61k
    pub fn s_typo_ascender_byte_range(&self) -> Range<usize> {
921
6.61k
        let start = self.us_last_char_index_byte_range().end;
922
6.61k
        let end = start + i16::RAW_BYTE_LEN;
923
6.61k
        start..end
924
6.61k
    }
925
926
5.67k
    pub fn s_typo_descender_byte_range(&self) -> Range<usize> {
927
5.67k
        let start = self.s_typo_ascender_byte_range().end;
928
5.67k
        let end = start + i16::RAW_BYTE_LEN;
929
5.67k
        start..end
930
5.67k
    }
931
932
4.72k
    pub fn s_typo_line_gap_byte_range(&self) -> Range<usize> {
933
4.72k
        let start = self.s_typo_descender_byte_range().end;
934
4.72k
        let end = start + i16::RAW_BYTE_LEN;
935
4.72k
        start..end
936
4.72k
    }
937
938
3.78k
    pub fn us_win_ascent_byte_range(&self) -> Range<usize> {
939
3.78k
        let start = self.s_typo_line_gap_byte_range().end;
940
3.78k
        let end = start + u16::RAW_BYTE_LEN;
941
3.78k
        start..end
942
3.78k
    }
943
944
2.83k
    pub fn us_win_descent_byte_range(&self) -> Range<usize> {
945
2.83k
        let start = self.us_win_ascent_byte_range().end;
946
2.83k
        let end = start + u16::RAW_BYTE_LEN;
947
2.83k
        start..end
948
2.83k
    }
949
950
1.89k
    pub fn ul_code_page_range_1_byte_range(&self) -> Range<usize> {
951
1.89k
        let start = self.us_win_descent_byte_range().end;
952
1.89k
        let end = if self.version().compatible(1u16) {
953
1.59k
            start + u32::RAW_BYTE_LEN
954
        } else {
955
296
            start
956
        };
957
1.89k
        start..end
958
1.89k
    }
959
960
1.89k
    pub fn ul_code_page_range_2_byte_range(&self) -> Range<usize> {
961
1.89k
        let start = self.ul_code_page_range_1_byte_range().end;
962
1.89k
        let end = if self.version().compatible(1u16) {
963
1.59k
            start + u32::RAW_BYTE_LEN
964
        } else {
965
296
            start
966
        };
967
1.89k
        start..end
968
1.89k
    }
969
970
1.89k
    pub fn sx_height_byte_range(&self) -> Range<usize> {
971
1.89k
        let start = self.ul_code_page_range_2_byte_range().end;
972
1.89k
        let end = if self.version().compatible(2u16) {
973
1.54k
            start + i16::RAW_BYTE_LEN
974
        } else {
975
348
            start
976
        };
977
1.89k
        start..end
978
1.89k
    }
979
980
945
    pub fn s_cap_height_byte_range(&self) -> Range<usize> {
981
945
        let start = self.sx_height_byte_range().end;
982
945
        let end = if self.version().compatible(2u16) {
983
771
            start + i16::RAW_BYTE_LEN
984
        } else {
985
174
            start
986
        };
987
945
        start..end
988
945
    }
989
990
0
    pub fn us_default_char_byte_range(&self) -> Range<usize> {
991
0
        let start = self.s_cap_height_byte_range().end;
992
0
        let end = if self.version().compatible(2u16) {
993
0
            start + u16::RAW_BYTE_LEN
994
        } else {
995
0
            start
996
        };
997
0
        start..end
998
0
    }
999
1000
0
    pub fn us_break_char_byte_range(&self) -> Range<usize> {
1001
0
        let start = self.us_default_char_byte_range().end;
1002
0
        let end = if self.version().compatible(2u16) {
1003
0
            start + u16::RAW_BYTE_LEN
1004
        } else {
1005
0
            start
1006
        };
1007
0
        start..end
1008
0
    }
1009
1010
0
    pub fn us_max_context_byte_range(&self) -> Range<usize> {
1011
0
        let start = self.us_break_char_byte_range().end;
1012
0
        let end = if self.version().compatible(2u16) {
1013
0
            start + u16::RAW_BYTE_LEN
1014
        } else {
1015
0
            start
1016
        };
1017
0
        start..end
1018
0
    }
1019
1020
0
    pub fn us_lower_optical_point_size_byte_range(&self) -> Range<usize> {
1021
0
        let start = self.us_max_context_byte_range().end;
1022
0
        let end = if self.version().compatible(5u16) {
1023
0
            start + u16::RAW_BYTE_LEN
1024
        } else {
1025
0
            start
1026
        };
1027
0
        start..end
1028
0
    }
1029
1030
0
    pub fn us_upper_optical_point_size_byte_range(&self) -> Range<usize> {
1031
0
        let start = self.us_lower_optical_point_size_byte_range().end;
1032
0
        let end = if self.version().compatible(5u16) {
1033
0
            start + u16::RAW_BYTE_LEN
1034
        } else {
1035
0
            start
1036
        };
1037
0
        start..end
1038
0
    }
1039
}
1040
1041
const _: () = assert!(FontData::default_data_long_enough(Os2::MIN_SIZE));
1042
1043
impl Default for Os2<'_> {
1044
0
    fn default() -> Self {
1045
        Self {
1046
0
            data: TableDataRef::new(FontData::default_table_data().as_bytes())
1047
0
                .unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
1048
        }
1049
0
    }
1050
}