1/* == Start of generated functions == */
2/*
3 * The following functions are generated by running:
4 *
5 * ./gen-vowel-constraints.py use Scripts.txt
6 *
7 * on files with these headers:
8 *
9 * # Copied from https://docs.microsoft.com/en-us/typography/script-development/use
10 * # On October 23, 2018; with documentd dated 02/07/2018.
11 *
12 * # Scripts-12.0.0.txt
13 * # Date: 2019-01-28, 22:16:47 GMT
14 */
15
16#include "hb.hh"
17
18#ifndef HB_NO_OT_SHAPE
19
20#include "hb-ot-shape-complex-vowel-constraints.hh"
21
22static void
23_output_dotted_circle (hb_buffer_t *buffer)
24{
25 hb_glyph_info_t &dottedcircle = buffer->output_glyph (0x25CCu);
26 _hb_glyph_info_reset_continuation (&dottedcircle);
27}
28
29static void
30_output_with_dotted_circle (hb_buffer_t *buffer)
31{
32 _output_dotted_circle (buffer);
33 buffer->next_glyph ();
34}
35
36void
37_hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
38 hb_buffer_t *buffer,
39 hb_font_t *font HB_UNUSED)
40{
41#ifdef HB_NO_OT_SHAPE_COMPLEX_VOWEL_CONSTRAINTS
42 return;
43#endif
44 if (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE)
45 return;
46
47 /* UGLY UGLY UGLY business of adding dotted-circle in the middle of
48 * vowel-sequences that look like another vowel. Data for each script
49 * collected from the USE script development spec.
50 *
51 * https://github.com/harfbuzz/harfbuzz/issues/1019
52 */
53 bool processed = false;
54 buffer->clear_output ();
55 unsigned int count = buffer->len;
56 switch ((unsigned) buffer->props.script)
57 {
58 case HB_SCRIPT_DEVANAGARI:
59 for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
60 {
61 bool matched = false;
62 switch (buffer->cur ().codepoint)
63 {
64 case 0x0905u:
65 switch (buffer->cur (1).codepoint)
66 {
67 case 0x093Au: case 0x093Bu: case 0x093Eu: case 0x0945u:
68 case 0x0946u: case 0x0949u: case 0x094Au: case 0x094Bu:
69 case 0x094Cu: case 0x094Fu: case 0x0956u: case 0x0957u:
70 matched = true;
71 break;
72 }
73 break;
74 case 0x0906u:
75 switch (buffer->cur (1).codepoint)
76 {
77 case 0x093Au: case 0x0945u: case 0x0946u: case 0x0947u:
78 case 0x0948u:
79 matched = true;
80 break;
81 }
82 break;
83 case 0x0909u:
84 matched = 0x0941u == buffer->cur (1).codepoint;
85 break;
86 case 0x090Fu:
87 switch (buffer->cur (1).codepoint)
88 {
89 case 0x0945u: case 0x0946u: case 0x0947u:
90 matched = true;
91 break;
92 }
93 break;
94 case 0x0930u:
95 if (0x094Du == buffer->cur (1).codepoint &&
96 buffer->idx + 2 < count &&
97 0x0907u == buffer->cur (2).codepoint)
98 {
99 buffer->next_glyph ();
100 buffer->next_glyph ();
101 _output_dotted_circle (buffer);
102 }
103 break;
104 }
105 buffer->next_glyph ();
106 if (matched) _output_with_dotted_circle (buffer);
107 }
108 processed = true;
109 break;
110
111 case HB_SCRIPT_BENGALI:
112 for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
113 {
114 bool matched = false;
115 switch (buffer->cur ().codepoint)
116 {
117 case 0x0985u:
118 matched = 0x09BEu == buffer->cur (1).codepoint;
119 break;
120 case 0x098Bu:
121 matched = 0x09C3u == buffer->cur (1).codepoint;
122 break;
123 case 0x098Cu:
124 matched = 0x09E2u == buffer->cur (1).codepoint;
125 break;
126 }
127 buffer->next_glyph ();
128 if (matched) _output_with_dotted_circle (buffer);
129 }
130 processed = true;
131 break;
132
133 case HB_SCRIPT_GURMUKHI:
134 for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
135 {
136 bool matched = false;
137 switch (buffer->cur ().codepoint)
138 {
139 case 0x0A05u:
140 switch (buffer->cur (1).codepoint)
141 {
142 case 0x0A3Eu: case 0x0A48u: case 0x0A4Cu:
143 matched = true;
144 break;
145 }
146 break;
147 case 0x0A72u:
148 switch (buffer->cur (1).codepoint)
149 {
150 case 0x0A3Fu: case 0x0A40u: case 0x0A47u:
151 matched = true;
152 break;
153 }
154 break;
155 case 0x0A73u:
156 switch (buffer->cur (1).codepoint)
157 {
158 case 0x0A41u: case 0x0A42u: case 0x0A4Bu:
159 matched = true;
160 break;
161 }
162 break;
163 }
164 buffer->next_glyph ();
165 if (matched) _output_with_dotted_circle (buffer);
166 }
167 processed = true;
168 break;
169
170 case HB_SCRIPT_GUJARATI:
171 for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
172 {
173 bool matched = false;
174 switch (buffer->cur ().codepoint)
175 {
176 case 0x0A85u:
177 switch (buffer->cur (1).codepoint)
178 {
179 case 0x0ABEu: case 0x0AC5u: case 0x0AC7u: case 0x0AC8u:
180 case 0x0AC9u: case 0x0ACBu: case 0x0ACCu:
181 matched = true;
182 break;
183 }
184 break;
185 case 0x0AC5u:
186 matched = 0x0ABEu == buffer->cur (1).codepoint;
187 break;
188 }
189 buffer->next_glyph ();
190 if (matched) _output_with_dotted_circle (buffer);
191 }
192 processed = true;
193 break;
194
195 case HB_SCRIPT_ORIYA:
196 for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
197 {
198 bool matched = false;
199 switch (buffer->cur ().codepoint)
200 {
201 case 0x0B05u:
202 matched = 0x0B3Eu == buffer->cur (1).codepoint;
203 break;
204 case 0x0B0Fu: case 0x0B13u:
205 matched = 0x0B57u == buffer->cur (1).codepoint;
206 break;
207 }
208 buffer->next_glyph ();
209 if (matched) _output_with_dotted_circle (buffer);
210 }
211 processed = true;
212 break;
213
214 case HB_SCRIPT_TELUGU:
215 for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
216 {
217 bool matched = false;
218 switch (buffer->cur ().codepoint)
219 {
220 case 0x0C12u:
221 switch (buffer->cur (1).codepoint)
222 {
223 case 0x0C4Cu: case 0x0C55u:
224 matched = true;
225 break;
226 }
227 break;
228 case 0x0C3Fu: case 0x0C46u: case 0x0C4Au:
229 matched = 0x0C55u == buffer->cur (1).codepoint;
230 break;
231 }
232 buffer->next_glyph ();
233 if (matched) _output_with_dotted_circle (buffer);
234 }
235 processed = true;
236 break;
237
238 case HB_SCRIPT_KANNADA:
239 for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
240 {
241 bool matched = false;
242 switch (buffer->cur ().codepoint)
243 {
244 case 0x0C89u: case 0x0C8Bu:
245 matched = 0x0CBEu == buffer->cur (1).codepoint;
246 break;
247 case 0x0C92u:
248 matched = 0x0CCCu == buffer->cur (1).codepoint;
249 break;
250 }
251 buffer->next_glyph ();
252 if (matched) _output_with_dotted_circle (buffer);
253 }
254 processed = true;
255 break;
256
257 case HB_SCRIPT_MALAYALAM:
258 for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
259 {
260 bool matched = false;
261 switch (buffer->cur ().codepoint)
262 {
263 case 0x0D07u: case 0x0D09u:
264 matched = 0x0D57u == buffer->cur (1).codepoint;
265 break;
266 case 0x0D0Eu:
267 matched = 0x0D46u == buffer->cur (1).codepoint;
268 break;
269 case 0x0D12u:
270 switch (buffer->cur (1).codepoint)
271 {
272 case 0x0D3Eu: case 0x0D57u:
273 matched = true;
274 break;
275 }
276 break;
277 }
278 buffer->next_glyph ();
279 if (matched) _output_with_dotted_circle (buffer);
280 }
281 processed = true;
282 break;
283
284 case HB_SCRIPT_SINHALA:
285 for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
286 {
287 bool matched = false;
288 switch (buffer->cur ().codepoint)
289 {
290 case 0x0D85u:
291 switch (buffer->cur (1).codepoint)
292 {
293 case 0x0DCFu: case 0x0DD0u: case 0x0DD1u:
294 matched = true;
295 break;
296 }
297 break;
298 case 0x0D8Bu: case 0x0D8Fu: case 0x0D94u:
299 matched = 0x0DDFu == buffer->cur (1).codepoint;
300 break;
301 case 0x0D8Du:
302 matched = 0x0DD8u == buffer->cur (1).codepoint;
303 break;
304 case 0x0D91u:
305 switch (buffer->cur (1).codepoint)
306 {
307 case 0x0DCAu: case 0x0DD9u: case 0x0DDAu: case 0x0DDCu:
308 case 0x0DDDu:
309 matched = true;
310 break;
311 }
312 break;
313 }
314 buffer->next_glyph ();
315 if (matched) _output_with_dotted_circle (buffer);
316 }
317 processed = true;
318 break;
319
320 case HB_SCRIPT_BRAHMI:
321 for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
322 {
323 bool matched = false;
324 switch (buffer->cur ().codepoint)
325 {
326 case 0x11005u:
327 matched = 0x11038u == buffer->cur (1).codepoint;
328 break;
329 case 0x1100Bu:
330 matched = 0x1103Eu == buffer->cur (1).codepoint;
331 break;
332 case 0x1100Fu:
333 matched = 0x11042u == buffer->cur (1).codepoint;
334 break;
335 }
336 buffer->next_glyph ();
337 if (matched) _output_with_dotted_circle (buffer);
338 }
339 processed = true;
340 break;
341
342 case HB_SCRIPT_KHUDAWADI:
343 for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
344 {
345 bool matched = false;
346 switch (buffer->cur ().codepoint)
347 {
348 case 0x112B0u:
349 switch (buffer->cur (1).codepoint)
350 {
351 case 0x112E0u: case 0x112E5u: case 0x112E6u: case 0x112E7u:
352 case 0x112E8u:
353 matched = true;
354 break;
355 }
356 break;
357 }
358 buffer->next_glyph ();
359 if (matched) _output_with_dotted_circle (buffer);
360 }
361 processed = true;
362 break;
363
364 case HB_SCRIPT_TIRHUTA:
365 for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
366 {
367 bool matched = false;
368 switch (buffer->cur ().codepoint)
369 {
370 case 0x11481u:
371 matched = 0x114B0u == buffer->cur (1).codepoint;
372 break;
373 case 0x1148Bu: case 0x1148Du:
374 matched = 0x114BAu == buffer->cur (1).codepoint;
375 break;
376 case 0x114AAu:
377 switch (buffer->cur (1).codepoint)
378 {
379 case 0x114B5u: case 0x114B6u:
380 matched = true;
381 break;
382 }
383 break;
384 }
385 buffer->next_glyph ();
386 if (matched) _output_with_dotted_circle (buffer);
387 }
388 processed = true;
389 break;
390
391 case HB_SCRIPT_MODI:
392 for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
393 {
394 bool matched = false;
395 switch (buffer->cur ().codepoint)
396 {
397 case 0x11600u: case 0x11601u:
398 switch (buffer->cur (1).codepoint)
399 {
400 case 0x11639u: case 0x1163Au:
401 matched = true;
402 break;
403 }
404 break;
405 }
406 buffer->next_glyph ();
407 if (matched) _output_with_dotted_circle (buffer);
408 }
409 processed = true;
410 break;
411
412 case HB_SCRIPT_TAKRI:
413 for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
414 {
415 bool matched = false;
416 switch (buffer->cur ().codepoint)
417 {
418 case 0x11680u:
419 switch (buffer->cur (1).codepoint)
420 {
421 case 0x116ADu: case 0x116B4u: case 0x116B5u:
422 matched = true;
423 break;
424 }
425 break;
426 case 0x11686u:
427 matched = 0x116B2u == buffer->cur (1).codepoint;
428 break;
429 }
430 buffer->next_glyph ();
431 if (matched) _output_with_dotted_circle (buffer);
432 }
433 processed = true;
434 break;
435
436 default:
437 break;
438 }
439 if (processed)
440 {
441 if (buffer->idx < count)
442 buffer->next_glyph ();
443 buffer->swap_buffers ();
444 }
445}
446
447
448#endif
449/* == End of generated functions == */
450