| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2011 Google Inc. All rights reserved. | 2 * Copyright (C) 2011 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 25 matching lines...) Expand all Loading... |
| 36 | 36 |
| 37 namespace blink { | 37 namespace blink { |
| 38 | 38 |
| 39 struct SubtagScript { | 39 struct SubtagScript { |
| 40 const char* subtag; | 40 const char* subtag; |
| 41 UScriptCode script; | 41 UScriptCode script; |
| 42 }; | 42 }; |
| 43 | 43 |
| 44 using SubtagScriptMap = HashMap<String, UScriptCode, CaseFoldingHash>; | 44 using SubtagScriptMap = HashMap<String, UScriptCode, CaseFoldingHash>; |
| 45 | 45 |
| 46 static SubtagScriptMap createSubtagScriptMap(const SubtagScript list[], size_t s
ize) | 46 static void createSubtagScriptMap(SubtagScriptMap& map, const SubtagScript list[
], size_t size) |
| 47 { | 47 { |
| 48 SubtagScriptMap map; | 48 map.reserveCapacityForSize(size); |
| 49 for (size_t i = 0; i < size; ++i) | 49 for (size_t i = 0; i < size; ++i) |
| 50 map.set(list[i].subtag, list[i].script); | 50 map.set(list[i].subtag, list[i].script); |
| 51 return map; | |
| 52 } | 51 } |
| 53 | 52 |
| 54 UScriptCode scriptNameToCode(const String& scriptName) | 53 UScriptCode scriptNameToCode(const String& scriptName) |
| 55 { | 54 { |
| 56 // This generally maps an ISO 15924 script code to its UScriptCode, but cert
ain families of script codes are | 55 // This generally maps an ISO 15924 script code to its UScriptCode, but cert
ain families of script codes are |
| 57 // treated as a single script for assigning a per-script font in Settings. F
or example, "hira" is mapped to | 56 // treated as a single script for assigning a per-script font in Settings. F
or example, "hira" is mapped to |
| 58 // USCRIPT_KATAKANA_OR_HIRAGANA instead of USCRIPT_HIRAGANA, since we want a
ll Japanese scripts to be rendered | 57 // USCRIPT_KATAKANA_OR_HIRAGANA instead of USCRIPT_HIRAGANA, since we want a
ll Japanese scripts to be rendered |
| 59 // using the same font setting. | 58 // using the same font setting. |
| 60 static const SubtagScript scriptNameCodeList[] = { | 59 static const SubtagScript scriptNameCodeList[] = { |
| 61 { "zyyy", USCRIPT_COMMON }, | 60 { "zyyy", USCRIPT_COMMON }, |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 158 { "syrn", USCRIPT_EASTERN_SYRIAC }, | 157 { "syrn", USCRIPT_EASTERN_SYRIAC }, |
| 159 { "teng", USCRIPT_TENGWAR }, | 158 { "teng", USCRIPT_TENGWAR }, |
| 160 { "vaii", USCRIPT_VAI }, | 159 { "vaii", USCRIPT_VAI }, |
| 161 { "visp", USCRIPT_VISIBLE_SPEECH }, | 160 { "visp", USCRIPT_VISIBLE_SPEECH }, |
| 162 { "xsux", USCRIPT_CUNEIFORM }, | 161 { "xsux", USCRIPT_CUNEIFORM }, |
| 163 { "jpan", USCRIPT_KATAKANA_OR_HIRAGANA }, | 162 { "jpan", USCRIPT_KATAKANA_OR_HIRAGANA }, |
| 164 { "kore", USCRIPT_HANGUL }, | 163 { "kore", USCRIPT_HANGUL }, |
| 165 { "zxxx", USCRIPT_UNWRITTEN_LANGUAGES }, | 164 { "zxxx", USCRIPT_UNWRITTEN_LANGUAGES }, |
| 166 { "zzzz", USCRIPT_UNKNOWN } | 165 { "zzzz", USCRIPT_UNKNOWN } |
| 167 }; | 166 }; |
| 168 DEFINE_STATIC_LOCAL(SubtagScriptMap, scriptNameCodeMap, | 167 DEFINE_STATIC_LOCAL(SubtagScriptMap, scriptNameCodeMap, ()); |
| 169 (createSubtagScriptMap(scriptNameCodeList, WTF_ARRAY_LENGTH(scriptNameCo
deList)))); | 168 if (scriptNameCodeMap.isEmpty()) |
| 169 createSubtagScriptMap(scriptNameCodeMap, scriptNameCodeList, WTF_ARRAY_L
ENGTH(scriptNameCodeList)); |
| 170 | 170 |
| 171 const auto& it = scriptNameCodeMap.find(scriptName); | 171 const auto& it = scriptNameCodeMap.find(scriptName); |
| 172 if (it != scriptNameCodeMap.end()) | 172 if (it != scriptNameCodeMap.end()) |
| 173 return it->value; | 173 return it->value; |
| 174 return USCRIPT_INVALID_CODE; | 174 return USCRIPT_INVALID_CODE; |
| 175 } | 175 } |
| 176 | 176 |
| 177 UScriptCode localeToScriptCodeForFontSelection(const String& locale) | 177 UScriptCode localeToScriptCodeForFontSelection(const String& locale) |
| 178 { | 178 { |
| 179 static const SubtagScript localeScriptList[] = { | 179 static const SubtagScript localeScriptList[] = { |
| (...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 446 { "zh-hak", USCRIPT_TRADITIONAL_HAN }, | 446 { "zh-hak", USCRIPT_TRADITIONAL_HAN }, |
| 447 { "zh-lzh", USCRIPT_TRADITIONAL_HAN }, | 447 { "zh-lzh", USCRIPT_TRADITIONAL_HAN }, |
| 448 { "zh-nan", USCRIPT_TRADITIONAL_HAN }, | 448 { "zh-nan", USCRIPT_TRADITIONAL_HAN }, |
| 449 { "zh-yue", USCRIPT_TRADITIONAL_HAN }, | 449 { "zh-yue", USCRIPT_TRADITIONAL_HAN }, |
| 450 // Chinese with regions. Logically, regions should be handled | 450 // Chinese with regions. Logically, regions should be handled |
| 451 // separately, but this works for the current purposes. | 451 // separately, but this works for the current purposes. |
| 452 { "zh-hk", USCRIPT_TRADITIONAL_HAN }, | 452 { "zh-hk", USCRIPT_TRADITIONAL_HAN }, |
| 453 { "zh-mo", USCRIPT_TRADITIONAL_HAN }, | 453 { "zh-mo", USCRIPT_TRADITIONAL_HAN }, |
| 454 { "zh-tw", USCRIPT_TRADITIONAL_HAN }, | 454 { "zh-tw", USCRIPT_TRADITIONAL_HAN }, |
| 455 }; | 455 }; |
| 456 DEFINE_STATIC_LOCAL(SubtagScriptMap, localeScriptMap, | 456 DEFINE_STATIC_LOCAL(SubtagScriptMap, localeScriptMap, ()); |
| 457 (createSubtagScriptMap(localeScriptList, WTF_ARRAY_LENGTH(localeScriptLi
st)))); | 457 if (localeScriptMap.isEmpty()) |
| 458 createSubtagScriptMap(localeScriptMap, localeScriptList, WTF_ARRAY_LENGT
H(localeScriptList)); |
| 458 | 459 |
| 459 // BCP 47 uses '-' as the delimiter but ICU uses '_'. | 460 // BCP 47 uses '-' as the delimiter but ICU uses '_'. |
| 460 // https://tools.ietf.org/html/bcp47 | 461 // https://tools.ietf.org/html/bcp47 |
| 461 String canonicalLocale = locale; | 462 String canonicalLocale = locale; |
| 462 canonicalLocale.replace('_', '-'); | 463 canonicalLocale.replace('_', '-'); |
| 463 while (!canonicalLocale.isEmpty()) { | 464 while (!canonicalLocale.isEmpty()) { |
| 464 const auto& it = localeScriptMap.find(canonicalLocale); | 465 const auto& it = localeScriptMap.find(canonicalLocale); |
| 465 if (it != localeScriptMap.end()) | 466 if (it != localeScriptMap.end()) |
| 466 return it->value; | 467 return it->value; |
| 467 size_t pos = canonicalLocale.reverseFind('-'); | 468 size_t pos = canonicalLocale.reverseFind('-'); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 480 | 481 |
| 481 static UScriptCode scriptCodeForHanFromRegion(const String& region) | 482 static UScriptCode scriptCodeForHanFromRegion(const String& region) |
| 482 { | 483 { |
| 483 static const SubtagScript regionScriptList[] = { | 484 static const SubtagScript regionScriptList[] = { |
| 484 { "hk", USCRIPT_TRADITIONAL_HAN }, | 485 { "hk", USCRIPT_TRADITIONAL_HAN }, |
| 485 { "jp", USCRIPT_KATAKANA_OR_HIRAGANA }, | 486 { "jp", USCRIPT_KATAKANA_OR_HIRAGANA }, |
| 486 { "kr", USCRIPT_HANGUL }, | 487 { "kr", USCRIPT_HANGUL }, |
| 487 { "mo", USCRIPT_TRADITIONAL_HAN }, | 488 { "mo", USCRIPT_TRADITIONAL_HAN }, |
| 488 { "tw", USCRIPT_TRADITIONAL_HAN }, | 489 { "tw", USCRIPT_TRADITIONAL_HAN }, |
| 489 }; | 490 }; |
| 490 DEFINE_STATIC_LOCAL(SubtagScriptMap, regionScriptMap, | 491 DEFINE_STATIC_LOCAL(SubtagScriptMap, regionScriptMap, ()); |
| 491 (createSubtagScriptMap(regionScriptList, WTF_ARRAY_LENGTH(regionScriptLi
st)))); | 492 if (regionScriptMap.isEmpty()) |
| 493 createSubtagScriptMap(regionScriptMap, regionScriptList, WTF_ARRAY_LENGT
H(regionScriptList)); |
| 492 | 494 |
| 493 const auto& it = regionScriptMap.find(region); | 495 const auto& it = regionScriptMap.find(region); |
| 494 return it != regionScriptMap.end() ? it->value : USCRIPT_COMMON; | 496 return it != regionScriptMap.end() ? it->value : USCRIPT_COMMON; |
| 495 } | 497 } |
| 496 | 498 |
| 497 UScriptCode scriptCodeForHanFromSubtags(const String& locale, char delimiter) | 499 UScriptCode scriptCodeForHanFromSubtags(const String& locale, char delimiter) |
| 498 { | 500 { |
| 499 // Some sites emit lang="en-JP" when English is set as the preferred | 501 // Some sites emit lang="en-JP" when English is set as the preferred |
| 500 // language. Use script/region subtags of the content locale to pick the | 502 // language. Use script/region subtags of the content locale to pick the |
| 501 // fallback font for unified Han ideographs. | 503 // fallback font for unified Han ideographs. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 514 script = scriptNameToCode(locale.substring(begin, len)); | 516 script = scriptNameToCode(locale.substring(begin, len)); |
| 515 if (script != USCRIPT_INVALID_CODE) | 517 if (script != USCRIPT_INVALID_CODE) |
| 516 return script; | 518 return script; |
| 517 } | 519 } |
| 518 } | 520 } |
| 519 | 521 |
| 520 return USCRIPT_COMMON; | 522 return USCRIPT_COMMON; |
| 521 } | 523 } |
| 522 | 524 |
| 523 } // namespace blink | 525 } // namespace blink |
| OLD | NEW |