// 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::*; /// The [feature name](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6feat.html) table. #[derive(Debug, Clone, Copy)] #[doc(hidden)] pub struct FeatMarker { names_byte_len: usize, } impl FeatMarker { pub fn version_byte_range(&self) -> Range { let start = 0; start..start + MajorMinor::RAW_BYTE_LEN } pub fn feature_name_count_byte_range(&self) -> Range { let start = self.version_byte_range().end; start..start + u16::RAW_BYTE_LEN } pub fn _reserved1_byte_range(&self) -> Range { let start = self.feature_name_count_byte_range().end; start..start + u16::RAW_BYTE_LEN } pub fn _reserved2_byte_range(&self) -> Range { let start = self._reserved1_byte_range().end; start..start + u32::RAW_BYTE_LEN } pub fn names_byte_range(&self) -> Range { let start = self._reserved2_byte_range().end; start..start + self.names_byte_len } } impl MinByteRange for FeatMarker { fn min_byte_range(&self) -> Range { 0..self.names_byte_range().end } } impl TopLevelTable for Feat<'_> { /// `feat` const TAG: Tag = Tag::new(b"feat"); } impl<'a> FontRead<'a> for Feat<'a> { fn read(data: FontData<'a>) -> Result { let mut cursor = data.cursor(); cursor.advance::(); let feature_name_count: u16 = cursor.read()?; cursor.advance::(); cursor.advance::(); let names_byte_len = (feature_name_count as usize) .checked_mul(FeatureName::RAW_BYTE_LEN) .ok_or(ReadError::OutOfBounds)?; cursor.advance_by(names_byte_len); cursor.finish(FeatMarker { names_byte_len }) } } /// The [feature name](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6feat.html) table. pub type Feat<'a> = TableRef<'a, FeatMarker>; #[allow(clippy::needless_lifetimes)] impl<'a> Feat<'a> { /// Version number of the feature name table (0x00010000 for the current /// version). pub fn version(&self) -> MajorMinor { let range = self.shape.version_byte_range(); self.data.read_at(range.start).unwrap() } /// The number of entries in the feature name array. pub fn feature_name_count(&self) -> u16 { let range = self.shape.feature_name_count_byte_range(); self.data.read_at(range.start).unwrap() } /// The feature name array, sorted by feature type. pub fn names(&self) -> &'a [FeatureName] { let range = self.shape.names_byte_range(); self.data.read_array(range).unwrap() } } #[cfg(feature = "experimental_traverse")] impl<'a> SomeTable<'a> for Feat<'a> { fn type_name(&self) -> &str { "Feat" } fn get_field(&self, idx: usize) -> Option> { match idx { 0usize => Some(Field::new("version", self.version())), 1usize => Some(Field::new("feature_name_count", self.feature_name_count())), 2usize => Some(Field::new( "names", traversal::FieldType::array_of_records( stringify!(FeatureName), self.names(), self.offset_data(), ), )), _ => None, } } } #[cfg(feature = "experimental_traverse")] #[allow(clippy::needless_lifetimes)] impl<'a> std::fmt::Debug for Feat<'a> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { (self as &dyn SomeTable<'a>).fmt(f) } } /// Type, flags and names for a feature. #[derive(Clone, Debug, Copy, bytemuck :: AnyBitPattern)] #[repr(C)] #[repr(packed)] pub struct FeatureName { /// Feature type. pub feature: BigEndian, /// The number of records in the setting name array. pub n_settings: BigEndian, /// Offset in bytes from the beginning of this table to this feature's /// setting name array. The actual type of record this offset refers /// to will depend on the exclusivity value, as described below. pub setting_table_offset: BigEndian, /// Flags associated with the feature type. pub feature_flags: BigEndian, /// The name table index for the feature's name. pub name_index: BigEndian, } impl FeatureName { /// Feature type. pub fn feature(&self) -> u16 { self.feature.get() } /// The number of records in the setting name array. pub fn n_settings(&self) -> u16 { self.n_settings.get() } /// Offset in bytes from the beginning of this table to this feature's /// setting name array. The actual type of record this offset refers /// to will depend on the exclusivity value, as described below. pub fn setting_table_offset(&self) -> Offset32 { self.setting_table_offset.get() } /// Offset in bytes from the beginning of this table to this feature's /// setting name array. The actual type of record this offset refers /// to will depend on the exclusivity value, as described below. /// /// The `data` argument should be retrieved from the parent table /// By calling its `offset_data` method. pub fn setting_table<'a>(&self, data: FontData<'a>) -> Result, ReadError> { let args = self.n_settings(); self.setting_table_offset().resolve_with_args(data, &args) } /// Flags associated with the feature type. pub fn feature_flags(&self) -> u16 { self.feature_flags.get() } /// The name table index for the feature's name. pub fn name_index(&self) -> NameId { self.name_index.get() } } impl FixedSize for FeatureName { const RAW_BYTE_LEN: usize = u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + Offset32::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + NameId::RAW_BYTE_LEN; } #[cfg(feature = "experimental_traverse")] impl<'a> SomeRecord<'a> for FeatureName { fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { RecordResolver { name: "FeatureName", get_field: Box::new(move |idx, _data| match idx { 0usize => Some(Field::new("feature", self.feature())), 1usize => Some(Field::new("n_settings", self.n_settings())), 2usize => Some(Field::new( "setting_table_offset", FieldType::offset(self.setting_table_offset(), self.setting_table(_data)), )), 3usize => Some(Field::new("feature_flags", self.feature_flags())), 4usize => Some(Field::new("name_index", self.name_index())), _ => None, }), data, } } } #[derive(Debug, Clone, Copy)] #[doc(hidden)] pub struct SettingNameArrayMarker { settings_byte_len: usize, } impl SettingNameArrayMarker { pub fn settings_byte_range(&self) -> Range { let start = 0; start..start + self.settings_byte_len } } impl MinByteRange for SettingNameArrayMarker { fn min_byte_range(&self) -> Range { 0..self.settings_byte_range().end } } impl ReadArgs for SettingNameArray<'_> { type Args = u16; } impl<'a> FontReadWithArgs<'a> for SettingNameArray<'a> { fn read_with_args(data: FontData<'a>, args: &u16) -> Result { let n_settings = *args; let mut cursor = data.cursor(); let settings_byte_len = (n_settings as usize) .checked_mul(SettingName::RAW_BYTE_LEN) .ok_or(ReadError::OutOfBounds)?; cursor.advance_by(settings_byte_len); cursor.finish(SettingNameArrayMarker { settings_byte_len }) } } impl<'a> SettingNameArray<'a> { /// A constructor that requires additional arguments. /// /// This type requires some external state in order to be /// parsed. pub fn read(data: FontData<'a>, n_settings: u16) -> Result { let args = n_settings; Self::read_with_args(data, &args) } } pub type SettingNameArray<'a> = TableRef<'a, SettingNameArrayMarker>; #[allow(clippy::needless_lifetimes)] impl<'a> SettingNameArray<'a> { /// List of setting names for a feature. pub fn settings(&self) -> &'a [SettingName] { let range = self.shape.settings_byte_range(); self.data.read_array(range).unwrap() } } #[cfg(feature = "experimental_traverse")] impl<'a> SomeTable<'a> for SettingNameArray<'a> { fn type_name(&self) -> &str { "SettingNameArray" } fn get_field(&self, idx: usize) -> Option> { match idx { 0usize => Some(Field::new( "settings", traversal::FieldType::array_of_records( stringify!(SettingName), self.settings(), self.offset_data(), ), )), _ => None, } } } #[cfg(feature = "experimental_traverse")] #[allow(clippy::needless_lifetimes)] impl<'a> std::fmt::Debug for SettingNameArray<'a> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { (self as &dyn SomeTable<'a>).fmt(f) } } /// Associates a setting with a name identifier. #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)] #[repr(C)] #[repr(packed)] pub struct SettingName { /// The setting. pub setting: BigEndian, /// The name table index for the setting's name. pub name_index: BigEndian, } impl SettingName { /// The setting. pub fn setting(&self) -> u16 { self.setting.get() } /// The name table index for the setting's name. pub fn name_index(&self) -> NameId { self.name_index.get() } } impl FixedSize for SettingName { const RAW_BYTE_LEN: usize = u16::RAW_BYTE_LEN + NameId::RAW_BYTE_LEN; } #[cfg(feature = "experimental_traverse")] impl<'a> SomeRecord<'a> for SettingName { fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { RecordResolver { name: "SettingName", get_field: Box::new(move |idx, _data| match idx { 0usize => Some(Field::new("setting", self.setting())), 1usize => Some(Field::new("name_index", self.name_index())), _ => None, }), data, } } }