From 4b2998893930e4bab19646e6f0a0c8d2a47f12a2 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 23 Oct 2008 14:34:30 +0100 Subject: [PATCH] Review users of cairo_rectangle_int_t for incorrect unsigned promotion. Adrian Johnson discovered cases where we mistakenly compared the result of unsigned arithmetic where we need signed quantities. Look for similar cases in the users of cairo_rectangle_int_t. --- src/cairo-analysis-surface.c | 48 +++++++++++++++++++------------ src/cairo-clip.c | 43 +++++++++++++-------------- src/cairo-gstate.c | 4 +-- src/cairo-pattern.c | 13 +++++---- src/cairo-rectangle.c | 6 +++- src/cairo-region-private.h | 3 +- src/cairo-region.c | 3 +- src/cairo-surface-fallback.c | 31 +++++++++++++------- src/cairo-surface.c | 27 +++++++++-------- src/cairo-win32-surface.c | 4 +-- src/cairo-xcb-surface.c | 56 ++++++++++++------------------------ src/cairo-xlib-surface.c | 52 +++++++++++---------------------- src/cairoint.h | 2 +- 13 files changed, 144 insertions(+), 148 deletions(-) diff --git a/src/cairo-analysis-surface.c b/src/cairo-analysis-surface.c index 5093459b0..90eb3f561 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,16 @@ _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 (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); @@ -441,7 +445,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 +465,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 +515,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 +534,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 +583,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 +612,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 +630,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 +662,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 +695,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 +713,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 308da326c..8a0d4db15 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 e1b4693c2..fe8d2792f 100644 --- a/src/cairo-gstate.c +++ b/src/cairo-gstate.c @@ -1785,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 83d371ca6..81fa62ad5 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); diff --git a/src/cairo-rectangle.c b/src/cairo-rectangle.c index ec08db42e..2143f0c64 100644 --- a/src/cairo-rectangle.c +++ b/src/cairo-rectangle.c @@ -95,7 +95,7 @@ _cairo_box_round_to_rectangle (const cairo_box_t *box, rectangle->height = _cairo_fixed_integer_ceil (box->p2.y) - rectangle->y; } -void +cairo_bool_t _cairo_rectangle_intersect (cairo_rectangle_int_t *dst, const cairo_rectangle_int_t *src) { @@ -114,11 +114,15 @@ _cairo_rectangle_intersect (cairo_rectangle_int_t *dst, dst->y = 0; dst->width = 0; dst->height = 0; + + return FALSE; } else { dst->x = x1; dst->y = y1; dst->width = x2 - x1; dst->height = y2 - y1; + + return TRUE; } } diff --git a/src/cairo-region-private.h b/src/cairo-region-private.h index 352a23f99..588762e51 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 746b3b192..23a042fd7 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 c44dfafae..5b9c99a64 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 d1df1869d..609a0e05a 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 a473c3815..5787e2619 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 1760bcbcf..dede00f3b 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 619eb36d7..ba38f5d8b 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 5172b9e23..43c5ae888 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -253,7 +253,7 @@ cairo_private void _cairo_box_round_to_rectangle (const cairo_box_t *box, cairo_rectangle_int_t *rectangle); -cairo_private void +cairo_private cairo_bool_t _cairo_rectangle_intersect (cairo_rectangle_int_t *dst, const cairo_rectangle_int_t *src);