OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [MW_0_8_9PRE7/] [mw/] [src/] [mwin/] [winrgn.c] - Diff between revs 674 and 1765

Only display areas with differences | Details | Blame | View Log

Rev 674 Rev 1765
/*
/*
 * Portions Copyright (c) 1999, 2000 Greg Haerr <greg@censoft.com>
 * Portions Copyright (c) 1999, 2000 Greg Haerr <greg@censoft.com>
 *      Somewhat less shamelessly ripped from the Wine distribution
 *      Somewhat less shamelessly ripped from the Wine distribution
 *
 *
 * Win32 API Region Management Routines.
 * Win32 API Region Management Routines.
 * Win32 API Complex Rectangle Routines.
 * Win32 API Complex Rectangle Routines.
 *
 *
 * GDI region objects. Shamelessly ripped out from the X11 distribution
 * GDI region objects. Shamelessly ripped out from the X11 distribution
 * Thanks for the nice licence.
 * Thanks for the nice licence.
 *
 *
 * Copyright 1993, 1994, 1995 Alexandre Julliard
 * Copyright 1993, 1994, 1995 Alexandre Julliard
 * Modifications and additions: Copyright 1998 Huw Davies
 * Modifications and additions: Copyright 1998 Huw Davies
 */
 */
#include "windows.h"
#include "windows.h"
#include "device.h"
#include "device.h"
#include <stdlib.h>
#include <stdlib.h>
#include <string.h>
#include <string.h>
 
 
/* later, error checking can be built into this get*/
/* later, error checking can be built into this get*/
#define GDI_GetObjPtr(hrgn,type)        (hrgn)
#define GDI_GetObjPtr(hrgn,type)        (hrgn)
 
 
/* local functions*/
/* local functions*/
static HRGN REGION_CreateRegion(void);
static HRGN REGION_CreateRegion(void);
/*BOOL REGION_UnionRectWithRgn( HRGN hrgn, const RECT *lpRect );*/
/*BOOL REGION_UnionRectWithRgn( HRGN hrgn, const RECT *lpRect );*/
/*BOOL REGION_FrameRgn( HRGN hDest, HRGN hSrc, INT x, INT y );*/
/*BOOL REGION_FrameRgn( HRGN hDest, HRGN hSrc, INT x, INT y );*/
 
 
#define EMPTY_REGION(pReg) { \
#define EMPTY_REGION(pReg) { \
    (pReg)->numRects = 0; \
    (pReg)->numRects = 0; \
    (pReg)->extents.left = (pReg)->extents.top = 0; \
    (pReg)->extents.left = (pReg)->extents.top = 0; \
    (pReg)->extents.right = (pReg)->extents.bottom = 0; \
    (pReg)->extents.right = (pReg)->extents.bottom = 0; \
    (pReg)->type = NULLREGION; \
    (pReg)->type = NULLREGION; \
 }
 }
 
 
/*
/*
 *          Create a new empty region.
 *          Create a new empty region.
 */
 */
static HRGN
static HRGN
REGION_CreateRegion(void)
REGION_CreateRegion(void)
{
{
    MWRGNOBJ *obj;
    MWRGNOBJ *obj;
 
 
    obj = GdItemNew(MWRGNOBJ);
    obj = GdItemNew(MWRGNOBJ);
    if(!obj)
    if(!obj)
        return NULL;
        return NULL;
    obj->hdr.type = OBJ_REGION;
    obj->hdr.type = OBJ_REGION;
    obj->hdr.stockobj = FALSE;
    obj->hdr.stockobj = FALSE;
    if(!(obj->rgn = GdAllocRegion())) {
    if(!(obj->rgn = GdAllocRegion())) {
        GdItemFree(obj);
        GdItemFree(obj);
        return NULL;
        return NULL;
    }
    }
    return (HRGN)obj;
    return (HRGN)obj;
}
}
 
 
 
 
INT WINAPI
INT WINAPI
OffsetRgn( HRGN hrgn, INT x, INT y )
OffsetRgn( HRGN hrgn, INT x, INT y )
{
{
    MWRGNOBJ * obj = (MWRGNOBJ *) GDI_GetObjPtr( hrgn, OBJ_REGION );
    MWRGNOBJ * obj = (MWRGNOBJ *) GDI_GetObjPtr( hrgn, OBJ_REGION );
 
 
    if (obj)
    if (obj)
    {
    {
        GdOffsetRegion(obj->rgn, x, y);
        GdOffsetRegion(obj->rgn, x, y);
        return obj->rgn->type;
        return obj->rgn->type;
    }
    }
    return ERRORREGION;
    return ERRORREGION;
}
}
 
 
 
 
INT WINAPI
INT WINAPI
GetRgnBox( HRGN hrgn, LPRECT rect )
GetRgnBox( HRGN hrgn, LPRECT rect )
{
{
    MWRGNOBJ * obj = (MWRGNOBJ *) GDI_GetObjPtr( hrgn, OBJ_REGION );
    MWRGNOBJ * obj = (MWRGNOBJ *) GDI_GetObjPtr( hrgn, OBJ_REGION );
    if (obj)
    if (obj)
        return GdGetRegionBox(obj->rgn, rect);
        return GdGetRegionBox(obj->rgn, rect);
    return ERRORREGION;
    return ERRORREGION;
}
}
 
 
 
 
HRGN WINAPI
HRGN WINAPI
CreateRectRgn(INT left, INT top, INT right, INT bottom)
CreateRectRgn(INT left, INT top, INT right, INT bottom)
{
{
    HRGN hrgn;
    HRGN hrgn;
 
 
    if (!(hrgn = REGION_CreateRegion()))
    if (!(hrgn = REGION_CreateRegion()))
        return 0;
        return 0;
    /*TRACE(region, "\n");*/
    /*TRACE(region, "\n");*/
    SetRectRgn(hrgn, left, top, right, bottom);
    SetRectRgn(hrgn, left, top, right, bottom);
    return hrgn;
    return hrgn;
}
}
 
 
 
 
HRGN WINAPI
HRGN WINAPI
CreateRectRgnIndirect( const RECT* rect )
CreateRectRgnIndirect( const RECT* rect )
{
{
    return CreateRectRgn( rect->left, rect->top, rect->right, rect->bottom );
    return CreateRectRgn( rect->left, rect->top, rect->right, rect->bottom );
}
}
 
 
 
 
/*
/*
 * Allows either or both left and top to be greater than right or bottom.
 * Allows either or both left and top to be greater than right or bottom.
 */
 */
