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 HorizontalHeaderTable([u8; 36]);
impl<'a> RandomAccess<'a> for &'a HorizontalHeaderTable {
fn bytes(&self) -> &'a [u8] { &self.0 }
}
impl HorizontalHeaderTable {
pub fn version(&self) -> (u16, u16) { (self.uint16(0), self.uint16(2)) }
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_width_max(&self) -> u16 { self.uint16(10) }
pub fn min_left_side_bearing(&self) -> i16 { self.int16(12) }
pub fn min_right_side_bearing(&self) -> i16 { self.int16(14) }
pub fn max_x_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_hmetrics(&self) -> u16 { self.uint16(34) }
}
impl Debug for HorizontalHeaderTable {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
f.debug_struct("HorizontalHeaderTable")
.field("version", &self.version())
.field("ascender", &self.ascender())
.field("descender", &self.descender())
.field("line_gap", &self.line_gap())
.field("advance_width_max", &self.advance_width_max())
.field("min_left_side_bearing", &self.min_left_side_bearing())
.field("min_right_side_bearing", &self.min_right_side_bearing())
.field("max_x_extent", &self.max_x_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_hmetrics", &self.number_of_hmetrics())
.finish()
}
}
impl<'a> TryFrom<&'a [u8]> for &'a HorizontalHeaderTable {
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 version != (1, 0) {
return Err(ReadError::UnsupportedTableVersionPair(version.0, version.1));
}
let metrics_data_format = value.metrics_data_format();
if metrics_data_format != 0 {
return Err(ReadError::UnsupportedMetricsDataFormat(metrics_data_format));
}
Ok(value)
}
}