[cairo-commit] 2 commits - src/cairo-clip-boxes.c src/cairo-image-compositor.c src/cairo-path-fill.c src/cairo-spans-compositor.c src/cairo-spans-compositor-private.h src/cairo-traps-compositor.c util/cairo-script

Chris Wilson ickle at kemper.freedesktop.org
Fri Sep 30 08:13:50 PDT 2011


 src/cairo-clip-boxes.c               |    6 ++++--
 src/cairo-image-compositor.c         |   34 ++++++++++++++++++++++++++++++++--
 src/cairo-path-fill.c                |   16 +++++++++++-----
 src/cairo-spans-compositor-private.h |    3 +++
 src/cairo-spans-compositor.c         |   17 ++++++-----------
 src/cairo-traps-compositor.c         |   16 +++++++++++++---
 util/cairo-script/csi-exec.c         |   20 +++++++++++++++-----
 7 files changed, 84 insertions(+), 28 deletions(-)

New commits:
commit 538fa0d6fbfe5f03b325e2dfb296538295f3b409
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Sep 30 15:58:14 2011 +0100

    fill: Fix unantialiased rectilinear-fill-to-boxes
    
    We were calling the antialias close function from the unantialiased
    paths - a function that operates on a completely different structure to
    the one passed in.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/cairo-clip-boxes.c b/src/cairo-clip-boxes.c
index 3b8265b..16f5f7f 100644
--- a/src/cairo-clip-boxes.c
+++ b/src/cairo-clip-boxes.c
@@ -142,7 +142,7 @@ _cairo_clip_intersect_rectilinear_path (cairo_clip_t *clip,
 							  fill_rule,
 							  antialias,
 							  &boxes);
-    if (likely (status == CAIRO_STATUS_SUCCESS))
+    if (likely (status == CAIRO_STATUS_SUCCESS && boxes.num_boxes))
 	clip = _cairo_clip_intersect_boxes (clip, &boxes);
     else
 	clip = _cairo_clip_set_all_clipped (clip);
@@ -297,7 +297,9 @@ _cairo_clip_intersect_boxes (cairo_clip_t *clip,
 	boxes = &clip_boxes;
     }
 
-    if (boxes->num_boxes == 1) {
+    if (boxes->num_boxes == 0) {
+	return _cairo_clip_set_all_clipped (clip);
+    } else if (boxes->num_boxes == 1) {
 	clip->boxes = &clip->embedded_box;
 	clip->boxes[0] = boxes->chunks.base[0];
 	clip->num_boxes = 1;
diff --git a/src/cairo-image-compositor.c b/src/cairo-image-compositor.c
index 5c11257..d299c9f 100644
--- a/src/cairo-image-compositor.c
+++ b/src/cairo-image-compositor.c
@@ -1079,7 +1079,7 @@ _cairo_image_bounded_spans (void *abstract_renderer,
 	    pixman_image_compositor_blt (r->compositor,
 					 spans[0].x, y,
 					 spans[1].x - spans[0].x, height,
-					  r->opacity * spans[0].coverage);
+					 r->opacity * spans[0].coverage);
 	}
 	spans++;
     } while (--num_spans > 1);
diff --git a/src/cairo-path-fill.c b/src/cairo-path-fill.c
index 8339307..4000c9c 100644
--- a/src/cairo-path-fill.c
+++ b/src/cairo-path-fill.c
@@ -53,7 +53,6 @@ typedef struct cairo_filler {
     cairo_point_t last_move_to;
 } cairo_filler_t;
 
-
 static cairo_status_t
 _cairo_filler_line_to (void *closure,
 		       const cairo_point_t *point)
@@ -185,15 +184,22 @@ _cairo_filler_ra_line_to (void *closure,
 }
 
 static cairo_status_t
