[gtk/gtk-3-24: 1/2] GDK W32: Correctly infer gtk-xft-antialias & gtk-xft-rgba



commit 217158995a3f0c10f3f88e1533f73eba0b64f270
Author: Руслан Ижбулатов <lrn1986 gmail com>
Date:   Wed Apr 22 21:23:15 2020 +0000

    GDK W32: Correctly infer gtk-xft-antialias & gtk-xft-rgba
    
    Instead of hardcoding gtk-xft-antialias, use SPI_GETFONTSMOOTHING to
    determine whether antialiasing is enabled.
    
    Make gtk-xft-rgba query more complex - try to determine display
    orientation, then use that to rotate subpixel structure. This
    won't help with monitors that have naturally vertical subpixels,
    but should improve things for monitors that are rotated (as long
    as Windows display settings are adjusted accordingly).
    
    Partially fixes #1774

 gdk/win32/gdkmonitor-win32.c  | 86 +++++++++++++++++++++++++++++++++++++++++--
 gdk/win32/gdkmonitor-win32.h  | 37 +++++++++++++++++++
 gdk/win32/gdkproperty-win32.c | 25 ++++++-------
 3 files changed, 130 insertions(+), 18 deletions(-)
---
diff --git a/gdk/win32/gdkmonitor-win32.c b/gdk/win32/gdkmonitor-win32.c
index 2f7afd3a74..5c0a47756a 100644
--- a/gdk/win32/gdkmonitor-win32.c
+++ b/gdk/win32/gdkmonitor-win32.c
@@ -559,6 +559,7 @@ enum_monitor (HMONITOR hmonitor,
       DEVMODEW dm;
       DWORD i_monitor;
       DWORD frequency;
+      GdkWin32MonitorRotation orientation;
 
       memset (&dd, 0, sizeof (dd));
       dd.cb = sizeof (dd);
@@ -577,12 +578,36 @@ enum_monitor (HMONITOR hmonitor,
         continue;
 
       dm.dmSize = sizeof (dm);
+      dm.dmDriverExtra = 0;
+      frequency = 0;
+      orientation = GDK_WIN32_MONITOR_ROTATION_UNKNOWN;
 
       /* Grab refresh rate for this adapter while we're at it */
-      if (EnumDisplaySettingsW (dd.DeviceName, ENUM_CURRENT_SETTINGS, &dm))
-        frequency = dm.dmDisplayFrequency;
-      else
-        frequency = 0;
+      if (EnumDisplaySettingsExW (dd.DeviceName, ENUM_CURRENT_SETTINGS, &dm, 0))
+        {
+          if ((dm.dmFields & DM_DISPLAYORIENTATION) == DM_DISPLAYORIENTATION)
+            {
+              switch (dm.dmDisplayOrientation)
+                {
+                default:
+                case DMDO_DEFAULT:
+                  orientation = GDK_WIN32_MONITOR_ROTATION_0;
+                  break;
+                case DMDO_90:
+                  orientation = GDK_WIN32_MONITOR_ROTATION_90;
+                  break;
+                case DMDO_180:
+                  orientation = GDK_WIN32_MONITOR_ROTATION_180;
+                  break;
+                case DMDO_270:
+                  orientation = GDK_WIN32_MONITOR_ROTATION_270;
+                  break;
+                }
+            }
+
+          if ((dm.dmFields & DM_DISPLAYFREQUENCY) == DM_DISPLAYFREQUENCY)
+            frequency = dm.dmDisplayFrequency;
+        }
 
       /* Enumerate monitors connected to this display adapter */
       for (i_monitor = 0; TRUE; i_monitor++)
@@ -744,6 +769,7 @@ enum_monitor (HMONITOR hmonitor,
            * keep remove == TRUE and be removed further up the stack.
            */
           w32mon->remove = FALSE;
+          w32mon->orientation = orientation;
 
           /* One virtual monitor per display adapter */
           if (w32mon->madeup)
@@ -770,6 +796,58 @@ prune_monitors (EnumMonitorData *data)
     }
 }
 
+const gchar *
+_gdk_win32_monitor_get_pixel_structure (GdkMonitor *monitor)
+{
+  GdkWin32Monitor *w32_m;
+  BOOL enabled = TRUE;
+  unsigned int smoothing_orientation = FE_FONTSMOOTHINGORIENTATIONRGB;
+  BOOL cleartype = TRUE;
+
+  g_return_val_if_fail (monitor != NULL, NULL);
+
+  w32_m = GDK_WIN32_MONITOR (monitor);
+
+  SystemParametersInfoW (SPI_GETFONTSMOOTHING, 0, &enabled, 0);
+  SystemParametersInfoW (SPI_GETCLEARTYPE, 0, &cleartype, 0);
+
+  if (!enabled ||
+      !cleartype ||
+      !SystemParametersInfoW (SPI_GETFONTSMOOTHINGORIENTATION, 0, &smoothing_orientation, 0))
+    return "none";
+
+  if (smoothing_orientation == FE_FONTSMOOTHINGORIENTATIONBGR)
+    switch (w32_m->orientation)
+      {
+      default:
+      case GDK_WIN32_MONITOR_ROTATION_UNKNOWN:
+        return "none";
+      case GDK_WIN32_MONITOR_ROTATION_0:
+        return "bgr";
+      case GDK_WIN32_MONITOR_ROTATION_90:
+        return "vbgr";
+      case GDK_WIN32_MONITOR_ROTATION_180:
+        return "rgb";
+      case GDK_WIN32_MONITOR_ROTATION_270:
+        return "vrgb";
+      }
+  else
+    switch (w32_m->orientation)
+      {
+      default:
+      case GDK_WIN32_MONITOR_ROTATION_UNKNOWN:
+        return "none";
+      case GDK_WIN32_MONITOR_ROTATION_0:
+        return "rgb";
+      case GDK_WIN32_MONITOR_ROTATION_90:
+        return "vrgb";
+      case GDK_WIN32_MONITOR_ROTATION_180:
+        return "bgr";
+      case GDK_WIN32_MONITOR_ROTATION_270:
+        return "vbgr";
+      }
+}
+
 GPtrArray *
 _gdk_win32_display_get_monitor_list (GdkWin32Display *win32_display)
 {
diff --git a/gdk/win32/gdkmonitor-win32.h b/gdk/win32/gdkmonitor-win32.h
index c32f403169..f8777e6f42 100644
--- a/gdk/win32/gdkmonitor-win32.h
+++ b/gdk/win32/gdkmonitor-win32.h
@@ -26,6 +26,36 @@
 
 #include "gdkwin32monitor.h"
 
+/*
+ * The number is the degrees the display is rotated clockwise
+ * from its natural position.
+ * I.e. most displays will have 0. A normal display
+ * that is rotated by 90 degrees will
+ * have 90. The same display rotated counter-clockwise
+ * will have 270. The same display
+ * rotated by 180 degrees (i.e. upside-down)
+ * will have 180.
+ * Accordingly, 0 mode
+ * fontsmoothing is used as-is - i.e. it is assumed that
+ * subpixel structure is horizontal (ClearType does not support
+ * vertical subpixels; if the display has naturally vertical
+ * subpixel structure, ClearType should be disabled altogether).
+ * In 90 subpixel structure has
+ * its verticality flipped (rgb -> vrgb; bgr -> vbgr).
+ * In 180 subpixel structure is
+ * horizontally flipped (rgb -> bgr; bgr -> rgb).
+ * In 270 subpixel structure is
+ * flipped both horizontally and vertically
+ * (rgb -> vbgr; bgr -> vrgb).
+ */
+typedef enum _GdkWin32MonitorRotation {
+  GDK_WIN32_MONITOR_ROTATION_UNKNOWN = 0,
+  GDK_WIN32_MONITOR_ROTATION_0 = 1,
+  GDK_WIN32_MONITOR_ROTATION_90 = 2,
+  GDK_WIN32_MONITOR_ROTATION_180 = 3,
+  GDK_WIN32_MONITOR_ROTATION_270 = 4,
+} GdkWin32MonitorRotation;
+
 struct _GdkWin32Monitor
 {
   GdkMonitor parent;
@@ -36,6 +66,11 @@ struct _GdkWin32Monitor
   /* Device instance path (used to match GdkWin32Monitor to monitor device) */
   gchar *instance_path;
 
+  /* Indicates display rotation and its normal proportions.
+   * Used to determine pixel structure for subpixel smoothing.
+   */
+  GdkWin32MonitorRotation orientation;
+
   /* TRUE if monitor is made up by us
    * (this happens when system has logical monitors, but no physical ones).
    */
@@ -54,4 +89,6 @@ struct _GdkWin32MonitorClass {
 
 int        _gdk_win32_monitor_compare  (GdkWin32Monitor *a, GdkWin32Monitor *b);
 
+const gchar *_gdk_win32_monitor_get_pixel_structure (GdkMonitor *monitor);
+
 #endif
diff --git a/gdk/win32/gdkproperty-win32.c b/gdk/win32/gdkproperty-win32.c
index 6d7ae3bb50..80a2d5f0f3 100644
--- a/gdk/win32/gdkproperty-win32.c
+++ b/gdk/win32/gdkproperty-win32.c
@@ -33,6 +33,7 @@
 #include "gdkproperty.h"
 #include "gdkselection.h"
 #include "gdkprivate-win32.h"
+#include "gdkmonitor-win32.h"
 #include "gdkwin32.h"
 
 GdkAtom
@@ -368,8 +369,11 @@ _gdk_win32_screen_get_setting (GdkScreen   *screen,
     }
   else if (strcmp ("gtk-xft-antialias", name) == 0)
     {
-      GDK_NOTE(MISC, g_print ("gdk_screen_get_setting(\"%s\") : 1\n", name));
-      g_value_set_int (value, 1);
+      BOOL val = TRUE;
+      SystemParametersInfoW (SPI_GETFONTSMOOTHING, 0, &val, 0);
+      g_value_set_int (value, val ? 1 : 0);
+
+      GDK_NOTE(MISC, g_print ("gdk_screen_get_setting(\"%s\") : %u\n", name, val));
       return TRUE;
     }
   else if (strcmp ("gtk-xft-hintstyle", name) == 0)
@@ -380,18 +384,11 @@ _gdk_win32_screen_get_setting (GdkScreen   *screen,
     }
   else if (strcmp ("gtk-xft-rgba", name) == 0)
     {
-      unsigned int orientation = 0;
-      if (SystemParametersInfoW (SPI_GETFONTSMOOTHINGORIENTATION, 0, &orientation, 0))
-        {
-          if (orientation == FE_FONTSMOOTHINGORIENTATIONRGB)
-            g_value_set_static_string (value, "rgb");
-          else if (orientation == FE_FONTSMOOTHINGORIENTATIONBGR)
-            g_value_set_static_string (value, "bgr");
-          else
-            g_value_set_static_string (value, "none");
-        }
-      else
-        g_value_set_static_string (value, "none");
+      const gchar *rgb_value;
+      GdkMonitor *monitor;
+      monitor = gdk_display_get_monitor (gdk_display_get_default (), 0);
+      rgb_value = _gdk_win32_monitor_get_pixel_structure (monitor);
+      g_value_set_static_string (value, rgb_value);
 
       GDK_NOTE(MISC, g_print ("gdk_screen_get_setting(\"%s\") : %s\n", name, g_value_get_string (value)));
       return TRUE;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]