Chromium Code Reviews| 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 "app/l10n_util.h" | 5 #include "app/l10n_util.h" |
| 6 | 6 |
| 7 #include <cstdlib> | |
| 7 #include "app/app_paths.h" | 8 #include "app/app_paths.h" |
| 8 #include "app/app_switches.h" | 9 #include "app/app_switches.h" |
| 9 #include "app/gfx/canvas.h" | 10 #include "app/gfx/canvas.h" |
| 10 #include "app/resource_bundle.h" | 11 #include "app/resource_bundle.h" |
| 11 #include "base/command_line.h" | 12 #include "base/command_line.h" |
| 12 #include "base/file_util.h" | 13 #include "base/file_util.h" |
| 13 #include "base/path_service.h" | 14 #include "base/path_service.h" |
| 14 #include "base/scoped_ptr.h" | 15 #include "base/scoped_ptr.h" |
| 15 #include "base/string16.h" | 16 #include "base/string16.h" |
| 16 #include "base/string_piece.h" | 17 #include "base/string_piece.h" |
| (...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 369 std::string ret; | 370 std::string ret; |
| 370 if (!language.empty()) | 371 if (!language.empty()) |
| 371 ret.append(language); | 372 ret.append(language); |
| 372 if (!region.empty()) { | 373 if (!region.empty()) { |
| 373 ret.append("-"); | 374 ret.append("-"); |
| 374 ret.append(region); | 375 ret.append(region); |
| 375 } | 376 } |
| 376 return ret; | 377 return ret; |
| 377 } | 378 } |
| 378 | 379 |
| 380 #if defined(OS_LINUX) | |
| 381 // Split and normalize the language list specified by LANGUAGE environment. | |
| 382 // LANGUAGE environment specifies a priority list of user prefered locales for | |
| 383 // application UI messages. Locales are separated by ':' character. The format | |
| 384 // of a locale is: language[_territory[.codeset]][@modifier] | |
| 385 // | |
| 386 // This function splits the language list and normalizes each locale into | |
| 387 // language[-territory] format, eg. fr, zh-CN, etc. | |
| 388 void SplitAndNormalizeLanguageList(const std::string& env_language, | |
| 389 std::vector<std::string>* result) { | |
| 390 std::vector<std::string> langs; | |
| 391 SplitString(env_language, ':', &langs); | |
| 392 std::vector<std::string>::iterator i = langs.begin(); | |
| 393 for (; i != langs.end(); ++i) { | |
| 394 size_t end_pos = i->find_first_of(".@"); | |
| 395 // Erase encoding and modifier part. | |
| 396 if (end_pos != std::string::npos) | |
| 397 i->erase(end_pos); | |
| 398 | |
| 399 if (!i->empty()) { | |
| 400 std::string locale; | |
| 401 size_t sep = i->find_first_of("_-"); | |
| 402 if (sep != std::string::npos) { | |
| 403 // language part is always in lower case. | |
| 404 locale = StringToLowerASCII(i->substr(0, sep)); | |
| 405 locale.append("-"); | |
| 406 // territory part is always in upper case. | |
| 407 locale.append(StringToUpperASCII(i->substr(sep + 1))); | |
| 408 } else { | |
| 409 locale = StringToLowerASCII(*i); | |
| 410 } | |
| 411 result->push_back(locale); | |
| 412 } | |
| 413 } | |
| 414 } | |
| 415 #endif | |
| 416 | |
| 379 } // namespace | 417 } // namespace |
| 380 | 418 |
| 381 namespace l10n_util { | 419 namespace l10n_util { |
| 382 | 420 |
| 383 // Represents the locale-specific text direction. | 421 // Represents the locale-specific text direction. |
| 384 static TextDirection g_text_direction = UNKNOWN_DIRECTION; | 422 static TextDirection g_text_direction = UNKNOWN_DIRECTION; |
| 385 | 423 |
| 386 // On the Mac, we don't want to test preferences or ICU for the language, | 424 // On the Mac, we don't want to test preferences or ICU for the language, |
| 387 // we want to use whatever Cocoa is using when it loaded the main nib file. | 425 // we want to use whatever Cocoa is using when it loaded the main nib file. |
| 388 // It handles all the mapping and fallbacks for us, we just need to ask. | 426 // It handles all the mapping and fallbacks for us, we just need to ask. |
| 389 // See l10n_util_mac for that implementation. | 427 // See l10n_util_mac for that implementation. |
| 390 #if !defined(OS_MACOSX) | 428 #if !defined(OS_MACOSX) |
| 391 std::string GetApplicationLocale(const std::wstring& pref_locale) { | 429 std::string GetApplicationLocale(const std::wstring& pref_locale) { |
| 392 FilePath locale_path; | 430 FilePath locale_path; |
| 393 PathService::Get(app::DIR_LOCALES, &locale_path); | 431 PathService::Get(app::DIR_LOCALES, &locale_path); |
| 394 std::string resolved_locale; | 432 std::string resolved_locale; |
| 433 std::vector<std::string> candidates; | |
| 434 const std::string system_locale = GetSystemLocale(); | |
| 395 | 435 |
| 396 // We only use --lang and the app pref on Windows. On Linux/Mac, we only | 436 // We only use --lang and the app pref on Windows. On Linux/Mac, we only |
| 397 // look at the LC_*/LANG environment variables. We do, however, pass --lang | 437 // look at the LC_*/LANG environment variables. We do, however, pass --lang |
| 398 // to renderer and plugin processes so they know what language the parent | 438 // to renderer and plugin processes so they know what language the parent |
| 399 // process decided to use. | 439 // process decided to use. |
| 400 #if defined(OS_WIN) | 440 #if defined(OS_WIN) |
| 401 // First, check to see if there's a --lang flag. | 441 // First, check to see if there's a --lang flag. |
| 402 const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess(); | 442 const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess(); |
| 403 const std::string& lang_arg = WideToASCII( | 443 const std::string& lang_arg = WideToASCII( |
| 404 parsed_command_line.GetSwitchValue(switches::kLang)); | 444 parsed_command_line.GetSwitchValue(switches::kLang)); |
| 405 if (!lang_arg.empty()) { | 445 if (!lang_arg.empty()) |
| 406 if (CheckAndResolveLocale(lang_arg, locale_path, &resolved_locale)) | 446 candidates.push_back(lang_arg); |
| 447 | |
| 448 // Second, try user prefs. | |
| 449 if (!pref_locale.empty()) | |
| 450 candidates.push_back(WideToASCII(pref_locale)); | |
| 451 | |
| 452 // Next, try the system locale. | |
| 453 candidates.push_back(system_locale); | |
| 454 #elif defined(OS_LINUX) | |
| 455 // On Linux, we also check LANGUAGE environment variable, which is supported | |
| 456 // by gettext to specify a priority list of prefered languages. | |
| 457 const char* env_language = ::getenv("LANGUAGE"); | |
| 458 if (env_language) | |
| 459 SplitAndNormalizeLanguageList(env_language, &candidates); | |
| 460 | |
| 461 // Only fallback to the system locale if LANGUAGE is not specified. | |
|
jungshik at Google
2009/09/28 18:37:34
Can you add a comment that we're emulating gettext
| |
| 462 if (candidates.empty()) | |
| 463 candidates.push_back(system_locale); | |
| 464 #endif | |
| 465 | |
| 466 std::vector<std::string>::const_iterator i = candidates.begin(); | |
| 467 for (; i != candidates.end(); ++i) { | |
| 468 if (CheckAndResolveLocale(*i, locale_path, &resolved_locale)) | |
| 407 return resolved_locale; | 469 return resolved_locale; |
| 408 } | 470 } |
| 409 | 471 |
| 410 // Second, try user prefs. | |
| 411 if (!pref_locale.empty()) { | |
| 412 if (CheckAndResolveLocale(WideToASCII(pref_locale), | |
| 413 locale_path, &resolved_locale)) | |
| 414 return resolved_locale; | |
| 415 } | |
| 416 #endif | |
| 417 | |
| 418 // Next, try the system locale. | |
| 419 const std::string system_locale = GetSystemLocale(); | |
| 420 if (CheckAndResolveLocale(system_locale, locale_path, &resolved_locale)) | |
| 421 return resolved_locale; | |
| 422 | |
| 423 // Fallback on en-US. | 472 // Fallback on en-US. |
| 424 const std::string fallback_locale("en-US"); | 473 const std::string fallback_locale("en-US"); |
| 425 if (IsLocaleAvailable(fallback_locale, locale_path)) | 474 if (IsLocaleAvailable(fallback_locale, locale_path)) |
| 426 return fallback_locale; | 475 return fallback_locale; |
| 427 | 476 |
| 428 // No locale data file was found; we shouldn't get here. | 477 // No locale data file was found; we shouldn't get here. |
| 429 NOTREACHED(); | 478 NOTREACHED(); |
| 430 | 479 |
| 431 return std::string(); | 480 return std::string(); |
| 432 } | 481 } |
| (...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 978 } | 1027 } |
| 979 | 1028 |
| 980 void BiDiLineIterator::GetLogicalRun(int start, | 1029 void BiDiLineIterator::GetLogicalRun(int start, |
| 981 int* end, | 1030 int* end, |
| 982 UBiDiLevel* level) { | 1031 UBiDiLevel* level) { |
| 983 DCHECK(bidi_ != NULL); | 1032 DCHECK(bidi_ != NULL); |
| 984 ubidi_getLogicalRun(bidi_, start, end, level); | 1033 ubidi_getLogicalRun(bidi_, start, end, level); |
| 985 } | 1034 } |
| 986 | 1035 |
| 987 } | 1036 } |
| OLD | NEW |