ttf_parser/tables/cff/
encoding.rs

1use super::charset::Charset;
2use super::StringId;
3use crate::parser::{FromData, LazyArray16, Stream};
4use crate::GlyphId;
5
6/// The Standard Encoding as defined in the Adobe Technical Note #5176 Appendix B.
7#[rustfmt::skip]
8pub const STANDARD_ENCODING: [u8; 256] = [
9      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
10      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
11      1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,  15,  16,
12     17,  18,  19,  20,  21,  22,  23,  24,  25,  26,  27,  28,  29,  30,  31,  32,
13     33,  34,  35,  36,  37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47,  48,
14     49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59,  60,  61,  62,  63,  64,
15     65,  66,  67,  68,  69,  70,  71,  72,  73,  74,  75,  76,  77,  78,  79,  80,
16     81,  82,  83,  84,  85,  86,  87,  88,  89,  90,  91,  92,  93,  94,  95,   0,
17      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
18      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
19      0,  96,  97,  98,  99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110,
20      0, 111, 112, 113, 114,   0, 115, 116, 117, 118, 119, 120, 121, 122,   0, 123,
21      0, 124, 125, 126, 127, 128, 129, 130, 131,   0, 132, 133,   0, 134, 135, 136,
22    137,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
23      0, 138,   0, 139,   0,   0,   0,   0, 140, 141, 142, 143,   0,   0,   0,   0,
24      0, 144,   0,   0,   0, 145,   0,   0, 146, 147, 148, 149,   0,   0,   0,   0,
25];
26
27#[derive(Clone, Copy, Debug)]
28pub(crate) struct Format1Range {
29    first: u8,
30    left: u8,
31}
32
33impl FromData for Format1Range {
34    const SIZE: usize = 2;
35
36    #[inline]
37    fn parse(data: &[u8]) -> Option<Self> {
38        let mut s = Stream::new(data);
39        Some(Format1Range {
40            first: s.read::<u8>()?,
41            left: s.read::<u8>()?,
42        })
43    }
44}
45
46#[derive(Clone, Copy, Debug)]
47pub(crate) struct Supplement {
48    code: u8,
49    name: StringId,
50}
51
52impl FromData for Supplement {
53    const SIZE: usize = 3;
54
55    #[inline]
56    fn parse(data: &[u8]) -> Option<Self> {
57        let mut s = Stream::new(data);
58        Some(Supplement {
59            code: s.read::<u8>()?,
60            name: s.read::<StringId>()?,
61        })
62    }
63}
64
65#[derive(Clone, Copy, Default, Debug)]
66pub(crate) struct Encoding<'a> {
67    kind: EncodingKind<'a>,
68    supplemental: LazyArray16<'a, Supplement>,
69}
70
71#[derive(Clone, Copy, Debug)]
72pub(crate) enum EncodingKind<'a> {
73    Standard,
74    Expert,
75    Format0(LazyArray16<'a, u8>),
76    Format1(LazyArray16<'a, Format1Range>),
77}
78
79impl Default for EncodingKind<'_> {
80    fn default() -> Self {
81        Self::Standard
82    }
83}
84
85impl Encoding<'_> {
86    pub fn new_standard() -> Self {
87        Encoding {
88            kind: EncodingKind::Standard,
89            supplemental: LazyArray16::default(),
90        }
91    }
92
93    pub fn new_expert() -> Self {
94        Encoding {
95            kind: EncodingKind::Expert,
96            supplemental: LazyArray16::default(),
97        }
98    }
99
100    pub fn code_to_gid(&self, charset: &Charset, code: u8) -> Option<GlyphId> {
101        if !self.supplemental.is_empty() {
102            if let Some(ref s) = self.supplemental.into_iter().find(|s| s.code == code) {
103                return charset.sid_to_gid(s.name);
104            }
105        }
106
107        let index = usize::from(code);
108        match self.kind {
109            // Standard encodings store a StringID/SID and not GlyphID/GID.
110            // Therefore we have to get SID first and then convert it to GID via Charset.
111            // Custom encodings (FormatN) store GID directly.
112            //
113            // Indexing for predefined encodings never fails,
114            // because `code` is always `u8` and encodings have 256 entries.
115            //
116            // We treat `Expert` as `Standard` as well, since we allow only 8bit codepoints.
117            EncodingKind::Standard | EncodingKind::Expert => {
118                let sid = StringId(u16::from(STANDARD_ENCODING[index]));
119                charset.sid_to_gid(sid)
120            }
121            EncodingKind::Format0(ref table) => {
122                // +1 because .notdef is implicit.
123                table
124                    .into_iter()
125                    .position(|c| c == code)
126                    .map(|i| (i + 1) as u16)
127                    .map(GlyphId)
128            }
129            EncodingKind::Format1(ref table) => {
130                // Starts from 1 because .notdef is implicit.
131                let mut gid: u16 = 1;
132                for range in table.into_iter() {
133                    let end = range.first.saturating_add(range.left);
134                    if (range.first..=end).contains(&code) {
135                        gid += u16::from(code - range.first);
136                        return Some(GlyphId(gid));
137                    } else {
138                        gid += u16::from(range.left) + 1;
139                    }
140                }
141
142                None
143            }
144        }
145    }
146}
147
148pub(crate) fn parse_encoding<'a>(s: &mut Stream<'a>) -> Option<Encoding<'a>> {
149    let format = s.read::<u8>()?;
150    // The first high-bit in format indicates that a Supplemental encoding is present.
151    // Check it and clear.
152    let has_supplemental = format & 0x80 != 0;
153    let format = format & 0x7f;
154
155    let count = u16::from(s.read::<u8>()?);
156    let kind = match format {
157        // TODO: read_array8?
158        0 => s.read_array16::<u8>(count).map(EncodingKind::Format0)?,
159        1 => s
160            .read_array16::<Format1Range>(count)
161            .map(EncodingKind::Format1)?,
162        _ => return None,
163    };
164
165    let supplemental = if has_supplemental {
166        let count = u16::from(s.read::<u8>()?);
167        s.read_array16::<Supplement>(count)?
168    } else {
169        LazyArray16::default()
170    };
171
172    Some(Encoding { kind, supplemental })
173}