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_sbix.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
/// Sbix header flags.
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 HeaderFlags {
13
    bits: u16,
14
}
15
16
impl HeaderFlags {
17
    /// Bit 0: Set to 1.
18
    pub const ALWAYS_SET: Self = Self { bits: 0x0001 };
19
20
    /// Bit 1: Draw outlines.
21
    pub const DRAW_OUTLINES: Self = Self { bits: 0x0002 };
22
}
23
24
impl HeaderFlags {
25
    ///  Returns an empty set of flags.
26
    #[inline]
27
0
    pub const fn empty() -> Self {
28
0
        Self { bits: 0 }
29
0
    }
30
31
    /// Returns the set containing all flags.
32
    #[inline]
33
0
    pub const fn all() -> Self {
34
0
        Self {
35
0
            bits: Self::ALWAYS_SET.bits | Self::DRAW_OUTLINES.bits,
36
0
        }
37
0
    }
38
39
    /// Returns the raw value of the flags currently stored.
40
    #[inline]
41
0
    pub const fn bits(&self) -> u16 {
42
0
        self.bits
43
0
    }
44
45
    /// Convert from underlying bit representation, unless that
46
    /// representation contains bits that do not correspond to a flag.
47
    #[inline]
48
0
    pub const fn from_bits(bits: u16) -> Option<Self> {
49
0
        if (bits & !Self::all().bits()) == 0 {
50
0
            Some(Self { bits })
51
        } else {
52
0
            None
53
        }
54
0
    }
55
56
    /// Convert from underlying bit representation, dropping any bits
57
    /// that do not correspond to flags.
58
    #[inline]
59
0
    pub const fn from_bits_truncate(bits: u16) -> Self {
60
0
        Self {
61
0
            bits: bits & Self::all().bits,
62
0
        }
63
0
    }
64
65
    /// Returns `true` if no flags are currently stored.
66
    #[inline]
67
0
    pub const fn is_empty(&self) -> bool {
68
0
        self.bits() == Self::empty().bits()
69
0
    }
70
71
    /// Returns `true` if there are flags common to both `self` and `other`.
72
    #[inline]
73
0
    pub const fn intersects(&self, other: Self) -> bool {
74
0
        !(Self {
75
0
            bits: self.bits & other.bits,
76
0
        })
77
0
        .is_empty()
78
0
    }
79
80
    /// Returns `true` if all of the flags in `other` are contained within `self`.
81
    #[inline]
82
0
    pub const fn contains(&self, other: Self) -> bool {
83
0
        (self.bits & other.bits) == other.bits
84
0
    }
85
86
    /// Inserts the specified flags in-place.
87
    #[inline]
88
0
    pub fn insert(&mut self, other: Self) {
89
0
        self.bits |= other.bits;
90
0
    }
91
92
    /// Removes the specified flags in-place.
93
    #[inline]
94
0
    pub fn remove(&mut self, other: Self) {
95
0
        self.bits &= !other.bits;
96
0
    }
97
98
    /// Toggles the specified flags in-place.
99
    #[inline]
100
0
    pub fn toggle(&mut self, other: Self) {
101
0
        self.bits ^= other.bits;
102
0
    }
103
104
    /// Returns the intersection between the flags in `self` and
105
    /// `other`.
106
    ///
107
    /// Specifically, the returned set contains only the flags which are
108
    /// present in *both* `self` *and* `other`.
109
    ///
110
    /// This is equivalent to using the `&` operator (e.g.
111
    /// [`ops::BitAnd`]), as in `flags & other`.
112
    ///
113
    /// [`ops::BitAnd`]: https://doc.rust-lang.org/std/ops/trait.BitAnd.html
114
    #[inline]
115
    #[must_use]
116
0
    pub const fn intersection(self, other: Self) -> Self {
117
0
        Self {
118
0
            bits: self.bits & other.bits,
119
0
        }
120
0
    }
121
122
    /// Returns the union of between the flags in `self` and `other`.
123
    ///
124
    /// Specifically, the returned set contains all flags which are
125
    /// present in *either* `self` *or* `other`, including any which are
126
    /// present in both.
127
    ///
128
    /// This is equivalent to using the `|` operator (e.g.
129
    /// [`ops::BitOr`]), as in `flags | other`.
130
    ///
131
    /// [`ops::BitOr`]: https://doc.rust-lang.org/std/ops/trait.BitOr.html
132
    #[inline]
133
    #[must_use]
134
0
    pub const fn union(self, other: Self) -> Self {
135
0
        Self {
136
0
            bits: self.bits | other.bits,
137
0
        }
138
0
    }
139
140
    /// Returns the difference between the flags in `self` and `other`.
141
    ///
142
    /// Specifically, the returned set contains all flags present in
143
    /// `self`, except for the ones present in `other`.
144
    ///
145
    /// It is also conceptually equivalent to the "bit-clear" operation:
146
    /// `flags & !other` (and this syntax is also supported).
147
    ///
148
    /// This is equivalent to using the `-` operator (e.g.
149
    /// [`ops::Sub`]), as in `flags - other`.
150
    ///
151
    /// [`ops::Sub`]: https://doc.rust-lang.org/std/ops/trait.Sub.html
152
    #[inline]
153
    #[must_use]
154
0
    pub const fn difference(self, other: Self) -> Self {
155
0
        Self {
156
0
            bits: self.bits & !other.bits,
157
0
        }
158
0
    }
159
}
160
161
impl std::ops::BitOr for HeaderFlags {
162
    type Output = Self;
163
164
    /// Returns the union of the two sets of flags.
165
    #[inline]
166
0
    fn bitor(self, other: HeaderFlags) -> Self {
167
0
        Self {
168
0
            bits: self.bits | other.bits,
169
0
        }
170
0
    }
171
}
172
173
impl std::ops::BitOrAssign for HeaderFlags {
174
    /// Adds the set of flags.
175
    #[inline]
176
0
    fn bitor_assign(&mut self, other: Self) {
177
0
        self.bits |= other.bits;
178
0
    }
179
}
180
181
impl std::ops::BitXor for HeaderFlags {
182
    type Output = Self;
183
184
    /// Returns the left flags, but with all the right flags toggled.
185
    #[inline]
186
0
    fn bitxor(self, other: Self) -> Self {
187
0
        Self {
188
0
            bits: self.bits ^ other.bits,
189
0
        }
190
0
    }
191
}
192
193
impl std::ops::BitXorAssign for HeaderFlags {
194
    /// Toggles the set of flags.
195
    #[inline]
196
0
    fn bitxor_assign(&mut self, other: Self) {
197
0
        self.bits ^= other.bits;
198
0
    }
199
}
200
201
impl std::ops::BitAnd for HeaderFlags {
202
    type Output = Self;
203
204
    /// Returns the intersection between the two sets of flags.
205
    #[inline]
206
0
    fn bitand(self, other: Self) -> Self {
207
0
        Self {
208
0
            bits: self.bits & other.bits,
209
0
        }
210
0
    }
211
}
212
213
impl std::ops::BitAndAssign for HeaderFlags {
214
    /// Disables all flags disabled in the set.
215
    #[inline]
216
0
    fn bitand_assign(&mut self, other: Self) {
217
0
        self.bits &= other.bits;
218
0
    }
219
}
220
221
impl std::ops::Sub for HeaderFlags {
222
    type Output = Self;
223
224
    /// Returns the set difference of the two sets of flags.
225
    #[inline]
226
0
    fn sub(self, other: Self) -> Self {
227
0
        Self {
228
0
            bits: self.bits & !other.bits,
229
0
        }
230
0
    }
231
}
232
233
impl std::ops::SubAssign for HeaderFlags {
234
    /// Disables all flags enabled in the set.
235
    #[inline]
236
0
    fn sub_assign(&mut self, other: Self) {
237
0
        self.bits &= !other.bits;
238
0
    }
239
}
240
241
impl std::ops::Not for HeaderFlags {
242
    type Output = Self;
243
244
    /// Returns the complement of this set of flags.
245
    #[inline]
246
0
    fn not(self) -> Self {
247
0
        Self { bits: !self.bits } & Self::all()
248
0
    }
249
}
250
251
impl std::fmt::Debug for HeaderFlags {
252
0
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
253
0
        let members: &[(&str, Self)] = &[
254
0
            ("ALWAYS_SET", Self::ALWAYS_SET),
255
0
            ("DRAW_OUTLINES", Self::DRAW_OUTLINES),
256
0
        ];
257
0
        let mut first = true;
258
0
        for (name, value) in members {
259
0
            if self.contains(*value) {
260
0
                if !first {
261
0
                    f.write_str(" | ")?;
262
0
                }
263
0
                first = false;
264
0
                f.write_str(name)?;
265
0
            }
266
        }
267
0
        if first {
268
0
            f.write_str("(empty)")?;
269
0
        }
270
0
        Ok(())
271
0
    }
