// 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 Discriminant for MyLookup<'_, ()> { fn read_discriminant(data: FontData<'_>) -> Result { data.read_at(0) } } impl<'a, T> MinByteRange<'a> for MyLookup<'a, T> { fn min_byte_range(&self) -> Range { 0..self.subtable_offsets_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, T> FontRead<'a> for MyLookup<'a, T> { fn read(data: FontData<'a>) -> Result { #[allow(clippy::absurd_extreme_comparisons)] if data.len() < Self::MIN_SIZE { return Err(ReadError::OutOfBounds); } Ok(Self { data, offset_type: std::marker::PhantomData, }) } } impl<'a, T> MyLookup<'a, T> { #[allow(dead_code)] /// Replace the specific generic type on this implementation with `()` pub(crate) fn of_unit_type(&self) -> MyLookup<'a, ()> { MyLookup { data: self.data, offset_type: std::marker::PhantomData, } } } /// A generic table parameterized by the type of its subtable offsets. #[derive(Clone)] pub struct MyLookup<'a, T = ()> { data: FontData<'a>, offset_type: std::marker::PhantomData<*const T>, } #[allow(clippy::needless_lifetimes)] impl<'a, T> MyLookup<'a, T> { pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN); basic_table_impls!(impl_the_methods); /// Determines the concrete type of T pub fn lookup_type(&self) -> u16 { let range = self.lookup_type_byte_range(); self.data.read_at(range.start).ok().unwrap() } /// Number of subtables pub fn sub_table_count(&self) -> u16 { let range = self.sub_table_count_byte_range(); self.data.read_at(range.start).ok().unwrap() } /// Offsets to subtables, from beginning of this table pub fn subtable_offsets(&self) -> &'a [BigEndian] { let range = self.subtable_offsets_byte_range(); self.data.read_array(range).ok().unwrap_or_default() } /// A dynamically resolving wrapper for [`subtable_offsets`][Self::subtable_offsets]. pub fn subtables(&self) -> ArrayOfOffsets<'a, T, Offset16> where T: FontRead<'a>, { let data = self.data; let offsets = self.subtable_offsets(); ArrayOfOffsets::new(offsets, data, ()) } pub fn lookup_type_byte_range(&self) -> Range { let start = 0; let end = start + u16::RAW_BYTE_LEN; start..end } pub fn sub_table_count_byte_range(&self) -> Range { let start = self.lookup_type_byte_range().end; let end = start + u16::RAW_BYTE_LEN; start..end } pub fn subtable_offsets_byte_range(&self) -> Range { let sub_table_count = self.sub_table_count(); let start = self.sub_table_count_byte_range().end; let end = start + (transforms::to_usize(sub_table_count)).saturating_mul(Offset16::RAW_BYTE_LEN); start..end } } const _: () = assert!(FontData::default_data_long_enough(MyLookup::<()>::MIN_SIZE)); impl Default for MyLookup<'_, T> { fn default() -> Self { Self { data: FontData::default_table_data(), offset_type: std::marker::PhantomData, } } } #[cfg(feature = "experimental_traverse")] impl<'a, T: FontRead<'a> + SomeTable<'a> + 'a> SomeTable<'a> for MyLookup<'a, T> { fn type_name(&self) -> &str { "MyLookup" } fn get_field(&self, idx: usize) -> Option> { match idx { 0usize => Some(Field::new("lookup_type", self.lookup_type())), 1usize => Some(Field::new("sub_table_count", self.sub_table_count())), 2usize => Some(Field::new( "subtable_offsets", FieldType::from(self.subtables()), )), _ => None, } } } #[cfg(feature = "experimental_traverse")] #[allow(clippy::needless_lifetimes)] impl<'a, T: FontRead<'a> + SomeTable<'a> + 'a> std::fmt::Debug for MyLookup<'a, T> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { (self as &dyn SomeTable<'a>).fmt(f) } } /// A concrete subtable with a format field (format group) #[derive(Clone)] pub enum MySubtable<'a> { Format1(MySubtableFormat1<'a>), Format2(MySubtableFormat2<'a>), } impl Default for MySubtable<'_> { fn default() -> Self { Self::Format1(Default::default()) } } impl<'a> MySubtable<'a> { ///Return the `FontData` used to resolve offsets for this table. pub fn offset_data(&self) -> FontData<'a> { match self { Self::Format1(item) => item.offset_data(), Self::Format2(item) => item.offset_data(), } } pub fn format(&self) -> u16 { match self { Self::Format1(item) => item.format(), Self::Format2(item) => item.format(), } } } impl<'a> FontRead<'a> for MySubtable<'a> { fn read(data: FontData<'a>) -> Result { let format: u16 = data.read_at(0usize)?; match format { MySubtableFormat1::FORMAT => Ok(Self::Format1(FontRead::read(data)?)), MySubtableFormat2::FORMAT => Ok(Self::Format2(FontRead::read(data)?)), other => Err(ReadError::InvalidFormat(other.into())), } } } impl<'a> MinByteRange<'a> for MySubtable<'a> { fn min_byte_range(&self) -> Range { match self { Self::Format1(item) => item.min_byte_range(), Self::Format2(item) => item.min_byte_range(), } } fn min_table_bytes(&self) -> &'a [u8] { match self { Self::Format1(item) => item.min_table_bytes(), Self::Format2(item) => item.min_table_bytes(), } } } #[cfg(feature = "experimental_traverse")] impl<'a> MySubtable<'a> { fn dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a> { match self { Self::Format1(table) => table, Self::Format2(table) => table, } } } #[cfg(feature = "experimental_traverse")] impl std::fmt::Debug for MySubtable<'_> { 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 MySubtable<'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 MySubtableFormat1<'_> { const FORMAT: u16 = 1; } impl<'a> MinByteRange<'a> for MySubtableFormat1<'a> { fn min_byte_range(&self) -> Range { 0..self.value_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 MySubtableFormat1<'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 }) } } #[derive(Clone)] pub struct MySubtableFormat1<'a> { data: FontData<'a>, } #[allow(clippy::needless_lifetimes)] impl<'a> MySubtableFormat1<'a> { pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN); basic_table_impls!(impl_the_methods); pub fn format(&self) -> u16 { let range = self.format_byte_range(); self.data.read_at(range.start).ok().unwrap() } pub fn value(&self) -> u16 { let range = self.value_byte_range(); self.data.read_at(range.start).ok().unwrap() } pub fn format_byte_range(&self) -> Range { let start = 0; let end = start + u16::RAW_BYTE_LEN; start..end } pub fn value_byte_range(&self) -> Range { let start = self.format_byte_range().end; let end = start + u16::RAW_BYTE_LEN; start..end } } const _: () = assert!(FontData::default_data_long_enough( MySubtableFormat1::MIN_SIZE )); impl Default for MySubtableFormat1<'_> { fn default() -> Self { Self { data: FontData::default_format_1_u16_table_data(), } } } #[cfg(feature = "experimental_traverse")] impl<'a> SomeTable<'a> for MySubtableFormat1<'a> { fn type_name(&self) -> &str { "MySubtableFormat1" } fn get_field(&self, idx: usize) -> Option> { match idx { 0usize => Some(Field::new("format", self.format())), 1usize => Some(Field::new("value", self.value())), _ => None, } } } #[cfg(feature = "experimental_traverse")] #[allow(clippy::needless_lifetimes)] impl<'a> std::fmt::Debug for MySubtableFormat1<'a> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { (self as &dyn SomeTable<'a>).fmt(f) } } impl Format for MySubtableFormat2<'_> { const FORMAT: u16 = 2; } impl<'a> MinByteRange<'a> for MySubtableFormat2<'a> { fn min_byte_range(&self) -> Range { 0..self.values_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 MySubtableFormat2<'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 }) } } #[derive(Clone)] pub struct MySubtableFormat2<'a> { data: FontData<'a>, } #[allow(clippy::needless_lifetimes)] impl<'a> MySubtableFormat2<'a> { pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN); basic_table_impls!(impl_the_methods); pub fn format(&self) -> u16 { let range = self.format_byte_range(); self.data.read_at(range.start).ok().unwrap() } pub fn count(&self) -> u16 { let range = self.count_byte_range(); self.data.read_at(range.start).ok().unwrap() } pub fn values(&self) -> &'a [BigEndian] { let range = self.values_byte_range(); self.data.read_array(range).ok().unwrap_or_default() } pub fn format_byte_range(&self) -> Range { let start = 0; let end = start + u16::RAW_BYTE_LEN; start..end } pub fn count_byte_range(&self) -> Range { let start = self.format_byte_range().end; let end = start + u16::RAW_BYTE_LEN; start..end } pub fn values_byte_range(&self) -> Range { let count = self.count(); let start = self.count_byte_range().end; let end = start + (transforms::to_usize(count)).saturating_mul(u16::RAW_BYTE_LEN); start..end } } #[cfg(feature = "experimental_traverse")] impl<'a> SomeTable<'a> for MySubtableFormat2<'a> { fn type_name(&self) -> &str { "MySubtableFormat2" } fn get_field(&self, idx: usize) -> Option> { match idx { 0usize => Some(Field::new("format", self.format())), 1usize => Some(Field::new("count", self.count())), 2usize => Some(Field::new("values", self.values())), _ => None, } } } #[cfg(feature = "experimental_traverse")] #[allow(clippy::needless_lifetimes)] impl<'a> std::fmt::Debug for MySubtableFormat2<'a> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { (self as &dyn SomeTable<'a>).fmt(f) } } /// The group enum dispatching on lookup_type. pub enum MyLookupGroup<'a> { TypeOne(MyLookup<'a, MySubtable<'a>>), TypeTwo(MyLookup<'a, MySubtableFormat1<'a>>), } impl Default for MyLookupGroup<'_> { fn default() -> Self { Self::TypeOne(Default::default()) } } impl<'a> FontRead<'a> for MyLookupGroup<'a> { fn read(bytes: FontData<'a>) -> Result { let discriminant = MyLookup::read_discriminant(bytes)?; match discriminant { 1 => Ok(MyLookupGroup::TypeOne(FontRead::read(bytes)?)), 2 => Ok(MyLookupGroup::TypeTwo(FontRead::read(bytes)?)), other => Err(ReadError::InvalidFormat(other.into())), } } } impl<'a> MyLookupGroup<'a> { #[allow(dead_code)] /// Return the inner table, removing the specific generics. /// /// This lets us return a single concrete type we can call methods on. pub(crate) fn of_unit_type(&self) -> MyLookup<'a, ()> { match self { MyLookupGroup::TypeOne(inner) => inner.of_unit_type(), MyLookupGroup::TypeTwo(inner) => inner.of_unit_type(), } } } #[cfg(feature = "experimental_traverse")] impl<'a> MyLookupGroup<'a> { fn dyn_inner(&self) -> &(dyn SomeTable<'a> + 'a) { match self { MyLookupGroup::TypeOne(table) => table, MyLookupGroup::TypeTwo(table) => table, } } } #[cfg(feature = "experimental_traverse")] impl<'a> SomeTable<'a> for MyLookupGroup<'a> { fn get_field(&self, idx: usize) -> Option> { self.dyn_inner().get_field(idx) } fn type_name(&self) -> &str { self.dyn_inner().type_name() } } #[cfg(feature = "experimental_traverse")] impl std::fmt::Debug for MyLookupGroup<'_> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { self.dyn_inner().fmt(f) } } impl<'a> MinByteRange<'a> for ContainsLookupGroup<'a> { fn min_byte_range(&self) -> Range { 0..self.lookup_offset_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 ContainsLookupGroup<'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 }) } } #[derive(Clone)] pub struct ContainsLookupGroup<'a> { data: FontData<'a>, } #[allow(clippy::needless_lifetimes)] impl<'a> ContainsLookupGroup<'a> { pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + Offset16::RAW_BYTE_LEN); basic_table_impls!(impl_the_methods); pub fn version(&self) -> u16 { let range = self.version_byte_range(); self.data.read_at(range.start).ok().unwrap() } pub fn lookup_offset(&self) -> Offset16 { let range = self.lookup_offset_byte_range(); self.data.read_at(range.start).ok().unwrap() } /// Attempt to resolve [`lookup_offset`][Self::lookup_offset]. pub fn lookup(&self) -> Result, ReadError> { let data = self.data; self.lookup_offset().resolve(data) } pub fn version_byte_range(&self) -> Range { let start = 0; let end = start + u16::RAW_BYTE_LEN; start..end } pub fn lookup_offset_byte_range(&self) -> Range { let start = self.version_byte_range().end; let end = start + Offset16::RAW_BYTE_LEN; start..end } } const _: () = assert!(FontData::default_data_long_enough( ContainsLookupGroup::MIN_SIZE )); impl Default for ContainsLookupGroup<'_> { fn default() -> Self { Self { data: FontData::default_table_data(), } } } #[cfg(feature = "experimental_traverse")] impl<'a> SomeTable<'a> for ContainsLookupGroup<'a> { fn type_name(&self) -> &str { "ContainsLookupGroup" } fn get_field(&self, idx: usize) -> Option> { match idx { 0usize => Some(Field::new("version", self.version())), 1usize => Some(Field::new( "lookup_offset", FieldType::offset(self.lookup_offset(), self.lookup()), )), _ => None, } } } #[cfg(feature = "experimental_traverse")] #[allow(clippy::needless_lifetimes)] impl<'a> std::fmt::Debug for ContainsLookupGroup<'a> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { (self as &dyn SomeTable<'a>).fmt(f) } }