diff options
author | Chun-wei Fan <fanchunwei@src.gnome.org> | 2022-07-07 12:36:26 +0800 |
---|---|---|
committer | Chun-wei Fan <fanchunwei@src.gnome.org> | 2022-09-26 11:04:25 +0800 |
commit | 5bc16f7896ba3eb5b37ffdb03f28c646aad5889e (patch) | |
tree | d8caafc9e81c3ab8e4628df6116a7e636a792211 /pango/pangowin32-dwrite-fontmap.cpp | |
parent | 6843d7fdd75382a162eefe0034d3e8e1d3b50293 (diff) | |
download | pango-5bc16f7896ba3eb5b37ffdb03f28c646aad5889e.tar.gz |
pangowin32: Use DirectWrite to enumerate system fonts
...instead of using EnumFontFamiliesEx(), 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. Also update synthesize_foreach() accordingly, since we should
also record the IDWriteFonts as well for synthesized LOGFONTWs.
Portions based on Luca Bacci's implementation of the DirectWrite fontmap
support in the upcoming Pango2.
Diffstat (limited to 'pango/pangowin32-dwrite-fontmap.cpp')
-rw-r--r-- | pango/pangowin32-dwrite-fontmap.cpp | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/pango/pangowin32-dwrite-fontmap.cpp b/pango/pangowin32-dwrite-fontmap.cpp index bb22efea..0a0278a9 100644 --- a/pango/pangowin32-dwrite-fontmap.cpp +++ b/pango/pangowin32-dwrite-fontmap.cpp @@ -84,3 +84,108 @@ pango_win32_dwrite_items_destroy (PangoWin32DWriteItems *dwrite_items) 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 = pango_win32_get_direct_write_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)) + pango_win32_insert_font (map, &lfw, font, FALSE); + else + g_warning ("GDIInterop::ConvertFontToLOGFONT failed with error code %x\n", + (unsigned)hr); + } + + face->Release (); + } + + family->Release (); + } + + collection->Release (); + collection = NULL; +} + +gpointer +pango_win32_logfontw_get_dwrite_font (LOGFONTW *logfontw) +{ + PangoWin32DWriteItems *dwrite_items = pango_win32_get_direct_write_items (); + IDWriteFont *font = NULL; + HRESULT hr; + + hr = dwrite_items->gdi_interop->CreateFontFromLOGFONT (logfontw, &font); + + if (FAILED (hr) || font == NULL) + g_warning ("IDWriteFactory::GdiInterop::CreateFontFromLOGFONT failed with error %x\n", + (unsigned)hr); + + return font; +} + +void +pango_win32_dwrite_font_release (gpointer dwrite_font) +{ + IDWriteFont *font = static_cast<IDWriteFont *>(dwrite_font); + + if (font != NULL) + font->Release (); +} |