macro_rules! array_ref {
($arr:expr, $len:expr) => {{
assert_eq!($arr.len(), $len);
unsafe { &*($arr.as_ptr() as *const [_; $len]) }
}};
}
use crate::parser::FromData;
use core::convert::TryInto;
#[derive(Clone, Copy)]
pub struct TTCHeader<'a> {
data: &'a [u8; 12],
}
impl<'a> TTCHeader<'a> {
pub const SIZE: usize = 12;
#[inline(always)]
pub fn new(input: &'a [u8]) -> Self {
TTCHeader {
data: array_ref![input, 12],
}
}
#[inline(always)]
pub fn ttc_tag(&self) -> [u8; 4] {
self.data[0..4].try_into().unwrap()
}
#[inline(always)]
pub fn num_fonts(&self) -> u32 {
u32::from_be_bytes([self.data[8], self.data[9], self.data[10], self.data[11]])
}
}
#[derive(Clone, Copy)]
pub struct TableRecord {
data: [u8; 16],
}
impl TableRecord {
pub const SIZE: usize = 16;
#[inline(always)]
pub fn new(input: &[u8]) -> Self {
let mut data = [0u8; Self::SIZE];
data.clone_from_slice(input);
TableRecord { data }
}
#[inline(always)]
pub fn table_tag(&self) -> [u8; 4] {
self.data[0..4].try_into().unwrap()
}
#[inline(always)]
pub fn offset(&self) -> u32 {
u32::from_be_bytes([self.data[8], self.data[9], self.data[10], self.data[11]])
}
#[inline(always)]
pub fn length(&self) -> u32 {
u32::from_be_bytes([self.data[12], self.data[13], self.data[14], self.data[15]])
}
}
impl FromData for TableRecord {
const SIZE: usize = TableRecord::SIZE;
#[inline]
fn parse(data: &[u8]) -> Self {
Self::new(data)
}
}
pub mod head {
#[derive(Clone, Copy)]
pub struct Table<'a> {
data: &'a [u8; 54],
}
impl<'a> Table<'a> {
pub const SIZE: usize = 54;
#[inline(always)]
pub fn new(input: &'a [u8]) -> Self {
Table {
data: array_ref![input, 54],
}
}
#[inline(always)]
pub fn units_per_em(&self) -> u16 {
u16::from_be_bytes([self.data[18], self.data[19]])
}
#[inline(always)]
pub fn index_to_loc_format(&self) -> i16 {
i16::from_be_bytes([self.data[50], self.data[51]])
}
}
}
pub mod maxp {
#[derive(Clone, Copy)]
pub struct Table<'a> {
data: &'a [u8; 6],
}
impl<'a> Table<'a> {
pub const SIZE: usize = 6;
#[inline(always)]
pub fn new(input: &'a [u8]) -> Self {
Table {
data: array_ref![input, 6],
}
}
#[inline(always)]
pub fn num_glyphs(&self) -> u16 {
u16::from_be_bytes([self.data[4], self.data[5]])
}
}
}
pub mod hhea {
#[derive(Clone, Copy)]
pub struct Table<'a> {
data: &'a [u8; 36],
}
impl<'a> Table<'a> {
pub const SIZE: usize = 36;
#[inline(always)]
pub fn new(input: &'a [u8]) -> Self {
Table {
data: array_ref![input, 36],
}
}
#[inline(always)]
pub fn ascender(&self) -> i16 {
i16::from_be_bytes([self.data[4], self.data[5]])
}
#[inline(always)]
pub fn descender(&self) -> i16 {
i16::from_be_bytes([self.data[6], self.data[7]])
}
#[inline(always)]
pub fn line_gap(&self) -> i16 {
i16::from_be_bytes([self.data[8], self.data[9]])
}
#[inline(always)]
pub fn number_of_h_metrics(&self) -> u16 {
u16::from_be_bytes([self.data[34], self.data[35]])
}
}
}
pub mod hmtx {
use crate::parser::FromData;
#[derive(Clone, Copy)]
pub struct HorizontalMetrics {
data: [u8; 4],
}
impl HorizontalMetrics {
pub const SIZE: usize = 4;
#[inline(always)]
pub fn new(input: &[u8]) -> Self {
let mut data = [0u8; Self::SIZE];
data.clone_from_slice(input);
HorizontalMetrics { data }
}
#[inline(always)]
pub fn advance_width(&self) -> u16 {
u16::from_be_bytes([self.data[0], self.data[1]])
}
#[inline(always)]
pub fn lsb(&self) -> i16 {
i16::from_be_bytes([self.data[2], self.data[3]])
}
}
impl FromData for HorizontalMetrics {
const SIZE: usize = HorizontalMetrics::SIZE;
#[inline]
fn parse(data: &[u8]) -> Self {
Self::new(data)
}
}
}
pub mod vhea {
#[derive(Clone, Copy)]
pub struct Table<'a> {
data: &'a [u8; 36],
}
impl<'a> Table<'a> {
pub const SIZE: usize = 36;
#[inline(always)]
pub fn new(input: &'a [u8]) -> Self {
Table {
data: array_ref![input, 36],
}
}
#[inline(always)]
pub fn num_of_long_ver_metrics(&self) -> u16 {
u16::from_be_bytes([self.data[34], self.data[35]])
}
}
}
pub mod vmtx {
use crate::parser::FromData;
#[derive(Clone, Copy)]
pub struct VerticalMetrics {
data: [u8; 4],
}
impl VerticalMetrics {
pub const SIZE: usize = 4;
#[inline(always)]
pub fn new(input: &[u8]) -> Self {
let mut data = [0u8; Self::SIZE];
data.clone_from_slice(input);
VerticalMetrics { data }
}
#[inline(always)]
pub fn advance_height(&self) -> u16 {
u16::from_be_bytes([self.data[0], self.data[1]])
}
#[inline(always)]
pub fn top_side_bearing(&self) -> i16 {
i16::from_be_bytes([self.data[2], self.data[3]])
}
}
impl FromData for VerticalMetrics {
const SIZE: usize = VerticalMetrics::SIZE;
#[inline]
fn parse(data: &[u8]) -> Self {
Self::new(data)
}
}
}
pub mod post {
#[derive(Clone, Copy)]
pub struct Table<'a> {
data: &'a [u8; 32],
}
impl<'a> Table<'a> {
pub const SIZE: usize = 32;
#[inline(always)]
pub fn new(input: &'a [u8]) -> Self {
Table {
data: array_ref![input, 32],
}
}
#[inline(always)]
pub fn underline_position(&self) -> i16 {
i16::from_be_bytes([self.data[8], self.data[9]])
}
#[inline(always)]
pub fn underline_thickness(&self) -> i16 {
i16::from_be_bytes([self.data[10], self.data[11]])
}
}
}
pub mod cmap {
use crate::parser::FromData;
use crate::GlyphId;
#[derive(Clone, Copy)]
pub struct EncodingRecord {
data: [u8; 8],
}
impl EncodingRecord {
pub const SIZE: usize = 8;
#[inline(always)]
pub fn new(input: &[u8]) -> Self {
let mut data = [0u8; Self::SIZE];
data.clone_from_slice(input);
EncodingRecord { data }
}
#[inline(always)]
pub fn platform_id(&self) -> u16 {
u16::from_be_bytes([self.data[0], self.data[1]])
}
#[inline(always)]
pub fn encoding_id(&self) -> u16 {
u16::from_be_bytes([self.data[2], self.data[3]])
}
#[inline(always)]
pub fn offset(&self) -> u32 {
u32::from_be_bytes([self.data[4], self.data[5], self.data[6], self.data[7]])
}
}
impl FromData for EncodingRecord {
const SIZE: usize = EncodingRecord::SIZE;
#[inline]
fn parse(data: &[u8]) -> Self {
Self::new(data)
}
}
#[derive(Clone, Copy)]
pub struct SubHeaderRecord {
data: [u8; 8],
}
impl SubHeaderRecord {
pub const SIZE: usize = 8;
#[inline(always)]
pub fn new(input: &[u8]) -> Self {
let mut data = [0u8; Self::SIZE];
data.clone_from_slice(input);
SubHeaderRecord { data }
}
#[inline(always)]
pub fn first_code(&self) -> u16 {
u16::from_be_bytes([self.data[0], self.data[1]])
}
#[inline(always)]
pub fn entry_count(&self) -> u16 {
u16::from_be_bytes([self.data[2], self.data[3]])
}
#[inline(always)]
pub fn id_delta(&self) -> i16 {
i16::from_be_bytes([self.data[4], self.data[5]])
}
#[inline(always)]
pub fn id_range_offset(&self) -> u16 {
u16::from_be_bytes([self.data[6], self.data[7]])
}
}
impl FromData for SubHeaderRecord {
const SIZE: usize = SubHeaderRecord::SIZE;
#[inline]
fn parse(data: &[u8]) -> Self {
Self::new(data)
}
}
#[derive(Clone, Copy)]
pub struct SequentialMapGroup {
data: [u8; 12],
}
impl SequentialMapGroup {
pub const SIZE: usize = 12;
#[inline(always)]
pub fn new(input: &[u8]) -> Self {
let mut data = [0u8; Self::SIZE];
data.clone_from_slice(input);
SequentialMapGroup { data }
}
#[inline(always)]
pub fn start_char_code(&self) -> u32 {
u32::from_be_bytes([self.data[0], self.data[1], self.data[2], self.data[3]])
}
#[inline(always)]
pub fn end_char_code(&self) -> u32 {
u32::from_be_bytes([self.data[4], self.data[5], self.data[6], self.data[7]])
}
#[inline(always)]
pub fn start_glyph_id(&self) -> u32 {
u32::from_be_bytes([self.data[8], self.data[9], self.data[10], self.data[11]])
}
}
impl FromData for SequentialMapGroup {
const SIZE: usize = SequentialMapGroup::SIZE;
#[inline]
fn parse(data: &[u8]) -> Self {
Self::new(data)
}
}
#[derive(Clone, Copy)]
pub struct UnicodeRangeRecord {
data: [u8; 4],
}
impl UnicodeRangeRecord {
pub const SIZE: usize = 4;
#[inline(always)]
pub fn new(input: &[u8]) -> Self {
let mut data = [0u8; Self::SIZE];
data.clone_from_slice(input);
UnicodeRangeRecord { data }
}
#[inline(always)]
pub fn start_unicode_value(&self) -> u32 {
(self.data[0] as u32) << 16 | (self.data[1] as u32) << 8 | self.data[2] as u32
}
#[inline(always)]
pub fn additional_count(&self) -> u8 {
self.data[3]
}
}
impl FromData for UnicodeRangeRecord {
const SIZE: usize = UnicodeRangeRecord::SIZE;
#[inline]
fn parse(data: &[u8]) -> Self {
Self::new(data)
}
}
#[derive(Clone, Copy)]
pub struct UVSMappingRecord {
data: [u8; 5],
}
impl UVSMappingRecord {
pub const SIZE: usize = 5;
#[inline(always)]
pub fn new(input: &[u8]) -> Self {
let mut data = [0u8; Self::SIZE];
data.clone_from_slice(input);
UVSMappingRecord { data }
}
#[inline(always)]
pub fn unicode_value(&self) -> u32 {
(self.data[0] as u32) << 16 | (self.data[1] as u32) << 8 | self.data[2] as u32
}
#[inline(always)]
pub fn glyph_id(&self) -> GlyphId {
GlyphId(u16::from_be_bytes([self.data[3], self.data[4]]))
}
}
impl FromData for UVSMappingRecord {
const SIZE: usize = UVSMappingRecord::SIZE;
#[inline]
fn parse(data: &[u8]) -> Self {
Self::new(data)
}
}
#[derive(Clone, Copy)]
pub struct VariationSelectorRecord {
data: [u8; 11],
}
impl VariationSelectorRecord {
pub const SIZE: usize = 11;
#[inline(always)]
pub fn new(input: &[u8]) -> Self {
let mut data = [0u8; Self::SIZE];
data.clone_from_slice(input);
VariationSelectorRecord { data }
}
#[inline(always)]
pub fn var_selector(&self) -> u32 {
(self.data[0] as u32) << 16 | (self.data[1] as u32) << 8 | self.data[2] as u32
}
#[inline(always)]
pub fn default_uvs_offset(&self) -> Option<u32> {
let n = u32::from_be_bytes([self.data[3], self.data[4], self.data[5], self.data[6]]);
if n != 0 {
Some(n)
} else {
None
}
}
#[inline(always)]
pub fn non_default_uvs_offset(&self) -> Option<u32> {
let n = u32::from_be_bytes([self.data[7], self.data[8], self.data[9], self.data[10]]);
if n != 0 {
Some(n)
} else {
None
}
}
}
impl FromData for VariationSelectorRecord {
const SIZE: usize = VariationSelectorRecord::SIZE;
#[inline]
fn parse(data: &[u8]) -> Self {
Self::new(data)
}
}
}
pub mod os_2 {
#[derive(Clone, Copy)]
pub struct TableV0<'a> {
data: &'a [u8; 78],
}
impl<'a> TableV0<'a> {
pub const SIZE: usize = 78;
#[inline(always)]
pub fn new(input: &'a [u8]) -> Self {
TableV0 {
data: array_ref![input, 78],
}
}
#[inline(always)]
pub fn version(&self) -> u16 {
u16::from_be_bytes([self.data[0], self.data[1]])
}
#[inline(always)]
pub fn us_weight_class(&self) -> u16 {
u16::from_be_bytes([self.data[4], self.data[5]])
}
#[inline(always)]
pub fn us_width_class(&self) -> u16 {
u16::from_be_bytes([self.data[6], self.data[7]])
}
#[inline(always)]
pub fn y_subscript_x_size(&self) -> i16 {
i16::from_be_bytes([self.data[10], self.data[11]])
}
#[inline(always)]
pub fn y_subscript_y_size(&self) -> i16 {
i16::from_be_bytes([self.data[12], self.data[13]])
}
#[inline(always)]
pub fn y_subscript_x_offset(&self) -> i16 {
i16::from_be_bytes([self.data[14], self.data[15]])
}
#[inline(always)]
pub fn y_subscript_y_offset(&self) -> i16 {
i16::from_be_bytes([self.data[16], self.data[17]])
}
#[inline(always)]
pub fn y_superscript_x_size(&self) -> i16 {
i16::from_be_bytes([self.data[18], self.data[19]])
}
#[inline(always)]
pub fn y_superscript_y_size(&self) -> i16 {
i16::from_be_bytes([self.data[20], self.data[21]])
}
#[inline(always)]
pub fn y_superscript_x_offset(&self) -> i16 {
i16::from_be_bytes([self.data[22], self.data[23]])
}
#[inline(always)]
pub fn y_superscript_y_offset(&self) -> i16 {
i16::from_be_bytes([self.data[24], self.data[25]])
}
#[inline(always)]
pub fn y_strikeout_size(&self) -> i16 {
i16::from_be_bytes([self.data[26], self.data[27]])
}
#[inline(always)]
pub fn y_strikeout_position(&self) -> i16 {
i16::from_be_bytes([self.data[28], self.data[29]])
}
#[inline(always)]
pub fn fs_selection(&self) -> u16 {
u16::from_be_bytes([self.data[62], self.data[63]])
}
}
}
pub mod name {
#[derive(Clone, Copy)]
pub struct NameRecord {
data: [u8; 12],
}
impl NameRecord {
pub const SIZE: usize = 12;
#[inline(always)]
pub fn new(input: &[u8]) -> Self {
let mut data = [0u8; Self::SIZE];
data.clone_from_slice(input);
NameRecord { data }
}
#[inline(always)]
pub fn platform_id(&self) -> u16 {
u16::from_be_bytes([self.data[0], self.data[1]])
}
#[inline(always)]
pub fn encoding_id(&self) -> u16 {
u16::from_be_bytes([self.data[2], self.data[3]])
}
#[inline(always)]
pub fn language_id(&self) -> u16 {
u16::from_be_bytes([self.data[4], self.data[5]])
}
#[inline(always)]
pub fn name_id(&self) -> u16 {
u16::from_be_bytes([self.data[6], self.data[7]])
}
#[inline(always)]
pub fn length(&self) -> u16 {
u16::from_be_bytes([self.data[8], self.data[9]])
}
#[inline(always)]
pub fn offset(&self) -> u16 {
u16::from_be_bytes([self.data[10], self.data[11]])
}
}
}