1#![allow(clippy::cast_possible_wrap)]
2#![allow(clippy::cast_possible_truncation)]
3use crate::error::ParseResult;
4use crate::reader::{BinaryReader, Parse};
5
6#[derive(Debug, Default)]
9pub struct PostTable {
10 pub is_monospaced: bool,
12
13 pub glyph_names: Vec<String>,
15}
16
17impl PostTable {
18 #[must_use]
20 pub fn get_glyph_name(&self, index: u16) -> Option<&str> {
21 self.glyph_names.get(index as usize).map(String::as_str)
22 }
23}
24
25impl Parse for PostTable {
26 fn parse(reader: &mut BinaryReader) -> ParseResult<Self> {
27 let mut table = Self::default();
28
29 let fmt = reader.read_fixed32()?;
32 reader.skip_u32()?; reader.skip_u16()?; reader.skip_u16()?; table.is_monospaced = reader.read_u32()? != 0; reader.skip_u32()?; reader.skip_u32()?; reader.skip_u32()?; reader.skip_u32()?; debug_msg!(" Format = {}.{}", fmt.0, fmt.1);
42
43 match fmt {
44 (1, 0) => {
45 table.glyph_names = POST_MAC_NAMES.iter().map(ToString::to_string).collect();
48 }
49
50 (2, 0) => {
51 let num_glyphs = reader.read_u16()?;
54 debug_msg!(" Num glyphs = {}", num_glyphs);
55
56 let mut names = Vec::with_capacity(num_glyphs as usize);
59 let mut name_reader = reader.clone();
60 name_reader.advance_by(num_glyphs as isize * 2)?;
61 while !name_reader.is_eof() {
62 let len = name_reader.read_u8()?;
63 let name = name_reader.read_string(len as usize)?;
64 names.push(name);
65 }
66
67 for _ in 0..num_glyphs {
68 let ordinal = reader.read_u16()?;
69 if ordinal < POST_MAC_NAMES_LEN as u16 {
70 table
71 .glyph_names
72 .push(POST_MAC_NAMES[ordinal as usize].to_string());
73 } else {
74 let index = (ordinal - POST_MAC_NAMES_LEN as u16) as usize;
75 table.glyph_names.push(names[index].clone());
76 }
77 }
78 }
79
80 (2, 5) => {
81 let num_glyphs = reader.read_u16()?;
84
85 let mut glyph_names = Vec::new();
86 for i in 0..num_glyphs {
87 let offset = reader.read_i8()?;
88 let index = i.wrapping_add_signed(i16::from(offset));
89 glyph_names.push(POST_MAC_NAMES[index as usize].to_string());
90 }
91 }
92
93 _ => {
94 }
96 }
97
98 debug_msg!(" Found {} glyph names", table.glyph_names.len());
99 Ok(table)
100 }
101}
102
103const POST_MAC_NAMES_LEN: usize = 258;
106#[rustfmt::skip]
107const POST_MAC_NAMES: [&str; POST_MAC_NAMES_LEN] = [
108 ".notdef", ".null", "nonmarkingreturn", "space", "exclam", "quotedbl", "numbersign", "dollar", "percent",
109 "ampersand", "quotesingle","parenleft","parenright","asterisk","plus","comma", "hyphen", "period", "slash",
110 "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "colon", "semicolon", "less",
111 "equal", "greater", "question", "at", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N",
112 "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "bracketleft", "backslash", "bracketright", "asciicircum",
113 "underscore", "grave", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r",
114 "s", "t", "u", "v", "w", "x", "y", "z", "braceleft", "bar", "braceright", "asciitilde", "Adieresis", "Aring",
115 "Ccedilla", "Eacute", "Ntilde", "Odieresis", "Udieresis", "aacute", "agrave", "acircumflex", "adieresis",
116 "atilde", "aring", "ccedilla", "eacute", "egrave", "ecircumflex", "edieresis", "iacute", "igrave",
117 "icircumflex", "idieresis", "ntilde", "oacute", "ograve", "ocircumflex", "odieresis", "otilde", "uacute", "ugrave",
118 "ucircumflex", "udieresis", "dagger", "degree", "cent", "sterling", "section", "bullet", "paragraph", "germandbls",
119 "registered", "copyright", "trademark", "acute", "dieresis", "notequal", "AE", "Oslash", "infinity", "plusminus",
120 "lessequal", "greaterequal", "yen", "mu", "partialdiff", "summation", "product", "pi", "integral", "ordfeminine",
121 "ordmasculine", "Omega", "ae", "oslash", "questiondown", "exclamdown", "logicalnot", "radical", "florin", "approxequal",
122 "Delta", "guillemotleft", "guillemotright", "ellipsis", "nonbreakingspace", "Agrave", "Atilde", "Otilde", "OE", "oe",
123 "endash", "emdash", "quotedblleft", "quotedblright", "quoteleft", "quoteright", "divide", "lozenge", "ydieresis",
124 "Ydieresis", "fraction", "currency", "guilsinglleft", "guilsinglright", "fi", "fl", "daggerdbl", "periodcentered",
125 "quotesinglbase", "quotedblbase", "perthousand", "Acircumflex", "Ecircumflex", "Aacute", "Edieresis", "Egrave",
126 "Iacute", "Icircumflex", "Idieresis", "Igrave", "Oacute", "Ocircumflex", "apple", "Ograve", "Uacute", "Ucircumflex",
127 "Ugrave", "dotlessi", "circumflex", "tilde", "macron", "breve", "dotaccent", "ring", "cedilla", "hungarumlaut",
128 "ogonek", "caron", "Lslash", "lslash", "Scaron", "scaron", "Zcaron", "zcaron", "brokenbar", "Eth", "eth", "Yacute",
129 "yacute", "Thorn", "thorn", "minus", "multiply", "onesuperior", "twosuperior", "threesuperior", "onehalf", "onequarter",
130 "threequarters", "franc", "Gbreve", "gbreve", "Idotaccent", "Scedilla", "scedilla", "Cacute", "cacute", "Ccaron",
131 "ccaron", "dcroat"
132];