diff options
Diffstat (limited to 'pango')
-rw-r--r-- | pango/pangowin32-dwrite-fontmap.cpp | 105 | ||||
-rw-r--r-- | pango/pangowin32-fontmap.c | 35 | ||||
-rw-r--r-- | pango/pangowin32-private.h | 16 |
3 files changed, 144 insertions, 12 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 (); +} diff --git a/pango/pangowin32-fontmap.c b/pango/pangowin32-fontmap.c index be6daa78..9a140702 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); @@ -197,7 +193,7 @@ pango_win32_inner_enum_proc (LOGFONTW *lfp, * Asian fonts with @ prepended to their name, ignore them. */ if (lfp->lfFaceName[0] != '@') - pango_win32_insert_font (win32fontmap, lfp, FALSE); + pango_win32_insert_font (win32fontmap, lfp, NULL, FALSE); return 1; } @@ -282,7 +278,7 @@ synthesize_foreach (gpointer key, lf = variant[NORMAL]->logfontw; lf.lfWeight = FW_BOLD; - pango_win32_insert_font (win32fontmap, &lf, TRUE); + pango_win32_insert_font (win32fontmap, &lf, NULL, TRUE); } if (variant[NORMAL] != NULL && variant[SLANTED] == NULL) @@ -290,7 +286,7 @@ synthesize_foreach (gpointer key, lf = variant[NORMAL]->logfontw; lf.lfItalic = 255; - pango_win32_insert_font (win32fontmap, &lf, TRUE); + pango_win32_insert_font (win32fontmap, &lf, NULL, TRUE); } if (variant[NORMAL] != NULL && @@ -300,7 +296,7 @@ synthesize_foreach (gpointer key, lf.lfWeight = FW_BOLD; lf.lfItalic = 255; - pango_win32_insert_font (win32fontmap, &lf, TRUE); + pango_win32_insert_font (win32fontmap, &lf, NULL, TRUE); } else if (variant[BOLDER] != NULL && variant[BOLDER+SLANTED] == NULL) @@ -308,7 +304,7 @@ synthesize_foreach (gpointer key, lf = variant[BOLDER]->logfontw; lf.lfItalic = 255; - pango_win32_insert_font (win32fontmap, &lf, TRUE); + pango_win32_insert_font (win32fontmap, &lf, NULL, TRUE); } else if (variant[SLANTED] != NULL && variant[BOLDER+SLANTED] == NULL) @@ -316,7 +312,7 @@ synthesize_foreach (gpointer key, lf = variant[SLANTED]->logfontw; lf.lfWeight = FW_BOLD; - pango_win32_insert_font (win32fontmap, &lf, TRUE); + pango_win32_insert_font (win32fontmap, &lf, NULL, TRUE); } } @@ -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}; win32fontmap->families = g_hash_table_new_full ((GHashFunc) case_insensitive_str_hash, @@ -713,6 +709,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 (); @@ -721,6 +722,9 @@ _pango_win32_font_map_init (PangoWin32FontMap *win32fontmap) g_free, NULL); + pango_win32_dwrite_font_map_populate (win32fontmap); + +#if 0 /* XXX: Implement fallback mode to GDI? */ memset (&logfont, 0, sizeof (logfont)); logfont.lfCharSet = DEFAULT_CHARSET; @@ -730,6 +734,7 @@ _pango_win32_font_map_init (PangoWin32FontMap *win32fontmap) EnumFontFamiliesExW (hdc, &logfont, (FONTENUMPROCW) pango_win32_enum_proc, (LPARAM) &enum_proc_data, 0); +#endif g_hash_table_foreach (win32fontmap->families, synthesize_foreach, win32fontmap); @@ -865,6 +870,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); @@ -1651,9 +1657,10 @@ ff_name (int ff, char* num) } } -static void +void pango_win32_insert_font (PangoWin32FontMap *win32fontmap, LOGFONTW *lfp, + gpointer dwrite_font, gboolean is_synthetic) { LOGFONTW *lfp2 = NULL; @@ -1690,7 +1697,11 @@ pango_win32_insert_font (PangoWin32FontMap *win32fontmap, PING (("not found")); lfp2 = g_new (LOGFONTW, 1); *lfp2 = *lfp; + if (dwrite_font == NULL) + dwrite_font = pango_win32_logfontw_get_dwrite_font (lfp2); + g_hash_table_insert (win32fontmap->fonts, lfp2, lfp2); + g_hash_table_insert (win32fontmap->dwrite_fonts, lfp2, dwrite_font); description = pango_win32_font_description_from_logfontw (lfp2); diff --git a/pango/pangowin32-private.h b/pango/pangowin32-private.h index ffd247c1..97bb6ba1 100644 --- a/pango/pangowin32-private.h +++ b/pango/pangowin32-private.h @@ -99,6 +99,11 @@ struct _PangoWin32FontMap */ GHashTable *fonts; + /* Map LOGFONTWs to IDWriteFonts corresponding to actual fonts + * installed, if applicable. + */ + GHashTable *dwrite_fonts; + /* keeps track of the system font aliases that we might have */ GHashTable *aliases; @@ -284,12 +289,23 @@ gpointer _pango_win32_copy_cmap (gpointer cmap, extern gboolean _pango_win32_debug; +void pango_win32_insert_font (PangoWin32FontMap *win32fontmap, + LOGFONTW *lfp, + gpointer dwrite_font, + gboolean is_synthetic); + PangoWin32DWriteItems *pango_win32_init_direct_write (void); PangoWin32DWriteItems *pango_win32_get_direct_write_items (void); +void pango_win32_dwrite_font_map_populate (PangoWin32FontMap *map); + void pango_win32_dwrite_items_destroy (PangoWin32DWriteItems *items); +void pango_win32_dwrite_font_release (gpointer dwrite_font); + +gpointer pango_win32_logfontw_get_dwrite_font (LOGFONTW *logfontw); + G_END_DECLS #endif /* __PANGOWIN32_PRIVATE_H__ */ |