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

Side by Side Diff: ui/gfx/win/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: constants 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "ui/gfx/win/dpi.h"
6
7 #include <windows.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"
12 #include "ui/gfx/point_conversions.h"
13 #include "ui/gfx/rect_conversions.h"
14 #include "ui/gfx/size_conversions.h"
15
16 namespace {
17
18 int kDefaultDPIX = 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
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 }
45
46 // Duplicated from Win8.1 SDK ShellScalingApi.h
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,
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
108
109 namespace gfx {
110
111 void InitDeviceScaleFactor(float scale) {
112 DCHECK_NE(0.0f, scale);
113 g_device_scale_factor = scale;
114 }
115
116 Size GetDPI() {
117 static int dpi_x = 0;
118 static int dpi_y = 0;
119 static bool should_initialize = true;
120
121 if (should_initialize) {
122 should_initialize = false;
123 base::win::ScopedGetDC screen_dc(NULL);
124 // 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
126 // to all screens.
127 dpi_x = GetDeviceCaps(screen_dc, LOGPIXELSX);
128 dpi_y = GetDeviceCaps(screen_dc, LOGPIXELSY);
129 }
130 return Size(dpi_x, dpi_y);
131 }
132
133 float GetDPIScale() {
134 if (IsHighDPIEnabled()) {
135 if (gfx::Display::HasForceDeviceScaleFactor())
136 return gfx::Display::GetForcedDeviceScaleFactor();
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
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) {
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) {
221 return static_cast<int>(GetSystemMetrics(metric) /
222 GetDeviceScaleFactor() + 0.5);
223 }
224
225 bool IsDeviceScaleFactorSet() {
226 return g_device_scale_factor != 0.0f;
227 }
228
229 } // namespace win
230 } // namespace gfx
OLDNEW
« ui/gfx/gfx.gyp ('K') | « ui/gfx/win/dpi.h ('k') | ui/native_theme/native_theme_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698