Coverage Report

Created: 2025-12-31 07:38

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/fontations/read-fonts/generated/generated_gasp.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
/// [gasp](https://learn.microsoft.com/en-us/typography/opentype/spec/gasp#gasp-table-formats)
9
#[derive(Debug, Clone, Copy)]
10
#[doc(hidden)]
11
pub struct GaspMarker {
12
    gasp_ranges_byte_len: usize,
13
}
14
15
impl GaspMarker {
16
    pub fn version_byte_range(&self) -> Range<usize> {
17
        let start = 0;
18
        start..start + u16::RAW_BYTE_LEN
19
    }
20
21
    pub fn num_ranges_byte_range(&self) -> Range<usize> {
22
        let start = self.version_byte_range().end;
23
        start..start + u16::RAW_BYTE_LEN
24
    }
25
26
    pub fn gasp_ranges_byte_range(&self) -> Range<usize> {
27
        let start = self.num_ranges_byte_range().end;
28
        start..start + self.gasp_ranges_byte_len
29
    }
30
}
31
32
impl MinByteRange for GaspMarker {
33
    fn min_byte_range(&self) -> Range<usize> {
34
        0..self.gasp_ranges_byte_range().end
35
    }
36
}
37
38
impl TopLevelTable for Gasp<'_> {
39
    /// `gasp`
40
    const TAG: Tag = Tag::new(b"gasp");
41
}
42
43
impl<'a> FontRead<'a> for Gasp<'a> {
44
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
45
        let mut cursor = data.cursor();
46
        cursor.advance::<u16>();
47
        let num_ranges: u16 = cursor.read()?;
48
        let gasp_ranges_byte_len = (num_ranges as usize)
49
            .checked_mul(GaspRange::RAW_BYTE_LEN)
50
            .ok_or(ReadError::OutOfBounds)?;
51
        cursor.advance_by(gasp_ranges_byte_len);
52
        cursor.finish(GaspMarker {
53
            gasp_ranges_byte_len,
54
        })
55
    }
56
}
57
58
/// [gasp](https://learn.microsoft.com/en-us/typography/opentype/spec/gasp#gasp-table-formats)
59
pub type Gasp<'a> = TableRef<'a, GaspMarker>;
60
61
#[allow(clippy::needless_lifetimes)]
62
impl<'a> Gasp<'a> {
63
    /// Version number (set to 1)
64
    pub fn version(&self) -> u16 {
65
        let range = self.shape.version_byte_range();
66
        self.data.read_at(range.start).unwrap()
67
    }
68
69
    /// Number of records to follow
70
    pub fn num_ranges(&self) -> u16 {
71
        let range = self.shape.num_ranges_byte_range();
72
        self.data.read_at(range.start).unwrap()
73
    }
74
75
    /// Sorted by ppem
76
    pub fn gasp_ranges(&self) -> &'a [GaspRange] {
77
        let range = self.shape.gasp_ranges_byte_range();
78
        self.data.read_array(range).unwrap()
79
    }
80
}
81
82
#[cfg(feature = "experimental_traverse")]
83
impl<'a> SomeTable<'a> for Gasp<'a> {
84
    fn type_name(&self) -> &str {
85
        "Gasp"
86
    }
87
    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
88
        match idx {
89
            0usize => Some(Field::new("version", self.version())),
90
            1usize => Some(Field::new("num_ranges", self.num_ranges())),
91
            2usize => Some(Field::new(
92
                "gasp_ranges",
93
                traversal::FieldType::array_of_records(
94
                    stringify!(GaspRange),
95
                    self.gasp_ranges(),
96
                    self.offset_data(),
97
                ),
98
            )),
99
            _ => None,
100
        }
101
    }
