Browse Source

Implement DPI scaling for Windows (#9586)

sfan5 4 years ago
parent
commit
40df3931d8
5 changed files with 69 additions and 25 deletions
  1. 2 2
      misc/minetest.exe.manifest
  2. 6 0
      misc/winresource.rc
  3. 1 1
      src/CMakeLists.txt
  4. 60 17
      src/client/renderingengine.cpp
  5. 0 5
      src/constants.h

+ 2 - 2
misc/minetest.exe.manifest

@@ -8,8 +8,8 @@
         </security>
     </trustInfo>
     <application xmlns="urn:schemas-microsoft-com:asm.v3">
-        <windowsSettings>
-            <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
+        <windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
+            <dpiAware>true</dpiAware>
         </windowsSettings>
     </application>
 </assembly>

+ 6 - 0
misc/winresource.rc

@@ -1,6 +1,8 @@
 #include <windows.h>
+#include <winuser.h>
 #include <commctrl.h>
 #include <richedit.h>
+
 #ifndef USE_CMAKE_CONFIG_H
 #define USE_CMAKE_CONFIG_H
 #endif
@@ -13,6 +15,10 @@
 	#define BUILDMODE "RUN_IN_PLACE=0"
 #endif
 
+#ifdef __MINGW32__
+CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "minetest.exe.manifest"
+#endif
+
 LANGUAGE 0, SUBLANG_NEUTRAL
 130        ICON         "minetest-icon.ico"
 

+ 1 - 1
src/CMakeLists.txt

@@ -451,7 +451,7 @@ if(WIN32)
 			-i${WINRESOURCE_FILE}
 			-o ${CMAKE_CURRENT_BINARY_DIR}/winresource_rc.o
 			WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
-			DEPENDS ${WINRESOURCE_FILE})
+			DEPENDS ${WINRESOURCE_FILE} ${MINETEST_EXE_MANIFEST_FILE})
 		SET(extra_windows_SRCS ${CMAKE_CURRENT_BINARY_DIR}/winresource_rc.o)
 	else(MINGW) # Probably MSVC
 		set(extra_windows_SRCS ${WINRESOURCE_FILE} ${MINETEST_EXE_MANIFEST_FILE})

+ 60 - 17
src/client/renderingengine.cpp

@@ -45,7 +45,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
 #include <X11/Xatom.h>
+#endif
 
+#ifdef _WIN32
+#include <windows.h>
+#include <winuser.h>
 #endif
 
 #if ENABLE_GLES
@@ -318,6 +322,28 @@ void RenderingEngine::setupTopLevelXorgWindow(const std::string &name)
 #endif
 }
 
+#ifdef _WIN32
+static bool getWindowHandle(irr::video::IVideoDriver *driver, HWND &hWnd)
+{
+	const video::SExposedVideoData exposedData = driver->getExposedVideoData();
+
+	switch (driver->getDriverType()) {
+	case video::EDT_DIRECT3D8:
+		hWnd = reinterpret_cast<HWND>(exposedData.D3D8.HWnd);
+		break;
+	case video::EDT_DIRECT3D9:
+		hWnd = reinterpret_cast<HWND>(exposedData.D3D9.HWnd);
+		break;
+	case video::EDT_OPENGL:
+		hWnd = reinterpret_cast<HWND>(exposedData.OpenGLWin32.HWnd);
+		break;
+	default:
+		return false;
+	}
+
+	return true;
+}
+#endif
 
 bool RenderingEngine::setWindowIcon()
 {
@@ -335,22 +361,9 @@ bool RenderingEngine::setWindowIcon()
 							       "-xorg-icon-128.png");
 #endif
 #elif defined(_WIN32)
-	const video::SExposedVideoData exposedData = driver->getExposedVideoData();
 	HWND hWnd; // Window handle
-
-	switch (driver->getDriverType()) {
-	case video::EDT_DIRECT3D8:
-		hWnd = reinterpret_cast<HWND>(exposedData.D3D8.HWnd);
-		break;
-	case video::EDT_DIRECT3D9:
-		hWnd = reinterpret_cast<HWND>(exposedData.D3D9.HWnd);
-		break;
-	case video::EDT_OPENGL:
-		hWnd = reinterpret_cast<HWND>(exposedData.OpenGLWin32.HWnd);
-		break;
-	default:
+	if (!getWindowHandle(driver, hWnd))
 		return false;
-	}
 
 	// Load the ICON from resource file
 	const HICON hicon = LoadIcon(GetModuleHandle(NULL),
@@ -632,7 +645,7 @@ const char *RenderingEngine::getVideoDriverFriendlyName(irr::video::E_DRIVER_TYP
 }
 
 #ifndef __ANDROID__
-#ifdef XORG_USED
+#if defined(XORG_USED)
 
 static float calcDisplayDensity()
 {
@@ -667,12 +680,42 @@ float RenderingEngine::getDisplayDensity()
 	return cached_display_density;
 }
 
-#else  // XORG_USED
+#elif defined(_WIN32)
+
+
+static float calcDisplayDensity(irr::video::IVideoDriver *driver)
+{
+	HWND hWnd;
+	if (getWindowHandle(driver, hWnd)) {
+		HDC hdc = GetDC(hWnd);
+		float dpi = GetDeviceCaps(hdc, LOGPIXELSX);
+		ReleaseDC(hWnd, hdc);
+		return dpi / 96.0f;
+	}
+
+	/* return manually specified dpi */
+	return g_settings->getFloat("screen_dpi") / 96.0f;
+}
+
+float RenderingEngine::getDisplayDensity()
+{
+	static bool cached = false;
+	static float display_density;
+	if (!cached) {
+		display_density = calcDisplayDensity(get_video_driver());
+		cached = true;
+	}
+	return display_density;
+}
+
+#else
+
 float RenderingEngine::getDisplayDensity()
 {
 	return g_settings->getFloat("screen_dpi") / 96.0;
 }
-#endif // XORG_USED
+
+#endif
 
 v2u32 RenderingEngine::getDisplaySize()
 {

+ 0 - 5
src/constants.h

@@ -110,10 +110,5 @@ with this program; if not, write to the Free Software Foundation, Inc.,
     GUI related things
 */
 
-// TODO: implement dpi-based scaling for windows and remove this hack
-#if defined(_WIN32)
-#define TTF_DEFAULT_FONT_SIZE (18)
-#else
 #define TTF_DEFAULT_FONT_SIZE (16)
-#endif
 #define DEFAULT_FONT_SIZE (10)