Coverage Report

Created: 2025-07-23 06:50

/src/fontations/read-fonts/generated/generated_sbix.rs
Line
Count
Source (jump to first uncovered line)
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
0
#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash, bytemuck :: AnyBitPattern)]
Unexecuted instantiation: read_fonts::tables::sbix::_::{closure#0}::check
Unexecuted instantiation: read_fonts::tables::sbix::_::{closure#0}
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
    }
Unexecuted instantiation: <read_fonts::tables::sbix::HeaderFlags>::bits
Unexecuted instantiation: <read_fonts::tables::sbix::HeaderFlags>::bits
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
#[cfg(feature = "experimental_traverse")]
310
impl<'a> From<HeaderFlags> for FieldType<'a> {
311
    fn from(src: HeaderFlags) -> FieldType<'a> {
312
        src.bits().into()
313
    }
314
}
315
316
/// The [sbix (Standard Bitmap Graphics)](https://docs.microsoft.com/en-us/typography/opentype/spec/sbix) table
317
#[derive(Debug, Clone, Copy)]
318
#[doc(hidden)]
319
pub struct SbixMarker {
320
    num_glyphs: u16,
321
    strike_offsets_byte_len: usize,
322
}
323
324
impl SbixMarker {
325
0
    pub fn version_byte_range(&self) -> Range<usize> {
326
0
        let start = 0;
327
0
        start..start + u16::RAW_BYTE_LEN
328
0
    }
329
330
0
    pub fn flags_byte_range(&self) -> Range<usize> {
331
0
        let start = self.version_byte_range().end;
332
0
        start..start + HeaderFlags::RAW_BYTE_LEN
333
0
    }
334
335
0
    pub fn num_strikes_byte_range(&self) -> Range<usize> {
336
0
        let start = self.flags_byte_range().end;
337
0
        start..start + u32::RAW_BYTE_LEN
338
0
    }
339
340
0
    pub fn strike_offsets_byte_range(&self) -> Range<usize> {
341
0
        let start = self.num_strikes_byte_range().end;
342
0
        start..start + self.strike_offsets_byte_len
343
0
    }
344
}
345
346
impl MinByteRange for SbixMarker {
347
0
    fn min_byte_range(&self) -> Range<usize> {
348
0
        0..self.strike_offsets_byte_range().end
349
0
    }
350
}
351
352
impl TopLevelTable for Sbix<'_> {
353
    /// `sbix`
354
    const TAG: Tag = Tag::new(b"sbix");
355
}
356
357
impl ReadArgs for Sbix<'_> {
358
    type Args = u16;
359
}
360
361
impl<'a> FontReadWithArgs<'a> for Sbix<'a> {
362
0
    fn read_with_args(data: FontData<'a>, args: &u16) -> Result<Self, ReadError> {
363
0
        let num_glyphs = *args;
364
0
        let mut cursor = data.cursor();
365
0
        cursor.advance::<u16>();
366
0
        cursor.advance::<HeaderFlags>();
367
0
        let num_strikes: u32 = cursor.read()?;
368
0
        let strike_offsets_byte_len = (num_strikes as usize)
369
0
            .checked_mul(Offset32::RAW_BYTE_LEN)
370
0
            .ok_or(ReadError::OutOfBounds)?;
371
0
        cursor.advance_by(strike_offsets_byte_len);
372
0
        cursor.finish(SbixMarker {
373
0
            num_glyphs,
374
0
            strike_offsets_byte_len,
375
0
        })
376
0
    }
