Skip to main content

read_fonts/generated/
generated_cpal.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
8impl<'a> MinByteRange<'a> for Cpal<'a> {
9    fn min_byte_range(&self) -> Range<usize> {
10        0..self.color_record_indices_byte_range().end
11    }
12    fn min_table_bytes(&self) -> &'a [u8] {
13        let range = self.min_byte_range();
14        self.data.as_bytes().get(range).unwrap_or_default()
15    }
16}
17
18impl TopLevelTable for Cpal<'_> {
19    /// `CPAL`
20    const TAG: Tag = Tag::new(b"CPAL");
21}
22
23impl ReadArgs for Cpal<'_> {
24    type Args = ();
25}
26
27impl<'a> FontRead<'a> for Cpal<'a> {
28    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
29        #[allow(clippy::absurd_extreme_comparisons)]
30        if data.len() < Self::MIN_SIZE {
31            return Err(ReadError::OutOfBounds);
32        }
33        Ok(Self { data })
34    }
35}
36
37/// [CPAL (Color Palette Table)](https://learn.microsoft.com/en-us/typography/opentype/spec/cpal#palette-table-header) table
38#[derive(Clone)]
39pub struct Cpal<'a> {
40    data: FontData<'a>,
41}
42
43#[allow(clippy::needless_lifetimes)]
44impl<'a> Cpal<'a> {
45    pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN
46        + u16::RAW_BYTE_LEN
47        + u16::RAW_BYTE_LEN
48        + u16::RAW_BYTE_LEN
49        + Offset32::RAW_BYTE_LEN);
50    basic_table_impls!(impl_the_methods);
51
52    /// Table version number (=0).
53    pub fn version(&self) -> u16 {
54        let range = self.version_byte_range();
55        self.data.read_at(range.start).ok().unwrap()
56    }
57
58    /// Number of palette entries in each palette.
59    pub fn num_palette_entries(&self) -> u16 {
60        let range = self.num_palette_entries_byte_range();
61        self.data.read_at(range.start).ok().unwrap()
62    }
63
64    /// Number of palettes in the table.
65    pub fn num_palettes(&self) -> u16 {
66        let range = self.num_palettes_byte_range();
67        self.data.read_at(range.start).ok().unwrap()
68    }
69
70    /// Total number of color records, combined for all palettes.
71    pub fn num_color_records(&self) -> u16 {
72        let range = self.num_color_records_byte_range();
73        self.data.read_at(range.start).ok().unwrap()
74    }
75
76    /// Offset from the beginning of CPAL table to the first
77    /// ColorRecord.
78    pub fn color_records_array_offset(&self) -> Nullable<Offset32> {
79        let range = self.color_records_array_offset_byte_range();
80        self.data.read_at(range.start).ok().unwrap()
81    }
82
83    /// Attempt to resolve [`color_records_array_offset`][Self::color_records_array_offset].
84    pub fn color_records_array(&self) -> Option<Result<&'a [ColorRecord], ReadError>> {
85        let data = self.data;
86        let args = self.num_color_records();
87        self.color_records_array_offset()
88            .resolve_with_args(data, args)
89    }
90
91    /// Index of each palette’s first color record in the combined
92    /// color record array.
93    pub fn color_record_indices(&self) -> &'a [BigEndian<u16>] {
94        let range = self.color_record_indices_byte_range();
95        self.data.read_array(range).ok().unwrap_or_default()
96    }
97
98    /// Offset from the beginning of CPAL table to the [Palette Types Array][].
99    ///
100    /// This is an array of 32-bit flag fields that describe properties of each palette.
101    ///
102    /// [Palette Types Array]: https://learn.microsoft.com/en-us/typography/opentype/spec/cpal#palette-type-array
103    pub fn palette_types_array_offset(&self) -> Option<Nullable<Offset32>> {
104        let range = self.palette_types_array_offset_byte_range();
105        (!range.is_empty())
106            .then(|| self.data.read_at(range.start).ok())
107            .flatten()
108    }
109
110    /// Attempt to resolve [`palette_types_array_offset`][Self::palette_types_array_offset].
111    pub fn palette_types_array(&self) -> Option<Result<&'a [BigEndian<PaletteType>], ReadError>> {
112        let data = self.data;
113        let args = self.num_palettes();
114        self.palette_types_array_offset()
115            .map(|x| x.resolve_with_args(data, args))?
116    }
117
118    /// Offset from the beginning of CPAL table to the [Palette Labels Array][].
119    ///
120    /// This is an array of 'name' table IDs (typically in the font-specific name
121    /// ID range) that specify user interface strings associated with  each palette.
122    /// Use 0xFFFF if no name ID is provided for a palette.
123    ///
124    /// [Palette Labels Array]: https://learn.microsoft.com/en-us/typography/opentype/spec/cpal#palette-labels-array
125    pub fn palette_labels_array_offset(&self) -> Option<Nullable<Offset32>> {
126        let range = self.palette_labels_array_offset_byte_range();
127        (!range.is_empty())
128            .then(|| self.data.read_at(range.start).ok())
129            .flatten()
130    }
131
132    /// Attempt to resolve [`palette_labels_array_offset`][Self::palette_labels_array_offset].
133    pub fn palette_labels_array(&self) -> Option<Result<&'a [BigEndian<NameId>], ReadError>> {
134        let data = self.data;
135        let args = self.num_palettes();
136        self.palette_labels_array_offset()
137            .map(|x| x.resolve_with_args(data, args))?
138    }
139
140    /// Offset from the beginning of CPAL table to the [Palette Entry Labels Array][].
141    ///
142    /// This is an array of 'name' table IDs (typically in the font-specific name
143    /// ID range) that specify user interface strings associated with  each palette
144    /// entry, e.g. “Outline”, “Fill”. This set of palette entry labels applies
145    /// to all palettes in the font. Use  0xFFFF if no name ID is provided for a
146    /// palette entry.
147    ///
148    /// [Palette Entry Labels Array]: https://learn.microsoft.com/en-us/typography/opentype/spec/cpal#palette-entry-label-array
149    pub fn palette_entry_labels_array_offset(&self) -> Option<Nullable<Offset32>> {
150        let range = self.palette_entry_labels_array_offset_byte_range();
151        (!range.is_empty())
152            .then(|| self.data.read_at(range.start).ok())
153            .flatten()
154    }
155
156    /// Attempt to resolve [`palette_entry_labels_array_offset`][Self::palette_entry_labels_array_offset].
157    pub fn palette_entry_labels_array(&self) -> Option<Result<&'a [BigEndian<NameId>], ReadError>> {
158        let data = self.data;
159        let args = self.num_palette_entries();
160        self.palette_entry_labels_array_offset()
161            .map(|x| x.resolve_with_args(data, args))?
162    }
163
164    pub fn version_byte_range(&self) -> Range<usize> {
165        let start = 0;
166        let end = start + u16::RAW_BYTE_LEN;
167        start..end
168    }
169
170    pub fn num_palette_entries_byte_range(&self) -> Range<usize> {
171        let start = self.version_byte_range().end;
172        let end = start + u16::RAW_BYTE_LEN;
173        start..end
174    }
175
176    pub fn num_palettes_byte_range(&self) -> Range<usize> {
177        let start = self.num_palette_entries_byte_range().end;
178        let end = start + u16::RAW_BYTE_LEN;
179        start..end
180    }
181
182    pub fn num_color_records_byte_range(&self) -> Range<usize> {
183        let start = self.num_palettes_byte_range().end;
184        let end = start + u16::RAW_BYTE_LEN;
185        start..end
186    }
187
188    pub fn color_records_array_offset_byte_range(&self) -> Range<usize> {
189        let start = self.num_color_records_byte_range().end;
190        let end = start + Offset32::RAW_BYTE_LEN;
191        start..end
192    }
193
194    pub fn color_record_indices_byte_range(&self) -> Range<usize> {
195        let num_palettes = self.num_palettes();
196        let start = self.color_records_array_offset_byte_range().end;
197        let end = start + (transforms::to_usize(num_palettes)).saturating_mul(u16::RAW_BYTE_LEN);
198        start..end
199    }
200
201    pub fn palette_types_array_offset_byte_range(&self) -> Range<usize> {
202        let start = self.color_record_indices_byte_range().end;
203        let end = if self.version().compatible(1u16) {
204            start + Offset32::RAW_BYTE_LEN
205        } else {
206            start
207        };
208        start..end
209    }
210
211    pub fn palette_labels_array_offset_byte_range(&self) -> Range<usize> {
212        let start = self.palette_types_array_offset_byte_range().end;
213        let end = if self.version().compatible(1u16) {
214            start + Offset32::RAW_BYTE_LEN
215        } else {
216            start
217        };
218        start..end
219    }
220
221    pub fn palette_entry_labels_array_offset_byte_range(&self) -> Range<usize> {
222        let start = self.palette_labels_array_offset_byte_range().end;
223        let end = if self.version().compatible(1u16) {
224            start + Offset32::RAW_BYTE_LEN
225        } else {
226            start
227        };
228        start..end
229    }
230}
231
232const _: () = assert!(FontData::default_data_long_enough(Cpal::MIN_SIZE));
233
234impl Default for Cpal<'_> {
235    fn default() -> Self {
236        Self {
237            data: FontData::default_table_data(),
238        }
239    }
240}
241
242/// The [PaletteType](https://learn.microsoft.com/en-us/typography/opentype/spec/cpal#palette-type-array) flags.
243#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash, bytemuck :: AnyBitPattern)]
244#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
245#[repr(transparent)]
246pub struct PaletteType {
247    bits: u32,
248}
249
250impl PaletteType {
251    /// Bit 0: palette is appropriate to use when displaying the font on a light background such as white.
252    pub const USABLE_WITH_LIGHT_BACKGROUND: Self = Self { bits: 0x0001 };
253
254    /// Bit 1: palette is appropriate to use when displaying the font on a dark background such as black.
255    pub const USABLE_WITH_DARK_BACKGROUND: Self = Self { bits: 0x0002 };
256}
257
258impl PaletteType {
259    ///  Returns an empty set of flags.
260    #[inline]
261    pub const fn empty() -> Self {
262        Self { bits: 0 }
263    }
264
265    /// Returns the set containing all flags.
266    #[inline]
267    pub const fn all() -> Self {
268        Self {
269            bits: Self::USABLE_WITH_LIGHT_BACKGROUND.bits | Self::USABLE_WITH_DARK_BACKGROUND.bits,
270        }
271    }
272
273    /// Returns the raw value of the flags currently stored.
274    #[inline]
275    pub const fn bits(&self) -> u32 {
276        self.bits
277    }
278
279    /// Convert from underlying bit representation, unless that
280    /// representation contains bits that do not correspond to a flag.
281    #[inline]
282    pub const fn from_bits(bits: u32) -> Option<Self> {
283        if (bits & !Self::all().bits()) == 0 {
284            Some(Self { bits })
285        } else {
286            None
287        }
288    }
289
290    /// Convert from underlying bit representation, dropping any bits
291    /// that do not correspond to flags.
292    #[inline]
293    pub const fn from_bits_truncate(bits: u32) -> Self {
294        Self {
295            bits: bits & Self::all().bits,
296        }
297    }
298
299    /// Returns `true` if no flags are currently stored.
300    #[inline]
301    pub const fn is_empty(&self) -> bool {
302        self.bits() == Self::empty().bits()
303    }
304
305    /// Returns `true` if there are flags common to both `self` and `other`.
306    #[inline]
307    pub const fn intersects(&self, other: Self) -> bool {
308        !(Self {
309            bits: self.bits & other.bits,
310        })
311        .is_empty()
312    }
313
314    /// Returns `true` if all of the flags in `other` are contained within `self`.
315    #[inline]
316    pub const fn contains(&self, other: Self) -> bool {
317        (self.bits & other.bits) == other.bits
318    }
319
320    /// Inserts the specified flags in-place.
321    #[inline]
322    pub fn insert(&mut self, other: Self) {
323        self.bits |= other.bits;
324    }
325
326    /// Removes the specified flags in-place.
327    #[inline]
328    pub fn remove(&mut self, other: Self) {
329        self.bits &= !other.bits;
330    }
331
332    /// Toggles the specified flags in-place.
333    #[inline]
334    pub fn toggle(&mut self, other: Self) {
335        self.bits ^= other.bits;
336    }
337
338    /// Returns the intersection between the flags in `self` and
339    /// `other`.
340    ///
341    /// Specifically, the returned set contains only the flags which are
342    /// present in *both* `self` *and* `other`.
343    ///
344    /// This is equivalent to using the `&` operator (e.g.
345    /// [`ops::BitAnd`]), as in `flags & other`.
346    ///
347    /// [`ops::BitAnd`]: https://doc.rust-lang.org/std/ops/trait.BitAnd.html
348    #[inline]
349    #[must_use]
350    pub const fn intersection(self, other: Self) -> Self {
351        Self {
352            bits: self.bits & other.bits,
353        }
354    }
355
356    /// Returns the union of between the flags in `self` and `other`.
357    ///
358    /// Specifically, the returned set contains all flags which are
359    /// present in *either* `self` *or* `other`, including any which are
360    /// present in both.
361    ///
362    /// This is equivalent to using the `|` operator (e.g.
363    /// [`ops::BitOr`]), as in `flags | other`.
364    ///
365    /// [`ops::BitOr`]: https://doc.rust-lang.org/std/ops/trait.BitOr.html
366    #[inline]
367    #[must_use]
368    pub const fn union(self, other: Self) -> Self {
369        Self {
370            bits: self.bits | other.bits,
371        }
372    }
373
374    /// Returns the difference between the flags in `self` and `other`.
375    ///
376    /// Specifically, the returned set contains all flags present in
377    /// `self`, except for the ones present in `other`.
378    ///
379    /// It is also conceptually equivalent to the "bit-clear" operation:
380    /// `flags & !other` (and this syntax is also supported).
381    ///
382    /// This is equivalent to using the `-` operator (e.g.
383    /// [`ops::Sub`]), as in `flags - other`.
384    ///
385    /// [`ops::Sub`]: https://doc.rust-lang.org/std/ops/trait.Sub.html
386    #[inline]
387    #[must_use]
388    pub const fn difference(self, other: Self) -> Self {
389        Self {
390            bits: self.bits & !other.bits,
391        }
392    }
393}
394
395impl std::ops::BitOr for PaletteType {
396    type Output = Self;
397
398    /// Returns the union of the two sets of flags.
399    #[inline]
400    fn bitor(self, other: PaletteType) -> Self {
401        Self {
402            bits: self.bits | other.bits,
403        }
404    }
405}
406
407impl std::ops::BitOrAssign for PaletteType {
408    /// Adds the set of flags.
409    #[inline]
410    fn bitor_assign(&mut self, other: Self) {
411        self.bits |= other.bits;
412    }
413}
414
415impl std::ops::BitXor for PaletteType {
416    type Output = Self;
417
418    /// Returns the left flags, but with all the right flags toggled.
419    #[inline]
420    fn bitxor(self, other: Self) -> Self {
421        Self {
422            bits: self.bits ^ other.bits,
423        }
424    }
425}
426
427impl std::ops::BitXorAssign for PaletteType {
428    /// Toggles the set of flags.
429    #[inline]
430    fn bitxor_assign(&mut self, other: Self) {
431        self.bits ^= other.bits;
432    }
433}
434
435impl std::ops::BitAnd for PaletteType {
436    type Output = Self;
437
438    /// Returns the intersection between the two sets of flags.
439    #[inline]
440    fn bitand(self, other: Self) -> Self {
441        Self {
442            bits: self.bits & other.bits,
443        }
444    }
445}
446
447impl std::ops::BitAndAssign for PaletteType {
448    /// Disables all flags disabled in the set.
449    #[inline]
450    fn bitand_assign(&mut self, other: Self) {
451        self.bits &= other.bits;
452    }
453}
454
455impl std::ops::Sub for PaletteType {
456    type Output = Self;
457
458    /// Returns the set difference of the two sets of flags.
459    #[inline]
460    fn sub(self, other: Self) -> Self {
461        Self {
462            bits: self.bits & !other.bits,
463        }
464    }
465}
466
467impl std::ops::SubAssign for PaletteType {
468    /// Disables all flags enabled in the set.
469    #[inline]
470    fn sub_assign(&mut self, other: Self) {
471        self.bits &= !other.bits;
472    }
473}
474
475impl std::ops::Not for PaletteType {
476    type Output = Self;
477
478    /// Returns the complement of this set of flags.
479    #[inline]
480    fn not(self) -> Self {
481        Self { bits: !self.bits } & Self::all()
482    }
483}
484
485impl std::fmt::Debug for PaletteType {
486    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
487        let members: &[(&str, Self)] = &[
488            (
489                "USABLE_WITH_LIGHT_BACKGROUND",
490                Self::USABLE_WITH_LIGHT_BACKGROUND,
491            ),
492            (
493                "USABLE_WITH_DARK_BACKGROUND",
494                Self::USABLE_WITH_DARK_BACKGROUND,
495            ),
496        ];
497        let mut first = true;
498        for (name, value) in members {
499            if self.contains(*value) {
500                if !first {
501                    f.write_str(" | ")?;
502                }
503                first = false;
504                f.write_str(name)?;
505            }
506        }
507        if first {
508            f.write_str("(empty)")?;
509        }
510        Ok(())
511    }
512}
513
514impl std::fmt::Binary for PaletteType {
515    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
516        std::fmt::Binary::fmt(&self.bits, f)
517    }
518}
519
520impl std::fmt::Octal for PaletteType {
521    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
522        std::fmt::Octal::fmt(&self.bits, f)
523    }
524}
525
526impl std::fmt::LowerHex for PaletteType {
527    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
528        std::fmt::LowerHex::fmt(&self.bits, f)
529    }
530}
531
532impl std::fmt::UpperHex for PaletteType {
533    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
534        std::fmt::UpperHex::fmt(&self.bits, f)
535    }
536}
537
538impl font_types::Scalar for PaletteType {
539    type Raw = <u32 as font_types::Scalar>::Raw;
540    fn to_raw(self) -> Self::Raw {
541        self.bits().to_raw()
542    }
543    fn from_raw(raw: Self::Raw) -> Self {
544        let t = <u32>::from_raw(raw);
545        Self::from_bits_truncate(t)
546    }
547}
548
549/// [CPAL (Color Record)](https://learn.microsoft.com/en-us/typography/opentype/spec/cpal#palette-entries-and-color-records) record
550///
551/// Contains a color in non-premultiplied BGRA form, in the sRGB color space.
552#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
553#[repr(C)]
554#[repr(packed)]
555pub struct ColorRecord {
556    /// Blue value (B0).
557    pub blue: u8,
558    /// Green value (B1).
559    pub green: u8,
560    /// Red value (B2).
561    pub red: u8,
562    /// Alpha value (B3).
563    pub alpha: u8,
564}
565
566impl ColorRecord {
567    /// Blue value (B0).
568    pub fn blue(&self) -> u8 {
569        self.blue
570    }
571
572    /// Green value (B1).
573    pub fn green(&self) -> u8 {
574        self.green
575    }
576
577    /// Red value (B2).
578    pub fn red(&self) -> u8 {
579        self.red
580    }
581
582    /// Alpha value (B3).
583    pub fn alpha(&self) -> u8 {
584        self.alpha
585    }
586}
587
588impl FixedSize for ColorRecord {
589    const RAW_BYTE_LEN: usize =
590        u8::RAW_BYTE_LEN + u8::RAW_BYTE_LEN + u8::RAW_BYTE_LEN + u8::RAW_BYTE_LEN;
591}