diff options
Diffstat (limited to 'chromium/ui/gfx/win/dpi.cc')
-rw-r--r-- | chromium/ui/gfx/win/dpi.cc | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/chromium/ui/gfx/win/dpi.cc b/chromium/ui/gfx/win/dpi.cc new file mode 100644 index 00000000000..98d23bd5ef9 --- /dev/null +++ b/chromium/ui/gfx/win/dpi.cc @@ -0,0 +1,175 @@ +// 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/gfx/win/dpi.h" + +#include <windows.h> +#include "base/command_line.h" +#include "base/win/scoped_hdc.h" +#include "base/win/windows_version.h" +#include "ui/base/layout.h" +#include "base/win/registry.h" +#include "ui/gfx/display.h" +#include "ui/gfx/switches.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; + +// Tests to see if the command line flag "--high-dpi-support" is set. +bool IsHighDPIEnabled() { + // Default is disabled. + if (CommandLine::ForCurrentProcess()->HasSwitch( + switches::kHighDPISupport)) { + return CommandLine::ForCurrentProcess()->GetSwitchValueASCII( + switches::kHighDPISupport).compare("1") == 0; + } + return false; +} + +// Gets the device scale factor. If support is enabled, this will return the +// best available scale based on the screen's pixel density. This can be +// affected (overridden) by --force-device-scale-factor=x +float GetDeviceScaleFactorImpl() { + if (IsHighDPIEnabled()) { + float scale = gfx::Display::HasForceDeviceScaleFactor() ? + gfx::Display::GetForcedDeviceScaleFactor() : gfx::GetDPIScale(); + // Quantize to nearest supported scale factor. + scale = ui::GetScaleFactorScale(ui::GetScaleFactorFromScale(scale)); + return scale; + } + 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 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 Size(dpi_x, dpi_y); +} + +float GetDPIScale() { + if (IsHighDPIEnabled()) { + return static_cast<float>(GetDPI().width()) / + static_cast<float>(kDefaultDPIX); + } + return 1.0; +} + +bool IsInHighDPIMode() { + return GetDPIScale() > 1.0; +} + +void EnableHighDPISupport() { + if (IsHighDPIEnabled()) { + 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; +} + +Point ScreenToDIPPoint(const Point& pixel_point) { + return ToFlooredPoint(ScalePoint(pixel_point, 1.0f / GetDeviceScaleFactor())); +} + +Point DIPToScreenPoint(const Point& dip_point) { + return ToFlooredPoint(ScalePoint(dip_point, GetDeviceScaleFactor())); +} + +Rect ScreenToDIPRect(const Rect& pixel_bounds) { + // TODO(kevers): Switch to non-deprecated method for float to int conversions. + return ToFlooredRectDeprecated( + ScaleRect(pixel_bounds, 1.0f / GetDeviceScaleFactor())); +} + +Rect DIPToScreenRect(const Rect& dip_bounds) { + // TODO(kevers): Switch to non-deprecated method for float to int conversions. + return ToFlooredRectDeprecated( + ScaleRect(dip_bounds, GetDeviceScaleFactor())); +} + +Size ScreenToDIPSize(const Size& size_in_pixels) { + return ToFlooredSize( + ScaleSize(size_in_pixels, 1.0f / GetDeviceScaleFactor())); +} + +Size DIPToScreenSize(const Size& dip_size) { + return ToFlooredSize(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; +} + + +double GetUndocumentedDPITouchScale() { + static double scale = + (base::win::GetVersion() < base::win::VERSION_WIN8_1) ? + GetUndocumentedDPIScale() : 1.0; + return scale; +} + + +} // namespace win +} // namespace gfx |