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}
48