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 VertialHeaderTable([u8; 36]);
impl<'a> RandomAccess<'a> for &'a VertialHeaderTable {
fn bytes(&self) -> &'a [u8] { &self.0 }
}
impl VertialHeaderTable {
pub fn version(&self) -> Version16Dot16 { self.version16dot16(0) }
pub fn ascender(&self) -> i16 { self.int16(4) }
pub fn descender(&self) -> i16 { self.int16(6) }
pub fn line_gap(&self) -> i16 { self.int16(8) }
pub fn advance_height_max(&self) -> u16 { self.uint16(10) }
pub fn min_top_side_bearing(&self) -> i16 { self.int16(12) }
pub fn min_bottom_side_bearing(&self) -> i16 { self.int16(14) }
pub fn max_y_extent(&self) -> i16 { self.int16(16) }
pub fn caret_slope_rise(&self) -> i16 { self.int16(18) }
pub fn caret_slope_run(&self) -> i16 { self.int16(20) }
pub fn caret_offset(&self) -> i16 { self.int16(22) }
pub fn metrics_data_format(&self) -> i16 { self.int16(32) }
pub fn number_of_vmetrics(&self) -> u16 { self.uint16(34) }
}
impl Debug for VertialHeaderTable {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
f.debug_struct("VertialHeaderTable")
.field("version", &self.version())
.field("ascender", &self.ascender())
.field("descender", &self.descender())
.field("line_gap", &self.line_gap())
.field("advance_height_max", &self.advance_height_max())
.field("min_top_side_bearing", &self.min_top_side_bearing())
.field("min_bottom_side_bearing", &self.min_bottom_side_bearing())
.field("max_y_extent", &self.max_y_extent())
.field("caret_slope_rise", &self.caret_slope_rise())
.field("caret_slope_run", &self.caret_slope_run())
.field("caret_offset", &self.caret_offset())
.field("metrics_data_format", &self.metrics_data_format())
.field("number_of_vmetrics", &self.number_of_vmetrics())
.finish()
}
}
impl<'a> TryFrom<&'a [u8]> for &'a VertialHeaderTable {
type Error = ReadError;
fn try_from(value: &'a [u8]) -> Result<Self, Self::Error> {
if value.len() < 36 {
return Err(ReadError::UnexpectedEof);
}
let value: Self = bytemuck::from_bytes(&value[0..36]);
let version = value.version();
if !matches!(version, Version16Dot16(1, 0) | Version16Dot16(1, 0x1000)) {
return Err(ReadError::UnsupportedTableVersion16Dot16(version));
}
let metrics_data_format = value.metrics_data_format();
if metrics_data_format != 0 {
return Err(ReadError::UnsupportedMetricsDataFormat(metrics_data_format));
}
Ok(value)
}
}