1 /*
2 * Copyright © 2017 Google, Inc.
3 * Copyright © 2018 Ebrahim Byagowi
4 *
5 * This is part of HarfBuzz, a text shaping library.
6 *
7 * Permission is hereby granted, without written agreement and without
8 * license or royalty fees, to use, copy, modify, and distribute this
9 * software and its documentation for any purpose, provided that the
10 * above copyright notice and the following two paragraphs appear in
11 * all copies of this software.
12 *
13 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
14 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
15 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
16 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
17 * DAMAGE.
18 *
19 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
20 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
21 * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
22 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
23 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
24 *
25 * Google Author(s): Behdad Esfahbod
26 */
27
28 #include "hb.hh"
29
30 #include "hb-aat-layout.hh"
31 #include "hb-aat-layout-ankr-table.hh"
32 #include "hb-aat-layout-feat-table.hh"
33 #include "hb-aat-layout-kerx-table.hh"
34 #include "hb-aat-layout-morx-table.hh"
35 #include "hb-aat-layout-trak-table.hh"
36
37 /*
38 * hb_aat_apply_context_t
39 */
40
41 /* Note: This context is used for kerning, even without AAT, hence the condition. */
42 #if !defined(HB_NO_AAT) || !defined(HB_NO_OT_KERN)
43
hb_aat_apply_context_t(const hb_ot_shape_plan_t * plan_,hb_font_t * font_,hb_buffer_t * buffer_,hb_blob_t * blob)44 AAT::hb_aat_apply_context_t::hb_aat_apply_context_t(const hb_ot_shape_plan_t *plan_,
45 hb_font_t *font_,
46 hb_buffer_t *buffer_,
47 hb_blob_t *blob)
48 : plan(plan_)
49 , font(font_)
50 , face(font->face)
51 , buffer(buffer_)
52 , sanitizer()
53 , ankr_table(&Null(AAT::ankr))
54 , lookup_index(0)
55 {
56 sanitizer.init(blob);
57 sanitizer.set_num_glyphs(face->get_num_glyphs());
58 sanitizer.start_processing();
59 sanitizer.set_max_ops(HB_SANITIZE_MAX_OPS_MAX);
60 }
61
~hb_aat_apply_context_t()62 AAT::hb_aat_apply_context_t::~hb_aat_apply_context_t()
63 {
64 sanitizer.end_processing();
65 }
66
set_ankr_table(const AAT::ankr * ankr_table_)67 void AAT::hb_aat_apply_context_t::set_ankr_table(const AAT::ankr *ankr_table_)
68 {
69 ankr_table = ankr_table_;
70 }
71
72 #endif
73
74 /**
75 * SECTION:hb-aat-layout
76 * @title: hb-aat-layout
77 * @short_description: Apple Advanced Typography Layout
78 * @include: hb-aat.h
79 *
80 * Functions for querying OpenType Layout features in the font face.
81 **/
82
83 #if !defined(HB_NO_AAT) || defined(HAVE_CORETEXT)
84
85 /* Table data courtesy of Apple. Converted from mnemonics to integers
86 * when moving to this file. */
87 static const hb_aat_feature_mapping_t feature_mappings[] = {
88 {HB_TAG('a', 'f', 'r', 'c'),
89 HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS,
90 HB_AAT_LAYOUT_FEATURE_SELECTOR_VERTICAL_FRACTIONS,
91 HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_FRACTIONS},
92 {HB_TAG('c', '2', 'p', 'c'),
93 HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE,
94 HB_AAT_LAYOUT_FEATURE_SELECTOR_UPPER_CASE_PETITE_CAPS,
95 HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_UPPER_CASE},
96 {HB_TAG('c', '2', 's', 'c'),
97 HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE,
98 HB_AAT_LAYOUT_FEATURE_SELECTOR_UPPER_CASE_SMALL_CAPS,
99 HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_UPPER_CASE},
100 {HB_TAG('c', 'a', 'l', 't'),
101 HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES,
102 HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_ALTERNATES_ON,
103 HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_ALTERNATES_OFF},
104 {HB_TAG('c', 'a', 's', 'e'),
105 HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT,
106 HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_LAYOUT_ON,
107 HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_LAYOUT_OFF},
108 {HB_TAG('c', 'l', 'i', 'g'),
109 HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES,
110 HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_LIGATURES_ON,
111 HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_LIGATURES_OFF},
112 {HB_TAG('c', 'p', 's', 'p'),
113 HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT,
114 HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_SPACING_ON,
115 HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_SPACING_OFF},
116 {HB_TAG('c', 's', 'w', 'h'),
117 HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES,
118 HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_SWASH_ALTERNATES_ON,
119 HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_SWASH_ALTERNATES_OFF},
120 {HB_TAG('d', 'l', 'i', 'g'),
121 HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES,
122 HB_AAT_LAYOUT_FEATURE_SELECTOR_RARE_LIGATURES_ON,
123 HB_AAT_LAYOUT_FEATURE_SELECTOR_RARE_LIGATURES_OFF},
124 {HB_TAG('e', 'x', 'p', 't'),
125 HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE,
126 HB_AAT_LAYOUT_FEATURE_SELECTOR_EXPERT_CHARACTERS,
127 (hb_aat_layout_feature_selector_t)16},
128 {HB_TAG('f', 'r', 'a', 'c'),
129 HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS,
130 HB_AAT_LAYOUT_FEATURE_SELECTOR_DIAGONAL_FRACTIONS,
131 HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_FRACTIONS},
132 {HB_TAG('f', 'w', 'i', 'd'),
133 HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING,
134 HB_AAT_LAYOUT_FEATURE_SELECTOR_MONOSPACED_TEXT,
135 (hb_aat_layout_feature_selector_t)7},
136 {HB_TAG('h', 'a', 'l', 't'),
137 HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING,
138 HB_AAT_LAYOUT_FEATURE_SELECTOR_ALT_HALF_WIDTH_TEXT,
139 (hb_aat_layout_feature_selector_t)7},
140 {HB_TAG('h', 'i', 's', 't'),
141 HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES,
142 HB_AAT_LAYOUT_FEATURE_SELECTOR_HISTORICAL_LIGATURES_ON,
143 HB_AAT_LAYOUT_FEATURE_SELECTOR_HISTORICAL_LIGATURES_OFF},
144 {HB_TAG('h', 'k', 'n', 'a'),
145 HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA,
146 HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_HORIZ_KANA_ON,
147 HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_HORIZ_KANA_OFF},
148 {HB_TAG('h', 'l', 'i', 'g'),
149 HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES,
150 HB_AAT_LAYOUT_FEATURE_SELECTOR_HISTORICAL_LIGATURES_ON,
151 HB_AAT_LAYOUT_FEATURE_SELECTOR_HISTORICAL_LIGATURES_OFF},
152 {HB_TAG('h', 'n', 'g', 'l'),
153 HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION,
154 HB_AAT_LAYOUT_FEATURE_SELECTOR_HANJA_TO_HANGUL,
155 HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_TRANSLITERATION},
156 {HB_TAG('h', 'o', 'j', 'o'),
157 HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE,
158 HB_AAT_LAYOUT_FEATURE_SELECTOR_HOJO_CHARACTERS,
159 (hb_aat_layout_feature_selector_t)16},
160 {HB_TAG('h', 'w', 'i', 'd'),
161 HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING,
162 HB_AAT_LAYOUT_FEATURE_SELECTOR_HALF_WIDTH_TEXT,
163 (hb_aat_layout_feature_selector_t)7},
164 {HB_TAG('i', 't', 'a', 'l'),
165 HB_AAT_LAYOUT_FEATURE_TYPE_ITALIC_CJK_ROMAN,
166 HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN_ON,
167 HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN_OFF},
168 {HB_TAG('j', 'p', '0', '4'),
169 HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE,
170 HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS2004_CHARACTERS,
171 (hb_aat_layout_feature_selector_t)16},
172 {HB_TAG('j', 'p', '7', '8'),
173 HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE,
174 HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS1978_CHARACTERS,
175 (hb_aat_layout_feature_selector_t)16},
176 {HB_TAG('j', 'p', '8', '3'),
177 HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE,
178 HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS1983_CHARACTERS,
179 (hb_aat_layout_feature_selector_t)16},
180 {HB_TAG('j', 'p', '9', '0'),
181 HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE,
182 HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS1990_CHARACTERS,
183 (hb_aat_layout_feature_selector_t)16},
184 {HB_TAG('l', 'i', 'g', 'a'),
185 HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES,
186 HB_AAT_LAYOUT_FEATURE_SELECTOR_COMMON_LIGATURES_ON,
187 HB_AAT_LAYOUT_FEATURE_SELECTOR_COMMON_LIGATURES_OFF},
188 {HB_TAG('l', 'n', 'u', 'm'),
189 HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE,
190 HB_AAT_LAYOUT_FEATURE_SELECTOR_UPPER_CASE_NUMBERS,
191 (hb_aat_layout_feature_selector_t)2},
192 {HB_TAG('m', 'g', 'r', 'k'),
193 HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS,
194 HB_AAT_LAYOUT_FEATURE_SELECTOR_MATHEMATICAL_GREEK_ON,
195 HB_AAT_LAYOUT_FEATURE_SELECTOR_MATHEMATICAL_GREEK_OFF},
196 {HB_TAG('n', 'l', 'c', 'k'),
197 HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE,
198 HB_AAT_LAYOUT_FEATURE_SELECTOR_NLCCHARACTERS,
199 (hb_aat_layout_feature_selector_t)16},
200 {HB_TAG('o', 'n', 'u', 'm'),
201 HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE,
202 HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_NUMBERS,
203 (hb_aat_layout_feature_selector_t)2},
204 {HB_TAG('o', 'r', 'd', 'n'),
205 HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION,
206 HB_AAT_LAYOUT_FEATURE_SELECTOR_ORDINALS,
207 HB_AAT_LAYOUT_FEATURE_SELECTOR_NORMAL_POSITION},
208 {HB_TAG('p', 'a', 'l', 't'),
209 HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING,
210 HB_AAT_LAYOUT_FEATURE_SELECTOR_ALT_PROPORTIONAL_TEXT,
211 (hb_aat_layout_feature_selector_t)7},
212 {HB_TAG('p', 'c', 'a', 'p'),
213 HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE,
214 HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_PETITE_CAPS,
215 HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_LOWER_CASE},
216 {HB_TAG('p', 'k', 'n', 'a'),
217 HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING,
218 HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_TEXT,
219 (hb_aat_layout_feature_selector_t)7},
220 {HB_TAG('p', 'n', 'u', 'm'),
221 HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING,
222 HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_NUMBERS,
223 (hb_aat_layout_feature_selector_t)4},
224 {HB_TAG('p', 'w', 'i', 'd'),
225 HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING,
226 HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_TEXT,
227 (hb_aat_layout_feature_selector_t)7},
228 {HB_TAG('q', 'w', 'i', 'd'),
229 HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING,
230 HB_AAT_LAYOUT_FEATURE_SELECTOR_QUARTER_WIDTH_TEXT,
231 (hb_aat_layout_feature_selector_t)7},
232 {HB_TAG('r', 'u', 'b', 'y'),
233 HB_AAT_LAYOUT_FEATURE_TYPE_RUBY_KANA,
234 HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA_ON,
235 HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA_OFF},
236 {HB_TAG('s', 'i', 'n', 'f'),
237 HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION,
238 HB_AAT_LAYOUT_FEATURE_SELECTOR_SCIENTIFIC_INFERIORS,
239 HB_AAT_LAYOUT_FEATURE_SELECTOR_NORMAL_POSITION},
240 {HB_TAG('s', 'm', 'c', 'p'),
241 HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE,
242 HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_SMALL_CAPS,
243 HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_LOWER_CASE},
244 {HB_TAG('s', 'm', 'p', 'l'),
245 HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE,
246 HB_AAT_LAYOUT_FEATURE_SELECTOR_SIMPLIFIED_CHARACTERS,
247 (hb_aat_layout_feature_selector_t)16},
248 {HB_TAG('s', 's', '0', '1'),
249 HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES,
250 HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ONE_ON,
251 HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ONE_OFF},
252 {HB_TAG('s', 's', '0', '2'),
253 HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES,
254 HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWO_ON,
255 HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWO_OFF},
256 {HB_TAG('s', 's', '0', '3'),
257 HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES,
258 HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THREE_ON,
259 HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THREE_OFF},
260 {HB_TAG('s', 's', '0', '4'),
261 HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES,
262 HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOUR_ON,
263 HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOUR_OFF},
264 {HB_TAG('s', 's', '0', '5'),
265 HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES,
266 HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIVE_ON,
267 HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIVE_OFF},
268 {HB_TAG('s', 's', '0', '6'),
269 HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES,
270 HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIX_ON,
271 HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIX_OFF},
272 {HB_TAG('s', 's', '0', '7'),
273 HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES,
274 HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVEN_ON,
275 HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVEN_OFF},
276 {HB_TAG('s', 's', '0', '8'),
277 HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES,
278 HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHT_ON,
279 HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHT_OFF},
280 {HB_TAG('s', 's', '0', '9'),
281 HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES,
282 HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINE_ON,
283 HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINE_OFF},
284 {HB_TAG('s', 's', '1', '0'),
285 HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES,
286 HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TEN_ON,
287 HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TEN_OFF},
288 {HB_TAG('s', 's', '1', '1'),
289 HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES,
290 HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ELEVEN_ON,
291 HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ELEVEN_OFF},
292 {HB_TAG('s', 's', '1', '2'),
293 HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES,
294 HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWELVE_ON,
295 HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWELVE_OFF},
296 {HB_TAG('s', 's', '1', '3'),
297 HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES,
298 HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THIRTEEN_ON,
299 HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THIRTEEN_OFF},
300 {HB_TAG('s', 's', '1', '4'),
301 HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES,
302 HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOURTEEN_ON,
303 HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOURTEEN_OFF},
304 {HB_TAG('s', 's', '1', '5'),
305 HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES,
306 HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIFTEEN_ON,
307 HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIFTEEN_OFF},
308 {HB_TAG('s', 's', '1', '6'),
309 HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES,
310 HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIXTEEN_ON,
311 HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIXTEEN_OFF},
312 {HB_TAG('s', 's', '1', '7'),
313 HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES,
314 HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVENTEEN_ON,
315 HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVENTEEN_OFF},
316 {HB_TAG('s', 's', '1', '8'),
317 HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES,
318 HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHTEEN_ON,
319 HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHTEEN_OFF},
320 {HB_TAG('s', 's', '1', '9'),
321 HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES,
322 HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINETEEN_ON,
323 HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINETEEN_OFF},
324 {HB_TAG('s', 's', '2', '0'),
325 HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES,
326 HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWENTY_ON,
327 HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWENTY_OFF},
328 {HB_TAG('s', 'u', 'b', 's'),
329 HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION,
330 HB_AAT_LAYOUT_FEATURE_SELECTOR_INFERIORS,
331 HB_AAT_LAYOUT_FEATURE_SELECTOR_NORMAL_POSITION},
332 {HB_TAG('s', 'u', 'p', 's'),
333 HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION,
334 HB_AAT_LAYOUT_FEATURE_SELECTOR_SUPERIORS,
335 HB_AAT_LAYOUT_FEATURE_SELECTOR_NORMAL_POSITION},
336 {HB_TAG('s', 'w', 's', 'h'),
337 HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES,
338 HB_AAT_LAYOUT_FEATURE_SELECTOR_SWASH_ALTERNATES_ON,
339 HB_AAT_LAYOUT_FEATURE_SELECTOR_SWASH_ALTERNATES_OFF},
340 {HB_TAG('t', 'i', 't', 'l'),
341 HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS,
342 HB_AAT_LAYOUT_FEATURE_SELECTOR_TITLING_CAPS,
343 HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_STYLE_OPTIONS},
344 {HB_TAG('t', 'n', 'a', 'm'),
345 HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE,
346 HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_NAMES_CHARACTERS,
347 (hb_aat_layout_feature_selector_t)16},
348 {HB_TAG('t', 'n', 'u', 'm'),
349 HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING,
350 HB_AAT_LAYOUT_FEATURE_SELECTOR_MONOSPACED_NUMBERS,
351 (hb_aat_layout_feature_selector_t)4},
352 {HB_TAG('t', 'r', 'a', 'd'),
353 HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE,
354 HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_CHARACTERS,
355 (hb_aat_layout_feature_selector_t)16},
356 {HB_TAG('t', 'w', 'i', 'd'),
357 HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING,
358 HB_AAT_LAYOUT_FEATURE_SELECTOR_THIRD_WIDTH_TEXT,
359 (hb_aat_layout_feature_selector_t)7},
360 {HB_TAG('u', 'n', 'i', 'c'),
361 HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE,
362 (hb_aat_layout_feature_selector_t)14,
363 (hb_aat_layout_feature_selector_t)15},
364 {HB_TAG('v', 'a', 'l', 't'),
365 HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING,
366 HB_AAT_LAYOUT_FEATURE_SELECTOR_ALT_PROPORTIONAL_TEXT,
367 (hb_aat_layout_feature_selector_t)7},
368 {HB_TAG('v', 'e', 'r', 't'),
369 HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION,
370 HB_AAT_LAYOUT_FEATURE_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_ON,
371 HB_AAT_LAYOUT_FEATURE_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_OFF},
372 {HB_TAG('v', 'h', 'a', 'l'),
373 HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING,
374 HB_AAT_LAYOUT_FEATURE_SELECTOR_ALT_HALF_WIDTH_TEXT,
375 (hb_aat_layout_feature_selector_t)7},
376 {HB_TAG('v', 'k', 'n', 'a'),
377 HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA,
378 HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_VERT_KANA_ON,
379 HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_VERT_KANA_OFF},
380 {HB_TAG('v', 'p', 'a', 'l'),
381 HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING,
382 HB_AAT_LAYOUT_FEATURE_SELECTOR_ALT_PROPORTIONAL_TEXT,
383 (hb_aat_layout_feature_selector_t)7},
384 {HB_TAG('v', 'r', 't', '2'),
385 HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION,
386 HB_AAT_LAYOUT_FEATURE_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_ON,
387 HB_AAT_LAYOUT_FEATURE_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_OFF},
388 {HB_TAG('z', 'e', 'r', 'o'),
389 HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS,
390 HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASHED_ZERO_ON,
391 HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASHED_ZERO_OFF},
392 };
393
hb_aat_layout_find_feature_mapping(hb_tag_t tag)394 const hb_aat_feature_mapping_t *hb_aat_layout_find_feature_mapping(hb_tag_t tag)
395 {
396 return hb_sorted_array(feature_mappings).bsearch(tag);
397 }
398 #endif
399
400 #ifndef HB_NO_AAT
401
402 /*
403 * mort/morx/kerx/trak
404 */
405
hb_aat_layout_compile_map(const hb_aat_map_builder_t * mapper,hb_aat_map_t * map)406 void hb_aat_layout_compile_map(const hb_aat_map_builder_t *mapper, hb_aat_map_t *map)
407 {
408 const AAT::morx &morx = *mapper->face->table.morx;
409 if (morx.has_data()) {
410 morx.compile_flags(mapper, map);
411 return;
412 }
413
414 const AAT::mort &mort = *mapper->face->table.mort;
415 if (mort.has_data()) {
416 mort.compile_flags(mapper, map);
417 return;
418 }
419 }
420
421 /*
422 * hb_aat_layout_has_substitution:
423 * @face:
424 *
425 * Returns:
426 * Since: 2.3.0
427 */
hb_aat_layout_has_substitution(hb_face_t * face)428 hb_bool_t hb_aat_layout_has_substitution(hb_face_t *face)
429 {
430 return face->table.morx->has_data() || face->table.mort->has_data();
431 }
432
hb_aat_layout_substitute(const hb_ot_shape_plan_t * plan,hb_font_t * font,hb_buffer_t * buffer)433 void hb_aat_layout_substitute(const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer)
434 {
435 hb_blob_t *morx_blob = font->face->table.morx.get_blob();
436 const AAT::morx &morx = *morx_blob->as<AAT::morx>();
437 if (morx.has_data()) {
438 AAT::hb_aat_apply_context_t c(plan, font, buffer, morx_blob);
439 morx.apply(&c);
440 return;
441 }
442
443 hb_blob_t *mort_blob = font->face->table.mort.get_blob();
444 const AAT::mort &mort = *mort_blob->as<AAT::mort>();
445 if (mort.has_data()) {
446 AAT::hb_aat_apply_context_t c(plan, font, buffer, mort_blob);
447 mort.apply(&c);
448 return;
449 }
450 }
451
hb_aat_layout_zero_width_deleted_glyphs(hb_buffer_t * buffer)452 void hb_aat_layout_zero_width_deleted_glyphs(hb_buffer_t *buffer)
453 {
454 unsigned int count = buffer->len;
455 hb_glyph_info_t *info = buffer->info;
456 hb_glyph_position_t *pos = buffer->pos;
457 for (unsigned int i = 0; i < count; i++)
458 if (unlikely(info[i].codepoint == AAT::DELETED_GLYPH))
459 pos[i].x_advance = pos[i].y_advance = pos[i].x_offset = pos[i].y_offset = 0;
460 }
461
is_deleted_glyph(const hb_glyph_info_t * info)462 static bool is_deleted_glyph(const hb_glyph_info_t *info)
463 {
464 return info->codepoint == AAT::DELETED_GLYPH;
465 }
466
hb_aat_layout_remove_deleted_glyphs(hb_buffer_t * buffer)467 void hb_aat_layout_remove_deleted_glyphs(hb_buffer_t *buffer)
468 {
469 hb_ot_layout_delete_glyphs_inplace(buffer, is_deleted_glyph);
470 }
471
472 /*
473 * hb_aat_layout_has_positioning:
474 * @face:
475 *
476 * Returns:
477 * Since: 2.3.0
478 */
hb_aat_layout_has_positioning(hb_face_t * face)479 hb_bool_t hb_aat_layout_has_positioning(hb_face_t *face)
480 {
481 return face->table.kerx->has_data();
482 }
483
hb_aat_layout_position(const hb_ot_shape_plan_t * plan,hb_font_t * font,hb_buffer_t * buffer)484 void hb_aat_layout_position(const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer)
485 {
486 hb_blob_t *kerx_blob = font->face->table.kerx.get_blob();
487 const AAT::kerx &kerx = *kerx_blob->as<AAT::kerx>();
488
489 AAT::hb_aat_apply_context_t c(plan, font, buffer, kerx_blob);
490 c.set_ankr_table(font->face->table.ankr.get());
491 kerx.apply(&c);
492 }
493
494 /*
495 * hb_aat_layout_has_tracking:
496 * @face:
497 *
498 * Returns:
499 * Since: 2.3.0
500 */
hb_aat_layout_has_tracking(hb_face_t * face)501 hb_bool_t hb_aat_layout_has_tracking(hb_face_t *face)
502 {
503 return face->table.trak->has_data();
504 }
505
hb_aat_layout_track(const hb_ot_shape_plan_t * plan,hb_font_t * font,hb_buffer_t * buffer)506 void hb_aat_layout_track(const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer)
507 {
508 const AAT::trak &trak = *font->face->table.trak;
509
510 AAT::hb_aat_apply_context_t c(plan, font, buffer);
511 trak.apply(&c);
512 }
513
514 /**
515 * hb_aat_layout_get_feature_types:
516 * @face: a face object
517 * @start_offset: iteration's start offset
518 * @feature_count:(inout) (allow-none): buffer size as input, filled size as output
519 * @features: (out caller-allocates) (array length=feature_count): features buffer
520 *
521 * Return value: Number of all available feature types.
522 *
523 * Since: 2.2.0
524 */
hb_aat_layout_get_feature_types(hb_face_t * face,unsigned int start_offset,unsigned int * feature_count,hb_aat_layout_feature_type_t * features)525 unsigned int hb_aat_layout_get_feature_types(hb_face_t *face,
526 unsigned int start_offset,
527 unsigned int *feature_count, /* IN/OUT. May be NULL. */
528 hb_aat_layout_feature_type_t *features /* OUT. May be NULL. */)
529 {
530 return face->table.feat->get_feature_types(start_offset, feature_count, features);
531 }
532
533 /**
534 * hb_aat_layout_feature_type_get_name_id:
535 * @face: a face object
536 * @feature_type: feature id
537 *
538 * Return value: Name ID index
539 *
540 * Since: 2.2.0
541 */
hb_aat_layout_feature_type_get_name_id(hb_face_t * face,hb_aat_layout_feature_type_t feature_type)542 hb_ot_name_id_t hb_aat_layout_feature_type_get_name_id(hb_face_t *face, hb_aat_layout_feature_type_t feature_type)
543 {
544 return face->table.feat->get_feature_name_id(feature_type);
545 }
546
547 /**
548 * hb_aat_layout_feature_type_get_selectors:
549 * @face: a face object
550 * @feature_type: feature id
551 * @start_offset: iteration's start offset
552 * @selector_count: (inout) (allow-none): buffer size as input, filled size as output
553 * @selectors: (out caller-allocates) (array length=selector_count): settings buffer
554 * @default_index: (out) (allow-none): index of default selector if any
555 *
556 * If upon return, @default_index is set to #HB_AAT_LAYOUT_NO_SELECTOR_INDEX, then
557 * the feature type is non-exclusive. Otherwise, @default_index is the index of
558 * the selector that is selected by default.
559 *
560 * Return value: Number of all available feature selectors.
561 *
562 * Since: 2.2.0
563 */
hb_aat_layout_feature_type_get_selector_infos(hb_face_t * face,hb_aat_layout_feature_type_t feature_type,unsigned int start_offset,unsigned int * selector_count,hb_aat_layout_feature_selector_info_t * selectors,unsigned int * default_index)564 unsigned int hb_aat_layout_feature_type_get_selector_infos(
565 hb_face_t *face,
566 hb_aat_layout_feature_type_t feature_type,
567 unsigned int start_offset,
568 unsigned int *selector_count, /* IN/OUT. May be NULL. */
569 hb_aat_layout_feature_selector_info_t *selectors, /* OUT. May be NULL. */
570 unsigned int *default_index /* OUT. May be NULL. */)
571 {
572 return face->table.feat->get_selector_infos(feature_type, start_offset, selector_count, selectors, default_index);
573 }
574
575 #endif
576