Coverage Report

Created: 2026-09-14 08:06

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/fontations/read-fonts/generated/generated_math.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 Math<'a> {
9
    fn min_byte_range(&self) -> Range<usize> {
10
        0..self.math_variants_offset_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
18
impl TopLevelTable for Math<'_> {
19
    /// `MATH`
20
    const TAG: Tag = Tag::new(b"MATH");
21
}
22
23
impl ReadArgs for Math<'_> {
24
    type Args = ();
25
}
26
27
impl<'a> FontRead<'a> for Math<'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
/// The [MATH](https://learn.microsoft.com/en-us/typography/opentype/spec/math) table
38
#[derive(Clone)]
39
pub struct Math<'a> {
40
    data: FontData<'a>,
41
}
42
43
#[allow(clippy::needless_lifetimes)]
44
impl<'a> Math<'a> {
45
    pub const MIN_SIZE: usize = (MajorMinor::RAW_BYTE_LEN
46
        + Offset16::RAW_BYTE_LEN
47
        + Offset16::RAW_BYTE_LEN
48
        + Offset16::RAW_BYTE_LEN);
49
    basic_table_impls!(impl_the_methods);
50
51
    /// (major, minor) Version for the MATH table (1,0)
52
    pub fn version(&self) -> MajorMinor {
53
        let range = self.version_byte_range();
54
        self.data.read_at(range.start).ok().unwrap()
55
    }
56
57
    /// Offset to MathConstants table, from beginning of MATH table.
58
    pub fn math_constants_offset(&self) -> Offset16 {
59
        let range = self.math_constants_offset_byte_range();
60
        self.data.read_at(range.start).ok().unwrap()
61
    }
62
63
    /// Attempt to resolve [`math_constants_offset`][Self::math_constants_offset].
64
    pub fn math_constants(&self) -> Result<MathConstants<'a>, ReadError> {
65
        let data = self.data;
66
        self.math_constants_offset().resolve(data)
67
    }
68
69
    /// Offset to MathGlyphInfo table, from beginning of MATH table.
70
    pub fn math_glyph_info_offset(&self) -> Offset16 {
71
        let range = self.math_glyph_info_offset_byte_range();
72
        self.data.read_at(range.start).ok().unwrap()
73
    }
74
75
    /// Attempt to resolve [`math_glyph_info_offset`][Self::math_glyph_info_offset].
76
    pub fn math_glyph_info(&self) -> Result<MathGlyphInfo<'a>, ReadError> {
77
        let data = self.data;
78
        self.math_glyph_info_offset().resolve(data)
79
    }
80
81
    /// Offset to MathVariants table, from beginning of MATH table.
82
    pub fn math_variants_offset(&self) -> Offset16 {
83
        let range = self.math_variants_offset_byte_range();
84
        self.data.read_at(range.start).ok().unwrap()
85
    }
86
87
    /// Attempt to resolve [`math_variants_offset`][Self::math_variants_offset].
88
    pub fn math_variants(&self) -> Result<MathVariants<'a>, ReadError> {
89
        let data = self.data;
90
        self.math_variants_offset().resolve(data)
91
    }
92
93
    pub fn version_byte_range(&self) -> Range<usize> {
94
        let start = 0;
95
        let end = start + MajorMinor::RAW_BYTE_LEN;
96
        start..end
97
    }
98
99
    pub fn math_constants_offset_byte_range(&self) -> Range<usize> {
100
        let start = self.version_byte_range().end;
101
        let end = start + Offset16::RAW_BYTE_LEN;
102
        start..end
103
    }
104
105
    pub fn math_glyph_info_offset_byte_range(&self) -> Range<usize> {
106
        let start = self.math_constants_offset_byte_range().end;
107
        let end = start + Offset16::RAW_BYTE_LEN;
108
        start..end
109
    }
110
111
    pub fn math_variants_offset_byte_range(&self) -> Range<usize> {
112
        let start = self.math_glyph_info_offset_byte_range().end;
113
        let end = start + Offset16::RAW_BYTE_LEN;
114
        start..end
115
    }
116
}
117
118
const _: () = assert!(FontData::default_data_long_enough(Math::MIN_SIZE));
119
120
impl Default for Math<'_> {
121
    fn default() -> Self {
122
        Self {
123
            data: FontData::default_table_data(),
124
        }
125
    }
126
}
127
128
/// [MathValueRecord](https://learn.microsoft.com/en-us/typography/opentype/spec/math#mathvaluerecord)
129
///
130
/// The device offset is measured from the beginning of the table that contains
131
/// the record, not from the record itself.
132
#[derive(Clone, Debug, Copy, bytemuck :: AnyBitPattern)]
133
#[repr(C)]
134
#[repr(packed)]
135
pub struct MathValueRecord {
136
    /// The X or Y value in design units.
137
    pub value: BigEndian<FWord>,
138
    /// Offset to the Device table (non-variable font) / VariationIndex table
139
    /// (variable font) for this value, from the beginning of the parent table.
140
    /// May be NULL.
141
    pub device_offset: BigEndian<Nullable<Offset16>>,
142
}
143
144
impl MathValueRecord {
145
    /// The X or Y value in design units.
146
    pub fn value(&self) -> FWord {
147
        self.value.get()
148
    }
149
150
    /// Offset to the Device table (non-variable font) / VariationIndex table
151
    /// (variable font) for this value, from the beginning of the parent table.
152
    /// May be NULL.
153
    pub fn device_offset(&self) -> Nullable<Offset16> {
154
        self.device_offset.get()
155
    }
156
157
    /// Offset to the Device table (non-variable font) / VariationIndex table
158
    /// (variable font) for this value, from the beginning of the parent table.
159
    /// May be NULL.
160
    ///
161
    /// The `data` argument should be retrieved from the parent table
162
    /// By calling its `offset_data` method.
163
    pub fn device<'a>(
164
        &self,
165
        data: FontData<'a>,
166
    ) -> Option<Result<DeviceOrVariationIndex<'a>, ReadError>> {
167
        self.device_offset().resolve(data)
168
    }
169
}
170
171
impl FixedSize for MathValueRecord {
172
    const RAW_BYTE_LEN: usize = FWord::RAW_BYTE_LEN + Offset16::RAW_BYTE_LEN;
173
}
174
175
impl<'a> MinByteRange<'a> for MathConstants<'a> {
176
    fn min_byte_range(&self) -> Range<usize> {
177
        0..self.radical_degree_bottom_raise_percent_byte_range().end
178
    }
179
    fn min_table_bytes(&self) -> &'a [u8] {
180
        let range = self.min_byte_range();
181
        self.data.as_bytes().get(range).unwrap_or_default()
182
    }
183
}
184
185
impl ReadArgs for MathConstants<'_> {
186
    type Args = ();
187
}
188
189
impl<'a> FontRead<'a> for MathConstants<'a> {
190
    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
191
        #[allow(clippy::absurd_extreme_comparisons)]
192
        if data.len() < Self::MIN_SIZE {
193
            return Err(ReadError::OutOfBounds);
194
        }
195
        Ok(Self { data })
196
    }
197
}
198
199
/// [MathConstants](https://learn.microsoft.com/en-us/typography/opentype/spec/math#mathconstants-table)
200
#[derive(Clone)]
201
pub struct MathConstants<'a> {
202
    data: FontData<'a>,
203
}
204
205
#[allow(clippy::needless_lifetimes)]
206
impl<'a> MathConstants<'a> {
207
    pub const MIN_SIZE: usize = (i16::RAW_BYTE_LEN
208
        + i16::RAW_BYTE_LEN
209
        + UfWord::RAW_BYTE_LEN
210
        + UfWord::RAW_BYTE_LEN
211
        + MathValueRecord::RAW_BYTE_LEN
212
        + MathValueRecord::RAW_BYTE_LEN
213
        + MathValueRecord::RAW_BYTE_LEN
214
        + MathValueRecord::RAW_BYTE_LEN
215
        + MathValueRecord::RAW_BYTE_LEN
216
        + MathValueRecord::RAW_BYTE_LEN
217
        + MathValueRecord::RAW_BYTE_LEN
218
        + MathValueRecord::RAW_BYTE_LEN
219
        + MathValueRecord::RAW_BYTE_LEN
220
        + MathValueRecord::RAW_BYTE_LEN
221
        + MathValueRecord::RAW_BYTE_LEN
222
        + MathValueRecord::RAW_BYTE_LEN
223
        + MathValueRecord::RAW_BYTE_LEN
224
        + MathValueRecord::RAW_BYTE_LEN
225
        + MathValueRecord::RAW_BYTE_LEN
226
        + MathValueRecord::RAW_BYTE_LEN
227
        + MathValueRecord::RAW_BYTE_LEN
228
        + MathValueRecord::RAW_BYTE_LEN
229
        + MathValueRecord::RAW_BYTE_LEN
230
        + MathValueRecord::RAW_BYTE_LEN
231
        + MathValueRecord::RAW_BYTE_LEN
232
        + MathValueRecord::RAW_BYTE_LEN
233
        + MathValueRecord::RAW_BYTE_LEN
234
        + MathValueRecord::RAW_BYTE_LEN
235
        + MathValueRecord::RAW_BYTE_LEN
236
        + MathValueRecord::RAW_BYTE_LEN
237
        + MathValueRecord::RAW_BYTE_LEN
238
        + MathValueRecord::RAW_BYTE_LEN
239
        + MathValueRecord::RAW_BYTE_LEN
240
        + MathValueRecord::RAW_BYTE_LEN
241
        + MathValueRecord::RAW_BYTE_LEN
242
        + MathValueRecord::RAW_BYTE_LEN
243
        + MathValueRecord::RAW_BYTE_LEN
244
        + MathValueRecord::RAW_BYTE_LEN
245
        + MathValueRecord::RAW_BYTE_LEN
246
        + MathValueRecord::RAW_BYTE_LEN
247
        + MathValueRecord::RAW_BYTE_LEN
248
        + MathValueRecord::RAW_BYTE_LEN
249
        + MathValueRecord::RAW_BYTE_LEN
250
        + MathValueRecord::RAW_BYTE_LEN
251
        + MathValueRecord::RAW_BYTE_LEN
252
        + MathValueRecord::RAW_BYTE_LEN
253
        + MathValueRecord::RAW_BYTE_LEN
254
        + MathValueRecord::RAW_BYTE_LEN
255
        + MathValueRecord::RAW_BYTE_LEN
256
        + MathValueRecord::RAW_BYTE_LEN
257
        + MathValueRecord::RAW_BYTE_LEN
258
        + MathValueRecord::RAW_BYTE_LEN
259
        + MathValueRecord::RAW_BYTE_LEN
260
        + MathValueRecord::RAW_BYTE_LEN
261
        + MathValueRecord::RAW_BYTE_LEN
262
        + i16::RAW_BYTE_LEN);
263
    basic_table_impls!(impl_the_methods);
264
265
    /// Percentage of scaling down for level 1 superscripts and subscripts.
266
    pub fn script_percent_scale_down(&self) -> i16 {
267
        let range = self.script_percent_scale_down_byte_range();
268
        self.data.read_at(range.start).ok().unwrap()
269
    }
270
271
    /// Percentage of scaling down for level 2 (scriptScript) superscripts and
272
    /// subscripts.
273
    pub fn script_script_percent_scale_down(&self) -> i16 {
274
        let range = self.script_script_percent_scale_down_byte_range();
275
        self.data.read_at(range.start).ok().unwrap()
276
    }
277
278
    /// Minimum height required for a delimited expression (contained within
279
    /// parentheses, etc.) to be treated as a sub-formula.
280
    pub fn delimited_sub_formula_min_height(&self) -> UfWord {
281
        let range = self.delimited_sub_formula_min_height_byte_range();
282
        self.data.read_at(range.start).ok().unwrap()
283
    }
284
285
    /// Minimum height of n-ary operators (such as integral and summation) for
286
    /// formulas in display mode (that is, appearing as standalone page
287
    /// elements, not embedded inline within text).
288
    pub fn display_operator_min_height(&self) -> UfWord {
289
        let range = self.display_operator_min_height_byte_range();
290
        self.data.read_at(range.start).ok().unwrap()
291
    }
292
293
    /// White space to be left between math formulas to ensure proper line
294
    /// spacing.
295
    pub fn math_leading(&self) -> &'a MathValueRecord {
296
        let range = self.math_leading_byte_range();
297
        self.data.read_ref_at(range.start).ok().unwrap()
298
    }
299
300
    /// Axis height of the font.
301
    pub fn axis_height(&self) -> &'a MathValueRecord {
