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.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 = u16;
326}
327
328impl<'a> FontRead<'a> for Sbix<'a> {
329    fn read_with_args(data: FontData<'a>, args: u16) -> 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        Ok(Self { data, num_glyphs })
337    }
338}
339
340impl<'a> Sbix<'a> {
341    /// A constructor that requires additional arguments.
342    ///
343    /// This type requires some external state in order to be
344    /// parsed.
345    pub fn read(data: FontData<'a>, num_glyphs: u16) -> Result<Self, ReadError> {
346        let args = num_glyphs;
347        Self::read_with_args(data, args)
348    }
349}
350
351/// The [sbix (Standard Bitmap Graphics)](https://docs.microsoft.com/en-us/typography/opentype/spec/sbix) table
352#[derive(Clone)]
353pub struct Sbix<'a> {
354    data: FontData<'a>,
355    num_glyphs: u16,
356}
357
358#[allow(clippy::needless_lifetimes)]
359impl<'a> Sbix<'a> {
360    pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + HeaderFlags::RAW_BYTE_LEN + u32::RAW_BYTE_LEN);
361    basic_table_impls!(impl_the_methods);
362
363    /// Table version number — set to 1.
364    pub fn version(&self) -> u16 {
365        let range = self.version_byte_range();
366        self.data.read_at(range.start).ok().unwrap()
367    }
368
369    /// Bit 0: Set to 1.
370    /// Bit 1: Draw outlines.
371    /// Bits 2 to 15: reserved (set to 0).
372    pub fn flags(&self) -> HeaderFlags {
373        let range = self.flags_byte_range();
374        self.data.read_at(range.start).ok().unwrap()
375    }
376
377    /// Number of bitmap strikes.
378    pub fn num_strikes(&self) -> u32 {
379        let range = self.num_strikes_byte_range();
380        self.data.read_at(range.start).ok().unwrap()
381    }
382
383    /// Offsets from the beginning of the 'sbix' table to data for each individual bitmap strike.
384    pub fn strike_offsets(&self) -> &'a [BigEndian<Offset32>] {
385        let range = self.strike_offsets_byte_range();
386        self.data.read_array(range).ok().unwrap_or_default()
387    }
388
389    /// A dynamically resolving wrapper for [`strike_offsets`][Self::strike_offsets].
390    pub fn strikes(&self) -> ArrayOfOffsets<'a, Strike<'a>, Offset32> {
391        let data = self.data;
392        let offsets = self.strike_offsets();
393        let args = self.num_glyphs();
394        ArrayOfOffsets::new(offsets, data, args)
395    }
396
397    pub(crate) fn num_glyphs(&self) -> u16 {
398        self.num_glyphs
399    }
400
401    pub fn version_byte_range(&self) -> Range<usize> {
402        let start = 0;
403        let end = start + u16::RAW_BYTE_LEN;
404        start..end
405    }
406
407    pub fn flags_byte_range(&self) -> Range<usize> {
408        let start = self.version_byte_range().end;
409        let end = start + HeaderFlags::RAW_BYTE_LEN;
410        start..end
411    }
412
413    pub fn num_strikes_byte_range(&self) -> Range<usize> {
414        let start = self.flags_byte_range().end;
415        let end = start + u32::RAW_BYTE_LEN;
416        start..end
417    }
418
419    pub fn strike_offsets_byte_range(&self) -> Range<usize> {
420        let num_strikes = self.num_strikes();
421        let start = self.num_strikes_byte_range().end;
422        let end =
423            start + (transforms::to_usize(num_strikes)).saturating_mul(Offset32::RAW_BYTE_LEN);
424        start..end
425    }
426}
427
428const _: () = assert!(FontData::default_data_long_enough(Sbix::MIN_SIZE));
429
430impl Default for Sbix<'_> {
431    fn default() -> Self {
432        Self {
433            data: FontData::default_table_data(),
434            num_glyphs: Default::default(),
435        }
436    }
437}
438
439impl<'a> MinByteRange<'a> for Strike<'a> {
440    fn min_byte_range(&self) -> Range<usize> {
441        0..self.glyph_data_offsets_byte_range().end
442    }
443    fn min_table_bytes(&self) -> &'a [u8] {
444        let range = self.min_byte_range();
445        self.data.as_bytes().get(range).unwrap_or_default()
446    }
447}
448
449impl ReadArgs for Strike<'_> {
450    type Args = u16;
451}
452
453impl<'a> FontRead<'a> for Strike<'a> {
454    fn read_with_args(data: FontData<'a>, args: u16) -> Result<Self, ReadError> {
455        let num_glyphs = args;
456
457        #[allow(clippy::absurd_extreme_comparisons)]
458        if data.len() < Self::MIN_SIZE {
459            return Err(ReadError::OutOfBounds);
460        }
461        Ok(Self { data, num_glyphs })
462    }
463}
464
465impl<'a> Strike<'a> {
466    /// A constructor that requires additional arguments.
467    ///
468    /// This type requires some external state in order to be
469    /// parsed.
470    pub fn read(data: FontData<'a>, num_glyphs: u16) -> Result<Self, ReadError> {
471        let args = num_glyphs;
472        Self::read_with_args(data, args)
473    }
474}
475
476/// [Strike](https://learn.microsoft.com/en-us/typography/opentype/spec/sbix#strikes) header table
477#[derive(Clone)]
478pub struct Strike<'a> {
479    data: FontData<'a>,
480    num_glyphs: u16,
481}
482
483#[allow(clippy::needless_lifetimes)]
484impl<'a> Strike<'a> {
485    pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN);
486    basic_table_impls!(impl_the_methods);
487
488    /// The PPEM size for which this strike was designed.
489    pub fn ppem(&self) -> u16 {
490        let range = self.ppem_byte_range();
491        self.data.read_at(range.start).ok().unwrap()
492    }
493
494    /// The device pixel density (in PPI) for which this strike was designed. (E.g., 96 PPI, 192 PPI.)
495    pub fn ppi(&self) -> u16 {
496        let range = self.ppi_byte_range();
497        self.data.read_at(range.start).ok().unwrap()
498    }
499
500    /// Offset from the beginning of the strike data header to bitmap data for an individual glyph ID.
501    pub fn glyph_data_offsets(&self) -> &'a [BigEndian<u32>] {
502        let range = self.glyph_data_offsets_byte_range();
503        self.data.read_array(range).ok().unwrap_or_default()
504    }
505
506    pub(crate) fn num_glyphs(&self) -> u16 {
507        self.num_glyphs
508    }
509
510    pub fn ppem_byte_range(&self) -> Range<usize> {
511        let start = 0;
512        let end = start + u16::RAW_BYTE_LEN;
513        start..end
514    }
515
516    pub fn ppi_byte_range(&self) -> Range<usize> {
517        let start = self.ppem_byte_range().end;
518        let end = start + u16::RAW_BYTE_LEN;
519        start..end
520    }
521
522    pub fn glyph_data_offsets_byte_range(&self) -> Range<usize> {
523        let num_glyphs = self.num_glyphs();
524        let start = self.ppi_byte_range().end;
525        let end = start + (transforms::add(num_glyphs, 1_usize)).saturating_mul(u32::RAW_BYTE_LEN);
526        start..end
527    }
528}
529
530const _: () = assert!(FontData::default_data_long_enough(Strike::MIN_SIZE));
531
532impl Default for Strike<'_> {
533    fn default() -> Self {
534        Self {
535            data: FontData::default_table_data(),
536            num_glyphs: Default::default(),
537        }
538    }
539}
540
541impl<'a> MinByteRange<'a> for GlyphData<'a> {
542    fn min_byte_range(&self) -> Range<usize> {
543        0..self.data_byte_range().end
544    }
545    fn min_table_bytes(&self) -> &'a [u8] {
546        let range = self.min_byte_range();
547        self.data.as_bytes().get(range).unwrap_or_default()
548    }
549}
550
551impl ReadArgs for GlyphData<'_> {
552    type Args = ();
553}
554
555impl<'a> FontRead<'a> for GlyphData<'a> {
556    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
557        #[allow(clippy::absurd_extreme_comparisons)]
558        if data.len() < Self::MIN_SIZE {
559            return Err(ReadError::OutOfBounds);
560        }
561        Ok(Self { data })
562    }
563}
564
565/// [Glyph data](https://learn.microsoft.com/en-us/typography/opentype/spec/sbix#glyph-data) table
566#[derive(Clone)]
567pub struct GlyphData<'a> {
568    data: FontData<'a>,
569}
570
571#[allow(clippy::needless_lifetimes)]
572impl<'a> GlyphData<'a> {
573    pub const MIN_SIZE: usize = (i16::RAW_BYTE_LEN + i16::RAW_BYTE_LEN + Tag::RAW_BYTE_LEN);
574    basic_table_impls!(impl_the_methods);
575
576    /// The horizontal (x-axis) position of the left edge of the bitmap graphic in relation to the glyph design space origin.
577    pub fn origin_offset_x(&self) -> i16 {
578        let range = self.origin_offset_x_byte_range();
579        self.data.read_at(range.start).ok().unwrap()
580    }
581
582    /// The vertical (y-axis) position of the bottom edge of the bitmap graphic in relation to the glyph design space origin.
583    pub fn origin_offset_y(&self) -> i16 {
584        let range = self.origin_offset_y_byte_range();
585        self.data.read_at(range.start).ok().unwrap()
586    }
587
588    /// Indicates the format of the embedded graphic data: one of 'jpg ', 'png ' or 'tiff', or the special format 'dupe'.
589    pub fn graphic_type(&self) -> Tag {
590        let range = self.graphic_type_byte_range();
591        self.data.read_at(range.start).ok().unwrap()
592    }
593
594    /// 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.
595    pub fn data(&self) -> &'a [u8] {
596        let range = self.data_byte_range();
597        self.data.read_array(range).ok().unwrap_or_default()
598    }
599
600    pub fn origin_offset_x_byte_range(&self) -> Range<usize> {
601        let start = 0;
602        let end = start + i16::RAW_BYTE_LEN;
603        start..end
604    }
605
606    pub fn origin_offset_y_byte_range(&self) -> Range<usize> {
607        let start = self.origin_offset_x_byte_range().end;
608        let end = start + i16::RAW_BYTE_LEN;
609        start..end
610    }
611
612    pub fn graphic_type_byte_range(&self) -> Range<usize> {
613        let start = self.origin_offset_y_byte_range().end;
614        let end = start + Tag::RAW_BYTE_LEN;
615        start..end
616    }
617
618    pub fn data_byte_range(&self) -> Range<usize> {
619        let start = self.graphic_type_byte_range().end;
620        let end =
621            start + self.data.len().saturating_sub(start) / u8::RAW_BYTE_LEN * u8::RAW_BYTE_LEN;
622        start..end
623    }
624}
625
626const _: () = assert!(FontData::default_data_long_enough(GlyphData::MIN_SIZE));
627
628impl Default for GlyphData<'_> {
629    fn default() -> Self {
630        Self {
631            data: FontData::default_table_data(),
632        }
633    }
634}