use super::parse_prelude::*;
use core::ops::Range;
pub const NAME: Tag = Tag::new(b"name");
#[derive(Copy, Clone)]
pub struct Name<'a>(Buffer<'a>);
impl<'a> Name<'a> {
pub fn new(data: &'a [u8]) -> Self {
Self(Buffer::new(data))
}
pub fn version(&self) -> u16 {
self.0.read(0).unwrap_or(0)
}
pub fn records(&self) -> Slice<'a, NameRecord> {
let len = self.0.read_u16(2).unwrap_or_default() as usize;
self.0.read_slice(6, len).unwrap_or_default()
}
pub fn entries(&self) -> impl Iterator<Item = Entry<'a>> + 'a + Clone {
let copy = *self;
self.records()
.iter()
.map(move |record| Entry { name: copy, record })
}
pub fn storage(&self) -> &'a [u8] {
if let Some(offset) = self.0.read_offset16(4, 0) {
self.0.data().get(offset as usize..).unwrap_or(&[])
} else {
&[]
}
}
}
#[derive(Copy, Clone, Default)]
#[repr(C)]
pub struct NameRecord {
pub platform_id: u16,
pub encoding_id: u16,
pub language_id: u16,
pub name_id: NameId,
pub len: u16,
pub offset: u16,
}
impl NameRecord {
pub fn is_decodable(&self) -> bool {
encoding(self.platform_id, self.encoding_id) < 2
}
pub fn storage_range(&self) -> Range<usize> {
let start = self.offset as usize;
start..start + self.len as usize
}
}
impl ReadData for NameRecord {
unsafe fn read_data_unchecked(buf: &[u8], offset: usize) -> Self {
Self {
platform_id: u16::read_data_unchecked(buf, offset),
encoding_id: u16::read_data_unchecked(buf, offset + 2),
language_id: u16::read_data_unchecked(buf, offset + 4),
name_id: u16::read_data_unchecked(buf, offset + 6),
len: u16::read_data_unchecked(buf, offset + 8),
offset: u16::read_data_unchecked(buf, offset + 10),
}
}
}
#[derive(Copy, Clone)]
pub struct Entry<'a> {
pub name: Name<'a>,
pub record: NameRecord,
}
impl<'a> Entry<'a> {
pub fn data(&self) -> Option<&'a [u8]> {
self.name.storage().get(self.record.storage_range())
}
pub fn decode(&self) -> Decode<'a> {
let data = Buffer::new(self.data().unwrap_or(&[]));
let encoding = encoding(self.record.platform_id, self.record.encoding_id);
let len = data.len();
Decode {
data,
encoding,
len,
pos: 0,
}
}
}
#[derive(Copy, Clone)]
pub struct Decode<'a> {
data: Buffer<'a>,
encoding: u32,
len: usize,
pos: usize,
}
impl<'a> Iterator for Decode<'a> {
type Item = char;
fn next(&mut self) -> Option<Self::Item> {
if self.pos >= self.len {
return None;
}
use core::char::from_u32;
let rep = core::char::REPLACEMENT_CHARACTER;
let d = &self.data;
match self.encoding {
0 => {
let mut c = d.read::<u16>(self.pos)? as u32;
self.pos += 2;
if (0xD800..0xDC00).contains(&c) {
let c2 = d.read::<u16>(self.pos)? as u32;
self.pos += 2;
c = ((c & 0x3FF) << 10) + (c2 & 0x3FF) + 0x10000;
}
Some(from_u32(c).unwrap_or(rep))
}
1 => {
let c = self.data.0[self.pos] as u32;
self.pos += 1;
if c > 127 {
let idx = c as usize - 128;
Some(from_u32(MAC_ROMAN[idx] as u32).unwrap_or(rep))
} else {
Some(from_u32(c).unwrap_or(rep))
}
}
_ => None,
}
}
}
pub type NameId = u16;
pub const COPYRIGHT_NOTICE: NameId = 0;
pub const FAMILY_NAME: NameId = 1;
pub const SUBFAMILY_NAME: NameId = 2;
pub const UNIQUE_ID: NameId = 3;
pub const FULL_NAME: NameId = 4;
pub const VERSION_STRING: NameId = 5;
pub const POSTSCRIPT_NAME: NameId = 6;
pub const TRADEMARK: NameId = 7;
pub const MANUFACTURER: NameId = 8;
pub const DESIGNER: NameId = 9;
pub const DESCRIPTION: NameId = 10;
pub const VENDOR_URL: NameId = 11;
pub const DESIGNER_URL: NameId = 12;
pub const LICENSE_DESCRIPTION: NameId = 13;
pub const LICENSE_URL: NameId = 14;
pub const TYPOGRAPHIC_FAMILY_NAME: NameId = 16;
pub const TYPOGRAPHIC_SUBFAMILY_NAME: NameId = 17;
pub const COMPATIBLE_FULL_NAME: NameId = 18;
pub const SAMPLE_TEXT: NameId = 19;
pub const POSTSCRIPT_CID_NAME: NameId = 20;
pub const WWS_FAMILY_NAME: NameId = 21;
pub const WWS_SUBFAMILY_NAME: NameId = 22;
pub const LIGHT_BACKGROUND_PALETTE: NameId = 23;
pub const DARK_BACKGROUND_PALETTE: NameId = 24;
pub const VARIATIONS_POSTSCRIPT_NAME_PREFIX: NameId = 25;
fn encoding(platform_id: u16, encoding_id: u16) -> u32 {
match (platform_id, encoding_id) {
(0, _) => 0,
(1, 0) => 1,
(3, 0) => 0,
(3, 1) => 0,
(3, 10) => 0,
_ => 2,
}
}
#[rustfmt::skip]
const MAC_ROMAN: [u16; 128] = [
196, 197, 199, 201, 209, 214, 220, 225, 224, 226, 228, 227, 229, 231, 233,
232, 234, 235, 237, 236, 238, 239, 241, 243, 242, 244, 246, 245, 250, 249,
251, 252, 8224, 176, 162, 163, 167, 8226, 182, 223, 174, 169, 8482, 180,
168, 8800, 198, 216, 8734, 177, 8804, 8805, 165, 181, 8706, 8721, 8719,
960, 8747, 170, 186, 937, 230, 248, 191, 161, 172, 8730, 402, 8776, 8710,
171, 187, 8230, 160, 192, 195, 213, 338, 339, 8211, 8212, 8220, 8221, 8216,
8217, 247, 9674, 255, 376, 8260, 8364, 8249, 8250, 64257, 64258, 8225, 183,
8218, 8222, 8240, 194, 202, 193, 203, 200, 205, 206, 207, 204, 211, 212,
63743, 210, 218, 219, 217, 305, 710, 732, 175, 728, 729, 730, 184, 733,
731, 711,
];