[pango/pango2-windows: 4/5] pangodwrite-fontmap.cpp: Support creating GDI-based hb_face_t's




commit 463aa4ca3c7d189655cea60b6d7e22c6c3d72cbd
Author: Chun-wei Fan <fanchunwei src gnome org>
Date:   Mon Jul 4 18:07:56 2022 +0800

    pangodwrite-fontmap.cpp: Support creating GDI-based hb_face_t's
    
    Use DirectWrite's GDI interop features to create HarfBuzz hb_face_t via GDI
    LOGFONTW's, so that we can allow people to use GDI font support if they do not
    have a custom GDI renderer for DirectWrite fonts and if they do not have
    Direct2D support to render the fonts.
    
    This support is only enabled if HarfBuzz is built with GDI support, and support
    for enabling this code path is not added at this point, yet.

 meson.build                    |  6 +++++
 pango2/pangodwrite-fontmap.cpp | 52 ++++++++++++++++++++++++++++++++++++++----
 2 files changed, 53 insertions(+), 5 deletions(-)
---
diff --git a/meson.build b/meson.build
index e410b7d48..34f1b5815 100644
--- a/meson.build
+++ b/meson.build
@@ -325,6 +325,12 @@ if host_system == 'windows'
     cc.find_library('dwrite'),
   ]
 
+  if cc.has_header_symbol('hb-gdi.h',
+                          'hb_gdi_face_create',
+                          dependencies: harfbuzz_dep)
+    pango_conf.set('HAVE_GDI', 1)
+  endif
+
   cairo_pkg = 'cairo-win32-dwrite-font'
 endif
 
diff --git a/pango2/pangodwrite-fontmap.cpp b/pango2/pangodwrite-fontmap.cpp
index ad6e8d018..7a9307948 100644
--- a/pango2/pangodwrite-fontmap.cpp
+++ b/pango2/pangodwrite-fontmap.cpp
@@ -28,6 +28,10 @@
 #include <hb-ot.h>
 #include <hb-directwrite.h>
 
+#ifdef HAVE_GDI
+#include <hb-gdi.h>
+#endif
+
 #include "pangodwrite-fontmap.h"
 #include "pango-fontmap-private.h"
 #include "pango-hbface-private.h"
@@ -239,20 +243,49 @@ util_dwrite_get_font_family_name (IDWriteFontFamily *family)
 }
 
 static Pango2HbFace*
-util_create_pango2_hb_face (IDWriteFontFamily *family,
-                            IDWriteFont *font,
-                            IDWriteFontFace *face)
+util_create_pango2_hb_face (Pango2FontMap     *map,
+                            IDWriteFontFamily *family,
+                            IDWriteFont       *font,
+                            IDWriteFontFace   *face)
 {
   char *family_name = util_dwrite_get_font_family_name (family);
   char *variant_name = util_dwrite_get_font_variant_name (font);
   Pango2HbFace *pango_face = NULL;
+  LOGFONTW lfw;
+  HFONT hfont = NULL;
 
   if (family_name && variant_name)
     {
       Pango2FontDescription *description = util_get_pango2_font_description (font, family_name);
-      hb_face_t *hb_face = hb_directwrite_face_create (face);
+      hb_face_t *hb_face = NULL;
       char *name = g_strconcat (family_name, " ", variant_name, NULL);
 
+#ifdef HAVE_GDI
+      if (pango2_direct_write_font_map_get_use_gdi (map))
+        {
+          HRESULT hr;
+
+          hr = PANGO2_DIRECT_WRITE_FONT_MAP (map)->gdi_interop->ConvertFontFaceToLOGFONT (face, &lfw);
+          if (FAILED (hr))
+            {
+              g_error ("Failed to retrieve LOGFONTW from IDWriteFontFace, error: %x\n", (unsigned)hr);
+              return NULL;
+            }
+
+          hfont = CreateFontIndirectW (&lfw);
+
+          if (hfont == NULL)
+            {
+              g_error ("Failed to create HFONT from LOGFONTW %x: %d\n", lfw, GetLastError ());
+              return NULL;
+            }
+
+          hb_face = hb_gdi_face_create (hfont);
+        }
+      else
+#endif /* HAVE_GDI */
+        hb_face = hb_directwrite_face_create (face);
+
       hb_face_make_immutable (hb_face);
 
       pango_face = pango2_hb_face_new_from_hb_face (hb_face, -1, name, description);
@@ -265,6 +298,9 @@ util_create_pango2_hb_face (IDWriteFontFamily *family,
   g_free (family_name);
   g_free (variant_name);
 
+  if (hfont != NULL)
+    DeleteObject (hfont);
+
   return pango_face;
 }
 
@@ -320,7 +356,8 @@ pango2_direct_write_font_map_populate (Pango2FontMap *map)
               continue;
             }
 
-          pango_face = util_create_pango2_hb_face (family, font, face);
+          pango_face = util_create_pango2_hb_face (map, family, font, face);
+
           if (pango_face)
             pango2_font_map_add_face (map, PANGO2_FONT_FACE (pango_face));
 
@@ -579,6 +616,7 @@ pango2_direct_write_font_map_set_use_gdi (Pango2FontMap *map,
 
   g_return_if_fail (PANGO2_IS_DIRECT_WRITE_FONT_MAP (map));
 
+#ifdef HAVE_GDI
   dwrite_map = PANGO2_DIRECT_WRITE_FONT_MAP (map);
 
   if (dwrite_map->use_gdi == use_gdi)
@@ -588,6 +626,10 @@ pango2_direct_write_font_map_set_use_gdi (Pango2FontMap *map,
   g_object_notify_by_pspec (G_OBJECT (dwrite_map), properties[PROP_USE_GDI]);
 
   pango2_font_map_repopulate (map, TRUE);
+#else
+  if (use_gdi)
+    g_message ("Use of GDI disabled due to lack of GDI support in HarfBuzz");
+#endif
 }
 
 /**


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