+_cairo_filler_ra_close (void *closure)
+{
+    cairo_filler_ra_t *filler = closure;
+    return _cairo_filler_ra_line_to (closure, &filler->last_move_to);
+}
+
+static cairo_status_t
 _cairo_filler_ra_move_to (void *closure,
 			  const cairo_point_t *point)
 {
-    cairo_filler_t *filler = closure;
+    cairo_filler_ra_t *filler = closure;
     cairo_status_t status;
     cairo_point_t p;
 
     /* close current subpath */
-    status = _cairo_filler_close (closure);
+    status = _cairo_filler_ra_close (closure);
     if (unlikely (status))
 	return status;
 
@@ -228,13 +234,13 @@ _cairo_path_fixed_fill_rectilinear_to_polygon (const cairo_path_fixed_t *path,
     status = _cairo_path_fixed_interpret_flat (path,
 					       _cairo_filler_ra_move_to,
 					       _cairo_filler_ra_line_to,
-					       _cairo_filler_close,
+					       _cairo_filler_ra_close,
 					       &filler,
 					       0.);
     if (unlikely (status))
 	return status;
 
-    return _cairo_filler_close (&filler);
+    return _cairo_filler_ra_close (&filler);
 }
 
 cairo_status_t
diff --git a/src/cairo-traps-compositor.c b/src/cairo-traps-compositor.c
index 012719a..0df3b78 100644
--- a/src/cairo-traps-compositor.c
+++ b/src/cairo-traps-compositor.c
@@ -327,8 +327,10 @@ out:
     return surface;
 
 error:
-    cairo_surface_destroy (surface);
-    surface = _cairo_surface_create_in_error (status);
+    if (status != CAIRO_INT_STATUS_NOTHING_TO_DO) {
+	cairo_surface_destroy (surface);
+	surface = _cairo_surface_create_in_error (status);
+    }
     compositor->release (surface);
     return surface;
 }
