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 Os2MetricsTable0([u8; 78]);
impl<'a> RandomAccess<'a> for &'a Os2MetricsTable0 {
fn bytes(&self) -> &'a [u8] { &self.0 }
}
impl Os2MetricsTable0 {
pub fn version(&self) -> u16 { self.uint16(0) }
pub fn avg_char_width(&self) -> i16 { self.int16(2) }
pub fn weight_class(&self) -> u16 { self.uint16(4) }
pub fn width_class(&self) -> u16 { self.uint16(6) }
pub fn type_flags(&self) -> u16 { self.uint16(8) }
pub fn subscript_size(&self) -> (i16, i16) { (self.int16(10), self.int16(12)) }
pub fn subscript_offset(&self) -> (i16, i16) { (self.int16(14), self.int16(16)) }
pub fn superscript_size(&self) -> (i16, i16) { (self.int16(18), self.int16(20)) }
pub fn superscript_offset(&self) -> (i16, i16) { (self.int16(22), self.int16(24)) }
pub fn strikeout_size(&self) -> i16 { self.int16(26) }
pub fn strikeout_position(&self) -> i16 { self.int16(28) }
pub fn family_class(&self) -> i16 { self.int16(30) }
pub fn panose(&self) -> &[u8; 10] { self.item(32) }
pub fn unicode_range_1(&self) -> u32 { self.uint32(42) }
pub fn unicode_range_2(&self) -> u32 { self.uint32(46) }
pub fn unicode_range_3(&self) -> u32 { self.uint32(50) }
pub fn unicode_range_4(&self) -> u32 { self.uint32(54) }
pub fn vendor_id(&self) -> &Tag { self.item(58) }
pub fn selection_flags(&self) -> u16 { self.uint16(62) }
pub fn first_char_index(&self) -> u16 { self.uint16(64) }
pub fn last_char_index(&self) -> u16 { self.uint16(66) }
pub fn typo_ascender(&self) -> i16 { self.int16(68) }
pub fn typo_descender(&self) -> i16 { self.int16(70) }
pub fn typo_line_gap(&self) -> i16 { self.int16(72) }
pub fn win_ascent(&self) -> u16 { self.uint16(74) }
pub fn win_descent(&self) -> u16 { self.uint16(76) }
}
impl Debug for Os2MetricsTable0 {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
f.debug_struct("Os2MetricsTable0")
.field("version", &self.version())
.field("avg_char_width", &self.avg_char_width())
.field("weight_class", &self.weight_class())
.field("width_class", &self.width_class())
.field("type_flags", &self.type_flags())
.field("subscript_size", &self.subscript_size())
.field("subscript_offset", &self.subscript_offset())
.field("superscript_size", &self.superscript_size())
.field("superscript_offset", &self.superscript_offset())
.field("strikeout_size", &self.strikeout_size())
.field("strikeout_position", &self.strikeout_position())
.field("family_class", &self.family_class())
.field("panose", &self.panose())
.field("unicode_range_1", &self.unicode_range_1())
.field("unicode_range_2", &self.unicode_range_2())
.field("unicode_range_3", &self.unicode_range_3())
.field("unicode_range_4", &self.unicode_range_4())
.field("vendor_id", &self.vendor_id())
.field("selection_flags", &self.selection_flags())
.field("first_char_index", &self.first_char_index())
.field("last_char_index", &self.last_char_index())
.field("typo_ascender", &self.typo_ascender())
.field("typo_descender", &self.typo_descender())
.field("typo_line_gap", &self.typo_line_gap())
.field("win_ascent", &self.win_ascent())
.field("win_descent", &self.win_descent())
.finish()
}
}
#[derive(Clone, Copy, Zeroable, Pod)]
#[repr(transparent)]
pub struct Os2MetricsTable1([u8; 86]);
impl<'a> RandomAccess<'a> for &'a Os2MetricsTable1 {
fn bytes(&self) -> &'a [u8] { &self.0 }
}
impl AsRef<Os2MetricsTable0> for Os2MetricsTable1 {
fn as_ref(&self) -> &Os2MetricsTable0 { bytemuck::from_bytes(&self.0[0..78]) }
}
impl Deref for Os2MetricsTable1 {
type Target = Os2MetricsTable0;
fn deref(&self) -> &Self::Target { self.as_ref() }
}
impl Os2MetricsTable1 {
pub fn code_page_range_1(&self) -> u32 { self.uint32(78) }
pub fn code_page_range_2(&self) -> u32 { self.uint32(82) }
}
impl Debug for Os2MetricsTable1 {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
f.debug_struct("Os2MetricsTable1")
.field("version", &self.version())
.field("avg_char_width", &self.avg_char_width())
.field("weight_class", &self.weight_class())
.field("width_class", &self.width_class())
.field("type_flags", &self.type_flags())
.field("subscript_size", &self.subscript_size())
.field("subscript_offset", &self.subscript_offset())
.field("superscript_size", &self.superscript_size())
.field("superscript_offset", &self.superscript_offset())
.field("strikeout_size", &self.strikeout_size())
.field("strikeout_position", &self.strikeout_position())
.field("family_class", &self.family_class())
.field("panose", &self.panose())
.field("unicode_range_1", &self.unicode_range_1())
.field("unicode_range_2", &self.unicode_range_2())
.field("unicode_range_3", &self.unicode_range_3())
.field("unicode_range_4", &self.unicode_range_4())
.field("vendor_id", &self.vendor_id())
.field("selection_flags", &self.selection_flags())
.field("first_char_index", &self.first_char_index())
.field("last_char_index", &self.last_char_index())
.field("typo_ascender", &self.typo_ascender())
.field("typo_descender", &self.typo_descender())
.field("typo_line_gap", &self.typo_line_gap())
.field("win_ascent", &self.win_ascent())
.field("win_descent", &self.win_descent())
.field("code_page_range_1", &self.code_page_range_1())
.field("code_page_range_2", &self.code_page_range_2())
.finish()
}
}
#[derive(Clone, Copy, Zeroable, Pod)]
#[repr(transparent)]
pub struct Os2MetricsTable2([u8; 96]);
impl<'a> RandomAccess<'a> for &'a Os2MetricsTable2 {
fn bytes(&self) -> &'a [u8] { &self.0 }
}
impl AsRef<Os2MetricsTable0> for Os2MetricsTable2 {
fn as_ref(&self) -> &Os2MetricsTable0 { bytemuck::from_bytes(&self.0[0..78]) }
}
impl AsRef<Os2MetricsTable1> for Os2MetricsTable2 {
fn as_ref(&self) -> &Os2MetricsTable1 { bytemuck::from_bytes(&self.0[0..86]) }
}
impl Deref for Os2MetricsTable2 {
type Target = Os2MetricsTable1;
fn deref(&self) -> &Self::Target { self.as_ref() }
}
impl Os2MetricsTable2 {
pub fn x_height(&self) -> i16 { self.int16(86) }
pub fn cap_height(&self) -> i16 { self.int16(88) }
pub fn default_char(&self) -> u16 { self.uint16(90) }
pub fn break_char(&self) -> u16 { self.uint16(92) }
pub fn max_context(&self) -> u16 { self.uint16(94) }
}
impl Debug for Os2MetricsTable2 {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
f.debug_struct("Os2MetricsTable2")
.field("version", &self.version())
.field("avg_char_width", &self.avg_char_width())
.field("weight_class", &self.weight_class())
.field("width_class", &self.width_class())
.field("type_flags", &self.type_flags())
.field("subscript_size", &self.subscript_size())
.field("subscript_offset", &self.subscript_offset())
.field("superscript_size", &self.superscript_size())
.field("superscript_offset", &self.superscript_offset())
.field("strikeout_size", &self.strikeout_size())
.field("strikeout_position", &self.strikeout_position())
.field("family_class", &self.family_class())
.field("panose", &self.panose())
.field("unicode_range_1", &self.unicode_range_1())
.field("unicode_range_2", &self.unicode_range_2())
.field("unicode_range_3", &self.unicode_range_3())
.field("unicode_range_4", &self.unicode_range_4())
.field("vendor_id", &self.vendor_id())
.field("selection_flags", &self.selection_flags())
.field("first_char_index", &self.first_char_index())
.field("last_char_index", &self.last_char_index())
.field("typo_ascender", &self.typo_ascender())
.field("typo_descender", &self.typo_descender())
.field("typo_line_gap", &self.typo_line_gap())
.field("win_ascent", &self.win_ascent())
.field("win_descent", &self.win_descent())
.field("code_page_range_1", &self.code_page_range_1())
.field("code_page_range_2", &self.code_page_range_2())
.field("x_height", &self.x_height())
.field("cap_height", &self.cap_height())
.field("default_char", &self.default_char())
.field("break_char", &self.break_char())
.field("max_context", &self.max_context())
.finish()
}
}
#[derive(Clone, Copy, Zeroable, Pod)]
#[repr(transparent)]
pub struct Os2MetricsTable5([u8; 100]);
impl<'a> RandomAccess<'a> for &'a Os2MetricsTable5 {
fn bytes(&self) -> &'a [u8] { &self.0 }
}
impl AsRef<Os2MetricsTable0> for Os2MetricsTable5 {
fn as_ref(&self) -> &Os2MetricsTable0 { bytemuck::from_bytes(&self.0[0..78]) }
}
impl AsRef<Os2MetricsTable1> for Os2MetricsTable5 {
fn as_ref(&self) -> &Os2MetricsTable1 { bytemuck::from_bytes(&self.0[0..86]) }
}
impl AsRef<Os2MetricsTable2> for Os2MetricsTable5 {
fn as_ref(&self) -> &Os2MetricsTable2 { bytemuck::from_bytes(&self.0[0..96]) }
}
impl Deref for Os2MetricsTable5 {
type Target = Os2MetricsTable2;
fn deref(&self) -> &Self::Target { self.as_ref() }
}
impl Os2MetricsTable5 {
pub fn lower_optical_point_size(&self) -> u16 { self.uint16(96) }
pub fn upper_optical_point_size(&self) -> u16 { self.uint16(98) }
}
impl Debug for Os2MetricsTable5 {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
f.debug_struct("Os2MetricsTable5")
.field("version", &self.version())
.field("avg_char_width", &self.avg_char_width())
.field("weight_class", &self.weight_class())
.field("width_class", &self.width_class())
.field("type_flags", &self.type_flags())
.field("subscript_size", &self.subscript_size())
.field("subscript_offset", &self.subscript_offset())
.field("superscript_size", &self.superscript_size())
.field("superscript_offset", &self.superscript_offset())
.field("strikeout_size", &self.strikeout_size())
.field("strikeout_position", &self.strikeout_position())
.field("family_class", &self.family_class())
.field("panose", &self.panose())
.field("unicode_range_1", &self.unicode_range_1())
.field("unicode_range_2", &self.unicode_range_2())
.field("unicode_range_3", &self.unicode_range_3())
.field("unicode_range_4", &self.unicode_range_4())
.field("vendor_id", &self.vendor_id())
.field("selection_flags", &self.selection_flags())
.field("first_char_index", &self.first_char_index())
.field("last_char_index", &self.last_char_index())
.field("typo_ascender", &self.typo_ascender())
.field("typo_descender", &self.typo_descender())
.field("typo_line_gap", &self.typo_line_gap())
.field("win_ascent", &self.win_ascent())
.field("win_descent", &self.win_descent())
.field("code_page_range_1", &self.code_page_range_1())
.field("code_page_range_2", &self.code_page_range_2())
.field("x_height", &self.x_height())
.field("cap_height", &self.cap_height())
.field("default_char", &self.default_char())
.field("break_char", &self.break_char())
.field("max_context", &self.max_context())
.field("lower_optical_point_size", &self.lower_optical_point_size())
.field("upper_optical_point_size", &self.upper_optical_point_size())
.finish()
}
}
#[derive(Clone, Copy)]
pub enum Os2MetricsTable<'a> {
Version0(&'a Os2MetricsTable0),
Version1(&'a Os2MetricsTable1),
Version2(&'a Os2MetricsTable2),
Version3(&'a Os2MetricsTable2),
Version4(&'a Os2MetricsTable2),
Version5(&'a Os2MetricsTable5),
}
impl<'a> RandomAccess<'a> for Os2MetricsTable<'a> {
fn bytes(&self) -> &'a [u8] {
match self {
Self::Version0(x) => x.bytes(),
Self::Version1(x) => x.bytes(),
Self::Version2(x) => x.bytes(),
Self::Version3(x) => x.bytes(),
Self::Version4(x) => x.bytes(),
Self::Version5(x) => x.bytes(),
}
}
}
impl<'a> Deref for Os2MetricsTable<'a> {
type Target = Os2MetricsTable0;
fn deref(&self) -> &Self::Target {
match self {
Self::Version0(x) => x,
Self::Version1(x) => x,
Self::Version2(x) => x,
Self::Version3(x) => x,
Self::Version4(x) => x,
Self::Version5(x) => x,
}
}
}
impl<'a> Debug for Os2MetricsTable<'a> {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
match self {
Self::Version0(x) => x.fmt(f),
Self::Version1(x) => x.fmt(f),
Self::Version2(x) => x.fmt(f),
Self::Version3(x) => x.fmt(f),
Self::Version4(x) => x.fmt(f),
Self::Version5(x) => x.fmt(f),
}
}
}
impl<'a> TryFrom<&'a [u8]> for Os2MetricsTable<'a> {
type Error = ReadError;
fn try_from(value: &'a [u8]) -> Result<Self, Self::Error> {
if value.len() < 2 { return Err(ReadError::UnexpectedEof); }
match value.uint16(0) {
0 => {
if value.len() < 78 { return Err(ReadError::UnexpectedEof); }
Ok(Os2MetricsTable::Version0(bytemuck::from_bytes(&value[0..78])))
},
1 => {
if value.len() < 86 { return Err(ReadError::UnexpectedEof); }
Ok(Os2MetricsTable::Version1(bytemuck::from_bytes(&value[0..86])))
},
2 => {
if value.len() < 96 { return Err(ReadError::UnexpectedEof); }
Ok(Os2MetricsTable::Version2(bytemuck::from_bytes(&value[0..96])))
},
3 => {
if value.len() < 96 { return Err(ReadError::UnexpectedEof); }
Ok(Os2MetricsTable::Version3(bytemuck::from_bytes(&value[0..96])))
},
4 => {
if value.len() < 96 { return Err(ReadError::UnexpectedEof); }
Ok(Os2MetricsTable::Version4(bytemuck::from_bytes(&value[0..96])))
},
5 => {
if value.len() < 100 { return Err(ReadError::UnexpectedEof); }
Ok(Os2MetricsTable::Version5(bytemuck::from_bytes(&value[0..100])))
},
x => Err(ReadError::UnsupportedTableVersionSingle(x))
}
}
}