1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "ui/base/l10n/l10n_util_win.h"
6 
7 #include <algorithm>
8 #include <iterator>
9 
10 #include "base/i18n/rtl.h"
11 #include "base/lazy_instance.h"
12 #include "base/macros.h"
13 #include "base/strings/string_number_conversions.h"
14 #include "base/strings/string_util.h"
15 #include "base/strings/utf_string_conversions.h"
16 #include "base/win/i18n.h"
17 #include "ui/base/l10n/l10n_util.h"
18 #include "ui/display/display.h"
19 #include "ui/display/win/screen_win.h"
20 #include "ui/strings/grit/app_locale_settings.h"
21 
22 namespace {
23 
24 class OverrideLocaleHolder {
25  public:
OverrideLocaleHolder()26   OverrideLocaleHolder() {}
value() const27   const std::vector<std::string>& value() const { return value_; }
swap_value(std::vector<std::string> * override_value)28   void swap_value(std::vector<std::string>* override_value) {
29     value_.swap(*override_value);
30   }
31  private:
32   std::vector<std::string> value_;
33   DISALLOW_COPY_AND_ASSIGN(OverrideLocaleHolder);
34 };
35 
36 base::LazyInstance<OverrideLocaleHolder>::DestructorAtExit
37     override_locale_holder = LAZY_INSTANCE_INITIALIZER;
38 
39 }  // namespace
40 
41 namespace l10n_util {
42 
GetExtendedStyles()43 int GetExtendedStyles() {
44   return !base::i18n::IsRTL() ? 0 : WS_EX_LAYOUTRTL | WS_EX_RTLREADING;
45 }
46 
GetExtendedTooltipStyles()47 int GetExtendedTooltipStyles() {
48   return !base::i18n::IsRTL() ? 0 : WS_EX_LAYOUTRTL;
49 }
50 
HWNDSetRTLLayout(HWND hwnd)51 void HWNDSetRTLLayout(HWND hwnd) {
52   DWORD ex_style = ::GetWindowLong(hwnd, GWL_EXSTYLE);
53 
54   // We don't have to do anything if the style is already set for the HWND.
55   if (!(ex_style & WS_EX_LAYOUTRTL)) {
56     ex_style |= WS_EX_LAYOUTRTL;
57     ::SetWindowLong(hwnd, GWL_EXSTYLE, ex_style);
58 
59     // Right-to-left layout changes are not applied to the window immediately
60     // so we should make sure a WM_PAINT is sent to the window by invalidating
61     // the entire window rect.
62     ::InvalidateRect(hwnd, NULL, true);
63   }
64 }
65 
IsLocaleSupportedByOS(const std::string & locale)66 bool IsLocaleSupportedByOS(const std::string& locale) {
67   return true;
68 }
69 
NeedOverrideDefaultUIFont(base::string16 * override_font_family,double * font_size_scaler)70 bool NeedOverrideDefaultUIFont(base::string16* override_font_family,
71                                double* font_size_scaler) {
72   // This is rather simple-minded to deal with the UI font size
73   // issue for some Indian locales (ml, bn, hi) for which
74   // the default Windows fonts are too small to be legible.  For those
75   // locales, IDS_UI_FONT_FAMILY is set to an actual font family to
76   // use while for other locales, it's set to 'default'.
77   base::string16 ui_font_family = GetStringUTF16(IDS_UI_FONT_FAMILY);
78   int scaler100;
79   if (!base::StringToInt(l10n_util::GetStringUTF16(IDS_UI_FONT_SIZE_SCALER),
80                          &scaler100))
81     return false;
82 
83   // We use the OS default in two cases:
84   // 1) The resource bundle has 'default' and '100' for font family and
85   //    font scaler.
86   // 2) The resource bundle is not available for some reason and
87   //    ui_font_family is empty.
88   if ((ui_font_family == L"default" && scaler100 == 100) ||
89       ui_font_family.empty())
90     return false;
91 
92   if (override_font_family && ui_font_family != L"default")
93     override_font_family->swap(ui_font_family);
94   if (font_size_scaler)
95     *font_size_scaler = scaler100 / 100.0;
96   return true;
97 }
98 
OverrideLocaleWithUILanguageList()99 void OverrideLocaleWithUILanguageList() {
100   std::vector<base::string16> ui_languages;
101   if (base::win::i18n::GetThreadPreferredUILanguageList(&ui_languages)) {
102     std::vector<std::string> ascii_languages;
103     ascii_languages.reserve(ui_languages.size());
104     std::transform(ui_languages.begin(), ui_languages.end(),
105                    std::back_inserter(ascii_languages), &base::UTF16ToASCII);
106     override_locale_holder.Get().swap_value(&ascii_languages);
107   } else {
108     NOTREACHED() << "Failed to determine the UI language for locale override.";
109   }
110 }
111 
GetLocaleOverrides()112 const std::vector<std::string>& GetLocaleOverrides() {
113   return override_locale_holder.Get().value();
114 }
115 
116 }  // namespace l10n_util
117