mirror of
https://github.com/reactos/reactos.git
synced 2025-02-22 08:25:03 +00:00
[NtGDI] Update Region code
Wine Sync/Port and update for Regions. See CORE-15906.
This commit is contained in:
parent
7fabc51d73
commit
feb9c045cf
3 changed files with 180 additions and 149 deletions
|
@ -113,6 +113,14 @@ SOFTWARE.
|
||||||
* the y-x-banding that's so nice to have...
|
* the y-x-banding that's so nice to have...
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// X11 sources for ReactOS region processing.
|
||||||
|
//
|
||||||
|
// libX11/src/PolyReg.c
|
||||||
|
// libX11/src/Region.c
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
#include <win32k.h>
|
#include <win32k.h>
|
||||||
#include <suppress.h>
|
#include <suppress.h>
|
||||||
|
|
||||||
|
@ -402,8 +410,8 @@ typedef struct _SCANLINE_LISTBLOCK
|
||||||
*
|
*
|
||||||
*************************************************************************/
|
*************************************************************************/
|
||||||
|
|
||||||
#define LARGE_COORDINATE 0x7fffffff /* FIXME */
|
#define LARGE_COORDINATE INT_MAX
|
||||||
#define SMALL_COORDINATE 0x80000000
|
#define SMALL_COORDINATE INT_MIN
|
||||||
|
|
||||||
static
|
static
|
||||||
BOOL
|
BOOL
|
||||||
|
@ -509,8 +517,8 @@ REGION_bAddRect(
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef VOID (FASTCALL *overlapProcp)(PREGION, PRECT, PRECT, PRECT, PRECT, INT, INT);
|
typedef BOOL (FASTCALL *overlapProcp)(PREGION, PRECT, PRECT, PRECT, PRECT, INT, INT);
|
||||||
typedef VOID (FASTCALL *nonOverlapProcp)(PREGION, PRECT, PRECT, INT, INT);
|
typedef BOOL (FASTCALL *nonOverlapProcp)(PREGION, PRECT, PRECT, INT, INT);
|
||||||
|
|
||||||
// Number of points to buffer before sending them off to scanlines() : Must be an even number
|
// Number of points to buffer before sending them off to scanlines() : Must be an even number
|
||||||
#define NUMPTSTOBUFFER 200
|
#define NUMPTSTOBUFFER 200
|
||||||
|
@ -947,7 +955,7 @@ REGION_Coalesce(
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static
|
static
|
||||||
VOID
|
BOOL
|
||||||
FASTCALL
|
FASTCALL
|
||||||
REGION_RegionOp(
|
REGION_RegionOp(
|
||||||
PREGION newReg, /* Place to store result */
|
PREGION newReg, /* Place to store result */
|
||||||
|
@ -1001,7 +1009,7 @@ REGION_RegionOp(
|
||||||
if (newReg->Buffer == NULL)
|
if (newReg->Buffer == NULL)
|
||||||
{
|
{
|
||||||
newReg->rdh.nRgnSize = 0;
|
newReg->rdh.nRgnSize = 0;
|
||||||
return;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize ybot and ytop.
|
/* Initialize ybot and ytop.
|
||||||
|
@ -1062,7 +1070,7 @@ REGION_RegionOp(
|
||||||
|
|
||||||
if ((top != bot) && (nonOverlap1Func != NULL))
|
if ((top != bot) && (nonOverlap1Func != NULL))
|
||||||
{
|
{
|
||||||
(*nonOverlap1Func)(newReg, r1, r1BandEnd, top, bot);
|
if (!(*nonOverlap1Func)(newReg, r1, r1BandEnd, top, bot)) return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ytop = r2->top;
|
ytop = r2->top;
|
||||||
|
@ -1074,7 +1082,7 @@ REGION_RegionOp(
|
||||||
|
|
||||||
if ((top != bot) && (nonOverlap2Func != NULL))
|
if ((top != bot) && (nonOverlap2Func != NULL))
|
||||||
{
|
{
|
||||||
(*nonOverlap2Func)(newReg, r2, r2BandEnd, top, bot);
|
if (!(*nonOverlap2Func)(newReg, r2, r2BandEnd, top, bot) ) return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ytop = r1->top;
|
ytop = r1->top;
|
||||||
|
@ -1099,7 +1107,7 @@ REGION_RegionOp(
|
||||||
curBand = newReg->rdh.nCount;
|
curBand = newReg->rdh.nCount;
|
||||||
if (ybot > ytop)
|
if (ybot > ytop)
|
||||||
{
|
{
|
||||||
(*overlapFunc)(newReg, r1, r1BandEnd, r2, r2BandEnd, ytop, ybot);
|
if (!(*overlapFunc)(newReg, r1, r1BandEnd, r2, r2BandEnd, ytop, ybot)) return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newReg->rdh.nCount != curBand)
|
if (newReg->rdh.nCount != curBand)
|
||||||
|
@ -1134,11 +1142,12 @@ REGION_RegionOp(
|
||||||
r1BandEnd++;
|
r1BandEnd++;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*nonOverlap1Func)(newReg,
|
if (!(*nonOverlap1Func)(newReg,
|
||||||
r1,
|
r1,
|
||||||
r1BandEnd,
|
r1BandEnd,
|
||||||
max(r1->top,ybot),
|
max(r1->top,ybot),
|
||||||
r1->bottom);
|
r1->bottom))
|
||||||
|
return FALSE;
|
||||||
r1 = r1BandEnd;
|
r1 = r1BandEnd;
|
||||||
}
|
}
|
||||||
while (r1 != r1End);
|
while (r1 != r1End);
|
||||||
|
@ -1154,11 +1163,12 @@ REGION_RegionOp(
|
||||||
r2BandEnd++;
|
r2BandEnd++;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*nonOverlap2Func)(newReg,
|
if (!(*nonOverlap2Func)(newReg,
|
||||||
r2,
|
r2,
|
||||||
r2BandEnd,
|
r2BandEnd,
|
||||||
max(r2->top,ybot),
|
max(r2->top,ybot),
|
||||||
r2->bottom);
|
r2->bottom))
|
||||||
|
return FALSE;
|
||||||
r2 = r2BandEnd;
|
r2 = r2BandEnd;
|
||||||
}
|
}
|
||||||
while (r2 != r2End);
|
while (r2 != r2End);
|
||||||
|
@ -1216,7 +1226,7 @@ REGION_RegionOp(
|
||||||
|
|
||||||
if (oldRects != &newReg->rdh.rcBound)
|
if (oldRects != &newReg->rdh.rcBound)
|
||||||
ExFreePoolWithTag(oldRects, TAG_REGION);
|
ExFreePoolWithTag(oldRects, TAG_REGION);
|
||||||
return;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
@ -1235,7 +1245,7 @@ REGION_RegionOp(
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static
|
static
|
||||||
VOID
|
BOOL
|
||||||
FASTCALL
|
FASTCALL
|
||||||
REGION_IntersectO(
|
REGION_IntersectO(
|
||||||
PREGION pReg,
|
PREGION pReg,
|
||||||
|
@ -1262,7 +1272,7 @@ REGION_IntersectO(
|
||||||
{
|
{
|
||||||
if (!REGION_bAddRect(pReg, left, top, right, bottom))
|
if (!REGION_bAddRect(pReg, left, top, right, bottom))
|
||||||
{
|
{
|
||||||
return;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1284,14 +1294,14 @@ REGION_IntersectO(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* REGION_IntersectRegion
|
* REGION_IntersectRegion
|
||||||
*/
|
*/
|
||||||
static
|
static
|
||||||
VOID
|
BOOL
|
||||||
FASTCALL
|
FASTCALL
|
||||||
REGION_IntersectRegion(
|
REGION_IntersectRegion(
|
||||||
PREGION newReg,
|
PREGION newReg,
|
||||||
|
@ -1307,12 +1317,13 @@ REGION_IntersectRegion(
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
REGION_RegionOp(newReg,
|
if (!REGION_RegionOp(newReg,
|
||||||
reg1,
|
reg1,
|
||||||
reg2,
|
reg2,
|
||||||
REGION_IntersectO,
|
REGION_IntersectO,
|
||||||
NULL,
|
NULL,
|
||||||
NULL);
|
NULL))
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Can't alter newReg's extents before we call miRegionOp because
|
/* Can't alter newReg's extents before we call miRegionOp because
|
||||||
|
@ -1321,6 +1332,7 @@ REGION_IntersectRegion(
|
||||||
* way there's no checking against rectangles that will be nuked
|
* way there's no checking against rectangles that will be nuked
|
||||||
* due to coalescing, so we have to examine fewer rectangles. */
|
* due to coalescing, so we have to examine fewer rectangles. */
|
||||||
REGION_SetExtents(newReg);
|
REGION_SetExtents(newReg);
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
@ -1341,7 +1353,7 @@ REGION_IntersectRegion(
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static
|
static
|
||||||
VOID
|
BOOL
|
||||||
FASTCALL
|
FASTCALL
|
||||||
REGION_UnionNonO(
|
REGION_UnionNonO(
|
||||||
PREGION pReg,
|
PREGION pReg,
|
||||||
|
@ -1354,7 +1366,7 @@ REGION_UnionNonO(
|
||||||
{
|
{
|
||||||
if (!REGION_bEnsureBufferSize(pReg, pReg->rdh.nCount + (rEnd - r)))
|
if (!REGION_bEnsureBufferSize(pReg, pReg->rdh.nCount + (rEnd - r)))
|
||||||
{
|
{
|
||||||
return;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
do
|
do
|
||||||
|
@ -1365,7 +1377,7 @@ REGION_UnionNonO(
|
||||||
while (r != rEnd);
|
while (r != rEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline
|
static __inline
|
||||||
|
@ -1411,7 +1423,7 @@ REGION_bMergeRect(
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static
|
static
|
||||||
VOID
|
BOOL
|
||||||
FASTCALL
|
FASTCALL
|
||||||
REGION_UnionO (
|
REGION_UnionO (
|
||||||
PREGION pReg,
|
PREGION pReg,
|
||||||
|
@ -1426,12 +1438,12 @@ REGION_UnionO (
|
||||||
{
|
{
|
||||||
if (r1->left < r2->left)
|
if (r1->left < r2->left)
|
||||||
{
|
{
|
||||||
REGION_bMergeRect(pReg, r1->left, top, r1->right, bottom);
|
if (!REGION_bMergeRect(pReg, r1->left, top, r1->right, bottom)) return FALSE;
|
||||||
r1++;
|
r1++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
REGION_bMergeRect(pReg, r2->left, top, r2->right, bottom);
|
if (!REGION_bMergeRect(pReg, r2->left, top, r2->right, bottom)) return FALSE;
|
||||||
r2++;
|
r2++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1440,7 +1452,7 @@ REGION_UnionO (
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
REGION_bMergeRect(pReg, r1->left, top, r1->right, bottom);
|
if (!REGION_bMergeRect(pReg, r1->left, top, r1->right, bottom)) return FALSE;
|
||||||
r1++;
|
r1++;
|
||||||
}
|
}
|
||||||
while (r1 != r1End);
|
while (r1 != r1End);
|
||||||
|
@ -1449,25 +1461,27 @@ REGION_UnionO (
|
||||||
{
|
{
|
||||||
while (r2 != r2End)
|
while (r2 != r2End)
|
||||||
{
|
{
|
||||||
REGION_bMergeRect(pReg, r2->left, top, r2->right, bottom);
|
if (!REGION_bMergeRect(pReg, r2->left, top, r2->right, bottom)) return FALSE;
|
||||||
r2++;
|
r2++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* REGION_UnionRegion
|
* REGION_UnionRegion
|
||||||
*/
|
*/
|
||||||
static
|
static
|
||||||
VOID
|
BOOL
|
||||||
FASTCALL
|
FASTCALL
|
||||||
REGION_UnionRegion(
|
REGION_UnionRegion(
|
||||||
PREGION newReg,
|
PREGION newReg,
|
||||||
PREGION reg1,
|
PREGION reg1,
|
||||||
PREGION reg2)
|
PREGION reg2)
|
||||||
{
|
{
|
||||||
|
BOOL ret = TRUE;
|
||||||
|
|
||||||
/* Checks all the simple cases
|
/* Checks all the simple cases
|
||||||
* Region 1 and 2 are the same or region 1 is empty */
|
* Region 1 and 2 are the same or region 1 is empty */
|
||||||
if ((reg1 == reg2) || (reg1->rdh.nCount == 0) ||
|
if ((reg1 == reg2) || (reg1->rdh.nCount == 0) ||
|
||||||
|
@ -1476,10 +1490,10 @@ REGION_UnionRegion(
|
||||||
{
|
{
|
||||||
if (newReg != reg2)
|
if (newReg != reg2)
|
||||||
{
|
{
|
||||||
REGION_CopyRegion(newReg, reg2);
|
ret = REGION_CopyRegion(newReg, reg2);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If nothing to union (region 2 empty) */
|
/* If nothing to union (region 2 empty) */
|
||||||
|
@ -1489,10 +1503,10 @@ REGION_UnionRegion(
|
||||||
{
|
{
|
||||||
if (newReg != reg1)
|
if (newReg != reg1)
|
||||||
{
|
{
|
||||||
REGION_CopyRegion(newReg, reg1);
|
ret = REGION_CopyRegion(newReg, reg1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Region 1 completely subsumes region 2 */
|
/* Region 1 completely subsumes region 2 */
|
||||||
|
@ -1504,10 +1518,10 @@ REGION_UnionRegion(
|
||||||
{
|
{
|
||||||
if (newReg != reg1)
|
if (newReg != reg1)
|
||||||
{
|
{
|
||||||
REGION_CopyRegion(newReg, reg1);
|
ret = REGION_CopyRegion(newReg, reg1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Region 2 completely subsumes region 1 */
|
/* Region 2 completely subsumes region 1 */
|
||||||
|
@ -1519,23 +1533,25 @@ REGION_UnionRegion(
|
||||||
{
|
{
|
||||||
if (newReg != reg2)
|
if (newReg != reg2)
|
||||||
{
|
{
|
||||||
REGION_CopyRegion(newReg, reg2);
|
ret = REGION_CopyRegion(newReg, reg2);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
REGION_RegionOp(newReg,
|
if ((ret = REGION_RegionOp(newReg,
|
||||||
reg1,
|
reg1,
|
||||||
reg2,
|
reg2,
|
||||||
REGION_UnionO,
|
REGION_UnionO,
|
||||||
REGION_UnionNonO,
|
REGION_UnionNonO,
|
||||||
REGION_UnionNonO);
|
REGION_UnionNonO)))
|
||||||
|
{
|
||||||
newReg->rdh.rcBound.left = min(reg1->rdh.rcBound.left, reg2->rdh.rcBound.left);
|
newReg->rdh.rcBound.left = min(reg1->rdh.rcBound.left, reg2->rdh.rcBound.left);
|
||||||
newReg->rdh.rcBound.top = min(reg1->rdh.rcBound.top, reg2->rdh.rcBound.top);
|
newReg->rdh.rcBound.top = min(reg1->rdh.rcBound.top, reg2->rdh.rcBound.top);
|
||||||
newReg->rdh.rcBound.right = max(reg1->rdh.rcBound.right, reg2->rdh.rcBound.right);
|
newReg->rdh.rcBound.right = max(reg1->rdh.rcBound.right, reg2->rdh.rcBound.right);
|
||||||
newReg->rdh.rcBound.bottom = max(reg1->rdh.rcBound.bottom, reg2->rdh.rcBound.bottom);
|
newReg->rdh.rcBound.bottom = max(reg1->rdh.rcBound.bottom, reg2->rdh.rcBound.bottom);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
@ -1554,7 +1570,7 @@ REGION_UnionRegion(
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static
|
static
|
||||||
VOID
|
BOOL
|
||||||
FASTCALL
|
FASTCALL
|
||||||
REGION_SubtractNonO1(
|
REGION_SubtractNonO1(
|
||||||
PREGION pReg,
|
PREGION pReg,
|
||||||
|
@ -1567,7 +1583,7 @@ REGION_SubtractNonO1(
|
||||||
{
|
{
|
||||||
if (!REGION_bEnsureBufferSize(pReg, pReg->rdh.nCount + (rEnd - r)))
|
if (!REGION_bEnsureBufferSize(pReg, pReg->rdh.nCount + (rEnd - r)))
|
||||||
{
|
{
|
||||||
return;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
do
|
do
|
||||||
|
@ -1578,7 +1594,7 @@ REGION_SubtractNonO1(
|
||||||
while (r != rEnd);
|
while (r != rEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1594,7 +1610,7 @@ REGION_SubtractNonO1(
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static
|
static
|
||||||
VOID
|
BOOL
|
||||||
FASTCALL
|
FASTCALL
|
||||||
REGION_SubtractO(
|
REGION_SubtractO(
|
||||||
PREGION pReg,
|
PREGION pReg,
|
||||||
|
@ -1641,7 +1657,7 @@ REGION_SubtractO(
|
||||||
* part of minuend to region and skip to next subtrahend. */
|
* part of minuend to region and skip to next subtrahend. */
|
||||||
if (!REGION_bAddRect(pReg, left, top, r2->left, bottom))
|
if (!REGION_bAddRect(pReg, left, top, r2->left, bottom))
|
||||||
{
|
{
|
||||||
return;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
left = r2->right;
|
left = r2->right;
|
||||||
|
@ -1665,7 +1681,7 @@ REGION_SubtractO(
|
||||||
{
|
{
|
||||||
if (!REGION_bAddRect(pReg, left, top, r1->right, bottom))
|
if (!REGION_bAddRect(pReg, left, top, r1->right, bottom))
|
||||||
{
|
{
|
||||||
return;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1680,7 +1696,7 @@ REGION_SubtractO(
|
||||||
{
|
{
|
||||||
if (!REGION_bEnsureBufferSize(pReg, pReg->rdh.nCount + (r1End - r1)))
|
if (!REGION_bEnsureBufferSize(pReg, pReg->rdh.nCount + (r1End - r1)))
|
||||||
{
|
{
|
||||||
return;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add remaining minuend rectangles to region. */
|
/* Add remaining minuend rectangles to region. */
|
||||||
|
@ -1696,7 +1712,7 @@ REGION_SubtractO(
|
||||||
while (r1 != r1End);
|
while (r1 != r1End);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -1711,7 +1727,7 @@ REGION_SubtractO(
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static
|
static
|
||||||
VOID
|
BOOL
|
||||||
FASTCALL
|
FASTCALL
|
||||||
REGION_SubtractRegion(
|
REGION_SubtractRegion(
|
||||||
PREGION regD,
|
PREGION regD,
|
||||||
|
@ -1723,16 +1739,16 @@ REGION_SubtractRegion(
|
||||||
(regS->rdh.nCount == 0) ||
|
(regS->rdh.nCount == 0) ||
|
||||||
(EXTENTCHECK(®M->rdh.rcBound, ®S->rdh.rcBound) == 0))
|
(EXTENTCHECK(®M->rdh.rcBound, ®S->rdh.rcBound) == 0))
|
||||||
{
|
{
|
||||||
REGION_CopyRegion(regD, regM);
|
return REGION_CopyRegion(regD, regM);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
REGION_RegionOp(regD,
|
if (!REGION_RegionOp(regD,
|
||||||
regM,
|
regM,
|
||||||
regS,
|
regS,
|
||||||
REGION_SubtractO,
|
REGION_SubtractO,
|
||||||
REGION_SubtractNonO1,
|
REGION_SubtractNonO1,
|
||||||
NULL);
|
NULL))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
/* Can't alter newReg's extents before we call miRegionOp because
|
/* Can't alter newReg's extents before we call miRegionOp because
|
||||||
* it might be one of the source regions and miRegionOp depends
|
* it might be one of the source regions and miRegionOp depends
|
||||||
|
@ -1740,13 +1756,14 @@ REGION_SubtractRegion(
|
||||||
* way there's no checking against rectangles that will be nuked
|
* way there's no checking against rectangles that will be nuked
|
||||||
* due to coalescing, so we have to examine fewer rectangles. */
|
* due to coalescing, so we have to examine fewer rectangles. */
|
||||||
REGION_SetExtents(regD);
|
REGION_SetExtents(regD);
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* REGION_XorRegion
|
* REGION_XorRegion
|
||||||
*/
|
*/
|
||||||
static
|
static
|
||||||
VOID
|
BOOL
|
||||||
FASTCALL
|
FASTCALL
|
||||||
REGION_XorRegion(
|
REGION_XorRegion(
|
||||||
PREGION dr,
|
PREGION dr,
|
||||||
|
@ -1755,12 +1772,13 @@ REGION_XorRegion(
|
||||||
{
|
{
|
||||||
HRGN htra, htrb;
|
HRGN htra, htrb;
|
||||||
PREGION tra, trb;
|
PREGION tra, trb;
|
||||||
|
BOOL ret;
|
||||||
|
|
||||||
// FIXME: Don't use a handle
|
// FIXME: Don't use a handle
|
||||||
tra = REGION_AllocRgnWithHandle(sra->rdh.nCount + 1);
|
tra = REGION_AllocRgnWithHandle(sra->rdh.nCount + 1);
|
||||||
if (tra == NULL)
|
if (tra == NULL)
|
||||||
{
|
{
|
||||||
return;
|
return FALSE;
|
||||||
}
|
}
|
||||||
htra = tra->BaseObject.hHmgr;
|
htra = tra->BaseObject.hHmgr;
|
||||||
|
|
||||||
|
@ -1770,26 +1788,26 @@ REGION_XorRegion(
|
||||||
{
|
{
|
||||||
REGION_UnlockRgn(tra);
|
REGION_UnlockRgn(tra);
|
||||||
GreDeleteObject(htra);
|
GreDeleteObject(htra);
|
||||||
return;
|
return FALSE;
|
||||||
}
|
}
|
||||||
htrb = trb->BaseObject.hHmgr;
|
htrb = trb->BaseObject.hHmgr;
|
||||||
|
|
||||||
REGION_SubtractRegion(tra, sra, srb);
|
ret = REGION_SubtractRegion(tra, sra, srb) &&
|
||||||
REGION_SubtractRegion(trb, srb, sra);
|
REGION_SubtractRegion(trb, srb, sra) &&
|
||||||
REGION_UnionRegion(dr, tra, trb);
|
REGION_UnionRegion(dr, tra, trb);
|
||||||
REGION_UnlockRgn(tra);
|
REGION_UnlockRgn(tra);
|
||||||
REGION_UnlockRgn(trb);
|
REGION_UnlockRgn(trb);
|
||||||
|
|
||||||
GreDeleteObject(htra);
|
GreDeleteObject(htra);
|
||||||
GreDeleteObject(htrb);
|
GreDeleteObject(htrb);
|
||||||
return;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Adds a rectangle to a REGION
|
* Adds a rectangle to a REGION
|
||||||
*/
|
*/
|
||||||
VOID
|
BOOL
|
||||||
FASTCALL
|
FASTCALL
|
||||||
REGION_UnionRectWithRgn(
|
REGION_UnionRectWithRgn(
|
||||||
PREGION rgn,
|
PREGION rgn,
|
||||||
|
@ -1801,7 +1819,7 @@ REGION_UnionRectWithRgn(
|
||||||
region.rdh.nCount = 1;
|
region.rdh.nCount = 1;
|
||||||
region.rdh.nRgnSize = sizeof(RECT);
|
region.rdh.nRgnSize = sizeof(RECT);
|
||||||
region.rdh.rcBound = *rect;
|
region.rdh.rcBound = *rect;
|
||||||
REGION_UnionRegion(rgn, rgn, ®ion);
|
return REGION_UnionRegion(rgn, rgn, ®ion);
|
||||||
}
|
}
|
||||||
|
|
||||||
INT
|
INT
|
||||||
|
@ -1821,6 +1839,27 @@ REGION_SubtractRectFromRgn(
|
||||||
return REGION_Complexity(prgnDest);
|
return REGION_Complexity(prgnDest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
FASTCALL
|
||||||
|
REGION_bCopy(
|
||||||
|
PREGION dst,
|
||||||
|
PREGION src)
|
||||||
|
{
|
||||||
|
if ( !dst || !src ) return FALSE;
|
||||||
|
return REGION_CopyRegion( dst, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
FASTCALL
|
||||||
|
REGION_bIntersectRegion(
|
||||||
|
PREGION newReg,
|
||||||
|
PREGION reg1,
|
||||||
|
PREGION reg2)
|
||||||
|
{
|
||||||
|
if ( !newReg || !reg1 || !reg2 ) return FALSE;
|
||||||
|
return REGION_IntersectRegion( newReg, reg1, reg2);
|
||||||
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
BOOL
|
BOOL
|
||||||
REGION_bMakeSimpleFrameRgn(
|
REGION_bMakeSimpleFrameRgn(
|
||||||
|
@ -2098,9 +2137,13 @@ REGION_bXformRgn(
|
||||||
RECTL_vMakeWellOrdered(&prgn->Buffer[i]);
|
RECTL_vMakeWellOrdered(&prgn->Buffer[i]);
|
||||||
|
|
||||||
/* Update bounds */
|
/* Update bounds */
|
||||||
RECTL_bUnionRect(&prgn->rdh.rcBound,
|
if (!RECTL_bUnionRect(&prgn->rdh.rcBound,
|
||||||
&prgn->rdh.rcBound,
|
&prgn->rdh.rcBound,
|
||||||
&prgn->Buffer[i]);
|
&prgn->Buffer[i]))
|
||||||
|
{
|
||||||
|
DPRINT1("NULL Set in Union Rects\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Loop all rects in the region */
|
/* Loop all rects in the region */
|
||||||
|
@ -2469,6 +2512,7 @@ IntGdiCombineRgn(
|
||||||
PREGION prgnSrc2,
|
PREGION prgnSrc2,
|
||||||
INT iCombineMode)
|
INT iCombineMode)
|
||||||
{
|
{
|
||||||
|
BOOL Ret = TRUE;
|
||||||
|
|
||||||
if (prgnDest == NULL)
|
if (prgnDest == NULL)
|
||||||
{
|
{
|
||||||
|
@ -2500,20 +2544,20 @@ IntGdiCombineRgn(
|
||||||
switch (iCombineMode)
|
switch (iCombineMode)
|
||||||
{
|
{
|
||||||
case RGN_AND:
|
case RGN_AND:
|
||||||
REGION_IntersectRegion(prgnDest, prgnSrc1, prgnSrc2);
|
Ret = REGION_IntersectRegion(prgnDest, prgnSrc1, prgnSrc2);
|
||||||
break;
|
break;
|
||||||
case RGN_OR:
|
case RGN_OR:
|
||||||
REGION_UnionRegion(prgnDest, prgnSrc1, prgnSrc2);
|
Ret = REGION_UnionRegion(prgnDest, prgnSrc1, prgnSrc2);
|
||||||
break;
|
break;
|
||||||
case RGN_XOR:
|
case RGN_XOR:
|
||||||
REGION_XorRegion(prgnDest, prgnSrc1, prgnSrc2);
|
Ret = REGION_XorRegion(prgnDest, prgnSrc1, prgnSrc2);
|
||||||
break;
|
break;
|
||||||
case RGN_DIFF:
|
case RGN_DIFF:
|
||||||
REGION_SubtractRegion(prgnDest, prgnSrc1, prgnSrc2);
|
Ret = REGION_SubtractRegion(prgnDest, prgnSrc1, prgnSrc2);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return REGION_Complexity(prgnDest);
|
return Ret ? REGION_Complexity(prgnDest) : ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
INT
|
INT
|
||||||
|
@ -3600,8 +3644,9 @@ NtGdiCreateRoundRectRgn(
|
||||||
{
|
{
|
||||||
PREGION obj;
|
PREGION obj;
|
||||||
HRGN hrgn;
|
HRGN hrgn;
|
||||||
INT asq, bsq, d, xd, yd;
|
int a, b, i, x, y;
|
||||||
RECTL rect;
|
INT64 asq, bsq, dx, dy, err;
|
||||||
|
RECT *rects;
|
||||||
|
|
||||||
/* Make the dimensions sensible */
|
/* Make the dimensions sensible */
|
||||||
if (left > right)
|
if (left > right)
|
||||||
|
@ -3618,95 +3663,75 @@ NtGdiCreateRoundRectRgn(
|
||||||
bottom = tmp;
|
bottom = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
ellipse_width = abs(ellipse_width);
|
/* the region is for the rectangle interior, but only at right and bottom for some reason */
|
||||||
ellipse_height = abs(ellipse_height);
|
right--;
|
||||||
|
bottom--;
|
||||||
|
|
||||||
/* Check parameters */
|
ellipse_width = min( right - left, abs( ellipse_width ));
|
||||||
if (ellipse_width > right-left)
|
ellipse_height = min( bottom - top, abs( ellipse_height ));
|
||||||
ellipse_width = right-left;
|
|
||||||
if (ellipse_height > bottom-top)
|
|
||||||
ellipse_height = bottom-top;
|
|
||||||
|
|
||||||
/* Check if we can do a normal rectangle instead */
|
/* Check if we can do a normal rectangle instead */
|
||||||
|
|
||||||
if ((ellipse_width < 2) || (ellipse_height < 2))
|
if ((ellipse_width < 2) || (ellipse_height < 2))
|
||||||
return NtGdiCreateRectRgn(left, top, right, bottom);
|
return NtGdiCreateRectRgn(left, top, right, bottom);
|
||||||
|
|
||||||
/* Create region */
|
obj = REGION_AllocUserRgnWithHandle( ellipse_height );
|
||||||
d = (ellipse_height < 128) ? ((3 * ellipse_height) >> 2) : 64;
|
|
||||||
obj = REGION_AllocUserRgnWithHandle(d);
|
|
||||||
if (obj == NULL)
|
if (obj == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
hrgn = obj->BaseObject.hHmgr;
|
hrgn = obj->BaseObject.hHmgr;
|
||||||
|
|
||||||
/* Ellipse algorithm, based on an article by K. Porter
|
obj->rdh.rcBound.left = left;
|
||||||
in DDJ Graphics Programming Column, 8/89 */
|
obj->rdh.rcBound.top = top;
|
||||||
asq = ellipse_width * ellipse_width / 4; /* a^2 */
|
obj->rdh.rcBound.right = right;
|
||||||
bsq = ellipse_height * ellipse_height / 4; /* b^2 */
|
obj->rdh.rcBound.bottom = bottom;
|
||||||
d = bsq - asq * ellipse_height / 2 + asq / 4; /* b^2 - a^2b + a^2/4 */
|
rects = obj->Buffer;
|
||||||
xd = 0;
|
|
||||||
yd = asq * ellipse_height; /* 2a^2b */
|
|
||||||
|
|
||||||
rect.left = left + ellipse_width / 2;
|
/* based on an algorithm by Alois Zingl */
|
||||||
rect.right = right - ellipse_width / 2;
|
|
||||||
|
|
||||||
/* Loop to draw first half of quadrant */
|
a = ellipse_width - 1;
|
||||||
while (xd < yd)
|
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)
|
||||||
{
|
{
|
||||||
/* If nearest pixel is toward the center */
|
INT64 e2 = 2 * err;
|
||||||
if (d > 0)
|
if (e2 >= dx)
|
||||||
{
|
{
|
||||||
/* Move toward center */
|
x++;
|
||||||
rect.top = top++;
|
err += dx += bsq;
|
||||||
rect.bottom = rect.top + 1;
|
|
||||||
REGION_UnionRectWithRgn(obj, &rect);
|
|
||||||
rect.top = --bottom;
|
|
||||||
rect.bottom = rect.top + 1;
|
|
||||||
REGION_UnionRectWithRgn(obj, &rect);
|
|
||||||
yd -= 2*asq;
|
|
||||||
d -= yd;
|
|
||||||
}
|
}
|
||||||
|
if (e2 <= dy)
|
||||||
/* Next horiz point */
|
|
||||||
rect.left--;
|
|
||||||
rect.right++;
|
|
||||||
xd += 2*bsq;
|
|
||||||
d += bsq + xd;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Loop to draw second half of quadrant */
|
|
||||||
d += (3 * (asq-bsq) / 2 - (xd+yd)) / 2;
|
|
||||||
while (yd >= 0)
|
|
||||||
{
|
|
||||||
/* next vertical point */
|
|
||||||
rect.top = top++;
|
|
||||||
rect.bottom = rect.top + 1;
|
|
||||||
REGION_UnionRectWithRgn(obj, &rect);
|
|
||||||
rect.top = --bottom;
|
|
||||||
rect.bottom = rect.top + 1;
|
|
||||||
REGION_UnionRectWithRgn(obj, &rect);
|
|
||||||
|
|
||||||
/* If nearest pixel is outside ellipse */
|
|
||||||
if (d < 0)
|
|
||||||
{
|
{
|
||||||
/* Move away from center */
|
y++;
|
||||||
rect.left--;
|
err += dy += asq;
|
||||||
rect.right++;
|
rects[y].left = left + x;
|
||||||
xd += 2*bsq;
|
rects[y].right = right - x;
|
||||||
d += xd;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
yd -= 2*asq;
|
|
||||||
d += asq - yd;
|
|
||||||
}
|
}
|
||||||
|
for (i = 0; i < ellipse_height / 2; i++)
|
||||||
/* Add the inside rectangle */
|
|
||||||
if (top <= bottom)
|
|
||||||
{
|
{
|
||||||
rect.top = top;
|
rects[i].left = rects[b - i].left;
|
||||||
rect.bottom = bottom;
|
rects[i].right = rects[b - i].right;
|
||||||
REGION_UnionRectWithRgn(obj, &rect);
|
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 */
|
||||||
|
|
||||||
REGION_UnlockRgn(obj);
|
REGION_UnlockRgn(obj);
|
||||||
return hrgn;
|
return hrgn;
|
||||||
|
@ -3860,7 +3885,13 @@ NtGdiExtCreateRegion(
|
||||||
{
|
{
|
||||||
if ( rects[i].left < rects[i].right && rects[i].top < rects[i].bottom )
|
if ( rects[i].left < rects[i].right && rects[i].top < rects[i].bottom )
|
||||||
{
|
{
|
||||||
REGION_UnionRectWithRgn(Region, &rects[i]);
|
if (!REGION_UnionRectWithRgn(Region, &rects[i]))
|
||||||
|
{
|
||||||
|
REGION_UnlockRgn(Region);
|
||||||
|
GreDeleteObject(hRgn);
|
||||||
|
hRgn = NULL;
|
||||||
|
_SEH2_LEAVE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3901,7 +3932,7 @@ NtGdiExtCreateRegion(
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
REGION_UnlockRgn(Region);
|
if (hRgn) REGION_UnlockRgn(Region);
|
||||||
|
|
||||||
return hRgn;
|
return hRgn;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ extern HRGN hrgnDefault;
|
||||||
|
|
||||||
PREGION FASTCALL REGION_AllocRgnWithHandle(INT n);
|
PREGION FASTCALL REGION_AllocRgnWithHandle(INT n);
|
||||||
PREGION FASTCALL REGION_AllocUserRgnWithHandle(INT n);
|
PREGION FASTCALL REGION_AllocUserRgnWithHandle(INT n);
|
||||||
VOID FASTCALL REGION_UnionRectWithRgn(PREGION rgn, const RECTL *rect);
|
BOOL FASTCALL REGION_UnionRectWithRgn(PREGION rgn, const RECTL *rect);
|
||||||
INT FASTCALL REGION_SubtractRectFromRgn(PREGION prgnDest, PREGION prgnSrc, const RECTL *prcl);
|
INT FASTCALL REGION_SubtractRectFromRgn(PREGION prgnDest, PREGION prgnSrc, const RECTL *prcl);
|
||||||
INT FASTCALL REGION_GetRgnBox(PREGION Rgn, RECTL *pRect);
|
INT FASTCALL REGION_GetRgnBox(PREGION Rgn, RECTL *pRect);
|
||||||
BOOL FASTCALL REGION_RectInRegion(PREGION Rgn, const RECTL *rc);
|
BOOL FASTCALL REGION_RectInRegion(PREGION Rgn, const RECTL *rc);
|
||||||
|
@ -93,6 +93,12 @@ GreCreateFrameRgn(
|
||||||
#define IntSysCreateRectpRgnIndirect(prc) \
|
#define IntSysCreateRectpRgnIndirect(prc) \
|
||||||
IntSysCreateRectpRgn((prc)->left, (prc)->top, (prc)->right, (prc)->bottom)
|
IntSysCreateRectpRgn((prc)->left, (prc)->top, (prc)->right, (prc)->bottom)
|
||||||
|
|
||||||
|
#define GreCreateRectRgnIndirect(prc) \
|
||||||
|
NtGdiCreateRectRgn((prc)->left, (prc)->top, (prc)->right, (prc)->bottom)
|
||||||
|
|
||||||
|
#define GreSetRectRgnIndirect(hRgn, prc) \
|
||||||
|
NtGdiSetRectRgn(hRgn, (prc)->left, (prc)->top, (prc)->right, (prc)->bottom);
|
||||||
|
|
||||||
PREGION
|
PREGION
|
||||||
FASTCALL
|
FASTCALL
|
||||||
IntSysCreateRectpRgn(INT LeftRect, INT TopRect, INT RightRect, INT BottomRect);
|
IntSysCreateRectpRgn(INT LeftRect, INT TopRect, INT RightRect, INT BottomRect);
|
||||||
|
|
|
@ -15,12 +15,6 @@
|
||||||
#define RDW_CLIPCHILDREN 4096
|
#define RDW_CLIPCHILDREN 4096
|
||||||
#define RDW_NOUPDATEDIRTY 32768
|
#define RDW_NOUPDATEDIRTY 32768
|
||||||
|
|
||||||
#define GreCreateRectRgnIndirect(prc) \
|
|
||||||
NtGdiCreateRectRgn((prc)->left, (prc)->top, (prc)->right, (prc)->bottom)
|
|
||||||
|
|
||||||
#define GreSetRectRgnIndirect(hRgn, prc) \
|
|
||||||
NtGdiSetRectRgn(hRgn, (prc)->left, (prc)->top, (prc)->right, (prc)->bottom);
|
|
||||||
|
|
||||||
BOOL FASTCALL co_UserRedrawWindow(PWND Wnd, const RECTL* UpdateRect, PREGION UpdateRgn, ULONG Flags);
|
BOOL FASTCALL co_UserRedrawWindow(PWND Wnd, const RECTL* UpdateRect, PREGION UpdateRgn, ULONG Flags);
|
||||||
VOID FASTCALL IntInvalidateWindows(PWND Window, PREGION Rgn, ULONG Flags);
|
VOID FASTCALL IntInvalidateWindows(PWND Window, PREGION Rgn, ULONG Flags);
|
||||||
BOOL FASTCALL IntGetPaintMessage(PWND Window, UINT MsgFilterMin, UINT MsgFilterMax, PTHREADINFO Thread, MSG *Message, BOOL Remove);
|
BOOL FASTCALL IntGetPaintMessage(PWND Window, UINT MsgFilterMin, UINT MsgFilterMax, PTHREADINFO Thread, MSG *Message, BOOL Remove);
|
||||||
|
|
Loading…
Reference in a new issue