rpms/cairo/devel cairo-1.1.2-XRenderAddGlyphs-4705.patch, NONE, 1.1 cairo.spec, 1.36, 1.37

fedora-cvs-commits at redhat.com fedora-cvs-commits at redhat.com
Fri Apr 28 15:18:27 UTC 2006


Author: cworth

Update of /cvs/dist/rpms/cairo/devel
In directory cvs.devel.redhat.com:/tmp/cvs-serv18703

Modified Files:
	cairo.spec 
Added Files:
	cairo-1.1.2-XRenderAddGlyphs-4705.patch 
Log Message:
Add cairo-1.1.2-XRenderAddGlyphs-4705.patch

cairo-1.1.2-XRenderAddGlyphs-4705.patch:
 cairo-xlib-surface.c |  191 ++++++++++++++++++++++++++++++++++++---------------
 1 files changed, 138 insertions(+), 53 deletions(-)

--- NEW FILE cairo-1.1.2-XRenderAddGlyphs-4705.patch ---
commit 046cb653e0cbecf19db93a38dd8765fa813b24d9
Author: Jinghua Luo <sunmoon1997 at gmail.com>
Date:   Fri Apr 28 08:10:26 2006 -0700

    Suggested patch to fix bug #4705
    
    https://bugs.freedesktop.org/show_bug.cgi?id=4705

diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index 0f195bf..3032904 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -2006,38 +2006,88 @@ cairo_xlib_surface_set_drawable (cairo_s
     surface->height = height;
 }
 
-typedef struct _cairo_xlib_surface_font_private {
-    Display		*dpy;
+#define GLYPH_INFO_MAX (3)
+typedef struct _cairo_xlib_font_glyph_info {
     GlyphSet		glyphset;
     XRenderPictFormat	*format;
+} cairo_xlib_font_glyph_info_t;
+
+typedef struct _cairo_xlib_surface_font_private {
+    Display		         *dpy;
+    cairo_xlib_font_glyph_info_t glyph_info[GLYPH_INFO_MAX];
+    int                          num_formats;
 } cairo_xlib_surface_font_private_t;
 
 static cairo_status_t
 _cairo_xlib_surface_font_init (Display		    *dpy,
-			       cairo_scaled_font_t  *scaled_font,
-			       cairo_format_t	     format)
+			       cairo_scaled_font_t  *scaled_font)
 {
     cairo_xlib_surface_font_private_t	*font_private;
+    int i;
 
     font_private = malloc (sizeof (cairo_xlib_surface_font_private_t));
     if (!font_private)
 	return CAIRO_STATUS_NO_MEMORY;
 
+    font_private->num_formats = 0;
+    for (i = 0; i < GLYPH_INFO_MAX; i ++) {
+	font_private->glyph_info[i].format = NULL;
+	font_private->glyph_info[i].glyphset = None;
+    }
+
     font_private->dpy = dpy;
-    font_private->format = _CAIRO_FORMAT_XRENDER_FORMAT(dpy, format);
-    font_private->glyphset = XRenderCreateGlyphSet (dpy, font_private->format);
     scaled_font->surface_private = font_private;
     scaled_font->surface_backend = &cairo_xlib_surface_backend;
     return CAIRO_STATUS_SUCCESS;
 }
 