377
}
378
379
impl<'a> Sbix<'a> {
380
    /// A constructor that requires additional arguments.
381
    ///
382
    /// This type requires some external state in order to be
383
    /// parsed.
384
0
    pub fn read(data: FontData<'a>, num_glyphs: u16) -> Result<Self, ReadError> {
385
0
        let args = num_glyphs;
386
0
        Self::read_with_args(data, &args)
387
0
    }
388
}
389
390
/// The [sbix (Standard Bitmap Graphics)](https://docs.microsoft.com/en-us/typography/opentype/spec/sbix) table
391
pub type Sbix<'a> = TableRef<'a, SbixMarker>;
392
393
#[allow(clippy::needless_lifetimes)]
394
impl<'a> Sbix<'a> {
395
    /// Table version number — set to 1.
396
0
    pub fn version(&self) -> u16 {
397
0
        let range = self.shape.version_byte_range();
398
0
        self.data.read_at(range.start).unwrap()
399
0
    }
400
401
    /// Bit 0: Set to 1.
402
    /// Bit 1: Draw outlines.
403
    /// Bits 2 to 15: reserved (set to 0).
404
0
    pub fn flags(&self) -> HeaderFlags {
405
0
        let range = self.shape.flags_byte_range();
406
0
        self.data.read_at(range.start).unwrap()
407
0
    }
408
409
    /// Number of bitmap strikes.
410
0
    pub fn num_strikes(&self) -> u32 {
411
0
        let range = self.shape.num_strikes_byte_range();
412
0
        self.data.read_at(range.start).unwrap()
413
0
    }
414
415
    /// Offsets from the beginning of the 'sbix' table to data for each individual bitmap strike.
416
0
    pub fn strike_offsets(&self) -> &'a [BigEndian<Offset32>] {
417
0
        let range = self.shape.strike_offsets_byte_range();
418
0
        self.data.read_array(range).unwrap()
419
0
    }
420
421
    /// A dynamically resolving wrapper for [`strike_offsets`][Self::strike_offsets].
422
0
    pub fn strikes(&self) -> ArrayOfOffsets<'a, Strike<'a>, Offset32> {
423
0
        let data = self.data;
424
0
        let offsets = self.strike_offsets();
425
0
        let args = self.num_glyphs();
426
0
        ArrayOfOffsets::new(offsets, data, args)
427
0
    }
428
429
0
    pub(crate) fn num_glyphs(&self) -> u16 {
430
0
        self.shape.num_glyphs
431
0
    }
432
}
433
434
#[cfg(feature = "experimental_traverse")]
435
impl<'a> SomeTable<'a> for Sbix<'a> {
436
    fn type_name(&self) -> &str {
437
        "Sbix"
438
    }
439
    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
440
        match idx {
441
            0usize => Some(Field::new("version", self.version())),
442
            1usize => Some(Field::new("flags", self.flags())),
443
            2usize => Some(Field::new("num_strikes", self.num_strikes())),
444
            3usize => Some({
445
                let data = self.data;
446
                let args = self.num_glyphs();
447
                Field::new(
448
                    "strike_offsets",
449
                    FieldType::array_of_offsets(
450
                        better_type_name::<Strike>(),
451
                        self.strike_offsets(),
452
                        move |off| {
453
                            let target = off.get().resolve_with_args::<Strike>(data, &args);
454
                            FieldType::offset(off.get(), target)
455
                        },
456
                    ),
457
                )
458
            }),
459
            _ => None,
460
        }
461
    }
462
}
463
464
#[cfg(feature = "experimental_traverse")]
465
#[allow(clippy::needless_lifetimes)]
466
impl<'a> std::fmt::Debug for Sbix<'a> {
467
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
468
        (self as &dyn SomeTable<'a>).fmt(f)
469
    }
470
}
471
472
/// [Strike](https://learn.microsoft.com/en-us/typography/opentype/spec/sbix#strikes) header table
473
#[derive(Debug, Clone, Copy)]
474
#[doc(hidden)]
475
pub struct StrikeMarker {
476
    glyph_data_offsets_byte_len: usize,
477
}
478
479
impl StrikeMarker {
480
0
    pub fn ppem_byte_range(&self) -> Range<usize> {
481
0
        let start = 0;
482
0
        start..start + u16::RAW_BYTE_LEN
483
0
    }
484
485
0
    pub fn ppi_byte_range(&self) -> Range<usize> {
486
0
        let start = self.ppem_byte_range().end;
487
0
        start..start + u16::RAW_BYTE_LEN
488
0
    }
489
490
0
    pub fn glyph_data_offsets_byte_range(&self) -> Range<usize> {
491
0
        let start = self.ppi_byte_range().end;
492
0
        start..start + self.glyph_data_offsets_byte_len
493
0
    }
494
}
495
496
impl MinByteRange for StrikeMarker {
497
0
    fn min_byte_range(&self) -> Range<usize> {
498
0
        0..self.glyph_data_offsets_byte_range().end
499
0
    }
500
}
501
502
impl ReadArgs for Strike<'_> {
503
    type Args = u16;
