gfx/graphite2/src/inc/locale2lcid.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* GRAPHITE2 LICENSING
michael@0 2
michael@0 3 Copyright 2010, SIL International
michael@0 4 All rights reserved.
michael@0 5
michael@0 6 This library is free software; you can redistribute it and/or modify
michael@0 7 it under the terms of the GNU Lesser General Public License as published
michael@0 8 by the Free Software Foundation; either version 2.1 of License, or
michael@0 9 (at your option) any later version.
michael@0 10
michael@0 11 This program is distributed in the hope that it will be useful,
michael@0 12 but WITHOUT ANY WARRANTY; without even the implied warranty of
michael@0 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
michael@0 14 Lesser General Public License for more details.
michael@0 15
michael@0 16 You should also have received a copy of the GNU Lesser General Public
michael@0 17 License along with this library in the file named "LICENSE".
michael@0 18 If not, write to the Free Software Foundation, 51 Franklin Street,
michael@0 19 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
michael@0 20 internet at http://www.fsf.org/licenses/lgpl.html.
michael@0 21
michael@0 22 Alternatively, the contents of this file may be used under the terms of the
michael@0 23 Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
michael@0 24 License, as published by the Free Software Foundation, either version 2
michael@0 25 of the License or (at your option) any later version.
michael@0 26 */
michael@0 27 #pragma once
michael@0 28 #include <cstring>
michael@0 29 #include <cassert>
michael@0 30
michael@0 31 #include "inc/Main.h"
michael@0 32
michael@0 33
michael@0 34 namespace graphite2 {
michael@0 35
michael@0 36 struct IsoLangEntry
michael@0 37 {
michael@0 38 unsigned short mnLang;
michael@0 39 const char maLangStr[4];
michael@0 40 const char maCountry[3];
michael@0 41 };
michael@0 42
michael@0 43 // Windows Language ID, Locale ISO-639 language, country code as used in
michael@0 44 // naming table of OpenType fonts
michael@0 45 const IsoLangEntry LANG_ENTRIES[] = {
michael@0 46 { 0x0401, "ar","SA" }, // Arabic Saudi Arabia
michael@0 47 { 0x0402, "bg","BG" }, // Bulgarian Bulgaria
michael@0 48 { 0x0403, "ca","ES" }, // Catalan Catalan
michael@0 49 { 0x0404, "zh","TW" }, // Chinese Taiwan
michael@0 50 { 0x0405, "cs","CZ" }, // Czech Czech Republic
michael@0 51 { 0x0406, "da","DK" }, // Danish Denmark
michael@0 52 { 0x0407, "de","DE" }, // German Germany
michael@0 53 { 0x0408, "el","GR" }, // Greek Greece
michael@0 54 { 0x0409, "en","US" }, // English United States
michael@0 55 { 0x040A, "es","ES" }, // Spanish (Traditional Sort) Spain
michael@0 56 { 0x040B, "fi","FI" }, // Finnish Finland
michael@0 57 { 0x040C, "fr","FR" }, // French France
michael@0 58 { 0x040D, "he","IL" }, // Hebrew Israel
michael@0 59 { 0x040E, "hu","HU" }, // Hungarian Hungary
michael@0 60 { 0x040F, "is","IS" }, // Icelandic Iceland
michael@0 61 { 0x0410, "it","IT" }, // Italian Italy
michael@0 62 { 0x0411, "jp","JP" }, // Japanese Japan
michael@0 63 { 0x0412, "ko","KR" }, // Korean Korea
michael@0 64 { 0x0413, "nl","NL" }, // Dutch Netherlands
michael@0 65 { 0x0414, "no","NO" }, // Norwegian (Bokmal) Norway
michael@0 66 { 0x0415, "pl","PL" }, // Polish Poland
michael@0 67 { 0x0416, "pt","BR" }, // Portuguese Brazil
michael@0 68 { 0x0417, "rm","CH" }, // Romansh Switzerland
michael@0 69 { 0x0418, "ro","RO" }, // Romanian Romania
michael@0 70 { 0x0419, "ru","RU" }, // Russian Russia
michael@0 71 { 0x041A, "hr","HR" }, // Croatian Croatia
michael@0 72 { 0x041B, "sk","SK" }, // Slovak Slovakia
michael@0 73 { 0x041C, "sq","AL" }, // Albanian Albania
michael@0 74 { 0x041D, "sv","SE" }, // Swedish Sweden
michael@0 75 { 0x041E, "th","TH" }, // Thai Thailand
michael@0 76 { 0x041F, "tr","TR" }, // Turkish Turkey
michael@0 77 { 0x0420, "ur","PK" }, // Urdu Islamic Republic of Pakistan
michael@0 78 { 0x0421, "id","ID" }, // Indonesian Indonesia
michael@0 79 { 0x0422, "uk","UA" }, // Ukrainian Ukraine
michael@0 80 { 0x0423, "be","BY" }, // Belarusian Belarus
michael@0 81 { 0x0424, "sl","SI" }, // Slovenian Slovenia
michael@0 82 { 0x0425, "et","EE" }, // Estonian Estonia
michael@0 83 { 0x0426, "lv","LV" }, // Latvian Latvia
michael@0 84 { 0x0427, "lt","LT" }, // Lithuanian Lithuania
michael@0 85 { 0x0428, "tg","TJ" }, // Tajik (Cyrillic) Tajikistan
michael@0 86 { 0x042A, "vi","VN" }, // Vietnamese Vietnam
michael@0 87 { 0x042B, "hy","AM" }, // Armenian Armenia
michael@0 88 { 0x042C, "az","AZ" }, // Azeri (Latin) Azerbaijan
michael@0 89 { 0x042D, "eu","" }, // Basque Basque
michael@0 90 { 0x042E, "hsb","DE" }, // Upper Sorbian Germany
michael@0 91 { 0x042F, "mk","MK" }, // Macedonian (FYROM) Former Yugoslav Republic of Macedonia
michael@0 92 { 0x0432, "tn","ZA" }, // Setswana South Africa
michael@0 93 { 0x0434, "xh","ZA" }, // isiXhosa South Africa
michael@0 94 { 0x0435, "zu","ZA" }, // isiZulu South Africa
michael@0 95 { 0x0436, "af","ZA" }, // Afrikaans South Africa
michael@0 96 { 0x0437, "ka","GE" }, // Georgian Georgia
michael@0 97 { 0x0438, "fo","FO" }, // Faroese Faroe Islands
michael@0 98 { 0x0439, "hi","IN" }, // Hindi India
michael@0 99 { 0x043A, "mt","MT" }, // Maltese Malta
michael@0 100 { 0x043B, "se","NO" }, // Sami (Northern) Norway
michael@0 101 { 0x043E, "ms","MY" }, // Malay Malaysia
michael@0 102 { 0x043F, "kk","KZ" }, // Kazakh Kazakhstan
michael@0 103 { 0x0440, "ky","KG" }, // Kyrgyz Kyrgyzstan
michael@0 104 { 0x0441, "sw","KE" }, // Kiswahili Kenya
michael@0 105 { 0x0442, "tk","TM" }, // Turkmen Turkmenistan
michael@0 106 { 0x0443, "uz","UZ" }, // Uzbek (Latin) Uzbekistan
michael@0 107 { 0x0444, "tt","RU" }, // Tatar Russia
michael@0 108 { 0x0445, "bn","IN" }, // Bengali India
michael@0 109 { 0x0446, "pa","IN" }, // Punjabi India
michael@0 110 { 0x0447, "gu","IN" }, // Gujarati India
michael@0 111 { 0x0448, "or","IN" }, // Oriya India
michael@0 112 { 0x0448, "wo","SN" }, // Wolof Senegal
michael@0 113 { 0x0449, "ta","IN" }, // Tamil India
michael@0 114 { 0x044A, "te","IN" }, // Telugu India
michael@0 115 { 0x044B, "kn","IN" }, // Kannada India
michael@0 116 { 0x044C, "ml","IN" }, // Malayalam India
michael@0 117 { 0x044D, "as","IN" }, // Assamese India
michael@0 118 { 0x044E, "mr","IN" }, // Marathi India
michael@0 119 { 0x044F, "sa","IN" }, // Sanskrit India
michael@0 120 { 0x0450, "mn","MN" }, // Mongolian (Cyrillic) Mongolia
michael@0 121 { 0x0451, "bo","CN" }, // Tibetan PRC
michael@0 122 { 0x0452, "cy","GB" }, // Welsh United Kingdom
michael@0 123 { 0x0453, "km","KH" }, // Khmer Cambodia
michael@0 124 { 0x0454, "lo","LA" }, // Lao Lao P.D.R.
michael@0 125 { 0x0455, "my","MM" }, // Burmese Myanmar - not listed in Microsoft docs anymore
michael@0 126 { 0x0456, "gl","ES" }, // Galician Galician
michael@0 127 { 0x0457, "kok","IN" }, // Konkani India
michael@0 128 { 0x045A, "syr","TR" }, // Syriac Syria
michael@0 129 { 0x045B, "si","LK" }, // Sinhala Sri Lanka
michael@0 130 { 0x045D, "iu","CA" }, // Inuktitut Canada
michael@0 131 { 0x045E, "am","ET" }, // Amharic Ethiopia
michael@0 132 { 0x0461, "ne","NP" }, // Nepali Nepal
michael@0 133 { 0x0462, "fy","NL" }, // Frisian Netherlands
michael@0 134 { 0x0463, "ps","AF" }, // Pashto Afghanistan
michael@0 135 { 0x0464, "fil","PH" }, // Filipino Philippines
michael@0 136 { 0x0465, "dv","MV" }, // Divehi Maldives
michael@0 137 { 0x0468, "ha","NG" }, // Hausa (Latin) Nigeria
michael@0 138 { 0x046A, "yo","NG" }, // Yoruba Nigeria
michael@0 139 { 0x046B, "qu","BO" }, // Quechua Bolivia
michael@0 140 { 0x046C, "st","ZA" }, // Sesotho sa Leboa South Africa
michael@0 141 { 0x046D, "ba","RU" }, // Bashkir Russia
michael@0 142 { 0x046E, "lb","LU" }, // Luxembourgish Luxembourg
michael@0 143 { 0x046F, "kl","GL" }, // Greenlandic Greenland
michael@0 144 { 0x0470, "ig","NG" }, // Igbo Nigeria
michael@0 145 { 0x0478, "ii","CN" }, // Yi PRC
michael@0 146 { 0x047A, "arn","CL" }, // Mapudungun Chile
michael@0 147 { 0x047C, "moh","CA" }, // Mohawk Mohawk
michael@0 148 { 0x047E, "br","FR" }, // Breton France
michael@0 149 { 0x0480, "ug","CN" }, // Uighur PRC
michael@0 150 { 0x0481, "mi","NZ" }, // Maori New Zealand
michael@0 151 { 0x0482, "oc","FR" }, // Occitan France
michael@0 152 { 0x0483, "co","FR" }, // Corsican France
michael@0 153 { 0x0484, "gsw","FR" }, // Alsatian France
michael@0 154 { 0x0485, "sah","RU" }, // Yakut Russia
michael@0 155 { 0x0486, "qut","GT" }, // K'iche Guatemala
michael@0 156 { 0x0487, "rw","RW" }, // Kinyarwanda Rwanda
michael@0 157 { 0x048C, "gbz","AF" }, // Dari Afghanistan
michael@0 158 { 0x0801, "ar","IQ" }, // Arabic Iraq
michael@0 159 { 0x0804, "zn","CH" }, // Chinese People's Republic of China
michael@0 160 { 0x0807, "de","CH" }, // German Switzerland
michael@0 161 { 0x0809, "en","GB" }, // English United Kingdom
michael@0 162 { 0x080A, "es","MX" }, // Spanish Mexico
michael@0 163 { 0x080C, "fr","BE" }, // French Belgium
michael@0 164 { 0x0810, "it","CH" }, // Italian Switzerland
michael@0 165 { 0x0813, "nl","BE" }, // Dutch Belgium
michael@0 166 { 0x0814, "nn","NO" }, // Norwegian (Nynorsk) Norway
michael@0 167 { 0x0816, "pt","PT" }, // Portuguese Portugal
michael@0 168 { 0x081A, "sh","RS" }, // Serbian (Latin) Serbia
michael@0 169 { 0x081D, "sv","FI" }, // Sweden Finland
michael@0 170 { 0x082C, "az","AZ" }, // Azeri (Cyrillic) Azerbaijan
michael@0 171 { 0x082E, "dsb","DE" }, // Lower Sorbian Germany
michael@0 172 { 0x083B, "se","SE" }, // Sami (Northern) Sweden
michael@0 173 { 0x083C, "ga","IE" }, // Irish Ireland
michael@0 174 { 0x083E, "ms","BN" }, // Malay Brunei Darussalam
michael@0 175 { 0x0843, "uz","UZ" }, // Uzbek (Cyrillic) Uzbekistan
michael@0 176 { 0x0845, "bn","BD" }, // Bengali Bangladesh
michael@0 177 { 0x0850, "mn","MN" }, // Mongolian (Traditional) People's Republic of China
michael@0 178 { 0x085D, "iu","CA" }, // Inuktitut (Latin) Canada
michael@0 179 { 0x085F, "ber","DZ" }, // Tamazight (Latin) Algeria
michael@0 180 { 0x086B, "es","EC" }, // Quechua Ecuador
michael@0 181 { 0x0C01, "ar","EG" }, // Arabic Egypt
michael@0 182 { 0x0C04, "zh","HK" }, // Chinese Hong Kong S.A.R.
michael@0 183 { 0x0C07, "de","AT" }, // German Austria
michael@0 184 { 0x0C09, "en","AU" }, // English Australia
michael@0 185 { 0x0C0A, "es","ES" }, // Spanish (Modern Sort) Spain
michael@0 186 { 0x0C0C, "fr","CA" }, // French Canada
michael@0 187 { 0x0C1A, "sr","CS" }, // Serbian (Cyrillic) Serbia
michael@0 188 { 0x0C3B, "se","FI" }, // Sami (Northern) Finland
michael@0 189 { 0x0C6B, "qu","PE" }, // Quechua Peru
michael@0 190 { 0x1001, "ar","LY" }, // Arabic Libya
michael@0 191 { 0x1004, "zh","SG" }, // Chinese Singapore
michael@0 192 { 0x1007, "de","LU" }, // German Luxembourg
michael@0 193 { 0x1009, "en","CA" }, // English Canada
michael@0 194 { 0x100A, "es","GT" }, // Spanish Guatemala
michael@0 195 { 0x100C, "fr","CH" }, // French Switzerland
michael@0 196 { 0x101A, "hr","BA" }, // Croatian (Latin) Bosnia and Herzegovina
michael@0 197 { 0x103B, "smj","NO" }, // Sami (Lule) Norway
michael@0 198 { 0x1401, "ar","DZ" }, // Arabic Algeria
michael@0 199 { 0x1404, "zh","MO" }, // Chinese Macao S.A.R.
michael@0 200 { 0x1407, "de","LI" }, // German Liechtenstein
michael@0 201 { 0x1409, "en","NZ" }, // English New Zealand
michael@0 202 { 0x140A, "es","CR" }, // Spanish Costa Rica
michael@0 203 { 0x140C, "fr","LU" }, // French Luxembourg
michael@0 204 { 0x141A, "bs","BA" }, // Bosnian (Latin) Bosnia and Herzegovina
michael@0 205 { 0x143B, "smj","SE" }, // Sami (Lule) Sweden
michael@0 206 { 0x1801, "ar","MA" }, // Arabic Morocco
michael@0 207 { 0x1809, "en","IE" }, // English Ireland
michael@0 208 { 0x180A, "es","PA" }, // Spanish Panama
michael@0 209 { 0x180C, "fr","MC" }, // French Principality of Monoco
michael@0 210 { 0x181A, "sh","BA" }, // Serbian (Latin) Bosnia and Herzegovina
michael@0 211 { 0x183B, "sma","NO" }, // Sami (Southern) Norway
michael@0 212 { 0x1C01, "ar","TN" }, // Arabic Tunisia
michael@0 213 { 0x1C09, "en","ZA" }, // English South Africa
michael@0 214 { 0x1C0A, "es","DO" }, // Spanish Dominican Republic
michael@0 215 { 0x1C1A, "sr","BA" }, // Serbian (Cyrillic) Bosnia and Herzegovina
michael@0 216 { 0x1C3B, "sma","SE" }, // Sami (Southern) Sweden
michael@0 217 { 0x2001, "ar","OM" }, // Arabic Oman
michael@0 218 { 0x2009, "en","JM" }, // English Jamaica
michael@0 219 { 0x200A, "es","VE" }, // Spanish Venezuela
michael@0 220 { 0x201A, "bs","BA" }, // Bosnian (Cyrillic) Bosnia and Herzegovina
michael@0 221 { 0x203B, "sms","FI" }, // Sami (Skolt) Finland
michael@0 222 { 0x2401, "ar","YE" }, // Arabic Yemen
michael@0 223 { 0x2409, "en","BS" }, // English Caribbean
michael@0 224 { 0x240A, "es","CO" }, // Spanish Colombia
michael@0 225 { 0x243B, "smn","FI" }, // Sami (Inari) Finland
michael@0 226 { 0x2801, "ar","SY" }, // Arabic Syria
michael@0 227 { 0x2809, "en","BZ" }, // English Belize
michael@0 228 { 0x280A, "es","PE" }, // Spanish Peru
michael@0 229 { 0x2C01, "ar","JO" }, // Arabic Jordan
michael@0 230 { 0x2C09, "en","TT" }, // English Trinidad and Tobago
michael@0 231 { 0x2C0A, "es","AR" }, // Spanish Argentina
michael@0 232 { 0x3001, "ar","LB" }, // Arabic Lebanon
michael@0 233 { 0x3009, "en","ZW" }, // English Zimbabwe
michael@0 234 { 0x300A, "es","EC" }, // Spanish Ecuador
michael@0 235 { 0x3401, "ar","KW" }, // Arabic Kuwait
michael@0 236 { 0x3409, "en","PH" }, // English Republic of the Philippines
michael@0 237 { 0x340A, "es","CL" }, // Spanish Chile
michael@0 238 { 0x3801, "ar","AE" }, // Arabic U.A.E.
michael@0 239 { 0x380A, "es","UY" }, // Spanish Uruguay
michael@0 240 { 0x3C01, "ar","BH" }, // Arabic Bahrain
michael@0 241 { 0x3C0A, "es","PY" }, // Spanish Paraguay
michael@0 242 { 0x4001, "ar","QA" }, // Arabic Qatar
michael@0 243 { 0x4009, "en","IN" }, // English India
michael@0 244 { 0x400A, "es","BO" }, // Spanish Bolivia
michael@0 245 { 0x4409, "en","MY" }, // English Malaysia
michael@0 246 { 0x440A, "es","SV" }, // Spanish El Salvador
michael@0 247 { 0x4809, "en","SG" }, // English Singapore
michael@0 248 { 0x480A, "es","HN" }, // Spanish Honduras
michael@0 249 { 0x4C0A, "es","NI" }, // Spanish Nicaragua
michael@0 250 { 0x500A, "es","PR" }, // Spanish Puerto Rico
michael@0 251 { 0x540A, "es","US" } // Spanish United States
michael@0 252 };
michael@0 253
michael@0 254 class Locale2Lang
michael@0 255 {
michael@0 256 Locale2Lang(const Locale2Lang &);
michael@0 257 Locale2Lang & operator = (const Locale2Lang &);
michael@0 258
michael@0 259 public:
michael@0 260 Locale2Lang() : mSeedPosition(128)
michael@0 261 {
michael@0 262 memset((void*)mLangLookup, 0, sizeof(mLangLookup));
michael@0 263 // create a tri lookup on first 2 letters of language code
michael@0 264 static const int maxIndex = sizeof(LANG_ENTRIES)/sizeof(IsoLangEntry);
michael@0 265 for (int i = 0; i < maxIndex; i++)
michael@0 266 {
michael@0 267 size_t a = LANG_ENTRIES[i].maLangStr[0] - 'a';
michael@0 268 size_t b = LANG_ENTRIES[i].maLangStr[1] - 'a';
michael@0 269 if (mLangLookup[a][b])
michael@0 270 {
michael@0 271 const IsoLangEntry ** old = mLangLookup[a][b];
michael@0 272 int len = 1;
michael@0 273 while (old[len]) len++;
michael@0 274 len += 2;
michael@0 275 mLangLookup[a][b] = gralloc<const IsoLangEntry *>(len);
michael@0 276 if (!mLangLookup[a][b])
michael@0 277 {
michael@0 278 mLangLookup[a][b] = old;
michael@0 279 continue;
michael@0 280 }
michael@0 281 mLangLookup[a][b][--len] = NULL;
michael@0 282 mLangLookup[a][b][--len] = &LANG_ENTRIES[i];
michael@0 283 while (--len >= 0)
michael@0 284 {
michael@0 285 assert(len >= 0);
michael@0 286 mLangLookup[a][b][len] = old[len];
michael@0 287 }
michael@0 288 free(old);
michael@0 289 }
michael@0 290 else
michael@0 291 {
michael@0 292 mLangLookup[a][b] = gralloc<const IsoLangEntry *>(2);
michael@0 293 if (!mLangLookup[a][b]) continue;
michael@0 294 mLangLookup[a][b][1] = NULL;
michael@0 295 mLangLookup[a][b][0] = &LANG_ENTRIES[i];
michael@0 296 }
michael@0 297 }
michael@0 298 while (2 * mSeedPosition < maxIndex)
michael@0 299 mSeedPosition *= 2;
michael@0 300 };
michael@0 301 ~Locale2Lang()
michael@0 302 {
michael@0 303 for (int i = 0; i != 26; ++i)
michael@0 304 for (int j = 0; j != 26; ++j)
michael@0 305 free(mLangLookup[i][j]);
michael@0 306 }
michael@0 307 unsigned short getMsId(const char * locale) const
michael@0 308 {
michael@0 309 size_t length = strlen(locale);
michael@0 310 size_t langLength = length;
michael@0 311 const char * language = locale;
michael@0 312 const char * script = NULL;
michael@0 313 const char * region = NULL;
michael@0 314 size_t regionLength = 0;
michael@0 315 const char * dash = strchr(locale, '-');
michael@0 316 if (dash && (dash != locale))
michael@0 317 {
michael@0 318 langLength = (dash - locale);
michael@0 319 size_t nextPartLength = length - langLength - 1;
michael@0 320 if (nextPartLength >= 2)
michael@0 321 {
michael@0 322 script = ++dash;
michael@0 323 dash = strchr(dash, '-');
michael@0 324 if (dash)
michael@0 325 {
michael@0 326 nextPartLength = (dash - script);
michael@0 327 region = ++dash;
michael@0 328 }
michael@0 329 if (nextPartLength == 2 &&
michael@0 330 (locale[langLength+1] > 0x40) && (locale[langLength+1] < 0x5B) &&
michael@0 331 (locale[langLength+2] > 0x40) && (locale[langLength+2] < 0x5B))
michael@0 332 {
michael@0 333 region = script;
michael@0 334 regionLength = nextPartLength;
michael@0 335 script = NULL;
michael@0 336 }
michael@0 337 else if (nextPartLength == 4)
michael@0 338 {
michael@0 339 if (dash)
michael@0 340 {
michael@0 341 dash = strchr(dash, '-');
michael@0 342 if (dash)
michael@0 343 {
michael@0 344 nextPartLength = (dash - region);
michael@0 345 }
michael@0 346 else
michael@0 347 {
michael@0 348 nextPartLength = langLength - (region - locale);
michael@0 349 }
michael@0 350 regionLength = nextPartLength;
michael@0 351 }
michael@0 352 }
michael@0 353 }
michael@0 354 }
michael@0 355 size_t a = 'e' - 'a';
michael@0 356 size_t b = 'n' - 'a';
michael@0 357 unsigned short langId = 0;
michael@0 358 int i = 0;
michael@0 359 switch (langLength)
michael@0 360 {
michael@0 361 case 2:
michael@0 362 {
michael@0 363 a = language[0] - 'a';
michael@0 364 b = language[1] - 'a';
michael@0 365 if ((a < 26) && (b < 26) && mLangLookup[a][b])
michael@0 366 {
michael@0 367 while (mLangLookup[a][b][i])
michael@0 368 {
michael@0 369 if (mLangLookup[a][b][i]->maLangStr[2] != '\0')
michael@0 370 {
michael@0 371 ++i;
michael@0 372 continue;
michael@0 373 }
michael@0 374 if (region && (strncmp(mLangLookup[a][b][i]->maCountry, region, regionLength) == 0))
michael@0 375 {
michael@0 376 langId = mLangLookup[a][b][i]->mnLang;
michael@0 377 break;
michael@0 378 }
michael@0 379 else if (langId == 0)
michael@0 380 {
michael@0 381 // possible fallback code
michael@0 382 langId = mLangLookup[a][b][i]->mnLang;
michael@0 383 }
michael@0 384 ++i;
michael@0 385 }
michael@0 386 }
michael@0 387 }
michael@0 388 break;
michael@0 389 case 3:
michael@0 390 {
michael@0 391 a = language[0] - 'a';
michael@0 392 b = language[1] - 'a';
michael@0 393 if (mLangLookup[a][b])
michael@0 394 {
michael@0 395 while (mLangLookup[a][b][i])
michael@0 396 {
michael@0 397 if (mLangLookup[a][b][i]->maLangStr[2] != language[2])
michael@0 398 {
michael@0 399 ++i;
michael@0 400 continue;
michael@0 401 }
michael@0 402 if (region && (strncmp(mLangLookup[a][b][i]->maCountry, region, regionLength) == 0))
michael@0 403 {
michael@0 404 langId = mLangLookup[a][b][i]->mnLang;
michael@0 405 break;
michael@0 406 }
michael@0 407 else if (langId == 0)
michael@0 408 {
michael@0 409 // possible fallback code
michael@0 410 langId = mLangLookup[a][b][i]->mnLang;
michael@0 411 }
michael@0 412 ++i;
michael@0 413 }
michael@0 414 }
michael@0 415 }
michael@0 416 break;
michael@0 417 default:
michael@0 418 break;
michael@0 419 }
michael@0 420 if (langId == 0) langId = 0x409;
michael@0 421 return langId;
michael@0 422 }
michael@0 423 const IsoLangEntry * findEntryById(unsigned short langId) const
michael@0 424 {
michael@0 425 static const int maxIndex = sizeof(LANG_ENTRIES)/sizeof(IsoLangEntry);
michael@0 426 int window = mSeedPosition;
michael@0 427 int guess = mSeedPosition - 1;
michael@0 428 while (LANG_ENTRIES[guess].mnLang != langId)
michael@0 429 {
michael@0 430 window /= 2;
michael@0 431 if (window == 0) return NULL;
michael@0 432 guess += (LANG_ENTRIES[guess].mnLang > langId)? -window : window;
michael@0 433 while (guess >= maxIndex)
michael@0 434 {
michael@0 435 window /= 2;
michael@0 436 guess -= window;
michael@0 437 assert(window);
michael@0 438 }
michael@0 439 }
michael@0 440 return &LANG_ENTRIES[guess];
michael@0 441 }
michael@0 442
michael@0 443 CLASS_NEW_DELETE;
michael@0 444
michael@0 445 private:
michael@0 446 const IsoLangEntry ** mLangLookup[26][26];
michael@0 447 int mSeedPosition;
michael@0 448 };
michael@0 449
michael@0 450 } // namespace graphite2

mercurial