VOID WINAPI
VOID WINAPI
SetRectRgn( HRGN hrgn, INT left, INT top, INT right, INT bottom )
SetRectRgn( HRGN hrgn, INT left, INT top, INT right, INT bottom )
{
{
    MWRGNOBJ * obj;
    MWRGNOBJ * obj;
    MWCLIPREGION *rgn;
    MWCLIPREGION *rgn;
 
 
    /*TRACE(region, " %04x %d,%d-%d,%d\n", hrgn, left, top, right, bottom );*/
    /*TRACE(region, " %04x %d,%d-%d,%d\n", hrgn, left, top, right, bottom );*/
 
 
    if (!(obj = (MWRGNOBJ *) GDI_GetObjPtr( hrgn, OBJ_REGION ))) return;
    if (!(obj = (MWRGNOBJ *) GDI_GetObjPtr( hrgn, OBJ_REGION ))) return;
 
 
    if (left > right) { INT tmp = left; left = right; right = tmp; }
    if (left > right) { INT tmp = left; left = right; right = tmp; }
    if (top > bottom) { INT tmp = top; top = bottom; bottom = tmp; }
    if (top > bottom) { INT tmp = top; top = bottom; bottom = tmp; }
 
 
    rgn = obj->rgn;
    rgn = obj->rgn;
    GdSetRectRegion(rgn, left, top, right, bottom);
    GdSetRectRegion(rgn, left, top, right, bottom);
}
}
 
 
 
 
HRGN WINAPI
HRGN WINAPI
CreateRoundRectRgn( INT left, INT top, INT right, INT bottom,
CreateRoundRectRgn( INT left, INT top, INT right, INT bottom,
        INT ellipse_width, INT ellipse_height )
        INT ellipse_width, INT ellipse_height )
{
{
    MWRGNOBJ * obj;
    MWRGNOBJ * obj;
    HRGN hrgn;
    HRGN hrgn;
    int asq, bsq, d, xd, yd;
    int asq, bsq, d, xd, yd;
    RECT rect;
    RECT rect;
 
 
    /* Check if we can do a normal rectangle instead */
    /* Check if we can do a normal rectangle instead */
    if (ellipse_width == 0 || ellipse_height == 0)
    if (ellipse_width == 0 || ellipse_height == 0)
        return CreateRectRgn( left, top, right, bottom );
        return CreateRectRgn( left, top, right, bottom );
 
 
    /* Make the dimensions sensible */
    /* Make the dimensions sensible */
    if (left > right) { INT tmp = left; left = right; right = tmp; }
    if (left > right) { INT tmp = left; left = right; right = tmp; }
    if (top > bottom) { INT tmp = top; top = bottom; bottom = tmp; }
    if (top > bottom) { INT tmp = top; top = bottom; bottom = tmp; }
 
 
    ellipse_width = abs(ellipse_width);
    ellipse_width = abs(ellipse_width);
    ellipse_height = abs(ellipse_height);
    ellipse_height = abs(ellipse_height);
 
 
    /* Create region */
    /* Create region */
 
 
    if (!(hrgn = REGION_CreateRegion()))
    if (!(hrgn = REGION_CreateRegion()))
            return 0;
            return 0;
    obj = (MWRGNOBJ *)hrgn;
    obj = (MWRGNOBJ *)hrgn;
    /*TRACE(region,"(%d,%d-%d,%d %dx%d): ret=%04x\n",
    /*TRACE(region,"(%d,%d-%d,%d %dx%d): ret=%04x\n",
               left, top, right, bottom, ellipse_width, ellipse_height, hrgn);*/
               left, top, right, bottom, ellipse_width, ellipse_height, hrgn);*/
 
 
    /* Check parameters */
    /* Check parameters */
 
 
    if (ellipse_width > right-left) ellipse_width = right-left;
    if (ellipse_width > right-left) ellipse_width = right-left;
    if (ellipse_height > bottom-top) ellipse_height = bottom-top;
    if (ellipse_height > bottom-top) ellipse_height = bottom-top;
 
 
    /* Ellipse algorithm, based on an article by K. Porter */
    /* Ellipse algorithm, based on an article by K. Porter */
    /* in DDJ Graphics Programming Column, 8/89 */
    /* in DDJ Graphics Programming Column, 8/89 */
 
 
    asq = ellipse_width * ellipse_width / 4;        /* a^2 */
    asq = ellipse_width * ellipse_width / 4;        /* a^2 */
    bsq = ellipse_height * ellipse_height / 4;      /* b^2 */
    bsq = ellipse_height * ellipse_height / 4;      /* b^2 */
    if (asq == 0) asq = 1;
    if (asq == 0) asq = 1;
    if (bsq == 0) bsq = 1;
    if (bsq == 0) bsq = 1;
    d = bsq - asq * ellipse_height / 2 + asq / 4;   /* b^2 - a^2b + a^2/4 */
    d = bsq - asq * ellipse_height / 2 + asq / 4;   /* b^2 - a^2b + a^2/4 */
    xd = 0;
    xd = 0;
    yd = asq * ellipse_height;                      /* 2a^2b */
    yd = asq * ellipse_height;                      /* 2a^2b */
 
 
    rect.left   = left + ellipse_width / 2;
    rect.left   = left + ellipse_width / 2;
    rect.right  = right - ellipse_width / 2;
    rect.right  = right - ellipse_width / 2;
 
 
    /* Loop to draw first half of quadrant */
    /* Loop to draw first half of quadrant */
 
 
    while (xd < yd)
    while (xd < yd)
    {
    {
        if (d > 0)  /* if nearest pixel is toward the center */
        if (d > 0)  /* if nearest pixel is toward the center */
        {
        {
              /* move toward center */
              /* move toward center */
            rect.top = top++;
            rect.top = top++;
            rect.bottom = rect.top + 1;
            rect.bottom = rect.top + 1;
            GdUnionRectWithRegion( &rect, obj->rgn );
            GdUnionRectWithRegion( &rect, obj->rgn );
            rect.top = --bottom;
            rect.top = --bottom;
            rect.bottom = rect.top + 1;
            rect.bottom = rect.top + 1;
            GdUnionRectWithRegion( &rect, obj->rgn );
            GdUnionRectWithRegion( &rect, obj->rgn );
            yd -= 2*asq;
            yd -= 2*asq;
            d  -= yd;
            d  -= yd;
        }
        }
        rect.left--;        /* next horiz point */
        rect.left--;        /* next horiz point */
        rect.right++;
        rect.right++;
        xd += 2*bsq;
        xd += 2*bsq;
        d  += bsq + xd;
        d  += bsq + xd;
    }
    }
 
 
    /* Loop to draw second half of quadrant */
    /* Loop to draw second half of quadrant */
 
 
    d += (3 * (asq-bsq) / 2 - (xd+yd)) / 2;
    d += (3 * (asq-bsq) / 2 - (xd+yd)) / 2;
    while (yd >= 0)
    while (yd >= 0)
    {
    {
          /* next vertical point */
          /* next vertical point */
        rect.top = top++;
        rect.top = top++;
        rect.bottom = rect.top + 1;
        rect.bottom = rect.top + 1;
        GdUnionRectWithRegion( &rect, obj->rgn );
        GdUnionRectWithRegion( &rect, obj->rgn );
        rect.top = --bottom;
        rect.top = --bottom;
        rect.bottom = rect.top + 1;
        rect.bottom = rect.top + 1;
        GdUnionRectWithRegion( &rect, obj->rgn );
        GdUnionRectWithRegion( &rect, obj->rgn );
        if (d < 0)   /* if nearest pixel is outside ellipse */
        if (d < 0)   /* if nearest pixel is outside ellipse */
        {
        {
            rect.left--;     /* move away from center */
            rect.left--;     /* move away from center */
            rect.right++;
            rect.right++;
            xd += 2*bsq;
            xd += 2*bsq;
            d  += xd;
            d  += xd;
        }
        }
        yd -= 2*asq;
        yd -= 2*asq;
        d  += asq - yd;
        d  += asq - yd;
    }
    }
 
 
    /* Add the inside rectangle */
    /* Add the inside rectangle */
 
 
    if (top <= bottom)
    if (top <= bottom)
    {
    {
        rect.top = top;
        rect.top = top;
        rect.bottom = bottom;
        rect.bottom = bottom;
        GdUnionRectWithRegion( &rect, obj->rgn );
        GdUnionRectWithRegion( &rect, obj->rgn );
    }
    }
    obj->rgn->type = SIMPLEREGION; /* FIXME? */
    obj->rgn->type = SIMPLEREGION; /* FIXME? */
    return hrgn;
    return hrgn;
}
}
 
 
 
 
HRGN WINAPI
HRGN WINAPI
CreateEllipticRgn( INT left, INT top, INT right, INT bottom )
CreateEllipticRgn( INT left, INT top, INT right, INT bottom )
{
{
    return CreateRoundRectRgn(left, top, right, bottom, right-left, bottom-top);
    return CreateRoundRectRgn(left, top, right, bottom, right-left, bottom-top);
}
}
 
 
 
 
HRGN WINAPI
HRGN WINAPI
CreateEllipticRgnIndirect( const RECT *rect )
CreateEllipticRgnIndirect( const RECT *rect )
{
{
    return CreateRoundRectRgn( rect->left, rect->top, rect->right,
    return CreateRoundRectRgn( rect->left, rect->top, rect->right,
                                 rect->bottom, rect->right - rect->left,
                                 rect->bottom, rect->right - rect->left,
                                 rect->bottom - rect->top );
                                 rect->bottom - rect->top );
}
}
 
 
HRGN WINAPI
HRGN WINAPI
CreatePolygonRgn(const POINT *points, INT count, INT mode)
CreatePolygonRgn(const POINT *points, INT count, INT mode)
{
{
#if POLYREGIONS
#if POLYREGIONS
        HRGN            hrgn;
        HRGN            hrgn;
        MWRGNOBJ *      obj;
        MWRGNOBJ *      obj;
        MWCLIPREGION *  rgn;
        MWCLIPREGION *  rgn;
 
 
        if (!(hrgn = REGION_CreateRegion()))
        if (!(hrgn = REGION_CreateRegion()))
                return NULL;
                return NULL;
        obj = (MWRGNOBJ *)GDI_GetObjPtr(hrgn, OBJ_REGION);
        obj = (MWRGNOBJ *)GDI_GetObjPtr(hrgn, OBJ_REGION);
        if (!obj)
        if (!obj)
                return NULL;
                return NULL;
 
 
        rgn = GdAllocPolygonRegion((POINT *)points, count, mode);
        rgn = GdAllocPolygonRegion((POINT *)points, count, mode);
        if (!rgn)
        if (!rgn)
                return hrgn;
                return hrgn;
        GdDestroyRegion(obj->rgn);
        GdDestroyRegion(obj->rgn);
        obj->rgn = rgn;
        obj->rgn = rgn;
        return hrgn;
        return hrgn;
#endif
#endif
}
}
 
 
DWORD WINAPI
DWORD WINAPI
GetRegionData(HRGN hrgn, DWORD count, LPRGNDATA rgndata)
GetRegionData(HRGN hrgn, DWORD count, LPRGNDATA rgndata)
{
{
    DWORD size;
    DWORD size;
    MWRGNOBJ *obj = (MWRGNOBJ *) GDI_GetObjPtr( hrgn, OBJ_REGION );
    MWRGNOBJ *obj = (MWRGNOBJ *) GDI_GetObjPtr( hrgn, OBJ_REGION );
    MWCLIPREGION *rgn;
    MWCLIPREGION *rgn;
 
 
    /*TRACE(region," %04x count = %ld, rgndata = %p\n", hrgn, count, rgndata);*/
    /*TRACE(region," %04x count = %ld, rgndata = %p\n", hrgn, count, rgndata);*/
 
 
    if(!obj) return 0;
    if(!obj) return 0;
 
 
    rgn = obj->rgn;
    rgn = obj->rgn;
    size = rgn->numRects * sizeof(RECT);
    size = rgn->numRects * sizeof(RECT);
    if(count < (size + sizeof(RGNDATAHEADER)) || rgndata == NULL)
    if(count < (size + sizeof(RGNDATAHEADER)) || rgndata == NULL)
        return size + sizeof(RGNDATAHEADER);
        return size + sizeof(RGNDATAHEADER);
 
 
    rgndata->rdh.dwSize = sizeof(RGNDATAHEADER);
    rgndata->rdh.dwSize = sizeof(RGNDATAHEADER);
    rgndata->rdh.iType = RDH_RECTANGLES;
    rgndata->rdh.iType = RDH_RECTANGLES;
    rgndata->rdh.nCount = rgn->numRects;
    rgndata->rdh.nCount = rgn->numRects;
    rgndata->rdh.nRgnSize = size;
    rgndata->rdh.nRgnSize = size;
    rgndata->rdh.rcBound.left = rgn->extents.left;
    rgndata->rdh.rcBound.left = rgn->extents.left;
    rgndata->rdh.rcBound.top = rgn->extents.top;
    rgndata->rdh.rcBound.top = rgn->extents.top;
    rgndata->rdh.rcBound.right = rgn->extents.right;
    rgndata->rdh.rcBound.right = rgn->extents.right;
    rgndata->rdh.rcBound.bottom = rgn->extents.bottom;
    rgndata->rdh.rcBound.bottom = rgn->extents.bottom;
 
 
    memcpy( rgndata->Buffer, rgn->rects, size );
    memcpy( rgndata->Buffer, rgn->rects, size );
 
 
    return 1;
    return 1;
}
}
 
 
 
 
#if 0
#if 0
HRGN WINAPI
HRGN WINAPI
ExtCreateRegion(const XFORM* lpXform, DWORD dwCount, const RGNDATA* rgndata)
ExtCreateRegion(const XFORM* lpXform, DWORD dwCount, const RGNDATA* rgndata)
{
{
    HRGN hrgn = CreateRectRgn(0, 0, 0, 0);
    HRGN hrgn = CreateRectRgn(0, 0, 0, 0);
    MWRGNOBJ *obj = (MWRGNOBJ *) GDI_GetObjPtr( hrgn, OBJ_REGION );
    MWRGNOBJ *obj = (MWRGNOBJ *) GDI_GetObjPtr( hrgn, OBJ_REGION );
    RECT *pCurRect, *pEndRect;
    RECT *pCurRect, *pEndRect;
 
 
    /*TRACE(region, " %p %ld %p. Returning %04x\n",
    /*TRACE(region, " %p %ld %p. Returning %04x\n",
                lpXform, dwCount, rgndata, hrgn);*/
                lpXform, dwCount, rgndata, hrgn);*/
    if(!hrgn)
    if(!hrgn)
    {
    {
        WARN(region, "Can't create a region!\n");
        WARN(region, "Can't create a region!\n");
        return 0;
        return 0;
    }
    }
    if(lpXform)
    if(lpXform)
        WARN(region, "Xform not implemented - ignoring\n");
        WARN(region, "Xform not implemented - ignoring\n");
 
 
    if(rgndata->rdh.iType != RDH_RECTANGLES)
    if(rgndata->rdh.iType != RDH_RECTANGLES)
    {
    {
        WARN(region, "Type not RDH_RECTANGLES\n");
        WARN(region, "Type not RDH_RECTANGLES\n");
        DeleteObject( hrgn );
        DeleteObject( hrgn );
        return 0;
        return 0;
    }
    }
 
 
    pEndRect = (RECT *)rgndata->Buffer + rgndata->rdh.nCount;
    pEndRect = (RECT *)rgndata->Buffer + rgndata->rdh.nCount;
    for(pCurRect = (RECT *)rgndata->Buffer; pCurRect < pEndRect; pCurRect++)
    for(pCurRect = (RECT *)rgndata->Buffer; pCurRect < pEndRect; pCurRect++)
        GdUnionRectWithRegion( pCurRect, obj->rgn );
        GdUnionRectWithRegion( pCurRect, obj->rgn );
 
 
    return hrgn;
    return hrgn;
}
}
#endif
#endif
 
 
 
 
BOOL WINAPI
BOOL WINAPI
PtInRegion( HRGN hrgn, INT x, INT y )
PtInRegion( HRGN hrgn, INT x, INT y )
{
{
    MWRGNOBJ * obj;
    MWRGNOBJ * obj;
 
 
    obj = (MWRGNOBJ *) GDI_GetObjPtr( hrgn, OBJ_REGION );
    obj = (MWRGNOBJ *) GDI_GetObjPtr( hrgn, OBJ_REGION );
    if(!obj)
    if(!obj)
            return FALSE;
            return FALSE;
    return GdPtInRegion(obj->rgn, x, y);
    return GdPtInRegion(obj->rgn, x, y);
}
}
 
 
/*
/*
 * Returns TRUE if rect is at least partly inside hrgn
 * Returns TRUE if rect is at least partly inside hrgn
 */
 */
