ttf_parser/
delta_set.rs

1use core::convert::TryFrom;
2
3use crate::parser::Stream;
4
5#[derive(Clone, Copy, Debug)]
6pub(crate) struct DeltaSetIndexMap<'a> {
7    data: &'a [u8],
8}
9
10impl<'a> DeltaSetIndexMap<'a> {
11    #[inline]
12    pub(crate) fn new(data: &'a [u8]) -> Self {
13        DeltaSetIndexMap { data }
14    }
15
16    #[inline]
17    pub(crate) fn map(&self, mut index: u32) -> Option<(u16, u16)> {
18        let mut s = Stream::new(self.data);
19        let format = s.read::<u8>()?;
20        let entry_format = s.read::<u8>()?;
21        let map_count = if format == 0 {
22            s.read::<u16>()? as u32
23        } else {
24            s.read::<u32>()?
25        };
26
27        if map_count == 0 {
28            return None;
29        }
30
31        // 'If a given glyph ID is greater than mapCount-1, then the last entry is used.'
32        if index >= map_count {
33            index = map_count - 1;
34        }
35
36        let entry_size = ((entry_format >> 4) & 3) + 1;
37        let inner_index_bit_count = u32::from((entry_format & 0xF) + 1);
38
39        s.advance(usize::from(entry_size) * usize::try_from(index).ok()?);
40
41        let mut n = 0u32;
42        for b in s.read_bytes(usize::from(entry_size))? {
43            n = (n << 8) + u32::from(*b);
44        }
45
46        let outer_index = n >> inner_index_bit_count;
47        let inner_index = n & ((1 << inner_index_bit_count) - 1);
48        Some((
49            u16::try_from(outer_index).ok()?,
50            u16::try_from(inner_index).ok()?,
51        ))
52    }
53}