102
}
103
104
#[cfg(feature = "experimental_traverse")]
105
#[allow(clippy::needless_lifetimes)]
106
impl<'a> std::fmt::Debug for Gasp<'a> {
107
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
108
        (self as &dyn SomeTable<'a>).fmt(f)
109
    }
110
}
111
112
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
113
#[repr(C)]
114
#[repr(packed)]
115
pub struct GaspRange {
116
    /// Upper limit of range, in PPEM
117
    pub range_max_ppem: BigEndian<u16>,
118
    /// Flags describing desired rasterizer behavior.
119
    pub range_gasp_behavior: BigEndian<GaspRangeBehavior>,
120
}
121
122
impl GaspRange {
123
    /// Upper limit of range, in PPEM
124
    pub fn range_max_ppem(&self) -> u16 {
125
        self.range_max_ppem.get()
126
    }
127
128
    /// Flags describing desired rasterizer behavior.
129
    pub fn range_gasp_behavior(&self) -> GaspRangeBehavior {
130
        self.range_gasp_behavior.get()
131
    }
132
}
133
134
impl FixedSize for GaspRange {
135
    const RAW_BYTE_LEN: usize = u16::RAW_BYTE_LEN + GaspRangeBehavior::RAW_BYTE_LEN;
136
}
137
138
#[cfg(feature = "experimental_traverse")]
139
impl<'a> SomeRecord<'a> for GaspRange {
140
    fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
141
        RecordResolver {
142
            name: "GaspRange",
143
            get_field: Box::new(move |idx, _data| match idx {
144
                0usize => Some(Field::new("range_max_ppem", self.range_max_ppem())),
145
                1usize => Some(Field::new(
146
                    "range_gasp_behavior",
147
                    self.range_gasp_behavior(),
148
                )),
149
                _ => None,
150
            }),
151
            data,
152
        }
153
    }