+static cairo_xlib_font_glyph_info_t *
+_cairo_xlib_surface_font_get_glyph_info (cairo_scaled_font_t *scaled_font,
+					 cairo_format_t	     format)
+{
+    cairo_xlib_surface_font_private_t	*font_private = scaled_font->surface_private;
+    cairo_xlib_font_glyph_info_t        *glyph_info = &font_private->glyph_info[0];
+    int foffset;
+    
+    switch (format) {
+    case CAIRO_FORMAT_A1:
+	foffset = 0;
+	break;
+    case CAIRO_FORMAT_A8:
+	foffset = 1;
+	break;
+    case CAIRO_FORMAT_ARGB32:
+	foffset = 2;
+	break;
+    case CAIRO_FORMAT_RGB24:
+    default:
+	ASSERT_NOT_REACHED;
+    }
+    
+    if (glyph_info[foffset].glyphset == None) {
+	glyph_info[foffset].format = _CAIRO_FORMAT_XRENDER_FORMAT(font_private->dpy,
+								  format);
+	glyph_info[foffset].glyphset = XRenderCreateGlyphSet (font_private->dpy, 
+							      glyph_info[foffset].format);
+	font_private->num_formats ++;
+    }
+    
+    return glyph_info + foffset;
+}
+
 static void
 _cairo_xlib_surface_scaled_font_fini (cairo_scaled_font_t *scaled_font)
 {
     cairo_xlib_surface_font_private_t	*font_private = scaled_font->surface_private;
 
     if (font_private) {
-	XRenderFreeGlyphSet (font_private->dpy, font_private->glyphset);
+	int i;
+
+	for (i = 0; i < GLYPH_INFO_MAX; i ++) {
+	    if (font_private->glyph_info[i].glyphset)
+		XRenderFreeGlyphSet (font_private->dpy,
+				     font_private->glyph_info[i].glyphset);
+	}
 	free (font_private);
     }
 }
@@ -2050,8 +2100,10 @@ _cairo_xlib_surface_scaled_glyph_fini (c
 
     if (font_private != NULL && scaled_glyph->surface_private != NULL) {
 	unsigned long	glyph_index = _cairo_scaled_glyph_index(scaled_glyph);
+	cairo_xlib_font_glyph_info_t *glyph_info = scaled_glyph->surface_private;
+
 	XRenderFreeGlyphs (font_private->dpy,
-			   font_private->glyphset,
+			   glyph_info->glyphset,
 			   &glyph_index, 1);
     }
 }
