/*
 * GDI region objects. Shamelessly ripped out from the X11 distribution
 * Thanks for the nice license.
 *
 * Copyright 1993, 1994, 1995 Alexandre Julliard
 * Modifications and additions: Copyright 1998 Huw Davies
 *					  1999 Alex Korobka
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

/************************************************************************

Copyright (c) 1987, 1988  X Consortium

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Except as contained in this notice, the name of the X Consortium shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from the X Consortium.


Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts.

			All Rights Reserved

Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation, and that the name of Digital not be
used in advertising or publicity pertaining to distribution of the
software without specific, written prior permission.

DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
SOFTWARE.

************************************************************************/
/*
 * The functions in this file implement the Region abstraction, similar to one
 * used in the X11 sample server. A Region is simply an area, as the name
 * implies, and is implemented as a "y-x-banded" array of rectangles. To
 * explain: Each Region is made up of a certain number of rectangles sorted
 * by y coordinate first, and then by x coordinate.
 *
 * Furthermore, the rectangles are banded such that every rectangle with a
 * given upper-left y coordinate (y1) will have the same lower-right y
 * coordinate (y2) and vice versa. If a rectangle has scanlines in a band, it
 * will span the entire vertical distance of the band. This means that some
 * areas that could be merged into a taller rectangle will be represented as
 * several shorter rectangles to account for shorter rectangles to its left
 * or right but within its "vertical scope".
 *
 * An added constraint on the rectangles is that they must cover as much
 * horizontal area as possible. E.g. no two rectangles in a band are allowed
 * to touch.
 *
 * Whenever possible, bands will be merged together to cover a greater vertical
 * distance (and thus reduce the number of rectangles). Two bands can be merged
 * only if the bottom of one touches the top of the other and they have
 * rectangles in the same places (of the same width, of course). This maintains
 * the y-x-banding that's so nice to have...
 */

#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "gdi_private.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(region);


static HGDIOBJ REGION_SelectObject( HGDIOBJ handle, HDC hdc );
static BOOL REGION_DeleteObject( HGDIOBJ handle );

static const struct gdi_obj_funcs region_funcs =
{
    REGION_SelectObject,  /* pSelectObject */
    NULL,                 /* pGetObjectA */
    NULL,                 /* pGetObjectW */
    NULL,                 /* pUnrealizeObject */
    REGION_DeleteObject   /* pDeleteObject */
};

/* Check if two RECTs overlap. */
static inline BOOL overlapping( const RECT *r1, const RECT *r2 )
{
    return (r1->right > r2->left && r1->left < r2->right &&
            r1->bottom > r2->top && r1->top < r2->bottom);
}

static BOOL grow_region( WINEREGION *rgn, int size )
{
    RECT *new_rects;

    if (size <= rgn->size) return TRUE;

    if (rgn->rects == rgn->rects_buf)
    {
        new_rects = HeapAlloc( GetProcessHeap(), 0, size * sizeof(RECT) );
        if (!new_rects) return FALSE;
        memcpy( new_rects, rgn->rects, rgn->numRects * sizeof(RECT) );
    }
    else
    {
        new_rects = HeapReAlloc( GetProcessHeap(), 0, rgn->rects, size * sizeof(RECT) );
        if (!new_rects) return FALSE;
    }
    rgn->rects = new_rects;
    rgn->size = size;
    return TRUE;
}

static BOOL add_rect( WINEREGION *reg, INT left, INT top, INT right, INT bottom )
{
    RECT *rect;
    if (reg->numRects >= reg->size && !grow_region( reg, 2 * reg->size ))
        return FALSE;

    rect = reg->rects + reg->numRects++;
    rect->left = left;
    rect->top = top;
    rect->right = right;
    rect->bottom = bottom;
    return TRUE;
}

static inline void empty_region( WINEREGION *reg )
{
    reg->numRects = 0;
    reg->extents.left = reg->extents.top = reg->extents.right = reg->extents.bottom = 0;
}

static inline BOOL is_in_rect( const RECT *rect, int x, int y )
{
    return (rect->right > x && rect->left <= x && rect->bottom > y && rect->top <= y);
}

/*
 * used to allocate buffers for points and link
 * the buffers together
 */

struct point_block
{
    int count, size;
    struct point_block *next;
    POINT pts[1]; /* Variable sized array - must be last. */
};

static struct point_block *add_point( struct point_block *block, int x, int y )
{
    if (block->count == block->size)
    {
        struct point_block *new;
        int size = block->size * 2;
        new = HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET( struct point_block, pts[size] ) );
        if (!new) return NULL;
        block->next = new;
        new->count = 0;
        new->size = size;
        new->next = NULL;
        block = new;
    }
    block->pts[block->count].x = x;
    block->pts[block->count].y = y;
    block->count++;
    return block;
}

static void free_point_blocks( struct point_block *block )
{
    while (block)
    {
	struct point_block *tmp = block->next;
	HeapFree( GetProcessHeap(), 0, block );
	block = tmp;
    }
}


/*
 *     This file contains a few macros to help track
 *     the edge of a filled object.  The object is assumed
 *     to be filled in scanline order, and thus the
 *     algorithm used is an extension of Bresenham's line
 *     drawing algorithm which assumes that y is always the
 *     major axis.
 *     Since these pieces of code are the same for any filled shape,
 *     it is more convenient to gather the library in one
 *     place, but since these pieces of code are also in
 *     the inner loops of output primitives, procedure call
 *     overhead is out of the question.
 *     See the author for a derivation if needed.
 */


/*
 *     This structure contains all of the information needed
 *     to run the bresenham algorithm.
 *     The variables may be hardcoded into the declarations
 *     instead of using this structure to make use of
 *     register declarations.
 */
struct bres_info
{
    INT minor_axis;	/* minor axis        */
    INT d;		/* decision variable */
    INT m, m1;       	/* slope and slope+1 */
    INT incr1, incr2;	/* error increments */
};


/*
 *  In scan converting polygons, we want to choose those pixels
 *  which are inside the polygon.  Thus, we add .5 to the starting
 *  x coordinate for both left and right edges.  Now we choose the
 *  first pixel which is inside the pgon for the left edge and the
 *  first pixel which is outside the pgon for the right edge.
 *  Draw the left pixel, but not the right.
 *
 *  How to add .5 to the starting x coordinate:
 *      If the edge is moving to the right, then subtract dy from the
 *  error term from the general form of the algorithm.
 *      If the edge is moving to the left, then add dy to the error term.
 *
 *  The reason for the difference between edges moving to the left
 *  and edges moving to the right is simple:  If an edge is moving
 *  to the right, then we want the algorithm to flip immediately.
 *  If it is moving to the left, then we don't want it to flip until
 *  we traverse an entire pixel.
 */
static inline void bres_init_polygon( int dy, int x1, int x2, struct bres_info *bres )
{
    int dx;

    /*
     *  if the edge is horizontal, then it is ignored
     *  and assumed not to be processed.  Otherwise, do this stuff.
     */
    if (!dy) return;

    bres->minor_axis = x1;
    dx = x2 - x1;
    if (dx < 0)
    {
        bres->m = dx / dy;
        bres->m1 = bres->m - 1;
        bres->incr1 = -2 * dx + 2 * dy * bres->m1;
        bres->incr2 = -2 * dx + 2 * dy * bres->m;
        bres->d = 2 * bres->m * dy - 2 * dx - 2 * dy;
    }
    else
    {
        bres->m = dx / (dy);
        bres->m1 = bres->m + 1;
        bres->incr1 = 2 * dx - 2 * dy * bres->m1;
        bres->incr2 = 2 * dx - 2 * dy * bres->m;
        bres->d = -2 * bres->m * dy + 2 * dx;
    }
}

static inline void bres_incr_polygon( struct bres_info *bres )
{
    if (bres->m1 > 0) {
        if (bres->d > 0) {
            bres->minor_axis += bres->m1;
            bres->d += bres->incr1;
        }
        else {
            bres->minor_axis += bres->m;
            bres->d += bres->incr2;
        }
    } else {
        if (bres->d >= 0) {
            bres->minor_axis += bres->m1;
            bres->d += bres->incr1;
        }
        else {
            bres->minor_axis += bres->m;
            bres->d += bres->incr2;
        }
    }
}


/*
 *     These are the data structures needed to scan
 *     convert regions.  Two different scan conversion
 *     methods are available -- the even-odd method, and
 *     the winding number method.
 *     The even-odd rule states that a point is inside
 *     the polygon if a ray drawn from that point in any
 *     direction will pass through an odd number of
 *     path segments.
 *     By the winding number rule, a point is decided
 *     to be inside the polygon if a ray drawn from that
 *     point in any direction passes through a different
 *     number of clockwise and counter-clockwise path
 *     segments.
 *
 *     These data structures are adapted somewhat from
 *     the algorithm in (Foley/Van Dam) for scan converting
 *     polygons.
 *     The basic algorithm is to start at the top (smallest y)
 *     of the polygon, stepping down to the bottom of
 *     the polygon by incrementing the y coordinate.  We
 *     keep a list of edges which the current scanline crosses,
 *     sorted by x.  This list is called the Active Edge Table (AET)
 *     As we change the y-coordinate, we update each entry in
 *     in the active edge table to reflect the edges new xcoord.
 *     This list must be sorted at each scanline in case
 *     two edges intersect.
 *     We also keep a data structure known as the Edge Table (ET),
 *     which keeps track of all the edges which the current
 *     scanline has not yet reached.  The ET is basically a
 *     list of ScanLineList structures containing a list of
 *     edges which are entered at a given scanline.  There is one
 *     ScanLineList per scanline at which an edge is entered.
 *     When we enter a new edge, we move it from the ET to the AET.
 *
 *     From the AET, we can implement the even-odd rule as in
 *     (Foley/Van Dam).
 *     The winding number rule is a little trickier.  We also
 *     keep the EdgeTableEntries in the AET linked by the
 *     nextWETE (winding EdgeTableEntry) link.  This allows
 *     the edges to be linked just as before for updating
 *     purposes, but only uses the edges linked by the nextWETE
 *     link as edges representing spans of the polygon to
 *     drawn (as with the even-odd rule).
 */

typedef struct edge_table_entry {
    struct list entry;
    struct list winding_entry;
    INT ymax;                     /* ycoord at which we exit this edge. */
    struct bres_info bres;        /* Bresenham info to run the edge     */
    int ClockWise;                /* flag for winding number rule       */
} EdgeTableEntry;


typedef struct _ScanLineList{
    struct list edgelist;
    INT scanline;            /* the scanline represented */
    struct _ScanLineList *next;  /* next in the list       */
} ScanLineList;


typedef struct {
     INT ymax;               /* ymax for the polygon     */
     INT ymin;               /* ymin for the polygon     */
     ScanLineList scanlines;   /* header node              */
} EdgeTable;


/*
 * Here is a struct to help with storage allocation
 * so we can allocate a big chunk at a time, and then take
 * pieces from this heap when we need to.
 */