272
}
273
274
impl std::fmt::Binary for HeaderFlags {
275
0
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
276
0
        std::fmt::Binary::fmt(&self.bits, f)
277
0
    }
278
}
279
280
impl std::fmt::Octal for HeaderFlags {
281
0
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
282
0
        std::fmt::Octal::fmt(&self.bits, f)
283
0
    }
284
}
285
286
impl std::fmt::LowerHex for HeaderFlags {
287
0
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
288
0
        std::fmt::LowerHex::fmt(&self.bits, f)
289
0
    }
290
}
291
292
impl std::fmt::UpperHex for HeaderFlags {
293
0
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
294
0
        std::fmt::UpperHex::fmt(&self.bits, f)
295
0
    }
296
}
297
298
impl font_types::Scalar for HeaderFlags {
299
    type Raw = <u16 as font_types::Scalar>::Raw;
300
0
    fn to_raw(self) -> Self::Raw {
301
0
        self.bits().to_raw()
302
0
    }
303
0
    fn from_raw(raw: Self::Raw) -> Self {
304
0
        let t = <u16>::from_raw(raw);
305
0
        Self::from_bits_truncate(t)
306
0
    }
307
}
308
309
impl<'a> MinByteRange<'a> for Sbix<'a> {
310
0
    fn min_byte_range(&self) -> Range<usize> {
311
0
        0..self.strike_offsets_byte_range().end
312
0
    }
