aboutsummaryrefslogtreecommitdiffhomepage
path: root/win32/PlatWin.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'win32/PlatWin.cxx')
-rw-r--r--win32/PlatWin.cxx52
1 files changed, 44 insertions, 8 deletions
diff --git a/win32/PlatWin.cxx b/win32/PlatWin.cxx
index c97b9283b..b52aa477a 100644
--- a/win32/PlatWin.cxx
+++ b/win32/PlatWin.cxx
@@ -36,6 +36,7 @@
#include <commctrl.h>
#include <richedit.h>
#include <windowsx.h>
+#include <shellscalingapi.h>
#if !defined(DISABLE_D2D)
#define USE_D2D 1
@@ -157,6 +158,15 @@ GetSystemMetricsForDpiSig fnGetSystemMetricsForDpi = nullptr;
using AdjustWindowRectExForDpiSig = BOOL(WINAPI *)(LPRECT lpRect, DWORD dwStyle, BOOL bMenu, DWORD dwExStyle, UINT dpi);
AdjustWindowRectExForDpiSig fnAdjustWindowRectExForDpi = nullptr;
+using AreDpiAwarenessContextsEqualSig = BOOL(WINAPI *)(DPI_AWARENESS_CONTEXT, DPI_AWARENESS_CONTEXT);
+AreDpiAwarenessContextsEqualSig fnAreDpiAwarenessContextsEqual = nullptr;
+
+using GetWindowDpiAwarenessContextSig = DPI_AWARENESS_CONTEXT(WINAPI *)(HWND);
+GetWindowDpiAwarenessContextSig fnGetWindowDpiAwarenessContext = nullptr;
+
+using GetScaleFactorForMonitorSig = HRESULT(WINAPI *)(HMONITOR, DEVICE_SCALE_FACTOR *);
+GetScaleFactorForMonitorSig fnGetScaleFactorForMonitor = nullptr;
+
using SetThreadDpiAwarenessContextSig = DPI_AWARENESS_CONTEXT(WINAPI *)(DPI_AWARENESS_CONTEXT);
SetThreadDpiAwarenessContextSig fnSetThreadDpiAwarenessContext = nullptr;
@@ -177,11 +187,13 @@ void LoadDpiForWindow() noexcept {
::DeleteDC(hdcMeasure);
}
- if (!fnGetDpiForWindow) {
- hDLLShcore = ::LoadLibraryExW(L"shcore.dll", {}, LOAD_LIBRARY_SEARCH_SYSTEM32);
- if (hDLLShcore) {
- fnGetDpiForMonitor = DLLFunction<GetDpiForMonitorSig>(hDLLShcore, "GetDpiForMonitor");
- }
+ fnGetWindowDpiAwarenessContext = DLLFunction<GetWindowDpiAwarenessContextSig>(user32, "GetWindowDpiAwarenessContext");
+ fnAreDpiAwarenessContextsEqual = DLLFunction<AreDpiAwarenessContextsEqualSig>(user32, "AreDpiAwarenessContextsEqual");
+
+ hDLLShcore = ::LoadLibraryExW(L"shcore.dll", {}, LOAD_LIBRARY_SEARCH_SYSTEM32);
+ if (hDLLShcore) {
+ fnGetScaleFactorForMonitor = DLLFunction<GetScaleFactorForMonitorSig>(hDLLShcore, "GetScaleFactorForMonitor");
+ fnGetDpiForMonitor = DLLFunction<GetDpiForMonitorSig>(hDLLShcore, "GetDpiForMonitor");
}
}
@@ -381,6 +393,20 @@ HMONITOR MonitorFromWindow(HWND hWnd) noexcept {
return monitor;
}
+int GetDeviceScaleFactorWhenGdiScalingActive(HWND hWnd) noexcept {
+ if (fnAreDpiAwarenessContextsEqual) {
+ PLATFORM_ASSERT(fnGetWindowDpiAwarenessContext && fnGetScaleFactorForMonitor);
+ if (fnAreDpiAwarenessContextsEqual(DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED, fnGetWindowDpiAwarenessContext(hWnd))) {
+ const HWND hRootWnd = ::GetAncestor(hWnd, GA_ROOT); // Scale factor applies to entire (root) window.
+ const HMONITOR hMonitor = MonitorFromWindow(hRootWnd, MONITOR_DEFAULTTONEAREST);
+ DEVICE_SCALE_FACTOR deviceScaleFactor;
+ if (S_OK == fnGetScaleFactorForMonitor(hMonitor, &deviceScaleFactor))
+ return (static_cast<int>(deviceScaleFactor) + 99) / 100; // increase to first integral multiple of 1
+ }
+ }
+ return 1;
+}
+
std::shared_ptr<Font> Font::Allocate(const FontParameters &fp) {
#if defined(USE_D2D)
if (fp.technology != Technology::Default) {
@@ -1310,11 +1336,13 @@ class SurfaceD2D : public Surface, public ISetRenderingParams {
static constexpr FontQuality invalidFontQuality = FontQuality::QualityMask;
FontQuality fontQuality = invalidFontQuality;
int logPixelsY = USER_DEFAULT_SCREEN_DPI;
+ int deviceScaleFactor = 1;
std::shared_ptr<RenderingParams> renderingParams;
void Clear() noexcept;
void SetFontQuality(FontQuality extraFontFlag);
HRESULT GetBitmap(ID2D1Bitmap **ppBitmap);
+ void SetDeviceScaleFactor(const ID2D1RenderTarget *const pRenderTarget) noexcept;
public:
SurfaceD2D() noexcept;
@@ -1404,6 +1432,7 @@ SurfaceD2D::SurfaceD2D(ID2D1RenderTarget *pRenderTargetCompatible, int width, in
&desiredSize, nullptr, &desiredFormat, D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, &pBitmapRenderTarget);
if (SUCCEEDED(hr)) {
pRenderTarget = pBitmapRenderTarget;
+ SetDeviceScaleFactor(pRenderTarget);
pRenderTarget->BeginDraw();
ownRenderTarget = true;
}
@@ -1462,6 +1491,7 @@ void SurfaceD2D::Init(SurfaceID sid, WindowID wid) {
Release();
SetScale(wid);
pRenderTarget = static_cast<ID2D1RenderTarget *>(sid);
+ SetDeviceScaleFactor(pRenderTarget);
}
std::unique_ptr<Surface> SurfaceD2D::AllocatePixMap(int width, int height) {
@@ -1510,9 +1540,15 @@ int SurfaceD2D::LogPixelsY() {
return logPixelsY;
}
+void SurfaceD2D::SetDeviceScaleFactor(const ID2D1RenderTarget *const pD2D1RenderTarget) noexcept {
+ FLOAT dpiX = 0.f;
+ FLOAT dpiY = 0.f;
+ pD2D1RenderTarget->GetDpi(&dpiX, &dpiY);
+ deviceScaleFactor = static_cast<int>(dpiX / 96.f);
+}
+
int SurfaceD2D::PixelDivisions() {
- // Win32 uses device pixels.
- return 1;
+ return deviceScaleFactor;
}
int SurfaceD2D::DeviceHeightFont(int points) {
@@ -1644,7 +1680,7 @@ void SurfaceD2D::FillRectangle(PRectangle rc, Fill fill) {
}
void SurfaceD2D::FillRectangleAligned(PRectangle rc, Fill fill) {
- FillRectangle(PixelAlign(rc, 1), fill);
+ FillRectangle(PixelAlign(rc, PixelDivisions()), fill);
}
void SurfaceD2D::FillRectangle(PRectangle rc, Surface &surfacePattern) {