#define SLLSPERBLOCK 25

typedef struct _ScanLineListBlock {
     ScanLineList SLLs[SLLSPERBLOCK];
     struct _ScanLineListBlock *next;
} ScanLineListBlock;


/* Note the parameter order is different from the X11 equivalents */

static BOOL REGION_CopyRegion(WINEREGION *d, WINEREGION *s);
static BOOL REGION_OffsetRegion(WINEREGION *d, WINEREGION *s, INT x, INT y);
static BOOL REGION_IntersectRegion(WINEREGION *d, WINEREGION *s1, WINEREGION *s2);
static BOOL REGION_UnionRegion(WINEREGION *d, WINEREGION *s1, WINEREGION *s2);
static BOOL REGION_SubtractRegion(WINEREGION *d, WINEREGION *s1, WINEREGION *s2);
static BOOL REGION_XorRegion(WINEREGION *d, WINEREGION *s1, WINEREGION *s2);
static BOOL REGION_UnionRectWithRegion(const RECT *rect, WINEREGION *rgn);

/***********************************************************************
 *            get_region_type
 */
static inline INT get_region_type( const WINEREGION *obj )
{
    switch(obj->numRects)
    {
    case 0:  return NULLREGION;
    case 1:  return SIMPLEREGION;
    default: return COMPLEXREGION;
    }
}


/***********************************************************************
 *            REGION_DumpRegion
 *            Outputs the contents of a WINEREGION
 */
static void REGION_DumpRegion(WINEREGION *pReg)
{
    RECT *pRect, *pRectEnd = pReg->rects + pReg->numRects;

    TRACE("Region %p: %s %d rects\n", pReg, wine_dbgstr_rect(&pReg->extents), pReg->numRects);
    for(pRect = pReg->rects; pRect < pRectEnd; pRect++)
        TRACE("\t%s\n", wine_dbgstr_rect(pRect));
    return;
}


/***********************************************************************
 *            init_region
 *
 * Initialize a new empty region.
 */
static BOOL init_region( WINEREGION *pReg, INT n )
{
    n = max( n, RGN_DEFAULT_RECTS );

    if (n > RGN_DEFAULT_RECTS)
    {
        if (!(pReg->rects = HeapAlloc( GetProcessHeap(), 0, n * sizeof( RECT ) )))
            return FALSE;
    }
    else
        pReg->rects = pReg->rects_buf;

    pReg->size = n;
    empty_region(pReg);
    return TRUE;
}

/***********************************************************************
 *           destroy_region
 */
static void destroy_region( WINEREGION *pReg )
{
    if (pReg->rects != pReg->rects_buf)
        HeapFree( GetProcessHeap(), 0, pReg->rects );
}

/***********************************************************************
 *           free_region
 */
static void free_region( WINEREGION *rgn )
{
    destroy_region( rgn );
    HeapFree( GetProcessHeap(), 0, rgn );
}

/***********************************************************************
 *           alloc_region
 */
static WINEREGION *alloc_region( INT n )
{
    WINEREGION *rgn = HeapAlloc( GetProcessHeap(), 0, sizeof(*rgn) );

    if (rgn && !init_region( rgn, n ))
    {
        free_region( rgn );
        rgn = NULL;
    }
    return rgn;
}

/************************************************************
 *              move_rects
 *
 * Move rectangles from src to dst leaving src with no rectangles.
 */
static inline void move_rects( WINEREGION *dst, WINEREGION *src )
{
    destroy_region( dst );
    if (src->rects == src->rects_buf)
    {
        dst->rects = dst->rects_buf;
        memcpy( dst->rects, src->rects, src->numRects * sizeof(RECT) );
    }
    else
        dst->rects = src->rects;
    dst->size = src->size;
    dst->numRects = src->numRects;
    init_region( src, 0 );
}

/***********************************************************************
 *           REGION_DeleteObject
 */
static BOOL REGION_DeleteObject( HGDIOBJ handle )
{
    WINEREGION *rgn = free_gdi_handle( handle );

    if (!rgn) return FALSE;
    free_region( rgn );
    return TRUE;
}

/***********************************************************************
 *           REGION_SelectObject
 */
static HGDIOBJ REGION_SelectObject( HGDIOBJ handle, HDC hdc )
{
    return ULongToHandle(SelectClipRgn( hdc, handle ));
}


/***********************************************************************
 *           REGION_OffsetRegion
 *           Offset a WINEREGION by x,y
 */
static BOOL REGION_OffsetRegion( WINEREGION *rgn, WINEREGION *srcrgn, INT x, INT y )
{
    if( rgn != srcrgn)
    {
        if (!REGION_CopyRegion( rgn, srcrgn)) return FALSE;
    }
    if(x || y) {
	int nbox = rgn->numRects;
	RECT *pbox = rgn->rects;

	if(nbox) {
	    while(nbox--) {
	        pbox->left += x;
		pbox->right += x;
		pbox->top += y;
		pbox->bottom += y;
		pbox++;
	    }
	    rgn->extents.left += x;
	    rgn->extents.right += x;
	    rgn->extents.top += y;
	    rgn->extents.bottom += y;
	}
    }
    return TRUE;
}

/***********************************************************************
 *           OffsetRgn   (GDI32.@)
 *
 * Moves a region by the specified X- and Y-axis offsets.
 *
 * PARAMS
 *   hrgn [I] Region to offset.
 *   x    [I] Offset right if positive or left if negative.
 *   y    [I] Offset down if positive or up if negative.
 *
 * RETURNS
 *   Success:
 *     NULLREGION - The new region is empty.
 *     SIMPLEREGION - The new region can be represented by one rectangle.
 *     COMPLEXREGION - The new region can only be represented by more than
 *                     one rectangle.
 *   Failure: ERROR
 */
INT WINAPI OffsetRgn( HRGN hrgn, INT x, INT y )
{
    WINEREGION *obj = GDI_GetObjPtr( hrgn, OBJ_REGION );
    INT ret;

    TRACE("%p %d,%d\n", hrgn, x, y);

    if (!obj)
        return ERROR;

    REGION_OffsetRegion( obj, obj, x, y);

    ret = get_region_type( obj );
    GDI_ReleaseObj( hrgn );
    return ret;
}


/***********************************************************************
 *           GetRgnBox    (GDI32.@)
 *
 * Retrieves the bounding rectangle of the region. The bounding rectangle
 * is the smallest rectangle that contains the entire region.
 *
 * PARAMS
 *   hrgn [I] Region to retrieve bounding rectangle from.
 *   rect [O] Rectangle that will receive the coordinates of the bounding
 *            rectangle.
 *
 * RETURNS
 *     NULLREGION - The new region is empty.
 *     SIMPLEREGION - The new region can be represented by one rectangle.
 *     COMPLEXREGION - The new region can only be represented by more than
 *                     one rectangle.
 */
INT WINAPI GetRgnBox( HRGN hrgn, LPRECT rect )
{
    WINEREGION *obj = GDI_GetObjPtr( hrgn, OBJ_REGION );
    if (obj)
    {
	INT ret;
	rect->left = obj->extents.left;
	rect->top = obj->extents.top;
	rect->right = obj->extents.right;
	rect->bottom = obj->extents.bottom;
        TRACE("%p %s\n", hrgn, wine_dbgstr_rect(rect));
	ret = get_region_type( obj );
	GDI_ReleaseObj(hrgn);
	return ret;
    }
    return ERROR;
}


/***********************************************************************
 *           CreateRectRgn   (GDI32.@)
 *
 * Creates a simple rectangular region.
 *
 * PARAMS
 *   left   [I] Left coordinate of rectangle.
 *   top    [I] Top coordinate of rectangle.
 *   right  [I] Right coordinate of rectangle.
 *   bottom [I] Bottom coordinate of rectangle.
 *
 * RETURNS
 *   Success: Handle to region.
 *   Failure: NULL.
 */
HRGN WINAPI CreateRectRgn(INT left, INT top, INT right, INT bottom)
{
    HRGN hrgn;
    WINEREGION *obj;

    if (!(obj = alloc_region( RGN_DEFAULT_RECTS ))) return 0;

    if (!(hrgn = alloc_gdi_handle( obj, OBJ_REGION, &region_funcs )))
    {
        free_region( obj );
        return 0;
    }
    TRACE( "%d,%d-%d,%d returning %p\n", left, top, right, bottom, hrgn );
    SetRectRgn(hrgn, left, top, right, bottom);
    return hrgn;
}


/***********************************************************************
 *           CreateRectRgnIndirect    (GDI32.@)
 *
 * Creates a simple rectangular region.
 *
 * PARAMS
 *   rect [I] Coordinates of rectangular region.
 *
 * RETURNS
 *   Success: Handle to region.
 *   Failure: NULL.
 */
HRGN WINAPI CreateRectRgnIndirect( const RECT* rect )
{
    return CreateRectRgn( rect->left, rect->top, rect->right, rect->bottom );
}


/***********************************************************************
 *           SetRectRgn    (GDI32.@)
 *
 * Sets a region to a simple rectangular region.
 *
 * PARAMS
 *   hrgn   [I] Region to convert.
 *   left   [I] Left coordinate of rectangle.
 *   top    [I] Top coordinate of rectangle.
 *   right  [I] Right coordinate of rectangle.
 *   bottom [I] Bottom coordinate of rectangle.
 *
 * RETURNS
 *   Success: Non-zero.
 *   Failure: Zero.
 *
 * NOTES
 *   Allows either or both left and top to be greater than right or bottom.
 */
BOOL WINAPI SetRectRgn( HRGN hrgn, INT left, INT top,
			  INT right, INT bottom )
{
    WINEREGION *obj;

    TRACE("%p %d,%d-%d,%d\n", hrgn, left, top, right, bottom );

    if (!(obj = GDI_GetObjPtr( hrgn, OBJ_REGION ))) return FALSE;

    if (left > right) { INT tmp = left; left = right; right = tmp; }
    if (top > bottom) { INT tmp = top; top = bottom; bottom = tmp; }

    if((left != right) && (top != bottom))
    {
        obj->rects->left = obj->extents.left = left;
        obj->rects->top = obj->extents.top = top;
        obj->rects->right = obj->extents.right = right;
        obj->rects->bottom = obj->extents.bottom = bottom;
        obj->numRects = 1;
    }
    else
	empty_region(obj);

    GDI_ReleaseObj( hrgn );
    return TRUE;
}


/***********************************************************************
 *           CreateRoundRectRgn    (GDI32.@)
 *
 * Creates a rectangular region with rounded corners.
 *
 * PARAMS
 *   left           [I] Left coordinate of rectangle.
 *   top            [I] Top coordinate of rectangle.
 *   right          [I] Right coordinate of rectangle.
 *   bottom         [I] Bottom coordinate of rectangle.
 *   ellipse_width  [I] Width of the ellipse at each corner.
 *   ellipse_height [I] Height of the ellipse at each corner.
 *
 * RETURNS
 *   Success: Handle to region.
 *   Failure: NULL.
 *
 * NOTES
 *   If ellipse_width or ellipse_height is less than 2 logical units then
 *   it is treated as though CreateRectRgn() was called instead.
 */
