use std::ops::Deref;
use std::fmt::{ Debug, Formatter, Result as FmtResult };
use bytemuck::{ Zeroable, Pod };
use super::ReadError;
use super::core::*;
#[derive(Clone, Copy, Zeroable, Pod)]
#[repr(transparent)]
pub struct MaximumProfile0([u8; 6]);
impl<'a> RandomAccess<'a> for &'a MaximumProfile0 {
fn bytes(&self) -> &'a [u8] { &self.0 }
}
impl MaximumProfile0 {
pub fn version(&self) -> Version16Dot16 { self.version16dot16(0) }
pub fn num_glyphs(&self) -> u16 { self.uint16(4) }
}
impl Debug for MaximumProfile0 {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
f.debug_struct("MaximumProfile0")
.field("version", &self.version())
.field("num_glyphs", &self.num_glyphs())
.finish()
}
}
#[derive(Clone, Copy, Zeroable, Pod)]
#[repr(transparent)]
pub struct MaximumProfile1([u8; 32]);
impl<'a> RandomAccess<'a> for &'a MaximumProfile1 {
fn bytes(&self) -> &'a [u8] { &self.0 }
}
impl AsRef<MaximumProfile0> for MaximumProfile1 {
fn as_ref(&self) -> &MaximumProfile0 { bytemuck::from_bytes(&self.0[0..6]) }
}
impl Deref for MaximumProfile1 {
type Target = MaximumProfile0;
fn deref(&self) -> &Self::Target { self.as_ref() }
}
impl MaximumProfile1 {
pub fn max_points(&self) -> u16 { self.uint16(6) }
pub fn max_contours(&self) -> u16 { self.uint16(8) }
pub fn max_composite_points(&self) -> u16 { self.uint16(10) }
pub fn max_composite_contours(&self) -> u16 { self.uint16(12) }
pub fn max_zones(&self) -> u16 { self.uint16(14) }
pub fn max_twilight_points(&self) -> u16 { self.uint16(16) }
pub fn max_storage(&self) -> u16 { self.uint16(18) }
pub fn max_function_defs(&self) -> u16 { self.uint16(20) }
pub fn max_instruction_defs(&self) -> u16 { self.uint16(22) }
pub fn max_stack_elements(&self) -> u16 { self.uint16(24) }
pub fn max_size_of_instructions(&self) -> u16 { self.uint16(26) }
pub fn max_component_elements(&self) -> u16 { self.uint16(28) }
pub fn max_component_depth(&self) -> u16 { self.uint16(30) }
}
impl Debug for MaximumProfile1 {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
f.debug_struct("MaximumProfile1")
.field("version", &self.version())
.field("num_glyphs", &self.num_glyphs())
.field("max_points", &self.max_points())
.field("max_contours", &self.max_contours())
.field("max_composite_points", &self.max_composite_points())
.field("max_composite_contours", &self.max_composite_contours())
.field("max_zones", &self.max_zones())
.field("max_twilight_points", &self.max_twilight_points())
.field("max_storage", &self.max_storage())
.field("max_function_defs", &self.max_function_defs())
.field("max_instruction_defs", &self.max_instruction_defs())
.field("max_stack_elements", &self.max_stack_elements())
.field("max_size_of_instructions", &self.max_size_of_instructions())
.field("max_component_elements", &self.max_component_elements())
.field("max_component_depth", &self.max_component_depth())
.finish()
}
}
#[derive(Clone, Copy)]
pub enum MaximumProfile<'a> {
Version0_5(&'a MaximumProfile0),
Version1_0(&'a MaximumProfile1),
}
impl<'a> RandomAccess<'a> for MaximumProfile<'a> {
fn bytes(&self) -> &'a [u8] {
match self {
Self::Version0_5(x) => x.bytes(),
Self::Version1_0(x) => x.bytes(),
}
}
}
impl<'a> Deref for MaximumProfile<'a> {
type Target = MaximumProfile0;
fn deref(&self) -> &Self::Target {
match self {
Self::Version0_5(x) => x,
Self::Version1_0(x) => x,
}
}
}
impl<'a> Debug for MaximumProfile<'a> {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
match self {
Self::Version0_5(x) => x.fmt(f),
Self::Version1_0(x) => x.fmt(f),
}
}
}
impl<'a> TryFrom<&'a [u8]> for MaximumProfile<'a> {
type Error = ReadError;
fn try_from(value: &'a [u8]) -> Result<Self, Self::Error> {
if value.len() < 6 { return Err(ReadError::UnexpectedEof); }
match value.version16dot16(0) {
Version16Dot16(0x0000, 0x5000) => Ok(Self::Version0_5(bytemuck::from_bytes(value))),
Version16Dot16(0x0001, 0x0000) => {
if value.as_ref().len() < 32 { return Err(ReadError::UnexpectedEof); }
Ok(Self::Version1_0(bytemuck::from_bytes(value)))
},
x => Err(ReadError::UnsupportedTableVersion16Dot16(x))
}
}
}