[cairo-commit] 5 commits - src/cairo-analysis-surface.c src/cairo-atsui-font.c src/cairo.c src/cairo-directfb-surface.c src/cairo-glitz-surface.c src/cairo-gstate.c src/cairo.h src/cairoint.h src/cairo-meta-surface.c src/cairo-nquartz-surface.c src/cairo-paginated-surface.c src/cairo-pdf-surface.c src/cairo-ps-surface.c src/cairo-scaled-font.c src/cairo-surface.c src/cairo-surface-fallback.c src/cairo-surface-fallback-private.h src/cairo-svg-surface.c src/cairo-win32-font.c src/cairo-win32-surface.c src/cairo-xcb-surface.c src/cairo-xlib-surface.c src/test-meta-surface.c src/test-paginated-surface.c

Behdad Esfahbod behdad at kemper.freedesktop.org
Tue Dec 12 00:34:14 PST 2006


 src/cairo-analysis-surface.c         |    2 
 src/cairo-atsui-font.c               |    2 
 src/cairo-directfb-surface.c         |    2 
 src/cairo-glitz-surface.c            |    2 
 src/cairo-gstate.c                   |   42 ++-
 src/cairo-meta-surface.c             |    2 
 src/cairo-nquartz-surface.c          |    2 
 src/cairo-paginated-surface.c        |    2 
 src/cairo-pdf-surface.c              |    2 
 src/cairo-ps-surface.c               |    2 
 src/cairo-scaled-font.c              |   14 -
 src/cairo-surface-fallback-private.h |    2 
 src/cairo-surface-fallback.c         |    4 
 src/cairo-surface.c                  |    4 
 src/cairo-svg-surface.c              |    2 
 src/cairo-win32-font.c               |    2 
 src/cairo-win32-surface.c            |    2 
 src/cairo-xcb-surface.c              |    4 
 src/cairo-xlib-surface.c             |  487 ++++++++++++++++++-----------------
 src/cairo.c                          |    4 
 src/cairo.h                          |    6 
 src/cairoint.h                       |   37 +-
 src/test-meta-surface.c              |    2 
 src/test-paginated-surface.c         |    2 
 24 files changed, 349 insertions(+), 283 deletions(-)

New commits:
diff-tree 1781e6018c17909311295a9cc74b70500c6b4d0a (from 198c1439ab21b1b19310335d93242709d1398ff3)
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Mon Dec 11 03:31:10 2006 -0500

    [Xlib] Rewrite an optimized cairo_xlib_show_glyphs()
    
    The old implementation was a very naive one that used to generate one XRender
    glyph element per glyph.  That is, position glyphs individually.  This was
    raised here:
    
      http://lists.freedesktop.org/archives/cairo/2006-December/008835.html
    
    The new implmentation is a free rewriting of the Xft logic, that is,
    compressing glyphs with "natural" advance into elements, but with various
    optimizations and improvements.
    
    In short, it works like this: glyphs are looped over, skipping those that are
    not desired, and computing offset from "current position".  Whenever a glyph
    has non-zero offsets from the current position, a new element should be
    started.  All these are used to compute the request size in the render
    protocol.  Whenever the request size may exceed the max request size, or at
    the end, glyphs are flushed.  For this to work, we now set non-zero glyph
    advances when sending glyphs to the server.
    
    Notable optimizations and improvements include:
    
      - Reusing the input glyph array (with double glyph positions) as a working
        array to compute glyph offsets.
    
      - Reusing the input glyph array as the output glyph-index array to be passed
        to XRender.
    
      - Marking glyphs to be skipped as so, avoiding a copy of the glyph array,
        which is what the old code was doing.
    
      - Skip glyphs with positions "out-of-range".  That is, those with positions
        that would cause an overflow in Xrender's glyph offset calculations.
    
    On my Fedora desktop on Pentium 4, and on a Nokia 770, it shows a 6% speedup on
    the timetext test.

diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index 5482a2f..fbfae75 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -33,6 +33,7 @@
  *
  * Contributor(s):
  *	Carl D. Worth <cworth at cworth.org>
+ *	Behdad Esfahbod <behdad at behdad.org>
  */
 
 #include "cairoint.h"