HRGN WINAPI CreateRoundRectRgn( INT left, INT top,
				    INT right, INT bottom,
				    INT ellipse_width, INT ellipse_height )
{
    WINEREGION *obj;
    HRGN hrgn = 0;
    int a, b, i, x, y;
    INT64 asq, bsq, dx, dy, err;
    RECT *rects;

      /* Make the dimensions sensible */

    if (left > right) { INT tmp = left; left = right; right = tmp; }
    if (top > bottom) { INT tmp = top; top = bottom; bottom = tmp; }
    /* the region is for the rectangle interior, but only at right and bottom for some reason */
    right--;
    bottom--;

    ellipse_width = min( right - left, abs( ellipse_width ));
    ellipse_height = min( bottom - top, abs( ellipse_height ));

      /* Check if we can do a normal rectangle instead */

    if ((ellipse_width < 2) || (ellipse_height < 2))
        return CreateRectRgn( left, top, right, bottom );

    if (!(obj = alloc_region( ellipse_height ))) return 0;
    obj->numRects = ellipse_height;
    obj->extents.left   = left;
    obj->extents.top    = top;
    obj->extents.right  = right;
    obj->extents.bottom = bottom;
    rects = obj->rects;

    /* based on an algorithm by Alois Zingl */

    a = ellipse_width - 1;
    b = ellipse_height - 1;
    asq = (INT64)8 * a * a;
    bsq = (INT64)8 * b * b;
    dx  = (INT64)4 * b * b * (1 - a);
    dy  = (INT64)4 * a * a * (1 + (b % 2));
    err = dx + dy + a * a * (b % 2);

    x = 0;
    y = ellipse_height / 2;

    rects[y].left = left;
    rects[y].right = right;

    while (x <= ellipse_width / 2)
    {
        INT64 e2 = 2 * err;
        if (e2 >= dx)
        {
            x++;
            err += dx += bsq;
        }
        if (e2 <= dy)
        {
            y++;
            err += dy += asq;
            rects[y].left = left + x;
            rects[y].right = right - x;
        }
    }
    for (i = 0; i < ellipse_height / 2; i++)
    {
        rects[i].left = rects[b - i].left;
        rects[i].right = rects[b - i].right;
        rects[i].top = top + i;
        rects[i].bottom = rects[i].top + 1;
    }
    for (; i < ellipse_height; i++)
    {
        rects[i].top = bottom - ellipse_height + i;
        rects[i].bottom = rects[i].top + 1;
    }
    rects[ellipse_height / 2].top = top + ellipse_height / 2;  /* extend to top of rectangle */

    hrgn = alloc_gdi_handle( obj, OBJ_REGION, &region_funcs );

    TRACE("(%d,%d-%d,%d %dx%d): ret=%p\n",
	  left, top, right, bottom, ellipse_width, ellipse_height, hrgn );
    if (!hrgn) free_region( obj );
    return hrgn;
}


/***********************************************************************
 *           CreateEllipticRgn    (GDI32.@)
 *
 * Creates an elliptical region.
 *
 * PARAMS
 *   left   [I] Left coordinate of bounding rectangle.
 *   top    [I] Top coordinate of bounding rectangle.
 *   right  [I] Right coordinate of bounding rectangle.
 *   bottom [I] Bottom coordinate of bounding rectangle.
 *
 * RETURNS
 *   Success: Handle to region.
 *   Failure: NULL.
 *
 * NOTES
 *   This is a special case of CreateRoundRectRgn() where the width of the
 *   ellipse at each corner is equal to the width the rectangle and
 *   the same for the height.
 */
HRGN WINAPI CreateEllipticRgn( INT left, INT top,
				   INT right, INT bottom )
{
    return CreateRoundRectRgn( left, top, right, bottom,
				 right-left, bottom-top );
}


/***********************************************************************
 *           CreateEllipticRgnIndirect    (GDI32.@)
 *
 * Creates an elliptical region.
 *
 * PARAMS
 *   rect [I] Pointer to bounding rectangle of the ellipse.
 *
 * RETURNS
 *   Success: Handle to region.
 *   Failure: NULL.
 *
 * NOTES
 *   This is a special case of CreateRoundRectRgn() where the width of the
 *   ellipse at each corner is equal to the width the rectangle and
 *   the same for the height.
 */
HRGN WINAPI CreateEllipticRgnIndirect( const RECT *rect )
{
    return CreateRoundRectRgn( rect->left, rect->top, rect->right,
				 rect->bottom, rect->right - rect->left,
				 rect->bottom - rect->top );
}

/***********************************************************************
 *           GetRegionData   (GDI32.@)
 *
 * Retrieves the data that specifies the region.
 *
 * PARAMS
 *   hrgn    [I] Region to retrieve the region data from.
 *   count   [I] The size of the buffer pointed to by rgndata in bytes.
 *   rgndata [I] The buffer to receive data about the region.
 *
 * RETURNS
 *   Success: If rgndata is NULL then the required number of bytes. Otherwise,
 *            the number of bytes copied to the output buffer.
 *   Failure: 0.
 *
 * NOTES
 *   The format of the Buffer member of RGNDATA is determined by the iType
 *   member of the region data header.
 *   Currently this is always RDH_RECTANGLES, which specifies that the format
 *   is the array of RECT's that specify the region. The length of the array
 *   is specified by the nCount member of the region data header.
 */
DWORD WINAPI GetRegionData(HRGN hrgn, DWORD count, LPRGNDATA rgndata)
{
    DWORD size;
    WINEREGION *obj = GDI_GetObjPtr( hrgn, OBJ_REGION );

    TRACE(" %p count = %d, rgndata = %p\n", hrgn, count, rgndata);

    if(!obj) return 0;

    size = obj->numRects * sizeof(RECT);
    if (!rgndata || count < FIELD_OFFSET(RGNDATA, Buffer[size]))
    {
        GDI_ReleaseObj( hrgn );
	if (rgndata) /* buffer is too small, signal it by return 0 */
	    return 0;
        /* user requested buffer size with NULL rgndata */
        return FIELD_OFFSET(RGNDATA, Buffer[size]);
    }

    rgndata->rdh.dwSize = sizeof(RGNDATAHEADER);
    rgndata->rdh.iType = RDH_RECTANGLES;
    rgndata->rdh.nCount = obj->numRects;
    rgndata->rdh.nRgnSize = size;
    rgndata->rdh.rcBound.left = obj->extents.left;
    rgndata->rdh.rcBound.top = obj->extents.top;
    rgndata->rdh.rcBound.right = obj->extents.right;
    rgndata->rdh.rcBound.bottom = obj->extents.bottom;

    memcpy( rgndata->Buffer, obj->rects, size );

    GDI_ReleaseObj( hrgn );
    return FIELD_OFFSET(RGNDATA, Buffer[size]);
}


static void translate( POINT *pt, UINT count, const XFORM *xform )
{
    while (count--)
    {
        double x = pt->x;
        double y = pt->y;
        pt->x = floor( x * xform->eM11 + y * xform->eM21 + xform->eDx + 0.5 );
        pt->y = floor( x * xform->eM12 + y * xform->eM22 + xform->eDy + 0.5 );
        pt++;
    }
}


/***********************************************************************
 *           ExtCreateRegion   (GDI32.@)
 *
 * Creates a region as specified by the transformation data and region data.
 *
 * PARAMS
 *   lpXform [I] World-space to logical-space transformation data.
 *   dwCount [I] Size of the data pointed to by rgndata, in bytes.
 *   rgndata [I] Data that specifies the region.
 *
 * RETURNS
 *   Success: Handle to region.
 *   Failure: NULL.
 *
 * NOTES
 *   See GetRegionData().
 */
HRGN WINAPI ExtCreateRegion( const XFORM* lpXform, DWORD dwCount, const RGNDATA* rgndata)
{
    HRGN hrgn = 0;
    WINEREGION *obj;
    const RECT *pCurRect, *pEndRect;

    if (!rgndata)
    {
        SetLastError( ERROR_INVALID_PARAMETER );
        return 0;
    }

    if (rgndata->rdh.dwSize < sizeof(RGNDATAHEADER))
        return 0;

    /* XP doesn't care about the type */
    if( rgndata->rdh.iType != RDH_RECTANGLES )
        WARN("(Unsupported region data type: %u)\n", rgndata->rdh.iType);

    if (lpXform)
    {
        const RECT *pCurRect, *pEndRect;

        hrgn = CreateRectRgn( 0, 0, 0, 0 );

        pEndRect = (const RECT *)rgndata->Buffer + rgndata->rdh.nCount;
        for (pCurRect = (const RECT *)rgndata->Buffer; pCurRect < pEndRect; pCurRect++)
        {
            static const INT count = 4;
            HRGN poly_hrgn;
            POINT pt[4];

            pt[0].x = pCurRect->left;
            pt[0].y = pCurRect->top;
            pt[1].x = pCurRect->right;
            pt[1].y = pCurRect->top;
            pt[2].x = pCurRect->right;
            pt[2].y = pCurRect->bottom;
            pt[3].x = pCurRect->left;
            pt[3].y = pCurRect->bottom;

            translate( pt, 4, lpXform );
            poly_hrgn = CreatePolyPolygonRgn( pt, &count, 1, WINDING );
            CombineRgn( hrgn, hrgn, poly_hrgn, RGN_OR );
            DeleteObject( poly_hrgn );
        }
        return hrgn;
    }

    if (!(obj = alloc_region( rgndata->rdh.nCount ))) return 0;

    pEndRect = (const RECT *)rgndata->Buffer + rgndata->rdh.nCount;
    for(pCurRect = (const RECT *)rgndata->Buffer; pCurRect < pEndRect; pCurRect++)
    {
        if (pCurRect->left < pCurRect->right && pCurRect->top < pCurRect->bottom)
        {
            if (!REGION_UnionRectWithRegion( pCurRect, obj )) goto done;
        }
    }
    hrgn = alloc_gdi_handle( obj, OBJ_REGION, &region_funcs );

done:
    if (!hrgn) free_region( obj );

    TRACE("%p %d %p returning %p\n", lpXform, dwCount, rgndata, hrgn );
    return hrgn;
}


/***********************************************************************
 *           PtInRegion    (GDI32.@)
 *
 * Tests whether the specified point is inside a region.
 *
 * PARAMS
 *   hrgn [I] Region to test.
 *   x    [I] X-coordinate of point to test.
 *   y    [I] Y-coordinate of point to test.
 *
 * RETURNS
 *   Non-zero if the point is inside the region or zero otherwise.
 */
