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