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-14.0.0.txt
14  * # Date: 2021-07-10, 00:35:31 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 
23 static void
_output_dotted_circle(hb_buffer_t * buffer)24 _output_dotted_circle (hb_buffer_t *buffer)
25 {
26   (void) buffer->output_glyph (0x25CCu);
27   _hb_glyph_info_reset_continuation (&buffer->prev());
28 }
29 
30 static void
_output_with_dotted_circle(hb_buffer_t * buffer)31 _output_with_dotted_circle (hb_buffer_t *buffer)
32 {
33   _output_dotted_circle (buffer);
34   (void) buffer->next_glyph ();
35 }
36 
37 void
_hb_preprocess_text_vowel_constraints(const hb_ot_shape_plan_t * plan HB_UNUSED,hb_buffer_t * buffer,hb_font_t * font HB_UNUSED)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   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 	      (void) buffer->next_glyph ();
100 	      matched = true;
101 	    }
102 	    break;
103 	}
104 	(void) buffer->next_glyph ();
105 	if (matched) _output_with_dotted_circle (buffer);
106       }
107       break;
108 
109     case HB_SCRIPT_BENGALI:
110       for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
111       {
112 	bool matched = false;
113 	switch (buffer->cur ().codepoint)
114 	{
115 	  case 0x0985u:
116 	    matched = 0x09BEu == buffer->cur (1).codepoint;
117 	    break;
118 	  case 0x098Bu:
119 	    matched = 0x09C3u == buffer->cur (1).codepoint;
120 	    break;
121 	  case 0x098Cu:
122 	    matched = 0x09E2u == buffer->cur (1).codepoint;
123 	    break;
124 	}
125 	(void) buffer->next_glyph ();
126 	if (matched) _output_with_dotted_circle (buffer);
127       }
128       break;
129 
130     case HB_SCRIPT_GURMUKHI:
131       for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
132       {
133 	bool matched = false;
134 	switch (buffer->cur ().codepoint)
135 	{
136 	  case 0x0A05u:
137 	    switch (buffer->cur (1).codepoint)
138 	    {
139 	      case 0x0A3Eu: case 0x0A48u: case 0x0A4Cu:
140 		matched = true;
141 		break;
142 	    }
143 	    break;
144 	  case 0x0A72u:
145 	    switch (buffer->cur (1).codepoint)
146 	    {
147 	      case 0x0A3Fu: case 0x0A40u: case 0x0A47u:
148 		matched = true;
149 		break;
150 	    }
151 	    break;
152 	  case 0x0A73u:
153 	    switch (buffer->cur (1).codepoint)
154 	    {
155 	      case 0x0A41u: case 0x0A42u: case 0x0A4Bu:
156 		matched = true;
157 		break;
158 	    }
159 	    break;
160 	}
161 	(void) buffer->next_glyph ();
162 	if (matched) _output_with_dotted_circle (buffer);
163       }
164       break;
165 
166     case HB_SCRIPT_GUJARATI:
167       for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
168       {
169 	bool matched = false;
170 	switch (buffer->cur ().codepoint)
171 	{
172 	  case 0x0A85u:
173 	    switch (buffer->cur (1).codepoint)
174 	    {
175 	      case 0x0ABEu: case 0x0AC5u: case 0x0AC7u: case 0x0AC8u:
176 	      case 0x0AC9u: case 0x0ACBu: case 0x0ACCu:
177 		matched = true;
178 		break;
179 	    }
180 	    break;
181 	  case 0x0AC5u:
182 	    matched = 0x0ABEu == buffer->cur (1).codepoint;
183 	    break;
184 	}
185 	(void) buffer->next_glyph ();
186 	if (matched) _output_with_dotted_circle (buffer);
187       }
188       break;
189 
190     case HB_SCRIPT_ORIYA:
191       for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
192       {
193 	bool matched = false;
194 	switch (buffer->cur ().codepoint)
195 	{
196 	  case 0x0B05u:
197 	    matched = 0x0B3Eu == buffer->cur (1).codepoint;
198 	    break;
199 	  case 0x0B0Fu: case 0x0B13u:
200 	    matched = 0x0B57u == buffer->cur (1).codepoint;
201 	    break;
202 	}
203 	(void) buffer->next_glyph ();
204 	if (matched) _output_with_dotted_circle (buffer);
205       }
206       break;
207 
208     case HB_SCRIPT_TAMIL:
209       for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
210       {
211 	bool matched = false;
212 	if (0x0B85u == buffer->cur ().codepoint &&
213 	    0x0BC2u == buffer->cur (1).codepoint)
214 	{
215 	  matched = true;
216 	}
217 	(void) buffer->next_glyph ();
218 	if (matched) _output_with_dotted_circle (buffer);
219       }
220       break;
221 
222     case HB_SCRIPT_TELUGU:
223       for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
224       {
225 	bool matched = false;
226 	switch (buffer->cur ().codepoint)
227 	{
228 	  case 0x0C12u:
229 	    switch (buffer->cur (1).codepoint)
230 	    {
231 	      case 0x0C4Cu: case 0x0C55u:
232 		matched = true;
233 		break;
234 	    }
235 	    break;
236 	  case 0x0C3Fu: case 0x0C46u: case 0x0C4Au:
237 	    matched = 0x0C55u == buffer->cur (1).codepoint;
238 	    break;
239 	}
240 	(void) buffer->next_glyph ();
241 	if (matched) _output_with_dotted_circle (buffer);
242       }
243       break;
244 
245     case HB_SCRIPT_KANNADA:
246       for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
247       {
248 	bool matched = false;
249 	switch (buffer->cur ().codepoint)
250 	{
251 	  case 0x0C89u: case 0x0C8Bu:
252 	    matched = 0x0CBEu == buffer->cur (1).codepoint;
253 	    break;
254 	  case 0x0C92u:
255 	    matched = 0x0CCCu == buffer->cur (1).codepoint;
256 	    break;
257 	}
258 	(void) buffer->next_glyph ();
259 	if (matched) _output_with_dotted_circle (buffer);
260       }
261       break;
262 
263     case HB_SCRIPT_MALAYALAM:
264       for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
265       {
266 	bool matched = false;
267 	switch (buffer->cur ().codepoint)
268 	{
269 	  case 0x0D07u: case 0x0D09u:
270 	    matched = 0x0D57u == buffer->cur (1).codepoint;
271 	    break;
272 	  case 0x0D0Eu:
273 	    matched = 0x0D46u == buffer->cur (1).codepoint;
274 	    break;
275 	  case 0x0D12u:
276 	    switch (buffer->cur (1).codepoint)
277 	    {
278 	      case 0x0D3Eu: case 0x0D57u:
279 		matched = true;
280 		break;
281 	    }
282 	    break;
283 	}
284 	(void) buffer->next_glyph ();
285 	if (matched) _output_with_dotted_circle (buffer);
286       }
287       break;
288 
289     case HB_SCRIPT_SINHALA:
290       for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
291       {
292 	bool matched = false;
293 	switch (buffer->cur ().codepoint)
294 	{
295 	  case 0x0D85u:
296 	    switch (buffer->cur (1).codepoint)
297 	    {
298 	      case 0x0DCFu: case 0x0DD0u: case 0x0DD1u:
299 		matched = true;
300 		break;
301 	    }
302 	    break;
303 	  case 0x0D8Bu: case 0x0D8Fu: case 0x0D94u:
304 	    matched = 0x0DDFu == buffer->cur (1).codepoint;
305 	    break;
306 	  case 0x0D8Du:
307 	    matched = 0x0DD8u == buffer->cur (1).codepoint;
308 	    break;
309 	  case 0x0D91u:
310 	    switch (buffer->cur (1).codepoint)
311 	    {
312 	      case 0x0DCAu: case 0x0DD9u: case 0x0DDAu: case 0x0DDCu:
313 	      case 0x0DDDu: case 0x0DDEu:
314 		matched = true;
315 		break;
316 	    }
317 	    break;
318 	}
319 	(void) buffer->next_glyph ();
320 	if (matched) _output_with_dotted_circle (buffer);
321       }
322       break;
323 
324     case HB_SCRIPT_BRAHMI:
325       for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
326       {
327 	bool matched = false;
328 	switch (buffer->cur ().codepoint)
329 	{
330 	  case 0x11005u:
331 	    matched = 0x11038u == buffer->cur (1).codepoint;
332 	    break;
333 	  case 0x1100Bu:
334 	    matched = 0x1103Eu == buffer->cur (1).codepoint;
335 	    break;
336 	  case 0x1100Fu:
337 	    matched = 0x11042u == buffer->cur (1).codepoint;
338 	    break;
339 	}
340 	(void) buffer->next_glyph ();
341 	if (matched) _output_with_dotted_circle (buffer);
342       }
343       break;
344 
345     case HB_SCRIPT_KHUDAWADI:
346       for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
347       {
348 	bool matched = false;
349 	switch (buffer->cur ().codepoint)
350 	{
351 	  case 0x112B0u:
352 	    switch (buffer->cur (1).codepoint)
353 	    {
354 	      case 0x112E0u: case 0x112E5u: case 0x112E6u: case 0x112E7u:
355 	      case 0x112E8u:
356 		matched = true;
357 		break;
358 	    }
359 	    break;
360 	}
361 	(void) buffer->next_glyph ();
362 	if (matched) _output_with_dotted_circle (buffer);
363       }
364       break;
365 
366     case HB_SCRIPT_TIRHUTA:
367       for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
368       {
369 	bool matched = false;
370 	switch (buffer->cur ().codepoint)
371 	{
372 	  case 0x11481u:
373 	    matched = 0x114B0u == buffer->cur (1).codepoint;
374 	    break;
375 	  case 0x1148Bu: case 0x1148Du:
376 	    matched = 0x114BAu == buffer->cur (1).codepoint;
377 	    break;
378 	  case 0x114AAu:
379 	    switch (buffer->cur (1).codepoint)
380 	    {
381 	      case 0x114B5u: case 0x114B6u:
382 		matched = true;
383 		break;
384 	    }
385 	    break;
386 	}
387 	(void) buffer->next_glyph ();
388 	if (matched) _output_with_dotted_circle (buffer);
389       }
390       break;
391 
392     case HB_SCRIPT_MODI:
393       for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
394       {
395 	bool matched = false;
396 	switch (buffer->cur ().codepoint)
397 	{
398 	  case 0x11600u: case 0x11601u:
399 	    switch (buffer->cur (1).codepoint)
400 	    {
401 	      case 0x11639u: case 0x1163Au:
402 		matched = true;
403 		break;
404 	    }
405 	    break;
406 	}
407 	(void) buffer->next_glyph ();
408 	if (matched) _output_with_dotted_circle (buffer);
409       }
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 	(void) buffer->next_glyph ();
431 	if (matched) _output_with_dotted_circle (buffer);
432       }
433       break;
434 
435     default:
436       break;
437   }
438   buffer->sync ();
439 }
440 
441 
442 #endif
443 /* == End of generated functions == */
444