@@ -355,6 +357,9 @@ clip_and_composite_with_mask (const cairo_traps_compositor_t *compositor,
     if (unlikely (mask->status))
 	return mask->status;
 
+    if (mask->is_clear)
+	goto skip;
+
     if (src != NULL || dst->content != CAIRO_CONTENT_ALPHA) {
 	compositor->composite (dst, op, src, mask,
 			       extents->bounded.x + src_x,
@@ -369,8 +374,9 @@ clip_and_composite_with_mask (const cairo_traps_compositor_t *compositor,
 			       extents->bounded.x,      extents->bounded.y,
 			       extents->bounded.width,  extents->bounded.height);
     }
-    cairo_surface_destroy (mask);
 
+skip:
+    cairo_surface_destroy (mask);
     return CAIRO_STATUS_SUCCESS;
 }
 
@@ -468,6 +474,9 @@ clip_and_composite_source (const cairo_traps_compositor_t	*compositor,
     if (unlikely (mask->status))
 	return mask->status;
 
+    if (mask->is_clear)
+	goto skip;
+
     if (dst->is_clear) {
 	compositor->composite (dst, CAIRO_OPERATOR_SOURCE, src, mask,
 			       extents->bounded.x + src_x, extents->bounded.y + src_y,
@@ -482,6 +491,7 @@ clip_and_composite_source (const cairo_traps_compositor_t	*compositor,
 			  extents->bounded.width, extents->bounded.height);
     }
 
+skip:
     cairo_surface_destroy (mask);
 
     return CAIRO_STATUS_SUCCESS;
diff --git a/util/cairo-script/csi-exec.c b/util/cairo-script/csi-exec.c
index 23e9c36..d30b1c9 100644
--- a/util/cairo-script/csi-exec.c
+++ b/util/cairo-script/csi-exec.c
@@ -20,12 +20,22 @@ main (int argc, char **argv)
 	.surface_create = _surface_create
     };
     cairo_script_interpreter_t *csi;
-	int status;
     int i;
 
-    csi = cairo_script_interpreter_create ();
-    cairo_script_interpreter_install_hooks (csi, &hooks);
-    for (i = 1; i < argc; i++)
+    for (i = 1; i < argc; i++) {
+	int status, line;
+
+	csi = cairo_script_interpreter_create ();
+	cairo_script_interpreter_install_hooks (csi, &hooks);
 	cairo_script_interpreter_run (csi, argv[i]);
-    return cairo_script_interpreter_destroy (csi);
+	line = cairo_script_interpreter_get_line_number (csi);
+	status = cairo_script_interpreter_destroy (csi);
+	if (status) {
+	    fprintf (stderr, "Error during replay of '%s', line %d: %d\n",
+		     argv[i], line, status);
+	    return 1;
+	}
+    }
+
+    return 0;
 }
commit 719bef0c90b73850e373c70d627fa1f730be84a1
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Sep 27 12:27:49 2011 +0100

    image: Enable use of LERP_SRC for masked source composition
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/cairo-image-compositor.c b/src/cairo-image-compositor.c
index 3e91a06..5c11257 100644
--- a/src/cairo-image-compositor.c
+++ b/src/cairo-image-compositor.c
@@ -465,7 +465,32 @@ composite_boxes (void			*_dst,
 
     /* XXX consider using a region? saves multiple prepare-composite */
 
-    op = _pixman_operator (op);
+    if (((cairo_surface_t *)_dst)->is_clear &&
+	(op == CAIRO_OPERATOR_SOURCE ||
+	 op == CAIRO_OPERATOR_OVER ||
+	 op == CAIRO_OPERATOR_ADD)) {
+	op = PIXMAN_OP_SRC;
+    } else if (mask) {
+	if (op == CAIRO_OPERATOR_CLEAR) {
+#if PIXMAN_HAS_OP_LERP
+	    op = PIXMAN_OP_LERP_CLEAR;
+#else
+	    src = _pixman_image_for_color (CAIRO_COLOR_WHITE);
+	    op = PIXMAN_OP_OUT_REVERSE;
+#endif
+	} else if (op == CAIRO_OPERATOR_SOURCE) {
+#if PIXMAN_HAS_OP_LERP
+	    op = PIXMAN_OP_LERP_SRC;
+#else
+	    return CAIRO_INT_STATUS_UNSUPPORTED;
+#endif
+	} else {
+	    op = _pixman_operator (op);
+	}
+    } else {
+	op = _pixman_operator (op);
+    }
+
     for (chunk = &boxes->chunks; chunk; chunk = chunk->next) {
 	for (i = 0; i < chunk->count; i++) {
 	    int x1 = _cairo_fixed_integer_part (chunk->base[i].p1.x);
@@ -1533,6 +1558,11 @@ _cairo_image_spans_compositor_get (void)
 	_cairo_spans_compositor_init (&compositor,
 				      _cairo_image_traps_compositor_get());
 
+	compositor.flags = 0;
+#if PIXMAN_HAS_OP_LERP
+	compositor.flags |= CAIRO_SPANS_COMPOSITOR_HAS_LERP;
+#endif
+
 	//compositor.acquire = acquire;
 	//compositor.release = release;
 	compositor.fill_boxes = fill_boxes;
diff --git a/src/cairo-spans-compositor-private.h b/src/cairo-spans-compositor-private.h
index 4175639..cab09f6 100644
--- a/src/cairo-spans-compositor-private.h
+++ b/src/cairo-spans-compositor-private.h
@@ -52,6 +52,9 @@ typedef struct _cairo_abstract_span_renderer {
 struct cairo_spans_compositor {
     cairo_compositor_t base;
 
+    unsigned int flags;
+#define CAIRO_SPANS_COMPOSITOR_HAS_LERP 0x1
+
     /* pixel-aligned fast paths */
     cairo_int_status_t (*fill_boxes)	(void			*surface,
 					 cairo_operator_t	 op,
diff --git a/src/cairo-spans-compositor.c b/src/cairo-spans-compositor.c
index 3b1a9a1..9d7b0ac 100644
--- a/src/cairo-spans-compositor.c
+++ b/src/cairo-spans-compositor.c
@@ -231,8 +231,8 @@ fixup_unbounded_mask (const cairo_spans_compositor_t *compositor,
 
     status = _cairo_composite_rectangles_init_for_boxes (&composite,
 							 extents->surface,
-							 CAIRO_OPERATOR_DEST_OUT,
-							 &_cairo_pattern_white.base,
+							 CAIRO_OPERATOR_CLEAR,
+							 &_cairo_pattern_clear.base,
 							 boxes,
 							 NULL);
     if (unlikely (status))
@@ -282,8 +282,8 @@ fixup_unbounded_polygon (const cairo_spans_compositor_t *compositor,
 
     status = _cairo_composite_rectangles_init_for_polygon (&composite,
 							   extents->surface,
-							   CAIRO_OPERATOR_DEST_OUT,
-							   &_cairo_pattern_white.base,
+							   CAIRO_OPERATOR_CLEAR,
+							   &_cairo_pattern_clear.base,
 							   &polygon,
 							   NULL);
     if (unlikely (status))
@@ -464,8 +464,8 @@ composite_aligned_boxes (const cairo_spans_compositor_t		*compositor,
 
     if (op == CAIRO_OPERATOR_SOURCE && (need_clip_mask || ! no_mask)) {
 	/* SOURCE with a mask is actually a LERP in cairo semantics */
-	/* XXX push this choice down to the backend */
-	return CAIRO_INT_STATUS_UNSUPPORTED;
+	if ((compositor->flags & CAIRO_SPANS_COMPOSITOR_HAS_LERP) == 0)
+	    return CAIRO_INT_STATUS_UNSUPPORTED;
     }
 
     /* Are we just copying a recording surface? */
@@ -551,11 +551,6 @@ composite_aligned_boxes (const cairo_spans_compositor_t		*compositor,
 	    }
 	}
 
-	if (mask && op == CAIRO_OPERATOR_CLEAR) {
-	    source = &_cairo_pattern_white.base;
-	    op = CAIRO_OPERATOR_DEST_OUT;
-	}
-
 	src = compositor->pattern_to_surface (dst, source, FALSE,
 					      &extents->bounded,
 					      &extents->source_sample_area,


More information about the cairo-commit mailing list