[cairo] [PATCH] fix _cairo_rectangle_intersect

David Reveman davidr at novell.com
Wed Feb 23 10:11:42 PST 2005


On Wed, 2005-02-23 at 14:46 -0500, Jeff Muizelaar wrote:
> _cairo_rectangle_intersect gives bad results whenever
> MIN (dest->x + dest->width, src->x + src->width) - out.x
> is negative because of assignment to an unsigned short.
> 
> The appended patch fixes the problem by using variables of type int for
> the computation results.
> 
> There are still problems when x + width is > 655536, but at
> least that is a lot more rare. Are there any reasons width and height
> are unsigned to begin with?
> 
> 
> 2005-02-23  Jeff Muizelaar <jrmuizel at nit.ca>
> 
> 	* src/cairo_gstate.c (_cairo_rectangle_intersect)
> 	make the computation correct when the intersection
> 	negative width
> 
> Index: src/cairo_gstate.c
> ===================================================================
> RCS file: /cvs/cairo/cairo/src/cairo_gstate.c,v
> retrieving revision 1.84
> diff -u -r1.84 cairo_gstate.c
> --- src/cairo_gstate.c	22 Feb 2005 19:35:03 -0000	1.84
> +++ src/cairo_gstate.c	23 Feb 2005 19:13:02 -0000
> @@ -1414,18 +1414,21 @@
>  _cairo_rectangle_intersect (cairo_rectangle_t *dest, cairo_rectangle_t *src)
>  {
>      cairo_rectangle_t out;
> +    int width, height;
>  
>      out.x = MAX (dest->x, src->x);
>      out.y = MAX (dest->y, src->y);
> -    out.width = MIN (dest->x + dest->width, src->x + src->width) - out.x;
> -    out.height = MIN (dest->y + dest->height, src->y + src->height) - out.y;
> +    width = MIN (dest->x + dest->width, src->x + src->width) - out.x;
> +    height = MIN (dest->y + dest->height, src->y + src->height) - out.y;
>  
> -    if (out.width <= 0 || out.height <= 0) {
> +    if (width <= 0 || height <= 0) {
>  	dest->x = 0;
>  	dest->y = 0;
>  	dest->width = 0;
>  	dest->height = 0;
>      } else {
> +	dest->width = width;
> +	dest->height = height;
>  	*dest = out;
>      }	
>  }

I prefer the following intersection code:

static void
_cairo_rectangle_intersect (cairo_rectangle_t *dest, cairo_rectangle_t
*src)
{
    int x1, y1, x2, y2;

    x1 = dest->x;
    y1 = dest->y;
    x2 = x1 + dest->width;
    y2 = y1 + dest->height;
    if (src->x > x1)
        x1 = src->x;
    if (src->y > y1)
        y1 = src->y;
    if (src->x + src->width < x2)
        x2 = src->x + src->width;
    if (src->y + src->height < y2)
        y2 = src->y + src->height;

    if (x2 > x1 && y2 > y1) 
    {
	dest->x = x1;
        dest->y = y1;
	dest->width = x2 - x1
        dest->height = y2 - y1;
    }
    else 
    {
        dest->x = dest->y = 0;
	dest->width = dest->height = 0;
    }
} 

-David




More information about the cairo mailing list