diff options
-rw-r--r-- | pango/pangowin32-dwrite-fontmap.cpp | 216 | ||||
-rw-r--r-- | pango/pangowin32-fontmap.c | 86 | ||||
-rw-r--r-- | pango/pangowin32-private.h | 8 |
3 files changed, 224 insertions, 86 deletions
diff --git a/pango/pangowin32-dwrite-fontmap.cpp b/pango/pangowin32-dwrite-fontmap.cpp index dd2f506a..ae1d11af 100644 --- a/pango/pangowin32-dwrite-fontmap.cpp +++ b/pango/pangowin32-dwrite-fontmap.cpp @@ -204,6 +204,222 @@ pango_win32_dwrite_font_is_monospace (gpointer dwrite_font, return result; } +static PangoStretch +util_to_pango_stretch (DWRITE_FONT_STRETCH stretch) +{ + PangoStretch pango_stretch = PANGO_STRETCH_NORMAL; + + switch (stretch) + { + case DWRITE_FONT_STRETCH_ULTRA_CONDENSED: + pango_stretch = PANGO_STRETCH_ULTRA_CONDENSED; + break; + case DWRITE_FONT_STRETCH_EXTRA_CONDENSED: + pango_stretch = PANGO_STRETCH_EXTRA_CONDENSED; + break; + case DWRITE_FONT_STRETCH_CONDENSED: + pango_stretch = PANGO_STRETCH_CONDENSED; + break; + case DWRITE_FONT_STRETCH_SEMI_CONDENSED: + pango_stretch = PANGO_STRETCH_SEMI_CONDENSED; + break; + case DWRITE_FONT_STRETCH_NORMAL: + /* also DWRITE_FONT_STRETCH_MEDIUM */ + pango_stretch = PANGO_STRETCH_NORMAL; + break; + case DWRITE_FONT_STRETCH_SEMI_EXPANDED: + pango_stretch = PANGO_STRETCH_SEMI_EXPANDED; + break; + case DWRITE_FONT_STRETCH_EXPANDED: + pango_stretch = PANGO_STRETCH_EXPANDED; + break; + case DWRITE_FONT_STRETCH_EXTRA_EXPANDED: + pango_stretch = PANGO_STRETCH_EXTRA_EXPANDED; + break; + case DWRITE_FONT_STRETCH_ULTRA_EXPANDED: + pango_stretch = PANGO_STRETCH_ULTRA_EXPANDED; + break; + case DWRITE_FONT_STRETCH_UNDEFINED: + default: + pango_stretch = PANGO_STRETCH_NORMAL; + } + + return pango_stretch; +} + +static PangoStyle +util_to_pango_style (DWRITE_FONT_STYLE style) +{ + switch (style) + { + case DWRITE_FONT_STYLE_NORMAL: + return PANGO_STYLE_NORMAL; + case DWRITE_FONT_STYLE_OBLIQUE: + return PANGO_STYLE_OBLIQUE; + case DWRITE_FONT_STYLE_ITALIC: + return PANGO_STYLE_ITALIC; + default: + g_assert_not_reached (); + return PANGO_STYLE_NORMAL; + } +} + +static int +util_map_weight (int weight) +{ + if G_UNLIKELY (weight < 100) + weight = 100; + + if G_UNLIKELY (weight > 1000) + weight = 1000; + + return weight; +} + +static PangoWeight +util_to_pango_weight (DWRITE_FONT_WEIGHT weight) +{ + /* DirectWrite weight values range from 1 to 999, Pango weight values + * range from 100 to 1000. */ + + return (PangoWeight) util_map_weight (weight); +} + +static PangoVariant +util_to_pango_variant (IDWriteFont *font) +{ + PangoVariant variant = PANGO_VARIANT_NORMAL; + + return variant; +} + +static PangoFontDescription* +util_get_pango_font_description (IDWriteFont *font, + const char *family_name) +{ + DWRITE_FONT_STRETCH stretch = font->GetStretch (); + DWRITE_FONT_STYLE style = font->GetStyle (); + DWRITE_FONT_WEIGHT weight = font->GetWeight (); + PangoFontDescription *description; + + description = pango_font_description_new (); + pango_font_description_set_family (description, family_name); + + pango_font_description_set_stretch (description, util_to_pango_stretch (stretch)); + pango_font_description_set_variant (description, util_to_pango_variant (font)); + pango_font_description_set_style (description, util_to_pango_style (style)); + pango_font_description_set_weight (description, util_to_pango_weight (weight)); + + return description; +} + +static char* +util_free_to_string (IDWriteLocalizedStrings *strings) +{ + char *string = NULL; + HRESULT hr; + + if (strings->GetCount() > 0) + { + UINT32 index = 0; + BOOL exists = FALSE; + UINT32 length = 0; + + hr = strings->FindLocaleName (L"en-us", &index, &exists); + if (FAILED (hr) || !exists || index == UINT32_MAX) + index = 0; + + hr = strings->GetStringLength (index, &length); + if (SUCCEEDED (hr) && length > 0) + { + gunichar2 *string_utf16 = g_new (gunichar2, length + 1); + + hr = strings->GetString (index, (wchar_t*) string_utf16, length + 1); + if (SUCCEEDED (hr)) + string = g_utf16_to_utf8 (string_utf16, -1, NULL, NULL, NULL); + + g_free (string_utf16); + } + } + + strings->Release (); + + return string; +} + +static char* +util_dwrite_get_font_family_name (IDWriteFontFamily *family) +{ + IDWriteLocalizedStrings *strings = NULL; + HRESULT hr; + + hr = family->GetFamilyNames (&strings); + if (FAILED (hr) || strings == NULL) + { + g_warning ("IDWriteFontFamily::GetFamilyNames failed with error code %x", (unsigned) hr); + return NULL; + } + + return util_free_to_string (strings); +} + +static char* +util_dwrite_get_font_variant_name (IDWriteFont *font) +{ + IDWriteLocalizedStrings *strings = NULL; + HRESULT hr; + + hr = font->GetFaceNames (&strings); + if (FAILED (hr) || strings == NULL) + { + g_warning ("IDWriteFont::GetFaceNames failed with error code %x", (unsigned) hr); + return NULL; + } + + return util_free_to_string (strings); +} + +PangoFontDescription * +pango_win32_font_description_from_logfontw_dwrite (const LOGFONTW *logfontw) +{ + PangoFontDescription *desc = NULL; + IDWriteFont *font = NULL; + HRESULT hr; + gchar *family; + PangoStyle style; + PangoVariant variant; + PangoWeight weight; + PangoStretch stretch; + PangoWin32DWriteItems *dwrite_items; + + dwrite_items = pango_win32_init_direct_write (); + if (dwrite_items == NULL) + return NULL; + + hr = dwrite_items->gdi_interop->CreateFontFromLOGFONT (logfontw, &font); + + if (SUCCEEDED (hr) && font != NULL) + { + IDWriteFontFamily *family = NULL; + + hr = font->GetFontFamily (&family); + + if (SUCCEEDED (hr) && family != NULL) + { + char *family_name = util_dwrite_get_font_family_name (family); + + if (family_name != NULL) + desc = util_get_pango_font_description (font, family_name); + + family->Release (); + } + + font->Release (); + } + + return desc; +} + void pango_win32_dwrite_font_release (gpointer dwrite_font) { diff --git a/pango/pangowin32-fontmap.c b/pango/pangowin32-fontmap.c index 3756c929..05542f74 100644 --- a/pango/pangowin32-fontmap.c +++ b/pango/pangowin32-fontmap.c @@ -717,10 +717,6 @@ _pango_win32_font_map_init (PangoWin32FontMap *win32fontmap) win32fontmap->font_cache = pango_win32_font_cache_new (); win32fontmap->freed_fonts = g_queue_new (); - win32fontmap->warned_fonts = g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, - NULL); pango_win32_dwrite_font_map_populate (win32fontmap); @@ -871,7 +867,6 @@ 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); @@ -1568,6 +1563,9 @@ get_family_nameW (const LOGFONTW *lfp) PangoFontDescription * pango_win32_font_description_from_logfontw (const LOGFONTW *lfp) { + return pango_win32_font_description_from_logfontw_dwrite (lfp); + +#if 0 /* XXX: Add GDI fallback? */ PangoFontDescription *description; gchar *family; PangoStyle style; @@ -1604,6 +1602,7 @@ pango_win32_font_description_from_logfontw (const LOGFONTW *lfp) pango_font_description_set_variant (description, variant); return description; +#endif } static char * @@ -1933,14 +1932,9 @@ pango_win32_font_map_load_fontset (PangoFontMap *fontmap, char **families; int i; PangoFontsetSimple *fonts; - PangoWin32FontMap *win32fontmap = NULL; - GHashTable *warned_fonts = NULL; g_return_val_if_fail (fontmap != NULL, NULL); - win32fontmap = PANGO_WIN32_FONT_MAP (fontmap); - warned_fonts = win32fontmap->warned_fonts; - family = pango_font_description_get_family (desc); families = g_strsplit (family ? family : "", ",", -1); @@ -1955,79 +1949,7 @@ pango_win32_font_map_load_fontset (PangoFontMap *fontmap, g_strfreev (families); - /* The font description was completely unloadable, try with - * family == "Sans" - */ - if (pango_fontset_simple_size (fonts) == 0) - { - char *ctmp1, *ctmp2; - - pango_font_description_set_family_static (tmp_desc, - pango_font_description_get_family (desc)); - - ctmp1 = pango_font_description_to_string (desc); - pango_font_description_set_family_static (tmp_desc, "Sans"); - - if (!g_hash_table_lookup (warned_fonts, ctmp1)) - { - - g_hash_table_insert (warned_fonts, g_strdup (ctmp1), GINT_TO_POINTER (1)); - - ctmp2 = pango_font_description_to_string (tmp_desc); - g_warning ("couldn't load font \"%s\", falling back to \"%s\", " - "expect ugly output.", ctmp1, ctmp2); - g_free (ctmp2); - } - - g_free (ctmp1); - - pango_win32_font_map_fontset_add_fonts (fontmap, - context, - fonts, - tmp_desc, - "Sans"); - } - - /* We couldn't try with Sans and the specified style. Try Sans Normal */ - if (pango_fontset_simple_size (fonts) == 0) - { - char *ctmp1, *ctmp2; - - pango_font_description_set_family_static (tmp_desc, "Sans"); - ctmp1 = pango_font_description_to_string (tmp_desc); - pango_font_description_set_style (tmp_desc, PANGO_STYLE_NORMAL); - pango_font_description_set_weight (tmp_desc, PANGO_WEIGHT_NORMAL); - pango_font_description_set_variant (tmp_desc, PANGO_VARIANT_NORMAL); - pango_font_description_set_stretch (tmp_desc, PANGO_STRETCH_NORMAL); - - - if (!g_hash_table_lookup (warned_fonts, ctmp1)) - { - g_hash_table_insert (warned_fonts, g_strdup (ctmp1), GINT_TO_POINTER (1)); - - ctmp2 = pango_font_description_to_string (tmp_desc); - - g_warning ("couldn't load font \"%s\", falling back to \"%s\", " - "expect ugly output.", ctmp1, ctmp2); - g_free (ctmp2); - } - - g_free (ctmp1); - - pango_win32_font_map_fontset_add_fonts (fontmap, - context, - fonts, - tmp_desc, - "Sans"); - } - pango_font_description_free (tmp_desc); - /* Everything failed, we are screwed, there is no way to continue, - * but lets just not crash here. - */ - if (pango_fontset_simple_size (fonts) == 0) - g_warning ("All font fallbacks failed!!!!"); - return PANGO_FONTSET (fonts); } diff --git a/pango/pangowin32-private.h b/pango/pangowin32-private.h index 1d843ec2..d0ef6dbc 100644 --- a/pango/pangowin32-private.h +++ b/pango/pangowin32-private.h @@ -107,9 +107,6 @@ struct _PangoWin32FontMap /* keeps track of the system font aliases that we might have */ GHashTable *aliases; - /* keeps track of the warned fonts that we might have */ - GHashTable *warned_fonts; - double resolution; /* (points / pixel) * PANGO_SCALE */ }; @@ -307,7 +304,10 @@ gboolean pango_win32_dwrite_font_is_monospace (gpointer void pango_win32_dwrite_font_release (gpointer dwrite_font); -gpointer pango_win32_logfontw_get_dwrite_font (LOGFONTW *logfontw); +gpointer pango_win32_logfontw_get_dwrite_font (LOGFONTW *logfontw); + +PangoFontDescription * +pango_win32_font_description_from_logfontw_dwrite (const LOGFONTW *logfontw); G_END_DECLS |