1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
|
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/base/win/dpi.h"
#include <windows.h>
#include "base/command_line.h"
#include "base/win/scoped_hdc.h"
#include "ui/base/layout.h"
#include "base/win/registry.h"
#include "ui/base/ui_base_switches.h"
#include "ui/gfx/display.h"
#include "ui/gfx/point_conversions.h"
#include "ui/gfx/rect_conversions.h"
#include "ui/gfx/size_conversions.h"
namespace {
int kDefaultDPIX = 96;
int kDefaultDPIY = 96;
bool IsHighDPIEnabled() {
// Default is disabled.
if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kHighDPISupport)) {
return CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
switches::kHighDPISupport).compare("1") == 0;
}
return false;
}
float GetDeviceScaleFactorImpl() {
#if defined(ENABLE_HIDPI)
if (IsHighDPIEnabled()) {
float scale = gfx::Display::HasForceDeviceScaleFactor() ?
gfx::Display::GetForcedDeviceScaleFactor() : ui::GetDPIScale();
// Quantize to nearest supported scale factor.
scale = ui::GetScaleFactorScale(ui::GetScaleFactorFromScale(scale));
return scale;
}
#endif
return 1.0f;
}
BOOL IsProcessDPIAwareWrapper() {
typedef BOOL(WINAPI *IsProcessDPIAwarePtr)(VOID);
IsProcessDPIAwarePtr is_process_dpi_aware_func =
reinterpret_cast<IsProcessDPIAwarePtr>(
GetProcAddress(GetModuleHandleA("user32.dll"), "IsProcessDPIAware"));
if (is_process_dpi_aware_func)
return is_process_dpi_aware_func();
return FALSE;
}
} // namespace
namespace ui {
gfx::Size GetDPI() {
static int dpi_x = 0;
static int dpi_y = 0;
static bool should_initialize = true;
if (should_initialize) {
should_initialize = false;
base::win::ScopedGetDC screen_dc(NULL);
// This value is safe to cache for the life time of the app since the
// user must logout to change the DPI setting. This value also applies
// to all screens.
dpi_x = GetDeviceCaps(screen_dc, LOGPIXELSX);
dpi_y = GetDeviceCaps(screen_dc, LOGPIXELSY);
}
return gfx::Size(dpi_x, dpi_y);
}
float GetDPIScale() {
return static_cast<float>(GetDPI().width()) /
static_cast<float>(kDefaultDPIX);
}
bool IsInHighDPIMode() {
gfx::Size dpi(GetDPI());
return dpi.width() > kDefaultDPIX || dpi.height() > kDefaultDPIY;
}
void EnableHighDPISupport() {
typedef BOOL(WINAPI *SetProcessDPIAwarePtr)(VOID);
SetProcessDPIAwarePtr set_process_dpi_aware_func =
reinterpret_cast<SetProcessDPIAwarePtr>(
GetProcAddress(GetModuleHandleA("user32.dll"), "SetProcessDPIAware"));
if (set_process_dpi_aware_func)
set_process_dpi_aware_func();
}
namespace win {
float GetDeviceScaleFactor() {
static const float device_scale_factor = GetDeviceScaleFactorImpl();
return device_scale_factor;
}
gfx::Point ScreenToDIPPoint(const gfx::Point& pixel_point) {
return gfx::ToFlooredPoint(
gfx::ScalePoint(pixel_point, 1.0f / GetDeviceScaleFactor()));
}
gfx::Point DIPToScreenPoint(const gfx::Point& dip_point) {
return gfx::ToFlooredPoint(
gfx::ScalePoint(dip_point, GetDeviceScaleFactor()));
}
gfx::Rect ScreenToDIPRect(const gfx::Rect& pixel_bounds) {
// TODO(kevers): Switch to non-deprecated method for float to int conversions.
return gfx::ToFlooredRectDeprecated(
gfx::ScaleRect(pixel_bounds, 1.0f / GetDeviceScaleFactor()));
}
gfx::Rect DIPToScreenRect(const gfx::Rect& dip_bounds) {
// TODO(kevers): Switch to non-deprecated method for float to int conversions.
return gfx::ToFlooredRectDeprecated(
gfx::ScaleRect(dip_bounds, GetDeviceScaleFactor()));
}
gfx::Size ScreenToDIPSize(const gfx::Size& size_in_pixels) {
return gfx::ToFlooredSize(
gfx::ScaleSize(size_in_pixels, 1.0f / GetDeviceScaleFactor()));
}
gfx::Size DIPToScreenSize(const gfx::Size& dip_size) {
return gfx::ToFlooredSize(gfx::ScaleSize(dip_size, GetDeviceScaleFactor()));
}
int GetSystemMetricsInDIP(int metric) {
return static_cast<int>(GetSystemMetrics(metric) /
GetDeviceScaleFactor() + 0.5);
}
double GetUndocumentedDPIScale() {
// TODO(girard): Remove this code when chrome is DPIAware.
static double scale = -1.0;
if (scale == -1.0) {
scale = 1.0;
if (!IsProcessDPIAwareWrapper()) {
base::win::RegKey key(HKEY_CURRENT_USER,
L"Control Panel\\Desktop\\WindowMetrics",
KEY_QUERY_VALUE);
if (key.Valid()) {
DWORD value = 0;
if (key.ReadValueDW(L"AppliedDPI", &value) == ERROR_SUCCESS) {
scale = static_cast<double>(value) / kDefaultDPIX;
}
}
}
}
return scale;
}
} // namespace win
} // namespace ui
|