/rust/registry/src/index.crates.io-1949cf8c6b5b557f/read-fonts-0.46.0/generated/generated_gvar.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 Gvar<'a> { |
9 | 0 | fn min_byte_range(&self) -> Range<usize> { |
10 | 0 | 0..self.glyph_variation_data_offsets_byte_range().end |
11 | 0 | } |
12 | 0 | fn min_table_bytes(&self) -> &'a [u8] { |
13 | 0 | let range = self.min_byte_range(); |
14 | 0 | self.offset_data().as_bytes().get(range).unwrap_or_default() |
15 | 0 | } |
16 | | } |
17 | | |
18 | | impl TopLevelTable for Gvar<'_> { |
19 | | /// `gvar` |
20 | | const TAG: Tag = Tag::new(b"gvar"); |
21 | | } |
22 | | |
23 | | impl ReadArgs for Gvar<'_> { |
24 | | type Args = (); |
25 | | } |
26 | | |
27 | | impl<'a> FontRead<'a> for Gvar<'a> { |
28 | 1.18k | fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> { |
29 | | #[allow(clippy::absurd_extreme_comparisons)] |
30 | 1.18k | if data.len() < Self::MIN_SIZE { |
31 | 10 | return Err(ReadError::OutOfBounds); |
32 | 1.17k | } |
33 | 1.17k | let Some(data) = TableDataRef::new(data.as_bytes()) else { |
34 | 0 | return Err(ReadError::OutOfBounds); |
35 | | }; |
36 | 1.17k | Ok(Self { data }) |
37 | 1.18k | } |
38 | | } |
39 | | |
40 | | /// The fields at the start of the table, which are read directly. |
41 | | #[derive(Clone, Copy, bytemuck :: AnyBitPattern)] |
42 | | #[repr(C, packed)] |
43 | | #[doc(hidden)] |
44 | | pub struct GvarFixedHeader { |
45 | | pub version: BigEndian<MajorMinor>, |
46 | | pub axis_count: BigEndian<u16>, |
47 | | pub shared_tuple_count: BigEndian<u16>, |
48 | | pub shared_tuples_offset: BigEndian<Offset32>, |
49 | | pub glyph_count: BigEndian<u16>, |
50 | | pub flags: BigEndian<GvarFlags>, |
51 | | pub glyph_variation_data_array_offset: BigEndian<u32>, |
52 | | } |
53 | | |
54 | | #[allow(clippy::absurd_extreme_comparisons)] |
55 | | const _: () = assert!(std::mem::size_of::<GvarFixedHeader>() <= Gvar::MIN_SIZE); |
56 | | |
57 | | /// The ['gvar' header](https://learn.microsoft.com/en-us/typography/opentype/spec/gvar#gvar-header) |
58 | | #[derive(Clone)] |
59 | | pub struct Gvar<'a> { |
60 | | data: TableDataRef<'a, GvarFixedHeader>, |
61 | | } |
62 | | |
63 | | #[allow(clippy::needless_lifetimes)] |
64 | | impl<'a> Gvar<'a> { |
65 | | pub const MIN_SIZE: usize = (MajorMinor::RAW_BYTE_LEN |
66 | | + u16::RAW_BYTE_LEN |
67 | | + u16::RAW_BYTE_LEN |
68 | | + Offset32::RAW_BYTE_LEN |
69 | | + u16::RAW_BYTE_LEN |
70 | | + GvarFlags::RAW_BYTE_LEN |
71 | | + u32::RAW_BYTE_LEN); |
72 | | basic_table_impls!(impl_the_methods); |
73 | | |
74 | | /// Major/minor version number of the glyph variations table — set to (1,0). |
75 | 0 | pub fn version(&self) -> MajorMinor { |
76 | 0 | self.data.header().version.get() |
77 | 0 | } |
78 | | |
79 | | /// The number of variation axes for this font. This must be the |
80 | | /// same number as axisCount in the 'fvar' table. |
81 | 9.63k | pub fn axis_count(&self) -> u16 { |
82 | 9.63k | self.data.header().axis_count.get() |
83 | 9.63k | } |
84 | | |
85 | | /// The number of shared tuple records. Shared tuple records can be |
86 | | /// referenced within glyph variation data tables for multiple |
87 | | /// glyphs, as opposed to other tuple records stored directly |
88 | | /// within a glyph variation data table. |
89 | 7.47k | pub fn shared_tuple_count(&self) -> u16 { |
90 | 7.47k | self.data.header().shared_tuple_count.get() |
91 | 7.47k | } |
92 | | |
93 | | /// The number of glyphs in this font. This must match the number |
94 | | /// of glyphs stored elsewhere in the font. |
95 | 6.30k | pub fn glyph_count(&self) -> u16 { |
96 | 6.30k | self.data.header().glyph_count.get() |
97 | 6.30k | } |
98 | | |
99 | | /// Bit-field that gives the format of the offset array that |
100 | | /// follows. If bit 0 is clear, the offsets are uint16; if bit 0 is |
101 | | /// set, the offsets are uint32. |
102 | 12.6k | pub fn flags(&self) -> GvarFlags { |
103 | 12.6k | self.data.header().flags.get() |
104 | 12.6k | } |
105 | | |
106 | | /// Offset from the start of this table to the array of |
107 | | /// GlyphVariationData tables. |
108 | 3.25k | pub fn glyph_variation_data_array_offset(&self) -> u32 { |
109 | 3.25k | self.data.header().glyph_variation_data_array_offset.get() |
110 | 3.25k | } |
111 | | |
112 | | /// Offsets from the start of the GlyphVariationData array to each |
113 | | /// GlyphVariationData table. |
114 | 6.30k | pub fn glyph_variation_data_offsets(&self) -> ComputedArray<'a, U16Or32> { |
115 | 6.30k | let range = self.glyph_variation_data_offsets_byte_range(); |
116 | 6.30k | ComputedArray::new(self.offset_data(), range, self.flags()).unwrap_or_default() |
117 | 6.30k | } |
118 | | |
119 | 11.7k | pub fn version_byte_range(&self) -> Range<usize> { |
120 | 11.7k | let start = 0; |
121 | 11.7k | let end = start + MajorMinor::RAW_BYTE_LEN; |
122 | 11.7k | start..end |
123 | 11.7k | } |
124 | | |
125 | 11.7k | pub fn axis_count_byte_range(&self) -> Range<usize> { |
126 | 11.7k | let start = self.version_byte_range().end; |
127 | 11.7k | let end = start + u16::RAW_BYTE_LEN; |
128 | 11.7k | start..end |
129 | 11.7k | } |
130 | | |
131 | 11.7k | pub fn shared_tuple_count_byte_range(&self) -> Range<usize> { |
132 | 11.7k | let start = self.axis_count_byte_range().end; |
133 | 11.7k | let end = start + u16::RAW_BYTE_LEN; |
134 | 11.7k | start..end |
135 | 11.7k | } |
136 | | |
137 | 11.7k | pub fn shared_tuples_offset_byte_range(&self) -> Range<usize> { |
138 | 11.7k | let start = self.shared_tuple_count_byte_range().end; |
139 | 11.7k | let end = start + Offset32::RAW_BYTE_LEN; |
140 | 11.7k | start..end |
141 | 11.7k | } |
142 | | |
143 | 6.30k | pub fn glyph_count_byte_range(&self) -> Range<usize> { |
144 | 6.30k | let start = self.shared_tuples_offset_byte_range().end; |
145 | 6.30k | let end = start + u16::RAW_BYTE_LEN; |
146 | 6.30k | start..end |
147 | 6.30k | } |
148 | | |
149 | 6.30k | pub fn flags_byte_range(&self) -> Range<usize> { |
150 | 6.30k | let start = self.glyph_count_byte_range().end; |
151 | 6.30k | let end = start + GvarFlags::RAW_BYTE_LEN; |
152 | 6.30k | start..end |
153 | 6.30k | } |
154 | | |
155 | 6.30k | pub fn glyph_variation_data_array_offset_byte_range(&self) -> Range<usize> { |
156 | 6.30k | let start = self.flags_byte_range().end; |
157 | 6.30k | let end = start + u32::RAW_BYTE_LEN; |
158 | 6.30k | start..end |
159 | 6.30k | } |
160 | | |
161 | 6.30k | pub fn glyph_variation_data_offsets_byte_range(&self) -> Range<usize> { |
162 | 6.30k | let glyph_count = self.glyph_count(); |
163 | 6.30k | let start = self.glyph_variation_data_array_offset_byte_range().end; |
164 | 6.30k | let end = start |
165 | 6.30k | + (transforms::add(glyph_count, 1_usize)) |
166 | 6.30k | .saturating_mul(<U16Or32 as ComputeSize>::compute_size(self.flags()).unwrap_or(0)); |
167 | 6.30k | start..end |
168 | 6.30k | } |
169 | | } |
170 | | |
171 | | const _: () = assert!(FontData::default_data_long_enough(Gvar::MIN_SIZE)); |
172 | | |
173 | | impl Default for Gvar<'_> { |
174 | 0 | fn default() -> Self { |
175 | | Self { |
176 | 0 | data: TableDataRef::new(FontData::default_table_data().as_bytes()) |
177 | 0 | .unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")), |
178 | | } |
179 | 0 | } |
180 | | } |
181 | | |
182 | | impl<'a> MinByteRange<'a> for GvarExtended<'a> { |
183 | 0 | fn min_byte_range(&self) -> Range<usize> { |
184 | 0 | 0..self.glyph_variation_data_offsets_byte_range().end |
185 | 0 | } |
186 | 0 | fn min_table_bytes(&self) -> &'a [u8] { |
187 | 0 | let range = self.min_byte_range(); |
188 | 0 | self.offset_data().as_bytes().get(range).unwrap_or_default() |
189 | 0 | } |
190 | | } |
191 | | |
192 | | impl TopLevelTable for GvarExtended<'_> { |
193 | | /// `GVAR` |
194 | | const TAG: Tag = Tag::new(b"GVAR"); |
195 | | } |
196 | | |
197 | | impl ReadArgs for GvarExtended<'_> { |
198 | | type Args = (); |
199 | | } |
200 | | |
201 | | impl<'a> FontRead<'a> for GvarExtended<'a> { |
202 | 69 | fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> { |
203 | | #[allow(clippy::absurd_extreme_comparisons)] |
204 | 69 | if data.len() < Self::MIN_SIZE { |
205 | 6 | return Err(ReadError::OutOfBounds); |
206 | 63 | } |
207 | 63 | let Some(data) = TableDataRef::new(data.as_bytes()) else { |
208 | 0 | return Err(ReadError::OutOfBounds); |
209 | | }; |
210 | 63 | Ok(Self { data }) |
211 | 69 | } |
212 | | } |
213 | | |
214 | | /// The fields at the start of the table, which are read directly. |
215 | | #[derive(Clone, Copy, bytemuck :: AnyBitPattern)] |
216 | | #[repr(C, packed)] |
217 | | #[doc(hidden)] |
218 | | pub struct GvarExtendedFixedHeader { |
219 | | pub version: BigEndian<MajorMinor>, |
220 | | pub axis_count: BigEndian<u16>, |
221 | | pub shared_tuple_count: BigEndian<u16>, |
222 | | pub shared_tuples_offset: BigEndian<Offset32>, |
223 | | pub glyph_count: BigEndian<Uint24>, |
224 | | pub flags: BigEndian<GvarFlags>, |
225 | | pub glyph_variation_data_array_offset: BigEndian<u32>, |
226 | | } |
227 | | |
228 | | #[allow(clippy::absurd_extreme_comparisons)] |
229 | | const _: () = assert!(std::mem::size_of::<GvarExtendedFixedHeader>() <= GvarExtended::MIN_SIZE); |
230 | | |
231 | | /// GVAR glyph variations table (ISO/IEC 14496-22:2026, 7.3.9). |
232 | | #[derive(Clone)] |
233 | | pub struct GvarExtended<'a> { |
234 | | data: TableDataRef<'a, GvarExtendedFixedHeader>, |
235 | | } |
236 | | |
237 | | #[allow(clippy::needless_lifetimes)] |
238 | | impl<'a> GvarExtended<'a> { |
239 | | pub const MIN_SIZE: usize = (MajorMinor::RAW_BYTE_LEN |
240 | | + u16::RAW_BYTE_LEN |
241 | | + u16::RAW_BYTE_LEN |
242 | | + Offset32::RAW_BYTE_LEN |
243 | | + Uint24::RAW_BYTE_LEN |
244 | | + GvarFlags::RAW_BYTE_LEN |
245 | | + u32::RAW_BYTE_LEN); |
246 | | basic_table_impls!(impl_the_methods); |
247 | | |
248 | 0 | pub fn version(&self) -> MajorMinor { |
249 | 0 | self.data.header().version.get() |
250 | 0 | } |
251 | | |
252 | 1.05k | pub fn axis_count(&self) -> u16 { |
253 | 1.05k | self.data.header().axis_count.get() |
254 | 1.05k | } |
255 | | |
256 | 795 | pub fn shared_tuple_count(&self) -> u16 { |
257 | 795 | self.data.header().shared_tuple_count.get() |
258 | 795 | } |
259 | | |
260 | | /// Number of glyphs, equal to numGlyphs in MAXP. |
261 | 507 | pub fn glyph_count(&self) -> Uint24 { |
262 | 507 | self.data.header().glyph_count.get() |
263 | 507 | } |
264 | | |
265 | 1.01k | pub fn flags(&self) -> GvarFlags { |
266 | 1.01k | self.data.header().flags.get() |
267 | 1.01k | } |
268 | | |
269 | 312 | pub fn glyph_variation_data_array_offset(&self) -> u32 { |
270 | 312 | self.data.header().glyph_variation_data_array_offset.get() |
271 | 312 | } |
272 | | |
273 | 507 | pub fn glyph_variation_data_offsets(&self) -> ComputedArray<'a, U16Or32> { |
274 | 507 | let range = self.glyph_variation_data_offsets_byte_range(); |
275 | 507 | ComputedArray::new(self.offset_data(), range, self.flags()).unwrap_or_default() |
276 | 507 | } |
277 | | |
278 | 1.22k | pub fn version_byte_range(&self) -> Range<usize> { |
279 | 1.22k | let start = 0; |
280 | 1.22k | let end = start + MajorMinor::RAW_BYTE_LEN; |
281 | 1.22k | start..end |
282 | 1.22k | } |
283 | | |
284 | 1.22k | pub fn axis_count_byte_range(&self) -> Range<usize> { |
285 | 1.22k | let start = self.version_byte_range().end; |
286 | 1.22k | let end = start + u16::RAW_BYTE_LEN; |
287 | 1.22k | start..end |
288 | 1.22k | } |
289 | | |
290 | 1.22k | pub fn shared_tuple_count_byte_range(&self) -> Range<usize> { |
291 | 1.22k | let start = self.axis_count_byte_range().end; |
292 | 1.22k | let end = start + u16::RAW_BYTE_LEN; |
293 | 1.22k | start..end |
294 | 1.22k | } |
295 | | |
296 | 1.22k | pub fn shared_tuples_offset_byte_range(&self) -> Range<usize> { |
297 | 1.22k | let start = self.shared_tuple_count_byte_range().end; |
298 | 1.22k | let end = start + Offset32::RAW_BYTE_LEN; |
299 | 1.22k | start..end |
300 | 1.22k | } |
301 | | |
302 | 507 | pub fn glyph_count_byte_range(&self) -> Range<usize> { |
303 | 507 | let start = self.shared_tuples_offset_byte_range().end; |
304 | 507 | let end = start + Uint24::RAW_BYTE_LEN; |
305 | 507 | start..end |
306 | 507 | } |
307 | | |
308 | 507 | pub fn flags_byte_range(&self) -> Range<usize> { |
309 | 507 | let start = self.glyph_count_byte_range().end; |
310 | 507 | let end = start + GvarFlags::RAW_BYTE_LEN; |
311 | 507 | start..end |
312 | 507 | } |
313 | | |
314 | 507 | pub fn glyph_variation_data_array_offset_byte_range(&self) -> Range<usize> { |
315 | 507 | let start = self.flags_byte_range().end; |
316 | 507 | let end = start + u32::RAW_BYTE_LEN; |
317 | 507 | start..end |
318 | 507 | } |
319 | | |
320 | 507 | pub fn glyph_variation_data_offsets_byte_range(&self) -> Range<usize> { |
321 | 507 | let glyph_count = self.glyph_count(); |
322 | 507 | let start = self.glyph_variation_data_array_offset_byte_range().end; |
323 | 507 | let end = start |
324 | 507 | + (transforms::add(glyph_count, 1_usize)) |
325 | 507 | .saturating_mul(<U16Or32 as ComputeSize>::compute_size(self.flags()).unwrap_or(0)); |
326 | 507 | start..end |
327 | 507 | } |
328 | | } |
329 | | |
330 | | const _: () = assert!(FontData::default_data_long_enough(GvarExtended::MIN_SIZE)); |
331 | | |
332 | | impl Default for GvarExtended<'_> { |
333 | 0 | fn default() -> Self { |
334 | | Self { |
335 | 0 | data: TableDataRef::new(FontData::default_table_data().as_bytes()) |
336 | 0 | .unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")), |
337 | | } |
338 | 0 | } |
339 | | } |
340 | | |
341 | | #[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash, bytemuck :: AnyBitPattern)] |
342 | | #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
343 | | #[repr(transparent)] |
344 | | pub struct GvarFlags { |
345 | | bits: u16, |
346 | | } |
347 | | |
348 | | impl GvarFlags { |
349 | | /// If set, offsets to GlyphVariationData are 32 bits |
350 | | pub const LONG_OFFSETS: Self = Self { bits: 1 }; |
351 | | } |
352 | | |
353 | | impl GvarFlags { |
354 | | /// Returns an empty set of flags. |
355 | | #[inline] |
356 | 0 | pub const fn empty() -> Self { |
357 | 0 | Self { bits: 0 } |
358 | 0 | } |
359 | | |
360 | | /// Returns the set containing all flags. |
361 | | #[inline] |
362 | 13.6k | pub const fn all() -> Self { |
363 | 13.6k | Self { |
364 | 13.6k | bits: Self::LONG_OFFSETS.bits, |
365 | 13.6k | } |
366 | 13.6k | } |
367 | | |
368 | | /// Returns the raw value of the flags currently stored. |
369 | | #[inline] |
370 | 0 | pub const fn bits(&self) -> u16 { |
371 | 0 | self.bits |
372 | 0 | } |
373 | | |
374 | | /// Convert from underlying bit representation, unless that |
375 | | /// representation contains bits that do not correspond to a flag. |
376 | | #[inline] |
377 | 0 | pub const fn from_bits(bits: u16) -> Option<Self> { |
378 | 0 | if (bits & !Self::all().bits()) == 0 { |
379 | 0 | Some(Self { bits }) |
380 | | } else { |
381 | 0 | None |
382 | | } |
383 | 0 | } |
384 | | |
385 | | /// Convert from underlying bit representation, dropping any bits |
386 | | /// that do not correspond to flags. |
387 | | #[inline] |
388 | 13.6k | pub const fn from_bits_truncate(bits: u16) -> Self { |
389 | 13.6k | Self { |
390 | 13.6k | bits: bits & Self::all().bits, |
391 | 13.6k | } |
392 | 13.6k | } |
393 | | |
394 | | /// Returns `true` if no flags are currently stored. |
395 | | #[inline] |
396 | 0 | pub const fn is_empty(&self) -> bool { |
397 | 0 | self.bits() == Self::empty().bits() |
398 | 0 | } |
399 | | |
400 | | /// Returns `true` if there are flags common to both `self` and `other`. |
401 | | #[inline] |
402 | 0 | pub const fn intersects(&self, other: Self) -> bool { |
403 | 0 | !(Self { |
404 | 0 | bits: self.bits & other.bits, |
405 | 0 | }) |
406 | 0 | .is_empty() |
407 | 0 | } |
408 | | |
409 | | /// Returns `true` if all of the flags in `other` are contained within `self`. |
410 | | #[inline] |
411 | 26.2k | pub const fn contains(&self, other: Self) -> bool { |
412 | 26.2k | (self.bits & other.bits) == other.bits |
413 | 26.2k | } |
414 | | |
415 | | /// Inserts the specified flags in-place. |
416 | | #[inline] |
417 | 0 | pub fn insert(&mut self, other: Self) { |
418 | 0 | self.bits |= other.bits; |
419 | 0 | } |
420 | | |
421 | | /// Removes the specified flags in-place. |
422 | | #[inline] |
423 | 0 | pub fn remove(&mut self, other: Self) { |
424 | 0 | self.bits &= !other.bits; |
425 | 0 | } |
426 | | |
427 | | /// Toggles the specified flags in-place. |
428 | | #[inline] |
429 | 0 | pub fn toggle(&mut self, other: Self) { |
430 | 0 | self.bits ^= other.bits; |
431 | 0 | } |
432 | | |
433 | | /// Returns the intersection between the flags in `self` and |
434 | | /// `other`. |
435 | | /// |
436 | | /// Specifically, the returned set contains only the flags which are |
437 | | /// present in *both* `self` *and* `other`. |
438 | | /// |
439 | | /// This is equivalent to using the `&` operator (e.g. |
440 | | /// [`ops::BitAnd`]), as in `flags & other`. |
441 | | /// |
442 | | /// [`ops::BitAnd`]: https://doc.rust-lang.org/std/ops/trait.BitAnd.html |
443 | | #[inline] |
444 | | #[must_use] |
445 | 0 | pub const fn intersection(self, other: Self) -> Self { |
446 | 0 | Self { |
447 | 0 | bits: self.bits & other.bits, |
448 | 0 | } |
449 | 0 | } |
450 | | |
451 | | /// Returns the union of between the flags in `self` and `other`. |
452 | | /// |
453 | | /// Specifically, the returned set contains all flags which are |
454 | | /// present in *either* `self` *or* `other`, including any which are |
455 | | /// present in both. |
456 | | /// |
457 | | /// This is equivalent to using the `|` operator (e.g. |
458 | | /// [`ops::BitOr`]), as in `flags | other`. |
459 | | /// |
460 | | /// [`ops::BitOr`]: https://doc.rust-lang.org/std/ops/trait.BitOr.html |
461 | | #[inline] |
462 | | #[must_use] |
463 | 0 | pub const fn union(self, other: Self) -> Self { |
464 | 0 | Self { |
465 | 0 | bits: self.bits | other.bits, |
466 | 0 | } |
467 | 0 | } |
468 | | |
469 | | /// Returns the difference between the flags in `self` and `other`. |
470 | | /// |
471 | | /// Specifically, the returned set contains all flags present in |
472 | | /// `self`, except for the ones present in `other`. |
473 | | /// |
474 | | /// It is also conceptually equivalent to the "bit-clear" operation: |
475 | | /// `flags & !other` (and this syntax is also supported). |
476 | | /// |
477 | | /// This is equivalent to using the `-` operator (e.g. |
478 | | /// [`ops::Sub`]), as in `flags - other`. |
479 | | /// |
480 | | /// [`ops::Sub`]: https://doc.rust-lang.org/std/ops/trait.Sub.html |
481 | | #[inline] |
482 | | #[must_use] |
483 | 0 | pub const fn difference(self, other: Self) -> Self { |
484 | 0 | Self { |
485 | 0 | bits: self.bits & !other.bits, |
486 | 0 | } |
487 | 0 | } |
488 | | } |
489 | | |
490 | | impl std::ops::BitOr for GvarFlags { |
491 | | type Output = Self; |
492 | | |
493 | | /// Returns the union of the two sets of flags. |
494 | | #[inline] |
495 | 0 | fn bitor(self, other: GvarFlags) -> Self { |
496 | 0 | Self { |
497 | 0 | bits: self.bits | other.bits, |
498 | 0 | } |
499 | 0 | } |
500 | | } |
501 | | |
502 | | impl std::ops::BitOrAssign for GvarFlags { |
503 | | /// Adds the set of flags. |
504 | | #[inline] |
505 | 0 | fn bitor_assign(&mut self, other: Self) { |
506 | 0 | self.bits |= other.bits; |
507 | 0 | } |
508 | | } |
509 | | |
510 | | impl std::ops::BitXor for GvarFlags { |
511 | | type Output = Self; |
512 | | |
513 | | /// Returns the left flags, but with all the right flags toggled. |
514 | | #[inline] |
515 | 0 | fn bitxor(self, other: Self) -> Self { |
516 | 0 | Self { |
517 | 0 | bits: self.bits ^ other.bits, |
518 | 0 | } |
519 | 0 | } |
520 | | } |
521 | | |
522 | | impl std::ops::BitXorAssign for GvarFlags { |
523 | | /// Toggles the set of flags. |
524 | | #[inline] |
525 | 0 | fn bitxor_assign(&mut self, other: Self) { |
526 | 0 | self.bits ^= other.bits; |
527 | 0 | } |
528 | | } |
529 | | |
530 | | impl std::ops::BitAnd for GvarFlags { |
531 | | type Output = Self; |
532 | | |
533 | | /// Returns the intersection between the two sets of flags. |
534 | | #[inline] |
535 | 0 | fn bitand(self, other: Self) -> Self { |
536 | 0 | Self { |
537 | 0 | bits: self.bits & other.bits, |
538 | 0 | } |
539 | 0 | } |
540 | | } |
541 | | |
542 | | impl std::ops::BitAndAssign for GvarFlags { |
543 | | /// Disables all flags disabled in the set. |
544 | | #[inline] |
545 | 0 | fn bitand_assign(&mut self, other: Self) { |
546 | 0 | self.bits &= other.bits; |
547 | 0 | } |
548 | | } |
549 | | |
550 | | impl std::ops::Sub for GvarFlags { |
551 | | type Output = Self; |
552 | | |
553 | | /// Returns the set difference of the two sets of flags. |
554 | | #[inline] |
555 | 0 | fn sub(self, other: Self) -> Self { |
556 | 0 | Self { |
557 | 0 | bits: self.bits & !other.bits, |
558 | 0 | } |
559 | 0 | } |
560 | | } |
561 | | |
562 | | impl std::ops::SubAssign for GvarFlags { |
563 | | /// Disables all flags enabled in the set. |
564 | | #[inline] |
565 | 0 | fn sub_assign(&mut self, other: Self) { |
566 | 0 | self.bits &= !other.bits; |
567 | 0 | } |
568 | | } |
569 | | |
570 | | impl std::ops::Not for GvarFlags { |
571 | | type Output = Self; |
572 | | |
573 | | /// Returns the complement of this set of flags. |
574 | | #[inline] |
575 | 0 | fn not(self) -> Self { |
576 | 0 | Self { bits: !self.bits } & Self::all() |
577 | 0 | } |
578 | | } |
579 | | |
580 | | impl std::fmt::Debug for GvarFlags { |
581 | 0 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { |
582 | 0 | let members: &[(&str, Self)] = &[("LONG_OFFSETS", Self::LONG_OFFSETS)]; |
583 | 0 | let mut first = true; |
584 | 0 | for (name, value) in members { |
585 | 0 | if self.contains(*value) { |
586 | 0 | if !first { |
587 | 0 | f.write_str(" | ")?; |
588 | 0 | } |
589 | 0 | first = false; |
590 | 0 | f.write_str(name)?; |
591 | 0 | } |
592 | | } |
593 | 0 | if first { |
594 | 0 | f.write_str("(empty)")?; |
595 | 0 | } |
596 | 0 | Ok(()) |
597 | 0 | } |
598 | | } |
599 | | |
600 | | impl std::fmt::Binary for GvarFlags { |
601 | 0 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { |
602 | 0 | std::fmt::Binary::fmt(&self.bits, f) |
603 | 0 | } |
604 | | } |
605 | | |
606 | | impl std::fmt::Octal for GvarFlags { |
607 | 0 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { |
608 | 0 | std::fmt::Octal::fmt(&self.bits, f) |
609 | 0 | } |
610 | | } |
611 | | |
612 | | impl std::fmt::LowerHex for GvarFlags { |
613 | 0 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { |
614 | 0 | std::fmt::LowerHex::fmt(&self.bits, f) |
615 | 0 | } |
616 | | } |
617 | | |
618 | | impl std::fmt::UpperHex for GvarFlags { |
619 | 0 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { |
620 | 0 | std::fmt::UpperHex::fmt(&self.bits, f) |
621 | 0 | } |
622 | | } |
623 | | |
624 | | impl font_types::Scalar for GvarFlags { |
625 | | type Raw = <u16 as font_types::Scalar>::Raw; |
626 | 0 | fn to_raw(self) -> Self::Raw { |
627 | 0 | self.bits().to_raw() |
628 | 0 | } |
629 | 13.6k | fn from_raw(raw: Self::Raw) -> Self { |
630 | 13.6k | let t = <u16>::from_raw(raw); |
631 | 13.6k | Self::from_bits_truncate(t) |
632 | 13.6k | } |
633 | | } |
634 | | |
635 | | impl<'a> MinByteRange<'a> for SharedTuples<'a> { |
636 | 0 | fn min_byte_range(&self) -> Range<usize> { |
637 | 0 | 0..self.tuples_byte_range().end |
638 | 0 | } |
639 | 0 | fn min_table_bytes(&self) -> &'a [u8] { |
640 | 0 | let range = self.min_byte_range(); |
641 | 0 | self.offset_data().as_bytes().get(range).unwrap_or_default() |
642 | 0 | } |
643 | | } |
644 | | |
645 | | impl ReadArgs for SharedTuples<'_> { |
646 | | type Args = (u16, u16); |
647 | | } |
648 | | |
649 | | impl<'a> FontRead<'a> for SharedTuples<'a> { |
650 | 4.47k | fn read_with_args(data: FontData<'a>, args: (u16, u16)) -> Result<Self, ReadError> { |
651 | 4.47k | let (shared_tuple_count, axis_count) = args; |
652 | | |
653 | | #[allow(clippy::absurd_extreme_comparisons)] |
654 | 4.47k | if data.len() < Self::MIN_SIZE { |
655 | 0 | return Err(ReadError::OutOfBounds); |
656 | 4.47k | } |
657 | 4.47k | let Some(data) = TableDataRef::new(data.as_bytes()) else { |
658 | 0 | return Err(ReadError::OutOfBounds); |
659 | | }; |
660 | 4.47k | Ok(Self { |
661 | 4.47k | data, |
662 | 4.47k | shared_tuple_count, |
663 | 4.47k | axis_count, |
664 | 4.47k | }) |
665 | 4.47k | } |
666 | | } |
667 | | |
668 | | impl<'a> SharedTuples<'a> { |
669 | | /// A constructor that requires additional arguments. |
670 | | /// |
671 | | /// This type requires some external state in order to be |
672 | | /// parsed. |
673 | 525 | pub fn read( |
674 | 525 | data: FontData<'a>, |
675 | 525 | shared_tuple_count: u16, |
676 | 525 | axis_count: u16, |
677 | 525 | ) -> Result<Self, ReadError> { |
678 | 525 | let args = (shared_tuple_count, axis_count); |
679 | 525 | Self::read_with_args(data, args) |
680 | 525 | } |
681 | | } |
682 | | |
683 | | /// The fields at the start of the table, which are read directly. |
684 | | #[derive(Clone, Copy, bytemuck :: AnyBitPattern)] |
685 | | #[repr(C, packed)] |
686 | | #[doc(hidden)] |
687 | | pub struct SharedTuplesFixedHeader {} |
688 | | |
689 | | #[allow(clippy::absurd_extreme_comparisons)] |
690 | | const _: () = assert!(std::mem::size_of::<SharedTuplesFixedHeader>() <= SharedTuples::MIN_SIZE); |
691 | | |
692 | | /// Array of tuple records shared across all glyph variation data tables. |
693 | | #[derive(Clone)] |
694 | | pub struct SharedTuples<'a> { |
695 | | data: TableDataRef<'a, SharedTuplesFixedHeader>, |
696 | | shared_tuple_count: u16, |
697 | | axis_count: u16, |
698 | | } |
699 | | |
700 | | #[allow(clippy::needless_lifetimes)] |
701 | | impl<'a> SharedTuples<'a> { |
702 | | pub const MIN_SIZE: usize = 0; |
703 | | basic_table_impls!(impl_the_methods); |
704 | | |
705 | 3.42k | pub fn tuples(&self) -> ComputedArray<'a, Tuple<'a>> { |
706 | 3.42k | let range = self.tuples_byte_range(); |
707 | 3.42k | ComputedArray::new(self.offset_data(), range, self.axis_count()).unwrap_or_default() |
708 | 3.42k | } |
709 | | |
710 | 3.42k | pub(crate) fn shared_tuple_count(&self) -> u16 { |
711 | 3.42k | self.shared_tuple_count |
712 | 3.42k | } |
713 | | |
714 | 6.84k | pub(crate) fn axis_count(&self) -> u16 { |
715 | 6.84k | self.axis_count |
716 | 6.84k | } |
717 | | |
718 | 3.42k | pub fn tuples_byte_range(&self) -> Range<usize> { |
719 | 3.42k | let shared_tuple_count = self.shared_tuple_count(); |
720 | 3.42k | let start = 0; |
721 | 3.42k | let end = start |
722 | 3.42k | + (transforms::to_usize(shared_tuple_count)).saturating_mul( |
723 | 3.42k | <Tuple as ComputeSize>::compute_size(self.axis_count()).unwrap_or(0), |
724 | 3.42k | ); |
725 | 3.42k | start..end |
726 | 3.42k | } |
727 | | } |
728 | | |
729 | | #[allow(clippy::absurd_extreme_comparisons)] |
730 | | const _: () = assert!(FontData::default_data_long_enough(SharedTuples::MIN_SIZE)); |
731 | | |
732 | | impl Default for SharedTuples<'_> { |
733 | 0 | fn default() -> Self { |
734 | | Self { |
735 | 0 | data: TableDataRef::new(FontData::default_table_data().as_bytes()) |
736 | 0 | .unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")), |
737 | 0 | shared_tuple_count: Default::default(), |
738 | 0 | axis_count: Default::default(), |
739 | | } |
740 | 0 | } |
741 | | } |
742 | | |
743 | | impl<'a> MinByteRange<'a> for GlyphVariationDataHeader<'a> { |
744 | 0 | fn min_byte_range(&self) -> Range<usize> { |
745 | 0 | 0..self.tuple_variation_headers_byte_range().end |
746 | 0 | } |
747 | 0 | fn min_table_bytes(&self) -> &'a [u8] { |
748 | 0 | let range = self.min_byte_range(); |
749 | 0 | self.offset_data().as_bytes().get(range).unwrap_or_default() |
750 | 0 | } |
751 | | } |
752 | | |
753 | | impl ReadArgs for GlyphVariationDataHeader<'_> { |
754 | | type Args = (); |
755 | | } |
756 | | |
757 | | impl<'a> FontRead<'a> for GlyphVariationDataHeader<'a> { |
758 | 2.70k | fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> { |
759 | | #[allow(clippy::absurd_extreme_comparisons)] |
760 | 2.70k | if data.len() < Self::MIN_SIZE { |
761 | 19 | return Err(ReadError::OutOfBounds); |
762 | 2.68k | } |
763 | 2.68k | let Some(data) = TableDataRef::new(data.as_bytes()) else { |
764 | 0 | return Err(ReadError::OutOfBounds); |
765 | | }; |
766 | 2.68k | Ok(Self { data }) |
767 | 2.70k | } |
768 | | } |
769 | | |
770 | | /// The fields at the start of the table, which are read directly. |
771 | | #[derive(Clone, Copy, bytemuck :: AnyBitPattern)] |
772 | | #[repr(C, packed)] |
773 | | #[doc(hidden)] |
774 | | pub struct GlyphVariationDataHeaderFixedHeader { |
775 | | pub tuple_variation_count: BigEndian<TupleVariationCount>, |
776 | | pub serialized_data_offset: BigEndian<Offset16>, |
777 | | } |
778 | | |
779 | | #[allow(clippy::absurd_extreme_comparisons)] |
780 | | const _: () = assert!( |
781 | | std::mem::size_of::<GlyphVariationDataHeaderFixedHeader>() |
782 | | <= GlyphVariationDataHeader::MIN_SIZE |
783 | | ); |
784 | | |
785 | | /// The [GlyphVariationData](https://learn.microsoft.com/en-us/typography/opentype/spec/gvar#the-glyphvariationdata-table-array) table |
786 | | #[derive(Clone)] |
787 | | pub struct GlyphVariationDataHeader<'a> { |
788 | | data: TableDataRef<'a, GlyphVariationDataHeaderFixedHeader>, |
789 | | } |
790 | | |
791 | | #[allow(clippy::needless_lifetimes)] |
792 | | impl<'a> GlyphVariationDataHeader<'a> { |
793 | | pub const MIN_SIZE: usize = (TupleVariationCount::RAW_BYTE_LEN + Offset16::RAW_BYTE_LEN); |
794 | | basic_table_impls!(impl_the_methods); |
795 | | |
796 | | /// A packed field. The high 4 bits are flags, and the low 12 bits |
797 | | /// are the number of tuple variation tables for this glyph. The |
798 | | /// number of tuple variation tables can be any number between 1 |
799 | | /// and 4095. |
800 | 2.68k | pub fn tuple_variation_count(&self) -> TupleVariationCount { |
801 | 2.68k | self.data.header().tuple_variation_count.get() |
802 | 2.68k | } |
803 | | |
804 | | /// Offset from the start of the GlyphVariationData table to the |
805 | | /// serialized data |
806 | 2.68k | pub fn serialized_data_offset(&self) -> Offset16 { |
807 | 2.68k | self.data.header().serialized_data_offset.get() |
808 | 2.68k | } |
809 | | |
810 | | /// Attempt to resolve [`serialized_data_offset`][Self::serialized_data_offset]. |
811 | 2.68k | pub fn serialized_data(&self) -> Result<FontData<'a>, ReadError> { |
812 | 2.68k | let data = self.offset_data(); |
813 | 2.68k | self.serialized_data_offset().resolve(data) |
814 | 2.68k | } |
815 | | |
816 | | /// Array of tuple variation headers. |
817 | 0 | pub fn tuple_variation_headers(&self) -> VarLenArray<'a, TupleVariationHeader<'a>> { |
818 | 0 | let range = self.tuple_variation_headers_byte_range(); |
819 | 0 | self.offset_data() |
820 | 0 | .split_off(range.start) |
821 | 0 | .and_then(|d| VarLenArray::read(d).ok()) |
822 | 0 | .unwrap_or_default() |
823 | 0 | } |
824 | | |
825 | 2.68k | pub fn tuple_variation_count_byte_range(&self) -> Range<usize> { |
826 | 2.68k | let start = 0; |
827 | 2.68k | let end = start + TupleVariationCount::RAW_BYTE_LEN; |
828 | 2.68k | start..end |
829 | 2.68k | } |
830 | | |
831 | 2.68k | pub fn serialized_data_offset_byte_range(&self) -> Range<usize> { |
832 | 2.68k | let start = self.tuple_variation_count_byte_range().end; |
833 | 2.68k | let end = start + Offset16::RAW_BYTE_LEN; |
834 | 2.68k | start..end |
835 | 2.68k | } |
836 | | |
837 | 2.68k | pub fn tuple_variation_headers_byte_range(&self) -> Range<usize> { |
838 | 2.68k | let start = self.serialized_data_offset_byte_range().end; |
839 | 2.68k | let end = start + self.offset_data().len().saturating_sub(start); |
840 | 2.68k | start..end |
841 | 2.68k | } |
842 | | } |
843 | | |
844 | | const _: () = assert!(FontData::default_data_long_enough( |
845 | | GlyphVariationDataHeader::MIN_SIZE |
846 | | )); |
847 | | |
848 | | impl Default for GlyphVariationDataHeader<'_> { |
849 | 0 | fn default() -> Self { |
850 | | Self { |
851 | 0 | data: TableDataRef::new(FontData::default_table_data().as_bytes()) |
852 | 0 | .unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")), |
853 | | } |
854 | 0 | } |
855 | | } |
856 | | |
857 | | impl<'a> MinByteRange<'a> for GlyphVariationDataHeaderExtended<'a> { |
858 | 0 | fn min_byte_range(&self) -> Range<usize> { |
859 | 0 | 0..self.tuple_variation_headers_byte_range().end |
860 | 0 | } |
861 | 0 | fn min_table_bytes(&self) -> &'a [u8] { |
862 | 0 | let range = self.min_byte_range(); |
863 | 0 | self.offset_data().as_bytes().get(range).unwrap_or_default() |
864 | 0 | } |
865 | | } |
866 | | |
867 | | impl ReadArgs for GlyphVariationDataHeaderExtended<'_> { |
868 | | type Args = (); |
869 | | } |
870 | | |
871 | | impl<'a> FontRead<'a> for GlyphVariationDataHeaderExtended<'a> { |
872 | 0 | fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> { |
873 | | #[allow(clippy::absurd_extreme_comparisons)] |
874 | 0 | if data.len() < Self::MIN_SIZE { |
875 | 0 | return Err(ReadError::OutOfBounds); |
876 | 0 | } |
877 | 0 | let Some(data) = TableDataRef::new(data.as_bytes()) else { |
878 | 0 | return Err(ReadError::OutOfBounds); |
879 | | }; |
880 | 0 | Ok(Self { data }) |
881 | 0 | } |
882 | | } |
883 | | |
884 | | /// The fields at the start of the table, which are read directly. |
885 | | #[derive(Clone, Copy, bytemuck :: AnyBitPattern)] |
886 | | #[repr(C, packed)] |
887 | | #[doc(hidden)] |
888 | | pub struct GlyphVariationDataHeaderExtendedFixedHeader { |
889 | | pub tuple_variation_count: BigEndian<TupleVariationCount>, |
890 | | pub serialized_data_offset: BigEndian<Offset24>, |
891 | | } |
892 | | |
893 | | #[allow(clippy::absurd_extreme_comparisons)] |
894 | | const _: () = assert!( |
895 | | std::mem::size_of::<GlyphVariationDataHeaderExtendedFixedHeader>() |
896 | | <= GlyphVariationDataHeaderExtended::MIN_SIZE |
897 | | ); |
898 | | |
899 | | /// Per-glyph variation header in GVAR (ISO/IEC 14496-22:2026, 7.3.9.1.3). |
900 | | #[derive(Clone)] |
901 | | pub struct GlyphVariationDataHeaderExtended<'a> { |
902 | | data: TableDataRef<'a, GlyphVariationDataHeaderExtendedFixedHeader>, |
903 | | } |
904 | | |
905 | | #[allow(clippy::needless_lifetimes)] |
906 | | impl<'a> GlyphVariationDataHeaderExtended<'a> { |
907 | | pub const MIN_SIZE: usize = (TupleVariationCount::RAW_BYTE_LEN + Offset24::RAW_BYTE_LEN); |
908 | | basic_table_impls!(impl_the_methods); |
909 | | |
910 | 0 | pub fn tuple_variation_count(&self) -> TupleVariationCount { |
911 | 0 | self.data.header().tuple_variation_count.get() |
912 | 0 | } |
913 | | |
914 | 0 | pub fn serialized_data_offset(&self) -> Offset24 { |
915 | 0 | self.data.header().serialized_data_offset.get() |
916 | 0 | } |
917 | | |
918 | | /// Attempt to resolve [`serialized_data_offset`][Self::serialized_data_offset]. |
919 | 0 | pub fn serialized_data(&self) -> Result<FontData<'a>, ReadError> { |
920 | 0 | let data = self.offset_data(); |
921 | 0 | self.serialized_data_offset().resolve(data) |
922 | 0 | } |
923 | | |
924 | 0 | pub fn tuple_variation_headers(&self) -> VarLenArray<'a, TupleVariationHeader<'a>> { |
925 | 0 | let range = self.tuple_variation_headers_byte_range(); |
926 | 0 | self.offset_data() |
927 | 0 | .split_off(range.start) |
928 | 0 | .and_then(|d| VarLenArray::read(d).ok()) |
929 | 0 | .unwrap_or_default() |
930 | 0 | } |
931 | | |
932 | 0 | pub fn tuple_variation_count_byte_range(&self) -> Range<usize> { |
933 | 0 | let start = 0; |
934 | 0 | let end = start + TupleVariationCount::RAW_BYTE_LEN; |
935 | 0 | start..end |
936 | 0 | } |
937 | | |
938 | 0 | pub fn serialized_data_offset_byte_range(&self) -> Range<usize> { |
939 | 0 | let start = self.tuple_variation_count_byte_range().end; |
940 | 0 | let end = start + Offset24::RAW_BYTE_LEN; |
941 | 0 | start..end |
942 | 0 | } |
943 | | |
944 | 0 | pub fn tuple_variation_headers_byte_range(&self) -> Range<usize> { |
945 | 0 | let start = self.serialized_data_offset_byte_range().end; |
946 | 0 | let end = start + self.offset_data().len().saturating_sub(start); |
947 | 0 | start..end |
948 | 0 | } |
949 | | } |
950 | | |
951 | | const _: () = assert!(FontData::default_data_long_enough( |
952 | | GlyphVariationDataHeaderExtended::MIN_SIZE |
953 | | )); |
954 | | |
955 | | impl Default for GlyphVariationDataHeaderExtended<'_> { |
956 | 0 | fn default() -> Self { |
957 | | Self { |
958 | 0 | data: TableDataRef::new(FontData::default_table_data().as_bytes()) |
959 | 0 | .unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")), |
960 | | } |
961 | 0 | } |
962 | | } |