BOOL WINAPI PtInRegion( HRGN hrgn, INT x, INT y )
{
    WINEREGION *obj;
    BOOL ret = FALSE;

    if ((obj = GDI_GetObjPtr( hrgn, OBJ_REGION )))
    {
        if (obj->numRects > 0 && is_in_rect( &obj->extents, x, y ))
            region_find_pt( obj, x, y, &ret );
	GDI_ReleaseObj( hrgn );
    }
    return ret;
}


/***********************************************************************
 *           RectInRegion    (GDI32.@)
 *
 * Tests if a rectangle is at least partly inside the specified region.
 *
 * PARAMS
 *   hrgn [I] Region to test.
 *   rect [I] Rectangle to test.
 *
 * RETURNS
 *   Non-zero if the rectangle is partially inside the region or
 *   zero otherwise.
 */
BOOL WINAPI RectInRegion( HRGN hrgn, const RECT *rect )
{
    WINEREGION *obj;
    BOOL ret = FALSE;
    RECT rc;
    int i;

    /* swap the coordinates to make right >= left and bottom >= top */
    /* (region building rectangles are normalized the same way) */
    rc = *rect;
    order_rect( &rc );

    if ((obj = GDI_GetObjPtr( hrgn, OBJ_REGION )))
    {
	if ((obj->numRects > 0) && overlapping(&obj->extents, &rc))
	{
	    for (i = region_find_pt( obj, rc.left, rc.top, &ret ); !ret && i < obj->numRects; i++ )
	    {
	        if (obj->rects[i].bottom <= rc.top)
		    continue;             /* not far enough down yet */

		if (obj->rects[i].top >= rc.bottom)
		    break;                /* too far down */

		if (obj->rects[i].right <= rc.left)
		    continue;              /* not far enough over yet */

		if (obj->rects[i].left >= rc.right)
		    continue;

		ret = TRUE;
	    }
	}
	GDI_ReleaseObj(hrgn);
    }
    return ret;
}

/***********************************************************************
 *           EqualRgn    (GDI32.@)
 *
 * Tests whether one region is identical to another.
 *
 * PARAMS
 *   hrgn1 [I] The first region to compare.
 *   hrgn2 [I] The second region to compare.
 *
 * RETURNS
 *   Non-zero if both regions are identical or zero otherwise.
 */
BOOL WINAPI EqualRgn( HRGN hrgn1, HRGN hrgn2 )
{
    WINEREGION *obj1, *obj2;
    BOOL ret = FALSE;

    if ((obj1 = GDI_GetObjPtr( hrgn1, OBJ_REGION )))
    {
        if ((obj2 = GDI_GetObjPtr( hrgn2, OBJ_REGION )))
	{
	    int i;

	    if ( obj1->numRects != obj2->numRects ) goto done;
            if ( obj1->numRects == 0 )
            {
                ret = TRUE;
                goto done;

            }
            if (obj1->extents.left   != obj2->extents.left) goto done;
            if (obj1->extents.right  != obj2->extents.right) goto done;
            if (obj1->extents.top    != obj2->extents.top) goto done;
            if (obj1->extents.bottom != obj2->extents.bottom) goto done;
            for( i = 0; i < obj1->numRects; i++ )
            {
                if (obj1->rects[i].left   != obj2->rects[i].left) goto done;
                if (obj1->rects[i].right  != obj2->rects[i].right) goto done;
                if (obj1->rects[i].top    != obj2->rects[i].top) goto done;
                if (obj1->rects[i].bottom != obj2->rects[i].bottom) goto done;
	    }
            ret = TRUE;
        done:
	    GDI_ReleaseObj(hrgn2);
	}
	GDI_ReleaseObj(hrgn1);
    }
    return ret;
}

/***********************************************************************
 *           REGION_UnionRectWithRegion
 *           Adds a rectangle to a WINEREGION
 */
static BOOL REGION_UnionRectWithRegion(const RECT *rect, WINEREGION *rgn)
{
    WINEREGION region;

    init_region( &region, 1 );
    region.numRects = 1;
    region.extents = *region.rects = *rect;
    return REGION_UnionRegion(rgn, rgn, &region);
}


BOOL add_rect_to_region( HRGN rgn, const RECT *rect )
{
    WINEREGION *obj = GDI_GetObjPtr( rgn, OBJ_REGION );
    BOOL ret;

    if (!obj) return FALSE;
    ret = REGION_UnionRectWithRegion( rect, obj );
    GDI_ReleaseObj( rgn );
    return ret;
}

/***********************************************************************
 *           REGION_CreateFrameRgn
 *
 * Create a region that is a frame around another region.
 * Compute the intersection of the region moved in all 4 directions
 * ( +x, -x, +y, -y) and subtract from the original.
 * The result looks slightly better than in Windows :)
 */
BOOL REGION_FrameRgn( HRGN hDest, HRGN hSrc, INT x, INT y )
{
    WINEREGION tmprgn;
    BOOL bRet = FALSE;
    WINEREGION* destObj = NULL;
    WINEREGION *srcObj = GDI_GetObjPtr( hSrc, OBJ_REGION );

    tmprgn.rects = NULL;
    if (!srcObj) return FALSE;
    if (srcObj->numRects != 0)
    {
        if (!(destObj = GDI_GetObjPtr( hDest, OBJ_REGION ))) goto done;
        if (!init_region( &tmprgn, srcObj->numRects )) goto done;

        if (!REGION_OffsetRegion( destObj, srcObj, -x, 0)) goto done;
        if (!REGION_OffsetRegion( &tmprgn, srcObj, x, 0)) goto done;
        if (!REGION_IntersectRegion( destObj, destObj, &tmprgn )) goto done;
        if (!REGION_OffsetRegion( &tmprgn, srcObj, 0, -y)) goto done;
        if (!REGION_IntersectRegion( destObj, destObj, &tmprgn )) goto done;
        if (!REGION_OffsetRegion( &tmprgn, srcObj, 0, y)) goto done;
        if (!REGION_IntersectRegion( destObj, destObj, &tmprgn )) goto done;
        if (!REGION_SubtractRegion( destObj, srcObj, destObj )) goto done;
	bRet = TRUE;
    }
done:
    destroy_region( &tmprgn );
    if (destObj) GDI_ReleaseObj ( hDest );
    GDI_ReleaseObj( hSrc );
    return bRet;
}


/***********************************************************************
 *           CombineRgn   (GDI32.@)
 *
 * Combines two regions with the specified operation and stores the result
 * in the specified destination region.
 *
 * PARAMS
 *   hDest [I] The region that receives the combined result.
 *   hSrc1 [I] The first source region.
 *   hSrc2 [I] The second source region.
 *   mode  [I] The way in which the source regions will be combined. See notes.
 *
 * RETURNS
 *   Success:
 *     NULLREGION - The new region is empty.
 *     SIMPLEREGION - The new region can be represented by one rectangle.
 *     COMPLEXREGION - The new region can only be represented by more than
 *                     one rectangle.
 *   Failure: ERROR
 *
 * NOTES
 *   The two source regions can be the same region.
 *   The mode can be one of the following:
 *|  RGN_AND - Intersection of the regions
 *|  RGN_OR - Union of the regions
 *|  RGN_XOR - Unions of the regions minus any intersection.
 *|  RGN_DIFF - Difference (subtraction) of the regions.
 */
INT WINAPI CombineRgn(HRGN hDest, HRGN hSrc1, HRGN hSrc2, INT mode)
{
    WINEREGION *destObj = GDI_GetObjPtr( hDest, OBJ_REGION );
    INT result = ERROR;

    TRACE(" %p,%p -> %p mode=%x\n", hSrc1, hSrc2, hDest, mode );
    if (destObj)
    {
        WINEREGION *src1Obj = GDI_GetObjPtr( hSrc1, OBJ_REGION );

	if (src1Obj)
	{
	    TRACE("dump src1Obj:\n");
	    if(TRACE_ON(region))
	      REGION_DumpRegion(src1Obj);
	    if (mode == RGN_COPY)
	    {
		if (REGION_CopyRegion( destObj, src1Obj ))
                    result = get_region_type( destObj );
	    }
	    else
	    {
                WINEREGION *src2Obj = GDI_GetObjPtr( hSrc2, OBJ_REGION );

		if (src2Obj)
		{
		    TRACE("dump src2Obj:\n");
		    if(TRACE_ON(region))
		        REGION_DumpRegion(src2Obj);
		    switch (mode)
		    {
		    case RGN_AND:
			if (REGION_IntersectRegion( destObj, src1Obj, src2Obj ))
                            result = get_region_type( destObj );
			break;
		    case RGN_OR:
			if (REGION_UnionRegion( destObj, src1Obj, src2Obj ))
                            result = get_region_type( destObj );
			break;
		    case RGN_XOR:
			if (REGION_XorRegion( destObj, src1Obj, src2Obj ))
                            result = get_region_type( destObj );
			break;
		    case RGN_DIFF:
			if (REGION_SubtractRegion( destObj, src1Obj, src2Obj ))
                            result = get_region_type( destObj );
			break;
		    }
		    GDI_ReleaseObj( hSrc2 );
		}
	    }
	    GDI_ReleaseObj( hSrc1 );
	}
	TRACE("dump destObj:\n");
	if(TRACE_ON(region))
	  REGION_DumpRegion(destObj);

	GDI_ReleaseObj( hDest );
    }
    return result;
}

/***********************************************************************
 *           REGION_SetExtents
 *           Re-calculate the extents of a region
 */
static void REGION_SetExtents (WINEREGION *pReg)
{
    RECT *pRect, *pRectEnd, *pExtents;

    if (pReg->numRects == 0)
    {
	pReg->extents.left = 0;
	pReg->extents.top = 0;
	pReg->extents.right = 0;
	pReg->extents.bottom = 0;
	return;
    }

    pExtents = &pReg->extents;
    pRect = pReg->rects;
    pRectEnd = &pRect[pReg->numRects - 1];

    /*
     * Since pRect is the first rectangle in the region, it must have the
     * smallest top and since pRectEnd is the last rectangle in the region,
     * it must have the largest bottom, because of banding. Initialize left and
     * right from pRect and pRectEnd, resp., as good things to initialize them
     * to...
     */
    pExtents->left = pRect->left;
    pExtents->top = pRect->top;
    pExtents->right = pRectEnd->right;
    pExtents->bottom = pRectEnd->bottom;

    while (pRect <= pRectEnd)
    {
	if (pRect->left < pExtents->left)
	    pExtents->left = pRect->left;
	if (pRect->right > pExtents->right)
	    pExtents->right = pRect->right;
	pRect++;
    }
}

/***********************************************************************
 *           REGION_CopyRegion
 */
static BOOL REGION_CopyRegion(WINEREGION *dst, WINEREGION *src)
{
    if (dst != src) /*  don't want to copy to itself */
    {
	if (dst->size < src->numRects && !grow_region( dst, src->numRects ))
            return FALSE;

	dst->numRects = src->numRects;
	dst->extents.left = src->extents.left;
	dst->extents.top = src->extents.top;
	dst->extents.right = src->extents.right;
	dst->extents.bottom = src->extents.bottom;
        memcpy(dst->rects, src->rects, src->numRects * sizeof(RECT));
    }
    return TRUE;
}

