1/* == Start of generated functions == */
2/*
3 * The following functions are generated by running:
4 *
5 * ./gen-vowel-constraints.py ms-use/IndicShapingInvalidCluster.txt Scripts.txt
6 *
7 * on files with these headers:
8 *
9 * # IndicShapingInvalidCluster.txt
10 * # Date: 2015-03-12, 21:17:00 GMT [AG]
11 * # Date: 2019-11-08, 23:22:00 GMT [AG]
12 *
13 * # Scripts-13.0.0.txt
14 * # Date: 2020-01-22, 00:07:43 GMT
15 */
16
17#include "hb.hh"
18
19#ifndef HB_NO_OT_SHAPE
20
21#include "hb-ot-shape-complex-vowel-constraints.hh"
22
23static void
24_output_dotted_circle (hb_buffer_t *buffer)
25{
26 hb_glyph_info_t &dottedcircle = buffer->output_glyph (0x25CCu);
27 _hb_glyph_info_reset_continuation (&dottedcircle);
28}
29
30static void
31_output_with_dotted_circle (hb_buffer_t *buffer)
32{
33 _output_dotted_circle (buffer);
34 buffer->next_glyph ();
35}
36
37void
38_hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
39 hb_buffer_t *buffer,
40 hb_font_t *font HB_UNUSED)
41{
42#ifdef HB_NO_OT_SHAPE_COMPLEX_VOWEL_CONSTRAINTS
43 return;
44#endif
45 if (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE)
46 return;
47
48 /* UGLY UGLY UGLY business of adding dotted-circle in the middle of
49 * vowel-sequences that look like another vowel. Data for each script
50 * collected from the USE script development spec.
51 *
52 * https://github.com/harfbuzz/harfbuzz/issues/1019
53 */
54 bool processed = false;
55 buffer->clear_output ();
56 unsigned int count = buffer->len;
57 switch ((unsigned) buffer->props.script)
58 {
59 case HB_SCRIPT_DEVANAGARI:
60 for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
61 {
62 bool matched = false;
63 switch (buffer->cur ().codepoint)
64 {
65 case 0x0905u:
66 switch (buffer->cur (1).codepoint)
67 {
68 case 0x093Au: case 0x093Bu: case 0x093Eu: case 0x0945u:
69 case 0x0946u: case 0x0949u: case 0x094Au: case 0x094Bu:
70 case 0x094Cu: case 0x094Fu: case 0x0956u: case 0x0957u:
71 matched = true;
72 break;
73 }
74 break;
75 case 0x0906u:
76 switch (buffer->cur (1).codepoint)
77 {
78 case 0x093Au: case 0x0945u: case 0x0946u: case 0x0947u:
79 case 0x0948u:
80 matched = true;
81 break;
82 }
83 break;
84 case 0x0909u:
85 matched = 0x0941u == buffer->cur (1).codepoint;
86 break;
87 case 0x090Fu:
88 switch (buffer->cur (1).codepoint)
89 {
90 case 0x0945u: case 0x0946u: case 0x0947u:
91 matched = true;
92 break;
93 }
94 break;
95 case 0x0930u:
96 if (0x094Du == buffer->cur (1).codepoint &&
97 buffer->idx + 2 < count &&
98 0x0907u == buffer->cur (2).codepoint)
99 {
100 buffer->next_glyph ();
101 matched = true;
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_TAMIL:
215 for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
216 {
217 bool matched = false;
218 if (0x0B85u == buffer->cur ().codepoint &&
219 0x0BC2u == buffer->cur (1).codepoint)
220 {
221 matched = true;
222 }
223 buffer->next_glyph ();
224 if (matched) _output_with_dotted_circle (buffer);
225 }
226 processed = true;
227 break;
228
229 case HB_SCRIPT_TELUGU:
230 for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
231 {
232 bool matched = false;
233 switch (buffer->cur ().codepoint)
234 {
235 case 0x0C12u:
236 switch (buffer->cur (1).codepoint)
237 {
238 case 0x0C4Cu: case 0x0C55u:
239 matched = true;
240 break;
241 }
242 break;
243 case 0x0C3Fu: case 0x0C46u: case 0x0C4Au:
244 matched = 0x0C55u == buffer->cur (1).codepoint;
245 break;
246 }
247 buffer->next_glyph ();
248 if (matched) _output_with_dotted_circle (buffer);
249 }
250 processed = true;
251 break;
252
253 case HB_SCRIPT_KANNADA:
254 for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
255 {
256 bool matched = false;
257 switch (buffer->cur ().codepoint)
258 {
259 case 0x0C89u: case 0x0C8Bu:
260 matched = 0x0CBEu == buffer->cur (1).codepoint;
261 break;
262 case 0x0C92u:
263 matched = 0x0CCCu == buffer->cur (1).codepoint;
264 break;
265 }
266 buffer->next_glyph ();
267 if (matched) _output_with_dotted_circle (buffer);
268 }
269 processed = true;
270 break;
271
272 case HB_SCRIPT_MALAYALAM:
273 for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
274 {
275 bool matched = false;
276 switch (buffer->cur ().codepoint)
277 {
278 case 0x0D07u: case 0x0D09u:
279 matched = 0x0D57u == buffer->cur (1).codepoint;
280 break;
281 case 0x0D0Eu:
282 matched = 0x0D46u == buffer->cur (1).codepoint;
283 break;
284 case 0x0D12u:
285 switch (buffer->cur (1).codepoint)
286 {
287 case 0x0D3Eu: case 0x0D57u:
288 matched = true;
289 break;
290 }
291 break;
292 }
293 buffer->next_glyph ();
294 if (matched) _output_with_dotted_circle (buffer);
295 }
296 processed = true;
297 break;
298
299 case HB_SCRIPT_SINHALA:
300 for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
301 {
302 bool matched = false;
303 switch (buffer->cur ().codepoint)
304 {
305 case 0x0D85u:
306 switch (buffer->cur (1).codepoint)
307 {
308 case 0x0DCFu: case 0x0DD0u: case 0x0DD1u:
309 matched = true;
310 break;
311 }
312 break;
313 case 0x0D8Bu: case 0x0D8Fu: case 0x0D94u:
314 matched = 0x0DDFu == buffer->cur (1).codepoint;
315 break;
316 case 0x0D8Du:
317 matched = 0x0DD8u == buffer->cur (1).codepoint;
318 break;
319 case 0x0D91u:
320 switch (buffer->cur (1).codepoint)
321 {
322 case 0x0DCAu: case 0x0DD9u: case 0x0DDAu: case 0x0DDCu:
323 case 0x0DDDu:
324 matched = true;
325 break;
326 }
327 break;
328 }
329 buffer->next_glyph ();
330 if (matched) _output_with_dotted_circle (buffer);
331 }
332 processed = true;
333 break;
334
335 case HB_SCRIPT_BRAHMI:
336 for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
337 {
338 bool matched = false;
339 switch (buffer->cur ().codepoint)
340 {
341 case 0x11005u:
342 matched = 0x11038u == buffer->cur (1).codepoint;
343 break;
344 case 0x1100Bu:
345 matched = 0x1103Eu == buffer->cur (1).codepoint;
346 break;
347 case 0x1100Fu:
348 matched = 0x11042u == buffer->cur (1).codepoint;
349 break;
350 }
351 buffer->next_glyph ();
352 if (matched) _output_with_dotted_circle (buffer);
353 }
354 processed = true;
355 break;
356
357 case HB_SCRIPT_KHUDAWADI:
358 for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
359 {
360 bool matched = false;
361 switch (buffer->cur ().codepoint)
362 {
363 case 0x112B0u:
364 switch (buffer->cur (1).codepoint)
365 {
366 case 0x112E0u: case 0x112E5u: case 0x112E6u: case 0x112E7u:
367 case 0x112E8u:
368 matched = true;
369 break;
370 }
371 break;
372 }
373 buffer->next_glyph ();
374 if (matched) _output_with_dotted_circle (buffer);
375 }
376 processed = true;
377 break;
378
379 case HB_SCRIPT_TIRHUTA:
380 for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
381 {
382 bool matched = false;
383 switch (buffer->cur ().codepoint)
384 {
385 case 0x11481u:
386 matched = 0x114B0u == buffer->cur (1).codepoint;
387 break;
388 case 0x1148Bu: case 0x1148Du:
389 matched = 0x114BAu == buffer->cur (1).codepoint;
390 break;
391 case 0x114AAu:
392 switch (buffer->cur (1).codepoint)
393 {
394 case 0x114B5u: case 0x114B6u:
395 matched = true;
396 break;
397 }
398 break;
399 }
400 buffer->next_glyph ();
401 if (matched) _output_with_dotted_circle (buffer);
402 }
403 processed = true;
404 break;
405
406 case HB_SCRIPT_MODI:
407 for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
408 {
409 bool matched = false;
410 switch (buffer->cur ().codepoint)
411 {
412 case 0x11600u: case 0x11601u:
413 switch (buffer->cur (1).codepoint)
414 {
415 case 0x11639u: case 0x1163Au:
416 matched = true;
417 break;
418 }
419 break;
420 }
421 buffer->next_glyph ();
422 if (matched) _output_with_dotted_circle (buffer);
423 }
424 processed = true;
425 break;
426
427 case HB_SCRIPT_TAKRI:
428 for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
429 {
430 bool matched = false;
431 switch (buffer->cur ().codepoint)
432 {
433 case 0x11680u:
434 switch (buffer->cur (1).codepoint)
435 {
436 case 0x116ADu: case 0x116B4u: case 0x116B5u:
437 matched = true;
438 break;
439 }
440 break;
441 case 0x11686u:
442 matched = 0x116B2u == buffer->cur (1).codepoint;
443 break;
444 }
445 buffer->next_glyph ();
446 if (matched) _output_with_dotted_circle (buffer);
447 }
448 processed = true;
449 break;
450
451 default:
452 break;
453 }
454 if (processed)
455 {
456 if (buffer->idx < count)
457 buffer->next_glyph ();
458 buffer->swap_buffers ();
459 }
460}
461
462
463#endif
464/* == End of generated functions == */
465