// THIS FILE IS AUTOGENERATED. // Any changes to this file will be overwritten. // For more information about how codegen works, see font-codegen/README.md #[allow(unused_imports)] use crate::codegen_prelude::*; impl<'a> MinByteRange<'a> for Fvar<'a> { fn min_byte_range(&self) -> Range { 0..self.instance_size_byte_range().end } fn min_table_bytes(&self) -> &'a [u8] { let range = self.min_byte_range(); self.data.as_bytes().get(range).unwrap_or_default() } } impl TopLevelTable for Fvar<'_> { /// `fvar` const TAG: Tag = Tag::new(b"fvar"); } impl<'a> FontRead<'a> for Fvar<'a> { fn read(data: FontData<'a>) -> Result { #[allow(clippy::absurd_extreme_comparisons)] if data.len() < Self::MIN_SIZE { return Err(ReadError::OutOfBounds); } Ok(Self { data }) } } /// The [fvar (Font Variations)](https://docs.microsoft.com/en-us/typography/opentype/spec/fvar) table #[derive(Clone)] pub struct Fvar<'a> { data: FontData<'a>, } #[allow(clippy::needless_lifetimes)] impl<'a> Fvar<'a> { pub const MIN_SIZE: usize = (MajorMinor::RAW_BYTE_LEN + Offset16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN); basic_table_impls!(impl_the_methods); /// Major version number of the font variations table — set to 1. /// Minor version number of the font variations table — set to 0. pub fn version(&self) -> MajorMinor { let range = self.version_byte_range(); self.data.read_at(range.start).ok().unwrap() } /// Offset in bytes from the beginning of the table to the start of the VariationAxisRecord array. The /// InstanceRecord array directly follows. pub fn axis_instance_arrays_offset(&self) -> Offset16 { let range = self.axis_instance_arrays_offset_byte_range(); self.data.read_at(range.start).ok().unwrap() } /// Attempt to resolve [`axis_instance_arrays_offset`][Self::axis_instance_arrays_offset]. pub fn axis_instance_arrays(&self) -> Result, ReadError> { let data = self.data; let args = ( self.axis_count(), self.instance_count(), self.instance_size(), ); self.axis_instance_arrays_offset() .resolve_with_args(data, &args) } /// The number of variation axes in the font (the number of records in the axes array). pub fn axis_count(&self) -> u16 { let range = self.axis_count_byte_range(); self.data.read_at(range.start).ok().unwrap() } /// The size in bytes of each VariationAxisRecord — set to 20 (0x0014) for this version. pub fn axis_size(&self) -> u16 { let range = self.axis_size_byte_range(); self.data.read_at(range.start).ok().unwrap() } /// The number of named instances defined in the font (the number of records in the instances array). pub fn instance_count(&self) -> u16 { let range = self.instance_count_byte_range(); self.data.read_at(range.start).ok().unwrap() } /// The size in bytes of each InstanceRecord — set to either axisCount * sizeof(Fixed) + 4, or to axisCount * sizeof(Fixed) + 6. pub fn instance_size(&self) -> u16 { let range = self.instance_size_byte_range(); self.data.read_at(range.start).ok().unwrap() } pub fn version_byte_range(&self) -> Range { let start = 0; let end = start + MajorMinor::RAW_BYTE_LEN; start..end } pub fn axis_instance_arrays_offset_byte_range(&self) -> Range { let start = self.version_byte_range().end; let end = start + Offset16::RAW_BYTE_LEN; start..end } pub fn _reserved_byte_range(&self) -> Range { let start = self.axis_instance_arrays_offset_byte_range().end; let end = start + u16::RAW_BYTE_LEN; start..end } pub fn axis_count_byte_range(&self) -> Range { let start = self._reserved_byte_range().end; let end = start + u16::RAW_BYTE_LEN; start..end } pub fn axis_size_byte_range(&self) -> Range { let start = self.axis_count_byte_range().end; let end = start + u16::RAW_BYTE_LEN; start..end } pub fn instance_count_byte_range(&self) -> Range { let start = self.axis_size_byte_range().end; let end = start + u16::RAW_BYTE_LEN; start..end } pub fn instance_size_byte_range(&self) -> Range { let start = self.instance_count_byte_range().end; let end = start + u16::RAW_BYTE_LEN; start..end } } const _: () = assert!(FontData::default_data_long_enough(Fvar::MIN_SIZE)); impl Default for Fvar<'_> { fn default() -> Self { Self { data: FontData::default_table_data(), } } } #[cfg(feature = "experimental_traverse")] impl<'a> SomeTable<'a> for Fvar<'a> { fn type_name(&self) -> &str { "Fvar" } fn get_field(&self, idx: usize) -> Option> { match idx { 0usize => Some(Field::new("version", self.version())), 1usize => Some(Field::new( "axis_instance_arrays_offset", FieldType::offset( self.axis_instance_arrays_offset(), self.axis_instance_arrays(), ), )), 2usize => Some(Field::new("axis_count", self.axis_count())), 3usize => Some(Field::new("axis_size", self.axis_size())), 4usize => Some(Field::new("instance_count", self.instance_count())), 5usize => Some(Field::new("instance_size", self.instance_size())), _ => None, } } } #[cfg(feature = "experimental_traverse")] #[allow(clippy::needless_lifetimes)] impl<'a> std::fmt::Debug for Fvar<'a> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { (self as &dyn SomeTable<'a>).fmt(f) } } impl<'a> MinByteRange<'a> for AxisInstanceArrays<'a> { fn min_byte_range(&self) -> Range { 0..self.instances_byte_range().end } fn min_table_bytes(&self) -> &'a [u8] { let range = self.min_byte_range(); self.data.as_bytes().get(range).unwrap_or_default() } } impl ReadArgs for AxisInstanceArrays<'_> { type Args = (u16, u16, u16); } impl<'a> FontReadWithArgs<'a> for AxisInstanceArrays<'a> { fn read_with_args(data: FontData<'a>, args: &(u16, u16, u16)) -> Result { let (axis_count, instance_count, instance_size) = *args; #[allow(clippy::absurd_extreme_comparisons)] if data.len() < Self::MIN_SIZE { return Err(ReadError::OutOfBounds); } Ok(Self { data, axis_count, instance_count, instance_size, }) } } impl<'a> AxisInstanceArrays<'a> { /// A constructor that requires additional arguments. /// /// This type requires some external state in order to be /// parsed. pub fn read( data: FontData<'a>, axis_count: u16, instance_count: u16, instance_size: u16, ) -> Result { let args = (axis_count, instance_count, instance_size); Self::read_with_args(data, &args) } } /// Shim table to handle combined axis and instance arrays. #[derive(Clone)] pub struct AxisInstanceArrays<'a> { data: FontData<'a>, axis_count: u16, instance_count: u16, instance_size: u16, } #[allow(clippy::needless_lifetimes)] impl<'a> AxisInstanceArrays<'a> { pub const MIN_SIZE: usize = 0; basic_table_impls!(impl_the_methods); /// Variation axis record array. pub fn axes(&self) -> &'a [VariationAxisRecord] { let range = self.axes_byte_range(); self.data.read_array(range).ok().unwrap_or_default() } /// Instance record array. pub fn instances(&self) -> ComputedArray<'a, InstanceRecord<'a>> { let range = self.instances_byte_range(); self.data .read_with_args(range, &(self.axis_count(), self.instance_size())) .unwrap_or_default() } pub(crate) fn axis_count(&self) -> u16 { self.axis_count } pub(crate) fn instance_count(&self) -> u16 { self.instance_count } pub(crate) fn instance_size(&self) -> u16 { self.instance_size } pub fn axes_byte_range(&self) -> Range { let axis_count = self.axis_count(); let start = 0; let end = start + (transforms::to_usize(axis_count)).saturating_mul(VariationAxisRecord::RAW_BYTE_LEN); start..end } pub fn instances_byte_range(&self) -> Range { let instance_count = self.instance_count(); let start = self.axes_byte_range().end; let end = start + (transforms::to_usize(instance_count)).saturating_mul( ::compute_size(&( self.axis_count(), self.instance_size(), )) .unwrap_or(0), ); start..end } } #[allow(clippy::absurd_extreme_comparisons)] const _: () = assert!(FontData::default_data_long_enough( AxisInstanceArrays::MIN_SIZE )); impl Default for AxisInstanceArrays<'_> { fn default() -> Self { Self { data: FontData::default_table_data(), axis_count: Default::default(), instance_count: Default::default(), instance_size: Default::default(), } } } #[cfg(feature = "experimental_traverse")] impl<'a> SomeTable<'a> for AxisInstanceArrays<'a> { fn type_name(&self) -> &str { "AxisInstanceArrays" } fn get_field(&self, idx: usize) -> Option> { match idx { 0usize => Some(Field::new( "axes", traversal::FieldType::array_of_records( stringify!(VariationAxisRecord), self.axes(), self.offset_data(), ), )), 1usize => Some(Field::new( "instances", traversal::FieldType::computed_array( "InstanceRecord", self.instances(), self.offset_data(), ), )), _ => None, } } } #[cfg(feature = "experimental_traverse")] #[allow(clippy::needless_lifetimes)] impl<'a> std::fmt::Debug for AxisInstanceArrays<'a> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { (self as &dyn SomeTable<'a>).fmt(f) } } /// The [VariationAxisRecord](https://learn.microsoft.com/en-us/typography/opentype/spec/fvar#variationaxisrecord) #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)] #[repr(C)] #[repr(packed)] pub struct VariationAxisRecord { /// Tag identifying the design variation for the axis. pub axis_tag: BigEndian, /// The minimum coordinate value for the axis. pub min_value: BigEndian, /// The default coordinate value for the axis. pub default_value: BigEndian, /// The maximum coordinate value for the axis. pub max_value: BigEndian, /// Axis qualifiers — see details below. pub flags: BigEndian, /// The name ID for entries in the 'name' table that provide a display name for this axis. pub axis_name_id: BigEndian, } impl VariationAxisRecord { /// Tag identifying the design variation for the axis. pub fn axis_tag(&self) -> Tag { self.axis_tag.get() } /// The minimum coordinate value for the axis. pub fn min_value(&self) -> Fixed { self.min_value.get() } /// The default coordinate value for the axis. pub fn default_value(&self) -> Fixed { self.default_value.get() } /// The maximum coordinate value for the axis. pub fn max_value(&self) -> Fixed { self.max_value.get() } /// Axis qualifiers — see details below. pub fn flags(&self) -> u16 { self.flags.get() } /// The name ID for entries in the 'name' table that provide a display name for this axis. pub fn axis_name_id(&self) -> NameId { self.axis_name_id.get() } } impl FixedSize for VariationAxisRecord { const RAW_BYTE_LEN: usize = Tag::RAW_BYTE_LEN + Fixed::RAW_BYTE_LEN + Fixed::RAW_BYTE_LEN + Fixed::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + NameId::RAW_BYTE_LEN; } #[cfg(feature = "experimental_traverse")] impl<'a> SomeRecord<'a> for VariationAxisRecord { fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { RecordResolver { name: "VariationAxisRecord", get_field: Box::new(move |idx, _data| match idx { 0usize => Some(Field::new("axis_tag", self.axis_tag())), 1usize => Some(Field::new("min_value", self.min_value())), 2usize => Some(Field::new("default_value", self.default_value())), 3usize => Some(Field::new("max_value", self.max_value())), 4usize => Some(Field::new("flags", self.flags())), 5usize => Some(Field::new("axis_name_id", self.axis_name_id())), _ => None, }), data, } } }