/***********************************************************************
 *           REGION_MirrorRegion
 */
static BOOL REGION_MirrorRegion( WINEREGION *dst, WINEREGION *src, int width )
{
    int i, start, end;
    RECT extents;
    RECT *rects;
    WINEREGION tmp;

    if (dst != src)
    {
        if (!grow_region( dst, src->numRects )) return FALSE;
        rects = dst->rects;
        dst->numRects = src->numRects;
    }
    else
    {
        if (!init_region( &tmp, src->numRects )) return FALSE;
        rects = tmp.rects;
        tmp.numRects = src->numRects;
    }

    extents.left   = width - src->extents.right;
    extents.right  = width - src->extents.left;
    extents.top    = src->extents.top;
    extents.bottom = src->extents.bottom;

    for (start = 0; start < src->numRects; start = end)
    {
        /* find the end of the current band */
        for (end = start + 1; end < src->numRects; end++)
            if (src->rects[end].top != src->rects[end - 1].top) break;

        for (i = 0; i < end - start; i++)
        {
            rects[start + i].left   = width - src->rects[end - i - 1].right;
            rects[start + i].right  = width - src->rects[end - i - 1].left;
            rects[start + i].top    = src->rects[end - i - 1].top;
            rects[start + i].bottom = src->rects[end - i - 1].bottom;
        }
    }

    if (dst == src)
        move_rects( dst, &tmp );

    dst->extents = extents;
    return TRUE;
}

/***********************************************************************
 *           mirror_region
 */
INT mirror_region( HRGN dst, HRGN src, INT width )
{
    WINEREGION *src_rgn, *dst_rgn;
    INT ret = ERROR;

    if (!(src_rgn = GDI_GetObjPtr( src, OBJ_REGION ))) return ERROR;
    if ((dst_rgn = GDI_GetObjPtr( dst, OBJ_REGION )))
    {
        if (REGION_MirrorRegion( dst_rgn, src_rgn, width )) ret = get_region_type( dst_rgn );
        GDI_ReleaseObj( dst_rgn );
    }
    GDI_ReleaseObj( src_rgn );
    return ret;
}

/***********************************************************************
 *           MirrorRgn    (GDI32.@)
 */
BOOL WINAPI MirrorRgn( HWND hwnd, HRGN hrgn )
{
    static const WCHAR user32W[] = {'u','s','e','r','3','2','.','d','l','l',0};
    static BOOL (WINAPI *pGetWindowRect)( HWND hwnd, LPRECT rect );
    RECT rect;

    /* yes, a HWND in gdi32, don't ask */
    if (!pGetWindowRect)
    {
        HMODULE user32 = GetModuleHandleW(user32W);
        if (!user32) return FALSE;
        if (!(pGetWindowRect = (void *)GetProcAddress( user32, "GetWindowRect" ))) return FALSE;
    }
    pGetWindowRect( hwnd, &rect );
    return mirror_region( hrgn, hrgn, rect.right - rect.left ) != ERROR;
}


/***********************************************************************
 *           REGION_Coalesce
 *
 *      Attempt to merge the rects in the current band with those in the
 *      previous one. Used only by REGION_RegionOp.
 *
 * Results:
 *      The new index for the previous band.
 *
 * Side Effects:
 *      If coalescing takes place:
 *          - rectangles in the previous band will have their bottom fields
 *            altered.
 *          - pReg->numRects will be decreased.
 *
 */
static INT REGION_Coalesce (
	     WINEREGION *pReg, /* Region to coalesce */
	     INT prevStart,  /* Index of start of previous band */
	     INT curStart    /* Index of start of current band */
) {
    RECT *pPrevRect;          /* Current rect in previous band */
    RECT *pCurRect;           /* Current rect in current band */
    RECT *pRegEnd;            /* End of region */
    INT curNumRects;          /* Number of rectangles in current band */
    INT prevNumRects;         /* Number of rectangles in previous band */
    INT bandtop;               /* top coordinate for current band */

    pRegEnd = &pReg->rects[pReg->numRects];

    pPrevRect = &pReg->rects[prevStart];
    prevNumRects = curStart - prevStart;

    /*
     * Figure out how many rectangles are in the current band. Have to do
     * this because multiple bands could have been added in REGION_RegionOp
     * at the end when one region has been exhausted.
     */
    pCurRect = &pReg->rects[curStart];
    bandtop = pCurRect->top;
    for (curNumRects = 0;
	 (pCurRect != pRegEnd) && (pCurRect->top == bandtop);
	 curNumRects++)
    {
	pCurRect++;
    }

    if (pCurRect != pRegEnd)
    {
	/*
	 * If more than one band was added, we have to find the start
	 * of the last band added so the next coalescing job can start
	 * at the right place... (given when multiple bands are added,
	 * this may be pointless -- see above).
	 */
	pRegEnd--;
	while (pRegEnd[-1].top == pRegEnd->top)
	{
	    pRegEnd--;
	}
	curStart = pRegEnd - pReg->rects;
	pRegEnd = pReg->rects + pReg->numRects;
    }

    if ((curNumRects == prevNumRects) && (curNumRects != 0)) {
	pCurRect -= curNumRects;
	/*
	 * The bands may only be coalesced if the bottom of the previous
	 * matches the top scanline of the current.
	 */
	if (pPrevRect->bottom == pCurRect->top)
	{
	    /*
	     * Make sure the bands have rects in the same places. This
	     * assumes that rects have been added in such a way that they
	     * cover the most area possible. I.e. two rects in a band must
	     * have some horizontal space between them.
	     */
	    do
	    {
		if ((pPrevRect->left != pCurRect->left) ||
		    (pPrevRect->right != pCurRect->right))
		{
		    /*
		     * The bands don't line up so they can't be coalesced.
		     */
		    return (curStart);
		}
		pPrevRect++;
		pCurRect++;
		prevNumRects -= 1;
	    } while (prevNumRects != 0);

	    pReg->numRects -= curNumRects;
	    pCurRect -= curNumRects;
	    pPrevRect -= curNumRects;

	    /*
	     * The bands may be merged, so set the bottom of each rect
	     * in the previous band to that of the corresponding rect in
	     * the current band.
	     */
	    do
	    {
		pPrevRect->bottom = pCurRect->bottom;
		pPrevRect++;
		pCurRect++;
		curNumRects -= 1;
	    } while (curNumRects != 0);

	    /*
	     * If only one band was added to the region, we have to backup
	     * curStart to the start of the previous band.
	     *
	     * If more than one band was added to the region, copy the
	     * other bands down. The assumption here is that the other bands
	     * came from the same region as the current one and no further
	     * coalescing can be done on them since it's all been done
	     * already... curStart is already in the right place.
	     */
	    if (pCurRect == pRegEnd)
	    {
		curStart = prevStart;
	    }
	    else
	    {
		do
		{
		    *pPrevRect++ = *pCurRect++;
		} while (pCurRect != pRegEnd);
	    }

	}
    }
    return (curStart);
}

/**********************************************************************
 *          REGION_compact
 *
 * To keep regions from growing without bound, shrink the array of rectangles
 * to match the new number of rectangles in the region.
 *
 * Only do this if the number of rectangles allocated is more than
 * twice the number of rectangles in the region.
 */
static void REGION_compact( WINEREGION *reg )
{
    if ((reg->numRects < reg->size / 2) && (reg->numRects > RGN_DEFAULT_RECTS))
    {
        RECT *new_rects = HeapReAlloc( GetProcessHeap(), 0, reg->rects, reg->numRects * sizeof(RECT) );
        if (new_rects)
        {
            reg->rects = new_rects;
            reg->size = reg->numRects;
        }
    }
}

/***********************************************************************
 *           REGION_RegionOp
 *
 *      Apply an operation to two regions. Called by REGION_Union,
 *      REGION_Inverse, REGION_Subtract, REGION_Intersect...
 *
 * Results:
 *      None.
 *
 * Side Effects:
 *      The new region is overwritten.
 *
 * Notes:
 *      The idea behind this function is to view the two regions as sets.
 *      Together they cover a rectangle of area that this function divides
 *      into horizontal bands where points are covered only by one region
 *      or by both. For the first case, the nonOverlapFunc is called with
 *      each the band and the band's upper and lower extents. For the
 *      second, the overlapFunc is called to process the entire band. It
 *      is responsible for clipping the rectangles in the band, though
 *      this function provides the boundaries.
 *      At the end of each band, the new region is coalesced, if possible,
 *      to reduce the number of rectangles in the region.
 *
 */