302
        let range = self.axis_height_byte_range();
303
        self.data.read_ref_at(range.start).ok().unwrap()
304
    }
305
306
    /// Maximum (ink) height of accent base that does not require raising the
307
    /// accents.
308
    pub fn accent_base_height(&self) -> &'a MathValueRecord {
309
        let range = self.accent_base_height_byte_range();
310
        self.data.read_ref_at(range.start).ok().unwrap()
311
    }
312
313
    /// Maximum (ink) height of accent base that does not require flattening the
314
    /// accents.
315
    pub fn flattened_accent_base_height(&self) -> &'a MathValueRecord {
316
        let range = self.flattened_accent_base_height_byte_range();
317
        self.data.read_ref_at(range.start).ok().unwrap()
318
    }
319
320
    /// The standard shift down applied to subscript elements.
321
    pub fn subscript_shift_down(&self) -> &'a MathValueRecord {
322
        let range = self.subscript_shift_down_byte_range();
323
        self.data.read_ref_at(range.start).ok().unwrap()
324
    }
325
326
    /// Maximum allowed height of the (ink) top of subscripts that does not
327
    /// require moving subscripts further down.
328
    pub fn subscript_top_max(&self) -> &'a MathValueRecord {
329
        let range = self.subscript_top_max_byte_range();
330
        self.data.read_ref_at(range.start).ok().unwrap()
331
    }
332
333
    /// Minimum allowed drop of the baseline of subscripts relative to the (ink)
334
    /// bottom of the base.
335
    pub fn subscript_baseline_drop_min(&self) -> &'a MathValueRecord {
336
        let range = self.subscript_baseline_drop_min_byte_range();
337
        self.data.read_ref_at(range.start).ok().unwrap()
338
    }
339
340
    /// Standard shift up applied to superscript elements.
341
    pub fn superscript_shift_up(&self) -> &'a MathValueRecord {
342
        let range = self.superscript_shift_up_byte_range();
343
        self.data.read_ref_at(range.start).ok().unwrap()
344
    }
345
346
    /// Standard shift of superscripts relative to the base, in cramped style.
347
    pub fn superscript_shift_up_cramped(&self) -> &'a MathValueRecord {
348
        let range = self.superscript_shift_up_cramped_byte_range();
349
        self.data.read_ref_at(range.start).ok().unwrap()
350
    }
351
352
    /// Minimum allowed height of the (ink) bottom of superscripts that does not
353
    /// require moving subscripts further up.
354
    pub fn superscript_bottom_min(&self) -> &'a MathValueRecord {
355
        let range = self.superscript_bottom_min_byte_range();
356
        self.data.read_ref_at(range.start).ok().unwrap()
357
    }
358
359
    /// Maximum allowed drop of the baseline of superscripts relative to the
360
    /// (ink) top of the base.
361
    pub fn superscript_baseline_drop_max(&self) -> &'a MathValueRecord {
362
        let range = self.superscript_baseline_drop_max_byte_range();
363
        self.data.read_ref_at(range.start).ok().unwrap()
364
    }
365
366
    /// Minimum gap between the superscript and subscript ink.
367
    pub fn sub_superscript_gap_min(&self) -> &'a MathValueRecord {
368
        let range = self.sub_superscript_gap_min_byte_range();
369
        self.data.read_ref_at(range.start).ok().unwrap()
370
    }
371
372
    /// The maximum level to which the (ink) bottom of superscript can be
373
    /// pushed to increase the gap between superscript and subscript, before
374
    /// subscript starts being moved down.
375
    pub fn superscript_bottom_max_with_subscript(&self) -> &'a MathValueRecord {
376
        let range = self.superscript_bottom_max_with_subscript_byte_range();
377
        self.data.read_ref_at(range.start).ok().unwrap()
378
    }
379
380
    /// Extra white space to be added after each subscript and superscript.
381
    pub fn space_after_script(&self) -> &'a MathValueRecord {
382
        let range = self.space_after_script_byte_range();
383
        self.data.read_ref_at(range.start).ok().unwrap()
384
    }
385
386
    /// Minimum gap between the (ink) bottom of the upper limit, and the (ink)
387
    /// top of the base operator.
388
    pub fn upper_limit_gap_min(&self) -> &'a MathValueRecord {
389
        let range = self.upper_limit_gap_min_byte_range();
390
        self.data.read_ref_at(range.start).ok().unwrap()
391
    }
392
393
    /// Minimum distance between baseline of upper limit and (ink) top of the
394
    /// base operator.
395
    pub fn upper_limit_baseline_rise_min(&self) -> &'a MathValueRecord {
396
        let range = self.upper_limit_baseline_rise_min_byte_range();
397
        self.data.read_ref_at(range.start).ok().unwrap()
398
    }
399
400
    /// Minimum gap between (ink) top of the lower limit, and (ink) bottom of
401
    /// the base operator.
402
    pub fn lower_limit_gap_min(&self) -> &'a MathValueRecord {
403
        let range = self.lower_limit_gap_min_byte_range();
404
        self.data.read_ref_at(range.start).ok().unwrap()
405
    }
406
407
    /// Minimum distance between baseline of the lower limit and (ink) bottom of
408
    /// the base operator.
409
    pub fn lower_limit_baseline_drop_min(&self) -> &'a MathValueRecord {
410
        let range = self.lower_limit_baseline_drop_min_byte_range();
411
        self.data.read_ref_at(range.start).ok().unwrap()
412
    }
413
414
    /// Standard shift up applied to the top element of a stack.
415
    pub fn stack_top_shift_up(&self) -> &'a MathValueRecord {
416
        let range = self.stack_top_shift_up_byte_range();
417
        self.data.read_ref_at(range.start).ok().unwrap()
418
    }
419
420
    /// Standard shift up applied to the top element of a stack in display
421
    /// style.
422
    pub fn stack_top_display_style_shift_up(&self) -> &'a MathValueRecord {
423
        let range = self.stack_top_display_style_shift_up_byte_range();
424
        self.data.read_ref_at(range.start).ok().unwrap()
425
    }
426
427
    /// Standard shift down applied to the bottom element of a stack.
428
    pub fn stack_bottom_shift_down(&self) -> &'a MathValueRecord {
429
        let range = self.stack_bottom_shift_down_byte_range();
430
        self.data.read_ref_at(range.start).ok().unwrap()
431
    }
432
433
    /// Standard shift down applied to the bottom element of a stack in display
434
    /// style.
435
    pub fn stack_bottom_display_style_shift_down(&self) -> &'a MathValueRecord {
436
        let range = self.stack_bottom_display_style_shift_down_byte_range();
437
        self.data.read_ref_at(range.start).ok().unwrap()
438
    }
439
440
    /// Minimum gap between (ink) bottom of the top element of a stack, and the
441
    /// (ink) top of the bottom element.
442
    pub fn stack_gap_min(&self) -> &'a MathValueRecord {
443
        let range = self.stack_gap_min_byte_range();
444
        self.data.read_ref_at(range.start).ok().unwrap()
445
    }
446
447
    /// Minimum gap between (ink) bottom of the top element of a stack, and the
448
    /// (ink) top of the bottom element in display style.
449
    pub fn stack_display_style_gap_min(&self) -> &'a MathValueRecord {
450
        let range = self.stack_display_style_gap_min_byte_range();
451
        self.data.read_ref_at(range.start).ok().unwrap()
452
    }
453
454
    /// Standard shift up applied to the top element of the stretch stack.
455
    pub fn stretch_stack_top_shift_up(&self) -> &'a MathValueRecord {
456
        let range = self.stretch_stack_top_shift_up_byte_range();
457
        self.data.read_ref_at(range.start).ok().unwrap()
458
    }
459
460
    /// Standard shift down applied to the bottom element of the stretch stack.
461
    pub fn stretch_stack_bottom_shift_down(&self) -> &'a MathValueRecord {
462
        let range = self.stretch_stack_bottom_shift_down_byte_range();
463
        self.data.read_ref_at(range.start).ok().unwrap()
464
    }
465
466
    /// Minimum gap between the ink of the stretched element, and the (ink)
467
    /// bottom of the element above.
468
    pub fn stretch_stack_gap_above_min(&self) -> &'a MathValueRecord {
469
        let range = self.stretch_stack_gap_above_min_byte_range();
470
        self.data.read_ref_at(range.start).ok().unwrap()
471
    }
472
473
    /// Minimum gap between the ink of the stretched element, and the (ink) top
474
    /// of the element below.
475
    pub fn stretch_stack_gap_below_min(&self) -> &'a MathValueRecord {
476
        let range = self.stretch_stack_gap_below_min_byte_range();
477
        self.data.read_ref_at(range.start).ok().unwrap()
478
    }
479
480
    /// Standard shift up applied to the numerator.
481
    pub fn fraction_numerator_shift_up(&self) -> &'a MathValueRecord {
482
        let range = self.fraction_numerator_shift_up_byte_range();
483
        self.data.read_ref_at(range.start).ok().unwrap()
484
    }
485
486
    /// Standard shift up applied to the numerator in display style.
487
    pub fn fraction_numerator_display_style_shift_up(&self) -> &'a MathValueRecord {
488
        let range = self.fraction_numerator_display_style_shift_up_byte_range();
489
        self.data.read_ref_at(range.start).ok().unwrap()
490
    }
491
492
    /// Standard shift down applied to the denominator.
493
    pub fn fraction_denominator_shift_down(&self) -> &'a MathValueRecord {
494
        let range = self.fraction_denominator_shift_down_byte_range();
495
        self.data.read_ref_at(range.start).ok().unwrap()
496
    }
497
498
    /// Standard shift down applied to the denominator in display style.
499
    pub fn fraction_denominator_display_style_shift_down(&self) -> &'a MathValueRecord {
500
        let range = self.fraction_denominator_display_style_shift_down_byte_range();
501
        self.data.read_ref_at(range.start).ok().unwrap()
502
    }
503
504
    /// Minimum tolerated gap between the (ink) bottom of the numerator and the
505
    /// ink of the fraction bar.
506
    pub fn fraction_numerator_gap_min(&self) -> &'a MathValueRecord {
507
        let range = self.fraction_numerator_gap_min_byte_range();
508
        self.data.read_ref_at(range.start).ok().unwrap()
509
    }
510
511
    /// Minimum tolerated gap between the (ink) bottom of the numerator and the
512
    /// ink of the fraction bar in display style.
513
    pub fn fraction_num_display_style_gap_min(&self) -> &'a MathValueRecord {
514
        let range = self.fraction_num_display_style_gap_min_byte_range();
515
        self.data.read_ref_at(range.start).ok().unwrap()
516
    }
517
518
    /// Thickness of the fraction bar.
519
    pub fn fraction_rule_thickness(&self) -> &'a MathValueRecord {
520
        let range = self.fraction_rule_thickness_byte_range();
521
        self.data.read_ref_at(range.start).ok().unwrap()
522
    }
523
524
    /// Minimum tolerated gap between the ink of the fraction bar and the (ink)
525
    /// top of the denominator.
526
    pub fn fraction_denominator_gap_min(&self) -> &'a MathValueRecord {
527
        let range = self.fraction_denominator_gap_min_byte_range();
528
        self.data.read_ref_at(range.start).ok().unwrap()
529
    }
530
531
    /// Minimum tolerated gap between the ink of the fraction bar and the (ink)
532
    /// top of the denominator in display style.
533
    pub fn fraction_denom_display_style_gap_min(&self) -> &'a MathValueRecord {
534
        let range = self.fraction_denom_display_style_gap_min_byte_range();
535
        self.data.read_ref_at(range.start).ok().unwrap()
536
    }
537
538
    /// Horizontal distance between the top and bottom elements of a skewed
539
    /// fraction.
540
    pub fn skewed_fraction_horizontal_gap(&self) -> &'a MathValueRecord {
541
        let range = self.skewed_fraction_horizontal_gap_byte_range();
542
        self.data.read_ref_at(range.start).ok().unwrap()
543
    }
544
545
    /// Vertical distance between the ink of the top and bottom elements of a
546
    /// skewed fraction.
547
    pub fn skewed_fraction_vertical_gap(&self) -> &'a MathValueRecord {
548
        let range = self.skewed_fraction_vertical_gap_byte_range();
549
        self.data.read_ref_at(range.start).ok().unwrap()
550
    }
551
552
    /// Distance between the overbar and the (ink) top of he base.
553
    pub fn overbar_vertical_gap(&self) -> &'a MathValueRecord {
554
        let range = self.overbar_vertical_gap_byte_range();
