#[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>),
}
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(),
}
}
pub fn coverage_format(&self) -> u16 {
match self {
Self::Format1(item) => item.coverage_format(),
Self::Format2(item) => item.coverage_format(),
}
}
}
impl ReadArgs for CoverageTable<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for CoverageTable<'a> {
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)?)),
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(),
}
}
fn min_table_bytes(&self) -> &'a [u8] {
match self {
Self::Format1(item) => item.min_table_bytes(),
Self::Format2(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>),
}
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(),
}
}
pub fn class_format(&self) -> u16 {
match self {
Self::Format1(item) => item.class_format(),
Self::Format2(item) => item.class_format(),
}
}
}
impl ReadArgs for ClassDef<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for ClassDef<'a> {
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)?)),
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(),
}
}
fn min_table_bytes(&self) -> &'a [u8] {
match self {
Self::Format1(item) => item.min_table_bytes(),
Self::Format2(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>),
}
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(),
}
}
pub fn format(&self) -> u16 {
match self {
Self::Format1(item) => item.format(),
Self::Format2(item) => item.format(),
Self::Format3(item) => item.format(),
}
}
}
impl ReadArgs for SequenceContext<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for SequenceContext<'a> {
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)?)),
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(),
}
}
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(),
}
}
}
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>),
}
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(),
}
}
pub fn format(&self) -> u16 {
match self {
Self::Format1(item) => item.format(),
Self::Format2(item) => item.format(),
Self::Format3(item) => item.format(),
}
}
}
impl ReadArgs for ChainedSequenceContext<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for ChainedSequenceContext<'a> {
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)?)),
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(),
}
}
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(),
}
}
}
#[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> {
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 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
}
}
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;
}
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> {
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")),
}
}
}