BOOL WINAPI
BOOL WINAPI
RectInRegion( HRGN hrgn, const RECT *rect )
RectInRegion( HRGN hrgn, const RECT *rect )
{
{
    MWRGNOBJ * obj;
    MWRGNOBJ * obj;
 
 
    obj = (MWRGNOBJ *) GDI_GetObjPtr( hrgn, OBJ_REGION );
    obj = (MWRGNOBJ *) GDI_GetObjPtr( hrgn, OBJ_REGION );
    if(!obj)
    if(!obj)
            return FALSE;
            return FALSE;
    return (GdRectInRegion(obj->rgn, rect) == MWRECT_OUT? FALSE: TRUE);
    return (GdRectInRegion(obj->rgn, rect) == MWRECT_OUT? FALSE: TRUE);
}
}
 
 
BOOL WINAPI
BOOL WINAPI
EqualRgn( HRGN hrgn1, HRGN hrgn2 )
EqualRgn( HRGN hrgn1, HRGN hrgn2 )
{
{
    MWRGNOBJ *obj1, *obj2;
    MWRGNOBJ *obj1, *obj2;
 
 
    if ((obj1 = (MWRGNOBJ *) GDI_GetObjPtr( hrgn1, OBJ_REGION )))
    if ((obj1 = (MWRGNOBJ *) GDI_GetObjPtr( hrgn1, OBJ_REGION )))
        if ((obj2 = (MWRGNOBJ *) GDI_GetObjPtr( hrgn2, OBJ_REGION )))
        if ((obj2 = (MWRGNOBJ *) GDI_GetObjPtr( hrgn2, OBJ_REGION )))
            return GdEqualRegion(obj1->rgn, obj2->rgn);
            return GdEqualRegion(obj1->rgn, obj2->rgn);
    return FALSE;
    return FALSE;
}
}
 
 
#if 0
#if 0
/*
/*
 *           REGION_UnionRectWithRgn
 *           REGION_UnionRectWithRgn
 *           Adds a rectangle to a HRGN
 *           Adds a rectangle to a HRGN
 *           A helper used by scroll.c
 *           A helper used by scroll.c
 */
 */