555
        self.data.read_ref_at(range.start).ok().unwrap()
556
    }
557
558
    /// Thickness of overbar.
559
    pub fn overbar_rule_thickness(&self) -> &'a MathValueRecord {
560
        let range = self.overbar_rule_thickness_byte_range();
561
        self.data.read_ref_at(range.start).ok().unwrap()
562
    }
563
564
    /// Extra white space reserved above the overbar.
565
    pub fn overbar_extra_ascender(&self) -> &'a MathValueRecord {
566
        let range = self.overbar_extra_ascender_byte_range();
567
        self.data.read_ref_at(range.start).ok().unwrap()
568
    }
569
570
    /// Distance between underbar and (ink) bottom of the base.
571
    pub fn underbar_vertical_gap(&self) -> &'a MathValueRecord {
572
        let range = self.underbar_vertical_gap_byte_range();
573
        self.data.read_ref_at(range.start).ok().unwrap()
574
    }
575
576
    /// Thickness of underbar.
577
    pub fn underbar_rule_thickness(&self) -> &'a MathValueRecord {
578
        let range = self.underbar_rule_thickness_byte_range();
579
        self.data.read_ref_at(range.start).ok().unwrap()
580
    }
581
582
    /// Extra white space reserved below the underbar.
583
    pub fn underbar_extra_descender(&self) -> &'a MathValueRecord {
584
        let range = self.underbar_extra_descender_byte_range();
585
        self.data.read_ref_at(range.start).ok().unwrap()
586
    }
587
588
    /// Space between the (ink) top of the expression and the bar over it.
589
    pub fn radical_vertical_gap(&self) -> &'a MathValueRecord {
590
        let range = self.radical_vertical_gap_byte_range();
591
        self.data.read_ref_at(range.start).ok().unwrap()
592
    }
593
594
    /// Space between the (ink) top of the expression and the bar over it in
595
    /// display style.
596
    pub fn radical_display_style_vertical_gap(&self) -> &'a MathValueRecord {
597
        let range = self.radical_display_style_vertical_gap_byte_range();
598
        self.data.read_ref_at(range.start).ok().unwrap()
599
    }
600
601
    /// Thickness of the radical rule.
602
    pub fn radical_rule_thickness(&self) -> &'a MathValueRecord {
603
        let range = self.radical_rule_thickness_byte_range();
604
        self.data.read_ref_at(range.start).ok().unwrap()
605
    }
606
607
    /// Extra white space reserved above the radical.
608
    pub fn radical_extra_ascender(&self) -> &'a MathValueRecord {
609
        let range = self.radical_extra_ascender_byte_range();
610
        self.data.read_ref_at(range.start).ok().unwrap()
611
    }
612
613
    /// Extra horizontal kern before the degree of a radical, if such is
614
    /// present.
615
    pub fn radical_kern_before_degree(&self) -> &'a MathValueRecord {
616
        let range = self.radical_kern_before_degree_byte_range();
617
        self.data.read_ref_at(range.start).ok().unwrap()
618
    }
619
620
    /// Negative kern after the degree of a radical, if such is present.
621
    pub fn radical_kern_after_degree(&self) -> &'a MathValueRecord {
622
        let range = self.radical_kern_after_degree_byte_range();
623
        self.data.read_ref_at(range.start).ok().unwrap()
624
    }
625
626
    /// Height of the bottom of the radical degree, if such is present, in
627
    /// proportion to the ascender of the radical sign.
628
    pub fn radical_degree_bottom_raise_percent(&self) -> i16 {
629
        let range = self.radical_degree_bottom_raise_percent_byte_range();
630
        self.data.read_at(range.start).ok().unwrap()
631
    }
632
633
    pub fn script_percent_scale_down_byte_range(&self) -> Range<usize> {
634
        let start = 0;
635
        let end = start + i16::RAW_BYTE_LEN;
636
        start..end
637
    }
638
639
    pub fn script_script_percent_scale_down_byte_range(&self) -> Range<usize> {
640
        let start = self.script_percent_scale_down_byte_range().end;
641
        let end = start + i16::RAW_BYTE_LEN;
642
        start..end
643
    }
644
645
    pub fn delimited_sub_formula_min_height_byte_range(&self) -> Range<usize> {
646
        let start = self.script_script_percent_scale_down_byte_range().end;
647
        let end = start + UfWord::RAW_BYTE_LEN;
648
        start..end
649
    }
650
651
    pub fn display_operator_min_height_byte_range(&self) -> Range<usize> {
652
        let start = self.delimited_sub_formula_min_height_byte_range().end;
653
        let end = start + UfWord::RAW_BYTE_LEN;
654
        start..end
655
    }
656
657
    pub fn math_leading_byte_range(&self) -> Range<usize> {
658
        let start = self.display_operator_min_height_byte_range().end;
659
        let end = start + MathValueRecord::RAW_BYTE_LEN;
660
        start..end
661
    }
662
663
    pub fn axis_height_byte_range(&self) -> Range<usize> {
664
        let start = self.math_leading_byte_range().end;
665
        let end = start + MathValueRecord::RAW_BYTE_LEN;
666
        start..end
667
    }
668
669
    pub fn accent_base_height_byte_range(&self) -> Range<usize> {
670
        let start = self.axis_height_byte_range().end;
671
        let end = start + MathValueRecord::RAW_BYTE_LEN;
672
        start..end
673
    }
674
675
    pub fn flattened_accent_base_height_byte_range(&self) -> Range<usize> {
676
        let start = self.accent_base_height_byte_range().end;
677
        let end = start + MathValueRecord::RAW_BYTE_LEN;
678
        start..end
679
    }
680
681
    pub fn subscript_shift_down_byte_range(&self) -> Range<usize> {
682
        let start = self.flattened_accent_base_height_byte_range().end;
683
        let end = start + MathValueRecord::RAW_BYTE_LEN;
684
        start..end
685
    }
686
687
    pub fn subscript_top_max_byte_range(&self) -> Range<usize> {
688
        let start = self.subscript_shift_down_byte_range().end;
689
        let end = start + MathValueRecord::RAW_BYTE_LEN;
690
        start..end
691
    }
692
693
    pub fn subscript_baseline_drop_min_byte_range(&self) -> Range<usize> {
694
        let start = self.subscript_top_max_byte_range().end;
695
        let end = start + MathValueRecord::RAW_BYTE_LEN;
696
        start..end
697
    }
698
699
    pub fn superscript_shift_up_byte_range(&self) -> Range<usize> {
700
        let start = self.subscript_baseline_drop_min_byte_range().end;
701
        let end = start + MathValueRecord::RAW_BYTE_LEN;
702
        start..end
703
    }
704
705
    pub fn superscript_shift_up_cramped_byte_range(&self) -> Range<usize> {
706
        let start = self.superscript_shift_up_byte_range().end;
707
        let end = start + MathValueRecord::RAW_BYTE_LEN;
708
        start..end
709
    }
710
711
    pub fn superscript_bottom_min_byte_range(&self) -> Range<usize> {
712
        let start = self.superscript_shift_up_cramped_byte_range().end;
713
        let end = start + MathValueRecord::RAW_BYTE_LEN;
714
        start..end
715
    }
716
717
    pub fn superscript_baseline_drop_max_byte_range(&self) -> Range<usize> {
718
        let start = self.superscript_bottom_min_byte_range().end;
719
        let end = start + MathValueRecord::RAW_BYTE_LEN;
720
        start..end
721
    }
722
723
    pub fn sub_superscript_gap_min_byte_range(&self) -> Range<usize> {
724
        let start = self.superscript_baseline_drop_max_byte_range().end;
725
        let end = start + MathValueRecord::RAW_BYTE_LEN;
726
        start..end
727
    }
728
729
    pub fn superscript_bottom_max_with_subscript_byte_range(&self) -> Range<usize> {
730
        let start = self.sub_superscript_gap_min_byte_range().end;
731
        let end = start + MathValueRecord::RAW_BYTE_LEN;
732
        start..end
733
    }
734
735
    pub fn space_after_script_byte_range(&self) -> Range<usize> {
736
        let start = self.superscript_bottom_max_with_subscript_byte_range().end;
737
        let end = start + MathValueRecord::RAW_BYTE_LEN;
738
        start..end
739
    }
740
741
    pub fn upper_limit_gap_min_byte_range(&self) -> Range<usize> {
742
        let start = self.space_after_script_byte_range().end;
743
        let end = start + MathValueRecord::RAW_BYTE_LEN;
744
        start..end
745
    }
746
747
    pub fn upper_limit_baseline_rise_min_byte_range(&self) -> Range<usize> {
748
        let start = self.upper_limit_gap_min_byte_range().end;
749
        let end = start + MathValueRecord::RAW_BYTE_LEN;
750
        start..end
751
    }
752
753
    pub fn lower_limit_gap_min_byte_range(&self) -> Range<usize> {
754
        let start = self.upper_limit_baseline_rise_min_byte_range().end;
755
        let end = start + MathValueRecord::RAW_BYTE_LEN;
756
        start..end
757
    }
758
759
    pub fn lower_limit_baseline_drop_min_byte_range(&self) -> Range<usize> {
760
        let start = self.lower_limit_gap_min_byte_range().end;
761
        let end = start + MathValueRecord::RAW_BYTE_LEN;
762
        start..end
763
    }
764
765
    pub fn stack_top_shift_up_byte_range(&self) -> Range<usize> {
766
        let start = self.lower_limit_baseline_drop_min_byte_range().end;
767
        let end = start + MathValueRecord::RAW_BYTE_LEN;
768
        start..end
769
    }
770
771
    pub fn stack_top_display_style_shift_up_byte_range(&self) -> Range<usize> {
772
        let start = self.stack_top_shift_up_byte_range().end;
773
        let end = start + MathValueRecord::RAW_BYTE_LEN;
774
        start..end
775
    }
776
777
    pub fn stack_bottom_shift_down_byte_range(&self) -> Range<usize> {
778
        let start = self.stack_top_display_style_shift_up_byte_range().end;
779
        let end = start + MathValueRecord::RAW_BYTE_LEN;
780
        start..end
781
    }
782
783
    pub fn stack_bottom_display_style_shift_down_byte_range(&self) -> Range<usize> {
784
        let start = self.stack_bottom_shift_down_byte_range().end;
785
        let end = start + MathValueRecord::RAW_BYTE_LEN;
786
        start..end
787
    }
788
789
    pub fn stack_gap_min_byte_range(&self) -> Range<usize> {
790
        let start = self.stack_bottom_display_style_shift_down_byte_range().end;
791
        let end = start + MathValueRecord::RAW_BYTE_LEN;
792
        start..end
793
    }
794
795
    pub fn stack_display_style_gap_min_byte_range(&self) -> Range<usize> {
796
        let start = self.stack_gap_min_byte_range().end;
797
        let end = start + MathValueRecord::RAW_BYTE_LEN;
798
        start..end
799
    }
800
801
    pub fn stretch_stack_top_shift_up_byte_range(&self) -> Range<usize> {
802
        let start = self.stack_display_style_gap_min_byte_range().end;
803
        let end = start + MathValueRecord::RAW_BYTE_LEN;
804
        start..end
805
    }
806
807
    pub fn stretch_stack_bottom_shift_down_byte_range(&self) -> Range<usize> {
808
        let start = self.stretch_stack_top_shift_up_byte_range().end;
809
        let end = start + MathValueRecord::RAW_BYTE_LEN;
810
        start..end
811
    }
812
813
    pub fn stretch_stack_gap_above_min_byte_range(&self) -> Range<usize> {
814
        let start = self.stretch_stack_bottom_shift_down_byte_range().end;
815
        let end = start + MathValueRecord::RAW_BYTE_LEN;
816
        start..end
817
    }
818
819
    pub fn stretch_stack_gap_below_min_byte_range(&self) -> Range<usize> {
820
        let start = self.stretch_stack_gap_above_min_byte_range().end;
821
        let end = start + MathValueRecord::RAW_BYTE_LEN;
822
        start..end
823
    }
824
825
    pub fn fraction_numerator_shift_up_byte_range(&self) -> Range<usize> {
826
        let start = self.stretch_stack_gap_below_min_byte_range().end;
827
        let end = start + MathValueRecord::RAW_BYTE_LEN;
828
        start..end
829
    }
830
831
    pub fn fraction_numerator_display_style_shift_up_byte_range(&self) -> Range<usize> {
832
        let start = self.fraction_numerator_shift_up_byte_range().end;
833
        let end = start + MathValueRecord::RAW_BYTE_LEN;
834
        start..end
835
    }
