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 == */