[pango/pango1-dwrite: 5/9] PangoWin32: Query font description using DirectWrite
- From: Chun-wei Fan <fanchunwei src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pango/pango1-dwrite: 5/9] PangoWin32: Query font description using DirectWrite
- Date: Mon, 15 Aug 2022 10:11:33 +0000 (UTC)
commit aaa687c8bc768091ff537a1588586133091e539b
Author: Chun-wei Fan <fanchunwei src gnome org>
Date: Fri Jul 15 18:48:43 2022 +0800
PangoWin32: Query font description using DirectWrite
We now use DirectWrite to query the font weight, stretch, description
and so on by using first DirectWrite's GdiInterop to convert the
logfontw into an IDirectWriteFont, since the support in there for
querying font attributes are more complete in there. Take out the
warned fonts items, as DirectWrite would support the font attributes
that we need much better (i.e. stretch and so on), and the warned fonts
items will get into the way.
Portions based on Luca Bacci's work for querying the font description
for Windows using DirectWrite for the upcoming Pango2.
pango/pangowin32-dwrite-fontmap.cpp | 216 ++++++++++++++++++++++++++++++++++++
pango/pangowin32-fontmap.c | 83 +-------------
pango/pangowin32-private.h | 8 +-
3 files changed, 224 insertions(+), 83 deletions(-)
---
diff --git a/pango/pangowin32-dwrite-fontmap.cpp b/pango/pangowin32-dwrite-fontmap.cpp
index b3b4af5fc..2d83eafe4 100644
--- a/pango/pangowin32-dwrite-fontmap.cpp
+++ b/pango/pangowin32-dwrite-fontmap.cpp
@@ -206,6 +206,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 3756c9293..f156508e2 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 *
@@ -1934,12 +1933,10 @@ pango_win32_font_map_load_fontset (PangoFontMap *fontmap,
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 +1952,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 1d843ec2d..d0ef6dbc7 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
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]