836
837
    pub fn fraction_denominator_shift_down_byte_range(&self) -> Range<usize> {
838
        let start = self
839
            .fraction_numerator_display_style_shift_up_byte_range()
840
            .end;
841
        let end = start + MathValueRecord::RAW_BYTE_LEN;
842
        start..end
843
    }
844
845
    pub fn fraction_denominator_display_style_shift_down_byte_range(&self) -> Range<usize> {
846
        let start = self.fraction_denominator_shift_down_byte_range().end;
847
        let end = start + MathValueRecord::RAW_BYTE_LEN;
848
        start..end
849
    }
850
851
    pub fn fraction_numerator_gap_min_byte_range(&self) -> Range<usize> {
852
        let start = self
853
            .fraction_denominator_display_style_shift_down_byte_range()
854
            .end;
855
        let end = start + MathValueRecord::RAW_BYTE_LEN;
856
        start..end
857
    }
858
859
    pub fn fraction_num_display_style_gap_min_byte_range(&self) -> Range<usize> {
860
        let start = self.fraction_numerator_gap_min_byte_range().end;
861
        let end = start + MathValueRecord::RAW_BYTE_LEN;
862
        start..end
863
    }
864
865
    pub fn fraction_rule_thickness_byte_range(&self) -> Range<usize> {
866
        let start = self.fraction_num_display_style_gap_min_byte_range().end;
867
        let end = start + MathValueRecord::RAW_BYTE_LEN;
868
        start..end
869
    }
870
871
    pub fn fraction_denominator_gap_min_byte_range(&self) -> Range<usize> {
872
        let start = self.fraction_rule_thickness_byte_range().end;
873
        let end = start + MathValueRecord::RAW_BYTE_LEN;
874
        start..end
875
    }
876
877
    pub fn fraction_denom_display_style_gap_min_byte_range(&self) -> Range<usize> {
878
        let start = self.fraction_denominator_gap_min_byte_range().end;
879
        let end = start + MathValueRecord::RAW_BYTE_LEN;
880
        start..end
881
    }
882
883
    pub fn skewed_fraction_horizontal_gap_byte_range(&self) -> Range<usize> {
884
        let start = self.fraction_denom_display_style_gap_min_byte_range().end;
885
        let end = start + MathValueRecord::RAW_BYTE_LEN;
886
        start..end
887
    }
888
889
    pub fn skewed_fraction_vertical_gap_byte_range(&self) -> Range<usize> {
890
        let start = self.skewed_fraction_horizontal_gap_byte_range().end;
891
        let end = start + MathValueRecord::RAW_BYTE_LEN;
892
        start..end
893
    }
894
895
    pub fn overbar_vertical_gap_byte_range(&self) -> Range<usize> {
896
        let start = self.skewed_fraction_vertical_gap_byte_range().end;
897
        let end = start + MathValueRecord::RAW_BYTE_LEN;
898
        start..end
899
    }
900
901
    pub fn overbar_rule_thickness_byte_range(&self) -> Range<usize> {
902
        let start = self.overbar_vertical_gap_byte_range().end;
903
        let end = start + MathValueRecord::RAW_BYTE_LEN;
904
        start..end
905
    }
906
907
    pub fn overbar_extra_ascender_byte_range(&self) -> Range<usize> {
908
        let start = self.overbar_rule_thickness_byte_range().end;
909
        let end = start + MathValueRecord::RAW_BYTE_LEN;
910
        start..end
911
    }
912
913
    pub fn underbar_vertical_gap_byte_range(&self) -> Range<usize> {
914
        let start = self.overbar_extra_ascender_byte_range().end;
915
        let end = start + MathValueRecord::RAW_BYTE_LEN;
916
        start..end
917
    }
918
919
    pub fn underbar_rule_thickness_byte_range(&self) -> Range<usize> {
920
        let start = self.underbar_vertical_gap_byte_range().end;
921
        let end = start + MathValueRecord::RAW_BYTE_LEN;
922
        start..end
923
    }
924
925
    pub fn underbar_extra_descender_byte_range(&self) -> Range<usize> {
926
        let start = self.underbar_rule_thickness_byte_range().end;
927
        let end = start + MathValueRecord::RAW_BYTE_LEN;
928
        start..end
929
    }
930
931
    pub fn radical_vertical_gap_byte_range(&self) -> Range<usize> {
932
        let start = self.underbar_extra_descender_byte_range().end;
933
        let end = start + MathValueRecord::RAW_BYTE_LEN;
934
        start..end
935
    }
936
937
    pub fn radical_display_style_vertical_gap_byte_range(&self) -> Range<usize> {
938
        let start = self.radical_vertical_gap_byte_range().end;
939
        let end = start + MathValueRecord::RAW_BYTE_LEN;
940
        start..end
941
    }
942
943
    pub fn radical_rule_thickness_byte_range(&self) -> Range<usize> {
944
        let start = self.radical_display_style_vertical_gap_byte_range().end;
945
        let end = start + MathValueRecord::RAW_BYTE_LEN;
946
        start..end
947
    }
948
949
    pub fn radical_extra_ascender_byte_range(&self) -> Range<usize> {
950
        let start = self.radical_rule_thickness_byte_range().end;
951
        let end = start + MathValueRecord::RAW_BYTE_LEN;
952
        start..end
953
    }
954
955
    pub fn radical_kern_before_degree_byte_range(&self) -> Range<usize> {
956
        let start = self.radical_extra_ascender_byte_range().end;
957
        let end = start + MathValueRecord::RAW_BYTE_LEN;
958
        start..end
959
    }
960
961
    pub fn radical_kern_after_degree_byte_range(&self) -> Range<usize> {
962
        let start = self.radical_kern_before_degree_byte_range().end;
963
        let end = start + MathValueRecord::RAW_BYTE_LEN;
964
        start..end
965
    }
966
967
    pub fn radical_degree_bottom_raise_percent_byte_range(&self) -> Range<usize> {
968
        let start = self.radical_kern_after_degree_byte_range().end;
969
        let end = start + i16::RAW_BYTE_LEN;
970
        start..end
971
    }
972
}
973
974
const _: () = assert!(FontData::default_data_long_enough(MathConstants::MIN_SIZE));
975
976
impl Default for MathConstants<'_> {
977
    fn default() -> Self {
978
        Self {
979
            data: FontData::default_table_data(),
980
        }
981
    }
982
}
983
984
impl<'a> MinByteRange<'a> for MathGlyphInfo<'a> {
985
    fn min_byte_range(&self) -> Range<usize> {
986
        0..self.math_kern_info_offset_byte_range().end
987
    }
988
    fn min_table_bytes(&self) -> &'a [u8] {
989
        let range = self.min_byte_range();
990
        self.data.as_bytes().get(range).unwrap_or_default()
991
    }
992
}
993
994
impl ReadArgs for MathGlyphInfo<'_> {
995
    type Args = ();
996
}
997
998
impl<'a> FontRead<'a> for MathGlyphInfo<'a> {
999
    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
1000
        #[allow(clippy::absurd_extreme_comparisons)]
1001
        if data.len() < Self::MIN_SIZE {
1002
            return Err(ReadError::OutOfBounds);
1003
        }
1004
        Ok(Self { data })
1005
    }
1006
}
1007
1008
/// [MathGlyphInfo](https://learn.microsoft.com/en-us/typography/opentype/spec/math#mathglyphinfo-table)
1009
#[derive(Clone)]
1010
pub struct MathGlyphInfo<'a> {
1011
    data: FontData<'a>,
1012
}
1013
1014
#[allow(clippy::needless_lifetimes)]
1015
impl<'a> MathGlyphInfo<'a> {
1016
    pub const MIN_SIZE: usize = (Offset16::RAW_BYTE_LEN
1017
        + Offset16::RAW_BYTE_LEN
1018
        + Offset16::RAW_BYTE_LEN
1019
        + Offset16::RAW_BYTE_LEN);
1020
    basic_table_impls!(impl_the_methods);
1021
1022
    /// Offset to MathItalicsCorrectionInfo table, from the beginning of the
1023
    /// MathGlyphInfo table. May be NULL.
1024
    pub fn math_italics_correction_info_offset(&self) -> Nullable<Offset16> {
1025
        let range = self.math_italics_correction_info_offset_byte_range();
1026
        self.data.read_at(range.start).ok().unwrap()
1027
    }
1028
1029
    /// Attempt to resolve [`math_italics_correction_info_offset`][Self::math_italics_correction_info_offset].
1030
    pub fn math_italics_correction_info(
1031
        &self,
1032
    ) -> Option<Result<MathItalicsCorrectionInfo<'a>, ReadError>> {
1033
        let data = self.data;
1034
        self.math_italics_correction_info_offset().resolve(data)
1035
    }
1036
1037
    /// Offset to MathTopAccentAttachment table, from the beginning of the
1038
    /// MathGlyphInfo table. May be NULL.
1039
    pub fn math_top_accent_attachment_offset(&self) -> Nullable<Offset16> {
1040
        let range = self.math_top_accent_attachment_offset_byte_range();
1041
        self.data.read_at(range.start).ok().unwrap()
1042
    }
1043
1044
    /// Attempt to resolve [`math_top_accent_attachment_offset`][Self::math_top_accent_attachment_offset].
1045
    pub fn math_top_accent_attachment(
1046
        &self,
1047
    ) -> Option<Result<MathTopAccentAttachment<'a>, ReadError>> {
1048
        let data = self.data;
1049
        self.math_top_accent_attachment_offset().resolve(data)
1050
    }
1051
1052
    /// Offset to the Coverage table for glyphs with extended shapes, from the
1053
    /// beginning of the MathGlyphInfo table. May be NULL.
1054
    pub fn extended_shape_coverage_offset(&self) -> Nullable<Offset16> {
1055
        let range = self.extended_shape_coverage_offset_byte_range();
1056
        self.data.read_at(range.start).ok().unwrap()
1057
    }
1058
1059
    /// Attempt to resolve [`extended_shape_coverage_offset`][Self::extended_shape_coverage_offset].
1060
    pub fn extended_shape_coverage(&self) -> Option<Result<CoverageTable<'a>, ReadError>> {
1061
        let data = self.data;
1062
        self.extended_shape_coverage_offset().resolve(data)
1063
    }
1064
1065
    /// Offset to the MathKernInfo table, from the beginning of the
1066
    /// MathGlyphInfo table. May be NULL.
1067
    pub fn math_kern_info_offset(&self) -> Nullable<Offset16> {
1068
        let range = self.math_kern_info_offset_byte_range();
1069
        self.data.read_at(range.start).ok().unwrap()
1070
    }
1071
1072
    /// Attempt to resolve [`math_kern_info_offset`][Self::math_kern_info_offset].
1073
    pub fn math_kern_info(&self) -> Option<Result<MathKernInfo<'a>, ReadError>> {
1074
        let data = self.data;
1075
        self.math_kern_info_offset().resolve(data)
1076
    }
1077
1078
    pub fn math_italics_correction_info_offset_byte_range(&self) -> Range<usize> {
1079
        let start = 0;
1080
        let end = start + Offset16::RAW_BYTE_LEN;
1081
        start..end
1082
    }
1083
1084
    pub fn math_top_accent_attachment_offset_byte_range(&self) -> Range<usize> {
1085
        let start = self.math_italics_correction_info_offset_byte_range().end;
1086
        let end = start + Offset16::RAW_BYTE_LEN;
1087
        start..end
1088
    }
1089
1090
    pub fn extended_shape_coverage_offset_byte_range(&self) -> Range<usize> {
1091
        let start = self.math_top_accent_attachment_offset_byte_range().end;
1092
        let end = start + Offset16::RAW_BYTE_LEN;
1093
        start..end
1094
    }
1095
1096
    pub fn math_kern_info_offset_byte_range(&self) -> Range<usize> {
1097
        let start = self.extended_shape_coverage_offset_byte_range().end;
1098
        let end = start + Offset16::RAW_BYTE_LEN;
1099
        start..end
1100
    }
1101
}
1102
1103
const _: () = assert!(FontData::default_data_long_enough(MathGlyphInfo::MIN_SIZE));
1104
1105
impl Default for MathGlyphInfo<'_> {
1106
    fn default() -> Self {
1107
        Self {
1108
            data: FontData::default_table_data(),
1109
        }
1110
    }
1111
}
1112
1113
impl<'a> MinByteRange<'a> for MathItalicsCorrectionInfo<'a> {
1114
    fn min_byte_range(&self) -> Range<usize> {
1115
        0..self.italics_correction_byte_range().end
1116
    }
