1 | // https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-13-many-to-one-range-mappings |
2 | |
3 | use core::convert::TryFrom; |
4 | |
5 | use super::format12::SequentialMapGroup; |
6 | use crate::parser::{LazyArray32, Stream}; |
7 | use crate::GlyphId; |
8 | |
9 | /// A [format 13](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-13-segmented-coverage) |
10 | /// subtable. |
11 | #[derive (Clone, Copy)] |
12 | pub struct Subtable13<'a> { |
13 | groups: LazyArray32<'a, SequentialMapGroup>, |
14 | } |
15 | |
16 | impl<'a> Subtable13<'a> { |
17 | /// Parses a subtable from raw data. |
18 | pub fn parse(data: &'a [u8]) -> Option<Self> { |
19 | let mut s = Stream::new(data); |
20 | s.skip::<u16>(); // format |
21 | s.skip::<u16>(); // reserved |
22 | s.skip::<u32>(); // length |
23 | s.skip::<u32>(); // language |
24 | let count = s.read::<u32>()?; |
25 | let groups = s.read_array32::<super::format12::SequentialMapGroup>(count)?; |
26 | Some(Self { groups }) |
27 | } |
28 | |
29 | /// Returns a glyph index for a code point. |
30 | pub fn glyph_index(&self, code_point: u32) -> Option<GlyphId> { |
31 | for group in self.groups { |
32 | let start_char_code = group.start_char_code; |
33 | if code_point >= start_char_code && code_point <= group.end_char_code { |
34 | return u16::try_from(group.start_glyph_id).ok().map(GlyphId); |
35 | } |
36 | } |
37 | |
38 | None |
39 | } |
40 | |
41 | /// Calls `f` for each codepoint defined in this table. |
42 | pub fn codepoints(&self, mut f: impl FnMut(u32)) { |
43 | for group in self.groups { |
44 | for code_point in group.start_char_code..=group.end_char_code { |
45 | f(code_point); |
46 | } |
47 | } |
48 | } |
49 | } |
50 | |
51 | impl core::fmt::Debug for Subtable13<'_> { |
52 | fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { |
53 | write!(f, "Subtable13 {{ ... }}" ) |
54 | } |
55 | } |
56 | |