read_fonts/generated/
generated_fvar.rs

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