[pango/win32-font-language: 3/3] PangoWin32: Initialize DirectWrite as well
- From: Chun-wei Fan <fanchunwei src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pango/win32-font-language: 3/3] PangoWin32: Initialize DirectWrite as well
- Date: Thu, 26 Nov 2020 11:02:26 +0000 (UTC)
commit 80b26d70920c5858811e6a75a8c7c4d05d9bf2f7
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 | 49 +++++++++++++++++++++++++++++++++++++++++
pango/pangowin32-private.h | 7 ++++++
pango/pangowin32.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 111 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..c335f27a 100644
--- a/pango/pangowin32-fontmap.c
+++ b/pango/pangowin32-fontmap.c
@@ -1594,6 +1594,9 @@ pango_win32_insert_font (PangoWin32FontMap *win32fontmap,
gboolean is_synthetic)
{
LOGFONTW *lfp2 = NULL;
+ IDWriteGdiInterop *gdi_interop = _pango_win32_setup_dwrite ();
+ IDWriteLocalizedStrings *dwrite_result_str;
+ gboolean exists = FALSE;
PangoFontDescription *description;
PangoWin32Family *win32family;
PangoWin32Face *win32face;
@@ -1645,6 +1648,12 @@ pango_win32_insert_font (PangoWin32FontMap *win32fontmap,
PING (("win32face created: %p for %S", win32face, lfp->lfFaceName));
win32face->logfontw = *lfp;
+
+ if (IDGdiInterop_CreateFontFromLOGFONT (gdi_interop,
+ &win32face->logfontw,
+ &win32face->dwrite_font) != S_OK)
+ g_warning ("Failed to create DirectWriteFont from LOGFONTW");
+
win32face->description = description;
win32face->coverage = NULL;
@@ -1667,6 +1676,44 @@ pango_win32_insert_font (PangoWin32FontMap *win32fontmap,
win32family->faces = g_slist_append (win32family->faces, win32face);
+ if (IDWriteFont_GetInformationalStrings (win32face->dwrite_font,
+ DWRITE_INFORMATIONAL_STRING_SUPPORTED_SCRIPT_LANGUAGE_TAG,
+ &dwrite_result_str,
+ &exists) != S_OK)
+ {
+ gchar *name = g_utf16_to_utf8 (lfp->lfFaceName, -1, NULL, NULL, NULL);
+ g_warning ("Failed to get supported languages of font %p (name: %s)", lfp, name);
+ g_free (name);
+ }
+
+ if (!exists)
+ {
+ gchar *name = g_utf16_to_utf8 (lfp->lfFaceName, -1, NULL, NULL, NULL);
+ g_message ("Font %s does not support languages", name);
+ g_free (name);
+ }
+ else
+ {
+ gchar *name = g_utf16_to_utf8 (lfp->lfFaceName, -1, NULL, NULL, NULL);
+ guint num_langs = IDWriteLocalizedStrings_GetCount (dwrite_result_str);
+ guint i = 0;
+
+ for (i = 0; i < num_langs; i ++)
+ {
+ guint strlength = 0;
+ wchar_t *str_utf16 = NULL;
+ gchar *str_utf8 = NULL;
+ IDWriteLocalizedStrings_GetStringLength (dwrite_result_str, i, &strlength);
+ str_utf16 = g_new0 (wchar_t, strlength + 1);
+ IDWriteLocalizedStrings_GetString (dwrite_result_str, i, str_utf16, strlength + 1);
+ str_utf8 = g_utf16_to_utf8 (str_utf16, -1, NULL, NULL, NULL);
+ g_message ("Font %s supports language: %s (%d)", name, str_utf8, i);
+ g_free (str_utf8);
+ g_free (str_utf16);
+ }
+ g_free (name);
+ }
+
PING (("name=%s, length(faces)=%d",
win32family->family_name, g_slist_length (win32family->faces)));
}
@@ -1763,6 +1810,8 @@ pango_win32_face_finalize (GObject *object)
g_slist_free (win32face->cached_fonts);
// g_slist_free_full (win32face->cached_fonts, g_object_unref); // This doesn't work.
+ if (win32face->dwrite_font != NULL)
+ IDWriteFont_Release (win32face->dwrite_font);
G_OBJECT_CLASS (pango_win32_family_parent_class)->finalize (object);
}
diff --git a/pango/pangowin32-private.h b/pango/pangowin32-private.h
index 1c9c1c09..c990fe07 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"
@@ -155,6 +159,7 @@ struct _PangoWin32Face
gpointer family;
LOGFONTW logfontw;
+ IDWriteFont *dwrite_font;
PangoFontDescription *description;
PangoCoverage *coverage;
char *face_name;
@@ -277,4 +282,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..87a278fe 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 ();
}
/**
@@ -1283,3 +1318,22 @@ pango_win32_font_create_hb_font (PangoFont *font)
return hb_font;
}
+
+PangoLanguage **
+pango_win32_font_get_languages (PangoFont *font)
+{
+ PangoWin32Font *win32font = NULL;
+ IDWriteGdiInterop *gdi_interop = NULL;
+ IDWriteFont *dwritefont = NULL;
+
+ g_return_val_if_fail (font != NULL, NULL);
+ g_return_val_if_fail (PANGO_WIN32_IS_FONT (font), NULL);
+
+ win32font = PANGO_WIN32_FONT (font);
+ gdi_interop = _pango_win32_setup_dwrite ();
+
+ if (IDGdiInterop_CreateFontFromLOGFONT (gdi_interop,
+ &win32font->logfontw,
+ &dwritefont) != S_OK)
+ g_warning ("Faild to create DirectWriteFont from LOGFONTW");
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]