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

Side by Side Diff: ui/gfx/dpi_win.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: constants Created 6 years, 1 month 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 2014 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 <windows.h>
8
9 #include "base/logging.h"
10 #include "base/win/registry.h"
8 #include "base/win/scoped_hdc.h" 11 #include "base/win/scoped_hdc.h"
9 #include "base/win/windows_version.h" 12 #include "base/win/windows_version.h"
10 #include "base/win/registry.h"
11 #include "ui/gfx/display.h" 13 #include "ui/gfx/display.h"
12 #include "ui/gfx/point_conversions.h" 14 #include "ui/gfx/point_conversions.h"
13 #include "ui/gfx/rect_conversions.h" 15 #include "ui/gfx/rect_conversions.h"
14 #include "ui/gfx/size_conversions.h" 16 #include "ui/gfx/size_conversions.h"
15 17
16 namespace { 18 namespace {
17 19
18 int kDefaultDPIX = 96; 20 DWORD ReadRegistryValue(HKEY root,
19 int kDefaultDPIY = 96; 21 const wchar_t* base_key,
20 22 const wchar_t* value_name,
21 bool force_highdpi_for_testing = false; 23 DWORD default_value) {
22 24 base::win::RegKey reg_key(HKEY_CURRENT_USER,
23 BOOL IsProcessDPIAwareWrapper() { 25 base_key,
24 typedef BOOL(WINAPI *IsProcessDPIAwarePtr)(VOID); 26 KEY_QUERY_VALUE);
25 IsProcessDPIAwarePtr is_process_dpi_aware_func = 27 DWORD value;
26 reinterpret_cast<IsProcessDPIAwarePtr>( 28 if (reg_key.Valid() &&
27 GetProcAddress(GetModuleHandleA("user32.dll"), "IsProcessDPIAware")); 29 reg_key.ReadValueDW(value_name, &value) == ERROR_SUCCESS) {
28 if (is_process_dpi_aware_func) 30 return value;
29 return is_process_dpi_aware_func(); 31 }
30 return FALSE; 32 return default_value;
31 }
32
33 float g_device_scale_factor = 0.0f;
34
35 float GetUnforcedDeviceScaleFactor() {
36 // 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
38 // GetDeviceScaleFactor function here because it fires a DCHECK if the
39 // g_device_scale_factor global is 0.
40 if (g_device_scale_factor)
41 return g_device_scale_factor;
42 return static_cast<float>(gfx::GetDPI().width()) /
43 static_cast<float>(kDefaultDPIX);
44 } 33 }
45 34
46 // Duplicated from Win8.1 SDK ShellScalingApi.h 35 // Duplicated from Win8.1 SDK ShellScalingApi.h
47 typedef enum PROCESS_DPI_AWARENESS { 36 typedef enum PROCESS_DPI_AWARENESS {
48 PROCESS_DPI_UNAWARE = 0, 37 PROCESS_DPI_UNAWARE = 0,
49 PROCESS_SYSTEM_DPI_AWARE = 1, 38 PROCESS_SYSTEM_DPI_AWARE = 1,
50 PROCESS_PER_MONITOR_DPI_AWARE = 2 39 PROCESS_PER_MONITOR_DPI_AWARE = 2
51 } PROCESS_DPI_AWARENESS; 40 } PROCESS_DPI_AWARENESS;
52 41
53 typedef enum MONITOR_DPI_TYPE { 42 typedef enum MONITOR_DPI_TYPE {
(...skipping 28 matching lines...) Expand all
82 BOOL SetProcessDPIAwareWrapper() { 71 BOOL SetProcessDPIAwareWrapper() {
83 typedef BOOL(WINAPI *SetProcessDPIAwarePtr)(VOID); 72 typedef BOOL(WINAPI *SetProcessDPIAwarePtr)(VOID);
84 SetProcessDPIAwarePtr set_process_dpi_aware_func = 73 SetProcessDPIAwarePtr set_process_dpi_aware_func =
85 reinterpret_cast<SetProcessDPIAwarePtr>( 74 reinterpret_cast<SetProcessDPIAwarePtr>(
86 GetProcAddress(GetModuleHandleA("user32.dll"), 75 GetProcAddress(GetModuleHandleA("user32.dll"),
87 "SetProcessDPIAware")); 76 "SetProcessDPIAware"));
88 return set_process_dpi_aware_func && 77 return set_process_dpi_aware_func &&
89 set_process_dpi_aware_func(); 78 set_process_dpi_aware_func();
90 } 79 }
91 80
92 DWORD ReadRegistryValue(HKEY root,
93 const wchar_t* base_key,
94 const wchar_t* value_name,
95 DWORD default_value) {
96 base::win::RegKey reg_key(HKEY_CURRENT_USER,
97 base_key,
98 KEY_QUERY_VALUE);
99 DWORD value;
100 if (reg_key.Valid() &&
101 reg_key.ReadValueDW(value_name, &value) == ERROR_SUCCESS) {
102 return value;
103 }
104 return default_value;
105 }
106
107 } // namespace 81 } // namespace
108 82
109 namespace gfx { 83 namespace gfx {
110 84
111 void InitDeviceScaleFactor(float scale) {
112 DCHECK_NE(0.0f, scale);
113 g_device_scale_factor = scale;
114 }
115
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;
123 base::win::ScopedGetDC screen_dc(NULL); 92 base::win::ScopedGetDC screen_dc(NULL);
124 // This value is safe to cache for the life time of the app since the 93 // 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 94 // user must logout to change the DPI setting. This value also applies
126 // to all screens. 95 // to all screens.
127 dpi_x = GetDeviceCaps(screen_dc, LOGPIXELSX); 96 dpi_x = GetDeviceCaps(screen_dc, LOGPIXELSX);
128 dpi_y = GetDeviceCaps(screen_dc, LOGPIXELSY); 97 dpi_y = GetDeviceCaps(screen_dc, LOGPIXELSY);
129 } 98 }
130 return Size(dpi_x, dpi_y); 99 return Size(dpi_x, dpi_y);
131 } 100 }
132 101
133 float GetDPIScale() { 102 bool IsHighDPIEnabled() {
134 if (IsHighDPIEnabled()) { 103 static const wchar_t kRegistryProfilePath[] =
135 if (gfx::Display::HasForceDeviceScaleFactor()) 104 L"Software\\Google\\Chrome\\Profile";
136 return gfx::Display::GetForcedDeviceScaleFactor(); 105 static const wchar_t kHighDPISupportW[] = L"high-dpi-support";
137 float dpi_scale = GetUnforcedDeviceScaleFactor();
138 if (dpi_scale <= 1.25) {
139 // 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.
141 dpi_scale = 1.0;
142 }
143 return dpi_scale;
144 }
145 return 1.0;
146 }
147 106
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, 107 // Flag stored in HKEY_CURRENT_USER\SOFTWARE\\Google\\Chrome\\Profile,
154 // under the DWORD value high-dpi-support. 108 // under the DWORD value high-dpi-support.
155 // Default is disabled. 109 // Default is disabled.
156 static DWORD value = ReadRegistryValue( 110 static DWORD value = ReadRegistryValue(
157 HKEY_CURRENT_USER, gfx::win::kRegistryProfilePath, 111 HKEY_CURRENT_USER, kRegistryProfilePath, kHighDPISupportW, TRUE);
158 gfx::win::kHighDPISupportW, TRUE);
159 return value != 0; 112 return value != 0;
160 } 113 }
161 114
162 bool IsInHighDPIMode() { 115 namespace win {
163 return GetDPIScale() > 1.0;
164 }
165 116
166 void EnableHighDPISupport() { 117 void EnableHighDPISupport() {
167 if (IsHighDPIEnabled() && 118 if (IsHighDPIEnabled() &&
168 !SetProcessDpiAwarenessWrapper(PROCESS_SYSTEM_DPI_AWARE)) { 119 !SetProcessDpiAwarenessWrapper(PROCESS_SYSTEM_DPI_AWARE)) {
169 SetProcessDPIAwareWrapper(); 120 SetProcessDPIAwareWrapper();
170 } 121 }
171 } 122 }
172 123
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) {
185 return ToFlooredPoint(ScalePoint(pixel_point,
186 1.0f / GetDeviceScaleFactor()));
187 }
188
189 Point DIPToScreenPoint(const Point& dip_point) {
190 return ToFlooredPoint(ScalePoint(dip_point, GetDeviceScaleFactor()));
191 }
192
193 Rect ScreenToDIPRect(const Rect& pixel_bounds) {
194 // It's important we scale the origin and size separately. If we instead
195 // calculated the size from the floored origin and ceiled right the size could
196 // vary depending upon where the two points land. That would cause problems
197 // for the places this code is used (in particular mapping from native window
198 // bounds to DIPs).
199 return Rect(ScreenToDIPPoint(pixel_bounds.origin()),
200 ScreenToDIPSize(pixel_bounds.size()));
201 }
202
203 Rect DIPToScreenRect(const Rect& dip_bounds) {
204 // See comment in ScreenToDIPRect for why we calculate size like this.
205 return Rect(DIPToScreenPoint(dip_bounds.origin()),
206 DIPToScreenSize(dip_bounds.size()));
207 }
208
209 Size ScreenToDIPSize(const Size& size_in_pixels) {
210 // Always ceil sizes. Otherwise we may be leaving off part of the bounds.
211 return ToCeiledSize(
212 ScaleSize(size_in_pixels, 1.0f / GetDeviceScaleFactor()));
213 }
214
215 Size DIPToScreenSize(const Size& dip_size) {
216 // Always ceil sizes. Otherwise we may be leaving off part of the bounds.
217 return ToCeiledSize(ScaleSize(dip_size, GetDeviceScaleFactor()));
218 }
219
220 int GetSystemMetricsInDIP(int metric) { 124 int GetSystemMetricsInDIP(int metric) {
221 return static_cast<int>(GetSystemMetrics(metric) / 125 return static_cast<int>(GetSystemMetrics(metric) /
222 GetDeviceScaleFactor() + 0.5); 126 GetDeviceScaleFactor() + 0.5);
223 } 127 }
224 128
225 bool IsDeviceScaleFactorSet() {
226 return g_device_scale_factor != 0.0f;
227 }
228
229 } // namespace win 129 } // namespace win
230 } // namespace gfx 130 } // namespace gfx
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698