summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cairo-clip-private.h2
-rw-r--r--src/cairo-clip.c85
-rw-r--r--src/cairo-region.c8
-rw-r--r--src/cairo-surface-fallback.c8
-rw-r--r--src/cairo-traps.c8
-rw-r--r--src/cairo.h2
-rw-r--r--test/clip-stroke.xlib.ref.pngbin1563 -> 1490 bytes
7 files changed, 56 insertions, 57 deletions
diff --git a/src/cairo-clip-private.h b/src/cairo-clip-private.h
index f8faa75a..131d4c7e 100644
--- a/src/cairo-clip-private.h
+++ b/src/cairo-clip-private.h
@@ -116,7 +116,7 @@ _cairo_clip_get_surface (cairo_clip_t *clip, cairo_surface_t *dst);
cairo_private cairo_status_t
_cairo_clip_combine_with_surface (cairo_clip_t *clip,
cairo_surface_t *dst,
- int dst_x, int dst_y);
+ const cairo_rectangle_int_t *extents);
cairo_private cairo_int_status_t
_cairo_clip_get_region (cairo_clip_t *clip,
diff --git a/src/cairo-clip.c b/src/cairo-clip.c
index 0f484424..6609f284 100644
--- a/src/cairo-clip.c
+++ b/src/cairo-clip.c
@@ -973,6 +973,31 @@ _cairo_clip_path_to_boxes (cairo_clip_path_t *clip_path,
return CAIRO_STATUS_SUCCESS;
}
+static cairo_status_t
+_combine_region (cairo_surface_t *surface,
+ const cairo_region_t *region,
+ const cairo_rectangle_int_t *extents)
+{
+ cairo_region_t clear_region;
+ cairo_status_t status;
+
+ _cairo_region_init_rectangle (&clear_region, extents);
+ status = cairo_region_subtract (&clear_region, region);
+ if (unlikely (status))
+ return status;
+
+ if (! cairo_region_is_empty (&clear_region)) {
+ cairo_region_translate (&clear_region, -extents->x, -extents->y);
+ status = _cairo_surface_fill_region (surface,
+ CAIRO_OPERATOR_CLEAR,
+ CAIRO_COLOR_TRANSPARENT,
+ &clear_region);
+ }
+ _cairo_region_fini (&clear_region);
+
+ return status;
+}
+
static cairo_surface_t *
_cairo_clip_path_get_surface (cairo_clip_path_t *clip_path,
cairo_surface_t *target)
@@ -1019,7 +1044,7 @@ _cairo_clip_path_get_surface (cairo_clip_path_t *clip_path,
if (unlikely (_cairo_status_is_error (status)))
goto BAIL;
- need_translate = clip_extents->x || clip_extents->y;
+ need_translate = clip_extents->x | clip_extents->y;
if (status == CAIRO_STATUS_SUCCESS) {
if (need_translate) {
cairo_region_translate (clip_path->region,
@@ -1069,18 +1094,7 @@ _cairo_clip_path_get_surface (cairo_clip_path_t *clip_path,
goto BAIL;
if (status == CAIRO_STATUS_SUCCESS) {
- if (need_translate) {
- cairo_region_translate (prev->region,
- -clip_extents->x, -clip_extents->y);
- }
- status = _cairo_surface_fill_region (surface,
- CAIRO_OPERATOR_IN,
- CAIRO_COLOR_WHITE,
- prev->region);
- if (need_translate) {
- cairo_region_translate (prev->region,
- clip_extents->x, clip_extents->y);
- }
+ status = _combine_region (surface, prev->region, clip_extents);
if (unlikely (status))
goto BAIL;
} else if (prev->path.is_rectilinear) {
@@ -1166,6 +1180,7 @@ _cairo_debug_print_clip (FILE *stream, cairo_clip_t *clip)
clip_path->region == NULL ? "no" : "yes",
clip_path->surface == NULL ? "no" : "yes");
_cairo_debug_print_path (stream, &clip_path->path);
+ fprintf (stream, "\n");
} while ((clip_path = clip_path->prev) != NULL);
}
@@ -1179,12 +1194,11 @@ _cairo_clip_get_surface (cairo_clip_t *clip, cairo_surface_t *target)
cairo_status_t
_cairo_clip_combine_with_surface (cairo_clip_t *clip,
cairo_surface_t *dst,
- int dst_x,
- int dst_y)
+ const cairo_rectangle_int_t *extents)
{
cairo_pattern_union_t pattern;
cairo_clip_path_t *clip_path = clip->path;
- cairo_bool_t translate;
+ cairo_bool_t need_translate;
cairo_status_t status;
assert (clip_path != NULL);
@@ -1195,8 +1209,8 @@ _cairo_clip_combine_with_surface (cairo_clip_t *clip,
_cairo_pattern_init_for_surface (&pattern.surface,
clip_path->surface);
cairo_matrix_init_translate (&pattern.base.matrix,
- dst_x - clip_path->extents.x,
- dst_y - clip_path->extents.y);
+ extents->x - clip_path->extents.x,
+ extents->y - clip_path->extents.y);
status = _cairo_surface_paint (dst,
CAIRO_OPERATOR_IN,
&pattern.base,
@@ -1211,26 +1225,14 @@ _cairo_clip_combine_with_surface (cairo_clip_t *clip,
CAIRO_COLOR_WHITE,
CAIRO_CONTENT_COLOR);
- translate = dst_x | dst_y;
+ need_translate = extents->x | extents->y;
do {
status = _cairo_clip_path_to_region (clip_path);
if (unlikely (_cairo_status_is_error (status)))
return status;
- if (status == CAIRO_STATUS_SUCCESS) {
- if (translate)
- cairo_region_translate (clip_path->region, -dst_x, -dst_y);
-
- status = _cairo_surface_fill_region (dst,
- CAIRO_OPERATOR_IN,
- CAIRO_COLOR_WHITE,
- clip_path->region);
-
- if (translate)
- cairo_region_translate (clip_path->region, dst_x, dst_y);
-
- return status;
- }
+ if (status == CAIRO_STATUS_SUCCESS)
+ return _combine_region (dst, clip_path->region, extents);
if (clip_path->surface != NULL &&
clip_path->surface->backend == dst->backend)
@@ -1238,8 +1240,8 @@ _cairo_clip_combine_with_surface (cairo_clip_t *clip,
_cairo_pattern_init_for_surface (&pattern.surface,
clip_path->surface);
cairo_matrix_init_translate (&pattern.base.matrix,
- dst_x - clip_path->extents.x,
- dst_y - clip_path->extents.y);
+ extents->x - clip_path->extents.x,
+ extents->y - clip_path->extents.y);
status = _cairo_surface_paint (dst,
CAIRO_OPERATOR_IN,
&pattern.base,
@@ -1250,10 +1252,10 @@ _cairo_clip_combine_with_surface (cairo_clip_t *clip,
return status;
}
- if (translate) {
+ if (need_translate) {
_cairo_path_fixed_translate (&clip_path->path,
- _cairo_fixed_from_int (-dst_x),
- _cairo_fixed_from_int (-dst_y));
+ _cairo_fixed_from_int (-extents->x),
+ _cairo_fixed_from_int (-extents->y));
}
status = _cairo_surface_fill (dst,
CAIRO_OPERATOR_IN,
@@ -1263,11 +1265,12 @@ _cairo_clip_combine_with_surface (cairo_clip_t *clip,
clip_path->tolerance,
clip_path->antialias,
NULL);
- if (translate) {
+ if (need_translate) {
_cairo_path_fixed_translate (&clip_path->path,
- _cairo_fixed_from_int (dst_x),
- _cairo_fixed_from_int (dst_y));
+ _cairo_fixed_from_int (extents->x),
+ _cairo_fixed_from_int (extents->y));
}
+
if (unlikely (status))
return status;
} while ((clip_path = clip_path->prev) != NULL);
diff --git a/src/cairo-region.c b/src/cairo-region.c
index 9983481c..2148fcab 100644
--- a/src/cairo-region.c
+++ b/src/cairo-region.c
@@ -426,7 +426,7 @@ slim_hidden_def (cairo_region_status);
* Since: 1.10
**/
cairo_status_t
-cairo_region_subtract (cairo_region_t *dst, cairo_region_t *other)
+cairo_region_subtract (cairo_region_t *dst, const cairo_region_t *other)
{
if (dst->status)
return dst->status;
@@ -434,8 +434,12 @@ cairo_region_subtract (cairo_region_t *dst, cairo_region_t *other)
if (other->status)
return _cairo_region_set_error (dst, other->status);
- if (! pixman_region32_subtract (&dst->rgn, &dst->rgn, &other->rgn))
+ if (! pixman_region32_subtract (&dst->rgn,
+ &dst->rgn,
+ CONST_CAST &other->rgn))
+ {
return _cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY);
+ }
return CAIRO_STATUS_SUCCESS;
}
diff --git a/src/cairo-surface-fallback.c b/src/cairo-surface-fallback.c
index 0f5f8212..79d719dc 100644
--- a/src/cairo-surface-fallback.c
+++ b/src/cairo-surface-fallback.c
@@ -163,12 +163,8 @@ _create_composite_mask_pattern (cairo_surface_pattern_t *mask_pattern,
if (unlikely (status))
goto CLEANUP_SURFACE;
- if (clip_surface) {
- status = _cairo_clip_combine_with_surface (clip,
- mask,
- extents->x,
- extents->y);
- }
+ if (clip_surface)
+ status = _cairo_clip_combine_with_surface (clip, mask, extents);
_cairo_pattern_init_for_surface (mask_pattern, mask);
diff --git a/src/cairo-traps.c b/src/cairo-traps.c
index d6fec260..70d4c69e 100644
--- a/src/cairo-traps.c
+++ b/src/cairo-traps.c
@@ -264,9 +264,7 @@ _cairo_traps_tessellate_rectangle (cairo_traps_t *traps,
continue;
_left = left;
- if (_left.p1.x <= limits->p1.x &&
- _left.p2.x <= limits->p1.x)
- {
+ if (_left.p1.x < limits->p1.x) {
_left.p1.x = limits->p1.x;
_left.p1.y = limits->p1.y;
_left.p2.x = limits->p1.x;
@@ -274,9 +272,7 @@ _cairo_traps_tessellate_rectangle (cairo_traps_t *traps,
}
_right = right;
- if (_right.p1.x >= limits->p2.x &&
- _right.p2.x >= limits->p2.x)
- {
+ if (_right.p1.x > limits->p2.x) {
_right.p1.x = limits->p2.x;
_right.p1.y = limits->p1.y;
_right.p2.x = limits->p2.x;
diff --git a/src/cairo.h b/src/cairo.h
index b750c4e3..a046a471 100644
--- a/src/cairo.h
+++ b/src/cairo.h
@@ -2518,7 +2518,7 @@ cairo_public void
cairo_region_translate (cairo_region_t *region, int dx, int dy);
cairo_public cairo_status_t
-cairo_region_subtract (cairo_region_t *dst, cairo_region_t *other);
+cairo_region_subtract (cairo_region_t *dst, const cairo_region_t *other);
cairo_public cairo_status_t
cairo_region_subtract_rectangle (cairo_region_t *dst,
diff --git a/test/clip-stroke.xlib.ref.png b/test/clip-stroke.xlib.ref.png
index 142dc79d..b7767498 100644
--- a/test/clip-stroke.xlib.ref.png
+++ b/test/clip-stroke.xlib.ref.png
Binary files differ