BOOL
BOOL
REGION_UnionRectWithRgn( HRGN hrgn, const RECT *lpRect )
REGION_UnionRectWithRgn( HRGN hrgn, const RECT *lpRect )
{
{
    MWRGNOBJ *obj = (MWRGNOBJ *)hrgn;
    MWRGNOBJ *obj = (MWRGNOBJ *)hrgn;
 
 
    if(!obj) return FALSE;
    if(!obj) return FALSE;
    GdUnionRectWithRegion( lpRect, obj->rgn );
    GdUnionRectWithRegion( lpRect, obj->rgn );
    return TRUE;
    return TRUE;
}
}
 
 
/*
/*
 *           REGION_FrameRgn
 *           REGION_FrameRgn
 * Create a region that is a frame around another region.
 * Create a region that is a frame around another region.
 * Expand all rectangles by +/- x and y, then subtract original region.
 * Expand all rectangles by +/- x and y, then subtract original region.
 */
 */
BOOL
BOOL
REGION_FrameRgn( HRGN hDest, HRGN hSrc, INT x, INT y )
REGION_FrameRgn( HRGN hDest, HRGN hSrc, INT x, INT y )
{
{
    BOOL bRet;
    BOOL bRet;
    MWRGNOBJ *srcObj = (MWRGNOBJ*) GDI_GetObjPtr( hSrc, OBJ_REGION );
    MWRGNOBJ *srcObj = (MWRGNOBJ*) GDI_GetObjPtr( hSrc, OBJ_REGION );
 
 
    if (srcObj->rgn->numRects != 0)
    if (srcObj->rgn->numRects != 0)
    {
    {
        MWRGNOBJ* destObj = (MWRGNOBJ*) GDI_GetObjPtr( hDest, OBJ_REGION );
        MWRGNOBJ* destObj = (MWRGNOBJ*) GDI_GetObjPtr( hDest, OBJ_REGION );
        RECT *pRect, *pEndRect;
        RECT *pRect, *pEndRect;
        RECT tempRect;
        RECT tempRect;
 
 
        EMPTY_REGION( destObj->rgn );
        EMPTY_REGION( destObj->rgn );
 
 
        pEndRect = srcObj->rgn->rects + srcObj->rgn->numRects;
        pEndRect = srcObj->rgn->rects + srcObj->rgn->numRects;
        for(pRect = srcObj->rgn->rects; pRect < pEndRect; pRect++)
        for(pRect = srcObj->rgn->rects; pRect < pEndRect; pRect++)
        {
        {
            tempRect.left = pRect->left - x;
            tempRect.left = pRect->left - x;
            tempRect.top = pRect->top - y;
            tempRect.top = pRect->top - y;
            tempRect.right = pRect->right + x;
            tempRect.right = pRect->right + x;
            tempRect.bottom = pRect->bottom + y;
            tempRect.bottom = pRect->bottom + y;
            GdUnionRectWithRegion( &tempRect, destObj->rgn );
            GdUnionRectWithRegion( &tempRect, destObj->rgn );
        }
        }
        GdSubtractRegion( destObj->rgn, destObj->rgn, srcObj->rgn );
        GdSubtractRegion( destObj->rgn, destObj->rgn, srcObj->rgn );
        bRet = TRUE;
        bRet = TRUE;
    }
    }
    else
    else
        bRet = FALSE;
        bRet = FALSE;
    return bRet;
    return bRet;
}
}
#endif
#endif
 
 
/*
/*
 * Note: The behavior is correct even if src and dest regions are the same.
 * Note: The behavior is correct even if src and dest regions are the same.
 */
 */