313
0
    fn min_table_bytes(&self) -> &'a [u8] {
314
0
        let range = self.min_byte_range();
315
0
        self.offset_data().as_bytes().get(range).unwrap_or_default()
316
0
    }
317
}
318
319
impl TopLevelTable for Sbix<'_> {
320
    /// `sbix`
321
    const TAG: Tag = Tag::new(b"sbix");
322
}
323
324
impl ReadArgs for Sbix<'_> {
325
    type Args = u32;
326
}
327
328
impl<'a> FontRead<'a> for Sbix<'a> {
329
210
    fn read_with_args(data: FontData<'a>, args: u32) -> Result<Self, ReadError> {
330
210
        let num_glyphs = args;
331
332
        #[allow(clippy::absurd_extreme_comparisons)]
333
210
        if data.len() < Self::MIN_SIZE {
334
2
            return Err(ReadError::OutOfBounds);
335
208
        }
336
208
        let Some(data) = TableDataRef::new(data.as_bytes()) else {
337
0
            return Err(ReadError::OutOfBounds);
338
        };
339
208
        Ok(Self { data, num_glyphs })
340
210
    }
341
}
342
343
impl<'a> Sbix<'a> {
344
    /// A constructor that requires additional arguments.
345
    ///
346
    /// This type requires some external state in order to be
347
    /// parsed.
348
0
    pub fn read(data: FontData<'a>, num_glyphs: u32) -> Result<Self, ReadError> {
349
0
        let args = num_glyphs;
350
0
        Self::read_with_args(data, args)
351
0
    }
352
}
353
354
/// The fields at the start of the table, which are read directly.
355
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
356
#[repr(C, packed)]
357
#[doc(hidden)]
358
pub struct SbixFixedHeader {
359
    pub version: BigEndian<u16>,
360
    pub flags: BigEndian<HeaderFlags>,
361
    pub num_strikes: BigEndian<u32>,
362
}
363
364
#[allow(clippy::absurd_extreme_comparisons)]
365
const _: () = assert!(std::mem::size_of::<SbixFixedHeader>() <= Sbix::MIN_SIZE);
366
367
/// The [sbix (Standard Bitmap Graphics)](https://docs.microsoft.com/en-us/typography/opentype/spec/sbix) table
368
#[derive(Clone)]
369
pub struct Sbix<'a> {
370
    data: TableDataRef<'a, SbixFixedHeader>,
371
    num_glyphs: u32,
372
}
373
374
#[allow(clippy::needless_lifetimes)]
375
impl<'a> Sbix<'a> {
376
    pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + HeaderFlags::RAW_BYTE_LEN + u32::RAW_BYTE_LEN);
377
    basic_table_impls!(impl_the_methods);
378
379
    /// Table version number — set to 1.
