diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2008-10-30 16:56:07 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2008-10-30 16:56:07 +0000 |
commit | 31ada1ea15d14c0a843728b105340c270e4e4613 (patch) | |
tree | 675c66cce8676320b55a95d1261edcaa5cd62852 | |
parent | 30f2df1dec419a10408b53ecd26cebfcf607bf27 (diff) | |
parent | ab15d7627506a837fea7101661425bb923ef5b4f (diff) |
Merge branch '1.8'
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 Binary files differindex b00cc00f..b3ee1437 100644 --- a/test/clip-operator-pdf-argb32-ref.png +++ b/test/clip-operator-pdf-argb32-ref.png diff --git a/test/clip-operator-pdf-rgb24-ref.png b/test/clip-operator-pdf-rgb24-ref.png Binary files differindex f9377fa0..b420f385 100644 --- a/test/clip-operator-pdf-rgb24-ref.png +++ b/test/clip-operator-pdf-rgb24-ref.png diff --git a/test/operator-clear-pdf-argb32-ref.png b/test/operator-clear-pdf-argb32-ref.png Binary files differindex d36de27f..06fc51e3 100644 --- a/test/operator-clear-pdf-argb32-ref.png +++ b/test/operator-clear-pdf-argb32-ref.png diff --git a/test/operator-clear-pdf-rgb24-ref.png b/test/operator-clear-pdf-rgb24-ref.png Binary files differindex 2dec75c8..55b44ad6 100644 --- a/test/operator-clear-pdf-rgb24-ref.png +++ b/test/operator-clear-pdf-rgb24-ref.png diff --git a/test/operator-source-pdf-argb32-ref.png b/test/operator-source-pdf-argb32-ref.png Binary files differindex 821112a6..f110ff2a 100644 --- a/test/operator-source-pdf-argb32-ref.png +++ b/test/operator-source-pdf-argb32-ref.png diff --git a/test/operator-source-pdf-rgb24-ref.png b/test/operator-source-pdf-rgb24-ref.png Binary files differindex 6faf143c..c6b71705 100644 --- a/test/operator-source-pdf-rgb24-ref.png +++ b/test/operator-source-pdf-rgb24-ref.png diff --git a/test/user-font-mask-pdf-ref.png b/test/user-font-mask-pdf-ref.png Binary files differnew file mode 100644 index 00000000..ebf14858 --- /dev/null +++ b/test/user-font-mask-pdf-ref.png diff --git a/test/user-font-mask-ps2-ref.png b/test/user-font-mask-ps2-ref.png Binary files differnew file mode 100644 index 00000000..ebf14858 --- /dev/null +++ b/test/user-font-mask-ps2-ref.png diff --git a/test/user-font-mask-ps3-ref.png b/test/user-font-mask-ps3-ref.png Binary files differnew file mode 100644 index 00000000..ebf14858 --- /dev/null +++ b/test/user-font-mask-ps3-ref.png diff --git a/test/user-font-mask-svg11-ref.png b/test/user-font-mask-svg11-ref.png Binary files differnew file mode 100644 index 00000000..55006bf7 --- /dev/null +++ b/test/user-font-mask-svg11-ref.png |