1117
    fn min_table_bytes(&self) -> &'a [u8] {
1118
        let range = self.min_byte_range();
1119
        self.data.as_bytes().get(range).unwrap_or_default()
1120
    }
1121
}
1122
1123
impl ReadArgs for MathItalicsCorrectionInfo<'_> {
1124
    type Args = ();
1125
}
1126
1127
impl<'a> FontRead<'a> for MathItalicsCorrectionInfo<'a> {
1128
    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
1129
        #[allow(clippy::absurd_extreme_comparisons)]
1130
        if data.len() < Self::MIN_SIZE {
1131
            return Err(ReadError::OutOfBounds);
1132
        }
1133
        Ok(Self { data })
1134
    }
1135
}
1136
1137
/// [MathItalicsCorrectionInfo](https://learn.microsoft.com/en-us/typography/opentype/spec/math#mathitalicscorrectioninfo-table)
1138
#[derive(Clone)]
1139
pub struct MathItalicsCorrectionInfo<'a> {
1140
    data: FontData<'a>,
1141
}
1142
1143
#[allow(clippy::needless_lifetimes)]
1144
impl<'a> MathItalicsCorrectionInfo<'a> {
1145
    pub const MIN_SIZE: usize = (Offset16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN);
1146
    basic_table_impls!(impl_the_methods);
1147
1148
    /// Offset to the Coverage table, from the beginning of the
1149
    /// MathItalicsCorrectionInfo table.
1150
    pub fn coverage_offset(&self) -> Offset16 {
1151
        let range = self.coverage_offset_byte_range();
1152
        self.data.read_at(range.start).ok().unwrap()
1153
    }
1154
1155
    /// Attempt to resolve [`coverage_offset`][Self::coverage_offset].
1156
    pub fn coverage(&self) -> Result<CoverageTable<'a>, ReadError> {
1157
        let data = self.data;
1158
        self.coverage_offset().resolve(data)
1159
    }
1160
1161
    /// Number of italics correction values. Should coincide with the number of
1162
    /// covered glyphs.
1163
    pub fn italics_correction_count(&self) -> u16 {
1164
        let range = self.italics_correction_count_byte_range();
1165
        self.data.read_at(range.start).ok().unwrap()
1166
    }
1167
1168
    /// Array of MathValueRecords defining italics correction values for each
1169
    /// covered glyph.
1170
    pub fn italics_correction(&self) -> &'a [MathValueRecord] {
1171
        let range = self.italics_correction_byte_range();
1172
        self.data.read_array(range).ok().unwrap_or_default()
1173
    }
1174
1175
    pub fn coverage_offset_byte_range(&self) -> Range<usize> {
1176
        let start = 0;
1177
        let end = start + Offset16::RAW_BYTE_LEN;
1178
        start..end
1179
    }
1180
1181
    pub fn italics_correction_count_byte_range(&self) -> Range<usize> {
1182
        let start = self.coverage_offset_byte_range().end;
1183
        let end = start + u16::RAW_BYTE_LEN;
1184
        start..end
1185
    }
1186
1187
    pub fn italics_correction_byte_range(&self) -> Range<usize> {
1188
        let italics_correction_count = self.italics_correction_count();
1189
        let start = self.italics_correction_count_byte_range().end;
1190
        let end = start
1191
            + (transforms::to_usize(italics_correction_count))
1192
                .saturating_mul(MathValueRecord::RAW_BYTE_LEN);
1193
        start..end
1194
    }
1195
}
1196
1197
const _: () = assert!(FontData::default_data_long_enough(
1198
    MathItalicsCorrectionInfo::MIN_SIZE
1199
));
1200
1201
impl Default for MathItalicsCorrectionInfo<'_> {
1202
    fn default() -> Self {
1203
        Self {
1204
            data: FontData::default_table_data(),
1205
        }
1206
    }
1207
}
1208
1209
impl<'a> MinByteRange<'a> for MathTopAccentAttachment<'a> {
1210
    fn min_byte_range(&self) -> Range<usize> {
1211
        0..self.top_accent_attachment_byte_range().end
1212
    }
1213
    fn min_table_bytes(&self) -> &'a [u8] {
1214
        let range = self.min_byte_range();
1215
        self.data.as_bytes().get(range).unwrap_or_default()
1216
    }
1217
}
1218
1219
impl ReadArgs for MathTopAccentAttachment<'_> {
1220
    type Args = ();
1221
}
1222
1223
impl<'a> FontRead<'a> for MathTopAccentAttachment<'a> {
1224
    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
1225
        #[allow(clippy::absurd_extreme_comparisons)]
1226
        if data.len() < Self::MIN_SIZE {
1227
            return Err(ReadError::OutOfBounds);
1228
        }
1229
        Ok(Self { data })
1230
    }
1231
}
1232
1233
/// [MathTopAccentAttachment](https://learn.microsoft.com/en-us/typography/opentype/spec/math#mathtopaccentattachment-table)
1234
#[derive(Clone)]
1235
pub struct MathTopAccentAttachment<'a> {
1236
    data: FontData<'a>,
1237
}
1238
1239
#[allow(clippy::needless_lifetimes)]
1240
impl<'a> MathTopAccentAttachment<'a> {
1241
    pub const MIN_SIZE: usize = (Offset16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN);
1242
    basic_table_impls!(impl_the_methods);
1243
1244
    /// Offset to the Coverage table, from the beginning of the
1245
    /// MathTopAccentAttachment table.
1246
    pub fn top_accent_coverage_offset(&self) -> Offset16 {
1247
        let range = self.top_accent_coverage_offset_byte_range();
1248
        self.data.read_at(range.start).ok().unwrap()
1249
    }
1250
1251
    /// Attempt to resolve [`top_accent_coverage_offset`][Self::top_accent_coverage_offset].
1252
    pub fn top_accent_coverage(&self) -> Result<CoverageTable<'a>, ReadError> {
1253
        let data = self.data;
1254
        self.top_accent_coverage_offset().resolve(data)
1255
    }
1256
1257
    /// Number of top accent attachment point values. Should coincide with the
1258
    /// number of covered glyphs.
1259
    pub fn top_accent_attachment_count(&self) -> u16 {
1260
        let range = self.top_accent_attachment_count_byte_range();
1261
        self.data.read_at(range.start).ok().unwrap()
1262
    }
1263
1264
    /// Array of MathValueRecords defining top accent attachment points for each
1265
    /// covered glyph.
1266
    pub fn top_accent_attachment(&self) -> &'a [MathValueRecord] {
1267
        let range = self.top_accent_attachment_byte_range();
1268
        self.data.read_array(range).ok().unwrap_or_default()
1269
    }
1270
1271
    pub fn top_accent_coverage_offset_byte_range(&self) -> Range<usize> {
1272
        let start = 0;
1273
        let end = start + Offset16::RAW_BYTE_LEN;
1274
        start..end
1275
    }
1276
1277
    pub fn top_accent_attachment_count_byte_range(&self) -> Range<usize> {
1278
        let start = self.top_accent_coverage_offset_byte_range().end;
1279
        let end = start + u16::RAW_BYTE_LEN;
1280
        start..end
1281
    }
1282
1283
    pub fn top_accent_attachment_byte_range(&self) -> Range<usize> {
1284
        let top_accent_attachment_count = self.top_accent_attachment_count();
1285
        let start = self.top_accent_attachment_count_byte_range().end;
1286
        let end = start
1287
            + (transforms::to_usize(top_accent_attachment_count))
1288
                .saturating_mul(MathValueRecord::RAW_BYTE_LEN);
1289
        start..end
1290
    }
1291
}
1292
1293
const _: () = assert!(FontData::default_data_long_enough(
1294
    MathTopAccentAttachment::MIN_SIZE
1295
));
1296
1297
impl Default for MathTopAccentAttachment<'_> {
1298
    fn default() -> Self {
1299
        Self {
1300
            data: FontData::default_table_data(),
1301
        }
1302
    }
1303
}
1304
1305
impl<'a> MinByteRange<'a> for MathKernInfo<'a> {
1306
    fn min_byte_range(&self) -> Range<usize> {
1307
        0..self.math_kern_info_records_byte_range().end
1308
    }
1309
    fn min_table_bytes(&self) -> &'a [u8] {
1310
        let range = self.min_byte_range();
1311
        self.data.as_bytes().get(range).unwrap_or_default()
1312
    }
1313
}
1314
1315
impl ReadArgs for MathKernInfo<'_> {
1316
    type Args = ();
1317
}
1318
1319
impl<'a> FontRead<'a> for MathKernInfo<'a> {
1320
    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
1321
        #[allow(clippy::absurd_extreme_comparisons)]
1322
        if data.len() < Self::MIN_SIZE {
1323
            return Err(ReadError::OutOfBounds);
1324
        }
1325
        Ok(Self { data })
1326
    }
1327
}
1328
1329
/// [MathKernInfo](https://learn.microsoft.com/en-us/typography/opentype/spec/math#mathkerninfo-table)
1330
#[derive(Clone)]
1331
pub struct MathKernInfo<'a> {
1332
    data: FontData<'a>,
1333
}
1334
1335
#[allow(clippy::needless_lifetimes)]
1336
impl<'a> MathKernInfo<'a> {
1337
    pub const MIN_SIZE: usize = (Offset16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN);
1338
    basic_table_impls!(impl_the_methods);
1339
1340
    /// Offset to the Coverage table, from the beginning of the MathKernInfo
1341
    /// table.
1342
    pub fn math_kern_coverage_offset(&self) -> Offset16 {
1343
        let range = self.math_kern_coverage_offset_byte_range();
1344
        self.data.read_at(range.start).ok().unwrap()
1345
    }
1346
1347
    /// Attempt to resolve [`math_kern_coverage_offset`][Self::math_kern_coverage_offset].
1348
    pub fn math_kern_coverage(&self) -> Result<CoverageTable<'a>, ReadError> {
1349
        let data = self.data;
1350
        self.math_kern_coverage_offset().resolve(data)
1351
    }
1352
1353
    /// Number of MathKernInfoRecords. Should coincide with the number of
1354
    /// covered glyphs.
1355
    pub fn math_kern_count(&self) -> u16 {
1356
        let range = self.math_kern_count_byte_range();
1357
        self.data.read_at(range.start).ok().unwrap()
1358
    }
1359
1360
    /// Array of MathKernInfoRecords, one for each covered glyph.
1361
    pub fn math_kern_info_records(&self) -> &'a [MathKernInfoRecord] {
1362
        let range = self.math_kern_info_records_byte_range();
1363
        self.data.read_array(range).ok().unwrap_or_default()
1364
    }
1365
1366
    pub fn math_kern_coverage_offset_byte_range(&self) -> Range<usize> {
1367
        let start = 0;
1368
        let end = start + Offset16::RAW_BYTE_LEN;
1369
        start..end
1370
    }
1371
1372
    pub fn math_kern_count_byte_range(&self) -> Range<usize> {
1373
        let start = self.math_kern_coverage_offset_byte_range().end;
1374
        let end = start + u16::RAW_BYTE_LEN;
1375
        start..end
1376
    }
1377
1378
    pub fn math_kern_info_records_byte_range(&self) -> Range<usize> {
1379
        let math_kern_count = self.math_kern_count();
1380
        let start = self.math_kern_count_byte_range().end;
1381
        let end = start
1382
            + (transforms::to_usize(math_kern_count))
1383
                .saturating_mul(MathKernInfoRecord::RAW_BYTE_LEN);
1384
        start..end
1385
    }
1386
}
1387
1388
const _: () = assert!(FontData::default_data_long_enough(MathKernInfo::MIN_SIZE));
1389
1390
impl Default for MathKernInfo<'_> {
1391
    fn default() -> Self {
1392
        Self {
1393
            data: FontData::default_table_data(),
1394
        }
1395
    }
