/src/fontations/read-fonts/generated/generated_fvar.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 Fvar<'a> { |
9 | 0 | fn min_byte_range(&self) -> Range<usize> { |
10 | 0 | 0..self.instance_size_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.data.as_bytes().get(range).unwrap_or_default() |
15 | 0 | } |
16 | | } |
17 | | |
18 | | impl TopLevelTable for Fvar<'_> { |
19 | | /// `fvar` |
20 | | const TAG: Tag = Tag::new(b"fvar"); |
21 | | } |
22 | | |
23 | | impl<'a> FontRead<'a> for Fvar<'a> { |
24 | 79.7k | fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
25 | | #[allow(clippy::absurd_extreme_comparisons)] |
26 | 79.7k | if data.len() < Self::MIN_SIZE { |
27 | 0 | return Err(ReadError::OutOfBounds); |
28 | 79.7k | } |
29 | 79.7k | Ok(Self { data }) |
30 | 79.7k | } |
31 | | } |
32 | | |
33 | | /// The [fvar (Font Variations)](https://docs.microsoft.com/en-us/typography/opentype/spec/fvar) table |
34 | | #[derive(Clone)] |
35 | | pub struct Fvar<'a> { |
36 | | data: FontData<'a>, |
37 | | } |
38 | | |
39 | | #[allow(clippy::needless_lifetimes)] |
40 | | impl<'a> Fvar<'a> { |
41 | | pub const MIN_SIZE: usize = (MajorMinor::RAW_BYTE_LEN |
42 | | + Offset16::RAW_BYTE_LEN |
43 | | + u16::RAW_BYTE_LEN |
44 | | + u16::RAW_BYTE_LEN |
45 | | + u16::RAW_BYTE_LEN |
46 | | + u16::RAW_BYTE_LEN |
47 | | + u16::RAW_BYTE_LEN); |
48 | | basic_table_impls!(impl_the_methods); |
49 | | |
50 | | /// Major version number of the font variations table — set to 1. |
51 | | /// Minor version number of the font variations table — set to 0. |
52 | 0 | pub fn version(&self) -> MajorMinor { |
53 | 0 | let range = self.version_byte_range(); |
54 | 0 | self.data.read_at(range.start).ok().unwrap() |
55 | 0 | } |
56 | | |
57 | | /// Offset in bytes from the beginning of the table to the start of the VariationAxisRecord array. The |
58 | | /// InstanceRecord array directly follows. |
59 | 6.11M | pub fn axis_instance_arrays_offset(&self) -> Offset16 { |
60 | 6.11M | let range = self.axis_instance_arrays_offset_byte_range(); |
61 | 6.11M | self.data.read_at(range.start).ok().unwrap() |
62 | 6.11M | } |
63 | | |
64 | | /// Attempt to resolve [`axis_instance_arrays_offset`][Self::axis_instance_arrays_offset]. |
65 | 6.11M | pub fn axis_instance_arrays(&self) -> Result<AxisInstanceArrays<'a>, ReadError> { |
66 | 6.11M | let data = self.data; |
67 | 6.11M | let args = ( |
68 | 6.11M | self.axis_count(), |
69 | 6.11M | self.instance_count(), |
70 | 6.11M | self.instance_size(), |
71 | 6.11M | ); |
72 | 6.11M | self.axis_instance_arrays_offset() |
73 | 6.11M | .resolve_with_args(data, &args) |
74 | 6.11M | } |
75 | | |
76 | | /// The number of variation axes in the font (the number of records in the axes array). |
77 | 6.19M | pub fn axis_count(&self) -> u16 { |
78 | 6.19M | let range = self.axis_count_byte_range(); |
79 | 6.19M | self.data.read_at(range.start).ok().unwrap() |
80 | 6.19M | } |
81 | | |
82 | | /// The size in bytes of each VariationAxisRecord — set to 20 (0x0014) for this version. |
83 | 0 | pub fn axis_size(&self) -> u16 { |
84 | 0 | let range = self.axis_size_byte_range(); |
85 | 0 | self.data.read_at(range.start).ok().unwrap() |
86 | 0 | } |
87 | | |
88 | | /// The number of named instances defined in the font (the number of records in the instances array). |
89 | 6.11M | pub fn instance_count(&self) -> u16 { |
90 | 6.11M | let range = self.instance_count_byte_range(); |
91 | 6.11M | self.data.read_at(range.start).ok().unwrap() |
92 | 6.11M | } |
93 | | |
94 | | /// The size in bytes of each InstanceRecord — set to either axisCount * sizeof(Fixed) + 4, or to axisCount * sizeof(Fixed) + 6. |
95 | 6.11M | pub fn instance_size(&self) -> u16 { |
96 | 6.11M | let range = self.instance_size_byte_range(); |
97 | 6.11M | self.data.read_at(range.start).ok().unwrap() |
98 | 6.11M | } |
99 | | |
100 | 24.5M | pub fn version_byte_range(&self) -> Range<usize> { |
101 | 24.5M | let start = 0; |
102 | 24.5M | start..start + MajorMinor::RAW_BYTE_LEN |
103 | 24.5M | } |
104 | | |
105 | 24.5M | pub fn axis_instance_arrays_offset_byte_range(&self) -> Range<usize> { |
106 | 24.5M | let start = self.version_byte_range().end; |
107 | 24.5M | start..start + Offset16::RAW_BYTE_LEN |
108 | 24.5M | } |
109 | | |
110 | 18.4M | pub fn _reserved_byte_range(&self) -> Range<usize> { |
111 | 18.4M | let start = self.axis_instance_arrays_offset_byte_range().end; |
112 | 18.4M | start..start + u16::RAW_BYTE_LEN |
113 | 18.4M | } |
114 | | |
115 | 18.4M | pub fn axis_count_byte_range(&self) -> Range<usize> { |
116 | 18.4M | let start = self._reserved_byte_range().end; |
117 | 18.4M | start..start + u16::RAW_BYTE_LEN |
118 | 18.4M | } |
119 | | |
120 | 12.2M | pub fn axis_size_byte_range(&self) -> Range<usize> { |
121 | 12.2M | let start = self.axis_count_byte_range().end; |
122 | 12.2M | start..start + u16::RAW_BYTE_LEN |
123 | 12.2M | } |
124 | | |
125 | 12.2M | pub fn instance_count_byte_range(&self) -> Range<usize> { |
126 | 12.2M | let start = self.axis_size_byte_range().end; |
127 | 12.2M | start..start + u16::RAW_BYTE_LEN |
128 | 12.2M | } |
129 | | |
130 | 6.11M | pub fn instance_size_byte_range(&self) -> Range<usize> { |
131 | 6.11M | let start = self.instance_count_byte_range().end; |
132 | 6.11M | start..start + u16::RAW_BYTE_LEN |
133 | 6.11M | } |
134 | | } |
135 | | |
136 | | #[cfg(feature = "experimental_traverse")] |
137 | | impl<'a> SomeTable<'a> for Fvar<'a> { |
138 | | fn type_name(&self) -> &str { |
139 | | "Fvar" |
140 | | } |
141 | | fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
142 | | match idx { |
143 | | 0usize => Some(Field::new("version", self.version())), |
144 | | 1usize => Some(Field::new( |
145 | | "axis_instance_arrays_offset", |
146 | | FieldType::offset( |
147 | | self.axis_instance_arrays_offset(), |
148 | | self.axis_instance_arrays(), |
149 | | ), |
150 | | )), |
151 | | 2usize => Some(Field::new("axis_count", self.axis_count())), |
152 | | 3usize => Some(Field::new("axis_size", self.axis_size())), |
153 | | 4usize => Some(Field::new("instance_count", self.instance_count())), |
154 | | 5usize => Some(Field::new("instance_size", self.instance_size())), |
155 | | _ => None, |
156 | | } |
157 | | } |
158 | | } |
159 | | |
160 | | #[cfg(feature = "experimental_traverse")] |
161 | | #[allow(clippy::needless_lifetimes)] |
162 | | impl<'a> std::fmt::Debug for Fvar<'a> { |
163 | | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
164 | | (self as &dyn SomeTable<'a>).fmt(f) |
165 | | } |
166 | | } |
167 | | |
168 | | impl<'a> MinByteRange<'a> for AxisInstanceArrays<'a> { |
169 | 0 | fn min_byte_range(&self) -> Range<usize> { |
170 | 0 | 0..self.instances_byte_range().end |
171 | 0 | } |
172 | 0 | fn min_table_bytes(&self) -> &'a [u8] { |
173 | 0 | let range = self.min_byte_range(); |
174 | 0 | self.data.as_bytes().get(range).unwrap_or_default() |
175 | 0 | } |
176 | | } |
177 | | |
178 | | impl ReadArgs for AxisInstanceArrays<'_> { |
179 | | type Args = (u16, u16, u16); |
180 | | } |
181 | | |
182 | | impl<'a> FontReadWithArgs<'a> for AxisInstanceArrays<'a> { |
183 | 1.29M | fn read_with_args(data: FontData<'a>, args: &(u16, u16, u16)) -> Result<Self, ReadError> { |
184 | 1.29M | let (axis_count, instance_count, instance_size) = *args; |
185 | | |
186 | | #[allow(clippy::absurd_extreme_comparisons)] |
187 | 1.29M | if data.len() < Self::MIN_SIZE { |
188 | 0 | return Err(ReadError::OutOfBounds); |
189 | 1.29M | } |
190 | 1.29M | Ok(Self { |
191 | 1.29M | data, |
192 | 1.29M | axis_count, |
193 | 1.29M | instance_count, |
194 | 1.29M | instance_size, |
195 | 1.29M | }) |
196 | 1.29M | } |
197 | | } |
198 | | |
199 | | impl<'a> AxisInstanceArrays<'a> { |
200 | | /// A constructor that requires additional arguments. |
201 | | /// |
202 | | /// This type requires some external state in order to be |
203 | | /// parsed. |
204 | 0 | pub fn read( |
205 | 0 | data: FontData<'a>, |
206 | 0 | axis_count: u16, |
207 | 0 | instance_count: u16, |
208 | 0 | instance_size: u16, |
209 | 0 | ) -> Result<Self, ReadError> { |
210 | 0 | let args = (axis_count, instance_count, instance_size); |
211 | 0 | Self::read_with_args(data, &args) |
212 | 0 | } |
213 | | } |
214 | | |
215 | | /// Shim table to handle combined axis and instance arrays. |
216 | | #[derive(Clone)] |
217 | | pub struct AxisInstanceArrays<'a> { |
218 | | data: FontData<'a>, |
219 | | axis_count: u16, |
220 | | instance_count: u16, |
221 | | instance_size: u16, |
222 | | } |
223 | | |
224 | | #[allow(clippy::needless_lifetimes)] |
225 | | impl<'a> AxisInstanceArrays<'a> { |
226 | | pub const MIN_SIZE: usize = 0; |
227 | | basic_table_impls!(impl_the_methods); |
228 | | |
229 | | /// Variation axis record array. |
230 | 1.29M | pub fn axes(&self) -> &'a [VariationAxisRecord] { |
231 | 1.29M | let range = self.axes_byte_range(); |
232 | 1.29M | self.data.read_array(range).ok().unwrap_or_default() |
233 | 1.29M | } |
234 | | |
235 | | /// Instance record array. |
236 | 0 | pub fn instances(&self) -> ComputedArray<'a, InstanceRecord<'a>> { |
237 | 0 | let range = self.instances_byte_range(); |
238 | 0 | self.data |
239 | 0 | .read_with_args(range, &(self.axis_count(), self.instance_size())) |
240 | 0 | .unwrap_or_default() |
241 | 0 | } |
242 | | |
243 | 1.29M | pub(crate) fn axis_count(&self) -> u16 { |
244 | 1.29M | self.axis_count |
245 | 1.29M | } |
246 | | |
247 | 0 | pub(crate) fn instance_count(&self) -> u16 { |
248 | 0 | self.instance_count |
249 | 0 | } |
250 | | |
251 | 0 | pub(crate) fn instance_size(&self) -> u16 { |
252 | 0 | self.instance_size |
253 | 0 | } |
254 | | |
255 | 1.29M | pub fn axes_byte_range(&self) -> Range<usize> { |
256 | 1.29M | let axis_count = self.axis_count(); |
257 | 1.29M | let start = 0; |
258 | 1.29M | start..start + (axis_count as usize).saturating_mul(VariationAxisRecord::RAW_BYTE_LEN) |
259 | 1.29M | } |
260 | | |
261 | 0 | pub fn instances_byte_range(&self) -> Range<usize> { |
262 | 0 | let instance_count = self.instance_count(); |
263 | 0 | let start = self.axes_byte_range().end; |
264 | 0 | start |
265 | 0 | ..start |
266 | 0 | + (instance_count as usize).saturating_mul( |
267 | 0 | <InstanceRecord as ComputeSize>::compute_size(&( |
268 | 0 | self.axis_count(), |
269 | 0 | self.instance_size(), |
270 | 0 | )) |
271 | 0 | .unwrap_or(0), |
272 | 0 | ) |
273 | 0 | } |
274 | | } |
275 | | |
276 | | #[cfg(feature = "experimental_traverse")] |
277 | | impl<'a> SomeTable<'a> for AxisInstanceArrays<'a> { |
278 | | fn type_name(&self) -> &str { |
279 | | "AxisInstanceArrays" |
280 | | } |
281 | | fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
282 | | match idx { |
283 | | 0usize => Some(Field::new( |
284 | | "axes", |
285 | | traversal::FieldType::array_of_records( |
286 | | stringify!(VariationAxisRecord), |
287 | | self.axes(), |
288 | | self.offset_data(), |
289 | | ), |
290 | | )), |
291 | | 1usize => Some(Field::new( |
292 | | "instances", |
293 | | traversal::FieldType::computed_array( |
294 | | "InstanceRecord", |
295 | | self.instances(), |
296 | | self.offset_data(), |
297 | | ), |
298 | | )), |
299 | | _ => None, |
300 | | } |
301 | | } |
302 | | } |
303 | | |
304 | | #[cfg(feature = "experimental_traverse")] |
305 | | #[allow(clippy::needless_lifetimes)] |
306 | | impl<'a> std::fmt::Debug for AxisInstanceArrays<'a> { |
307 | | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
308 | | (self as &dyn SomeTable<'a>).fmt(f) |
309 | | } |
310 | | } |
311 | | |
312 | | /// The [VariationAxisRecord](https://learn.microsoft.com/en-us/typography/opentype/spec/fvar#variationaxisrecord) |
313 | | #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)] |
314 | | #[repr(C)] |
315 | | #[repr(packed)] |
316 | | pub struct VariationAxisRecord { |
317 | | /// Tag identifying the design variation for the axis. |
318 | | pub axis_tag: BigEndian<Tag>, |
319 | | /// The minimum coordinate value for the axis. |
320 | | pub min_value: BigEndian<Fixed>, |
321 | | /// The default coordinate value for the axis. |
322 | | pub default_value: BigEndian<Fixed>, |
323 | | /// The maximum coordinate value for the axis. |
324 | | pub max_value: BigEndian<Fixed>, |
325 | | /// Axis qualifiers — see details below. |
326 | | pub flags: BigEndian<u16>, |
327 | | /// The name ID for entries in the 'name' table that provide a display name for this axis. |
328 | | pub axis_name_id: BigEndian<NameId>, |
329 | | } |
330 | | |
331 | | impl VariationAxisRecord { |
332 | | /// Tag identifying the design variation for the axis. |
333 | 12.4M | pub fn axis_tag(&self) -> Tag { |
334 | 12.4M | self.axis_tag.get() |
335 | 12.4M | } |
336 | | |
337 | | /// The minimum coordinate value for the axis. |
338 | 802k | pub fn min_value(&self) -> Fixed { |
339 | 802k | self.min_value.get() |
340 | 802k | } |
341 | | |
342 | | /// The default coordinate value for the axis. |
343 | 805k | pub fn default_value(&self) -> Fixed { |
344 | 805k | self.default_value.get() |
345 | 805k | } |
346 | | |
347 | | /// The maximum coordinate value for the axis. |
348 | 802k | pub fn max_value(&self) -> Fixed { |
349 | 802k | self.max_value.get() |
350 | 802k | } |
351 | | |
352 | | /// Axis qualifiers — see details below. |
353 | 0 | pub fn flags(&self) -> u16 { |
354 | 0 | self.flags.get() |
355 | 0 | } |
356 | | |
357 | | /// The name ID for entries in the 'name' table that provide a display name for this axis. |
358 | 0 | pub fn axis_name_id(&self) -> NameId { |
359 | 0 | self.axis_name_id.get() |
360 | 0 | } |
361 | | } |
362 | | |
363 | | impl FixedSize for VariationAxisRecord { |
364 | | const RAW_BYTE_LEN: usize = Tag::RAW_BYTE_LEN |
365 | | + Fixed::RAW_BYTE_LEN |
366 | | + Fixed::RAW_BYTE_LEN |
367 | | + Fixed::RAW_BYTE_LEN |
368 | | + u16::RAW_BYTE_LEN |
369 | | + NameId::RAW_BYTE_LEN; |
370 | | } |
371 | | |
372 | | #[cfg(feature = "experimental_traverse")] |
373 | | impl<'a> SomeRecord<'a> for VariationAxisRecord { |
374 | | fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { |
375 | | RecordResolver { |
376 | | name: "VariationAxisRecord", |
377 | | get_field: Box::new(move |idx, _data| match idx { |
378 | | 0usize => Some(Field::new("axis_tag", self.axis_tag())), |
379 | | 1usize => Some(Field::new("min_value", self.min_value())), |
380 | | 2usize => Some(Field::new("default_value", self.default_value())), |
381 | | 3usize => Some(Field::new("max_value", self.max_value())), |
382 | | 4usize => Some(Field::new("flags", self.flags())), |
383 | | 5usize => Some(Field::new("axis_name_id", self.axis_name_id())), |
384 | | _ => None, |
385 | | }), |
386 | | data, |
387 | | } |
388 | | } |
389 | | } |