// THIS FILE IS AUTOGENERATED. // Any changes to this file will be overwritten. // For more information about how codegen works, see font-codegen/README.md #[allow(unused_imports)] use crate::codegen_prelude::*; impl<'a> MinByteRange<'a> for CffHeader<'a> { fn min_byte_range(&self) -> Range { 0..self.trailing_data_byte_range().end } fn min_table_bytes(&self) -> &'a [u8] { let range = self.min_byte_range(); self.data.as_bytes().get(range).unwrap_or_default() } } impl<'a> FontRead<'a> for CffHeader<'a> { fn read(data: FontData<'a>) -> Result { #[allow(clippy::absurd_extreme_comparisons)] if data.len() < Self::MIN_SIZE { return Err(ReadError::OutOfBounds); } Ok(Self { data }) } } /// [Compact Font Format](https://learn.microsoft.com/en-us/typography/opentype/spec/cff) table header #[derive(Clone)] pub struct CffHeader<'a> { data: FontData<'a>, } #[allow(clippy::needless_lifetimes)] impl<'a> CffHeader<'a> { pub const MIN_SIZE: usize = (u8::RAW_BYTE_LEN + u8::RAW_BYTE_LEN + u8::RAW_BYTE_LEN + u8::RAW_BYTE_LEN); basic_table_impls!(impl_the_methods); /// Format major version (starting at 1). pub fn major(&self) -> u8 { let range = self.major_byte_range(); self.data.read_at(range.start).ok().unwrap() } /// Format minor version (starting at 0). pub fn minor(&self) -> u8 { let range = self.minor_byte_range(); self.data.read_at(range.start).ok().unwrap() } /// Header size (bytes). pub fn hdr_size(&self) -> u8 { let range = self.hdr_size_byte_range(); self.data.read_at(range.start).ok().unwrap() } /// Absolute offset size. pub fn off_size(&self) -> u8 { let range = self.off_size_byte_range(); self.data.read_at(range.start).ok().unwrap() } /// Padding bytes before the start of the Name INDEX. pub fn _padding(&self) -> &'a [u8] { let range = self._padding_byte_range(); self.data.read_array(range).ok().unwrap_or_default() } /// Remaining table data. pub fn trailing_data(&self) -> &'a [u8] { let range = self.trailing_data_byte_range(); self.data.read_array(range).ok().unwrap_or_default() } pub fn major_byte_range(&self) -> Range { let start = 0; let end = start + u8::RAW_BYTE_LEN; start..end } pub fn minor_byte_range(&self) -> Range { let start = self.major_byte_range().end; let end = start + u8::RAW_BYTE_LEN; start..end } pub fn hdr_size_byte_range(&self) -> Range { let start = self.minor_byte_range().end; let end = start + u8::RAW_BYTE_LEN; start..end } pub fn off_size_byte_range(&self) -> Range { let start = self.hdr_size_byte_range().end; let end = start + u8::RAW_BYTE_LEN; start..end } pub fn _padding_byte_range(&self) -> Range { let hdr_size = self.hdr_size(); let start = self.off_size_byte_range().end; let end = start + (transforms::subtract(hdr_size, 4_usize)).saturating_mul(u8::RAW_BYTE_LEN); start..end } pub fn trailing_data_byte_range(&self) -> Range { let start = self._padding_byte_range().end; let end = start + self.data.len().saturating_sub(start) / u8::RAW_BYTE_LEN * u8::RAW_BYTE_LEN; start..end } } const _: () = assert!(FontData::default_data_long_enough(CffHeader::MIN_SIZE)); impl Default for CffHeader<'_> { fn default() -> Self { Self { data: FontData::default_table_data(), } } } #[cfg(feature = "experimental_traverse")] impl<'a> SomeTable<'a> for CffHeader<'a> { fn type_name(&self) -> &str { "CffHeader" } fn get_field(&self, idx: usize) -> Option> { match idx { 0usize => Some(Field::new("major", self.major())), 1usize => Some(Field::new("minor", self.minor())), 2usize => Some(Field::new("hdr_size", self.hdr_size())), 3usize => Some(Field::new("off_size", self.off_size())), 4usize => Some(Field::new("_padding", self._padding())), 5usize => Some(Field::new("trailing_data", self.trailing_data())), _ => None, } } } #[cfg(feature = "experimental_traverse")] #[allow(clippy::needless_lifetimes)] impl<'a> std::fmt::Debug for CffHeader<'a> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { (self as &dyn SomeTable<'a>).fmt(f) } } impl<'a> MinByteRange<'a> for Index<'a> { fn min_byte_range(&self) -> Range { 0..self.data_byte_range().end } fn min_table_bytes(&self) -> &'a [u8] { let range = self.min_byte_range(); self.data.as_bytes().get(range).unwrap_or_default() } } impl<'a> FontRead<'a> for Index<'a> { fn read(data: FontData<'a>) -> Result { #[allow(clippy::absurd_extreme_comparisons)] if data.len() < Self::MIN_SIZE { return Err(ReadError::OutOfBounds); } Ok(Self { data }) } } /// An array of variable-sized objects in a `CFF` table. #[derive(Clone)] pub struct Index<'a> { data: FontData<'a>, } #[allow(clippy::needless_lifetimes)] impl<'a> Index<'a> { pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + u8::RAW_BYTE_LEN); basic_table_impls!(impl_the_methods); /// Number of objects stored in INDEX. pub fn count(&self) -> u16 { let range = self.count_byte_range(); self.data.read_at(range.start).ok().unwrap() } /// Object array element size. pub fn off_size(&self) -> u8 { let range = self.off_size_byte_range(); self.data.read_at(range.start).ok().unwrap() } /// Bytes containing `count + 1` offsets each of `off_size`. pub fn offsets(&self) -> &'a [u8] { let range = self.offsets_byte_range(); self.data.read_array(range).ok().unwrap_or_default() } /// Array containing the object data. pub fn data(&self) -> &'a [u8] { let range = self.data_byte_range(); self.data.read_array(range).ok().unwrap_or_default() } pub fn count_byte_range(&self) -> Range { let start = 0; let end = start + u16::RAW_BYTE_LEN; start..end } pub fn off_size_byte_range(&self) -> Range { let start = self.count_byte_range().end; let end = start + u8::RAW_BYTE_LEN; start..end } pub fn offsets_byte_range(&self) -> Range { let count = self.count(); let off_size = self.off_size(); let start = self.off_size_byte_range().end; let end = start + (transforms::add_multiply(count, 1_usize, off_size)).saturating_mul(u8::RAW_BYTE_LEN); start..end } pub fn data_byte_range(&self) -> Range { let start = self.offsets_byte_range().end; let end = start + self.data.len().saturating_sub(start) / u8::RAW_BYTE_LEN * u8::RAW_BYTE_LEN; start..end } } const _: () = assert!(FontData::default_data_long_enough(Index::MIN_SIZE)); impl Default for Index<'_> { fn default() -> Self { Self { data: FontData::default_table_data(), } } } #[cfg(feature = "experimental_traverse")] impl<'a> SomeTable<'a> for Index<'a> { fn type_name(&self) -> &str { "Index" } fn get_field(&self, idx: usize) -> Option> { 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 Index<'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 Default for FdSelect<'_> { fn default() -> Self { Self::Format0(Default::default()) } } 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 { let format: u8 = data.read_at(0usize)?; match format { FdSelectFormat0::FORMAT => Ok(Self::Format0(FontRead::read(data)?)), FdSelectFormat3::FORMAT => Ok(Self::Format3(FontRead::read(data)?)), FdSelectFormat4::FORMAT => Ok(Self::Format4(FontRead::read(data)?)), other => Err(ReadError::InvalidFormat(other.into())), } } } impl<'a> MinByteRange<'a> for FdSelect<'a> { fn min_byte_range(&self) -> Range { match self { Self::Format0(item) => item.min_byte_range(), Self::Format3(item) => item.min_byte_range(), Self::Format4(item) => item.min_byte_range(), } } fn min_table_bytes(&self) -> &'a [u8] { match self { Self::Format0(item) => item.min_table_bytes(), Self::Format3(item) => item.min_table_bytes(), Self::Format4(item) => item.min_table_bytes(), } } } #[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> { self.dyn_inner().get_field(idx) } } impl Format for FdSelectFormat0<'_> { const FORMAT: u8 = 0; } impl<'a> MinByteRange<'a> for FdSelectFormat0<'a> { fn min_byte_range(&self) -> Range { 0..self.fds_byte_range().end } fn min_table_bytes(&self) -> &'a [u8] { let range = self.min_byte_range(); self.data.as_bytes().get(range).unwrap_or_default() } } impl<'a> FontRead<'a> for FdSelectFormat0<'a> { fn read(data: FontData<'a>) -> Result { #[allow(clippy::absurd_extreme_comparisons)] if data.len() < Self::MIN_SIZE { return Err(ReadError::OutOfBounds); } Ok(Self { data }) } } /// FdSelect format 0. #[derive(Clone)] pub struct FdSelectFormat0<'a> { data: FontData<'a>, } #[allow(clippy::needless_lifetimes)] impl<'a> FdSelectFormat0<'a> { pub const MIN_SIZE: usize = u8::RAW_BYTE_LEN; basic_table_impls!(impl_the_methods); /// Format = 0. pub fn format(&self) -> u8 { let range = self.format_byte_range(); self.data.read_at(range.start).ok().unwrap() } /// FD selector array (one entry for each glyph). pub fn fds(&self) -> &'a [u8] { let range = self.fds_byte_range(); self.data.read_array(range).ok().unwrap_or_default() } pub fn format_byte_range(&self) -> Range { let start = 0; let end = start + u8::RAW_BYTE_LEN; start..end } pub fn fds_byte_range(&self) -> Range { let start = self.format_byte_range().end; let end = start + self.data.len().saturating_sub(start) / u8::RAW_BYTE_LEN * u8::RAW_BYTE_LEN; start..end } } const _: () = assert!(FontData::default_data_long_enough( FdSelectFormat0::MIN_SIZE )); impl Default for FdSelectFormat0<'_> { fn default() -> Self { Self { data: FontData::default_table_data(), } } } #[cfg(feature = "experimental_traverse")] impl<'a> SomeTable<'a> for FdSelectFormat0<'a> { fn type_name(&self) -> &str { "FdSelectFormat0" } fn get_field(&self, idx: usize) -> Option> { 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 for FdSelectFormat3<'_> { const FORMAT: u8 = 3; } impl<'a> MinByteRange<'a> for FdSelectFormat3<'a> { fn min_byte_range(&self) -> Range { 0..self.sentinel_byte_range().end } fn min_table_bytes(&self) -> &'a [u8] { let range = self.min_byte_range(); self.data.as_bytes().get(range).unwrap_or_default() } } impl<'a> FontRead<'a> for FdSelectFormat3<'a> { fn read(data: FontData<'a>) -> Result { #[allow(clippy::absurd_extreme_comparisons)] if data.len() < Self::MIN_SIZE { return Err(ReadError::OutOfBounds); } Ok(Self { data }) } } /// FdSelect format 3. #[derive(Clone)] pub struct FdSelectFormat3<'a> { data: FontData<'a>, } #[allow(clippy::needless_lifetimes)] impl<'a> FdSelectFormat3<'a> { pub const MIN_SIZE: usize = (u8::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN); basic_table_impls!(impl_the_methods); /// Format = 3. pub fn format(&self) -> u8 { let range = self.format_byte_range(); self.data.read_at(range.start).ok().unwrap() } /// Number of ranges. pub fn n_ranges(&self) -> u16 { let range = self.n_ranges_byte_range(); self.data.read_at(range.start).ok().unwrap() } /// Range3 array. pub fn ranges(&self) -> &'a [FdSelectRange3] { let range = self.ranges_byte_range(); self.data.read_array(range).ok().unwrap_or_default() } /// Sentinel GID. Set equal to the number of glyphs in the font. pub fn sentinel(&self) -> u16 { let range = self.sentinel_byte_range(); self.data.read_at(range.start).ok().unwrap_or_default() } pub fn format_byte_range(&self) -> Range { let start = 0; let end = start + u8::RAW_BYTE_LEN; start..end } pub fn n_ranges_byte_range(&self) -> Range { let start = self.format_byte_range().end; let end = start + u16::RAW_BYTE_LEN; start..end } pub fn ranges_byte_range(&self) -> Range { let n_ranges = self.n_ranges(); let start = self.n_ranges_byte_range().end; let end = start + (transforms::to_usize(n_ranges)).saturating_mul(FdSelectRange3::RAW_BYTE_LEN); start..end } pub fn sentinel_byte_range(&self) -> Range { let start = self.ranges_byte_range().end; let end = start + u16::RAW_BYTE_LEN; start..end } } #[cfg(feature = "experimental_traverse")] impl<'a> SomeTable<'a> for FdSelectFormat3<'a> { fn type_name(&self) -> &str { "FdSelectFormat3" } fn get_field(&self, idx: usize) -> Option> { 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, /// 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 for FdSelectFormat4<'_> { const FORMAT: u8 = 4; } impl<'a> MinByteRange<'a> for FdSelectFormat4<'a> { fn min_byte_range(&self) -> Range { 0..self.sentinel_byte_range().end } fn min_table_bytes(&self) -> &'a [u8] { let range = self.min_byte_range(); self.data.as_bytes().get(range).unwrap_or_default() } } impl<'a> FontRead<'a> for FdSelectFormat4<'a> { fn read(data: FontData<'a>) -> Result { #[allow(clippy::absurd_extreme_comparisons)] if data.len() < Self::MIN_SIZE { return Err(ReadError::OutOfBounds); } Ok(Self { data }) } } /// FdSelect format 4. #[derive(Clone)] pub struct FdSelectFormat4<'a> { data: FontData<'a>, } #[allow(clippy::needless_lifetimes)] impl<'a> FdSelectFormat4<'a> { pub const MIN_SIZE: usize = (u8::RAW_BYTE_LEN + u32::RAW_BYTE_LEN + u32::RAW_BYTE_LEN); basic_table_impls!(impl_the_methods); /// Format = 4. pub fn format(&self) -> u8 { let range = self.format_byte_range(); self.data.read_at(range.start).ok().unwrap() } /// Number of ranges. pub fn n_ranges(&self) -> u32 { let range = self.n_ranges_byte_range(); self.data.read_at(range.start).ok().unwrap() } /// Range4 array. pub fn ranges(&self) -> &'a [FdSelectRange4] { let range = self.ranges_byte_range(); self.data.read_array(range).ok().unwrap_or_default() } /// Sentinel GID. Set equal to the number of glyphs in the font. pub fn sentinel(&self) -> u32 { let range = self.sentinel_byte_range(); self.data.read_at(range.start).ok().unwrap_or_default() } pub fn format_byte_range(&self) -> Range { let start = 0; let end = start + u8::RAW_BYTE_LEN; start..end } pub fn n_ranges_byte_range(&self) -> Range { let start = self.format_byte_range().end; let end = start + u32::RAW_BYTE_LEN; start..end } pub fn ranges_byte_range(&self) -> Range { let n_ranges = self.n_ranges(); let start = self.n_ranges_byte_range().end; let end = start + (transforms::to_usize(n_ranges)).saturating_mul(FdSelectRange4::RAW_BYTE_LEN); start..end } pub fn sentinel_byte_range(&self) -> Range { let start = self.ranges_byte_range().end; let end = start + u32::RAW_BYTE_LEN; start..end } } #[cfg(feature = "experimental_traverse")] impl<'a> SomeTable<'a> for FdSelectFormat4<'a> { fn type_name(&self) -> &str { "FdSelectFormat4" } fn get_field(&self, idx: usize) -> Option> { 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, /// FD index for all glyphs in range. pub fd: BigEndian, } 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 Default for CustomCharset<'_> { fn default() -> Self { Self::Format0(Default::default()) } } 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 { let format: u8 = data.read_at(0usize)?; match format { CharsetFormat0::FORMAT => Ok(Self::Format0(FontRead::read(data)?)), CharsetFormat1::FORMAT => Ok(Self::Format1(FontRead::read(data)?)), CharsetFormat2::FORMAT => Ok(Self::Format2(FontRead::read(data)?)), other => Err(ReadError::InvalidFormat(other.into())), } } } impl<'a> MinByteRange<'a> for CustomCharset<'a> { fn min_byte_range(&self) -> Range { match self { Self::Format0(item) => item.min_byte_range(), Self::Format1(item) => item.min_byte_range(), Self::Format2(item) => item.min_byte_range(), } } fn min_table_bytes(&self) -> &'a [u8] { match self { Self::Format0(item) => item.min_table_bytes(), Self::Format1(item) => item.min_table_bytes(), Self::Format2(item) => item.min_table_bytes(), } } } #[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> { self.dyn_inner().get_field(idx) } } impl Format for CharsetFormat0<'_> { const FORMAT: u8 = 0; } impl<'a> MinByteRange<'a> for CharsetFormat0<'a> { fn min_byte_range(&self) -> Range { 0..self.glyph_byte_range().end } fn min_table_bytes(&self) -> &'a [u8] { let range = self.min_byte_range(); self.data.as_bytes().get(range).unwrap_or_default() } } impl<'a> FontRead<'a> for CharsetFormat0<'a> { fn read(data: FontData<'a>) -> Result { #[allow(clippy::absurd_extreme_comparisons)] if data.len() < Self::MIN_SIZE { return Err(ReadError::OutOfBounds); } Ok(Self { data }) } } /// Charset format 0. #[derive(Clone)] pub struct CharsetFormat0<'a> { data: FontData<'a>, } #[allow(clippy::needless_lifetimes)] impl<'a> CharsetFormat0<'a> { pub const MIN_SIZE: usize = u8::RAW_BYTE_LEN; basic_table_impls!(impl_the_methods); /// Format; =0 pub fn format(&self) -> u8 { let range = self.format_byte_range(); self.data.read_at(range.start).ok().unwrap() } /// Glyph name array. pub fn glyph(&self) -> &'a [BigEndian] { let range = self.glyph_byte_range(); self.data.read_array(range).ok().unwrap_or_default() } pub fn format_byte_range(&self) -> Range { let start = 0; let end = start + u8::RAW_BYTE_LEN; start..end } pub fn glyph_byte_range(&self) -> Range { let start = self.format_byte_range().end; let end = start + self.data.len().saturating_sub(start) / u16::RAW_BYTE_LEN * u16::RAW_BYTE_LEN; start..end } } const _: () = assert!(FontData::default_data_long_enough(CharsetFormat0::MIN_SIZE)); impl Default for CharsetFormat0<'_> { fn default() -> Self { Self { data: FontData::default_table_data(), } } } #[cfg(feature = "experimental_traverse")] impl<'a> SomeTable<'a> for CharsetFormat0<'a> { fn type_name(&self) -> &str { "CharsetFormat0" } fn get_field(&self, idx: usize) -> Option> { 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 for CharsetFormat1<'_> { const FORMAT: u8 = 1; } impl<'a> MinByteRange<'a> for CharsetFormat1<'a> { fn min_byte_range(&self) -> Range { 0..self.ranges_byte_range().end } fn min_table_bytes(&self) -> &'a [u8] { let range = self.min_byte_range(); self.data.as_bytes().get(range).unwrap_or_default() } } impl<'a> FontRead<'a> for CharsetFormat1<'a> { fn read(data: FontData<'a>) -> Result { #[allow(clippy::absurd_extreme_comparisons)] if data.len() < Self::MIN_SIZE { return Err(ReadError::OutOfBounds); } Ok(Self { data }) } } /// Charset format 1. #[derive(Clone)] pub struct CharsetFormat1<'a> { data: FontData<'a>, } #[allow(clippy::needless_lifetimes)] impl<'a> CharsetFormat1<'a> { pub const MIN_SIZE: usize = u8::RAW_BYTE_LEN; basic_table_impls!(impl_the_methods); /// Format; =1 pub fn format(&self) -> u8 { let range = self.format_byte_range(); self.data.read_at(range.start).ok().unwrap() } /// Range1 array. pub fn ranges(&self) -> &'a [CharsetRange1] { let range = self.ranges_byte_range(); self.data.read_array(range).ok().unwrap_or_default() } pub fn format_byte_range(&self) -> Range { let start = 0; let end = start + u8::RAW_BYTE_LEN; start..end } pub fn ranges_byte_range(&self) -> Range { let start = self.format_byte_range().end; let end = start + self.data.len().saturating_sub(start) / CharsetRange1::RAW_BYTE_LEN * CharsetRange1::RAW_BYTE_LEN; start..end } } const _: () = assert!(FontData::default_data_long_enough(CharsetFormat1::MIN_SIZE)); impl Default for CharsetFormat1<'_> { fn default() -> Self { Self { data: FontData::default_format_1_u8_table_data(), } } } #[cfg(feature = "experimental_traverse")] impl<'a> SomeTable<'a> for CharsetFormat1<'a> { fn type_name(&self) -> &str { "CharsetFormat1" } fn get_field(&self, idx: usize) -> Option> { 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, /// 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 for CharsetFormat2<'_> { const FORMAT: u8 = 2; } impl<'a> MinByteRange<'a> for CharsetFormat2<'a> { fn min_byte_range(&self) -> Range { 0..self.ranges_byte_range().end } fn min_table_bytes(&self) -> &'a [u8] { let range = self.min_byte_range(); self.data.as_bytes().get(range).unwrap_or_default() } } impl<'a> FontRead<'a> for CharsetFormat2<'a> { fn read(data: FontData<'a>) -> Result { #[allow(clippy::absurd_extreme_comparisons)] if data.len() < Self::MIN_SIZE { return Err(ReadError::OutOfBounds); } Ok(Self { data }) } } /// Charset format 2. #[derive(Clone)] pub struct CharsetFormat2<'a> { data: FontData<'a>, } #[allow(clippy::needless_lifetimes)] impl<'a> CharsetFormat2<'a> { pub const MIN_SIZE: usize = u8::RAW_BYTE_LEN; basic_table_impls!(impl_the_methods); /// Format; =2 pub fn format(&self) -> u8 { let range = self.format_byte_range(); self.data.read_at(range.start).ok().unwrap() } /// Range2 array. pub fn ranges(&self) -> &'a [CharsetRange2] { let range = self.ranges_byte_range(); self.data.read_array(range).ok().unwrap_or_default() } pub fn format_byte_range(&self) -> Range { let start = 0; let end = start + u8::RAW_BYTE_LEN; start..end } pub fn ranges_byte_range(&self) -> Range { let start = self.format_byte_range().end; let end = start + self.data.len().saturating_sub(start) / CharsetRange2::RAW_BYTE_LEN * CharsetRange2::RAW_BYTE_LEN; start..end } } #[cfg(feature = "experimental_traverse")] impl<'a> SomeTable<'a> for CharsetFormat2<'a> { fn type_name(&self) -> &str { "CharsetFormat2" } fn get_field(&self, idx: usize) -> Option> { 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, /// Glyphs left in range (excluding first). pub n_left: BigEndian, } 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, } } } /// Range struct for Encoding format 1. #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)] #[repr(C)] #[repr(packed)] pub struct EncodingRange1 { /// First code in range. pub first: u8, /// Codes left in range (excluding first). pub n_left: u8, } impl EncodingRange1 { /// First code in range. pub fn first(&self) -> u8 { self.first } /// Codes left in range (excluding first). pub fn n_left(&self) -> u8 { self.n_left } } impl FixedSize for EncodingRange1 { const RAW_BYTE_LEN: usize = u8::RAW_BYTE_LEN + u8::RAW_BYTE_LEN; } #[cfg(feature = "experimental_traverse")] impl<'a> SomeRecord<'a> for EncodingRange1 { fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { RecordResolver { name: "EncodingRange1", 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, } } } /// Supplemental encoding record. #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)] #[repr(C)] #[repr(packed)] pub struct EncodingSupplement { /// Encoding. pub code: u8, /// Name. pub glyph: BigEndian, } impl EncodingSupplement { /// Encoding. pub fn code(&self) -> u8 { self.code } /// Name. pub fn glyph(&self) -> u16 { self.glyph.get() } } impl FixedSize for EncodingSupplement { const RAW_BYTE_LEN: usize = u8::RAW_BYTE_LEN + u16::RAW_BYTE_LEN; } #[cfg(feature = "experimental_traverse")] impl<'a> SomeRecord<'a> for EncodingSupplement { fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { RecordResolver { name: "EncodingSupplement", get_field: Box::new(move |idx, _data| match idx { 0usize => Some(Field::new("code", self.code())), 1usize => Some(Field::new("glyph", self.glyph())), _ => None, }), data, } } }