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