[cairo-commit] 2 commits - src/cairo-xlib-surface.c

Carl Worth cworth at kemper.freedesktop.org
Thu May 18 17:31:01 PDT 2006


 src/cairo-xlib-surface.c |  295 ++++++++++++++++++++++++++---------------------
 1 files changed, 168 insertions(+), 127 deletions(-)

New commits:
diff-tree 92a015ff8ec5c11aac6d9c0c6702fa4873c04381 (from 108431414faa8792659616bae35584b8fced3b21)
Author: Vladimir Vukicevic <vladimir at cyclone.vlad1.com>
Date:   Mon Mar 27 13:49:58 2006 -0800

    [xlib] only do glyph extents computation if non-solid source.
    
    xlib_show_glyphs was always calculating the glyph extents, even when it
    didn't need to; this only does it when necessary.
    
    Also adds an implementation of surface_flush() for xlib that just calls
    XSync.
    (cherry picked from 8770ac5b5cdba8007c4c6a6a980e6e06acf6aeb6 commit)

diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index df85239..2bf60ad 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -1715,9 +1715,14 @@ _cairo_xlib_surface_get_font_options (vo
     cairo_xlib_surface_t *surface = abstract_surface;
   
     *options = surface->screen_info->font_options;
-    
-    if (_surface_has_alpha (surface) && options->antialias == CAIRO_ANTIALIAS_SUBPIXEL)
-	options->antialias = CAIRO_ANTIALIAS_GRAY;
+}
+
+static cairo_status_t
+_cairo_xlib_surface_flush (void *abstract_surface)
+{
+    cairo_xlib_surface_t *surface = abstract_surface;
+    XSync (surface->dpy, False);
+    return CAIRO_STATUS_SUCCESS;
 }
 
 static void
@@ -1746,7 +1751,7 @@ static const cairo_surface_backend_t cai
     _cairo_xlib_surface_get_extents,
     NULL, /* old_show_glyphs */
     _cairo_xlib_surface_get_font_options,
-    NULL, /* flush */
+    _cairo_xlib_surface_flush,
     NULL, /* mark_dirty_rectangle */
     _cairo_xlib_surface_scaled_font_fini,
     _cairo_xlib_surface_scaled_glyph_fini,
