diff options
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | pango/pangoxft-font.c | 17 | ||||
-rw-r--r-- | pango/pangoxft-private.h | 8 | ||||
-rw-r--r-- | pango/pangoxft-render.c | 64 |
4 files changed, 72 insertions, 22 deletions
@@ -1,5 +1,10 @@ 2006-02-02 Behdad Esfahbod <behdad@gnome.org> + * pango/pangoxft-font.c, pango/pangoxft-render.c: Guard Xft + backend agains crashes too. + +2006-02-02 Behdad Esfahbod <behdad@gnome.org> + * modules/arabic/arabic-fc.c, modules/basic/basic-atsui.c, modules/basic/basic-fc.c, modules/basic/basic-win32.c, modules/basic/basic-x.c, modules/hangul/hangul-fc.c, diff --git a/pango/pangoxft-font.c b/pango/pangoxft-font.c index c7004c0c..f67d7b5b 100644 --- a/pango/pangoxft-font.c +++ b/pango/pangoxft-font.c @@ -27,6 +27,8 @@ #include "pangoxft-private.h" #include "pangofc-private.h" +PangoXftWarningHistory _pango_xft_warning_history = { FALSE }; + #define PANGO_XFT_FONT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PANGO_TYPE_XFT_FONT, PangoXftFontClass)) #define PANGO_XFT_IS_FONT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PANGO_TYPE_XFT_FONT)) #define PANGO_XFT_FONT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PANGO_TYPE_XFT_FONT, PangoXftFontClass)) @@ -121,7 +123,8 @@ _pango_xft_font_get_mini_font (PangoXftFont *xfont) { PangoFcFont *fcfont = (PangoFcFont *)xfont; - g_assert (fcfont->fontmap); + if (!fcfont || !fcfont->fontmap) + return NULL; if (!xfont->mini_font) { @@ -150,6 +153,8 @@ _pango_xft_font_get_mini_font (PangoXftFont *xfont) pango_font_description_set_size (desc, new_size); xfont->mini_font = pango_font_map_load_font (fcfont->fontmap, context, desc); + if (!xfont->mini_font) + return NULL; pango_font_description_free (desc); g_object_unref (context); @@ -474,7 +479,15 @@ pango_xft_font_real_shutdown (PangoFcFont *fcfont) XftFont * pango_xft_font_get_font (PangoFont *font) { - g_return_val_if_fail (PANGO_XFT_IS_FONT (font), NULL); + if (G_UNLIKELY (!PANGO_XFT_IS_FONT (font))) + { + if (!_pango_xft_warning_history.get_font) + { + _pango_xft_warning_history.get_font = TRUE; + g_critical ("pango_xft_font_get_font called with font == NULL, expect ugly output"); + } + return NULL; + } return xft_font_get_font (font); } diff --git a/pango/pangoxft-private.h b/pango/pangoxft-private.h index 1a00860a..82e57da7 100644 --- a/pango/pangoxft-private.h +++ b/pango/pangoxft-private.h @@ -55,6 +55,14 @@ PangoRenderer *_pango_xft_font_map_get_renderer (PangoXftFontMap *xftfontmap); PangoFont *_pango_xft_font_get_mini_font (PangoXftFont *xfont); +typedef struct _PangoXftWarningHistory PangoXftWarningHistory; + +struct _PangoXftWarningHistory { + guint get_font : 1; +}; + +extern PangoXftWarningHistory _pango_xft_warning_history; + G_END_DECLS #endif /* __PANGOXFT_PRIVATE_H__ */ diff --git a/pango/pangoxft-render.c b/pango/pangoxft-render.c index 3e089bdd..d95bce65 100644 --- a/pango/pangoxft-render.c +++ b/pango/pangoxft-render.c @@ -22,6 +22,7 @@ #include <config.h> #include <math.h> +#include "pango-engine-private.h" #include "pangoxft-render.h" #include "pangoxft-private.h" @@ -297,20 +298,20 @@ box_in_bounds (PangoRenderer *renderer, static void draw_box (PangoRenderer *renderer, - PangoXftFont *xfont, + gint line_width, gint x, gint y, gint width, gint height) { pango_renderer_draw_rectangle (renderer, PANGO_RENDER_PART_FOREGROUND, - x, y, width, xfont->mini_pad); + x, y, width, line_width); pango_renderer_draw_rectangle (renderer, PANGO_RENDER_PART_FOREGROUND, - x, y + xfont->mini_pad, xfont->mini_pad, height - xfont->mini_pad * 2); + x, y + line_width, line_width, height - line_width * 2); pango_renderer_draw_rectangle (renderer, PANGO_RENDER_PART_FOREGROUND, - x + width - xfont->mini_pad, y + xfont->mini_pad, xfont->mini_pad, height - xfont->mini_pad * 2); + x + width - line_width, y + line_width, line_width, height - line_width * 2); pango_renderer_draw_rectangle (renderer, PANGO_RENDER_PART_FOREGROUND, - x, y + height - xfont->mini_pad, width, xfont->mini_pad); + x, y + height - line_width, width, line_width); } static void @@ -326,7 +327,31 @@ pango_xft_renderer_draw_glyphs (PangoRenderer *renderer, int i; int x_off = 0; - if (!fcfont->fontmap) /* Display closed */ + if (!fcfont) + { + for (i=0; i<glyphs->num_glyphs; i++) + { + PangoGlyph glyph = glyphs->glyphs[i].glyph; + int glyph_x = x + x_off + glyphs->glyphs[i].geometry.x_offset; + int glyph_y = y + glyphs->glyphs[i].geometry.y_offset; + + if (glyph != PANGO_GLYPH_NULL && glyph & PANGO_GLYPH_UNKNOWN_FLAG) + { + int x = glyph_x + PANGO_SCALE; + int y = glyph_y + PANGO_SCALE; + int width = PANGO_SCALE * (PANGO_UNKNOWN_GLYPH_WIDTH - 2); + int height = PANGO_SCALE * (PANGO_UNKNOWN_GLYPH_HEIGHT - 2); + + if (box_in_bounds (renderer, x, y, width, height)) + draw_box (renderer, PANGO_SCALE, x, y, width, height); + } + + x_off += glyphs->glyphs[i].geometry.width; + } + return; + } + + if (!fcfont->fontmap) /* Display closed */ return; for (i=0; i<glyphs->num_glyphs; i++) @@ -359,23 +384,23 @@ pango_xft_renderer_draw_glyphs (PangoRenderer *renderer, xs[2] = xs[1] + xfont->mini_width + xfont->mini_pad; xs[3] = xs[2] + xfont->mini_width + xfont->mini_pad; - if (glyph > 0xffff) - { - cols = 3; - g_snprintf (buf, sizeof(buf), "%06X", glyph); - } - else - { - cols = 2; - g_snprintf (buf, sizeof(buf), "%04X", glyph); - } + if (glyph > 0xffff) + { + cols = 3; + g_snprintf (buf, sizeof(buf), "%06X", glyph); + } + else + { + cols = 2; + g_snprintf (buf, sizeof(buf), "%04X", glyph); + } if (box_in_bounds (renderer, xs[0], ys[0], xfont->mini_width * cols + xfont->mini_pad * (2 * cols + 1), xfont->mini_height * 2 + xfont->mini_pad * 5)) { - draw_box (renderer, xfont, + draw_box (renderer, xfont->mini_pad, xs[0], ys[0], xfont->mini_width * cols + xfont->mini_pad * (2 * cols + 1), xfont->mini_height * 2 + xfont->mini_pad * 5); @@ -391,10 +416,9 @@ pango_xft_renderer_draw_glyphs (PangoRenderer *renderer, } } } - else if (glyph) + else { - draw_glyph (renderer, font, - glyph, glyph_x, glyph_y); + draw_glyph (renderer, font, glyph, glyph_x, glyph_y); } } |