@@ -2074,16 +2126,23 @@ _cairo_xlib_surface_add_glyph (Display *
     unsigned char *data;
     cairo_status_t status;
     cairo_xlib_surface_font_private_t *font_private;
+    cairo_xlib_font_glyph_info_t * cairo_glyph_info;
     cairo_image_surface_t *glyph_surface = scaled_glyph->surface;
 
     if (scaled_font->surface_private == NULL) {
-	status = _cairo_xlib_surface_font_init (dpy, scaled_font, 
-						glyph_surface->format);
+	status = _cairo_xlib_surface_font_init (dpy, scaled_font);
 	if (status)
 	    return status;
     }
     font_private = scaled_font->surface_private;
 
+    cairo_glyph_info = _cairo_xlib_surface_font_get_glyph_info (scaled_font,
+								glyph_surface->format);
+    if (cairo_glyph_info->glyphset == None)
+	return CAIRO_STATUS_NO_MEMORY;
+    
+    scaled_glyph->surface_private = cairo_glyph_info;
+
     /*
      *  Most of the font rendering system thinks of glyph tiles as having
      *  an origin at (0,0) and an x and y bounding box "offset" which
@@ -2188,11 +2247,11 @@ _cairo_xlib_surface_add_glyph (Display *
 
     glyph_index = _cairo_scaled_glyph_index (scaled_glyph);
     
-    XRenderAddGlyphs (dpy, font_private->glyphset,
+    XRenderAddGlyphs (dpy, cairo_glyph_info->glyphset,
 		      &glyph_index, &(glyph_info), 1,
 		      (char *) data,
 		      glyph_surface->stride * glyph_surface->height);
-
+    
     if (data != glyph_surface->data)
 	free (data);
     
@@ -2209,9 +2268,9 @@ _cairo_xlib_surface_old_show_glyphs8  (c
 				       int                     source_x,
 				       int                     source_y,
 				       const cairo_glyph_t    *glyphs,
-				       int                     num_glyphs)
+				       int                     num_glyphs,
+				       cairo_xlib_font_glyph_info_t *glyph_info)
 {
-    cairo_xlib_surface_font_private_t *font_private = scaled_font->surface_private;
     XGlyphElt8 *elts = NULL;
     XGlyphElt8 stack_elts [N_STACK_BUF];
 
@@ -2239,7 +2298,7 @@ _cairo_xlib_surface_old_show_glyphs8  (c
 	chars[i] = glyphs[i].index;
 	elts[i].chars = &(chars[i]);
 	elts[i].nchars = 1;
-	elts[i].glyphset = font_private->glyphset;
+	elts[i].glyphset = glyph_info->glyphset;
 	thisX = (int) floor (glyphs[i].x + 0.5);
 	thisY = (int) floor (glyphs[i].y + 0.5);
 	elts[i].xOff = thisX - lastX;
@@ -2252,7 +2311,7 @@ _cairo_xlib_surface_old_show_glyphs8  (c
 			    _render_operator (op),
 			    src->src_picture,
 			    self->dst_picture,
-			    font_private->format,
+			    glyph_info->format,
 			    source_x + elts[0].xOff, source_y + elts[0].yOff,
 			    0, 0,
 			    elts, num_glyphs);
@@ -2271,9 +2330,9 @@ _cairo_xlib_surface_old_show_glyphs16 (c
 				       int                     source_x,
 				       int                     source_y,
 				       const cairo_glyph_t    *glyphs,
-				       int                     num_glyphs)
+				       int                     num_glyphs,
+				       cairo_xlib_font_glyph_info_t *glyph_info)
 {
-    cairo_xlib_surface_font_private_t *font_private = scaled_font->surface_private;
     XGlyphElt16 *elts = NULL;
     XGlyphElt16 stack_elts [N_STACK_BUF];
 
@@ -2301,7 +2360,7 @@ _cairo_xlib_surface_old_show_glyphs16 (c
 	chars[i] = glyphs[i].index;
 	elts[i].chars = &(chars[i]);
 	elts[i].nchars = 1;
-	elts[i].glyphset = font_private->glyphset;
+	elts[i].glyphset = glyph_info->glyphset;
 	thisX = (int) floor (glyphs[i].x + 0.5);
 	thisY = (int) floor (glyphs[i].y + 0.5);
 	elts[i].xOff = thisX - lastX;
@@ -2314,7 +2373,7 @@ _cairo_xlib_surface_old_show_glyphs16 (c
 			    _render_operator (op),
 			    src->src_picture,
 			    self->dst_picture,
-			    font_private->format,
+			    glyph_info->format,
 			    source_x + elts[0].xOff, source_y + elts[0].yOff,
 			    0, 0,
 			    elts, num_glyphs);
@@ -2326,16 +2385,16 @@ _cairo_xlib_surface_old_show_glyphs16 (c
 }
 
 static cairo_status_t
-_cairo_xlib_surface_old_show_glyphs32 (cairo_scaled_font_t    *scaled_font,
-				       cairo_operator_t        op,
-				       cairo_xlib_surface_t   *src,
-				       cairo_xlib_surface_t   *self,
-				       int                     source_x,
-				       int                     source_y,
-				       const cairo_glyph_t    *glyphs,
-				       int                     num_glyphs)
+_cairo_xlib_surface_old_show_glyphs32 (cairo_scaled_font_t         *scaled_font,
+				       cairo_operator_t            op,
+				       cairo_xlib_surface_t        *src,
+				       cairo_xlib_surface_t        *self,
+				       int                          source_x,
+				       int                          source_y,
+				       const cairo_glyph_t          *glyphs,
+				       int                          num_glyphs,
+				       cairo_xlib_font_glyph_info_t *glyph_info)
 {
-    cairo_xlib_surface_font_private_t *font_private = scaled_font->surface_private;
     XGlyphElt32 *elts = NULL;
     XGlyphElt32 stack_elts [N_STACK_BUF];
 
@@ -2363,7 +2422,7 @@ _cairo_xlib_surface_old_show_glyphs32 (c
 	chars[i] = glyphs[i].index;
 	elts[i].chars = &(chars[i]);
 	elts[i].nchars = 1;
-	elts[i].glyphset = font_private->glyphset;
+	elts[i].glyphset = glyph_info->glyphset;
 	thisX = (int) floor (glyphs[i].x + 0.5);
 	thisY = (int) floor (glyphs[i].y + 0.5);
 	elts[i].xOff = thisX - lastX;
@@ -2376,7 +2435,7 @@ _cairo_xlib_surface_old_show_glyphs32 (c
 			    _render_operator (op),
 			    src->src_picture,
 			    self->dst_picture,
-			    font_private->format,
+			    glyph_info->format,
 			    source_x + elts[0].xOff, source_y + elts[0].yOff,
 			    0, 0,
 			    elts, num_glyphs);
@@ -2409,8 +2468,10 @@ _cairo_xlib_surface_old_show_glyphs (cai
     int glyphs_remaining, chunk_size, max_chunk_size;
     composite_operation_t operation;
     cairo_scaled_glyph_t *scaled_glyph;
+    cairo_xlib_font_glyph_info_t **glyphs_info, **glyphs_info_chunk;
+    cairo_xlib_font_glyph_info_t *stack_glyphs_info[N_STACK_BUF];
     cairo_xlib_surface_font_private_t *font_private;
-    int i;
+    int i, boundary;
     unsigned long max_index = 0;
     
 
@@ -2444,6 +2505,15 @@ _cairo_xlib_surface_old_show_glyphs (cai
     if (status)
 	goto FAIL;
     
+    if (num_glyphs < N_STACK_BUF)
+	glyphs_info = stack_glyphs_info;
+    else
+	glyphs_info = malloc (sizeof(cairo_xlib_font_glyph_info_t *) * num_glyphs);
+    if (!glyphs_info) {
+	status = CAIRO_STATUS_NO_MEMORY;
+	goto FAIL;
+    }
+
     /* Send all unsent glyphs to the server */
     for (i = 0; i < num_glyphs; i++) {
 	if (glyphs[i].index > max_index)
@@ -2453,11 +2523,11 @@ _cairo_xlib_surface_old_show_glyphs (cai
 					     CAIRO_SCALED_GLYPH_INFO_SURFACE,
 					     &scaled_glyph);
 	if (status != CAIRO_STATUS_SUCCESS)
-	    return status;
+	    goto FAIL1;
 	if (scaled_glyph->surface_private == NULL) {
 	    _cairo_xlib_surface_add_glyph (self->dpy, scaled_font, scaled_glyph);
-	    scaled_glyph->surface_private = (void *) 1;
 	}
+	glyphs_info[i] = (cairo_xlib_font_glyph_info_t *)scaled_glyph->surface_private;
     }
     
     _cairo_xlib_surface_ensure_dst_picture (self);
@@ -2471,28 +2541,40 @@ _cairo_xlib_surface_old_show_glyphs (cai
 	max_chunk_size -= sz_xRenderCompositeGlyphs32Req;
     max_chunk_size /= sz_xGlyphElt;
 
-    for (glyphs_remaining = num_glyphs, glyphs_chunk = glyphs;
-	 glyphs_remaining;
-	 glyphs_remaining -= chunk_size, glyphs_chunk += chunk_size)
+    font_private = scaled_font->surface_private;
+
+    for (glyphs_remaining = num_glyphs, glyphs_chunk = glyphs,
+	     glyphs_info_chunk = glyphs_info; glyphs_remaining;
+	 glyphs_remaining -= chunk_size, glyphs_chunk += chunk_size, 
+	     glyphs_info_chunk += chunk_size)
     {
 	chunk_size = MIN (glyphs_remaining, max_chunk_size);
 
+	if (font_private->num_formats > 1 && chunk_size > 1) {
+	    for (boundary = 1; boundary < chunk_size; boundary ++) {
+		if (glyphs_info_chunk[boundary - 1]->glyphset != glyphs_info_chunk[boundary]->glyphset) {
+		    chunk_size = boundary;
+		    break;
+		}
+	    }
+	}
+
 	/* Call the appropriate sub-function. */
 	if (max_index < 256)
 	    status = _cairo_xlib_surface_old_show_glyphs8 (scaled_font, op, src, self,
-					      source_x + attributes.x_offset - dest_x,
-					      source_y + attributes.y_offset - dest_y, 
-					      glyphs_chunk, chunk_size);
+							   source_x + attributes.x_offset - dest_x,
+							   source_y + attributes.y_offset - dest_y, 
+							   glyphs_chunk, chunk_size, glyphs_info_chunk[0]);
 	else if (max_index < 65536)
 	    status = _cairo_xlib_surface_old_show_glyphs16 (scaled_font, op, src, self,
-					       source_x + attributes.x_offset - dest_x,
-					       source_y + attributes.y_offset - dest_y, 
-					       glyphs_chunk, chunk_size);
+							    source_x + attributes.x_offset - dest_x,
+							    source_y + attributes.y_offset - dest_y, 
+							    glyphs_chunk, chunk_size, glyphs_info_chunk[0]);
 	else 
 	    status = _cairo_xlib_surface_old_show_glyphs32 (scaled_font, op, src, self,
-					       source_x + attributes.x_offset - dest_x,
-					       source_y + attributes.y_offset - dest_y, 
-					       glyphs_chunk, chunk_size);
+							    source_x + attributes.x_offset - dest_x,
+							    source_y + attributes.y_offset - dest_y, 
+							    glyphs_chunk, chunk_size, glyphs_info_chunk[0]);
 	if (status != CAIRO_STATUS_SUCCESS)
 	    break;
     }
