Skip to main content

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