@@ -2571,8 +2576,6 @@ _cairo_xlib_surface_show_glyphs (void   
     cairo_scaled_glyph_t *scaled_glyph;
     cairo_xlib_surface_font_private_t *font_private;
 
-    cairo_rectangle_fixed_t glyph_extents;
-
     int i;
     unsigned long max_index = 0;
 
@@ -2617,13 +2620,6 @@ _cairo_xlib_surface_show_glyphs (void   
 	(font_private != NULL && font_private->dpy != dst->dpy))
 	return CAIRO_INT_STATUS_UNSUPPORTED;
 
-    status = _cairo_scaled_font_glyph_device_extents (scaled_font,
-                                                      glyphs,
-                                                      num_glyphs,
-                                                      &glyph_extents);
-    if (status)
-        return status;
-
     /* PictOpClear doesn't seem to work with CompositeText; it seems to ignore
      * the mask (the glyphs).  This code below was executed as a side effect
      * of going through the _clip_and_composite fallback code for old_show_glyphs,
@@ -2635,11 +2631,28 @@ _cairo_xlib_surface_show_glyphs (void   
 	op = CAIRO_OPERATOR_DEST_OUT;
     }
 
-    status = _cairo_pattern_acquire_surface (src_pattern, &dst->base,
-                                             glyph_extents.x, glyph_extents.y,
-                                             glyph_extents.width, glyph_extents.height,
-                                             (cairo_surface_t **) &src,
-                                             &attributes);
+    if (src_pattern->type == CAIRO_PATTERN_TYPE_SOLID) {
+        status = _cairo_pattern_acquire_surface (src_pattern, &dst->base,
+                                                 0, 0, 1, 1,
+                                                 (cairo_surface_t **) &src,
+                                                 &attributes);
+    } else {
+        cairo_rectangle_fixed_t glyph_extents;
+
+        status = _cairo_scaled_font_glyph_device_extents (scaled_font,
+                                                          glyphs,
+                                                          num_glyphs,
+                                                          &glyph_extents);
+        if (status)
+            return status;
+
+        status = _cairo_pattern_acquire_surface (src_pattern, &dst->base,
+                                                 glyph_extents.x, glyph_extents.y,
+                                                 glyph_extents.width, glyph_extents.height,
+                                                 (cairo_surface_t **) &src,
+                                                 &attributes);
+    }
+
     if (status)
         goto FAIL;
 
diff-tree 108431414faa8792659616bae35584b8fced3b21 (from 3487191b2230571323201ed045263433e77e5345)
Author: Vladimir Vukicevic <vladimir at pobox.com>
Date:   Wed Mar 8 21:08:57 2006 -0800

    [xlib] implement _cairo_xlib_surface_show_glyphs
    
    Avoid using the fallback paths as much as possible; implement real
    show_glyphs, falling back for OPERATOR_SOURCE (due to Render bug), and all
    unbounded operators (let the fallback code deal with fixup).  Also fall
    back if we have a fallback mask clip set.
    
    (cherry picked from 3225a4ec820fd4051dd893ffc4258b182bd62dca commit)

diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index 3d528bf..df85239 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -40,6 +40,7 @@
 #include "cairo-xlib-xrender.h"
 #include "cairo-xlib-test.h"
 #include "cairo-xlib-private.h"
+#include "cairo-clip-private.h"
 #include <X11/extensions/Xrender.h>
 #include <X11/extensions/renderproto.h>
 
@@ -64,6 +65,14 @@ _cairo_surface_is_xlib (cairo_surface_t 
 static cairo_bool_t
 _native_byte_order_lsb (void);
 
+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,
+				 int		      num_glyphs,
+				 cairo_scaled_font_t *scaled_font);
+
 /*
  * Instead of taking two round trips for each blending request,
  * assume that if a particular drawable fails GetImage that it will
@@ -1711,20 +1720,6 @@ _cairo_xlib_surface_get_font_options (vo
 	options->antialias = CAIRO_ANTIALIAS_GRAY;
 }
 
-static cairo_int_status_t
-_cairo_xlib_surface_old_show_glyphs (cairo_scaled_font_t	*scaled_font,
-				     cairo_operator_t		 op,
-				     cairo_pattern_t		*pattern,
-				     void			*abstract_surface,
-				     int			 source_x,
-				     int			 source_y,
-				     int			 dest_x,
-				     int			 dest_y,
-				     unsigned int		 width,
-				     unsigned int		 height,
-				     const cairo_glyph_t	*glyphs,
-				     int			 num_glyphs);
-
 static void
 _cairo_xlib_surface_scaled_font_fini (cairo_scaled_font_t *scaled_font);
 
@@ -1749,12 +1744,19 @@ static const cairo_surface_backend_t cai
     _cairo_xlib_surface_set_clip_region,
     NULL, /* intersect_clip_path */
     _cairo_xlib_surface_get_extents,
-    _cairo_xlib_surface_old_show_glyphs,
+    NULL, /* old_show_glyphs */
     _cairo_xlib_surface_get_font_options,
     NULL, /* flush */
     NULL, /* mark_dirty_rectangle */
     _cairo_xlib_surface_scaled_font_fini,
     _cairo_xlib_surface_scaled_glyph_fini,
+
+    NULL, /* paint */
+    NULL, /* mask */
+    NULL, /* stroke */
+    NULL, /* fill */
+    _cairo_xlib_surface_show_glyphs,
+    NULL  /* snapshot */
 };
 
 /**
@@ -2363,14 +2365,13 @@ _cairo_xlib_surface_add_glyph (Display *
 #define N_STACK_BUF 1024
 
 static cairo_status_t
-_cairo_xlib_surface_old_show_glyphs8  (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_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_font_private_t *font_private = scaled_font->surface_private;
     XGlyphElt8 *elts = NULL;
@@ -2409,13 +2410,13 @@ _cairo_xlib_surface_old_show_glyphs8  (c
 	lastY = thisY;
     }
 
-    XRenderCompositeText8  (self->dpy,
+    XRenderCompositeText8  (dst->dpy,
 			    _render_operator (op),
 			    src->src_picture,
-			    self->dst_picture,
+			    dst->dst_picture,
 			    font_private->xrender_format,
-			    source_x + elts[0].xOff, source_y + elts[0].yOff,
-			    0, 0,
+                            src_x_offset + elts[0].xOff, src_y_offset + elts[0].yOff,
+                            elts[0].xOff, elts[0].yOff,
 			    elts, num_glyphs);
 
     if (elts != stack_elts)
@@ -2425,14 +2426,13 @@ _cairo_xlib_surface_old_show_glyphs8  (c
 }
 
 static cairo_status_t
-_cairo_xlib_surface_old_show_glyphs16 (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_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_font_private_t *font_private = scaled_font->surface_private;
     XGlyphElt16 *elts = NULL;
@@ -2471,13 +2471,13 @@ _cairo_xlib_surface_old_show_glyphs16 (c
 	lastY = thisY;
     }
 
-    XRenderCompositeText16 (self->dpy,
+    XRenderCompositeText16 (dst->dpy,
 			    _render_operator (op),
 			    src->src_picture,
-			    self->dst_picture,
+			    dst->dst_picture,
 			    font_private->xrender_format,
-			    source_x + elts[0].xOff, source_y + elts[0].yOff,
-			    0, 0,
+                            src_x_offset + elts[0].xOff, src_y_offset + elts[0].yOff,
+                            elts[0].xOff, elts[0].yOff,
 			    elts, num_glyphs);
 
     if (elts != stack_elts)
@@ -2487,14 +2487,13 @@ _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_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;
@@ -2533,13 +2532,13 @@ _cairo_xlib_surface_old_show_glyphs32 (c
 	lastY = thisY;
     }
 
-    XRenderCompositeText32 (self->dpy,
+    XRenderCompositeText32 (dst->dpy,
 			    _render_operator (op),
 			    src->src_picture,
-			    self->dst_picture,
+			    dst->dst_picture,
 			    font_private->xrender_format,
-			    source_x + elts[0].xOff, source_y + elts[0].yOff,
-			    0, 0,
+                            src_x_offset + elts[0].xOff, src_y_offset + elts[0].yOff,
+                            elts[0].xOff, elts[0].yOff,
 			    elts, num_glyphs);
 
     if (elts != stack_elts)
@@ -2548,63 +2547,113 @@ _cairo_xlib_surface_old_show_glyphs32 (c
     return CAIRO_STATUS_SUCCESS;
 }
 
+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 *);
+
 static cairo_int_status_t
-_cairo_xlib_surface_old_show_glyphs (cairo_scaled_font_t	*scaled_font,
-				     cairo_operator_t		 op,
-				     cairo_pattern_t		*pattern,
-				     void			*abstract_surface,
-				     int			 source_x,
-				     int			 source_y,
-				     int			 dest_x,
-				     int			 dest_y,
-				     unsigned int		 width,
-				     unsigned int		 height,
-				     const cairo_glyph_t	*glyphs,
-				     int			 num_glyphs)
+_cairo_xlib_surface_show_glyphs (void                *abstract_dst,
+				 cairo_operator_t     op,
+				 cairo_pattern_t     *src_pattern,
+				 const cairo_glyph_t *glyphs,
+				 int		      num_glyphs,
+				 cairo_scaled_font_t *scaled_font)
 {
-    cairo_surface_attributes_t	attributes;
-    cairo_int_status_t		status;
-    cairo_xlib_surface_t *self = abstract_surface;
-    cairo_xlib_surface_t *src;
+    cairo_int_status_t status;
+    cairo_xlib_surface_t *dst = (cairo_xlib_surface_t*) abstract_dst;
+
+    composite_operation_t operation;
+    cairo_surface_attributes_t attributes;
+    cairo_xlib_surface_t *src = NULL;
+
     const cairo_glyph_t *glyphs_chunk;
     int glyphs_remaining, chunk_size, max_chunk_size;
-    composite_operation_t operation;
     cairo_scaled_glyph_t *scaled_glyph;
     cairo_xlib_surface_font_private_t *font_private;
+
+    cairo_rectangle_fixed_t glyph_extents;
+
     int i;
     unsigned long max_index = 0;
-    
-    if (!CAIRO_SURFACE_RENDER_HAS_COMPOSITE_TEXT (self) || !self->xrender_format)
+
+    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)
 	return CAIRO_INT_STATUS_UNSUPPORTED;
 
-    operation = _categorize_composite_operation (self, op, pattern, TRUE);
+    /* Just let unbounded operators go through the fallback code
+     * instead of trying to do the fixups here */
+    if (!_cairo_operator_bounded_by_mask (op))
+        return CAIRO_INT_STATUS_UNSUPPORTED;
+
+    /* Render <= 0.10 seems to have a bug with PictOpSrc and glyphs --
+     * the solid source seems to be multiplied by the glyph mask, and
+     * then the entire thing is copied to the destination surface,
+     * including the fully transparent "background" of the rectangular
+     * glyph surface. */
+    if (op == CAIRO_OPERATOR_SOURCE &&
+        !CAIRO_SURFACE_RENDER_AT_LEAST(dst, 0, 11))
+        return CAIRO_INT_STATUS_UNSUPPORTED;
+
+    /* We can only use our code if we either have no clip or
+     * have a real native clip region set.  If we're using
+     * fallback clip masking, we have to go through the full
+     * fallback path.
+     */
+    if (dst->base.clip &&
+        (dst->base.clip->mode != CAIRO_CLIP_MODE_REGION ||
+         dst->base.clip->surface != NULL))
+        return CAIRO_INT_STATUS_UNSUPPORTED;
+
+    operation = _categorize_composite_operation (dst, op, src_pattern, TRUE);
     if (operation == DO_UNSUPPORTED)
 	return CAIRO_INT_STATUS_UNSUPPORTED;
