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