504
}
505
506
impl<'a> FontReadWithArgs<'a> for Strike<'a> {
507
0
    fn read_with_args(data: FontData<'a>, args: &u16) -> Result<Self, ReadError> {
508
0
        let num_glyphs = *args;
509
0
        let mut cursor = data.cursor();
510
0
        cursor.advance::<u16>();
511
0
        cursor.advance::<u16>();
512
0
        let glyph_data_offsets_byte_len = (transforms::add(num_glyphs, 1_usize))
513
0
            .checked_mul(u32::RAW_BYTE_LEN)
514
0
            .ok_or(ReadError::OutOfBounds)?;
515
0
        cursor.advance_by(glyph_data_offsets_byte_len);
516
0
        cursor.finish(StrikeMarker {
517
0
            glyph_data_offsets_byte_len,
518
0
        })
519
0
    }
520
}
521
522
impl<'a> Strike<'a> {
523
    /// A constructor that requires additional arguments.
524
    ///
525
    /// This type requires some external state in order to be
526
    /// parsed.
527
0
    pub fn read(data: FontData<'a>, num_glyphs: u16) -> Result<Self, ReadError> {
528
0
        let args = num_glyphs;
529
0
        Self::read_with_args(data, &args)
530
0
    }
531
}
532
533
/// [Strike](https://learn.microsoft.com/en-us/typography/opentype/spec/sbix#strikes) header table
534
pub type Strike<'a> = TableRef<'a, StrikeMarker>;
535
536
#[allow(clippy::needless_lifetimes)]
537
impl<'a> Strike<'a> {
538
    /// The PPEM size for which this strike was designed.
539
0
    pub fn ppem(&self) -> u16 {
540
0
        let range = self.shape.ppem_byte_range();
541
0
        self.data.read_at(range.start).unwrap()
542
0
    }
543
544
    /// The device pixel density (in PPI) for which this strike was designed. (E.g., 96 PPI, 192 PPI.)
545
0
    pub fn ppi(&self) -> u16 {
546
0
        let range = self.shape.ppi_byte_range();
547
0
        self.data.read_at(range.start).unwrap()
548
0
    }
549
550
    /// Offset from the beginning of the strike data header to bitmap data for an individual glyph ID.
551
0
    pub fn glyph_data_offsets(&self) -> &'a [BigEndian<u32>] {
552
0
        let range = self.shape.glyph_data_offsets_byte_range();
553
0
        self.data.read_array(range).unwrap()
554
0
    }
555
}
556
557
#[cfg(feature = "experimental_traverse")]
558
impl<'a> SomeTable<'a> for Strike<'a> {
559
    fn type_name(&self) -> &str {
560
        "Strike"
561
    }
562
    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
563
        match idx {
564
            0usize => Some(Field::new("ppem", self.ppem())),
565
            1usize => Some(Field::new("ppi", self.ppi())),
566
            2usize => Some(Field::new("glyph_data_offsets", self.glyph_data_offsets())),
567
            _ => None,
568
        }
569
    }
