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 
22 static void
_output_dotted_circle(hb_buffer_t * buffer)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 
29 static void
_output_with_dotted_circle(hb_buffer_t * buffer)30 _output_with_dotted_circle (hb_buffer_t *buffer)
31 {
32   _output_dotted_circle (buffer);
33   buffer->next_glyph ();
34 }
35 
36 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)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