[cairo-commit] 4 commits - src/cairo-script-surface.c src/cairo-surface-subsurface.c test/xlib-expose-event.c util/cairo-script util/cairo-trace

Chris Wilson ickle at kemper.freedesktop.org
Wed Apr 28 01:56:03 PDT 2010


 src/cairo-script-surface.c                 |   84 ++++++++++++++++++++---------
 src/cairo-surface-subsurface.c             |   22 ++++---
 test/xlib-expose-event.c                   |   76 +++-----------------------
 util/cairo-script/cairo-script-operators.c |   33 +++++++++++
 util/cairo-trace/trace.c                   |   36 ++++++++++++
 5 files changed, 148 insertions(+), 103 deletions(-)

New commits:
commit 6a99e83c50d715ba1e47aa5c7be714a423568e57
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Apr 28 09:55:20 2010 +0100

    subsurface: Mark the image as !clear after copying.

diff --git a/src/cairo-surface-subsurface.c b/src/cairo-surface-subsurface.c
index 93754aa..3d6d4a5 100644
--- a/src/cairo-surface-subsurface.c
+++ b/src/cairo-surface-subsurface.c
@@ -293,7 +293,7 @@ _cairo_surface_subsurface_acquire_source_image (void                    *abstrac
 	goto CLEANUP;
 
     /* only copy if we need to perform sub-byte manipulation */
-    if (PIXMAN_FORMAT_BPP (extra->image->pixman_format) > 8) {
+    if (PIXMAN_FORMAT_BPP (extra->image->pixman_format) >= 8) {
 	assert ((PIXMAN_FORMAT_BPP (extra->image->pixman_format) % 8) == 0);
 
 	data = extra->image->data + surface->extents.y * extra->image->stride;
@@ -325,6 +325,8 @@ _cairo_surface_subsurface_acquire_source_image (void                    *abstrac
                                   surface->extents.width, surface->extents.height);
     }
 
+    image->base.is_clear = FALSE;
+
     *image_out = image;
     *extra_out = extra;
     return CAIRO_STATUS_SUCCESS;
@@ -372,15 +374,15 @@ _cairo_surface_subsurface_snapshot (void *abstract_surface)
 							surface->extents.width,
 							surface->extents.height,
 							0);
-    if (unlikely (clone->base.status))
-	return &clone->base;
-
-    pixman_image_composite32 (PIXMAN_OP_SRC,
-                              image->pixman_image, NULL, clone->pixman_image,
-                              surface->extents.x, surface->extents.y,
-                              0, 0,
-                              0, 0,
-                              surface->extents.width, surface->extents.height);
+    if (likely (clone->base.status == CAIRO_STATUS_SUCCESS)) {
+	pixman_image_composite32 (PIXMAN_OP_SRC,
+				  image->pixman_image, NULL, clone->pixman_image,
+				  surface->extents.x, surface->extents.y,
+				  0, 0,
+				  0, 0,
+				  surface->extents.width, surface->extents.height);
+	clone->base.is_clear = FALSE;
+    }
 
     _cairo_surface_release_source_image (surface->target, image, image_extra);
 
commit ca3df75e8f876991f2dc9e85c9daa3fd96e826d2
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Apr 28 09:54:56 2010 +0100

    script: Reconstruct subsurfaces.

diff --git a/src/cairo-script-surface.c b/src/cairo-script-surface.c
index c505499..ac49178 100644
--- a/src/cairo-script-surface.c
+++ b/src/cairo-script-surface.c
@@ -54,6 +54,8 @@
 #include "cairo-output-stream-private.h"
 #include "cairo-scaled-font-private.h"
 #include "cairo-surface-clipper-private.h"
+#include "cairo-surface-snapshot-private.h"
+#include "cairo-surface-subsurface-private.h"
 #include "cairo-surface-wrapper-private.h"
 
 #if CAIRO_HAS_FT_FONT
@@ -958,19 +960,14 @@ _emit_radial_pattern (cairo_script_surface_t *surface,
 
 static cairo_status_t
 _emit_recording_surface_pattern (cairo_script_surface_t *surface,
-				 const cairo_pattern_t *pattern)
+				 cairo_recording_surface_t *source)
 {
     cairo_script_implicit_context_t old_cr;
-    cairo_surface_pattern_t *surface_pattern;
-    cairo_recording_surface_t *source;
     cairo_script_surface_t *similar;
     cairo_status_t status;
     cairo_box_t bbox;
     cairo_rectangle_int_t rect;
 
-    surface_pattern = (cairo_surface_pattern_t *) pattern;
-    source = (cairo_recording_surface_t *) surface_pattern->surface;
-
     /* first measure the extents */
     status = _cairo_recording_surface_get_bbox (source, &bbox, NULL);
     if (unlikely (status))
@@ -1011,7 +1008,7 @@ _emit_recording_surface_pattern (cairo_script_surface_t *surface,
     cairo_list_del (&similar->operand.link);
     assert (target_is_active (surface));
 
-    _cairo_output_stream_puts (to_context (surface)->stream, "pop pattern");
+    _cairo_output_stream_puts (to_context (surface)->stream, "pop");
     cairo_surface_destroy (&similar->base);
 
     return CAIRO_STATUS_SUCCESS;
@@ -1019,16 +1016,9 @@ _emit_recording_surface_pattern (cairo_script_surface_t *surface,
 
 static cairo_status_t
 _emit_script_surface_pattern (cairo_script_surface_t *surface,
-			      const cairo_pattern_t *pattern)
+			      cairo_script_surface_t *source)
 {
-    cairo_surface_pattern_t *surface_pattern;
-    cairo_script_surface_t *source;
-
-    surface_pattern = (cairo_surface_pattern_t *) pattern;
-    source = (cairo_script_surface_t *) surface_pattern->surface;
-
     _get_target (source);
-    _cairo_output_stream_puts (to_context (surface)->stream, "pattern");
 
     return CAIRO_STATUS_SUCCESS;
 }
@@ -1227,7 +1217,7 @@ _emit_image_surface (cairo_script_surface_t *surface,
 					 (cairo_user_data_key_t *) ctx))
     {
 	_cairo_output_stream_printf (ctx->stream,
-				     "s%u pattern ",
+				     "s%u ",
 				     image->base.unique_id);
 	return CAIRO_STATUS_SUCCESS;
     }
@@ -1364,16 +1354,13 @@ _emit_image_surface (cairo_script_surface_t *surface,
 	_cairo_output_stream_puts (ctx->stream, "~> set-mime-data\n");
     }
 
-    _cairo_output_stream_puts (ctx->stream, "pattern");
-
     return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_status_t
 _emit_image_surface_pattern (cairo_script_surface_t *surface,
-			     const cairo_pattern_t *pattern)
+			     cairo_surface_t *source)
 {
-    cairo_surface_pattern_t *surface_pattern;
     cairo_surface_t *snapshot;
     cairo_image_surface_t *image;
     cairo_status_t status;
@@ -1382,8 +1369,7 @@ _emit_image_surface_pattern (cairo_script_surface_t *surface,
     /* XXX keeping a copy is nasty, but we want to hook into the surface's
      * lifetime. Using a snapshot is a convenient method.
      */
-    surface_pattern = (cairo_surface_pattern_t *) pattern;
-    snapshot = _cairo_surface_snapshot (surface_pattern->surface);
+    snapshot = _cairo_surface_snapshot (source);
     status = _cairo_surface_acquire_source_image (snapshot, &image, &extra);
     if (likely (status == CAIRO_STATUS_SUCCESS)) {
 	status = _emit_image_surface (surface, image);
@@ -1395,24 +1381,68 @@ _emit_image_surface_pattern (cairo_script_surface_t *surface,
 }
 
 static cairo_status_t
+_emit_subsurface_pattern (cairo_script_surface_t *surface,
+			  cairo_surface_subsurface_t *sub)
+{
+    cairo_surface_t *source = sub->target;
+    cairo_status_t status;
+
+    switch ((int) source->backend->type) {
+    case CAIRO_SURFACE_TYPE_RECORDING:
+	status = _emit_recording_surface_pattern (surface, (cairo_recording_surface_t *) source);
+	break;
+    case CAIRO_SURFACE_TYPE_SCRIPT:
+	status = _emit_script_surface_pattern (surface, (cairo_script_surface_t *) source);
+	break;
+    default:
+	status = _emit_image_surface_pattern (surface, source);
+	break;
+    }
+    if (unlikely (status))
+	return status;
+
+    _cairo_output_stream_printf (to_context (surface)->stream,
+				 "%d %d %d %d subsurface ",
+				 sub->extents.x,
+				 sub->extents.y,
+				 sub->extents.width,
+				 sub->extents.height);
+    return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_status_t
 _emit_surface_pattern (cairo_script_surface_t *surface,
 		       const cairo_pattern_t *pattern)
 {
     cairo_surface_pattern_t *surface_pattern;
     cairo_surface_t *source;
+    cairo_status_t status;
 
     surface_pattern = (cairo_surface_pattern_t *) pattern;
     source = surface_pattern->surface;
 
-    /* XXX true subsurface support. */
+    if (source->backend->type == CAIRO_INTERNAL_SURFACE_TYPE_SNAPSHOT)
+	source = ((cairo_surface_snapshot_t *) source)->target;
+
     switch ((int) source->backend->type) {
     case CAIRO_SURFACE_TYPE_RECORDING:
-	return _emit_recording_surface_pattern (surface, pattern);
+	status = _emit_recording_surface_pattern (surface, (cairo_recording_surface_t *) source);
+	break;
     case CAIRO_SURFACE_TYPE_SCRIPT:
-	return _emit_script_surface_pattern (surface, pattern);
+	status = _emit_script_surface_pattern (surface, (cairo_script_surface_t *) source);
+	break;
+    case CAIRO_INTERNAL_SURFACE_TYPE_SUBSURFACE:
+	status = _emit_subsurface_pattern (surface, (cairo_surface_subsurface_t *) source);
+	break;
     default:
-	return _emit_image_surface_pattern (surface, pattern);
+	status = _emit_image_surface_pattern (surface, source);
+	break;
     }
+    if (unlikely (status))
+	return status;
+
+    _cairo_output_stream_puts (to_context (surface)->stream, "pattern");
+    return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_status_t
@@ -2824,6 +2854,8 @@ _emit_scaled_glyph_bitmap (cairo_script_surface_t *surface,
     if (unlikely (status))
 	return status;
 
+    _cairo_output_stream_puts (ctx->stream, "pattern ");
+
     if (! _cairo_matrix_is_identity (&scaled_font->font_matrix)) {
 	_cairo_output_stream_printf (ctx->stream,
 				     "\n  [%f %f %f %f %f %f] set-matrix\n",
commit 0f0d349a400e097856e6d9863e66c0a041e65c35
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Apr 28 09:54:37 2010 +0100

    trace: Wrap cairo_surface_create_for_region()

diff --git a/util/cairo-script/cairo-script-operators.c b/util/cairo-script/cairo-script-operators.c
index e2f12b1..d1685e5 100644
--- a/util/cairo-script/cairo-script-operators.c
+++ b/util/cairo-script/cairo-script-operators.c
@@ -5274,6 +5274,38 @@ _similar (csi_t *ctx)
 }
 
 static csi_status_t
+_subsurface (csi_t *ctx)
+{
+    csi_object_t obj;
+    long x, y, width, height;
+    cairo_surface_t *target;
+    csi_status_t status;
+
+    check (5);
+
+    status = _csi_ostack_get_integer (ctx, 0, &height);
+    if (_csi_unlikely (status))
+	return status;
+    status = _csi_ostack_get_integer (ctx, 1, &width);
+    if (_csi_unlikely (status))
+	return status;
+    status = _csi_ostack_get_integer (ctx, 2, &y);
+    if (_csi_unlikely (status))
+	return status;
+    status = _csi_ostack_get_integer (ctx, 3, &x);
+    if (_csi_unlikely (status))
+	return status;
+    status = _csi_ostack_get_surface (ctx, 4, &target);
+    if (_csi_unlikely (status))
+	return status;
+
+    obj.type = CSI_OBJECT_TYPE_SURFACE;
+    obj.datum.surface = cairo_surface_create_for_region (target, x, y, width, height);
+    pop (5);
+    return push (&obj);
+}
+
+static csi_status_t
 _show_text (csi_t *ctx)
 {
     csi_status_t status;
@@ -6051,6 +6083,7 @@ _defs[] = {
     { "sin", NULL },
     { "sqrt", NULL },
     { "sub", _sub },
+    { "subsurface", _subsurface },
     { "surface", _surface },
     { "string", NULL },
     { "stroke", _stroke },
diff --git a/util/cairo-trace/trace.c b/util/cairo-trace/trace.c
index b19d670..01eadf4 100644
--- a/util/cairo-trace/trace.c
+++ b/util/cairo-trace/trace.c
@@ -3494,6 +3494,42 @@ cairo_surface_create_similar (cairo_surface_t *other,
     return ret;
 }
 
+cairo_surface_t *
+cairo_surface_create_for_region (cairo_surface_t *target,
+				 int x, int y,
+				 int width, int height)
+{
+    cairo_surface_t *ret;
+    long surface_id;
+
+    _enter_trace ();
+
+    ret = DLCALL (cairo_surface_create_for_region, target, x, y, width, height);
+    surface_id = _create_surface_id (ret);
+
+    _emit_line_info ();
+    if (target != NULL && _write_lock ()) {
+	Object *obj;
+
+	obj = _get_object (SURFACE, target);
+	if (obj->defined)
+	    _trace_printf ("s%ld ", obj->token);
+	else if (current_stack_depth == obj->operand + 1)
+	    _trace_printf ("dup ");
+	else
+	    _trace_printf ("%d index ", current_stack_depth - obj->operand - 1);
+	_trace_printf ("%d %d %d %d subsurface %% s%ld\n",
+		       x, y, width, height,
+		       surface_id);
+
+	_push_operand (SURFACE, ret);
+	_write_unlock ();
+    }
+
+    _exit_trace ();
+    return ret;
+}
+
 static void CAIRO_PRINTF_FORMAT(2, 3)
 _emit_surface_op (cairo_surface_t *surface, const char *fmt, ...)
 {
commit 80fc2a8e49aa6ab4646b14eed9a4cf348a9149b4
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Apr 28 09:50:49 2010 +0100

    test: Expand xlib-expose-event to cover all backends
    
    Use a similar surface to create an equivalent backing surface for
    any backend, thus enabling the test to run against any target.
    
    The comment about forcing fallbacks has long since been false.

diff --git a/test/xlib-expose-event.c b/test/xlib-expose-event.c
index fb1950e..091fef5 100644
--- a/test/xlib-expose-event.c
+++ b/test/xlib-expose-event.c
@@ -36,11 +36,8 @@
 #include <stdlib.h>
 
 #include "cairo.h"
-#include "cairo-xlib.h"
 #include "cairo-test.h"
 
-#include "cairo-boilerplate-xlib.h"
-
 #include "buffer-diff.h"
 
 #define SIZE 160
@@ -48,31 +45,6 @@
 
 static const char *png_filename = "romedalen.png";
 
-static cairo_bool_t
-check_visual (Display *dpy)
-{
-    Visual *visual = DefaultVisual (dpy, DefaultScreen (dpy));
-
-    if ((visual->red_mask   == 0xff0000 &&
-	 visual->green_mask == 0x00ff00 &&
-	 visual->blue_mask  == 0x0000ff) ||
-	(visual->red_mask   == 0x0000ff &&
-	 visual->green_mask == 0x00ff00 &&
-	 visual->blue_mask  == 0xff0000))
-	return 1;
-    else
-	return 0;
-}
-
-static void
-clear (cairo_surface_t *surface)
-{
-    cairo_t *cr = cairo_create (surface);
-    cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
-    cairo_paint (cr);
-    cairo_destroy (cr);
-}
-
 static void
 draw_mask (cairo_t *cr)
 {
@@ -82,14 +54,9 @@ draw_mask (cairo_t *cr)
     surface = cairo_surface_create_similar (cairo_get_group_target (cr),
 	                                    CAIRO_CONTENT_ALPHA,
 					    50, 50);
-    cairo_boilerplate_xlib_surface_disable_render (surface);
-
     cr2 = cairo_create (surface);
     cairo_surface_destroy (surface);
 
-    /* This complex clip and forcing of fallbacks is to reproduce bug
-     * http://bugs.freedesktop.org/show_bug.cgi?id=10921
-     */
     cairo_rectangle (cr2,
 	             0, 0,
 	             40, 40);
@@ -151,11 +118,11 @@ draw_image (const cairo_test_context_t *ctx, cairo_t *cr)
 
 static void
 draw (const cairo_test_context_t *ctx,
-      cairo_surface_t *surface,
+      cairo_t *cr,
       cairo_rectangle_t *region,
       int n_regions)
 {
-    cairo_t *cr = cairo_create (surface);
+    cairo_save (cr);
     if (region != NULL) {
 	int i;
 	for (i = 0; i < n_regions; i++) {
@@ -171,42 +138,20 @@ draw (const cairo_test_context_t *ctx,
     cairo_pop_group_to_source (cr);
     cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
     cairo_paint (cr);
-    cairo_destroy (cr);
+    cairo_restore (cr);
 }
 
 static cairo_test_status_t
 draw_func (cairo_t *cr, int width, int height)
 {
-    Display *dpy;
-    Drawable drawable;
-    int screen;
-    cairo_surface_t *surface;
     cairo_rectangle_t region[4];
-    int i, j;
     const cairo_test_context_t *ctx;
-    
-    ctx = cairo_test_get_context (cr);
-    surface = cairo_get_target (cr);
-
-    if (cairo_surface_get_type (surface) != CAIRO_SURFACE_TYPE_XLIB)
-        return CAIRO_TEST_UNTESTED;
-
-    dpy = cairo_xlib_surface_get_display (surface);
+    int i, j;
 
-    if (! check_visual (dpy)) {
-	cairo_test_log (ctx, "xlib-expose-event: default visual is not RGB24 or BGR24, skipping\n");
-        return CAIRO_TEST_UNTESTED;
-    }
+    ctx = cairo_test_get_context (cr);
 
-    screen = DefaultScreen (dpy);
-    drawable = XCreatePixmap (dpy, DefaultRootWindow (dpy),
-			      SIZE, SIZE, DefaultDepth (dpy, screen));
-    surface = cairo_xlib_surface_create (dpy,
-					 drawable,
-					 DefaultVisual (dpy, screen),
-					 SIZE, SIZE);
-    clear (surface);
-    draw (ctx, surface, NULL, 0);
+    cairo_push_group_with_content (cr, CAIRO_CONTENT_COLOR);
+    draw (ctx, cr, NULL, 0);
     for (i = 0; i < NLOOPS; i++) {
 	for (j = 0; j < NLOOPS; j++) {
 	    region[0].x = i * SIZE / NLOOPS;
@@ -229,17 +174,14 @@ draw_func (cairo_t *cr, int width, int height)
 	    region[3].width = SIZE / 4;
 	    region[3].height = SIZE / 4;
 
-	    draw (ctx, surface, region, 4);
+	    draw (ctx, cr, region, 4);
 	}
     }
 
-    cairo_set_source_surface (cr, surface, 0, 0);
-    cairo_surface_destroy (surface);
+    cairo_pop_group_to_source (cr);
     cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
     cairo_paint (cr);
 
-    XFreePixmap (dpy, drawable);
-
     return CAIRO_TEST_SUCCESS;
 }
 


More information about the cairo-commit mailing list