[cairo-commit] src/cairo-clip-surface.c test/reference

Chris Wilson ickle at kemper.freedesktop.org
Fri May 11 15:15:32 PDT 2012


 src/cairo-clip-surface.c                          |   86 +++++++++++++++++++---
 test/reference/tighten-bounds.base.argb32.ref.png |binary
 test/reference/tighten-bounds.base.rgb24.ref.png  |binary
 3 files changed, 77 insertions(+), 9 deletions(-)

New commits:
commit 6cd1f5040fed1385c2990a68d6017a7ca6c37103
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri May 11 22:38:27 2012 +0100

    clip: Apply clip boxes to the clip surface
    
    As we convert the unaligned clip boxes to a region, we need to process
    the intersection of the boxes with the clip surface as a separate step.
    
    Fixes tighten-box for the base compositor.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/cairo-clip-surface.c b/src/cairo-clip-surface.c
index 523cd42..fff9724 100644
--- a/src/cairo-clip-surface.c
+++ b/src/cairo-clip-surface.c
@@ -91,6 +91,33 @@ _cairo_clip_combine_with_surface (const cairo_clip_t *clip,
     return status;
 }
 
+static cairo_status_t
+_cairo_path_fixed_add_box (cairo_path_fixed_t *path,
+			   const cairo_box_t *box,
+			   cairo_fixed_t fx,
+			   cairo_fixed_t fy)
+{
+    cairo_status_t status;
+
+    status = _cairo_path_fixed_move_to (path, box->p1.x + fx, box->p1.y + fy);
+    if (unlikely (status))
+	return status;
+
+    status = _cairo_path_fixed_line_to (path, box->p2.x + fx, box->p1.y + fy);
+    if (unlikely (status))
+	return status;
+
+    status = _cairo_path_fixed_line_to (path, box->p2.x + fx, box->p2.y + fy);
+    if (unlikely (status))
+	return status;
+
+    status = _cairo_path_fixed_line_to (path, box->p1.x + fx, box->p2.y + fy);
+    if (unlikely (status))
+	return status;
+
+    return _cairo_path_fixed_close_path (path);
+}
+
 cairo_surface_t *
 _cairo_clip_get_surface (const cairo_clip_t *clip,
 			 cairo_surface_t *target,
@@ -98,16 +125,51 @@ _cairo_clip_get_surface (const cairo_clip_t *clip,
 {
     cairo_surface_t *surface;
     cairo_status_t status;
-    cairo_clip_t *copy;
+    cairo_clip_t *copy, *region;
     cairo_clip_path_t *copy_path, *clip_path;
 
-    surface = _cairo_surface_create_similar_solid (target,
-						   CAIRO_CONTENT_ALPHA,
-						   clip->extents.width,
-						   clip->extents.height,
-						   CAIRO_COLOR_WHITE);
-    if (unlikely (surface->status))
-	return surface;
+    if (clip->num_boxes) {
+	cairo_path_fixed_t path;
+	int i;
+
+	surface = _cairo_surface_create_similar_solid (target,
+						       CAIRO_CONTENT_ALPHA,
+						       clip->extents.width,
+						       clip->extents.height,
+						       CAIRO_COLOR_TRANSPARENT);
+	if (unlikely (surface->status))
+	    return surface;
+
+	_cairo_path_fixed_init (&path);
+	status = CAIRO_STATUS_SUCCESS;
+	for (i = 0; status == CAIRO_STATUS_SUCCESS && i < clip->num_boxes; i++) {
+	    status = _cairo_path_fixed_add_box (&path, &clip->boxes[i],
+						-_cairo_fixed_from_int (clip->extents.x),
+						-_cairo_fixed_from_int (clip->extents.y));
+	}
+	if (status == CAIRO_STATUS_SUCCESS)
+	    status = _cairo_surface_fill (surface,
+					  CAIRO_OPERATOR_ADD,
+					  &_cairo_pattern_white.base,
+					  &path,
+					  CAIRO_FILL_RULE_WINDING,
+					  1.,
+					  CAIRO_ANTIALIAS_DEFAULT,
+					  NULL);
+	_cairo_path_fixed_fini (&path);
+	if (unlikely (status)) {
+	    cairo_surface_destroy (surface);
+	    return _cairo_surface_create_in_error (status);
+	}
+    } else {
+	surface = _cairo_surface_create_similar_solid (target,
+						       CAIRO_CONTENT_ALPHA,
+						       clip->extents.width,
+						       clip->extents.height,
+						       CAIRO_COLOR_WHITE);
+	if (unlikely (surface->status))
+	    return surface;
+    }
 
     copy = _cairo_clip_copy_with_translation (clip,
 					      -clip->extents.x,
@@ -115,6 +177,10 @@ _cairo_clip_get_surface (const cairo_clip_t *clip,
     copy_path = copy->path;
     copy->path = NULL;
 
+    region = copy;
+    if (! _cairo_clip_is_region (copy))
+	region = _cairo_clip_copy_region (copy);
+
     status = CAIRO_STATUS_SUCCESS;
     clip_path = copy_path;
     while (status == CAIRO_STATUS_SUCCESS && clip_path) {
@@ -125,12 +191,14 @@ _cairo_clip_get_surface (const cairo_clip_t *clip,
 				      clip_path->fill_rule,
 				      clip_path->tolerance,
 				      clip_path->antialias,
-				      copy);
+				      region);
 	clip_path = clip_path->prev;
     }
 
     copy->path = copy_path;
     _cairo_clip_destroy (copy);
+    if (region != copy)
+	_cairo_clip_destroy (region);
 
     if (unlikely (status)) {
 	cairo_surface_destroy (surface);
diff --git a/test/reference/tighten-bounds.base.argb32.ref.png b/test/reference/tighten-bounds.base.argb32.ref.png
index 169d9de..dad3a7f 100644
Binary files a/test/reference/tighten-bounds.base.argb32.ref.png and b/test/reference/tighten-bounds.base.argb32.ref.png differ
diff --git a/test/reference/tighten-bounds.base.rgb24.ref.png b/test/reference/tighten-bounds.base.rgb24.ref.png
index d984ff7..9d3a252 100644
Binary files a/test/reference/tighten-bounds.base.rgb24.ref.png and b/test/reference/tighten-bounds.base.rgb24.ref.png differ


More information about the cairo-commit mailing list