@@ -2504,14 +2586,17 @@ _cairo_xlib_surface_old_show_glyphs (cai
 							  num_glyphs,
 							  &extents);
 	if (status == CAIRO_STATUS_SUCCESS)
-	    status = _cairo_surface_composite_shape_fixup_unbounded 
-			(&self->base, &attributes, src->width, src->height,
-			 extents.width, extents.height,
-			 source_x, source_y,
-			 dest_x - extents.x, dest_y - extents.y,
-			 dest_x, dest_y,
-			 width, height);
+	    status = _cairo_surface_composite_shape_fixup_unbounded (&self->base, &attributes, src->width, src->height,
+								     extents.width, extents.height,
+								     source_x, source_y,
+								     dest_x - extents.x, dest_y - extents.y,
+								     dest_x, dest_y,
+								     width, height);
     }
+
+ FAIL1:
+    if (glyphs_info != stack_glyphs_info)
+	free (glyphs_info);
  FAIL:
     _cairo_pattern_release_surface (pattern, &src->base, &attributes);
     


Index: cairo.spec
===================================================================
RCS file: /cvs/dist/rpms/cairo/devel/cairo.spec,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -r1.36 -r1.37
--- cairo.spec	25 Apr 2006 17:41:23 -0000	1.36
+++ cairo.spec	28 Apr 2006 15:18:25 -0000	1.37
@@ -4,7 +4,7 @@
 Summary:   A vector graphics library
 Name:      cairo
 Version:   1.1.2
