ttf_parser/tables/cmap/
format0.rs

1use crate::parser::{NumFrom, Stream};
2use crate::GlyphId;
3
4/// A [format 0](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-0-byte-encoding-table)
5/// subtable.
6#[derive(Clone, Copy, Debug)]
7pub struct Subtable0<'a> {
8    /// Just a list of 256 8bit glyph IDs.
9    pub glyph_ids: &'a [u8],
10}
11
12impl<'a> Subtable0<'a> {
13    /// Parses a subtable from raw data.
14    pub fn parse(data: &'a [u8]) -> Option<Self> {
15        let mut s = Stream::new(data);
16        s.skip::<u16>(); // format
17        s.skip::<u16>(); // length
18        s.skip::<u16>(); // language
19        let glyph_ids = s.read_bytes(256)?;
20        Some(Self { glyph_ids })
21    }
22
23    /// Returns a glyph index for a code point.
24    pub fn glyph_index(&self, code_point: u32) -> Option<GlyphId> {
25        let glyph_id = *self.glyph_ids.get(usize::num_from(code_point))?;
26        // Make sure that the glyph is not zero, the array always has 256 ids,
27        // but some codepoints may be mapped to zero.
28        if glyph_id != 0 {
29            Some(GlyphId(u16::from(glyph_id)))
30        } else {
31            None
32        }
33    }
34
35    /// Calls `f` for each codepoint defined in this table.
36    pub fn codepoints(&self, mut f: impl FnMut(u32)) {
37        for (i, glyph_id) in self.glyph_ids.iter().enumerate() {
38            // In contrast to every other format, here we take a look at the glyph
39            // id and check whether it is zero because otherwise this method would
40            // always simply call `f` for `0..256` which would be kind of pointless
41            // (this array always has length 256 even when the face has fewer glyphs).
42            if *glyph_id != 0 {
43                f(i as u32);
44            }
45        }
46    }
47}