#[allow(unused_imports)]
use crate::codegen_prelude::*;
impl<'a> MinByteRange<'a> for ScriptList<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.script_records_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for ScriptList<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for ScriptList<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self { data })
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct ScriptListFixedHeader {
pub script_count: BigEndian<u16>,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () = assert!(std::mem::size_of::<ScriptListFixedHeader>() <= ScriptList::MIN_SIZE);
#[derive(Clone)]
pub struct ScriptList<'a> {
data: TableDataRef<'a, ScriptListFixedHeader>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> ScriptList<'a> {
pub const MIN_SIZE: usize = u16::RAW_BYTE_LEN;
basic_table_impls!(impl_the_methods);
pub fn script_count(&self) -> u16 {
self.data.header().script_count.get()
}
pub fn script_records(&self) -> &'a [ScriptRecord] {
let range = self.script_records_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn script_count_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn script_records_byte_range(&self) -> Range<usize> {
let script_count = self.script_count();
let start = self.script_count_byte_range().end;
let end =
start + (transforms::to_usize(script_count)).saturating_mul(ScriptRecord::RAW_BYTE_LEN);
start..end
}
}
const _: () = assert!(FontData::default_data_long_enough(ScriptList::MIN_SIZE));
impl Default for ScriptList<'_> {
fn default() -> Self {
Self {
data: TableDataRef::new(FontData::default_table_data().as_bytes())
.unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
}
}
}
#[derive(Clone, Debug, Copy, bytemuck :: AnyBitPattern)]
#[repr(C)]
#[repr(packed)]
pub struct ScriptRecord {
pub script_tag: BigEndian<Tag>,
pub script_offset: BigEndian<Offset16>,
}
impl ScriptRecord {
pub fn script_tag(&self) -> Tag {
self.script_tag.get()
}
pub fn script_offset(&self) -> Offset16 {
self.script_offset.get()
}
pub fn script<'a>(&self, data: FontData<'a>) -> Result<Script<'a>, ReadError> {
self.script_offset().resolve(data)
}
}
impl FixedSize for ScriptRecord {
const RAW_BYTE_LEN: usize = Tag::RAW_BYTE_LEN + Offset16::RAW_BYTE_LEN;
}
impl<'a> MinByteRange<'a> for Script<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.lang_sys_records_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for Script<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for Script<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self { data })
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct ScriptFixedHeader {
pub default_lang_sys_offset: BigEndian<Nullable<Offset16>>,
pub lang_sys_count: BigEndian<u16>,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () = assert!(std::mem::size_of::<ScriptFixedHeader>() <= Script::MIN_SIZE);
#[derive(Clone)]
pub struct Script<'a> {
data: TableDataRef<'a, ScriptFixedHeader>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> Script<'a> {
pub const MIN_SIZE: usize = (Offset16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN);
basic_table_impls!(impl_the_methods);
pub fn default_lang_sys_offset(&self) -> Nullable<Offset16> {
self.data.header().default_lang_sys_offset.get()
}
pub fn default_lang_sys(&self) -> Option<Result<LangSys<'a>, ReadError>> {
let data = self.offset_data();
self.default_lang_sys_offset().resolve(data)
}
pub fn lang_sys_count(&self) -> u16 {
self.data.header().lang_sys_count.get()
}
pub fn lang_sys_records(&self) -> &'a [LangSysRecord] {
let range = self.lang_sys_records_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn default_lang_sys_offset_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + Offset16::RAW_BYTE_LEN;
start..end
}
pub fn lang_sys_count_byte_range(&self) -> Range<usize> {
let start = self.default_lang_sys_offset_byte_range().end;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn lang_sys_records_byte_range(&self) -> Range<usize> {
let lang_sys_count = self.lang_sys_count();
let start = self.lang_sys_count_byte_range().end;
let end = start
+ (transforms::to_usize(lang_sys_count)).saturating_mul(LangSysRecord::RAW_BYTE_LEN);
start..end
}
}
const _: () = assert!(FontData::default_data_long_enough(Script::MIN_SIZE));
impl Default for Script<'_> {
fn default() -> Self {
Self {
data: TableDataRef::new(FontData::default_table_data().as_bytes())
.unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
}
}
}
#[derive(Clone, Debug, Copy, bytemuck :: AnyBitPattern)]
#[repr(C)]
#[repr(packed)]
pub struct LangSysRecord {
pub lang_sys_tag: BigEndian<Tag>,
pub lang_sys_offset: BigEndian<Offset16>,
}
impl LangSysRecord {
pub fn lang_sys_tag(&self) -> Tag {
self.lang_sys_tag.get()
}
pub fn lang_sys_offset(&self) -> Offset16 {
self.lang_sys_offset.get()
}
pub fn lang_sys<'a>(&self, data: FontData<'a>) -> Result<LangSys<'a>, ReadError> {
self.lang_sys_offset().resolve(data)
}
}
impl FixedSize for LangSysRecord {
const RAW_BYTE_LEN: usize = Tag::RAW_BYTE_LEN + Offset16::RAW_BYTE_LEN;
}
impl<'a> MinByteRange<'a> for LangSys<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.feature_indices_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for LangSys<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for LangSys<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self { data })
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct LangSysFixedHeader {
pub lookup_order_offset: BigEndian<u16>,
pub required_feature_index: BigEndian<u16>,
pub feature_index_count: BigEndian<u16>,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () = assert!(std::mem::size_of::<LangSysFixedHeader>() <= LangSys::MIN_SIZE);
#[derive(Clone)]
pub struct LangSys<'a> {
data: TableDataRef<'a, LangSysFixedHeader>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> LangSys<'a> {
pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN);
basic_table_impls!(impl_the_methods);
pub fn required_feature_index(&self) -> u16 {
self.data.header().required_feature_index.get()
}
pub fn feature_index_count(&self) -> u16 {
self.data.header().feature_index_count.get()
}
pub fn feature_indices(&self) -> &'a [BigEndian<u16>] {
let range = self.feature_indices_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn lookup_order_offset_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn required_feature_index_byte_range(&self) -> Range<usize> {
let start = self.lookup_order_offset_byte_range().end;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn feature_index_count_byte_range(&self) -> Range<usize> {
let start = self.required_feature_index_byte_range().end;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn feature_indices_byte_range(&self) -> Range<usize> {
let feature_index_count = self.feature_index_count();
let start = self.feature_index_count_byte_range().end;
let end =
start + (transforms::to_usize(feature_index_count)).saturating_mul(u16::RAW_BYTE_LEN);
start..end
}
}
const _: () = assert!(FontData::default_data_long_enough(LangSys::MIN_SIZE));
impl Default for LangSys<'_> {
fn default() -> Self {
Self {
data: TableDataRef::new(FontData::default_table_data().as_bytes())
.unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
}
}
}
impl<'a> MinByteRange<'a> for FeatureList<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.feature_records_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for FeatureList<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for FeatureList<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self { data })
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct FeatureListFixedHeader {
pub feature_count: BigEndian<u16>,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () = assert!(std::mem::size_of::<FeatureListFixedHeader>() <= FeatureList::MIN_SIZE);
#[derive(Clone)]
pub struct FeatureList<'a> {
data: TableDataRef<'a, FeatureListFixedHeader>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> FeatureList<'a> {
pub const MIN_SIZE: usize = u16::RAW_BYTE_LEN;
basic_table_impls!(impl_the_methods);
pub fn feature_count(&self) -> u16 {
self.data.header().feature_count.get()
}
pub fn feature_records(&self) -> &'a [FeatureRecord] {
let range = self.feature_records_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn feature_count_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn feature_records_byte_range(&self) -> Range<usize> {
let feature_count = self.feature_count();
let start = self.feature_count_byte_range().end;
let end = start
+ (transforms::to_usize(feature_count)).saturating_mul(FeatureRecord::RAW_BYTE_LEN);
start..end
}
}
const _: () = assert!(FontData::default_data_long_enough(FeatureList::MIN_SIZE));
impl Default for FeatureList<'_> {
fn default() -> Self {
Self {
data: TableDataRef::new(FontData::default_table_data().as_bytes())
.unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
}
}
}
#[derive(Clone, Debug, Copy, bytemuck :: AnyBitPattern)]
#[repr(C)]
#[repr(packed)]
pub struct FeatureRecord {
pub feature_tag: BigEndian<Tag>,
pub feature_offset: BigEndian<Offset16>,
}
impl FeatureRecord {
pub fn feature_tag(&self) -> Tag {
self.feature_tag.get()
}
pub fn feature_offset(&self) -> Offset16 {
self.feature_offset.get()
}
pub fn feature<'a>(&self, data: FontData<'a>) -> Result<Feature<'a>, ReadError> {
let args = self.feature_tag();
self.feature_offset().resolve_with_args(data, args)
}
}
impl FixedSize for FeatureRecord {
const RAW_BYTE_LEN: usize = Tag::RAW_BYTE_LEN + Offset16::RAW_BYTE_LEN;
}
impl<'a> MinByteRange<'a> for Feature<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.lookup_list_indices_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for Feature<'_> {
type Args = Tag;
}
impl<'a> FontRead<'a> for Feature<'a> {
fn read_with_args(data: FontData<'a>, args: Tag) -> Result<Self, ReadError> {
let feature_tag = args;
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self { data, feature_tag })
}
}
impl<'a> Feature<'a> {
pub fn read(data: FontData<'a>, feature_tag: Tag) -> Result<Self, ReadError> {
let args = feature_tag;
Self::read_with_args(data, args)
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct FeatureFixedHeader {
pub feature_params_offset: BigEndian<Nullable<Offset16>>,
pub lookup_index_count: BigEndian<u16>,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () = assert!(std::mem::size_of::<FeatureFixedHeader>() <= Feature::MIN_SIZE);
#[derive(Clone)]
pub struct Feature<'a> {
data: TableDataRef<'a, FeatureFixedHeader>,
feature_tag: Tag,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> Feature<'a> {
pub const MIN_SIZE: usize = (Offset16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN);
basic_table_impls!(impl_the_methods);
pub fn feature_params_offset(&self) -> Nullable<Offset16> {
self.data.header().feature_params_offset.get()
}
pub fn feature_params(&self) -> Option<Result<FeatureParams<'a>, ReadError>> {
let data = self.offset_data();
let args = self.feature_tag();
self.feature_params_offset().resolve_with_args(data, args)
}
pub fn lookup_index_count(&self) -> u16 {
self.data.header().lookup_index_count.get()
}
pub fn lookup_list_indices(&self) -> &'a [BigEndian<u16>] {
let range = self.lookup_list_indices_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub(crate) fn feature_tag(&self) -> Tag {
self.feature_tag
}
pub fn feature_params_offset_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + Offset16::RAW_BYTE_LEN;
start..end
}
pub fn lookup_index_count_byte_range(&self) -> Range<usize> {
let start = self.feature_params_offset_byte_range().end;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn lookup_list_indices_byte_range(&self) -> Range<usize> {
let lookup_index_count = self.lookup_index_count();
let start = self.lookup_index_count_byte_range().end;
let end =
start + (transforms::to_usize(lookup_index_count)).saturating_mul(u16::RAW_BYTE_LEN);
start..end
}
}
const _: () = assert!(FontData::default_data_long_enough(Feature::MIN_SIZE));
impl Default for Feature<'_> {
fn default() -> Self {
Self {
data: TableDataRef::new(FontData::default_table_data().as_bytes())
.unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
feature_tag: Default::default(),
}
}
}
impl<'a, T> MinByteRange<'a> for LookupList<'a, T> {
fn min_byte_range(&self) -> Range<usize> {
0..self.lookup_offsets_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl<T> ReadArgs for LookupList<'_, T> {
type Args = ();
}
impl<'a, T> FontRead<'a> for LookupList<'a, T> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self {
data,
offset_type: std::marker::PhantomData,
})
}
}
impl<'a, T> LookupList<'a, T> {
#[allow(dead_code)]
pub(crate) fn of_unit_type(&self) -> LookupList<'a, ()> {
LookupList {
data: self.data,
offset_type: std::marker::PhantomData,
}
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct LookupListFixedHeader {
pub lookup_count: BigEndian<u16>,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () = assert!(std::mem::size_of::<LookupListFixedHeader>() <= LookupList::<()>::MIN_SIZE);
#[derive(Clone)]
pub struct LookupList<'a, T = ()> {
data: TableDataRef<'a, LookupListFixedHeader>,
offset_type: std::marker::PhantomData<*const T>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a, T> LookupList<'a, T> {
pub const MIN_SIZE: usize = u16::RAW_BYTE_LEN;
basic_table_impls!(impl_the_methods);
pub fn lookup_count(&self) -> u16 {
self.data.header().lookup_count.get()
}
pub fn lookup_offsets(&self) -> &'a [BigEndian<Offset16>] {
let range = self.lookup_offsets_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn lookups(&self) -> ArrayOfOffsets<'a, T, Offset16>
where
T: FontRead<'a, Args = ()>,
{
let data = self.offset_data();
let offsets = self.lookup_offsets();
ArrayOfOffsets::new(offsets, data, ())
}
pub fn lookup_count_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn lookup_offsets_byte_range(&self) -> Range<usize> {
let lookup_count = self.lookup_count();
let start = self.lookup_count_byte_range().end;
let end =
start + (transforms::to_usize(lookup_count)).saturating_mul(Offset16::RAW_BYTE_LEN);
start..end
}
}
const _: () = assert!(FontData::default_data_long_enough(
LookupList::<()>::MIN_SIZE
));
impl<T> Default for LookupList<'_, T> {
fn default() -> Self {
Self {
data: TableDataRef::new(FontData::default_table_data().as_bytes())
.unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
offset_type: std::marker::PhantomData,
}
}
}
impl Discriminant for Lookup<'_, ()> {
fn read_discriminant(data: FontData<'_>) -> Result<u16, ReadError> {
data.read_at(0)
}
}
impl<'a, T> MinByteRange<'a> for Lookup<'a, T> {
fn min_byte_range(&self) -> Range<usize> {
0..self.subtable_offsets_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl<T> ReadArgs for Lookup<'_, T> {
type Args = ();
}
impl<'a, T> FontRead<'a> for Lookup<'a, T> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self {
data,
offset_type: std::marker::PhantomData,
})
}
}
impl<'a, T> Lookup<'a, T> {
#[allow(dead_code)]
pub(crate) fn of_unit_type(&self) -> Lookup<'a, ()> {
Lookup {
data: self.data,
offset_type: std::marker::PhantomData,
}
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct LookupFixedHeader {
pub lookup_type: BigEndian<u16>,
pub lookup_flag: BigEndian<LookupFlag>,
pub sub_table_count: BigEndian<u16>,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () = assert!(std::mem::size_of::<LookupFixedHeader>() <= Lookup::<()>::MIN_SIZE);
#[derive(Clone)]
pub struct Lookup<'a, T = ()> {
data: TableDataRef<'a, LookupFixedHeader>,
offset_type: std::marker::PhantomData<*const T>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a, T> Lookup<'a, T> {
pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + LookupFlag::RAW_BYTE_LEN + u16::RAW_BYTE_LEN);
basic_table_impls!(impl_the_methods);
pub fn lookup_type(&self) -> u16 {
self.data.header().lookup_type.get()
}
pub fn lookup_flag(&self) -> LookupFlag {
self.data.header().lookup_flag.get()
}
pub fn sub_table_count(&self) -> u16 {
self.data.header().sub_table_count.get()
}
pub fn subtable_offsets(&self) -> &'a [BigEndian<Offset16>] {
let range = self.subtable_offsets_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn subtables(&self) -> ArrayOfOffsets<'a, T, Offset16>
where
T: FontRead<'a, Args = ()>,
{
let data = self.offset_data();
let offsets = self.subtable_offsets();
ArrayOfOffsets::new(offsets, data, ())
}
pub fn mark_filtering_set(&self) -> Option<u16> {
let range = self.mark_filtering_set_byte_range();
(!range.is_empty())
.then(|| self.offset_data().read_at(range.start).ok())
.flatten()
}
pub fn lookup_type_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn lookup_flag_byte_range(&self) -> Range<usize> {
let start = self.lookup_type_byte_range().end;
let end = start + LookupFlag::RAW_BYTE_LEN;
start..end
}
pub fn sub_table_count_byte_range(&self) -> Range<usize> {
let start = self.lookup_flag_byte_range().end;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn subtable_offsets_byte_range(&self) -> Range<usize> {
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
}
pub fn mark_filtering_set_byte_range(&self) -> Range<usize> {
let start = self.subtable_offsets_byte_range().end;
let end = if self
.lookup_flag()
.contains(LookupFlag::USE_MARK_FILTERING_SET)
{
start + u16::RAW_BYTE_LEN
} else {
start
};
start..end
}
}
const _: () = assert!(FontData::default_data_long_enough(Lookup::<()>::MIN_SIZE));
impl<T> Default for Lookup<'_, T> {
fn default() -> Self {
Self {
data: TableDataRef::new(FontData::default_table_data().as_bytes())
.unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
offset_type: std::marker::PhantomData,
}
}
}
impl Format<u16> for CoverageFormat1<'_> {
const FORMAT: u16 = 1;
}
impl<'a> MinByteRange<'a> for CoverageFormat1<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.glyph_array_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for CoverageFormat1<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for CoverageFormat1<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self { data })
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct CoverageFormat1FixedHeader {
pub coverage_format: BigEndian<u16>,
pub glyph_count: BigEndian<u16>,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () =
assert!(std::mem::size_of::<CoverageFormat1FixedHeader>() <= CoverageFormat1::MIN_SIZE);
#[derive(Clone)]
pub struct CoverageFormat1<'a> {
data: TableDataRef<'a, CoverageFormat1FixedHeader>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> CoverageFormat1<'a> {
pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN);
basic_table_impls!(impl_the_methods);
pub fn coverage_format(&self) -> u16 {
self.data.header().coverage_format.get()
}
pub fn glyph_count(&self) -> u16 {
self.data.header().glyph_count.get()
}
pub fn glyph_array(&self) -> &'a [BigEndian<GlyphId16>] {
let range = self.glyph_array_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn coverage_format_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn glyph_count_byte_range(&self) -> Range<usize> {
let start = self.coverage_format_byte_range().end;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn glyph_array_byte_range(&self) -> Range<usize> {
let glyph_count = self.glyph_count();
let start = self.glyph_count_byte_range().end;
let end =
start + (transforms::to_usize(glyph_count)).saturating_mul(GlyphId16::RAW_BYTE_LEN);
start..end
}
}
const _: () = assert!(FontData::default_data_long_enough(
CoverageFormat1::MIN_SIZE
));
impl Default for CoverageFormat1<'_> {
fn default() -> Self {
Self {
data: TableDataRef::new(FontData::default_format_1_u16_table_data().as_bytes())
.unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
}
}
}
impl Format<u16> for CoverageFormat2<'_> {
const FORMAT: u16 = 2;
}
impl<'a> MinByteRange<'a> for CoverageFormat2<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.range_records_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for CoverageFormat2<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for CoverageFormat2<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self { data })
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct CoverageFormat2FixedHeader {
pub coverage_format: BigEndian<u16>,
pub range_count: BigEndian<u16>,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () =
assert!(std::mem::size_of::<CoverageFormat2FixedHeader>() <= CoverageFormat2::MIN_SIZE);
#[derive(Clone)]
pub struct CoverageFormat2<'a> {
data: TableDataRef<'a, CoverageFormat2FixedHeader>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> CoverageFormat2<'a> {
pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN);
basic_table_impls!(impl_the_methods);
pub fn coverage_format(&self) -> u16 {
self.data.header().coverage_format.get()
}
pub fn range_count(&self) -> u16 {
self.data.header().range_count.get()
}
pub fn range_records(&self) -> &'a [RangeRecord] {
let range = self.range_records_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn coverage_format_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn range_count_byte_range(&self) -> Range<usize> {
let start = self.coverage_format_byte_range().end;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn range_records_byte_range(&self) -> Range<usize> {
let range_count = self.range_count();
let start = self.range_count_byte_range().end;
let end =
start + (transforms::to_usize(range_count)).saturating_mul(RangeRecord::RAW_BYTE_LEN);
start..end
}
}
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
#[repr(C)]
#[repr(packed)]
pub struct RangeRecord {
pub start_glyph_id: BigEndian<GlyphId16>,
pub end_glyph_id: BigEndian<GlyphId16>,
pub start_coverage_index: BigEndian<u16>,
}
impl RangeRecord {
pub fn start_glyph_id(&self) -> GlyphId16 {
self.start_glyph_id.get()
}
pub fn end_glyph_id(&self) -> GlyphId16 {
self.end_glyph_id.get()
}
pub fn start_coverage_index(&self) -> u16 {
self.start_coverage_index.get()
}
}
impl FixedSize for RangeRecord {
const RAW_BYTE_LEN: usize =
GlyphId16::RAW_BYTE_LEN + GlyphId16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN;
}
#[derive(Clone)]
pub enum CoverageTable<'a> {
Format1(CoverageFormat1<'a>),
Format2(CoverageFormat2<'a>),
Format3(CoverageFormat3<'a>),
Format4(CoverageFormat4<'a>),
}
impl Default for CoverageTable<'_> {
fn default() -> Self {
Self::Format1(Default::default())
}
}
impl<'a> CoverageTable<'a> {
pub fn offset_data(&self) -> FontData<'a> {
match self {
Self::Format1(item) => item.offset_data(),
Self::Format2(item) => item.offset_data(),
Self::Format3(item) => item.offset_data(),
Self::Format4(item) => item.offset_data(),
}
}
pub fn coverage_format(&self) -> u16 {
match self {
Self::Format1(item) => item.coverage_format(),
Self::Format2(item) => item.coverage_format(),
Self::Format3(item) => item.coverage_format(),
Self::Format4(item) => item.coverage_format(),
}
}
}
impl ReadArgs for CoverageTable<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for CoverageTable<'a> {
#[inline]
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
let format: u16 = data.read_at(0usize)?;
match format {
CoverageFormat1::FORMAT => Ok(Self::Format1(FontRead::read(data)?)),
CoverageFormat2::FORMAT => Ok(Self::Format2(FontRead::read(data)?)),
CoverageFormat3::FORMAT => Ok(Self::Format3(FontRead::read(data)?)),
CoverageFormat4::FORMAT => Ok(Self::Format4(FontRead::read(data)?)),
other => Err(ReadError::InvalidFormat(other.into())),
}
}
}
impl<'a> MinByteRange<'a> for CoverageTable<'a> {
fn min_byte_range(&self) -> Range<usize> {
match self {
Self::Format1(item) => item.min_byte_range(),
Self::Format2(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::Format1(item) => item.min_table_bytes(),
Self::Format2(item) => item.min_table_bytes(),
Self::Format3(item) => item.min_table_bytes(),
Self::Format4(item) => item.min_table_bytes(),
}
}
}
impl Format<u16> for ClassDefFormat1<'_> {
const FORMAT: u16 = 1;
}
impl<'a> MinByteRange<'a> for ClassDefFormat1<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.class_value_array_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for ClassDefFormat1<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for ClassDefFormat1<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self { data })
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct ClassDefFormat1FixedHeader {
pub class_format: BigEndian<u16>,
pub start_glyph_id: BigEndian<GlyphId16>,
pub glyph_count: BigEndian<u16>,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () =
assert!(std::mem::size_of::<ClassDefFormat1FixedHeader>() <= ClassDefFormat1::MIN_SIZE);
#[derive(Clone)]
pub struct ClassDefFormat1<'a> {
data: TableDataRef<'a, ClassDefFormat1FixedHeader>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> ClassDefFormat1<'a> {
pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + GlyphId16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN);
basic_table_impls!(impl_the_methods);
pub fn class_format(&self) -> u16 {
self.data.header().class_format.get()
}
pub fn start_glyph_id(&self) -> GlyphId16 {
self.data.header().start_glyph_id.get()
}
pub fn glyph_count(&self) -> u16 {
self.data.header().glyph_count.get()
}
pub fn class_value_array(&self) -> &'a [BigEndian<u16>] {
let range = self.class_value_array_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn class_format_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn start_glyph_id_byte_range(&self) -> Range<usize> {
let start = self.class_format_byte_range().end;
let end = start + GlyphId16::RAW_BYTE_LEN;
start..end
}
pub fn glyph_count_byte_range(&self) -> Range<usize> {
let start = self.start_glyph_id_byte_range().end;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn class_value_array_byte_range(&self) -> Range<usize> {
let glyph_count = self.glyph_count();
let start = self.glyph_count_byte_range().end;
let end = start + (transforms::to_usize(glyph_count)).saturating_mul(u16::RAW_BYTE_LEN);
start..end
}
}
const _: () = assert!(FontData::default_data_long_enough(
ClassDefFormat1::MIN_SIZE
));
impl Default for ClassDefFormat1<'_> {
fn default() -> Self {
Self {
data: TableDataRef::new(FontData::default_format_1_u16_table_data().as_bytes())
.unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
}
}
}
impl Format<u16> for ClassDefFormat2<'_> {
const FORMAT: u16 = 2;
}
impl<'a> MinByteRange<'a> for ClassDefFormat2<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.class_range_records_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for ClassDefFormat2<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for ClassDefFormat2<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self { data })
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct ClassDefFormat2FixedHeader {
pub class_format: BigEndian<u16>,
pub class_range_count: BigEndian<u16>,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () =
assert!(std::mem::size_of::<ClassDefFormat2FixedHeader>() <= ClassDefFormat2::MIN_SIZE);
#[derive(Clone)]
pub struct ClassDefFormat2<'a> {
data: TableDataRef<'a, ClassDefFormat2FixedHeader>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> ClassDefFormat2<'a> {
pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN);
basic_table_impls!(impl_the_methods);
pub fn class_format(&self) -> u16 {
self.data.header().class_format.get()
}
pub fn class_range_count(&self) -> u16 {
self.data.header().class_range_count.get()
}
pub fn class_range_records(&self) -> &'a [ClassRangeRecord] {
let range = self.class_range_records_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn class_format_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn class_range_count_byte_range(&self) -> Range<usize> {
let start = self.class_format_byte_range().end;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn class_range_records_byte_range(&self) -> Range<usize> {
let class_range_count = self.class_range_count();
let start = self.class_range_count_byte_range().end;
let end = start
+ (transforms::to_usize(class_range_count))
.saturating_mul(ClassRangeRecord::RAW_BYTE_LEN);
start..end
}
}
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
#[repr(C)]
#[repr(packed)]
pub struct ClassRangeRecord {
pub start_glyph_id: BigEndian<GlyphId16>,
pub end_glyph_id: BigEndian<GlyphId16>,
pub class: BigEndian<u16>,
}
impl ClassRangeRecord {
pub fn start_glyph_id(&self) -> GlyphId16 {
self.start_glyph_id.get()
}
pub fn end_glyph_id(&self) -> GlyphId16 {
self.end_glyph_id.get()
}
pub fn class(&self) -> u16 {
self.class.get()
}
}
impl FixedSize for ClassRangeRecord {
const RAW_BYTE_LEN: usize =
GlyphId16::RAW_BYTE_LEN + GlyphId16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN;
}
#[derive(Clone)]
pub enum ClassDef<'a> {
Format1(ClassDefFormat1<'a>),
Format2(ClassDefFormat2<'a>),
Format3(ClassDefFormat3<'a>),
Format4(ClassDefFormat4<'a>),
}
impl Default for ClassDef<'_> {
fn default() -> Self {
Self::Format1(Default::default())
}
}
impl<'a> ClassDef<'a> {
pub fn offset_data(&self) -> FontData<'a> {
match self {
Self::Format1(item) => item.offset_data(),
Self::Format2(item) => item.offset_data(),
Self::Format3(item) => item.offset_data(),
Self::Format4(item) => item.offset_data(),
}
}
pub fn class_format(&self) -> u16 {
match self {
Self::Format1(item) => item.class_format(),
Self::Format2(item) => item.class_format(),
Self::Format3(item) => item.class_format(),
Self::Format4(item) => item.class_format(),
}
}
}
impl ReadArgs for ClassDef<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for ClassDef<'a> {
#[inline]
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
let format: u16 = data.read_at(0usize)?;
match format {
ClassDefFormat1::FORMAT => Ok(Self::Format1(FontRead::read(data)?)),
ClassDefFormat2::FORMAT => Ok(Self::Format2(FontRead::read(data)?)),
ClassDefFormat3::FORMAT => Ok(Self::Format3(FontRead::read(data)?)),
ClassDefFormat4::FORMAT => Ok(Self::Format4(FontRead::read(data)?)),
other => Err(ReadError::InvalidFormat(other.into())),
}
}
}
impl<'a> MinByteRange<'a> for ClassDef<'a> {
fn min_byte_range(&self) -> Range<usize> {
match self {
Self::Format1(item) => item.min_byte_range(),
Self::Format2(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::Format1(item) => item.min_table_bytes(),
Self::Format2(item) => item.min_table_bytes(),
Self::Format3(item) => item.min_table_bytes(),
Self::Format4(item) => item.min_table_bytes(),
}
}
}
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
#[repr(C)]
#[repr(packed)]
pub struct SequenceLookupRecord {
pub sequence_index: BigEndian<u16>,
pub lookup_list_index: BigEndian<u16>,
}
impl SequenceLookupRecord {
pub fn sequence_index(&self) -> u16 {
self.sequence_index.get()
}
pub fn lookup_list_index(&self) -> u16 {
self.lookup_list_index.get()
}
}
impl FixedSize for SequenceLookupRecord {
const RAW_BYTE_LEN: usize = u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN;
}
impl Format<u16> for SequenceContextFormat1<'_> {
const FORMAT: u16 = 1;
}
impl<'a> MinByteRange<'a> for SequenceContextFormat1<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.seq_rule_set_offsets_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for SequenceContextFormat1<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for SequenceContextFormat1<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self { data })
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct SequenceContextFormat1FixedHeader {
pub format: BigEndian<u16>,
pub coverage_offset: BigEndian<Offset16>,
pub seq_rule_set_count: BigEndian<u16>,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () = assert!(
std::mem::size_of::<SequenceContextFormat1FixedHeader>() <= SequenceContextFormat1::MIN_SIZE
);
#[derive(Clone)]
pub struct SequenceContextFormat1<'a> {
data: TableDataRef<'a, SequenceContextFormat1FixedHeader>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> SequenceContextFormat1<'a> {
pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + Offset16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN);
basic_table_impls!(impl_the_methods);
pub fn format(&self) -> u16 {
self.data.header().format.get()
}
pub fn coverage_offset(&self) -> Offset16 {
self.data.header().coverage_offset.get()
}
pub fn coverage(&self) -> Result<CoverageTable<'a>, ReadError> {
let data = self.offset_data();
self.coverage_offset().resolve(data)
}
pub fn seq_rule_set_count(&self) -> u16 {
self.data.header().seq_rule_set_count.get()
}
pub fn seq_rule_set_offsets(&self) -> &'a [BigEndian<Nullable<Offset16>>] {
let range = self.seq_rule_set_offsets_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn seq_rule_sets(&self) -> ArrayOfNullableOffsets<'a, SequenceRuleSet<'a>, Offset16> {
let data = self.offset_data();
let offsets = self.seq_rule_set_offsets();
ArrayOfNullableOffsets::new(offsets, data, ())
}
pub fn format_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn coverage_offset_byte_range(&self) -> Range<usize> {
let start = self.format_byte_range().end;
let end = start + Offset16::RAW_BYTE_LEN;
start..end
}
pub fn seq_rule_set_count_byte_range(&self) -> Range<usize> {
let start = self.coverage_offset_byte_range().end;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn seq_rule_set_offsets_byte_range(&self) -> Range<usize> {
let seq_rule_set_count = self.seq_rule_set_count();
let start = self.seq_rule_set_count_byte_range().end;
let end = start
+ (transforms::to_usize(seq_rule_set_count)).saturating_mul(Offset16::RAW_BYTE_LEN);
start..end
}
}
const _: () = assert!(FontData::default_data_long_enough(
SequenceContextFormat1::MIN_SIZE
));
impl Default for SequenceContextFormat1<'_> {
fn default() -> Self {
Self {
data: TableDataRef::new(FontData::default_format_1_u16_table_data().as_bytes())
.unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
}
}
}
impl<'a> MinByteRange<'a> for SequenceRuleSet<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.seq_rule_offsets_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for SequenceRuleSet<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for SequenceRuleSet<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self { data })
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct SequenceRuleSetFixedHeader {
pub seq_rule_count: BigEndian<u16>,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () =
assert!(std::mem::size_of::<SequenceRuleSetFixedHeader>() <= SequenceRuleSet::MIN_SIZE);
#[derive(Clone)]
pub struct SequenceRuleSet<'a> {
data: TableDataRef<'a, SequenceRuleSetFixedHeader>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> SequenceRuleSet<'a> {
pub const MIN_SIZE: usize = u16::RAW_BYTE_LEN;
basic_table_impls!(impl_the_methods);
pub fn seq_rule_count(&self) -> u16 {
self.data.header().seq_rule_count.get()
}
pub fn seq_rule_offsets(&self) -> &'a [BigEndian<Offset16>] {
let range = self.seq_rule_offsets_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn seq_rules(&self) -> ArrayOfOffsets<'a, SequenceRule<'a>, Offset16> {
let data = self.offset_data();
let offsets = self.seq_rule_offsets();
ArrayOfOffsets::new(offsets, data, ())
}
pub fn seq_rule_count_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn seq_rule_offsets_byte_range(&self) -> Range<usize> {
let seq_rule_count = self.seq_rule_count();
let start = self.seq_rule_count_byte_range().end;
let end =
start + (transforms::to_usize(seq_rule_count)).saturating_mul(Offset16::RAW_BYTE_LEN);
start..end
}
}
const _: () = assert!(FontData::default_data_long_enough(
SequenceRuleSet::MIN_SIZE
));
impl Default for SequenceRuleSet<'_> {
fn default() -> Self {
Self {
data: TableDataRef::new(FontData::default_table_data().as_bytes())
.unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
}
}
}
impl<'a> MinByteRange<'a> for SequenceRule<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.seq_lookup_records_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for SequenceRule<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for SequenceRule<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self { data })
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct SequenceRuleFixedHeader {
pub glyph_count: BigEndian<u16>,
pub seq_lookup_count: BigEndian<u16>,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () = assert!(std::mem::size_of::<SequenceRuleFixedHeader>() <= SequenceRule::MIN_SIZE);
#[derive(Clone)]
pub struct SequenceRule<'a> {
data: TableDataRef<'a, SequenceRuleFixedHeader>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> SequenceRule<'a> {
pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN);
basic_table_impls!(impl_the_methods);
pub fn glyph_count(&self) -> u16 {
self.data.header().glyph_count.get()
}
pub fn seq_lookup_count(&self) -> u16 {
self.data.header().seq_lookup_count.get()
}
pub fn input_sequence(&self) -> &'a [BigEndian<GlyphId16>] {
let range = self.input_sequence_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn seq_lookup_records(&self) -> &'a [SequenceLookupRecord] {
let range = self.seq_lookup_records_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn glyph_count_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn seq_lookup_count_byte_range(&self) -> Range<usize> {
let start = self.glyph_count_byte_range().end;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn input_sequence_byte_range(&self) -> Range<usize> {
let glyph_count = self.glyph_count();
let start = self.seq_lookup_count_byte_range().end;
let end = start
+ (transforms::subtract(glyph_count, 1_usize)).saturating_mul(GlyphId16::RAW_BYTE_LEN);
start..end
}
pub fn seq_lookup_records_byte_range(&self) -> Range<usize> {
let seq_lookup_count = self.seq_lookup_count();
let start = self.input_sequence_byte_range().end;
let end = start
+ (transforms::to_usize(seq_lookup_count))
.saturating_mul(SequenceLookupRecord::RAW_BYTE_LEN);
start..end
}
}
const _: () = assert!(FontData::default_data_long_enough(SequenceRule::MIN_SIZE));
impl Default for SequenceRule<'_> {
fn default() -> Self {
Self {
data: TableDataRef::new(FontData::default_table_data().as_bytes())
.unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
}
}
}
impl Format<u16> for SequenceContextFormat2<'_> {
const FORMAT: u16 = 2;
}
impl<'a> MinByteRange<'a> for SequenceContextFormat2<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.class_seq_rule_set_offsets_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for SequenceContextFormat2<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for SequenceContextFormat2<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self { data })
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct SequenceContextFormat2FixedHeader {
pub format: BigEndian<u16>,
pub coverage_offset: BigEndian<Offset16>,
pub class_def_offset: BigEndian<Offset16>,
pub class_seq_rule_set_count: BigEndian<u16>,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () = assert!(
std::mem::size_of::<SequenceContextFormat2FixedHeader>() <= SequenceContextFormat2::MIN_SIZE
);
#[derive(Clone)]
pub struct SequenceContextFormat2<'a> {
data: TableDataRef<'a, SequenceContextFormat2FixedHeader>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> SequenceContextFormat2<'a> {
pub const MIN_SIZE: usize =
(u16::RAW_BYTE_LEN + Offset16::RAW_BYTE_LEN + Offset16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN);
basic_table_impls!(impl_the_methods);
pub fn format(&self) -> u16 {
self.data.header().format.get()
}
pub fn coverage_offset(&self) -> Offset16 {
self.data.header().coverage_offset.get()
}
pub fn coverage(&self) -> Result<CoverageTable<'a>, ReadError> {
let data = self.offset_data();
self.coverage_offset().resolve(data)
}
pub fn class_def_offset(&self) -> Offset16 {
self.data.header().class_def_offset.get()
}
pub fn class_def(&self) -> Result<ClassDef<'a>, ReadError> {
let data = self.offset_data();
self.class_def_offset().resolve(data)
}
pub fn class_seq_rule_set_count(&self) -> u16 {
self.data.header().class_seq_rule_set_count.get()
}
pub fn class_seq_rule_set_offsets(&self) -> &'a [BigEndian<Nullable<Offset16>>] {
let range = self.class_seq_rule_set_offsets_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn class_seq_rule_sets(
&self,
) -> ArrayOfNullableOffsets<'a, ClassSequenceRuleSet<'a>, Offset16> {
let data = self.offset_data();
let offsets = self.class_seq_rule_set_offsets();
ArrayOfNullableOffsets::new(offsets, data, ())
}
pub fn format_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn coverage_offset_byte_range(&self) -> Range<usize> {
let start = self.format_byte_range().end;
let end = start + Offset16::RAW_BYTE_LEN;
start..end
}
pub fn class_def_offset_byte_range(&self) -> Range<usize> {
let start = self.coverage_offset_byte_range().end;
let end = start + Offset16::RAW_BYTE_LEN;
start..end
}
pub fn class_seq_rule_set_count_byte_range(&self) -> Range<usize> {
let start = self.class_def_offset_byte_range().end;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn class_seq_rule_set_offsets_byte_range(&self) -> Range<usize> {
let class_seq_rule_set_count = self.class_seq_rule_set_count();
let start = self.class_seq_rule_set_count_byte_range().end;
let end = start
+ (transforms::to_usize(class_seq_rule_set_count))
.saturating_mul(Offset16::RAW_BYTE_LEN);
start..end
}
}
impl<'a> MinByteRange<'a> for ClassSequenceRuleSet<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.class_seq_rule_offsets_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for ClassSequenceRuleSet<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for ClassSequenceRuleSet<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self { data })
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct ClassSequenceRuleSetFixedHeader {
pub class_seq_rule_count: BigEndian<u16>,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () = assert!(
std::mem::size_of::<ClassSequenceRuleSetFixedHeader>() <= ClassSequenceRuleSet::MIN_SIZE
);
#[derive(Clone)]
pub struct ClassSequenceRuleSet<'a> {
data: TableDataRef<'a, ClassSequenceRuleSetFixedHeader>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> ClassSequenceRuleSet<'a> {
pub const MIN_SIZE: usize = u16::RAW_BYTE_LEN;
basic_table_impls!(impl_the_methods);
pub fn class_seq_rule_count(&self) -> u16 {
self.data.header().class_seq_rule_count.get()
}
pub fn class_seq_rule_offsets(&self) -> &'a [BigEndian<Offset16>] {
let range = self.class_seq_rule_offsets_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn class_seq_rules(&self) -> ArrayOfOffsets<'a, ClassSequenceRule<'a>, Offset16> {
let data = self.offset_data();
let offsets = self.class_seq_rule_offsets();
ArrayOfOffsets::new(offsets, data, ())
}
pub fn class_seq_rule_count_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn class_seq_rule_offsets_byte_range(&self) -> Range<usize> {
let class_seq_rule_count = self.class_seq_rule_count();
let start = self.class_seq_rule_count_byte_range().end;
let end = start
+ (transforms::to_usize(class_seq_rule_count)).saturating_mul(Offset16::RAW_BYTE_LEN);
start..end
}
}
const _: () = assert!(FontData::default_data_long_enough(
ClassSequenceRuleSet::MIN_SIZE
));
impl Default for ClassSequenceRuleSet<'_> {
fn default() -> Self {
Self {
data: TableDataRef::new(FontData::default_table_data().as_bytes())
.unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
}
}
}
impl<'a> MinByteRange<'a> for ClassSequenceRule<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.seq_lookup_records_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for ClassSequenceRule<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for ClassSequenceRule<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self { data })
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct ClassSequenceRuleFixedHeader {
pub glyph_count: BigEndian<u16>,
pub seq_lookup_count: BigEndian<u16>,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () =
assert!(std::mem::size_of::<ClassSequenceRuleFixedHeader>() <= ClassSequenceRule::MIN_SIZE);
#[derive(Clone)]
pub struct ClassSequenceRule<'a> {
data: TableDataRef<'a, ClassSequenceRuleFixedHeader>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> ClassSequenceRule<'a> {
pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN);
basic_table_impls!(impl_the_methods);
pub fn glyph_count(&self) -> u16 {
self.data.header().glyph_count.get()
}
pub fn seq_lookup_count(&self) -> u16 {
self.data.header().seq_lookup_count.get()
}
pub fn input_sequence(&self) -> &'a [BigEndian<u16>] {
let range = self.input_sequence_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn seq_lookup_records(&self) -> &'a [SequenceLookupRecord] {
let range = self.seq_lookup_records_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn glyph_count_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn seq_lookup_count_byte_range(&self) -> Range<usize> {
let start = self.glyph_count_byte_range().end;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn input_sequence_byte_range(&self) -> Range<usize> {
let glyph_count = self.glyph_count();
let start = self.seq_lookup_count_byte_range().end;
let end =
start + (transforms::subtract(glyph_count, 1_usize)).saturating_mul(u16::RAW_BYTE_LEN);
start..end
}
pub fn seq_lookup_records_byte_range(&self) -> Range<usize> {
let seq_lookup_count = self.seq_lookup_count();
let start = self.input_sequence_byte_range().end;
let end = start
+ (transforms::to_usize(seq_lookup_count))
.saturating_mul(SequenceLookupRecord::RAW_BYTE_LEN);
start..end
}
}
const _: () = assert!(FontData::default_data_long_enough(
ClassSequenceRule::MIN_SIZE
));
impl Default for ClassSequenceRule<'_> {
fn default() -> Self {
Self {
data: TableDataRef::new(FontData::default_table_data().as_bytes())
.unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
}
}
}
impl Format<u16> for SequenceContextFormat3<'_> {
const FORMAT: u16 = 3;
}
impl<'a> MinByteRange<'a> for SequenceContextFormat3<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.seq_lookup_records_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for SequenceContextFormat3<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for SequenceContextFormat3<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self { data })
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct SequenceContextFormat3FixedHeader {
pub format: BigEndian<u16>,
pub glyph_count: BigEndian<u16>,
pub seq_lookup_count: BigEndian<u16>,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () = assert!(
std::mem::size_of::<SequenceContextFormat3FixedHeader>() <= SequenceContextFormat3::MIN_SIZE
);
#[derive(Clone)]
pub struct SequenceContextFormat3<'a> {
data: TableDataRef<'a, SequenceContextFormat3FixedHeader>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> SequenceContextFormat3<'a> {
pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN);
basic_table_impls!(impl_the_methods);
pub fn format(&self) -> u16 {
self.data.header().format.get()
}
pub fn glyph_count(&self) -> u16 {
self.data.header().glyph_count.get()
}
pub fn seq_lookup_count(&self) -> u16 {
self.data.header().seq_lookup_count.get()
}
pub fn coverage_offsets(&self) -> &'a [BigEndian<Offset16>] {
let range = self.coverage_offsets_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn coverages(&self) -> ArrayOfOffsets<'a, CoverageTable<'a>, Offset16> {
let data = self.offset_data();
let offsets = self.coverage_offsets();
ArrayOfOffsets::new(offsets, data, ())
}
pub fn seq_lookup_records(&self) -> &'a [SequenceLookupRecord] {
let range = self.seq_lookup_records_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn format_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn glyph_count_byte_range(&self) -> Range<usize> {
let start = self.format_byte_range().end;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn seq_lookup_count_byte_range(&self) -> Range<usize> {
let start = self.glyph_count_byte_range().end;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn coverage_offsets_byte_range(&self) -> Range<usize> {
let glyph_count = self.glyph_count();
let start = self.seq_lookup_count_byte_range().end;
let end =
start + (transforms::to_usize(glyph_count)).saturating_mul(Offset16::RAW_BYTE_LEN);
start..end
}
pub fn seq_lookup_records_byte_range(&self) -> Range<usize> {
let seq_lookup_count = self.seq_lookup_count();
let start = self.coverage_offsets_byte_range().end;
let end = start
+ (transforms::to_usize(seq_lookup_count))
.saturating_mul(SequenceLookupRecord::RAW_BYTE_LEN);
start..end
}
}
#[derive(Clone)]
pub enum SequenceContext<'a> {
Format1(SequenceContextFormat1<'a>),
Format2(SequenceContextFormat2<'a>),
Format3(SequenceContextFormat3<'a>),
Format4(SequenceContextFormat4<'a>),
Format5(SequenceContextFormat5<'a>),
Format6(SequenceContextFormat6<'a>),
}
impl Default for SequenceContext<'_> {
fn default() -> Self {
Self::Format1(Default::default())
}
}
impl<'a> SequenceContext<'a> {
pub fn offset_data(&self) -> FontData<'a> {
match self {
Self::Format1(item) => item.offset_data(),
Self::Format2(item) => item.offset_data(),
Self::Format3(item) => item.offset_data(),
Self::Format4(item) => item.offset_data(),
Self::Format5(item) => item.offset_data(),
Self::Format6(item) => item.offset_data(),
}
}
pub fn format(&self) -> u16 {
match self {
Self::Format1(item) => item.format(),
Self::Format2(item) => item.format(),
Self::Format3(item) => item.format(),
Self::Format4(item) => item.format(),
Self::Format5(item) => item.format(),
Self::Format6(item) => item.format(),
}
}
}
impl ReadArgs for SequenceContext<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for SequenceContext<'a> {
#[inline]
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
let format: u16 = data.read_at(0usize)?;
match format {
SequenceContextFormat1::FORMAT => Ok(Self::Format1(FontRead::read(data)?)),
SequenceContextFormat2::FORMAT => Ok(Self::Format2(FontRead::read(data)?)),
SequenceContextFormat3::FORMAT => Ok(Self::Format3(FontRead::read(data)?)),
SequenceContextFormat4::FORMAT => Ok(Self::Format4(FontRead::read(data)?)),
SequenceContextFormat5::FORMAT => Ok(Self::Format5(FontRead::read(data)?)),
SequenceContextFormat6::FORMAT => Ok(Self::Format6(FontRead::read(data)?)),
other => Err(ReadError::InvalidFormat(other.into())),
}
}
}
impl<'a> MinByteRange<'a> for SequenceContext<'a> {
fn min_byte_range(&self) -> Range<usize> {
match self {
Self::Format1(item) => item.min_byte_range(),
Self::Format2(item) => item.min_byte_range(),
Self::Format3(item) => item.min_byte_range(),
Self::Format4(item) => item.min_byte_range(),
Self::Format5(item) => item.min_byte_range(),
Self::Format6(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(),
Self::Format3(item) => item.min_table_bytes(),
Self::Format4(item) => item.min_table_bytes(),
Self::Format5(item) => item.min_table_bytes(),
Self::Format6(item) => item.min_table_bytes(),
}
}
}
impl Format<u16> for ChainedSequenceContextFormat1<'_> {
const FORMAT: u16 = 1;
}
impl<'a> MinByteRange<'a> for ChainedSequenceContextFormat1<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.chained_seq_rule_set_offsets_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for ChainedSequenceContextFormat1<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for ChainedSequenceContextFormat1<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self { data })
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct ChainedSequenceContextFormat1FixedHeader {
pub format: BigEndian<u16>,
pub coverage_offset: BigEndian<Offset16>,
pub chained_seq_rule_set_count: BigEndian<u16>,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () = assert!(
std::mem::size_of::<ChainedSequenceContextFormat1FixedHeader>()
<= ChainedSequenceContextFormat1::MIN_SIZE
);
#[derive(Clone)]
pub struct ChainedSequenceContextFormat1<'a> {
data: TableDataRef<'a, ChainedSequenceContextFormat1FixedHeader>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> ChainedSequenceContextFormat1<'a> {
pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + Offset16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN);
basic_table_impls!(impl_the_methods);
pub fn format(&self) -> u16 {
self.data.header().format.get()
}
pub fn coverage_offset(&self) -> Offset16 {
self.data.header().coverage_offset.get()
}
pub fn coverage(&self) -> Result<CoverageTable<'a>, ReadError> {
let data = self.offset_data();
self.coverage_offset().resolve(data)
}
pub fn chained_seq_rule_set_count(&self) -> u16 {
self.data.header().chained_seq_rule_set_count.get()
}
pub fn chained_seq_rule_set_offsets(&self) -> &'a [BigEndian<Nullable<Offset16>>] {
let range = self.chained_seq_rule_set_offsets_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn chained_seq_rule_sets(
&self,
) -> ArrayOfNullableOffsets<'a, ChainedSequenceRuleSet<'a>, Offset16> {
let data = self.offset_data();
let offsets = self.chained_seq_rule_set_offsets();
ArrayOfNullableOffsets::new(offsets, data, ())
}
pub fn format_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn coverage_offset_byte_range(&self) -> Range<usize> {
let start = self.format_byte_range().end;
let end = start + Offset16::RAW_BYTE_LEN;
start..end
}
pub fn chained_seq_rule_set_count_byte_range(&self) -> Range<usize> {
let start = self.coverage_offset_byte_range().end;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn chained_seq_rule_set_offsets_byte_range(&self) -> Range<usize> {
let chained_seq_rule_set_count = self.chained_seq_rule_set_count();
let start = self.chained_seq_rule_set_count_byte_range().end;
let end = start
+ (transforms::to_usize(chained_seq_rule_set_count))
.saturating_mul(Offset16::RAW_BYTE_LEN);
start..end
}
}
const _: () = assert!(FontData::default_data_long_enough(
ChainedSequenceContextFormat1::MIN_SIZE
));
impl Default for ChainedSequenceContextFormat1<'_> {
fn default() -> Self {
Self {
data: TableDataRef::new(FontData::default_format_1_u16_table_data().as_bytes())
.unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
}
}
}
impl<'a> MinByteRange<'a> for ChainedSequenceRuleSet<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.chained_seq_rule_offsets_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for ChainedSequenceRuleSet<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for ChainedSequenceRuleSet<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self { data })
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct ChainedSequenceRuleSetFixedHeader {
pub chained_seq_rule_count: BigEndian<u16>,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () = assert!(
std::mem::size_of::<ChainedSequenceRuleSetFixedHeader>() <= ChainedSequenceRuleSet::MIN_SIZE
);
#[derive(Clone)]
pub struct ChainedSequenceRuleSet<'a> {
data: TableDataRef<'a, ChainedSequenceRuleSetFixedHeader>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> ChainedSequenceRuleSet<'a> {
pub const MIN_SIZE: usize = u16::RAW_BYTE_LEN;
basic_table_impls!(impl_the_methods);
pub fn chained_seq_rule_count(&self) -> u16 {
self.data.header().chained_seq_rule_count.get()
}
pub fn chained_seq_rule_offsets(&self) -> &'a [BigEndian<Offset16>] {
let range = self.chained_seq_rule_offsets_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn chained_seq_rules(&self) -> ArrayOfOffsets<'a, ChainedSequenceRule<'a>, Offset16> {
let data = self.offset_data();
let offsets = self.chained_seq_rule_offsets();
ArrayOfOffsets::new(offsets, data, ())
}
pub fn chained_seq_rule_count_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn chained_seq_rule_offsets_byte_range(&self) -> Range<usize> {
let chained_seq_rule_count = self.chained_seq_rule_count();
let start = self.chained_seq_rule_count_byte_range().end;
let end = start
+ (transforms::to_usize(chained_seq_rule_count)).saturating_mul(Offset16::RAW_BYTE_LEN);
start..end
}
}
const _: () = assert!(FontData::default_data_long_enough(
ChainedSequenceRuleSet::MIN_SIZE
));
impl Default for ChainedSequenceRuleSet<'_> {
fn default() -> Self {
Self {
data: TableDataRef::new(FontData::default_table_data().as_bytes())
.unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
}
}
}
impl<'a> MinByteRange<'a> for ChainedSequenceRule<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.seq_lookup_records_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for ChainedSequenceRule<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for ChainedSequenceRule<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self { data })
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct ChainedSequenceRuleFixedHeader {
pub backtrack_glyph_count: BigEndian<u16>,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () =
assert!(std::mem::size_of::<ChainedSequenceRuleFixedHeader>() <= ChainedSequenceRule::MIN_SIZE);
#[derive(Clone)]
pub struct ChainedSequenceRule<'a> {
data: TableDataRef<'a, ChainedSequenceRuleFixedHeader>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> ChainedSequenceRule<'a> {
pub const MIN_SIZE: usize =
(u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN);
basic_table_impls!(impl_the_methods);
pub fn backtrack_glyph_count(&self) -> u16 {
self.data.header().backtrack_glyph_count.get()
}
pub fn backtrack_sequence(&self) -> &'a [BigEndian<GlyphId16>] {
let range = self.backtrack_sequence_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn input_glyph_count(&self) -> u16 {
let range = self.input_glyph_count_byte_range();
self.offset_data()
.read_at(range.start)
.ok()
.unwrap_or_default()
}
pub fn input_sequence(&self) -> &'a [BigEndian<GlyphId16>] {
let range = self.input_sequence_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn lookahead_glyph_count(&self) -> u16 {
let range = self.lookahead_glyph_count_byte_range();
self.offset_data()
.read_at(range.start)
.ok()
.unwrap_or_default()
}
pub fn lookahead_sequence(&self) -> &'a [BigEndian<GlyphId16>] {
let range = self.lookahead_sequence_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn seq_lookup_count(&self) -> u16 {
let range = self.seq_lookup_count_byte_range();
self.offset_data()
.read_at(range.start)
.ok()
.unwrap_or_default()
}
pub fn seq_lookup_records(&self) -> &'a [SequenceLookupRecord] {
let range = self.seq_lookup_records_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn backtrack_glyph_count_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn backtrack_sequence_byte_range(&self) -> Range<usize> {
let backtrack_glyph_count = self.backtrack_glyph_count();
let start = self.backtrack_glyph_count_byte_range().end;
let end = start
+ (transforms::to_usize(backtrack_glyph_count)).saturating_mul(GlyphId16::RAW_BYTE_LEN);
start..end
}
pub fn input_glyph_count_byte_range(&self) -> Range<usize> {
let start = self.backtrack_sequence_byte_range().end;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn input_sequence_byte_range(&self) -> Range<usize> {
let input_glyph_count = self.input_glyph_count();
let start = self.input_glyph_count_byte_range().end;
let end = start
+ (transforms::subtract(input_glyph_count, 1_usize))
.saturating_mul(GlyphId16::RAW_BYTE_LEN);
start..end
}
pub fn lookahead_glyph_count_byte_range(&self) -> Range<usize> {
let start = self.input_sequence_byte_range().end;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn lookahead_sequence_byte_range(&self) -> Range<usize> {
let lookahead_glyph_count = self.lookahead_glyph_count();
let start = self.lookahead_glyph_count_byte_range().end;
let end = start
+ (transforms::to_usize(lookahead_glyph_count)).saturating_mul(GlyphId16::RAW_BYTE_LEN);
start..end
}
pub fn seq_lookup_count_byte_range(&self) -> Range<usize> {
let start = self.lookahead_sequence_byte_range().end;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn seq_lookup_records_byte_range(&self) -> Range<usize> {
let seq_lookup_count = self.seq_lookup_count();
let start = self.seq_lookup_count_byte_range().end;
let end = start
+ (transforms::to_usize(seq_lookup_count))
.saturating_mul(SequenceLookupRecord::RAW_BYTE_LEN);
start..end
}
}
const _: () = assert!(FontData::default_data_long_enough(
ChainedSequenceRule::MIN_SIZE
));
impl Default for ChainedSequenceRule<'_> {
fn default() -> Self {
Self {
data: TableDataRef::new(FontData::default_table_data().as_bytes())
.unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
}
}
}
impl Format<u16> for ChainedSequenceContextFormat2<'_> {
const FORMAT: u16 = 2;
}
impl<'a> MinByteRange<'a> for ChainedSequenceContextFormat2<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.chained_class_seq_rule_set_offsets_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for ChainedSequenceContextFormat2<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for ChainedSequenceContextFormat2<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self { data })
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct ChainedSequenceContextFormat2FixedHeader {
pub format: BigEndian<u16>,
pub coverage_offset: BigEndian<Offset16>,
pub backtrack_class_def_offset: BigEndian<Offset16>,
pub input_class_def_offset: BigEndian<Offset16>,
pub lookahead_class_def_offset: BigEndian<Offset16>,
pub chained_class_seq_rule_set_count: BigEndian<u16>,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () = assert!(
std::mem::size_of::<ChainedSequenceContextFormat2FixedHeader>()
<= ChainedSequenceContextFormat2::MIN_SIZE
);
#[derive(Clone)]
pub struct ChainedSequenceContextFormat2<'a> {
data: TableDataRef<'a, ChainedSequenceContextFormat2FixedHeader>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> ChainedSequenceContextFormat2<'a> {
pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN
+ Offset16::RAW_BYTE_LEN
+ Offset16::RAW_BYTE_LEN
+ Offset16::RAW_BYTE_LEN
+ Offset16::RAW_BYTE_LEN
+ u16::RAW_BYTE_LEN);
basic_table_impls!(impl_the_methods);
pub fn format(&self) -> u16 {
self.data.header().format.get()
}
pub fn coverage_offset(&self) -> Offset16 {
self.data.header().coverage_offset.get()
}
pub fn coverage(&self) -> Result<CoverageTable<'a>, ReadError> {
let data = self.offset_data();
self.coverage_offset().resolve(data)
}
pub fn backtrack_class_def_offset(&self) -> Offset16 {
self.data.header().backtrack_class_def_offset.get()
}
pub fn backtrack_class_def(&self) -> Result<ClassDef<'a>, ReadError> {
let data = self.offset_data();
self.backtrack_class_def_offset().resolve(data)
}
pub fn input_class_def_offset(&self) -> Offset16 {
self.data.header().input_class_def_offset.get()
}
pub fn input_class_def(&self) -> Result<ClassDef<'a>, ReadError> {
let data = self.offset_data();
self.input_class_def_offset().resolve(data)
}
pub fn lookahead_class_def_offset(&self) -> Offset16 {
self.data.header().lookahead_class_def_offset.get()
}
pub fn lookahead_class_def(&self) -> Result<ClassDef<'a>, ReadError> {
let data = self.offset_data();
self.lookahead_class_def_offset().resolve(data)
}
pub fn chained_class_seq_rule_set_count(&self) -> u16 {
self.data.header().chained_class_seq_rule_set_count.get()
}
pub fn chained_class_seq_rule_set_offsets(&self) -> &'a [BigEndian<Nullable<Offset16>>] {
let range = self.chained_class_seq_rule_set_offsets_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn chained_class_seq_rule_sets(
&self,
) -> ArrayOfNullableOffsets<'a, ChainedClassSequenceRuleSet<'a>, Offset16> {
let data = self.offset_data();
let offsets = self.chained_class_seq_rule_set_offsets();
ArrayOfNullableOffsets::new(offsets, data, ())
}
pub fn format_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn coverage_offset_byte_range(&self) -> Range<usize> {
let start = self.format_byte_range().end;
let end = start + Offset16::RAW_BYTE_LEN;
start..end
}
pub fn backtrack_class_def_offset_byte_range(&self) -> Range<usize> {
let start = self.coverage_offset_byte_range().end;
let end = start + Offset16::RAW_BYTE_LEN;
start..end
}
pub fn input_class_def_offset_byte_range(&self) -> Range<usize> {
let start = self.backtrack_class_def_offset_byte_range().end;
let end = start + Offset16::RAW_BYTE_LEN;
start..end
}
pub fn lookahead_class_def_offset_byte_range(&self) -> Range<usize> {
let start = self.input_class_def_offset_byte_range().end;
let end = start + Offset16::RAW_BYTE_LEN;
start..end
}
pub fn chained_class_seq_rule_set_count_byte_range(&self) -> Range<usize> {
let start = self.lookahead_class_def_offset_byte_range().end;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn chained_class_seq_rule_set_offsets_byte_range(&self) -> Range<usize> {
let chained_class_seq_rule_set_count = self.chained_class_seq_rule_set_count();
let start = self.chained_class_seq_rule_set_count_byte_range().end;
let end = start
+ (transforms::to_usize(chained_class_seq_rule_set_count))
.saturating_mul(Offset16::RAW_BYTE_LEN);
start..end
}
}
impl<'a> MinByteRange<'a> for ChainedClassSequenceRuleSet<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.chained_class_seq_rule_offsets_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for ChainedClassSequenceRuleSet<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for ChainedClassSequenceRuleSet<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self { data })
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct ChainedClassSequenceRuleSetFixedHeader {
pub chained_class_seq_rule_count: BigEndian<u16>,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () = assert!(
std::mem::size_of::<ChainedClassSequenceRuleSetFixedHeader>()
<= ChainedClassSequenceRuleSet::MIN_SIZE
);
#[derive(Clone)]
pub struct ChainedClassSequenceRuleSet<'a> {
data: TableDataRef<'a, ChainedClassSequenceRuleSetFixedHeader>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> ChainedClassSequenceRuleSet<'a> {
pub const MIN_SIZE: usize = u16::RAW_BYTE_LEN;
basic_table_impls!(impl_the_methods);
pub fn chained_class_seq_rule_count(&self) -> u16 {
self.data.header().chained_class_seq_rule_count.get()
}
pub fn chained_class_seq_rule_offsets(&self) -> &'a [BigEndian<Offset16>] {
let range = self.chained_class_seq_rule_offsets_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn chained_class_seq_rules(
&self,
) -> ArrayOfOffsets<'a, ChainedClassSequenceRule<'a>, Offset16> {
let data = self.offset_data();
let offsets = self.chained_class_seq_rule_offsets();
ArrayOfOffsets::new(offsets, data, ())
}
pub fn chained_class_seq_rule_count_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn chained_class_seq_rule_offsets_byte_range(&self) -> Range<usize> {
let chained_class_seq_rule_count = self.chained_class_seq_rule_count();
let start = self.chained_class_seq_rule_count_byte_range().end;
let end = start
+ (transforms::to_usize(chained_class_seq_rule_count))
.saturating_mul(Offset16::RAW_BYTE_LEN);
start..end
}
}
const _: () = assert!(FontData::default_data_long_enough(
ChainedClassSequenceRuleSet::MIN_SIZE
));
impl Default for ChainedClassSequenceRuleSet<'_> {
fn default() -> Self {
Self {
data: TableDataRef::new(FontData::default_table_data().as_bytes())
.unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
}
}
}
impl<'a> MinByteRange<'a> for ChainedClassSequenceRule<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.seq_lookup_records_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for ChainedClassSequenceRule<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for ChainedClassSequenceRule<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self { data })
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct ChainedClassSequenceRuleFixedHeader {
pub backtrack_glyph_count: BigEndian<u16>,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () = assert!(
std::mem::size_of::<ChainedClassSequenceRuleFixedHeader>()
<= ChainedClassSequenceRule::MIN_SIZE
);
#[derive(Clone)]
pub struct ChainedClassSequenceRule<'a> {
data: TableDataRef<'a, ChainedClassSequenceRuleFixedHeader>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> ChainedClassSequenceRule<'a> {
pub const MIN_SIZE: usize =
(u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN);
basic_table_impls!(impl_the_methods);
pub fn backtrack_glyph_count(&self) -> u16 {
self.data.header().backtrack_glyph_count.get()
}
pub fn backtrack_sequence(&self) -> &'a [BigEndian<u16>] {
let range = self.backtrack_sequence_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn input_glyph_count(&self) -> u16 {
let range = self.input_glyph_count_byte_range();
self.offset_data()
.read_at(range.start)
.ok()
.unwrap_or_default()
}
pub fn input_sequence(&self) -> &'a [BigEndian<u16>] {
let range = self.input_sequence_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn lookahead_glyph_count(&self) -> u16 {
let range = self.lookahead_glyph_count_byte_range();
self.offset_data()
.read_at(range.start)
.ok()
.unwrap_or_default()
}
pub fn lookahead_sequence(&self) -> &'a [BigEndian<u16>] {
let range = self.lookahead_sequence_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn seq_lookup_count(&self) -> u16 {
let range = self.seq_lookup_count_byte_range();
self.offset_data()
.read_at(range.start)
.ok()
.unwrap_or_default()
}
pub fn seq_lookup_records(&self) -> &'a [SequenceLookupRecord] {
let range = self.seq_lookup_records_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn backtrack_glyph_count_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn backtrack_sequence_byte_range(&self) -> Range<usize> {
let backtrack_glyph_count = self.backtrack_glyph_count();
let start = self.backtrack_glyph_count_byte_range().end;
let end =
start + (transforms::to_usize(backtrack_glyph_count)).saturating_mul(u16::RAW_BYTE_LEN);
start..end
}
pub fn input_glyph_count_byte_range(&self) -> Range<usize> {
let start = self.backtrack_sequence_byte_range().end;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn input_sequence_byte_range(&self) -> Range<usize> {
let input_glyph_count = self.input_glyph_count();
let start = self.input_glyph_count_byte_range().end;
let end = start
+ (transforms::subtract(input_glyph_count, 1_usize)).saturating_mul(u16::RAW_BYTE_LEN);
start..end
}
pub fn lookahead_glyph_count_byte_range(&self) -> Range<usize> {
let start = self.input_sequence_byte_range().end;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn lookahead_sequence_byte_range(&self) -> Range<usize> {
let lookahead_glyph_count = self.lookahead_glyph_count();
let start = self.lookahead_glyph_count_byte_range().end;
let end =
start + (transforms::to_usize(lookahead_glyph_count)).saturating_mul(u16::RAW_BYTE_LEN);
start..end
}
pub fn seq_lookup_count_byte_range(&self) -> Range<usize> {
let start = self.lookahead_sequence_byte_range().end;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn seq_lookup_records_byte_range(&self) -> Range<usize> {
let seq_lookup_count = self.seq_lookup_count();
let start = self.seq_lookup_count_byte_range().end;
let end = start
+ (transforms::to_usize(seq_lookup_count))
.saturating_mul(SequenceLookupRecord::RAW_BYTE_LEN);
start..end
}
}
const _: () = assert!(FontData::default_data_long_enough(
ChainedClassSequenceRule::MIN_SIZE
));
impl Default for ChainedClassSequenceRule<'_> {
fn default() -> Self {
Self {
data: TableDataRef::new(FontData::default_table_data().as_bytes())
.unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
}
}
}
impl Format<u16> for ChainedSequenceContextFormat3<'_> {
const FORMAT: u16 = 3;
}
impl<'a> MinByteRange<'a> for ChainedSequenceContextFormat3<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.seq_lookup_records_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for ChainedSequenceContextFormat3<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for ChainedSequenceContextFormat3<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self { data })
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct ChainedSequenceContextFormat3FixedHeader {
pub format: BigEndian<u16>,
pub backtrack_glyph_count: BigEndian<u16>,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () = assert!(
std::mem::size_of::<ChainedSequenceContextFormat3FixedHeader>()
<= ChainedSequenceContextFormat3::MIN_SIZE
);
#[derive(Clone)]
pub struct ChainedSequenceContextFormat3<'a> {
data: TableDataRef<'a, ChainedSequenceContextFormat3FixedHeader>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> ChainedSequenceContextFormat3<'a> {
pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN
+ u16::RAW_BYTE_LEN
+ u16::RAW_BYTE_LEN
+ u16::RAW_BYTE_LEN
+ u16::RAW_BYTE_LEN);
basic_table_impls!(impl_the_methods);
pub fn format(&self) -> u16 {
self.data.header().format.get()
}
pub fn backtrack_glyph_count(&self) -> u16 {
self.data.header().backtrack_glyph_count.get()
}
pub fn backtrack_coverage_offsets(&self) -> &'a [BigEndian<Offset16>] {
let range = self.backtrack_coverage_offsets_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn backtrack_coverages(&self) -> ArrayOfOffsets<'a, CoverageTable<'a>, Offset16> {
let data = self.offset_data();
let offsets = self.backtrack_coverage_offsets();
ArrayOfOffsets::new(offsets, data, ())
}
pub fn input_glyph_count(&self) -> u16 {
let range = self.input_glyph_count_byte_range();
self.offset_data()
.read_at(range.start)
.ok()
.unwrap_or_default()
}
pub fn input_coverage_offsets(&self) -> &'a [BigEndian<Offset16>] {
let range = self.input_coverage_offsets_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn input_coverages(&self) -> ArrayOfOffsets<'a, CoverageTable<'a>, Offset16> {
let data = self.offset_data();
let offsets = self.input_coverage_offsets();
ArrayOfOffsets::new(offsets, data, ())
}
pub fn lookahead_glyph_count(&self) -> u16 {
let range = self.lookahead_glyph_count_byte_range();
self.offset_data()
.read_at(range.start)
.ok()
.unwrap_or_default()
}
pub fn lookahead_coverage_offsets(&self) -> &'a [BigEndian<Offset16>] {
let range = self.lookahead_coverage_offsets_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn lookahead_coverages(&self) -> ArrayOfOffsets<'a, CoverageTable<'a>, Offset16> {
let data = self.offset_data();
let offsets = self.lookahead_coverage_offsets();
ArrayOfOffsets::new(offsets, data, ())
}
pub fn seq_lookup_count(&self) -> u16 {
let range = self.seq_lookup_count_byte_range();
self.offset_data()
.read_at(range.start)
.ok()
.unwrap_or_default()
}
pub fn seq_lookup_records(&self) -> &'a [SequenceLookupRecord] {
let range = self.seq_lookup_records_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn format_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn backtrack_glyph_count_byte_range(&self) -> Range<usize> {
let start = self.format_byte_range().end;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn backtrack_coverage_offsets_byte_range(&self) -> Range<usize> {
let backtrack_glyph_count = self.backtrack_glyph_count();
let start = self.backtrack_glyph_count_byte_range().end;
let end = start
+ (transforms::to_usize(backtrack_glyph_count)).saturating_mul(Offset16::RAW_BYTE_LEN);
start..end
}
pub fn input_glyph_count_byte_range(&self) -> Range<usize> {
let start = self.backtrack_coverage_offsets_byte_range().end;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn input_coverage_offsets_byte_range(&self) -> Range<usize> {
let input_glyph_count = self.input_glyph_count();
let start = self.input_glyph_count_byte_range().end;
let end = start
+ (transforms::to_usize(input_glyph_count)).saturating_mul(Offset16::RAW_BYTE_LEN);
start..end
}
pub fn lookahead_glyph_count_byte_range(&self) -> Range<usize> {
let start = self.input_coverage_offsets_byte_range().end;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn lookahead_coverage_offsets_byte_range(&self) -> Range<usize> {
let lookahead_glyph_count = self.lookahead_glyph_count();
let start = self.lookahead_glyph_count_byte_range().end;
let end = start
+ (transforms::to_usize(lookahead_glyph_count)).saturating_mul(Offset16::RAW_BYTE_LEN);
start..end
}
pub fn seq_lookup_count_byte_range(&self) -> Range<usize> {
let start = self.lookahead_coverage_offsets_byte_range().end;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn seq_lookup_records_byte_range(&self) -> Range<usize> {
let seq_lookup_count = self.seq_lookup_count();
let start = self.seq_lookup_count_byte_range().end;
let end = start
+ (transforms::to_usize(seq_lookup_count))
.saturating_mul(SequenceLookupRecord::RAW_BYTE_LEN);
start..end
}
}
#[derive(Clone)]
pub enum ChainedSequenceContext<'a> {
Format1(ChainedSequenceContextFormat1<'a>),
Format2(ChainedSequenceContextFormat2<'a>),
Format3(ChainedSequenceContextFormat3<'a>),
Format4(ChainedSequenceContextFormat4<'a>),
Format5(ChainedSequenceContextFormat5<'a>),
}
impl Default for ChainedSequenceContext<'_> {
fn default() -> Self {
Self::Format1(Default::default())
}
}
impl<'a> ChainedSequenceContext<'a> {
pub fn offset_data(&self) -> FontData<'a> {
match self {
Self::Format1(item) => item.offset_data(),
Self::Format2(item) => item.offset_data(),
Self::Format3(item) => item.offset_data(),
Self::Format4(item) => item.offset_data(),
Self::Format5(item) => item.offset_data(),
}
}
pub fn format(&self) -> u16 {
match self {
Self::Format1(item) => item.format(),
Self::Format2(item) => item.format(),
Self::Format3(item) => item.format(),
Self::Format4(item) => item.format(),
Self::Format5(item) => item.format(),
}
}
}
impl ReadArgs for ChainedSequenceContext<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for ChainedSequenceContext<'a> {
#[inline]
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
let format: u16 = data.read_at(0usize)?;
match format {
ChainedSequenceContextFormat1::FORMAT => Ok(Self::Format1(FontRead::read(data)?)),
ChainedSequenceContextFormat2::FORMAT => Ok(Self::Format2(FontRead::read(data)?)),
ChainedSequenceContextFormat3::FORMAT => Ok(Self::Format3(FontRead::read(data)?)),
ChainedSequenceContextFormat4::FORMAT => Ok(Self::Format4(FontRead::read(data)?)),
ChainedSequenceContextFormat5::FORMAT => Ok(Self::Format5(FontRead::read(data)?)),
other => Err(ReadError::InvalidFormat(other.into())),
}
}
}
impl<'a> MinByteRange<'a> for ChainedSequenceContext<'a> {
fn min_byte_range(&self) -> Range<usize> {
match self {
Self::Format1(item) => item.min_byte_range(),
Self::Format2(item) => item.min_byte_range(),
Self::Format3(item) => item.min_byte_range(),
Self::Format4(item) => item.min_byte_range(),
Self::Format5(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(),
Self::Format3(item) => item.min_table_bytes(),
Self::Format4(item) => item.min_table_bytes(),
Self::Format5(item) => item.min_table_bytes(),
}
}
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[repr(u16)]
#[allow(clippy::manual_non_exhaustive)]
pub enum DeltaFormat {
#[default]
Local2BitDeltas = 0x0001,
Local4BitDeltas = 0x0002,
Local8BitDeltas = 0x0003,
VariationIndex = 0x8000,
#[doc(hidden)]
Unknown,
}
impl DeltaFormat {
pub fn new(raw: u16) -> Self {
match raw {
0x0001 => Self::Local2BitDeltas,
0x0002 => Self::Local4BitDeltas,
0x0003 => Self::Local8BitDeltas,
0x8000 => Self::VariationIndex,
_ => Self::Unknown,
}
}
}
impl font_types::Scalar for DeltaFormat {
type Raw = <u16 as font_types::Scalar>::Raw;
fn to_raw(self) -> Self::Raw {
(self as u16).to_raw()
}
fn from_raw(raw: Self::Raw) -> Self {
let t = <u16>::from_raw(raw);
Self::new(t)
}
}
impl<'a> MinByteRange<'a> for Device<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.delta_value_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for Device<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for Device<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self { data })
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct DeviceFixedHeader {
pub start_size: BigEndian<u16>,
pub end_size: BigEndian<u16>,
pub delta_format: BigEndian<DeltaFormat>,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () = assert!(std::mem::size_of::<DeviceFixedHeader>() <= Device::MIN_SIZE);
#[derive(Clone)]
pub struct Device<'a> {
data: TableDataRef<'a, DeviceFixedHeader>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> Device<'a> {
pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + DeltaFormat::RAW_BYTE_LEN);
basic_table_impls!(impl_the_methods);
pub fn start_size(&self) -> u16 {
self.data.header().start_size.get()
}
pub fn end_size(&self) -> u16 {
self.data.header().end_size.get()
}
pub fn delta_format(&self) -> DeltaFormat {
self.data.header().delta_format.get()
}
pub fn delta_value(&self) -> &'a [BigEndian<u16>] {
let range = self.delta_value_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn start_size_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn end_size_byte_range(&self) -> Range<usize> {
let start = self.start_size_byte_range().end;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn delta_format_byte_range(&self) -> Range<usize> {
let start = self.end_size_byte_range().end;
let end = start + DeltaFormat::RAW_BYTE_LEN;
start..end
}
pub fn delta_value_byte_range(&self) -> Range<usize> {
let delta_format = self.delta_format();
let start_size = self.start_size();
let end_size = self.end_size();
let start = self.delta_format_byte_range().end;
let end = start
+ (DeltaFormat::value_count(delta_format, start_size, end_size))
.saturating_mul(u16::RAW_BYTE_LEN);
start..end
}
}
const _: () = assert!(FontData::default_data_long_enough(Device::MIN_SIZE));
impl Default for Device<'_> {
fn default() -> Self {
Self {
data: TableDataRef::new(FontData::default_table_data().as_bytes())
.unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
}
}
}
impl<'a> MinByteRange<'a> for VariationIndex<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.delta_format_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for VariationIndex<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for VariationIndex<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self { data })
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct VariationIndexFixedHeader {
pub delta_set_outer_index: BigEndian<u16>,
pub delta_set_inner_index: BigEndian<u16>,
pub delta_format: BigEndian<DeltaFormat>,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () = assert!(std::mem::size_of::<VariationIndexFixedHeader>() <= VariationIndex::MIN_SIZE);
#[derive(Clone)]
pub struct VariationIndex<'a> {
data: TableDataRef<'a, VariationIndexFixedHeader>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> VariationIndex<'a> {
pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + DeltaFormat::RAW_BYTE_LEN);
basic_table_impls!(impl_the_methods);
pub fn delta_set_outer_index(&self) -> u16 {
self.data.header().delta_set_outer_index.get()
}
pub fn delta_set_inner_index(&self) -> u16 {
self.data.header().delta_set_inner_index.get()
}
pub fn delta_format(&self) -> DeltaFormat {
self.data.header().delta_format.get()
}
pub fn delta_set_outer_index_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn delta_set_inner_index_byte_range(&self) -> Range<usize> {
let start = self.delta_set_outer_index_byte_range().end;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn delta_format_byte_range(&self) -> Range<usize> {
let start = self.delta_set_inner_index_byte_range().end;
let end = start + DeltaFormat::RAW_BYTE_LEN;
start..end
}
}
const _: () = assert!(FontData::default_data_long_enough(VariationIndex::MIN_SIZE));
impl Default for VariationIndex<'_> {
fn default() -> Self {
Self {
data: TableDataRef::new(FontData::default_table_data().as_bytes())
.unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
}
}
}
#[derive(Clone)]
pub enum DeviceOrVariationIndex<'a> {
Device(Device<'a>),
VariationIndex(VariationIndex<'a>),
}
impl Default for DeviceOrVariationIndex<'_> {
fn default() -> Self {
Self::Device(Default::default())
}
}
impl<'a> DeviceOrVariationIndex<'a> {
pub fn offset_data(&self) -> FontData<'a> {
match self {
Self::Device(item) => item.offset_data(),
Self::VariationIndex(item) => item.offset_data(),
}
}
}
impl ReadArgs for DeviceOrVariationIndex<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for DeviceOrVariationIndex<'a> {
#[inline]
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
let format: DeltaFormat = data.read_at(4usize)?;
#[allow(clippy::redundant_guards)]
match format {
format if format != DeltaFormat::VariationIndex => {
Ok(Self::Device(FontRead::read(data)?))
}
format if format == DeltaFormat::VariationIndex => {
Ok(Self::VariationIndex(FontRead::read(data)?))
}
other => Err(ReadError::InvalidFormat(other.into())),
}
}
}
impl<'a> MinByteRange<'a> for DeviceOrVariationIndex<'a> {
fn min_byte_range(&self) -> Range<usize> {
match self {
Self::Device(item) => item.min_byte_range(),
Self::VariationIndex(item) => item.min_byte_range(),
}
}
fn min_table_bytes(&self) -> &'a [u8] {
match self {
Self::Device(item) => item.min_table_bytes(),
Self::VariationIndex(item) => item.min_table_bytes(),
}
}
}
impl<'a> MinByteRange<'a> for FeatureVariations<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.feature_variation_records_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for FeatureVariations<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for FeatureVariations<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self { data })
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct FeatureVariationsFixedHeader {
pub version: BigEndian<MajorMinor>,
pub feature_variation_record_count: BigEndian<u32>,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () =
assert!(std::mem::size_of::<FeatureVariationsFixedHeader>() <= FeatureVariations::MIN_SIZE);
#[derive(Clone)]
pub struct FeatureVariations<'a> {
data: TableDataRef<'a, FeatureVariationsFixedHeader>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> FeatureVariations<'a> {
pub const MIN_SIZE: usize = (MajorMinor::RAW_BYTE_LEN + u32::RAW_BYTE_LEN);
basic_table_impls!(impl_the_methods);
pub fn version(&self) -> MajorMinor {
self.data.header().version.get()
}
pub fn feature_variation_record_count(&self) -> u32 {
self.data.header().feature_variation_record_count.get()
}
pub fn feature_variation_records(&self) -> &'a [FeatureVariationRecord] {
let range = self.feature_variation_records_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn lookup_variation_record_count(&self) -> Option<u32> {
let range = self.lookup_variation_record_count_byte_range();
(!range.is_empty())
.then(|| self.offset_data().read_at(range.start).ok())
.flatten()
}
pub fn version_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + MajorMinor::RAW_BYTE_LEN;
start..end
}
pub fn feature_variation_record_count_byte_range(&self) -> Range<usize> {
let start = self.version_byte_range().end;
let end = start + u32::RAW_BYTE_LEN;
start..end
}
pub fn feature_variation_records_byte_range(&self) -> Range<usize> {
let feature_variation_record_count = self.feature_variation_record_count();
let start = self.feature_variation_record_count_byte_range().end;
let end = start
+ (transforms::to_usize(feature_variation_record_count))
.saturating_mul(FeatureVariationRecord::RAW_BYTE_LEN);
start..end
}
pub fn lookup_variation_record_count_byte_range(&self) -> Range<usize> {
let start = self.feature_variation_records_byte_range().end;
let end = if self.version().compatible((1u16, 1u16)) {
start + u32::RAW_BYTE_LEN
} else {
start
};
start..end
}
pub fn lookup_variation_records_byte_range(&self) -> Range<usize> {
let lookup_variation_record_count =
self.lookup_variation_record_count().unwrap_or_default();
let start = self.lookup_variation_record_count_byte_range().end;
let end = if self.version().compatible((1u16, 1u16)) {
start
+ (transforms::to_usize(lookup_variation_record_count))
.saturating_mul(LookupVariationRecord::RAW_BYTE_LEN)
} else {
start
};
start..end
}
}
const _: () = assert!(FontData::default_data_long_enough(
FeatureVariations::MIN_SIZE
));
impl Default for FeatureVariations<'_> {
fn default() -> Self {
Self {
data: TableDataRef::new(FontData::default_table_data().as_bytes())
.unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
}
}
}
#[derive(Clone, Debug, Copy, bytemuck :: AnyBitPattern)]
#[repr(C)]
#[repr(packed)]
pub struct FeatureVariationRecord {
pub condition_set_offset: BigEndian<Nullable<Offset32>>,
pub feature_table_substitution_offset: BigEndian<Nullable<Offset32>>,
}
impl FeatureVariationRecord {
pub fn condition_set_offset(&self) -> Nullable<Offset32> {
self.condition_set_offset.get()
}
pub fn condition_set<'a>(
&self,
data: FontData<'a>,
) -> Option<Result<ConditionSet<'a>, ReadError>> {
self.condition_set_offset().resolve(data)
}
pub fn feature_table_substitution_offset(&self) -> Nullable<Offset32> {
self.feature_table_substitution_offset.get()
}
pub fn feature_table_substitution<'a>(
&self,
data: FontData<'a>,
) -> Option<Result<FeatureTableSubstitution<'a>, ReadError>> {
self.feature_table_substitution_offset().resolve(data)
}
}
impl FixedSize for FeatureVariationRecord {
const RAW_BYTE_LEN: usize = Offset32::RAW_BYTE_LEN + Offset32::RAW_BYTE_LEN;
}
#[derive(Clone, Debug, Copy, bytemuck :: AnyBitPattern)]
#[repr(C)]
#[repr(packed)]
pub struct LookupVariationRecord {
pub feature_index: BigEndian<u16>,
pub feature_lookups_offset: BigEndian<Offset32>,
}
impl LookupVariationRecord {
pub fn feature_index(&self) -> u16 {
self.feature_index.get()
}
pub fn feature_lookups_offset(&self) -> Offset32 {
self.feature_lookups_offset.get()
}
pub fn feature_lookups<'a>(&self, data: FontData<'a>) -> Result<FeatureLookups<'a>, ReadError> {
self.feature_lookups_offset().resolve(data)
}
}
impl FixedSize for LookupVariationRecord {
const RAW_BYTE_LEN: usize = u16::RAW_BYTE_LEN + Offset32::RAW_BYTE_LEN;
}
impl<'a> MinByteRange<'a> for FeatureLookups<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.lookup_condition_records_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for FeatureLookups<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for FeatureLookups<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self { data })
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct FeatureLookupsFixedHeader {
pub version: BigEndian<MajorMinor>,
pub flags: BigEndian<FeatureLookupsFlags>,
pub lookup_condition_count: BigEndian<u32>,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () = assert!(std::mem::size_of::<FeatureLookupsFixedHeader>() <= FeatureLookups::MIN_SIZE);
#[derive(Clone)]
pub struct FeatureLookups<'a> {
data: TableDataRef<'a, FeatureLookupsFixedHeader>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> FeatureLookups<'a> {
pub const MIN_SIZE: usize =
(MajorMinor::RAW_BYTE_LEN + FeatureLookupsFlags::RAW_BYTE_LEN + u32::RAW_BYTE_LEN);
basic_table_impls!(impl_the_methods);
pub fn version(&self) -> MajorMinor {
self.data.header().version.get()
}
pub fn flags(&self) -> FeatureLookupsFlags {
self.data.header().flags.get()
}
pub fn lookup_condition_count(&self) -> u32 {
self.data.header().lookup_condition_count.get()
}
pub fn lookup_condition_records(&self) -> &'a [LookupConditionRecord] {
let range = self.lookup_condition_records_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn version_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + MajorMinor::RAW_BYTE_LEN;
start..end
}
pub fn flags_byte_range(&self) -> Range<usize> {
let start = self.version_byte_range().end;
let end = start + FeatureLookupsFlags::RAW_BYTE_LEN;
start..end
}
pub fn lookup_condition_count_byte_range(&self) -> Range<usize> {
let start = self.flags_byte_range().end;
let end = start + u32::RAW_BYTE_LEN;
start..end
}
pub fn lookup_condition_records_byte_range(&self) -> Range<usize> {
let lookup_condition_count = self.lookup_condition_count();
let start = self.lookup_condition_count_byte_range().end;
let end = start
+ (transforms::to_usize(lookup_condition_count))
.saturating_mul(LookupConditionRecord::RAW_BYTE_LEN);
start..end
}
}
const _: () = assert!(FontData::default_data_long_enough(FeatureLookups::MIN_SIZE));
impl Default for FeatureLookups<'_> {
fn default() -> Self {
Self {
data: TableDataRef::new(FontData::default_table_data().as_bytes())
.unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
}
}
}
#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash, bytemuck :: AnyBitPattern)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[repr(transparent)]
pub struct FeatureLookupsFlags {
bits: u16,
}
impl FeatureLookupsFlags {
pub const ADD_DEFAULT_LOOKUPS: Self = Self { bits: 0x0001 };
}
impl FeatureLookupsFlags {
#[inline]
pub const fn empty() -> Self {
Self { bits: 0 }
}
#[inline]
pub const fn all() -> Self {
Self {
bits: Self::ADD_DEFAULT_LOOKUPS.bits,
}
}
#[inline]
pub const fn bits(&self) -> u16 {
self.bits
}
#[inline]
pub const fn from_bits(bits: u16) -> Option<Self> {
if (bits & !Self::all().bits()) == 0 {
Some(Self { bits })
} else {
None
}
}
#[inline]
pub const fn from_bits_truncate(bits: u16) -> Self {
Self {
bits: bits & Self::all().bits,
}
}
#[inline]
pub const fn is_empty(&self) -> bool {
self.bits() == Self::empty().bits()
}
#[inline]
pub const fn intersects(&self, other: Self) -> bool {
!(Self {
bits: self.bits & other.bits,
})
.is_empty()
}
#[inline]
pub const fn contains(&self, other: Self) -> bool {
(self.bits & other.bits) == other.bits
}
#[inline]
pub fn insert(&mut self, other: Self) {
self.bits |= other.bits;
}
#[inline]
pub fn remove(&mut self, other: Self) {
self.bits &= !other.bits;
}
#[inline]
pub fn toggle(&mut self, other: Self) {
self.bits ^= other.bits;
}
#[inline]
#[must_use]
pub const fn intersection(self, other: Self) -> Self {
Self {
bits: self.bits & other.bits,
}
}
#[inline]
#[must_use]
pub const fn union(self, other: Self) -> Self {
Self {
bits: self.bits | other.bits,
}
}
#[inline]
#[must_use]
pub const fn difference(self, other: Self) -> Self {
Self {
bits: self.bits & !other.bits,
}
}
}
impl std::ops::BitOr for FeatureLookupsFlags {
type Output = Self;
#[inline]
fn bitor(self, other: FeatureLookupsFlags) -> Self {
Self {
bits: self.bits | other.bits,
}
}
}
impl std::ops::BitOrAssign for FeatureLookupsFlags {
#[inline]
fn bitor_assign(&mut self, other: Self) {
self.bits |= other.bits;
}
}
impl std::ops::BitXor for FeatureLookupsFlags {
type Output = Self;
#[inline]
fn bitxor(self, other: Self) -> Self {
Self {
bits: self.bits ^ other.bits,
}
}
}
impl std::ops::BitXorAssign for FeatureLookupsFlags {
#[inline]
fn bitxor_assign(&mut self, other: Self) {
self.bits ^= other.bits;
}
}
impl std::ops::BitAnd for FeatureLookupsFlags {
type Output = Self;
#[inline]
fn bitand(self, other: Self) -> Self {
Self {
bits: self.bits & other.bits,
}
}
}
impl std::ops::BitAndAssign for FeatureLookupsFlags {
#[inline]
fn bitand_assign(&mut self, other: Self) {
self.bits &= other.bits;
}
}
impl std::ops::Sub for FeatureLookupsFlags {
type Output = Self;
#[inline]
fn sub(self, other: Self) -> Self {
Self {
bits: self.bits & !other.bits,
}
}
}
impl std::ops::SubAssign for FeatureLookupsFlags {
#[inline]
fn sub_assign(&mut self, other: Self) {
self.bits &= !other.bits;
}
}
impl std::ops::Not for FeatureLookupsFlags {
type Output = Self;
#[inline]
fn not(self) -> Self {
Self { bits: !self.bits } & Self::all()
}
}
impl std::fmt::Debug for FeatureLookupsFlags {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
let members: &[(&str, Self)] = &[("ADD_DEFAULT_LOOKUPS", Self::ADD_DEFAULT_LOOKUPS)];
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 FeatureLookupsFlags {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
std::fmt::Binary::fmt(&self.bits, f)
}
}
impl std::fmt::Octal for FeatureLookupsFlags {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
std::fmt::Octal::fmt(&self.bits, f)
}
}
impl std::fmt::LowerHex for FeatureLookupsFlags {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
std::fmt::LowerHex::fmt(&self.bits, f)
}
}
impl std::fmt::UpperHex for FeatureLookupsFlags {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
std::fmt::UpperHex::fmt(&self.bits, f)
}
}
impl font_types::Scalar for FeatureLookupsFlags {
type Raw = <u16 as font_types::Scalar>::Raw;
fn to_raw(self) -> Self::Raw {
self.bits().to_raw()
}
fn from_raw(raw: Self::Raw) -> Self {
let t = <u16>::from_raw(raw);
Self::from_bits_truncate(t)
}
}
#[derive(Clone, Debug, Copy, bytemuck :: AnyBitPattern)]
#[repr(C)]
#[repr(packed)]
pub struct LookupConditionRecord {
pub condition_offset: BigEndian<Nullable<Offset32>>,
pub lookup_index_list_offset: BigEndian<Offset32>,
}
impl LookupConditionRecord {
pub fn condition_offset(&self) -> Nullable<Offset32> {
self.condition_offset.get()
}
pub fn condition<'a>(&self, data: FontData<'a>) -> Option<Result<Condition<'a>, ReadError>> {
self.condition_offset().resolve(data)
}
pub fn lookup_index_list_offset(&self) -> Offset32 {
self.lookup_index_list_offset.get()
}
pub fn lookup_index_list<'a>(
&self,
data: FontData<'a>,
) -> Result<LookupIndexList<'a>, ReadError> {
self.lookup_index_list_offset().resolve(data)
}
}
impl FixedSize for LookupConditionRecord {
const RAW_BYTE_LEN: usize = Offset32::RAW_BYTE_LEN + Offset32::RAW_BYTE_LEN;
}
impl<'a> MinByteRange<'a> for LookupIndexList<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.lookup_indices_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for LookupIndexList<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for LookupIndexList<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self { data })
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct LookupIndexListFixedHeader {
pub lookup_index_count: BigEndian<u16>,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () =
assert!(std::mem::size_of::<LookupIndexListFixedHeader>() <= LookupIndexList::MIN_SIZE);
#[derive(Clone)]
pub struct LookupIndexList<'a> {
data: TableDataRef<'a, LookupIndexListFixedHeader>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> LookupIndexList<'a> {
pub const MIN_SIZE: usize = u16::RAW_BYTE_LEN;
basic_table_impls!(impl_the_methods);
pub fn lookup_index_count(&self) -> u16 {
self.data.header().lookup_index_count.get()
}
pub fn lookup_indices(&self) -> &'a [BigEndian<u16>] {
let range = self.lookup_indices_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn lookup_index_count_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn lookup_indices_byte_range(&self) -> Range<usize> {
let lookup_index_count = self.lookup_index_count();
let start = self.lookup_index_count_byte_range().end;
let end =
start + (transforms::to_usize(lookup_index_count)).saturating_mul(u16::RAW_BYTE_LEN);
start..end
}
}
const _: () = assert!(FontData::default_data_long_enough(
LookupIndexList::MIN_SIZE
));
impl Default for LookupIndexList<'_> {
fn default() -> Self {
Self {
data: TableDataRef::new(FontData::default_table_data().as_bytes())
.unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
}
}
}
impl<'a> MinByteRange<'a> for ConditionSet<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.condition_offsets_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for ConditionSet<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for ConditionSet<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self { data })
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct ConditionSetFixedHeader {
pub condition_count: BigEndian<u16>,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () = assert!(std::mem::size_of::<ConditionSetFixedHeader>() <= ConditionSet::MIN_SIZE);
#[derive(Clone)]
pub struct ConditionSet<'a> {
data: TableDataRef<'a, ConditionSetFixedHeader>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> ConditionSet<'a> {
pub const MIN_SIZE: usize = u16::RAW_BYTE_LEN;
basic_table_impls!(impl_the_methods);
pub fn condition_count(&self) -> u16 {
self.data.header().condition_count.get()
}
pub fn condition_offsets(&self) -> &'a [BigEndian<Offset32>] {
let range = self.condition_offsets_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn conditions(&self) -> ArrayOfOffsets<'a, Condition<'a>, Offset32> {
let data = self.offset_data();
let offsets = self.condition_offsets();
ArrayOfOffsets::new(offsets, data, ())
}
pub fn condition_count_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn condition_offsets_byte_range(&self) -> Range<usize> {
let condition_count = self.condition_count();
let start = self.condition_count_byte_range().end;
let end =
start + (transforms::to_usize(condition_count)).saturating_mul(Offset32::RAW_BYTE_LEN);
start..end
}
}
const _: () = assert!(FontData::default_data_long_enough(ConditionSet::MIN_SIZE));
impl Default for ConditionSet<'_> {
fn default() -> Self {
Self {
data: TableDataRef::new(FontData::default_table_data().as_bytes())
.unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
}
}
}
#[derive(Clone)]
pub enum Condition<'a> {
Format1AxisRange(ConditionFormat1<'a>),
Format2VariableValue(ConditionFormat2<'a>),
Format3And(ConditionFormat3<'a>),
Format4Or(ConditionFormat4<'a>),
Format5Negate(ConditionFormat5<'a>),
}
impl Default for Condition<'_> {
fn default() -> Self {
Self::Format1AxisRange(Default::default())
}
}
impl<'a> Condition<'a> {
pub fn offset_data(&self) -> FontData<'a> {
match self {
Self::Format1AxisRange(item) => item.offset_data(),
Self::Format2VariableValue(item) => item.offset_data(),
Self::Format3And(item) => item.offset_data(),
Self::Format4Or(item) => item.offset_data(),
Self::Format5Negate(item) => item.offset_data(),
}
}
pub fn format(&self) -> u16 {
match self {
Self::Format1AxisRange(item) => item.format(),
Self::Format2VariableValue(item) => item.format(),
Self::Format3And(item) => item.format(),
Self::Format4Or(item) => item.format(),
Self::Format5Negate(item) => item.format(),
}
}
}
impl ReadArgs for Condition<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for Condition<'a> {
#[inline]
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
let format: u16 = data.read_at(0usize)?;
match format {
ConditionFormat1::FORMAT => Ok(Self::Format1AxisRange(FontRead::read(data)?)),
ConditionFormat2::FORMAT => Ok(Self::Format2VariableValue(FontRead::read(data)?)),
ConditionFormat3::FORMAT => Ok(Self::Format3And(FontRead::read(data)?)),
ConditionFormat4::FORMAT => Ok(Self::Format4Or(FontRead::read(data)?)),
ConditionFormat5::FORMAT => Ok(Self::Format5Negate(FontRead::read(data)?)),
other => Err(ReadError::InvalidFormat(other.into())),
}
}
}
impl<'a> MinByteRange<'a> for Condition<'a> {
fn min_byte_range(&self) -> Range<usize> {
match self {
Self::Format1AxisRange(item) => item.min_byte_range(),
Self::Format2VariableValue(item) => item.min_byte_range(),
Self::Format3And(item) => item.min_byte_range(),
Self::Format4Or(item) => item.min_byte_range(),
Self::Format5Negate(item) => item.min_byte_range(),
}
}
fn min_table_bytes(&self) -> &'a [u8] {
match self {
Self::Format1AxisRange(item) => item.min_table_bytes(),
Self::Format2VariableValue(item) => item.min_table_bytes(),
Self::Format3And(item) => item.min_table_bytes(),
Self::Format4Or(item) => item.min_table_bytes(),
Self::Format5Negate(item) => item.min_table_bytes(),
}
}
}
impl Format<u16> for ConditionFormat1<'_> {
const FORMAT: u16 = 1;
}
impl<'a> MinByteRange<'a> for ConditionFormat1<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.filter_range_max_value_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for ConditionFormat1<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for ConditionFormat1<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self { data })
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct ConditionFormat1FixedHeader {
pub format: BigEndian<u16>,
pub axis_index: BigEndian<u16>,
pub filter_range_min_value: BigEndian<F2Dot14>,
pub filter_range_max_value: BigEndian<F2Dot14>,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () =
assert!(std::mem::size_of::<ConditionFormat1FixedHeader>() <= ConditionFormat1::MIN_SIZE);
#[derive(Clone)]
pub struct ConditionFormat1<'a> {
data: TableDataRef<'a, ConditionFormat1FixedHeader>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> ConditionFormat1<'a> {
pub const MIN_SIZE: usize =
(u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + F2Dot14::RAW_BYTE_LEN + F2Dot14::RAW_BYTE_LEN);
basic_table_impls!(impl_the_methods);
pub fn format(&self) -> u16 {
self.data.header().format.get()
}
pub fn axis_index(&self) -> u16 {
self.data.header().axis_index.get()
}
pub fn filter_range_min_value(&self) -> F2Dot14 {
self.data.header().filter_range_min_value.get()
}
pub fn filter_range_max_value(&self) -> F2Dot14 {
self.data.header().filter_range_max_value.get()
}
pub fn format_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn axis_index_byte_range(&self) -> Range<usize> {
let start = self.format_byte_range().end;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn filter_range_min_value_byte_range(&self) -> Range<usize> {
let start = self.axis_index_byte_range().end;
let end = start + F2Dot14::RAW_BYTE_LEN;
start..end
}
pub fn filter_range_max_value_byte_range(&self) -> Range<usize> {
let start = self.filter_range_min_value_byte_range().end;
let end = start + F2Dot14::RAW_BYTE_LEN;
start..end
}
}
const _: () = assert!(FontData::default_data_long_enough(
ConditionFormat1::MIN_SIZE
));
impl Default for ConditionFormat1<'_> {
fn default() -> Self {
Self {
data: TableDataRef::new(FontData::default_format_1_u16_table_data().as_bytes())
.unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
}
}
}
impl Format<u16> for ConditionFormat2<'_> {
const FORMAT: u16 = 2;
}
impl<'a> MinByteRange<'a> for ConditionFormat2<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.var_index_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for ConditionFormat2<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for ConditionFormat2<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self { data })
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct ConditionFormat2FixedHeader {
pub format: BigEndian<u16>,
pub default_value: BigEndian<i16>,
pub var_index: BigEndian<u32>,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () =
assert!(std::mem::size_of::<ConditionFormat2FixedHeader>() <= ConditionFormat2::MIN_SIZE);
#[derive(Clone)]
pub struct ConditionFormat2<'a> {
data: TableDataRef<'a, ConditionFormat2FixedHeader>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> ConditionFormat2<'a> {
pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + i16::RAW_BYTE_LEN + u32::RAW_BYTE_LEN);
basic_table_impls!(impl_the_methods);
pub fn format(&self) -> u16 {
self.data.header().format.get()
}
pub fn default_value(&self) -> i16 {
self.data.header().default_value.get()
}
pub fn var_index(&self) -> u32 {
self.data.header().var_index.get()
}
pub fn format_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn default_value_byte_range(&self) -> Range<usize> {
let start = self.format_byte_range().end;
let end = start + i16::RAW_BYTE_LEN;
start..end
}
pub fn var_index_byte_range(&self) -> Range<usize> {
let start = self.default_value_byte_range().end;
let end = start + u32::RAW_BYTE_LEN;
start..end
}
}
impl Format<u16> for ConditionFormat3<'_> {
const FORMAT: u16 = 3;
}
impl<'a> MinByteRange<'a> for ConditionFormat3<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.condition_offsets_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for ConditionFormat3<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for ConditionFormat3<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self { data })
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct ConditionFormat3FixedHeader {
pub format: BigEndian<u16>,
pub condition_count: u8,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () =
assert!(std::mem::size_of::<ConditionFormat3FixedHeader>() <= ConditionFormat3::MIN_SIZE);
#[derive(Clone)]
pub struct ConditionFormat3<'a> {
data: TableDataRef<'a, ConditionFormat3FixedHeader>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> ConditionFormat3<'a> {
pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + u8::RAW_BYTE_LEN);
basic_table_impls!(impl_the_methods);
pub fn format(&self) -> u16 {
self.data.header().format.get()
}
pub fn condition_count(&self) -> u8 {
self.data.header().condition_count
}
pub fn condition_offsets(&self) -> &'a [BigEndian<Offset24>] {
let range = self.condition_offsets_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn conditions(&self) -> ArrayOfOffsets<'a, Condition<'a>, Offset24> {
let data = self.offset_data();
let offsets = self.condition_offsets();
ArrayOfOffsets::new(offsets, data, ())
}
pub fn format_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn condition_count_byte_range(&self) -> Range<usize> {
let start = self.format_byte_range().end;
let end = start + u8::RAW_BYTE_LEN;
start..end
}
pub fn condition_offsets_byte_range(&self) -> Range<usize> {
let condition_count = self.condition_count();
let start = self.condition_count_byte_range().end;
let end =
start + (transforms::to_usize(condition_count)).saturating_mul(Offset24::RAW_BYTE_LEN);
start..end
}
}
impl Format<u16> for ConditionFormat4<'_> {
const FORMAT: u16 = 4;
}
impl<'a> MinByteRange<'a> for ConditionFormat4<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.condition_offsets_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for ConditionFormat4<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for ConditionFormat4<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self { data })
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct ConditionFormat4FixedHeader {
pub format: BigEndian<u16>,
pub condition_count: u8,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () =
assert!(std::mem::size_of::<ConditionFormat4FixedHeader>() <= ConditionFormat4::MIN_SIZE);
#[derive(Clone)]
pub struct ConditionFormat4<'a> {
data: TableDataRef<'a, ConditionFormat4FixedHeader>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> ConditionFormat4<'a> {
pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + u8::RAW_BYTE_LEN);
basic_table_impls!(impl_the_methods);
pub fn format(&self) -> u16 {
self.data.header().format.get()
}
pub fn condition_count(&self) -> u8 {
self.data.header().condition_count
}
pub fn condition_offsets(&self) -> &'a [BigEndian<Offset24>] {
let range = self.condition_offsets_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn conditions(&self) -> ArrayOfOffsets<'a, Condition<'a>, Offset24> {
let data = self.offset_data();
let offsets = self.condition_offsets();
ArrayOfOffsets::new(offsets, data, ())
}
pub fn format_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn condition_count_byte_range(&self) -> Range<usize> {
let start = self.format_byte_range().end;
let end = start + u8::RAW_BYTE_LEN;
start..end
}
pub fn condition_offsets_byte_range(&self) -> Range<usize> {
let condition_count = self.condition_count();
let start = self.condition_count_byte_range().end;
let end =
start + (transforms::to_usize(condition_count)).saturating_mul(Offset24::RAW_BYTE_LEN);
start..end
}
}
impl Format<u16> for ConditionFormat5<'_> {
const FORMAT: u16 = 5;
}
impl<'a> MinByteRange<'a> for ConditionFormat5<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.condition_offset_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for ConditionFormat5<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for ConditionFormat5<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self { data })
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct ConditionFormat5FixedHeader {
pub format: BigEndian<u16>,
pub condition_offset: BigEndian<Offset24>,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () =
assert!(std::mem::size_of::<ConditionFormat5FixedHeader>() <= ConditionFormat5::MIN_SIZE);
#[derive(Clone)]
pub struct ConditionFormat5<'a> {
data: TableDataRef<'a, ConditionFormat5FixedHeader>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> ConditionFormat5<'a> {
pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + Offset24::RAW_BYTE_LEN);
basic_table_impls!(impl_the_methods);
pub fn format(&self) -> u16 {
self.data.header().format.get()
}
pub fn condition_offset(&self) -> Offset24 {
self.data.header().condition_offset.get()
}
pub fn condition(&self) -> Result<Condition<'a>, ReadError> {
let data = self.offset_data();
self.condition_offset().resolve(data)
}
pub fn format_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn condition_offset_byte_range(&self) -> Range<usize> {
let start = self.format_byte_range().end;
let end = start + Offset24::RAW_BYTE_LEN;
start..end
}
}
impl<'a> MinByteRange<'a> for FeatureTableSubstitution<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.substitutions_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for FeatureTableSubstitution<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for FeatureTableSubstitution<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self { data })
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct FeatureTableSubstitutionFixedHeader {
pub version: BigEndian<MajorMinor>,
pub substitution_count: BigEndian<u16>,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () = assert!(
std::mem::size_of::<FeatureTableSubstitutionFixedHeader>()
<= FeatureTableSubstitution::MIN_SIZE
);
#[derive(Clone)]
pub struct FeatureTableSubstitution<'a> {
data: TableDataRef<'a, FeatureTableSubstitutionFixedHeader>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> FeatureTableSubstitution<'a> {
pub const MIN_SIZE: usize = (MajorMinor::RAW_BYTE_LEN + u16::RAW_BYTE_LEN);
basic_table_impls!(impl_the_methods);
pub fn version(&self) -> MajorMinor {
self.data.header().version.get()
}
pub fn substitution_count(&self) -> u16 {
self.data.header().substitution_count.get()
}
pub fn substitutions(&self) -> &'a [FeatureTableSubstitutionRecord] {
let range = self.substitutions_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn version_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + MajorMinor::RAW_BYTE_LEN;
start..end
}
pub fn substitution_count_byte_range(&self) -> Range<usize> {
let start = self.version_byte_range().end;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn substitutions_byte_range(&self) -> Range<usize> {
let substitution_count = self.substitution_count();
let start = self.substitution_count_byte_range().end;
let end = start
+ (transforms::to_usize(substitution_count))
.saturating_mul(FeatureTableSubstitutionRecord::RAW_BYTE_LEN);
start..end
}
}
const _: () = assert!(FontData::default_data_long_enough(
FeatureTableSubstitution::MIN_SIZE
));
impl Default for FeatureTableSubstitution<'_> {
fn default() -> Self {
Self {
data: TableDataRef::new(FontData::default_table_data().as_bytes())
.unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
}
}
}
#[derive(Clone, Debug, Copy, bytemuck :: AnyBitPattern)]
#[repr(C)]
#[repr(packed)]
pub struct FeatureTableSubstitutionRecord {
pub feature_index: BigEndian<u16>,
pub alternate_feature_offset: BigEndian<Offset32>,
}
impl FeatureTableSubstitutionRecord {
pub fn feature_index(&self) -> u16 {
self.feature_index.get()
}
pub fn alternate_feature_offset(&self) -> Offset32 {
self.alternate_feature_offset.get()
}
}
impl FixedSize for FeatureTableSubstitutionRecord {
const RAW_BYTE_LEN: usize = u16::RAW_BYTE_LEN + Offset32::RAW_BYTE_LEN;
}
impl<'a> MinByteRange<'a> for SizeParams<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.range_end_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for SizeParams<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for SizeParams<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self { data })
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct SizeParamsFixedHeader {
pub design_size: BigEndian<u16>,
pub identifier: BigEndian<u16>,
pub name_entry: BigEndian<u16>,
pub range_start: BigEndian<u16>,
pub range_end: BigEndian<u16>,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () = assert!(std::mem::size_of::<SizeParamsFixedHeader>() <= SizeParams::MIN_SIZE);
#[derive(Clone)]
pub struct SizeParams<'a> {
data: TableDataRef<'a, SizeParamsFixedHeader>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> SizeParams<'a> {
pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN
+ u16::RAW_BYTE_LEN
+ u16::RAW_BYTE_LEN
+ u16::RAW_BYTE_LEN
+ u16::RAW_BYTE_LEN);
basic_table_impls!(impl_the_methods);
pub fn design_size(&self) -> u16 {
self.data.header().design_size.get()
}
pub fn identifier(&self) -> u16 {
self.data.header().identifier.get()
}
pub fn name_entry(&self) -> u16 {
self.data.header().name_entry.get()
}
pub fn range_start(&self) -> u16 {
self.data.header().range_start.get()
}
pub fn range_end(&self) -> u16 {
self.data.header().range_end.get()
}
pub fn design_size_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn identifier_byte_range(&self) -> Range<usize> {
let start = self.design_size_byte_range().end;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn name_entry_byte_range(&self) -> Range<usize> {
let start = self.identifier_byte_range().end;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn range_start_byte_range(&self) -> Range<usize> {
let start = self.name_entry_byte_range().end;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn range_end_byte_range(&self) -> Range<usize> {
let start = self.range_start_byte_range().end;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
}
const _: () = assert!(FontData::default_data_long_enough(SizeParams::MIN_SIZE));
impl Default for SizeParams<'_> {
fn default() -> Self {
Self {
data: TableDataRef::new(FontData::default_table_data().as_bytes())
.unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
}
}
}
impl<'a> MinByteRange<'a> for StylisticSetParams<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.ui_name_id_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for StylisticSetParams<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for StylisticSetParams<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self { data })
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct StylisticSetParamsFixedHeader {
pub version: BigEndian<u16>,
pub ui_name_id: BigEndian<NameId>,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () =
assert!(std::mem::size_of::<StylisticSetParamsFixedHeader>() <= StylisticSetParams::MIN_SIZE);
#[derive(Clone)]
pub struct StylisticSetParams<'a> {
data: TableDataRef<'a, StylisticSetParamsFixedHeader>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> StylisticSetParams<'a> {
pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + NameId::RAW_BYTE_LEN);
basic_table_impls!(impl_the_methods);
pub fn version(&self) -> u16 {
self.data.header().version.get()
}
pub fn ui_name_id(&self) -> NameId {
self.data.header().ui_name_id.get()
}
pub fn version_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn ui_name_id_byte_range(&self) -> Range<usize> {
let start = self.version_byte_range().end;
let end = start + NameId::RAW_BYTE_LEN;
start..end
}
}
const _: () = assert!(FontData::default_data_long_enough(
StylisticSetParams::MIN_SIZE
));
impl Default for StylisticSetParams<'_> {
fn default() -> Self {
Self {
data: TableDataRef::new(FontData::default_table_data().as_bytes())
.unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
}
}
}
impl Format<u16> for CharacterVariantParams<'_> {
const FORMAT: u16 = 0;
}
impl<'a> MinByteRange<'a> for CharacterVariantParams<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.character_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for CharacterVariantParams<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for CharacterVariantParams<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self { data })
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct CharacterVariantParamsFixedHeader {
pub format: BigEndian<u16>,
pub feat_ui_label_name_id: BigEndian<NameId>,
pub feat_ui_tooltip_text_name_id: BigEndian<NameId>,
pub sample_text_name_id: BigEndian<NameId>,
pub num_named_parameters: BigEndian<u16>,
pub first_param_ui_label_name_id: BigEndian<NameId>,
pub char_count: BigEndian<u16>,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () = assert!(
std::mem::size_of::<CharacterVariantParamsFixedHeader>() <= CharacterVariantParams::MIN_SIZE
);
#[derive(Clone)]
pub struct CharacterVariantParams<'a> {
data: TableDataRef<'a, CharacterVariantParamsFixedHeader>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> CharacterVariantParams<'a> {
pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN
+ NameId::RAW_BYTE_LEN
+ NameId::RAW_BYTE_LEN
+ NameId::RAW_BYTE_LEN
+ u16::RAW_BYTE_LEN
+ NameId::RAW_BYTE_LEN
+ u16::RAW_BYTE_LEN);
basic_table_impls!(impl_the_methods);
pub fn format(&self) -> u16 {
self.data.header().format.get()
}
pub fn feat_ui_label_name_id(&self) -> NameId {
self.data.header().feat_ui_label_name_id.get()
}
pub fn feat_ui_tooltip_text_name_id(&self) -> NameId {
self.data.header().feat_ui_tooltip_text_name_id.get()
}
pub fn sample_text_name_id(&self) -> NameId {
self.data.header().sample_text_name_id.get()
}
pub fn num_named_parameters(&self) -> u16 {
self.data.header().num_named_parameters.get()
}
pub fn first_param_ui_label_name_id(&self) -> NameId {
self.data.header().first_param_ui_label_name_id.get()
}
pub fn char_count(&self) -> u16 {
self.data.header().char_count.get()
}
pub fn character(&self) -> &'a [BigEndian<Uint24>] {
let range = self.character_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn format_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn feat_ui_label_name_id_byte_range(&self) -> Range<usize> {
let start = self.format_byte_range().end;
let end = start + NameId::RAW_BYTE_LEN;
start..end
}
pub fn feat_ui_tooltip_text_name_id_byte_range(&self) -> Range<usize> {
let start = self.feat_ui_label_name_id_byte_range().end;
let end = start + NameId::RAW_BYTE_LEN;
start..end
}
pub fn sample_text_name_id_byte_range(&self) -> Range<usize> {
let start = self.feat_ui_tooltip_text_name_id_byte_range().end;
let end = start + NameId::RAW_BYTE_LEN;
start..end
}
pub fn num_named_parameters_byte_range(&self) -> Range<usize> {
let start = self.sample_text_name_id_byte_range().end;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn first_param_ui_label_name_id_byte_range(&self) -> Range<usize> {
let start = self.num_named_parameters_byte_range().end;
let end = start + NameId::RAW_BYTE_LEN;
start..end
}
pub fn char_count_byte_range(&self) -> Range<usize> {
let start = self.first_param_ui_label_name_id_byte_range().end;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn character_byte_range(&self) -> Range<usize> {
let char_count = self.char_count();
let start = self.char_count_byte_range().end;
let end = start + (transforms::to_usize(char_count)).saturating_mul(Uint24::RAW_BYTE_LEN);
start..end
}
}
const _: () = assert!(FontData::default_data_long_enough(
CharacterVariantParams::MIN_SIZE
));
impl Default for CharacterVariantParams<'_> {
fn default() -> Self {
Self {
data: TableDataRef::new(FontData::default_table_data().as_bytes())
.unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
}
}
}
impl Format<u16> for CoverageFormat3<'_> {
const FORMAT: u16 = 3;
}
impl<'a> MinByteRange<'a> for CoverageFormat3<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.glyph_array_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for CoverageFormat3<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for CoverageFormat3<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self { data })
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct CoverageFormat3FixedHeader {
pub coverage_format: BigEndian<u16>,
pub glyph_count: BigEndian<Uint24>,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () =
assert!(std::mem::size_of::<CoverageFormat3FixedHeader>() <= CoverageFormat3::MIN_SIZE);
#[derive(Clone)]
pub struct CoverageFormat3<'a> {
data: TableDataRef<'a, CoverageFormat3FixedHeader>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> CoverageFormat3<'a> {
pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + Uint24::RAW_BYTE_LEN);
basic_table_impls!(impl_the_methods);
pub fn coverage_format(&self) -> u16 {
self.data.header().coverage_format.get()
}
pub fn glyph_count(&self) -> Uint24 {
self.data.header().glyph_count.get()
}
pub fn glyph_array(&self) -> &'a [BigEndian<GlyphId24>] {
let range = self.glyph_array_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn coverage_format_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn glyph_count_byte_range(&self) -> Range<usize> {
let start = self.coverage_format_byte_range().end;
let end = start + Uint24::RAW_BYTE_LEN;
start..end
}
pub fn glyph_array_byte_range(&self) -> Range<usize> {
let glyph_count = self.glyph_count();
let start = self.glyph_count_byte_range().end;
let end =
start + (transforms::to_usize(glyph_count)).saturating_mul(GlyphId24::RAW_BYTE_LEN);
start..end
}
}
impl Format<u16> for CoverageFormat4<'_> {
const FORMAT: u16 = 4;
}
impl<'a> MinByteRange<'a> for CoverageFormat4<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.range_records_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for CoverageFormat4<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for CoverageFormat4<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self { data })
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct CoverageFormat4FixedHeader {
pub coverage_format: BigEndian<u16>,
pub range_count: BigEndian<Uint24>,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () =
assert!(std::mem::size_of::<CoverageFormat4FixedHeader>() <= CoverageFormat4::MIN_SIZE);
#[derive(Clone)]
pub struct CoverageFormat4<'a> {
data: TableDataRef<'a, CoverageFormat4FixedHeader>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> CoverageFormat4<'a> {
pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + Uint24::RAW_BYTE_LEN);
basic_table_impls!(impl_the_methods);
pub fn coverage_format(&self) -> u16 {
self.data.header().coverage_format.get()
}
pub fn range_count(&self) -> Uint24 {
self.data.header().range_count.get()
}
pub fn range_records(&self) -> &'a [RangeRecord2] {
let range = self.range_records_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn coverage_format_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn range_count_byte_range(&self) -> Range<usize> {
let start = self.coverage_format_byte_range().end;
let end = start + Uint24::RAW_BYTE_LEN;
start..end
}
pub fn range_records_byte_range(&self) -> Range<usize> {
let range_count = self.range_count();
let start = self.range_count_byte_range().end;
let end =
start + (transforms::to_usize(range_count)).saturating_mul(RangeRecord2::RAW_BYTE_LEN);
start..end
}
}
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
#[repr(C)]
#[repr(packed)]
pub struct RangeRecord2 {
pub start_glyph_id: BigEndian<GlyphId24>,
pub end_glyph_id: BigEndian<GlyphId24>,
pub start_coverage_index: BigEndian<Uint24>,
}
impl RangeRecord2 {
pub fn start_glyph_id(&self) -> GlyphId24 {
self.start_glyph_id.get()
}
pub fn end_glyph_id(&self) -> GlyphId24 {
self.end_glyph_id.get()
}
pub fn start_coverage_index(&self) -> Uint24 {
self.start_coverage_index.get()
}
}
impl FixedSize for RangeRecord2 {
const RAW_BYTE_LEN: usize =
GlyphId24::RAW_BYTE_LEN + GlyphId24::RAW_BYTE_LEN + Uint24::RAW_BYTE_LEN;
}
impl Format<u16> for ClassDefFormat3<'_> {
const FORMAT: u16 = 3;
}
impl<'a> MinByteRange<'a> for ClassDefFormat3<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.class_value_array_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for ClassDefFormat3<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for ClassDefFormat3<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self { data })
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct ClassDefFormat3FixedHeader {
pub class_format: BigEndian<u16>,
pub start_glyph_id: BigEndian<GlyphId24>,
pub glyph_count: BigEndian<Uint24>,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () =
assert!(std::mem::size_of::<ClassDefFormat3FixedHeader>() <= ClassDefFormat3::MIN_SIZE);
#[derive(Clone)]
pub struct ClassDefFormat3<'a> {
data: TableDataRef<'a, ClassDefFormat3FixedHeader>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> ClassDefFormat3<'a> {
pub const MIN_SIZE: usize =
(u16::RAW_BYTE_LEN + GlyphId24::RAW_BYTE_LEN + Uint24::RAW_BYTE_LEN);
basic_table_impls!(impl_the_methods);
pub fn class_format(&self) -> u16 {
self.data.header().class_format.get()
}
pub fn start_glyph_id(&self) -> GlyphId24 {
self.data.header().start_glyph_id.get()
}
pub fn glyph_count(&self) -> Uint24 {
self.data.header().glyph_count.get()
}
pub fn class_value_array(&self) -> &'a [BigEndian<Uint24>] {
let range = self.class_value_array_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn class_format_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn start_glyph_id_byte_range(&self) -> Range<usize> {
let start = self.class_format_byte_range().end;
let end = start + GlyphId24::RAW_BYTE_LEN;
start..end
}
pub fn glyph_count_byte_range(&self) -> Range<usize> {
let start = self.start_glyph_id_byte_range().end;
let end = start + Uint24::RAW_BYTE_LEN;
start..end
}
pub fn class_value_array_byte_range(&self) -> Range<usize> {
let glyph_count = self.glyph_count();
let start = self.glyph_count_byte_range().end;
let end = start + (transforms::to_usize(glyph_count)).saturating_mul(Uint24::RAW_BYTE_LEN);
start..end
}
}
impl Format<u16> for ClassDefFormat4<'_> {
const FORMAT: u16 = 4;
}
impl<'a> MinByteRange<'a> for ClassDefFormat4<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.class_range_records_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for ClassDefFormat4<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for ClassDefFormat4<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self { data })
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct ClassDefFormat4FixedHeader {
pub class_format: BigEndian<u16>,
pub class_range_count: BigEndian<Uint24>,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () =
assert!(std::mem::size_of::<ClassDefFormat4FixedHeader>() <= ClassDefFormat4::MIN_SIZE);
#[derive(Clone)]
pub struct ClassDefFormat4<'a> {
data: TableDataRef<'a, ClassDefFormat4FixedHeader>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> ClassDefFormat4<'a> {
pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + Uint24::RAW_BYTE_LEN);
basic_table_impls!(impl_the_methods);
pub fn class_format(&self) -> u16 {
self.data.header().class_format.get()
}
pub fn class_range_count(&self) -> Uint24 {
self.data.header().class_range_count.get()
}
pub fn class_range_records(&self) -> &'a [ClassRangeRecord2] {
let range = self.class_range_records_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn class_format_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn class_range_count_byte_range(&self) -> Range<usize> {
let start = self.class_format_byte_range().end;
let end = start + Uint24::RAW_BYTE_LEN;
start..end
}
pub fn class_range_records_byte_range(&self) -> Range<usize> {
let class_range_count = self.class_range_count();
let start = self.class_range_count_byte_range().end;
let end = start
+ (transforms::to_usize(class_range_count))
.saturating_mul(ClassRangeRecord2::RAW_BYTE_LEN);
start..end
}
}
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
#[repr(C)]
#[repr(packed)]
pub struct ClassRangeRecord2 {
pub start_glyph_id: BigEndian<GlyphId24>,
pub end_glyph_id: BigEndian<GlyphId24>,
pub class: BigEndian<u16>,
}
impl ClassRangeRecord2 {
pub fn start_glyph_id(&self) -> GlyphId24 {
self.start_glyph_id.get()
}
pub fn end_glyph_id(&self) -> GlyphId24 {
self.end_glyph_id.get()
}
pub fn class(&self) -> u16 {
self.class.get()
}
}
impl FixedSize for ClassRangeRecord2 {
const RAW_BYTE_LEN: usize =
GlyphId24::RAW_BYTE_LEN + GlyphId24::RAW_BYTE_LEN + u16::RAW_BYTE_LEN;
}
impl Format<u16> for SequenceContextFormat4<'_> {
const FORMAT: u16 = 4;
}
impl<'a> MinByteRange<'a> for SequenceContextFormat4<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.seq_rule_set_offsets_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for SequenceContextFormat4<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for SequenceContextFormat4<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self { data })
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct SequenceContextFormat4FixedHeader {
pub format: BigEndian<u16>,
pub coverage_offset: BigEndian<Offset32>,
pub seq_rule_set_count: BigEndian<Uint24>,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () = assert!(
std::mem::size_of::<SequenceContextFormat4FixedHeader>() <= SequenceContextFormat4::MIN_SIZE
);
#[derive(Clone)]
pub struct SequenceContextFormat4<'a> {
data: TableDataRef<'a, SequenceContextFormat4FixedHeader>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> SequenceContextFormat4<'a> {
pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + Offset32::RAW_BYTE_LEN + Uint24::RAW_BYTE_LEN);
basic_table_impls!(impl_the_methods);
pub fn format(&self) -> u16 {
self.data.header().format.get()
}
pub fn coverage_offset(&self) -> Offset32 {
self.data.header().coverage_offset.get()
}
pub fn coverage(&self) -> Result<CoverageTable<'a>, ReadError> {
let data = self.offset_data();
self.coverage_offset().resolve(data)
}
pub fn seq_rule_set_count(&self) -> Uint24 {
self.data.header().seq_rule_set_count.get()
}
pub fn seq_rule_set_offsets(&self) -> &'a [BigEndian<Nullable<Offset24>>] {
let range = self.seq_rule_set_offsets_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn seq_rule_sets(&self) -> ArrayOfNullableOffsets<'a, SequenceRuleSet2<'a>, Offset24> {
let data = self.offset_data();
let offsets = self.seq_rule_set_offsets();
ArrayOfNullableOffsets::new(offsets, data, ())
}
pub fn format_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn coverage_offset_byte_range(&self) -> Range<usize> {
let start = self.format_byte_range().end;
let end = start + Offset32::RAW_BYTE_LEN;
start..end
}
pub fn seq_rule_set_count_byte_range(&self) -> Range<usize> {
let start = self.coverage_offset_byte_range().end;
let end = start + Uint24::RAW_BYTE_LEN;
start..end
}
pub fn seq_rule_set_offsets_byte_range(&self) -> Range<usize> {
let seq_rule_set_count = self.seq_rule_set_count();
let start = self.seq_rule_set_count_byte_range().end;
let end = start
+ (transforms::to_usize(seq_rule_set_count)).saturating_mul(Offset24::RAW_BYTE_LEN);
start..end
}
}
impl<'a> MinByteRange<'a> for SequenceRuleSet2<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.seq_rule_offsets_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for SequenceRuleSet2<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for SequenceRuleSet2<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self { data })
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct SequenceRuleSet2FixedHeader {
pub seq_rule_count: BigEndian<u16>,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () =
assert!(std::mem::size_of::<SequenceRuleSet2FixedHeader>() <= SequenceRuleSet2::MIN_SIZE);
#[derive(Clone)]
pub struct SequenceRuleSet2<'a> {
data: TableDataRef<'a, SequenceRuleSet2FixedHeader>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> SequenceRuleSet2<'a> {
pub const MIN_SIZE: usize = u16::RAW_BYTE_LEN;
basic_table_impls!(impl_the_methods);
pub fn seq_rule_count(&self) -> u16 {
self.data.header().seq_rule_count.get()
}
pub fn seq_rule_offsets(&self) -> &'a [BigEndian<Offset16>] {
let range = self.seq_rule_offsets_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn seq_rules(&self) -> ArrayOfOffsets<'a, SequenceRule2<'a>, Offset16> {
let data = self.offset_data();
let offsets = self.seq_rule_offsets();
ArrayOfOffsets::new(offsets, data, ())
}
pub fn seq_rule_count_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn seq_rule_offsets_byte_range(&self) -> Range<usize> {
let seq_rule_count = self.seq_rule_count();
let start = self.seq_rule_count_byte_range().end;
let end =
start + (transforms::to_usize(seq_rule_count)).saturating_mul(Offset16::RAW_BYTE_LEN);
start..end
}
}
const _: () = assert!(FontData::default_data_long_enough(
SequenceRuleSet2::MIN_SIZE
));
impl Default for SequenceRuleSet2<'_> {
fn default() -> Self {
Self {
data: TableDataRef::new(FontData::default_table_data().as_bytes())
.unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
}
}
}
impl<'a> MinByteRange<'a> for SequenceRule2<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.seq_lookup_records_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for SequenceRule2<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for SequenceRule2<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self { data })
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct SequenceRule2FixedHeader {
pub glyph_count: BigEndian<u16>,
pub seq_lookup_count: BigEndian<u16>,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () = assert!(std::mem::size_of::<SequenceRule2FixedHeader>() <= SequenceRule2::MIN_SIZE);
#[derive(Clone)]
pub struct SequenceRule2<'a> {
data: TableDataRef<'a, SequenceRule2FixedHeader>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> SequenceRule2<'a> {
pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN);
basic_table_impls!(impl_the_methods);
pub fn glyph_count(&self) -> u16 {
self.data.header().glyph_count.get()
}
pub fn seq_lookup_count(&self) -> u16 {
self.data.header().seq_lookup_count.get()
}
pub fn input_sequence(&self) -> &'a [BigEndian<GlyphId24>] {
let range = self.input_sequence_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn seq_lookup_records(&self) -> &'a [SequenceLookupRecord] {
let range = self.seq_lookup_records_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn glyph_count_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn seq_lookup_count_byte_range(&self) -> Range<usize> {
let start = self.glyph_count_byte_range().end;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn input_sequence_byte_range(&self) -> Range<usize> {
let glyph_count = self.glyph_count();
let start = self.seq_lookup_count_byte_range().end;
let end = start
+ (transforms::subtract(glyph_count, 1_usize)).saturating_mul(GlyphId24::RAW_BYTE_LEN);
start..end
}
pub fn seq_lookup_records_byte_range(&self) -> Range<usize> {
let seq_lookup_count = self.seq_lookup_count();
let start = self.input_sequence_byte_range().end;
let end = start
+ (transforms::to_usize(seq_lookup_count))
.saturating_mul(SequenceLookupRecord::RAW_BYTE_LEN);
start..end
}
}
const _: () = assert!(FontData::default_data_long_enough(SequenceRule2::MIN_SIZE));
impl Default for SequenceRule2<'_> {
fn default() -> Self {
Self {
data: TableDataRef::new(FontData::default_table_data().as_bytes())
.unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
}
}
}
impl Format<u16> for SequenceContextFormat5<'_> {
const FORMAT: u16 = 5;
}
impl<'a> MinByteRange<'a> for SequenceContextFormat5<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.class_seq_rule_set_offsets_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for SequenceContextFormat5<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for SequenceContextFormat5<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self { data })
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct SequenceContextFormat5FixedHeader {
pub format: BigEndian<u16>,
pub coverage_offset: BigEndian<Offset32>,
pub class_def_offset: BigEndian<Offset32>,
pub class_seq_rule_set_count: BigEndian<Uint24>,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () = assert!(
std::mem::size_of::<SequenceContextFormat5FixedHeader>() <= SequenceContextFormat5::MIN_SIZE
);
#[derive(Clone)]
pub struct SequenceContextFormat5<'a> {
data: TableDataRef<'a, SequenceContextFormat5FixedHeader>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> SequenceContextFormat5<'a> {
pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN
+ Offset32::RAW_BYTE_LEN
+ Offset32::RAW_BYTE_LEN
+ Uint24::RAW_BYTE_LEN);
basic_table_impls!(impl_the_methods);
pub fn format(&self) -> u16 {
self.data.header().format.get()
}
pub fn coverage_offset(&self) -> Offset32 {
self.data.header().coverage_offset.get()
}
pub fn coverage(&self) -> Result<CoverageTable<'a>, ReadError> {
let data = self.offset_data();
self.coverage_offset().resolve(data)
}
pub fn class_def_offset(&self) -> Offset32 {
self.data.header().class_def_offset.get()
}
pub fn class_def(&self) -> Result<ClassDef<'a>, ReadError> {
let data = self.offset_data();
self.class_def_offset().resolve(data)
}
pub fn class_seq_rule_set_count(&self) -> Uint24 {
self.data.header().class_seq_rule_set_count.get()
}
pub fn class_seq_rule_set_offsets(&self) -> &'a [BigEndian<Nullable<Offset24>>] {
let range = self.class_seq_rule_set_offsets_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn class_seq_rule_sets(
&self,
) -> ArrayOfNullableOffsets<'a, ClassSequenceRuleSet2<'a>, Offset24> {
let data = self.offset_data();
let offsets = self.class_seq_rule_set_offsets();
ArrayOfNullableOffsets::new(offsets, data, ())
}
pub fn format_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn coverage_offset_byte_range(&self) -> Range<usize> {
let start = self.format_byte_range().end;
let end = start + Offset32::RAW_BYTE_LEN;
start..end
}
pub fn class_def_offset_byte_range(&self) -> Range<usize> {
let start = self.coverage_offset_byte_range().end;
let end = start + Offset32::RAW_BYTE_LEN;
start..end
}
pub fn class_seq_rule_set_count_byte_range(&self) -> Range<usize> {
let start = self.class_def_offset_byte_range().end;
let end = start + Uint24::RAW_BYTE_LEN;
start..end
}
pub fn class_seq_rule_set_offsets_byte_range(&self) -> Range<usize> {
let class_seq_rule_set_count = self.class_seq_rule_set_count();
let start = self.class_seq_rule_set_count_byte_range().end;
let end = start
+ (transforms::to_usize(class_seq_rule_set_count))
.saturating_mul(Offset24::RAW_BYTE_LEN);
start..end
}
}
impl<'a> MinByteRange<'a> for ClassSequenceRuleSet2<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.class_seq_rule_offsets_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for ClassSequenceRuleSet2<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for ClassSequenceRuleSet2<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self { data })
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct ClassSequenceRuleSet2FixedHeader {
pub class_seq_rule_count: BigEndian<u16>,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () = assert!(
std::mem::size_of::<ClassSequenceRuleSet2FixedHeader>() <= ClassSequenceRuleSet2::MIN_SIZE
);
#[derive(Clone)]
pub struct ClassSequenceRuleSet2<'a> {
data: TableDataRef<'a, ClassSequenceRuleSet2FixedHeader>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> ClassSequenceRuleSet2<'a> {
pub const MIN_SIZE: usize = u16::RAW_BYTE_LEN;
basic_table_impls!(impl_the_methods);
pub fn class_seq_rule_count(&self) -> u16 {
self.data.header().class_seq_rule_count.get()
}
pub fn class_seq_rule_offsets(&self) -> &'a [BigEndian<Offset24>] {
let range = self.class_seq_rule_offsets_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn class_seq_rules(&self) -> ArrayOfOffsets<'a, ClassSequenceRule<'a>, Offset24> {
let data = self.offset_data();
let offsets = self.class_seq_rule_offsets();
ArrayOfOffsets::new(offsets, data, ())
}
pub fn class_seq_rule_count_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn class_seq_rule_offsets_byte_range(&self) -> Range<usize> {
let class_seq_rule_count = self.class_seq_rule_count();
let start = self.class_seq_rule_count_byte_range().end;
let end = start
+ (transforms::to_usize(class_seq_rule_count)).saturating_mul(Offset24::RAW_BYTE_LEN);
start..end
}
}
const _: () = assert!(FontData::default_data_long_enough(
ClassSequenceRuleSet2::MIN_SIZE
));
impl Default for ClassSequenceRuleSet2<'_> {
fn default() -> Self {
Self {
data: TableDataRef::new(FontData::default_table_data().as_bytes())
.unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
}
}
}
impl Format<u16> for SequenceContextFormat6<'_> {
const FORMAT: u16 = 6;
}
impl<'a> MinByteRange<'a> for SequenceContextFormat6<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.seq_lookup_records_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for SequenceContextFormat6<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for SequenceContextFormat6<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self { data })
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct SequenceContextFormat6FixedHeader {
pub format: BigEndian<u16>,
pub glyph_count: BigEndian<u16>,
pub seq_lookup_count: BigEndian<u16>,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () = assert!(
std::mem::size_of::<SequenceContextFormat6FixedHeader>() <= SequenceContextFormat6::MIN_SIZE
);
#[derive(Clone)]
pub struct SequenceContextFormat6<'a> {
data: TableDataRef<'a, SequenceContextFormat6FixedHeader>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> SequenceContextFormat6<'a> {
pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN);
basic_table_impls!(impl_the_methods);
pub fn format(&self) -> u16 {
self.data.header().format.get()
}
pub fn glyph_count(&self) -> u16 {
self.data.header().glyph_count.get()
}
pub fn seq_lookup_count(&self) -> u16 {
self.data.header().seq_lookup_count.get()
}
pub fn coverage_offsets(&self) -> &'a [BigEndian<Offset24>] {
let range = self.coverage_offsets_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn coverages(&self) -> ArrayOfOffsets<'a, CoverageTable<'a>, Offset24> {
let data = self.offset_data();
let offsets = self.coverage_offsets();
ArrayOfOffsets::new(offsets, data, ())
}
pub fn seq_lookup_records(&self) -> &'a [SequenceLookupRecord] {
let range = self.seq_lookup_records_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn format_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn glyph_count_byte_range(&self) -> Range<usize> {
let start = self.format_byte_range().end;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn seq_lookup_count_byte_range(&self) -> Range<usize> {
let start = self.glyph_count_byte_range().end;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn coverage_offsets_byte_range(&self) -> Range<usize> {
let glyph_count = self.glyph_count();
let start = self.seq_lookup_count_byte_range().end;
let end =
start + (transforms::to_usize(glyph_count)).saturating_mul(Offset24::RAW_BYTE_LEN);
start..end
}
pub fn seq_lookup_records_byte_range(&self) -> Range<usize> {
let seq_lookup_count = self.seq_lookup_count();
let start = self.coverage_offsets_byte_range().end;
let end = start
+ (transforms::to_usize(seq_lookup_count))
.saturating_mul(SequenceLookupRecord::RAW_BYTE_LEN);
start..end
}
}
impl Format<u16> for ChainedSequenceContextFormat4<'_> {
const FORMAT: u16 = 4;
}
impl<'a> MinByteRange<'a> for ChainedSequenceContextFormat4<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.chained_seq_rule_set_offsets_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for ChainedSequenceContextFormat4<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for ChainedSequenceContextFormat4<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self { data })
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct ChainedSequenceContextFormat4FixedHeader {
pub format: BigEndian<u16>,
pub coverage_offset: BigEndian<Offset32>,
pub chained_seq_rule_set_count: BigEndian<Uint24>,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () = assert!(
std::mem::size_of::<ChainedSequenceContextFormat4FixedHeader>()
<= ChainedSequenceContextFormat4::MIN_SIZE
);
#[derive(Clone)]
pub struct ChainedSequenceContextFormat4<'a> {
data: TableDataRef<'a, ChainedSequenceContextFormat4FixedHeader>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> ChainedSequenceContextFormat4<'a> {
pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + Offset32::RAW_BYTE_LEN + Uint24::RAW_BYTE_LEN);
basic_table_impls!(impl_the_methods);
pub fn format(&self) -> u16 {
self.data.header().format.get()
}
pub fn coverage_offset(&self) -> Offset32 {
self.data.header().coverage_offset.get()
}
pub fn coverage(&self) -> Result<CoverageTable<'a>, ReadError> {
let data = self.offset_data();
self.coverage_offset().resolve(data)
}
pub fn chained_seq_rule_set_count(&self) -> Uint24 {
self.data.header().chained_seq_rule_set_count.get()
}
pub fn chained_seq_rule_set_offsets(&self) -> &'a [BigEndian<Nullable<Offset24>>] {
let range = self.chained_seq_rule_set_offsets_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn chained_seq_rule_sets(
&self,
) -> ArrayOfNullableOffsets<'a, ChainedSequenceRuleSet2<'a>, Offset24> {
let data = self.offset_data();
let offsets = self.chained_seq_rule_set_offsets();
ArrayOfNullableOffsets::new(offsets, data, ())
}
pub fn format_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn coverage_offset_byte_range(&self) -> Range<usize> {
let start = self.format_byte_range().end;
let end = start + Offset32::RAW_BYTE_LEN;
start..end
}
pub fn chained_seq_rule_set_count_byte_range(&self) -> Range<usize> {
let start = self.coverage_offset_byte_range().end;
let end = start + Uint24::RAW_BYTE_LEN;
start..end
}
pub fn chained_seq_rule_set_offsets_byte_range(&self) -> Range<usize> {
let chained_seq_rule_set_count = self.chained_seq_rule_set_count();
let start = self.chained_seq_rule_set_count_byte_range().end;
let end = start
+ (transforms::to_usize(chained_seq_rule_set_count))
.saturating_mul(Offset24::RAW_BYTE_LEN);
start..end
}
}
impl<'a> MinByteRange<'a> for ChainedSequenceRuleSet2<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.chained_seq_rule_offsets_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for ChainedSequenceRuleSet2<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for ChainedSequenceRuleSet2<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self { data })
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct ChainedSequenceRuleSet2FixedHeader {
pub chained_seq_rule_count: BigEndian<u16>,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () = assert!(
std::mem::size_of::<ChainedSequenceRuleSet2FixedHeader>() <= ChainedSequenceRuleSet2::MIN_SIZE
);
#[derive(Clone)]
pub struct ChainedSequenceRuleSet2<'a> {
data: TableDataRef<'a, ChainedSequenceRuleSet2FixedHeader>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> ChainedSequenceRuleSet2<'a> {
pub const MIN_SIZE: usize = u16::RAW_BYTE_LEN;
basic_table_impls!(impl_the_methods);
pub fn chained_seq_rule_count(&self) -> u16 {
self.data.header().chained_seq_rule_count.get()
}
pub fn chained_seq_rule_offsets(&self) -> &'a [BigEndian<Offset24>] {
let range = self.chained_seq_rule_offsets_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn chained_seq_rules(&self) -> ArrayOfOffsets<'a, ChainedSequenceRule2<'a>, Offset24> {
let data = self.offset_data();
let offsets = self.chained_seq_rule_offsets();
ArrayOfOffsets::new(offsets, data, ())
}
pub fn chained_seq_rule_count_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn chained_seq_rule_offsets_byte_range(&self) -> Range<usize> {
let chained_seq_rule_count = self.chained_seq_rule_count();
let start = self.chained_seq_rule_count_byte_range().end;
let end = start
+ (transforms::to_usize(chained_seq_rule_count)).saturating_mul(Offset24::RAW_BYTE_LEN);
start..end
}
}
const _: () = assert!(FontData::default_data_long_enough(
ChainedSequenceRuleSet2::MIN_SIZE
));
impl Default for ChainedSequenceRuleSet2<'_> {
fn default() -> Self {
Self {
data: TableDataRef::new(FontData::default_table_data().as_bytes())
.unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
}
}
}
impl<'a> MinByteRange<'a> for ChainedSequenceRule2<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.seq_lookup_records_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for ChainedSequenceRule2<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for ChainedSequenceRule2<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self { data })
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct ChainedSequenceRule2FixedHeader {
pub backtrack_glyph_count: BigEndian<u16>,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () = assert!(
std::mem::size_of::<ChainedSequenceRule2FixedHeader>() <= ChainedSequenceRule2::MIN_SIZE
);
#[derive(Clone)]
pub struct ChainedSequenceRule2<'a> {
data: TableDataRef<'a, ChainedSequenceRule2FixedHeader>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> ChainedSequenceRule2<'a> {
pub const MIN_SIZE: usize =
(u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN);
basic_table_impls!(impl_the_methods);
pub fn backtrack_glyph_count(&self) -> u16 {
self.data.header().backtrack_glyph_count.get()
}
pub fn backtrack_sequence(&self) -> &'a [BigEndian<GlyphId24>] {
let range = self.backtrack_sequence_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn input_glyph_count(&self) -> u16 {
let range = self.input_glyph_count_byte_range();
self.offset_data()
.read_at(range.start)
.ok()
.unwrap_or_default()
}
pub fn input_sequence(&self) -> &'a [BigEndian<GlyphId24>] {
let range = self.input_sequence_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn lookahead_glyph_count(&self) -> u16 {
let range = self.lookahead_glyph_count_byte_range();
self.offset_data()
.read_at(range.start)
.ok()
.unwrap_or_default()
}
pub fn lookahead_sequence(&self) -> &'a [BigEndian<GlyphId24>] {
let range = self.lookahead_sequence_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn seq_lookup_count(&self) -> u16 {
let range = self.seq_lookup_count_byte_range();
self.offset_data()
.read_at(range.start)
.ok()
.unwrap_or_default()
}
pub fn seq_lookup_records(&self) -> &'a [SequenceLookupRecord] {
let range = self.seq_lookup_records_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn backtrack_glyph_count_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn backtrack_sequence_byte_range(&self) -> Range<usize> {
let backtrack_glyph_count = self.backtrack_glyph_count();
let start = self.backtrack_glyph_count_byte_range().end;
let end = start
+ (transforms::to_usize(backtrack_glyph_count)).saturating_mul(GlyphId24::RAW_BYTE_LEN);
start..end
}
pub fn input_glyph_count_byte_range(&self) -> Range<usize> {
let start = self.backtrack_sequence_byte_range().end;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn input_sequence_byte_range(&self) -> Range<usize> {
let input_glyph_count = self.input_glyph_count();
let start = self.input_glyph_count_byte_range().end;
let end = start
+ (transforms::subtract(input_glyph_count, 1_usize))
.saturating_mul(GlyphId24::RAW_BYTE_LEN);
start..end
}
pub fn lookahead_glyph_count_byte_range(&self) -> Range<usize> {
let start = self.input_sequence_byte_range().end;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn lookahead_sequence_byte_range(&self) -> Range<usize> {
let lookahead_glyph_count = self.lookahead_glyph_count();
let start = self.lookahead_glyph_count_byte_range().end;
let end = start
+ (transforms::to_usize(lookahead_glyph_count)).saturating_mul(GlyphId24::RAW_BYTE_LEN);
start..end
}
pub fn seq_lookup_count_byte_range(&self) -> Range<usize> {
let start = self.lookahead_sequence_byte_range().end;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn seq_lookup_records_byte_range(&self) -> Range<usize> {
let seq_lookup_count = self.seq_lookup_count();
let start = self.seq_lookup_count_byte_range().end;
let end = start
+ (transforms::to_usize(seq_lookup_count))
.saturating_mul(SequenceLookupRecord::RAW_BYTE_LEN);
start..end
}
}
const _: () = assert!(FontData::default_data_long_enough(
ChainedSequenceRule2::MIN_SIZE
));
impl Default for ChainedSequenceRule2<'_> {
fn default() -> Self {
Self {
data: TableDataRef::new(FontData::default_table_data().as_bytes())
.unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
}
}
}
impl Format<u16> for ChainedSequenceContextFormat5<'_> {
const FORMAT: u16 = 5;
}
impl<'a> MinByteRange<'a> for ChainedSequenceContextFormat5<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.chained_class_seq_rule_set_offsets_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for ChainedSequenceContextFormat5<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for ChainedSequenceContextFormat5<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self { data })
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct ChainedSequenceContextFormat5FixedHeader {
pub format: BigEndian<u16>,
pub coverage_offset: BigEndian<Offset32>,
pub backtrack_class_def_offset: BigEndian<Offset32>,
pub input_class_def_offset: BigEndian<Offset32>,
pub lookahead_class_def_offset: BigEndian<Offset32>,
pub chained_class_seq_rule_set_count: BigEndian<u16>,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () = assert!(
std::mem::size_of::<ChainedSequenceContextFormat5FixedHeader>()
<= ChainedSequenceContextFormat5::MIN_SIZE
);
#[derive(Clone)]
pub struct ChainedSequenceContextFormat5<'a> {
data: TableDataRef<'a, ChainedSequenceContextFormat5FixedHeader>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> ChainedSequenceContextFormat5<'a> {
pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN
+ Offset32::RAW_BYTE_LEN
+ Offset32::RAW_BYTE_LEN
+ Offset32::RAW_BYTE_LEN
+ Offset32::RAW_BYTE_LEN
+ u16::RAW_BYTE_LEN);
basic_table_impls!(impl_the_methods);
pub fn format(&self) -> u16 {
self.data.header().format.get()
}
pub fn coverage_offset(&self) -> Offset32 {
self.data.header().coverage_offset.get()
}
pub fn coverage(&self) -> Result<CoverageTable<'a>, ReadError> {
let data = self.offset_data();
self.coverage_offset().resolve(data)
}
pub fn backtrack_class_def_offset(&self) -> Offset32 {
self.data.header().backtrack_class_def_offset.get()
}
pub fn backtrack_class_def(&self) -> Result<ClassDef<'a>, ReadError> {
let data = self.offset_data();
self.backtrack_class_def_offset().resolve(data)
}
pub fn input_class_def_offset(&self) -> Offset32 {
self.data.header().input_class_def_offset.get()
}
pub fn input_class_def(&self) -> Result<ClassDef<'a>, ReadError> {
let data = self.offset_data();
self.input_class_def_offset().resolve(data)
}
pub fn lookahead_class_def_offset(&self) -> Offset32 {
self.data.header().lookahead_class_def_offset.get()
}
pub fn lookahead_class_def(&self) -> Result<ClassDef<'a>, ReadError> {
let data = self.offset_data();
self.lookahead_class_def_offset().resolve(data)
}
pub fn chained_class_seq_rule_set_count(&self) -> u16 {
self.data.header().chained_class_seq_rule_set_count.get()
}
pub fn chained_class_seq_rule_set_offsets(&self) -> &'a [BigEndian<Nullable<Offset24>>] {
let range = self.chained_class_seq_rule_set_offsets_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn chained_class_seq_rule_sets(
&self,
) -> ArrayOfNullableOffsets<'a, ChainedClassSequenceRuleSet2<'a>, Offset24> {
let data = self.offset_data();
let offsets = self.chained_class_seq_rule_set_offsets();
ArrayOfNullableOffsets::new(offsets, data, ())
}
pub fn format_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn coverage_offset_byte_range(&self) -> Range<usize> {
let start = self.format_byte_range().end;
let end = start + Offset32::RAW_BYTE_LEN;
start..end
}
pub fn backtrack_class_def_offset_byte_range(&self) -> Range<usize> {
let start = self.coverage_offset_byte_range().end;
let end = start + Offset32::RAW_BYTE_LEN;
start..end
}
pub fn input_class_def_offset_byte_range(&self) -> Range<usize> {
let start = self.backtrack_class_def_offset_byte_range().end;
let end = start + Offset32::RAW_BYTE_LEN;
start..end
}
pub fn lookahead_class_def_offset_byte_range(&self) -> Range<usize> {
let start = self.input_class_def_offset_byte_range().end;
let end = start + Offset32::RAW_BYTE_LEN;
start..end
}
pub fn chained_class_seq_rule_set_count_byte_range(&self) -> Range<usize> {
let start = self.lookahead_class_def_offset_byte_range().end;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn chained_class_seq_rule_set_offsets_byte_range(&self) -> Range<usize> {
let chained_class_seq_rule_set_count = self.chained_class_seq_rule_set_count();
let start = self.chained_class_seq_rule_set_count_byte_range().end;
let end = start
+ (transforms::to_usize(chained_class_seq_rule_set_count))
.saturating_mul(Offset24::RAW_BYTE_LEN);
start..end
}
}
impl<'a> MinByteRange<'a> for ChainedClassSequenceRuleSet2<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.chained_class_seq_rule_offsets_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for ChainedClassSequenceRuleSet2<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for ChainedClassSequenceRuleSet2<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self { data })
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct ChainedClassSequenceRuleSet2FixedHeader {
pub chained_class_seq_rule_count: BigEndian<u16>,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () = assert!(
std::mem::size_of::<ChainedClassSequenceRuleSet2FixedHeader>()
<= ChainedClassSequenceRuleSet2::MIN_SIZE
);
#[derive(Clone)]
pub struct ChainedClassSequenceRuleSet2<'a> {
data: TableDataRef<'a, ChainedClassSequenceRuleSet2FixedHeader>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> ChainedClassSequenceRuleSet2<'a> {
pub const MIN_SIZE: usize = u16::RAW_BYTE_LEN;
basic_table_impls!(impl_the_methods);
pub fn chained_class_seq_rule_count(&self) -> u16 {
self.data.header().chained_class_seq_rule_count.get()
}
pub fn chained_class_seq_rule_offsets(&self) -> &'a [BigEndian<Offset24>] {
let range = self.chained_class_seq_rule_offsets_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn chained_class_seq_rules(
&self,
) -> ArrayOfOffsets<'a, ChainedClassSequenceRule<'a>, Offset24> {
let data = self.offset_data();
let offsets = self.chained_class_seq_rule_offsets();
ArrayOfOffsets::new(offsets, data, ())
}
pub fn chained_class_seq_rule_count_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn chained_class_seq_rule_offsets_byte_range(&self) -> Range<usize> {
let chained_class_seq_rule_count = self.chained_class_seq_rule_count();
let start = self.chained_class_seq_rule_count_byte_range().end;
let end = start
+ (transforms::to_usize(chained_class_seq_rule_count))
.saturating_mul(Offset24::RAW_BYTE_LEN);
start..end
}
}
const _: () = assert!(FontData::default_data_long_enough(
ChainedClassSequenceRuleSet2::MIN_SIZE
));
impl Default for ChainedClassSequenceRuleSet2<'_> {
fn default() -> Self {
Self {
data: TableDataRef::new(FontData::default_table_data().as_bytes())
.unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
}
}
}
impl<'a, T> MinByteRange<'a> for LookupList2<'a, T> {
fn min_byte_range(&self) -> Range<usize> {
0..self.lookup_offsets_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.offset_data().as_bytes().get(range).unwrap_or_default()
}
}
impl<T> ReadArgs for LookupList2<'_, T> {
type Args = ();
}
impl<'a, T> FontRead<'a> for LookupList2<'a, T> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
let Some(data) = TableDataRef::new(data.as_bytes()) else {
return Err(ReadError::OutOfBounds);
};
Ok(Self {
data,
offset_type: std::marker::PhantomData,
})
}
}
impl<'a, T> LookupList2<'a, T> {
#[allow(dead_code)]
pub(crate) fn of_unit_type(&self) -> LookupList2<'a, ()> {
LookupList2 {
data: self.data,
offset_type: std::marker::PhantomData,
}
}
}
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
#[repr(C, packed)]
#[doc(hidden)]
pub struct LookupList2FixedHeader {
pub lookup_count: BigEndian<u16>,
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () = assert!(std::mem::size_of::<LookupList2FixedHeader>() <= LookupList2::<()>::MIN_SIZE);
#[derive(Clone)]
pub struct LookupList2<'a, T = ()> {
data: TableDataRef<'a, LookupList2FixedHeader>,
offset_type: std::marker::PhantomData<*const T>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a, T> LookupList2<'a, T> {
pub const MIN_SIZE: usize = u16::RAW_BYTE_LEN;
basic_table_impls!(impl_the_methods);
pub fn lookup_count(&self) -> u16 {
self.data.header().lookup_count.get()
}
pub fn lookup_offsets(&self) -> &'a [BigEndian<Offset32>] {
let range = self.lookup_offsets_byte_range();
self.offset_data()
.read_array(range)
.ok()
.unwrap_or_default()
}
pub fn lookups(&self) -> ArrayOfOffsets<'a, T, Offset32>
where
T: FontRead<'a, Args = ()>,
{
let data = self.offset_data();
let offsets = self.lookup_offsets();
ArrayOfOffsets::new(offsets, data, ())
}
pub fn lookup_count_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn lookup_offsets_byte_range(&self) -> Range<usize> {
let lookup_count = self.lookup_count();
let start = self.lookup_count_byte_range().end;
let end =
start + (transforms::to_usize(lookup_count)).saturating_mul(Offset32::RAW_BYTE_LEN);
start..end
}
}
const _: () = assert!(FontData::default_data_long_enough(
LookupList2::<()>::MIN_SIZE
));
impl<T> Default for LookupList2<'_, T> {
fn default() -> Self {
Self {
data: TableDataRef::new(FontData::default_table_data().as_bytes())
.unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
offset_type: std::marker::PhantomData,
}
}
}