summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2008-10-30 16:56:07 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2008-10-30 16:56:07 +0000
commit31ada1ea15d14c0a843728b105340c270e4e4613 (patch)
tree675c66cce8676320b55a95d1261edcaa5cd62852
parent30f2df1dec419a10408b53ecd26cebfcf607bf27 (diff)
parentab15d7627506a837fea7101661425bb923ef5b4f (diff)
Merge branch '1.8'
-rw-r--r--src/cairo-analysis-surface.c54
-rw-r--r--src/cairo-clip.c43
-rw-r--r--src/cairo-gstate.c73
-rw-r--r--src/cairo-pattern.c21
-rw-r--r--src/cairo-rectangle.c37
-rw-r--r--src/cairo-region-private.h3
-rw-r--r--src/cairo-region.c3
-rw-r--r--src/cairo-surface-fallback.c31
-rw-r--r--src/cairo-surface.c27
-rw-r--r--src/cairo-win32-surface.c4
-rw-r--r--src/cairo-xcb-surface.c56
-rw-r--r--src/cairo-xlib-surface.c52
-rw-r--r--src/cairoint.h5
-rw-r--r--test/Makefile.am15
-rw-r--r--test/clip-operator-pdf-argb32-ref.pngbin11145 -> 12125 bytes
-rw-r--r--test/clip-operator-pdf-rgb24-ref.pngbin6530 -> 7367 bytes
-rw-r--r--test/operator-clear-pdf-argb32-ref.pngbin1438 -> 1614 bytes
-rw-r--r--test/operator-clear-pdf-rgb24-ref.pngbin1170 -> 1402 bytes
-rw-r--r--test/operator-source-pdf-argb32-ref.pngbin4694 -> 5149 bytes
-rw-r--r--test/operator-source-pdf-rgb24-ref.pngbin3848 -> 4354 bytes
-rw-r--r--test/user-font-mask-pdf-ref.pngbin0 -> 1927 bytes
-rw-r--r--test/user-font-mask-ps2-ref.pngbin0 -> 1927 bytes
-rw-r--r--test/user-font-mask-ps3-ref.pngbin0 -> 1927 bytes
-rw-r--r--test/user-font-mask-svg11-ref.pngbin0 -> 2224 bytes
24 files changed, 228 insertions, 196 deletions
diff --git a/src/cairo-analysis-surface.c b/src/cairo-analysis-surface.c
index 5093459b..057be529 100644
--- a/src/cairo-analysis-surface.c
+++ b/src/cairo-analysis-surface.c
@@ -285,6 +285,7 @@ _cairo_analysis_surface_intersect_clip_path (void *abstract_surface,
cairo_analysis_surface_t *surface = abstract_surface;
double x1, y1, x2, y2;
cairo_rectangle_int_t extent;
+ cairo_bool_t is_empty;
if (path == NULL) {
surface->current_clip.x = 0;
@@ -303,7 +304,7 @@ _cairo_analysis_surface_intersect_clip_path (void *abstract_surface,
extent.width = ceil (x2) - extent.x;
extent.height = ceil (y2) - extent.y;
- _cairo_rectangle_intersect (&surface->current_clip, &extent);
+ is_empty = _cairo_rectangle_intersect (&surface->current_clip, &extent);
}
return CAIRO_STATUS_SUCCESS;
@@ -326,6 +327,7 @@ _cairo_analysis_surface_paint (void *abstract_surface,
cairo_analysis_surface_t *surface = abstract_surface;
cairo_status_t status, backend_status;
cairo_rectangle_int_t extents;
+ cairo_bool_t is_empty;
if (!surface->target->backend->paint)
backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
@@ -342,14 +344,15 @@ _cairo_analysis_surface_paint (void *abstract_surface,
if (_cairo_operator_bounded_by_source (op)) {
cairo_rectangle_int_t source_extents;
+
status = _cairo_pattern_get_extents (source, &source_extents);
if (status)
return status;
- _cairo_rectangle_intersect (&extents, &source_extents);
+ is_empty = _cairo_rectangle_intersect (&extents, &source_extents);
}
- _cairo_rectangle_intersect (&extents, &surface->current_clip);
+ is_empty = _cairo_rectangle_intersect (&extents, &surface->current_clip);
status = _add_operation (surface, &extents, backend_status);
@@ -365,6 +368,7 @@ _cairo_analysis_surface_mask (void *abstract_surface,
cairo_analysis_surface_t *surface = abstract_surface;
cairo_int_status_t status, backend_status;
cairo_rectangle_int_t extents;
+ cairo_bool_t is_empty;
if (!surface->target->backend->mask)
backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
@@ -411,16 +415,20 @@ _cairo_analysis_surface_mask (void *abstract_surface,
if (status)
return status;
- _cairo_rectangle_intersect (&extents, &source_extents);
+ is_empty = _cairo_rectangle_intersect (&extents, &source_extents);
+ }
- status = _cairo_pattern_get_extents (mask, &source_extents);
+ if (_cairo_operator_bounded_by_mask (op)) {
+ cairo_rectangle_int_t mask_extents;
+
+ status = _cairo_pattern_get_extents (mask, &mask_extents);
if (status)
return status;
- _cairo_rectangle_intersect (&extents, &source_extents);
+ is_empty = _cairo_rectangle_intersect (&extents, &mask_extents);
}
- _cairo_rectangle_intersect (&extents, &surface->current_clip);
+ is_empty = _cairo_rectangle_intersect (&extents, &surface->current_clip);
status = _add_operation (surface, &extents, backend_status);
@@ -441,7 +449,8 @@ _cairo_analysis_surface_stroke (void *abstract_surface,
cairo_analysis_surface_t *surface = abstract_surface;
cairo_status_t status, backend_status;
cairo_traps_t traps;
- cairo_rectangle_int_t extents;
+ cairo_rectangle_int_t extents;
+ cairo_bool_t is_empty;
if (!surface->target->backend->stroke)
backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
@@ -460,14 +469,15 @@ _cairo_analysis_surface_stroke (void *abstract_surface,
if (_cairo_operator_bounded_by_source (op)) {
cairo_rectangle_int_t source_extents;
+
status = _cairo_pattern_get_extents (source, &source_extents);
if (status)
return status;
- _cairo_rectangle_intersect (&extents, &source_extents);
+ is_empty = _cairo_rectangle_intersect (&extents, &source_extents);
}
- _cairo_rectangle_intersect (&extents, &surface->current_clip);
+ is_empty = _cairo_rectangle_intersect (&extents, &surface->current_clip);
if (_cairo_operator_bounded_by_mask (op)) {
cairo_box_t box;
@@ -509,7 +519,8 @@ _cairo_analysis_surface_fill (void *abstract_surface,
cairo_analysis_surface_t *surface = abstract_surface;
cairo_status_t status, backend_status;
cairo_traps_t traps;
- cairo_rectangle_int_t extents;
+ cairo_rectangle_int_t extents;
+ cairo_bool_t is_empty;
if (!surface->target->backend->fill)
backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
@@ -527,14 +538,15 @@ _cairo_analysis_surface_fill (void *abstract_surface,
if (_cairo_operator_bounded_by_source (op)) {
cairo_rectangle_int_t source_extents;
+
status = _cairo_pattern_get_extents (source, &source_extents);
if (status)
return status;
- _cairo_rectangle_intersect (&extents, &source_extents);
+ is_empty = _cairo_rectangle_intersect (&extents, &source_extents);
}
- _cairo_rectangle_intersect (&extents, &surface->current_clip);
+ is_empty = _cairo_rectangle_intersect (&extents, &surface->current_clip);
if (_cairo_operator_bounded_by_mask (op)) {
cairo_box_t box;
@@ -575,6 +587,7 @@ _cairo_analysis_surface_show_glyphs (void *abstract_surface,
cairo_analysis_surface_t *surface = abstract_surface;
cairo_status_t status, backend_status;
cairo_rectangle_int_t extents, glyph_extents;
+ cairo_bool_t is_empty;
/* Adapted from _cairo_surface_show_glyphs */
if (surface->target->backend->show_glyphs)
@@ -603,14 +616,15 @@ _cairo_analysis_surface_show_glyphs (void *abstract_surface,
if (_cairo_operator_bounded_by_source (op)) {
cairo_rectangle_int_t source_extents;
+
status = _cairo_pattern_get_extents (source, &source_extents);
if (status)
return status;
- _cairo_rectangle_intersect (&extents, &source_extents);
+ is_empty = _cairo_rectangle_intersect (&extents, &source_extents);
}
- _cairo_rectangle_intersect (&extents, &surface->current_clip);
+ is_empty = _cairo_rectangle_intersect (&extents, &surface->current_clip);
if (_cairo_operator_bounded_by_mask (op)) {
status = _cairo_scaled_font_glyph_device_extents (scaled_font,
@@ -620,7 +634,7 @@ _cairo_analysis_surface_show_glyphs (void *abstract_surface,
if (status)
return status;
- _cairo_rectangle_intersect (&extents, &glyph_extents);
+ is_empty = _cairo_rectangle_intersect (&extents, &glyph_extents);
}
status = _add_operation (surface, &extents, backend_status);
@@ -652,6 +666,7 @@ _cairo_analysis_surface_show_text_glyphs (void *abstract_surface,
cairo_analysis_surface_t *surface = abstract_surface;
cairo_status_t status, backend_status;
cairo_rectangle_int_t extents, glyph_extents;
+ cairo_bool_t is_empty;
/* Adapted from _cairo_surface_show_glyphs */
backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
@@ -684,14 +699,15 @@ _cairo_analysis_surface_show_text_glyphs (void *abstract_surface,
if (_cairo_operator_bounded_by_source (op)) {
cairo_rectangle_int_t source_extents;
+
status = _cairo_pattern_get_extents (source, &source_extents);
if (status)
return status;
- _cairo_rectangle_intersect (&extents, &source_extents);
+ is_empty = _cairo_rectangle_intersect (&extents, &source_extents);
}
- _cairo_rectangle_intersect (&extents, &surface->current_clip);
+ is_empty = _cairo_rectangle_intersect (&extents, &surface->current_clip);
if (_cairo_operator_bounded_by_mask (op)) {
status = _cairo_scaled_font_glyph_device_extents (scaled_font,
@@ -701,7 +717,7 @@ _cairo_analysis_surface_show_text_glyphs (void *abstract_surface,
if (status)
return status;
- _cairo_rectangle_intersect (&extents, &glyph_extents);
+ is_empty = _cairo_rectangle_intersect (&extents, &glyph_extents);
}
status = _add_operation (surface, &extents, backend_status);
diff --git a/src/cairo-clip.c b/src/cairo-clip.c
index 308da326..8a0d4db1 100644
--- a/src/cairo-clip.c
+++ b/src/cairo-clip.c
@@ -166,7 +166,8 @@ _cairo_clip_path_intersect_to_rectangle (cairo_clip_path_t *clip_path,
_cairo_traps_fini (&traps);
_cairo_box_round_to_rectangle (&extents, &extents_rect);
- _cairo_rectangle_intersect (rectangle, &extents_rect);
+ if (! _cairo_rectangle_intersect (rectangle, &extents_rect))
+ return CAIRO_STATUS_SUCCESS;
clip_path = clip_path->prev;
}
@@ -178,6 +179,9 @@ cairo_status_t
_cairo_clip_intersect_to_rectangle (cairo_clip_t *clip,
cairo_rectangle_int_t *rectangle)
{
+ cairo_status_t status;
+ cairo_bool_t is_empty;
+
if (!clip)
return CAIRO_STATUS_SUCCESS;
@@ -187,8 +191,6 @@ _cairo_clip_intersect_to_rectangle (cairo_clip_t *clip,
}
if (clip->path) {
- cairo_status_t status;
-
status = _cairo_clip_path_intersect_to_rectangle (clip->path,
rectangle);
if (status)
@@ -196,7 +198,6 @@ _cairo_clip_intersect_to_rectangle (cairo_clip_t *clip,
}
if (clip->has_region) {
- cairo_status_t status = CAIRO_STATUS_SUCCESS;
cairo_region_t intersection;
_cairo_region_init_rect (&intersection, rectangle);
@@ -214,7 +215,7 @@ _cairo_clip_intersect_to_rectangle (cairo_clip_t *clip,
}
if (clip->surface)
- _cairo_rectangle_intersect (rectangle, &clip->surface_rect);
+ is_empty = _cairo_rectangle_intersect (rectangle, &clip->surface_rect);
return CAIRO_STATUS_SUCCESS;
}
@@ -421,7 +422,7 @@ _cairo_clip_intersect_mask (cairo_clip_t *clip,
cairo_pattern_union_t pattern;
cairo_box_t extents;
cairo_rectangle_int_t surface_rect, target_rect;
- cairo_surface_t *surface;
+ cairo_surface_t *surface = NULL;
cairo_status_t status;
if (clip->all_clipped)
@@ -434,22 +435,21 @@ _cairo_clip_intersect_mask (cairo_clip_t *clip,
_cairo_traps_extents (traps, &extents);
_cairo_box_round_to_rectangle (&extents, &surface_rect);
- if (clip->surface != NULL)
- _cairo_rectangle_intersect (&surface_rect, &clip->surface_rect);
+ if (clip->surface != NULL) {
+ if (! _cairo_rectangle_intersect (&surface_rect, &clip->surface_rect))
+ goto DONE;
+ }
/* Intersect with the target surface rectangle so we don't use
* more memory and time than we need to. */
status = _cairo_surface_get_extents (target, &target_rect);
- if (status == CAIRO_STATUS_SUCCESS)
- _cairo_rectangle_intersect (&surface_rect, &target_rect);
+ if (status == CAIRO_STATUS_SUCCESS) {
+ if (! _cairo_rectangle_intersect (&surface_rect, &target_rect))
+ goto DONE;
+ }
- if (surface_rect.width == 0 || surface_rect.height == 0) {
- surface = NULL;
- status = CAIRO_STATUS_SUCCESS;
- if (clip->surface != NULL)
- cairo_surface_destroy (clip->surface);
+ if (surface_rect.width == 0 || surface_rect.height == 0)
goto DONE;
- }
_cairo_pattern_init_solid (&pattern.solid, CAIRO_COLOR_WHITE,
CAIRO_CONTENT_COLOR);
@@ -539,11 +539,10 @@ _cairo_clip_intersect_mask (cairo_clip_t *clip,
cairo_surface_destroy (surface);
return status;
}
-
- cairo_surface_destroy (clip->surface);
}
DONE:
+ cairo_surface_destroy (clip->surface);
clip->surface = surface;
clip->surface_rect = surface_rect;
clip->serial = _cairo_surface_allocate_clip_serial (target);
@@ -740,10 +739,12 @@ _cairo_clip_int_rect_to_user (cairo_gstate_t *gstate,
double x1 = clip_rect->x;
double y1 = clip_rect->y;
- double x2 = clip_rect->x + clip_rect->width;
- double y2 = clip_rect->y + clip_rect->height;
+ double x2 = clip_rect->x + (int) clip_rect->width;
+ double y2 = clip_rect->y + (int) clip_rect->height;
- _cairo_gstate_backend_to_user_rectangle (gstate, &x1, &y1, &x2, &y2, &is_tight);
+ _cairo_gstate_backend_to_user_rectangle (gstate,
+ &x1, &y1, &x2, &y2,
+ &is_tight);
user_rect->x = x1;
user_rect->y = y1;
diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c
index 00f498e0..fe8d2792 100644
--- a/src/cairo-gstate.c
+++ b/src/cairo-gstate.c
@@ -785,12 +785,25 @@ _cairo_gstate_path_extents (cairo_gstate_t *gstate,
double *x2, double *y2)
{
cairo_status_t status;
+ double px1, py1, px2, py2;
- status = _cairo_path_fixed_bounds (path, x1, y1, x2, y2, gstate->tolerance);
+ status = _cairo_path_fixed_bounds (path,
+ &px1, &py1, &px2, &py2,
+ gstate->tolerance);
if (status)
return status;
- _cairo_gstate_backend_to_user_rectangle (gstate, x1, y1, x2, y2, NULL);
+ _cairo_gstate_backend_to_user_rectangle (gstate,
+ &px1, &py1, &px2, &py2,
+ NULL);
+ if (x1)
+ *x1 = px1;
+ if (y1)
+ *y1 = py1;
+ if (x2)
+ *x2 = px2;
+ if (y2)
+ *y2 = py2;
return CAIRO_STATUS_SUCCESS;
}
@@ -1083,18 +1096,26 @@ _cairo_gstate_traps_extents_to_user_rectangle (cairo_gstate_t *gstate,
if (y2)
*y2 = 0.0;
} else {
+ double px1, py1, px2, py2;
+
_cairo_traps_extents (traps, &extents);
+ px1 = _cairo_fixed_to_double (extents.p1.x);
+ py1 = _cairo_fixed_to_double (extents.p1.y);
+ px2 = _cairo_fixed_to_double (extents.p2.x);
+ py2 = _cairo_fixed_to_double (extents.p2.y);
+
+ _cairo_gstate_backend_to_user_rectangle (gstate,
+ &px1, &py1, &px2, &py2,
+ NULL);
if (x1)
- *x1 = _cairo_fixed_to_double (extents.p1.x);
+ *x1 = px1;
if (y1)
- *y1 = _cairo_fixed_to_double (extents.p1.y);
+ *y1 = py1;
if (x2)
- *x2 = _cairo_fixed_to_double (extents.p2.x);
+ *x2 = px2;
if (y2)
- *y2 = _cairo_fixed_to_double (extents.p2.y);
-
- _cairo_gstate_backend_to_user_rectangle (gstate, x1, y1, x2, y2, NULL);
+ *y2 = py2;
}
}
@@ -1128,7 +1149,8 @@ _cairo_gstate_stroke_extents (cairo_gstate_t *gstate,
gstate->tolerance,
&traps);
if (status == CAIRO_STATUS_SUCCESS) {
- _cairo_gstate_traps_extents_to_user_rectangle(gstate, &traps, x1, y1, x2, y2);
+ _cairo_gstate_traps_extents_to_user_rectangle (gstate, &traps,
+ x1, y1, x2, y2);
}
_cairo_traps_fini (&traps);
@@ -1152,7 +1174,8 @@ _cairo_gstate_fill_extents (cairo_gstate_t *gstate,
gstate->tolerance,
&traps);
if (status == CAIRO_STATUS_SUCCESS) {
- _cairo_gstate_traps_extents_to_user_rectangle(gstate, &traps, x1, y1, x2, y2);
+ _cairo_gstate_traps_extents_to_user_rectangle (gstate, &traps,
+ x1, y1, x2, y2);
}
_cairo_traps_fini (&traps);
@@ -1195,26 +1218,34 @@ cairo_status_t
_cairo_gstate_clip_extents (cairo_gstate_t *gstate,
double *x1,
double *y1,
- double *x2,
- double *y2)
+ double *x2,
+ double *y2)
{
cairo_rectangle_int_t extents;
+ double px1, py1, px2, py2;
cairo_status_t status;
-
+
status = _cairo_gstate_int_clip_extents (gstate, &extents);
if (status)
return status;
+ px1 = extents.x;
+ py1 = extents.y;
+ px2 = extents.x + (int) extents.width;
+ py2 = extents.y + (int) extents.height;
+
+ _cairo_gstate_backend_to_user_rectangle (gstate,
+ &px1, &py1, &px2, &py2,
+ NULL);
+
if (x1)
- *x1 = extents.x;
+ *x1 = px1;
if (y1)
- *y1 = extents.y;
+ *y1 = py1;
if (x2)
- *x2 = extents.x + extents.width;
+ *x2 = px2;
if (y2)
- *y2 = extents.y + extents.height;
-
- _cairo_gstate_backend_to_user_rectangle (gstate, x1, y1, x2, y2, NULL);
+ *y2 = py2;
return CAIRO_STATUS_SUCCESS;
}
@@ -1754,8 +1785,8 @@ _cairo_gstate_transform_glyphs_to_backend (cairo_gstate_t *gstate,
*/
x1 = surface_extents.x - 2*scale;
y1 = surface_extents.y - 2*scale;
- x2 = surface_extents.x + surface_extents.width + scale;
- y2 = surface_extents.y + surface_extents.height + scale;
+ x2 = surface_extents.x + (int) surface_extents.width + scale;
+ y2 = surface_extents.y + (int) surface_extents.height + scale;
}
if (!drop)
diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c
index d83142a9..81fa62ad 100644
--- a/src/cairo-pattern.c
+++ b/src/cairo-pattern.c
@@ -1908,6 +1908,7 @@ _cairo_pattern_acquire_surface_for_surface (cairo_surface_pattern_t *pattern,
attr->acquired = TRUE;
} else {
cairo_rectangle_int_t extents;
+ cairo_bool_t is_empty;
status = _cairo_surface_get_extents (pattern->surface, &extents);
if (status)
@@ -1932,8 +1933,8 @@ _cairo_pattern_acquire_surface_for_surface (cairo_surface_pattern_t *pattern,
} else {
double x1 = x;
double y1 = y;
- double x2 = x + width;
- double y2 = y + height;
+ double x2 = x + (int) width;
+ double y2 = y + (int) height;
_cairo_matrix_transform_bounding_box (&attr->matrix,
&x1, &y1, &x2, &y2,
@@ -1950,9 +1951,11 @@ _cairo_pattern_acquire_surface_for_surface (cairo_surface_pattern_t *pattern,
sampled_area.y += ty;
/* Never acquire a larger area than the source itself */
- _cairo_rectangle_intersect (&extents, &sampled_area);
+ is_empty = _cairo_rectangle_intersect (&extents, &sampled_area);
}
+ /* XXX can we use is_empty? */
+
status = _cairo_surface_clone_similar (dst, pattern->surface,
extents.x, extents.y,
extents.width, extents.height,
@@ -2237,8 +2240,8 @@ _cairo_pattern_get_extents (cairo_pattern_t *pattern,
_cairo_pattern_analyze_filter (surface_pattern, &pad);
x1 = surface_extents.x - pad;
y1 = surface_extents.y - pad;
- x2 = surface_extents.x + surface_extents.width + pad;
- y2 = surface_extents.y + surface_extents.height + pad;
+ x2 = surface_extents.x + (int) surface_extents.width + pad;
+ y2 = surface_extents.y + (int) surface_extents.height + pad;
imatrix = pattern->matrix;
status = cairo_matrix_invert (&imatrix);
@@ -2250,11 +2253,11 @@ _cairo_pattern_get_extents (cairo_pattern_t *pattern,
NULL);
x1 = floor (x1);
- if (x1 < 0)
- x1 = 0;
+ if (x1 < CAIRO_RECT_INT_MIN)
+ x1 = CAIRO_RECT_INT_MIN;
y1 = floor (y1);
- if (y1 < 0)
- y1 = 0;
+ if (y1 < CAIRO_RECT_INT_MIN)
+ y1 = CAIRO_RECT_INT_MIN;
x2 = ceil (x2);
if (x2 > CAIRO_RECT_INT_MAX)
diff --git a/src/cairo-rectangle.c b/src/cairo-rectangle.c
index 3618ba0b..2143f0c6 100644
--- a/src/cairo-rectangle.c
+++ b/src/cairo-rectangle.c
@@ -95,30 +95,37 @@ _cairo_box_round_to_rectangle (const cairo_box_t *box,
rectangle->height = _cairo_fixed_integer_ceil (box->p2.y) - rectangle->y;
}
-void
-_cairo_rectangle_intersect (cairo_rectangle_int_t *dest, cairo_rectangle_int_t *src)
+cairo_bool_t
+_cairo_rectangle_intersect (cairo_rectangle_int_t *dst,
+ const cairo_rectangle_int_t *src)
{
int x1, y1, x2, y2;
- x1 = MAX (dest->x, src->x);
- y1 = MAX (dest->y, src->y);
- x2 = MIN (dest->x + dest->width, src->x + src->width);
- y2 = MIN (dest->y + dest->height, src->y + src->height);
+ x1 = MAX (dst->x, src->x);
+ y1 = MAX (dst->y, src->y);
+ /* Beware the unsigned promotion, fortunately we have bits to spare
+ * as (CAIRO_RECT_INT_MAX - CAIRO_RECT_INT_MIN) < UINT_MAX
+ */
+ x2 = MIN (dst->x + (int) dst->width, src->x + (int) src->width);
+ y2 = MIN (dst->y + (int) dst->height, src->y + (int) src->height);
if (x1 >= x2 || y1 >= y2) {
- dest->x = 0;
- dest->y = 0;
- dest->width = 0;
- dest->height = 0;
+ dst->x = 0;
+ dst->y = 0;
+ dst->width = 0;
+ dst->height = 0;
+
+ return FALSE;
} else {
- dest->x = x1;
- dest->y = y1;
- dest->width = x2 - x1;
- dest->height = y2 - y1;
+ dst->x = x1;
+ dst->y = y1;
+ dst->width = x2 - x1;
+ dst->height = y2 - y1;
+
+ return TRUE;
}
}
-
#define P1x (line->p1.x)
#define P1y (line->p1.y)
#define P2x (line->p2.x)
diff --git a/src/cairo-region-private.h b/src/cairo-region-private.h
index 352a23f9..588762e5 100644
--- a/src/cairo-region-private.h
+++ b/src/cairo-region-private.h
@@ -108,7 +108,8 @@ _cairo_region_translate (cairo_region_t *region,
int x, int y);
cairo_private pixman_region_overlap_t
-_cairo_region_contains_rectangle (cairo_region_t *region, cairo_rectangle_int_t *box);
+_cairo_region_contains_rectangle (cairo_region_t *region,
+ const cairo_rectangle_int_t *box);
CAIRO_END_DECLS
diff --git a/src/cairo-region.c b/src/cairo-region.c
index 746b3b19..23a042fd 100644
--- a/src/cairo-region.c
+++ b/src/cairo-region.c
@@ -207,7 +207,8 @@ _cairo_region_translate (cairo_region_t *region,
}
pixman_region_overlap_t
-_cairo_region_contains_rectangle (cairo_region_t *region, cairo_rectangle_int_t *rect)
+_cairo_region_contains_rectangle (cairo_region_t *region,
+ const cairo_rectangle_int_t *rect)
{
pixman_box32_t pbox;
diff --git a/src/cairo-surface-fallback.c b/src/cairo-surface-fallback.c
index c44dfafa..5b9c99a6 100644
--- a/src/cairo-surface-fallback.c
+++ b/src/cairo-surface-fallback.c
@@ -548,7 +548,6 @@ _clip_and_composite_trapezoids (cairo_pattern_t *src,
if (has_trap_region) {
status = _cairo_clip_intersect_to_region (clip, &trap_region);
-
if (status)
goto out;
@@ -559,9 +558,12 @@ _clip_and_composite_trapezoids (cairo_pattern_t *src,
_cairo_box_round_to_rectangle (&trap_box, &trap_extents);
}
- _cairo_rectangle_intersect (&extents, &trap_extents);
- status = _cairo_clip_intersect_to_rectangle (clip, &extents);
+ if (! _cairo_rectangle_intersect (&extents, &trap_extents)) {
+ status = CAIRO_STATUS_SUCCESS;
+ goto out;
+ }
+ status = _cairo_clip_intersect_to_rectangle (clip, &extents);
if (status)
goto out;
} else {
@@ -688,7 +690,8 @@ _cairo_surface_fallback_paint (cairo_surface_t *surface,
if (status)
return status;
- _cairo_rectangle_intersect (&extents, &source_extents);
+ if (! _cairo_rectangle_intersect (&extents, &source_extents))
+ return CAIRO_STATUS_SUCCESS;
}
status = _cairo_clip_intersect_to_rectangle (surface->clip, &extents);
@@ -756,7 +759,8 @@ _cairo_surface_fallback_mask (cairo_surface_t *surface,
if (status)
return status;
- _cairo_rectangle_intersect (&extents, &source_extents);
+ if (! _cairo_rectangle_intersect (&extents, &source_extents))
+ return CAIRO_STATUS_SUCCESS;
}
if (_cairo_operator_bounded_by_mask (op)) {
@@ -764,7 +768,8 @@ _cairo_surface_fallback_mask (cairo_surface_t *surface,
if (status)
return status;
- _cairo_rectangle_intersect (&extents, &mask_extents);
+ if (! _cairo_rectangle_intersect (&extents, &mask_extents))
+ return CAIRO_STATUS_SUCCESS;
}
status = _cairo_clip_intersect_to_rectangle (surface->clip, &extents);
@@ -807,7 +812,8 @@ _cairo_surface_fallback_stroke (cairo_surface_t *surface,
if (status)
return status;
- _cairo_rectangle_intersect (&extents, &source_extents);
+ if (! _cairo_rectangle_intersect (&extents, &source_extents))
+ return CAIRO_STATUS_SUCCESS;
}
status = _cairo_clip_intersect_to_rectangle (surface->clip, &extents);
@@ -863,11 +869,13 @@ _cairo_surface_fallback_fill (cairo_surface_t *surface,
if (_cairo_operator_bounded_by_source (op)) {
cairo_rectangle_int_t source_extents;
+
status = _cairo_pattern_get_extents (source, &source_extents);
if (status)
return status;
- _cairo_rectangle_intersect (&extents, &source_extents);
+ if (! _cairo_rectangle_intersect (&extents, &source_extents))
+ return CAIRO_STATUS_SUCCESS;
}
status = _cairo_clip_intersect_to_rectangle (surface->clip, &extents);
@@ -996,7 +1004,8 @@ _cairo_surface_fallback_show_glyphs (cairo_surface_t *surface,
if (status)
return status;
- _cairo_rectangle_intersect (&extents, &glyph_extents);
+ if (! _cairo_rectangle_intersect (&extents, &glyph_extents))
+ return CAIRO_STATUS_SUCCESS;
}
status = _cairo_clip_intersect_to_rectangle (surface->clip, &extents);
@@ -1142,9 +1151,9 @@ _cairo_surface_fallback_fill_rectangles (cairo_surface_t *surface,
if (rects[i].y < y1)
y1 = rects[i].y;
- if ((int)(rects[i].x + rects[i].width) > x2)
+ if ((int) (rects[i].x + rects[i].width) > x2)
x2 = rects[i].x + rects[i].width;
- if ((int)(rects[i].y + rects[i].height) > y2)
+ if ((int) (rects[i].y + rects[i].height) > y2)
y2 = rects[i].y + rects[i].height;
}
diff --git a/src/cairo-surface.c b/src/cairo-surface.c
index d1df1869..609a0e05 100644
--- a/src/cairo-surface.c
+++ b/src/cairo-surface.c
@@ -2388,7 +2388,6 @@ _cairo_surface_composite_fixup_unbounded_internal (cairo_surface_t *dst,
cairo_rectangle_int_t dst_rectangle;
cairo_rectangle_int_t drawn_rectangle;
cairo_bool_t has_drawn_region = FALSE;
- cairo_bool_t has_clear_region = FALSE;
cairo_region_t drawn_region;
cairo_region_t clear_region;
cairo_status_t status;
@@ -2400,36 +2399,40 @@ _cairo_surface_composite_fixup_unbounded_internal (cairo_surface_t *dst,
dst_rectangle.y = dst_y;
dst_rectangle.width = width;
dst_rectangle.height = height;
+ _cairo_region_init_rect (&clear_region, &dst_rectangle);
drawn_rectangle = dst_rectangle;
- if (src_rectangle)
- _cairo_rectangle_intersect (&drawn_rectangle, src_rectangle);
+ if (src_rectangle) {
+ if (! _cairo_rectangle_intersect (&drawn_rectangle, src_rectangle))
+ goto EMPTY;
+ }
- if (mask_rectangle)
- _cairo_rectangle_intersect (&drawn_rectangle, mask_rectangle);
+ if (mask_rectangle) {
+ if (! _cairo_rectangle_intersect (&drawn_rectangle, mask_rectangle))
+ goto EMPTY;
+ }
/* Now compute the area that is in dst_rectangle but not in drawn_rectangle
*/
_cairo_region_init_rect (&drawn_region, &drawn_rectangle);
- _cairo_region_init_rect (&clear_region, &dst_rectangle);
-
has_drawn_region = TRUE;
- has_clear_region = TRUE;
- status = _cairo_region_subtract (&clear_region, &clear_region, &drawn_region);
+ status = _cairo_region_subtract (&clear_region,
+ &clear_region,
+ &drawn_region);
if (status)
goto CLEANUP_REGIONS;
+ EMPTY:
status = _cairo_surface_fill_region (dst, CAIRO_OPERATOR_SOURCE,
CAIRO_COLOR_TRANSPARENT,
&clear_region);
-CLEANUP_REGIONS:
+ CLEANUP_REGIONS:
if (has_drawn_region)
_cairo_region_fini (&drawn_region);
- if (has_clear_region)
- _cairo_region_fini (&clear_region);
+ _cairo_region_fini (&clear_region);
return _cairo_surface_set_error (dst, status);
}
diff --git a/src/cairo-win32-surface.c b/src/cairo-win32-surface.c
index a473c381..5787e261 100644
--- a/src/cairo-win32-surface.c
+++ b/src/cairo-win32-surface.c
@@ -638,9 +638,9 @@ _cairo_win32_surface_acquire_dest_image (void *abstract_surfa
x1 = interest_rect->x;
if (interest_rect->y > y1)
y1 = interest_rect->y;
- if (interest_rect->x + interest_rect->width < x2)
+ if ((int) (interest_rect->x + interest_rect->width) < x2)
x2 = interest_rect->x + interest_rect->width;
- if (interest_rect->y + interest_rect->height < y2)
+ if ((int) (interest_rect->y + interest_rect->height) < y2)
y2 = interest_rect->y + interest_rect->height;
if (x1 >= x2 || y1 >= y2) {
diff --git a/src/cairo-xcb-surface.c b/src/cairo-xcb-surface.c
index 1760bcbc..dede00f3 100644
--- a/src/cairo-xcb-surface.c
+++ b/src/cairo-xcb-surface.c
@@ -302,45 +302,25 @@ _get_image_surface (cairo_xcb_surface_t *surface,
cairo_image_surface_t *image;
xcb_get_image_reply_t *imagerep;
int bpp, bytes_per_line;
- short x1, y1, x2, y2;
+ cairo_rectangle_int_t extents;
unsigned char *data;
cairo_format_masks_t masks;
cairo_format_t format;
- x1 = 0;
- y1 = 0;
- x2 = surface->width;
- y2 = surface->height;
+ extents.x = 0;
+ extents.y = 0;
+ extents.width = surface->width;
+ extents.height = surface->height;
if (interest_rect) {
- cairo_rectangle_int_t rect;
-
- rect.x = interest_rect->x;
- rect.y = interest_rect->y;
- rect.width = interest_rect->width;
- rect.height = interest_rect->height;
-
- if (rect.x > x1)
- x1 = rect.x;
- if (rect.y > y1)
- y1 = rect.y;
- if (rect.x + rect.width < x2)
- x2 = rect.x + rect.width;
- if (rect.y + rect.height < y2)
- y2 = rect.y + rect.height;
-
- if (x1 >= x2 || y1 >= y2) {
+ if (! _cairo_rectangle_intersect (&extents, interest_rect)) {
*image_out = NULL;
return CAIRO_STATUS_SUCCESS;
}
}
- if (image_rect) {
- image_rect->x = x1;
- image_rect->y = y1;
- image_rect->width = x2 - x1;
- image_rect->height = y2 - y1;
- }
+ if (image_rect)
+ *image_rect = extents;
/* XXX: This should try to use the XShm extension if available */
@@ -350,8 +330,8 @@ _get_image_surface (cairo_xcb_surface_t *surface,
imagerep = xcb_get_image_reply(surface->dpy,
xcb_get_image(surface->dpy, XCB_IMAGE_FORMAT_Z_PIXMAP,
surface->drawable,
- x1, y1,
- x2 - x1, y2 - y1,
+ extents.x, extents.y,
+ extents.width, extents.height,
AllPlanes), &error);
/* If we get an error, the surface must have been a window,
@@ -380,17 +360,17 @@ _get_image_surface (cairo_xcb_surface_t *surface,
surface->depth,
pixmap,
surface->drawable,
- x2 - x1, y2 - y1);
+ extents.width, extents.height);
_cairo_xcb_surface_ensure_gc (surface);
xcb_copy_area (surface->dpy, surface->drawable, pixmap, surface->gc,
- x1, y1, 0, 0, x2 - x1, y2 - y1);
+ extents.x, extents.y, 0, 0, extents.width, extents.height);
imagerep = xcb_get_image_reply(surface->dpy,
xcb_get_image(surface->dpy, XCB_IMAGE_FORMAT_Z_PIXMAP,
pixmap,
- x1, y1,
- x2 - x1, y2 - y1,
+ extents.x, extents.y,
+ extents.width, extents.height,
AllPlanes), 0);
xcb_free_pixmap (surface->dpy, pixmap);
@@ -447,8 +427,8 @@ _get_image_surface (cairo_xcb_surface_t *surface,
image = (cairo_image_surface_t *)
cairo_image_surface_create_for_data (data,
format,
- x2 - x1,
- y2 - y1,
+ extents.width,
+ extents.height,
bytes_per_line);
if (image->base.status)
goto FAIL;
@@ -462,8 +442,8 @@ _get_image_surface (cairo_xcb_surface_t *surface,
image = (cairo_image_surface_t *)
_cairo_image_surface_create_with_masks (data,
&masks,
- x2 - x1,
- y2 - y1,
+ extents.width,
+ extents.height,
bytes_per_line);
if (image->base.status)
goto FAIL;
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index 619eb36d..ba38f5d8 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -612,44 +612,24 @@ _get_image_surface (cairo_xlib_surface_t *surface,
cairo_int_status_t status;
cairo_image_surface_t *image = NULL;
XImage *ximage;
- unsigned short x1, y1, x2, y2;
+ cairo_rectangle_int_t extents;
pixman_format_code_t pixman_format;
cairo_format_masks_t xlib_masks;
- x1 = 0;
- y1 = 0;
- x2 = surface->width;
- y2 = surface->height;
+ extents.x = 0;
+ extents.y = 0;
+ extents.width = surface->width;
+ extents.height = surface->height;
if (interest_rect) {
- cairo_rectangle_int_t rect;
-
- rect.x = interest_rect->x;
- rect.y = interest_rect->y;
- rect.width = interest_rect->width;
- rect.height = interest_rect->height;
-
- if (rect.x > x1)
- x1 = rect.x;
- if (rect.y > y1)
- y1 = rect.y;
- if (rect.x + rect.width < x2)
- x2 = rect.x + rect.width;
- if (rect.y + rect.height < y2)
- y2 = rect.y + rect.height;
-
- if (x1 >= x2 || y1 >= y2) {
+ if (! _cairo_rectangle_intersect (&extents, interest_rect)) {
*image_out = NULL;
return CAIRO_STATUS_SUCCESS;
}
}
- if (image_rect) {
- image_rect->x = x1;
- image_rect->y = y1;
- image_rect->width = x2 - x1;
- image_rect->height = y2 - y1;
- }
+ if (image_rect)
+ *image_rect = extents;
/* XXX: This should try to use the XShm extension if available */
@@ -661,8 +641,8 @@ _get_image_surface (cairo_xlib_surface_t *surface,
ximage = XGetImage (surface->dpy,
surface->drawable,
- x1, y1,
- x2 - x1, y2 - y1,
+ extents.x, extents.y,
+ extents.width, extents.height,
AllPlanes, ZPixmap);
XSetErrorHandler (old_handler);
@@ -695,16 +675,18 @@ _get_image_surface (cairo_xlib_surface_t *surface,
pixmap = XCreatePixmap (surface->dpy,
surface->drawable,
- x2 - x1, y2 - y1,
+ extents.width, extents.height,
surface->depth);
if (pixmap) {
XCopyArea (surface->dpy, surface->drawable, pixmap, surface->gc,
- x1, y1, x2 - x1, y2 - y1, 0, 0);
+ extents.x, extents.y,
+ extents.width, extents.height,
+ 0, 0);
ximage = XGetImage (surface->dpy,
pixmap,
0, 0,
- x2 - x1, y2 - y1,
+ extents.width, extents.height,
AllPlanes, ZPixmap);
XFreePixmap (surface->dpy, pixmap);
@@ -807,8 +789,8 @@ _get_image_surface (cairo_xlib_surface_t *surface,
data = cairo_image_surface_get_data (&image->base);
rowstride = cairo_image_surface_get_stride (&image->base) >> 2;
row = (uint32_t *) data;
- x0 = x1 + surface->base.device_transform.x0;
- y0 = y1 + surface->base.device_transform.y0;
+ x0 = extents.x + surface->base.device_transform.x0;
+ y0 = extents.y + surface->base.device_transform.y0;
for (y = 0, y_off = y0 % ARRAY_LENGTH (dither_pattern);
y < ximage->height;
y++, y_off = (y_off+1) % ARRAY_LENGTH (dither_pattern)) {
diff --git a/src/cairoint.h b/src/cairoint.h
index a00e6e12..43c5ae88 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -253,8 +253,9 @@ cairo_private void
_cairo_box_round_to_rectangle (const cairo_box_t *box,
cairo_rectangle_int_t *rectangle);
-cairo_private void
-_cairo_rectangle_intersect (cairo_rectangle_int_t *dest, cairo_rectangle_int_t *src);
+cairo_private cairo_bool_t
+_cairo_rectangle_intersect (cairo_rectangle_int_t *dst,
+ const cairo_rectangle_int_t *src);
cairo_private cairo_bool_t
_cairo_box_intersects_line_segment (cairo_box_t *box, cairo_line_t *line);
diff --git a/test/Makefile.am b/test/Makefile.am
index eaeff9af..887bd73a 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -938,7 +938,11 @@ REFERENCE_IMAGES = \
user-font-ps3-ref.png \
user-font-svg12-ref.png \
user-font-svg11-ref.png \
- user-font-mask-ref.png \
+ user-font-mask-ref.png \
+ user-font-mask-pdf-ref.png \
+ user-font-mask-ps2-ref.png \
+ user-font-mask-ps3-ref.png \
+ user-font-mask-svg11-ref.png \
user-font-proxy-ref.png \
user-font-proxy-pdf-ref.png \
user-font-proxy-ps2-ref.png \
@@ -1017,13 +1021,6 @@ $(REFERENCE_IMAGES)
# /Interpolate support - which causes a half-pixel
# shift in GS (and consequently virtually every
# image/fallback-image using test to FAIL).
-# user-font-mask - Two bugs here: an unsigned promotion issue and
-# non-negative pattern extents. Chris claims
-# to have fixes in hand for both, but doesn't
-# feel comfortable pushing them just before
-# the 1.8.2 release. So if 1.9.x is open and
-# this comment is still here, please pester
-# Chris.
XFAIL_TESTS = \
alpha-similar$(EXEEXT) \
big-line$(EXEEXT) \
@@ -1040,7 +1037,7 @@ surface-pattern$(EXEEXT) \
surface-pattern-big-scale-down$(EXEEXT) \
surface-pattern-scale-down$(EXEEXT) \
surface-pattern-scale-up$(EXEEXT) \
-user-font-mask$(EXEEXT)
+$(NULL)
# Any test that doesn't generate a log file goes here
NOLOG_TESTS = \
diff --git a/test/clip-operator-pdf-argb32-ref.png b/test/clip-operator-pdf-argb32-ref.png
index b00cc00f..b3ee1437 100644
--- a/test/clip-operator-pdf-argb32-ref.png
+++ b/test/clip-operator-pdf-argb32-ref.png
Binary files differ
diff --git a/test/clip-operator-pdf-rgb24-ref.png b/test/clip-operator-pdf-rgb24-ref.png
index f9377fa0..b420f385 100644
--- a/test/clip-operator-pdf-rgb24-ref.png
+++ b/test/clip-operator-pdf-rgb24-ref.png
Binary files differ
diff --git a/test/operator-clear-pdf-argb32-ref.png b/test/operator-clear-pdf-argb32-ref.png
index d36de27f..06fc51e3 100644
--- a/test/operator-clear-pdf-argb32-ref.png
+++ b/test/operator-clear-pdf-argb32-ref.png
Binary files differ
diff --git a/test/operator-clear-pdf-rgb24-ref.png b/test/operator-clear-pdf-rgb24-ref.png
index 2dec75c8..55b44ad6 100644
--- a/test/operator-clear-pdf-rgb24-ref.png
+++ b/test/operator-clear-pdf-rgb24-ref.png
Binary files differ
diff --git a/test/operator-source-pdf-argb32-ref.png b/test/operator-source-pdf-argb32-ref.png
index 821112a6..f110ff2a 100644
--- a/test/operator-source-pdf-argb32-ref.png
+++ b/test/operator-source-pdf-argb32-ref.png
Binary files differ
diff --git a/test/operator-source-pdf-rgb24-ref.png b/test/operator-source-pdf-rgb24-ref.png
index 6faf143c..c6b71705 100644
--- a/test/operator-source-pdf-rgb24-ref.png
+++ b/test/operator-source-pdf-rgb24-ref.png
Binary files differ
diff --git a/test/user-font-mask-pdf-ref.png b/test/user-font-mask-pdf-ref.png
new file mode 100644
index 00000000..ebf14858
--- /dev/null
+++ b/test/user-font-mask-pdf-ref.png
Binary files differ
diff --git a/test/user-font-mask-ps2-ref.png b/test/user-font-mask-ps2-ref.png
new file mode 100644
index 00000000..ebf14858
--- /dev/null
+++ b/test/user-font-mask-ps2-ref.png
Binary files differ
diff --git a/test/user-font-mask-ps3-ref.png b/test/user-font-mask-ps3-ref.png
new file mode 100644
index 00000000..ebf14858
--- /dev/null
+++ b/test/user-font-mask-ps3-ref.png
Binary files differ
diff --git a/test/user-font-mask-svg11-ref.png b/test/user-font-mask-svg11-ref.png
new file mode 100644
index 00000000..55006bf7
--- /dev/null
+++ b/test/user-font-mask-svg11-ref.png
Binary files differ