fonts/
font_feature_values.rs1use std::collections::HashMap;
6
7use malloc_size_of_derive::MallocSizeOf;
8use style::Atom;
9use style::stylesheets::FontFeatureValuesRule;
10use style::stylesheets::font_feature_values_rule::{PairValues, SingleValue, VectorValues};
11
12#[derive(Clone, Debug, Eq, Hash, MallocSizeOf, PartialEq)]
14struct HashKey {
15 family_name: Atom,
17 kind: AlternateKindRequiringResolution,
18 name: Atom,
20}
21
22#[derive(Clone, Debug, MallocSizeOf)]
24pub(crate) enum FontFeatureValue {
25 Single(SingleValue),
26 Pair(PairValues),
27 Vector(VectorValues),
28}
29
30#[derive(Debug, Default, MallocSizeOf)]
34pub(crate) struct FontFeatureValueMap {
35 map: HashMap<HashKey, FontFeatureValue>,
36}
37
38#[derive(Clone, Debug, Eq, Hash, MallocSizeOf, PartialEq)]
43pub enum AlternateKindRequiringResolution {
44 Stylistic,
46 Styleset,
48 CharacterVariant,
50 Swash,
52 Annotation,
54 Ornaments,
56}
57
58impl FontFeatureValueMap {
59 pub(crate) fn lookup(
61 &self,
62 family_name: Atom,
63 kind: AlternateKindRequiringResolution,
64 name: Atom,
65 ) -> Option<FontFeatureValue> {
66 let key = HashKey {
67 family_name,
68 kind,
69 name,
70 };
71
72 let value = self.map.get(&key).cloned();
73 log::debug!(
74 "@font-feature-values lookup for {:?} {:?} {:?} -> {value:?}",
75 key.family_name,
76 key.kind,
77 key.name
78 );
79 value
80 }
81
82 pub(crate) fn add_rule(&mut self, rule: &FontFeatureValuesRule) {
87 self.map.reserve(rule.family_names.len() * rule.len());
88 for family_name in &rule.family_names {
89 for swash in &rule.swash {
90 let key = HashKey {
91 family_name: family_name.name.clone(),
92 kind: AlternateKindRequiringResolution::Swash,
93 name: swash.name.clone(),
94 };
95 self.map
96 .insert(key, FontFeatureValue::Single(swash.value.clone()));
97 }
98
99 for annotation in &rule.annotation {
100 let key = HashKey {
101 family_name: family_name.name.clone(),
102 kind: AlternateKindRequiringResolution::Annotation,
103 name: annotation.name.clone(),
104 };
105 self.map
106 .insert(key, FontFeatureValue::Single(annotation.value.clone()));
107 }
108
109 for ornament in &rule.ornaments {
110 let key = HashKey {
111 family_name: family_name.name.clone(),
112 kind: AlternateKindRequiringResolution::Ornaments,
113 name: ornament.name.clone(),
114 };
115 self.map
116 .insert(key, FontFeatureValue::Single(ornament.value.clone()));
117 }
118
119 for stylistic in &rule.stylistic {
120 let key = HashKey {
121 family_name: family_name.name.clone(),
122 kind: AlternateKindRequiringResolution::Stylistic,
123 name: stylistic.name.clone(),
124 };
125 self.map
126 .insert(key, FontFeatureValue::Single(stylistic.value.clone()));
127 }
128
129 for styleset in &rule.styleset {
130 let key = HashKey {
131 family_name: family_name.name.clone(),
132 kind: AlternateKindRequiringResolution::Styleset,
133 name: styleset.name.clone(),
134 };
135 self.map
136 .insert(key, FontFeatureValue::Vector(styleset.value.clone()));
137 }
138
139 for character_variant in &rule.character_variant {
140 let key = HashKey {
141 family_name: family_name.name.clone(),
142 kind: AlternateKindRequiringResolution::CharacterVariant,
143 name: character_variant.name.clone(),
144 };
145 self.map
146 .insert(key, FontFeatureValue::Pair(character_variant.value.clone()));
147 }
148 }
149 }
150}
151
152#[derive(Clone, Debug, Default, Eq, Hash, MallocSizeOf, PartialEq)]
157pub struct ResolvedFontVariantAlternates {
158 pub historical_forms: bool,
160 pub stylistic: Option<SingleValue>,
162 pub styleset: Vec<u32>,
164 pub character_variant: Vec<PairValues>,
166 pub swash: Option<SingleValue>,
168 pub ornaments: Option<SingleValue>,
170 pub annotation: Option<SingleValue>,
172}