Bug 1350643 - Part 6.1: Extract getting DPI logic from LogToPhysFactor & SystemScaleFactor to provide new functions MonitorDPI & SystemDPI. r?jimm
MozReview-Commit-ID: E9mXvFMM3pA
--- a/widget/windows/WinUtils.cpp
+++ b/widget/windows/WinUtils.cpp
@@ -544,37 +544,41 @@ WinUtils::Log(const char *fmt, ...)
NS_ASSERTION(gWindowsLog, "Called WinUtils Log() but Widget "
"log module doesn't exist!");
MOZ_LOG(gWindowsLog, LogLevel::Error, (buffer));
delete[] buffer;
}
// static
-double
-WinUtils::SystemScaleFactor()
+float
+WinUtils::SystemDPI()
{
// The result of GetDeviceCaps won't change dynamically, as it predates
// per-monitor DPI and support for on-the-fly resolution changes.
// Therefore, we only need to look it up once.
- static double systemScale = 0;
- if (systemScale == 0) {
+ static float dpi = 0;
+ if (dpi <= 0) {
HDC screenDC = GetDC(nullptr);
- systemScale = GetDeviceCaps(screenDC, LOGPIXELSY) / 96.0;
+ dpi = GetDeviceCaps(screenDC, LOGPIXELSY);
ReleaseDC(nullptr, screenDC);
+ }
- if (systemScale == 0) {
- // Bug 1012487 - This can occur when the Screen DC is used off the
- // main thread on windows. For now just assume a 100% DPI for this
- // drawing call.
- // XXX - fixme!
- return 1.0;
- }
- }
- return systemScale;
+ // Bug 1012487 - dpi can be 0 when the Screen DC is used off the
+ // main thread on windows. For now just assume a 100% DPI for this
+ // drawing call.
+ // XXX - fixme!
+ return dpi > 0 ? dpi : 96;
+}
+
+// static
+double
+WinUtils::SystemScaleFactor()
+{
+ return SystemDPI() / 96.0;
}
#if WINVER < 0x603
typedef enum {
MDT_EFFECTIVE_DPI = 0,
MDT_ANGULAR_DPI = 1,
MDT_RAW_DPI = 2,
MDT_DEFAULT = MDT_EFFECTIVE_DPI
@@ -617,27 +621,35 @@ SlowIsPerMonitorDPIAware()
/* static */ bool
WinUtils::IsPerMonitorDPIAware()
{
static bool perMonitorDPIAware = SlowIsPerMonitorDPIAware();
return perMonitorDPIAware;
}
/* static */
-double
-WinUtils::LogToPhysFactor(HMONITOR aMonitor)
+float
+WinUtils::MonitorDPI(HMONITOR aMonitor)
{
if (IsPerMonitorDPIAware()) {
UINT dpiX, dpiY = 96;
sGetDpiForMonitor(aMonitor ? aMonitor : GetPrimaryMonitor(),
MDT_EFFECTIVE_DPI, &dpiX, &dpiY);
- return dpiY / 96.0;
+ return dpiY;
}
- return SystemScaleFactor();
+ // We're not per-monitor aware, use system DPI instead.
+ return SystemDPI();
+}
+
+/* static */
+double
+WinUtils::LogToPhysFactor(HMONITOR aMonitor)
+{
+ return MonitorDPI(aMonitor) / 96.0;
}
/* static */
int32_t
WinUtils::LogToPhys(HMONITOR aMonitor, double aValue)
{
return int32_t(NS_round(aValue * LogToPhysFactor(aMonitor)));
}
--- a/widget/windows/WinUtils.h
+++ b/widget/windows/WinUtils.h
@@ -204,16 +204,22 @@ public:
* a session even if the displays are reconfigured. This scale factor
* is used by Windows theme metrics etc, which do not fully support
* dynamic resolution changes but are only updated on logout.
*/
static double SystemScaleFactor();
static bool IsPerMonitorDPIAware();
/**
+ * Get the DPI of the given monitor if it's per-monitor DPI aware, otherwise
+ * return the system DPI.
+ */
+ static float MonitorDPI(HMONITOR aMonitor);
+ static float SystemDPI();
+ /**
* Functions to convert between logical pixels as used by most Windows APIs
* and physical (device) pixels.
*/
static double LogToPhysFactor(HMONITOR aMonitor);
static double LogToPhysFactor(HWND aWnd) {
// if there's an ancestor window, we want to share its DPI setting
HWND ancestor = ::GetAncestor(aWnd, GA_ROOTOWNER);
return LogToPhysFactor(::MonitorFromWindow(ancestor ? ancestor : aWnd,