static BOOL REGION_RegionOp(
	    WINEREGION *destReg, /* Place to store result */
	    WINEREGION *reg1,   /* First region in operation */
            WINEREGION *reg2,   /* 2nd region in operation */
	    BOOL (*overlapFunc)(WINEREGION*, RECT*, RECT*, RECT*, RECT*, INT, INT),     /* Function to call for over-lapping bands */
	    BOOL (*nonOverlap1Func)(WINEREGION*, RECT*, RECT*, INT, INT), /* Function to call for non-overlapping bands in region 1 */
	    BOOL (*nonOverlap2Func)(WINEREGION*, RECT*, RECT*, INT, INT)  /* Function to call for non-overlapping bands in region 2 */
) {
    WINEREGION newReg;
    RECT *r1;                         /* Pointer into first region */
    RECT *r2;                         /* Pointer into 2d region */
    RECT *r1End;                      /* End of 1st region */
    RECT *r2End;                      /* End of 2d region */
    INT ybot;                         /* Bottom of intersection */
    INT ytop;                         /* Top of intersection */
    INT prevBand;                     /* Index of start of
						 * previous band in newReg */
    INT curBand;                      /* Index of start of current
						 * band in newReg */
    RECT *r1BandEnd;                  /* End of current band in r1 */
    RECT *r2BandEnd;                  /* End of current band in r2 */
    INT top;                          /* Top of non-overlapping band */
    INT bot;                          /* Bottom of non-overlapping band */

    /*
     * Initialization:
     *  set r1, r2, r1End and r2End appropriately, preserve the important
     * parts of the destination region until the end in case it's one of
     * the two source regions, then mark the "new" region empty, allocating
     * another array of rectangles for it to use.
     */
    r1 = reg1->rects;
    r2 = reg2->rects;
    r1End = r1 + reg1->numRects;
    r2End = r2 + reg2->numRects;

    /*
     * Allocate a reasonable number of rectangles for the new region. The idea
     * is to allocate enough so the individual functions don't need to
     * reallocate and copy the array, which is time consuming, yet we don't
     * have to worry about using too much memory. I hope to be able to
     * nuke the Xrealloc() at the end of this function eventually.
     */
    if (!init_region( &newReg, max(reg1->numRects,reg2->numRects) * 2 )) return FALSE;

    /*
     * Initialize ybot and ytop.
     * In the upcoming loop, ybot and ytop serve different functions depending
     * on whether the band being handled is an overlapping or non-overlapping
     * band.
     *  In the case of a non-overlapping band (only one of the regions
     * has points in the band), ybot is the bottom of the most recent
     * intersection and thus clips the top of the rectangles in that band.
     * ytop is the top of the next intersection between the two regions and
     * serves to clip the bottom of the rectangles in the current band.
     *  For an overlapping band (where the two regions intersect), ytop clips
     * the top of the rectangles of both regions and ybot clips the bottoms.
     */
    if (reg1->extents.top < reg2->extents.top)
	ybot = reg1->extents.top;
    else
	ybot = reg2->extents.top;

    /*
     * prevBand serves to mark the start of the previous band so rectangles
     * can be coalesced into larger rectangles. qv. miCoalesce, above.
     * In the beginning, there is no previous band, so prevBand == curBand
     * (curBand is set later on, of course, but the first band will always
     * start at index 0). prevBand and curBand must be indices because of
     * the possible expansion, and resultant moving, of the new region's
     * array of rectangles.
     */
    prevBand = 0;

    do
    {
	curBand = newReg.numRects;

	/*
	 * This algorithm proceeds one source-band (as opposed to a
	 * destination band, which is determined by where the two regions
	 * intersect) at a time. r1BandEnd and r2BandEnd serve to mark the
	 * rectangle after the last one in the current band for their
	 * respective regions.
	 */
	r1BandEnd = r1;
	while ((r1BandEnd != r1End) && (r1BandEnd->top == r1->top))
	{
	    r1BandEnd++;
	}

	r2BandEnd = r2;
	while ((r2BandEnd != r2End) && (r2BandEnd->top == r2->top))
	{
	    r2BandEnd++;
	}

	/*
	 * First handle the band that doesn't intersect, if any.
	 *
	 * Note that attention is restricted to one band in the
	 * non-intersecting region at once, so if a region has n
	 * bands between the current position and the next place it overlaps
	 * the other, this entire loop will be passed through n times.
	 */
	if (r1->top < r2->top)
	{
	    top = max(r1->top,ybot);
	    bot = min(r1->bottom,r2->top);

            if ((top != bot) && (nonOverlap1Func != NULL))
	    {
		if (!nonOverlap1Func(&newReg, r1, r1BandEnd, top, bot)) return FALSE;
	    }

	    ytop = r2->top;
	}
	else if (r2->top < r1->top)
	{
	    top = max(r2->top,ybot);
	    bot = min(r2->bottom,r1->top);

            if ((top != bot) && (nonOverlap2Func != NULL))
	    {
		if (!nonOverlap2Func(&newReg, r2, r2BandEnd, top, bot)) return FALSE;
	    }

	    ytop = r1->top;
	}
	else
	{
	    ytop = r1->top;
	}

	/*
	 * If any rectangles got added to the region, try and coalesce them
	 * with rectangles from the previous band. Note we could just do
	 * this test in miCoalesce, but some machines incur a not
	 * inconsiderable cost for function calls, so...
	 */
	if (newReg.numRects != curBand)
	{
	    prevBand = REGION_Coalesce (&newReg, prevBand, curBand);
	}

	/*
	 * Now see if we've hit an intersecting band. The two bands only
	 * intersect if ybot > ytop
	 */
	ybot = min(r1->bottom, r2->bottom);
	curBand = newReg.numRects;
	if (ybot > ytop)
	{
	    if (!overlapFunc(&newReg, r1, r1BandEnd, r2, r2BandEnd, ytop, ybot)) return FALSE;
	}

	if (newReg.numRects != curBand)
	{
	    prevBand = REGION_Coalesce (&newReg, prevBand, curBand);
	}

	/*
	 * If we've finished with a band (bottom == ybot) we skip forward
	 * in the region to the next band.
	 */
	if (r1->bottom == ybot)
	{
	    r1 = r1BandEnd;
	}
	if (r2->bottom == ybot)
	{
	    r2 = r2BandEnd;
	}
    } while ((r1 != r1End) && (r2 != r2End));

    /*
     * Deal with whichever region still has rectangles left.
     */
    curBand = newReg.numRects;
    if (r1 != r1End)
    {
        if (nonOverlap1Func != NULL)
	{
	    do
	    {
		r1BandEnd = r1;
		while ((r1BandEnd < r1End) && (r1BandEnd->top == r1->top))
		{
		    r1BandEnd++;
		}
		if (!nonOverlap1Func(&newReg, r1, r1BandEnd, max(r1->top,ybot), r1->bottom))
                    return FALSE;
		r1 = r1BandEnd;
	    } while (r1 != r1End);
	}
    }
    else if ((r2 != r2End) && (nonOverlap2Func != NULL))
    {
	do
	{
	    r2BandEnd = r2;
	    while ((r2BandEnd < r2End) && (r2BandEnd->top == r2->top))
	    {
		 r2BandEnd++;
	    }
	    if (!nonOverlap2Func(&newReg, r2, r2BandEnd, max(r2->top,ybot), r2->bottom))
                return FALSE;
	    r2 = r2BandEnd;
	} while (r2 != r2End);
    }

    if (newReg.numRects != curBand)
    {
	REGION_Coalesce (&newReg, prevBand, curBand);
    }

    REGION_compact( &newReg );
    move_rects( destReg, &newReg );
    return TRUE;
}

/***********************************************************************
 *          Region Intersection
 ***********************************************************************/


/***********************************************************************
 *	     REGION_IntersectO
 *
 * Handle an overlapping band for REGION_Intersect.
 *
 * Results:
 *      None.
 *
 * Side Effects:
 *      Rectangles may be added to the region.
 *
 */
static BOOL REGION_IntersectO(WINEREGION *pReg,  RECT *r1, RECT *r1End,
                              RECT *r2, RECT *r2End, INT top, INT bottom)

{
    INT       left, right;

    while ((r1 != r1End) && (r2 != r2End))
    {
	left = max(r1->left, r2->left);
	right =	min(r1->right, r2->right);

	/*
	 * If there's any overlap between the two rectangles, add that
	 * overlap to the new region.
	 * There's no need to check for subsumption because the only way
	 * such a need could arise is if some region has two rectangles
	 * right next to each other. Since that should never happen...
	 */
	if (left < right)
        {
            if (!add_rect( pReg, left, top, right, bottom )) return FALSE;
        }

	/*
	 * Need to advance the pointers. Shift the one that extends
	 * to the right the least, since the other still has a chance to
	 * overlap with that region's next rectangle, if you see what I mean.
	 */
	if (r1->right < r2->right)
	{
	    r1++;
	}
	else if (r2->right < r1->right)
	{
	    r2++;
	}
	else
	{
	    r1++;
	    r2++;
	}
    }
    return TRUE;
}

/***********************************************************************
 *	     REGION_IntersectRegion
 */
static BOOL REGION_IntersectRegion(WINEREGION *newReg, WINEREGION *reg1,
				   WINEREGION *reg2)
{
   /* check for trivial reject */
    if ( (!(reg1->numRects)) || (!(reg2->numRects))  ||
	(!overlapping(&reg1->extents, &reg2->extents)))
	newReg->numRects = 0;
    else
	if (!REGION_RegionOp (newReg, reg1, reg2, REGION_IntersectO, NULL, NULL)) return FALSE;

    /*
     * Can't alter newReg's extents before we call miRegionOp because
     * it might be one of the source regions and miRegionOp depends
     * on the extents of those regions being the same. Besides, this
     * way there's no checking against rectangles that will be nuked
     * due to coalescing, so we have to examine fewer rectangles.
     */
    REGION_SetExtents(newReg);
    return TRUE;
}

/***********************************************************************
 *	     Region Union
 ***********************************************************************/

/***********************************************************************
 *	     REGION_UnionNonO
 *
 *      Handle a non-overlapping band for the union operation. Just
 *      Adds the rectangles into the region. Doesn't have to check for
 *      subsumption or anything.
 *
 * Results:
 *      None.
 *
 * Side Effects:
 *      pReg->numRects is incremented and the final rectangles overwritten
 *      with the rectangles we're passed.
 *
 */
static BOOL REGION_UnionNonO(WINEREGION *pReg, RECT *r, RECT *rEnd, INT top, INT bottom)
{
    while (r != rEnd)
    {
        if (!add_rect( pReg, r->left, top, r->right, bottom )) return FALSE;
	r++;
    }
    return TRUE;
}

/***********************************************************************
 *	     REGION_UnionO
 *
 *      Handle an overlapping band for the union operation. Picks the
 *      left-most rectangle each time and merges it into the region.
 *
 * Results:
 *      None.
 *
 * Side Effects:
 *      Rectangles are overwritten in pReg->rects and pReg->numRects will
 *      be changed.
 *
 */
static BOOL REGION_UnionO (WINEREGION *pReg, RECT *r1, RECT *r1End,
			   RECT *r2, RECT *r2End, INT top, INT bottom)
{
#define MERGERECT(r) \
    if ((pReg->numRects != 0) &&  \
	(pReg->rects[pReg->numRects-1].top == top) &&  \
	(pReg->rects[pReg->numRects-1].bottom == bottom) &&  \
	(pReg->rects[pReg->numRects-1].right >= r->left))  \
    {  \
	if (pReg->rects[pReg->numRects-1].right < r->right)  \
	    pReg->rects[pReg->numRects-1].right = r->right;  \
    }  \
    else  \
    { \
        if (!add_rect( pReg, r->left, top, r->right, bottom )) return FALSE; \
    } \
    r++;

    while ((r1 != r1End) && (r2 != r2End))
    {
	if (r1->left < r2->left)
	{
	    MERGERECT(r1);
	}
	else
	{
	    MERGERECT(r2);
	}
    }

    if (r1 != r1End)
    {
	do
	{
	    MERGERECT(r1);
	} while (r1 != r1End);
    }
    else while (r2 != r2End)
    {
	MERGERECT(r2);
    }
    return TRUE;
#undef MERGERECT
}

/***********************************************************************
 *	     REGION_UnionRegion
 */