154
}
155
156
#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash, bytemuck :: AnyBitPattern)]
157
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
158
#[repr(transparent)]
159
pub struct GaspRangeBehavior {
160
    bits: u16,
161
}
162
163
impl GaspRangeBehavior {
164
    /// Use gridfitting
165
    pub const GASP_GRIDFIT: Self = Self { bits: 0x0001 };
166
167
    /// Use grayscale rendering
168
    pub const GASP_DOGRAY: Self = Self { bits: 0x0002 };
169
170
    /// Use gridfitting with ClearType symmetric smoothing Only
171
    /// supported in version 1 'gasp'
172
    pub const GASP_SYMMETRIC_GRIDFIT: Self = Self { bits: 0x0004 };
173
174
    /// Use smoothing along multiple axes with ClearType® Only
175
    /// supported in version 1 'gasp'
176
    pub const GASP_SYMMETRIC_SMOOTHING: Self = Self { bits: 0x0008 };
177
}
178
179
impl GaspRangeBehavior {
180
    ///  Returns an empty set of flags.
181
    #[inline]
182
    pub const fn empty() -> Self {
183
        Self { bits: 0 }
184
    }
185
186
    /// Returns the set containing all flags.
187
    #[inline]
188
    pub const fn all() -> Self {
189
        Self {
190
            bits: Self::GASP_GRIDFIT.bits
191
                | Self::GASP_DOGRAY.bits
192
                | Self::GASP_SYMMETRIC_GRIDFIT.bits
193
                | Self::GASP_SYMMETRIC_SMOOTHING.bits,
194
        }
195
    }
196
197
    /// Returns the raw value of the flags currently stored.
198
    #[inline]
199
0
    pub const fn bits(&self) -> u16 {
200
0
        self.bits
201
0
    }
202
203
    /// Convert from underlying bit representation, unless that
204
    /// representation contains bits that do not correspond to a flag.
205
    #[inline]
206
    pub const fn from_bits(bits: u16) -> Option<Self> {
207
        if (bits & !Self::all().bits()) == 0 {
208
            Some(Self { bits })
209
        } else {
210
            None
211
        }
212
    }
213
214
    /// Convert from underlying bit representation, dropping any bits
215
    /// that do not correspond to flags.
216
    #[inline]
217
    pub const fn from_bits_truncate(bits: u16) -> Self {
218
        Self {
219
            bits: bits & Self::all().bits,
220
        }
221
    }
222
223
    /// Returns `true` if no flags are currently stored.
224
    #[inline]
225
    pub const fn is_empty(&self) -> bool {
226
        self.bits() == Self::empty().bits()
227
    }
228
229
    /// Returns `true` if there are flags common to both `self` and `other`.
230
    #[inline]
231
    pub const fn intersects(&self, other: Self) -> bool {
232
        !(Self {
233
            bits: self.bits & other.bits,
234
        })
235
        .is_empty()
236
    }
237
238
    /// Returns `true` if all of the flags in `other` are contained within `self`.
239
    #[inline]
240
    pub const fn contains(&self, other: Self) -> bool {
241
        (self.bits & other.bits) == other.bits
242
    }
243
244
    /// Inserts the specified flags in-place.
245
    #[inline]
246
    pub fn insert(&mut self, other: Self) {
247
        self.bits |= other.bits;
248
    }
249
250
    /// Removes the specified flags in-place.
251
    #[inline]
252
    pub fn remove(&mut self, other: Self) {
253
        self.bits &= !other.bits;
254
    }
255
256
    /// Toggles the specified flags in-place.
257
    #[inline]
258
    pub fn toggle(&mut self, other: Self) {
259
        self.bits ^= other.bits;
260
    }
261
262
    /// Returns the intersection between the flags in `self` and
263
    /// `other`.
264
    ///
265
    /// Specifically, the returned set contains only the flags which are
266
    /// present in *both* `self` *and* `other`.
267
    ///
268
    /// This is equivalent to using the `&` operator (e.g.
269
    /// [`ops::BitAnd`]), as in `flags & other`.
270
    ///
271
    /// [`ops::BitAnd`]: https://doc.rust-lang.org/std/ops/trait.BitAnd.html
272
    #[inline]
273
    #[must_use]
274
    pub const fn intersection(self, other: Self) -> Self {
275
        Self {
276
            bits: self.bits & other.bits,
277
        }
278
    }
279
280
    /// Returns the union of between the flags in `self` and `other`.
281
    ///
282
    /// Specifically, the returned set contains all flags which are
283
    /// present in *either* `self` *or* `other`, including any which are
284
    /// present in both.
285
    ///
286
    /// This is equivalent to using the `|` operator (e.g.
287
    /// [`ops::BitOr`]), as in `flags | other`.
288
    ///
289
    /// [`ops::BitOr`]: https://doc.rust-lang.org/std/ops/trait.BitOr.html
290
    #[inline]
291
    #[must_use]
292
    pub const fn union(self, other: Self) -> Self {
293
        Self {
294
            bits: self.bits | other.bits,
295
        }
296
    }
297
298
    /// Returns the difference between the flags in `self` and `other`.
299
    ///
300
    /// Specifically, the returned set contains all flags present in
301
    /// `self`, except for the ones present in `other`.
302
    ///
303
    /// It is also conceptually equivalent to the "bit-clear" operation:
304
    /// `flags & !other` (and this syntax is also supported).
305
    ///
306
    /// This is equivalent to using the `-` operator (e.g.
307
    /// [`ops::Sub`]), as in `flags - other`.
308
    ///
309
    /// [`ops::Sub`]: https://doc.rust-lang.org/std/ops/trait.Sub.html
310
    #[inline]
311
    #[must_use]
312
    pub const fn difference(self, other: Self) -> Self {
313
        Self {
314
            bits: self.bits & !other.bits,
315
        }
316
    }
317
}
318
319
impl std::ops::BitOr for GaspRangeBehavior {
320
    type Output = Self;
321
322
    /// Returns the union of the two sets of flags.
323
    #[inline]
324
    fn bitor(self, other: GaspRangeBehavior) -> Self {
325
        Self {
326
            bits: self.bits | other.bits,
327
        }
328
    }
329
}
330
331
impl std::ops::BitOrAssign for GaspRangeBehavior {
332
    /// Adds the set of flags.
333
    #[inline]
334
    fn bitor_assign(&mut self, other: Self) {
335
        self.bits |= other.bits;
336
    }
337
}
338
339
impl std::ops::BitXor for GaspRangeBehavior {
340
    type Output = Self;
341
342
    /// Returns the left flags, but with all the right flags toggled.
343
    #[inline]
344
    fn bitxor(self, other: Self) -> Self {
345
        Self {
346
            bits: self.bits ^ other.bits,
347
        }
348
    }
349
}
350
351
impl std::ops::BitXorAssign for GaspRangeBehavior {
352
    /// Toggles the set of flags.
353
    #[inline]
354
    fn bitxor_assign(&mut self, other: Self) {
355
        self.bits ^= other.bits;
356
    }
357
}
358
359
impl std::ops::BitAnd for GaspRangeBehavior {
360
    type Output = Self;
361
362
    /// Returns the intersection between the two sets of flags.
363
    #[inline]
364
    fn bitand(self, other: Self) -> Self {
365
        Self {
366
            bits: self.bits & other.bits,
367
        }
368
    }
369
}
370
371
impl std::ops::BitAndAssign for GaspRangeBehavior {
372
    /// Disables all flags disabled in the set.
373
    #[inline]
374
    fn bitand_assign(&mut self, other: Self) {
375
        self.bits &= other.bits;
376
    }
377
}
378
379
impl std::ops::Sub for GaspRangeBehavior {
380
    type Output = Self;
381
382
    /// Returns the set difference of the two sets of flags.
383
    #[inline]
384
    fn sub(self, other: Self) -> Self {
385
        Self {
386
            bits: self.bits & !other.bits,
387
        }
388
    }
389
}
390
391
impl std::ops::SubAssign for GaspRangeBehavior {
392
    /// Disables all flags enabled in the set.
393
    #[inline]
394
    fn sub_assign(&mut self, other: Self) {
395
        self.bits &= !other.bits;
396
    }
397
}
398
399
impl std::ops::Not for GaspRangeBehavior {
400
    type Output = Self;
401
402
    /// Returns the complement of this set of flags.
403
    #[inline]
404
    fn not(self) -> Self {
405
        Self { bits: !self.bits } & Self::all()
406
    }
407
}
408
409
impl std::fmt::Debug for GaspRangeBehavior {
410
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
411
        let members: &[(&str, Self)] = &[
412
            ("GASP_GRIDFIT", Self::GASP_GRIDFIT),
413
            ("GASP_DOGRAY", Self::GASP_DOGRAY),
414
            ("GASP_SYMMETRIC_GRIDFIT", Self::GASP_SYMMETRIC_GRIDFIT),
415
            ("GASP_SYMMETRIC_SMOOTHING", Self::GASP_SYMMETRIC_SMOOTHING),
416
        ];
417
        let mut first = true;
418
        for (name, value) in members {
419
            if self.contains(*value) {
420
                if !first {
421
                    f.write_str(" | ")?;
422
                }
423
                first = false;
424
                f.write_str(name)?;
425
            }
426
        }
427
        if first {
428
            f.write_str("(empty)")?;
429
        }
430
        Ok(())
431
    }
