tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

afadjust.c (58791B)


      1 /****************************************************************************
      2 *
      3 * afadjust.c
      4 *
      5 *   Auto-fitter routines to adjust components based on charcode (body).
      6 *
      7 * Copyright (C) 2023-2025 by
      8 * David Turner, Robert Wilhelm, and Werner Lemberg.
      9 *
     10 * Written by Craig White <gerzytet@gmail.com>.
     11 *
     12 * This file is part of the FreeType project, and may only be used,
     13 * modified, and distributed under the terms of the FreeType project
     14 * license, LICENSE.TXT.  By continuing to use, modify, or distribute
     15 * this file you indicate that you have read the license and
     16 * understand and accept it fully.
     17 *
     18 */
     19 
     20 #include "afadjust.h"
     21 #ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
     22 #  include "afgsub.h"
     23 #endif
     24 
     25 #include <freetype/freetype.h>
     26 #include <freetype/internal/ftobjs.h>
     27 #include <freetype/internal/ftmemory.h>
     28 #include <freetype/internal/ftdebug.h>
     29 
     30 #define AF_ADJUSTMENT_DATABASE_LENGTH           \
     31          ( sizeof ( adjustment_database ) /    \
     32            sizeof ( adjustment_database[0] ) )
     33 
     34 #undef  FT_COMPONENT
     35 #define FT_COMPONENT  afadjust
     36 
     37 
     38  typedef struct  AF_AdjustmentDatabaseEntry_
     39  {
     40    FT_UInt32  codepoint;
     41    FT_UInt32  flags;
     42 
     43  } AF_AdjustmentDatabaseEntry;
     44 
     45 
     46  /*
     47    All entries in this list must be sorted by ascending Unicode code
     48    points.  The table entries are 3 numbers consisting of:
     49 
     50    - Unicode code point.
     51    - The vertical adjustment type.  This should be a combination of the
     52      AF_ADJUST_XXX and AF_IGNORE_XXX macros.
     53  */
     54  static AF_AdjustmentDatabaseEntry  adjustment_database[] =
     55  {
     56    /* C0 Controls and Basic Latin */
     57    { 0x21,  AF_ADJUST_UP | AF_ADJUST_NO_HEIGHT_CHECK }, /* ! */
     58    { 0x51,  AF_IGNORE_CAPITAL_BOTTOM } , /* Q */
     59    { 0x3F,  AF_ADJUST_UP | AF_ADJUST_NO_HEIGHT_CHECK }, /* ? */
     60    { 0x69,  AF_ADJUST_UP }, /* i */
     61    { 0x6A,  AF_ADJUST_UP }, /* j */
     62 #if 0
     63    /* XXX TODO */
     64    { 0x7E,  AF_ADJUST_TILDE_TOP }, /* ~ */
     65 #endif
     66 
     67    /* C1 Controls and Latin-1 Supplement */
     68    { 0xA1,  AF_ADJUST_UP }, /* ¡ */
     69    { 0xA6,  AF_ADJUST_UP | AF_ADJUST_NO_HEIGHT_CHECK }, /* ¦ */
     70    { 0xAA,  AF_ADJUST_UP }, /* ª */
     71    { 0xBA,  AF_ADJUST_UP }, /* º */
     72    { 0xBF,  AF_ADJUST_UP }, /* ¿ */
     73 
     74    { 0xC0,  AF_ADJUST_UP }, /* À */
     75    { 0xC1,  AF_ADJUST_UP }, /* Á */
     76    { 0xC2,  AF_ADJUST_UP }, /* Â */
     77    { 0xC3,  AF_ADJUST_UP | AF_ADJUST_TILDE_TOP }, /* Ã */
     78    { 0xC4,  AF_ADJUST_UP }, /* Ä */
     79    { 0xC5,  AF_ADJUST_UP }, /* Å */
     80    { 0xC7,  AF_IGNORE_CAPITAL_BOTTOM }, /* Ç */
     81    { 0xC8,  AF_ADJUST_UP }, /* È */
     82    { 0xC9,  AF_ADJUST_UP }, /* É */
     83    { 0xCA,  AF_ADJUST_UP }, /* Ê */
     84    { 0xCB,  AF_ADJUST_UP }, /* Ë */
     85    { 0xCC,  AF_ADJUST_UP }, /* Ì */
     86    { 0xCD,  AF_ADJUST_UP }, /* Í */
     87    { 0xCE,  AF_ADJUST_UP }, /* Î */
     88    { 0xCF,  AF_ADJUST_UP }, /* Ï */
     89 
     90    { 0xD1,  AF_ADJUST_UP | AF_ADJUST_TILDE_TOP }, /* Ñ */
     91    { 0xD2,  AF_ADJUST_UP }, /* Ò */
     92    { 0xD3,  AF_ADJUST_UP }, /* Ó */
     93    { 0xD4,  AF_ADJUST_UP }, /* Ô */
     94    { 0xD5,  AF_ADJUST_UP | AF_ADJUST_TILDE_TOP }, /* Õ */
     95    { 0xD6,  AF_ADJUST_UP }, /* Ö */
     96    { 0xD8,  AF_IGNORE_CAPITAL_TOP | AF_IGNORE_CAPITAL_BOTTOM }, /* Ø */
     97    { 0xD9,  AF_ADJUST_UP }, /* Ù */
     98    { 0xDA,  AF_ADJUST_UP }, /* Ú */
     99    { 0xDB,  AF_ADJUST_UP }, /* Û */
    100    { 0xDC,  AF_ADJUST_UP }, /* Ü */
    101    { 0xDD,  AF_ADJUST_UP }, /* Ý */
    102 
    103    { 0xE0,  AF_ADJUST_UP }, /* à */
    104    { 0xE1,  AF_ADJUST_UP }, /* á */
    105    { 0xE2,  AF_ADJUST_UP }, /* â */
    106    { 0xE3,  AF_ADJUST_UP | AF_ADJUST_TILDE_TOP }, /* ã */
    107    { 0xE4,  AF_ADJUST_UP }, /* ä */
    108    { 0xE5,  AF_ADJUST_UP }, /* å */
    109    { 0xE7,  AF_IGNORE_SMALL_BOTTOM }, /* ç */
    110    { 0xE8,  AF_ADJUST_UP }, /* è */
    111    { 0xE9,  AF_ADJUST_UP }, /* é */
    112    { 0xEA,  AF_ADJUST_UP }, /* ê */
    113    { 0xEB,  AF_ADJUST_UP }, /* ë */
    114    { 0xEC,  AF_ADJUST_UP }, /* ì */
    115    { 0xED,  AF_ADJUST_UP }, /* í */
    116    { 0xEE,  AF_ADJUST_UP }, /* î */
    117    { 0xEF,  AF_ADJUST_UP }, /* ï */
    118 
    119    { 0xF1,  AF_ADJUST_UP | AF_ADJUST_TILDE_TOP }, /* ñ */
    120    { 0xF2,  AF_ADJUST_UP }, /* ò */
    121    { 0xF3,  AF_ADJUST_UP }, /* ó */
    122    { 0xF4,  AF_ADJUST_UP }, /* ô */
    123    { 0xF5,  AF_ADJUST_UP | AF_ADJUST_TILDE_TOP }, /* õ */
    124    { 0xF6,  AF_ADJUST_UP }, /* ö */
    125    { 0xF8,  AF_IGNORE_SMALL_TOP | AF_IGNORE_SMALL_BOTTOM }, /* ø */
    126    { 0xF9,  AF_ADJUST_UP }, /* ù */
    127    { 0xFA,  AF_ADJUST_UP }, /* ú */
    128    { 0xFB,  AF_ADJUST_UP }, /* û */
    129    { 0xFC,  AF_ADJUST_UP }, /* ü */
    130    { 0xFD,  AF_ADJUST_UP }, /* ý */
    131    { 0xFF,  AF_ADJUST_UP }, /* ÿ */
    132 
    133    /* Latin Extended-A */
    134    { 0x100, AF_ADJUST_UP }, /* Ā */
    135    { 0x101, AF_ADJUST_UP }, /* ā */
    136    { 0x102, AF_ADJUST_UP }, /* Ă */
    137    { 0x103, AF_ADJUST_UP }, /* ă */
    138    { 0x104, AF_IGNORE_CAPITAL_BOTTOM }, /* Ą */
    139    { 0x105, AF_IGNORE_SMALL_BOTTOM }, /* ą */
    140    { 0x106, AF_ADJUST_UP }, /* Ć */
    141    { 0x107, AF_ADJUST_UP }, /* ć */
    142    { 0x108, AF_ADJUST_UP }, /* Ĉ */
    143    { 0x109, AF_ADJUST_UP }, /* ĉ */
    144    { 0x10A, AF_ADJUST_UP }, /* Ċ */
    145    { 0x10B, AF_ADJUST_UP }, /* ċ */
    146    { 0x10C, AF_ADJUST_UP }, /* Č */
    147    { 0x10D, AF_ADJUST_UP }, /* č */
    148    { 0x10E, AF_ADJUST_UP }, /* Ď */
    149 
    150    { 0x112, AF_ADJUST_UP }, /* Ē */
    151    { 0x113, AF_ADJUST_UP }, /* ē */
    152    { 0x114, AF_ADJUST_UP }, /* Ĕ */
    153    { 0x115, AF_ADJUST_UP }, /* ĕ */
    154    { 0x116, AF_ADJUST_UP }, /* Ė */
    155    { 0x117, AF_ADJUST_UP }, /* ė */
    156    { 0x118, AF_IGNORE_CAPITAL_BOTTOM }, /* Ę */
    157    { 0x119, AF_IGNORE_SMALL_BOTTOM }, /* ę */
    158    { 0x11A, AF_ADJUST_UP }, /* Ě */
    159    { 0x11B, AF_ADJUST_UP }, /* ě */
    160    { 0x11C, AF_ADJUST_UP }, /* Ĝ */
    161    { 0x11D, AF_ADJUST_UP }, /* ĝ */
    162    { 0x11E, AF_ADJUST_UP }, /* Ğ */
    163    { 0x11F, AF_ADJUST_UP }, /* ğ */
    164 
    165    { 0x120, AF_ADJUST_UP }, /* Ġ */
    166    { 0x121, AF_ADJUST_UP }, /* ġ */
    167    { 0x122, AF_ADJUST_DOWN }, /* Ģ */
    168    { 0x123, AF_ADJUST_UP }, /* ģ */
    169    { 0x124, AF_ADJUST_UP }, /* Ĥ */
    170    { 0x125, AF_ADJUST_UP }, /* ĥ */
    171    { 0x128, AF_ADJUST_UP | AF_ADJUST_TILDE_TOP }, /* Ĩ */
    172    { 0x129, AF_ADJUST_UP | AF_ADJUST_TILDE_TOP }, /* ĩ */
    173    { 0x12A, AF_ADJUST_UP }, /* Ī */
    174    { 0x12B, AF_ADJUST_UP }, /* ī */
    175    { 0x12C, AF_ADJUST_UP }, /* Ĭ */
    176    { 0x12D, AF_ADJUST_UP }, /* ĭ */
    177    { 0x12E, AF_IGNORE_CAPITAL_BOTTOM }, /* Į */
    178    { 0x12F, AF_ADJUST_UP | AF_IGNORE_SMALL_BOTTOM }, /* į */
    179 
    180    { 0x130, AF_ADJUST_UP }, /* İ */
    181    { 0x133, AF_ADJUST_UP }, /* ij */
    182    { 0x134, AF_ADJUST_UP }, /* Ĵ */
    183    { 0x135, AF_ADJUST_UP }, /* ĵ */
    184    { 0x136, AF_ADJUST_DOWN }, /* Ķ */
    185    { 0x137, AF_ADJUST_DOWN }, /* ķ */
    186    { 0x139, AF_ADJUST_UP }, /* Ĺ */
    187    { 0x13A, AF_ADJUST_UP }, /* ĺ */
    188    { 0x13B, AF_ADJUST_DOWN }, /* Ļ */
    189    { 0x13C, AF_ADJUST_DOWN }, /* ļ */
    190 
    191    { 0x143, AF_ADJUST_UP }, /* Ń */
    192    { 0x144, AF_ADJUST_UP }, /* ń */
    193    { 0x145, AF_ADJUST_DOWN }, /* Ņ */
    194    { 0x146, AF_ADJUST_DOWN }, /* ņ */
    195    { 0x147, AF_ADJUST_UP }, /* Ň */
    196    { 0x148, AF_ADJUST_UP }, /* ň */
    197    { 0x14C, AF_ADJUST_UP }, /* Ō */
    198    { 0x14D, AF_ADJUST_UP }, /* ō */
    199    { 0x14E, AF_ADJUST_UP }, /* Ŏ */
    200    { 0x14F, AF_ADJUST_UP }, /* ŏ */
    201 
    202    { 0x150, AF_ADJUST_UP }, /* Ő */
    203    { 0x151, AF_ADJUST_UP }, /* ő */
    204    { 0x154, AF_ADJUST_UP }, /* Ŕ */
    205    { 0x155, AF_ADJUST_UP }, /* ŕ */
    206    { 0x156, AF_ADJUST_DOWN }, /* Ŗ */
    207    { 0x157, AF_ADJUST_DOWN }, /* ŗ */
    208    { 0x158, AF_ADJUST_UP }, /* Ř */
    209    { 0x159, AF_ADJUST_UP }, /* ř */
    210    { 0x15A, AF_ADJUST_UP }, /* Ś */
    211    { 0x15B, AF_ADJUST_UP }, /* ś */
    212    { 0x15C, AF_ADJUST_UP }, /* Ŝ */
    213    { 0x15D, AF_ADJUST_UP }, /* ŝ */
    214    { 0x15E, AF_IGNORE_CAPITAL_BOTTOM }, /* Ş */
    215    { 0x15F, AF_IGNORE_SMALL_BOTTOM }, /* ş */
    216 
    217    { 0x160, AF_ADJUST_UP }, /* Š */
    218    { 0x161, AF_ADJUST_UP }, /* š */
    219    { 0x162, AF_IGNORE_CAPITAL_BOTTOM }, /* Ţ */
    220    { 0x163, AF_IGNORE_SMALL_BOTTOM }, /* ţ */
    221    { 0x164, AF_ADJUST_UP }, /* Ť */
    222    { 0x168, AF_ADJUST_UP | AF_ADJUST_TILDE_TOP }, /* Ũ */
    223    { 0x169, AF_ADJUST_UP | AF_ADJUST_TILDE_TOP }, /* ũ */
    224    { 0x16A, AF_ADJUST_UP }, /* Ū */
    225    { 0x16B, AF_ADJUST_UP }, /* ū */
    226    { 0x16C, AF_ADJUST_UP }, /* Ŭ */
    227    { 0x16D, AF_ADJUST_UP }, /* ŭ */
    228    { 0x16E, AF_ADJUST_UP }, /* Ů */
    229    { 0x16F, AF_ADJUST_UP }, /* ů */
    230 
    231    { 0x170, AF_ADJUST_UP }, /* Ű */
    232    { 0x171, AF_ADJUST_UP }, /* ű */
    233    { 0x172, AF_IGNORE_CAPITAL_BOTTOM }, /* Ų */
    234    { 0x173, AF_IGNORE_SMALL_BOTTOM }, /* ų */
    235    { 0x174, AF_ADJUST_UP }, /* Ŵ */
    236    { 0x175, AF_ADJUST_UP }, /* ŵ */
    237    { 0x176, AF_ADJUST_UP }, /* Ŷ */
    238    { 0x177, AF_ADJUST_UP }, /* ŷ */
    239    { 0x178, AF_ADJUST_UP }, /* Ÿ */
    240    { 0x179, AF_ADJUST_UP }, /* Ź */
    241    { 0x17A, AF_ADJUST_UP }, /* ź */
    242    { 0x17B, AF_ADJUST_UP }, /* Ż */
    243    { 0x17C, AF_ADJUST_UP }, /* ż */
    244    { 0x17D, AF_ADJUST_UP }, /* Ž */
    245    { 0x17E, AF_ADJUST_UP }, /* ž */
    246 
    247    /* Latin Extended-B */
    248    { 0x187, AF_IGNORE_CAPITAL_TOP }, /* Ƈ */
    249    { 0x188, AF_IGNORE_SMALL_TOP }, /* ƈ */
    250 
    251    { 0x1A0, AF_IGNORE_CAPITAL_TOP }, /* Ơ */
    252    { 0x1A1, AF_IGNORE_SMALL_TOP }, /* ơ */
    253    { 0x1A5, AF_IGNORE_SMALL_TOP }, /* ƥ */
    254    { 0x1AB, AF_IGNORE_SMALL_BOTTOM }, /* ƫ */
    255    { 0x1AE, AF_IGNORE_CAPITAL_BOTTOM }, /* Ʈ */
    256    { 0x1AF, AF_IGNORE_CAPITAL_TOP }, /* Ư */
    257 
    258    { 0x1B0, AF_IGNORE_SMALL_TOP }, /* ư */
    259    { 0x1B4, AF_IGNORE_SMALL_TOP }, /* ƴ */
    260 
    261    { 0x1C3, AF_ADJUST_UP | AF_ADJUST_NO_HEIGHT_CHECK }, /* ǃ */
    262    { 0x1C4, AF_ADJUST_UP }, /* DŽ */
    263 #if 0
    264    { 0x1C5, AF_ADJUST_UP }, /* Dž */
    265    { 0x1C6, AF_ADJUST_UP }, /* dž */
    266    { 0x1C8, AF_ADJUST_UP }, /* Lj */
    267    { 0x1C9, AF_ADJUST_UP }, /* lj */
    268    { 0x1CB, AF_ADJUST_UP }, /* Nj */
    269 #endif
    270    { 0x1CC, AF_ADJUST_UP }, /* nj */
    271    { 0x1CD, AF_ADJUST_UP }, /* Ǎ */
    272    { 0x1CE, AF_ADJUST_UP }, /* ǎ */
    273    { 0x1CF, AF_ADJUST_UP }, /* Ǐ */
    274 
    275    { 0x1D0, AF_ADJUST_UP }, /* ǐ */
    276    { 0x1D1, AF_ADJUST_UP }, /* Ǒ */
    277    { 0x1D2, AF_ADJUST_UP }, /* ǒ */
    278    { 0x1D3, AF_ADJUST_UP }, /* Ǔ */
    279    { 0x1D4, AF_ADJUST_UP }, /* ǔ */
    280    { 0x1D5, AF_ADJUST_UP2 }, /* Ǖ */
    281    { 0x1D6, AF_ADJUST_UP2 }, /* ǖ */
    282    { 0x1D7, AF_ADJUST_UP2 }, /* Ǘ */
    283    { 0x1D8, AF_ADJUST_UP2 }, /* ǘ */
    284    { 0x1D9, AF_ADJUST_UP2 }, /* Ǚ */
    285    { 0x1DA, AF_ADJUST_UP2 }, /* ǚ */
    286    { 0x1DB, AF_ADJUST_UP2 }, /* Ǜ */
    287    { 0x1DC, AF_ADJUST_UP2 }, /* ǜ */
    288    { 0x1DE, AF_ADJUST_UP2 }, /* Ǟ */
    289    { 0x1DF, AF_ADJUST_UP2 }, /* ǟ */
    290 
    291    { 0x1E0, AF_ADJUST_UP2 }, /* Ǡ */
    292    { 0x1E1, AF_ADJUST_UP2 }, /* ǡ */
    293    { 0x1E2, AF_ADJUST_UP }, /* Ǣ */
    294    { 0x1E3, AF_ADJUST_UP }, /* ǣ */
    295    { 0x1E6, AF_ADJUST_UP }, /* Ǧ */
    296    { 0x1E7, AF_ADJUST_UP }, /* ǧ */
    297    { 0x1E8, AF_ADJUST_UP }, /* Ǩ */
    298    { 0x1E9, AF_ADJUST_UP }, /* ǩ */
    299    { 0x1EA, AF_IGNORE_CAPITAL_BOTTOM }, /* Ǫ */
    300    { 0x1EB, AF_IGNORE_SMALL_BOTTOM }, /* ǫ */
    301    { 0x1EC, AF_ADJUST_UP | AF_IGNORE_CAPITAL_BOTTOM }, /* Ǭ */
    302    { 0x1ED, AF_ADJUST_UP | AF_IGNORE_SMALL_BOTTOM }, /* ǭ */
    303    { 0x1EE, AF_ADJUST_UP }, /* Ǯ */
    304    { 0x1EF, AF_ADJUST_UP }, /* ǯ */
    305 
    306    { 0x1F0, AF_ADJUST_UP }, /* ǰ */
    307    { 0x1F4, AF_ADJUST_UP }, /* Ǵ */
    308    { 0x1F5, AF_ADJUST_UP }, /* ǵ */
    309    { 0x1F8, AF_ADJUST_UP }, /* Ǹ */
    310    { 0x1F9, AF_ADJUST_UP }, /* ǹ */
    311    { 0x1FA, AF_ADJUST_UP2 }, /* Ǻ */
    312    { 0x1FB, AF_ADJUST_UP2 }, /* ǻ */
    313    { 0x1FC, AF_ADJUST_UP }, /* Ǽ */
    314    { 0x1FD, AF_ADJUST_UP }, /* ǽ */
    315    { 0x1FE, AF_ADJUST_UP }, /* Ǿ */
    316    { 0x1FF, AF_ADJUST_UP }, /* ǿ */
    317 
    318    { 0x200, AF_ADJUST_UP }, /* Ȁ */
    319    { 0x201, AF_ADJUST_UP }, /* ȁ */
    320    { 0x202, AF_ADJUST_UP }, /* Ȃ */
    321    { 0x203, AF_ADJUST_UP }, /* ȃ */
    322    { 0x204, AF_ADJUST_UP }, /* Ȅ */
    323    { 0x205, AF_ADJUST_UP }, /* ȅ */
    324    { 0x206, AF_ADJUST_UP }, /* Ȇ */
    325    { 0x207, AF_ADJUST_UP }, /* ȇ */
    326    { 0x208, AF_ADJUST_UP }, /* Ȉ */
    327    { 0x209, AF_ADJUST_UP }, /* ȉ */
    328    { 0x20A, AF_ADJUST_UP }, /* Ȋ */
    329    { 0x20B, AF_ADJUST_UP }, /* ȋ */
    330    { 0x20C, AF_ADJUST_UP }, /* Ȍ */
    331    { 0x20D, AF_ADJUST_UP }, /* ȍ */
    332    { 0x20E, AF_ADJUST_UP }, /* Ȏ */
    333    { 0x20F, AF_ADJUST_UP }, /* ȏ */
    334 
    335    { 0x210, AF_ADJUST_UP }, /* Ȑ */
    336    { 0x211, AF_ADJUST_UP }, /* ȑ */
    337    { 0x212, AF_ADJUST_UP }, /* Ȓ */
    338    { 0x213, AF_ADJUST_UP }, /* ȓ */
    339    { 0x214, AF_ADJUST_UP }, /* Ȕ */
    340    { 0x215, AF_ADJUST_UP }, /* ȕ */
    341    { 0x216, AF_ADJUST_UP }, /* Ȗ */
    342    { 0x217, AF_ADJUST_UP }, /* ȗ */
    343    { 0x218, AF_ADJUST_DOWN }, /* Ș */
    344    { 0x219, AF_ADJUST_DOWN }, /* ș */
    345    { 0x21A, AF_ADJUST_DOWN }, /* Ț */
    346    { 0x21B, AF_ADJUST_DOWN }, /* ț */
    347    { 0x21E, AF_ADJUST_UP }, /* Ȟ */
    348    { 0x21F, AF_ADJUST_UP }, /* ȟ */
    349 
    350    { 0x224, AF_IGNORE_CAPITAL_BOTTOM }, /* Ȥ */
    351    { 0x225, AF_IGNORE_SMALL_BOTTOM }, /* ȥ */
    352    { 0x226, AF_ADJUST_UP }, /* Ȧ */
    353    { 0x227, AF_ADJUST_UP }, /* ȧ */
    354    { 0x228, AF_IGNORE_CAPITAL_BOTTOM }, /* Ȩ */
    355    { 0x229, AF_IGNORE_SMALL_BOTTOM }, /* ȩ */
    356    { 0x22A, AF_ADJUST_UP2 }, /* Ȫ */
    357    { 0x22B, AF_ADJUST_UP2 }, /* ȫ */
    358    { 0x22C, AF_ADJUST_UP2 }, /* Ȭ */
    359    { 0x22D, AF_ADJUST_UP2 }, /* ȭ */
    360    { 0x22E, AF_ADJUST_UP }, /* Ȯ */
    361    { 0x22F, AF_ADJUST_UP }, /* ȯ */
    362 
    363    { 0x230, AF_ADJUST_UP2 }, /* Ȱ */
    364    { 0x231, AF_ADJUST_UP2 }, /* ȱ */
    365    { 0x232, AF_ADJUST_UP }, /* Ȳ */
    366    { 0x233, AF_ADJUST_UP }, /* ȳ */
    367    { 0x23A, AF_IGNORE_CAPITAL_TOP | AF_IGNORE_CAPITAL_BOTTOM }, /* Ⱥ */
    368    { 0x23B, AF_IGNORE_CAPITAL_TOP | AF_IGNORE_CAPITAL_BOTTOM }, /* Ȼ */
    369    { 0x23F, AF_IGNORE_SMALL_BOTTOM }, /* ȿ */
    370 
    371    { 0x240, AF_IGNORE_SMALL_BOTTOM }, /* ɀ */
    372    { 0x249, AF_ADJUST_UP }, /* ɉ */
    373 
    374    /* IPA Extensions */
    375    { 0x256, AF_IGNORE_SMALL_BOTTOM }, /* ɖ */
    376 
    377    { 0x260, AF_IGNORE_SMALL_TOP }, /* ɠ */
    378    { 0x267, AF_IGNORE_SMALL_BOTTOM }, /* ɧ */
    379    { 0x268, AF_ADJUST_UP }, /* ɨ */
    380 
    381    { 0x272, AF_IGNORE_SMALL_BOTTOM }, /* ɲ */
    382    { 0x273, AF_IGNORE_SMALL_BOTTOM }, /* ɳ */
    383    { 0x27B, AF_IGNORE_SMALL_BOTTOM }, /* ɻ */
    384    { 0x27D, AF_IGNORE_SMALL_BOTTOM }, /* ɽ */
    385 
    386    { 0x282, AF_IGNORE_SMALL_BOTTOM }, /* ʂ */
    387    { 0x288, AF_IGNORE_SMALL_BOTTOM }, /* ʈ */
    388 
    389    { 0x290, AF_IGNORE_SMALL_BOTTOM }, /* ʐ */
    390    { 0x29B, AF_IGNORE_SMALL_TOP }, /* ʛ */
    391 
    392    { 0x2A0, AF_IGNORE_SMALL_TOP }, /* ʠ */
    393 
    394    /* Spacing Modifier Letters */
    395    { 0x2B2, AF_ADJUST_UP }, /* ʲ */
    396    { 0x2B5, AF_IGNORE_SMALL_BOTTOM }, /* ʵ */
    397 
    398    /* Greek and Coptic */
    399    { 0x390, AF_ADJUST_UP2 }, /* ΐ */
    400 
    401    { 0x3AA, AF_ADJUST_UP }, /* Ϊ */
    402    { 0x3AB, AF_ADJUST_UP }, /* Ϋ */
    403    { 0x3AC, AF_ADJUST_UP }, /* ά */
    404    { 0x3AD, AF_ADJUST_UP }, /* έ */
    405    { 0x3AE, AF_ADJUST_UP }, /* ή */
    406    { 0x3AF, AF_ADJUST_UP }, /* ί */
    407 
    408    { 0x3B0, AF_ADJUST_UP2 }, /* ΰ */
    409 
    410    { 0x3CA, AF_ADJUST_UP }, /* ϊ */
    411    { 0x3CB, AF_ADJUST_UP }, /* ϋ */
    412    { 0x3CC, AF_ADJUST_UP }, /* ό */
    413    { 0x3CD, AF_ADJUST_UP }, /* ύ */
    414    { 0x3CE, AF_ADJUST_UP }, /* ώ */
    415    { 0x3CF, AF_IGNORE_CAPITAL_BOTTOM }, /* Ϗ */
    416 
    417    { 0x3D4, AF_ADJUST_UP }, /* ϔ */
    418    { 0x3D7, AF_IGNORE_SMALL_BOTTOM }, /* ϗ */
    419    { 0x3D9, AF_IGNORE_SMALL_BOTTOM }, /* ϙ */
    420 
    421    { 0x3E2, AF_IGNORE_CAPITAL_BOTTOM }, /* Ϣ */
    422    { 0x3E3, AF_IGNORE_SMALL_BOTTOM }, /* ϣ */
    423 
    424    { 0x3F3, AF_ADJUST_UP }, /* ϳ */
    425 
    426    /* Cyrillic */
    427    { 0x400, AF_ADJUST_UP }, /* Ѐ */
    428    { 0x401, AF_ADJUST_UP }, /* Ё */
    429    { 0x403, AF_ADJUST_UP }, /* Ѓ */
    430    { 0x407, AF_ADJUST_UP }, /* Ї */
    431    { 0x40C, AF_ADJUST_UP }, /* Ќ */
    432    { 0x40D, AF_ADJUST_UP }, /* Ѝ */
    433    { 0x40E, AF_ADJUST_UP }, /* Ў */
    434    { 0x40F, AF_IGNORE_CAPITAL_BOTTOM }, /* Џ */
    435 
    436    { 0x419, AF_ADJUST_UP }, /* Й */
    437 
    438    { 0x426, AF_IGNORE_CAPITAL_BOTTOM }, /* Ц */
    439    { 0x429, AF_IGNORE_CAPITAL_BOTTOM }, /* Щ */
    440 
    441    { 0x439, AF_ADJUST_UP }, /* й */
    442 
    443    { 0x446, AF_IGNORE_SMALL_BOTTOM }, /* ц */
    444    { 0x449, AF_IGNORE_SMALL_BOTTOM }, /* щ */
    445 
    446    { 0x450, AF_ADJUST_UP }, /* ѐ */
    447    { 0x451, AF_ADJUST_UP }, /* ё */
    448    { 0x453, AF_ADJUST_UP }, /* ѓ */
    449    { 0x456, AF_ADJUST_UP }, /* і */
    450    { 0x457, AF_ADJUST_UP }, /* ї */
    451    { 0x458, AF_ADJUST_UP }, /* ј */
    452    { 0x45C, AF_ADJUST_UP }, /* ќ */
    453    { 0x45D, AF_ADJUST_UP }, /* ѝ */
    454    { 0x45E, AF_ADJUST_UP }, /* ў */
    455    { 0x45F, AF_IGNORE_SMALL_BOTTOM }, /* џ */
    456 
    457    { 0x476, AF_ADJUST_UP }, /* Ѷ */
    458    { 0x477, AF_ADJUST_UP }, /* ѷ */
    459    { 0x47C, AF_ADJUST_UP2 }, /* Ѽ */
    460    { 0x47D, AF_ADJUST_UP2 }, /* ѽ */
    461    { 0x47E, AF_ADJUST_UP }, /* Ѿ */
    462    { 0x47F, AF_ADJUST_UP }, /* ѿ */
    463 
    464    { 0x480, AF_IGNORE_CAPITAL_BOTTOM }, /* Ҁ */
    465    { 0x481, AF_IGNORE_SMALL_BOTTOM }, /* ҁ */
    466    { 0x48A, AF_ADJUST_UP | AF_IGNORE_CAPITAL_BOTTOM }, /* Ҋ */
    467    { 0x48B, AF_ADJUST_UP | AF_IGNORE_SMALL_BOTTOM }, /* ҋ */
    468 
    469    { 0x490, AF_IGNORE_CAPITAL_TOP }, /* Ґ */
    470    { 0x491, AF_IGNORE_SMALL_TOP }, /* ґ */
    471    { 0x496, AF_IGNORE_CAPITAL_BOTTOM }, /* Җ */
    472    { 0x497, AF_IGNORE_SMALL_BOTTOM }, /* җ */
    473    { 0x498, AF_IGNORE_CAPITAL_BOTTOM }, /* Ҙ */
    474    { 0x499, AF_IGNORE_SMALL_BOTTOM }, /* ҙ */
    475    { 0x49A, AF_IGNORE_CAPITAL_BOTTOM }, /* Қ */
    476    { 0x49B, AF_IGNORE_SMALL_BOTTOM }, /* қ */
    477 
    478    { 0x4A2, AF_IGNORE_CAPITAL_BOTTOM }, /* Ң */
    479    { 0x4A3, AF_IGNORE_SMALL_BOTTOM }, /* ң */
    480    { 0x4AA, AF_IGNORE_CAPITAL_BOTTOM }, /* Ҫ */
    481    { 0x4AB, AF_IGNORE_SMALL_BOTTOM }, /* ҫ */
    482    { 0x4AC, AF_IGNORE_CAPITAL_BOTTOM }, /* Ҭ */
    483    { 0x4AD, AF_IGNORE_SMALL_BOTTOM }, /* ҭ */
    484 
    485    { 0x4B2, AF_IGNORE_CAPITAL_BOTTOM }, /* Ҳ */
    486    { 0x4B3, AF_IGNORE_SMALL_BOTTOM }, /* ҳ */
    487    { 0x4B4, AF_IGNORE_CAPITAL_BOTTOM }, /* Ҵ */
    488    { 0x4B5, AF_IGNORE_SMALL_BOTTOM }, /* ҵ */
    489    { 0x4B6, AF_IGNORE_CAPITAL_BOTTOM }, /* Ҷ */
    490    { 0x4B7, AF_IGNORE_SMALL_BOTTOM }, /* ҷ */
    491    { 0x4BE, AF_IGNORE_CAPITAL_BOTTOM }, /* Ҿ */
    492    { 0x4BF, AF_IGNORE_SMALL_BOTTOM }, /* ҿ */
    493 
    494    { 0x4C1, AF_ADJUST_UP }, /* Ӂ */
    495    { 0x4C2, AF_ADJUST_UP }, /* ӂ */
    496    { 0x4C5, AF_IGNORE_CAPITAL_BOTTOM }, /* Ӆ */
    497    { 0x4C6, AF_IGNORE_SMALL_BOTTOM }, /* ӆ */
    498    { 0x4C9, AF_IGNORE_CAPITAL_BOTTOM }, /* Ӊ */
    499    { 0x4CA, AF_IGNORE_SMALL_BOTTOM }, /* ӊ */
    500    { 0x4CB, AF_IGNORE_CAPITAL_BOTTOM }, /* Ӌ */
    501    { 0x4CC, AF_IGNORE_SMALL_BOTTOM }, /* ӌ */
    502    { 0x4CD, AF_IGNORE_CAPITAL_BOTTOM }, /* Ӎ */
    503    { 0x4CE, AF_IGNORE_SMALL_BOTTOM }, /* ӎ */
    504 
    505    { 0x4D0, AF_ADJUST_UP }, /* Ӑ */
    506    { 0x4D1, AF_ADJUST_UP }, /* ӑ */
    507    { 0x4D2, AF_ADJUST_UP }, /* Ӓ */
    508    { 0x4D3, AF_ADJUST_UP }, /* ӓ */
    509    { 0x4D6, AF_ADJUST_UP }, /* Ӗ */
    510    { 0x4D7, AF_ADJUST_UP }, /* ӗ */
    511    { 0x4DA, AF_ADJUST_UP }, /* Ӛ */
    512    { 0x4DB, AF_ADJUST_UP }, /* ӛ */
    513    { 0x4DC, AF_ADJUST_UP }, /* Ӝ */
    514    { 0x4DD, AF_ADJUST_UP }, /* ӝ */
    515    { 0x4DE, AF_ADJUST_UP }, /* Ӟ */
    516    { 0x4DF, AF_ADJUST_UP }, /* ӟ */
    517 
    518    { 0x4E2, AF_ADJUST_UP }, /* Ӣ */
    519    { 0x4E3, AF_ADJUST_UP }, /* ӣ */
    520    { 0x4E4, AF_ADJUST_UP }, /* Ӥ */
    521    { 0x4E5, AF_ADJUST_UP }, /* ӥ */
    522    { 0x4E6, AF_ADJUST_UP }, /* Ӧ */
    523    { 0x4E7, AF_ADJUST_UP }, /* ӧ */
    524    { 0x4EA, AF_ADJUST_UP }, /* Ӫ */
    525    { 0x4EB, AF_ADJUST_UP }, /* ӫ */
    526    { 0x4EC, AF_ADJUST_UP }, /* Ӭ */
    527    { 0x4ED, AF_ADJUST_UP }, /* ӭ */
    528    { 0x4EE, AF_ADJUST_UP }, /* Ӯ */
    529    { 0x4EF, AF_ADJUST_UP }, /* ӯ */
    530 
    531    { 0x4F0, AF_ADJUST_UP }, /* Ӱ */
    532    { 0x4F1, AF_ADJUST_UP }, /* ӱ */
    533    { 0x4F2, AF_ADJUST_UP }, /* Ӳ */
    534    { 0x4F3, AF_ADJUST_UP }, /* ӳ */
    535    { 0x4F4, AF_ADJUST_UP }, /* Ӵ */
    536    { 0x4F5, AF_ADJUST_UP }, /* ӵ */
    537    { 0x4F6, AF_IGNORE_CAPITAL_BOTTOM }, /* Ӷ */
    538    { 0x4F7, AF_IGNORE_SMALL_BOTTOM }, /* ӷ */
    539    { 0x4F8, AF_ADJUST_UP }, /* Ӹ */
    540    { 0x4F9, AF_ADJUST_UP }, /* ӹ */
    541    { 0x4FA, AF_IGNORE_CAPITAL_BOTTOM }, /* Ӻ */
    542    { 0x4FB, AF_IGNORE_SMALL_BOTTOM }, /* ӻ */
    543 
    544    /* Cyrillic Supplement */
    545    { 0x506, AF_IGNORE_CAPITAL_BOTTOM }, /* Ԇ */
    546    { 0x507, AF_IGNORE_SMALL_BOTTOM }, /* ԇ */
    547 
    548    { 0x524, AF_IGNORE_CAPITAL_BOTTOM }, /* Ԥ */
    549    { 0x525, AF_IGNORE_SMALL_BOTTOM }, /* ԥ */
    550    { 0x526, AF_IGNORE_CAPITAL_BOTTOM }, /* Ԧ */
    551    { 0x527, AF_IGNORE_SMALL_BOTTOM }, /* ԧ */
    552    { 0x52E, AF_IGNORE_CAPITAL_BOTTOM }, /* Ԯ */
    553    { 0x52F, AF_IGNORE_SMALL_BOTTOM }, /* ԯ */
    554 
    555    /* Cherokee */
    556    { 0x13A5, AF_ADJUST_UP }, /* Ꭵ */
    557 
    558    /* Phonetic Extensions */
    559    { 0x1D09, AF_ADJUST_DOWN }, /* ᴉ */
    560 
    561    { 0x1D4E, AF_ADJUST_DOWN }, /* ᵎ */
    562 
    563    { 0x1D51, AF_IGNORE_SMALL_BOTTOM }, /* ᵑ */
    564 
    565    { 0x1D62, AF_ADJUST_UP }, /* ᵢ */
    566 
    567    /* Phonetic Extensions Supplement */
    568    { 0x1D80, AF_IGNORE_SMALL_BOTTOM }, /* ᶀ */
    569    { 0x1D81, AF_IGNORE_SMALL_BOTTOM }, /* ᶁ */
    570    { 0x1D82, AF_IGNORE_SMALL_BOTTOM }, /* ᶂ */
    571    { 0x1D84, AF_IGNORE_SMALL_BOTTOM }, /* ᶄ */
    572    { 0x1D85, AF_IGNORE_SMALL_BOTTOM }, /* ᶅ */
    573    { 0x1D86, AF_IGNORE_SMALL_BOTTOM }, /* ᶆ */
    574    { 0x1D87, AF_IGNORE_SMALL_BOTTOM }, /* ᶇ */
    575    { 0x1D89, AF_IGNORE_SMALL_BOTTOM }, /* ᶉ */
    576    { 0x1D8A, AF_IGNORE_SMALL_BOTTOM }, /* ᶊ */
    577    { 0x1D8C, AF_IGNORE_SMALL_BOTTOM }, /* ᶌ */
    578    { 0x1D8D, AF_IGNORE_SMALL_BOTTOM }, /* ᶍ */
    579    { 0x1D8E, AF_IGNORE_SMALL_BOTTOM }, /* ᶎ */
    580    { 0x1D8F, AF_IGNORE_SMALL_BOTTOM }, /* ᶏ */
    581 
    582    { 0x1D90, AF_IGNORE_SMALL_BOTTOM }, /* ᶐ */
    583    { 0x1D91, AF_IGNORE_SMALL_BOTTOM }, /* ᶑ */
    584    { 0x1D92, AF_IGNORE_SMALL_BOTTOM }, /* ᶒ */
    585    { 0x1D93, AF_IGNORE_SMALL_BOTTOM }, /* ᶓ */
    586    { 0x1D94, AF_IGNORE_SMALL_BOTTOM }, /* ᶔ */
    587    { 0x1D95, AF_IGNORE_SMALL_BOTTOM }, /* ᶕ */
    588    { 0x1D96, AF_ADJUST_UP | AF_IGNORE_SMALL_BOTTOM }, /* ᶖ */
    589    { 0x1D97, AF_IGNORE_SMALL_BOTTOM }, /* ᶗ */
    590    { 0x1D98, AF_IGNORE_SMALL_BOTTOM }, /* ᶘ */
    591    { 0x1D99, AF_IGNORE_SMALL_BOTTOM }, /* ᶙ */
    592    { 0x1D9A, AF_IGNORE_SMALL_BOTTOM }, /* ᶚ */
    593 
    594    { 0x1DA4, AF_ADJUST_UP }, /* ᶤ */
    595    { 0x1DA8, AF_ADJUST_UP }, /* ᶨ */
    596    { 0x1DA9, AF_IGNORE_SMALL_BOTTOM }, /* ᶩ */
    597    { 0x1DAA, AF_IGNORE_SMALL_BOTTOM }, /* ᶪ */
    598    { 0x1DAC, AF_IGNORE_SMALL_BOTTOM }, /* ᶬ */
    599    { 0x1DAE, AF_IGNORE_SMALL_BOTTOM }, /* ᶮ */
    600    { 0x1DAF, AF_IGNORE_SMALL_BOTTOM }, /* ᶯ */
    601 
    602    { 0x1DB3, AF_IGNORE_SMALL_BOTTOM }, /* ᶳ */
    603    { 0x1DB5, AF_IGNORE_SMALL_BOTTOM }, /* ᶵ */
    604    { 0x1DBC, AF_IGNORE_SMALL_BOTTOM }, /* ᶼ */
    605 
    606    /* Latin Extended Additional */
    607    { 0x1E00, AF_ADJUST_DOWN }, /* Ḁ */
    608    { 0x1E01, AF_ADJUST_DOWN }, /* ḁ */
    609    { 0x1E02, AF_ADJUST_UP }, /* Ḃ */
    610    { 0x1E03, AF_ADJUST_UP }, /* ḃ */
    611    { 0x1E04, AF_ADJUST_DOWN }, /* Ḅ */
    612    { 0x1E05, AF_ADJUST_DOWN }, /* ḅ */
    613    { 0x1E06, AF_ADJUST_DOWN }, /* Ḇ */
    614    { 0x1E07, AF_ADJUST_DOWN }, /* ḇ */
    615    { 0x1E08, AF_ADJUST_UP | AF_IGNORE_CAPITAL_BOTTOM }, /* Ḉ */
    616    { 0x1E09, AF_ADJUST_UP | AF_IGNORE_SMALL_BOTTOM }, /* ḉ */
    617    { 0x1E0A, AF_ADJUST_UP }, /* Ḋ */
    618    { 0x1E0B, AF_ADJUST_UP }, /* ḋ */
    619    { 0x1E0C, AF_ADJUST_DOWN }, /* Ḍ */
    620    { 0x1E0D, AF_ADJUST_DOWN }, /* ḍ */
    621    { 0x1E0E, AF_ADJUST_DOWN }, /* Ḏ */
    622    { 0x1E0F, AF_ADJUST_DOWN }, /* ḏ */
    623 
    624    { 0x1E10, AF_ADJUST_DOWN }, /* Ḑ */
    625    { 0x1E11, AF_ADJUST_DOWN }, /* ḑ */
    626    { 0x1E12, AF_ADJUST_DOWN }, /* Ḓ */
    627    { 0x1E13, AF_ADJUST_DOWN }, /* ḓ */
    628    { 0x1E14, AF_ADJUST_UP2 }, /* Ḕ */
    629    { 0x1E15, AF_ADJUST_UP2 }, /* ḕ */
    630    { 0x1E16, AF_ADJUST_UP2 }, /* Ḗ */
    631    { 0x1E17, AF_ADJUST_UP2 }, /* ḗ */
    632    { 0x1E18, AF_ADJUST_DOWN }, /* Ḙ */
    633    { 0x1E19, AF_ADJUST_DOWN }, /* ḙ */
    634    { 0x1E1A, AF_ADJUST_DOWN | AF_ADJUST_TILDE_BOTTOM }, /* Ḛ */
    635    { 0x1E1B, AF_ADJUST_DOWN | AF_ADJUST_TILDE_BOTTOM }, /* ḛ */
    636    { 0x1E1C, AF_ADJUST_UP | AF_IGNORE_CAPITAL_BOTTOM }, /* Ḝ */
    637    { 0x1E1D, AF_ADJUST_UP | AF_IGNORE_SMALL_BOTTOM }, /* ḝ */
    638    { 0x1E1E, AF_ADJUST_UP }, /* Ḟ */
    639    { 0x1E1F, AF_ADJUST_UP }, /* ḟ */
    640 
    641    { 0x1E20, AF_ADJUST_UP }, /* Ḡ */
    642    { 0x1E21, AF_ADJUST_UP }, /* ḡ */
    643    { 0x1E22, AF_ADJUST_UP }, /* Ḣ */
    644    { 0x1E23, AF_ADJUST_UP }, /* ḣ */
    645    { 0x1E24, AF_ADJUST_DOWN }, /* Ḥ */
    646    { 0x1E25, AF_ADJUST_DOWN }, /* ḥ */
    647    { 0x1E26, AF_ADJUST_UP }, /* Ḧ */
    648    { 0x1E27, AF_ADJUST_UP }, /* ḧ */
    649    { 0x1E28, AF_IGNORE_CAPITAL_BOTTOM }, /* Ḩ */
    650    { 0x1E29, AF_IGNORE_SMALL_BOTTOM }, /* ḩ */
    651    { 0x1E2A, AF_ADJUST_DOWN }, /* Ḫ */
    652    { 0x1E2B, AF_ADJUST_DOWN }, /* ḫ */
    653    { 0x1E2C, AF_ADJUST_DOWN | AF_ADJUST_TILDE_BOTTOM }, /* Ḭ */
    654    { 0x1E2D, AF_ADJUST_UP | AF_ADJUST_DOWN | AF_ADJUST_TILDE_BOTTOM }, /* ḭ */
    655    { 0x1E2E, AF_ADJUST_UP2 }, /* Ḯ */
    656    { 0x1E2F, AF_ADJUST_UP2 }, /* ḯ */
    657 
    658    { 0x1E30, AF_ADJUST_UP }, /* Ḱ */
    659    { 0x1E31, AF_ADJUST_UP }, /* ḱ */
    660    { 0x1E32, AF_ADJUST_DOWN }, /* Ḳ */
    661    { 0x1E33, AF_ADJUST_DOWN }, /* ḳ */
    662    { 0x1E34, AF_ADJUST_DOWN }, /* Ḵ */
    663    { 0x1E35, AF_ADJUST_DOWN }, /* ḵ */
    664    { 0x1E36, AF_ADJUST_DOWN }, /* Ḷ */
    665    { 0x1E37, AF_ADJUST_DOWN }, /* ḷ */
    666    { 0x1E38, AF_ADJUST_UP | AF_ADJUST_DOWN }, /* Ḹ */
    667    { 0x1E39, AF_ADJUST_UP | AF_ADJUST_DOWN }, /* ḹ */
    668    { 0x1E3A, AF_ADJUST_DOWN }, /* Ḻ */
    669    { 0x1E3B, AF_ADJUST_DOWN }, /* ḻ */
    670    { 0x1E3C, AF_ADJUST_DOWN }, /* Ḽ */
    671    { 0x1E3D, AF_ADJUST_DOWN }, /* ḽ */
    672    { 0x1E3E, AF_ADJUST_UP }, /* Ḿ */
    673    { 0x1E3F, AF_ADJUST_UP }, /* ḿ */
    674 
    675    { 0x1E40, AF_ADJUST_UP }, /* Ṁ */
    676    { 0x1E41, AF_ADJUST_UP }, /* ṁ */
    677    { 0x1E42, AF_ADJUST_DOWN }, /* Ṃ */
    678    { 0x1E43, AF_ADJUST_DOWN }, /* ṃ */
    679    { 0x1E44, AF_ADJUST_UP }, /* Ṅ */
    680    { 0x1E45, AF_ADJUST_UP }, /* ṅ */
    681    { 0x1E46, AF_ADJUST_DOWN }, /* Ṇ */
    682    { 0x1E47, AF_ADJUST_DOWN }, /* ṇ */
    683    { 0x1E48, AF_ADJUST_DOWN }, /* Ṉ */
    684    { 0x1E49, AF_ADJUST_DOWN }, /* ṉ */
    685    { 0x1E4A, AF_ADJUST_DOWN }, /* Ṋ */
    686    { 0x1E4B, AF_ADJUST_DOWN }, /* ṋ */
    687    { 0x1E4C, AF_ADJUST_UP2 | AF_ADJUST_TILDE_TOP2 }, /* Ṍ */
    688    { 0x1E4D, AF_ADJUST_UP2 | AF_ADJUST_TILDE_TOP2 }, /* ṍ */
    689    { 0x1E4E, AF_ADJUST_UP2 | AF_ADJUST_TILDE_TOP2 }, /* Ṏ */
    690    { 0x1E4F, AF_ADJUST_UP2 | AF_ADJUST_TILDE_TOP2 }, /* ṏ */
    691 
    692    { 0x1E50, AF_ADJUST_UP2 }, /* Ṑ */
    693    { 0x1E51, AF_ADJUST_UP2 }, /* ṑ */
    694    { 0x1E52, AF_ADJUST_UP2 }, /* Ṓ */
    695    { 0x1E53, AF_ADJUST_UP2 }, /* ṓ */
    696    { 0x1E54, AF_ADJUST_UP }, /* Ṕ */
    697    { 0x1E55, AF_ADJUST_UP }, /* ṕ */
    698    { 0x1E56, AF_ADJUST_UP }, /* Ṗ */
    699    { 0x1E57, AF_ADJUST_UP }, /* ṗ */
    700    { 0x1E58, AF_ADJUST_UP }, /* Ṙ */
    701    { 0x1E59, AF_ADJUST_UP }, /* ṙ */
    702    { 0x1E5A, AF_ADJUST_DOWN }, /* Ṛ */
    703    { 0x1E5B, AF_ADJUST_DOWN }, /* ṛ */
    704    { 0x1E5C, AF_ADJUST_UP | AF_ADJUST_DOWN }, /* Ṝ */
    705    { 0x1E5D, AF_ADJUST_UP | AF_ADJUST_DOWN }, /* ṝ */
    706    { 0x1E5E, AF_ADJUST_DOWN }, /* Ṟ */
    707    { 0x1E5F, AF_ADJUST_DOWN }, /* ṟ */
    708 
    709    { 0x1E60, AF_ADJUST_UP }, /* Ṡ */
    710    { 0x1E61, AF_ADJUST_UP }, /* ṡ */
    711    { 0x1E62, AF_ADJUST_DOWN }, /* Ṣ */
    712    { 0x1E63, AF_ADJUST_DOWN }, /* ṣ */
    713    { 0x1E64, AF_ADJUST_UP }, /* Ṥ */
    714    { 0x1E65, AF_ADJUST_UP }, /* ṥ */
    715    { 0x1E66, AF_ADJUST_UP }, /* Ṧ */
    716    { 0x1E67, AF_ADJUST_UP }, /* ṧ */
    717    { 0x1E68, AF_ADJUST_UP | AF_ADJUST_DOWN }, /* Ṩ */
    718    { 0x1E69, AF_ADJUST_UP | AF_ADJUST_DOWN }, /* ṩ */
    719    { 0x1E6A, AF_ADJUST_UP }, /* Ṫ */
    720    { 0x1E6B, AF_ADJUST_UP }, /* ṫ */
    721    { 0x1E6C, AF_ADJUST_DOWN }, /* Ṭ */
    722    { 0x1E6D, AF_ADJUST_DOWN }, /* ṭ */
    723    { 0x1E6E, AF_ADJUST_DOWN }, /* Ṯ */
    724    { 0x1E6F, AF_ADJUST_DOWN }, /* ṯ */
    725 
    726    { 0x1E70, AF_ADJUST_DOWN }, /* Ṱ */
    727    { 0x1E71, AF_ADJUST_DOWN }, /* ṱ */
    728    { 0x1E72, AF_ADJUST_DOWN }, /* Ṳ */
    729    { 0x1E73, AF_ADJUST_DOWN }, /* ṳ */
    730    { 0x1E74, AF_ADJUST_DOWN | AF_ADJUST_TILDE_BOTTOM }, /* Ṵ */
    731    { 0x1E75, AF_ADJUST_DOWN | AF_ADJUST_TILDE_BOTTOM }, /* ṵ */
    732    { 0x1E76, AF_ADJUST_DOWN }, /* Ṷ */
    733    { 0x1E77, AF_ADJUST_DOWN }, /* ṷ */
    734    { 0x1E78, AF_ADJUST_UP2 | AF_ADJUST_TILDE_TOP2 }, /* Ṹ */
    735    { 0x1E79, AF_ADJUST_UP2 | AF_ADJUST_TILDE_TOP2 }, /* ṹ */
    736    { 0x1E7A, AF_ADJUST_UP2 }, /* Ṻ */
    737    { 0x1E7B, AF_ADJUST_UP2 }, /* ṻ */
    738    { 0x1E7C, AF_ADJUST_UP | AF_ADJUST_TILDE_TOP }, /* Ṽ */
    739    { 0x1E7D, AF_ADJUST_UP | AF_ADJUST_TILDE_TOP }, /* ṽ */
    740    { 0x1E7E, AF_ADJUST_DOWN }, /* Ṿ */
    741    { 0x1E7F, AF_ADJUST_DOWN }, /* ṿ */
    742 
    743    { 0x1E80, AF_ADJUST_UP }, /* Ẁ */
    744    { 0x1E81, AF_ADJUST_UP }, /* ẁ */
    745    { 0x1E82, AF_ADJUST_UP }, /* Ẃ */
    746    { 0x1E83, AF_ADJUST_UP }, /* ẃ */
    747    { 0x1E84, AF_ADJUST_UP }, /* Ẅ */
    748    { 0x1E85, AF_ADJUST_UP }, /* ẅ */
    749    { 0x1E86, AF_ADJUST_UP }, /* Ẇ */
    750    { 0x1E87, AF_ADJUST_UP }, /* ẇ */
    751    { 0x1E88, AF_ADJUST_DOWN }, /* Ẉ */
    752    { 0x1E89, AF_ADJUST_DOWN }, /* ẉ */
    753    { 0x1E8A, AF_ADJUST_UP }, /* Ẋ */
    754    { 0x1E8B, AF_ADJUST_UP }, /* ẋ */
    755    { 0x1E8C, AF_ADJUST_UP }, /* Ẍ */
    756    { 0x1E8D, AF_ADJUST_UP }, /* ẍ */
    757    { 0x1E8E, AF_ADJUST_UP }, /* Ẏ */
    758    { 0x1E8F, AF_ADJUST_UP }, /* ẏ */
    759 
    760    { 0x1E90, AF_ADJUST_UP }, /* Ẑ */
    761    { 0x1E91, AF_ADJUST_UP }, /* ẑ */
    762    { 0x1E92, AF_ADJUST_DOWN }, /* Ẓ */
    763    { 0x1E93, AF_ADJUST_DOWN }, /* ẓ */
    764    { 0x1E94, AF_ADJUST_DOWN }, /* Ẕ */
    765    { 0x1E95, AF_ADJUST_DOWN }, /* ẕ */
    766    { 0x1E96, AF_ADJUST_DOWN }, /* ẖ */
    767    { 0x1E97, AF_ADJUST_UP }, /* ẗ */
    768    { 0x1E98, AF_ADJUST_UP }, /* ẘ */
    769    { 0x1E99, AF_ADJUST_UP }, /* ẙ */
    770    { 0x1E9A, AF_ADJUST_UP }, /* ẚ */
    771    { 0x1E9B, AF_ADJUST_UP }, /* ẛ */
    772 
    773    { 0x1EA0, AF_ADJUST_DOWN }, /* Ạ */
    774    { 0x1EA1, AF_ADJUST_DOWN }, /* ạ */
    775    { 0x1EA2, AF_ADJUST_UP }, /* Ả */
    776    { 0x1EA3, AF_ADJUST_UP }, /* ả */
    777    { 0x1EA4, AF_ADJUST_UP2 }, /* Ấ */
    778    { 0x1EA5, AF_ADJUST_UP2 }, /* ấ */
    779    { 0x1EA6, AF_ADJUST_UP2 }, /* Ầ */
    780    { 0x1EA7, AF_ADJUST_UP2 }, /* ầ */
    781    { 0x1EA8, AF_ADJUST_UP2 }, /* Ẩ */
    782    { 0x1EA9, AF_ADJUST_UP2 }, /* ẩ */
    783    { 0x1EAA, AF_ADJUST_UP2 | AF_ADJUST_TILDE_TOP }, /* Ẫ */
    784    { 0x1EAB, AF_ADJUST_UP2 | AF_ADJUST_TILDE_TOP }, /* ẫ */
    785    { 0x1EAC, AF_ADJUST_UP | AF_ADJUST_DOWN }, /* Ậ */
    786    { 0x1EAD, AF_ADJUST_UP | AF_ADJUST_DOWN }, /* ậ */
    787    { 0x1EAE, AF_ADJUST_UP2 }, /* Ắ */
    788    { 0x1EAF, AF_ADJUST_UP2 }, /* ắ */
    789 
    790    { 0x1EB0, AF_ADJUST_UP2 }, /* Ằ */
    791    { 0x1EB1, AF_ADJUST_UP2 }, /* ằ */
    792    { 0x1EB2, AF_ADJUST_UP2 }, /* Ẳ */
    793    { 0x1EB3, AF_ADJUST_UP2 }, /* ẳ */
    794    { 0x1EB4, AF_ADJUST_UP2 | AF_ADJUST_TILDE_TOP }, /* Ẵ */
    795    { 0x1EB5, AF_ADJUST_UP2 | AF_ADJUST_TILDE_TOP }, /* ẵ */
    796    { 0x1EB6, AF_ADJUST_UP | AF_ADJUST_DOWN }, /* Ặ */
    797    { 0x1EB7, AF_ADJUST_UP | AF_ADJUST_DOWN }, /* ặ */
    798    { 0x1EB8, AF_ADJUST_DOWN }, /* Ẹ */
    799    { 0x1EB9, AF_ADJUST_DOWN }, /* ẹ */
    800    { 0x1EBA, AF_ADJUST_UP }, /* Ẻ */
    801    { 0x1EBB, AF_ADJUST_UP }, /* ẻ */
    802    { 0x1EBC, AF_ADJUST_UP | AF_ADJUST_TILDE_TOP }, /* Ẽ */
    803    { 0x1EBD, AF_ADJUST_UP | AF_ADJUST_TILDE_TOP }, /* ẽ */
    804    { 0x1EBE, AF_ADJUST_UP2 }, /* Ế */
    805    { 0x1EBF, AF_ADJUST_UP2 }, /* ế */
    806 
    807    { 0x1EC0, AF_ADJUST_UP2 }, /* Ề */
    808    { 0x1EC1, AF_ADJUST_UP2 }, /* ề */
    809    { 0x1EC2, AF_ADJUST_UP2 }, /* Ể */
    810    { 0x1EC3, AF_ADJUST_UP2 }, /* ể */
    811    { 0x1EC4, AF_ADJUST_UP2 | AF_ADJUST_TILDE_TOP }, /* Ễ */
    812    { 0x1EC5, AF_ADJUST_UP2 | AF_ADJUST_TILDE_TOP }, /* ễ */
    813    { 0x1EC6, AF_ADJUST_UP | AF_ADJUST_DOWN }, /* Ệ */
    814    { 0x1EC7, AF_ADJUST_UP | AF_ADJUST_DOWN }, /* ệ */
    815    { 0x1EC8, AF_ADJUST_UP }, /* Ỉ */
    816    { 0x1EC9, AF_ADJUST_UP }, /* ỉ */
    817    { 0x1ECA, AF_ADJUST_DOWN }, /* Ị */
    818    { 0x1ECB, AF_ADJUST_UP | AF_ADJUST_DOWN }, /* ị */
    819    { 0x1ECC, AF_ADJUST_DOWN }, /* Ọ */
    820    { 0x1ECD, AF_ADJUST_DOWN }, /* ọ */
    821    { 0x1ECE, AF_ADJUST_UP }, /* Ỏ */
    822    { 0x1ECF, AF_ADJUST_UP }, /* ỏ */
    823 
    824    { 0x1ED0, AF_ADJUST_UP2 }, /* Ố */
    825    { 0x1ED1, AF_ADJUST_UP2 }, /* ố */
    826    { 0x1ED2, AF_ADJUST_UP2 }, /* Ồ */
    827    { 0x1ED3, AF_ADJUST_UP2 }, /* ồ */
    828    { 0x1ED4, AF_ADJUST_UP2 }, /* Ổ */
    829    { 0x1ED5, AF_ADJUST_UP2 }, /* ổ */
    830    { 0x1ED6, AF_ADJUST_UP2 | AF_ADJUST_TILDE_TOP }, /* Ỗ */
    831    { 0x1ED7, AF_ADJUST_UP2 | AF_ADJUST_TILDE_TOP }, /* ỗ */
    832    { 0x1ED8, AF_ADJUST_UP | AF_ADJUST_DOWN }, /* Ộ */
    833    { 0x1ED9, AF_ADJUST_UP | AF_ADJUST_DOWN }, /* ộ */
    834    { 0x1EDA, AF_ADJUST_UP | AF_IGNORE_CAPITAL_TOP }, /* Ớ */
    835    { 0x1EDB, AF_ADJUST_UP | AF_IGNORE_SMALL_TOP }, /* ớ */
    836    { 0x1EDC, AF_ADJUST_UP | AF_IGNORE_CAPITAL_TOP }, /* Ờ */
    837    { 0x1EDD, AF_ADJUST_UP | AF_IGNORE_SMALL_TOP }, /* ờ */
    838    { 0x1EDE, AF_ADJUST_UP | AF_IGNORE_CAPITAL_TOP }, /* Ở */
    839    { 0x1EDF, AF_ADJUST_UP | AF_IGNORE_SMALL_TOP }, /* ở */
    840 
    841    { 0x1EE0, AF_ADJUST_UP | AF_ADJUST_TILDE_TOP | AF_IGNORE_CAPITAL_TOP }, /* Ỡ */
    842    { 0x1EE1, AF_ADJUST_UP | AF_ADJUST_TILDE_TOP | AF_IGNORE_SMALL_TOP }, /* ỡ */
    843    { 0x1EE2, AF_ADJUST_DOWN | AF_IGNORE_CAPITAL_TOP }, /* Ợ */
    844    { 0x1EE3, AF_ADJUST_DOWN | AF_IGNORE_SMALL_TOP }, /* ợ */
    845    { 0x1EE4, AF_ADJUST_DOWN }, /* Ụ */
    846    { 0x1EE5, AF_ADJUST_DOWN }, /* ụ */
    847    { 0x1EE6, AF_ADJUST_UP }, /* Ủ */
    848    { 0x1EE7, AF_ADJUST_UP }, /* ủ */
    849    { 0x1EE8, AF_ADJUST_UP | AF_IGNORE_CAPITAL_TOP }, /* Ứ */
    850    { 0x1EE9, AF_ADJUST_UP | AF_IGNORE_SMALL_TOP }, /* ứ */
    851    { 0x1EEA, AF_ADJUST_UP | AF_IGNORE_CAPITAL_TOP }, /* Ừ */
    852    { 0x1EEB, AF_ADJUST_UP | AF_IGNORE_SMALL_TOP }, /* ừ */
    853    { 0x1EEC, AF_ADJUST_UP | AF_IGNORE_CAPITAL_TOP }, /* Ử */
    854    { 0x1EED, AF_ADJUST_UP | AF_IGNORE_SMALL_TOP }, /* ử */
    855    { 0x1EEE, AF_ADJUST_UP | AF_ADJUST_TILDE_TOP | AF_IGNORE_CAPITAL_TOP }, /* Ữ */
    856    { 0x1EEF, AF_ADJUST_UP | AF_ADJUST_TILDE_TOP | AF_IGNORE_SMALL_TOP }, /* ữ */
    857 
    858    { 0x1EF0, AF_ADJUST_DOWN | AF_IGNORE_CAPITAL_TOP }, /* Ự */
    859    { 0x1EF1, AF_ADJUST_DOWN | AF_IGNORE_SMALL_TOP }, /* ự */
    860    { 0x1EF2, AF_ADJUST_UP }, /* Ỳ */
    861    { 0x1EF3, AF_ADJUST_UP }, /* ỳ */
    862    { 0x1EF4, AF_ADJUST_DOWN }, /* Ỵ */
    863    { 0x1EF5, AF_ADJUST_DOWN }, /* ỵ */
    864    { 0x1EF6, AF_ADJUST_UP }, /* Ỷ */
    865    { 0x1EF7, AF_ADJUST_UP }, /* ỷ */
    866    { 0x1EF8, AF_ADJUST_UP | AF_ADJUST_TILDE_TOP }, /* Ỹ */
    867    { 0x1EF9, AF_ADJUST_UP | AF_ADJUST_TILDE_TOP }, /* ỹ */
    868 
    869    /* Greek Extended */
    870    { 0x1F00, AF_ADJUST_UP }, /* ἀ */
    871    { 0x1F01, AF_ADJUST_UP }, /* ἁ */
    872    { 0x1F02, AF_ADJUST_UP }, /* ἂ */
    873    { 0x1F03, AF_ADJUST_UP }, /* ἃ */
    874    { 0x1F04, AF_ADJUST_UP }, /* ἄ */
    875    { 0x1F05, AF_ADJUST_UP }, /* ἅ */
    876    { 0x1F06, AF_ADJUST_UP2 | AF_ADJUST_TILDE_TOP }, /* ἆ */
    877    { 0x1F07, AF_ADJUST_UP2 | AF_ADJUST_TILDE_TOP }, /* ἇ */
    878 
    879    { 0x1F10, AF_ADJUST_UP }, /* ἐ */
    880    { 0x1F11, AF_ADJUST_UP }, /* ἑ */
    881    { 0x1F12, AF_ADJUST_UP }, /* ἒ */
    882    { 0x1F13, AF_ADJUST_UP }, /* ἓ */
    883    { 0x1F14, AF_ADJUST_UP }, /* ἔ */
    884    { 0x1F15, AF_ADJUST_UP }, /* ἕ */
    885 
    886    { 0x1F20, AF_ADJUST_UP }, /* ἠ */
    887    { 0x1F21, AF_ADJUST_UP }, /* ἡ */
    888    { 0x1F22, AF_ADJUST_UP }, /* ἢ */
    889    { 0x1F23, AF_ADJUST_UP }, /* ἣ */
    890    { 0x1F24, AF_ADJUST_UP }, /* ἤ */
    891    { 0x1F25, AF_ADJUST_UP }, /* ἥ */
    892    { 0x1F26, AF_ADJUST_UP2 | AF_ADJUST_TILDE_TOP }, /* ἦ */
    893    { 0x1F27, AF_ADJUST_UP2 | AF_ADJUST_TILDE_TOP }, /* ἧ */
    894 
    895    { 0x1F30, AF_ADJUST_UP }, /* ἰ */
    896    { 0x1F31, AF_ADJUST_UP }, /* ἱ */
    897    { 0x1F32, AF_ADJUST_UP }, /* ἲ */
    898    { 0x1F33, AF_ADJUST_UP }, /* ἳ */
    899    { 0x1F34, AF_ADJUST_UP }, /* ἴ */
    900    { 0x1F35, AF_ADJUST_UP }, /* ἵ */
    901    { 0x1F36, AF_ADJUST_UP2 | AF_ADJUST_TILDE_TOP }, /* ἶ */
    902    { 0x1F37, AF_ADJUST_UP2 | AF_ADJUST_TILDE_TOP }, /* ἷ */
    903 
    904    { 0x1F40, AF_ADJUST_UP }, /* ὀ */
    905    { 0x1F41, AF_ADJUST_UP }, /* ὁ */
    906    { 0x1F42, AF_ADJUST_UP }, /* ὂ */
    907    { 0x1F43, AF_ADJUST_UP }, /* ὃ */
    908    { 0x1F44, AF_ADJUST_UP }, /* ὄ */
    909    { 0x1F45, AF_ADJUST_UP }, /* ὅ */
    910 
    911    { 0x1F50, AF_ADJUST_UP }, /* ὐ */
    912    { 0x1F51, AF_ADJUST_UP }, /* ὑ */
    913    { 0x1F52, AF_ADJUST_UP }, /* ὒ */
    914    { 0x1F53, AF_ADJUST_UP }, /* ὓ */
    915    { 0x1F54, AF_ADJUST_UP }, /* ὔ */
    916    { 0x1F55, AF_ADJUST_UP }, /* ὕ */
    917    { 0x1F56, AF_ADJUST_UP2 | AF_ADJUST_TILDE_TOP }, /* ὖ */
    918    { 0x1F57, AF_ADJUST_UP2 | AF_ADJUST_TILDE_TOP }, /* ὗ */
    919 
    920    { 0x1F60, AF_ADJUST_UP }, /* ὠ */
    921    { 0x1F61, AF_ADJUST_UP }, /* ὡ */
    922    { 0x1F62, AF_ADJUST_UP }, /* ὢ */
    923    { 0x1F63, AF_ADJUST_UP }, /* ὣ */
    924    { 0x1F64, AF_ADJUST_UP }, /* ὤ */
    925    { 0x1F65, AF_ADJUST_UP }, /* ὥ */
    926    { 0x1F66, AF_ADJUST_UP2 | AF_ADJUST_TILDE_TOP }, /* ὦ */
    927    { 0x1F67, AF_ADJUST_UP2 | AF_ADJUST_TILDE_TOP }, /* ὧ */
    928 
    929    { 0x1F70, AF_ADJUST_UP }, /* ὰ */
    930    { 0x1F71, AF_ADJUST_UP }, /* ά */
    931    { 0x1F72, AF_ADJUST_UP }, /* ὲ */
    932    { 0x1F73, AF_ADJUST_UP }, /* έ */
    933    { 0x1F74, AF_ADJUST_UP }, /* ὴ */
    934    { 0x1F75, AF_ADJUST_UP }, /* ή */
    935    { 0x1F76, AF_ADJUST_UP }, /* ὶ */
    936    { 0x1F77, AF_ADJUST_UP }, /* ί */
    937    { 0x1F78, AF_ADJUST_UP }, /* ὸ */
    938    { 0x1F79, AF_ADJUST_UP }, /* ό */
    939    { 0x1F7A, AF_ADJUST_UP }, /* ὺ */
    940    { 0x1F7B, AF_ADJUST_UP }, /* ύ */
    941    { 0x1F7C, AF_ADJUST_UP }, /* ὼ */
    942    { 0x1F7D, AF_ADJUST_UP }, /* ώ */
    943 
    944    { 0x1F80, AF_ADJUST_UP | AF_ADJUST_DOWN }, /* ᾀ */
    945    { 0x1F81, AF_ADJUST_UP | AF_ADJUST_DOWN }, /* ᾁ */
    946    { 0x1F82, AF_ADJUST_UP | AF_ADJUST_DOWN }, /* ᾂ */
    947    { 0x1F83, AF_ADJUST_UP | AF_ADJUST_DOWN }, /* ᾃ */
    948    { 0x1F84, AF_ADJUST_UP | AF_ADJUST_DOWN }, /* ᾄ */
    949    { 0x1F85, AF_ADJUST_UP | AF_ADJUST_DOWN }, /* ᾅ */
    950    { 0x1F86, AF_ADJUST_UP2 | AF_ADJUST_TILDE_TOP | AF_ADJUST_DOWN }, /* ᾆ */
    951    { 0x1F87, AF_ADJUST_UP2 | AF_ADJUST_TILDE_TOP | AF_ADJUST_DOWN }, /* ᾇ */
    952    { 0x1F88, AF_ADJUST_DOWN }, /* ᾈ */
    953    { 0x1F89, AF_ADJUST_DOWN }, /* ᾉ */
    954    { 0x1F8A, AF_ADJUST_DOWN }, /* ᾊ */
    955    { 0x1F8B, AF_ADJUST_DOWN }, /* ᾋ */
    956    { 0x1F8C, AF_ADJUST_DOWN }, /* ᾌ */
    957    { 0x1F8D, AF_ADJUST_DOWN }, /* ᾍ */
    958    { 0x1F8E, AF_ADJUST_DOWN }, /* ᾎ */
    959    { 0x1F8F, AF_ADJUST_DOWN }, /* ᾏ */
    960 
    961    { 0x1F90, AF_ADJUST_UP | AF_ADJUST_DOWN }, /* ᾐ */
    962    { 0x1F91, AF_ADJUST_UP | AF_ADJUST_DOWN }, /* ᾑ */
    963    { 0x1F92, AF_ADJUST_UP | AF_ADJUST_DOWN }, /* ᾒ */
    964    { 0x1F93, AF_ADJUST_UP | AF_ADJUST_DOWN }, /* ᾓ */
    965    { 0x1F94, AF_ADJUST_UP | AF_ADJUST_DOWN }, /* ᾔ */
    966    { 0x1F95, AF_ADJUST_UP | AF_ADJUST_DOWN }, /* ᾕ */
    967    { 0x1F96, AF_ADJUST_UP2 | AF_ADJUST_TILDE_TOP | AF_ADJUST_DOWN }, /* ᾖ */
    968    { 0x1F97, AF_ADJUST_UP2 | AF_ADJUST_TILDE_TOP | AF_ADJUST_DOWN }, /* ᾗ */
    969    { 0x1F98, AF_ADJUST_DOWN }, /* ᾘ */
    970    { 0x1F99, AF_ADJUST_DOWN }, /* ᾙ */
    971    { 0x1F9A, AF_ADJUST_DOWN }, /* ᾚ */
    972    { 0x1F9B, AF_ADJUST_DOWN }, /* ᾛ */
    973    { 0x1F9C, AF_ADJUST_DOWN }, /* ᾜ */
    974    { 0x1F9D, AF_ADJUST_DOWN }, /* ᾝ */
    975    { 0x1F9E, AF_ADJUST_DOWN }, /* ᾞ */
    976    { 0x1F9F, AF_ADJUST_DOWN }, /* ᾟ */
    977 
    978    { 0x1FA0, AF_ADJUST_UP | AF_ADJUST_DOWN }, /* ᾠ */
    979    { 0x1FA1, AF_ADJUST_UP | AF_ADJUST_DOWN }, /* ᾡ */
    980    { 0x1FA2, AF_ADJUST_UP | AF_ADJUST_DOWN }, /* ᾢ */
    981    { 0x1FA3, AF_ADJUST_UP | AF_ADJUST_DOWN }, /* ᾣ */
    982    { 0x1FA4, AF_ADJUST_UP | AF_ADJUST_DOWN }, /* ᾤ */
    983    { 0x1FA5, AF_ADJUST_UP | AF_ADJUST_DOWN }, /* ᾥ */
    984    { 0x1FA6, AF_ADJUST_UP2 | AF_ADJUST_TILDE_TOP | AF_ADJUST_DOWN }, /* ᾦ */
    985    { 0x1FA7, AF_ADJUST_UP2 | AF_ADJUST_TILDE_TOP | AF_ADJUST_DOWN }, /* ᾧ */
    986    { 0x1FA8, AF_ADJUST_DOWN }, /* ᾨ */
    987    { 0x1FA9, AF_ADJUST_DOWN }, /* ᾩ */
    988    { 0x1FAA, AF_ADJUST_DOWN }, /* ᾪ */
    989    { 0x1FAB, AF_ADJUST_DOWN }, /* ᾫ */
    990    { 0x1FAC, AF_ADJUST_DOWN }, /* ᾬ */
    991    { 0x1FAD, AF_ADJUST_DOWN }, /* ᾭ */
    992    { 0x1FAE, AF_ADJUST_DOWN }, /* ᾮ */
    993    { 0x1FAF, AF_ADJUST_DOWN }, /* ᾯ */
    994 
    995    { 0x1FB0, AF_ADJUST_UP }, /* ᾰ */
    996    { 0x1FB1, AF_ADJUST_UP }, /* ᾱ */
    997    { 0x1FB2, AF_ADJUST_UP | AF_ADJUST_DOWN }, /* ᾲ */
    998    { 0x1FB3, AF_ADJUST_DOWN }, /* ᾳ */
    999    { 0x1FB4, AF_ADJUST_UP | AF_ADJUST_DOWN }, /* ᾴ */
   1000    { 0x1FB6, AF_ADJUST_UP | AF_ADJUST_TILDE_TOP }, /* ᾶ */
   1001    { 0x1FB7, AF_ADJUST_UP | AF_ADJUST_TILDE_TOP | AF_ADJUST_DOWN }, /* ᾷ */
   1002    { 0x1FB8, AF_ADJUST_UP }, /* Ᾰ */
   1003    { 0x1FB9, AF_ADJUST_UP }, /* Ᾱ */
   1004    { 0x1FBC, AF_ADJUST_DOWN }, /* ᾼ */
   1005 
   1006    { 0x1FC2, AF_ADJUST_UP | AF_ADJUST_DOWN }, /* ῂ */
   1007    { 0x1FC3, AF_ADJUST_DOWN }, /* ῃ */
   1008    { 0x1FC4, AF_ADJUST_UP | AF_ADJUST_DOWN }, /* ῄ */
   1009    { 0x1FC6, AF_ADJUST_UP | AF_ADJUST_TILDE_TOP }, /* ῆ */
   1010    { 0x1FC7, AF_ADJUST_UP | AF_ADJUST_TILDE_TOP | AF_ADJUST_DOWN }, /* ῇ */
   1011    { 0x1FCC, AF_ADJUST_DOWN }, /* ῌ */
   1012 
   1013    { 0x1FD0, AF_ADJUST_UP }, /* ῐ */
   1014    { 0x1FD1, AF_ADJUST_UP }, /* ῑ */
   1015    { 0x1FD2, AF_ADJUST_UP2 }, /* ῒ */
   1016    { 0x1FD3, AF_ADJUST_UP2 }, /* ΐ */
   1017    { 0x1FD6, AF_ADJUST_UP | AF_ADJUST_TILDE_TOP }, /* ῖ */
   1018    { 0x1FD7, AF_ADJUST_UP2 | AF_ADJUST_TILDE_TOP }, /* ῗ */
   1019    { 0x1FD8, AF_ADJUST_UP }, /* Ῐ */
   1020    { 0x1FD9, AF_ADJUST_UP }, /* Ῑ */
   1021 
   1022    { 0x1FE0, AF_ADJUST_UP }, /* ῠ */
   1023    { 0x1FE1, AF_ADJUST_UP }, /* ῡ */
   1024    { 0x1FE2, AF_ADJUST_UP2 }, /* ῢ */
   1025    { 0x1FE3, AF_ADJUST_UP2 }, /* ΰ */
   1026    { 0x1FE4, AF_ADJUST_UP }, /* ῤ */
   1027    { 0x1FE5, AF_ADJUST_UP }, /* ῥ */
   1028    { 0x1FE6, AF_ADJUST_UP | AF_ADJUST_TILDE_TOP }, /* ῦ */
   1029    { 0x1FE7, AF_ADJUST_UP2 | AF_ADJUST_TILDE_TOP }, /* ῧ */
   1030    { 0x1FE8, AF_ADJUST_UP }, /* Ῠ */
   1031    { 0x1FE9, AF_ADJUST_UP }, /* Ῡ */
   1032    { 0x1FF2, AF_ADJUST_UP | AF_ADJUST_DOWN }, /* ῲ */
   1033    { 0x1FF3, AF_ADJUST_DOWN }, /* ῳ */
   1034    { 0x1FF4, AF_ADJUST_UP | AF_ADJUST_DOWN }, /* ῴ */
   1035    { 0x1FF6, AF_ADJUST_UP | AF_ADJUST_TILDE_TOP }, /* ῶ */
   1036    { 0x1FF7, AF_ADJUST_UP | AF_ADJUST_TILDE_TOP | AF_ADJUST_DOWN }, /* ῷ */
   1037    { 0x1FFC, AF_ADJUST_DOWN }, /* ῼ */
   1038 
   1039    /* General Punctuation */
   1040    { 0x203C, AF_ADJUST_UP | AF_ADJUST_NO_HEIGHT_CHECK }, /* ‼ */
   1041    { 0x203D, AF_ADJUST_UP | AF_ADJUST_NO_HEIGHT_CHECK }, /* ‽ */
   1042 
   1043    { 0x2047, AF_ADJUST_UP | AF_ADJUST_NO_HEIGHT_CHECK }, /* ⁇ */
   1044    { 0x2048, AF_ADJUST_UP | AF_ADJUST_NO_HEIGHT_CHECK }, /* ⁈ */
   1045    { 0x2049, AF_ADJUST_UP | AF_ADJUST_NO_HEIGHT_CHECK }, /* ⁉ */
   1046 
   1047    /* Superscripts and Subscripts */
   1048    { 0x2071, AF_ADJUST_UP }, /* ⁱ */
   1049 
   1050    /* Currency Symbols */
   1051    { 0x20AB, AF_ADJUST_DOWN }, /* ₫ */
   1052 
   1053    { 0x20C0, AF_ADJUST_DOWN }, /* ⃀ */
   1054 
   1055    /* Number Forms */
   1056    { 0x2170, AF_ADJUST_UP }, /* ⅰ */
   1057    { 0x2171, AF_ADJUST_UP }, /* ⅱ */
   1058    { 0x2172, AF_ADJUST_UP }, /* ⅲ */
   1059    { 0x2173, AF_ADJUST_UP }, /* ⅳ */
   1060    { 0x2175, AF_ADJUST_UP }, /* ⅵ */
   1061    { 0x2176, AF_ADJUST_UP }, /* ⅶ */
   1062    { 0x2177, AF_ADJUST_UP }, /* ⅷ */
   1063    { 0x2178, AF_ADJUST_UP }, /* ⅸ */
   1064    { 0x217A, AF_ADJUST_UP }, /* ⅺ */
   1065    { 0x217B, AF_ADJUST_UP }, /* ⅻ */
   1066 
   1067    /* Latin Extended-C */
   1068    { 0x2C64, AF_IGNORE_CAPITAL_BOTTOM } , /* Ɽ */
   1069    { 0x2C67, AF_IGNORE_CAPITAL_BOTTOM } , /* Ⱨ */
   1070    { 0x2C68, AF_IGNORE_SMALL_BOTTOM } , /* ⱨ */
   1071    { 0x2C69, AF_IGNORE_CAPITAL_BOTTOM } , /* Ⱪ */
   1072    { 0x2C6A, AF_IGNORE_SMALL_BOTTOM } , /* ⱪ */
   1073    { 0x2C6B, AF_IGNORE_CAPITAL_BOTTOM } , /* Ⱬ */
   1074    { 0x2C6C, AF_IGNORE_SMALL_BOTTOM } , /* ⱬ */
   1075    { 0x2C6E, AF_IGNORE_CAPITAL_BOTTOM } , /* Ɱ */
   1076 
   1077    { 0x2C7C, AF_ADJUST_UP }, /* ⱼ */
   1078    { 0x2C7E, AF_IGNORE_CAPITAL_BOTTOM } , /* Ȿ */
   1079    { 0x2C7F, AF_IGNORE_CAPITAL_BOTTOM } , /* Ɀ */
   1080 
   1081    /* Coptic */
   1082    { 0x2CC2, AF_ADJUST_UP }, /* Ⳃ */
   1083    { 0x2CC3, AF_ADJUST_UP }, /* ⳃ */
   1084 
   1085    /* Supplemental Punctuation */
   1086    { 0x2E18, AF_ADJUST_UP }, /* ⸘ */
   1087 
   1088    { 0x2E2E, AF_ADJUST_UP | AF_ADJUST_NO_HEIGHT_CHECK }, /* ⸮ */
   1089 
   1090    /* Cyrillic Extended-B */
   1091    { 0xA640, AF_IGNORE_CAPITAL_BOTTOM } , /* Ꙁ */
   1092    { 0xA641, AF_IGNORE_SMALL_BOTTOM } , /* ꙁ */
   1093    { 0xA642, AF_IGNORE_CAPITAL_BOTTOM } , /* Ꙃ */
   1094    { 0xA643, AF_IGNORE_SMALL_BOTTOM } , /* ꙃ */
   1095 
   1096    { 0xA680, AF_IGNORE_CAPITAL_TOP } , /* Ꚁ */
   1097    { 0xA681, AF_IGNORE_SMALL_TOP } , /* ꚁ */
   1098    { 0xA688, AF_IGNORE_CAPITAL_BOTTOM } , /* Ꚉ */
   1099    { 0xA689, AF_IGNORE_SMALL_BOTTOM } , /* ꚉ */
   1100    { 0xA68A, AF_IGNORE_CAPITAL_BOTTOM } , /* Ꚋ */
   1101    { 0xA68B, AF_IGNORE_SMALL_BOTTOM } , /* ꚋ */
   1102    { 0xA68E, AF_IGNORE_CAPITAL_BOTTOM } , /* Ꚏ */
   1103    { 0xA68F, AF_IGNORE_SMALL_BOTTOM } , /* ꚏ */
   1104 
   1105    { 0xA690, AF_IGNORE_CAPITAL_BOTTOM } , /* Ꚑ */
   1106    { 0xA691, AF_IGNORE_SMALL_BOTTOM } , /* ꚑ */
   1107    { 0xA696, AF_IGNORE_CAPITAL_BOTTOM } , /* Ꚗ */
   1108    { 0xA697, AF_IGNORE_SMALL_BOTTOM } , /* ꚗ */
   1109 
   1110    /* Latin Extended-D */
   1111    { 0xA726, AF_IGNORE_CAPITAL_BOTTOM } , /* Ꜧ */
   1112    { 0xA727, AF_IGNORE_SMALL_BOTTOM } , /* ꜧ */
   1113 
   1114    { 0xA756, AF_IGNORE_CAPITAL_BOTTOM } , /* Ꝗ */
   1115    { 0xA758, AF_IGNORE_CAPITAL_BOTTOM } , /* Ꝙ */
   1116 
   1117    { 0xA771, AF_IGNORE_SMALL_BOTTOM } , /* ꝱ */
   1118    { 0xA772, AF_IGNORE_SMALL_BOTTOM } , /* ꝲ */
   1119    { 0xA773, AF_IGNORE_SMALL_BOTTOM } , /* ꝳ */
   1120    { 0xA774, AF_IGNORE_SMALL_BOTTOM } , /* ꝴ */
   1121    { 0xA776, AF_IGNORE_SMALL_BOTTOM } , /* ꝶ */
   1122 
   1123    { 0xA790, AF_IGNORE_CAPITAL_BOTTOM } , /* Ꞑ */
   1124    { 0xA791, AF_IGNORE_SMALL_BOTTOM } , /* ꞑ */
   1125    { 0xA794, AF_IGNORE_SMALL_BOTTOM } , /* ꞔ */
   1126    { 0xA795, AF_IGNORE_SMALL_BOTTOM } , /* ꞕ */
   1127 
   1128    { 0xA7C0, AF_IGNORE_CAPITAL_TOP | AF_IGNORE_CAPITAL_BOTTOM }, /* Ꟁ */
   1129    { 0xA7C1, AF_IGNORE_SMALL_TOP | AF_IGNORE_SMALL_BOTTOM }, /* ꟁ */
   1130    { 0xA7C4, AF_IGNORE_CAPITAL_BOTTOM } , /* Ꞔ */
   1131    { 0xA7C5, AF_IGNORE_CAPITAL_BOTTOM } , /* Ʂ */
   1132    { 0xA7C6, AF_IGNORE_CAPITAL_BOTTOM } , /* Ᶎ */
   1133    { 0xA7CC, AF_IGNORE_CAPITAL_TOP | AF_IGNORE_CAPITAL_BOTTOM }, /* Ꟍ */
   1134    { 0xA7CD, AF_IGNORE_SMALL_TOP | AF_IGNORE_SMALL_BOTTOM }, /* ꟍ */
   1135 
   1136    /* Latin Extended-E */
   1137    { 0xAB3C, AF_IGNORE_SMALL_BOTTOM } , /* ꬼ */
   1138 
   1139    { 0xAB46, AF_IGNORE_SMALL_BOTTOM } , /* ꭆ */
   1140 
   1141    { 0xAB5C, AF_IGNORE_SMALL_BOTTOM } , /* ꭜ */
   1142 
   1143    { 0xAB66, AF_IGNORE_SMALL_BOTTOM } , /* ꭦ */
   1144    { 0xAB67, AF_IGNORE_SMALL_BOTTOM } , /* ꭧ */
   1145  };
   1146 
   1147 
   1148  FT_LOCAL_DEF( FT_UInt32 )
   1149  af_adjustment_database_lookup( FT_UInt32  codepoint )
   1150  {
   1151    /* Binary search for database entry */
   1152    FT_Offset  low  = 0;
   1153    FT_Offset  high = AF_ADJUSTMENT_DATABASE_LENGTH - 1;
   1154 
   1155 
   1156    while ( high >= low )
   1157    {
   1158      FT_Offset  mid           = ( low + high ) / 2;
   1159      FT_UInt32  mid_codepoint = adjustment_database[mid].codepoint;
   1160 
   1161 
   1162      if ( mid_codepoint < codepoint )
   1163        low = mid + 1;
   1164      else if ( mid_codepoint > codepoint )
   1165        high = mid - 1;
   1166      else
   1167        return adjustment_database[mid].flags;
   1168    }
   1169 
   1170    return 0;
   1171  }
   1172 
   1173 
   1174 #ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
   1175 
   1176  static FT_Error
   1177  add_substitute( FT_Int     glyph_idx,
   1178                  size_t     value,
   1179                  FT_UInt32  codepoint,
   1180                  FT_Hash    reverse_map,
   1181                  FT_Hash    subst_map,
   1182                  FT_Memory  memory )
   1183  {
   1184    FT_Error  error;
   1185 
   1186    FT_Int  first_substitute = (FT_Int)( value & 0xFFFF );
   1187 
   1188    FT_UInt  used = reverse_map->used;
   1189 
   1190 
   1191    /*
   1192      OpenType features like 'unic' map lowercase letter glyphs to uppercase
   1193      forms (and vice versa), which could lead to the use of wrong entries
   1194      in the adjustment database.  For this reason we don't overwrite,
   1195      prioritizing cmap entries.
   1196 
   1197      XXX Note, however, that this cannot cover all cases since there might
   1198      be contradictory entries for glyphs not in the cmap.  A possible
   1199      solution might be to specially mark pairs of related lowercase and
   1200      uppercase characters in the adjustment database that have diacritics
   1201      on different vertical sides (for example, U+0122 'Ģ' and U+0123 'ģ').
   1202      The auto-hinter could then perform a topological analysis to do the
   1203      right thing.
   1204    */
   1205    error = ft_hash_num_insert_no_overwrite( first_substitute, codepoint,
   1206                                             reverse_map, memory );
   1207    if ( error )
   1208      return error;
   1209 
   1210    if ( reverse_map->used > used )
   1211    {
   1212      size_t*  subst = ft_hash_num_lookup( first_substitute, subst_map );
   1213 
   1214 
   1215      if ( subst )
   1216      {
   1217        error = add_substitute( first_substitute, *subst, codepoint,
   1218                                reverse_map, subst_map, memory );
   1219        if ( error )
   1220          return error;
   1221      }
   1222    }
   1223 
   1224    /* The remaining substitutes. */
   1225    if ( value & 0xFFFF0000U )
   1226    {
   1227      FT_UInt  num_substitutes = value >> 16;
   1228 
   1229      FT_UInt  i;
   1230 
   1231 
   1232      for ( i = 1; i <= num_substitutes; i++ )
   1233      {
   1234        FT_Int   idx        = glyph_idx + (FT_Int)( i << 16 );
   1235        size_t*  substitute = ft_hash_num_lookup( idx, subst_map );
   1236 
   1237 
   1238        used = reverse_map->used;
   1239 
   1240        error = ft_hash_num_insert_no_overwrite( *substitute,
   1241                                                 codepoint,
   1242                                                 reverse_map,
   1243                                                 memory );
   1244        if ( error )
   1245          return error;
   1246 
   1247        if ( reverse_map->used > used )
   1248        {
   1249          size_t*  subst = ft_hash_num_lookup( *substitute, subst_map );
   1250 
   1251 
   1252          if ( subst )
   1253          {
   1254            error = add_substitute( *substitute, *subst, codepoint,
   1255                                    reverse_map, subst_map, memory );
   1256            if ( error )
   1257              return error;
   1258          }
   1259        }
   1260      }
   1261    }
   1262 
   1263    return FT_Err_Ok;
   1264  }
   1265 
   1266 #endif /* FT_CONFIG_OPTION_USE_HARFBUZZ */
   1267 
   1268 
   1269  /* Construct a 'reverse cmap' (i.e., a mapping from glyph indices to   */
   1270  /* character codes) for all glyphs that an input code point could turn */
   1271  /* into.                                                               */
   1272  /*                                                                     */
   1273  /* If HarfBuzz support is not available, this is the direct inversion  */
   1274  /* of the cmap table, otherwise the mapping gets extended with data    */
   1275  /* from the 'GSUB' table.                                              */
   1276  FT_LOCAL_DEF( FT_Error )
   1277  af_reverse_character_map_new( FT_Hash         *map,
   1278                                AF_StyleMetrics  metrics )
   1279  {
   1280    FT_Error  error;
   1281 
   1282    AF_FaceGlobals  globals = metrics->globals;
   1283    FT_Face         face    = globals->face;
   1284    FT_Memory       memory  = face->memory;
   1285 
   1286    FT_CharMap  old_charmap;
   1287 
   1288    FT_UInt32  codepoint;
   1289    FT_Offset  i;
   1290 
   1291 
   1292    FT_TRACE4(( "af_reverse_character_map_new:"
   1293                " building reverse character map (style `%s')\n",
   1294                af_style_names[metrics->style_class->style] ));
   1295 
   1296    /* Search for a unicode charmap.           */
   1297    /* If there isn't one, create a blank map. */
   1298 
   1299    /* Back up `face->charmap` because `find_unicode_charmap` sets it. */
   1300    old_charmap = face->charmap;
   1301 
   1302    if ( ( error = find_unicode_charmap( face ) ) )
   1303      goto Exit;
   1304 
   1305    *map = NULL;
   1306    if ( FT_QNEW( *map ) )
   1307      goto Exit;
   1308 
   1309    error = ft_hash_num_init( *map, memory );
   1310    if ( error )
   1311      goto Exit;
   1312 
   1313    /* Initialize reverse cmap with data directly from the cmap table. */
   1314    for ( i = 0; i < AF_ADJUSTMENT_DATABASE_LENGTH; i++ )
   1315    {
   1316      FT_Int  cmap_glyph;
   1317 
   1318 
   1319      /*
   1320        We cannot restrict `codepoint` to character ranges; we have no
   1321        control what data the script-specific portion of the GSUB table
   1322        actually holds.
   1323 
   1324        An example is `arial.ttf` version 7.00; in this font, there are
   1325        lookups for Cyrillic (lookup 43), Greek (lookup 44), and Latin
   1326        (lookup 45) that map capital letter glyphs to small capital glyphs.
   1327        It is tempting to expect that script-specific versions of the 'c2sc'
   1328        feature only use script-specific lookups.  However, this is not the
   1329        case in this font: the feature uses all three lookups regardless of
   1330        the script.
   1331 
   1332        The auto-hinter, while assigning glyphs to styles, uses the first
   1333        coverage result it encounters for a particular glyph.  For example,
   1334        if the coverage for Cyrillic is tested before Latin (as is currently
   1335        the case), glyphs without a cmap entry that are covered in 'c2sc'
   1336        are treated as Cyrillic.
   1337 
   1338        If we now look at glyph 3498, which is a small-caps version of the
   1339        Latin character 'A grave' (U+00C0, glyph 172), we can see that it is
   1340        registered as belonging to a Cyrillic style due to the algorithm
   1341        just described.  As a result, checking only for characters from the
   1342        Latin range would miss this glyph; we thus have to test all
   1343        character codes in the database.
   1344      */
   1345      codepoint = adjustment_database[i].codepoint;
   1346 
   1347      cmap_glyph = (FT_Int)FT_Get_Char_Index( face, codepoint );
   1348      if ( cmap_glyph == 0 )
   1349        continue;
   1350 
   1351      error = ft_hash_num_insert( cmap_glyph, codepoint, *map, memory );
   1352      if ( error )
   1353        goto Exit;
   1354    }
   1355 
   1356 #ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
   1357 
   1358    if ( ft_hb_enabled( globals ) )
   1359    {
   1360      hb_font_t  *hb_font;
   1361      hb_face_t  *hb_face;
   1362 
   1363      hb_set_t    *gsub_lookups;
   1364      hb_script_t  script;
   1365 
   1366      unsigned int  script_count   = 1;
   1367      hb_tag_t      script_tags[2] = { HB_TAG_NONE, HB_TAG_NONE };
   1368 
   1369      FT_Hash  subst_map = NULL;
   1370 
   1371      hb_codepoint_t  idx;
   1372      FT_UInt         hash_idx;
   1373      FT_Int          glyph_idx;
   1374      size_t          value;
   1375 
   1376 
   1377      /* No need to check whether HarfBuzz has allocation issues; */
   1378      /* it continues to work in such cases and simply returns    */
   1379      /* 'empty' objects that do nothing.                         */
   1380 
   1381      hb_font = globals->hb_font;
   1382      hb_face = hb( font_get_face )( hb_font );
   1383 
   1384      gsub_lookups = hb( set_create )();
   1385 
   1386      script = af_hb_scripts[metrics->style_class->script];
   1387 
   1388      hb( ot_tags_from_script_and_language )( script, NULL,
   1389                                              &script_count, script_tags,
   1390                                              NULL, NULL );
   1391 
   1392      /* Compute set of all script-specific GSUB lookups. */
   1393      hb( ot_layout_collect_lookups )( hb_face,
   1394                                       HB_OT_TAG_GSUB,
   1395                                       script_tags, NULL, NULL,
   1396                                       gsub_lookups );
   1397 
   1398 #ifdef FT_DEBUG_LEVEL_TRACE
   1399      {
   1400        FT_Bool  have_idx = FALSE;
   1401 
   1402 
   1403        FT_TRACE4(( "  GSUB lookups to check:\n" ));
   1404 
   1405        FT_TRACE4(( "  " ));
   1406        idx = HB_SET_VALUE_INVALID;
   1407        while ( hb( set_next )( gsub_lookups, &idx ) )
   1408          if ( globals->gsub_lookups_single_alternate[idx] )
   1409          {
   1410            have_idx = TRUE;
   1411            FT_TRACE4(( "  %u", idx ));
   1412          }
   1413        if ( !have_idx )
   1414          FT_TRACE4(( "  (none)" ));
   1415        FT_TRACE4(( "\n" ));
   1416 
   1417        FT_TRACE4(( "\n" ));
   1418      }
   1419 #endif
   1420 
   1421      if ( FT_QNEW( subst_map ) )
   1422        goto Exit_HarfBuzz;
   1423 
   1424      error = ft_hash_num_init( subst_map, memory );
   1425      if ( error )
   1426        goto Exit_HarfBuzz;
   1427 
   1428      idx = HB_SET_VALUE_INVALID;
   1429      while ( hb( set_next )( gsub_lookups, &idx ) )
   1430      {
   1431        FT_UInt32  offset = globals->gsub_lookups_single_alternate[idx];
   1432 
   1433 
   1434        /* Put all substitutions into a single hash table.  Note that   */
   1435        /* the hash values usually contain more than a single character */
   1436        /* code; this can happen if different 'SingleSubst' subtables   */
   1437        /* map a given glyph index to different substitutions, or if    */
   1438        /* 'AlternateSubst' subtable entries are present.               */
   1439        if ( offset )
   1440          af_map_lookup( globals, subst_map, offset );
   1441      }
   1442 
   1443      /*
   1444        Now iterate over the collected substitution data in `subst_map`
   1445        (using recursion to resolve one-to-many mappings) and insert the
   1446        data into the reverse cmap.
   1447 
   1448        As an example, suppose we have the following cmap and substitution
   1449        data:
   1450 
   1451          cmap: X -> a
   1452                Y -> b
   1453                Z -> c
   1454 
   1455          substitutions: a -> b
   1456                         b -> c, d
   1457                         d -> e
   1458 
   1459        The reverse map now becomes as follows.
   1460 
   1461          a -> X
   1462          b -> Y
   1463          c -> Z (via cmap, ignoring mapping from 'b')
   1464          d -> Y (via 'b')
   1465          e -> Y (via 'b' and 'd')
   1466      */
   1467 
   1468      hash_idx = 0;
   1469      while ( ft_hash_num_iterator( &hash_idx,
   1470                                    &glyph_idx,
   1471                                    &value,
   1472                                    subst_map ) )
   1473      {
   1474        size_t*  val;
   1475 
   1476 
   1477        /* Ignore keys that do not point to the first substitute. */
   1478        if ( (FT_UInt)glyph_idx & 0xFFFF0000U )
   1479          continue;
   1480 
   1481        /* Ignore glyph indices that are not related to accents. */
   1482        val = ft_hash_num_lookup( glyph_idx, *map );
   1483        if ( !val )
   1484          continue;
   1485 
   1486        codepoint = *val;
   1487 
   1488        error = add_substitute( glyph_idx, value, codepoint,
   1489                                *map, subst_map, memory );
   1490        if ( error )
   1491          break;
   1492      }
   1493 
   1494    Exit_HarfBuzz:
   1495      hb( set_destroy )( gsub_lookups );
   1496 
   1497      ft_hash_num_free( subst_map, memory );
   1498      FT_FREE( subst_map );
   1499 
   1500      if ( error )
   1501        goto Exit;
   1502    }
   1503 
   1504 #endif /* FT_CONFIG_OPTION_USE_HARFBUZZ */
   1505 
   1506    FT_TRACE4(( "    reverse character map built successfully"
   1507                " with %u entries\n", ( *map )->used ));
   1508 
   1509 #ifdef FT_DEBUG_LEVEL_TRACE
   1510 
   1511    {
   1512      FT_UInt  cnt;
   1513 
   1514 
   1515      FT_TRACE7(( "       gidx   code    flags\n" ));
   1516               /* "      XXXXX  0xXXXX  XXXXXXXXXXX..." */
   1517      FT_TRACE7(( "     ------------------------------\n" ));
   1518 
   1519      for ( cnt = 0; cnt < globals->glyph_count; cnt++ )
   1520      {
   1521        size_t*    val;
   1522        FT_UInt32  adj_type;
   1523 
   1524        const char*  flag_names[] =
   1525        {
   1526          "up",          /* AF_ADJUST_UP    */
   1527          "down",        /* AF_ADJUST_DOWN  */
   1528          "double up",   /* AF_ADJUST_UP2   */
   1529          "double down", /* AF_ADJUST_DOWN2 */
   1530 
   1531          "top tilde",          /* AF_ADJUST_TILDE_TOP     */
   1532          "bottom tilde",       /* AF_ADJUST_TILDE_BOTTOM  */
   1533          "below-top tilde",    /* AF_ADJUST_TILDE_TOP2    */
   1534          "above-bottom tilde", /* AF_ADJUST_TILDE_BOTTOM2 */
   1535 
   1536          "ignore capital top",    /* AF_IGNORE_CAPITAL_TOP    */
   1537          "ignore capital bottom", /* AF_IGNORE_CAPITAL_BOTTOM */
   1538          "ignore small top",      /* AF_IGNORE_SMALL_TOP      */
   1539          "ignore small bottom",   /* AF_IGNORE_SMALL_BOTTOM   */
   1540        };
   1541        size_t  flag_names_size = sizeof ( flag_names ) / sizeof ( char* );
   1542 
   1543        char  flag_str[256];
   1544        int   need_comma;
   1545 
   1546        size_t  j;
   1547 
   1548 
   1549        val = ft_hash_num_lookup( (FT_Int)cnt, *map );
   1550        if ( !val )
   1551          continue;
   1552        codepoint = *val;
   1553 
   1554        adj_type = af_adjustment_database_lookup( codepoint );
   1555        if ( !adj_type )
   1556          continue;
   1557 
   1558        flag_str[0] = '\0';
   1559        need_comma  = 0;
   1560 
   1561        for ( j = 0; j < flag_names_size; j++ )
   1562        {
   1563          if ( adj_type & (1 << j ) )
   1564          {
   1565            if ( !need_comma )
   1566              need_comma = 1;
   1567            else
   1568              strcat( flag_str, ", " );
   1569            strcat( flag_str, flag_names[j] );
   1570          }
   1571        }
   1572 
   1573        FT_TRACE7(( "      %5u  0x%04X  %s\n", cnt, codepoint, flag_str ));
   1574      }
   1575    }
   1576 
   1577 #endif /* FT_DEBUG_LEVEL_TRACE */
   1578 
   1579 
   1580  Exit:
   1581    face->charmap = old_charmap;
   1582 
   1583    if ( error )
   1584    {
   1585      FT_TRACE4(( "    error while building reverse character map."
   1586                  " Using blank map.\n" ));
   1587 
   1588      if ( *map )
   1589        ft_hash_num_free( *map, memory );
   1590 
   1591      FT_FREE( *map );
   1592      *map = NULL;
   1593      return error;
   1594    }
   1595 
   1596    return FT_Err_Ok;
   1597  }
   1598 
   1599 
   1600  FT_LOCAL_DEF( FT_Error )
   1601  af_reverse_character_map_done( FT_Hash    map,
   1602                                 FT_Memory  memory )
   1603  {
   1604    if ( map )
   1605      ft_hash_num_free( map, memory );
   1606    FT_FREE( map );
   1607 
   1608    return FT_Err_Ok;
   1609  }
   1610 
   1611 
   1612 /* END */