1 /*
   2  * Copyright © 2018  Google, Inc.
   3  *
   4  *  This is part of HarfBuzz, a text shaping library.
   5  *
   6  * Permission is hereby granted, without written agreement and without
   7  * license or royalty fees, to use, copy, modify, and distribute this
   8  * software and its documentation for any purpose, provided that the
   9  * above copyright notice and the following two paragraphs appear in
  10  * all copies of this software.
  11  *
  12  * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
  13  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
  14  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
  15  * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
  16  * DAMAGE.
  17  *
  18  * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
  19  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  20  * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  21  * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
  22  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  23  *
  24  * Google Author(s): Behdad Esfahbod
  25  */
  26 
  27 #include "hb-ot-name-language.hh"
  28 
  29 /* Following two tables were generated by joining FreeType, FontConfig,
  30  * and OpenType specification language lists, then filled in missing
  31  * entries using:
  32  * https://docs.microsoft.com/en-us/windows/desktop/intl/language-identifier-constants-and-strings
  33  */
  34 
  35 struct hb_ot_language_map_t
  36 {
  37   static int cmp (const void *key, const void *item)
  38   {
  39     unsigned int a = * (unsigned int *) key;
  40     unsigned int b = ((const hb_ot_language_map_t *) item)->code;
  41     return a < b ? -1 : a > b ? +1 : 0;
  42   }
  43 
  44   uint16_t      code;
  45   char          lang[6];
  46 };
  47 
  48 static const hb_ot_language_map_t
  49 hb_ms_language_map[] =
  50 {
  51   {0x0001,      "ar"},  /* ??? */
  52   {0x0004,      "zh"},  /* ??? */
  53   {0x0009,      "en"},  /* ??? */
  54   {0x0401,      "ar"},  /* Arabic (Saudi Arabia) */
  55   {0x0402,      "bg"},  /* Bulgarian (Bulgaria) */
  56   {0x0403,      "ca"},  /* Catalan (Catalan) */
  57   {0x0404,      "zh-tw"},       /* Chinese (Taiwan) */
  58   {0x0405,      "cs"},  /* Czech (Czech Republic) */
  59   {0x0406,      "da"},  /* Danish (Denmark) */
  60   {0x0407,      "de"},  /* German (Germany) */
  61   {0x0408,      "el"},  /* Greek (Greece) */
  62   {0x0409,      "en"},  /* English (United States) */
  63   {0x040A,      "es"},  /* Spanish (Traditional Sort) (Spain) */
  64   {0x040B,      "fi"},  /* Finnish (Finland) */
  65   {0x040C,      "fr"},  /* French (France) */
  66   {0x040D,      "he"},  /* Hebrew (Israel) */
  67   {0x040E,      "hu"},  /* Hungarian (Hungary) */
  68   {0x040F,      "is"},  /* Icelandic (Iceland) */
  69   {0x0410,      "it"},  /* Italian (Italy) */
  70   {0x0411,      "ja"},  /* Japanese (Japan) */
  71   {0x0412,      "ko"},  /* Korean (Korea) */
  72   {0x0413,      "nl"},  /* Dutch (Netherlands) */
  73   {0x0414,      "no"},  /* Norwegian (Bokmal) (Norway) */
  74   {0x0415,      "pl"},  /* Polish (Poland) */
  75   {0x0416,      "pt"},  /* Portuguese (Brazil) */
  76   {0x0417,      "rm"},  /* Romansh (Switzerland) */
  77   {0x0418,      "ro"},  /* Romanian (Romania) */
  78   {0x0419,      "ru"},  /* Russian (Russia) */
  79   {0x041A,      "hr"},  /* Croatian (Croatia) */
  80   {0x041B,      "sk"},  /* Slovak (Slovakia) */
  81   {0x041C,      "sq"},  /* Albanian (Albania) */
  82   {0x041D,      "sv"},  /* Swedish (Sweden) */
  83   {0x041E,      "th"},  /* Thai (Thailand) */
  84   {0x041F,      "tr"},  /* Turkish (Turkey) */
  85   {0x0420,      "ur"},  /* Urdu (Islamic Republic of Pakistan) */
  86   {0x0421,      "id"},  /* Indonesian (Indonesia) */
  87   {0x0422,      "uk"},  /* Ukrainian (Ukraine) */
  88   {0x0423,      "be"},  /* Belarusian (Belarus) */
  89   {0x0424,      "sl"},  /* Slovenian (Slovenia) */
  90   {0x0425,      "et"},  /* Estonian (Estonia) */
  91   {0x0426,      "lv"},  /* Latvian (Latvia) */
  92   {0x0427,      "lt"},  /* Lithuanian (Lithuania) */
  93   {0x0428,      "tg"},  /* Tajik (Cyrillic) (Tajikistan) */
  94   {0x0429,      "fa"},  /* Persian (Iran) */
  95   {0x042A,      "vi"},  /* Vietnamese (Vietnam) */
  96   {0x042B,      "hy"},  /* Armenian (Armenia) */
  97   {0x042C,      "az"},  /* Azeri (Latin) (Azerbaijan) */
  98   {0x042D,      "eu"},  /* Basque (Basque) */
  99   {0x042E,      "hsb"}, /* Upper Sorbian (Germany) */
 100   {0x042F,      "mk"},  /* Macedonian (FYROM) (Former Yugoslav Republic of Macedonia) */
 101   {0x0430,      "st"},  /* ??? */
 102   {0x0431,      "ts"},  /* ??? */
 103   {0x0432,      "tn"},  /* Setswana (South Africa) */
 104   {0x0433,      "ven"}, /* ??? */
 105   {0x0434,      "xh"},  /* isiXhosa (South Africa) */
 106   {0x0435,      "zu"},  /* isiZulu (South Africa) */
 107   {0x0436,      "af"},  /* Afrikaans (South Africa) */
 108   {0x0437,      "ka"},  /* Georgian (Georgia) */
 109   {0x0438,      "fo"},  /* Faroese (Faroe Islands) */
 110   {0x0439,      "hi"},  /* Hindi (India) */
 111   {0x043A,      "mt"},  /* Maltese (Malta) */
 112   {0x043B,      "se"},  /* Sami (Northern) (Norway) */
 113   {0x043C,      "ga"},  /* ??? */
 114   {0x043D,      "yi"},  /* ??? */
 115   {0x043E,      "ms"},  /* Malay (Malaysia) */
 116   {0x043F,      "kk"},  /* Kazakh (Kazakhstan) */
 117   {0x0440,      "ky"},  /* Kyrgyz (Kyrgyzstan) */
 118   {0x0441,      "sw"},  /* Kiswahili (Kenya) */
 119   {0x0442,      "tk"},  /* Turkmen (Turkmenistan) */
 120   {0x0443,      "uz"},  /* Uzbek (Latin) (Uzbekistan) */
 121   {0x0444,      "tt"},  /* Tatar (Russia) */
 122   {0x0445,      "bn"},  /* Bengali (India) */
 123   {0x0446,      "pa"},  /* Punjabi (India) */
 124   {0x0447,      "gu"},  /* Gujarati (India) */
 125   {0x0448,      "or"},  /* Odia (formerly Oriya) (India) */
 126   {0x0449,      "ta"},  /* Tamil (India) */
 127   {0x044A,      "te"},  /* Telugu (India) */
 128   {0x044B,      "kn"},  /* Kannada (India) */
 129   {0x044C,      "ml"},  /* Malayalam (India) */
 130   {0x044D,      "as"},  /* Assamese (India) */
 131   {0x044E,      "mr"},  /* Marathi (India) */
 132   {0x044F,      "sa"},  /* Sanskrit (India) */
 133   {0x0450,      "mn"},  /* Mongolian (Cyrillic) (Mongolia) */
 134   {0x0451,      "bo"},  /* Tibetan (PRC) */
 135   {0x0452,      "cy"},  /* Welsh (United Kingdom) */
 136   {0x0453,      "km"},  /* Khmer (Cambodia) */
 137   {0x0454,      "lo"},  /* Lao (Lao P.D.R.) */
 138   {0x0455,      "my"},  /* ??? */
 139   {0x0456,      "gl"},  /* Galician (Galician) */
 140   {0x0457,      "kok"}, /* Konkani (India) */
 141   {0x0458,      "mni"}, /* ??? */
 142   {0x0459,      "sd"},  /* ??? */
 143   {0x045A,      "syr"}, /* Syriac (Syria) */
 144   {0x045B,      "si"},  /* Sinhala (Sri Lanka) */
 145   {0x045C,      "chr"}, /* ??? */
 146   {0x045D,      "iu"},  /* Inuktitut (Canada) */
 147   {0x045E,      "am"},  /* Amharic (Ethiopia) */
 148   {0x0460,      "ks"},  /* ??? */
 149   {0x0461,      "ne"},  /* Nepali (Nepal) */
 150   {0x0462,      "fy"},  /* Frisian (Netherlands) */
 151   {0x0463,      "ps"},  /* Pashto (Afghanistan) */
 152   {0x0464,      "phi"}, /* Filipino (Philippines) */
 153   {0x0465,      "div"}, /* Divehi (Maldives) */
 154   {0x0468,      "ha"},  /* Hausa (Latin) (Nigeria) */
 155   {0x046A,      "yo"},  /* Yoruba (Nigeria) */
 156   {0x046B,      "quz"}, /* Quechua (Bolivia) */
 157   {0x046C,      "nso"}, /* Sesotho sa Leboa (South Africa) */
 158   {0x046D,      "ba"},  /* Bashkir (Russia) */
 159   {0x046E,      "lb"},  /* Luxembourgish (Luxembourg) */
 160   {0x046F,      "kl"},  /* Greenlandic (Greenland) */
 161   {0x0470,      "ibo"}, /* Igbo (Nigeria) */
 162   {0x0471,      "kau"}, /* ??? */
 163   {0x0472,      "om"},  /* ??? */
 164   {0x0473,      "ti"},  /* ??? */
 165   {0x0474,      "gn"},  /* ??? */
 166   {0x0475,      "haw"}, /* ??? */
 167   {0x0476,      "la"},  /* ??? */
 168   {0x0477,      "so"},  /* ??? */
 169   {0x0478,      "ii"},  /* Yi (PRC) */
 170   {0x0479,      "pap"}, /* ??? */
 171   {0x047A,      "arn"}, /* Mapudungun (Chile) */
 172   {0x047C,      "moh"}, /* Mohawk (Mohawk) */
 173   {0x047E,      "br"},  /* Breton (France) */
 174   {0x0480,      "ug"},  /* Uighur (PRC) */
 175   {0x0481,      "mi"},  /* Maori (New Zealand) */
 176   {0x0482,      "oc"},  /* Occitan (France) */
 177   {0x0483,      "co"},  /* Corsican (France) */
 178   {0x0484,      "gsw"}, /* Alsatian (France) */
 179   {0x0485,      "sah"}, /* Yakut (Russia) */
 180   {0x0486,      "qut"}, /* K'iche (Guatemala) */
 181   {0x0487,      "rw"},  /* Kinyarwanda (Rwanda) */
 182   {0x0488,      "wo"},  /* Wolof (Senegal) */
 183   {0x048C,      "fa"},  /* Dari (Afghanistan) */
 184   {0x0801,      "ar"},  /* Arabic (Iraq) */
 185   {0x0804,      "zh-cn"},       /* Chinese (People’s Republic of China) */
 186   {0x0807,      "de"},  /* German (Switzerland) */
 187   {0x0809,      "en"},  /* English (United Kingdom) */
 188   {0x080A,      "es"},  /* Spanish (Mexico) */
 189   {0x080C,      "fr"},  /* French (Belgium) */
 190   {0x0810,      "it"},  /* Italian (Switzerland) */
 191   {0x0812,      "ko"},  /* ??? */
 192   {0x0813,      "nl"},  /* Dutch (Belgium) */
 193   {0x0814,      "nn"},  /* Norwegian (Nynorsk) (Norway) */
 194   {0x0816,      "pt"},  /* Portuguese (Portugal) */
 195   {0x0818,      "mo"},  /* ??? */
 196   {0x0819,      "ru"},  /* ??? */
 197   {0x081A,      "sr"},  /* Serbian (Latin) (Serbia) */
 198   {0x081D,      "sv"},  /* Sweden (Finland) */
 199   {0x0820,      "ur"},  /* ??? */
 200   {0x0827,      "lt"},  /* ??? */
 201   {0x082C,      "az"},  /* Azeri (Cyrillic) (Azerbaijan) */
 202   {0x082E,      "dsb"}, /* Lower Sorbian (Germany) */
 203 //{0x083B,      ""},    /* Sami (Northern) (Sweden) */
 204   {0x083C,      "gd"},  /* Irish (Ireland) */
 205   {0x083E,      "ms"},  /* Malay (Brunei Darussalam) */
 206   {0x0843,      "uz"},  /* Uzbek (Cyrillic) (Uzbekistan) */
 207   {0x0845,      "bn"},  /* Bengali (Bangladesh) */
 208   {0x0846,      "ar"},  /* ??? */
 209   {0x0850,      "mn"},  /* Mongolian (Traditional) (People’s Republic of China) */
 210   {0x0851,      "dz"},  /* ??? */
 211   {0x085D,      "iu"},  /* Inuktitut (Latin) (Canada) */
 212   {0x085F,      "tzm"}, /* Tamazight (Latin) (Algeria) */
 213   {0x0861,      "ne"},  /* ??? */
 214 //{0x086B,      ""},    /* Quechua (Ecuador) */
 215   {0x0873,      "ti"},  /* ??? */
 216   {0x0C01,      "ar"},  /* Arabic (Egypt) */
 217   {0x0C04,      "zh-hk"},       /* Chinese (Hong Kong S.A.R.) */
 218   {0x0C07,      "de"},  /* German (Austria) */
 219   {0x0C09,      "en"},  /* English (Australia) */
 220   {0x0C0A,      "es"},  /* Spanish (Modern Sort) (Spain) */
 221   {0x0C0C,      "fr"},  /* French (Canada) */
 222   {0x0C1A,      "sr"},  /* Serbian (Cyrillic) (Serbia) */
 223   {0x0C3B,      "se"},  /* Sami (Northern) (Finland) */
 224 //{0x0C6B,      ""},    /* Quechua (Peru) */
 225   {0x1001,      "ar"},  /* Arabic (Libya) */
 226   {0x1004,      "zh-sg"},       /* Chinese (Singapore) */
 227   {0x1007,      "de"},  /* German (Luxembourg) */
 228   {0x1009,      "en"},  /* English (Canada) */
 229   {0x100A,      "es"},  /* Spanish (Guatemala) */
 230   {0x100C,      "fr"},  /* French (Switzerland) */
 231   {0x101A,      "hr"},  /* Croatian (Latin) (Bosnia and Herzegovina) */
 232   {0x103B,      "smj"}, /* Sami (Lule) (Norway) */
 233   {0x1401,      "ar"},  /* Arabic (Algeria) */
 234 //{0x1404,      ""},    /* Chinese (Macao S.A.R.) */
 235   {0x1407,      "de"},  /* German (Liechtenstein) */
 236   {0x1409,      "en"},  /* English (New Zealand) */
 237   {0x140A,      "es"},  /* Spanish (Costa Rica) */
 238   {0x140C,      "fr"},  /* French (Luxembourg) */
 239   {0x141A,      "bs"},  /* Bosnian (Latin) (Bosnia and Herzegovina) */
 240 //{0x143B,      ""},    /* Sami (Lule) (Sweden) */
 241   {0x1801,      "ar"},  /* Arabic (Morocco) */
 242   {0x1809,      "en"},  /* English (Ireland) */
 243   {0x180A,      "es"},  /* Spanish (Panama) */
 244   {0x180C,      "fr"},  /* French (Principality of Monaco) */
 245 //{0x181A,      ""},    /* Serbian (Latin) (Bosnia and Herzegovina) */
 246   {0x183B,      "sma"}, /* Sami (Southern) (Norway) */
 247   {0x1C01,      "ar"},  /* Arabic (Tunisia) */
 248   {0x1C09,      "en"},  /* English (South Africa) */
 249   {0x1C0A,      "es"},  /* Spanish (Dominican Republic) */
 250   {0x1C0C,      "fr"},  /* ??? */
 251 //{0x1C1A,      ""},    /* Serbian (Cyrillic) (Bosnia and Herzegovina) */
 252 //{0x1C3B,      ""},    /* Sami (Southern) (Sweden) */
 253   {0x2001,      "ar"},  /* Arabic (Oman) */
 254   {0x2009,      "en"},  /* English (Jamaica) */
 255   {0x200A,      "es"},  /* Spanish (Venezuela) */
 256   {0x200C,      "fr"},  /* ??? */
 257   {0x201A,      "bs"},  /* Bosnian (Cyrillic) (Bosnia and Herzegovina) */
 258   {0x203B,      "sms"}, /* Sami (Skolt) (Finland) */
 259   {0x2401,      "ar"},  /* Arabic (Yemen) */
 260   {0x2409,      "en"},  /* English (Caribbean) */
 261   {0x240A,      "es"},  /* Spanish (Colombia) */
 262   {0x240C,      "fr"},  /* ??? */
 263   {0x243B,      "smn"}, /* Sami (Inari) (Finland) */
 264   {0x2801,      "ar"},  /* Arabic (Syria) */
 265   {0x2809,      "en"},  /* English (Belize) */
 266   {0x280A,      "es"},  /* Spanish (Peru) */
 267   {0x280C,      "fr"},  /* ??? */
 268   {0x2C01,      "ar"},  /* Arabic (Jordan) */
 269   {0x2C09,      "en"},  /* English (Trinidad and Tobago) */
 270   {0x2C0A,      "es"},  /* Spanish (Argentina) */
 271   {0x2C0C,      "fr"},  /* ??? */
 272   {0x3001,      "ar"},  /* Arabic (Lebanon) */
 273   {0x3009,      "en"},  /* English (Zimbabwe) */
 274   {0x300A,      "es"},  /* Spanish (Ecuador) */
 275   {0x300C,      "fr"},  /* ??? */
 276   {0x3401,      "ar"},  /* Arabic (Kuwait) */
 277   {0x3409,      "en"},  /* English (Republic of the Philippines) */
 278   {0x340A,      "es"},  /* Spanish (Chile) */
 279   {0x340C,      "fr"},  /* ??? */
 280   {0x3801,      "ar"},  /* Arabic (U.A.E.) */
 281   {0x380A,      "es"},  /* Spanish (Uruguay) */
 282   {0x380C,      "fr"},  /* ??? */
 283   {0x3C01,      "ar"},  /* Arabic (Bahrain) */
 284   {0x3C09,      "en"},  /* ??? */
 285   {0x3C0A,      "es"},  /* Spanish (Paraguay) */
 286   {0x3C0C,      "fr"},  /* ??? */
 287   {0x4001,      "ar"},  /* Arabic (Qatar) */
 288   {0x4009,      "en"},  /* English (India) */
 289   {0x400A,      "es"},  /* Spanish (Bolivia) */
 290   {0x4409,      "en"},  /* English (Malaysia) */
 291   {0x440A,      "es"},  /* Spanish (El Salvador) */
 292   {0x4809,      "en"},  /* English (Singapore) */
 293   {0x480A,      "es"},  /* Spanish (Honduras) */
 294   {0x4C0A,      "es"},  /* Spanish (Nicaragua) */
 295   {0x500A,      "es"},  /* Spanish (Puerto Rico) */
 296   {0x540A,      "es"},  /* Spanish (United States) */
 297   {0xE40A,      "es"},  /* ??? */
 298   {0xE40C,      "fr"},  /* ??? */
 299 };
 300 
 301 static const hb_ot_language_map_t
 302 hb_mac_language_map[] =
 303 {
 304   {  0, "en"},  /* English */
 305   {  1, "fr"},  /* French */
 306   {  2, "de"},  /* German */
 307   {  3, "it"},  /* Italian */
 308   {  4, "nl"},  /* Dutch */
 309   {  5, "sv"},  /* Swedish */
 310   {  6, "es"},  /* Spanish */
 311   {  7, "da"},  /* Danish */
 312   {  8, "pt"},  /* Portuguese */
 313   {  9, "no"},  /* Norwegian */
 314   { 10, "he"},  /* Hebrew */
 315   { 11, "ja"},  /* Japanese */
 316   { 12, "ar"},  /* Arabic */
 317   { 13, "fi"},  /* Finnish */
 318   { 14, "el"},  /* Greek */
 319   { 15, "is"},  /* Icelandic */
 320   { 16, "mt"},  /* Maltese */
 321   { 17, "tr"},  /* Turkish */
 322   { 18, "hr"},  /* Croatian */
 323   { 19, "zh-tw"},       /* Chinese (Traditional) */
 324   { 20, "ur"},  /* Urdu */
 325   { 21, "hi"},  /* Hindi */
 326   { 22, "th"},  /* Thai */
 327   { 23, "ko"},  /* Korean */
 328   { 24, "lt"},  /* Lithuanian */
 329   { 25, "pl"},  /* Polish */
 330   { 26, "hu"},  /* Hungarian */
 331   { 27, "et"},  /* Estonian */
 332   { 28, "lv"},  /* Latvian */
 333 //{ 29, ""},    /* Sami */
 334   { 30, "fo"},  /* Faroese */
 335   { 31, "fa"},  /* Farsi/Persian */
 336   { 32, "ru"},  /* Russian */
 337   { 33, "zh-cn"},       /* Chinese (Simplified) */
 338   { 34, "nl"},  /* Flemish */
 339   { 35, "ga"},  /* Irish Gaelic */
 340   { 36, "sq"},  /* Albanian */
 341   { 37, "ro"},  /* Romanian */
 342   { 38, "cs"},  /* Czech */
 343   { 39, "sk"},  /* Slovak */
 344   { 40, "sl"},  /* Slovenian */
 345   { 41, "yi"},  /* Yiddish */
 346   { 42, "sr"},  /* Serbian */
 347   { 43, "mk"},  /* Macedonian */
 348   { 44, "bg"},  /* Bulgarian */
 349   { 45, "uk"},  /* Ukrainian */
 350   { 46, "be"},  /* Byelorussian */
 351   { 47, "uz"},  /* Uzbek */
 352   { 48, "kk"},  /* Kazakh */
 353   { 49, "az"},  /* Azerbaijani (Cyrillic script) */
 354   { 50, "az"},  /* Azerbaijani (Arabic script) */
 355   { 51, "hy"},  /* Armenian */
 356   { 52, "ka"},  /* Georgian */
 357   { 53, "mo"},  /* Moldavian */
 358   { 54, "ky"},  /* Kirghiz */
 359   { 55, "tg"},  /* Tajiki */
 360   { 56, "tk"},  /* Turkmen */
 361   { 57, "mn"},  /* Mongolian (Mongolian script) */
 362   { 58, "mn"},  /* Mongolian (Cyrillic script) */
 363   { 59, "ps"},  /* Pashto */
 364   { 60, "ku"},  /* Kurdish */
 365   { 61, "ks"},  /* Kashmiri */
 366   { 62, "sd"},  /* Sindhi */
 367   { 63, "bo"},  /* Tibetan */
 368   { 64, "ne"},  /* Nepali */
 369   { 65, "sa"},  /* Sanskrit */
 370   { 66, "mr"},  /* Marathi */
 371   { 67, "bn"},  /* Bengali */
 372   { 68, "as"},  /* Assamese */
 373   { 69, "gu"},  /* Gujarati */
 374   { 70, "pa"},  /* Punjabi */
 375   { 71, "or"},  /* Oriya */
 376   { 72, "ml"},  /* Malayalam */
 377   { 73, "kn"},  /* Kannada */
 378   { 74, "ta"},  /* Tamil */
 379   { 75, "te"},  /* Telugu */
 380   { 76, "si"},  /* Sinhalese */
 381   { 77, "my"},  /* Burmese */
 382   { 78, "km"},  /* Khmer */
 383   { 79, "lo"},  /* Lao */
 384   { 80, "vi"},  /* Vietnamese */
 385   { 81, "id"},  /* Indonesian */
 386   { 82, "tl"},  /* Tagalog */
 387   { 83, "ms"},  /* Malay (Roman script) */
 388   { 84, "ms"},  /* Malay (Arabic script) */
 389   { 85, "am"},  /* Amharic */
 390   { 86, "ti"},  /* Tigrinya */
 391   { 87, "om"},  /* Galla */
 392   { 88, "so"},  /* Somali */
 393   { 89, "sw"},  /* Swahili */
 394   { 90, "rw"},  /* Kinyarwanda/Ruanda */
 395   { 91, "rn"},  /* Rundi */
 396   { 92, "ny"},  /* Nyanja/Chewa */
 397   { 93, "mg"},  /* Malagasy */
 398   { 94, "eo"},  /* Esperanto */
 399   {128, "cy"},  /* Welsh */
 400   {129, "eu"},  /* Basque */
 401   {130, "ca"},  /* Catalan */
 402   {131, "la"},  /* Latin */
 403   {132, "qu"},  /* Quechua */
 404   {133, "gn"},  /* Guarani */
 405   {134, "ay"},  /* Aymara */
 406   {135, "tt"},  /* Tatar */
 407   {136, "ug"},  /* Uighur */
 408   {137, "dz"},  /* Dzongkha */
 409   {138, "jw"},  /* Javanese (Roman script) */
 410   {139, "su"},  /* Sundanese (Roman script) */
 411   {140, "gl"},  /* Galician */
 412   {141, "af"},  /* Afrikaans */
 413   {142, "br"},  /* Breton */
 414   {143, "iu"},  /* Inuktitut */
 415   {144, "gd"},  /* Scottish Gaelic */
 416   {145, "gv"},  /* Manx Gaelic */
 417   {146, "ga"},  /* Irish Gaelic (with dot above) */
 418   {147, "to"},  /* Tongan */
 419   {148, "el"},  /* Greek (polytonic) */
 420   {149, "ik"},  /* Greenlandic */
 421   {150, "az"},  /* Azerbaijani (Roman script) */
 422 };
 423 
 424 
 425 static hb_language_t
 426 _hb_ot_name_language_for (unsigned int code,
 427                           const hb_ot_language_map_t *array,
 428                           unsigned int len)
 429 {
 430   const hb_ot_language_map_t *entry = (const hb_ot_language_map_t *)
 431                                       hb_bsearch (&code,
 432                                                   array,
 433                                                   len,
 434                                                   sizeof (array[0]),
 435                                                   hb_ot_language_map_t::cmp);
 436 
 437   if (entry)
 438     return hb_language_from_string (entry->lang, -1);
 439 
 440   return HB_LANGUAGE_INVALID;
 441 }
 442 
 443 hb_language_t
 444 _hb_ot_name_language_for_ms_code (unsigned int code)
 445 {
 446   return _hb_ot_name_language_for (code,
 447                                    hb_ms_language_map,
 448                                    ARRAY_LENGTH (hb_ms_language_map));
 449 }
 450 
 451 hb_language_t
 452 _hb_ot_name_language_for_mac_code (unsigned int code)
 453 {
 454   return _hb_ot_name_language_for (code,
 455                                    hb_mac_language_map,
 456                                    ARRAY_LENGTH (hb_mac_language_map));
 457 }