[pango/pango1-dwrite] pangowin32: Use DirectWrite to enumerate system fonts
- From: Chun-wei Fan <fanchunwei src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pango/pango1-dwrite] pangowin32: Use DirectWrite to enumerate system fonts
- Date: Thu, 7 Jul 2022 11:26:25 +0000 (UTC)
commit 2b8e670cf8c5365affa0cd65f2e794df07236277
Author: Chun-wei Fan <fanchunwei src gnome org>
Date: Thu Jul 7 12:36:26 2022 +0800
pangowin32: Use DirectWrite to enumerate system fonts
...instead of using EnumFontFamiliesEx() if we have DirectWrite support, and
retrieve the LOGFONTW's that we need via DirectWrite's GDI interop. Also
cache up our IDWriteFont's that we obtained, so that we can use DirectWrite to
query font properties better than what GDI/Uniscribe can do for us, such as
obtaining stretch info from the font.
Portions based on Lucca Bacci's implementation of the DirectWrite fontmap
support in the upcoming Pango2.
pango/pangowin32-dwrite-fontmap.cpp | 97 +++++++++++++++++++++++++++++++++++++
pango/pangowin32-fontmap.c | 21 ++++----
pango/pangowin32-private.h | 18 ++++++-
3 files changed, 125 insertions(+), 11 deletions(-)
---
diff --git a/pango/pangowin32-dwrite-fontmap.cpp b/pango/pangowin32-dwrite-fontmap.cpp
index b2e690c25..30955f520 100644
--- a/pango/pangowin32-dwrite-fontmap.cpp
+++ b/pango/pangowin32-dwrite-fontmap.cpp
@@ -93,6 +93,98 @@ pango_win32_dwrite_font_map_destroy (PangoWin32FontMap *map)
g_free (dwrite_items);
}
+void
+pango_win32_dwrite_font_map_populate (PangoWin32FontMap *map)
+{
+ IDWriteFontCollection *collection = NULL;
+ UINT32 count;
+ HRESULT hr;
+ gboolean failed = FALSE;
+ PangoWin32DWriteItems *dwrite_items = map->dwrite_items;
+
+ hr = dwrite_items->dwrite_factory->GetSystemFontCollection (&collection, FALSE);
+ if (FAILED (hr) || collection == NULL)
+ {
+ g_error ("IDWriteFactory::GetSystemFontCollection failed with error code %x\n", (unsigned)hr);
+ return;
+ }
+
+ count = collection->GetFontFamilyCount ();
+
+ for (UINT32 i = 0; i < count; i++)
+ {
+ IDWriteFontFamily *family = NULL;
+ UINT32 font_count;
+
+ hr = collection->GetFontFamily (i, &family);
+ if G_UNLIKELY (FAILED (hr) || family == NULL)
+ {
+ g_warning ("IDWriteFontCollection::GetFontFamily failed with error code %x\n", (unsigned)hr);
+ continue;
+ }
+
+ font_count = family->GetFontCount ();
+
+ for (UINT32 j = 0; j < font_count; j++)
+ {
+ IDWriteFont *font = NULL;
+ IDWriteFontFace *face = NULL;
+ DWRITE_FONT_FACE_TYPE font_face_type;
+
+ hr = family->GetFont (j, &font);
+ if (FAILED (hr) || font == NULL)
+ {
+ g_warning ("IDWriteFontFamily::GetFont failed with error code %x\n", (unsigned)hr);
+ break;
+ }
+
+ hr = font->CreateFontFace (&face);
+ if (FAILED (hr) || face == NULL)
+ {
+ g_warning ("IDWriteFont::CreateFontFace failed with error code %x\n", (unsigned)hr);
+ font->Release ();
+ continue;
+ }
+
+ font_face_type = face->GetType ();
+
+ /* don't include Type-1 fonts */
+ if (font_face_type != DWRITE_FONT_FACE_TYPE_TYPE1)
+ {
+ LOGFONTW lfw;
+ BOOL is_sys_font;
+
+ hr = dwrite_items->gdi_interop->ConvertFontToLOGFONT (font, &lfw, &is_sys_font);
+
+ if (SUCCEEDED (hr))
+ {
+ g_hash_table_insert (map->dwrite_fonts, &lfw, font);
+ pango_win32_insert_font (map, &lfw, FALSE);
+ }
+ else
+ g_warning ("GDIInterop::ConvertFontToLOGFONT failed with error code %x\n",
+ (unsigned)hr);
+ }
+
+ face->Release ();
+ }
+
+ family->Release ();
+ }
+
+ collection->Release ();
+ collection = NULL;
+}
+
+void
+pango_win32_dwrite_font_release (gpointer dwrite_font)
+{
+ IDWriteFont *font = static_cast<IDWriteFont *>(dwrite_font);
+
+ if (font != NULL)
+ font->Release ();
+}
+
#else
/* no-op's, no DirectWrite support */
void
@@ -104,4 +196,9 @@ void
pango_win32_dwrite_font_map_destroy (PangoWin32FontMap *map)
{
}
+
+void
+pango_win32_dwrite_font_release (gpointer dwrite_font)
+{
+}
#endif
\ No newline at end of file
diff --git a/pango/pangowin32-fontmap.c b/pango/pangowin32-fontmap.c
index e6b64eb0d..fea285bbe 100644
--- a/pango/pangowin32-fontmap.c
+++ b/pango/pangowin32-fontmap.c
@@ -101,10 +101,6 @@ static PangoFont *pango_win32_font_map_real_find_font (PangoWin32FontMap
static void pango_win32_fontmap_cache_clear (PangoWin32FontMap *win32fontmap);
-static void pango_win32_insert_font (PangoWin32FontMap *fontmap,
- LOGFONTW *lfp,
- gboolean is_synthetic);
-
static PangoWin32Family *pango_win32_get_font_family (PangoWin32FontMap *win32fontmap,
const char *family_name);
@@ -705,7 +701,7 @@ _pango_win32_font_map_init (PangoWin32FontMap *win32fontmap)
{
LOGFONTW logfont;
HDC hdc = _pango_win32_get_display_dc ();
- struct EnumProcData enum_proc_data;
+ struct EnumProcData enum_proc_data = {hdc, win32fontmap};
pango_win32_dwrite_font_map_init (win32fontmap);
win32fontmap->families =
@@ -714,6 +710,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->dwrite_fonts =
+ g_hash_table_new_full ((GHashFunc) logfontw_nosize_hash,
+ (GEqualFunc) logfontw_nosize_equal,
+ NULL,
+ pango_win32_dwrite_font_release);
win32fontmap->font_cache = pango_win32_font_cache_new ();
win32fontmap->freed_fonts = g_queue_new ();
@@ -722,15 +723,16 @@ _pango_win32_font_map_init (PangoWin32FontMap *win32fontmap)
g_free,
NULL);
+#ifdef HAVE_DIRECTWRITE
+ pango_win32_dwrite_font_map_populate (win32fontmap);
+#else
memset (&logfont, 0, sizeof (logfont));
logfont.lfCharSet = DEFAULT_CHARSET;
- enum_proc_data.hdc = hdc;
- enum_proc_data.font_map = win32fontmap;
-
EnumFontFamiliesExW (hdc, &logfont,
(FONTENUMPROCW) pango_win32_enum_proc,
(LPARAM) &enum_proc_data, 0);
+#endif
g_hash_table_foreach (win32fontmap->families, synthesize_foreach, win32fontmap);
@@ -866,6 +868,7 @@ pango_win32_font_map_finalize (GObject *object)
pango_win32_font_cache_free (win32fontmap->font_cache);
+ g_hash_table_destroy (win32fontmap->dwrite_fonts);
g_hash_table_destroy (win32fontmap->warned_fonts);
g_hash_table_destroy (win32fontmap->fonts);
g_hash_table_destroy (win32fontmap->families);
@@ -1653,7 +1656,7 @@ ff_name (int ff, char* num)
}
}
-static void
+void
pango_win32_insert_font (PangoWin32FontMap *win32fontmap,
LOGFONTW *lfp,
gboolean is_synthetic)
diff --git a/pango/pangowin32-private.h b/pango/pangowin32-private.h
index db7d73a3c..3802412b5 100644
--- a/pango/pangowin32-private.h
+++ b/pango/pangowin32-private.h
@@ -109,6 +109,11 @@ struct _PangoWin32FontMap
/* keep track of DirectWrite boiler plate items */
PangoWin32DWriteItems *dwrite_items;
+
+ /* Map LOGFONTWs to IDWriteFonts corresponding to actual fonts
+ * installed, if applicable.
+ */
+ GHashTable *dwrite_fonts;
};
struct _PangoWin32FontMapClass
@@ -287,9 +292,18 @@ gpointer _pango_win32_copy_cmap (gpointer cmap,
extern gboolean _pango_win32_debug;
-void pango_win32_dwrite_font_map_init (PangoWin32FontMap *map);
-void pango_win32_dwrite_font_map_destroy (PangoWin32FontMap *map);
+void pango_win32_insert_font (PangoWin32FontMap *win32fontmap,
+ LOGFONTW *lfp,
+ gboolean is_synthetic);
+
+void pango_win32_dwrite_font_map_init (PangoWin32FontMap *map);
+
+void pango_win32_dwrite_font_map_populate (PangoWin32FontMap *map);
+
+void pango_win32_dwrite_font_map_destroy (PangoWin32FontMap *map);
+
+void pango_win32_dwrite_font_release (gpointer dwrite_font);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]