| // 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<usize> { |
| let start = 0; |
| start..start + MajorMinor::RAW_BYTE_LEN |
| } |
| |
| pub fn feature_name_count_byte_range(&self) -> Range<usize> { |
| let start = self.version_byte_range().end; |
| start..start + u16::RAW_BYTE_LEN |
| } |
| |
| pub fn _reserved1_byte_range(&self) -> Range<usize> { |
| let start = self.feature_name_count_byte_range().end; |
| start..start + u16::RAW_BYTE_LEN |
| } |
| |
| pub fn _reserved2_byte_range(&self) -> Range<usize> { |
| let start = self._reserved1_byte_range().end; |
| start..start + u32::RAW_BYTE_LEN |
| } |
| |
| pub fn names_byte_range(&self) -> Range<usize> { |
| let start = self._reserved2_byte_range().end; |
| start..start + self.names_byte_len |
| } |
| } |
| |
| impl MinByteRange for FeatMarker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 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<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| cursor.advance::<MajorMinor>(); |
| let feature_name_count: u16 = cursor.read()?; |
| cursor.advance::<u16>(); |
| cursor.advance::<u32>(); |
| 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<Field<'a>> { |
| 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<u16>, |
| /// The number of records in the setting name array. |
| pub n_settings: BigEndian<u16>, |
| /// 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<Offset32>, |
| /// Flags associated with the feature type. |
| pub feature_flags: BigEndian<u16>, |
| /// The name table index for the feature's name. |
| pub name_index: BigEndian<NameId>, |
| } |
| |
| 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<SettingNameArray<'a>, 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<usize> { |
| let start = 0; |
| start..start + self.settings_byte_len |
| } |
| } |
| |
| impl MinByteRange for SettingNameArrayMarker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 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<Self, ReadError> { |
| 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<Self, ReadError> { |
| 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<Field<'a>> { |
| 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<u16>, |
| /// The name table index for the setting's name. |
| pub name_index: BigEndian<NameId>, |
| } |
| |
| 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, |
| } |
| } |
| } |