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 <algorithm> | |
8 | |
9 #include "chrome/common/l10n_util.h" | 7 #include "chrome/common/l10n_util.h" |
10 | 8 |
11 #include "base/command_line.h" | 9 #include "base/command_line.h" |
12 #include "base/file_util.h" | 10 #include "base/file_util.h" |
13 #include "base/logging.h" | |
14 #include "base/path_service.h" | 11 #include "base/path_service.h" |
15 #include "base/scoped_ptr.h" | |
16 #include "base/string_util.h" | |
17 #include "chrome/common/chrome_paths.h" | 12 #include "chrome/common/chrome_paths.h" |
18 #include "chrome/common/chrome_switches.h" | 13 #include "chrome/common/chrome_switches.h" |
19 #include "chrome/common/gfx/chrome_canvas.h" | 14 #include "chrome/common/gfx/chrome_canvas.h" |
20 #if defined(OS_WIN) || defined(OS_LINUX) | 15 #if defined(OS_WIN) || defined(OS_LINUX) |
21 // TODO(port): re-enable. | 16 // TODO(port): re-enable. |
22 #include "chrome/common/resource_bundle.h" | 17 #include "chrome/common/resource_bundle.h" |
23 #endif | 18 #endif |
24 #if defined(OS_WIN) | 19 #if defined(OS_WIN) |
25 #include "chrome/views/view.h" | 20 #include "chrome/views/view.h" |
26 #endif // defined(OS_WIN) | 21 #endif // defined(OS_WIN) |
27 #include "unicode/coll.h" | |
28 #include "unicode/locid.h" | |
29 #include "unicode/rbbi.h" | 22 #include "unicode/rbbi.h" |
30 #include "unicode/uchar.h" | 23 #include "unicode/uchar.h" |
31 | 24 |
32 // TODO(playmobil): remove this undef once SkPostConfig.h is fixed. | 25 // TODO(playmobil): remove this undef once SkPostConfig.h is fixed. |
33 // skia/include/corecg/SkPostConfig.h #defines strcasecmp() so we can't use | 26 // skia/include/corecg/SkPostConfig.h #defines strcasecmp() so we can't use |
34 // base::strcasecmp() without #undefing it here. | 27 // base::strcasecmp() without #undefing it here. |
35 #undef strcasecmp | 28 #undef strcasecmp |
36 | 29 |
37 namespace { | 30 namespace { |
38 | 31 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 Locale locale(ICULocaleName(locale_string).c_str()); | 85 Locale locale(ICULocaleName(locale_string).c_str()); |
93 UErrorCode error_code = U_ZERO_ERROR; | 86 UErrorCode error_code = U_ZERO_ERROR; |
94 Locale::setDefault(locale, error_code); | 87 Locale::setDefault(locale, error_code); |
95 // This return value is actually bogus because Locale object is | 88 // This return value is actually bogus because Locale object is |
96 // an ID and setDefault seems to always succeed (regardless of the | 89 // an ID and setDefault seems to always succeed (regardless of the |
97 // presence of actual locale data). However, | 90 // presence of actual locale data). However, |
98 // it does not hurt to have it as a sanity check. | 91 // it does not hurt to have it as a sanity check. |
99 return U_SUCCESS(error_code); | 92 return U_SUCCESS(error_code); |
100 } | 93 } |
101 | 94 |
102 // Compares two wstrings and returns true if the first arg is less than the | |
103 // second arg. This uses the locale specified in the constructor. | |
104 class StringComparator : public std::binary_function<const std::wstring&, | |
105 const std::wstring&, | |
106 bool> { | |
107 public: | |
108 explicit StringComparator(Collator* collator) | |
109 : collator_(collator) { } | |
110 | |
111 // Returns true if lhs preceeds rhs. | |
112 bool operator() (const std::wstring& lhs, const std::wstring& rhs) { | |
113 UErrorCode error = U_ZERO_ERROR; | |
114 #if defined(WCHAR_T_IS_UTF32) | |
115 // Need to convert to UTF-16 to be compatible with UnicodeString's | |
116 // constructor. | |
117 string16 lhs_utf16 = WideToUTF16(lhs); | |
118 string16 rhs_utf16 = WideToUTF16(rhs); | |
119 | |
120 UCollationResult result = collator_->compare( | |
121 static_cast<const UChar*>(lhs_utf16.c_str()), | |
122 static_cast<int>(lhs_utf16.length()), | |
123 static_cast<const UChar*>(rhs_utf16.c_str()), | |
124 static_cast<int>(rhs_utf16.length()), | |
125 error); | |
126 #else | |
127 UCollationResult result = collator_->compare( | |
128 static_cast<const UChar*>(lhs.c_str()), static_cast<int>(lhs.length()), | |
129 static_cast<const UChar*>(rhs.c_str()), static_cast<int>(rhs.length()), | |
130 error); | |
131 #endif | |
132 DCHECK(U_SUCCESS(error)); | |
133 | |
134 return result == UCOL_LESS; | |
135 } | |
136 | |
137 private: | |
138 Collator* collator_; | |
139 }; | |
140 | |
141 // Returns true if |locale_name| has an alias in the ICU data file. | 95 // Returns true if |locale_name| has an alias in the ICU data file. |
142 bool IsDuplicateName(const std::string& locale_name) { | 96 bool IsDuplicateName(const std::string& locale_name) { |
143 static const char* const kDuplicateNames[] = { | 97 static const char* const kDuplicateNames[] = { |
144 "en", | 98 "en", |
145 "pt", | 99 "pt", |
146 "zh", | 100 "zh", |
147 "zh_hans_cn", | 101 "zh_hans_cn", |
148 "zh_hant_tw" | 102 "zh_hant_tw" |
149 }; | 103 }; |
150 | 104 |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
243 std::string ret; | 197 std::string ret; |
244 if (!language.empty()) | 198 if (!language.empty()) |
245 ret.append(language); | 199 ret.append(language); |
246 if (!region.empty()) { | 200 if (!region.empty()) { |
247 ret.append("-"); | 201 ret.append("-"); |
248 ret.append(region); | 202 ret.append(region); |
249 } | 203 } |
250 return ASCIIToWide(ret); | 204 return ASCIIToWide(ret); |
251 } | 205 } |
252 | 206 |
| 207 // Compares the character data stored in two different strings by specified |
| 208 // Collator instance. |
| 209 UCollationResult CompareStringWithCollator(const Collator* collator, |
| 210 const std::wstring& lhs, |
| 211 const std::wstring& rhs) { |
| 212 DCHECK(collator); |
| 213 UErrorCode error = U_ZERO_ERROR; |
| 214 #if defined(WCHAR_T_IS_UTF32) |
| 215 // Need to convert to UTF-16 to be compatible with UnicodeString's |
| 216 // constructor. |
| 217 string16 lhs_utf16 = WideToUTF16(lhs); |
| 218 string16 rhs_utf16 = WideToUTF16(rhs); |
| 219 |
| 220 UCollationResult result = collator->compare( |
| 221 static_cast<const UChar*>(lhs_utf16.c_str()), |
| 222 static_cast<int>(lhs_utf16.length()), |
| 223 static_cast<const UChar*>(rhs_utf16.c_str()), |
| 224 static_cast<int>(rhs_utf16.length()), |
| 225 error); |
| 226 #else |
| 227 UCollationResult result = collator->compare( |
| 228 static_cast<const UChar*>(lhs.c_str()), static_cast<int>(lhs.length()), |
| 229 static_cast<const UChar*>(rhs.c_str()), static_cast<int>(rhs.length()), |
| 230 error); |
| 231 #endif |
| 232 DCHECK(U_SUCCESS(error)); |
| 233 return result; |
| 234 } |
| 235 |
253 } // namespace | 236 } // namespace |
254 | 237 |
255 namespace l10n_util { | 238 namespace l10n_util { |
256 | 239 |
257 // Represents the locale-specific text direction. | 240 // Represents the locale-specific text direction. |
258 static TextDirection g_text_direction = UNKNOWN_DIRECTION; | 241 static TextDirection g_text_direction = UNKNOWN_DIRECTION; |
259 | 242 |
260 std::wstring GetApplicationLocale(const std::wstring& pref_locale) { | 243 std::wstring GetApplicationLocale(const std::wstring& pref_locale) { |
261 std::wstring locale_path; | 244 std::wstring locale_path; |
262 PathService::Get(chrome::DIR_LOCALES, &locale_path); | 245 PathService::Get(chrome::DIR_LOCALES, &locale_path); |
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
594 ::SetWindowLong(hwnd, GWL_EXSTYLE, ex_style); | 577 ::SetWindowLong(hwnd, GWL_EXSTYLE, ex_style); |
595 | 578 |
596 // Right-to-left layout changes are not applied to the window immediately | 579 // Right-to-left layout changes are not applied to the window immediately |
597 // so we should make sure a WM_PAINT is sent to the window by invalidating | 580 // so we should make sure a WM_PAINT is sent to the window by invalidating |
598 // the entire window rect. | 581 // the entire window rect. |
599 ::InvalidateRect(hwnd, NULL, true); | 582 ::InvalidateRect(hwnd, NULL, true); |
600 } | 583 } |
601 } | 584 } |
602 #endif // defined(OS_WIN) | 585 #endif // defined(OS_WIN) |
603 | 586 |
| 587 // Specialization of operator() method for std::wstring version. |
| 588 template <> |
| 589 bool StringComparator<std::wstring>::operator()(const std::wstring& lhs, |
| 590 const std::wstring& rhs) { |
| 591 // If we can not get collator instance for specified locale, just do simple |
| 592 // string compare. |
| 593 if (!collator_) |
| 594 return lhs < rhs; |
| 595 return CompareStringWithCollator(collator_, lhs, rhs) == UCOL_LESS; |
| 596 }; |
| 597 |
604 void SortStrings(const std::wstring& locale, | 598 void SortStrings(const std::wstring& locale, |
605 std::vector<std::wstring>* strings) { | 599 std::vector<std::wstring>* strings) { |
606 UErrorCode error = U_ZERO_ERROR; | 600 SortVectorWithStringKey(locale, strings, false); |
607 Locale loc(WideToUTF8(locale).c_str()); | |
608 scoped_ptr<Collator> collator(Collator::createInstance(loc, error)); | |
609 if (U_FAILURE(error)) { | |
610 // Just do an string sort. | |
611 sort(strings->begin(), strings->end()); | |
612 return; | |
613 } | |
614 StringComparator c(collator.get()); | |
615 sort(strings->begin(), strings->end(), c); | |
616 } | 601 } |
617 | 602 |
618 const std::vector<std::wstring>& GetAvailableLocales() { | 603 const std::vector<std::wstring>& GetAvailableLocales() { |
619 static std::vector<std::wstring> locales; | 604 static std::vector<std::wstring> locales; |
620 if (locales.empty()) { | 605 if (locales.empty()) { |
621 int num_locales = uloc_countAvailable(); | 606 int num_locales = uloc_countAvailable(); |
622 for (int i = 0; i < num_locales; ++i) { | 607 for (int i = 0; i < num_locales; ++i) { |
623 std::string locale_name = uloc_getAvailable(i); | 608 std::string locale_name = uloc_getAvailable(i); |
624 // Filter out the names that have aliases. | 609 // Filter out the names that have aliases. |
625 if (IsDuplicateName(locale_name)) | 610 if (IsDuplicateName(locale_name)) |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
686 } | 671 } |
687 | 672 |
688 void BiDiLineIterator::GetLogicalRun(int start, | 673 void BiDiLineIterator::GetLogicalRun(int start, |
689 int* end, | 674 int* end, |
690 UBiDiLevel* level) { | 675 UBiDiLevel* level) { |
691 DCHECK(bidi_ != NULL); | 676 DCHECK(bidi_ != NULL); |
692 ubidi_getLogicalRun(bidi_, start, end, level); | 677 ubidi_getLogicalRun(bidi_, start, end, level); |
693 } | 678 } |
694 | 679 |
695 } | 680 } |
OLD | NEW |