#[allow(unused_imports)]
use crate::codegen_prelude::*;
impl<'a> MinByteRange<'a> for PositionedTable<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.pairs_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.data.as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for PositionedTable<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for PositionedTable<'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);
}
Ok(Self { data })
}
}
#[derive(Clone)]
pub struct PositionedTable<'a> {
data: FontData<'a>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> PositionedTable<'a> {
pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN);
basic_table_impls!(impl_the_methods);
pub fn positioned_size(&self) -> u16 {
let range = self.positioned_size_byte_range();
self.data.read_at(range.start).ok().unwrap()
}
pub fn solo(&self) -> Positioned<'a> {
let range = self.solo_byte_range();
Positioned::read_at(self.data, range.start, self.positioned_size()).unwrap_or_default()
}
pub fn pair_count(&self) -> u16 {
let range = self.pair_count_byte_range();
self.data.read_at(range.start).ok().unwrap_or_default()
}
pub fn pairs(&self) -> ComputedArray<'a, PositionedPair<'a>> {
let range = self.pairs_byte_range();
ComputedArray::new(self.data, range, self.positioned_size()).unwrap_or_default()
}
pub fn positioned_size_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn solo_byte_range(&self) -> Range<usize> {
let start = self.positioned_size_byte_range().end;
let end =
start + <Positioned as ComputeSize>::compute_size(self.positioned_size()).unwrap_or(0);
start..end
}
pub fn pair_count_byte_range(&self) -> Range<usize> {
let start = self.solo_byte_range().end;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn pairs_byte_range(&self) -> Range<usize> {
let pair_count = self.pair_count();
let start = self.pair_count_byte_range().end;
let end = start
+ (transforms::to_usize(pair_count)).saturating_mul(
<PositionedPair as ComputeSize>::compute_size(self.positioned_size()).unwrap_or(0),
);
start..end
}
}
const _: () = assert!(FontData::default_data_long_enough(
PositionedTable::MIN_SIZE
));
impl Default for PositionedTable<'_> {
fn default() -> Self {
Self {
data: FontData::default_table_data(),
}
}
}
#[derive(Clone, Debug)]
pub struct PositionedPair<'a> {
pub tag: BigEndian<u16>,
pub first: Positioned<'a>,
pub second: Positioned<'a>,
}
impl<'a> PositionedPair<'a> {
pub fn tag(&self) -> u16 {
self.tag.get()
}
pub fn first(&self) -> &Positioned<'a> {
&self.first
}
pub fn second(&self) -> &Positioned<'a> {
&self.second
}
}
impl ReadArgs for PositionedPair<'_> {
type Args = u16;
}
impl ComputeSize for PositionedPair<'_> {
#[allow(clippy::needless_question_mark)]
fn compute_size(args: u16) -> Result<usize, ReadError> {
let positioned_size = args;
let mut result = 0usize;
result = result
.checked_add(u16::RAW_BYTE_LEN)
.ok_or(ReadError::OutOfBounds)?;
result = result
.checked_add(<Positioned as ComputeSize>::compute_size(positioned_size).unwrap_or(0))
.ok_or(ReadError::OutOfBounds)?;
result = result
.checked_add(<Positioned as ComputeSize>::compute_size(positioned_size).unwrap_or(0))
.ok_or(ReadError::OutOfBounds)?;
Ok(result)
}
}
impl<'a> FontReadAt<'a> for PositionedPair<'a> {
fn read_at(data: FontData<'a>, offset: usize, args: u16) -> Result<Self, ReadError> {
let mut cursor = data.cursor();
cursor.advance_by(offset);
let positioned_size = args;
Ok(Self {
tag: cursor.read_be()?,
first: cursor.read_at_with_args(positioned_size)?,
second: cursor.read_at_with_args(positioned_size)?,
})
}
}
#[allow(clippy::needless_lifetimes)]
impl<'a> PositionedPair<'a> {
pub fn read(
data: FontData<'a>,
offset: usize,
positioned_size: u16,
) -> Result<Self, ReadError> {
let args = positioned_size;
Self::read_at(data, offset, args)
}
}
impl<'a> MinByteRange<'a> for NestedPositionedTable<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.groups_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.data.as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for NestedPositionedTable<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for NestedPositionedTable<'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);
}
Ok(Self { data })
}
}
#[derive(Clone)]
pub struct NestedPositionedTable<'a> {
data: FontData<'a>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> NestedPositionedTable<'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 positioned_size(&self) -> u16 {
let range = self.positioned_size_byte_range();
self.data.read_at(range.start).ok().unwrap()
}
pub fn pairs_per_group(&self) -> u16 {
let range = self.pairs_per_group_byte_range();
self.data.read_at(range.start).ok().unwrap()
}
pub fn group_count(&self) -> u16 {
let range = self.group_count_byte_range();
self.data.read_at(range.start).ok().unwrap()
}
pub fn groups(&self) -> ComputedArray<'a, PositionedGroup<'a>> {
let range = self.groups_byte_range();
ComputedArray::new(
self.data,
range,
(self.pairs_per_group(), self.positioned_size()),
)
.unwrap_or_default()
}
pub fn positioned_size_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn pairs_per_group_byte_range(&self) -> Range<usize> {
let start = self.positioned_size_byte_range().end;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn group_count_byte_range(&self) -> Range<usize> {
let start = self.pairs_per_group_byte_range().end;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn groups_byte_range(&self) -> Range<usize> {
let group_count = self.group_count();
let start = self.group_count_byte_range().end;
let end = start
+ (transforms::to_usize(group_count)).saturating_mul(
<PositionedGroup as ComputeSize>::compute_size((
self.pairs_per_group(),
self.positioned_size(),
))
.unwrap_or(0),
);
start..end
}
}
const _: () = assert!(FontData::default_data_long_enough(
NestedPositionedTable::MIN_SIZE
));
impl Default for NestedPositionedTable<'_> {
fn default() -> Self {
Self {
data: FontData::default_table_data(),
}
}
}
#[derive(Clone, Debug)]
pub struct PositionedGroup<'a> {
pub pairs: ComputedArray<'a, PositionedPair<'a>>,
}
impl<'a> PositionedGroup<'a> {
pub fn pairs(&self) -> &ComputedArray<'a, PositionedPair<'a>> {
&self.pairs
}
}
impl ReadArgs for PositionedGroup<'_> {
type Args = (u16, u16);
}
impl ComputeSize for PositionedGroup<'_> {
#[allow(clippy::needless_question_mark)]
fn compute_size(args: (u16, u16)) -> Result<usize, ReadError> {
let (pairs_per_group, positioned_size) = args;
Ok((transforms::to_usize(pairs_per_group)).saturating_mul(
<PositionedPair as ComputeSize>::compute_size(positioned_size).unwrap_or(0),
))
}
}
impl<'a> FontReadAt<'a> for PositionedGroup<'a> {
fn read_at(data: FontData<'a>, offset: usize, args: (u16, u16)) -> Result<Self, ReadError> {
let mut cursor = data.cursor();
cursor.advance_by(offset);
let (pairs_per_group, positioned_size) = args;
Ok(Self {
pairs: cursor
.read_computed_array(transforms::to_usize(pairs_per_group), positioned_size)?,
})
}
}
#[allow(clippy::needless_lifetimes)]
impl<'a> PositionedGroup<'a> {
pub fn read(
data: FontData<'a>,
offset: usize,
pairs_per_group: u16,
positioned_size: u16,
) -> Result<Self, ReadError> {
let args = (pairs_per_group, positioned_size);
Self::read_at(data, offset, args)
}
}