INT WINAPI
INT WINAPI
CombineRgn(HRGN hDest, HRGN hSrc1, HRGN hSrc2, INT mode)
CombineRgn(HRGN hDest, HRGN hSrc1, HRGN hSrc2, INT mode)
{
{
    MWRGNOBJ *destObj = (MWRGNOBJ *) GDI_GetObjPtr( hDest, OBJ_REGION);
    MWRGNOBJ *destObj = (MWRGNOBJ *) GDI_GetObjPtr( hDest, OBJ_REGION);
    INT result = ERRORREGION;
    INT result = ERRORREGION;
 
 
    /*TRACE(region, " %04x,%04x -> %04x mode=%x\n", hSrc1, hSrc2, hDest,mode);*/
    /*TRACE(region, " %04x,%04x -> %04x mode=%x\n", hSrc1, hSrc2, hDest,mode);*/
 
 
    if (destObj)
    if (destObj)
    {
    {
        MWRGNOBJ *src1Obj = (MWRGNOBJ *) GDI_GetObjPtr( hSrc1, OBJ_REGION);
        MWRGNOBJ *src1Obj = (MWRGNOBJ *) GDI_GetObjPtr( hSrc1, OBJ_REGION);
 
 
        if (src1Obj)
        if (src1Obj)
        {
        {
            /*TRACE(region, "dump:\n");
            /*TRACE(region, "dump:\n");
            if(TRACE_ON(region))
            if(TRACE_ON(region))
                REGION_DumpRegion(src1Obj->rgn);*/
                REGION_DumpRegion(src1Obj->rgn);*/
            if (mode == RGN_COPY)
            if (mode == RGN_COPY)
            {
            {
                GdCopyRegion( destObj->rgn, src1Obj->rgn );
                GdCopyRegion( destObj->rgn, src1Obj->rgn );
                result = destObj->rgn->type;
                result = destObj->rgn->type;
            }
            }
            else
            else
            {
            {
                MWRGNOBJ *src2Obj = (MWRGNOBJ *) GDI_GetObjPtr( hSrc2, OBJ_REGION);
                MWRGNOBJ *src2Obj = (MWRGNOBJ *) GDI_GetObjPtr( hSrc2, OBJ_REGION);
 
 
                if (src2Obj)
                if (src2Obj)
                {
                {
                    /*TRACE(region, "dump:\n");
                    /*TRACE(region, "dump:\n");
                    if(TRACE_ON(region))
                    if(TRACE_ON(region))
                        REGION_DumpRegion(src2Obj->rgn);*/
                        REGION_DumpRegion(src2Obj->rgn);*/
                    switch (mode)
                    switch (mode)
                    {
                    {
                    case RGN_AND:
                    case RGN_AND:
                        GdIntersectRegion( destObj->rgn, src1Obj->rgn, src2Obj->rgn);
                        GdIntersectRegion( destObj->rgn, src1Obj->rgn, src2Obj->rgn);
                        break;
                        break;
                    case RGN_OR:
                    case RGN_OR:
                        GdUnionRegion( destObj->rgn, src1Obj->rgn, src2Obj->rgn );
                        GdUnionRegion( destObj->rgn, src1Obj->rgn, src2Obj->rgn );
                        break;
                        break;
                    case RGN_XOR:
                    case RGN_XOR:
                        GdXorRegion( destObj->rgn, src1Obj->rgn, src2Obj->rgn );
                        GdXorRegion( destObj->rgn, src1Obj->rgn, src2Obj->rgn );
                        break;
                        break;
                    case RGN_DIFF:
                    case RGN_DIFF:
                        GdSubtractRegion( destObj->rgn, src1Obj->rgn, src2Obj->rgn );
                        GdSubtractRegion( destObj->rgn, src1Obj->rgn, src2Obj->rgn );
                        break;
                        break;
                    }
                    }
                    result = destObj->rgn->type;
                    result = destObj->rgn->type;
                }
                }
            }
            }
        }
        }
        /*TRACE(region, "dump:\n");
        /*TRACE(region, "dump:\n");
        if(TRACE_ON(region))
        if(TRACE_ON(region))
            REGION_DumpRegion(destObj->rgn);*/
            REGION_DumpRegion(destObj->rgn);*/
    }
    }
    return result;
    return result;
}
}
 
 
/*
/*
 * Rectangle-related functions
 * Rectangle-related functions
 *
 *
 * Copyright 1993, 1996 Alexandre Julliard
 * Copyright 1993, 1996 Alexandre Julliard
 *
 *
 */
 */
