[pango/win32-font-language: 3/3] PangoWin32: Initialize DirectWrite as well




commit 5233f7c31720f2144c328f0928c4d8a4fe036fcb
Author: Chun-wei Fan <fanchunwei src gnome org>
Date:   Wed Nov 11 20:15:25 2020 +0800

    PangoWin32: Initialize DirectWrite as well
    
    We want to start using DirectWrite to help us implement some features
    that are not that easily done with GDI/Uniscribe, via a GDI interop
    layer as provided by DirectWrite, and by creating and keeping track of
    the IDWriteFont's that are created from each of the LOGFONTs that we
    acquire by quering the fonts that is installed on the system.

 pango/meson.build          |  1 +
 pango/pangowin32-fontmap.c | 26 ++++++++++++++++++++++++++
 pango/pangowin32-private.h | 12 ++++++++++++
 pango/pangowin32.c         | 35 +++++++++++++++++++++++++++++++++++
 4 files changed, 74 insertions(+)
---
diff --git a/pango/meson.build b/pango/meson.build
index 91261274..21b620ec 100644
--- a/pango/meson.build
+++ b/pango/meson.build
@@ -413,6 +413,7 @@ if host_system == 'windows'
   pangowin32_deps = pango_deps + [
     libpango_dep,
     cc.find_library('gdi32'),
+    cc.find_library('dwrite'),
   ]
 
   pangowin32_rc = configure_file(
diff --git a/pango/pangowin32-fontmap.c b/pango/pangowin32-fontmap.c
index 6bc10a7a..67b29b39 100644
--- a/pango/pangowin32-fontmap.c
+++ b/pango/pangowin32-fontmap.c
@@ -697,6 +697,13 @@ create_standard_family (PangoWin32FontMap *win32fontmap,
    */
 }
 
+/* we can't use IDWriteFont_Release for our key releasing function directly... */
+static void
+pango_win32_release_dwrite_font (IDWriteFont *font)
+{
+  IDWriteFont_Release (font);
+}
+
 static void
 _pango_win32_font_map_init (PangoWin32FontMap *win32fontmap)
 {
@@ -710,6 +717,11 @@ _pango_win32_font_map_init (PangoWin32FontMap *win32fontmap)
   win32fontmap->fonts =
     g_hash_table_new_full ((GHashFunc) logfontw_nosize_hash,
                            (GEqualFunc) logfontw_nosize_equal, NULL, g_free);
+  win32fontmap->fonts_dwrite =
+    g_hash_table_new_full ((GHashFunc) logfontw_nosize_hash,
+                           (GEqualFunc) logfontw_nosize_equal,
+                           pango_win32_release_dwrite_font,
+                           g_free);
 
   win32fontmap->font_cache = pango_win32_font_cache_new ();
   win32fontmap->freed_fonts = g_queue_new ();
@@ -859,6 +871,7 @@ pango_win32_font_map_finalize (GObject *object)
   pango_win32_font_cache_free (win32fontmap->font_cache);
 
   g_hash_table_destroy (win32fontmap->warned_fonts);
+  g_hash_table_destroy (win32fontmap->fonts_dwrite);
   g_hash_table_destroy (win32fontmap->fonts);
   g_hash_table_destroy (win32fontmap->families);
 
@@ -1600,6 +1613,8 @@ pango_win32_insert_font (PangoWin32FontMap *win32fontmap,
 
   char tmp_for_charset_name[10];
   char tmp_for_ff_name[10];
+  IDWriteGdiInterop *dwrite_gdi_interop = _pango_win32_setup_dwrite ();
+  IDWriteFont *dwrite_font = NULL;
 
   PING (("face=%S,charset=%s,it=%s,wt=%ld,ht=%ld,ff=%s%s",
          lfp->lfFaceName,
@@ -1629,6 +1644,17 @@ pango_win32_insert_font (PangoWin32FontMap *win32fontmap,
   *lfp2 = *lfp;
   g_hash_table_insert (win32fontmap->fonts, lfp2, lfp2);
 
+  if (IDGdiInterop_CreateFontFromLOGFONT (dwrite_gdi_interop,
+                                          lfp2,
+                                         &dwrite_font) != S_OK)
+    {
+      g_warning ("DirectWrite Font creation from LOGFONT failed!");
+    }
+  else
+    PING ("DirectWrite Font: %p\n", dwrite_font);
+
+  g_hash_table_insert (win32fontmap->fonts_dwrite, lfp2, dwrite_font);
+
   description = pango_win32_font_description_from_logfontw (lfp2);
 
   /* In some cases, extracting a name for a font can fail; such fonts
diff --git a/pango/pangowin32-private.h b/pango/pangowin32-private.h
index 1c9c1c09..9482d2a0 100644
--- a/pango/pangowin32-private.h
+++ b/pango/pangowin32-private.h
@@ -52,6 +52,10 @@
 #define PING(printlist)
 #endif
 
+/* this is a C-compatible counterpart of the DirectWrite headers */
+#define COBJMACROS
+#include "dwrite_c.h"
+
 #include "pangowin32.h"
 #include "pango-font-private.h"
 #include "pango-fontset-private.h"
@@ -96,6 +100,12 @@ struct _PangoWin32FontMap
    */
   GHashTable *fonts;
 
+  /* Map LOGFONTWs (taking into account only the lfFaceName, lfItalic
+   * and lfWeight fields) to IDWriteFonts corresponding to actual fonts
+   * installed.
+   */
+  GHashTable *fonts_dwrite;
+
   /* keeps track of the system font aliases that we might have */
   GHashTable *aliases;
 
@@ -277,4 +287,6 @@ HDC             _pango_win32_get_display_dc                 (void);
 
 extern gboolean _pango_win32_debug;
 
+IDWriteGdiInterop * _pango_win32_setup_dwrite (void);
+
 #endif /* __PANGOWIN32_PRIVATE_H__ */
diff --git a/pango/pangowin32.c b/pango/pangowin32.c
index 213a665e..59b0ca9d 100644
--- a/pango/pangowin32.c
+++ b/pango/pangowin32.c
@@ -32,6 +32,8 @@
  */
 #include "config.h"
 
+#include <initguid.h>
+
 #include <string.h>
 #include <stdlib.h>
 #include <glib.h>
@@ -134,6 +136,8 @@ _pango_win32_font_init (PangoWin32Font *win32font)
 }
 
 static GPrivate display_dc_key = G_PRIVATE_INIT ((GDestroyNotify) DeleteDC);
+static GPrivate dwrite_factory_key;
+static GPrivate dwrite_gdi_key;
 
 HDC
 _pango_win32_get_display_dc (void)
@@ -190,6 +194,36 @@ pango_win32_get_debug_flag (void)
   return _pango_win32_debug;
 }
 
+IDWriteGdiInterop *
+_pango_win32_setup_dwrite (void)
+{
+  IDWriteFactory *dwrite_factory = NULL;
+  IDWriteGdiInterop *dwrite_gdi = NULL;
+
+  dwrite_factory = g_private_get (&dwrite_factory_key);
+  if (dwrite_factory == NULL)
+    {
+      if (DWriteCreateFactory (DWRITE_FACTORY_TYPE_SHARED,
+                              &IID_IDWriteFactory,
+                              (IUnknown **)&dwrite_factory) != S_OK)
+        g_warning ("DWrite factory creation failed!");
+      else
+        g_private_set (&dwrite_factory_key, dwrite_factory);
+    }
+
+  dwrite_gdi = g_private_get (&dwrite_gdi_key);
+  if (dwrite_factory != NULL && dwrite_gdi == NULL)
+    {
+      if (IDWriteFactory_GetGdiInterop (dwrite_factory,
+                                       &dwrite_gdi) != S_OK)
+        g_warning ("DWrite GDI interop creation failed!");
+      else
+        g_private_set (&dwrite_gdi_key, dwrite_gdi);
+    }
+
+  return dwrite_gdi;
+}
+
 static void
 _pango_win32_font_class_init (PangoWin32FontClass *class)
 {
@@ -212,6 +246,7 @@ _pango_win32_font_class_init (PangoWin32FontClass *class)
   class->get_metrics_factor = pango_win32_font_real_get_metrics_factor;
 
   _pango_win32_get_display_dc ();
+  _pango_win32_setup_dwrite ();
 }
 
 /**


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