static BOOL REGION_UnionRegion(WINEREGION *newReg, WINEREGION *reg1, WINEREGION *reg2)
{
    BOOL ret = TRUE;

    /*  checks all the simple cases */

    /*
     * Region 1 and 2 are the same or region 1 is empty
     */
    if ( (reg1 == reg2) || (!(reg1->numRects)) )
    {
	if (newReg != reg2)
	    ret = REGION_CopyRegion(newReg, reg2);
	return ret;
    }

    /*
     * if nothing to union (region 2 empty)
     */
    if (!(reg2->numRects))
    {
	if (newReg != reg1)
	    ret = REGION_CopyRegion(newReg, reg1);
	return ret;
    }

    /*
     * Region 1 completely subsumes region 2
     */
    if ((reg1->numRects == 1) &&
	(reg1->extents.left <= reg2->extents.left) &&
	(reg1->extents.top <= reg2->extents.top) &&
	(reg1->extents.right >= reg2->extents.right) &&
	(reg1->extents.bottom >= reg2->extents.bottom))
    {
	if (newReg != reg1)
	    ret = REGION_CopyRegion(newReg, reg1);
	return ret;
    }

    /*
     * Region 2 completely subsumes region 1
     */
    if ((reg2->numRects == 1) &&
	(reg2->extents.left <= reg1->extents.left) &&
	(reg2->extents.top <= reg1->extents.top) &&
	(reg2->extents.right >= reg1->extents.right) &&
	(reg2->extents.bottom >= reg1->extents.bottom))
    {
	if (newReg != reg2)
	    ret = REGION_CopyRegion(newReg, reg2);
	return ret;
    }

    if ((ret = REGION_RegionOp (newReg, reg1, reg2, REGION_UnionO, REGION_UnionNonO, REGION_UnionNonO)))
    {
        newReg->extents.left = min(reg1->extents.left, reg2->extents.left);
        newReg->extents.top = min(reg1->extents.top, reg2->extents.top);
        newReg->extents.right = max(reg1->extents.right, reg2->extents.right);
        newReg->extents.bottom = max(reg1->extents.bottom, reg2->extents.bottom);
    }
    return ret;
}

/***********************************************************************
 *	     Region Subtraction
 ***********************************************************************/

/***********************************************************************
 *	     REGION_SubtractNonO1
 *
 *      Deal with non-overlapping band for subtraction. Any parts from
 *      region 2 we discard. Anything from region 1 we add to the region.
 *
 * Results:
 *      None.
 *
 * Side Effects:
 *      pReg may be affected.
 *
 */
static BOOL REGION_SubtractNonO1 (WINEREGION *pReg, RECT *r, RECT *rEnd, INT top, INT bottom)
{
    while (r != rEnd)
    {
        if (!add_rect( pReg, r->left, top, r->right, bottom )) return FALSE;
	r++;
    }
    return TRUE;
}


/***********************************************************************
 *	     REGION_SubtractO
 *
 *      Overlapping band subtraction. x1 is the left-most point not yet
 *      checked.
 *
 * Results:
 *      None.
 *
 * Side Effects:
 *      pReg may have rectangles added to it.
 *
 */
static BOOL REGION_SubtractO (WINEREGION *pReg, RECT *r1, RECT *r1End,
                              RECT *r2, RECT *r2End, INT top, INT bottom)
{
    INT left = r1->left;

    while ((r1 != r1End) && (r2 != r2End))
    {
	if (r2->right <= left)
	{
	    /*
	     * Subtrahend missed the boat: go to next subtrahend.
	     */
	    r2++;
	}
	else if (r2->left <= left)
	{
	    /*
	     * Subtrahend precedes minuend: nuke left edge of minuend.
	     */
	    left = r2->right;
	    if (left >= r1->right)
	    {
		/*
		 * Minuend completely covered: advance to next minuend and
		 * reset left fence to edge of new minuend.
		 */
		r1++;
		if (r1 != r1End)
		    left = r1->left;
	    }
	    else
	    {
		/*
		 * Subtrahend now used up since it doesn't extend beyond
		 * minuend
		 */
		r2++;
	    }
	}
	else if (r2->left < r1->right)
	{
	    /*
	     * Left part of subtrahend covers part of minuend: add uncovered
	     * part of minuend to region and skip to next subtrahend.
	     */
            if (!add_rect( pReg, left, top, r2->left, bottom )) return FALSE;
	    left = r2->right;
	    if (left >= r1->right)
	    {
		/*
		 * Minuend used up: advance to new...
		 */
		r1++;
		if (r1 != r1End)
		    left = r1->left;
	    }
	    else
	    {
		/*
		 * Subtrahend used up
		 */
		r2++;
	    }
	}
	else
	{
	    /*
	     * Minuend used up: add any remaining piece before advancing.
	     */
	    if (r1->right > left)
	    {
                if (!add_rect( pReg, left, top, r1->right, bottom )) return FALSE;
	    }
	    r1++;
	    if (r1 != r1End)
	        left = r1->left;
	}
    }

    /*
     * Add remaining minuend rectangles to region.
     */
    while (r1 != r1End)
    {
        if (!add_rect( pReg, left, top, r1->right, bottom )) return FALSE;
	r1++;
	if (r1 != r1End)
	{
	    left = r1->left;
	}
    }
    return TRUE;
}

/***********************************************************************
 *	     REGION_SubtractRegion
 *
 *      Subtract regS from regM and leave the result in regD.
 *      S stands for subtrahend, M for minuend and D for difference.
 *
 * Results:
 *      TRUE.
 *
 * Side Effects:
 *      regD is overwritten.
 *
 */
static BOOL REGION_SubtractRegion(WINEREGION *regD, WINEREGION *regM, WINEREGION *regS )
{
   /* check for trivial reject */
    if ( (!(regM->numRects)) || (!(regS->numRects))  ||
	(!overlapping(&regM->extents, &regS->extents)) )
	return REGION_CopyRegion(regD, regM);

    if (!REGION_RegionOp (regD, regM, regS, REGION_SubtractO, REGION_SubtractNonO1, NULL))
        return FALSE;

    /*
     * Can't alter newReg's extents before we call miRegionOp because
     * it might be one of the source regions and miRegionOp depends
     * on the extents of those regions being the unaltered. Besides, this
     * way there's no checking against rectangles that will be nuked
     * due to coalescing, so we have to examine fewer rectangles.
     */
    REGION_SetExtents (regD);
    return TRUE;
}

/***********************************************************************
 *	     REGION_XorRegion
 */
static BOOL REGION_XorRegion(WINEREGION *dr, WINEREGION *sra, WINEREGION *srb)
{
    WINEREGION tra, trb;
    BOOL ret;

    if (!init_region( &tra, sra->numRects + 1 )) return FALSE;
    if ((ret = init_region( &trb, srb->numRects + 1 )))
    {
        ret = REGION_SubtractRegion(&tra,sra,srb) &&
              REGION_SubtractRegion(&trb,srb,sra) &&
              REGION_UnionRegion(dr,&tra,&trb);
        destroy_region(&trb);
    }
    destroy_region(&tra);
    return ret;
}

/**************************************************************************
 *
 *    Poly Regions
 *
 *************************************************************************/

#define LARGE_COORDINATE  0x7fffffff /* FIXME */
#define SMALL_COORDINATE  0x80000000

/***********************************************************************
 *     REGION_InsertEdgeInET
 *
 *     Insert the given edge into the edge table.
 *     First we must find the correct bucket in the
 *     Edge table, then find the right slot in the
 *     bucket.  Finally, we can insert it.
 *
 */
static void REGION_InsertEdgeInET(EdgeTable *ET, EdgeTableEntry *ETE,
                INT scanline, ScanLineListBlock **SLLBlock, INT *iSLLBlock)

{
    struct list *ptr;
    ScanLineList *pSLL, *pPrevSLL;
    ScanLineListBlock *tmpSLLBlock;

    /*
     * find the right bucket to put the edge into
     */
    pPrevSLL = &ET->scanlines;
    pSLL = pPrevSLL->next;
    while (pSLL && (pSLL->scanline < scanline))
    {
        pPrevSLL = pSLL;
        pSLL = pSLL->next;
    }

    /*
     * reassign pSLL (pointer to ScanLineList) if necessary
     */
    if ((!pSLL) || (pSLL->scanline > scanline))
    {
        if (*iSLLBlock > SLLSPERBLOCK-1)
        {
            tmpSLLBlock = HeapAlloc( GetProcessHeap(), 0, sizeof(ScanLineListBlock));
	    if(!tmpSLLBlock)
	    {
	        WARN("Can't alloc SLLB\n");
		return;
	    }
            (*SLLBlock)->next = tmpSLLBlock;
            tmpSLLBlock->next = NULL;
            *SLLBlock = tmpSLLBlock;
            *iSLLBlock = 0;
        }
        pSLL = &((*SLLBlock)->SLLs[(*iSLLBlock)++]);

        pSLL->next = pPrevSLL->next;
        list_init( &pSLL->edgelist );
        pPrevSLL->next = pSLL;
    }
    pSLL->scanline = scanline;

    /*
     * now insert the edge in the right bucket
     */
    LIST_FOR_EACH( ptr, &pSLL->edgelist )
    {
        struct edge_table_entry *entry = LIST_ENTRY( ptr, struct edge_table_entry, entry );
        if (entry->bres.minor_axis >= ETE->bres.minor_axis) break;
    }
    list_add_before( ptr, &ETE->entry );
}

/***********************************************************************
 *     REGION_CreateEdgeTable
 *
 *     This routine creates the edge table for
 *     scan converting polygons.
 *     The Edge Table (ET) looks like:
 *
 *    EdgeTable
 *     --------
 *    |  ymax  |        ScanLineLists
 *    |scanline|-->------------>-------------->...
 *     --------   |scanline|   |scanline|
 *                |edgelist|   |edgelist|
 *                ---------    ---------
 *                    |             |
 *                    |             |
 *                    V             V
 *              list of ETEs   list of ETEs
 *
 *     where ETE is an EdgeTableEntry data structure,
 *     and there is one ScanLineList per scanline at
 *     which an edge is initially entered.
 *
 */
static void REGION_CreateEdgeTable(const INT *Count, INT nbpolygons,
            const POINT *pts, EdgeTable *ET,
            EdgeTableEntry *pETEs, ScanLineListBlock *pSLLBlock)
{
    const POINT *top, *bottom;
    const POINT *PrevPt, *CurrPt, *EndPt;
    INT poly, count;
    int iSLLBlock = 0;
    int dy;

    /*
     *  initialize the Edge Table.
     */
    ET->scanlines.next = NULL;
    ET->ymax = SMALL_COORDINATE;
    ET->ymin = LARGE_COORDINATE;
    pSLLBlock->next = NULL;

    EndPt = pts - 1;
    for(poly = 0; poly < nbpolygons; poly++)
    {
        count = Count[poly];
        EndPt += count;
        if(count < 2)
	    continue;

	PrevPt = EndPt;

    /*
     *  for each vertex in the array of points.
     *  In this loop we are dealing with two vertices at
     *  a time -- these make up one edge of the polygon.
     */
	while (count--)
	{
	    CurrPt = pts++;

        /*
         *  find out which point is above and which is below.
         */
	    if (PrevPt->y > CurrPt->y)
	    {
	        bottom = PrevPt, top = CurrPt;
		pETEs->ClockWise = 0;
	    }
	    else
	    {
	        bottom = CurrPt, top = PrevPt;
		pETEs->ClockWise = 1;
	    }

        /*
         * don't add horizontal edges to the Edge table.
         */
	    if (bottom->y != top->y)
	    {
	        pETEs->ymax = bottom->y-1;
				/* -1 so we don't get last scanline */

            /*
             *  initialize integer edge algorithm
             */
		dy = bottom->y - top->y;
		bres_init_polygon(dy, top->x, bottom->x, &pETEs->bres);

		REGION_InsertEdgeInET(ET, pETEs, top->y, &pSLLBlock,
								&iSLLBlock);

		if (PrevPt->y > ET->ymax)
		  ET->ymax = PrevPt->y;
		if (PrevPt->y < ET->ymin)
		  ET->ymin = PrevPt->y;
		pETEs++;
	    }

	    PrevPt = CurrPt;
	}
    }
}

