- add sources.
[platform/framework/web/crosswalk.git] / src / ui / gfx / win / dpi.cc
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/command_line.h"
9 #include "base/win/scoped_hdc.h"
10 #include "base/win/windows_version.h"
11 #include "base/win/registry.h"
12 #include "ui/gfx/display.h"
13 #include "ui/gfx/switches.h"
14 #include "ui/gfx/point_conversions.h"
15 #include "ui/gfx/rect_conversions.h"
16 #include "ui/gfx/size_conversions.h"
17
18 namespace {
19
20 int kDefaultDPIX = 96;
21 int kDefaultDPIY = 96;
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   return static_cast<float>(gfx::GetDPI().width()) /
37       static_cast<float>(kDefaultDPIX);
38 }
39 }  // namespace
40
41 namespace gfx {
42
43 void InitDeviceScaleFactor(float scale) {
44   DCHECK_NE(0.0f, scale);
45   g_device_scale_factor = scale;
46 }
47
48 Size GetDPI() {
49   static int dpi_x = 0;
50   static int dpi_y = 0;
51   static bool should_initialize = true;
52
53   if (should_initialize) {
54     should_initialize = false;
55     base::win::ScopedGetDC screen_dc(NULL);
56     // This value is safe to cache for the life time of the app since the
57     // user must logout to change the DPI setting. This value also applies
58     // to all screens.
59     dpi_x = GetDeviceCaps(screen_dc, LOGPIXELSX);
60     dpi_y = GetDeviceCaps(screen_dc, LOGPIXELSY);
61   }
62   return Size(dpi_x, dpi_y);
63 }
64
65 float GetDPIScale() {
66   if (IsHighDPIEnabled()) {
67     return gfx::Display::HasForceDeviceScaleFactor() ?
68         gfx::Display::GetForcedDeviceScaleFactor() :
69         GetUnforcedDeviceScaleFactor();
70   }
71   return 1.0;
72 }
73
74 bool IsHighDPIEnabled() {
75   // Default is disabled.
76   if (CommandLine::ForCurrentProcess()->HasSwitch(
77       switches::kHighDPISupport)) {
78     return CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
79         switches::kHighDPISupport).compare("1") == 0;
80   }
81   return false;
82 }
83
84 bool IsInHighDPIMode() {
85   return GetDPIScale() > 1.0;
86 }
87
88 void EnableHighDPISupport() {
89   if (IsHighDPIEnabled()) {
90     typedef BOOL(WINAPI *SetProcessDPIAwarePtr)(VOID);
91     SetProcessDPIAwarePtr set_process_dpi_aware_func =
92         reinterpret_cast<SetProcessDPIAwarePtr>(
93             GetProcAddress(GetModuleHandleA("user32.dll"),
94                            "SetProcessDPIAware"));
95     if (set_process_dpi_aware_func)
96       set_process_dpi_aware_func();
97   }
98 }
99
100 namespace win {
101
102 float GetDeviceScaleFactor() {
103   DCHECK_NE(0.0f, g_device_scale_factor);
104   return g_device_scale_factor;
105 }
106
107 Point ScreenToDIPPoint(const Point& pixel_point) {
108   static float scaling_factor =
109       GetDeviceScaleFactor() > GetUnforcedDeviceScaleFactor() ?
110       1.0f / GetDeviceScaleFactor() :
111       1.0f;
112   return ToFlooredPoint(ScalePoint(pixel_point,
113       scaling_factor));
114 }
115
116 Point DIPToScreenPoint(const Point& dip_point) {
117   return ToFlooredPoint(ScalePoint(dip_point, GetDeviceScaleFactor()));
118 }
119
120 Rect ScreenToDIPRect(const Rect& pixel_bounds) {
121   // TODO(kevers): Switch to non-deprecated method for float to int conversions.
122   return ToFlooredRectDeprecated(
123       ScaleRect(pixel_bounds, 1.0f / GetDeviceScaleFactor()));
124 }
125
126 Rect DIPToScreenRect(const Rect& dip_bounds) {
127   // TODO(kevers): Switch to non-deprecated method for float to int conversions.
128   return ToFlooredRectDeprecated(
129       ScaleRect(dip_bounds, GetDeviceScaleFactor()));
130 }
131
132 Size ScreenToDIPSize(const Size& size_in_pixels) {
133   return ToFlooredSize(
134       ScaleSize(size_in_pixels, 1.0f / GetDeviceScaleFactor()));
135 }
136
137 Size DIPToScreenSize(const Size& dip_size) {
138   return ToFlooredSize(ScaleSize(dip_size, GetDeviceScaleFactor()));
139 }
140
141 int GetSystemMetricsInDIP(int metric) {
142   return static_cast<int>(GetSystemMetrics(metric) /
143       GetDeviceScaleFactor() + 0.5);
144 }
145
146 double GetUndocumentedDPIScale() {
147   // TODO(girard): Remove this code when chrome is DPIAware.
148   static double scale = -1.0;
149   if (scale == -1.0) {
150     scale = 1.0;
151     if (!IsProcessDPIAwareWrapper()) {
152       base::win::RegKey key(HKEY_CURRENT_USER,
153                             L"Control Panel\\Desktop\\WindowMetrics",
154                             KEY_QUERY_VALUE);
155       if (key.Valid()) {
156         DWORD value = 0;
157         if (key.ReadValueDW(L"AppliedDPI", &value) == ERROR_SUCCESS) {
158           scale = static_cast<double>(value) / kDefaultDPIX;
159         }
160       }
161     }
162   }
163   return scale;
164 }
165
166
167 double GetUndocumentedDPITouchScale() {
168   static double scale =
169       (base::win::GetVersion() < base::win::VERSION_WIN8_1) ?
170       GetUndocumentedDPIScale() : 1.0;
171   return scale;
172 }
173
174
175 }  // namespace win
176 }  // namespace gfx