summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2010-01-19 17:11:55 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2010-01-22 23:01:51 +0000
commitae25f1c360b79f0b7b1bb73e9ebc47eb794d8007 (patch)
tree1e8275333922a32bf5f22bdf42a3a44751085adb
parent9cd9137843f8f1c3d32bedb6510259ab3638a2c5 (diff)
Alter definition of cairo_composite_rectangles_t
This is a more useful definition that is able to individually track the rectangles that compose the composite operation. This will be used by the specialist compositors as a means to perform the common extents determination for an operation.
-rw-r--r--src/Makefile.sources2
-rw-r--r--src/cairo-composite-rectangles-private.h105
-rw-r--r--src/cairo-composite-rectangles.c197
-rw-r--r--src/cairo-gl-surface.c19
-rw-r--r--src/cairo-image-surface.c31
-rw-r--r--src/cairo-misc.c41
-rw-r--r--src/cairo-rectangle.c21
-rw-r--r--src/cairo-spans.c29
-rw-r--r--src/cairo-surface-fallback.c13
-rw-r--r--src/cairo-types-private.h24
-rw-r--r--src/cairo-win32-surface.c21
-rw-r--r--src/cairoint.h14
12 files changed, 417 insertions, 100 deletions
diff --git a/src/Makefile.sources b/src/Makefile.sources
index 20829e78..391f2858 100644
--- a/src/Makefile.sources
+++ b/src/Makefile.sources
@@ -59,6 +59,7 @@ cairo_private = \
cairo-clip-private.h \
cairo-combsort-private.h \
cairo-compiler-private.h \
+ cairo-composite-rectangles-private.h \
cairo-device-private.h \
cairo-error-private.h \
cairo-fixed-private.h \
@@ -114,6 +115,7 @@ cairo_sources = \
cairo-cache.c \
cairo-clip.c \
cairo-color.c \
+ cairo-composite-rectangles.c \
cairo-debug.c \
cairo-device.c \
cairo-fixed.c \
diff --git a/src/cairo-composite-rectangles-private.h b/src/cairo-composite-rectangles-private.h
new file mode 100644
index 00000000..be1a16a2
--- /dev/null
+++ b/src/cairo-composite-rectangles-private.h
@@ -0,0 +1,105 @@
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2009 Intel Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is University of Southern
+ * California.
+ *
+ * Contributor(s):
+ * Chris Wilson <chris@chris-wilson.co.u>
+ */
+
+#ifndef CAIRO_COMPOSITE_RECTANGLES_PRIVATE_H
+#define CAIRO_COMPOSITE_RECTANGLES_PRIVATE_H
+
+#include "cairo-types-private.h"
+
+CAIRO_BEGIN_DECLS
+
+/* Rectangles that take part in a composite operation.
+ *
+ * The source and mask track the extents of the respective patterns in device
+ * space. The unbounded rectangle is essentially the clip rectangle. And the
+ * intersection of all is the bounded rectangle, which is the minimum extents
+ * the operation may require. Whether or not the operation is actually bounded
+ * is tracked in the is_bounded boolean.
+ *
+ */
+struct _cairo_composite_rectangles {
+ cairo_rectangle_int_t source;
+ cairo_rectangle_int_t mask;
+ cairo_rectangle_int_t bounded; /* dst */
+ cairo_rectangle_int_t unbounded; /* clip */
+ uint32_t is_bounded;
+};
+
+cairo_private cairo_int_status_t
+_cairo_composite_rectangles_init_for_paint (cairo_composite_rectangles_t *extents,
+ int surface_width, int surface_height,
+ cairo_operator_t op,
+ const cairo_pattern_t *source,
+ cairo_clip_t *clip);
+
+cairo_private cairo_int_status_t
+_cairo_composite_rectangles_init_for_mask (cairo_composite_rectangles_t *extents,
+ int surface_width, int surface_height,
+ cairo_operator_t op,
+ const cairo_pattern_t *source,
+ const cairo_pattern_t *mask,
+ cairo_clip_t *clip);
+
+cairo_private cairo_int_status_t
+_cairo_composite_rectangles_init_for_stroke (cairo_composite_rectangles_t *extents,
+ int surface_width, int surface_height,
+ cairo_operator_t op,
+ const cairo_pattern_t *source,
+ cairo_path_fixed_t *path,
+ const cairo_stroke_style_t *style,
+ const cairo_matrix_t *ctm,
+ cairo_clip_t *clip);
+
+cairo_private cairo_int_status_t
+_cairo_composite_rectangles_init_for_fill (cairo_composite_rectangles_t *extents,
+ int surface_width, int surface_height,
+ cairo_operator_t op,
+ const cairo_pattern_t *source,
+ cairo_path_fixed_t *path,
+ cairo_clip_t *clip);
+
+cairo_private cairo_int_status_t
+_cairo_composite_rectangles_init_for_glyphs (cairo_composite_rectangles_t *extents,
+ int surface_width, int surface_height,
+ cairo_operator_t op,
+ const cairo_pattern_t *source,
+ cairo_scaled_font_t *scaled_font,
+ cairo_glyph_t *glyphs,
+ int num_glyphs,
+ cairo_clip_t *clip,
+ cairo_bool_t *overlap);
+
+#endif /* CAIRO_COMPOSITE_RECTANGLES_PRIVATE_H */
diff --git a/src/cairo-composite-rectangles.c b/src/cairo-composite-rectangles.c
new file mode 100644
index 00000000..2bd823f1
--- /dev/null
+++ b/src/cairo-composite-rectangles.c
@@ -0,0 +1,197 @@
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2009 Intel Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is Red Hat, Inc.
+ *
+ * Contributor(s):
+ * Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairoint.h"
+
+#include "cairo-error-private.h"
+#include "cairo-composite-rectangles-private.h"
+
+/* A collection of routines to facilitate writing compositors. */
+
+static inline cairo_bool_t
+_cairo_composite_rectangles_init (cairo_composite_rectangles_t *extents,
+ int width, int height,
+ cairo_operator_t op,
+ const cairo_pattern_t *source,
+ cairo_clip_t *clip)
+{
+ extents->unbounded.x = extents->unbounded.y = 0;
+ extents->unbounded.width = width;
+ extents->unbounded.height = height;
+
+ if (clip != NULL) {
+ const cairo_rectangle_int_t *clip_extents;
+
+ clip_extents = _cairo_clip_get_extents (clip);
+ if (clip_extents == NULL)
+ return FALSE;
+
+ if (! _cairo_rectangle_intersect (&extents->unbounded, clip_extents))
+ return FALSE;
+ }
+
+ extents->bounded = extents->unbounded;
+ extents->is_bounded = _cairo_operator_bounded_by_either (op);
+
+ _cairo_pattern_get_extents (source, &extents->source);
+ if (extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_SOURCE) {
+ if (! _cairo_rectangle_intersect (&extents->bounded, &extents->source))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+cairo_int_status_t
+_cairo_composite_rectangles_init_for_paint (cairo_composite_rectangles_t *extents,
+ int surface_width, int surface_height,
+ cairo_operator_t op,
+ const cairo_pattern_t *source,
+ cairo_clip_t *clip)
+{
+ if (! _cairo_composite_rectangles_init (extents,
+ surface_width, surface_height,
+ op, source, clip))
+ {
+ return CAIRO_INT_STATUS_NOTHING_TO_DO;
+ }
+
+ extents->mask = extents->bounded;
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_int_status_t
+_cairo_composite_rectangles_intersect (cairo_composite_rectangles_t *extents)
+{
+ cairo_bool_t ret;
+
+ ret = _cairo_rectangle_intersect (&extents->bounded, &extents->mask);
+ if (! ret && extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK)
+ return CAIRO_INT_STATUS_NOTHING_TO_DO;
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+cairo_int_status_t
+_cairo_composite_rectangles_init_for_mask (cairo_composite_rectangles_t *extents,
+ int surface_width, int surface_height,
+ cairo_operator_t op,
+ const cairo_pattern_t *source,
+ const cairo_pattern_t *mask,
+ cairo_clip_t *clip)
+{
+ if (! _cairo_composite_rectangles_init (extents,
+ surface_width, surface_height,
+ op, source, clip))
+ {
+ return CAIRO_INT_STATUS_NOTHING_TO_DO;
+ }
+
+ _cairo_pattern_get_extents (mask, &extents->mask);
+
+ return _cairo_composite_rectangles_intersect (extents);
+}
+
+cairo_int_status_t
+_cairo_composite_rectangles_init_for_stroke (cairo_composite_rectangles_t *extents,
+ int surface_width, int surface_height,
+ cairo_operator_t op,
+ const cairo_pattern_t *source,
+ cairo_path_fixed_t *path,
+ const cairo_stroke_style_t *style,
+ const cairo_matrix_t *ctm,
+ cairo_clip_t *clip)
+{
+ if (! _cairo_composite_rectangles_init (extents,
+ surface_width, surface_height,
+ op, source, clip))
+ {
+ return CAIRO_INT_STATUS_NOTHING_TO_DO;
+ }
+
+ _cairo_path_fixed_approximate_stroke_extents (path, style, ctm, &extents->mask);
+
+ return _cairo_composite_rectangles_intersect (extents);
+}
+
+cairo_int_status_t
+_cairo_composite_rectangles_init_for_fill (cairo_composite_rectangles_t *extents,
+ int surface_width, int surface_height,
+ cairo_operator_t op,
+ const cairo_pattern_t *source,
+ cairo_path_fixed_t *path,
+ cairo_clip_t *clip)
+{
+ if (! _cairo_composite_rectangles_init (extents,
+ surface_width, surface_height,
+ op, source, clip))
+ {
+ return CAIRO_INT_STATUS_NOTHING_TO_DO;
+ }
+
+ _cairo_path_fixed_approximate_fill_extents (path, &extents->mask);
+
+ return _cairo_composite_rectangles_intersect (extents);
+}
+
+cairo_int_status_t
+_cairo_composite_rectangles_init_for_glyphs (cairo_composite_rectangles_t *extents,
+ int surface_width, int surface_height,
+ cairo_operator_t op,
+ const cairo_pattern_t *source,
+ cairo_scaled_font_t *scaled_font,
+ cairo_glyph_t *glyphs,
+ int num_glyphs,
+ cairo_clip_t *clip,
+ cairo_bool_t *overlap)
+{
+ cairo_status_t status;
+
+ if (! _cairo_composite_rectangles_init (extents,
+ surface_width, surface_height,
+ op, source, clip))
+ {
+ return CAIRO_INT_STATUS_NOTHING_TO_DO;
+ }
+
+ status = _cairo_scaled_font_glyph_device_extents (scaled_font,
+ glyphs, num_glyphs,
+ &extents->mask,
+ overlap);
+ if (unlikely (status))
+ return status;
+
+ return _cairo_composite_rectangles_intersect (extents);
+}
diff --git a/src/cairo-gl-surface.c b/src/cairo-gl-surface.c
index 30f6d44d..35b946c9 100644
--- a/src/cairo-gl-surface.c
+++ b/src/cairo-gl-surface.c
@@ -37,6 +37,7 @@
#include "cairoint.h"
+#include "cairo-composite-rectangles-private.h"
#include "cairo-error-private.h"
#include "cairo-gl-private.h"
@@ -2261,6 +2262,7 @@ _cairo_gl_surface_create_span_renderer (cairo_operator_t op,
cairo_gl_surface_span_renderer_t *renderer;
cairo_status_t status;
cairo_surface_attributes_t *src_attributes;
+ const cairo_rectangle_int_t *extents;
GLenum err;
renderer = calloc (1, sizeof (*renderer));
@@ -2269,21 +2271,24 @@ _cairo_gl_surface_create_span_renderer (cairo_operator_t op,
renderer->base.destroy = _cairo_gl_surface_span_renderer_destroy;
renderer->base.finish = _cairo_gl_surface_span_renderer_finish;
- if (_cairo_operator_bounded_by_mask (op))
+ if (rects->is_bounded) {
renderer->base.render_rows = _cairo_gl_render_bounded_spans;
- else
+ extents = &rects->bounded;
+ } else {
renderer->base.render_rows = _cairo_gl_render_unbounded_spans;
- renderer->xmin = rects->mask.x;
- renderer->xmax = rects->mask.x + rects->width;
+ extents = &rects->unbounded;
+ }
+ renderer->xmin = extents->x;
+ renderer->xmax = extents->x + extents->width;
renderer->op = op;
renderer->antialias = antialias;
renderer->dst = dst;
renderer->clip = clip_region;
status = _cairo_gl_operand_init (&renderer->setup.src, src, dst,
- rects->src.x, rects->src.y,
- rects->dst.x, rects->dst.y,
- rects->width, rects->height);
+ rects->source.x, rects->source.y,
+ extents->x, extents->y,
+ extents->width, extents->height);
if (unlikely (status)) {
free (renderer);
return _cairo_span_renderer_create_in_error (status);
diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index d3bc6cae..b50a9941 100644
--- a/src/cairo-image-surface.c
+++ b/src/cairo-image-surface.c
@@ -38,6 +38,7 @@
#include "cairoint.h"
#include "cairo-clip-private.h"
+#include "cairo-composite-rectangles-private.h"
#include "cairo-error-private.h"
#include "cairo-region-private.h"
@@ -1484,28 +1485,28 @@ _cairo_image_surface_span_renderer_finish (void *abstract_renderer)
cairo_image_surface_t *src = renderer->src;
cairo_image_surface_t *dst = renderer->dst;
cairo_surface_attributes_t *src_attributes = &renderer->src_attributes;
- int width = rects->width;
- int height = rects->height;
+ int width = rects->bounded.width;
+ int height = rects->bounded.height;
pixman_image_composite (_pixman_operator (renderer->op),
src->pixman_image,
renderer->mask->pixman_image,
dst->pixman_image,
- rects->src.x + src_attributes->x_offset,
- rects->src.y + src_attributes->y_offset,
+ rects->bounded.x + src_attributes->x_offset,
+ rects->bounded.y + src_attributes->y_offset,
0, 0, /* mask.x, mask.y */
- rects->dst.x, rects->dst.y,
+ rects->bounded.x, rects->bounded.y,
width, height);
- if (! _cairo_operator_bounded_by_mask (renderer->op)) {
+ if (! rects->is_bounded) {
status = _cairo_surface_composite_shape_fixup_unbounded (
&dst->base,
src_attributes,
src->width, src->height,
width, height,
- rects->src.x, rects->src.y,
+ rects->bounded.x, rects->bounded.y,
0, 0, /* mask.x, mask.y */
- rects->dst.x, rects->dst.y,
+ rects->bounded.x, rects->bounded.y,
width, height,
dst->clip_region);
}
@@ -1540,8 +1541,6 @@ _cairo_image_surface_create_span_renderer (cairo_operator_t op,
cairo_image_surface_t *dst = abstract_dst;
cairo_image_surface_span_renderer_t *renderer = calloc(1, sizeof(*renderer));
cairo_status_t status;
- int width = rects->width;
- int height = rects->height;
status = _cairo_image_surface_set_clip_region (dst, clip_region);
if (unlikely (status))
@@ -1562,8 +1561,8 @@ _cairo_image_surface_create_span_renderer (cairo_operator_t op,
status = _cairo_pattern_acquire_surface (
renderer->pattern, &renderer->dst->base,
- rects->src.x, rects->src.y,
- width, height,
+ rects->bounded.x, rects->bounded.y,
+ rects->bounded.width, rects->bounded.height,
CAIRO_PATTERN_ACQUIRE_NONE,
(cairo_surface_t **) &renderer->src,
&renderer->src_attributes);
@@ -1572,7 +1571,8 @@ _cairo_image_surface_create_span_renderer (cairo_operator_t op,
status = _cairo_image_surface_set_attributes (
renderer->src, &renderer->src_attributes,
- rects->dst.x + width/2, rects->dst.y + height/2);
+ rects->bounded.x + rects->bounded.width/2,
+ rects->bounded.y + rects->bounded.height/2);
if (status)
goto unwind;
@@ -1580,7 +1580,8 @@ _cairo_image_surface_create_span_renderer (cairo_operator_t op,
* compositing to pixman.) */
renderer->mask = (cairo_image_surface_t *)
cairo_image_surface_create (CAIRO_FORMAT_A8,
- width, height);
+ rects->bounded.width,
+ rects->bounded.height);
status = cairo_surface_status (&renderer->mask->base);
@@ -1590,7 +1591,7 @@ _cairo_image_surface_create_span_renderer (cairo_operator_t op,
return _cairo_span_renderer_create_in_error (status);
}
- renderer->mask_data = renderer->mask->data - rects->mask.x - rects->mask.y * renderer->mask->stride;
+ renderer->mask_data = renderer->mask->data - rects->bounded.x - rects->bounded.y * renderer->mask->stride;
renderer->mask_stride = renderer->mask->stride;
return &renderer->base;
}
diff --git a/src/cairo-misc.c b/src/cairo-misc.c
index 5f9cba5f..cd1032a4 100644
--- a/src/cairo-misc.c
+++ b/src/cairo-misc.c
@@ -421,6 +421,47 @@ _cairo_operator_bounded_by_source (cairo_operator_t op)
return FALSE;
}
+uint32_t
+_cairo_operator_bounded_by_either (cairo_operator_t op)
+{
+ switch (op) {
+ default:
+ ASSERT_NOT_REACHED;
+ case CAIRO_OPERATOR_OVER:
+ case CAIRO_OPERATOR_ATOP:
+ case CAIRO_OPERATOR_DEST:
+ case CAIRO_OPERATOR_DEST_OVER:
+ case CAIRO_OPERATOR_DEST_OUT:
+ case CAIRO_OPERATOR_XOR:
+ case CAIRO_OPERATOR_ADD:
+ case CAIRO_OPERATOR_SATURATE:
+ case CAIRO_OPERATOR_MULTIPLY:
+ case CAIRO_OPERATOR_SCREEN:
+ case CAIRO_OPERATOR_OVERLAY:
+ case CAIRO_OPERATOR_DARKEN:
+ case CAIRO_OPERATOR_LIGHTEN:
+ case CAIRO_OPERATOR_COLOR_DODGE:
+ case CAIRO_OPERATOR_COLOR_BURN:
+ case CAIRO_OPERATOR_HARD_LIGHT:
+ case CAIRO_OPERATOR_SOFT_LIGHT:
+ case CAIRO_OPERATOR_DIFFERENCE:
+ case CAIRO_OPERATOR_EXCLUSION:
+ case CAIRO_OPERATOR_HSL_HUE:
+ case CAIRO_OPERATOR_HSL_SATURATION:
+ case CAIRO_OPERATOR_HSL_COLOR:
+ case CAIRO_OPERATOR_HSL_LUMINOSITY:
+ return CAIRO_OPERATOR_BOUND_BY_MASK | CAIRO_OPERATOR_BOUND_BY_SOURCE;
+ case CAIRO_OPERATOR_CLEAR:
+ case CAIRO_OPERATOR_SOURCE:
+ return CAIRO_OPERATOR_BOUND_BY_MASK;
+ case CAIRO_OPERATOR_OUT:
+ case CAIRO_OPERATOR_IN:
+ case CAIRO_OPERATOR_DEST_IN:
+ case CAIRO_OPERATOR_DEST_ATOP:
+ return 0;
+ }
+
+}
/* This function is identical to the C99 function lround(), except that it
* performs arithmetic rounding (floor(d + .5) instead of away-from-zero rounding) and
diff --git a/src/cairo-rectangle.c b/src/cairo-rectangle.c
index e887c751..2bc45350 100644
--- a/src/cairo-rectangle.c
+++ b/src/cairo-rectangle.c
@@ -246,24 +246,3 @@ _cairo_box_contains_point (cairo_box_t *box, const cairo_point_t *point)
return FALSE;
return TRUE;
}
-
-void
-_cairo_composite_rectangles_init(
- cairo_composite_rectangles_t *rects,
- int all_x,
- int all_y,
- int width,
- int height)
-{
- rects->src.x = all_x;
- rects->src.y = all_y;
- rects->mask.x = all_x;
- rects->mask.y = all_y;
- rects->clip.x = all_x;
- rects->clip.y = all_y;
- rects->dst.x = all_x;
- rects->dst.y = all_y;
-
- rects->width = width;
- rects->height = height;
-}
diff --git a/src/cairo-spans.c b/src/cairo-spans.c
index 0b0f40cd..e8ef0cfb 100644
--- a/src/cairo-spans.c
+++ b/src/cairo-spans.c
@@ -26,6 +26,7 @@
*/
#include "cairoint.h"
+#include "cairo-composite-rectangles-private.h"
#include "cairo-fixed-private.h"
static cairo_scan_converter_t *
@@ -38,10 +39,10 @@ _create_scan_converter (cairo_fill_rule_t fill_rule,
return NULL;
}
- return _cairo_tor_scan_converter_create (rects->mask.x,
- rects->mask.y,
- rects->mask.x + rects->width,
- rects->mask.y + rects->height,
+ return _cairo_tor_scan_converter_create (rects->bounded.x,
+ rects->bounded.y,
+ rects->bounded.x + rects->bounded.width,
+ rects->bounded.y + rects->bounded.height,
fill_rule);
}
@@ -100,14 +101,22 @@ _cairo_surface_composite_trapezoids_as_polygon (cairo_surface_t *surface,
cairo_composite_rectangles_t rects;
cairo_status_t status;
- rects.src.x = src_x;
- rects.src.y = src_y;
- rects.dst.x = dst_x;
- rects.dst.y = dst_y;
+ rects.source.x = src_x;
+ rects.source.y = src_y;
+ rects.source.width = width;
+ rects.source.height = height;
+
rects.mask.x = dst_x;
rects.mask.y = dst_y;
- rects.width = width;
- rects.height = height;
+ rects.mask.width = width;
+ rects.mask.height = height;
+
+ rects.bounded.x = dst_x;
+ rects.bounded.y = dst_y;
+ rects.bounded.width = width;
+ rects.bounded.height = height;
+
+ rects.unbounded = rects.bounded;
converter = _create_scan_converter (CAIRO_FILL_RULE_WINDING,
antialias,
diff --git a/src/cairo-surface-fallback.c b/src/cairo-surface-fallback.c
index dbc2a217..a20bd68c 100644
--- a/src/cairo-surface-fallback.c
+++ b/src/cairo-surface-fallback.c
@@ -42,6 +42,7 @@
#include "cairo-surface-fallback-private.h"
#include "cairo-clip-private.h"
+#include "cairo-composite-rectangles-private.h"
#include "cairo-error-private.h"
#include "cairo-region-private.h"
#include "cairo-spans-private.h"
@@ -883,15 +884,15 @@ _composite_spans_draw_func (void *closure,
cairo_composite_rectangles_t rects;
cairo_composite_spans_info_t *info = closure;
- _cairo_composite_rectangles_init (&rects,
- extents->x, extents->y,
- extents->width, extents->height);
-
+ rects.source = *extents;
+ rects.mask = *extents;
+ rects.bounded = *extents;
/* The incoming dst_x/y are where we're pretending the origin of
* the dst surface is -- *not* the offset of a rectangle where
* we'd like to place the result. */
- rects.dst.x -= dst_x;
- rects.dst.y -= dst_y;
+ rects.bounded.x -= dst_x;
+ rects.bounded.y -= dst_y;
+ rects.unbounded = rects.bounded;;
return _cairo_surface_composite_polygon (dst, op, src,
info->fill_rule,
diff --git a/src/cairo-types-private.h b/src/cairo-types-private.h
index 051a0ae1..f4f600c6 100644
--- a/src/cairo-types-private.h
+++ b/src/cairo-types-private.h
@@ -47,6 +47,7 @@
typedef struct _cairo_array cairo_array_t;
typedef struct _cairo_backend cairo_backend_t;
typedef struct _cairo_cache cairo_cache_t;
+typedef struct _cairo_composite_rectangles cairo_composite_rectangles_t;
typedef struct _cairo_clip cairo_clip_t;
typedef struct _cairo_clip_path cairo_clip_path_t;
typedef struct _cairo_color cairo_color_t;
@@ -214,29 +215,6 @@ typedef struct _cairo_point_int {
#define CAIRO_RECT_INT_MIN (INT_MIN >> CAIRO_FIXED_FRAC_BITS)
#define CAIRO_RECT_INT_MAX (INT_MAX >> CAIRO_FIXED_FRAC_BITS)
-/* Rectangles that take part in a composite operation.
- *
- * This defines four translations that define which pixels of the
- * source pattern, mask, clip and destination surface take part in a
- * general composite operation. The idea is that the pixels at
- *
- * (i,j)+(src.x, src.y) of the source,
- * (i,j)+(mask.x, mask.y) of the mask,
- * (i,j)+(clip.x, clip.y) of the clip and
- * (i,j)+(dst.x, dst.y) of the destination
- *
- * all combine together to form the result at (i,j)+(dst.x,dst.y),
- * for i,j ranging in [0,width) and [0,height) respectively.
- */
-typedef struct _cairo_composite_rectangles {
- cairo_point_int_t src;
- cairo_point_int_t mask;
- cairo_point_int_t clip;
- cairo_point_int_t dst;
- int width;
- int height;
-} cairo_composite_rectangles_t;
-
typedef enum _cairo_direction {
CAIRO_DIRECTION_FORWARD,
CAIRO_DIRECTION_REVERSE
diff --git a/src/cairo-win32-surface.c b/src/cairo-win32-surface.c
index 2bc0bdc7..3f5180ee 100644
--- a/src/cairo-win32-surface.c
+++ b/src/cairo-win32-surface.c
@@ -48,6 +48,7 @@
#include "cairoint.h"
#include "cairo-clip-private.h"
+#include "cairo-composite-rectangles-private.h"
#include "cairo-error-private.h"
#include "cairo-paginated-private.h"
#include "cairo-win32-private.h"
@@ -1930,11 +1931,10 @@ _cairo_win32_surface_span_renderer_finish (void *abstract_renderer)
status = dst->image->backend->composite (renderer->op,
renderer->pattern, mask_pattern, dst->image,
- rects->src.x,
- rects->src.y,
+ rects->bounded.x, rects->bounded.y,
0, 0, /* mask.x, mask.y */
- rects->dst.x, rects->dst.y,
- rects->width, rects->height,
+ rects->bounded.x, rects->bounded.y,
+ rects->bounded.width, rects->bounded.height,
renderer->clip_region);
} else {
/* otherwise go through the fallback_composite path which
@@ -1942,11 +1942,10 @@ _cairo_win32_surface_span_renderer_finish (void *abstract_renderer)
status = _cairo_surface_fallback_composite (
renderer->op,
renderer->pattern, mask_pattern, &dst->base,
- rects->src.x,
- rects->src.y,
+ rects->bounded.x, rects->bounded.y,
0, 0, /* mask.x, mask.y */
- rects->dst.x, rects->dst.y,
- rects->width, rects->height,
+ rects->bounded.x, rects->bounded.y,
+ rects->bounded.width, rects->bounded.height,
renderer->clip_region);
}
cairo_pattern_destroy (mask_pattern);
@@ -1982,8 +1981,8 @@ _cairo_win32_surface_create_span_renderer (cairo_operator_t op,
cairo_win32_surface_t *dst = abstract_dst;
cairo_win32_surface_span_renderer_t *renderer;
cairo_status_t status;
- int width = rects->width;
- int height = rects->height;
+ int width = rects->bounded.width;
+ int height = rects->bounded.height;
renderer = calloc(1, sizeof(*renderer));
if (renderer == NULL)
@@ -2013,7 +2012,7 @@ _cairo_win32_surface_create_span_renderer (cairo_operator_t op,
return _cairo_span_renderer_create_in_error (status);
}
- renderer->mask_data = renderer->mask->data - rects->mask.x - rects->mask.y * renderer->mask->stride;
+ renderer->mask_data = renderer->mask->data - rects->bounded.x - rects->bounded.y * renderer->mask->stride;
renderer->mask_stride = renderer->mask->stride;
return &renderer->base;
}
diff --git a/src/cairoint.h b/src/cairoint.h
index 4e9762ef..0ea68e54 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -294,13 +294,6 @@ cairo_private cairo_bool_t
_cairo_box_contains_point (cairo_box_t *box,
const cairo_point_t *point) cairo_pure;
-cairo_private void
-_cairo_composite_rectangles_init (cairo_composite_rectangles_t *rects,
- int all_x,
- int all_y,
- int width,
- int height);
-
/* cairo-array.c structures and functions */
cairo_private void
@@ -1293,6 +1286,13 @@ _cairo_operator_bounded_by_mask (cairo_operator_t op) cairo_const;
cairo_private cairo_bool_t
_cairo_operator_bounded_by_source (cairo_operator_t op) cairo_const;
+enum {
+ CAIRO_OPERATOR_BOUND_BY_MASK = 1 << 1,
+ CAIRO_OPERATOR_BOUND_BY_SOURCE = 1 << 2,
+};
+
+cairo_private uint32_t
+_cairo_operator_bounded_by_either (cairo_operator_t op) cairo_const;
/* cairo-color.c */
cairo_private const cairo_color_t *
_cairo_stock_color (cairo_stock_t stock) cairo_pure;