read_fonts/tables/
feat.rs1include!("../../generated/generated_feat.rs");
4
5impl Feat<'_> {
6 pub fn find(&self, feature: u16) -> Option<FeatureName> {
8 let names = self.names();
9 let ix = names
10 .binary_search_by(|name| name.feature().cmp(&feature))
11 .ok()?;
12 names.get(ix).copied()
13 }
14}
15
16impl FeatureName {
17 pub fn is_exclusive(&self) -> bool {
19 self.feature_flags() & 0x8000 != 0
21 }
22
23 pub fn default_setting_index(&self) -> u16 {
25 if self.feature_flags() & 0x4000 != 0 {
27 self.feature_flags() & 0xFF
28 } else {
29 0
30 }
31 }
32}
33
34#[cfg(test)]
35mod tests {
36 use font_test_data::bebuffer::BeBuffer;
37
38 use super::*;
39
40 #[test]
41 fn feat_example() {
42 let feat_data = build_feat_example();
43 let feat = Feat::read(feat_data.data().into()).unwrap();
44 let names = feat.names();
45 #[rustfmt::skip]
46 let expected_name_fields = [
47 (0, 1, 0, NameId::new(260), false, 0),
49 (1, 1, 0, NameId::new(256), false, 0),
50 (3, 3, 0x8000, NameId::new(262), true, 0),
51 (6, 2, 0xC001, NameId::new(258), true, 1),
52 ];
53 let name_fields = names
54 .iter()
55 .map(|name| {
56 (
57 name.feature(),
58 name.n_settings(),
59 name.feature_flags(),
60 name.name_index(),
61 name.is_exclusive(),
62 name.default_setting_index(),
63 )
64 })
65 .collect::<Vec<_>>();
66 assert_eq!(name_fields, expected_name_fields);
67 #[rustfmt::skip]
68 let expected_setting_names: [&[(u16, NameId)]; 4] = [
69 &[(0, NameId::new(261))],
70 &[(2, NameId::new(257))],
71 &[(0, NameId::new(268)), (3, NameId::new(264)), (4, NameId::new(265))],
72 &[(0, NameId::new(259)), (1, NameId::new(260))],
73 ];
74 let setting_names = names
75 .iter()
76 .map(|name| {
77 let settings = name.setting_table(feat.offset_data()).unwrap();
78 settings
79 .settings()
80 .iter()
81 .map(|setting| (setting.setting(), setting.name_index()))
82 .collect::<Vec<_>>()
83 })
84 .collect::<Vec<_>>();
85 assert!(expected_setting_names.iter().eq(setting_names.iter()));
86 }
87
88 #[test]
89 fn feat_find() {
90 let feat_data = build_feat_example();
91 let feat = Feat::read(feat_data.data().into()).unwrap();
92 let valid_features = [0, 1, 3, 6];
94 for i in 0..10 {
95 let is_valid = valid_features.contains(&i);
96 let name = feat.find(i);
97 if is_valid {
98 assert_eq!(name.unwrap().feature(), i);
99 } else {
100 assert!(name.is_none());
101 }
102 }
103 }
104
105 fn build_feat_example() -> BeBuffer {
106 let mut buf = BeBuffer::new();
108 buf = buf.push(0x00010000u32).extend([4u16, 0, 0, 0]);
110 buf = buf.extend([0u16, 1]).push(60u32).extend([0u16, 260]);
112 buf = buf.extend([1u16, 1]).push(64u32).extend([0u16, 256]);
113 buf = buf.extend([3u16, 3]).push(68u32).extend([0x8000u16, 262]);
114 buf = buf.extend([6u16, 2]).push(80u32).extend([0xC001u16, 258]);
115 buf.extend([0u16, 261, 2, 257, 0, 268, 3, 264, 4, 265, 0, 259, 1, 260])
117 }
118}