Skip to main content

read_fonts/generated/
generated_sbix.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/// 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)]
12pub struct HeaderFlags {
13    bits: u16,
14}
15
16impl 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
24impl HeaderFlags {
25    ///  Returns an empty set of flags.
26    #[inline]
27    pub const fn empty() -> Self {
28        Self { bits: 0 }
29    }
30
31    /// Returns the set containing all flags.
32    #[inline]
33    pub const fn all() -> Self {
34        Self {
35            bits: Self::ALWAYS_SET.bits | Self::DRAW_OUTLINES.bits,
36        }
37    }
38
39    /// Returns the raw value of the flags currently stored.
40    #[inline]
41    pub const fn bits(&self) -> u16 {
42        self.bits
43    }
44
45    /// Convert from underlying bit representation, unless that
46    /// representation contains bits that do not correspond to a flag.
47    #[inline]
48    pub const fn from_bits(bits: u16) -> Option<Self> {
49        if (bits & !Self::all().bits()) == 0 {
50            Some(Self { bits })
51        } else {
52            None
53        }
54    }
55
56    /// Convert from underlying bit representation, dropping any bits
57    /// that do not correspond to flags.
58    #[inline]
59    pub const fn from_bits_truncate(bits: u16) -> Self {
60        Self {
61            bits: bits & Self::all().bits,
62        }
63    }
64
65    /// Returns `true` if no flags are currently stored.
66    #[inline]
67    pub const fn is_empty(&self) -> bool {
68        self.bits() == Self::empty().bits()
69    }
70
71    /// Returns `true` if there are flags common to both `self` and `other`.
72    #[inline]
73    pub const fn intersects(&self, other: Self) -> bool {
74        !(Self {
75            bits: self.bits & other.bits,
76        })
77        .is_empty()
78    }
79
80    /// Returns `true` if all of the flags in `other` are contained within `self`.
81    #[inline]
82    pub const fn contains(&self, other: Self) -> bool {
83        (self.bits & other.bits) == other.bits
84    }
85
86    /// Inserts the specified flags in-place.
87    #[inline]
88    pub fn insert(&mut self, other: Self) {
89        self.bits |= other.bits;
90    }
91
92    /// Removes the specified flags in-place.
93    #[inline]
94    pub fn remove(&mut self, other: Self) {
95        self.bits &= !other.bits;
96    }
97
98    /// Toggles the specified flags in-place.
99    #[inline]
100    pub fn toggle(&mut self, other: Self) {
101        self.bits ^= other.bits;
102    }
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    pub const fn intersection(self, other: Self) -> Self {
117        Self {
118            bits: self.bits & other.bits,
119        }
120    }
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    pub const fn union(self, other: Self) -> Self {
135        Self {
136            bits: self.bits | other.bits,
137        }
138    }
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    pub const fn difference(self, other: Self) -> Self {
155        Self {
156            bits: self.bits & !other.bits,
157        }
158    }
159}
160
161impl std::ops::BitOr for HeaderFlags {
162    type Output = Self;
163
164    /// Returns the union of the two sets of flags.
165    #[inline]
166    fn bitor(self, other: HeaderFlags) -> Self {
167        Self {
168            bits: self.bits | other.bits,
169        }
170    }
171}
172
173impl std::ops::BitOrAssign for HeaderFlags {
174    /// Adds the set of flags.
175    #[inline]
176    fn bitor_assign(&mut self, other: Self) {
177        self.bits |= other.bits;
178    }
179}
180
181impl 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    fn bitxor(self, other: Self) -> Self {
187        Self {
188            bits: self.bits ^ other.bits,
189        }
190    }
191}
192
193impl std::ops::BitXorAssign for HeaderFlags {
194    /// Toggles the set of flags.
195    #[inline]
196    fn bitxor_assign(&mut self, other: Self) {
197        self.bits ^= other.bits;
198    }
199}
200
201impl std::ops::BitAnd for HeaderFlags {
202    type Output = Self;
203
204    /// Returns the intersection between the two sets of flags.
205    #[inline]
206    fn bitand(self, other: Self) -> Self {
207        Self {
208            bits: self.bits & other.bits,
209        }
210    }
211}
212
213impl std::ops::BitAndAssign for HeaderFlags {
214    /// Disables all flags disabled in the set.
215    #[inline]
216    fn bitand_assign(&mut self, other: Self) {
217        self.bits &= other.bits;
218    }
219}
220
221impl std::ops::Sub for HeaderFlags {
222    type Output = Self;
223
224    /// Returns the set difference of the two sets of flags.
225    #[inline]
226    fn sub(self, other: Self) -> Self {
227        Self {
228            bits: self.bits & !other.bits,
229        }
230    }
231}
232
233impl std::ops::SubAssign for HeaderFlags {
234    /// Disables all flags enabled in the set.
235    #[inline]
236    fn sub_assign(&mut self, other: Self) {
237        self.bits &= !other.bits;
238    }
239}
240
241impl std::ops::Not for HeaderFlags {
242    type Output = Self;
243
244    /// Returns the complement of this set of flags.
245    #[inline]
246    fn not(self) -> Self {
247        Self { bits: !self.bits } & Self::all()
248    }
249}
250
251impl std::fmt::Debug for HeaderFlags {
252    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
253        let members: &[(&str, Self)] = &[
254            ("ALWAYS_SET", Self::ALWAYS_SET),
255            ("DRAW_OUTLINES", Self::DRAW_OUTLINES),
256        ];
257        let mut first = true;
258        for (name, value) in members {
259            if self.contains(*value) {
260                if !first {
261                    f.write_str(" | ")?;
262                }
263                first = false;
264                f.write_str(name)?;
265            }
266        }
267        if first {
268            f.write_str("(empty)")?;
269        }
270        Ok(())
271    }
272}
273
274impl std::fmt::Binary for HeaderFlags {
275    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
276        std::fmt::Binary::fmt(&self.bits, f)
277    }
278}
279
280impl std::fmt::Octal for HeaderFlags {
281    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
282        std::fmt::Octal::fmt(&self.bits, f)
283    }
284}
285
286impl std::fmt::LowerHex for HeaderFlags {
287    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
288        std::fmt::LowerHex::fmt(&self.bits, f)
289    }
290}
291
292impl std::fmt::UpperHex for HeaderFlags {
293    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
294        std::fmt::UpperHex::fmt(&self.bits, f)
295    }
296}
297
298impl font_types::Scalar for HeaderFlags {
299    type Raw = <u16 as font_types::Scalar>::Raw;
300    fn to_raw(self) -> Self::Raw {
301        self.bits().to_raw()
302    }
303    fn from_raw(raw: Self::Raw) -> Self {
304        let t = <u16>::from_raw(raw);
305        Self::from_bits_truncate(t)
306    }
307}
308
309impl<'a> MinByteRange<'a> for Sbix<'a> {
310    fn min_byte_range(&self) -> Range<usize> {
311        0..self.strike_offsets_byte_range().end
312    }
313    fn min_table_bytes(&self) -> &'a [u8] {
314        let range = self.min_byte_range();
315        self.offset_data().as_bytes().get(range).unwrap_or_default()
316    }
317}
318
319impl TopLevelTable for Sbix<'_> {
320    /// `sbix`
321    const TAG: Tag = Tag::new(b"sbix");
322}
323
324impl ReadArgs for Sbix<'_> {
325    type Args = u32;
326}
327
328impl<'a> FontRead<'a> for Sbix<'a> {
329    fn read_with_args(data: FontData<'a>, args: u32) -> Result<Self, ReadError> {
330        let num_glyphs = args;
331
332        #[allow(clippy::absurd_extreme_comparisons)]
333        if data.len() < Self::MIN_SIZE {
334            return Err(ReadError::OutOfBounds);
335        }
336        let Some(data) = TableDataRef::new(data.as_bytes()) else {
337            return Err(ReadError::OutOfBounds);
338        };
339        Ok(Self { data, num_glyphs })
340    }
341}
342
343impl<'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    pub fn read(data: FontData<'a>, num_glyphs: u32) -> Result<Self, ReadError> {
349        let args = num_glyphs;
350        Self::read_with_args(data, args)
351    }
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)]
358pub 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)]
365const _: () = 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)]
369pub struct Sbix<'a> {
370    data: TableDataRef<'a, SbixFixedHeader>,
371    num_glyphs: u32,
372}
373
374#[allow(clippy::needless_lifetimes)]
375impl<'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    pub fn version(&self) -> u16 {
381        self.data.header().version.get()
382    }
383
384    /// Bit 0: Set to 1.
385    /// Bit 1: Draw outlines.
386    /// Bits 2 to 15: reserved (set to 0).
387    pub fn flags(&self) -> HeaderFlags {
388        self.data.header().flags.get()
389    }
390
391    /// Number of bitmap strikes.
392    pub fn num_strikes(&self) -> u32 {
393        self.data.header().num_strikes.get()
394    }
395
396    /// Offsets from the beginning of the 'sbix' table to data for each individual bitmap strike.
397    pub fn strike_offsets(&self) -> &'a [BigEndian<Offset32>] {
398        let range = self.strike_offsets_byte_range();
399        self.offset_data()
400            .read_array(range)
401            .ok()
402            .unwrap_or_default()
403    }
404
405    /// A dynamically resolving wrapper for [`strike_offsets`][Self::strike_offsets].
406    pub fn strikes(&self) -> ArrayOfOffsets<'a, Strike<'a>, Offset32> {
407        let data = self.offset_data();
408        let offsets = self.strike_offsets();
409        let args = self.num_glyphs();
410        ArrayOfOffsets::new(offsets, data, args)
411    }
412
413    pub(crate) fn num_glyphs(&self) -> u32 {
414        self.num_glyphs
415    }
416
417    pub fn version_byte_range(&self) -> Range<usize> {
418        let start = 0;
419        let end = start + u16::RAW_BYTE_LEN;
420        start..end
421    }
422
423    pub fn flags_byte_range(&self) -> Range<usize> {
424        let start = self.version_byte_range().end;
425        let end = start + HeaderFlags::RAW_BYTE_LEN;
426        start..end
427    }
428
429    pub fn num_strikes_byte_range(&self) -> Range<usize> {
430        let start = self.flags_byte_range().end;
431        let end = start + u32::RAW_BYTE_LEN;
432        start..end
433    }
434
435    pub fn strike_offsets_byte_range(&self) -> Range<usize> {
436        let num_strikes = self.num_strikes();
437        let start = self.num_strikes_byte_range().end;
438        let end =
439            start + (transforms::to_usize(num_strikes)).saturating_mul(Offset32::RAW_BYTE_LEN);
440        start..end
441    }
442}
443
444const _: () = assert!(FontData::default_data_long_enough(Sbix::MIN_SIZE));
445
446impl Default for Sbix<'_> {
447    fn default() -> Self {
448        Self {
449            data: TableDataRef::new(FontData::default_table_data().as_bytes())
450                .unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
451            num_glyphs: Default::default(),
452        }
453    }
454}
455
456impl<'a> MinByteRange<'a> for Strike<'a> {
457    fn min_byte_range(&self) -> Range<usize> {
458        0..self.glyph_data_offsets_byte_range().end
459    }
460    fn min_table_bytes(&self) -> &'a [u8] {
461        let range = self.min_byte_range();
462        self.offset_data().as_bytes().get(range).unwrap_or_default()
463    }
464}
465
466impl ReadArgs for Strike<'_> {
467    type Args = u32;
468}
469
470impl<'a> FontRead<'a> for Strike<'a> {
471    fn read_with_args(data: FontData<'a>, args: u32) -> Result<Self, ReadError> {
472        let num_glyphs = args;
473
474        #[allow(clippy::absurd_extreme_comparisons)]
475        if data.len() < Self::MIN_SIZE {
476            return Err(ReadError::OutOfBounds);
477        }
478        let Some(data) = TableDataRef::new(data.as_bytes()) else {
479            return Err(ReadError::OutOfBounds);
480        };
481        Ok(Self { data, num_glyphs })
482    }
483}
484
485impl<'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    pub fn read(data: FontData<'a>, num_glyphs: u32) -> Result<Self, ReadError> {
491        let args = num_glyphs;
492        Self::read_with_args(data, args)
493    }
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)]
500pub struct StrikeFixedHeader {
501    pub ppem: BigEndian<u16>,
502    pub ppi: BigEndian<u16>,
503}
504
505#[allow(clippy::absurd_extreme_comparisons)]
506const _: () = 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)]
510pub struct Strike<'a> {
511    data: TableDataRef<'a, StrikeFixedHeader>,
512    num_glyphs: u32,
513}
514
515#[allow(clippy::needless_lifetimes)]
516impl<'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    pub fn ppem(&self) -> u16 {
522        self.data.header().ppem.get()
523    }
524
525    /// The device pixel density (in PPI) for which this strike was designed. (E.g., 96 PPI, 192 PPI.)
526    pub fn ppi(&self) -> u16 {
527        self.data.header().ppi.get()
528    }
529
530    /// Offset from the beginning of the strike data header to bitmap data for an individual glyph ID.
531    pub fn glyph_data_offsets(&self) -> &'a [BigEndian<u32>] {
532        let range = self.glyph_data_offsets_byte_range();
533        self.offset_data()
534            .read_array(range)
535            .ok()
536            .unwrap_or_default()
537    }
538
539    pub(crate) fn num_glyphs(&self) -> u32 {
540        self.num_glyphs
541    }
542
543    pub fn ppem_byte_range(&self) -> Range<usize> {
544        let start = 0;
545        let end = start + u16::RAW_BYTE_LEN;
546        start..end
547    }
548
549    pub fn ppi_byte_range(&self) -> Range<usize> {
550        let start = self.ppem_byte_range().end;
551        let end = start + u16::RAW_BYTE_LEN;
552        start..end
553    }
554
555    pub fn glyph_data_offsets_byte_range(&self) -> Range<usize> {
556        let num_glyphs = self.num_glyphs();
557        let start = self.ppi_byte_range().end;
558        let end = start + (transforms::add(num_glyphs, 1_usize)).saturating_mul(u32::RAW_BYTE_LEN);
559        start..end
560    }
561}
562
563const _: () = assert!(FontData::default_data_long_enough(Strike::MIN_SIZE));
564
565impl Default for Strike<'_> {
566    fn default() -> Self {
567        Self {
568            data: TableDataRef::new(FontData::default_table_data().as_bytes())
569                .unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
570            num_glyphs: Default::default(),
571        }
572    }
573}
574
575impl<'a> MinByteRange<'a> for GlyphData<'a> {
576    fn min_byte_range(&self) -> Range<usize> {
577        0..self.data_byte_range().end
578    }
579    fn min_table_bytes(&self) -> &'a [u8] {
580        let range = self.min_byte_range();
581        self.offset_data().as_bytes().get(range).unwrap_or_default()
582    }
583}
584
585impl ReadArgs for GlyphData<'_> {
586    type Args = ();
587}
588
589impl<'a> FontRead<'a> for GlyphData<'a> {
590    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
591        #[allow(clippy::absurd_extreme_comparisons)]
592        if data.len() < Self::MIN_SIZE {
593            return Err(ReadError::OutOfBounds);
594        }
595        let Some(data) = TableDataRef::new(data.as_bytes()) else {
596            return Err(ReadError::OutOfBounds);
597        };
598        Ok(Self { data })
599    }
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)]
606pub 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)]
613const _: () = 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)]
617pub struct GlyphData<'a> {
618    data: TableDataRef<'a, GlyphDataFixedHeader>,
619}
620
621#[allow(clippy::needless_lifetimes)]
622impl<'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    pub fn origin_offset_x(&self) -> i16 {
628        self.data.header().origin_offset_x.get()
629    }
630
631    /// The vertical (y-axis) position of the bottom edge of the bitmap graphic in relation to the glyph design space origin.
632    pub fn origin_offset_y(&self) -> i16 {
633        self.data.header().origin_offset_y.get()
634    }
635
636    /// Indicates the format of the embedded graphic data: one of 'jpg ', 'png ' or 'tiff', or the special format 'dupe'.
637    pub fn graphic_type(&self) -> Tag {
638        self.data.header().graphic_type.get()
639    }
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    pub fn data(&self) -> &'a [u8] {
643        let range = self.data_byte_range();
644        self.offset_data()
645            .read_array(range)
646            .ok()
647            .unwrap_or_default()
648    }
649
650    pub fn origin_offset_x_byte_range(&self) -> Range<usize> {
651        let start = 0;
652        let end = start + i16::RAW_BYTE_LEN;
653        start..end
654    }
655
656    pub fn origin_offset_y_byte_range(&self) -> Range<usize> {
657        let start = self.origin_offset_x_byte_range().end;
658        let end = start + i16::RAW_BYTE_LEN;
659        start..end
660    }
661
662    pub fn graphic_type_byte_range(&self) -> Range<usize> {
663        let start = self.origin_offset_y_byte_range().end;
664        let end = start + Tag::RAW_BYTE_LEN;
665        start..end
666    }
667
668    pub fn data_byte_range(&self) -> Range<usize> {
669        let start = self.graphic_type_byte_range().end;
670        let end = start
671            + self.offset_data().len().saturating_sub(start) / u8::RAW_BYTE_LEN * u8::RAW_BYTE_LEN;
672        start..end
673    }
674}
675
676const _: () = assert!(FontData::default_data_long_enough(GlyphData::MIN_SIZE));
677
678impl Default for GlyphData<'_> {
679    fn default() -> Self {
680        Self {
681            data: TableDataRef::new(FontData::default_table_data().as_bytes())
682                .unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
683        }
684    }
685}