-    
+
     font_private = scaled_font->surface_private;
     if ((scaled_font->surface_backend != NULL &&
 	 scaled_font->surface_backend != &cairo_xlib_surface_backend) ||
-	(font_private != NULL && font_private->dpy != self->dpy))
+	(font_private != NULL && font_private->dpy != dst->dpy))
 	return CAIRO_INT_STATUS_UNSUPPORTED;
 
-    status = _cairo_pattern_acquire_surface (pattern, &self->base,
-					     source_x, source_y, width, height,
-					     (cairo_surface_t **) &src,
-					     &attributes);
+    status = _cairo_scaled_font_glyph_device_extents (scaled_font,
+                                                      glyphs,
+                                                      num_glyphs,
+                                                      &glyph_extents);
     if (status)
-	return status;
+        return status;
 
-    operation = _recategorize_composite_operation (self, op, src, &attributes, TRUE);
+    /* PictOpClear doesn't seem to work with CompositeText; it seems to ignore
+     * the mask (the glyphs).  This code below was executed as a side effect
+     * of going through the _clip_and_composite fallback code for old_show_glyphs,
+     * so PictOpClear was never used with CompositeText before.
+     */
+    if (op == CAIRO_OPERATOR_CLEAR) {
+	_cairo_pattern_init_solid (&solid_pattern.solid, CAIRO_COLOR_WHITE);
+	src_pattern = &solid_pattern.base;
+	op = CAIRO_OPERATOR_DEST_OUT;
+    }
+
+    status = _cairo_pattern_acquire_surface (src_pattern, &dst->base,
+                                             glyph_extents.x, glyph_extents.y,
+                                             glyph_extents.width, glyph_extents.height,
+                                             (cairo_surface_t **) &src,
+                                             &attributes);
+    if (status)
+        goto FAIL;
+
+    operation = _recategorize_composite_operation (dst, op, src, &attributes, TRUE);
     if (operation == DO_UNSUPPORTED) {
 	status = CAIRO_INT_STATUS_UNSUPPORTED;
 	goto FAIL;
     }
