| 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 |