1396
}
1397
1398
/// [MathKernInfoRecord](https://learn.microsoft.com/en-us/typography/opentype/spec/math#mathkerninforecord)
1399
///
1400
/// The offsets are measured from the beginning of the MathKernInfo table.
1401
#[derive(Clone, Debug, Copy, bytemuck :: AnyBitPattern)]
1402
#[repr(C)]
1403
#[repr(packed)]
1404
pub struct MathKernInfoRecord {
1405
    /// Offset to the MathKern table for the top right corner, from the
1406
    /// beginning of the MathKernInfo table. May be NULL.
1407
    pub top_right_math_kern_offset: BigEndian<Nullable<Offset16>>,
1408
    /// Offset to the MathKern table for the top left corner, from the beginning
1409
    /// of the MathKernInfo table. May be NULL.
1410
    pub top_left_math_kern_offset: BigEndian<Nullable<Offset16>>,
1411
    /// Offset to the MathKern table for the bottom right corner, from the
1412
    /// beginning of the MathKernInfo table. May be NULL.
1413
    pub bottom_right_math_kern_offset: BigEndian<Nullable<Offset16>>,
1414
    /// Offset to the MathKern table for the bottom left corner, from the
1415
    /// beginning of the MathKernInfo table. May be NULL.
1416
    pub bottom_left_math_kern_offset: BigEndian<Nullable<Offset16>>,
1417
}
1418
1419
impl MathKernInfoRecord {
1420
    /// Offset to the MathKern table for the top right corner, from the
1421
    /// beginning of the MathKernInfo table. May be NULL.
1422
    pub fn top_right_math_kern_offset(&self) -> Nullable<Offset16> {
1423
        self.top_right_math_kern_offset.get()
1424
    }
1425
1426
    /// Offset to the MathKern table for the top right corner, from the
1427
    /// beginning of the MathKernInfo table. May be NULL.
1428
    ///
1429
    /// The `data` argument should be retrieved from the parent table
1430
    /// By calling its `offset_data` method.
1431
    pub fn top_right_math_kern<'a>(
1432
        &self,
1433
        data: FontData<'a>,
1434
    ) -> Option<Result<MathKern<'a>, ReadError>> {
1435
        self.top_right_math_kern_offset().resolve(data)
1436
    }
1437
1438
    /// Offset to the MathKern table for the top left corner, from the beginning
1439
    /// of the MathKernInfo table. May be NULL.
1440
    pub fn top_left_math_kern_offset(&self) -> Nullable<Offset16> {
1441
        self.top_left_math_kern_offset.get()
1442
    }
1443
1444
    /// Offset to the MathKern table for the top left corner, from the beginning
1445
    /// of the MathKernInfo table. May be NULL.
1446
    ///
1447
    /// The `data` argument should be retrieved from the parent table
1448
    /// By calling its `offset_data` method.
1449
    pub fn top_left_math_kern<'a>(
1450
        &self,
1451
        data: FontData<'a>,
1452
    ) -> Option<Result<MathKern<'a>, ReadError>> {
1453
        self.top_left_math_kern_offset().resolve(data)
1454
    }
1455
1456
    /// Offset to the MathKern table for the bottom right corner, from the
1457
    /// beginning of the MathKernInfo table. May be NULL.
1458
    pub fn bottom_right_math_kern_offset(&self) -> Nullable<Offset16> {
1459
        self.bottom_right_math_kern_offset.get()
1460
    }
1461
1462
    /// Offset to the MathKern table for the bottom right corner, from the
1463
    /// beginning of the MathKernInfo table. May be NULL.
1464
    ///
1465
    /// The `data` argument should be retrieved from the parent table
1466
    /// By calling its `offset_data` method.
1467
    pub fn bottom_right_math_kern<'a>(
1468
        &self,
1469
        data: FontData<'a>,
1470
    ) -> Option<Result<MathKern<'a>, ReadError>> {
1471
        self.bottom_right_math_kern_offset().resolve(data)
1472
    }
1473
1474
    /// Offset to the MathKern table for the bottom left corner, from the
1475
    /// beginning of the MathKernInfo table. May be NULL.
1476
    pub fn bottom_left_math_kern_offset(&self) -> Nullable<Offset16> {
1477
        self.bottom_left_math_kern_offset.get()
1478
    }
1479
1480
    /// Offset to the MathKern table for the bottom left corner, from the
1481
    /// beginning of the MathKernInfo table. May be NULL.
1482
    ///
1483
    /// The `data` argument should be retrieved from the parent table
1484
    /// By calling its `offset_data` method.
1485
    pub fn bottom_left_math_kern<'a>(
1486
        &self,
1487
        data: FontData<'a>,
1488
    ) -> Option<Result<MathKern<'a>, ReadError>> {
1489
        self.bottom_left_math_kern_offset().resolve(data)
1490
    }
1491
}
1492
1493
impl FixedSize for MathKernInfoRecord {
1494
    const RAW_BYTE_LEN: usize = Offset16::RAW_BYTE_LEN
1495
        + Offset16::RAW_BYTE_LEN
1496
        + Offset16::RAW_BYTE_LEN
1497
        + Offset16::RAW_BYTE_LEN;
1498
}
1499
1500
impl<'a> MinByteRange<'a> for MathKern<'a> {
1501
    fn min_byte_range(&self) -> Range<usize> {
1502
        0..self.kern_values_byte_range().end
1503
    }
1504
    fn min_table_bytes(&self) -> &'a [u8] {
1505
        let range = self.min_byte_range();
1506
        self.data.as_bytes().get(range).unwrap_or_default()
1507
    }
1508
}
1509
1510
impl ReadArgs for MathKern<'_> {
1511
    type Args = ();
1512
}
1513
1514
impl<'a> FontRead<'a> for MathKern<'a> {
1515
    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
1516
        #[allow(clippy::absurd_extreme_comparisons)]
1517
        if data.len() < Self::MIN_SIZE {
1518
            return Err(ReadError::OutOfBounds);
1519
        }
1520
        Ok(Self { data })
1521
    }
1522
}
1523
1524
/// [MathKern](https://learn.microsoft.com/en-us/typography/opentype/spec/math#mathkern-table)
1525
#[derive(Clone)]
1526
pub struct MathKern<'a> {
1527
    data: FontData<'a>,
1528
}
1529
1530
#[allow(clippy::needless_lifetimes)]
1531
impl<'a> MathKern<'a> {
1532
    pub const MIN_SIZE: usize = u16::RAW_BYTE_LEN;
1533
    basic_table_impls!(impl_the_methods);
1534
1535
    /// Number of heights at which the kern value changes.
1536
    pub fn height_count(&self) -> u16 {
1537
        let range = self.height_count_byte_range();
1538
        self.data.read_at(range.start).ok().unwrap()
1539
    }
1540
1541
    /// Array of correction heights, in design units, sorted from lowest to
1542
    /// highest.
1543
    pub fn correction_height(&self) -> &'a [MathValueRecord] {
1544
        let range = self.correction_height_byte_range();
1545
        self.data.read_array(range).ok().unwrap_or_default()
1546
    }
1547
1548
    /// Array of kerning values for different height ranges, in design units.
1549
    ///
1550
    /// There is one more of these than there are correction heights: the first
1551
    /// applies below the first correction height, and the last above the last.
1552
    pub fn kern_values(&self) -> &'a [MathValueRecord] {
1553
        let range = self.kern_values_byte_range();
1554
        self.data.read_array(range).ok().unwrap_or_default()
1555
    }
1556
1557
    pub fn height_count_byte_range(&self) -> Range<usize> {
1558
        let start = 0;
1559
        let end = start + u16::RAW_BYTE_LEN;
1560
        start..end
1561
    }
1562
1563
    pub fn correction_height_byte_range(&self) -> Range<usize> {
1564
        let height_count = self.height_count();
1565
        let start = self.height_count_byte_range().end;
1566
        let end = start
1567
            + (transforms::to_usize(height_count)).saturating_mul(MathValueRecord::RAW_BYTE_LEN);
1568
        start..end
1569
    }
1570
1571
    pub fn kern_values_byte_range(&self) -> Range<usize> {
1572
        let height_count = self.height_count();
1573
        let start = self.correction_height_byte_range().end;
1574
        let end = start
1575
            + (transforms::add(height_count, 1_usize))
1576
                .saturating_mul(MathValueRecord::RAW_BYTE_LEN);
1577
        start..end
1578
    }
1579
}
1580
1581
const _: () = assert!(FontData::default_data_long_enough(MathKern::MIN_SIZE));
1582
1583
impl Default for MathKern<'_> {
1584
    fn default() -> Self {
1585
        Self {
1586
            data: FontData::default_table_data(),
1587
        }
1588
    }
1589
}
1590
1591
impl<'a> MinByteRange<'a> for MathVariants<'a> {
1592
    fn min_byte_range(&self) -> Range<usize> {
1593
        0..self.horiz_glyph_construction_offsets_byte_range().end
1594
    }
1595
    fn min_table_bytes(&self) -> &'a [u8] {
1596
        let range = self.min_byte_range();
1597
        self.data.as_bytes().get(range).unwrap_or_default()
1598
    }
1599
}
1600
1601
impl ReadArgs for MathVariants<'_> {
1602
    type Args = ();
1603
}
1604
1605
impl<'a> FontRead<'a> for MathVariants<'a> {
1606
    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
1607
        #[allow(clippy::absurd_extreme_comparisons)]
1608
        if data.len() < Self::MIN_SIZE {
1609
            return Err(ReadError::OutOfBounds);
1610
        }
1611
        Ok(Self { data })
1612
    }
1613
}
1614
1615
/// [MathVariants](https://learn.microsoft.com/en-us/typography/opentype/spec/math#mathvariants-table)
1616
#[derive(Clone)]
1617
pub struct MathVariants<'a> {
1618
    data: FontData<'a>,
1619
}
1620
1621
#[allow(clippy::needless_lifetimes)]
1622
impl<'a> MathVariants<'a> {
1623
    pub const MIN_SIZE: usize = (UfWord::RAW_BYTE_LEN
1624
        + Offset16::RAW_BYTE_LEN
1625
        + Offset16::RAW_BYTE_LEN
1626
        + u16::RAW_BYTE_LEN
1627
        + u16::RAW_BYTE_LEN);
1628
    basic_table_impls!(impl_the_methods);
1629
1630
    /// Minimum overlap of connecting glyphs during glyph construction, in
1631
    /// design units.
1632
    pub fn min_connector_overlap(&self) -> UfWord {
1633
        let range = self.min_connector_overlap_byte_range();
1634
        self.data.read_at(range.start).ok().unwrap()
1635
    }
1636
1637
    /// Offset to the Coverage table for shapes growing in the vertical
1638
    /// direction, from the beginning of the MathVariants table. May be NULL.
1639
    pub fn vert_glyph_coverage_offset(&self) -> Nullable<Offset16> {
1640
        let range = self.vert_glyph_coverage_offset_byte_range();
1641
        self.data.read_at(range.start).ok().unwrap()
1642
    }
1643
1644
    /// Attempt to resolve [`vert_glyph_coverage_offset`][Self::vert_glyph_coverage_offset].
1645
    pub fn vert_glyph_coverage(&self) -> Option<Result<CoverageTable<'a>, ReadError>> {
1646
        let data = self.data;
1647
        self.vert_glyph_coverage_offset().resolve(data)
1648
    }
1649
1650
    /// Offset to the Coverage table for shapes growing in the horizontal
1651
    /// direction, from the beginning of the MathVariants table. May be NULL.
1652
    pub fn horiz_glyph_coverage_offset(&self) -> Nullable<Offset16> {
1653
        let range = self.horiz_glyph_coverage_offset_byte_range();
1654
        self.data.read_at(range.start).ok().unwrap()
1655
    }
1656
1657
    /// Attempt to resolve [`horiz_glyph_coverage_offset`][Self::horiz_glyph_coverage_offset].
1658
    pub fn horiz_glyph_coverage(&self) -> Option<Result<CoverageTable<'a>, ReadError>> {
1659
        let data = self.data;
1660
        self.horiz_glyph_coverage_offset().resolve(data)
1661
    }
1662
1663
    /// Number of glyphs for which information is provided for vertically
1664
    /// growing variants. Must be the same as the number of glyph IDs referenced
1665
    /// in the vertical Coverage table.
1666
    pub fn vert_glyph_count(&self) -> u16 {
1667
        let range = self.vert_glyph_count_byte_range();
1668
        self.data.read_at(range.start).ok().unwrap()
1669
    }
1670
1671
    /// Number of glyphs for which information is provided for horizontally
1672
    /// growing variants. Must be the same as the number of glyph IDs referenced
1673
    /// in the horizontal Coverage table.
1674
    pub fn horiz_glyph_count(&self) -> u16 {
1675
        let range = self.horiz_glyph_count_byte_range();
1676
        self.data.read_at(range.start).ok().unwrap()
1677
    }
1678
1679
    /// Array of offsets to MathGlyphConstruction tables, from the beginning of
1680
    /// the MathVariants table, for shapes growing in the vertical direction.
1681
    pub fn vert_glyph_construction_offsets(&self) -> &'a [BigEndian<Offset16>] {
1682
        let range = self.vert_glyph_construction_offsets_byte_range();
1683
        self.data.read_array(range).ok().unwrap_or_default()