@@ -2412,8 +2413,8 @@ _cairo_xlib_surface_add_glyph (Display *
     glyph_info.y = - _cairo_lround (glyph_surface->base.device_transform.y0);
     glyph_info.width = glyph_surface->width;
     glyph_info.height = glyph_surface->height;
-    glyph_info.xOff = 0;
-    glyph_info.yOff = 0;
+    glyph_info.xOff = scaled_glyph->x_advance;
+    glyph_info.yOff = scaled_glyph->y_advance;
 
     data = glyph_surface->data;
 
@@ -2496,194 +2497,295 @@ _cairo_xlib_surface_add_glyph (Display *
     return status;
 }
 
-#define N_STACK_BUF 1024
+typedef void (*cairo_xrender_composite_text_func_t)
+	      (Display                      *dpy,
+	       int                          op,
+	       Picture                      src,
+	       Picture                      dst,
+	       _Xconst XRenderPictFormat    *maskFormat,
+	       int                          xSrc,
+	       int                          ySrc,
+	       int                          xDst,
+	       int                          yDst,
+	       _Xconst XGlyphElt8           *elts,
+	       int                          nelt);
+
+/* Build a struct of the same size of cairo_glyph_t that can be used both as
+ * an input glyph with double coordinates, and as "working" glyph with
+ * integer from-current-point offsets. */
+typedef struct {
+  unsigned long index;
+  union {
+    struct {
+      double x;
+      double y;
+    } d;
+    struct {
+      int x;
+      int y;
+    } i;
+  } p;
+} cairo_xlib_glyph_t;
+
+#define GLYPH_INDEX_SKIP ((unsigned long) -1)
+#define STACK_ELTS_LEN ((int) (CAIRO_STACK_BUFFER_SIZE / sizeof (XGlyphElt8)))
 
 static cairo_status_t
-_cairo_xlib_surface_show_glyphs8  (cairo_xlib_surface_t *dst,
-                                   cairo_operator_t op,
-                                   cairo_xlib_surface_t *src,
-                                   int src_x_offset, int src_y_offset,
-                                   const cairo_glyph_t *glyphs,
-                                   int num_glyphs,
-                                   cairo_scaled_font_t *scaled_font)
+_cairo_xlib_surface_emit_glyphs_chunk (cairo_xlib_surface_t *dst,
+				       cairo_xlib_glyph_t *glyphs,
+				       int num_glyphs,
+				       int width,
+				       int num_elts,
+				       cairo_scaled_font_t *scaled_font,
+				       cairo_operator_t op,
+				       cairo_xlib_surface_t *src,
+				       cairo_surface_attributes_t *attributes)
 {
-    cairo_xlib_surface_font_private_t *font_private = scaled_font->surface_private;
-    XGlyphElt8 *elts = NULL;
-    XGlyphElt8 stack_elts [N_STACK_BUF];
-
-    char *chars = NULL;
-    char stack_chars [N_STACK_BUF];
+    /* Which XRenderCompositeText function to use */
+    cairo_xrender_composite_text_func_t composite_text_func;
+    int size;
+
+    /* Element buffer stuff */
+    XGlyphElt8 *elts;
+    XGlyphElt8 stack_elts[STACK_ELTS_LEN];
+
+    /* Reuse the input glyph array for output char generation */
+    char *char8 = (char *) glyphs;
+    unsigned short *char16 = (unsigned short *) glyphs;
+    unsigned int *char32 = (unsigned int *) glyphs;
 
     int i;
-    int thisX, thisY;
-    int lastX = 0, lastY = 0;
+    int nelt; /* Element index */
+    int n; /* Num output glyphs in current element */
+    int j; /* Num output glyphs so far */
 
-    /* Acquire arrays of suitable sizes. */
-    if (num_glyphs < N_STACK_BUF) {
-	elts = stack_elts;
-	chars = stack_chars;
-    } else {
-	elts = malloc (num_glyphs * sizeof (XGlyphElt8) +
-		       num_glyphs * sizeof (unsigned char));
-	if (elts == NULL)
-	    return CAIRO_STATUS_NO_MEMORY;
+    cairo_xlib_surface_font_private_t *font_private = scaled_font->surface_private;
 
-	chars = (char *) (elts + num_glyphs);
+    switch (width) {
+    case 1:
+	/* don't cast the 8-variant, to catch possible mismatches */
+	composite_text_func = XRenderCompositeText8;
+	size = sizeof (char);
+	break;
+    case 2:
+	composite_text_func = (cairo_xrender_composite_text_func_t) XRenderCompositeText16;
+	size = sizeof (unsigned short);
+	break;
+    default:
+    case 4:
+	composite_text_func = (cairo_xrender_composite_text_func_t) XRenderCompositeText32;
+	size = sizeof (unsigned int);
     }
 
-    for (i = 0; i < num_glyphs; ++i) {
-	chars[i] = glyphs[i].index;
-	elts[i].chars = &(chars[i]);
-	elts[i].nchars = 1;
-	elts[i].glyphset = font_private->glyphset;
-	thisX = _cairo_lround (glyphs[i].x);
-	thisY = _cairo_lround (glyphs[i].y);
-	elts[i].xOff = thisX - lastX;
-	elts[i].yOff = thisY - lastY;
-	lastX = thisX;
-	lastY = thisY;
-    }
-
-    XRenderCompositeText8  (dst->dpy,
-			    _render_operator (op),
-			    src->src_picture,
-			    dst->dst_picture,
-			    font_private->xrender_format,
-                            src_x_offset + elts[0].xOff, src_y_offset + elts[0].yOff,
-                            elts[0].xOff, elts[0].yOff,
-			    elts, num_glyphs);
+    /* Allocate element array */
+    if (num_elts <= STACK_ELTS_LEN) {
+      elts = stack_elts;
+    } else {
+      elts = malloc (num_elts * sizeof (XGlyphElt8));
+      if (elts == NULL)
+	  return CAIRO_STATUS_NO_MEMORY;
+    }
+
+    /* Fill them in */
+    nelt = 0;
+    n = 0;
+    j = 0;
+    for (i = 0; i < num_glyphs; i++) {
+
+      /* Skip glyphs marked so */
+      if (glyphs[i].index == GLYPH_INDEX_SKIP)
+	continue;
+
+      /* Start a new element for first output glyph, and for glyphs with
+       * unexpected position */
+      if (!j || glyphs[i].p.i.x || glyphs[i].p.i.y) {
+	  if (j) {
+	    elts[nelt].nchars = n;
+	    nelt++;
+	    n = 0;
+	  }
+	  elts[nelt].chars = char8 + size * j;
+	  elts[nelt].glyphset = font_private->glyphset;
+	  elts[nelt].xOff = glyphs[i].p.i.x;
+	  elts[nelt].yOff = glyphs[i].p.i.y;
+      }
+
+      switch (width) {
+      case 1: char8 [j] = (char)           glyphs[i].index; break;
+      case 2: char16[j] = (unsigned short) glyphs[i].index; break;
+      default:
+      case 4: char32[j] = (unsigned int)   glyphs[i].index; break;
+      }
+
+      n++;
+      j++;
+    }
+
+    if (n) {
+	elts[nelt].nchars = n;
+	nelt++;
+	n = 0;
+    }
+
+    composite_text_func (dst->dpy,
+			 _render_operator (op),
+			 src->src_picture,
+			 dst->dst_picture,
+			 font_private->xrender_format,
+			 attributes->x_offset + elts[0].xOff,
+			 attributes->y_offset + elts[0].yOff,
+			 elts[0].xOff, elts[0].yOff,
+			 (XGlyphElt8 *) elts, nelt);
 
     if (elts != stack_elts)
-	free (elts);
+      free (elts);
 
     return CAIRO_STATUS_SUCCESS;
 }
 
+#undef STACK_ELTS_LEN
+
 static cairo_status_t
-_cairo_xlib_surface_show_glyphs16 (cairo_xlib_surface_t *dst,
-                                   cairo_operator_t op,
-                                   cairo_xlib_surface_t *src,
-                                   int src_x_offset, int src_y_offset,
-                                   const cairo_glyph_t *glyphs,
-                                   int num_glyphs,
-                                   cairo_scaled_font_t *scaled_font)
+_cairo_xlib_surface_emit_glyphs (cairo_xlib_surface_t *dst,
+				 cairo_xlib_glyph_t *glyphs,
+				 int num_glyphs,
+				 cairo_scaled_font_t *scaled_font,
+				 cairo_operator_t op,
+				 cairo_xlib_surface_t *src,
+				 cairo_surface_attributes_t *attributes)
 {
-    cairo_xlib_surface_font_private_t *font_private = scaled_font->surface_private;
-    XGlyphElt16 *elts = NULL;
-    XGlyphElt16 stack_elts [N_STACK_BUF];
+    int i;
+    cairo_status_t status = CAIRO_STATUS_SUCCESS;
+    cairo_scaled_glyph_t *scaled_glyph;
+    cairo_fixed_t x = 0, y = 0;
 
-    unsigned short *chars = NULL;
-    unsigned short stack_chars [N_STACK_BUF];
+    unsigned long max_index = 0;
+    int width = 1;
+    int num_elts = 0;
+    int num_out_glyphs = 0;
+
+    int max_request_size = XMaxRequestSize (dst->dpy)
+			 - MAX (sz_xRenderCompositeGlyphs8Req,
+				MAX(sz_xRenderCompositeGlyphs16Req,
+				    sz_xRenderCompositeGlyphs32Req));
+    int request_size = 0;
 
-    int i;
-    int thisX, thisY;
-    int lastX = 0, lastY = 0;
+    _cairo_xlib_surface_ensure_dst_picture (dst);
 
-    /* Acquire arrays of suitable sizes. */
-    if (num_glyphs < N_STACK_BUF) {
-	elts = stack_elts;
-	chars = stack_chars;
-    } else {
-	elts = malloc (num_glyphs * sizeof (XGlyphElt16) +
-		       num_glyphs * sizeof (unsigned short));
-	if (elts == NULL)
-	    return CAIRO_STATUS_NO_MEMORY;
+    for (i = 0; i < num_glyphs; i++) {
+	int this_x, this_y;
+	int old_width;
 
-	chars = (unsigned short *) (elts + num_glyphs);
-    }
+	status = _cairo_scaled_glyph_lookup (scaled_font,
+					     glyphs[i].index,
+					     CAIRO_SCALED_GLYPH_INFO_SURFACE |
+					     CAIRO_SCALED_GLYPH_INFO_METRICS,
+					     &scaled_glyph);
+	if (status != CAIRO_STATUS_SUCCESS)
+	    return status;
 
-    for (i = 0; i < num_glyphs; ++i) {
-	chars[i] = glyphs[i].index;
-	elts[i].chars = &(chars[i]);
-	elts[i].nchars = 1;
-	elts[i].glyphset = font_private->glyphset;
-	thisX = _cairo_lround (glyphs[i].x);
-	thisY = _cairo_lround (glyphs[i].y);
-	elts[i].xOff = thisX - lastX;
-	elts[i].yOff = thisY - lastY;
-	lastX = thisX;
-	lastY = thisY;
-    }
-
-    XRenderCompositeText16 (dst->dpy,
-			    _render_operator (op),
-			    src->src_picture,
-			    dst->dst_picture,
-			    font_private->xrender_format,
-                            src_x_offset + elts[0].xOff, src_y_offset + elts[0].yOff,
-                            elts[0].xOff, elts[0].yOff,
-			    elts, num_glyphs);
+	this_x = _cairo_lround (glyphs[i].p.d.x);
+	this_y = _cairo_lround (glyphs[i].p.d.y);
 
-    if (elts != stack_elts)
-	free (elts);
+	/* Glyph skipping:
+	 *
+	 * We skip any initial size-zero glyphs to avoid an X server bug (present
+	 * in at least Xorg 7.1 without EXA) which stops rendering glyphs after
+	 * the first zero-size glyph.  However, we don't skip all size-zero
+	 * glyphs, since that will force a new element at every space.  We
+	 * skip initial size-zero glyphs and hope that it's enough.  Since
+	 * Xft never exposed that bug, this assumptation should be correct.
+	 *
+	 * We also skip any glyph that hav troublesome coordinates.  We want
+	 * to make sure that (glyph2.x - (glyph1.x + glyph1.width)) fits in
+	 * a signed 16bit integer, otherwise it will overflow in the render
+	 * protocol.
+	 * To ensure this, we'll make sure that (glyph2.x - glyph1.x) fits in
+	 * a signed 15bit integer.  The trivial option would be to allow
+	 * coordinates -8192..8192, but that's kinda dull.  It probably will
+	 * take a decade or so to get monitors 8192x4096 or something.  A
+	 * negative value of -8192 on the other hand, is absolutely useless.
+	 * Note that we do want to allow some negative positions.  The glyph
+	 * may start off the screen but part of it make it to the screen.
+	 * Anyway, we will allow positions in the range -1024..15359.  That
+	 * will buy us a few more years before this stops working.
+	 */
+	if ((!num_out_glyphs && !(scaled_glyph->surface->width && scaled_glyph->surface->height)) ||
+	    (((this_x+1024)|(this_y+1024))&~0x3fffu)) {
+	    glyphs[i].index = GLYPH_INDEX_SKIP;
+	    continue;
+	}
 
-    return CAIRO_STATUS_SUCCESS;
-}
+	old_width = width;
 
-static cairo_status_t
-_cairo_xlib_surface_show_glyphs32 (cairo_xlib_surface_t *dst,
-                                   cairo_operator_t op,
-                                   cairo_xlib_surface_t *src,
-                                   int src_x_offset, int src_y_offset,
-                                   const cairo_glyph_t *glyphs,
-                                   int num_glyphs,
-                                   cairo_scaled_font_t *scaled_font)
-{
-    cairo_xlib_surface_font_private_t *font_private = scaled_font->surface_private;
-    XGlyphElt32 *elts = NULL;
-    XGlyphElt32 stack_elts [N_STACK_BUF];
+	/* Update max glyph index */
+	if (glyphs[i].index > max_index) {
+	    max_index = glyphs[i].index;
+	    if (max_index >= 65536)
+	      width = 4;
+	    else if (max_index >= 256)
+	      width = 2;
+	    if (width != old_width)
+	      request_size += (width - old_width) * num_out_glyphs;
+	}
+
+	/* If we will pass the max request size by adding this glyph,
+	 * flush current glyphs.  Note that we account for a
+	 * possible element being added below. */
+	if (request_size + width > max_request_size - sz_xGlyphElt) {
+	    status = _cairo_xlib_surface_emit_glyphs_chunk (dst, glyphs, i,
+							    old_width, num_elts,
+							    scaled_font, op, src, attributes);
+	    if (status != CAIRO_STATUS_SUCCESS)
+		return status;
+
+	    glyphs += i;
+	    num_glyphs -= i;
+	    i = 0;
+	    max_index = glyphs[i].index;
+	    width = max_index < 256 ? 1 : max_index < 65536 ? 2 : 4;
+	    request_size = 0;
+	    num_elts = 0;
+	    num_out_glyphs = 0;
+	    x = y = 0;
 
-    unsigned int *chars = NULL;
-    unsigned int stack_chars [N_STACK_BUF];
+	}
 
-    int i;
-    int thisX, thisY;
-    int lastX = 0, lastY = 0;
+	/* Convert absolute glyph position to relative-to-current-point
+	 * position */
+	glyphs[i].p.i.x = this_x - x;
+	glyphs[i].p.i.y = this_y - y;
 
-    /* Acquire arrays of suitable sizes. */
-    if (num_glyphs < N_STACK_BUF) {
-	elts = stack_elts;
-	chars = stack_chars;
-    } else {
-	elts = malloc (num_glyphs * sizeof (XGlyphElt32) +
-		       num_glyphs * sizeof (unsigned int));
-	if (elts == NULL)
-	    return CAIRO_STATUS_NO_MEMORY;
+	/* Start a new element for the first glyph, or for any glyph that
+	 * has unexpected position */
+	if (!num_out_glyphs || glyphs[i].p.i.x || glyphs[i].p.i.y) {
+	    num_elts++;
+	    request_size += sz_xGlyphElt;
+	}
 
-	chars = (unsigned int *) (elts + num_glyphs);
-    }
+	/* Send unsent glyphs to the server */
+	if (scaled_glyph->surface_private == NULL) {
+	    _cairo_xlib_surface_add_glyph (dst->dpy, scaled_font, scaled_glyph);
+	    scaled_glyph->surface_private = (void *) 1;
+	}
 
-    for (i = 0; i < num_glyphs; ++i) {
-	chars[i] = glyphs[i].index;
-	elts[i].chars = &(chars[i]);
-	elts[i].nchars = 1;
-	elts[i].glyphset = font_private->glyphset;
-	thisX = _cairo_lround (glyphs[i].x);
-	thisY = _cairo_lround (glyphs[i].y);
-	elts[i].xOff = thisX - lastX;
-	elts[i].yOff = thisY - lastY;
-	lastX = thisX;
-	lastY = thisY;
-    }
-
-    XRenderCompositeText32 (dst->dpy,
-			    _render_operator (op),
-			    src->src_picture,
-			    dst->dst_picture,
-			    font_private->xrender_format,
-                            src_x_offset + elts[0].xOff, src_y_offset + elts[0].yOff,
-                            elts[0].xOff, elts[0].yOff,
-			    elts, num_glyphs);
+	/* adjust current-position */
+	x = this_x + scaled_glyph->x_advance;
+	y = this_y + scaled_glyph->y_advance;
 
-    if (elts != stack_elts)
-	free (elts);
+	num_out_glyphs++;
+	request_size += width;
+    }
 
-    return CAIRO_STATUS_SUCCESS;
+    if (num_elts)
+	status = _cairo_xlib_surface_emit_glyphs_chunk (dst, glyphs, num_glyphs,
+							width, num_elts,
+							scaled_font, op, src, attributes);
+
+    return status;
 }
 
-typedef cairo_status_t (*cairo_xlib_surface_show_glyphs_func_t)
-    (cairo_xlib_surface_t *, cairo_operator_t, cairo_xlib_surface_t *, int, int,
-     const cairo_glyph_t *, int, cairo_scaled_font_t *);
+#undef GLYPH_INDEX_SKIP
 
 static cairo_int_status_t
 _cairo_xlib_surface_show_glyphs (void                *abstract_dst,
@@ -2700,17 +2802,8 @@ _cairo_xlib_surface_show_glyphs (void   
     cairo_surface_attributes_t attributes;
     cairo_xlib_surface_t *src = NULL;
 
-    cairo_glyph_t *output_glyphs;
-    const cairo_glyph_t *glyphs_chunk;
-    int glyphs_remaining, chunk_size, max_chunk_size;
-    cairo_scaled_glyph_t *scaled_glyph;
     cairo_xlib_surface_font_private_t *font_private;
 
-    int i, o;
-    unsigned long max_index = 0;
-
-    cairo_xlib_surface_show_glyphs_func_t show_glyphs_func;
-
     cairo_pattern_union_t solid_pattern;
 
     if (!CAIRO_SURFACE_RENDER_HAS_COMPOSITE_TEXT (dst) || !dst->xrender_format)
@@ -2750,13 +2843,6 @@ _cairo_xlib_surface_show_glyphs (void   
 	(font_private != NULL && font_private->dpy != dst->dpy))
 	return CAIRO_INT_STATUS_UNSUPPORTED;
 
-    /* We make a copy of the glyphs so that we can elide any size-zero
-     * glyphs to workaround an X server bug, (present in at least Xorg
-     * 7.1 without EXA). */
-    output_glyphs = malloc (num_glyphs * sizeof (cairo_glyph_t));
-    if (output_glyphs == NULL)
-	return CAIRO_STATUS_NO_MEMORY;
-
     /* After passing all those tests, we're now committed to rendering
      * these glyphs or to fail trying. We first upload any glyphs to
      * the X server that it doesn't have already, then we draw
@@ -2814,60 +2900,11 @@ _cairo_xlib_surface_show_glyphs (void   
     if (status)
         goto BAIL;
 
-    /* Send all unsent glyphs to the server, and count the max of the glyph indices */
-    for (i = 0, o = 0; i < num_glyphs; i++) {
-	if (glyphs[i].index > max_index)
-	    max_index = glyphs[i].index;
-	status = _cairo_scaled_glyph_lookup (scaled_font,
-					     glyphs[i].index,
-					     CAIRO_SCALED_GLYPH_INFO_SURFACE,
-					     &scaled_glyph);
-	if (status != CAIRO_STATUS_SUCCESS)
-	    goto BAIL;
-	/* Don't put any size-zero glyphs into output_glyphs to avoid
-	 * an X server bug which stops rendering glyphs after the
-	 * first size-zero glyph. */
-	if (scaled_glyph->surface->width && scaled_glyph->surface->height) {
-	    output_glyphs[o++] = glyphs[i];
-	    if (scaled_glyph->surface_private == NULL) {
-		_cairo_xlib_surface_add_glyph (dst->dpy, scaled_font, scaled_glyph);
-		scaled_glyph->surface_private = (void *) 1;
-	    }
-	}
-    }
-    num_glyphs = o;
-
-    _cairo_xlib_surface_ensure_dst_picture (dst);
-
-    max_chunk_size = XMaxRequestSize (dst->dpy);
-    if (max_index < 256) {
-	max_chunk_size -= sz_xRenderCompositeGlyphs8Req;
-	show_glyphs_func = _cairo_xlib_surface_show_glyphs8;
-    } else if (max_index < 65536) {
-	max_chunk_size -= sz_xRenderCompositeGlyphs16Req;
-	show_glyphs_func = _cairo_xlib_surface_show_glyphs16;
-    } else {
-	max_chunk_size -= sz_xRenderCompositeGlyphs32Req;
-	show_glyphs_func = _cairo_xlib_surface_show_glyphs32;
-    }
-    max_chunk_size /= sz_xGlyphElt;
-
-    for (glyphs_remaining = num_glyphs, glyphs_chunk = output_glyphs;
-	 glyphs_remaining;
-	 glyphs_remaining -= chunk_size, glyphs_chunk += chunk_size)
-    {
-	chunk_size = MIN (glyphs_remaining, max_chunk_size);
-
-	status = show_glyphs_func (dst, op, src,
-                                   attributes.x_offset, attributes.y_offset,
-                                   glyphs_chunk, chunk_size, scaled_font);
-	if (status != CAIRO_STATUS_SUCCESS)
-	    break;
-    }
+    _cairo_xlib_surface_emit_glyphs (dst, (cairo_xlib_glyph_t *) glyphs, num_glyphs,
+				     scaled_font, op, src, &attributes);
 
   BAIL:
     _cairo_scaled_font_thaw_cache (scaled_font);
-    free (output_glyphs);
 
     if (src)
         _cairo_pattern_release_surface (src_pattern, &src->base, &attributes);
diff-tree 198c1439ab21b1b19310335d93242709d1398ff3 (from e7ed9eee767c85853d6d2fb823ff3317c490948c)
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Mon Dec 11 03:16:50 2006 -0500

    Cache rounded glyph advance values
    
    This is done in cairo_scaled_glyph_t->x/y_advance.  The value is mostly useful
    for raster backends, for example to set as default advance of a glyph, and
    later on optimize glyph positionings that use the default advance.

diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
index b800cf9..316c603 100755
--- a/src/cairo-scaled-font.c
+++ b/src/cairo-scaled-font.c
@@ -1211,6 +1211,7 @@ _cairo_scaled_glyph_set_metrics (cairo_s
     double hm, wm;
     double min_user_x = 0.0, max_user_x = 0.0, min_user_y = 0.0, max_user_y = 0.0;
     double min_device_x = 0.0, max_device_x = 0.0, min_device_y = 0.0, max_device_y = 0.0;
+    double device_x_advance, device_y_advance;
 
     for (hm = 0.0; hm <= 1.0; hm += 1.0)
 	for (wm = 0.0; wm <= 1.0; wm += 1.0) {
@@ -1259,10 +1260,19 @@ _cairo_scaled_glyph_set_metrics (cairo_s
 				     &scaled_glyph->metrics.x_advance,
 				     &scaled_glyph->metrics.y_advance);
 
+    device_x_advance = fs_metrics->x_advance;
+    device_y_advance = fs_metrics->y_advance;
+    cairo_matrix_transform_distance (&scaled_font->scale,
+				     &device_x_advance,
+				     &device_y_advance);
+
     scaled_glyph->bbox.p1.x = _cairo_fixed_from_double (min_device_x);
     scaled_glyph->bbox.p1.y = _cairo_fixed_from_double (min_device_y);
     scaled_glyph->bbox.p2.x = _cairo_fixed_from_double (max_device_x);
     scaled_glyph->bbox.p2.y = _cairo_fixed_from_double (max_device_y);
+
+    scaled_glyph->x_advance = _cairo_lround (device_x_advance);
+    scaled_glyph->y_advance = _cairo_lround (device_y_advance);
 }
 
 void
diff --git a/src/cairoint.h b/src/cairoint.h
index c894372..f855a41 100755
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -511,6 +511,8 @@ typedef struct _cairo_scaled_glyph {
     cairo_scaled_font_t	    *scaled_font;	/* font the glyph lives in */
     cairo_text_extents_t    metrics;		/* user-space metrics */
     cairo_box_t		    bbox;		/* device-space bounds */
+    int16_t                 x_advance;		/* device-space rounded X advance */
+    int16_t                 y_advance;		/* device-space rounded Y advance */
     cairo_image_surface_t   *surface;		/* device-space image */
     cairo_path_fixed_t	    *path;		/* device-space outline */
     void		    *surface_private;	/* for the surface backend */
diff-tree e7ed9eee767c85853d6d2fb823ff3317c490948c (from da60bc45f295b15c62089874fb30cedc1d70bcd2)
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Mon Dec 11 03:13:34 2006 -0500

    [cairo-gstate] Use a local buffer on the stack for small glyph operations
    
    We duplicate the incoming glyph array for two reasons: 1) applying
    transformations, and 2) to let the lower level functions have a glyph array
    they can modify.  By using a 2kb array on the stack we can avoid malloc() for
    requests of less than 100 glyphs.  The size of the array can be tuned by
    setting CAIRO_STACK_BUFFER_SIZE.

diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c
index ab32545..f1b5897 100644
--- a/src/cairo-gstate.c
+++ b/src/cairo-gstate.c
@@ -1464,6 +1464,7 @@ _cairo_gstate_glyph_extents (cairo_gstat
     return CAIRO_STATUS_SUCCESS;
 }
 
+#define STACK_GLYPHS_LEN ((int) (CAIRO_STACK_BUFFER_SIZE / sizeof (cairo_glyph_t)))
 cairo_status_t
 _cairo_gstate_show_glyphs (cairo_gstate_t *gstate,
 			   const cairo_glyph_t *glyphs,
@@ -1472,6 +1473,8 @@ _cairo_gstate_show_glyphs (cairo_gstate_
     cairo_status_t status;
     cairo_pattern_union_t source_pattern;
     cairo_glyph_t *transformed_glyphs;
+    cairo_glyph_t stack_transformed_glyphs[STACK_GLYPHS_LEN];
+
 
     if (gstate->source->status)
 	return gstate->source->status;
@@ -1484,9 +1487,13 @@ _cairo_gstate_show_glyphs (cairo_gstate_
     if (status)
 	return status;
 
-    transformed_glyphs = malloc (num_glyphs * sizeof(cairo_glyph_t));
-    if (transformed_glyphs == NULL)
-	return CAIRO_STATUS_NO_MEMORY;
+    if (num_glyphs <= STACK_GLYPHS_LEN) {
+	transformed_glyphs = stack_transformed_glyphs;
+    } else {
+	transformed_glyphs = malloc (num_glyphs * sizeof(cairo_glyph_t));
+	if (transformed_glyphs == NULL)
+	    return CAIRO_STATUS_NO_MEMORY;
+    }
 
     _cairo_gstate_transform_glyphs_to_backend (gstate, glyphs, num_glyphs,
                                                transformed_glyphs);
@@ -1501,7 +1508,9 @@ _cairo_gstate_show_glyphs (cairo_gstate_
 					 gstate->scaled_font);
 
     _cairo_pattern_fini (&source_pattern.base);
-    free (transformed_glyphs);
+
+    if (transformed_glyphs != stack_transformed_glyphs)
+      free (transformed_glyphs);
 
     return status;
 }
@@ -1513,13 +1522,17 @@ _cairo_gstate_glyph_path (cairo_gstate_t
 			  cairo_path_fixed_t  *path)
 {
     cairo_status_t status;
-    cairo_glyph_t *transformed_glyphs = NULL;
+    cairo_glyph_t *transformed_glyphs;
+    cairo_glyph_t stack_transformed_glyphs[STACK_GLYPHS_LEN];
 
     status = _cairo_gstate_ensure_scaled_font (gstate);
     if (status)
 	return status;
 
-    transformed_glyphs = malloc (num_glyphs * sizeof(cairo_glyph_t));
+    if (num_glyphs < STACK_GLYPHS_LEN)
+      transformed_glyphs = stack_transformed_glyphs;
+    else
+      transformed_glyphs = malloc (num_glyphs * sizeof(cairo_glyph_t));
     if (transformed_glyphs == NULL)
 	return CAIRO_STATUS_NO_MEMORY;
 
@@ -1530,9 +1543,12 @@ _cairo_gstate_glyph_path (cairo_gstate_t
 					    transformed_glyphs, num_glyphs,
 					    path);
 
-    free (transformed_glyphs);
+    if (transformed_glyphs != stack_transformed_glyphs)
+      free (transformed_glyphs);
+
     return status;
 }
+#undef STACK_GLYPHS_LEN
 
 cairo_status_t
 _cairo_gstate_set_antialias (cairo_gstate_t *gstate,
diff-tree da60bc45f295b15c62089874fb30cedc1d70bcd2 (from 5a9642c5746fd677aed35ce620ce90b1029b1a0c)
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Mon Dec 11 03:10:05 2006 -0500

    [cairoint] Define CAIRO_STACK_BUFFER_SIZE (defaults to 2kb)
    
    This is the suggested size in bytes of buffers allocated on the stack per
    function, mostly used for glyph rendering.  We typically use a local buffer on
    the stack to avoid mallocing for small requests.  Requests that do not fit are
    malloc()ed automatically.  The default value should be enough for about a
    100-glyph cairo_show_glyphs() operation.

diff --git a/src/cairoint.h b/src/cairoint.h
index b481d45..c894372 100755
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -208,6 +208,13 @@ cairo_private void _cairo_beos_unlock(vo
 #define M_PI 3.14159265358979323846
 #endif
 
+/* Size in bytes of buffer to use off the stack per functions.
+ * Mostly used by text functions.  For larger allocations, they'll
+ * malloc(). */
+#ifndef CAIRO_STACK_BUFFER_SIZE
+#define CAIRO_STACK_BUFFER_SIZE (512 * sizeof (int))
+#endif
+
 #define ASSERT_NOT_REACHED		\
 do {					\
     static const int NOT_REACHED = 0;	\
diff-tree 5a9642c5746fd677aed35ce620ce90b1029b1a0c (from 70695f5c62b89b417c1e8b42451470a5a8920bf3)
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Mon Dec 11 01:39:51 2006 -0500

    Add/remove const to cairo_glyph_t* arguments consistently
    
    The rule is: cairo_glyph_t* is always passed as const for measurement
    purposes.  This was not reflected in our public api previously.  Fixed
    
    Showing glyphs used to have cairo_glyph_t* always as const.  With this
    changed, it is only const on cairo_t and cairo_gstate_t operations.
    cairo_surface_t, cairo_scaled_font_t, and individual backends receive
    cairo_glyph_t* as non-const.  The desired semantics is that they may modify
    the contents of the array as long as they do not return
    CAIRO_STATUS_UNSUPPORTED.  This makes it possible to avoid copying the glyph
    array again and again, and edit it in-place.  Backends are in fact free to use
    the array as a generic buffer as they see fit.

diff --git a/src/cairo-analysis-surface.c b/src/cairo-analysis-surface.c
index fd764c6..a89636e 100644
--- a/src/cairo-analysis-surface.c
+++ b/src/cairo-analysis-surface.c
@@ -154,7 +154,7 @@ static cairo_int_status_t
 _cairo_analysis_surface_show_glyphs (void		  *abstract_surface,
 				     cairo_operator_t	   op,
 				     cairo_pattern_t	  *source,
-				     const cairo_glyph_t  *glyphs,
+				     cairo_glyph_t	  *glyphs,
 				     int		   num_glyphs,
 				     cairo_scaled_font_t  *scaled_font)
 {
diff --git a/src/cairo-atsui-font.c b/src/cairo-atsui-font.c
index 973160d..2927caa 100644
--- a/src/cairo-atsui-font.c
+++ b/src/cairo-atsui-font.c
@@ -578,7 +578,7 @@ _cairo_atsui_font_old_show_glyphs (void	
 				   int			dest_y,
 				   unsigned int		width,
 				   unsigned int		height,
-				   const cairo_glyph_t *glyphs,
+				   cairo_glyph_t       *glyphs,
 				   int                 	num_glyphs)
 {
     cairo_atsui_font_t *font = abstract_font;
diff --git a/src/cairo-directfb-surface.c b/src/cairo-directfb-surface.c
index fc6cbef..46a4c7f 100644
--- a/src/cairo-directfb-surface.c
+++ b/src/cairo-directfb-surface.c
@@ -1450,7 +1450,7 @@ static cairo_int_status_t
 _cairo_directfb_surface_show_glyphs ( void                 *abstract_dst,
                                      cairo_operator_t      op,
                                      cairo_pattern_t      *pattern,
-                                     const cairo_glyph_t  *glyphs,
+                                     cairo_glyph_t	  *glyphs,
                                      int                   num_glyphs,
                                      cairo_scaled_font_t  *scaled_font)
 {
diff --git a/src/cairo-glitz-surface.c b/src/cairo-glitz-surface.c
index a579511..3b23691 100644
--- a/src/cairo-glitz-surface.c
+++ b/src/cairo-glitz-surface.c
@@ -1909,7 +1909,7 @@ _cairo_glitz_surface_old_show_glyphs (ca
 				      int		   dst_y,
 				      unsigned int	   width,
 				      unsigned int	   height,
-				      const cairo_glyph_t *glyphs,
+				      cairo_glyph_t       *glyphs,
 				      int		   num_glyphs)
 {
     cairo_glitz_surface_attributes_t	attributes;
diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c
index d04c332..ab32545 100644
--- a/src/cairo-gstate.c
+++ b/src/cairo-gstate.c
@@ -65,7 +65,7 @@ static void
 _cairo_gstate_transform_glyphs_to_backend (cairo_gstate_t      *gstate,
                                            const cairo_glyph_t *glyphs,
                                            int                  num_glyphs,
-                                           cairo_glyph_t *transformed_glyphs);
+                                           cairo_glyph_t       *transformed_glyphs);
 
 /**
  * _cairo_gstate_create:
@@ -1447,7 +1447,7 @@ _cairo_gstate_set_font_face (cairo_gstat
 
 cairo_status_t
 _cairo_gstate_glyph_extents (cairo_gstate_t *gstate,
-			     cairo_glyph_t *glyphs,
+			     const cairo_glyph_t *glyphs,
 			     int num_glyphs,
 			     cairo_text_extents_t *extents)
 {
@@ -1507,10 +1507,10 @@ _cairo_gstate_show_glyphs (cairo_gstate_
 }
 
 cairo_status_t
-_cairo_gstate_glyph_path (cairo_gstate_t     *gstate,
-			  cairo_glyph_t	     *glyphs,
-			  int		      num_glyphs,
-			  cairo_path_fixed_t *path)
+_cairo_gstate_glyph_path (cairo_gstate_t      *gstate,
+			  const cairo_glyph_t *glyphs,
+			  int		       num_glyphs,
+			  cairo_path_fixed_t  *path)
 {
     cairo_status_t status;
     cairo_glyph_t *transformed_glyphs = NULL;
diff --git a/src/cairo-meta-surface.c b/src/cairo-meta-surface.c
index d6beaf0..a82ab8f 100644
--- a/src/cairo-meta-surface.c
+++ b/src/cairo-meta-surface.c
@@ -416,7 +416,7 @@ static cairo_int_status_t
 _cairo_meta_surface_show_glyphs (void			*abstract_surface,
 				 cairo_operator_t	 op,
 				 cairo_pattern_t	*source,
-				 const cairo_glyph_t	*glyphs,
+				 cairo_glyph_t		*glyphs,
 				 int			 num_glyphs,
 				 cairo_scaled_font_t	*scaled_font)
 {
diff --git a/src/cairo-nquartz-surface.c b/src/cairo-nquartz-surface.c
index 5e82616..15b3d61 100644
--- a/src/cairo-nquartz-surface.c
+++ b/src/cairo-nquartz-surface.c
@@ -1304,7 +1304,7 @@ static cairo_int_status_t
 _cairo_nquartz_surface_show_glyphs (void *abstract_surface,
 				    cairo_operator_t op,
 				    cairo_pattern_t *source,
-				    const cairo_glyph_t *glyphs,
+				    cairo_glyph_t *glyphs,
 				    int num_glyphs,
 				    cairo_scaled_font_t *scaled_font)
 {
diff --git a/src/cairo-paginated-surface.c b/src/cairo-paginated-surface.c
index d497778..b313ac1 100644
--- a/src/cairo-paginated-surface.c
+++ b/src/cairo-paginated-surface.c
@@ -437,7 +437,7 @@ static cairo_int_status_t
 _cairo_paginated_surface_show_glyphs (void			*abstract_surface,
 				      cairo_operator_t		 op,
 				      cairo_pattern_t		*source,
-				      const cairo_glyph_t	*glyphs,
+				      cairo_glyph_t		*glyphs,
 				      int			 num_glyphs,
 				      cairo_scaled_font_t	*scaled_font)
 {
diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index 25d367e..a59cd99 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -2720,7 +2720,7 @@ static cairo_int_status_t
 _cairo_pdf_surface_show_glyphs (void			*abstract_surface,
 				cairo_operator_t	 op,
 				cairo_pattern_t		*source,
-				const cairo_glyph_t	*glyphs,
+				cairo_glyph_t		*glyphs,
 				int			 num_glyphs,
 				cairo_scaled_font_t	*scaled_font)
 {
diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index 75fe83e..6d1afe9 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -2136,7 +2136,7 @@ static cairo_int_status_t
 _cairo_ps_surface_show_glyphs (void		     *abstract_surface,
 			       cairo_operator_t	      op,
 			       cairo_pattern_t	     *source,
-			       const cairo_glyph_t   *glyphs,
+			       cairo_glyph_t         *glyphs,
 			       int		      num_glyphs,
 			       cairo_scaled_font_t   *scaled_font)
 {
diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
index 0b060fd..b800cf9 100755
--- a/src/cairo-scaled-font.c
+++ b/src/cairo-scaled-font.c
@@ -698,7 +698,7 @@ cairo_scaled_font_text_extents (cairo_sc
  **/
 void
 cairo_scaled_font_glyph_extents (cairo_scaled_font_t   *scaled_font,
-				 cairo_glyph_t         *glyphs,
+				 const cairo_glyph_t   *glyphs,
 				 int                    num_glyphs,
 				 cairo_text_extents_t  *extents)
 {
@@ -891,7 +891,7 @@ _cairo_scaled_font_show_glyphs (cairo_sc
 				int			dest_y,
 				unsigned int		width,
 				unsigned int		height,
-				const cairo_glyph_t    *glyphs,
+				cairo_glyph_t	       *glyphs,
 				int                     num_glyphs)
 {
     cairo_status_t status;
diff --git a/src/cairo-surface-fallback-private.h b/src/cairo-surface-fallback-private.h
index 89a11cb..e0f83c4 100644
--- a/src/cairo-surface-fallback-private.h
+++ b/src/cairo-surface-fallback-private.h
@@ -74,7 +74,7 @@ cairo_private cairo_status_t
 _cairo_surface_fallback_show_glyphs (cairo_surface_t		*surface,
 				     cairo_operator_t		 op,
 				     cairo_pattern_t		*source,
-				     const cairo_glyph_t	*glyphs,
+				     cairo_glyph_t		*glyphs,
 				     int			 num_glyphs,
 				     cairo_scaled_font_t	*scaled_font);
 
diff --git a/src/cairo-surface-fallback.c b/src/cairo-surface-fallback.c
index 2d23411..02033c8 100644
--- a/src/cairo-surface-fallback.c
+++ b/src/cairo-surface-fallback.c
@@ -839,7 +839,7 @@ _cairo_surface_fallback_fill (cairo_surf
 
 typedef struct {
     cairo_scaled_font_t *font;
-    const cairo_glyph_t *glyphs;
+    cairo_glyph_t *glyphs;
     int num_glyphs;
 } cairo_show_glyphs_info_t;
 
@@ -907,7 +907,7 @@ cairo_status_t
 _cairo_surface_fallback_show_glyphs (cairo_surface_t		*surface,
 				     cairo_operator_t		 op,
 				     cairo_pattern_t		*source,
-				     const cairo_glyph_t	*glyphs,
+				     cairo_glyph_t		*glyphs,
 				     int			 num_glyphs,
 				     cairo_scaled_font_t	*scaled_font)
 {
diff --git a/src/cairo-surface.c b/src/cairo-surface.c
index dfcf39d..6690971 100644
--- a/src/cairo-surface.c
+++ b/src/cairo-surface.c
@@ -1795,7 +1795,7 @@ cairo_status_t
 _cairo_surface_show_glyphs (cairo_surface_t	*surface,
 			    cairo_operator_t	 op,
 			    cairo_pattern_t	*source,
-			    const cairo_glyph_t	*glyphs,
+			    cairo_glyph_t	*glyphs,
 			    int			 num_glyphs,
 			    cairo_scaled_font_t	*scaled_font)
 {
@@ -1873,7 +1873,7 @@ _cairo_surface_old_show_glyphs (cairo_sc
 				int			 dest_y,
 				unsigned int		 width,
 				unsigned int		 height,
-				const cairo_glyph_t	*glyphs,
+				cairo_glyph_t		*glyphs,
 				int			 num_glyphs)
 {
     cairo_status_t status;
diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c
index 0ca0e72..573fb3c 100644
--- a/src/cairo-svg-surface.c
+++ b/src/cairo-svg-surface.c
@@ -1608,7 +1608,7 @@ static cairo_int_status_t
 _cairo_svg_surface_show_glyphs (void			*abstract_surface,
 				cairo_operator_t	 op,
 				cairo_pattern_t		*pattern,
-				const cairo_glyph_t	*glyphs,
+				cairo_glyph_t		*glyphs,
 				int			 num_glyphs,
 				cairo_scaled_font_t	*scaled_font)
 {
diff --git a/src/cairo-win32-font.c b/src/cairo-win32-font.c
index 58b4dd1..139a73b 100644
--- a/src/cairo-win32-font.c
+++ b/src/cairo-win32-font.c
@@ -1151,7 +1151,7 @@ _cairo_win32_scaled_font_show_glyphs (vo
 				      int			dest_y,
 				      unsigned int		width,
 				      unsigned int		height,
-				      const cairo_glyph_t      *glyphs,
+				      cairo_glyph_t	       *glyphs,
 				      int                 	num_glyphs)
 {
     cairo_win32_scaled_font_t *scaled_font = abstract_font;
diff --git a/src/cairo-win32-surface.c b/src/cairo-win32-surface.c
index a90f867..8b34549 100644
--- a/src/cairo-win32-surface.c
+++ b/src/cairo-win32-surface.c
@@ -1473,7 +1473,7 @@ static cairo_int_status_t
 _cairo_win32_surface_show_glyphs (void			*surface,
 				  cairo_operator_t	 op,
 				  cairo_pattern_t	*source,
-				  const cairo_glyph_t	*glyphs,
+				  cairo_glyph_t		*glyphs,
 				  int			 num_glyphs,
 				  cairo_scaled_font_t	*scaled_font)
 {
diff --git a/src/cairo-xcb-surface.c b/src/cairo-xcb-surface.c
index 9c34879..8b8ba1d 100644
--- a/src/cairo-xcb-surface.c
+++ b/src/cairo-xcb-surface.c
@@ -1574,7 +1574,7 @@ static cairo_int_status_t
 _cairo_xcb_surface_show_glyphs (void                *abstract_dst,
 				 cairo_operator_t     op,
 				 cairo_pattern_t     *src_pattern,
-				 const cairo_glyph_t *glyphs,
+				 cairo_glyph_t       *glyphs,
 				 int		      num_glyphs,
 				 cairo_scaled_font_t *scaled_font);
 
@@ -2260,7 +2260,7 @@ static cairo_int_status_t
 _cairo_xcb_surface_show_glyphs (void                *abstract_dst,
 				 cairo_operator_t     op,
 				 cairo_pattern_t     *src_pattern,
-				 const cairo_glyph_t *glyphs,
+				 cairo_glyph_t       *glyphs,
 				 int		      num_glyphs,
 				 cairo_scaled_font_t *scaled_font)
 {
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index 4e7f640..5482a2f 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -69,7 +69,7 @@ static cairo_int_status_t
 _cairo_xlib_surface_show_glyphs (void                *abstract_dst,
 				 cairo_operator_t     op,
 				 cairo_pattern_t     *src_pattern,
-				 const cairo_glyph_t *glyphs,
+				 cairo_glyph_t       *glyphs,
 				 int		      num_glyphs,
 				 cairo_scaled_font_t *scaled_font);
 
@@ -2689,7 +2689,7 @@ static cairo_int_status_t
 _cairo_xlib_surface_show_glyphs (void                *abstract_dst,
 				 cairo_operator_t     op,
 				 cairo_pattern_t     *src_pattern,
-				 const cairo_glyph_t *glyphs,
+				 cairo_glyph_t       *glyphs,
 				 int		      num_glyphs,
 				 cairo_scaled_font_t *scaled_font)
 {
diff --git a/src/cairo.c b/src/cairo.c
index b874777..7546d7a 100644
--- a/src/cairo.c
+++ b/src/cairo.c
@@ -2613,7 +2613,7 @@ cairo_text_extents (cairo_t             
  **/
 void
 cairo_glyph_extents (cairo_t                *cr,
-		     cairo_glyph_t          *glyphs,
+		     const cairo_glyph_t    *glyphs,
 		     int                    num_glyphs,
 		     cairo_text_extents_t   *extents)
 {
@@ -2749,7 +2749,7 @@ cairo_text_path  (cairo_t *cr, const cha
 }
 
 void
-cairo_glyph_path (cairo_t *cr, cairo_glyph_t *glyphs, int num_glyphs)
+cairo_glyph_path (cairo_t *cr, const cairo_glyph_t *glyphs, int num_glyphs)
 {
     if (cr->status)
 	return;
diff --git a/src/cairo.h b/src/cairo.h
index 1b599d5..5e58244 100644
--- a/src/cairo.h
+++ b/src/cairo.h
@@ -954,7 +954,7 @@ cairo_text_extents (cairo_t             
 
 cairo_public void
 cairo_glyph_extents (cairo_t               *cr,
-		     cairo_glyph_t         *glyphs,
+		     const cairo_glyph_t   *glyphs,
 		     int                   num_glyphs,
 		     cairo_text_extents_t  *extents);
 
@@ -962,7 +962,7 @@ cairo_public void
 cairo_text_path  (cairo_t *cr, const char *utf8);
 
 cairo_public void
-cairo_glyph_path (cairo_t *cr, cairo_glyph_t *glyphs, int num_glyphs);
+cairo_glyph_path (cairo_t *cr, const cairo_glyph_t *glyphs, int num_glyphs);
 
 /* Generic identifier for a font style */
 
@@ -1062,7 +1062,7 @@ cairo_scaled_font_text_extents (cairo_sc
 
 cairo_public void
 cairo_scaled_font_glyph_extents (cairo_scaled_font_t   *scaled_font,
-				 cairo_glyph_t         *glyphs,
+				 const cairo_glyph_t   *glyphs,
 				 int                   num_glyphs,
 				 cairo_text_extents_t  *extents);
 
diff --git a/src/cairoint.h b/src/cairoint.h
index e996a1c..b481d45 100755
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -632,7 +632,7 @@ struct _cairo_scaled_font_backend {
 			 int			 dest_y,
 			 unsigned int		 width,
 			 unsigned int		 height,
-			 const cairo_glyph_t	*glyphs,
+			 cairo_glyph_t		*glyphs,
 			 int			 num_glyphs);
 
     cairo_int_status_t
@@ -855,7 +855,7 @@ struct _cairo_surface_backend {
 				 int				 dest_y,
 				 unsigned int			 width,
 				 unsigned int			 height,
-				 const cairo_glyph_t		*glyphs,
+				 cairo_glyph_t			*glyphs,
 				 int				 num_glyphs);
 
     void
@@ -917,7 +917,7 @@ struct _cairo_surface_backend {
     (*show_glyphs)		(void			*surface,
 				 cairo_operator_t	 op,
 				 cairo_pattern_t	*source,
-				 const cairo_glyph_t	*glyphs,
+				 cairo_glyph_t		*glyphs,
 				 int			 num_glyphs,
 				 cairo_scaled_font_t	*scaled_font);
 
@@ -1428,7 +1428,7 @@ _cairo_gstate_text_to_glyphs (cairo_gsta
 
 cairo_private cairo_status_t
 _cairo_gstate_glyph_extents (cairo_gstate_t *gstate,
-			     cairo_glyph_t *glyphs,
+			     const cairo_glyph_t *glyphs,
 			     int num_glyphs,
 			     cairo_text_extents_t *extents);
 
@@ -1438,10 +1438,10 @@ _cairo_gstate_show_glyphs (cairo_gstate_
 			   int num_glyphs);
 
 cairo_private cairo_status_t
-_cairo_gstate_glyph_path (cairo_gstate_t     *gstate,
-			  cairo_glyph_t	     *glyphs,
-			  int		      num_glyphs,
-			  cairo_path_fixed_t *path);
+_cairo_gstate_glyph_path (cairo_gstate_t      *gstate,
+			  const cairo_glyph_t *glyphs,
+			  int		       num_glyphs,
+			  cairo_path_fixed_t  *path);
 
 cairo_private cairo_bool_t
 _cairo_operator_bounded_by_mask (cairo_operator_t op);
@@ -1685,12 +1685,6 @@ _cairo_scaled_font_text_to_glyphs (cairo
 				   int 		        *num_glyphs);
 
 cairo_private cairo_status_t
-_cairo_scaled_font_glyph_extents (cairo_scaled_font_t	*scaled_font,
-				  cairo_glyph_t 	*glyphs,
-				  int 			num_glyphs,
-				  cairo_text_extents_t *extents);
-
-cairo_private cairo_status_t
 _cairo_scaled_font_glyph_device_extents (cairo_scaled_font_t	 *scaled_font,
 					 const cairo_glyph_t	 *glyphs,
 					 int                      num_glyphs,
@@ -1707,7 +1701,7 @@ _cairo_scaled_font_show_glyphs (cairo_sc
 				int		     dest_y,
 				unsigned int	     width,
 				unsigned int	     height,
-				const cairo_glyph_t *glyphs,
+				cairo_glyph_t	    *glyphs,
 				int		     num_glyphs);
 
 cairo_private cairo_status_t
@@ -1858,7 +1852,7 @@ cairo_private cairo_status_t
 _cairo_surface_show_glyphs (cairo_surface_t	*surface,
 			    cairo_operator_t	 op,
 			    cairo_pattern_t	*source,
-			    const cairo_glyph_t	*glyphs,
+			    cairo_glyph_t	*glyphs,
 			    int			 num_glyphs,
 			    cairo_scaled_font_t	*scaled_font);
 
@@ -1957,7 +1951,7 @@ _cairo_surface_old_show_glyphs (cairo_sc
 				int			 dest_y,
 				unsigned int		 width,
 				unsigned int		 height,
-				const cairo_glyph_t	*glyphs,
+				cairo_glyph_t		*glyphs,
 				int			 num_glyphs);
 
 cairo_private cairo_status_t
diff --git a/src/test-meta-surface.c b/src/test-meta-surface.c
index d50119f..7939b6e 100644
--- a/src/test-meta-surface.c
+++ b/src/test-meta-surface.c
@@ -247,7 +247,7 @@ static cairo_int_status_t
 _test_meta_surface_show_glyphs (void			*abstract_surface,
 				cairo_operator_t	 op,
 				cairo_pattern_t		*source,
-				const cairo_glyph_t	*glyphs,
+				cairo_glyph_t		*glyphs,
 				int			 num_glyphs,
 				cairo_scaled_font_t	*scaled_font)
 {
diff --git a/src/test-paginated-surface.c b/src/test-paginated-surface.c
index 4548df5..544efcf 100644
--- a/src/test-paginated-surface.c
+++ b/src/test-paginated-surface.c
@@ -228,7 +228,7 @@ static cairo_int_status_t
 _test_paginated_surface_show_glyphs (void			*abstract_surface,
 				     cairo_operator_t		 op,
 				     cairo_pattern_t		*source,
-				     const cairo_glyph_t	*glyphs,
+				     cairo_glyph_t		*glyphs,
 				     int			 num_glyphs,
 				     cairo_scaled_font_t	*scaled_font)
 {


More information about the cairo-commit mailing list