[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