| // 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::*; |
| |
| /// An array of variable-sized objects in a `CFF` table. |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct Index1Marker { |
| offsets_byte_len: usize, |
| data_byte_len: usize, |
| } |
| |
| impl Index1Marker { |
| pub fn count_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + u16::RAW_BYTE_LEN |
| } |
| |
| pub fn off_size_byte_range(&self) -> Range<usize> { |
| let start = self.count_byte_range().end; |
| start..start + u8::RAW_BYTE_LEN |
| } |
| |
| pub fn offsets_byte_range(&self) -> Range<usize> { |
| let start = self.off_size_byte_range().end; |
| start..start + self.offsets_byte_len |
| } |
| |
| pub fn data_byte_range(&self) -> Range<usize> { |
| let start = self.offsets_byte_range().end; |
| start..start + self.data_byte_len |
| } |
| } |
| |
| impl MinByteRange for Index1Marker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.data_byte_range().end |
| } |
| } |
| |
| impl<'a> FontRead<'a> for Index1<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| let count: u16 = cursor.read()?; |
| let off_size: u8 = cursor.read()?; |
| let offsets_byte_len = (transforms::add_multiply(count, 1_usize, off_size)) |
| .checked_mul(u8::RAW_BYTE_LEN) |
| .ok_or(ReadError::OutOfBounds)?; |
| cursor.advance_by(offsets_byte_len); |
| let data_byte_len = cursor.remaining_bytes() / u8::RAW_BYTE_LEN * u8::RAW_BYTE_LEN; |
| cursor.advance_by(data_byte_len); |
| cursor.finish(Index1Marker { |
| offsets_byte_len, |
| data_byte_len, |
| }) |
| } |
| } |
| |
| /// An array of variable-sized objects in a `CFF` table. |
| pub type Index1<'a> = TableRef<'a, Index1Marker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> Index1<'a> { |
| /// Number of objects stored in INDEX. |
| pub fn count(&self) -> u16 { |
| let range = self.shape.count_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Object array element size. |
| pub fn off_size(&self) -> u8 { |
| let range = self.shape.off_size_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Bytes containing `count + 1` offsets each of `off_size`. |
| pub fn offsets(&self) -> &'a [u8] { |
| let range = self.shape.offsets_byte_range(); |
| self.data.read_array(range).unwrap() |
| } |
| |
| /// Array containing the object data. |
| pub fn data(&self) -> &'a [u8] { |
| let range = self.shape.data_byte_range(); |
| self.data.read_array(range).unwrap() |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for Index1<'a> { |
| fn type_name(&self) -> &str { |
| "Index1" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new("count", self.count())), |
| 1usize => Some(Field::new("off_size", self.off_size())), |
| 2usize => Some(Field::new("offsets", self.offsets())), |
| 3usize => Some(Field::new("data", self.data())), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for Index1<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| /// An array of variable-sized objects in a `CFF2` table. |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct Index2Marker { |
| offsets_byte_len: usize, |
| data_byte_len: usize, |
| } |
| |
| impl Index2Marker { |
| pub fn count_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + u32::RAW_BYTE_LEN |
| } |
| |
| pub fn off_size_byte_range(&self) -> Range<usize> { |
| let start = self.count_byte_range().end; |
| start..start + u8::RAW_BYTE_LEN |
| } |
| |
| pub fn offsets_byte_range(&self) -> Range<usize> { |
| let start = self.off_size_byte_range().end; |
| start..start + self.offsets_byte_len |
| } |
| |
| pub fn data_byte_range(&self) -> Range<usize> { |
| let start = self.offsets_byte_range().end; |
| start..start + self.data_byte_len |
| } |
| } |
| |
| impl MinByteRange for Index2Marker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.data_byte_range().end |
| } |
| } |
| |
| impl<'a> FontRead<'a> for Index2<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| let count: u32 = cursor.read()?; |
| let off_size: u8 = cursor.read()?; |
| let offsets_byte_len = (transforms::add_multiply(count, 1_usize, off_size)) |
| .checked_mul(u8::RAW_BYTE_LEN) |
| .ok_or(ReadError::OutOfBounds)?; |
| cursor.advance_by(offsets_byte_len); |
| let data_byte_len = cursor.remaining_bytes() / u8::RAW_BYTE_LEN * u8::RAW_BYTE_LEN; |
| cursor.advance_by(data_byte_len); |
| cursor.finish(Index2Marker { |
| offsets_byte_len, |
| data_byte_len, |
| }) |
| } |
| } |
| |
| /// An array of variable-sized objects in a `CFF2` table. |
| pub type Index2<'a> = TableRef<'a, Index2Marker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> Index2<'a> { |
| /// Number of objects stored in INDEX. |
| pub fn count(&self) -> u32 { |
| let range = self.shape.count_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Object array element size. |
| pub fn off_size(&self) -> u8 { |
| let range = self.shape.off_size_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Bytes containing `count + 1` offsets each of `off_size`. |
| pub fn offsets(&self) -> &'a [u8] { |
| let range = self.shape.offsets_byte_range(); |
| self.data.read_array(range).unwrap() |
| } |
| |
| /// Array containing the object data. |
| pub fn data(&self) -> &'a [u8] { |
| let range = self.shape.data_byte_range(); |
| self.data.read_array(range).unwrap() |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for Index2<'a> { |
| fn type_name(&self) -> &str { |
| "Index2" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new("count", self.count())), |
| 1usize => Some(Field::new("off_size", self.off_size())), |
| 2usize => Some(Field::new("offsets", self.offsets())), |
| 3usize => Some(Field::new("data", self.data())), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for Index2<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| /// Associates a glyph identifier with a Font DICT. |
| #[derive(Clone)] |
| pub enum FdSelect<'a> { |
| Format0(FdSelectFormat0<'a>), |
| Format3(FdSelectFormat3<'a>), |
| Format4(FdSelectFormat4<'a>), |
| } |
| |
| impl<'a> FdSelect<'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::Format3(item) => item.offset_data(), |
| Self::Format4(item) => item.offset_data(), |
| } |
| } |
| |
| /// Format = 0. |
| pub fn format(&self) -> u8 { |
| match self { |
| Self::Format0(item) => item.format(), |
| Self::Format3(item) => item.format(), |
| Self::Format4(item) => item.format(), |
| } |
| } |
| } |
| |
| impl<'a> FontRead<'a> for FdSelect<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let format: u8 = data.read_at(0usize)?; |
| match format { |
| FdSelectFormat0Marker::FORMAT => Ok(Self::Format0(FontRead::read(data)?)), |
| FdSelectFormat3Marker::FORMAT => Ok(Self::Format3(FontRead::read(data)?)), |
| FdSelectFormat4Marker::FORMAT => Ok(Self::Format4(FontRead::read(data)?)), |
| other => Err(ReadError::InvalidFormat(other.into())), |
| } |
| } |
| } |
| |
| impl MinByteRange for FdSelect<'_> { |
| fn min_byte_range(&self) -> Range<usize> { |
| match self { |
| Self::Format0(item) => item.min_byte_range(), |
| Self::Format3(item) => item.min_byte_range(), |
| Self::Format4(item) => item.min_byte_range(), |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> FdSelect<'a> { |
| fn dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a> { |
| match self { |
| Self::Format0(table) => table, |
| Self::Format3(table) => table, |
| Self::Format4(table) => table, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl std::fmt::Debug for FdSelect<'_> { |
| 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 FdSelect<'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) |
| } |
| } |
| |
| impl Format<u8> for FdSelectFormat0Marker { |
| const FORMAT: u8 = 0; |
| } |
| |
| /// FdSelect format 0. |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct FdSelectFormat0Marker { |
| fds_byte_len: usize, |
| } |
| |
| impl FdSelectFormat0Marker { |
| pub fn format_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + u8::RAW_BYTE_LEN |
| } |
| |
| pub fn fds_byte_range(&self) -> Range<usize> { |
| let start = self.format_byte_range().end; |
| start..start + self.fds_byte_len |
| } |
| } |
| |
| impl MinByteRange for FdSelectFormat0Marker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.fds_byte_range().end |
| } |
| } |
| |
| impl<'a> FontRead<'a> for FdSelectFormat0<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| cursor.advance::<u8>(); |
| let fds_byte_len = cursor.remaining_bytes() / u8::RAW_BYTE_LEN * u8::RAW_BYTE_LEN; |
| cursor.advance_by(fds_byte_len); |
| cursor.finish(FdSelectFormat0Marker { fds_byte_len }) |
| } |
| } |
| |
| /// FdSelect format 0. |
| pub type FdSelectFormat0<'a> = TableRef<'a, FdSelectFormat0Marker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> FdSelectFormat0<'a> { |
| /// Format = 0. |
| pub fn format(&self) -> u8 { |
| let range = self.shape.format_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// FD selector array (one entry for each glyph). |
| pub fn fds(&self) -> &'a [u8] { |
| let range = self.shape.fds_byte_range(); |
| self.data.read_array(range).unwrap() |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for FdSelectFormat0<'a> { |
| fn type_name(&self) -> &str { |
| "FdSelectFormat0" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new("format", self.format())), |
| 1usize => Some(Field::new("fds", self.fds())), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for FdSelectFormat0<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| impl Format<u8> for FdSelectFormat3Marker { |
| const FORMAT: u8 = 3; |
| } |
| |
| /// FdSelect format 3. |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct FdSelectFormat3Marker { |
| ranges_byte_len: usize, |
| } |
| |
| impl FdSelectFormat3Marker { |
| pub fn format_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + u8::RAW_BYTE_LEN |
| } |
| |
| pub fn n_ranges_byte_range(&self) -> Range<usize> { |
| let start = self.format_byte_range().end; |
| start..start + u16::RAW_BYTE_LEN |
| } |
| |
| pub fn ranges_byte_range(&self) -> Range<usize> { |
| let start = self.n_ranges_byte_range().end; |
| start..start + self.ranges_byte_len |
| } |
| |
| pub fn sentinel_byte_range(&self) -> Range<usize> { |
| let start = self.ranges_byte_range().end; |
| start..start + u16::RAW_BYTE_LEN |
| } |
| } |
| |
| impl MinByteRange for FdSelectFormat3Marker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.sentinel_byte_range().end |
| } |
| } |
| |
| impl<'a> FontRead<'a> for FdSelectFormat3<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| cursor.advance::<u8>(); |
| let n_ranges: u16 = cursor.read()?; |
| let ranges_byte_len = (n_ranges as usize) |
| .checked_mul(FdSelectRange3::RAW_BYTE_LEN) |
| .ok_or(ReadError::OutOfBounds)?; |
| cursor.advance_by(ranges_byte_len); |
| cursor.advance::<u16>(); |
| cursor.finish(FdSelectFormat3Marker { ranges_byte_len }) |
| } |
| } |
| |
| /// FdSelect format 3. |
| pub type FdSelectFormat3<'a> = TableRef<'a, FdSelectFormat3Marker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> FdSelectFormat3<'a> { |
| /// Format = 3. |
| pub fn format(&self) -> u8 { |
| let range = self.shape.format_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Number of ranges. |
| pub fn n_ranges(&self) -> u16 { |
| let range = self.shape.n_ranges_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Range3 array. |
| pub fn ranges(&self) -> &'a [FdSelectRange3] { |
| let range = self.shape.ranges_byte_range(); |
| self.data.read_array(range).unwrap() |
| } |
| |
| /// Sentinel GID. Set equal to the number of glyphs in the font. |
| pub fn sentinel(&self) -> u16 { |
| let range = self.shape.sentinel_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for FdSelectFormat3<'a> { |
| fn type_name(&self) -> &str { |
| "FdSelectFormat3" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new("format", self.format())), |
| 1usize => Some(Field::new("n_ranges", self.n_ranges())), |
| 2usize => Some(Field::new( |
| "ranges", |
| traversal::FieldType::array_of_records( |
| stringify!(FdSelectRange3), |
| self.ranges(), |
| self.offset_data(), |
| ), |
| )), |
| 3usize => Some(Field::new("sentinel", self.sentinel())), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for FdSelectFormat3<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| /// Range struct for FdSelect format 3. |
| #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)] |
| #[repr(C)] |
| #[repr(packed)] |
| pub struct FdSelectRange3 { |
| /// First glyph index in range. |
| pub first: BigEndian<u16>, |
| /// FD index for all glyphs in range. |
| pub fd: u8, |
| } |
| |
| impl FdSelectRange3 { |
| /// First glyph index in range. |
| pub fn first(&self) -> u16 { |
| self.first.get() |
| } |
| |
| /// FD index for all glyphs in range. |
| pub fn fd(&self) -> u8 { |
| self.fd |
| } |
| } |
| |
| impl FixedSize for FdSelectRange3 { |
| const RAW_BYTE_LEN: usize = u16::RAW_BYTE_LEN + u8::RAW_BYTE_LEN; |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeRecord<'a> for FdSelectRange3 { |
| fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { |
| RecordResolver { |
| name: "FdSelectRange3", |
| get_field: Box::new(move |idx, _data| match idx { |
| 0usize => Some(Field::new("first", self.first())), |
| 1usize => Some(Field::new("fd", self.fd())), |
| _ => None, |
| }), |
| data, |
| } |
| } |
| } |
| |
| impl Format<u8> for FdSelectFormat4Marker { |
| const FORMAT: u8 = 4; |
| } |
| |
| /// FdSelect format 4. |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct FdSelectFormat4Marker { |
| ranges_byte_len: usize, |
| } |
| |
| impl FdSelectFormat4Marker { |
| pub fn format_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + u8::RAW_BYTE_LEN |
| } |
| |
| pub fn n_ranges_byte_range(&self) -> Range<usize> { |
| let start = self.format_byte_range().end; |
| start..start + u32::RAW_BYTE_LEN |
| } |
| |
| pub fn ranges_byte_range(&self) -> Range<usize> { |
| let start = self.n_ranges_byte_range().end; |
| start..start + self.ranges_byte_len |
| } |
| |
| pub fn sentinel_byte_range(&self) -> Range<usize> { |
| let start = self.ranges_byte_range().end; |
| start..start + u32::RAW_BYTE_LEN |
| } |
| } |
| |
| impl MinByteRange for FdSelectFormat4Marker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.sentinel_byte_range().end |
| } |
| } |
| |
| impl<'a> FontRead<'a> for FdSelectFormat4<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| cursor.advance::<u8>(); |
| let n_ranges: u32 = cursor.read()?; |
| let ranges_byte_len = (n_ranges as usize) |
| .checked_mul(FdSelectRange4::RAW_BYTE_LEN) |
| .ok_or(ReadError::OutOfBounds)?; |
| cursor.advance_by(ranges_byte_len); |
| cursor.advance::<u32>(); |
| cursor.finish(FdSelectFormat4Marker { ranges_byte_len }) |
| } |
| } |
| |
| /// FdSelect format 4. |
| pub type FdSelectFormat4<'a> = TableRef<'a, FdSelectFormat4Marker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> FdSelectFormat4<'a> { |
| /// Format = 4. |
| pub fn format(&self) -> u8 { |
| let range = self.shape.format_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Number of ranges. |
| pub fn n_ranges(&self) -> u32 { |
| let range = self.shape.n_ranges_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Range4 array. |
| pub fn ranges(&self) -> &'a [FdSelectRange4] { |
| let range = self.shape.ranges_byte_range(); |
| self.data.read_array(range).unwrap() |
| } |
| |
| /// Sentinel GID. Set equal to the number of glyphs in the font. |
| pub fn sentinel(&self) -> u32 { |
| let range = self.shape.sentinel_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for FdSelectFormat4<'a> { |
| fn type_name(&self) -> &str { |
| "FdSelectFormat4" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new("format", self.format())), |
| 1usize => Some(Field::new("n_ranges", self.n_ranges())), |
| 2usize => Some(Field::new( |
| "ranges", |
| traversal::FieldType::array_of_records( |
| stringify!(FdSelectRange4), |
| self.ranges(), |
| self.offset_data(), |
| ), |
| )), |
| 3usize => Some(Field::new("sentinel", self.sentinel())), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for FdSelectFormat4<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| /// Range struct for FdSelect format 4. |
| #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)] |
| #[repr(C)] |
| #[repr(packed)] |
| pub struct FdSelectRange4 { |
| /// First glyph index in range. |
| pub first: BigEndian<u32>, |
| /// FD index for all glyphs in range. |
| pub fd: BigEndian<u16>, |
| } |
| |
| impl FdSelectRange4 { |
| /// First glyph index in range. |
| pub fn first(&self) -> u32 { |
| self.first.get() |
| } |
| |
| /// FD index for all glyphs in range. |
| pub fn fd(&self) -> u16 { |
| self.fd.get() |
| } |
| } |
| |
| impl FixedSize for FdSelectRange4 { |
| const RAW_BYTE_LEN: usize = u32::RAW_BYTE_LEN + u16::RAW_BYTE_LEN; |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeRecord<'a> for FdSelectRange4 { |
| fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { |
| RecordResolver { |
| name: "FdSelectRange4", |
| get_field: Box::new(move |idx, _data| match idx { |
| 0usize => Some(Field::new("first", self.first())), |
| 1usize => Some(Field::new("fd", self.fd())), |
| _ => None, |
| }), |
| data, |
| } |
| } |
| } |
| |
| /// Charset with custom glyph id to string id mappings. |
| #[derive(Clone)] |
| pub enum CustomCharset<'a> { |
| Format0(CharsetFormat0<'a>), |
| Format1(CharsetFormat1<'a>), |
| Format2(CharsetFormat2<'a>), |
| } |
| |
| impl<'a> CustomCharset<'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(), |
| Self::Format2(item) => item.offset_data(), |
| } |
| } |
| |
| /// Format; =0 |
| pub fn format(&self) -> u8 { |
| match self { |
| Self::Format0(item) => item.format(), |
| Self::Format1(item) => item.format(), |
| Self::Format2(item) => item.format(), |
| } |
| } |
| } |
| |
| impl<'a> FontRead<'a> for CustomCharset<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let format: u8 = data.read_at(0usize)?; |
| match format { |
| CharsetFormat0Marker::FORMAT => Ok(Self::Format0(FontRead::read(data)?)), |
| CharsetFormat1Marker::FORMAT => Ok(Self::Format1(FontRead::read(data)?)), |
| CharsetFormat2Marker::FORMAT => Ok(Self::Format2(FontRead::read(data)?)), |
| other => Err(ReadError::InvalidFormat(other.into())), |
| } |
| } |
| } |
| |
| impl MinByteRange for CustomCharset<'_> { |
| fn min_byte_range(&self) -> Range<usize> { |
| match self { |
| Self::Format0(item) => item.min_byte_range(), |
| Self::Format1(item) => item.min_byte_range(), |
| Self::Format2(item) => item.min_byte_range(), |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> CustomCharset<'a> { |
| fn dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a> { |
| match self { |
| Self::Format0(table) => table, |
| Self::Format1(table) => table, |
| Self::Format2(table) => table, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl std::fmt::Debug for CustomCharset<'_> { |
| 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 CustomCharset<'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) |
| } |
| } |
| |
| impl Format<u8> for CharsetFormat0Marker { |
| const FORMAT: u8 = 0; |
| } |
| |
| /// Charset format 0. |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct CharsetFormat0Marker { |
| glyph_byte_len: usize, |
| } |
| |
| impl CharsetFormat0Marker { |
| pub fn format_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + u8::RAW_BYTE_LEN |
| } |
| |
| pub fn glyph_byte_range(&self) -> Range<usize> { |
| let start = self.format_byte_range().end; |
| start..start + self.glyph_byte_len |
| } |
| } |
| |
| impl MinByteRange for CharsetFormat0Marker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.glyph_byte_range().end |
| } |
| } |
| |
| impl<'a> FontRead<'a> for CharsetFormat0<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| cursor.advance::<u8>(); |
| let glyph_byte_len = cursor.remaining_bytes() / u16::RAW_BYTE_LEN * u16::RAW_BYTE_LEN; |
| cursor.advance_by(glyph_byte_len); |
| cursor.finish(CharsetFormat0Marker { glyph_byte_len }) |
| } |
| } |
| |
| /// Charset format 0. |
| pub type CharsetFormat0<'a> = TableRef<'a, CharsetFormat0Marker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> CharsetFormat0<'a> { |
| /// Format; =0 |
| pub fn format(&self) -> u8 { |
| let range = self.shape.format_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Glyph name array. |
| pub fn glyph(&self) -> &'a [BigEndian<u16>] { |
| let range = self.shape.glyph_byte_range(); |
| self.data.read_array(range).unwrap() |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for CharsetFormat0<'a> { |
| fn type_name(&self) -> &str { |
| "CharsetFormat0" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new("format", self.format())), |
| 1usize => Some(Field::new("glyph", self.glyph())), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for CharsetFormat0<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| impl Format<u8> for CharsetFormat1Marker { |
| const FORMAT: u8 = 1; |
| } |
| |
| /// Charset format 1. |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct CharsetFormat1Marker { |
| ranges_byte_len: usize, |
| } |
| |
| impl CharsetFormat1Marker { |
| pub fn format_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + u8::RAW_BYTE_LEN |
| } |
| |
| pub fn ranges_byte_range(&self) -> Range<usize> { |
| let start = self.format_byte_range().end; |
| start..start + self.ranges_byte_len |
| } |
| } |
| |
| impl MinByteRange for CharsetFormat1Marker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.ranges_byte_range().end |
| } |
| } |
| |
| impl<'a> FontRead<'a> for CharsetFormat1<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| cursor.advance::<u8>(); |
| let ranges_byte_len = |
| cursor.remaining_bytes() / CharsetRange1::RAW_BYTE_LEN * CharsetRange1::RAW_BYTE_LEN; |
| cursor.advance_by(ranges_byte_len); |
| cursor.finish(CharsetFormat1Marker { ranges_byte_len }) |
| } |
| } |
| |
| /// Charset format 1. |
| pub type CharsetFormat1<'a> = TableRef<'a, CharsetFormat1Marker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> CharsetFormat1<'a> { |
| /// Format; =1 |
| pub fn format(&self) -> u8 { |
| let range = self.shape.format_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Range1 array. |
| pub fn ranges(&self) -> &'a [CharsetRange1] { |
| let range = self.shape.ranges_byte_range(); |
| self.data.read_array(range).unwrap() |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for CharsetFormat1<'a> { |
| fn type_name(&self) -> &str { |
| "CharsetFormat1" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new("format", self.format())), |
| 1usize => Some(Field::new( |
| "ranges", |
| traversal::FieldType::array_of_records( |
| stringify!(CharsetRange1), |
| self.ranges(), |
| self.offset_data(), |
| ), |
| )), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for CharsetFormat1<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| /// Range struct for Charset format 1. |
| #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)] |
| #[repr(C)] |
| #[repr(packed)] |
| pub struct CharsetRange1 { |
| /// First glyph in range. |
| pub first: BigEndian<u16>, |
| /// Glyphs left in range (excluding first). |
| pub n_left: u8, |
| } |
| |
| impl CharsetRange1 { |
| /// First glyph in range. |
| pub fn first(&self) -> u16 { |
| self.first.get() |
| } |
| |
| /// Glyphs left in range (excluding first). |
| pub fn n_left(&self) -> u8 { |
| self.n_left |
| } |
| } |
| |
| impl FixedSize for CharsetRange1 { |
| const RAW_BYTE_LEN: usize = u16::RAW_BYTE_LEN + u8::RAW_BYTE_LEN; |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeRecord<'a> for CharsetRange1 { |
| fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { |
| RecordResolver { |
| name: "CharsetRange1", |
| get_field: Box::new(move |idx, _data| match idx { |
| 0usize => Some(Field::new("first", self.first())), |
| 1usize => Some(Field::new("n_left", self.n_left())), |
| _ => None, |
| }), |
| data, |
| } |
| } |
| } |
| |
| impl Format<u8> for CharsetFormat2Marker { |
| const FORMAT: u8 = 2; |
| } |
| |
| /// Charset format 2. |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct CharsetFormat2Marker { |
| ranges_byte_len: usize, |
| } |
| |
| impl CharsetFormat2Marker { |
| pub fn format_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + u8::RAW_BYTE_LEN |
| } |
| |
| pub fn ranges_byte_range(&self) -> Range<usize> { |
| let start = self.format_byte_range().end; |
| start..start + self.ranges_byte_len |
| } |
| } |
| |
| impl MinByteRange for CharsetFormat2Marker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.ranges_byte_range().end |
| } |
| } |
| |
| impl<'a> FontRead<'a> for CharsetFormat2<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| cursor.advance::<u8>(); |
| let ranges_byte_len = |
| cursor.remaining_bytes() / CharsetRange2::RAW_BYTE_LEN * CharsetRange2::RAW_BYTE_LEN; |
| cursor.advance_by(ranges_byte_len); |
| cursor.finish(CharsetFormat2Marker { ranges_byte_len }) |
| } |
| } |
| |
| /// Charset format 2. |
| pub type CharsetFormat2<'a> = TableRef<'a, CharsetFormat2Marker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> CharsetFormat2<'a> { |
| /// Format; =2 |
| pub fn format(&self) -> u8 { |
| let range = self.shape.format_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Range2 array. |
| pub fn ranges(&self) -> &'a [CharsetRange2] { |
| let range = self.shape.ranges_byte_range(); |
| self.data.read_array(range).unwrap() |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for CharsetFormat2<'a> { |
| fn type_name(&self) -> &str { |
| "CharsetFormat2" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new("format", self.format())), |
| 1usize => Some(Field::new( |
| "ranges", |
| traversal::FieldType::array_of_records( |
| stringify!(CharsetRange2), |
| self.ranges(), |
| self.offset_data(), |
| ), |
| )), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for CharsetFormat2<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| /// Range struct for Charset format 2. |
| #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)] |
| #[repr(C)] |
| #[repr(packed)] |
| pub struct CharsetRange2 { |
| /// First glyph in range. |
| pub first: BigEndian<u16>, |
| /// Glyphs left in range (excluding first). |
| pub n_left: BigEndian<u16>, |
| } |
| |
| impl CharsetRange2 { |
| /// First glyph in range. |
| pub fn first(&self) -> u16 { |
| self.first.get() |
| } |
| |
| /// Glyphs left in range (excluding first). |
| pub fn n_left(&self) -> u16 { |
| self.n_left.get() |
| } |
| } |
| |
| impl FixedSize for CharsetRange2 { |
| const RAW_BYTE_LEN: usize = u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN; |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeRecord<'a> for CharsetRange2 { |
| fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { |
| RecordResolver { |
| name: "CharsetRange2", |
| get_field: Box::new(move |idx, _data| match idx { |
| 0usize => Some(Field::new("first", self.first())), |
| 1usize => Some(Field::new("n_left", self.n_left())), |
| _ => None, |
| }), |
| data, |
| } |
| } |
| } |