OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "build/build_config.h" | 5 #include "build/build_config.h" |
6 | 6 |
7 #include "chrome/common/l10n_util.h" | 7 #include "chrome/common/l10n_util.h" |
8 | 8 |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/file_path.h" | 10 #include "base/file_path.h" |
11 #include "base/file_util.h" | 11 #include "base/file_util.h" |
12 #include "base/path_service.h" | 12 #include "base/path_service.h" |
13 #include "base/scoped_ptr.h" | 13 #include "base/scoped_ptr.h" |
14 #include "base/string16.h" | 14 #include "base/string16.h" |
15 #include "base/string_piece.h" | 15 #include "base/string_piece.h" |
16 #include "base/string_util.h" | 16 #include "base/string_util.h" |
17 #include "base/sys_string_conversions.h" | 17 #include "base/sys_string_conversions.h" |
18 #include "chrome/common/chrome_paths.h" | 18 #include "chrome/common/chrome_paths.h" |
19 #include "chrome/common/chrome_switches.h" | 19 #include "chrome/common/chrome_switches.h" |
20 #include "chrome/common/gfx/chrome_canvas.h" | 20 #include "chrome/common/gfx/chrome_canvas.h" |
21 #include "chrome/common/resource_bundle.h" | 21 #include "chrome/common/resource_bundle.h" |
22 | 22 |
23 // TODO(playmobil): remove this undef once SkPostConfig.h is fixed. | 23 // TODO(playmobil): remove this undef once SkPostConfig.h is fixed. |
24 // skia/include/corecg/SkPostConfig.h #defines strcasecmp() so we can't use | 24 // skia/include/corecg/SkPostConfig.h #defines strcasecmp() so we can't use |
25 // base::strcasecmp() without #undefing it here. | 25 // base::strcasecmp() without #undefing it here. |
26 #undef strcasecmp | 26 #undef strcasecmp |
27 | 27 |
28 namespace { | 28 namespace { |
29 | 29 |
| 30 #if defined(OS_WIN) |
| 31 static const FilePath::CharType kLocaleFileExtension[] = L".dll"; |
| 32 #elif defined(OS_POSIX) |
| 33 static const FilePath::CharType kLocaleFileExtension[] = ".pak"; |
| 34 #endif |
| 35 |
30 // Added to the end of strings that are too big in TrucateString. | 36 // Added to the end of strings that are too big in TrucateString. |
31 static const wchar_t* const kElideString = L"\x2026"; | 37 static const wchar_t* const kElideString = L"\x2026"; |
32 | 38 |
33 // Get language and region from the OS. | 39 // Get language and region from the OS. |
34 void GetLanguageAndRegionFromOS(std::string* lang, std::string* region) { | 40 void GetLanguageAndRegionFromOS(std::string* lang, std::string* region) { |
35 // Later we may have to change this to be OS-dependent so that | 41 // Later we may have to change this to be OS-dependent so that |
36 // it's not affected by ICU's default locale. It's all right | 42 // it's not affected by ICU's default locale. It's all right |
37 // to do this way because SetICUDefaultLocale is internal | 43 // to do this way because SetICUDefaultLocale is internal |
38 // to this file and we know where/when it's called. | 44 // to this file and we know where/when it's called. |
39 Locale locale = Locale::getDefault(); | 45 Locale locale = Locale::getDefault(); |
40 const char* language = locale.getLanguage(); | 46 const char* language = locale.getLanguage(); |
41 const char* country = locale.getCountry(); | 47 const char* country = locale.getCountry(); |
42 DCHECK(language); | 48 DCHECK(language); |
43 *lang = language; | 49 *lang = language; |
44 *region = country; | 50 *region = country; |
45 } | 51 } |
46 | 52 |
47 // Convert Chrome locale name (DLL name) to ICU locale name | 53 // Convert Chrome locale name to ICU locale name |
48 std::string ICULocaleName(const std::wstring& locale_string) { | 54 std::string ICULocaleName(const std::wstring& locale_string) { |
49 // If not Spanish, just return it. | 55 // If not Spanish, just return it. |
50 if (locale_string.substr(0, 2) != L"es") | 56 if (locale_string.substr(0, 2) != L"es") |
51 return WideToASCII(locale_string); | 57 return WideToASCII(locale_string); |
52 // Expand es to es-ES. | 58 // Expand es to es-ES. |
53 if (LowerCaseEqualsASCII(locale_string, "es")) | 59 if (LowerCaseEqualsASCII(locale_string, "es")) |
54 return "es-ES"; | 60 return "es-ES"; |
55 // Map es-419 (Latin American Spanish) to es-FOO depending on the system | 61 // Map es-419 (Latin American Spanish) to es-FOO depending on the system |
56 // locale. If it's es-RR other than es-ES, map to es-RR. Otherwise, map | 62 // locale. If it's es-RR other than es-ES, map to es-RR. Otherwise, map |
57 // to es-MX (the most populous in Spanish-speaking Latin America). | 63 // to es-MX (the most populous in Spanish-speaking Latin America). |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
109 if (base::strcasecmp(kDuplicateNames[i], locale_name.c_str()) == 0) | 115 if (base::strcasecmp(kDuplicateNames[i], locale_name.c_str()) == 0) |
110 return true; | 116 return true; |
111 } | 117 } |
112 return false; | 118 return false; |
113 } | 119 } |
114 | 120 |
115 bool IsLocaleAvailable(const std::wstring& locale, | 121 bool IsLocaleAvailable(const std::wstring& locale, |
116 const std::wstring& locale_path) { | 122 const std::wstring& locale_path) { |
117 std::wstring test_locale = locale; | 123 std::wstring test_locale = locale; |
118 // If locale has any illegal characters in it, we don't want to try to | 124 // If locale has any illegal characters in it, we don't want to try to |
119 // load it because it may be pointing outside the locale dll directory. | 125 // load it because it may be pointing outside the locale data file directory. |
120 file_util::ReplaceIllegalCharacters(&test_locale, ' '); | 126 file_util::ReplaceIllegalCharacters(&test_locale, ' '); |
121 if (test_locale != locale) | 127 if (test_locale != locale) |
122 return false; | 128 return false; |
123 | 129 |
124 std::wstring test_path = locale_path; | 130 FilePath test_path = FilePath::FromWStringHack(locale_path) |
125 file_util::AppendToPath(&test_path, locale + L".dll"); | 131 .Append(FilePath::FromWStringHack(locale)) |
| 132 .ReplaceExtension(kLocaleFileExtension); |
126 return file_util::PathExists(test_path) && SetICUDefaultLocale(locale); | 133 return file_util::PathExists(test_path) && SetICUDefaultLocale(locale); |
127 } | 134 } |
128 | 135 |
129 bool CheckAndResolveLocale(const std::wstring& locale, | 136 bool CheckAndResolveLocale(const std::wstring& locale, |
130 const std::wstring& locale_path, | 137 const std::wstring& locale_path, |
131 std::wstring* resolved_locale) { | 138 std::wstring* resolved_locale) { |
132 if (IsLocaleAvailable(locale, locale_path)) { | 139 if (IsLocaleAvailable(locale, locale_path)) { |
133 *resolved_locale = locale; | 140 *resolved_locale = locale; |
134 return true; | 141 return true; |
135 } | 142 } |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
232 // Next, try the system locale. | 239 // Next, try the system locale. |
233 const std::wstring system_locale = GetSystemLocale(); | 240 const std::wstring system_locale = GetSystemLocale(); |
234 if (CheckAndResolveLocale(system_locale, locale_path, &resolved_locale)) | 241 if (CheckAndResolveLocale(system_locale, locale_path, &resolved_locale)) |
235 return resolved_locale; | 242 return resolved_locale; |
236 | 243 |
237 // Fallback on en-US. | 244 // Fallback on en-US. |
238 const std::wstring fallback_locale(L"en-US"); | 245 const std::wstring fallback_locale(L"en-US"); |
239 if (IsLocaleAvailable(fallback_locale, locale_path)) | 246 if (IsLocaleAvailable(fallback_locale, locale_path)) |
240 return fallback_locale; | 247 return fallback_locale; |
241 | 248 |
242 #if defined(OS_WIN) | 249 // No locale data file was found; we shouldn't get here. |
243 // No DLL, we shouldn't get here. | |
244 NOTREACHED(); | 250 NOTREACHED(); |
245 #else | |
246 // We need a locale data file. | |
247 NOTIMPLEMENTED(); | |
248 #endif | |
249 | 251 |
250 return std::wstring(); | 252 return std::wstring(); |
251 } | 253 } |
252 | 254 |
253 std::wstring GetLocalName(const std::wstring& locale_code_wstr, | 255 std::wstring GetLocalName(const std::wstring& locale_code_wstr, |
254 const std::wstring& app_locale_wstr, | 256 const std::wstring& app_locale_wstr, |
255 bool is_for_ui) { | 257 bool is_for_ui) { |
256 std::string locale_code_str = WideToASCII(locale_code_wstr); | 258 std::string locale_code_str = WideToASCII(locale_code_wstr); |
257 const std::string app_locale = WideToASCII(app_locale_wstr); | 259 const std::string app_locale = WideToASCII(app_locale_wstr); |
258 const char* locale_code = locale_code_str.c_str(); | 260 const char* locale_code = locale_code_str.c_str(); |
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
644 | 646 |
645 const std::vector<std::wstring>& GetAvailableLocales() { | 647 const std::vector<std::wstring>& GetAvailableLocales() { |
646 static std::vector<std::wstring> locales; | 648 static std::vector<std::wstring> locales; |
647 if (locales.empty()) { | 649 if (locales.empty()) { |
648 int num_locales = uloc_countAvailable(); | 650 int num_locales = uloc_countAvailable(); |
649 for (int i = 0; i < num_locales; ++i) { | 651 for (int i = 0; i < num_locales; ++i) { |
650 std::string locale_name = uloc_getAvailable(i); | 652 std::string locale_name = uloc_getAvailable(i); |
651 // Filter out the names that have aliases. | 653 // Filter out the names that have aliases. |
652 if (IsDuplicateName(locale_name)) | 654 if (IsDuplicateName(locale_name)) |
653 continue; | 655 continue; |
654 // Normalize underscores to hyphens because that's what our locale dlls | 656 // Normalize underscores to hyphens because that's what our locale files |
655 // use. | 657 // use. |
656 std::replace(locale_name.begin(), locale_name.end(), '_', '-'); | 658 std::replace(locale_name.begin(), locale_name.end(), '_', '-'); |
657 | 659 |
658 // Map the Chinese locale names over to zh-CN and zh-TW. | 660 // Map the Chinese locale names over to zh-CN and zh-TW. |
659 if (LowerCaseEqualsASCII(locale_name, "zh-hans")) { | 661 if (LowerCaseEqualsASCII(locale_name, "zh-hans")) { |
660 locale_name = "zh-CN"; | 662 locale_name = "zh-CN"; |
661 } else if (LowerCaseEqualsASCII(locale_name, "zh-hant")) { | 663 } else if (LowerCaseEqualsASCII(locale_name, "zh-hant")) { |
662 locale_name = "zh-TW"; | 664 locale_name = "zh-TW"; |
663 } | 665 } |
664 locales.push_back(ASCIIToWide(locale_name)); | 666 locales.push_back(ASCIIToWide(locale_name)); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
713 } | 715 } |
714 | 716 |
715 void BiDiLineIterator::GetLogicalRun(int start, | 717 void BiDiLineIterator::GetLogicalRun(int start, |
716 int* end, | 718 int* end, |
717 UBiDiLevel* level) { | 719 UBiDiLevel* level) { |
718 DCHECK(bidi_ != NULL); | 720 DCHECK(bidi_ != NULL); |
719 ubidi_getLogicalRun(bidi_, start, end, level); | 721 ubidi_getLogicalRun(bidi_, start, end, level); |
720 } | 722 } |
721 | 723 |
722 } | 724 } |
OLD | NEW |