BOOL WINAPI
BOOL WINAPI
IntersectRect( LPRECT dest, const RECT *src1, const RECT *src2 )
IntersectRect( LPRECT dest, const RECT *src1, const RECT *src2 )
{
{
    if (IsRectEmpty(src1) || IsRectEmpty(src2) ||
    if (IsRectEmpty(src1) || IsRectEmpty(src2) ||
        (src1->left >= src2->right) || (src2->left >= src1->right) ||
        (src1->left >= src2->right) || (src2->left >= src1->right) ||
        (src1->top >= src2->bottom) || (src2->top >= src1->bottom))
        (src1->top >= src2->bottom) || (src2->top >= src1->bottom))
    {
    {
        SetRectEmpty( dest );
        SetRectEmpty( dest );
        return FALSE;
        return FALSE;
    }
    }
    dest->left   = MWMAX( src1->left, src2->left );
    dest->left   = MWMAX( src1->left, src2->left );
    dest->right  = MWMIN( src1->right, src2->right );
    dest->right  = MWMIN( src1->right, src2->right );
    dest->top    = MWMAX( src1->top, src2->top );
    dest->top    = MWMAX( src1->top, src2->top );
    dest->bottom = MWMIN( src1->bottom, src2->bottom );
    dest->bottom = MWMIN( src1->bottom, src2->bottom );
    return TRUE;
    return TRUE;
}
}
 
 
 
 
BOOL WINAPI
BOOL WINAPI
UnionRect( LPRECT dest, const RECT *src1, const RECT *src2 )
UnionRect( LPRECT dest, const RECT *src1, const RECT *src2 )
{
{
    if (IsRectEmpty(src1))
    if (IsRectEmpty(src1))
    {
    {
        if (IsRectEmpty(src2))
        if (IsRectEmpty(src2))
        {
        {
            SetRectEmpty( dest );
            SetRectEmpty( dest );
            return FALSE;
            return FALSE;
        }
        }
        else *dest = *src2;
        else *dest = *src2;
    }
    }
    else
    else
    {
    {
        if (IsRectEmpty(src2)) *dest = *src1;
        if (IsRectEmpty(src2)) *dest = *src1;
        else
        else
        {
        {
            dest->left   = MWMIN( src1->left, src2->left );
            dest->left   = MWMIN( src1->left, src2->left );
            dest->right  = MWMAX( src1->right, src2->right );
            dest->right  = MWMAX( src1->right, src2->right );
            dest->top    = MWMIN( src1->top, src2->top );
            dest->top    = MWMIN( src1->top, src2->top );
            dest->bottom = MWMAX( src1->bottom, src2->bottom );
            dest->bottom = MWMAX( src1->bottom, src2->bottom );
        }
        }
    }
    }
    return TRUE;
    return TRUE;
}
}
 
 
 
 
BOOL WINAPI
BOOL WINAPI
EqualRect( const RECT* rect1, const RECT* rect2 )
EqualRect( const RECT* rect1, const RECT* rect2 )
{
{
    return ((rect1->left == rect2->left) && (rect1->right == rect2->right) &&
    return ((rect1->left == rect2->left) && (rect1->right == rect2->right) &&
            (rect1->top == rect2->top) && (rect1->bottom == rect2->bottom));
            (rect1->top == rect2->top) && (rect1->bottom == rect2->bottom));
}
}
 
 
 
 
BOOL WINAPI
BOOL WINAPI
SubtractRect( LPRECT dest, const RECT *src1, const RECT *src2 )
SubtractRect( LPRECT dest, const RECT *src1, const RECT *src2 )
{
{
    RECT tmp;
    RECT tmp;
 
 
    if (IsRectEmpty( src1 ))
    if (IsRectEmpty( src1 ))
    {
    {
        SetRectEmpty( dest );
        SetRectEmpty( dest );
        return FALSE;
        return FALSE;
    }
    }
    *dest = *src1;
    *dest = *src1;
    if (IntersectRect( &tmp, src1, src2 ))
    if (IntersectRect( &tmp, src1, src2 ))
    {
    {
        if (EqualRect( &tmp, dest ))
        if (EqualRect( &tmp, dest ))
        {
        {
            SetRectEmpty( dest );
            SetRectEmpty( dest );
            return FALSE;
            return FALSE;
        }
        }
        if ((tmp.top == dest->top) && (tmp.bottom == dest->bottom))
        if ((tmp.top == dest->top) && (tmp.bottom == dest->bottom))
        {
        {
            if (tmp.left == dest->left) dest->left = tmp.right;
            if (tmp.left == dest->left) dest->left = tmp.right;
            else if (tmp.right == dest->right) dest->right = tmp.left;
            else if (tmp.right == dest->right) dest->right = tmp.left;
        }
        }
        else if ((tmp.left == dest->left) && (tmp.right == dest->right))
        else if ((tmp.left == dest->left) && (tmp.right == dest->right))
        {
        {
            if (tmp.top == dest->top) dest->top = tmp.bottom;
            if (tmp.top == dest->top) dest->top = tmp.bottom;
            else if (tmp.bottom == dest->bottom) dest->bottom = tmp.top;
            else if (tmp.bottom == dest->bottom) dest->bottom = tmp.top;
        }
        }
    }
    }
    return TRUE;
    return TRUE;
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.