1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
use crate::GlyphId;
use crate::parser::{Stream, FromData, Offset, Offset32, U24};
#[derive(Clone, Copy)]
struct VariationSelectorRecord {
var_selector: u32,
default_uvs_offset: Option<Offset32>,
non_default_uvs_offset: Option<Offset32>,
}
impl FromData for VariationSelectorRecord {
const SIZE: usize = 11;
#[inline]
fn parse(data: &[u8]) -> Option<Self> {
let mut s = Stream::new(data);
Some(VariationSelectorRecord {
var_selector: s.read::<U24>()?.0,
default_uvs_offset: s.read::<Option<Offset32>>()?,
non_default_uvs_offset: s.read::<Option<Offset32>>()?,
})
}
}
#[derive(Clone, Copy)]
struct UVSMappingRecord {
unicode_value: u32,
glyph_id: GlyphId,
}
impl FromData for UVSMappingRecord {
const SIZE: usize = 5;
#[inline]
fn parse(data: &[u8]) -> Option<Self> {
let mut s = Stream::new(data);
Some(UVSMappingRecord {
unicode_value: s.read::<U24>()?.0,
glyph_id: s.read::<GlyphId>()?,
})
}
}
#[derive(Clone, Copy)]
struct UnicodeRangeRecord {
start_unicode_value: u32,
additional_count: u8,
}
impl UnicodeRangeRecord {
fn contains(&self, c: u32) -> bool {
let end = self.start_unicode_value + u32::from(self.additional_count);
(self.start_unicode_value..=end).contains(&c)
}
}
impl FromData for UnicodeRangeRecord {
const SIZE: usize = 4;
#[inline]
fn parse(data: &[u8]) -> Option<Self> {
let mut s = Stream::new(data);
Some(UnicodeRangeRecord {
start_unicode_value: s.read::<U24>()?.0,
additional_count: s.read::<u8>()?,
})
}
}
#[derive(Clone, Copy, PartialEq, Debug)]
pub enum GlyphVariationResult {
Found(GlyphId),
UseDefault,
}
pub fn parse(data: &[u8], c: u32, variation: u32) -> Option<GlyphVariationResult> {
let mut s = Stream::new(data);
s.skip::<u16>();
s.skip::<u32>();
let count: u32 = s.read()?;
let records = s.read_array32::<VariationSelectorRecord>(count)?;
let (_, record) = records.binary_search_by(|v| v.var_selector.cmp(&variation))?;
if let Some(offset) = record.default_uvs_offset {
let data = data.get(offset.to_usize()..)?;
let mut s = Stream::new(data);
let count: u32 = s.read()?;
let ranges = s.read_array32::<UnicodeRangeRecord>(count)?;
for range in ranges {
if range.contains(c) {
return Some(GlyphVariationResult::UseDefault);
}
}
}
if let Some(offset) = record.non_default_uvs_offset {
let data = data.get(offset.to_usize()..)?;
let mut s = Stream::new(data);
let count: u32 = s.read()?;
let uvs_mappings = s.read_array32::<UVSMappingRecord>(count)?;
let (_, mapping) = uvs_mappings.binary_search_by(|v| v.unicode_value.cmp(&c))?;
return Some(GlyphVariationResult::Found(mapping.glyph_id));
}
None
}