[cairo] Problem with bitmap fonts
Behdad Esfahbod
behdad at cs.toronto.edu
Wed Jan 25 17:12:33 PST 2006
Hi,
Trying to fix some of the "pango+cairo crashes" bugs led me to
this problem:
If a bitmap font has a 0x0 glyphs, the current
cairo-ft-font.c:_get_bitmap_surface returns a NULL surface:
- if (width * height == 0) {
- if (own_buffer && bitmap->buffer)
- free (bitmap->buffer);
-
- *surface = NULL;
- } else {
which indeed crashes in the calling function immediately. So I
first fixed that by fixing the calling function. This is the
first patch attached.
But seems like (at least) the xlib backend expects non-NULL glyph
surfaces:
(gdb) f 0
#0 0x00477e66 in _cairo_xlib_surface_add_glyph (dpy=0x9ef1878, scaled_font=0xa1d0238,
scaled_glyph=0xa1d4518) at cairo-xlib-surface.c:2121
2121 glyph_info.x = -(int) glyph_surface->base.device_x_offset;
So I backed up and removed the special case for 0x0 glyphs.
Everything seems to be fine now. That's the second patch
attached. I think it can be committed (with some format change
maybe), as 0x0 glyphs are not common enough to try to save a 0x0
surface for them...
Both patches fix another problem, _render_glyph_bitmap should
check the status returned by _get_bitmap_surface.
Cheers,
--behdad
http://behdad.org/
"Commandment Three says Do Not Kill, Amendment Two says Blood Will Spill"
-- Dan Bern, "New American Language"
-------------- next part --------------
Index: src/cairo-ft-font.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-ft-font.c,v
retrieving revision 1.115
diff -u -p -r1.115 cairo-ft-font.c
--- src/cairo-ft-font.c 21 Dec 2005 16:19:47 -0000 1.115
+++ src/cairo-ft-font.c 26 Jan 2006 01:01:58 -0000
@@ -699,7 +699,7 @@ _native_byte_order_lsb (void)
return *((char *) &x) == 1;
}
-/* Fills in val->image with an image surface created from @bitmap
+/* Fills in *surface with an image surface created from @bitmap
*/
static cairo_status_t
_get_bitmap_surface (FT_Bitmap *bitmap,
@@ -892,13 +892,15 @@ _get_bitmap_surface (FT_Bitmap *bi
width, height, stride);
if ((*surface)->base.status) {
free (data);
+ cairo_surface_destory (*surface);
+ *surface = NULL;
return CAIRO_STATUS_NO_MEMORY;
}
if (subpixel)
pixman_image_set_component_alpha ((*surface)->pixman_image, TRUE);
- _cairo_image_surface_assume_ownership_of_data ((*surface));
+ _cairo_image_surface_assume_ownership_of_data (*surface);
}
return CAIRO_STATUS_SUCCESS;
@@ -1074,15 +1076,19 @@ _render_glyph_bitmap (FT_Face fac
if (error)
return CAIRO_STATUS_NO_MEMORY;
- _get_bitmap_surface (&glyphslot->bitmap, FALSE, font_options, surface);
+ status = _get_bitmap_surface (&glyphslot->bitmap, FALSE, font_options, surface);
+ if (status)
+ return status;
/*
* Note: the font's coordinate system is upside down from ours, so the
* Y coordinate of the control box needs to be negated.
*/
- (*surface)->base.device_x_offset = glyphslot->bitmap_left;
- (*surface)->base.device_y_offset = -glyphslot->bitmap_top;
+ if (*surface) {
+ (*surface)->base.device_x_offset = glyphslot->bitmap_left;
+ (*surface)->base.device_y_offset = -glyphslot->bitmap_top;
+ }
return status;
}
More information about the cairo
mailing list