380
0
    pub fn version(&self) -> u16 {
381
0
        self.data.header().version.get()
382
0
    }
383
384
    /// Bit 0: Set to 1.
385
    /// Bit 1: Draw outlines.
386
    /// Bits 2 to 15: reserved (set to 0).
387
0
    pub fn flags(&self) -> HeaderFlags {
388
0
        self.data.header().flags.get()
389
0
    }
390
391
    /// Number of bitmap strikes.
392
32.8k
    pub fn num_strikes(&self) -> u32 {
393
32.8k
        self.data.header().num_strikes.get()
394
32.8k
    }
395
396
    /// Offsets from the beginning of the 'sbix' table to data for each individual bitmap strike.
397
32.8k
    pub fn strike_offsets(&self) -> &'a [BigEndian<Offset32>] {
398
32.8k
        let range = self.strike_offsets_byte_range();
399
32.8k
        self.offset_data()
400
32.8k
            .read_array(range)
401
32.8k
            .ok()
402
32.8k
            .unwrap_or_default()
403
32.8k
    }
404
405
    /// A dynamically resolving wrapper for [`strike_offsets`][Self::strike_offsets].
406
32.8k
    pub fn strikes(&self) -> ArrayOfOffsets<'a, Strike<'a>, Offset32> {
407
32.8k
        let data = self.offset_data();
408
32.8k
        let offsets = self.strike_offsets();
409
32.8k
        let args = self.num_glyphs();
410
32.8k
        ArrayOfOffsets::new(offsets, data, args)
411
32.8k
    }
412
413
32.8k
    pub(crate) fn num_glyphs(&self) -> u32 {
414
32.8k
        self.num_glyphs
415
32.8k
    }
416
417
32.8k
    pub fn version_byte_range(&self) -> Range<usize> {
418
32.8k
        let start = 0;
419
32.8k
        let end = start + u16::RAW_BYTE_LEN;
420
32.8k
        start..end
421
32.8k
    }
422
423
32.8k
    pub fn flags_byte_range(&self) -> Range<usize> {
424
32.8k
        let start = self.version_byte_range().end;
425
32.8k
        let end = start + HeaderFlags::RAW_BYTE_LEN;
426
32.8k
        start..end
427
32.8k
    }
428
429
32.8k
    pub fn num_strikes_byte_range(&self) -> Range<usize> {
430
32.8k
        let start = self.flags_byte_range().end;
431
32.8k
        let end = start + u32::RAW_BYTE_LEN;
432
32.8k
        start..end
433
32.8k
    }
434
435
32.8k
    pub fn strike_offsets_byte_range(&self) -> Range<usize> {
436
32.8k
        let num_strikes = self.num_strikes();
437
32.8k
        let start = self.num_strikes_byte_range().end;
438
32.8k
        let end =
439
32.8k
            start + (transforms::to_usize(num_strikes)).saturating_mul(Offset32::RAW_BYTE_LEN);
440
32.8k
        start..end
441
32.8k
    }
442
}
443
444
const _: () = assert!(FontData::default_data_long_enough(Sbix::MIN_SIZE));
445
446
impl Default for Sbix<'_> {
447
0
    fn default() -> Self {
448
        Self {
449
0
            data: TableDataRef::new(FontData::default_table_data().as_bytes())
450
0
                .unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
451
0
            num_glyphs: Default::default(),
452
        }
453
0
    }
454
}
455
456
impl<'a> MinByteRange<'a> for Strike<'a> {
457
0
    fn min_byte_range(&self) -> Range<usize> {
458
0
        0..self.glyph_data_offsets_byte_range().end
459
0
    }
460
0
    fn min_table_bytes(&self) -> &'a [u8] {
461
0
        let range = self.min_byte_range();
462
0
        self.offset_data().as_bytes().get(range).unwrap_or_default()
463
0
    }
464
}
465
466
impl ReadArgs for Strike<'_> {
467
    type Args = u32;
468
}
469
470
impl<'a> FontRead<'a> for Strike<'a> {
471
2.06k
    fn read_with_args(data: FontData<'a>, args: u32) -> Result<Self, ReadError> {
472
2.06k
        let num_glyphs = args;
473
474
        #[allow(clippy::absurd_extreme_comparisons)]
475
2.06k
        if data.len() < Self::MIN_SIZE {
476
24
            return Err(ReadError::OutOfBounds);
477
2.04k
        }
478
2.04k
        let Some(data) = TableDataRef::new(data.as_bytes()) else {
479
0
            return Err(ReadError::OutOfBounds);
480
        };
481
2.04k
        Ok(Self { data, num_glyphs })
482
2.06k
    }
