[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