summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Boxer <Aaron Boxer>2020-09-24 11:24:27 -0400
committerGStreamer Merge Bot <gitlab-merge-bot@gstreamer-foundation.org>2020-09-30 18:21:12 +0000
commit37cd678f481b0103cc507b709e0797c4280fe703 (patch)
treefbc86d1cbc497f05e66f6855932991986e476e9a
parent4bebbb908bf1850ce2e162891a833f2603ad0358 (diff)
pango: fix font corruption on windows
1. provide windows font fallbacks 2. do not share windows HDC across threads Part-of: <https://gitlab.freedesktop.org/gstreamer/cerbero/-/merge_requests/574>
-rw-r--r--recipes/pango.recipe4
-rw-r--r--recipes/pango/0001-pangowin32-fontmap-read-windows-fallbacks-from-regis.patch193
-rw-r--r--recipes/pango/0002-win32-Use-GPrivate-managed-display-device-context.patch496
3 files changed, 693 insertions, 0 deletions
diff --git a/recipes/pango.recipe b/recipes/pango.recipe
index 62ec09df..05198261 100644
--- a/recipes/pango.recipe
+++ b/recipes/pango.recipe
@@ -19,6 +19,10 @@ class Recipe(recipe.Recipe):
name + '/0001-meson-Set-the-compatibility-version-correctly-on-mac.patch',
# https://gitlab.gnome.org/GNOME/pango/-/merge_requests/181
name + '/0001-meson-Fix-check-for-builtype-arguments.patch',
+ name + '/0001-pangowin32-fontmap-read-windows-fallbacks-from-regis.patch',
+ # https://gitlab.gnome.org/GNOME/pango/-/merge_requests/34
+ name + '/0002-win32-Use-GPrivate-managed-display-device-context.patch',
+ # https://gitlab.freedesktop.org/gstreamer/cerbero/-/merge_requests/574
]
files_libs = ['libpangocairo-1.0', 'libpango-1.0', 'libpangoft2-1.0']
diff --git a/recipes/pango/0001-pangowin32-fontmap-read-windows-fallbacks-from-regis.patch b/recipes/pango/0001-pangowin32-fontmap-read-windows-fallbacks-from-regis.patch
new file mode 100644
index 00000000..7a68f273
--- /dev/null
+++ b/recipes/pango/0001-pangowin32-fontmap-read-windows-fallbacks-from-regis.patch
@@ -0,0 +1,193 @@
+From e88684bafe932035bea279d71e2e2905b3541807 Mon Sep 17 00:00:00 2001
+From: Aaron Boxer <Aaron Boxer>
+Date: Thu, 24 Sep 2020 11:10:54 -0400
+Subject: [PATCH 1/2] pangowin32-fontmap: read windows fallbacks from registry
+ and add to alias hash
+
+---
+ pango/pangowin32-fontmap.c | 130 +++++++++++++++++++++++++++++++++++--
+ 1 file changed, 126 insertions(+), 4 deletions(-)
+
+diff --git a/pango/pangowin32-fontmap.c b/pango/pangowin32-fontmap.c
+index 12fa4f26..afb8272f 100644
+--- a/pango/pangowin32-fontmap.c
++++ b/pango/pangowin32-fontmap.c
+@@ -30,10 +30,11 @@
+ #include <string.h>
+ #include <errno.h>
+ #include <glib/gstdio.h>
+-
+ #include "pango-fontmap.h"
+ #include "pango-impl-utils.h"
+ #include "pangowin32-private.h"
++#include <windows.h>
++#include <winreg.h>
+
+ typedef struct _PangoWin32Family PangoWin32Family;
+ typedef PangoFontFamilyClass PangoWin32FamilyClass;
+@@ -445,17 +446,16 @@ handle_alias_line (GString *line_buffer,
+ g_string_free (tmp_buffer2, TRUE);
+ }
+
++
+ #ifdef HAVE_CAIRO_WIN32
+
+ static const char * const builtin_aliases[] = {
+ "courier = \"courier new\"",
+- "\"segoe ui\" = \"segoe ui,meiryo,malgun gothic,microsoft jhenghei,microsoft yahei,gisha,leelawadee,arial unicode ms,browallia new,mingliu,simhei,gulimche,ms gothic,sylfaen,kartika,latha,mangal,raavi\"",
+- "tahoma = \"tahoma,arial unicode ms,lucida sans unicode,browallia new,mingliu,simhei,gulimche,ms gothic,sylfaen,kartika,latha,mangal,raavi\"",
+ /* It sucks to use the same GulimChe, MS Gothic, Sylfaen, Kartika,
+ * Latha, Mangal and Raavi fonts for all three of sans, serif and
+ * mono, but it isn't like there would be much choice. For most
+ * non-Latin scripts that Windows includes any font at all for, it
+- * has ony one. One solution is to install the free DejaVu fonts
++ * has only one. One solution is to install the free DejaVu fonts
+ * that are popular on Linux. They are listed here first.
+ */
+ "sans = \"dejavu sans,tahoma,arial unicode ms,lucida sans unicode,browallia new,mingliu,simhei,gulimche,ms gothic,sylfaen,kartika,latha,mangal,raavi\"",
+@@ -464,6 +464,9 @@ static const char * const builtin_aliases[] = {
+ "mono = \"dejavu sans mono,courier new,lucida console,courier monothai,mingliu,simsun,gulimche,ms gothic,sylfaen,kartika,latha,mangal,raavi\"",
+ "monospace = \"dejavu sans mono,courier new,lucida console,courier monothai,mingliu,simsun,gulimche,ms gothic,sylfaen,kartika,latha,mangal,raavi\"",
+ "emoji = \"segoe ui emoji,segoe ui symbol,segoe ui\"",
++ "cursive = \"commic sans ms\"",
++ "fantasy = \"gabriola,impact\"",
++ "system-ui = \"yu gothic ui,segoe ui,meiryo\"",
+ };
+
+ static void
+@@ -490,6 +493,124 @@ read_builtin_aliases (GHashTable *ht_aliases)
+
+ g_string_free (line_buffer, TRUE);
+ }
++
++#define MAX_VALUE_NAME 16383
++
++static void
++read_windows_fallbacks (GHashTable *ht_aliases)
++{
++
++#if 0
++ DWORD value_index;
++ HKEY hkey;
++ LSTATUS status;
++ GString *line_buffer;
++
++ /* https://docs.microsoft.com/en-us/globalization/input/font-technology */
++ status = RegOpenKeyExW (HKEY_LOCAL_MACHINE,
++ L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\FontLink\\SystemLink",
++ 0,
++ KEY_READ,
++ &hkey);
++ if (status != ERROR_SUCCESS)
++ return;
++
++ line_buffer = g_string_new (NULL);
++ status = ERROR_SUCCESS;
++ for (value_index = 0; status != ERROR_NO_MORE_ITEMS; value_index++)
++ {
++ wchar_t name[MAX_VALUE_NAME];
++ DWORD name_length = MAX_VALUE_NAME, value_length = 0;
++ char *errstring = NULL;
++ gchar *utf8_name;
++ wchar_t *value_data, *entry;
++ size_t entry_len;
++
++ status = RegEnumValueW (hkey, value_index, name, &name_length,
++ NULL, NULL, NULL, NULL);
++
++ if (status != ERROR_SUCCESS)
++ continue;
++
++ utf8_name = g_utf16_to_utf8 (name, -1, NULL, NULL, NULL);
++ if (utf8_name == NULL)
++ continue;
++ g_string_truncate (line_buffer, 0);
++ g_string_append_printf (line_buffer,
++ "\"%s\" = \"%s",
++ utf8_name,
++ utf8_name);
++ g_free (utf8_name);
++
++ status = RegGetValueW (hkey, NULL, name, RRF_RT_REG_MULTI_SZ,
++ NULL, NULL, &value_length);
++ if (status != ERROR_SUCCESS)
++ continue;
++
++ value_data = g_malloc (value_length);
++ status = RegGetValueW (hkey, NULL, name, RRF_RT_REG_MULTI_SZ, NULL,
++ value_data, &value_length);
++ if (status != ERROR_SUCCESS)
++ {
++ g_free (value_data);
++ continue;
++ }
++
++ entry = value_data;
++ entry_len = wcslen (entry);
++ while (entry_len > 0)
++ {
++ wchar_t *comma;
++ gchar *entry_utf8;
++
++ comma = wcsstr (entry, L",");
++ /* The value after the first comma, as long as it isn't followed
++ * by another comma with a font scale */
++ if (comma && wcsstr (comma + 1, L",") == NULL)
++ {
++ g_string_append (line_buffer, ",");
++ entry_utf8 = g_utf16_to_utf8 (comma + 1, -1, NULL, NULL, NULL);
++ if (entry_utf8 != NULL)
++ {
++ g_string_append (line_buffer, entry_utf8);
++ g_free (entry_utf8);
++ }
++ }
++
++ entry += entry_len + 1;
++ entry_len = wcslen (entry);
++ }
++ g_free (value_data);
++
++ /* For some reason the default fallback list doesn't cover all of Unicode
++ * and Windows has additional fonts for certain languages.
++ * Some of them are listed in
++ * SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontMapperFamilyFallback
++ * but I couldn't find any docs for it. Feel free to improve this */
++ g_string_append (line_buffer,
++ ",gisha,leelawadee,arial unicode ms,browallia new,"
++ "mingliu,simhei,gulimche,ms gothic,sylfaen,kartika,"
++ "latha,mangal,raavi");
++
++ g_string_append (line_buffer, "\"");
++
++ handle_alias_line (line_buffer, &errstring, ht_aliases);
++ if (errstring != NULL)
++ {
++ g_warning ("error in windows fallback: %s (%s)\n",
++ errstring, line_buffer->str);
++ g_free (errstring);
++ errstring = NULL;
++ }
++ }
++
++ RegCloseKey (hkey);
++ g_string_free (line_buffer, TRUE);
++#endif
++}
++
++
++
+ #endif
+
+
+@@ -502,6 +623,7 @@ load_aliases (void)
+ NULL);
+
+ #ifdef HAVE_CAIRO_WIN32
++ read_windows_fallbacks (ht_aliases);
+ read_builtin_aliases (ht_aliases);
+ #endif
+
+--
+2.17.1
+
diff --git a/recipes/pango/0002-win32-Use-GPrivate-managed-display-device-context.patch b/recipes/pango/0002-win32-Use-GPrivate-managed-display-device-context.patch
new file mode 100644
index 00000000..4ce515aa
--- /dev/null
+++ b/recipes/pango/0002-win32-Use-GPrivate-managed-display-device-context.patch
@@ -0,0 +1,496 @@
+From 01ee140274f85c4fb3e153b39c0b320bb2f89ada Mon Sep 17 00:00:00 2001
+From: Aaron Boxer <Aaron Boxer>
+Date: Thu, 24 Sep 2020 11:11:18 -0400
+Subject: [PATCH 2/2] win32: Use GPrivate-managed display device context
+
+The document of [CreateDCA][1] says:
+
+> If lpszDriver or lpszDevice is DISPLAY, the thread that calls
+> CreateDC owns the HDC that is created. When this thread is
+> destroyed, the HDC is no longer valid. Thus, if you create the HDC
+> and pass it to another thread, then exit the first thread,
+> the second thread will not be able to use the HDC.
+
+So this change introduces GPrivate to fix potential problem.
+
+This also fixes the problem caused by accessing the global
+variable DC directly, which makes some early call to Pango functions
+fail.
+
+(e.g., failure of calling pango_win32_font_description_from_logfontw
+from _get_system_font_name in GTK.)
+
+[1]: https://docs.microsoft.com/windows/win32/api/wingdi/nf-wingdi-createdca
+---
+ pango/pangocairo-win32fontmap.c | 2 +-
+ pango/pangowin32-fontmap.c | 59 ++++++++++++++--------
+ pango/pangowin32-private.h | 4 +-
+ pango/pangowin32-shape.c | 2 +-
+ pango/pangowin32.c | 89 ++++++++++++++++++---------------
+ 5 files changed, 93 insertions(+), 63 deletions(-)
+
+diff --git a/pango/pangocairo-win32fontmap.c b/pango/pangocairo-win32fontmap.c
+index b58d16f6..94500fd6 100644
+--- a/pango/pangocairo-win32fontmap.c
++++ b/pango/pangocairo-win32fontmap.c
+@@ -121,5 +121,5 @@ static void
+ pango_cairo_win32_font_map_init (PangoCairoWin32FontMap *cwfontmap)
+ {
+ cwfontmap->serial = 1;
+- cwfontmap->dpi = GetDeviceCaps (pango_win32_get_dc (), LOGPIXELSY);
++ cwfontmap->dpi = GetDeviceCaps (_pango_win32_get_display_dc (), LOGPIXELSY);
+ }
+diff --git a/pango/pangowin32-fontmap.c b/pango/pangowin32-fontmap.c
+index afb8272f..eab44765 100644
+--- a/pango/pangowin32-fontmap.c
++++ b/pango/pangowin32-fontmap.c
+@@ -200,6 +200,12 @@ pango_win32_inner_enum_proc (LOGFONTW *lfp,
+ return 1;
+ }
+
++struct EnumProcData
++{
++ HDC hdc;
++ PangoWin32FontMap *font_map;
++};
++
+ static int CALLBACK
+ pango_win32_enum_proc (LOGFONTW *lfp,
+ NEWTEXTMETRICW *metrics,
+@@ -207,6 +213,7 @@ pango_win32_enum_proc (LOGFONTW *lfp,
+ LPARAM lParam)
+ {
+ LOGFONTW lf;
++ struct EnumProcData *data = (struct EnumProcData *) lParam;
+
+ PING (("%S: %lu %lx", lfp->lfFaceName, fontType, metrics->ntmFlags));
+
+@@ -216,9 +223,9 @@ pango_win32_enum_proc (LOGFONTW *lfp,
+ {
+ lf = *lfp;
+
+- EnumFontFamiliesExW (_pango_win32_hdc, &lf,
++ EnumFontFamiliesExW (data->hdc, &lf,
+ (FONTENUMPROCW) pango_win32_inner_enum_proc,
+- lParam, 0);
++ (LPARAM) data->font_map, 0);
+ }
+
+ return 1;
+@@ -725,6 +732,12 @@ static void
+ _pango_win32_font_map_init (PangoWin32FontMap *win32fontmap)
+ {
+ LOGFONTW logfont;
++ HDC hdc = _pango_win32_get_display_dc ();
++
++ struct EnumProcData enum_proc_data = {
++ .hdc = hdc,
++ .font_map = win32fontmap,
++ };
+
+ win32fontmap->families =
+ g_hash_table_new_full ((GHashFunc) case_insensitive_str_hash,
+@@ -738,9 +751,9 @@ _pango_win32_font_map_init (PangoWin32FontMap *win32fontmap)
+
+ memset (&logfont, 0, sizeof (logfont));
+ logfont.lfCharSet = DEFAULT_CHARSET;
+- EnumFontFamiliesExW (_pango_win32_hdc, &logfont,
++ EnumFontFamiliesExW (hdc, &logfont,
+ (FONTENUMPROCW) pango_win32_enum_proc,
+- (LPARAM) win32fontmap, 0);
++ (LPARAM) &enum_proc_data, 0);
+
+ g_hash_table_foreach (win32fontmap->families, synthesize_foreach, win32fontmap);
+
+@@ -749,7 +762,7 @@ _pango_win32_font_map_init (PangoWin32FontMap *win32fontmap)
+ create_standard_family (win32fontmap, "Serif");
+ create_standard_family (win32fontmap, "Monospace");
+
+- win32fontmap->resolution = (PANGO_SCALE / (double) GetDeviceCaps (_pango_win32_hdc, LOGPIXELSY)) * 72.0;
++ win32fontmap->resolution = (PANGO_SCALE / (double) GetDeviceCaps (hdc, LOGPIXELSY)) * 72.0;
+ }
+
+ static void
+@@ -802,7 +815,7 @@ _pango_win32_font_map_class_init (PangoWin32FontMapClass *class)
+ fontmap_class->list_families = pango_win32_font_map_list_families;
+ fontmap_class->shape_engine_type = PANGO_RENDER_TYPE_WIN32;
+
+- pango_win32_get_dc ();
++ _pango_win32_get_display_dc ();
+ }
+
+ /**
+@@ -1125,6 +1138,7 @@ get_family_nameA (const LOGFONTA *lfp)
+ {
+ HFONT hfont;
+ HFONT oldhfont;
++ HDC hdc;
+
+ struct name_header header;
+ struct name_record record;
+@@ -1155,17 +1169,19 @@ get_family_nameA (const LOGFONTA *lfp)
+ if ((hfont = CreateFontIndirect (lfp)) == NULL)
+ goto fail0;
+
+- if ((oldhfont = SelectObject (_pango_win32_hdc, hfont)) == NULL)
++ hdc = _pango_win32_get_display_dc ();
++
++ if ((oldhfont = SelectObject (hdc, hfont)) == NULL)
+ goto fail1;
+
+- if (!_pango_win32_get_name_header (_pango_win32_hdc, &header))
++ if (!_pango_win32_get_name_header (hdc, &header))
+ goto fail2;
+
+ PING (("%d name records", header.num_records));
+
+ for (i = 0; i < header.num_records; i++)
+ {
+- if (!_pango_win32_get_name_record (_pango_win32_hdc, i, &record))
++ if (!_pango_win32_get_name_record (hdc, i, &record))
+ goto fail2;
+
+ if ((record.name_id != 1 && record.name_id != 16) || record.string_length <= 0)
+@@ -1199,11 +1215,11 @@ get_family_nameA (const LOGFONTA *lfp)
+ else
+ goto fail2;
+
+- if (!_pango_win32_get_name_record (_pango_win32_hdc, name_ix, &record))
++ if (!_pango_win32_get_name_record (hdc, name_ix, &record))
+ goto fail2;
+
+ string = g_malloc (record.string_length + 1);
+- if (GetFontData (_pango_win32_hdc, NAME,
++ if (GetFontData (hdc, NAME,
+ header.string_storage_offset + record.string_offset,
+ string, record.string_length) != record.string_length)
+ goto fail2;
+@@ -1229,14 +1245,14 @@ get_family_nameA (const LOGFONTA *lfp)
+
+ PING (("%s", name));
+
+- SelectObject (_pango_win32_hdc, oldhfont);
++ SelectObject (hdc, oldhfont);
+ DeleteObject (hfont);
+
+ return name;
+
+ fail2:
+ g_free (string);
+- SelectObject (_pango_win32_hdc, oldhfont);
++ SelectObject (hdc, oldhfont);
+
+ fail1:
+ DeleteObject (hfont);
+@@ -1308,6 +1324,7 @@ get_family_nameW (const LOGFONTW *lfp)
+ {
+ HFONT hfont;
+ HFONT oldhfont;
++ HDC hdc;
+
+ struct name_header header;
+ struct name_record record;
+@@ -1338,17 +1355,19 @@ get_family_nameW (const LOGFONTW *lfp)
+ if ((hfont = CreateFontIndirectW (lfp)) == NULL)
+ goto fail0;
+
+- if ((oldhfont = SelectObject (_pango_win32_hdc, hfont)) == NULL)
++ hdc = _pango_win32_get_display_dc ();
++
++ if ((oldhfont = SelectObject (hdc, hfont)) == NULL)
+ goto fail1;
+
+- if (!_pango_win32_get_name_header (_pango_win32_hdc, &header))
++ if (!_pango_win32_get_name_header (hdc, &header))
+ goto fail2;
+
+ PING (("%d name records", header.num_records));
+
+ for (i = 0; i < header.num_records; i++)
+ {
+- if (!_pango_win32_get_name_record (_pango_win32_hdc, i, &record))
++ if (!_pango_win32_get_name_record (hdc, i, &record))
+ goto fail2;
+
+ if ((record.name_id != 1 && record.name_id != 16) || record.string_length <= 0)
+@@ -1382,11 +1401,11 @@ get_family_nameW (const LOGFONTW *lfp)
+ else
+ goto fail2;
+
+- if (!_pango_win32_get_name_record (_pango_win32_hdc, name_ix, &record))
++ if (!_pango_win32_get_name_record (hdc, name_ix, &record))
+ goto fail2;
+
+ string = g_malloc (record.string_length + 1);
+- if (GetFontData (_pango_win32_hdc, NAME,
++ if (GetFontData (hdc, NAME,
+ header.string_storage_offset + record.string_offset,
+ string, record.string_length) != record.string_length)
+ goto fail2;
+@@ -1412,14 +1431,14 @@ get_family_nameW (const LOGFONTW *lfp)
+
+ PING (("%s", name));
+
+- SelectObject (_pango_win32_hdc, oldhfont);
++ SelectObject (hdc, oldhfont);
+ DeleteObject (hfont);
+
+ return name;
+
+ fail2:
+ g_free (string);
+- SelectObject (_pango_win32_hdc, oldhfont);
++ SelectObject (hdc, oldhfont);
+
+ fail1:
+ DeleteObject (hfont);
+diff --git a/pango/pangowin32-private.h b/pango/pangowin32-private.h
+index 88e5655d..72cae50e 100644
+--- a/pango/pangowin32-private.h
++++ b/pango/pangowin32-private.h
+@@ -291,7 +291,9 @@ _pango_win32_shape (PangoFont *font,
+ const char *paragraph_text G_GNUC_UNUSED,
+ unsigned int paragraph_length G_GNUC_UNUSED);
+
+-extern HDC _pango_win32_hdc;
++_PANGO_EXTERN
++HDC _pango_win32_get_display_dc (void);
++
+ extern OSVERSIONINFO _pango_win32_os_version_info;
+ extern gboolean _pango_win32_debug;
+
+diff --git a/pango/pangowin32-shape.c b/pango/pangowin32-shape.c
+index aad0243e..36d43413 100644
+--- a/pango/pangowin32-shape.c
++++ b/pango/pangowin32-shape.c
+@@ -607,7 +607,7 @@ uniscribe_shape (PangoFont *font,
+ {
+ wchar_t *wtext;
+ long wlen;
+- HDC hdc = _pango_win32_hdc;
++ HDC hdc = _pango_win32_get_display_dc ();
+ gboolean retval = TRUE;
+
+ if (!pango_win32_font_select_font (font, hdc))
+diff --git a/pango/pangowin32.c b/pango/pangowin32.c
+index 630898e0..71204606 100644
+--- a/pango/pangowin32.c
++++ b/pango/pangowin32.c
+@@ -47,7 +47,6 @@
+ ((ch) >= 0x20000 && (ch) <= 0x2A6DF) || \
+ ((ch) >= 0x2F800 && (ch) <= 0x2FA1F))
+
+-HDC _pango_win32_hdc;
+ OSVERSIONINFO _pango_win32_os_version_info;
+ gboolean _pango_win32_debug = FALSE;
+
+@@ -143,24 +142,17 @@ _pango_win32_font_init (PangoWin32Font *win32font)
+ win32font->glyph_info = g_hash_table_new_full (NULL, NULL, NULL, g_free);
+ }
+
+-/**
+- * pango_win32_get_dc:
+- *
+- * Obtains a handle to the Windows device context that is used by Pango.
+- *
+- * Return value: A handle to the Windows device context that is used by Pango.
+- **/
++static GPrivate display_dc_key = G_PRIVATE_INIT ((GDestroyNotify) DeleteDC);
++
+ HDC
+-pango_win32_get_dc (void)
++_pango_win32_get_display_dc (void)
+ {
+- if (g_once_init_enter (&_pango_win32_hdc))
++ HDC hdc = g_private_get (&display_dc_key);
++
++ if (hdc == NULL)
+ {
+- HDC hdc = CreateDC ("DISPLAY", NULL, NULL, NULL);
+- memset (&_pango_win32_os_version_info, 0,
+- sizeof (_pango_win32_os_version_info));
+- _pango_win32_os_version_info.dwOSVersionInfoSize =
+- sizeof (OSVERSIONINFO);
+- GetVersionEx (&_pango_win32_os_version_info);
++ hdc = CreateDC ("DISPLAY", NULL, NULL, NULL);
++ g_private_set (&display_dc_key, hdc);
+
+ /* Also do some generic pangowin32 initialisations... this function
+ * is a suitable place for those as it is called from a couple
+@@ -170,10 +162,22 @@ pango_win32_get_dc (void)
+ if (getenv ("PANGO_WIN32_DEBUG") != NULL)
+ _pango_win32_debug = TRUE;
+ #endif
+- g_once_init_leave (&_pango_win32_hdc, hdc);
+ }
+
+- return _pango_win32_hdc;
++ return hdc;
++}
++
++/**
++ * pango_win32_get_dc:
++ *
++ * Obtains a handle to the Windows device context that is used by Pango.
++ *
++ * Return value: A handle to the Windows device context that is used by Pango.
++ **/
++HDC
++pango_win32_get_dc (void)
++{
++ return _pango_win32_get_display_dc ();
+ }
+
+ /**
+@@ -212,7 +216,7 @@ _pango_win32_font_class_init (PangoWin32FontClass *class)
+ class->done_font = pango_win32_font_real_done_font;
+ class->get_metrics_factor = pango_win32_font_real_get_metrics_factor;
+
+- pango_win32_get_dc ();
++ _pango_win32_get_display_dc ();
+ }
+
+ /**
+@@ -462,15 +466,14 @@ pango_win32_font_get_glyph_extents (PangoFont *font,
+
+ if (!info)
+ {
++ HDC hdc = _pango_win32_get_display_dc ();
+ info = g_new0 (PangoWin32GlyphInfo, 1);
+
+ memset (&gm, 0, sizeof (gm));
+
+ hfont = _pango_win32_font_get_hfont (font);
+- SelectObject (_pango_win32_hdc, hfont);
+- /* FIXME: (Alex) This constant reuse of _pango_win32_hdc is
+- not thread-safe */
+- res = GetGlyphOutlineA (_pango_win32_hdc,
++ SelectObject (hdc, hfont);
++ res = GetGlyphOutlineA (hdc,
+ glyph_index,
+ GGO_METRICS | GGO_GLYPH_INDEX,
+ &gm,
+@@ -492,7 +495,7 @@ pango_win32_font_get_glyph_extents (PangoFont *font,
+ info->ink_rect.y = - PANGO_SCALE * gm.gmptGlyphOrigin.y;
+ info->ink_rect.height = PANGO_SCALE * gm.gmBlackBoxY;
+
+- GetTextMetrics (_pango_win32_hdc, &tm);
++ GetTextMetrics (hdc, &tm);
+ info->logical_rect.x = 0;
+ info->logical_rect.width = PANGO_SCALE * gm.gmCellIncX;
+ info->logical_rect.y = - PANGO_SCALE * tm.tmAscent;
+@@ -569,9 +572,10 @@ pango_win32_font_get_metrics (PangoFont *font,
+ {
+ PangoCoverage *coverage;
+ TEXTMETRIC tm;
++ HDC hdc = _pango_win32_get_display_dc ();
+
+- SelectObject (_pango_win32_hdc, hfont);
+- GetTextMetrics (_pango_win32_hdc, &tm);
++ SelectObject (hdc, hfont);
++ GetTextMetrics (hdc, &tm);
+
+ metrics->ascent = tm.tmAscent * PANGO_SCALE;
+ metrics->descent = tm.tmDescent * PANGO_SCALE;
+@@ -1489,19 +1493,20 @@ font_get_cmap (PangoFont *font)
+ {
+ PangoWin32Font *win32font = (PangoWin32Font *)font;
+ gpointer cmap;
++ HDC hdc = _pango_win32_get_display_dc ();
+
+ if (win32font->win32face->cmap)
+ return win32font->win32face->cmap;
+
+- pango_win32_font_select_font (font, _pango_win32_hdc);
++ pango_win32_font_select_font (font, hdc);
+
+ /* Prefer the format 12 cmap */
+- if ((cmap = get_format_12_cmap (_pango_win32_hdc)) != NULL)
++ if ((cmap = get_format_12_cmap (hdc)) != NULL)
+ {
+ win32font->win32face->cmap_format = 12;
+ win32font->win32face->cmap = cmap;
+ }
+- else if ((cmap = get_format_4_cmap (_pango_win32_hdc)) != NULL)
++ else if ((cmap = get_format_4_cmap (hdc)) != NULL)
+ {
+ win32font->win32face->cmap_format = 4;
+ win32font->win32face->cmap = cmap;
+@@ -1519,11 +1524,12 @@ pango_win32_font_get_type1_glyph_index (PangoFont *font,
+ wchar_t unicode[2];
+ WORD glyph_index;
+ gint32 res;
++ HDC hdc = _pango_win32_get_display_dc ();
+
+ unicode[0] = wc;
+ unicode[1] = 0;
+- pango_win32_font_select_font (font, _pango_win32_hdc);
+- res = GetGlyphIndicesW (_pango_win32_hdc, unicode, 1, &glyph_index, 0);
++ pango_win32_font_select_font (font, hdc);
++ res = GetGlyphIndicesW (hdc, unicode, 1, &glyph_index, 0);
+ pango_win32_font_done_font (font);
+
+ if (res == 1)
+@@ -1656,24 +1662,25 @@ font_has_name_in (PangoFont *font,
+ struct name_record record;
+ gint i;
+ gboolean retval = FALSE;
++ HDC hdc = _pango_win32_get_display_dc ();
+
+ if (cjkv == PANGO_WIN32_COVERAGE_UNSPEC)
+ return TRUE;
+
+ hfont = _pango_win32_font_get_hfont (font);
+- oldhfont = SelectObject (_pango_win32_hdc, hfont);
++ oldhfont = SelectObject (hdc, hfont);
+
+- if (!_pango_win32_get_name_header (_pango_win32_hdc, &header))
++ if (!_pango_win32_get_name_header (hdc, &header))
+ {
+- SelectObject (_pango_win32_hdc, oldhfont);
++ SelectObject (hdc, oldhfont);
+ return FALSE;
+ }
+
+ for (i = 0; i < header.num_records; i++)
+ {
+- if (!_pango_win32_get_name_record (_pango_win32_hdc, i, &record))
++ if (!_pango_win32_get_name_record (hdc, i, &record))
+ {
+- SelectObject (_pango_win32_hdc, oldhfont);
++ SelectObject (hdc, oldhfont);
+ return FALSE;
+ }
+
+@@ -1705,7 +1712,7 @@ font_has_name_in (PangoFont *font,
+ }
+ }
+
+- SelectObject (_pango_win32_hdc, oldhfont);
++ SelectObject (hdc, oldhfont);
+ return retval;
+ }
+
+@@ -1718,14 +1725,16 @@ pango_win32_font_calc_type1_coverage (PangoFont *font,
+ gint32 res;
+ guint32 ch;
+ guint32 i;
++ HDC hdc = _pango_win32_get_display_dc ();
++
+
+- pango_win32_font_select_font (font, _pango_win32_hdc);
+- res = GetFontUnicodeRanges(_pango_win32_hdc, NULL);
++ pango_win32_font_select_font (font, hdc);
++ res = GetFontUnicodeRanges(hdc, NULL);
+ if (res == 0)
+ goto fail1;
+
+ glyph_set = g_malloc (res);
+- res = GetFontUnicodeRanges(_pango_win32_hdc, glyph_set);
++ res = GetFontUnicodeRanges(hdc, glyph_set);
+ if (res == 0)
+ goto fail2;
+
+--
+2.17.1
+