483
}
484
485
impl<'a> Strike<'a> {
486
    /// A constructor that requires additional arguments.
487
    ///
488
    /// This type requires some external state in order to be
489
    /// parsed.
490
0
    pub fn read(data: FontData<'a>, num_glyphs: u32) -> Result<Self, ReadError> {
491
0
        let args = num_glyphs;
492
0
        Self::read_with_args(data, args)
493
0
    }
494
}
495
496
/// The fields at the start of the table, which are read directly.
497
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
498
#[repr(C, packed)]
499
#[doc(hidden)]
500
pub struct StrikeFixedHeader {
501
    pub ppem: BigEndian<u16>,
502
    pub ppi: BigEndian<u16>,
503
}
504
505
#[allow(clippy::absurd_extreme_comparisons)]
506
const _: () = assert!(std::mem::size_of::<StrikeFixedHeader>() <= Strike::MIN_SIZE);
507
508
/// [Strike](https://learn.microsoft.com/en-us/typography/opentype/spec/sbix#strikes) header table
509
#[derive(Clone)]
510
pub struct Strike<'a> {
511
    data: TableDataRef<'a, StrikeFixedHeader>,
512
    num_glyphs: u32,
513
}
514
515
#[allow(clippy::needless_lifetimes)]
516
impl<'a> Strike<'a> {
517
    pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN);
518
    basic_table_impls!(impl_the_methods);
519
520
    /// The PPEM size for which this strike was designed.
521
1.79k
    pub fn ppem(&self) -> u16 {
522
1.79k
        self.data.header().ppem.get()
523
1.79k
    }
524
525
    /// The device pixel density (in PPI) for which this strike was designed. (E.g., 96 PPI, 192 PPI.)
526
0
    pub fn ppi(&self) -> u16 {
527
0
        self.data.header().ppi.get()
528
0
    }
529
530
    /// Offset from the beginning of the strike data header to bitmap data for an individual glyph ID.
531
247
    pub fn glyph_data_offsets(&self) -> &'a [BigEndian<u32>] {
532
247
        let range = self.glyph_data_offsets_byte_range();
533
247
        self.offset_data()
534
247
            .read_array(range)
535
247
            .ok()
536
247
            .unwrap_or_default()
537
247
    }
538
539
247
    pub(crate) fn num_glyphs(&self) -> u32 {
540
247
        self.num_glyphs
541
247
    }
542
543
247
    pub fn ppem_byte_range(&self) -> Range<usize> {
544
247
        let start = 0;
545
247
        let end = start + u16::RAW_BYTE_LEN;
546
247
        start..end
547
247
    }
548
549
247
    pub fn ppi_byte_range(&self) -> Range<usize> {
550
247
        let start = self.ppem_byte_range().end;
551
247
        let end = start + u16::RAW_BYTE_LEN;
552
247
        start..end
553
247
    }
554
555
247
    pub fn glyph_data_offsets_byte_range(&self) -> Range<usize> {
556
247
        let num_glyphs = self.num_glyphs();
557
247
        let start = self.ppi_byte_range().end;
558
247
        let end = start + (transforms::add(num_glyphs, 1_usize)).saturating_mul(u32::RAW_BYTE_LEN);
559
247
        start..end
560
247
    }
561
}
562
563
const _: () = assert!(FontData::default_data_long_enough(Strike::MIN_SIZE));
564
565
impl Default for Strike<'_> {
566
0
    fn default() -> Self {
567
        Self {
568
0
            data: TableDataRef::new(FontData::default_table_data().as_bytes())
569
0
                .unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
570
0
            num_glyphs: Default::default(),
571
        }
572
0
    }
573
}
574
575
impl<'a> MinByteRange<'a> for GlyphData<'a> {
576
0
    fn min_byte_range(&self) -> Range<usize> {
577
0
        0..self.data_byte_range().end
578
0
    }
579
0
    fn min_table_bytes(&self) -> &'a [u8] {
580
0
        let range = self.min_byte_range();
581
0
        self.offset_data().as_bytes().get(range).unwrap_or_default()
582
0
    }
583
}
584
585
impl ReadArgs for GlyphData<'_> {
586
    type Args = ();
