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 
NeedOverrideDefaultUIFont(std::wstring * override_font_family,double * font_size_scaler)66 bool NeedOverrideDefaultUIFont(std::wstring* override_font_family,
67                                double* font_size_scaler) {
68   // This is rather simple-minded to deal with the UI font size
69   // issue for some Indian locales (ml, bn, hi) for which
70   // the default Windows fonts are too small to be legible.  For those
71   // locales, IDS_UI_FONT_FAMILY is set to an actual font family to
72   // use while for other locales, it's set to 'default'.
73   std::wstring ui_font_family = GetWideString(IDS_UI_FONT_FAMILY);
74   int scaler100;
75   if (!base::StringToInt(l10n_util::GetStringUTF16(IDS_UI_FONT_SIZE_SCALER),
76                          &scaler100))
77     return false;
78 
79   // We use the OS default in two cases:
80   // 1) The resource bundle has 'default' and '100' for font family and
81   //    font scaler.
82   // 2) The resource bundle is not available for some reason and
83   //    ui_font_family is empty.
84   if ((ui_font_family == L"default" && scaler100 == 100) ||
85       ui_font_family.empty())
86     return false;
87 
88   if (override_font_family && ui_font_family != L"default")
89     override_font_family->swap(ui_font_family);
90   if (font_size_scaler)
91     *font_size_scaler = scaler100 / 100.0;
92   return true;
93 }
94 
OverrideLocaleWithUILanguageList()95 void OverrideLocaleWithUILanguageList() {
96   std::vector<std::wstring> ui_languages;
97   if (base::win::i18n::GetThreadPreferredUILanguageList(&ui_languages)) {
98     std::vector<std::string> ascii_languages;
99     ascii_languages.reserve(ui_languages.size());
100     std::transform(ui_languages.begin(), ui_languages.end(),
101                    std::back_inserter(ascii_languages), &base::WideToASCII);
102     override_locale_holder.Get().swap_value(&ascii_languages);
103   } else {
104     NOTREACHED() << "Failed to determine the UI language for locale override.";
105   }
106 }
107 
GetLocaleOverrides()108 const std::vector<std::string>& GetLocaleOverrides() {
109   return override_locale_holder.Get().value();
110 }
111 
GetWideString(int message_id)112 std::wstring GetWideString(int message_id) {
113   return base::UTF16ToWide(GetStringUTF16(message_id));
114 }
115 
116 }  // namespace l10n_util
117