summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cairo-clip-private.h2
-rw-r--r--src/cairo-clip.c26
-rw-r--r--src/cairo-image-surface.c39
-rw-r--r--src/cairo-surface-fallback.c20
-rw-r--r--src/cairo-xcb-surface-render.c31
-rw-r--r--src/drm/cairo-drm-i915-shader.c9
-rw-r--r--src/drm/cairo-drm-i965-shader.c7
7 files changed, 75 insertions, 59 deletions
diff --git a/src/cairo-clip-private.h b/src/cairo-clip-private.h
index 815fbf864..8e30f13ad 100644
--- a/src/cairo-clip-private.h
+++ b/src/cairo-clip-private.h
@@ -112,7 +112,7 @@ cairo_private const cairo_rectangle_int_t *
_cairo_clip_get_extents (const cairo_clip_t *clip);
cairo_private cairo_surface_t *
-_cairo_clip_get_surface (cairo_clip_t *clip, cairo_surface_t *dst);
+_cairo_clip_get_surface (cairo_clip_t *clip, cairo_surface_t *dst, int *tx, int *ty);
cairo_private cairo_status_t
_cairo_clip_combine_with_surface (cairo_clip_t *clip,
diff --git a/src/cairo-clip.c b/src/cairo-clip.c
index fca47597c..ff4aeb636 100644
--- a/src/cairo-clip.c
+++ b/src/cairo-clip.c
@@ -942,7 +942,8 @@ _cairo_clip_path_to_boxes (cairo_clip_path_t *clip_path,
static cairo_surface_t *
_cairo_clip_path_get_surface (cairo_clip_path_t *clip_path,
- cairo_surface_t *target)
+ cairo_surface_t *target,
+ int *tx, int *ty)
{
const cairo_rectangle_int_t *clip_extents = &clip_path->extents;
cairo_bool_t need_translate;
@@ -950,9 +951,19 @@ _cairo_clip_path_get_surface (cairo_clip_path_t *clip_path,
cairo_clip_path_t *prev;
cairo_status_t status;
+ while (clip_path->prev != NULL &&
+ clip_path->flags & CAIRO_CLIP_PATH_IS_BOX &&
+ clip_path->path.maybe_fill_region)
+ {
+ clip_path = clip_path->prev;
+ }
+
+ clip_extents = &clip_path->extents;
if (clip_path->surface != NULL &&
clip_path->surface->backend == target->backend)
{
+ *tx = clip_extents->x;
+ *ty = clip_extents->y;
return clip_path->surface;
}
@@ -1046,16 +1057,17 @@ _cairo_clip_path_get_surface (cairo_clip_path_t *clip_path,
{
cairo_surface_pattern_t pattern;
cairo_surface_t *prev_surface;
+ int prev_tx, prev_ty;
- prev_surface = _cairo_clip_path_get_surface (prev, target);
+ prev_surface = _cairo_clip_path_get_surface (prev, target, &prev_tx, &prev_ty);
if (unlikely (prev_surface->status))
goto BAIL;
_cairo_pattern_init_for_surface (&pattern, prev_surface);
pattern.base.filter = CAIRO_FILTER_NEAREST;
cairo_matrix_init_translate (&pattern.base.matrix,
- clip_extents->x - prev->extents.x,
- clip_extents->y - prev->extents.y);
+ clip_extents->x - prev_tx,
+ clip_extents->y - prev_ty);
status = _cairo_surface_paint (surface,
CAIRO_OPERATOR_IN,
&pattern.base,
@@ -1071,6 +1083,8 @@ _cairo_clip_path_get_surface (cairo_clip_path_t *clip_path,
prev = prev->prev;
}
+ *tx = clip_extents->x;
+ *ty = clip_extents->y;
cairo_surface_destroy (clip_path->surface);
return clip_path->surface = surface;
@@ -1158,11 +1172,11 @@ _cairo_debug_print_clip (FILE *stream, cairo_clip_t *clip)
}
cairo_surface_t *
-_cairo_clip_get_surface (cairo_clip_t *clip, cairo_surface_t *target)
+_cairo_clip_get_surface (cairo_clip_t *clip, cairo_surface_t *target, int *tx, int *ty)
{
/* XXX is_clear -> all_clipped */
assert (clip->path != NULL);
- return _cairo_clip_path_get_surface (clip->path, target);
+ return _cairo_clip_path_get_surface (clip->path, target, tx, ty);
}
cairo_status_t
diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index 753882647..36958185d 100644
--- a/src/cairo-image-surface.c
+++ b/src/cairo-image-surface.c
@@ -1481,13 +1481,14 @@ _cairo_image_surface_fixup_unbounded (cairo_image_surface_t *dst,
if (clip != NULL) {
cairo_surface_t *clip_surface;
+ int clip_x, clip_y;
- clip_surface = _cairo_clip_get_surface (clip, &dst->base);
+ clip_surface = _cairo_clip_get_surface (clip, &dst->base, &clip_x, &clip_y);
assert (clip_surface->status == CAIRO_STATUS_SUCCESS);
mask = ((cairo_image_surface_t *) clip_surface)->pixman_image;
- mask_x = -clip->path->extents.x;
- mask_y = -clip->path->extents.y;
+ mask_x = -clip_x;
+ mask_y = -clip_y;
} else {
if (rects->bounded.width == rects->unbounded.width &&
rects->bounded.height == rects->unbounded.height)
@@ -1852,6 +1853,7 @@ _clip_and_composite_combine (cairo_clip_t *clip,
{
pixman_image_t *tmp;
cairo_surface_t *clip_surface;
+ int clip_x, clip_y;
cairo_status_t status;
tmp = pixman_image_create_bits (dst->pixman_format,
@@ -1887,7 +1889,7 @@ _clip_and_composite_combine (cairo_clip_t *clip,
goto CLEANUP_SURFACE;
assert (clip->path != NULL);
- clip_surface = _cairo_clip_get_surface (clip, &dst->base);
+ clip_surface = _cairo_clip_get_surface (clip, &dst->base, &clip_x, &clip_y);
if (unlikely (clip_surface->status))
goto CLEANUP_SURFACE;
@@ -1898,8 +1900,8 @@ _clip_and_composite_combine (cairo_clip_t *clip,
((cairo_image_surface_t *) clip_surface)->pixman_image,
dst->pixman_image,
0, 0,
- extents->x - clip->path->extents.x,
- extents->y - clip->path->extents.y,
+ extents->x - clip_x,
+ extents->y - clip_y,
extents->x, extents->y,
extents->width, extents->height);
#else
@@ -1907,8 +1909,8 @@ _clip_and_composite_combine (cairo_clip_t *clip,
pixman_image_composite32 (PIXMAN_OP_OUT_REVERSE,
((cairo_image_surface_t *) clip_surface)->pixman_image,
NULL, dst->pixman_image,
- extents->x - clip->path->extents.x,
- extents->y - clip->path->extents.y,
+ extents->x - clip_x,
+ extents->y - clip_y,
0, 0,
extents->x, extents->y,
extents->width, extents->height);
@@ -1919,8 +1921,8 @@ _clip_and_composite_combine (cairo_clip_t *clip,
((cairo_image_surface_t *) clip_surface)->pixman_image,
dst->pixman_image,
0, 0,
- extents->x - clip->path->extents.x,
- extents->y - clip->path->extents.y,
+ extents->x - clip_x,
+ extents->y - clip_y,
extents->x, extents->y,
extents->width, extents->height);
#endif
@@ -1930,8 +1932,8 @@ _clip_and_composite_combine (cairo_clip_t *clip,
((cairo_image_surface_t *) clip_surface)->pixman_image,
dst->pixman_image,
0, 0,
- extents->x - clip->path->extents.x,
- extents->y - clip->path->extents.y,
+ extents->x - clip_x,
+ extents->y - clip_y,
extents->x, extents->y,
extents->width, extents->height);
}
@@ -2741,13 +2743,14 @@ _composite_boxes (cairo_image_surface_t *dst,
if (need_clip_mask) {
cairo_surface_t *clip_surface;
+ int clip_x, clip_y;
- clip_surface = _cairo_clip_get_surface (clip, &dst->base);
+ clip_surface = _cairo_clip_get_surface (clip, &dst->base, &clip_x, &clip_y);
if (unlikely (clip_surface->status))
return clip_surface->status;
- mask_x = -clip->path->extents.x;
- mask_y = -clip->path->extents.y;
+ mask_x = -clip_x;
+ mask_y = -clip_y;
if (op == CAIRO_OPERATOR_CLEAR) {
pattern = NULL;
@@ -2831,9 +2834,9 @@ _clip_and_composite_boxes (cairo_image_surface_t *dst,
info.num_traps = traps.num_traps;
info.traps = traps.traps;
info.antialias = antialias;
- status = _clip_and_composite (dst, op, src,
- _composite_traps, &info,
- extents, clip);
+ status = _clip_and_composite (dst, op, src,
+ _composite_traps, &info,
+ extents, clip);
_cairo_traps_fini (&traps);
return status;
diff --git a/src/cairo-surface-fallback.c b/src/cairo-surface-fallback.c
index 7a6932249..f2b017a6d 100644
--- a/src/cairo-surface-fallback.c
+++ b/src/cairo-surface-fallback.c
@@ -222,6 +222,7 @@ _clip_and_composite_combine (cairo_clip_t *clip,
cairo_surface_pattern_t pattern;
cairo_surface_pattern_t clip_pattern;
cairo_surface_t *clip_surface;
+ int clip_x, clip_y;
cairo_status_t status;
/* We'd be better off here creating a surface identical in format
@@ -266,7 +267,7 @@ _clip_and_composite_combine (cairo_clip_t *clip,
goto CLEANUP_SURFACE;
assert (clip->path != NULL);
- clip_surface = _cairo_clip_get_surface (clip, dst);
+ clip_surface = _cairo_clip_get_surface (clip, dst, &clip_x, &clip_y);
if (unlikely (clip_surface->status))
goto CLEANUP_SURFACE;
@@ -275,8 +276,8 @@ _clip_and_composite_combine (cairo_clip_t *clip,
/* Combine that with the clip */
status = _cairo_surface_composite (CAIRO_OPERATOR_DEST_IN,
&clip_pattern.base, NULL, intermediate,
- extents->x - clip->path->extents.x,
- extents->y - clip->path->extents.y,
+ extents->x - clip_x,
+ extents->y - clip_y,
0, 0,
0, 0,
extents->width, extents->height,
@@ -287,8 +288,8 @@ _clip_and_composite_combine (cairo_clip_t *clip,
/* Punch the clip out of the destination */
status = _cairo_surface_composite (CAIRO_OPERATOR_DEST_OUT,
&clip_pattern.base, NULL, dst,
- extents->x - clip->path->extents.x,
- extents->y - clip->path->extents.y,
+ extents->x - clip_x,
+ extents->y - clip_y,
0, 0,
extents->x, extents->y,
extents->width, extents->height,
@@ -477,9 +478,9 @@ _composite_trap_region (cairo_clip_t *clip,
if (clip != NULL) {
cairo_surface_t *clip_surface = NULL;
- const cairo_rectangle_int_t *clip_extents;
+ int clip_x, clip_y;
- clip_surface = _cairo_clip_get_surface (clip, dst);
+ clip_surface = _cairo_clip_get_surface (clip, dst, &clip_x, &clip_y);
if (unlikely (clip_surface->status))
return clip_surface->status;
@@ -489,9 +490,8 @@ _composite_trap_region (cairo_clip_t *clip,
}
_cairo_pattern_init_for_surface (&mask_pattern, clip_surface);
- clip_extents = _cairo_clip_get_extents (clip);
- mask_x = extents->x - clip_extents->x;
- mask_y = extents->y - clip_extents->y;
+ mask_x = extents->x - clip_x;
+ mask_y = extents->y - clip_y;
mask = &mask_pattern.base;
}
diff --git a/src/cairo-xcb-surface-render.c b/src/cairo-xcb-surface-render.c
index 9cd51f8a9..5775a9eb6 100644
--- a/src/cairo-xcb-surface-render.c
+++ b/src/cairo-xcb-surface-render.c
@@ -1894,6 +1894,7 @@ _clip_and_composite_combine (cairo_clip_t *clip,
{
cairo_xcb_surface_t *tmp;
cairo_surface_t *clip_surface;
+ int clip_x, clip_y;
xcb_render_picture_t clip_picture;
cairo_status_t status;
@@ -1952,7 +1953,7 @@ _clip_and_composite_combine (cairo_clip_t *clip,
if (unlikely (status))
goto CLEANUP_SURFACE;
- clip_surface = _cairo_clip_get_surface (clip, &dst->base);
+ clip_surface = _cairo_clip_get_surface (clip, &dst->base, &clip_x, &clip_y);
if (unlikely (clip_surface->status))
goto CLEANUP_SURFACE;
@@ -1972,8 +1973,8 @@ _clip_and_composite_combine (cairo_clip_t *clip,
_cairo_xcb_connection_render_composite (dst->connection,
XCB_RENDER_PICT_OP_OUT_REVERSE,
clip_picture, XCB_NONE, dst->picture,
- extents->x - clip->path->extents.x,
- extents->y - clip->path->extents.y,
+ extents->x - clip_x,
+ extents->y - clip_y,
0, 0,
extents->x, extents->y,
extents->width, extents->height);
@@ -1983,8 +1984,8 @@ _clip_and_composite_combine (cairo_clip_t *clip,
XCB_RENDER_PICT_OP_ADD,
tmp->picture, clip_picture, dst->picture,
0, 0,
- extents->x - clip->path->extents.x,
- extents->y - clip->path->extents.y,
+ extents->x - clip_x,
+ extents->y - clip_y,
extents->x, extents->y,
extents->width, extents->height);
}
@@ -2182,13 +2183,10 @@ _cairo_xcb_surface_fixup_unbounded_with_mask (cairo_xcb_surface_t *dst,
cairo_xcb_surface_t *mask;
int mask_x, mask_y;
- mask = (cairo_xcb_surface_t *) _cairo_clip_get_surface (clip, &dst->base);
+ mask = (cairo_xcb_surface_t *) _cairo_clip_get_surface (clip, &dst->base, &mask_x, &mask_y);
if (unlikely (mask->base.status))
return mask->base.status;
- mask_x = - clip->path->extents.x;
- mask_y = - clip->path->extents.y;
-
/* top */
if (rects->bounded.y != rects->unbounded.y) {
int x = rects->unbounded.x;
@@ -2199,7 +2197,7 @@ _cairo_xcb_surface_fixup_unbounded_with_mask (cairo_xcb_surface_t *dst,
_cairo_xcb_connection_render_composite (dst->connection,
XCB_RENDER_PICT_OP_OUT_REVERSE,
mask->picture, XCB_NONE, dst->picture,
- x + mask_x, y + mask_y,
+ x - mask_x, y - mask_y,
0, 0,
x, y,
width, height);
@@ -2215,7 +2213,7 @@ _cairo_xcb_surface_fixup_unbounded_with_mask (cairo_xcb_surface_t *dst,
_cairo_xcb_connection_render_composite (dst->connection,
XCB_RENDER_PICT_OP_OUT_REVERSE,
mask->picture, XCB_NONE, dst->picture,
- x + mask_x, y + mask_y,
+ x - mask_x, y - mask_y,
0, 0,
x, y,
width, height);
@@ -2231,7 +2229,7 @@ _cairo_xcb_surface_fixup_unbounded_with_mask (cairo_xcb_surface_t *dst,
_cairo_xcb_connection_render_composite (dst->connection,
XCB_RENDER_PICT_OP_OUT_REVERSE,
mask->picture, XCB_NONE, dst->picture,
- x + mask_x, y + mask_y,
+ x - mask_x, y - mask_y,
0, 0,
x, y,
width, height);
@@ -2247,7 +2245,7 @@ _cairo_xcb_surface_fixup_unbounded_with_mask (cairo_xcb_surface_t *dst,
_cairo_xcb_connection_render_composite (dst->connection,
XCB_RENDER_PICT_OP_OUT_REVERSE,
mask->picture, XCB_NONE, dst->picture,
- x + mask_x, y + mask_y,
+ x - mask_x, y - mask_y,
0, 0,
x, y,
width, height);
@@ -2541,16 +2539,17 @@ _composite_boxes (cairo_xcb_surface_t *dst,
if (need_clip_mask) {
cairo_surface_t *clip_surface;
+ int clip_x, clip_y;
- clip_surface = _cairo_clip_get_surface (clip, &dst->base);
+ clip_surface = _cairo_clip_get_surface (clip, &dst->base, &clip_x, &clip_y);
if (unlikely (clip_surface->status))
return clip_surface->status;
_cairo_pattern_init_for_surface (&mask, clip_surface);
mask.base.filter = CAIRO_FILTER_NEAREST;
cairo_matrix_init_translate (&mask.base.matrix,
- -clip->path->extents.x,
- -clip->path->extents.y);
+ -clip_x,
+ -clip_y);
if (op == CAIRO_OPERATOR_CLEAR) {
src = NULL;
diff --git a/src/drm/cairo-drm-i915-shader.c b/src/drm/cairo-drm-i915-shader.c
index 13f9d85ab..a56513d1f 100644
--- a/src/drm/cairo-drm-i915-shader.c
+++ b/src/drm/cairo-drm-i915-shader.c
@@ -2403,11 +2403,11 @@ i915_shader_set_clip (i915_shader_t *shader,
cairo_clip_t *clip)
{
cairo_surface_t *clip_surface;
- const cairo_rectangle_int_t *clip_extents;
+ int clip_x, clip_y;
union i915_shader_channel *channel;
i915_surface_t *s;
- clip_surface = _cairo_clip_get_surface (clip, &shader->target->intel.drm.base);
+ clip_surface = _cairo_clip_get_surface (clip, &shader->target->intel.drm.base, &clip_x, &clip_y);
assert (clip_surface->status == CAIRO_STATUS_SUCCESS);
assert (clip_surface->type == CAIRO_SURFACE_TYPE_DRM);
@@ -2434,13 +2434,12 @@ i915_shader_set_clip (i915_shader_t *shader,
SS3_NORMALIZED_COORDS |
i915_texture_extend (CAIRO_EXTEND_NONE);
- clip_extents = _cairo_clip_get_extents (clip);
cairo_matrix_init_scale (&shader->clip.base.matrix,
1. / s->intel.drm.width,
1. / s->intel.drm.height);
cairo_matrix_translate (&shader->clip.base.matrix,
- NEAREST_BIAS - clip_extents->x,
- NEAREST_BIAS - clip_extents->y);
+ NEAREST_BIAS - clip_x,
+ NEAREST_BIAS - clip_y);
}
static cairo_status_t
diff --git a/src/drm/cairo-drm-i965-shader.c b/src/drm/cairo-drm-i965-shader.c
index fcfec2957..f18494ce0 100644
--- a/src/drm/cairo-drm-i965-shader.c
+++ b/src/drm/cairo-drm-i965-shader.c
@@ -762,10 +762,11 @@ i965_shader_set_clip (i965_shader_t *shader,
cairo_clip_t *clip)
{
cairo_surface_t *clip_surface;
+ int clip_x, clip_y;
union i965_shader_channel *channel;
i965_surface_t *s;
- clip_surface = _cairo_clip_get_surface (clip, &shader->target->intel.drm.base);
+ clip_surface = _cairo_clip_get_surface (clip, &shader->target->intel.drm.base, &clip_x, &clip_y);
assert (clip_surface->status == CAIRO_STATUS_SUCCESS);
assert (clip_surface->type == CAIRO_SURFACE_TYPE_DRM);
s = (i965_surface_t *) clip_surface;
@@ -793,8 +794,8 @@ i965_shader_set_clip (i965_shader_t *shader,
1. / s->intel.drm.height);
cairo_matrix_translate (&shader->clip.base.matrix,
- NEAREST_BIAS - clip->path->extents.x,
- NEAREST_BIAS - clip->path->extents.y);
+ NEAREST_BIAS - clip_x,
+ NEAREST_BIAS - clip_y);
}
static cairo_bool_t