SkOTTable_name.cpp revision 7839ce1af63bf12fe7b3caa866970bbbb3afb13d
17839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger/* 27839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * Copyright 2013 Google Inc. 37839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * 47839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * Use of this source code is governed by a BSD-style license that can be 57839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * found in the LICENSE file. 67839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger */ 77839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 87839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "SkOTTable_name.h" 97839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "SkEndian.h" 117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "SkString.h" 127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "SkTSearch.h" 137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "SkTemplates.h" 147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "SkUtils.h" 157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerstatic SkUnichar SkUTF16BE_NextUnichar(const uint16_t** srcPtr) { 177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkASSERT(srcPtr && *srcPtr); 187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const uint16_t* src = *srcPtr; 207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkUnichar c = SkEndian_SwapBE16(*src++); 217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkASSERT(!SkUTF16_IsLowSurrogate(c)); 237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (SkUTF16_IsHighSurrogate(c)) { 247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger unsigned c2 = SkEndian_SwapBE16(*src++); 257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkASSERT(SkUTF16_IsLowSurrogate(c2)); 267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger c = (c << 10) + c2 + (0x10000 - (0xD800 << 10) - 0xDC00); 287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger *srcPtr = src; 307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger return c; 317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger} 327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerstatic void SkStringFromUTF16BE(const uint16_t* utf16be, size_t length, SkString& utf8) { 347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkASSERT(utf16be != NULL); 357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger utf8.reset(); 377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger size_t numberOf16BitValues = length / 2; 387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const uint16_t* end = utf16be + numberOf16BitValues; 397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger while (utf16be < end) { 407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger utf8.appendUnichar(SkUTF16BE_NextUnichar(&utf16be)); 417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger} 437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger/** UnicodeFromMacRoman[macRomanPoint - 0x80] -> unicodeCodePoint. 457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * Derived from http://www.unicode.org/Public/MAPPINGS/VENDORS/APPLE/ROMAN.TXT . 467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * In MacRoman the first 128 code points match ASCII code points. 477839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * This maps the second 128 MacRoman code points to unicode code points. 487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger */ 497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerstatic uint16_t UnicodeFromMacRoman[0x80] = { 507839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 0x00C4, 0x00C5, 0x00C7, 0x00C9, 0x00D1, 0x00D6, 0x00DC, 0x00E1, 517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 0x00E0, 0x00E2, 0x00E4, 0x00E3, 0x00E5, 0x00E7, 0x00E9, 0x00E8, 527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 0x00EA, 0x00EB, 0x00ED, 0x00EC, 0x00EE, 0x00EF, 0x00F1, 0x00F3, 537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 0x00F2, 0x00F4, 0x00F6, 0x00F5, 0x00FA, 0x00F9, 0x00FB, 0x00FC, 547839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 0x2020, 0x00B0, 0x00A2, 0x00A3, 0x00A7, 0x2022, 0x00B6, 0x00DF, 557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 0x00AE, 0x00A9, 0x2122, 0x00B4, 0x00A8, 0x2260, 0x00C6, 0x00D8, 567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 0x221E, 0x00B1, 0x2264, 0x2265, 0x00A5, 0x00B5, 0x2202, 0x2211, 577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 0x220F, 0x03C0, 0x222B, 0x00AA, 0x00BA, 0x03A9, 0x00E6, 0x00F8, 587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 0x00BF, 0x00A1, 0x00AC, 0x221A, 0x0192, 0x2248, 0x2206, 0x00AB, 597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 0x00BB, 0x2026, 0x00A0, 0x00C0, 0x00C3, 0x00D5, 0x0152, 0x0153, 607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 0x2013, 0x2014, 0x201C, 0x201D, 0x2018, 0x2019, 0x00F7, 0x25CA, 617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 0x00FF, 0x0178, 0x2044, 0x20AC, 0x2039, 0x203A, 0xFB01, 0xFB02, 627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 0x2021, 0x00B7, 0x201A, 0x201E, 0x2030, 0x00C2, 0x00CA, 0x00C1, 637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 0x00CB, 0x00C8, 0x00CD, 0x00CE, 0x00CF, 0x00CC, 0x00D3, 0x00D4, 647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 0xF8FF, 0x00D2, 0x00DA, 0x00DB, 0x00D9, 0x0131, 0x02C6, 0x02DC, 657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 0x00AF, 0x02D8, 0x02D9, 0x02DA, 0x00B8, 0x02DD, 0x02DB, 0x02C7, 667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}; 677839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerstatic void SkStringFromMacRoman(const uint8_t* macRoman, size_t length, SkString& utf8) { 697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger utf8.reset(); 707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger for (size_t i = 0; i < length; ++i) { 717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger utf8.appendUnichar(macRoman[i] < 0x80 ? macRoman[i] : UnicodeFromMacRoman[macRoman[i]]); 727839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 737839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger} 747839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 757839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerstatic struct BCP47FromLanguageId { 767839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger uint16_t languageID; 777839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const char* bcp47; 787839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger} 797839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger/** The Mac and Windows values do not conflict, so this is currently one single table. */ 807839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek SollenbergerBCP47FromLanguageID[] = { 817839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger /** A mapping from Mac Language Designators to BCP 47 codes. 827839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * The following list was constructed more or less manually. 837839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * Apple now uses BCP 47 (post OSX10.4), so there will be no new entries. 847839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger */ 857839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {0, "en"}, //English 867839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {1, "fr"}, //French 877839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {2, "de"}, //German 887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {3, "it"}, //Italian 897839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {4, "nl"}, //Dutch 907839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {5, "sv"}, //Swedish 917839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {6, "es"}, //Spanish 927839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {7, "da"}, //Danish 937839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {8, "pt"}, //Portuguese 947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {9, "nb"}, //Norwegian 957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {10, "he"}, //Hebrew 967839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {11, "ja"}, //Japanese 977839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {12, "ar"}, //Arabic 987839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {13, "fi"}, //Finnish 997839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {14, "el"}, //Greek 1007839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {15, "is"}, //Icelandic 1017839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {16, "mt"}, //Maltese 1027839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {17, "tr"}, //Turkish 1037839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {18, "hr"}, //Croatian 1047839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {19, "zh-Hant"}, //Chinese (Traditional) 1057839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {20, "ur"}, //Urdu 1067839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {21, "hi"}, //Hindi 1077839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {22, "th"}, //Thai 1087839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {23, "ko"}, //Korean 1097839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {24, "lt"}, //Lithuanian 1107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {25, "pl"}, //Polish 1117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {26, "hu"}, //Hungarian 1127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {27, "et"}, //Estonian 1137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {28, "lv"}, //Latvian 1147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {29, "se"}, //Sami 1157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {30, "fo"}, //Faroese 1167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {31, "fa"}, //Farsi (Persian) 1177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {32, "ru"}, //Russian 1187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {33, "zh-Hans"}, //Chinese (Simplified) 1197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {34, "nl"}, //Dutch 1207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {35, "ga"}, //Irish(Gaelic) 1217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {36, "sq"}, //Albanian 1227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {37, "ro"}, //Romanian 1237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {38, "cs"}, //Czech 1247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {39, "sk"}, //Slovak 1257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {40, "sl"}, //Slovenian 1267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {41, "yi"}, //Yiddish 1277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {42, "sr"}, //Serbian 1287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {43, "mk"}, //Macedonian 1297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {44, "bg"}, //Bulgarian 1307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {45, "uk"}, //Ukrainian 1317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {46, "be"}, //Byelorussian 1327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {47, "uz"}, //Uzbek 1337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {48, "kk"}, //Kazakh 1347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {49, "az-Cyrl"}, //Azerbaijani (Cyrillic) 1357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {50, "az-Arab"}, //Azerbaijani (Arabic) 1367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {51, "hy"}, //Armenian 1377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {52, "ka"}, //Georgian 1387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {53, "mo"}, //Moldavian 1397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {54, "ky"}, //Kirghiz 1407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {55, "tg"}, //Tajiki 1417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {56, "tk"}, //Turkmen 1427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {57, "mn-Mong"}, //Mongolian (Traditional) 1437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {58, "mn-Cyrl"}, //Mongolian (Cyrillic) 1447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {59, "ps"}, //Pashto 1457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {60, "ku"}, //Kurdish 1467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {61, "ks"}, //Kashmiri 1477839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {62, "sd"}, //Sindhi 1487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {63, "bo"}, //Tibetan 1497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {64, "ne"}, //Nepali 1507839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {65, "sa"}, //Sanskrit 1517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {66, "mr"}, //Marathi 1527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {67, "bn"}, //Bengali 1537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {68, "as"}, //Assamese 1547839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {69, "gu"}, //Gujarati 1557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {70, "pa"}, //Punjabi 1567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {71, "or"}, //Oriya 1577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {72, "ml"}, //Malayalam 1587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {73, "kn"}, //Kannada 1597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {74, "ta"}, //Tamil 1607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {75, "te"}, //Telugu 1617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {76, "si"}, //Sinhalese 1627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {77, "my"}, //Burmese 1637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {78, "km"}, //Khmer 1647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {79, "lo"}, //Lao 1657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {80, "vi"}, //Vietnamese 1667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {81, "id"}, //Indonesian 1677839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {82, "tl"}, //Tagalog 1687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {83, "ms-Latn"}, //Malay (Roman) 1697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {84, "ms-Arab"}, //Malay (Arabic) 1707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {85, "am"}, //Amharic 1717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {86, "ti"}, //Tigrinya 1727839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {87, "om"}, //Oromo 1737839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {88, "so"}, //Somali 1747839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {89, "sw"}, //Swahili 1757839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {90, "rw"}, //Kinyarwanda/Ruanda 1767839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {91, "rn"}, //Rundi 1777839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {92, "ny"}, //Nyanja/Chewa 1787839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {93, "mg"}, //Malagasy 1797839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {94, "eo"}, //Esperanto 1807839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {128, "cy"}, //Welsh 1817839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {129, "eu"}, //Basque 1827839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {130, "ca"}, //Catalan 1837839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {131, "la"}, //Latin 1847839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {132, "qu"}, //Quechua 1857839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {133, "gn"}, //Guarani 1867839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {134, "ay"}, //Aymara 1877839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {135, "tt"}, //Tatar 1887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {136, "ug"}, //Uighur 1897839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {137, "dz"}, //Dzongkha 1907839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {138, "jv-Latn"}, //Javanese (Roman) 1917839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {139, "su-Latn"}, //Sundanese (Roman) 1927839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {140, "gl"}, //Galician 1937839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {141, "af"}, //Afrikaans 1947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {142, "br"}, //Breton 1957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {143, "iu"}, //Inuktitut 1967839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {144, "gd"}, //Scottish (Gaelic) 1977839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {145, "gv"}, //Manx (Gaelic) 1987839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {146, "ga"}, //Irish (Gaelic with Lenition) 1997839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {147, "to"}, //Tongan 2007839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {148, "el"}, //Greek (Polytonic) Note: ISO 15924 does not have an equivalent script name. 2017839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {149, "kl"}, //Greenlandic 2027839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {150, "az-Latn"}, //Azerbaijani (Roman) 2037839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {151, "nn"}, //Nynorsk 2047839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 2057839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger /** A mapping from Windows LCID to BCP 47 codes. 2067839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * This list is the sorted, curated output of tools/win_lcid.cpp. 2077839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * Note that these are sorted by value for quick binary lookup, and not logically by lsb. 2087839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * The 'bare' language ids (e.g. 0x0001 for Arabic) are ommitted 2097839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * as they do not appear as valid language ids in the OpenType specification. 2107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger */ 2117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0401, "ar-SA" }, //Arabic 2127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0402, "bg-BG" }, //Bulgarian 2137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0403, "ca-ES" }, //Catalan 2147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0404, "zh-TW" }, //Chinese (Traditional) 2157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0405, "cs-CZ" }, //Czech 2167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0406, "da-DK" }, //Danish 2177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0407, "de-DE" }, //German 2187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0408, "el-GR" }, //Greek 2197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0409, "en-US" }, //English 2207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x040a, "es-ES_tradnl" }, //Spanish 2217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x040b, "fi-FI" }, //Finnish 2227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x040c, "fr-FR" }, //French 2237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x040d, "he-IL" }, //Hebrew 2247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x040d, "he" }, //Hebrew 2257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x040e, "hu-HU" }, //Hungarian 2267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x040e, "hu" }, //Hungarian 2277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x040f, "is-IS" }, //Icelandic 2287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0410, "it-IT" }, //Italian 2297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0411, "ja-JP" }, //Japanese 2307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0412, "ko-KR" }, //Korean 2317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0413, "nl-NL" }, //Dutch 2327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0414, "nb-NO" }, //Norwegian (Bokm�l) 2337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0415, "pl-PL" }, //Polish 2347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0416, "pt-BR" }, //Portuguese 2357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0417, "rm-CH" }, //Romansh 2367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0418, "ro-RO" }, //Romanian 2377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0419, "ru-RU" }, //Russian 2387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x041a, "hr-HR" }, //Croatian 2397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x041b, "sk-SK" }, //Slovak 2407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x041c, "sq-AL" }, //Albanian 2417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x041d, "sv-SE" }, //Swedish 2427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x041e, "th-TH" }, //Thai 2437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x041f, "tr-TR" }, //Turkish 2447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0420, "ur-PK" }, //Urdu 2457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0421, "id-ID" }, //Indonesian 2467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0422, "uk-UA" }, //Ukrainian 2477839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0423, "be-BY" }, //Belarusian 2487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0424, "sl-SI" }, //Slovenian 2497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0425, "et-EE" }, //Estonian 2507839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0426, "lv-LV" }, //Latvian 2517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0427, "lt-LT" }, //Lithuanian 2527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0428, "tg-Cyrl-TJ" }, //Tajik (Cyrillic) 2537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0429, "fa-IR" }, //Persian 2547839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x042a, "vi-VN" }, //Vietnamese 2557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x042b, "hy-AM" }, //Armenian 2567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x042c, "az-Latn-AZ" }, //Azeri (Latin) 2577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x042d, "eu-ES" }, //Basque 2587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x042e, "hsb-DE" }, //Upper Sorbian 2597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x042f, "mk-MK" }, //Macedonian (FYROM) 2607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0432, "tn-ZA" }, //Setswana 2617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0434, "xh-ZA" }, //isiXhosa 2627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0435, "zu-ZA" }, //isiZulu 2637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0436, "af-ZA" }, //Afrikaans 2647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0437, "ka-GE" }, //Georgian 2657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0438, "fo-FO" }, //Faroese 2667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0439, "hi-IN" }, //Hindi 2677839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x043a, "mt-MT" }, //Maltese 2687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x043b, "se-NO" }, //Sami (Northern) 2697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x043e, "ms-MY" }, //Malay 2707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x043f, "kk-KZ" }, //Kazakh 2717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0440, "ky-KG" }, //Kyrgyz 2727839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0441, "sw-KE" }, //Kiswahili 2737839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0442, "tk-TM" }, //Turkmen 2747839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0443, "uz-Latn-UZ" }, //Uzbek (Latin) 2757839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0443, "uz" }, //Uzbek 2767839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0444, "tt-RU" }, //Tatar 2777839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0445, "bn-IN" }, //Bengali 2787839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0446, "pa-IN" }, //Punjabi 2797839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0447, "gu-IN" }, //Gujarati 2807839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0448, "or-IN" }, //Oriya 2817839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0449, "ta-IN" }, //Tamil 2827839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x044a, "te-IN" }, //Telugu 2837839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x044b, "kn-IN" }, //Kannada 2847839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x044c, "ml-IN" }, //Malayalam 2857839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x044d, "as-IN" }, //Assamese 2867839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x044e, "mr-IN" }, //Marathi 2877839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x044f, "sa-IN" }, //Sanskrit 2887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0450, "mn-Cyrl" }, //Mongolian (Cyrillic) 2897839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0451, "bo-CN" }, //Tibetan 2907839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0452, "cy-GB" }, //Welsh 2917839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0453, "km-KH" }, //Khmer 2927839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0454, "lo-LA" }, //Lao 2937839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0456, "gl-ES" }, //Galician 2947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0457, "kok-IN" }, //Konkani 2957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x045a, "syr-SY" }, //Syriac 2967839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x045b, "si-LK" }, //Sinhala 2977839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x045d, "iu-Cans-CA" }, //Inuktitut (Syllabics) 2987839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x045e, "am-ET" }, //Amharic 2997839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0461, "ne-NP" }, //Nepali 3007839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0462, "fy-NL" }, //Frisian 3017839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0463, "ps-AF" }, //Pashto 3027839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0464, "fil-PH" }, //Filipino 3037839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0465, "dv-MV" }, //Divehi 3047839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0468, "ha-Latn-NG" }, //Hausa (Latin) 3057839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x046a, "yo-NG" }, //Yoruba 3067839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x046b, "quz-BO" }, //Quechua 3077839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x046c, "nso-ZA" }, //Sesotho sa Leboa 3087839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x046d, "ba-RU" }, //Bashkir 3097839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x046e, "lb-LU" }, //Luxembourgish 3107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x046f, "kl-GL" }, //Greenlandic 3117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0470, "ig-NG" }, //Igbo 3127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0478, "ii-CN" }, //Yi 3137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x047a, "arn-CL" }, //Mapudungun 3147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x047c, "moh-CA" }, //Mohawk 3157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x047e, "br-FR" }, //Breton 3167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0480, "ug-CN" }, //Uyghur 3177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0481, "mi-NZ" }, //Maori 3187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0482, "oc-FR" }, //Occitan 3197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0483, "co-FR" }, //Corsican 3207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0484, "gsw-FR" }, //Alsatian 3217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0485, "sah-RU" }, //Yakut 3227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0486, "qut-GT" }, //K'iche 3237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0487, "rw-RW" }, //Kinyarwanda 3247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0488, "wo-SN" }, //Wolof 3257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x048c, "prs-AF" }, //Dari 3267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0491, "gd-GB" }, //Scottish Gaelic 3277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0801, "ar-IQ" }, //Arabic 3287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0804, "zh-Hans" }, //Chinese (Simplified) 3297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0807, "de-CH" }, //German 3307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0809, "en-GB" }, //English 3317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x080a, "es-MX" }, //Spanish 3327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x080c, "fr-BE" }, //French 3337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0810, "it-CH" }, //Italian 3347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0813, "nl-BE" }, //Dutch 3357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0814, "nn-NO" }, //Norwegian (Nynorsk) 3367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0816, "pt-PT" }, //Portuguese 3377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x081a, "sr-Latn-CS" }, //Serbian (Latin) 3387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x081d, "sv-FI" }, //Swedish 3397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x082c, "az-Cyrl-AZ" }, //Azeri (Cyrillic) 3407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x082e, "dsb-DE" }, //Lower Sorbian 3417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x082e, "dsb" }, //Lower Sorbian 3427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x083b, "se-SE" }, //Sami (Northern) 3437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x083c, "ga-IE" }, //Irish 3447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x083e, "ms-BN" }, //Malay 3457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0843, "uz-Cyrl-UZ" }, //Uzbek (Cyrillic) 3467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0845, "bn-BD" }, //Bengali 3477839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0850, "mn-Mong-CN" }, //Mongolian (Traditional Mongolian) 3487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x085d, "iu-Latn-CA" }, //Inuktitut (Latin) 3497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x085f, "tzm-Latn-DZ" }, //Tamazight (Latin) 3507839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x086b, "quz-EC" }, //Quechua 3517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0c01, "ar-EG" }, //Arabic 3527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0c04, "zh-Hant" }, //Chinese (Traditional) 3537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0c07, "de-AT" }, //German 3547839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0c09, "en-AU" }, //English 3557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0c0a, "es-ES" }, //Spanish 3567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0c0c, "fr-CA" }, //French 3577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0c1a, "sr-Cyrl-CS" }, //Serbian (Cyrillic) 3587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0c3b, "se-FI" }, //Sami (Northern) 3597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x0c6b, "quz-PE" }, //Quechua 3607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x1001, "ar-LY" }, //Arabic 3617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x1004, "zh-SG" }, //Chinese (Simplified) 3627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x1007, "de-LU" }, //German 3637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x1009, "en-CA" }, //English 3647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x100a, "es-GT" }, //Spanish 3657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x100c, "fr-CH" }, //French 3667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x101a, "hr-BA" }, //Croatian (Latin) 3677839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x103b, "smj-NO" }, //Sami (Lule) 3687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x1401, "ar-DZ" }, //Arabic 3697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x1404, "zh-MO" }, //Chinese (Traditional) 3707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x1407, "de-LI" }, //German 3717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x1409, "en-NZ" }, //English 3727839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x140a, "es-CR" }, //Spanish 3737839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x140c, "fr-LU" }, //French 3747839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x141a, "bs-Latn-BA" }, //Bosnian (Latin) 3757839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x141a, "bs" }, //Bosnian 3767839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x143b, "smj-SE" }, //Sami (Lule) 3777839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x143b, "smj" }, //Sami (Lule) 3787839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x1801, "ar-MA" }, //Arabic 3797839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x1809, "en-IE" }, //English 3807839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x180a, "es-PA" }, //Spanish 3817839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x180c, "fr-MC" }, //French 3827839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x181a, "sr-Latn-BA" }, //Serbian (Latin) 3837839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x183b, "sma-NO" }, //Sami (Southern) 3847839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x1c01, "ar-TN" }, //Arabic 3857839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x1c09, "en-ZA" }, //English 3867839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x1c0a, "es-DO" }, //Spanish 3877839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x1c1a, "sr-Cyrl-BA" }, //Serbian (Cyrillic) 3887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x1c3b, "sma-SE" }, //Sami (Southern) 3897839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x1c3b, "sma" }, //Sami (Southern) 3907839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x2001, "ar-OM" }, //Arabic 3917839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x2009, "en-JM" }, //English 3927839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x200a, "es-VE" }, //Spanish 3937839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x201a, "bs-Cyrl-BA" }, //Bosnian (Cyrillic) 3947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x201a, "bs-Cyrl" }, //Bosnian (Cyrillic) 3957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x203b, "sms-FI" }, //Sami (Skolt) 3967839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x203b, "sms" }, //Sami (Skolt) 3977839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x2401, "ar-YE" }, //Arabic 3987839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x2409, "en-029" }, //English 3997839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x240a, "es-CO" }, //Spanish 4007839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x241a, "sr-Latn-RS" }, //Serbian (Latin) 4017839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x243b, "smn-FI" }, //Sami (Inari) 4027839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x2801, "ar-SY" }, //Arabic 4037839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x2809, "en-BZ" }, //English 4047839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x280a, "es-PE" }, //Spanish 4057839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x281a, "sr-Cyrl-RS" }, //Serbian (Cyrillic) 4067839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x2c01, "ar-JO" }, //Arabic 4077839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x2c09, "en-TT" }, //English 4087839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x2c0a, "es-AR" }, //Spanish 4097839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x2c1a, "sr-Latn-ME" }, //Serbian (Latin) 4107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x3001, "ar-LB" }, //Arabic 4117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x3009, "en-ZW" }, //English 4127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x300a, "es-EC" }, //Spanish 4137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x301a, "sr-Cyrl-ME" }, //Serbian (Cyrillic) 4147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x3401, "ar-KW" }, //Arabic 4157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x3409, "en-PH" }, //English 4167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x340a, "es-CL" }, //Spanish 4177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x3801, "ar-AE" }, //Arabic 4187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x380a, "es-UY" }, //Spanish 4197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x3c01, "ar-BH" }, //Arabic 4207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x3c0a, "es-PY" }, //Spanish 4217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x4001, "ar-QA" }, //Arabic 4227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x4009, "en-IN" }, //English 4237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x400a, "es-BO" }, //Spanish 4247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x4409, "en-MY" }, //English 4257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x440a, "es-SV" }, //Spanish 4267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x4809, "en-SG" }, //English 4277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x480a, "es-HN" }, //Spanish 4287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x4c0a, "es-NI" }, //Spanish 4297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x500a, "es-PR" }, //Spanish 4307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger { 0x540a, "es-US" }, //Spanish 4317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}; 4327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 4337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergernamespace { 4347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerbool BCP47FromLanguageIdLess(const BCP47FromLanguageId& a, const BCP47FromLanguageId& b) { 4357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger return a.languageID < b.languageID; 4367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger} 4377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger} 4387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 4397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerbool SkOTTableName::Iterator::next(SkOTTableName::Iterator::Record& record) { 4407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const size_t nameRecordsCount = SkEndian_SwapBE16(fName.count); 4417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const SkOTTableName::Record* nameRecords = SkTAfter<const SkOTTableName::Record>(&fName); 4427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const SkOTTableName::Record* nameRecord; 4437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 4447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // Find the next record which matches the requested type. 4457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger do { 4467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (fIndex >= nameRecordsCount) { 4477839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger return false; 4487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 4497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 4507839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger nameRecord = &nameRecords[fIndex]; 4517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger ++fIndex; 4527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } while (fType != -1 && nameRecord->nameID.fontSpecific != fType); 4537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 4547839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const uint16_t stringTableOffset = SkEndian_SwapBE16(fName.stringOffset); 4557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const char* stringTable = SkTAddOffset<const char>(&fName, stringTableOffset); 4567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 4577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // Decode the name into UTF-8. 4587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const uint16_t nameOffset = SkEndian_SwapBE16(nameRecord->offset); 4597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const uint16_t nameLength = SkEndian_SwapBE16(nameRecord->length); 4607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const char* nameString = SkTAddOffset<const char>(stringTable, nameOffset); 4617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger switch (nameRecord->platformID.value) { 4627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger case SkOTTableName::Record::PlatformID::Windows: 4637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkASSERT(SkOTTableName::Record::EncodingID::Windows::UnicodeBMPUCS2 4647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger == nameRecord->encodingID.windows.value 4657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger || SkOTTableName::Record::EncodingID::Windows::UnicodeUCS4 4667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger == nameRecord->encodingID.windows.value 4677839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger || SkOTTableName::Record::EncodingID::Windows::Symbol 4687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger == nameRecord->encodingID.windows.value); 4697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger case SkOTTableName::Record::PlatformID::Unicode: 4707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger case SkOTTableName::Record::PlatformID::ISO: 4717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkStringFromUTF16BE((const uint16_t*)nameString, nameLength, record.name); 4727839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger break; 4737839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 4747839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger case SkOTTableName::Record::PlatformID::Macintosh: 4757839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkASSERT(SkOTTableName::Record::EncodingID::Macintosh::Roman 4767839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger == nameRecord->encodingID.macintosh.value); 4777839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkStringFromMacRoman((const uint8_t*)nameString, nameLength, record.name); 4787839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger break; 4797839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 4807839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger case SkOTTableName::Record::PlatformID::Custom: 4817839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // These should never appear in a 'name' table. 4827839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger default: 4837839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkASSERT(false); 4847839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger record.name.reset(); 4857839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger break; 4867839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 4877839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 4887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // Determine the language. 4897839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const uint16_t languageID = SkEndian_SwapBE16(nameRecord->languageID.languageTagID); 4907839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 4917839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // Handle format 1 languages. 4927839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (SkOTTableName::format_1 == fName.format && languageID >= 0x8000) { 4937839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const uint16_t languageTagRecordIndex = languageID - 0x8000; 4947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 4957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const SkOTTableName::Format1Ext* format1ext = 4967839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkTAfter<const SkOTTableName::Format1Ext>(nameRecords, nameRecordsCount); 4977839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 4987839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (languageTagRecordIndex < format1ext->langTagCount) { 4997839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const SkOTTableName::Format1Ext::LangTagRecord* languageTagRecord = 5007839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkTAfter<const SkOTTableName::Format1Ext::LangTagRecord>(format1ext); 5017839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 5027839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger uint16_t offset = SkEndian_SwapBE16(languageTagRecord[languageTagRecordIndex].offset); 5037839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger uint16_t length = SkEndian_SwapBE16(languageTagRecord[languageTagRecordIndex].length); 5047839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const uint16_t* string = SkTAddOffset<const uint16_t>(stringTable, offset); 5057839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkStringFromUTF16BE(string, length, record.language); 5067839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger return true; 5077839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 5087839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 5097839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 5107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // Handle format 0 languages, translating them into BCP 47. 5117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const BCP47FromLanguageId target = { languageID, "" }; 5127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger int languageIndex = SkTSearch<BCP47FromLanguageId, BCP47FromLanguageIdLess>( 5137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger BCP47FromLanguageID, SK_ARRAY_COUNT(BCP47FromLanguageID), target, sizeof(target)); 5147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (languageIndex >= 0) { 5157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger record.language = BCP47FromLanguageID[languageIndex].bcp47; 5167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger return true; 5177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 5187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 5197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // Unknown language, return the BCP 47 code 'und' for 'undetermined'. 5207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkASSERT(false); 5217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger record.language = "und"; 5227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger return true; 5237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger} 524