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
454e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger    record.type = nameRecord->nameID.fontSpecific;
455e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger
4567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const uint16_t stringTableOffset = SkEndian_SwapBE16(fName.stringOffset);
4577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* stringTable = SkTAddOffset<const char>(&fName, stringTableOffset);
4587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
4597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Decode the name into UTF-8.
4607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const uint16_t nameOffset = SkEndian_SwapBE16(nameRecord->offset);
4617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const uint16_t nameLength = SkEndian_SwapBE16(nameRecord->length);
4627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* nameString = SkTAddOffset<const char>(stringTable, nameOffset);
4637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    switch (nameRecord->platformID.value) {
4647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        case SkOTTableName::Record::PlatformID::Windows:
465e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger            if (SkOTTableName::Record::EncodingID::Windows::UnicodeBMPUCS2
466e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger                   != nameRecord->encodingID.windows.value
467e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger                && SkOTTableName::Record::EncodingID::Windows::UnicodeUCS4
468e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger                   != nameRecord->encodingID.windows.value
469e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger                && SkOTTableName::Record::EncodingID::Windows::Symbol
470e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger                   != nameRecord->encodingID.windows.value)
471e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger            {
472e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger                record.name.reset();
473e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger                break;
474e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger            }
4757839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        case SkOTTableName::Record::PlatformID::Unicode:
4767839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        case SkOTTableName::Record::PlatformID::ISO:
4777839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            SkStringFromUTF16BE((const uint16_t*)nameString, nameLength, record.name);
4787839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            break;
4797839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
4807839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        case SkOTTableName::Record::PlatformID::Macintosh:
481e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger            // TODO: need better decoding, especially on Mac.
482e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger            if (SkOTTableName::Record::EncodingID::Macintosh::Roman
483e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger                != nameRecord->encodingID.macintosh.value)
484e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger            {
485e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger                record.name.reset();
486e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger                break;
487e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger            }
4887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            SkStringFromMacRoman((const uint8_t*)nameString, nameLength, record.name);
4897839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            break;
4907839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
4917839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        case SkOTTableName::Record::PlatformID::Custom:
4927839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            // These should never appear in a 'name' table.
4937839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        default:
4947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            SkASSERT(false);
4957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            record.name.reset();
4967839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            break;
4977839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
4987839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
4997839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Determine the language.
5007839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const uint16_t languageID = SkEndian_SwapBE16(nameRecord->languageID.languageTagID);
5017839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5027839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Handle format 1 languages.
5037839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (SkOTTableName::format_1 == fName.format && languageID >= 0x8000) {
5047839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        const uint16_t languageTagRecordIndex = languageID - 0x8000;
5057839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5067839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        const SkOTTableName::Format1Ext* format1ext =
5077839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            SkTAfter<const SkOTTableName::Format1Ext>(nameRecords, nameRecordsCount);
5087839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
509e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger        if (languageTagRecordIndex < SkEndian_SwapBE16(format1ext->langTagCount)) {
5107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            const SkOTTableName::Format1Ext::LangTagRecord* languageTagRecord =
5117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                SkTAfter<const SkOTTableName::Format1Ext::LangTagRecord>(format1ext);
5127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            uint16_t offset = SkEndian_SwapBE16(languageTagRecord[languageTagRecordIndex].offset);
5147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            uint16_t length = SkEndian_SwapBE16(languageTagRecord[languageTagRecordIndex].length);
5157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            const uint16_t* string = SkTAddOffset<const uint16_t>(stringTable, offset);
5167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            SkStringFromUTF16BE(string, length, record.language);
5177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            return true;
5187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
5197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
5207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Handle format 0 languages, translating them into BCP 47.
5227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const BCP47FromLanguageId target = { languageID, "" };
5237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    int languageIndex = SkTSearch<BCP47FromLanguageId, BCP47FromLanguageIdLess>(
5247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        BCP47FromLanguageID, SK_ARRAY_COUNT(BCP47FromLanguageID), target, sizeof(target));
5257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (languageIndex >= 0) {
5267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        record.language = BCP47FromLanguageID[languageIndex].bcp47;
5277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return true;
5287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
5297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Unknown language, return the BCP 47 code 'und' for 'undetermined'.
5317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkASSERT(false);
5327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    record.language = "und";
5337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    return true;
5347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
535