570
}
571
572
#[cfg(feature = "experimental_traverse")]
573
#[allow(clippy::needless_lifetimes)]
574
impl<'a> std::fmt::Debug for Strike<'a> {
575
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
576
        (self as &dyn SomeTable<'a>).fmt(f)
577
    }
578
}
579
580
/// [Glyph data](https://learn.microsoft.com/en-us/typography/opentype/spec/sbix#glyph-data) table
581
#[derive(Debug, Clone, Copy)]
582
#[doc(hidden)]
583
pub struct GlyphDataMarker {
584
    data_byte_len: usize,
585
}
586
587
impl GlyphDataMarker {
588
0
    pub fn origin_offset_x_byte_range(&self) -> Range<usize> {
589
0
        let start = 0;
590
0
        start..start + i16::RAW_BYTE_LEN
591
0
    }
592
593
0
    pub fn origin_offset_y_byte_range(&self) -> Range<usize> {
594
0
        let start = self.origin_offset_x_byte_range().end;
595
0
        start..start + i16::RAW_BYTE_LEN
596
0
    }
597
598
0
    pub fn graphic_type_byte_range(&self) -> Range<usize> {
599
0
        let start = self.origin_offset_y_byte_range().end;
600
0
        start..start + Tag::RAW_BYTE_LEN
601
0
    }
602
603
0
    pub fn data_byte_range(&self) -> Range<usize> {
604
0
        let start = self.graphic_type_byte_range().end;
605
0
        start..start + self.data_byte_len
606
0
    }
607
}
608
609
impl MinByteRange for GlyphDataMarker {
610
0
    fn min_byte_range(&self) -> Range<usize> {
611
0
        0..self.data_byte_range().end
612
0
    }
613
}
614
615
impl<'a> FontRead<'a> for GlyphData<'a> {
616
0
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
617
0
        let mut cursor = data.cursor();
618
0
        cursor.advance::<i16>();
619
0
        cursor.advance::<i16>();
620
0
        cursor.advance::<Tag>();
621
0
        let data_byte_len = cursor.remaining_bytes() / u8::RAW_BYTE_LEN * u8::RAW_BYTE_LEN;
622
0
        cursor.advance_by(data_byte_len);
623
0
        cursor.finish(GlyphDataMarker { data_byte_len })
624
0
    }
625
}
626
627
/// [Glyph data](https://learn.microsoft.com/en-us/typography/opentype/spec/sbix#glyph-data) table
628
pub type GlyphData<'a> = TableRef<'a, GlyphDataMarker>;
629
630
#[allow(clippy::needless_lifetimes)]
631
impl<'a> GlyphData<'a> {
632
    /// The horizontal (x-axis) position of the left edge of the bitmap graphic in relation to the glyph design space origin.
633
0
    pub fn origin_offset_x(&self) -> i16 {
634
0
        let range = self.shape.origin_offset_x_byte_range();
635
0
        self.data.read_at(range.start).unwrap()
636
0
    }
637
638
    /// The vertical (y-axis) position of the bottom edge of the bitmap graphic in relation to the glyph design space origin.
639
0
    pub fn origin_offset_y(&self) -> i16 {
640
0
        let range = self.shape.origin_offset_y_byte_range();
641
0
        self.data.read_at(range.start).unwrap()
642
0
    }
643
644
    /// Indicates the format of the embedded graphic data: one of 'jpg ', 'png ' or 'tiff', or the special format 'dupe'.
645
0
    pub fn graphic_type(&self) -> Tag {
646
0
        let range = self.shape.graphic_type_byte_range();
647
0
        self.data.read_at(range.start).unwrap()
648
0
    }
649
650
    /// 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.
651
0
    pub fn data(&self) -> &'a [u8] {
652
0
        let range = self.shape.data_byte_range();
653
0
        self.data.read_array(range).unwrap()
654
0
    }
655
}
656
657
#[cfg(feature = "experimental_traverse")]
658
impl<'a> SomeTable<'a> for GlyphData<'a> {
659
    fn type_name(&self) -> &str {
660
        "GlyphData"
661
    }
662
    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
663
        match idx {
664
            0usize => Some(Field::new("origin_offset_x", self.origin_offset_x())),
665
            1usize => Some(Field::new("origin_offset_y", self.origin_offset_y())),
666
            2usize => Some(Field::new("graphic_type", self.graphic_type())),
667
            3usize => Some(Field::new("data", self.data())),
668
            _ => None,
669
        }
670
    }
671
}
672
673
#[cfg(feature = "experimental_traverse")]
674
#[allow(clippy::needless_lifetimes)]
675
impl<'a> std::fmt::Debug for GlyphData<'a> {
676
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
677
        (self as &dyn SomeTable<'a>).fmt(f)
678
    }
679
}