1use truetype::Tag;
4
5table! {
6 @position
7 pub Features { count (u16), headers (Vec<Header>) |this, tape, _| { tape.take_given(this.count as usize)
13 },
14
15 records (Vec<Record>) |this, tape, position| {
16 jump_take!(tape, position, this.count, i => this.headers[i].offset)
17 },
18 }
19}
20
21table! {
22 #[derive(Copy)]
24 pub Header { tag (Tag), offset (u16), }
28}
29
30table! {
31 @position
32 pub Record { parameter_offset (u16), lookup_index_count (u16), lookup_indices (Vec<u16>) |this, tape, _| { tape.take_given(this.lookup_index_count as usize)
39 },
40
41 parameters (Option<Vec<u8>>) |this, tape, position| {
42 if this.parameter_offset > 0 {
43 tape.jump(position + this.parameter_offset as u64)?;
44 Ok(Some(tape.take_bytes(0)?))
45 } else {
46 Ok(None)
47 }
48 },
49 }
50}
51
52table! {
53 #[derive(Copy)]
55 pub Variations { major_version (u16) = { 1 }, minor_version (u16) = { 0 }, count (u32), }
60}
61
62impl Features {
63 pub fn get<T: Into<Tag>>(&self, tag: T) -> Option<&Record> {
65 let tag = tag.into();
66 self.headers
67 .iter()
68 .enumerate()
69 .find(|(_, header)| header.tag == tag)
70 .map(|(i, _)| &self.records[i])
71 }
72}
73
74macro_rules! implement {
75 ($($tag:literal => $name:literal => $variant:ident,)*) => (
76 #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
78 pub enum Feature {
79 $(#[doc = $name] $variant,)*
80 Other(Tag),
81 }
82
83 impl Feature {
84 pub fn from_tag(tag: &Tag) -> Self {
86 match &**tag {
87 $($tag => Self::$variant,)*
88 _ => Self::Other(tag.clone()),
89 }
90 }
91
92 pub fn name(&self) -> Option<&'static str> {
94 match self {
95 $(Self::$variant => Some($name),)*
96 _ => None,
97 }
98 }
99 }
100
101 impl From<Feature> for Tag {
102 fn from(feature: Feature) -> Self {
103 match feature {
104 $(Feature::$variant => Tag(*$tag),)*
105 Feature::Other(tag) => tag,
106 }
107 }
108 }
109 );
110}
111
112implement! {
113 b"aalt" => "Access All Alternates" => AccessAllAlternates,
114 b"abvf" => "Above-base Forms" => AboveBaseForms,
115 b"abvm" => "Above-base Mark Positioning" => AboveBaseMarkPositioning,
116 b"abvs" => "Above-base Substitutions" => AboveBaseSubstitutions,
117 b"afrc" => "Alternative Fractions" => AlternativeFractions,
118 b"akhn" => "Akhand" => Akhand,
119 b"blwf" => "Below-base Forms" => BelowBaseForms,
120 b"blwm" => "Below-base Mark Positioning" => BelowBaseMarkPositioning,
121 b"blws" => "Below-base Substitutions" => BelowBaseSubstitutions,
122 b"calt" => "Contextual Alternates" => ContextualAlternates,
123 b"case" => "Case-sensitive Forms" => CaseSensitiveForms,
124 b"ccmp" => "Glyph Composition and Decomposition" => GlyphCompositionDecomposition,
125 b"cfar" => "Conjunct Form After Ro" => ConjunctFormAfterRo,
126 b"chws" => "Contextual Half-width Spacing" => ContextualHalfWidthSpacing,
127 b"cjct" => "Conjunct Forms" => ConjunctForms,
128 b"clig" => "Contextual Ligatures" => ContextualLigatures,
129 b"cpct" => "Centered CJK Punctuation" => CenteredCJKPunctuation,
130 b"cpsp" => "Capital Spacing" => CapitalSpacing,
131 b"cswh" => "Contextual Swash" => ContextualSwash,
132 b"curs" => "Cursive Positioning" => CursivePositioning,
133 b"cv01" => "Character Variants 1" => CharacterVariants1,
134 b"cv02" => "Character Variants 2" => CharacterVariants2,
135 b"cv03" => "Character Variants 3" => CharacterVariants3,
136 b"cv04" => "Character Variants 4" => CharacterVariants4,
137 b"cv05" => "Character Variants 5" => CharacterVariants5,
138 b"cv06" => "Character Variants 6" => CharacterVariants6,
139 b"cv07" => "Character Variants 7" => CharacterVariants7,
140 b"cv08" => "Character Variants 8" => CharacterVariants8,
141 b"cv09" => "Character Variants 9" => CharacterVariants9,
142 b"cv10" => "Character Variants 10" => CharacterVariants10,
143 b"cv11" => "Character Variants 11" => CharacterVariants11,
144 b"cv12" => "Character Variants 12" => CharacterVariants12,
145 b"cv13" => "Character Variants 13" => CharacterVariants13,
146 b"cv14" => "Character Variants 14" => CharacterVariants14,
147 b"cv15" => "Character Variants 15" => CharacterVariants15,
148 b"cv16" => "Character Variants 16" => CharacterVariants16,
149 b"cv17" => "Character Variants 17" => CharacterVariants17,
150 b"cv18" => "Character Variants 18" => CharacterVariants18,
151 b"cv19" => "Character Variants 19" => CharacterVariants19,
152 b"cv20" => "Character Variants 20" => CharacterVariants20,
153 b"cv21" => "Character Variants 21" => CharacterVariants21,
154 b"cv22" => "Character Variants 22" => CharacterVariants22,
155 b"cv23" => "Character Variants 23" => CharacterVariants23,
156 b"cv24" => "Character Variants 24" => CharacterVariants24,
157 b"cv25" => "Character Variants 25" => CharacterVariants25,
158 b"cv26" => "Character Variants 26" => CharacterVariants26,
159 b"cv27" => "Character Variants 27" => CharacterVariants27,
160 b"cv28" => "Character Variants 28" => CharacterVariants28,
161 b"cv29" => "Character Variants 29" => CharacterVariants29,
162 b"cv30" => "Character Variants 30" => CharacterVariants30,
163 b"cv31" => "Character Variants 31" => CharacterVariants31,
164 b"cv32" => "Character Variants 32" => CharacterVariants32,
165 b"cv33" => "Character Variants 33" => CharacterVariants33,
166 b"cv34" => "Character Variants 34" => CharacterVariants34,
167 b"cv35" => "Character Variants 35" => CharacterVariants35,
168 b"cv36" => "Character Variants 36" => CharacterVariants36,
169 b"cv37" => "Character Variants 37" => CharacterVariants37,
170 b"cv38" => "Character Variants 38" => CharacterVariants38,
171 b"cv39" => "Character Variants 39" => CharacterVariants39,
172 b"cv40" => "Character Variants 40" => CharacterVariants40,
173 b"cv41" => "Character Variants 41" => CharacterVariants41,
174 b"cv42" => "Character Variants 42" => CharacterVariants42,
175 b"cv43" => "Character Variants 43" => CharacterVariants43,
176 b"cv44" => "Character Variants 44" => CharacterVariants44,
177 b"cv45" => "Character Variants 45" => CharacterVariants45,
178 b"cv46" => "Character Variants 46" => CharacterVariants46,
179 b"cv47" => "Character Variants 47" => CharacterVariants47,
180 b"cv48" => "Character Variants 48" => CharacterVariants48,
181 b"cv49" => "Character Variants 49" => CharacterVariants49,
182 b"cv50" => "Character Variants 50" => CharacterVariants50,
183 b"cv51" => "Character Variants 51" => CharacterVariants51,
184 b"cv52" => "Character Variants 52" => CharacterVariants52,
185 b"cv53" => "Character Variants 53" => CharacterVariants53,
186 b"cv54" => "Character Variants 54" => CharacterVariants54,
187 b"cv55" => "Character Variants 55" => CharacterVariants55,
188 b"cv56" => "Character Variants 56" => CharacterVariants56,
189 b"cv57" => "Character Variants 57" => CharacterVariants57,
190 b"cv58" => "Character Variants 58" => CharacterVariants58,
191 b"cv59" => "Character Variants 59" => CharacterVariants59,
192 b"cv60" => "Character Variants 60" => CharacterVariants60,
193 b"cv61" => "Character Variants 61" => CharacterVariants61,
194 b"cv62" => "Character Variants 62" => CharacterVariants62,
195 b"cv63" => "Character Variants 63" => CharacterVariants63,
196 b"cv64" => "Character Variants 64" => CharacterVariants64,
197 b"cv65" => "Character Variants 65" => CharacterVariants65,
198 b"cv66" => "Character Variants 66" => CharacterVariants66,
199 b"cv67" => "Character Variants 67" => CharacterVariants67,
200 b"cv68" => "Character Variants 68" => CharacterVariants68,
201 b"cv69" => "Character Variants 69" => CharacterVariants69,
202 b"cv70" => "Character Variants 70" => CharacterVariants70,
203 b"cv71" => "Character Variants 71" => CharacterVariants71,
204 b"cv72" => "Character Variants 72" => CharacterVariants72,
205 b"cv73" => "Character Variants 73" => CharacterVariants73,
206 b"cv74" => "Character Variants 74" => CharacterVariants74,
207 b"cv75" => "Character Variants 75" => CharacterVariants75,
208 b"cv76" => "Character Variants 76" => CharacterVariants76,
209 b"cv77" => "Character Variants 77" => CharacterVariants77,
210 b"cv78" => "Character Variants 78" => CharacterVariants78,
211 b"cv79" => "Character Variants 79" => CharacterVariants79,
212 b"cv80" => "Character Variants 80" => CharacterVariants80,
213 b"cv81" => "Character Variants 81" => CharacterVariants81,
214 b"cv82" => "Character Variants 82" => CharacterVariants82,
215 b"cv83" => "Character Variants 83" => CharacterVariants83,
216 b"cv84" => "Character Variants 84" => CharacterVariants84,
217 b"cv85" => "Character Variants 85" => CharacterVariants85,
218 b"cv86" => "Character Variants 86" => CharacterVariants86,
219 b"cv87" => "Character Variants 87" => CharacterVariants87,
220 b"cv88" => "Character Variants 88" => CharacterVariants88,
221 b"cv89" => "Character Variants 89" => CharacterVariants89,
222 b"cv90" => "Character Variants 90" => CharacterVariants90,
223 b"cv91" => "Character Variants 91" => CharacterVariants91,
224 b"cv92" => "Character Variants 92" => CharacterVariants92,
225 b"cv93" => "Character Variants 93" => CharacterVariants93,
226 b"cv94" => "Character Variants 94" => CharacterVariants94,
227 b"cv95" => "Character Variants 95" => CharacterVariants95,
228 b"cv96" => "Character Variants 96" => CharacterVariants96,
229 b"cv97" => "Character Variants 97" => CharacterVariants97,
230 b"cv98" => "Character Variants 98" => CharacterVariants98,
231 b"cv99" => "Character Variants 99" => CharacterVariants99,
232 b"c2pc" => "Petite Capitals from Capitals" => PetiteCapitalsFromCapitals,
233 b"c2sc" => "Small Capitals from Capitals" => SmallCapitalsFromCapitals,
234 b"dist" => "Distances" => Distances,
235 b"dlig" => "Discretionary Ligatures" => DiscretionaryLigatures,
236 b"dnom" => "Denominators" => Denominators,
237 b"dtls" => "Dotless Forms" => DotlessForms,
238 b"expt" => "Expert Forms" => ExpertForms,
239 b"falt" => "Final Glyph on Line Alternates" => FinalGlyphonLineAlternates,
240 b"fin2" => "Terminal Forms 2" => TerminalForms2,
241 b"fin3" => "Terminal Forms 3" => TerminalForms3,
242 b"fina" => "Terminal Forms 1" => TerminalForms1,
243 b"flac" => "Flattened Accent Forms" => FlattenedAccentForms,
244 b"frac" => "Fractions" => Fractions,
245 b"fwid" => "Full Widths" => FullWidths,
246 b"half" => "Half Forms" => HalfForms,
247 b"haln" => "Halant Forms" => HalantForms,
248 b"halt" => "Alternate Half Widths" => AlternateHalfWidths,
249 b"hist" => "Historical Forms" => HistoricalForms,
250 b"hkna" => "Horizontal Kana Alternates" => HorizontalKanaAlternates,
251 b"hlig" => "Historical Ligatures" => HistoricalLigatures,
252 b"hngl" => "Hangul" => Hangul,
253 b"hojo" => "Hojo Kanji Forms" => HojoKanjiForms,
254 b"hwid" => "Half Widths" => HalfWidths,
255 b"init" => "Initial Forms" => InitialForms,
256 b"isol" => "Isolated Forms" => IsolatedForms,
257 b"ital" => "Italics" => Italics,
258 b"jalt" => "Justification Alternates" => JustificationAlternates,
259 b"jp78" => "JIS78 Forms" => JIS78Forms,
260 b"jp83" => "JIS83 Forms" => JIS83Forms,
261 b"jp90" => "JIS90 Forms" => JIS90Forms,
262 b"jp04" => "JIS2004 Forms" => JIS2004Forms,
263 b"kern" => "Kerning" => Kerning,
264 b"lfbd" => "Left Bounds" => LeftBounds,
265 b"liga" => "Standard Ligatures" => StandardLigatures,
266 b"ljmo" => "Leading Jamo Forms" => LeadingJamoForms,
267 b"lnum" => "Lining Figures" => LiningFigures,
268 b"locl" => "Localized Forms" => LocalizedForms,
269 b"ltra" => "Left-to-right Alternates" => LeftToRightAlternates,
270 b"ltrm" => "Left-to-right Mirrored Forms" => LeftToRightMirroredForms,
271 b"mark" => "Mark Positioning" => MarkPositioning,
272 b"med2" => "Medial Forms 2" => MedialForms2,
273 b"medi" => "Medial Forms 1" => MedialForms1,
274 b"mgrk" => "Mathematical Greek" => MathematicalGreek,
275 b"mkmk" => "Mark-to-mark Positioning" => MarkToMarkPositioning,
276 b"mset" => "Mark Positioning via Substitution" => MarkPositioningViaSubstitution,
277 b"nalt" => "Alternate Annotation Forms" => AlternateAnnotationForms,
278 b"nlck" => "NLC Kanji Forms" => NLCKanjiForms,
279 b"nukt" => "Nukta Forms" => NuktaForms,
280 b"numr" => "Numerators" => Numerators,
281 b"onum" => "Oldstyle Figures" => OldstyleFigures,
282 b"opbd" => "Optical Bounds" => OpticalBounds,
283 b"ordn" => "Ordinals" => Ordinals,
284 b"ornm" => "Ornaments" => Ornaments,
285 b"palt" => "Proportional Alternate Widths" => ProportionalAlternateWidths,
286 b"pcap" => "Petite Capitals" => PetiteCapitals,
287 b"pkna" => "Proportional Kana" => ProportionalKana,
288 b"pnum" => "Proportional Figures" => ProportionalFigures,
289 b"pref" => "Pre-base Forms" => PreBaseForms,
290 b"pres" => "Pre-base Substitutions" => PreBaseSubstitutions,
291 b"pstf" => "Post-base Forms" => PostBaseForms,
292 b"psts" => "Post-base Substitutions" => PostBaseSubstitutions,
293 b"pwid" => "Proportional Widths" => ProportionalWidths,
294 b"qwid" => "Quarter Widths" => QuarterWidths,
295 b"rand" => "Randomize" => Randomize,
296 b"rclt" => "Required Contextual Alternates" => RequiredContextualAlternates,
297 b"rkrf" => "Rakar Forms" => RakarForms,
298 b"rlig" => "Required Ligatures" => RequiredLigatures,
299 b"rphf" => "Reph Forms" => RephForms,
300 b"rtbd" => "Right Bounds" => RightBounds,
301 b"rtla" => "Right-to-left Alternates" => RightToLeftAlternates,
302 b"rtlm" => "Right-to-left Mirrored Forms" => RightToLeftMirroredForms,
303 b"ruby" => "Ruby Notation Forms" => RubyNotationForms,
304 b"rvrn" => "Required Variation Alternates" => RequiredVariationAlternates,
305 b"salt" => "Stylistic Alternates" => StylisticAlternates,
306 b"sinf" => "Scientific Inferiors" => ScientificInferiors,
307 b"size" => "Optical Size" => OpticalSize,
308 b"smcp" => "Small Capitals" => SmallCapitals,
309 b"smpl" => "Simplified Forms" => SimplifiedForms,
310 b"ss01" => "Stylistic Set 1" => StylisticSet1,
311 b"ss02" => "Stylistic Set 2" => StylisticSet2,
312 b"ss03" => "Stylistic Set 3" => StylisticSet3,
313 b"ss04" => "Stylistic Set 4" => StylisticSet4,
314 b"ss05" => "Stylistic Set 5" => StylisticSet5,
315 b"ss06" => "Stylistic Set 6" => StylisticSet6,
316 b"ss07" => "Stylistic Set 7" => StylisticSet7,
317 b"ss08" => "Stylistic Set 8" => StylisticSet8,
318 b"ss09" => "Stylistic Set 9" => StylisticSet9,
319 b"ss10" => "Stylistic Set 10" => StylisticSet10,
320 b"ss11" => "Stylistic Set 11" => StylisticSet11,
321 b"ss12" => "Stylistic Set 12" => StylisticSet12,
322 b"ss13" => "Stylistic Set 13" => StylisticSet13,
323 b"ss14" => "Stylistic Set 14" => StylisticSet14,
324 b"ss15" => "Stylistic Set 15" => StylisticSet15,
325 b"ss16" => "Stylistic Set 16" => StylisticSet16,
326 b"ss17" => "Stylistic Set 17" => StylisticSet17,
327 b"ss18" => "Stylistic Set 18" => StylisticSet18,
328 b"ss19" => "Stylistic Set 19" => StylisticSet19,
329 b"ss20" => "Stylistic Set 20" => StylisticSet20,
330 b"ssty" => "Math Script Style Alternates" => MathScriptStyleAlternates,
331 b"stch" => "Stretching Glyph Decomposition" => StretchingGlyphDecomposition,
332 b"subs" => "Subscript" => Subscript,
333 b"sups" => "Superscript" => Superscript,
334 b"swsh" => "Swash" => Swash,
335 b"titl" => "Titling" => Titling,
336 b"tjmo" => "Trailing Jamo Forms" => TrailingJamoForms,
337 b"tnam" => "Traditional Name Forms" => TraditionalNameForms,
338 b"tnum" => "Tabular Figures" => TabularFigures,
339 b"trad" => "Traditional Forms" => TraditionalForms,
340 b"twid" => "Third Widths" => ThirdWidths,
341 b"unic" => "Unicase" => Unicase,
342 b"valt" => "Alternate Vertical Metrics" => AlternateVerticalMetrics,
343 b"vatu" => "Vattu Variants" => VattuVariants,
344 b"vchw" => "Vertical Contextual Half-width Spacing" => VerticalContextualHalfWidthSpacing,
345 b"vert" => "Vertical Writing" => VerticalWriting,
346 b"vhal" => "Alternate Vertical Half Metrics" => AlternateVerticalHalfMetrics,
347 b"vjmo" => "Vowel Jamo Forms" => VowelJamoForms,
348 b"vkna" => "Vertical Kana Alternates" => VerticalKanaAlternates,
349 b"vkrn" => "Vertical Kerning" => VerticalKerning,
350 b"vpal" => "Proportional Alternate Vertical Metrics" => ProportionalAlternateVerticalMetrics,
351 b"vrt2" => "Vertical Alternates and Rotation" => VerticalAlternatesAndRotation,
352 b"vrtr" => "Vertical Alternates for Rotation" => VerticalAlternatesForRotation,
353 b"zero" => "Slashed Zero" => SlashedZero,
354}