summaryrefslogtreecommitdiff
path: root/pango/pangowin32.c
diff options
context:
space:
mode:
authorYongsu Park <pcpenpal@gmail.com>2020-05-19 09:35:43 +0000
committerChun-wei Fan <fanc999@yahoo.com.tw>2020-05-19 09:35:43 +0000
commitf59acff3b08d60f1d3d3469efd6d603f707bc07f (patch)
tree9e2e6f2b7af5536c63e4af0d119a8f262f6aeb53 /pango/pangowin32.c
parent2a773323f1f7b5510ee0de7a1ea0ac8bec0e05d4 (diff)
downloadpango-f59acff3b08d60f1d3d3469efd6d603f707bc07f.tar.gz
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
Diffstat (limited to 'pango/pangowin32.c')
-rw-r--r--pango/pangowin32.c52
1 files changed, 33 insertions, 19 deletions
diff --git a/pango/pangowin32.c b/pango/pangowin32.c
index 737cfa14..8849d4af 100644
--- a/pango/pangowin32.c
+++ b/pango/pangowin32.c
@@ -43,7 +43,6 @@
#define MAX_FREED_FONTS 256
-HDC _pango_win32_hdc;
gboolean _pango_win32_debug = FALSE;
static void pango_win32_font_dispose (GObject *object);
@@ -134,19 +133,21 @@ _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);
+ hdc = CreateDC ("DISPLAY", NULL, NULL, NULL);
+
+ if (G_UNLIKELY (hdc == NULL))
+ g_warning ("CreateDC() failed");
+
+ 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
@@ -156,10 +157,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 ();
}
/**
@@ -198,7 +211,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 ();
}
/**
@@ -448,7 +461,7 @@ pango_win32_font_get_glyph_extents (PangoFont *font,
if (!info)
{
- HDC hdc = pango_win32_get_dc ();
+ HDC hdc = _pango_win32_get_display_dc ();
info = g_new0 (PangoWin32GlyphInfo, 1);
@@ -478,7 +491,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;
@@ -555,9 +568,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;
@@ -1215,7 +1229,7 @@ hfont_reference_table (hb_face_t *face, hb_tag_t tag, void *user_data)
DWORD size;
/* We have a common DC for our PangoWin32Font, so let's just use it */
- hdc = pango_win32_get_dc ();
+ hdc = _pango_win32_get_display_dc ();
hfont = (HFONT) user_data;
/* we want to restore things, just to be safe */