| OLD | NEW |
| 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 Loading... |
| 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 |
| OLD | NEW |