587
}
588
589
impl<'a> FontRead<'a> for GlyphData<'a> {
590
11
    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
591
        #[allow(clippy::absurd_extreme_comparisons)]
592
11
        if data.len() < Self::MIN_SIZE {
593
6
            return Err(ReadError::OutOfBounds);
594
5
        }
595
5
        let Some(data) = TableDataRef::new(data.as_bytes()) else {
596
0
            return Err(ReadError::OutOfBounds);
597
        };
598
5
        Ok(Self { data })
599
11
    }
600
}
601
602
/// The fields at the start of the table, which are read directly.
603
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
604
#[repr(C, packed)]
605
#[doc(hidden)]
606
pub struct GlyphDataFixedHeader {
607
    pub origin_offset_x: BigEndian<i16>,
608
    pub origin_offset_y: BigEndian<i16>,
609
    pub graphic_type: BigEndian<Tag>,
610
}
611
612
#[allow(clippy::absurd_extreme_comparisons)]
613
const _: () = assert!(std::mem::size_of::<GlyphDataFixedHeader>() <= GlyphData::MIN_SIZE);
614
615
/// [Glyph data](https://learn.microsoft.com/en-us/typography/opentype/spec/sbix#glyph-data) table
616
#[derive(Clone)]
617
pub struct GlyphData<'a> {
618
    data: TableDataRef<'a, GlyphDataFixedHeader>,
619
}
620
621
#[allow(clippy::needless_lifetimes)]
622
impl<'a> GlyphData<'a> {
623
    pub const MIN_SIZE: usize = (i16::RAW_BYTE_LEN + i16::RAW_BYTE_LEN + Tag::RAW_BYTE_LEN);
624
    basic_table_impls!(impl_the_methods);
625
626
    /// The horizontal (x-axis) position of the left edge of the bitmap graphic in relation to the glyph design space origin.
627
0
    pub fn origin_offset_x(&self) -> i16 {
628
0
        self.data.header().origin_offset_x.get()
629
0
    }
630
631
    /// The vertical (y-axis) position of the bottom edge of the bitmap graphic in relation to the glyph design space origin.
632
0
    pub fn origin_offset_y(&self) -> i16 {
633
0
        self.data.header().origin_offset_y.get()
634
0
    }
635
636
    /// Indicates the format of the embedded graphic data: one of 'jpg ', 'png ' or 'tiff', or the special format 'dupe'.
637
5
    pub fn graphic_type(&self) -> Tag {
638
5
        self.data.header().graphic_type.get()
639
5
    }
640
641
    /// The actual embedded graphic data. The total length is inferred from sequential entries in the glyphDataOffsets array and the fixed size (8 bytes) of the preceding fields.
642
0
    pub fn data(&self) -> &'a [u8] {
643
0
        let range = self.data_byte_range();
644
0
        self.offset_data()
645
0
            .read_array(range)
646
0
            .ok()
647
0
            .unwrap_or_default()
648
0
    }
649
650
0
    pub fn origin_offset_x_byte_range(&self) -> Range<usize> {
651
0
        let start = 0;
652
0
        let end = start + i16::RAW_BYTE_LEN;
653
0
        start..end
654
0
    }
655
656
0
    pub fn origin_offset_y_byte_range(&self) -> Range<usize> {
657
0
        let start = self.origin_offset_x_byte_range().end;
658
0
        let end = start + i16::RAW_BYTE_LEN;
659
0
        start..end
660
0
    }
661
662
0
    pub fn graphic_type_byte_range(&self) -> Range<usize> {
663
0
        let start = self.origin_offset_y_byte_range().end;
664
0
        let end = start + Tag::RAW_BYTE_LEN;
665
0
        start..end
666
0
    }
667
668
0
    pub fn data_byte_range(&self) -> Range<usize> {
669
0
        let start = self.graphic_type_byte_range().end;
670
0
        let end = start
671
0
            + self.offset_data().len().saturating_sub(start) / u8::RAW_BYTE_LEN * u8::RAW_BYTE_LEN;
672
0
        start..end
673
0
    }
674
}
675
676
const _: () = assert!(FontData::default_data_long_enough(GlyphData::MIN_SIZE));
677
678
impl Default for GlyphData<'_> {
679
0
    fn default() -> Self {
680
        Self {
681
0
            data: TableDataRef::new(FontData::default_table_data().as_bytes())
682
0
                .unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
683
        }
684
0
    }
685
}