432
}
433
434
impl std::fmt::Binary for GaspRangeBehavior {
435
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
436
        std::fmt::Binary::fmt(&self.bits, f)
437
    }
438
}
439
440
impl std::fmt::Octal for GaspRangeBehavior {
441
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
442
        std::fmt::Octal::fmt(&self.bits, f)
443
    }
444
}
445
446
impl std::fmt::LowerHex for GaspRangeBehavior {
447
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
448
        std::fmt::LowerHex::fmt(&self.bits, f)
449
    }
450
}
451
452
impl std::fmt::UpperHex for GaspRangeBehavior {
453
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
454
        std::fmt::UpperHex::fmt(&self.bits, f)
455
    }
456
}
457
458
impl font_types::Scalar for GaspRangeBehavior {
459
    type Raw = <u16 as font_types::Scalar>::Raw;
460
    fn to_raw(self) -> Self::Raw {
461
        self.bits().to_raw()
462
    }
463
    fn from_raw(raw: Self::Raw) -> Self {
464
        let t = <u16>::from_raw(raw);
465
        Self::from_bits_truncate(t)
466
    }
467
}
468
469
#[cfg(feature = "experimental_traverse")]
470
impl<'a> From<GaspRangeBehavior> for FieldType<'a> {
471
    fn from(src: GaspRangeBehavior) -> FieldType<'a> {
472
        src.bits().into()
473
    }
474
}