| // 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::*; |
| |
| /// [TupleVariationHeader](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#tuplevariationheader) |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct TupleVariationHeaderMarker { |
| peak_tuple_byte_len: usize, |
| intermediate_start_tuple_byte_len: usize, |
| intermediate_end_tuple_byte_len: usize, |
| } |
| |
| impl TupleVariationHeaderMarker { |
| pub fn variation_data_size_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + u16::RAW_BYTE_LEN |
| } |
| |
| pub fn tuple_index_byte_range(&self) -> Range<usize> { |
| let start = self.variation_data_size_byte_range().end; |
| start..start + TupleIndex::RAW_BYTE_LEN |
| } |
| |
| pub fn peak_tuple_byte_range(&self) -> Range<usize> { |
| let start = self.tuple_index_byte_range().end; |
| start..start + self.peak_tuple_byte_len |
| } |
| |
| pub fn intermediate_start_tuple_byte_range(&self) -> Range<usize> { |
| let start = self.peak_tuple_byte_range().end; |
| start..start + self.intermediate_start_tuple_byte_len |
| } |
| |
| pub fn intermediate_end_tuple_byte_range(&self) -> Range<usize> { |
| let start = self.intermediate_start_tuple_byte_range().end; |
| start..start + self.intermediate_end_tuple_byte_len |
| } |
| } |
| |
| impl MinByteRange for TupleVariationHeaderMarker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.intermediate_end_tuple_byte_range().end |
| } |
| } |
| |
| impl ReadArgs for TupleVariationHeader<'_> { |
| type Args = u16; |
| } |
| |
| impl<'a> FontReadWithArgs<'a> for TupleVariationHeader<'a> { |
| fn read_with_args(data: FontData<'a>, args: &u16) -> Result<Self, ReadError> { |
| let axis_count = *args; |
| let mut cursor = data.cursor(); |
| cursor.advance::<u16>(); |
| let tuple_index: TupleIndex = cursor.read()?; |
| let peak_tuple_byte_len = (TupleIndex::tuple_len(tuple_index, axis_count, 0_usize)) |
| .checked_mul(F2Dot14::RAW_BYTE_LEN) |
| .ok_or(ReadError::OutOfBounds)?; |
| cursor.advance_by(peak_tuple_byte_len); |
| let intermediate_start_tuple_byte_len = |
| (TupleIndex::tuple_len(tuple_index, axis_count, 1_usize)) |
| .checked_mul(F2Dot14::RAW_BYTE_LEN) |
| .ok_or(ReadError::OutOfBounds)?; |
| cursor.advance_by(intermediate_start_tuple_byte_len); |
| let intermediate_end_tuple_byte_len = |
| (TupleIndex::tuple_len(tuple_index, axis_count, 1_usize)) |
| .checked_mul(F2Dot14::RAW_BYTE_LEN) |
| .ok_or(ReadError::OutOfBounds)?; |
| cursor.advance_by(intermediate_end_tuple_byte_len); |
| cursor.finish(TupleVariationHeaderMarker { |
| peak_tuple_byte_len, |
| intermediate_start_tuple_byte_len, |
| intermediate_end_tuple_byte_len, |
| }) |
| } |
| } |
| |
| impl<'a> TupleVariationHeader<'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) -> Result<Self, ReadError> { |
| let args = axis_count; |
| Self::read_with_args(data, &args) |
| } |
| } |
| |
| /// [TupleVariationHeader](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#tuplevariationheader) |
| pub type TupleVariationHeader<'a> = TableRef<'a, TupleVariationHeaderMarker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> TupleVariationHeader<'a> { |
| /// The size in bytes of the serialized data for this tuple |
| /// variation table. |
| pub fn variation_data_size(&self) -> u16 { |
| let range = self.shape.variation_data_size_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// A packed field. The high 4 bits are flags (see below). The low |
| /// 12 bits are an index into a shared tuple records array. |
| pub fn tuple_index(&self) -> TupleIndex { |
| let range = self.shape.tuple_index_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for TupleVariationHeader<'a> { |
| fn type_name(&self) -> &str { |
| "TupleVariationHeader" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new( |
| "variation_data_size", |
| self.variation_data_size(), |
| )), |
| 1usize => Some(Field::new("tuple_index", self.traverse_tuple_index())), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for TupleVariationHeader<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| /// A [Tuple Record](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#tuple-records) |
| /// |
| /// The tuple variation store formats reference regions within the font’s |
| /// variation space using tuple records. A tuple record identifies a position |
| /// in terms of normalized coordinates, which use F2DOT14 values. |
| #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| pub struct Tuple<'a> { |
| /// Coordinate array specifying a position within the font’s variation space. |
| /// |
| /// The number of elements must match the axisCount specified in the |
| /// 'fvar' table. |
| pub values: &'a [BigEndian<F2Dot14>], |
| } |
| |
| impl<'a> Tuple<'a> { |
| /// Coordinate array specifying a position within the font’s variation space. |
| /// |
| /// The number of elements must match the axisCount specified in the |
| /// 'fvar' table. |
| pub fn values(&self) -> &'a [BigEndian<F2Dot14>] { |
| self.values |
| } |
| } |
| |
| impl ReadArgs for Tuple<'_> { |
| type Args = u16; |
| } |
| |
| impl ComputeSize for Tuple<'_> { |
| #[allow(clippy::needless_question_mark)] |
| fn compute_size(args: &u16) -> Result<usize, ReadError> { |
| let axis_count = *args; |
| Ok((axis_count as usize) |
| .checked_mul(F2Dot14::RAW_BYTE_LEN) |
| .ok_or(ReadError::OutOfBounds)?) |
| } |
| } |
| |
| impl<'a> FontReadWithArgs<'a> for Tuple<'a> { |
| fn read_with_args(data: FontData<'a>, args: &u16) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| let axis_count = *args; |
| Ok(Self { |
| values: cursor.read_array(axis_count as usize)?, |
| }) |
| } |
| } |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> Tuple<'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) -> Result<Self, ReadError> { |
| let args = axis_count; |
| Self::read_with_args(data, &args) |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeRecord<'a> for Tuple<'a> { |
| fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { |
| RecordResolver { |
| name: "Tuple", |
| get_field: Box::new(move |idx, _data| match idx { |
| 0usize => Some(Field::new("values", self.values())), |
| _ => None, |
| }), |
| data, |
| } |
| } |
| } |
| |
| impl Format<u8> for DeltaSetIndexMapFormat0Marker { |
| const FORMAT: u8 = 0; |
| } |
| |
| /// The [DeltaSetIndexMap](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#associating-target-items-to-variation-data) table format 0 |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct DeltaSetIndexMapFormat0Marker { |
| map_data_byte_len: usize, |
| } |
| |
| impl DeltaSetIndexMapFormat0Marker { |
| pub fn format_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + u8::RAW_BYTE_LEN |
| } |
| |
| pub fn entry_format_byte_range(&self) -> Range<usize> { |
| let start = self.format_byte_range().end; |
| start..start + EntryFormat::RAW_BYTE_LEN |
| } |
| |
| pub fn map_count_byte_range(&self) -> Range<usize> { |
| let start = self.entry_format_byte_range().end; |
| start..start + u16::RAW_BYTE_LEN |
| } |
| |
| pub fn map_data_byte_range(&self) -> Range<usize> { |
| let start = self.map_count_byte_range().end; |
| start..start + self.map_data_byte_len |
| } |
| } |
| |
| impl MinByteRange for DeltaSetIndexMapFormat0Marker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.map_data_byte_range().end |
| } |
| } |
| |
| impl<'a> FontRead<'a> for DeltaSetIndexMapFormat0<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| cursor.advance::<u8>(); |
| let entry_format: EntryFormat = cursor.read()?; |
| let map_count: u16 = cursor.read()?; |
| let map_data_byte_len = (EntryFormat::map_size(entry_format, map_count)) |
| .checked_mul(u8::RAW_BYTE_LEN) |
| .ok_or(ReadError::OutOfBounds)?; |
| cursor.advance_by(map_data_byte_len); |
| cursor.finish(DeltaSetIndexMapFormat0Marker { map_data_byte_len }) |
| } |
| } |
| |
| /// The [DeltaSetIndexMap](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#associating-target-items-to-variation-data) table format 0 |
| pub type DeltaSetIndexMapFormat0<'a> = TableRef<'a, DeltaSetIndexMapFormat0Marker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> DeltaSetIndexMapFormat0<'a> { |
| /// DeltaSetIndexMap format: set to 0. |
| pub fn format(&self) -> u8 { |
| let range = self.shape.format_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// A packed field that describes the compressed representation of |
| /// delta-set indices. See details below. |
| pub fn entry_format(&self) -> EntryFormat { |
| let range = self.shape.entry_format_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// The number of mapping entries. |
| pub fn map_count(&self) -> u16 { |
| let range = self.shape.map_count_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// The delta-set index mapping data. See details below. |
| pub fn map_data(&self) -> &'a [u8] { |
| let range = self.shape.map_data_byte_range(); |
| self.data.read_array(range).unwrap() |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for DeltaSetIndexMapFormat0<'a> { |
| fn type_name(&self) -> &str { |
| "DeltaSetIndexMapFormat0" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new("format", self.format())), |
| 1usize => Some(Field::new("entry_format", self.entry_format())), |
| 2usize => Some(Field::new("map_count", self.map_count())), |
| 3usize => Some(Field::new("map_data", self.map_data())), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for DeltaSetIndexMapFormat0<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| impl Format<u8> for DeltaSetIndexMapFormat1Marker { |
| const FORMAT: u8 = 1; |
| } |
| |
| /// The [DeltaSetIndexMap](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#associating-target-items-to-variation-data) table format 1 |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct DeltaSetIndexMapFormat1Marker { |
| map_data_byte_len: usize, |
| } |
| |
| impl DeltaSetIndexMapFormat1Marker { |
| pub fn format_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + u8::RAW_BYTE_LEN |
| } |
| |
| pub fn entry_format_byte_range(&self) -> Range<usize> { |
| let start = self.format_byte_range().end; |
| start..start + EntryFormat::RAW_BYTE_LEN |
| } |
| |
| pub fn map_count_byte_range(&self) -> Range<usize> { |
| let start = self.entry_format_byte_range().end; |
| start..start + u32::RAW_BYTE_LEN |
| } |
| |
| pub fn map_data_byte_range(&self) -> Range<usize> { |
| let start = self.map_count_byte_range().end; |
| start..start + self.map_data_byte_len |
| } |
| } |
| |
| impl MinByteRange for DeltaSetIndexMapFormat1Marker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.map_data_byte_range().end |
| } |
| } |
| |
| impl<'a> FontRead<'a> for DeltaSetIndexMapFormat1<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| cursor.advance::<u8>(); |
| let entry_format: EntryFormat = cursor.read()?; |
| let map_count: u32 = cursor.read()?; |
| let map_data_byte_len = (EntryFormat::map_size(entry_format, map_count)) |
| .checked_mul(u8::RAW_BYTE_LEN) |
| .ok_or(ReadError::OutOfBounds)?; |
| cursor.advance_by(map_data_byte_len); |
| cursor.finish(DeltaSetIndexMapFormat1Marker { map_data_byte_len }) |
| } |
| } |
| |
| /// The [DeltaSetIndexMap](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#associating-target-items-to-variation-data) table format 1 |
| pub type DeltaSetIndexMapFormat1<'a> = TableRef<'a, DeltaSetIndexMapFormat1Marker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> DeltaSetIndexMapFormat1<'a> { |
| /// DeltaSetIndexMap format: set to 1. |
| pub fn format(&self) -> u8 { |
| let range = self.shape.format_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// A packed field that describes the compressed representation of |
| /// delta-set indices. See details below. |
| pub fn entry_format(&self) -> EntryFormat { |
| let range = self.shape.entry_format_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// The number of mapping entries. |
| pub fn map_count(&self) -> u32 { |
| let range = self.shape.map_count_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// The delta-set index mapping data. See details below. |
| pub fn map_data(&self) -> &'a [u8] { |
| let range = self.shape.map_data_byte_range(); |
| self.data.read_array(range).unwrap() |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for DeltaSetIndexMapFormat1<'a> { |
| fn type_name(&self) -> &str { |
| "DeltaSetIndexMapFormat1" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new("format", self.format())), |
| 1usize => Some(Field::new("entry_format", self.entry_format())), |
| 2usize => Some(Field::new("map_count", self.map_count())), |
| 3usize => Some(Field::new("map_data", self.map_data())), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for DeltaSetIndexMapFormat1<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| /// The [DeltaSetIndexMap](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#associating-target-items-to-variation-data) table |
| #[derive(Clone)] |
| pub enum DeltaSetIndexMap<'a> { |
| Format0(DeltaSetIndexMapFormat0<'a>), |
| Format1(DeltaSetIndexMapFormat1<'a>), |
| } |
| |
| impl<'a> DeltaSetIndexMap<'a> { |
| ///Return the `FontData` used to resolve offsets for this table. |
| pub fn offset_data(&self) -> FontData<'a> { |
| match self { |
| Self::Format0(item) => item.offset_data(), |
| Self::Format1(item) => item.offset_data(), |
| } |
| } |
| |
| /// DeltaSetIndexMap format: set to 0. |
| pub fn format(&self) -> u8 { |
| match self { |
| Self::Format0(item) => item.format(), |
| Self::Format1(item) => item.format(), |
| } |
| } |
| |
| /// A packed field that describes the compressed representation of |
| /// delta-set indices. See details below. |
| pub fn entry_format(&self) -> EntryFormat { |
| match self { |
| Self::Format0(item) => item.entry_format(), |
| Self::Format1(item) => item.entry_format(), |
| } |
| } |
| |
| /// The delta-set index mapping data. See details below. |
| pub fn map_data(&self) -> &'a [u8] { |
| match self { |
| Self::Format0(item) => item.map_data(), |
| Self::Format1(item) => item.map_data(), |
| } |
| } |
| } |
| |
| impl<'a> FontRead<'a> for DeltaSetIndexMap<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let format: u8 = data.read_at(0usize)?; |
| match format { |
| DeltaSetIndexMapFormat0Marker::FORMAT => Ok(Self::Format0(FontRead::read(data)?)), |
| DeltaSetIndexMapFormat1Marker::FORMAT => Ok(Self::Format1(FontRead::read(data)?)), |
| other => Err(ReadError::InvalidFormat(other.into())), |
| } |
| } |
| } |
| |
| impl MinByteRange for DeltaSetIndexMap<'_> { |
| fn min_byte_range(&self) -> Range<usize> { |
| match self { |
| Self::Format0(item) => item.min_byte_range(), |
| Self::Format1(item) => item.min_byte_range(), |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> DeltaSetIndexMap<'a> { |
| fn dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a> { |
| match self { |
| Self::Format0(table) => table, |
| Self::Format1(table) => table, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl std::fmt::Debug for DeltaSetIndexMap<'_> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| self.dyn_inner().fmt(f) |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for DeltaSetIndexMap<'a> { |
| fn type_name(&self) -> &str { |
| self.dyn_inner().type_name() |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| self.dyn_inner().get_field(idx) |
| } |
| } |
| |
| /// Entry format for a [DeltaSetIndexMap]. |
| #[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash, bytemuck :: AnyBitPattern)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| #[repr(transparent)] |
| pub struct EntryFormat { |
| bits: u8, |
| } |
| |
| impl EntryFormat { |
| /// Mask for the low 4 bits, which give the count of bits minus one that are used in each entry for the inner-level index. |
| pub const INNER_INDEX_BIT_COUNT_MASK: Self = Self { bits: 0x0F }; |
| |
| /// Mask for bits that indicate the size in bytes minus one of each entry. |
| pub const MAP_ENTRY_SIZE_MASK: Self = Self { bits: 0x30 }; |
| } |
| |
| impl EntryFormat { |
| /// Returns an empty set of flags. |
| #[inline] |
| pub const fn empty() -> Self { |
| Self { bits: 0 } |
| } |
| |
| /// Returns the set containing all flags. |
| #[inline] |
| pub const fn all() -> Self { |
| Self { |
| bits: Self::INNER_INDEX_BIT_COUNT_MASK.bits | Self::MAP_ENTRY_SIZE_MASK.bits, |
| } |
| } |
| |
| /// Returns the raw value of the flags currently stored. |
| #[inline] |
| pub const fn bits(&self) -> u8 { |
| self.bits |
| } |
| |
| /// Convert from underlying bit representation, unless that |
| /// representation contains bits that do not correspond to a flag. |
| #[inline] |
| pub const fn from_bits(bits: u8) -> Option<Self> { |
| if (bits & !Self::all().bits()) == 0 { |
| Some(Self { bits }) |
| } else { |
| None |
| } |
| } |
| |
| /// Convert from underlying bit representation, dropping any bits |
| /// that do not correspond to flags. |
| #[inline] |
| pub const fn from_bits_truncate(bits: u8) -> Self { |
| Self { |
| bits: bits & Self::all().bits, |
| } |
| } |
| |
| /// Returns `true` if no flags are currently stored. |
| #[inline] |
| pub const fn is_empty(&self) -> bool { |
| self.bits() == Self::empty().bits() |
| } |
| |
| /// Returns `true` if there are flags common to both `self` and `other`. |
| #[inline] |
| pub const fn intersects(&self, other: Self) -> bool { |
| !(Self { |
| bits: self.bits & other.bits, |
| }) |
| .is_empty() |
| } |
| |
| /// Returns `true` if all of the flags in `other` are contained within `self`. |
| #[inline] |
| pub const fn contains(&self, other: Self) -> bool { |
| (self.bits & other.bits) == other.bits |
| } |
| |
| /// Inserts the specified flags in-place. |
| #[inline] |
| pub fn insert(&mut self, other: Self) { |
| self.bits |= other.bits; |
| } |
| |
| /// Removes the specified flags in-place. |
| #[inline] |
| pub fn remove(&mut self, other: Self) { |
| self.bits &= !other.bits; |
| } |
| |
| /// Toggles the specified flags in-place. |
| #[inline] |
| pub fn toggle(&mut self, other: Self) { |
| self.bits ^= other.bits; |
| } |
| |
| /// Returns the intersection between the flags in `self` and |
| /// `other`. |
| /// |
| /// Specifically, the returned set contains only the flags which are |
| /// present in *both* `self` *and* `other`. |
| /// |
| /// This is equivalent to using the `&` operator (e.g. |
| /// [`ops::BitAnd`]), as in `flags & other`. |
| /// |
| /// [`ops::BitAnd`]: https://doc.rust-lang.org/std/ops/trait.BitAnd.html |
| #[inline] |
| #[must_use] |
| pub const fn intersection(self, other: Self) -> Self { |
| Self { |
| bits: self.bits & other.bits, |
| } |
| } |
| |
| /// Returns the union of between the flags in `self` and `other`. |
| /// |
| /// Specifically, the returned set contains all flags which are |
| /// present in *either* `self` *or* `other`, including any which are |
| /// present in both. |
| /// |
| /// This is equivalent to using the `|` operator (e.g. |
| /// [`ops::BitOr`]), as in `flags | other`. |
| /// |
| /// [`ops::BitOr`]: https://doc.rust-lang.org/std/ops/trait.BitOr.html |
| #[inline] |
| #[must_use] |
| pub const fn union(self, other: Self) -> Self { |
| Self { |
| bits: self.bits | other.bits, |
| } |
| } |
| |
| /// Returns the difference between the flags in `self` and `other`. |
| /// |
| /// Specifically, the returned set contains all flags present in |
| /// `self`, except for the ones present in `other`. |
| /// |
| /// It is also conceptually equivalent to the "bit-clear" operation: |
| /// `flags & !other` (and this syntax is also supported). |
| /// |
| /// This is equivalent to using the `-` operator (e.g. |
| /// [`ops::Sub`]), as in `flags - other`. |
| /// |
| /// [`ops::Sub`]: https://doc.rust-lang.org/std/ops/trait.Sub.html |
| #[inline] |
| #[must_use] |
| pub const fn difference(self, other: Self) -> Self { |
| Self { |
| bits: self.bits & !other.bits, |
| } |
| } |
| } |
| |
| impl std::ops::BitOr for EntryFormat { |
| type Output = Self; |
| |
| /// Returns the union of the two sets of flags. |
| #[inline] |
| fn bitor(self, other: EntryFormat) -> Self { |
| Self { |
| bits: self.bits | other.bits, |
| } |
| } |
| } |
| |
| impl std::ops::BitOrAssign for EntryFormat { |
| /// Adds the set of flags. |
| #[inline] |
| fn bitor_assign(&mut self, other: Self) { |
| self.bits |= other.bits; |
| } |
| } |
| |
| impl std::ops::BitXor for EntryFormat { |
| type Output = Self; |
| |
| /// Returns the left flags, but with all the right flags toggled. |
| #[inline] |
| fn bitxor(self, other: Self) -> Self { |
| Self { |
| bits: self.bits ^ other.bits, |
| } |
| } |
| } |
| |
| impl std::ops::BitXorAssign for EntryFormat { |
| /// Toggles the set of flags. |
| #[inline] |
| fn bitxor_assign(&mut self, other: Self) { |
| self.bits ^= other.bits; |
| } |
| } |
| |
| impl std::ops::BitAnd for EntryFormat { |
| type Output = Self; |
| |
| /// Returns the intersection between the two sets of flags. |
| #[inline] |
| fn bitand(self, other: Self) -> Self { |
| Self { |
| bits: self.bits & other.bits, |
| } |
| } |
| } |
| |
| impl std::ops::BitAndAssign for EntryFormat { |
| /// Disables all flags disabled in the set. |
| #[inline] |
| fn bitand_assign(&mut self, other: Self) { |
| self.bits &= other.bits; |
| } |
| } |
| |
| impl std::ops::Sub for EntryFormat { |
| type Output = Self; |
| |
| /// Returns the set difference of the two sets of flags. |
| #[inline] |
| fn sub(self, other: Self) -> Self { |
| Self { |
| bits: self.bits & !other.bits, |
| } |
| } |
| } |
| |
| impl std::ops::SubAssign for EntryFormat { |
| /// Disables all flags enabled in the set. |
| #[inline] |
| fn sub_assign(&mut self, other: Self) { |
| self.bits &= !other.bits; |
| } |
| } |
| |
| impl std::ops::Not for EntryFormat { |
| type Output = Self; |
| |
| /// Returns the complement of this set of flags. |
| #[inline] |
| fn not(self) -> Self { |
| Self { bits: !self.bits } & Self::all() |
| } |
| } |
| |
| impl std::fmt::Debug for EntryFormat { |
| fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { |
| let members: &[(&str, Self)] = &[ |
| ( |
| "INNER_INDEX_BIT_COUNT_MASK", |
| Self::INNER_INDEX_BIT_COUNT_MASK, |
| ), |
| ("MAP_ENTRY_SIZE_MASK", Self::MAP_ENTRY_SIZE_MASK), |
| ]; |
| let mut first = true; |
| for (name, value) in members { |
| if self.contains(*value) { |
| if !first { |
| f.write_str(" | ")?; |
| } |
| first = false; |
| f.write_str(name)?; |
| } |
| } |
| if first { |
| f.write_str("(empty)")?; |
| } |
| Ok(()) |
| } |
| } |
| |
| impl std::fmt::Binary for EntryFormat { |
| fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { |
| std::fmt::Binary::fmt(&self.bits, f) |
| } |
| } |
| |
| impl std::fmt::Octal for EntryFormat { |
| fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { |
| std::fmt::Octal::fmt(&self.bits, f) |
| } |
| } |
| |
| impl std::fmt::LowerHex for EntryFormat { |
| fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { |
| std::fmt::LowerHex::fmt(&self.bits, f) |
| } |
| } |
| |
| impl std::fmt::UpperHex for EntryFormat { |
| fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { |
| std::fmt::UpperHex::fmt(&self.bits, f) |
| } |
| } |
| |
| impl font_types::Scalar for EntryFormat { |
| type Raw = <u8 as font_types::Scalar>::Raw; |
| fn to_raw(self) -> Self::Raw { |
| self.bits().to_raw() |
| } |
| fn from_raw(raw: Self::Raw) -> Self { |
| let t = <u8>::from_raw(raw); |
| Self::from_bits_truncate(t) |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> From<EntryFormat> for FieldType<'a> { |
| fn from(src: EntryFormat) -> FieldType<'a> { |
| src.bits().into() |
| } |
| } |
| |
| /// The [VariationRegionList](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#variation-regions) table |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct VariationRegionListMarker { |
| variation_regions_byte_len: usize, |
| } |
| |
| impl VariationRegionListMarker { |
| pub fn axis_count_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + u16::RAW_BYTE_LEN |
| } |
| |
| pub fn region_count_byte_range(&self) -> Range<usize> { |
| let start = self.axis_count_byte_range().end; |
| start..start + u16::RAW_BYTE_LEN |
| } |
| |
| pub fn variation_regions_byte_range(&self) -> Range<usize> { |
| let start = self.region_count_byte_range().end; |
| start..start + self.variation_regions_byte_len |
| } |
| } |
| |
| impl MinByteRange for VariationRegionListMarker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.variation_regions_byte_range().end |
| } |
| } |
| |
| impl<'a> FontRead<'a> for VariationRegionList<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| let axis_count: u16 = cursor.read()?; |
| let region_count: u16 = cursor.read()?; |
| let variation_regions_byte_len = (region_count as usize) |
| .checked_mul(<VariationRegion as ComputeSize>::compute_size(&axis_count)?) |
| .ok_or(ReadError::OutOfBounds)?; |
| cursor.advance_by(variation_regions_byte_len); |
| cursor.finish(VariationRegionListMarker { |
| variation_regions_byte_len, |
| }) |
| } |
| } |
| |
| /// The [VariationRegionList](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#variation-regions) table |
| pub type VariationRegionList<'a> = TableRef<'a, VariationRegionListMarker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> VariationRegionList<'a> { |
| /// The number of variation axes for this font. This must be the |
| /// same number as axisCount in the 'fvar' table. |
| pub fn axis_count(&self) -> u16 { |
| let range = self.shape.axis_count_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// The number of variation region tables in the variation region |
| /// list. Must be less than 32,768. |
| pub fn region_count(&self) -> u16 { |
| let range = self.shape.region_count_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Array of variation regions. |
| pub fn variation_regions(&self) -> ComputedArray<'a, VariationRegion<'a>> { |
| let range = self.shape.variation_regions_byte_range(); |
| self.data.read_with_args(range, &self.axis_count()).unwrap() |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for VariationRegionList<'a> { |
| fn type_name(&self) -> &str { |
| "VariationRegionList" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new("axis_count", self.axis_count())), |
| 1usize => Some(Field::new("region_count", self.region_count())), |
| 2usize => Some(Field::new( |
| "variation_regions", |
| traversal::FieldType::computed_array( |
| "VariationRegion", |
| self.variation_regions(), |
| self.offset_data(), |
| ), |
| )), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for VariationRegionList<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| /// The [VariationRegion](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#variation-regions) record |
| #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| pub struct VariationRegion<'a> { |
| /// Array of region axis coordinates records, in the order of axes |
| /// given in the 'fvar' table. |
| pub region_axes: &'a [RegionAxisCoordinates], |
| } |
| |
| impl<'a> VariationRegion<'a> { |
| /// Array of region axis coordinates records, in the order of axes |
| /// given in the 'fvar' table. |
| pub fn region_axes(&self) -> &'a [RegionAxisCoordinates] { |
| self.region_axes |
| } |
| } |
| |
| impl ReadArgs for VariationRegion<'_> { |
| type Args = u16; |
| } |
| |
| impl ComputeSize for VariationRegion<'_> { |
| #[allow(clippy::needless_question_mark)] |
| fn compute_size(args: &u16) -> Result<usize, ReadError> { |
| let axis_count = *args; |
| Ok((axis_count as usize) |
| .checked_mul(RegionAxisCoordinates::RAW_BYTE_LEN) |
| .ok_or(ReadError::OutOfBounds)?) |
| } |
| } |
| |
| impl<'a> FontReadWithArgs<'a> for VariationRegion<'a> { |
| fn read_with_args(data: FontData<'a>, args: &u16) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| let axis_count = *args; |
| Ok(Self { |
| region_axes: cursor.read_array(axis_count as usize)?, |
| }) |
| } |
| } |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> VariationRegion<'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) -> Result<Self, ReadError> { |
| let args = axis_count; |
| Self::read_with_args(data, &args) |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeRecord<'a> for VariationRegion<'a> { |
| fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { |
| RecordResolver { |
| name: "VariationRegion", |
| get_field: Box::new(move |idx, _data| match idx { |
| 0usize => Some(Field::new( |
| "region_axes", |
| traversal::FieldType::array_of_records( |
| stringify!(RegionAxisCoordinates), |
| self.region_axes(), |
| _data, |
| ), |
| )), |
| _ => None, |
| }), |
| data, |
| } |
| } |
| } |
| |
| /// The [RegionAxisCoordinates](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#variation-regions) record |
| #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)] |
| #[repr(C)] |
| #[repr(packed)] |
| pub struct RegionAxisCoordinates { |
| /// The region start coordinate value for the current axis. |
| pub start_coord: BigEndian<F2Dot14>, |
| /// The region peak coordinate value for the current axis. |
| pub peak_coord: BigEndian<F2Dot14>, |
| /// The region end coordinate value for the current axis. |
| pub end_coord: BigEndian<F2Dot14>, |
| } |
| |
| impl RegionAxisCoordinates { |
| /// The region start coordinate value for the current axis. |
| pub fn start_coord(&self) -> F2Dot14 { |
| self.start_coord.get() |
| } |
| |
| /// The region peak coordinate value for the current axis. |
| pub fn peak_coord(&self) -> F2Dot14 { |
| self.peak_coord.get() |
| } |
| |
| /// The region end coordinate value for the current axis. |
| pub fn end_coord(&self) -> F2Dot14 { |
| self.end_coord.get() |
| } |
| } |
| |
| impl FixedSize for RegionAxisCoordinates { |
| const RAW_BYTE_LEN: usize = |
| F2Dot14::RAW_BYTE_LEN + F2Dot14::RAW_BYTE_LEN + F2Dot14::RAW_BYTE_LEN; |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeRecord<'a> for RegionAxisCoordinates { |
| fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { |
| RecordResolver { |
| name: "RegionAxisCoordinates", |
| get_field: Box::new(move |idx, _data| match idx { |
| 0usize => Some(Field::new("start_coord", self.start_coord())), |
| 1usize => Some(Field::new("peak_coord", self.peak_coord())), |
| 2usize => Some(Field::new("end_coord", self.end_coord())), |
| _ => None, |
| }), |
| data, |
| } |
| } |
| } |
| |
| /// The [ItemVariationStore](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#item-variation-store-header-and-item-variation-data-subtables) table |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct ItemVariationStoreMarker { |
| item_variation_data_offsets_byte_len: usize, |
| } |
| |
| impl ItemVariationStoreMarker { |
| pub fn format_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + u16::RAW_BYTE_LEN |
| } |
| |
| pub fn variation_region_list_offset_byte_range(&self) -> Range<usize> { |
| let start = self.format_byte_range().end; |
| start..start + Offset32::RAW_BYTE_LEN |
| } |
| |
| pub fn item_variation_data_count_byte_range(&self) -> Range<usize> { |
| let start = self.variation_region_list_offset_byte_range().end; |
| start..start + u16::RAW_BYTE_LEN |
| } |
| |
| pub fn item_variation_data_offsets_byte_range(&self) -> Range<usize> { |
| let start = self.item_variation_data_count_byte_range().end; |
| start..start + self.item_variation_data_offsets_byte_len |
| } |
| } |
| |
| impl MinByteRange for ItemVariationStoreMarker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.item_variation_data_offsets_byte_range().end |
| } |
| } |
| |
| impl<'a> FontRead<'a> for ItemVariationStore<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| cursor.advance::<u16>(); |
| cursor.advance::<Offset32>(); |
| let item_variation_data_count: u16 = cursor.read()?; |
| let item_variation_data_offsets_byte_len = (item_variation_data_count as usize) |
| .checked_mul(Offset32::RAW_BYTE_LEN) |
| .ok_or(ReadError::OutOfBounds)?; |
| cursor.advance_by(item_variation_data_offsets_byte_len); |
| cursor.finish(ItemVariationStoreMarker { |
| item_variation_data_offsets_byte_len, |
| }) |
| } |
| } |
| |
| /// The [ItemVariationStore](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#item-variation-store-header-and-item-variation-data-subtables) table |
| pub type ItemVariationStore<'a> = TableRef<'a, ItemVariationStoreMarker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> ItemVariationStore<'a> { |
| /// Format— set to 1 |
| pub fn format(&self) -> u16 { |
| let range = self.shape.format_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Offset in bytes from the start of the item variation store to |
| /// the variation region list. |
| pub fn variation_region_list_offset(&self) -> Offset32 { |
| let range = self.shape.variation_region_list_offset_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Attempt to resolve [`variation_region_list_offset`][Self::variation_region_list_offset]. |
| pub fn variation_region_list(&self) -> Result<VariationRegionList<'a>, ReadError> { |
| let data = self.data; |
| self.variation_region_list_offset().resolve(data) |
| } |
| |
| /// The number of item variation data subtables. |
| pub fn item_variation_data_count(&self) -> u16 { |
| let range = self.shape.item_variation_data_count_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Offsets in bytes from the start of the item variation store to |
| /// each item variation data subtable. |
| pub fn item_variation_data_offsets(&self) -> &'a [BigEndian<Nullable<Offset32>>] { |
| let range = self.shape.item_variation_data_offsets_byte_range(); |
| self.data.read_array(range).unwrap() |
| } |
| |
| /// A dynamically resolving wrapper for [`item_variation_data_offsets`][Self::item_variation_data_offsets]. |
| pub fn item_variation_data( |
| &self, |
| ) -> ArrayOfNullableOffsets<'a, ItemVariationData<'a>, Offset32> { |
| let data = self.data; |
| let offsets = self.item_variation_data_offsets(); |
| ArrayOfNullableOffsets::new(offsets, data, ()) |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for ItemVariationStore<'a> { |
| fn type_name(&self) -> &str { |
| "ItemVariationStore" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new("format", self.format())), |
| 1usize => Some(Field::new( |
| "variation_region_list_offset", |
| FieldType::offset( |
| self.variation_region_list_offset(), |
| self.variation_region_list(), |
| ), |
| )), |
| 2usize => Some(Field::new( |
| "item_variation_data_count", |
| self.item_variation_data_count(), |
| )), |
| 3usize => Some({ |
| let data = self.data; |
| Field::new( |
| "item_variation_data_offsets", |
| FieldType::array_of_offsets( |
| better_type_name::<ItemVariationData>(), |
| self.item_variation_data_offsets(), |
| move |off| { |
| let target = off.get().resolve::<ItemVariationData>(data); |
| FieldType::offset(off.get(), target) |
| }, |
| ), |
| ) |
| }), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for ItemVariationStore<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| /// The [ItemVariationData](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#item-variation-store-header-and-item-variation-data-subtables) subtable |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct ItemVariationDataMarker { |
| region_indexes_byte_len: usize, |
| delta_sets_byte_len: usize, |
| } |
| |
| impl ItemVariationDataMarker { |
| pub fn item_count_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + u16::RAW_BYTE_LEN |
| } |
| |
| pub fn word_delta_count_byte_range(&self) -> Range<usize> { |
| let start = self.item_count_byte_range().end; |
| start..start + u16::RAW_BYTE_LEN |
| } |
| |
| pub fn region_index_count_byte_range(&self) -> Range<usize> { |
| let start = self.word_delta_count_byte_range().end; |
| start..start + u16::RAW_BYTE_LEN |
| } |
| |
| pub fn region_indexes_byte_range(&self) -> Range<usize> { |
| let start = self.region_index_count_byte_range().end; |
| start..start + self.region_indexes_byte_len |
| } |
| |
| pub fn delta_sets_byte_range(&self) -> Range<usize> { |
| let start = self.region_indexes_byte_range().end; |
| start..start + self.delta_sets_byte_len |
| } |
| } |
| |
| impl MinByteRange for ItemVariationDataMarker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.delta_sets_byte_range().end |
| } |
| } |
| |
| impl<'a> FontRead<'a> for ItemVariationData<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| let item_count: u16 = cursor.read()?; |
| let word_delta_count: u16 = cursor.read()?; |
| let region_index_count: u16 = cursor.read()?; |
| let region_indexes_byte_len = (region_index_count as usize) |
| .checked_mul(u16::RAW_BYTE_LEN) |
| .ok_or(ReadError::OutOfBounds)?; |
| cursor.advance_by(region_indexes_byte_len); |
| let delta_sets_byte_len = |
| (ItemVariationData::delta_sets_len(item_count, word_delta_count, region_index_count)) |
| .checked_mul(u8::RAW_BYTE_LEN) |
| .ok_or(ReadError::OutOfBounds)?; |
| cursor.advance_by(delta_sets_byte_len); |
| cursor.finish(ItemVariationDataMarker { |
| region_indexes_byte_len, |
| delta_sets_byte_len, |
| }) |
| } |
| } |
| |
| /// The [ItemVariationData](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#item-variation-store-header-and-item-variation-data-subtables) subtable |
| pub type ItemVariationData<'a> = TableRef<'a, ItemVariationDataMarker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> ItemVariationData<'a> { |
| /// The number of delta sets for distinct items. |
| pub fn item_count(&self) -> u16 { |
| let range = self.shape.item_count_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// A packed field: the high bit is a flag—see details below. |
| pub fn word_delta_count(&self) -> u16 { |
| let range = self.shape.word_delta_count_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// The number of variation regions referenced. |
| pub fn region_index_count(&self) -> u16 { |
| let range = self.shape.region_index_count_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Array of indices into the variation region list for the regions |
| /// referenced by this item variation data table. |
| pub fn region_indexes(&self) -> &'a [BigEndian<u16>] { |
| let range = self.shape.region_indexes_byte_range(); |
| self.data.read_array(range).unwrap() |
| } |
| |
| /// Delta-set rows. |
| pub fn delta_sets(&self) -> &'a [u8] { |
| let range = self.shape.delta_sets_byte_range(); |
| self.data.read_array(range).unwrap() |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for ItemVariationData<'a> { |
| fn type_name(&self) -> &str { |
| "ItemVariationData" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new("item_count", self.item_count())), |
| 1usize => Some(Field::new("word_delta_count", self.word_delta_count())), |
| 2usize => Some(Field::new("region_index_count", self.region_index_count())), |
| 3usize => Some(Field::new("region_indexes", self.region_indexes())), |
| 4usize => Some(Field::new("delta_sets", self.delta_sets())), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for ItemVariationData<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |