[cairo-commit] cairo/src cairo-pattern.c, 1.68, 1.69 cairo-surface.c, 1.105, 1.106 cairoint.h, 1.219, 1.220

Keith Packard commit at pdx.freedesktop.org
Fri Oct 28 20:50:01 PDT 2005


Committed by: keithp

Update of /cvs/cairo/cairo/src
In directory gabe:/tmp/cvs-serv28139/src

Modified Files:
	cairo-pattern.c cairo-surface.c cairoint.h 
Log Message:
2005-10-28  Keith Packard  <keithp at keithp.com>

	* src/cairo-pattern.c: (_cairo_pattern_get_extents):
	* src/cairo-surface.c: (_fallback_mask):
	* src/cairoint.h:
	Bound mask fallback operation by transformed mask and
	source. This should speed up any applications calling
	cairo_mask with a bounded source or mask operand.


Index: cairo-pattern.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-pattern.c,v
retrieving revision 1.68
retrieving revision 1.69
diff -u -d -r1.68 -r1.69
--- cairo-pattern.c	10 Oct 2005 19:45:15 -0000	1.68
+++ cairo-pattern.c	29 Oct 2005 03:49:59 -0000	1.69
@@ -22,7 +22,9 @@
  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
  * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  *
- * Author: David Reveman <davidr at novell.com>
+ * Authors: David Reveman <davidr at novell.com>
+ *	    Keith Packard <keithp at keithp.com>
+ *	    Carl Worth <cworth at cworth.org>
  */
 
 #include "cairoint.h"
@@ -1624,3 +1626,84 @@
 
     return status;
 }
+
+/**
+ * _cairo_pattern_get_extents:
+ * 
+ * Return the "target-space" extents of @pattern in @extents.
+ *
+ * For unbounded patterns, the @extents will be initialized with
+ * "infinite" extents, (minimum and maximum fixed-point values).
+ *
+ * XXX: Currently, bounded gradient patterns will also return
+ * "infinite" extents, though it would be possible to optimize these
+ * with a little more work.
+ **/
+cairo_status_t
+_cairo_pattern_get_extents (cairo_pattern_t	*pattern,
+			    cairo_rectangle_t	*extents)
+{
+    if (pattern->extend == CAIRO_EXTEND_NONE &&
+	pattern->type == CAIRO_PATTERN_SURFACE)
+    {
+	cairo_status_t status;
+	cairo_rectangle_t surface_extents;
+	cairo_surface_pattern_t *surface_pattern =
+	    (cairo_surface_pattern_t *) pattern;
+	cairo_surface_t *surface = surface_pattern->surface;
+	cairo_matrix_t imatrix;
+	double x, y;
+	int left, right, top, bottom;
+	int lx, rx, ty, by;
+	int sx, sy;
+	cairo_bool_t set = FALSE;
+
+	status = _cairo_surface_get_extents (surface, &surface_extents);
+	if (status)
+	    return status;
+
+	imatrix = pattern->matrix;
+	cairo_matrix_invert (&imatrix);
+
+	for (sy = 0; sy <= 1; sy++) {
+	    for (sx = 0; sx <= 1; sx++) {
+		x = surface_extents.x + sx * surface_extents.width;
+		y = surface_extents.y + sy * surface_extents.height;
+		cairo_matrix_transform_point (&imatrix, &x, &y);
+		if (x < 0) x = 0;
+		if (x > CAIRO_MAXSHORT) x = CAIRO_MAXSHORT;
+		if (y < 0) y = 0;
+		if (y > CAIRO_MAXSHORT) y = CAIRO_MAXSHORT;
+		lx = floor (x); rx = ceil (x);
+		ty = floor (y); by = ceil (y);
+		if (!set) {
+		    left = lx;
+		    right = rx;
+		    top = ty;
+		    bottom = by;
+		    set = TRUE;
+		} else {
+		    if (lx < left) left = lx;
+		    if (rx > right) right = rx;
+		    if (ty < top) top = ty;
+		    if (by > bottom) bottom = by;
+		}
+	    }
+	}
+	extents->x = left; extents->width = right - left;
+	extents->y = top; extents->height = bottom - top;
+	return CAIRO_STATUS_SUCCESS;
+    }
+
+    /* XXX: We could optimize gradients with pattern->extend of NONE
+     * here in some cases, (eg. radial gradients and 1 axis of
+     * horizontal/vertical linear gradients).
+     */
+
+    extents->x = 0;
+    extents->y = 0;
+    extents->width = CAIRO_MAXSHORT;
+    extents->height = CAIRO_MAXSHORT;
+
+    return CAIRO_STATUS_SUCCESS;
+}

Index: cairo-surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-surface.c,v
retrieving revision 1.105
retrieving revision 1.106
diff -u -d -r1.105 -r1.106
--- cairo-surface.c	28 Oct 2005 00:16:47 -0000	1.105
+++ cairo-surface.c	29 Oct 2005 03:49:59 -0000	1.106
@@ -1236,18 +1236,27 @@
 		cairo_surface_t		*dst)
 {
     cairo_status_t status;
-    cairo_rectangle_t extents;
+    cairo_rectangle_t extents, source_extents, mask_extents;
 
     status = _cairo_surface_get_extents (dst, &extents);
     if (status)
 	return status;
 
-    /*
-     * XXX should take mask extents into account, but
-     * that involves checking the transform and
-     * _cairo_operator_bounded (operator)...  For now,
-     * be lazy and just use the destination extents
-     */
+    if (_cairo_operator_bounded_by_source (operator)) {
+	status = _cairo_pattern_get_extents (source_pattern, &source_extents);
+	if (status)
+	    return status;
+
+	_cairo_rectangle_intersect (&extents, &source_extents);
+    }
+    
+    if (_cairo_operator_bounded_by_mask (operator)) {
+	status = _cairo_pattern_get_extents (mask_pattern, &mask_extents);
+	if (status)
+	    return status;
+
+	_cairo_rectangle_intersect (&extents, &mask_extents);
+    }
 
     status = _cairo_clip_intersect_to_rectangle (dst->clip, &extents);
     if (status)

Index: cairoint.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairoint.h,v
retrieving revision 1.219
retrieving revision 1.220
diff -u -d -r1.219 -r1.220
--- cairoint.h	29 Oct 2005 03:41:22 -0000	1.219
+++ cairoint.h	29 Oct 2005 03:49:59 -0000	1.220
@@ -1972,6 +1972,10 @@
 				 cairo_surface_attributes_t *src_attributes,
 				 cairo_surface_attributes_t *mask_attributes);
 
+cairo_status_t
+_cairo_pattern_get_extents (cairo_pattern_t	*pattern,
+			    cairo_rectangle_t	*extents);
+
 cairo_private cairo_status_t
 _cairo_gstate_set_antialias (cairo_gstate_t *gstate,
 			     cairo_antialias_t antialias);



More information about the cairo-commit mailing list