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
53#[derive(Clone, Copy, Debug)]
54pub struct Format1Range {
55    pub first: u8,
56    pub left: u8,
57}
58
59impl FromData for Format1Range {
60    const SIZE: usize = 2;
61
62    #[inline]
63    fn parse(data: &[u8]) -> Option<Self> {
64        let mut s = Stream::new(data);
65        Some(Format1Range {
66            first: s.read::<u8>()?,
67            left: s.read::<u8>()?,
68        })
69    }
70}
71
72#[derive(Clone, Copy, Debug)]
73pub(crate) struct Supplement {
74    code: u8,
75    name: StringId,
76}
77
78impl FromData for Supplement {
79    const SIZE: usize = 3;
80
81    #[inline]
82    fn parse(data: &[u8]) -> Option<Self> {
83        let mut s = Stream::new(data);
84        Some(Supplement {
85            code: s.read::<u8>()?,
86            name: s.read::<StringId>()?,
87        })
88    }
89}
90
91#[derive(Clone, Copy, Default, Debug)]
92pub struct Encoding<'a> {
93    pub kind: EncodingKind<'a>,
94    supplemental: LazyArray16<'a, Supplement>,
95}
96
97#[derive(Clone, Copy, Debug)]
98pub enum EncodingKind<'a> {
99    Standard,
100    Expert,
101    Format0(LazyArray16<'a, u8>),
102    Format1(LazyArray16<'a, Format1Range>),
103}
104
105impl Default for EncodingKind<'_> {
106    fn default() -> Self {
107        Self::Standard
108    }
109}
110
111impl Encoding<'_> {
112    pub fn new_standard() -> Self {
113        Encoding {
114            kind: EncodingKind::Standard,
115            supplemental: LazyArray16::default(),
116        }
117    }
118
119    pub fn new_expert() -> Self {
120        Encoding {
121            kind: EncodingKind::Expert,
122            supplemental: LazyArray16::default(),
123        }
124    }
125
126    pub fn code_to_gid(&self, charset: &Charset, code: u8) -> Option<GlyphId> {
127        if !self.supplemental.is_empty() {
128            if let Some(ref s) = self.supplemental.into_iter().find(|s| s.code == code) {
129                return charset.sid_to_gid(s.name);
130            }
131        }
132
133        let index = usize::from(code);
134        match self.kind {
135            // Standard encodings store a StringID/SID and not GlyphID/GID.
136            // Therefore we have to get SID first and then convert it to GID via Charset.
137            // Custom encodings (FormatN) store GID directly.
138            //
139            // Indexing for predefined encodings never fails,
140            // because `code` is always `u8` and encodings have 256 entries.
141            //
142            // We treat `Expert` as `Standard` as well, since we allow only 8bit codepoints.
143            EncodingKind::Standard | EncodingKind::Expert => {
144                let sid = StringId(u16::from(STANDARD_ENCODING[index]));
145                charset.sid_to_gid(sid)
146            }
147            EncodingKind::Format0(ref table) => {
148                // +1 because .notdef is implicit.
149                table
150                    .into_iter()
151                    .position(|c| c == code)
152                    .map(|i| (i + 1) as u16)
153                    .map(GlyphId)
154            }
155            EncodingKind::Format1(ref table) => {
156                // Starts from 1 because .notdef is implicit.
157                let mut gid: u16 = 1;
158                for range in table.into_iter() {
159                    let end = range.first.saturating_add(range.left);
160                    if (range.first..=end).contains(&code) {
161                        gid += u16::from(code - range.first);
162                        return Some(GlyphId(gid));
163                    } else {
164                        gid += u16::from(range.left) + 1;
165                    }
166                }
167
168                None
169            }
170        }
171    }
172
173    pub fn get_code_to_sid_table(&self, charset: &Charset) -> HashMap<u8, StringId> {
174        match self.kind {
175            EncodingKind::Standard => {
176                let mut result = HashMap::new();
177                for i in 0..255 {
178                    result.insert(i as u8, StringId(STANDARD_ENCODING[i] as u16));
179                }
180                result
181            },
182            EncodingKind::Expert => {
183                let mut result = HashMap::new();
184                let charset = charset.get_table();
185
186                for i in 0..255 {
187                    result.insert(i as u8, StringId(EXPERT_ENCODING[i] as u16));
188                }
189                result
190            },
191            EncodingKind::Format0(ref encoding) => {
192                let enc: Vec<_> = encoding.clone().into_iter().collect();
193                let charset = charset.get_table();
194                let mut result = HashMap::new();
195                for i in 0..enc.len() {
196                    let cid = enc[i];
197                    let sid = charset[i];
198                    result.insert(cid, sid);
199                }
200                result
201            }
202            EncodingKind::Format1(ref table) => {
203                let mut encoding = Vec::new();
204                for range in table.clone() {
205                    for code in range.first..=range.first.saturating_add(range.left) {
206                        encoding.push(code);
207                    }
208                }
209                let enc = encoding;
210                let charset = charset.get_table();
211                let mut result = HashMap::new();
212                for i in 0..enc.len() {
213                    let cid = enc[i];
214                    let sid = charset[i];
215                    result.insert(cid, sid);
216                }
217                result
218            }
219        }
220    }
221}
222
223pub(crate) fn parse_encoding<'a>(s: &mut Stream<'a>) -> Option<Encoding<'a>> {
224    let format = s.read::<u8>()?;
225    // The first high-bit in format indicates that a Supplemental encoding is present.
226    // Check it and clear.
227    let has_supplemental = format & 0x80 != 0;
228    let format = format & 0x7f;
229
230    let count = u16::from(s.read::<u8>()?);
231    let kind = match format {
232        // TODO: read_array8?
233        0 => s.read_array16::<u8>(count).map(EncodingKind::Format0)?,
234        1 => s
235            .read_array16::<Format1Range>(count)
236            .map(EncodingKind::Format1)?,
237        _ => return None,
238    };
239
240    let supplemental = if has_supplemental {
241        let count = u16::from(s.read::<u8>()?);
242        s.read_array16::<Supplement>(count)?
243    } else {
244        LazyArray16::default()
245    };
246
247    Some(Encoding { kind, supplemental })
248}