1684
    }
1685
1686
    /// A dynamically resolving wrapper for [`vert_glyph_construction_offsets`][Self::vert_glyph_construction_offsets].
1687
    pub fn vert_glyph_constructions(
1688
        &self,
1689
    ) -> ArrayOfOffsets<'a, MathGlyphConstruction<'a>, Offset16> {
1690
        let data = self.data;
1691
        let offsets = self.vert_glyph_construction_offsets();
1692
        ArrayOfOffsets::new(offsets, data, ())
1693
    }
1694
1695
    /// Array of offsets to MathGlyphConstruction tables, from the beginning of
1696
    /// the MathVariants table, for shapes growing in the horizontal direction.
1697
    pub fn horiz_glyph_construction_offsets(&self) -> &'a [BigEndian<Offset16>] {
1698
        let range = self.horiz_glyph_construction_offsets_byte_range();
1699
        self.data.read_array(range).ok().unwrap_or_default()
1700
    }
1701
1702
    /// A dynamically resolving wrapper for [`horiz_glyph_construction_offsets`][Self::horiz_glyph_construction_offsets].
1703
    pub fn horiz_glyph_constructions(
1704
        &self,
1705
    ) -> ArrayOfOffsets<'a, MathGlyphConstruction<'a>, Offset16> {
1706
        let data = self.data;
1707
        let offsets = self.horiz_glyph_construction_offsets();
1708
        ArrayOfOffsets::new(offsets, data, ())
1709
    }
1710
1711
    pub fn min_connector_overlap_byte_range(&self) -> Range<usize> {
1712
        let start = 0;
1713
        let end = start + UfWord::RAW_BYTE_LEN;
1714
        start..end
1715
    }
1716
1717
    pub fn vert_glyph_coverage_offset_byte_range(&self) -> Range<usize> {
1718
        let start = self.min_connector_overlap_byte_range().end;
1719
        let end = start + Offset16::RAW_BYTE_LEN;
1720
        start..end
1721
    }
1722
1723
    pub fn horiz_glyph_coverage_offset_byte_range(&self) -> Range<usize> {
1724
        let start = self.vert_glyph_coverage_offset_byte_range().end;
1725
        let end = start + Offset16::RAW_BYTE_LEN;
1726
        start..end
1727
    }
1728
1729
    pub fn vert_glyph_count_byte_range(&self) -> Range<usize> {
1730
        let start = self.horiz_glyph_coverage_offset_byte_range().end;
1731
        let end = start + u16::RAW_BYTE_LEN;
1732
        start..end
1733
    }
1734
1735
    pub fn horiz_glyph_count_byte_range(&self) -> Range<usize> {
1736
        let start = self.vert_glyph_count_byte_range().end;
1737
        let end = start + u16::RAW_BYTE_LEN;
1738
        start..end
1739
    }
1740
1741
    pub fn vert_glyph_construction_offsets_byte_range(&self) -> Range<usize> {
1742
        let vert_glyph_count = self.vert_glyph_count();
1743
        let start = self.horiz_glyph_count_byte_range().end;
1744
        let end =
1745
            start + (transforms::to_usize(vert_glyph_count)).saturating_mul(Offset16::RAW_BYTE_LEN);
1746
        start..end
1747
    }
1748
1749
    pub fn horiz_glyph_construction_offsets_byte_range(&self) -> Range<usize> {
1750
        let horiz_glyph_count = self.horiz_glyph_count();
1751
        let start = self.vert_glyph_construction_offsets_byte_range().end;
1752
        let end = start
1753
            + (transforms::to_usize(horiz_glyph_count)).saturating_mul(Offset16::RAW_BYTE_LEN);
1754
        start..end
1755
    }
1756
}
1757
1758
const _: () = assert!(FontData::default_data_long_enough(MathVariants::MIN_SIZE));
1759
1760
impl Default for MathVariants<'_> {
1761
    fn default() -> Self {
1762
        Self {
1763
            data: FontData::default_table_data(),
1764
        }
1765
    }
1766
}
1767
1768
impl<'a> MinByteRange<'a> for MathGlyphConstruction<'a> {
1769
    fn min_byte_range(&self) -> Range<usize> {
1770
        0..self.math_glyph_variant_records_byte_range().end
1771
    }
1772
    fn min_table_bytes(&self) -> &'a [u8] {
1773
        let range = self.min_byte_range();
1774
        self.data.as_bytes().get(range).unwrap_or_default()
1775
    }
1776
}
1777
1778
impl ReadArgs for MathGlyphConstruction<'_> {
1779
    type Args = ();
1780
}
1781
1782
impl<'a> FontRead<'a> for MathGlyphConstruction<'a> {
1783
    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
1784
        #[allow(clippy::absurd_extreme_comparisons)]
1785
        if data.len() < Self::MIN_SIZE {
1786
            return Err(ReadError::OutOfBounds);
1787
        }
1788
        Ok(Self { data })
1789
    }
1790
}
1791
1792
/// [MathGlyphConstruction](https://learn.microsoft.com/en-us/typography/opentype/spec/math#mathglyphconstruction-table)
1793
#[derive(Clone)]
1794
pub struct MathGlyphConstruction<'a> {
1795
    data: FontData<'a>,
1796
}
1797
1798
#[allow(clippy::needless_lifetimes)]
1799
impl<'a> MathGlyphConstruction<'a> {
1800
    pub const MIN_SIZE: usize = (Offset16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN);
1801
    basic_table_impls!(impl_the_methods);
1802
1803
    /// Offset to the GlyphAssembly table for this shape, from the beginning of
1804
    /// the MathGlyphConstruction table. May be NULL.
1805
    pub fn glyph_assembly_offset(&self) -> Nullable<Offset16> {
1806
        let range = self.glyph_assembly_offset_byte_range();
1807
        self.data.read_at(range.start).ok().unwrap()
1808
    }
1809
1810
    /// Attempt to resolve [`glyph_assembly_offset`][Self::glyph_assembly_offset].
1811
    pub fn glyph_assembly(&self) -> Option<Result<GlyphAssembly<'a>, ReadError>> {
1812
        let data = self.data;
1813
        self.glyph_assembly_offset().resolve(data)
1814
    }
1815
1816
    /// Count of glyph growing variants for this glyph.
1817
    pub fn variant_count(&self) -> u16 {
1818
        let range = self.variant_count_byte_range();
1819
        self.data.read_at(range.start).ok().unwrap()
1820
    }
1821
1822
    /// MathGlyphVariantRecords for alternative variants of the base glyph.
1823
    pub fn math_glyph_variant_records(&self) -> &'a [MathGlyphVariantRecord] {
1824
        let range = self.math_glyph_variant_records_byte_range();
1825
        self.data.read_array(range).ok().unwrap_or_default()
1826
    }
1827
1828
    pub fn glyph_assembly_offset_byte_range(&self) -> Range<usize> {
1829
        let start = 0;
1830
        let end = start + Offset16::RAW_BYTE_LEN;
1831
        start..end
1832
    }
1833
1834
    pub fn variant_count_byte_range(&self) -> Range<usize> {
1835
        let start = self.glyph_assembly_offset_byte_range().end;
1836
        let end = start + u16::RAW_BYTE_LEN;
1837
        start..end
1838
    }
1839
1840
    pub fn math_glyph_variant_records_byte_range(&self) -> Range<usize> {
1841
        let variant_count = self.variant_count();
1842
        let start = self.variant_count_byte_range().end;
1843
        let end = start
1844
            + (transforms::to_usize(variant_count))
1845
                .saturating_mul(MathGlyphVariantRecord::RAW_BYTE_LEN);
1846
        start..end
1847
    }
1848
}
1849
1850
const _: () = assert!(FontData::default_data_long_enough(
1851
    MathGlyphConstruction::MIN_SIZE
1852
));
1853
1854
impl Default for MathGlyphConstruction<'_> {
1855
    fn default() -> Self {
1856
        Self {
1857
            data: FontData::default_table_data(),
1858
        }
1859
    }
1860
}
1861
1862
/// [MathGlyphVariantRecord](https://learn.microsoft.com/en-us/typography/opentype/spec/math#mathglyphvariantrecord)
1863
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
1864
#[repr(C)]
1865
#[repr(packed)]
1866
pub struct MathGlyphVariantRecord {
1867
    /// Glyph ID for the variant.
1868
    pub variant_glyph: BigEndian<GlyphId16>,
1869
    /// Advance width/height, in design units, of the variant, in the direction
1870
    /// of requested glyph extension.
1871
    pub advance_measurement: BigEndian<UfWord>,
1872
}
1873
1874
impl MathGlyphVariantRecord {
1875
    /// Glyph ID for the variant.
1876
    pub fn variant_glyph(&self) -> GlyphId16 {
1877
        self.variant_glyph.get()
1878
    }
1879
1880
    /// Advance width/height, in design units, of the variant, in the direction
1881
    /// of requested glyph extension.
1882
    pub fn advance_measurement(&self) -> UfWord {
1883
        self.advance_measurement.get()
1884
    }
1885
}
1886
1887
impl FixedSize for MathGlyphVariantRecord {
1888
    const RAW_BYTE_LEN: usize = GlyphId16::RAW_BYTE_LEN + UfWord::RAW_BYTE_LEN;
1889
}
1890
1891
impl<'a> MinByteRange<'a> for GlyphAssembly<'a> {
1892
    fn min_byte_range(&self) -> Range<usize> {
1893
        0..self.part_records_byte_range().end
1894
    }
1895
    fn min_table_bytes(&self) -> &'a [u8] {
1896
        let range = self.min_byte_range();
1897
        self.data.as_bytes().get(range).unwrap_or_default()
1898
    }
1899
}
1900
1901
impl ReadArgs for GlyphAssembly<'_> {
1902
    type Args = ();
1903
}
1904
1905
impl<'a> FontRead<'a> for GlyphAssembly<'a> {
1906
    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
1907
        #[allow(clippy::absurd_extreme_comparisons)]
1908
        if data.len() < Self::MIN_SIZE {
1909
            return Err(ReadError::OutOfBounds);
1910
        }
1911
        Ok(Self { data })
1912
    }
1913
}
1914
1915
/// [GlyphAssembly](https://learn.microsoft.com/en-us/typography/opentype/spec/math#glyphassembly-table)
1916
#[derive(Clone)]
1917
pub struct GlyphAssembly<'a> {
1918
    data: FontData<'a>,
1919
}
1920
1921
#[allow(clippy::needless_lifetimes)]
1922
impl<'a> GlyphAssembly<'a> {
1923
    pub const MIN_SIZE: usize = (MathValueRecord::RAW_BYTE_LEN + u16::RAW_BYTE_LEN);
1924
    basic_table_impls!(impl_the_methods);
1925
1926
    /// Italics correction of this GlyphAssembly. Should not depend on the
1927
    /// assembly size.
1928
    pub fn italics_correction(&self) -> &'a MathValueRecord {
1929
        let range = self.italics_correction_byte_range();
1930
        self.data.read_ref_at(range.start).ok().unwrap()
1931
    }
1932
1933
    /// Number of parts in this assembly.
1934
    pub fn part_count(&self) -> u16 {
1935
        let range = self.part_count_byte_range();
1936
        self.data.read_at(range.start).ok().unwrap()
1937
    }
1938
1939
    /// Array of part records, from left to right (for assemblies that extend
1940
    /// horizontally) or bottom to top (for assemblies that extend vertically).
1941
    pub fn part_records(&self) -> &'a [GlyphPartRecord] {
1942
        let range = self.part_records_byte_range();
1943
        self.data.read_array(range).ok().unwrap_or_default()
1944
    }
1945
1946
    pub fn italics_correction_byte_range(&self) -> Range<usize> {
1947
        let start = 0;
1948
        let end = start + MathValueRecord::RAW_BYTE_LEN;
1949
        start..end
1950
    }
1951
1952
    pub fn part_count_byte_range(&self) -> Range<usize> {
1953
        let start = self.italics_correction_byte_range().end;
1954
        let end = start + u16::RAW_BYTE_LEN;
1955
        start..end
1956
    }
1957
1958
    pub fn part_records_byte_range(&self) -> Range<usize> {
1959
        let part_count = self.part_count();
1960
        let start = self.part_count_byte_range().end;
1961
        let end = start
1962
            + (transforms::to_usize(part_count)).saturating_mul(GlyphPartRecord::RAW_BYTE_LEN);
1963
        start..end
1964
    }