-	
+
     status = _cairo_xlib_surface_set_attributes (src, &attributes);
     if (status)
-	goto FAIL;
-    
-    /* Send all unsent glyphs to the server */
+        goto FAIL;
+
+    /* Send all unsent glyphs to the server, and count the max of the glyph indices */
     for (i = 0; i < num_glyphs; i++) {
 	if (glyphs[i].index > max_index)
 	    max_index = glyphs[i].index;
@@ -2615,20 +2664,24 @@ _cairo_xlib_surface_old_show_glyphs (cai
 	if (status != CAIRO_STATUS_SUCCESS)
 	    return status;
 	if (scaled_glyph->surface_private == NULL) {
-	    _cairo_xlib_surface_add_glyph (self->dpy, scaled_font, scaled_glyph);
+	    _cairo_xlib_surface_add_glyph (dst->dpy, scaled_font, scaled_glyph);
 	    scaled_glyph->surface_private = (void *) 1;
 	}
     }
-    
-    _cairo_xlib_surface_ensure_dst_picture (self);
 
-    max_chunk_size = XMaxRequestSize (self->dpy);
-    if (max_index < 256)
+    _cairo_xlib_surface_ensure_dst_picture (dst);
+
+    max_chunk_size = XMaxRequestSize (dst->dpy);
+    if (max_index < 256) {
 	max_chunk_size -= sz_xRenderCompositeGlyphs8Req;
-    else if (max_index < 65536)
+	show_glyphs_func = _cairo_xlib_surface_show_glyphs8;
+    } else if (max_index < 65536) {
 	max_chunk_size -= sz_xRenderCompositeGlyphs16Req;
-    else
+	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 = glyphs;
@@ -2637,43 +2690,18 @@ _cairo_xlib_surface_old_show_glyphs (cai
     {
 	chunk_size = MIN (glyphs_remaining, max_chunk_size);
 
-	/* 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);
-	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);
-	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);
+	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;
     }
 
-    if (status == CAIRO_STATUS_SUCCESS && !_cairo_operator_bounded_by_mask (op)) {
-	cairo_rectangle_fixed_t extents;
-	status = _cairo_scaled_font_glyph_device_extents (scaled_font,
-							  glyphs,
-							  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);
-    }
- FAIL:
-    _cairo_pattern_release_surface (pattern, &src->base, &attributes);
-    
+  FAIL:
+    if (src)
+        _cairo_pattern_release_surface (src_pattern, &src->base, &attributes);
+    if (src_pattern == &solid_pattern.base)
+	_cairo_pattern_fini (&solid_pattern.base);
     return status;
 }
+


More information about the cairo-commit mailing list