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