/***********************************************************************
 *     REGION_loadAET
 *
 *     This routine moves EdgeTableEntries from the
 *     EdgeTable into the Active Edge Table,
 *     leaving them sorted by smaller x coordinate.
 *
 */
static void REGION_loadAET( struct list *AET, struct list *ETEs )
{
    struct edge_table_entry *ptr, *next, *entry;
    struct list *active;

    LIST_FOR_EACH_ENTRY_SAFE( ptr, next, ETEs, struct edge_table_entry, entry )
    {
        LIST_FOR_EACH( active, AET )
        {
            entry = LIST_ENTRY( active, struct edge_table_entry, entry );
            if (entry->bres.minor_axis >= ptr->bres.minor_axis) break;
        }
        list_remove( &ptr->entry );
        list_add_before( active, &ptr->entry );
    }
}

/***********************************************************************
 *     REGION_computeWAET
 *
 *     This routine links the AET by the
 *     nextWETE (winding EdgeTableEntry) link for
 *     use by the winding number rule.  The final
 *     Active Edge Table (AET) might look something
 *     like:
 *
 *     AET
 *     ----------  ---------   ---------
 *     |ymax    |  |ymax    |  |ymax    |
 *     | ...    |  |...     |  |...     |
 *     |next    |->|next    |->|next    |->...
 *     |nextWETE|  |nextWETE|  |nextWETE|
 *     ---------   ---------   ^--------
 *         |                   |       |
 *         V------------------->       V---> ...
 *
 */
static void REGION_computeWAET( struct list *AET, struct list *WETE )
{
    struct edge_table_entry *active;
    BOOL inside = TRUE;
    int isInside = 0;

    list_init( WETE );
    LIST_FOR_EACH_ENTRY( active, AET, struct edge_table_entry, entry )
    {
        if (active->ClockWise)
            isInside++;
        else
            isInside--;

        if ((!inside && !isInside) || (inside && isInside))
        {
            list_add_tail( WETE, &active->winding_entry );
            inside = !inside;
        }
    }
}

/***********************************************************************
 *     REGION_InsertionSort
 *
 *     Just a simple insertion sort to sort the Active Edge Table.
 *
 */
static BOOL REGION_InsertionSort( struct list *AET )
{
    struct edge_table_entry *active, *next, *insert;
    BOOL changed = FALSE;

    LIST_FOR_EACH_ENTRY_SAFE( active, next, AET, struct edge_table_entry, entry )
    {
        LIST_FOR_EACH_ENTRY( insert, AET, struct edge_table_entry, entry )
        {
            if (insert == active) break;
            if (insert->bres.minor_axis > active->bres.minor_axis) break;
        }
        if (insert == active) continue;
        list_remove( &active->entry );
        list_add_before( &insert->entry, &active->entry );
        changed = TRUE;
    }
    return changed;
}

/***********************************************************************
 *     REGION_FreeStorage
 *
 *     Clean up our act.
 */
static void REGION_FreeStorage(ScanLineListBlock *pSLLBlock)
{
    ScanLineListBlock   *tmpSLLBlock;

    while (pSLLBlock)
    {
        tmpSLLBlock = pSLLBlock->next;
        HeapFree( GetProcessHeap(), 0, pSLLBlock );
        pSLLBlock = tmpSLLBlock;
    }
}


/***********************************************************************
 *     REGION_PtsToRegion
 *
 *     Create an array of rectangles from a list of points.
 */
static WINEREGION *REGION_PtsToRegion( struct point_block *FirstPtBlock )
{
    POINT *pts;
    struct point_block *pb;
    int i, size, cur_band = 0, prev_band = 0;
    RECT *extents;
    WINEREGION *reg;

    for (pb = FirstPtBlock, size = 0; pb; pb = pb->next) size += pb->count;
    if (!(reg = alloc_region( size ))) return NULL;

    extents = &reg->extents;
    extents->left = LARGE_COORDINATE,  extents->right = SMALL_COORDINATE;

    for (pb = FirstPtBlock; pb; pb = pb->next)
    {
	/* the loop uses 2 points per iteration */
	i = pb->count / 2;
	for (pts = pb->pts; i--; pts += 2) {
	    if (pts->x == pts[1].x)
		continue;

            if (reg->numRects && pts[0].y != reg->rects[cur_band].top)
            {
                prev_band = REGION_Coalesce( reg, prev_band, cur_band );
                cur_band = reg->numRects;
            }

            add_rect( reg, pts[0].x, pts[0].y, pts[1].x, pts[1].y + 1 );
            if (pts[0].x < extents->left)
                extents->left = pts[0].x;
            if (pts[1].x > extents->right)
                extents->right = pts[1].x;
        }
    }

    if (reg->numRects) {
        REGION_Coalesce( reg, prev_band, cur_band );
        extents->top = reg->rects[0].top;
        extents->bottom = reg->rects[reg->numRects-1].bottom;
    } else {
	extents->left = 0;
	extents->top = 0;
	extents->right = 0;
	extents->bottom = 0;
    }
    REGION_compact( reg );

    return reg;
}

/* Number of points in the first point buffer.  Must be an even number. */
#define NUMPTSTOBUFFER 200

/***********************************************************************
 *           CreatePolyPolygonRgn    (GDI32.@)
 */
HRGN WINAPI CreatePolyPolygonRgn(const POINT *Pts, const INT *Count,
		      INT nbpolygons, INT mode)
{
    HRGN hrgn = 0;
    WINEREGION *obj;
    INT y;                           /* current scanline        */
    struct list WETE, *pWETE;        /* Winding Edge Table */
    ScanLineList *pSLL;              /* current scanLineList    */
    EdgeTable ET;                    /* header node for ET      */
    struct list AET;                 /* header for AET     */
    EdgeTableEntry *pETEs;           /* EdgeTableEntries pool   */
    ScanLineListBlock SLLBlock;      /* header for scanlinelist */
    BOOL fixWAET = FALSE;
    char first_blk_buf[FIELD_OFFSET( struct point_block, pts[NUMPTSTOBUFFER] )];
    struct point_block *first_block = (struct point_block *)first_blk_buf, *block;
    struct edge_table_entry *active, *next;
    INT poly, total;

    TRACE("%p, count %d, polygons %d, mode %d\n", Pts, *Count, nbpolygons, mode);

    /* special case a rectangle */

    if (((nbpolygons == 1) && ((*Count == 4) ||
       ((*Count == 5) && (Pts[4].x == Pts[0].x) && (Pts[4].y == Pts[0].y)))) &&
	(((Pts[0].y == Pts[1].y) &&
	  (Pts[1].x == Pts[2].x) &&
	  (Pts[2].y == Pts[3].y) &&
	  (Pts[3].x == Pts[0].x)) ||
	 ((Pts[0].x == Pts[1].x) &&
	  (Pts[1].y == Pts[2].y) &&
	  (Pts[2].x == Pts[3].x) &&
	  (Pts[3].y == Pts[0].y))))
        return CreateRectRgn( min(Pts[0].x, Pts[2].x), min(Pts[0].y, Pts[2].y),
                              max(Pts[0].x, Pts[2].x), max(Pts[0].y, Pts[2].y) );

    for(poly = total = 0; poly < nbpolygons; poly++)
        total += Count[poly];
    if (! (pETEs = HeapAlloc( GetProcessHeap(), 0, sizeof(EdgeTableEntry) * total )))
	return 0;

    REGION_CreateEdgeTable(Count, nbpolygons, Pts, &ET, pETEs, &SLLBlock);
    list_init( &AET );
    pSLL = ET.scanlines.next;
    block = first_block;
    first_block->count = 0;
    first_block->size  = NUMPTSTOBUFFER;
    first_block->next  = NULL;

    if (mode != WINDING) {
        /*
         *  for each scanline
         */
        for (y = ET.ymin; y < ET.ymax; y++) {
            /*
             *  Add a new edge to the active edge table when we
             *  get to the next edge.
             */
            if (pSLL != NULL && y == pSLL->scanline) {
                REGION_loadAET(&AET, &pSLL->edgelist);
                pSLL = pSLL->next;
            }

            LIST_FOR_EACH_ENTRY_SAFE( active, next, &AET, struct edge_table_entry, entry )
            {
                block = add_point( block, active->bres.minor_axis, y );
                if (!block) goto done;

                if (active->ymax == y)  /* leaving this edge */
                    list_remove( &active->entry );
                else
                    bres_incr_polygon( &active->bres );
            }
            REGION_InsertionSort(&AET);
        }
    }
    else {
        /*
         *  for each scanline
         */
        for (y = ET.ymin; y < ET.ymax; y++) {
            /*
             *  Add a new edge to the active edge table when we
             *  get to the next edge.
             */
            if (pSLL != NULL && y == pSLL->scanline) {
                REGION_loadAET(&AET, &pSLL->edgelist);
                REGION_computeWAET( &AET, &WETE );
                pSLL = pSLL->next;
            }
            pWETE = list_head( &WETE );

            /*
             *  for each active edge
             */
            LIST_FOR_EACH_ENTRY_SAFE( active, next, &AET, struct edge_table_entry, entry )
            {
                /*
                 *  add to the buffer only those edges that
                 *  are in the Winding active edge table.
                 */
                if (pWETE == &active->winding_entry) {
                    block = add_point( block, active->bres.minor_axis, y );
                    if (!block) goto done;
                    pWETE = list_next( &WETE, pWETE );
                }
                if (active->ymax == y)  /* leaving this edge */
                {
                    list_remove( &active->entry );
                    fixWAET = TRUE;
                }
                else
                    bres_incr_polygon( &active->bres );
            }

            /*
             *  recompute the winding active edge table if
             *  we just resorted or have exited an edge.
             */
            if (REGION_InsertionSort(&AET) || fixWAET) {
                REGION_computeWAET( &AET, &WETE );
                fixWAET = FALSE;
            }
        }
    }

    if (!(obj = REGION_PtsToRegion( first_block ))) goto done;
    if (!(hrgn = alloc_gdi_handle( obj, OBJ_REGION, &region_funcs )))
        free_region( obj );

done:
    REGION_FreeStorage(SLLBlock.next);
    free_point_blocks( first_block->next );
    HeapFree( GetProcessHeap(), 0, pETEs );
    return hrgn;
}


/***********************************************************************
 *           CreatePolygonRgn    (GDI32.@)
 */
HRGN WINAPI CreatePolygonRgn( const POINT *points, INT count,
                                  INT mode )
{
    return CreatePolyPolygonRgn( points, &count, 1, mode );
}
