Skip to main content

cff_parser/
encoding.rs

1use std::collections::HashMap;
2use std::result;
3use std::str::Chars;
4
5use super::charset::Charset;
6use super::StringId;
7use crate::parser::{FromData, LazyArray16, Stream};
8use crate::GlyphId;
9
10/// The Standard Encoding as defined in the Adobe Technical Note #5176 Appendix B.
11#[rustfmt::skip]
12pub const STANDARD_ENCODING: [u8; 256] = [
13      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
14      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
15      1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,  15,  16,
16     17,  18,  19,  20,  21,  22,  23,  24,  25,  26,  27,  28,  29,  30,  31,  32,
17     33,  34,  35,  36,  37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47,  48,
18     49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59,  60,  61,  62,  63,  64,
19     65,  66,  67,  68,  69,  70,  71,  72,  73,  74,  75,  76,  77,  78,  79,  80,
20     81,  82,  83,  84,  85,  86,  87,  88,  89,  90,  91,  92,  93,  94,  95,   0,
21      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
22      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
23      0,  96,  97,  98,  99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110,
24      0, 111, 112, 113, 114,   0, 115, 116, 117, 118, 119, 120, 121, 122,   0, 123,
25      0, 124, 125, 126, 127, 128, 129, 130, 131,   0, 132, 133,   0, 134, 135, 136,
26    137,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
27      0, 138,   0, 139,   0,   0,   0,   0, 140, 141, 142, 143,   0,   0,   0,   0,
28      0, 144,   0,   0,   0, 145,   0,   0, 146, 147, 148, 149,   0,   0,   0,   0,
29];
30
31/// The Expert Encoding as defined in the Adobe Technical Note #5176 Appendix B.
32#[rustfmt::skip]
33pub const EXPERT_ENCODING: [u16; 256] = [
34      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
35      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
36      1, 229, 230,   0, 231, 232, 233, 234, 235, 236, 237, 238,  13,  14,  15,  99,
37    239, 240, 241, 242, 243, 244, 245, 246, 247, 248,  27,  28, 249, 250, 251, 252,
38      0, 253, 254, 255, 256, 257,   0,   0,   0, 258,   0,   0, 259, 260, 261, 262,
39      0,   0, 263, 264, 265,   0, 266, 109, 110, 267, 268, 269,   0, 270, 271, 272,
40    273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288,
41    289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303,   0,
42      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
43      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
44      0, 304, 305, 306,   0,   0, 307, 308, 309, 310, 311,   0, 312,   0,   0, 313,
45      0,   0, 314, 315,   0,   0, 316, 317, 318,   0,   0,   0, 158, 155, 163, 319,
46    320, 321, 322, 323, 324, 325,   0,   0, 326, 150, 164, 169, 327, 328, 329, 330,
47    331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346,
48    347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362,
49    363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378,
50];
51
52#[derive(Clone, Copy, Debug)]
53pub struct Format1Range {
54    pub first: u8,
55    pub left: u8,
56}
57
58impl FromData for Format1Range {
59    const SIZE: usize = 2;
60
61    #[inline]
62    fn parse(data: &[u8]) -> Option<Self> {
63        let mut s = Stream::new(data);
64        Some(Format1Range {
65            first: s.read::<u8>()?,
66            left: s.read::<u8>()?,
67        })
68    }
69}
70
71#[derive(Clone, Copy, Debug)]
72pub(crate) struct Supplement {
73    code: u8,
74    name: StringId,
75}
76
77impl FromData for Supplement {
78    const SIZE: usize = 3;
79
80    #[inline]
81    fn parse(data: &[u8]) -> Option<Self> {
82        let mut s = Stream::new(data);
83        Some(Supplement {
84            code: s.read::<u8>()?,
85            name: s.read::<StringId>()?,
86        })
87    }
88}
89
90#[derive(Clone, Copy, Default, Debug)]
91pub struct Encoding<'a> {
92    pub kind: EncodingKind<'a>,
93    supplemental: LazyArray16<'a, Supplement>,
94}
95
96#[derive(Clone, Copy, Debug)]
97pub enum EncodingKind<'a> {
98    Standard,
99    Expert,
100    Format0(LazyArray16<'a, u8>),
101    Format1(LazyArray16<'a, Format1Range>),
102}
103
104impl Default for EncodingKind<'_> {
105    fn default() -> Self {
106        Self::Standard
107    }
108}
109
110impl Encoding<'_> {
111    pub fn new_standard() -> Self {
112        Encoding {
113            kind: EncodingKind::Standard,
114            supplemental: LazyArray16::default(),
115        }
116    }
117
118    pub fn new_expert() -> Self {
119        Encoding {
120            kind: EncodingKind::Expert,
121            supplemental: LazyArray16::default(),
122        }
123    }
124
125    pub fn code_to_gid(&self, charset: &Charset, code: u8) -> Option<GlyphId> {
126        if !self.supplemental.is_empty() {
127            if let Some(ref s) = self.supplemental.into_iter().find(|s| s.code == code) {
128                return charset.sid_to_gid(s.name);
129            }
130        }
131
132        let index = usize::from(code);
133        match self.kind {
134            // Standard encodings store a StringID/SID and not GlyphID/GID.
135            // Therefore we have to get SID first and then convert it to GID via Charset.
136            // Custom encodings (FormatN) store GID directly.
137            //
138            // Indexing for predefined encodings never fails,
139            // because `code` is always `u8` and encodings have 256 entries.
140            //
141            // We treat `Expert` as `Standard` as well, since we allow only 8bit codepoints.
142            EncodingKind::Standard | EncodingKind::Expert => {
143                let sid = StringId(u16::from(STANDARD_ENCODING[index]));
144                charset.sid_to_gid(sid)
145            }
146            EncodingKind::Format0(ref table) => {
147                // +1 because .notdef is implicit.
148                table
149                    .into_iter()
150                    .position(|c| c == code)
151                    .map(|i| (i + 1) as u16)
152                    .map(GlyphId)
153            }
154            EncodingKind::Format1(ref table) => {
155                // Starts from 1 because .notdef is implicit.
156                let mut gid: u16 = 1;
157                for range in table.into_iter() {
158                    let end = range.first.saturating_add(range.left);
159                    if (range.first..=end).contains(&code) {
160                        gid += u16::from(code - range.first);
161                        return Some(GlyphId(gid));
162                    } else {
163                        gid += u16::from(range.left) + 1;
164                    }
165                }
166
167                None
168            }
169        }
170    }
171
172    pub fn get_code_to_sid_table(&self, charset: &Charset) -> HashMap<u8, StringId> {
173        match self.kind {
174            EncodingKind::Standard => {
175                let mut result = HashMap::new();
176                for i in 0..255 {
177                    result.insert(i as u8, StringId(STANDARD_ENCODING[i] as u16));
178                }
179                result
180            }
181            EncodingKind::Expert => {
182                let mut result = HashMap::new();
183                let charset = charset.get_table();
184
185                for i in 0..255 {
186                    result.insert(i as u8, StringId(EXPERT_ENCODING[i] as u16));
187                }
188                result
189            }
190            EncodingKind::Format0(ref encoding) => {
191                let enc: Vec<_> = encoding.clone().into_iter().collect();
192                let charset = charset.get_table();
193                let mut result = HashMap::new();
194                for i in 0..enc.len() {
195                    let cid = enc[i];
196                    let sid = charset[i];
197                    result.insert(cid, sid);
198                }
199                result
200            }
201            EncodingKind::Format1(ref table) => {
202                let mut encoding = Vec::new();
203                for range in table.clone() {
204                    for code in range.first..=range.first.saturating_add(range.left) {
205                        encoding.push(code);
206                    }
207                }
208                let enc = encoding;
209                let charset = charset.get_table();
210                let mut result = HashMap::new();
211                for i in 0..enc.len() {
212                    let cid = enc[i];
213                    let sid = charset[i];
214                    result.insert(cid, sid);
215                }
216                result
217            }
218        }
219    }
220}
221
222pub(crate) fn parse_encoding<'a>(s: &mut Stream<'a>) -> Option<Encoding<'a>> {
223    let format = s.read::<u8>()?;
224    // The first high-bit in format indicates that a Supplemental encoding is present.
225    // Check it and clear.
226    let has_supplemental = format & 0x80 != 0;
227    let format = format & 0x7f;
228
229    let count = u16::from(s.read::<u8>()?);
230    let kind = match format {
231        // TODO: read_array8?
232        0 => s.read_array16::<u8>(count).map(EncodingKind::Format0)?,
233        1 => s
234            .read_array16::<Format1Range>(count)
235            .map(EncodingKind::Format1)?,
236        _ => return None,
237    };
238
239    let supplemental = if has_supplemental {
240        let count = u16::from(s.read::<u8>()?);
241        s.read_array16::<Supplement>(count)?
242    } else {
243        LazyArray16::default()
244    };
245
246    Some(Encoding { kind, supplemental })
247}