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