-Release:   1
+Release:   2
 URL:       http://cairographics.org
 Source0:   %{name}-%{version}.tar.gz
 License:   LGPL/MPL
@@ -24,6 +24,7 @@
 BuildRequires: fontconfig-devel >= %{fontconfig_version}
 
 Patch0: cairo-1.1.2-embedded-bitmaps.patch
+Patch1: cairo-1.1.2-XRenderAddGlyphs-4705.patch
 
 %description 
 Cairo is a vector graphics library designed to provide high-quality
@@ -51,6 +52,7 @@
 %prep
 %setup -q
 %patch0 -p1 -b .embedded-bitmaps
+%patch1 -p1 -b .XRenderAddGlyphs-4705
 
 %build
 %configure --enable-warnings --disable-glitz --disable-quartz \
@@ -85,6 +87,10 @@
 %{_datadir}/gtk-doc/*
 
 %changelog
+* Fri Apr 28 2006 Carl Worth <cworth at redhat.com> - 1.1.2-2
+- Add suggested patch for XRenderAddGlyphs crash of bug #4705
+  https://bugs.freedesktop.org/show_bug.cgi?id=4705
+
 * Tue Apr 25 2006 Carl Worth <cworth at redhat.com> - 1.1.2-1
 - Update to new upstream 1.1.2
 - Port forward the embedded bitmaps patch (now committed upstream to




More information about the fedora-cvs-commits mailing list