1965
}
1966
1967
const _: () = assert!(FontData::default_data_long_enough(GlyphAssembly::MIN_SIZE));
1968
1969
impl Default for GlyphAssembly<'_> {
1970
    fn default() -> Self {
1971
        Self {
1972
            data: FontData::default_table_data(),
1973
        }
1974
    }
1975
}
1976
1977
/// [GlyphPartRecord](https://learn.microsoft.com/en-us/typography/opentype/spec/math#glyphpartrecord)
1978
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
1979
#[repr(C)]
1980
#[repr(packed)]
1981
pub struct GlyphPartRecord {
1982
    /// Glyph ID for the part.
1983
    pub glyph_id: BigEndian<GlyphId16>,
1984
    /// Advance width/ height, in design units, of the straight bar connector
1985
    /// material at the start of the glyph in the direction of the extension.
1986
    pub start_connector_length: BigEndian<UfWord>,
1987
    /// Advance width/ height, in design units, of the straight bar connector
1988
    /// material at the end of the glyph in the direction of the extension.
1989
    pub end_connector_length: BigEndian<UfWord>,
1990
    /// Full advance width/height for this part in the direction of the
1991
    /// extension, in design units.
1992
    pub full_advance: BigEndian<UfWord>,
1993
    /// Part qualifiers.
1994
    pub part_flags: BigEndian<PartFlags>,
1995
}
1996
1997
impl GlyphPartRecord {
1998
    /// Glyph ID for the part.
1999
    pub fn glyph_id(&self) -> GlyphId16 {
2000
        self.glyph_id.get()
2001
    }
2002
2003
    /// Advance width/ height, in design units, of the straight bar connector
2004
    /// material at the start of the glyph in the direction of the extension.
2005
    pub fn start_connector_length(&self) -> UfWord {
2006
        self.start_connector_length.get()
2007
    }
2008
2009
    /// Advance width/ height, in design units, of the straight bar connector
2010
    /// material at the end of the glyph in the direction of the extension.
2011
    pub fn end_connector_length(&self) -> UfWord {
2012
        self.end_connector_length.get()
2013
    }
2014
2015
    /// Full advance width/height for this part in the direction of the
2016
    /// extension, in design units.
2017
    pub fn full_advance(&self) -> UfWord {
2018
        self.full_advance.get()
2019
    }
2020
2021
    /// Part qualifiers.
2022
    pub fn part_flags(&self) -> PartFlags {
2023
        self.part_flags.get()
2024
    }
2025
}
2026
2027
impl FixedSize for GlyphPartRecord {
2028
    const RAW_BYTE_LEN: usize = GlyphId16::RAW_BYTE_LEN
2029
        + UfWord::RAW_BYTE_LEN
2030
        + UfWord::RAW_BYTE_LEN
2031
        + UfWord::RAW_BYTE_LEN
2032
        + PartFlags::RAW_BYTE_LEN;
2033
}
2034
2035
/// Qualifiers for a [`GlyphPartRecord`].
2036
#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash, bytemuck :: AnyBitPattern)]
2037
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2038
#[repr(transparent)]
2039
pub struct PartFlags {
2040
    bits: u16,
2041
}
2042
2043
impl PartFlags {
2044
    /// If set, the part can be skipped or repeated.
2045
    pub const EXTENDER_FLAG: Self = Self { bits: 0x0001 };
2046
}
2047
2048
impl PartFlags {
2049
    ///  Returns an empty set of flags.
2050
    #[inline]
2051
    pub const fn empty() -> Self {
2052
        Self { bits: 0 }
2053
    }
2054
2055
    /// Returns the set containing all flags.
2056
    #[inline]
2057
    pub const fn all() -> Self {
2058
        Self {
2059
            bits: Self::EXTENDER_FLAG.bits,
2060
        }
2061
    }
2062
2063
    /// Returns the raw value of the flags currently stored.
2064
    #[inline]
2065
0
    pub const fn bits(&self) -> u16 {
2066
0
        self.bits
2067
0
    }
2068
2069
    /// Convert from underlying bit representation, unless that
2070
    /// representation contains bits that do not correspond to a flag.
2071
    #[inline]
2072
    pub const fn from_bits(bits: u16) -> Option<Self> {
2073
        if (bits & !Self::all().bits()) == 0 {
2074
            Some(Self { bits })
2075
        } else {
2076
            None
2077
        }
2078
    }
2079
2080
    /// Convert from underlying bit representation, dropping any bits
2081
    /// that do not correspond to flags.
2082
    #[inline]
2083
    pub const fn from_bits_truncate(bits: u16) -> Self {
2084
        Self {
2085
            bits: bits & Self::all().bits,
2086
        }
2087
    }
2088
2089
    /// Returns `true` if no flags are currently stored.
2090
    #[inline]
2091
    pub const fn is_empty(&self) -> bool {
2092
        self.bits() == Self::empty().bits()
2093
    }
2094
2095
    /// Returns `true` if there are flags common to both `self` and `other`.
2096
    #[inline]
2097
    pub const fn intersects(&self, other: Self) -> bool {
2098
        !(Self {
2099
            bits: self.bits & other.bits,
2100
        })
2101
        .is_empty()
2102
    }
2103
2104
    /// Returns `true` if all of the flags in `other` are contained within `self`.
2105
    #[inline]
2106
    pub const fn contains(&self, other: Self) -> bool {
2107
        (self.bits & other.bits) == other.bits
2108
    }
2109
2110
    /// Inserts the specified flags in-place.
2111
    #[inline]
2112
    pub fn insert(&mut self, other: Self) {
2113
        self.bits |= other.bits;
2114
    }
2115
2116
    /// Removes the specified flags in-place.
2117
    #[inline]
2118
    pub fn remove(&mut self, other: Self) {
2119
        self.bits &= !other.bits;
2120
    }
2121
2122
    /// Toggles the specified flags in-place.
2123
    #[inline]
2124
    pub fn toggle(&mut self, other: Self) {
2125
        self.bits ^= other.bits;
2126
    }
2127
2128
    /// Returns the intersection between the flags in `self` and
2129
    /// `other`.
2130
    ///
2131
    /// Specifically, the returned set contains only the flags which are
2132
    /// present in *both* `self` *and* `other`.
2133
    ///
2134
    /// This is equivalent to using the `&` operator (e.g.
2135
    /// [`ops::BitAnd`]), as in `flags & other`.
2136
    ///
2137
    /// [`ops::BitAnd`]: https://doc.rust-lang.org/std/ops/trait.BitAnd.html
2138
    #[inline]
2139
    #[must_use]
2140
    pub const fn intersection(self, other: Self) -> Self {
2141
        Self {
2142
            bits: self.bits & other.bits,
2143
        }
2144
    }
2145
2146
    /// Returns the union of between the flags in `self` and `other`.
2147
    ///
2148
    /// Specifically, the returned set contains all flags which are
2149
    /// present in *either* `self` *or* `other`, including any which are
2150
    /// present in both.
2151
    ///
2152
    /// This is equivalent to using the `|` operator (e.g.
2153
    /// [`ops::BitOr`]), as in `flags | other`.
2154
    ///
2155
    /// [`ops::BitOr`]: https://doc.rust-lang.org/std/ops/trait.BitOr.html
2156
    #[inline]
2157
    #[must_use]
2158
    pub const fn union(self, other: Self) -> Self {
2159
        Self {
2160
            bits: self.bits | other.bits,
2161
        }
2162
    }
2163
2164
    /// Returns the difference between the flags in `self` and `other`.
2165
    ///
2166
    /// Specifically, the returned set contains all flags present in
2167
    /// `self`, except for the ones present in `other`.
2168
    ///
2169
    /// It is also conceptually equivalent to the "bit-clear" operation:
2170
    /// `flags & !other` (and this syntax is also supported).
2171
    ///
2172
    /// This is equivalent to using the `-` operator (e.g.
2173
    /// [`ops::Sub`]), as in `flags - other`.
2174
    ///
2175
    /// [`ops::Sub`]: https://doc.rust-lang.org/std/ops/trait.Sub.html
2176
    #[inline]
2177
    #[must_use]
2178
    pub const fn difference(self, other: Self) -> Self {
2179
        Self {
2180
            bits: self.bits & !other.bits,
2181
        }
2182
    }
2183
}
2184
2185
impl std::ops::BitOr for PartFlags {
2186
    type Output = Self;
2187
2188
    /// Returns the union of the two sets of flags.
2189
    #[inline]
2190
    fn bitor(self, other: PartFlags) -> Self {
2191
        Self {
2192
            bits: self.bits | other.bits,
2193
        }
2194
    }
2195
}
2196
2197
impl std::ops::BitOrAssign for PartFlags {
2198
    /// Adds the set of flags.
2199
    #[inline]
2200
    fn bitor_assign(&mut self, other: Self) {
2201
        self.bits |= other.bits;
2202
    }
2203
}
2204
2205
impl std::ops::BitXor for PartFlags {
2206
    type Output = Self;
2207
2208
    /// Returns the left flags, but with all the right flags toggled.
2209
    #[inline]
2210
    fn bitxor(self, other: Self) -> Self {
2211
        Self {
2212
            bits: self.bits ^ other.bits,
2213
        }
2214
    }
2215
}
2216
2217
impl std::ops::BitXorAssign for PartFlags {
2218
    /// Toggles the set of flags.
2219
    #[inline]
2220
    fn bitxor_assign(&mut self, other: Self) {
2221
        self.bits ^= other.bits;
2222
    }
2223
}
2224
2225
impl std::ops::BitAnd for PartFlags {
2226
    type Output = Self;
2227
2228
    /// Returns the intersection between the two sets of flags.
2229
    #[inline]
2230
    fn bitand(self, other: Self) -> Self {
2231
        Self {
2232
            bits: self.bits & other.bits,
2233
        }
2234
    }
2235
}
2236
2237
impl std::ops::BitAndAssign for PartFlags {
2238
    /// Disables all flags disabled in the set.
2239
    #[inline]
2240
    fn bitand_assign(&mut self, other: Self) {
2241
        self.bits &= other.bits;
2242
    }
2243
}
2244
2245
impl std::ops::Sub for PartFlags {
2246
    type Output = Self;
2247
2248
    /// Returns the set difference of the two sets of flags.
2249
    #[inline]
2250
    fn sub(self, other: Self) -> Self {
2251
        Self {
2252
            bits: self.bits & !other.bits,
2253
        }
2254
    }
2255
}
2256
2257
impl std::ops::SubAssign for PartFlags {
2258
    /// Disables all flags enabled in the set.
2259
    #[inline]
2260
    fn sub_assign(&mut self, other: Self) {
2261
        self.bits &= !other.bits;
2262
    }
2263
}
2264
2265
impl std::ops::Not for PartFlags {
2266
    type Output = Self;
2267
2268
    /// Returns the complement of this set of flags.
2269
    #[inline]
2270
    fn not(self) -> Self {
2271
        Self { bits: !self.bits } & Self::all()
2272
    }
2273
}
2274
2275
impl std::fmt::Debug for PartFlags {
2276
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
2277
        let members: &[(&str, Self)] = &[("EXTENDER_FLAG", Self::EXTENDER_FLAG)];
2278
        let mut first = true;
2279
        for (name, value) in members {
2280
            if self.contains(*value) {
2281
                if !first {
2282
                    f.write_str(" | ")?;
2283
                }
2284
                first = false;
2285
                f.write_str(name)?;
2286
            }
2287
        }
2288
        if first {
2289
            f.write_str("(empty)")?;
2290
        }
2291
        Ok(())
2292
    }
2293
}
2294
2295
impl std::fmt::Binary for PartFlags {
2296
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
2297
        std::fmt::Binary::fmt(&self.bits, f)
2298
    }
2299
}
2300
2301
impl std::fmt::Octal for PartFlags {
2302
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
2303
        std::fmt::Octal::fmt(&self.bits, f)
2304
    }
2305
}
2306
2307
impl std::fmt::LowerHex for PartFlags {
2308
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
2309
        std::fmt::LowerHex::fmt(&self.bits, f)
2310
    }
2311
}
2312
2313
impl std::fmt::UpperHex for PartFlags {
2314
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
2315
        std::fmt::UpperHex::fmt(&self.bits, f)
2316
    }
2317
}
2318
2319
impl font_types::Scalar for PartFlags {
2320
    type Raw = <u16 as font_types::Scalar>::Raw;
2321
    fn to_raw(self) -> Self::Raw {
2322
        self.bits().to_raw()
2323
    }
2324
    fn from_raw(raw: Self::Raw) -> Self {
2325
        let t = <u16>::from_raw(raw);
2326
        Self::from_bits_truncate(t)
2327
    }
2328
}