summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog38
-rw-r--r--pango/fonts.c10
-rw-r--r--pango/pangoatsui.c8
-rw-r--r--pango/pangocairo-font.c17
-rw-r--r--pango/pangocairo-win32font.c5
-rw-r--r--pango/pangofc-font.c9
-rw-r--r--pango/pangofc-fontmap.c9
-rw-r--r--pango/pangowin32-fontmap.c4
-rw-r--r--pango/pangowin32.c4
-rw-r--r--pango/pangox-fontmap.c1
-rw-r--r--pango/pangox.c8
11 files changed, 93 insertions, 20 deletions
diff --git a/ChangeLog b/ChangeLog
index 8fb9486f..4f9b5d38 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,41 @@
+2008-08-22 Behdad Esfahbod <behdad@gnome.org>
+
+ Bug 143542 – PangoFT2Fontmap leak
+
+ * pango/fonts.c:
+ * pango/pangoatsui.c (pango_atsui_font_finalize),
+ (_pango_atsui_font_set_font_map):
+ * pango/pangocairo-font.c (_pango_cairo_font_get_metrics),
+ (_pango_cairo_font_private_get_hex_box_info):
+ * pango/pangocairo-win32font.c (_pango_cairo_win32_font_new):
+ * pango/pangofc-font.c (pango_fc_font_get_metrics):
+ * pango/pangofc-fontmap.c (pango_fc_font_map_add),
+ (_pango_fc_font_map_remove), (cleanup_font):
+ * pango/pangowin32-fontmap.c (pango_win32_font_neww),
+ (pango_win32_font_map_real_find_font):
+ * pango/pangowin32.c (pango_win32_font_finalize):
+ * pango/pangox-fontmap.c (pango_x_font_map_load_font):
+ * pango/pangox.c (pango_x_font_new), (pango_x_font_finalize):
+ Make the reference the font->fontmap reference weak.
+
+ The code for setting the reference must look like this:
+
+ g_assert (font->fontmap == NULL);
+ font->fontmap = (PangoFontMap *) fontmap;
+ g_object_add_weak_pointer (G_OBJECT (font->fontmap), (gpointer *) (gpointer) &font->fontmap);
+
+ And releasing it like:
+
+ g_assert (font->fontmap != NULL);
+ g_object_remove_weak_pointer (G_OBJECT (font->fontmap), (gpointer *) (gpointer) &font->fontmap);
+ font->fontmap = NULL;
+
+ I have converted all fontmaps. The win32 and atsui ones can
+ use some simple testing.
+
+ The PangoFc fonts actually don't need the weakref as the fontmap
+ already provides a similar link by itself.
+
2008-08-20 Murray Cumming <murrayc@murrayc.com>
* pango/pango-language.c: pango_language_get_scripts(): Fix a
diff --git a/pango/fonts.c b/pango/fonts.c
index efb989bb..2f997035 100644
--- a/pango/fonts.c
+++ b/pango/fonts.c
@@ -1414,10 +1414,18 @@ pango_font_get_metrics (PangoFont *font,
/**
* pango_font_get_font_map:
- * @font: a #PangoFont
+ * @font: a #PangoFont, or %NULL
*
* Gets the font map for which the font was created.
*
+ * Note that the font maintains a <firstterm>weak</firstterm> reference
+ * to the font map, so if all references to font map are dropped, the font
+ * map will be finalized even if there are fonts created with the font
+ * map that are still alive. In that case this function will return %NULL.
+ * It is the responsibility of the user to ensure that the font map is kept
+ * alive. In most uses this is not an issue as a #PangoContext holds
+ * a reference to the font map.
+ *
* Return value: the #PangoFontMap for the font, or %NULL if @font is %NULL.
*
* Since: 1.10
diff --git a/pango/pangoatsui.c b/pango/pangoatsui.c
index 58a4569a..a8c026e6 100644
--- a/pango/pangoatsui.c
+++ b/pango/pangoatsui.c
@@ -45,7 +45,9 @@ pango_atsui_font_finalize (GObject *object)
pango_font_description_free (priv->desc);
- g_object_unref (priv->fontmap);
+ g_assert (priv->fontmap != NULL);
+ g_object_remove_weak_pointer (G_OBJECT (priv->fontmap), (gpointer *) (gpointer) &priv->fontmap);
+ priv->fontmap = NULL;
G_OBJECT_CLASS (pango_atsui_font_parent_class)->finalize (object);
}
@@ -135,8 +137,8 @@ _pango_atsui_font_set_font_map (PangoATSUIFont *font,
PangoATSUIFontPrivate *priv = font->priv;
g_assert (priv->fontmap == NULL);
-
- priv->fontmap = g_object_ref (fontmap);
+ priv->fontmap = (PangoFontMap *) fontmap;
+ g_object_add_weak_pointer (G_OBJECT (prev->fontmap), (gpointer *) (gpointer) &priv->fontmap);
}
void
diff --git a/pango/pangocairo-font.c b/pango/pangocairo-font.c
index 0ce3cafc..15757eee 100644
--- a/pango/pangocairo-font.c
+++ b/pango/pangocairo-font.c
@@ -223,17 +223,24 @@ _pango_cairo_font_get_metrics (PangoFont *font,
if (!tmp_list)
{
+ PangoFontMap *fontmap;
PangoContext *context;
cairo_font_options_t *font_options;
int height, shift;
+ /* XXX this is racy. need a ref'ing getter... */
+ fontmap = pango_font_get_font_map (font);
+ if (!fontmap)
+ return pango_font_metrics_new ();
+ fontmap = g_object_ref (fontmap);
+
info = g_slice_new0 (PangoCairoFontMetricsInfo);
cf_priv->metrics_by_lang = g_slist_prepend (cf_priv->metrics_by_lang, info);
info->sample_str = sample_str;
- context = pango_font_map_create_context (pango_font_get_font_map (font));
+ context = pango_font_map_create_context (fontmap);
pango_context_set_language (context, language);
font_options = cairo_font_options_create ();
cairo_scaled_font_get_font_options (_pango_cairo_font_private_get_scaled_font (cf_priv), font_options);
@@ -271,6 +278,7 @@ _pango_cairo_font_get_metrics (PangoFont *font,
info->metrics->ascent = height - info->metrics->descent;
g_object_unref (context);
+ g_object_unref (fontmap);
}
return pango_font_metrics_ref (info->metrics);
@@ -356,10 +364,14 @@ _pango_cairo_font_private_get_hex_box_info (PangoCairoFontPrivate *cf_priv)
/* create mini_font description */
{
- PangoContext *context;
PangoFontMap *fontmap;
+ PangoContext *context;
+ /* XXX this is racy. need a ref'ing getter... */
fontmap = pango_font_get_font_map ((PangoFont *)cf_priv->cfont);
+ if (!fontmap)
+ return NULL;
+ fontmap = g_object_ref (fontmap);
/* we inherit most font properties for the mini font. just
* change family and size. means, you get bold hex digits
@@ -396,6 +408,7 @@ _pango_cairo_font_private_get_hex_box_info (PangoCairoFontPrivate *cf_priv)
mini_font = pango_font_map_load_font (fontmap, context, desc);
g_object_unref (context);
+ g_object_unref (fontmap);
}
pango_font_description_free (desc);
diff --git a/pango/pangocairo-win32font.c b/pango/pangocairo-win32font.c
index 6cfe29ed..4f0ec3d7 100644
--- a/pango/pangocairo-win32font.c
+++ b/pango/pangocairo-win32font.c
@@ -288,8 +288,9 @@ _pango_cairo_win32_font_new (PangoCairoWin32FontMap *cwfontmap,
cwfont = g_object_new (PANGO_TYPE_CAIRO_WIN32_FONT, NULL);
win32font = PANGO_WIN32_FONT (cwfont);
- win32font->fontmap = PANGO_FONT_MAP (cwfontmap);
- g_object_ref (cwfontmap);
+ g_assert (win32font->fontmap == NULL);
+ win32font->fontmap = (PangoFontMap *) cwfontmap;
+ g_object_add_weak_pointer (G_OBJECT (win32font->fontmap), (gpointer *) (gpointer) &win32font->fontmap);
win32font->win32face = face;
diff --git a/pango/pangofc-font.c b/pango/pangofc-font.c
index 8bd23e2b..9acd75d6 100644
--- a/pango/pangofc-font.c
+++ b/pango/pangofc-font.c
@@ -529,10 +529,14 @@ pango_fc_font_get_metrics (PangoFont *font,
if (!tmp_list)
{
+ PangoFontMap *fontmap;
PangoContext *context;
- if (!fcfont->fontmap)
+ /* XXX this is racy. because weakref's are racy... */
+ fontmap = fcfont->fontmap;
+ if (!fontmap)
return pango_font_metrics_new ();
+ fontmap = g_object_ref (fontmap);
info = g_slice_new0 (PangoFcMetricsInfo);
@@ -541,12 +545,13 @@ pango_fc_font_get_metrics (PangoFont *font,
info->sample_str = sample_str;
- context = pango_font_map_create_context (fcfont->fontmap);
+ context = pango_font_map_create_context (fontmap);
pango_context_set_language (context, language);
info->metrics = pango_fc_font_create_metrics_for_context (fcfont, context);
g_object_unref (context);
+ g_object_unref (fontmap);
}
return pango_font_metrics_ref (info->metrics);
diff --git a/pango/pangofc-fontmap.c b/pango/pangofc-fontmap.c
index e3963e84..0bc21b96 100644
--- a/pango/pangofc-fontmap.c
+++ b/pango/pangofc-fontmap.c
@@ -554,8 +554,11 @@ pango_fc_font_map_add (PangoFcFontMap *fcfontmap,
FontHashKey *key_copy;
g_assert (fcfont->fontmap == NULL);
-
- fcfont->fontmap = g_object_ref (fcfontmap);
+ fcfont->fontmap = (PangoFontMap *) fcfontmap;
+ /* In other fontmaps we add a weak pointer on ->fontmap so the
+ * field is unset when fontmap is finalized. We don't need it
+ * here though as PangoFcFontMap already cleans up fcfont->fontmap
+ * as part of it's caching scheme. */
font_hash_key_for_context (fcfontmap, context, &key);
key.pattern = fcfont->font_pattern;
@@ -597,7 +600,6 @@ _pango_fc_font_map_remove (PangoFcFontMap *fcfontmap,
g_hash_table_remove (priv->font_hash, &key);
fcfont->fontmap = NULL;
_pango_fc_font_set_context_key (fcfont, NULL);
- g_object_unref (fcfontmap);
}
static PangoFcFamily *
@@ -1435,7 +1437,6 @@ cleanup_font (gpointer key,
{
_pango_fc_font_shutdown (fcfont);
- g_object_unref (fcfont->fontmap);
fcfont->fontmap = NULL;
}
diff --git a/pango/pangowin32-fontmap.c b/pango/pangowin32-fontmap.c
index 055f99bd..28e0ebd0 100644
--- a/pango/pangowin32-fontmap.c
+++ b/pango/pangowin32-fontmap.c
@@ -667,8 +667,9 @@ pango_win32_font_neww (PangoFontMap *fontmap,
result = (PangoWin32Font *)g_object_new (PANGO_TYPE_WIN32_FONT, NULL);
+ g_assert (result->fontmap == NULL);
result->fontmap = fontmap;
- g_object_ref (fontmap);
+ g_object_add_weak_pointer (G_OBJECT (result->fontmap), (gpointer *) (gpointer) &result->fontmap);
result->size = size;
_pango_win32_make_matching_logfontw (fontmap, lfp, size, &result->logfontw);
@@ -713,7 +714,6 @@ pango_win32_font_map_real_find_font (PangoWin32FontMap *win32fontmap,
if (!win32font)
return NULL;
- win32font->fontmap = fontmap;
win32font->win32face = face;
face->cached_fonts = g_slist_prepend (face->cached_fonts, win32font);
diff --git a/pango/pangowin32.c b/pango/pangowin32.c
index d2e8ad5f..1f8c1d25 100644
--- a/pango/pangowin32.c
+++ b/pango/pangowin32.c
@@ -835,7 +835,9 @@ pango_win32_font_finalize (GObject *object)
g_hash_table_destroy (win32font->glyph_info);
- g_object_unref (win32font->fontmap);
+ g_assert (win32font->fontmap != NULL);
+ g_object_remove_weak_pointer (G_OBJECT (win32font->fontmap), (gpointer *) (gpointer) &win32font->fontmap);
+ win32font->fontmap = NULL;
G_OBJECT_CLASS (_pango_win32_font_parent_class)->finalize (object);
}
diff --git a/pango/pangox-fontmap.c b/pango/pangox-fontmap.c
index 716374ba..1cfc0aec 100644
--- a/pango/pangox-fontmap.c
+++ b/pango/pangox-fontmap.c
@@ -519,7 +519,6 @@ pango_x_font_map_load_font (PangoFontMap *fontmap,
{
PangoXFont *xfont = pango_x_font_new (fontmap, best_match->xlfd, size);
- xfont->fontmap = fontmap;
xfont->xface = best_match;
best_match->cached_fonts = g_slist_prepend (best_match->cached_fonts, xfont);
diff --git a/pango/pangox.c b/pango/pangox.c
index 92bedff8..b542f852 100644
--- a/pango/pangox.c
+++ b/pango/pangox.c
@@ -298,8 +298,10 @@ pango_x_font_new (PangoFontMap *fontmap, const char *spec, int size)
result = g_object_new (PANGO_TYPE_X_FONT, NULL);
+ g_assert (result->fontmap == NULL);
result->fontmap = fontmap;
- g_object_ref (fontmap);
+ g_object_add_weak_pointer (G_OBJECT (result->fontmap), (gpointer *) (gpointer) &result->fontmap);
+
result->display = pango_x_fontmap_get_display (fontmap);
result->fonts = g_strsplit(spec, ",", -1);
@@ -1318,7 +1320,9 @@ pango_x_font_finalize (GObject *object)
if (xfont->xface)
pango_x_face_remove (xfont->xface, (PangoFont *)xfont);
- g_object_unref (xfont->fontmap);
+ g_assert (xfont->fontmap != NULL);
+ g_object_remove_weak_pointer (G_OBJECT (xfont->fontmap), (gpointer *) (gpointer) &xfont->fontmap);
+ xfont->fontmap = NULL;
g_strfreev (xfont->fonts);