Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(167)

Side by Side Diff: ui/gfx/dpi.cc

Issue 659883002: Enable hidpi on Linux, refactor a bit on Windows to share Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: resource bundle loading Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "ui/gfx/win/dpi.h" 5 #include "ui/gfx/dpi.h"
6 6
7 #include <windows.h> 7 #include "base/logging.h"
8 #include "base/win/scoped_hdc.h"
9 #include "base/win/windows_version.h"
10 #include "base/win/registry.h"
11 #include "ui/gfx/display.h" 8 #include "ui/gfx/display.h"
12 #include "ui/gfx/point_conversions.h" 9 #include "ui/gfx/point_conversions.h"
13 #include "ui/gfx/rect_conversions.h" 10 #include "ui/gfx/rect_conversions.h"
14 #include "ui/gfx/size_conversions.h" 11 #include "ui/gfx/size_conversions.h"
15 12
13 #if defined(OS_WIN)
14 #include <windows.h>
15 #include "base/win/registry.h"
16 #include "base/win/scoped_hdc.h"
17 #include "base/win/windows_version.h"
18 #endif
19
20 #if defined(OS_LINUX)
21 #include "ui/gfx/linux_font_delegate.h"
22 #endif
23
16 namespace { 24 namespace {
17 25
18 int kDefaultDPIX = 96; 26 int kDefaultDPI = 96;
19 int kDefaultDPIY = 96;
20
21 bool force_highdpi_for_testing = false;
22
23 BOOL IsProcessDPIAwareWrapper() {
24 typedef BOOL(WINAPI *IsProcessDPIAwarePtr)(VOID);
25 IsProcessDPIAwarePtr is_process_dpi_aware_func =
26 reinterpret_cast<IsProcessDPIAwarePtr>(
27 GetProcAddress(GetModuleHandleA("user32.dll"), "IsProcessDPIAware"));
28 if (is_process_dpi_aware_func)
29 return is_process_dpi_aware_func();
30 return FALSE;
31 }
32 27
33 float g_device_scale_factor = 0.0f; 28 float g_device_scale_factor = 0.0f;
34 29
35 float GetUnforcedDeviceScaleFactor() { 30 float GetUnforcedDeviceScaleFactor() {
36 // If the global device scale factor is initialized use it. This is to ensure 31 // If the global device scale factor is initialized use it. This is to ensure
37 // we use the same scale factor across all callsites. We don't use the 32 // we use the same scale factor across all callsites. We don't use the
38 // GetDeviceScaleFactor function here because it fires a DCHECK if the 33 // GetDeviceScaleFactor function here because it fires a DCHECK if the
39 // g_device_scale_factor global is 0. 34 // g_device_scale_factor global is 0.
40 if (g_device_scale_factor) 35 if (g_device_scale_factor)
41 return g_device_scale_factor; 36 return g_device_scale_factor;
42 return static_cast<float>(gfx::GetDPI().width()) / 37 return static_cast<float>(gfx::GetDPI().width()) /
43 static_cast<float>(kDefaultDPIX); 38 static_cast<float>(kDefaultDPI);
44 } 39 }
45 40
46 // Duplicated from Win8.1 SDK ShellScalingApi.h 41 #if defined(OS_WIN)
47 typedef enum PROCESS_DPI_AWARENESS {
48 PROCESS_DPI_UNAWARE = 0,
49 PROCESS_SYSTEM_DPI_AWARE = 1,
50 PROCESS_PER_MONITOR_DPI_AWARE = 2
51 } PROCESS_DPI_AWARENESS;
52
53 typedef enum MONITOR_DPI_TYPE {
54 MDT_EFFECTIVE_DPI = 0,
55 MDT_ANGULAR_DPI = 1,
56 MDT_RAW_DPI = 2,
57 MDT_DEFAULT = MDT_EFFECTIVE_DPI
58 } MONITOR_DPI_TYPE;
59
60 // Win8.1 supports monitor-specific DPI scaling.
61 bool SetProcessDpiAwarenessWrapper(PROCESS_DPI_AWARENESS value) {
62 typedef BOOL(WINAPI *SetProcessDpiAwarenessPtr)(PROCESS_DPI_AWARENESS);
63 SetProcessDpiAwarenessPtr set_process_dpi_awareness_func =
64 reinterpret_cast<SetProcessDpiAwarenessPtr>(
65 GetProcAddress(GetModuleHandleA("user32.dll"),
66 "SetProcessDpiAwarenessInternal"));
67 if (set_process_dpi_awareness_func) {
68 HRESULT hr = set_process_dpi_awareness_func(value);
69 if (SUCCEEDED(hr)) {
70 VLOG(1) << "SetProcessDpiAwareness succeeded.";
71 return true;
72 } else if (hr == E_ACCESSDENIED) {
73 LOG(ERROR) << "Access denied error from SetProcessDpiAwareness. "
74 "Function called twice, or manifest was used.";
75 }
76 }
77 return false;
78 }
79
80 // This function works for Windows Vista through Win8. Win8.1 must use
81 // SetProcessDpiAwareness[Wrapper]
82 BOOL SetProcessDPIAwareWrapper() {
83 typedef BOOL(WINAPI *SetProcessDPIAwarePtr)(VOID);
84 SetProcessDPIAwarePtr set_process_dpi_aware_func =
85 reinterpret_cast<SetProcessDPIAwarePtr>(
86 GetProcAddress(GetModuleHandleA("user32.dll"),
87 "SetProcessDPIAware"));
88 return set_process_dpi_aware_func &&
89 set_process_dpi_aware_func();
90 }
91
92 DWORD ReadRegistryValue(HKEY root, 42 DWORD ReadRegistryValue(HKEY root,
93 const wchar_t* base_key, 43 const wchar_t* base_key,
94 const wchar_t* value_name, 44 const wchar_t* value_name,
95 DWORD default_value) { 45 DWORD default_value) {
96 base::win::RegKey reg_key(HKEY_CURRENT_USER, 46 base::win::RegKey reg_key(HKEY_CURRENT_USER,
97 base_key, 47 base_key,
98 KEY_QUERY_VALUE); 48 KEY_QUERY_VALUE);
99 DWORD value; 49 DWORD value;
100 if (reg_key.Valid() && 50 if (reg_key.Valid() &&
101 reg_key.ReadValueDW(value_name, &value) == ERROR_SUCCESS) { 51 reg_key.ReadValueDW(value_name, &value) == ERROR_SUCCESS) {
102 return value; 52 return value;
103 } 53 }
104 return default_value; 54 return default_value;
105 } 55 }
56 #endif
106 57
107 } // namespace 58 } // namespace
108 59
60
109 namespace gfx { 61 namespace gfx {
110 62
111 void InitDeviceScaleFactor(float scale) { 63 void InitDeviceScaleFactor(float scale) {
112 DCHECK_NE(0.0f, scale); 64 DCHECK_NE(0.0f, scale);
oshima 2014/10/20 21:11:59 what happens if the scale is between 0.0 and 1.0 ?
scottmg 2014/10/22 18:54:14 Assets and fonts seem to be rendered at 1.0, but s
113 g_device_scale_factor = scale; 65 g_device_scale_factor = scale;
114 } 66 }
115 67
68 float GetDeviceScaleFactor() {
69 DCHECK_NE(0.0f, g_device_scale_factor);
70 return g_device_scale_factor;
71 }
72
73 bool IsDeviceScaleFactorSet() {
74 return g_device_scale_factor != 0.0f;
75 }
76
77 void ForceHighDPISupportForTesting(float scale) {
78 g_device_scale_factor = scale;
79 }
80
81 bool IsInHighDPIMode() {
82 return GetDPIScale() > 1.0;
83 }
84
116 Size GetDPI() { 85 Size GetDPI() {
117 static int dpi_x = 0; 86 static int dpi_x = 0;
118 static int dpi_y = 0; 87 static int dpi_y = 0;
119 static bool should_initialize = true; 88 static bool should_initialize = true;
120 89
121 if (should_initialize) { 90 if (should_initialize) {
122 should_initialize = false; 91 should_initialize = false;
92 #if defined(OS_WIN)
123 base::win::ScopedGetDC screen_dc(NULL); 93 base::win::ScopedGetDC screen_dc(NULL);
124 // This value is safe to cache for the life time of the app since the 94 // This value is safe to cache for the life time of the app since the
125 // user must logout to change the DPI setting. This value also applies 95 // user must logout to change the DPI setting. This value also applies
126 // to all screens. 96 // to all screens.
127 dpi_x = GetDeviceCaps(screen_dc, LOGPIXELSX); 97 dpi_x = GetDeviceCaps(screen_dc, LOGPIXELSX);
128 dpi_y = GetDeviceCaps(screen_dc, LOGPIXELSY); 98 dpi_y = GetDeviceCaps(screen_dc, LOGPIXELSY);
99 #else
100 const gfx::LinuxFontDelegate* delegate = gfx::LinuxFontDelegate::instance();
101 if (delegate)
102 dpi_x = delegate->GetFontDPI();
103 if (dpi_x <= 0)
104 dpi_x = 96;
105 dpi_y = dpi_x;
106 #endif
129 } 107 }
130 return Size(dpi_x, dpi_y); 108 return Size(dpi_x, dpi_y);
131 } 109 }
132 110
133 float GetDPIScale() { 111 float GetDPIScale() {
134 if (IsHighDPIEnabled()) { 112 if (IsHighDPIEnabled()) {
135 if (gfx::Display::HasForceDeviceScaleFactor()) 113 if (gfx::Display::HasForceDeviceScaleFactor())
136 return gfx::Display::GetForcedDeviceScaleFactor(); 114 return gfx::Display::GetForcedDeviceScaleFactor();
137 float dpi_scale = GetUnforcedDeviceScaleFactor(); 115 float dpi_scale = GetUnforcedDeviceScaleFactor();
138 if (dpi_scale <= 1.25) { 116 if (dpi_scale <= 1.25) {
139 // Force 125% and below to 100% scale. We do this to maintain previous 117 // Force 125% and below to 100% scale. We do this to maintain previous
140 // (non-DPI-aware) behavior where only the font size was boosted. 118 // (non-DPI-aware) behavior where only the font size was boosted.
141 dpi_scale = 1.0; 119 dpi_scale = 1.0;
142 } 120 }
143 return dpi_scale; 121 return dpi_scale;
144 } 122 }
145 return 1.0; 123 return 1.0;
146 } 124 }
147 125
148 void ForceHighDPISupportForTesting(float scale) {
149 g_device_scale_factor = scale;
150 }
151
152 bool IsHighDPIEnabled() {
153 // Flag stored in HKEY_CURRENT_USER\SOFTWARE\\Google\\Chrome\\Profile,
154 // under the DWORD value high-dpi-support.
155 // Default is disabled.
156 static DWORD value = ReadRegistryValue(
157 HKEY_CURRENT_USER, gfx::win::kRegistryProfilePath,
158 gfx::win::kHighDPISupportW, TRUE);
159 return value != 0;
160 }
161
162 bool IsInHighDPIMode() {
163 return GetDPIScale() > 1.0;
164 }
165
166 void EnableHighDPISupport() {
167 if (IsHighDPIEnabled() &&
168 !SetProcessDpiAwarenessWrapper(PROCESS_SYSTEM_DPI_AWARE)) {
169 SetProcessDPIAwareWrapper();
170 }
171 }
172
173 namespace win {
174
175 GFX_EXPORT const wchar_t kRegistryProfilePath[] =
176 L"Software\\Google\\Chrome\\Profile";
177 GFX_EXPORT const wchar_t kHighDPISupportW[] = L"high-dpi-support";
178
179 float GetDeviceScaleFactor() {
180 DCHECK_NE(0.0f, g_device_scale_factor);
181 return g_device_scale_factor;
182 }
183
184 Point ScreenToDIPPoint(const Point& pixel_point) { 126 Point ScreenToDIPPoint(const Point& pixel_point) {
185 return ToFlooredPoint(ScalePoint(pixel_point, 127 return ToFlooredPoint(ScalePoint(pixel_point,
186 1.0f / GetDeviceScaleFactor())); 128 1.0f / GetDeviceScaleFactor()));
187 } 129 }
188 130
189 Point DIPToScreenPoint(const Point& dip_point) { 131 Point DIPToScreenPoint(const Point& dip_point) {
190 return ToFlooredPoint(ScalePoint(dip_point, GetDeviceScaleFactor())); 132 return ToFlooredPoint(ScalePoint(dip_point, GetDeviceScaleFactor()));
191 } 133 }
192 134
193 Rect ScreenToDIPRect(const Rect& pixel_bounds) { 135 Rect ScreenToDIPRect(const Rect& pixel_bounds) {
(...skipping 16 matching lines...) Expand all
210 // Always ceil sizes. Otherwise we may be leaving off part of the bounds. 152 // Always ceil sizes. Otherwise we may be leaving off part of the bounds.
211 return ToCeiledSize( 153 return ToCeiledSize(
212 ScaleSize(size_in_pixels, 1.0f / GetDeviceScaleFactor())); 154 ScaleSize(size_in_pixels, 1.0f / GetDeviceScaleFactor()));
213 } 155 }
214 156
215 Size DIPToScreenSize(const Size& dip_size) { 157 Size DIPToScreenSize(const Size& dip_size) {
216 // Always ceil sizes. Otherwise we may be leaving off part of the bounds. 158 // Always ceil sizes. Otherwise we may be leaving off part of the bounds.
217 return ToCeiledSize(ScaleSize(dip_size, GetDeviceScaleFactor())); 159 return ToCeiledSize(ScaleSize(dip_size, GetDeviceScaleFactor()));
218 } 160 }
219 161
162 bool IsHighDPIEnabled() {
163 #if defined(OS_WIN)
164 static const wchar_t kRegistryProfilePath[] =
165 L"Software\\Google\\Chrome\\Profile";
166 static const wchar_t kHighDPISupportW[] = L"high-dpi-support";
167
168 // Flag stored in HKEY_CURRENT_USER\SOFTWARE\\Google\\Chrome\\Profile,
169 // under the DWORD value high-dpi-support.
170 // Default is disabled.
171 static DWORD value = ReadRegistryValue(
172 HKEY_CURRENT_USER, kRegistryProfilePath, kHighDPISupportW, TRUE);
173 return value != 0;
174 #elif defined(OS_LINUX)
175 return true;
176 #endif
177 }
178
179
180 #if defined(OS_WIN)
181
182 namespace win {
183
184 namespace {
185
186 // Duplicated from Win8.1 SDK ShellScalingApi.h
187 typedef enum PROCESS_DPI_AWARENESS {
188 PROCESS_DPI_UNAWARE = 0,
189 PROCESS_SYSTEM_DPI_AWARE = 1,
190 PROCESS_PER_MONITOR_DPI_AWARE = 2
191 } PROCESS_DPI_AWARENESS;
192
193 typedef enum MONITOR_DPI_TYPE {
194 MDT_EFFECTIVE_DPI = 0,
195 MDT_ANGULAR_DPI = 1,
196 MDT_RAW_DPI = 2,
197 MDT_DEFAULT = MDT_EFFECTIVE_DPI
198 } MONITOR_DPI_TYPE;
199
200 // Win8.1 supports monitor-specific DPI scaling.
201 bool SetProcessDpiAwarenessWrapper(PROCESS_DPI_AWARENESS value) {
202 typedef BOOL(WINAPI *SetProcessDpiAwarenessPtr)(PROCESS_DPI_AWARENESS);
203 SetProcessDpiAwarenessPtr set_process_dpi_awareness_func =
204 reinterpret_cast<SetProcessDpiAwarenessPtr>(
205 GetProcAddress(GetModuleHandleA("user32.dll"),
206 "SetProcessDpiAwarenessInternal"));
207 if (set_process_dpi_awareness_func) {
208 HRESULT hr = set_process_dpi_awareness_func(value);
209 if (SUCCEEDED(hr)) {
210 VLOG(1) << "SetProcessDpiAwareness succeeded.";
211 return true;
212 } else if (hr == E_ACCESSDENIED) {
213 LOG(ERROR) << "Access denied error from SetProcessDpiAwareness. "
214 "Function called twice, or manifest was used.";
215 }
216 }
217 return false;
218 }
219
220 // This function works for Windows Vista through Win8. Win8.1 must use
221 // SetProcessDpiAwareness[Wrapper]
222 BOOL SetProcessDPIAwareWrapper() {
223 typedef BOOL(WINAPI *SetProcessDPIAwarePtr)(VOID);
224 SetProcessDPIAwarePtr set_process_dpi_aware_func =
225 reinterpret_cast<SetProcessDPIAwarePtr>(
226 GetProcAddress(GetModuleHandleA("user32.dll"),
227 "SetProcessDPIAware"));
228 return set_process_dpi_aware_func &&
229 set_process_dpi_aware_func();
230 }
231
232 } // namespace
233
234 void EnableHighDPISupport() {
235 if (IsHighDPIEnabled() &&
236 !SetProcessDpiAwarenessWrapper(PROCESS_SYSTEM_DPI_AWARE)) {
237 SetProcessDPIAwareWrapper();
238 }
239 }
240
220 int GetSystemMetricsInDIP(int metric) { 241 int GetSystemMetricsInDIP(int metric) {
221 return static_cast<int>(GetSystemMetrics(metric) / 242 return static_cast<int>(GetSystemMetrics(metric) /
222 GetDeviceScaleFactor() + 0.5); 243 GetDeviceScaleFactor() + 0.5);
223 } 244 }
224 245
225 bool IsDeviceScaleFactorSet() { 246 } // namespace win
226 return g_device_scale_factor != 0.0f;
227 }
228 247
229 } // namespace win 248 #endif // OS_WIN
oshima 2014/10/20 21:11:59 consider moving win impl to dip_win.cc ?
scottmg 2014/10/22 18:54:14 Done.
249
230 } // namespace gfx 250 } // namespace gfx
OLDNEW
« no previous file with comments | « ui/gfx/dpi.h ('k') | ui/gfx/gfx.gyp » ('j') | ui/views/widget/desktop_aura/desktop_screen_x11.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698