summaryrefslogtreecommitdiff
path: root/chromium/ui/gfx/win/dpi.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/ui/gfx/win/dpi.cc')
-rw-r--r--chromium/ui/gfx/win/dpi.cc175
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