ReactOS  0.4.14-dev-98-gb0d4763
region.c File Reference
#include <win32k.h>
#include <suppress.h>
#include <debug.h>
Include dependency graph for region.c:

Go to the source code of this file.

Classes

struct  BRESINFO
 
struct  _EDGE_TABLE_ENTRY
 
struct  _SCANLINE_LIST
 
struct  EDGE_TABLE
 
struct  _SCANLINE_LISTBLOCK
 
struct  _POINTBLOCK
 

Macros

#define NDEBUG
 
#define COPY_RECTS(dest, src, nRects)
 
#define EMPTY_REGION(pReg)
 
#define REGION_NOT_EMPTY(pReg)   pReg->rdh.nCount
 
#define INRECT(r, x, y)
 
#define EXTENTCHECK(r1, r2)
 
#define BRESINITPGON(dy, x1, x2, xStart, d, m, m1, incr1, incr2)
 
#define BRESINCRPGON(d, minval, m, m1, incr1, incr2)
 
#define BRESINITPGONSTRUCT(dmaj, min1, min2, bres)
 
#define BRESINCRPGONSTRUCT(bres)   BRESINCRPGON(bres.d, bres.minor_axis, bres.m, bres.m1, bres.incr1, bres.incr2)
 
#define CLOCKWISE   1
 
#define COUNTERCLOCKWISE   -1
 
#define SLLSPERBLOCK   25
 
#define EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET)
 
#define EVALUATEEDGEEVENODD(pAET, pPrevAET, y)
 
#define LARGE_COORDINATE   INT_MAX
 
#define SMALL_COORDINATE   INT_MIN
 
#define NUMPTSTOBUFFER   200
 
#define RGN_DEFAULT_RECTS   2
 

Typedefs

typedef struct _EDGE_TABLE_ENTRY EDGE_TABLE_ENTRY
 
typedef struct _SCANLINE_LIST SCANLINE_LIST
 
typedef struct _SCANLINE_LISTBLOCK SCANLINE_LISTBLOCK
 
typedef BOOL(FASTCALLoverlapProcp) (PREGION, PRECT, PRECT, PRECT, PRECT, INT, INT)
 
typedef BOOL(FASTCALLnonOverlapProcp) (PREGION, PRECT, PRECT, INT, INT)
 
typedef struct _POINTBLOCK POINTBLOCK
 

Functions

static BOOL REGION_bGrowBufferSize (_Inout_ PREGION prgn, _In_ UINT cRects)
 
static __inline BOOL REGION_bEnsureBufferSize (_Inout_ PREGION prgn, _In_ UINT cRects)
 
FORCEINLINE VOID REGION_vAddRect (_Inout_ PREGION prgn, _In_ LONG left, _In_ LONG top, _In_ LONG right, _In_ LONG bottom)
 
static __inline BOOL REGION_bAddRect (_Inout_ PREGION prgn, _In_ LONG left, _In_ LONG top, _In_ LONG right, _In_ LONG bottom)
 
INT FASTCALL REGION_Complexity (PREGION prgn)
 
static BOOL FASTCALL REGION_CopyRegion (PREGION dst, PREGION src)
 
static VOID FASTCALL REGION_SetExtents (PREGION pReg)
 
INT FASTCALL REGION_CropRegion (PREGION rgnDst, PREGION rgnSrc, const RECTL *rect)
 
static INT FASTCALL REGION_Coalesce (PREGION pReg, INT prevStart, INT curStart)
 
static BOOL FASTCALL REGION_RegionOp (PREGION newReg, PREGION reg1, PREGION reg2, overlapProcp overlapFunc, nonOverlapProcp nonOverlap1Func, nonOverlapProcp nonOverlap2Func)
 
static BOOL FASTCALL REGION_IntersectO (PREGION pReg, PRECTL r1, PRECTL r1End, PRECTL r2, PRECTL r2End, INT top, INT bottom)
 
static BOOL FASTCALL REGION_IntersectRegion (PREGION newReg, PREGION reg1, PREGION reg2)
 
static BOOL FASTCALL REGION_UnionNonO (PREGION pReg, PRECTL r, PRECTL rEnd, INT top, INT bottom)
 
static __inline BOOL REGION_bMergeRect (_Inout_ PREGION prgn, _In_ LONG left, _In_ LONG top, _In_ LONG right, _In_ LONG bottom)
 
static BOOL FASTCALL REGION_UnionO (PREGION pReg, PRECTL r1, PRECTL r1End, PRECTL r2, PRECTL r2End, INT top, INT bottom)
 
static BOOL FASTCALL REGION_UnionRegion (PREGION newReg, PREGION reg1, PREGION reg2)
 
static BOOL FASTCALL REGION_SubtractNonO1 (PREGION pReg, PRECTL r, PRECTL rEnd, INT top, INT bottom)
 
static BOOL FASTCALL REGION_SubtractO (PREGION pReg, PRECTL r1, PRECTL r1End, PRECTL r2, PRECTL r2End, INT top, INT bottom)
 
static BOOL FASTCALL REGION_SubtractRegion (PREGION regD, PREGION regM, PREGION regS)
 
static BOOL FASTCALL REGION_XorRegion (PREGION dr, PREGION sra, PREGION srb)
 
BOOL FASTCALL REGION_UnionRectWithRgn (PREGION rgn, const RECTL *rect)
 
INT FASTCALL REGION_SubtractRectFromRgn (PREGION prgnDest, PREGION prgnSrc, const RECTL *prcl)
 
BOOL FASTCALL REGION_bCopy (PREGION dst, PREGION src)
 
BOOL FASTCALL REGION_bIntersectRegion (PREGION newReg, PREGION reg1, PREGION reg2)
 
static BOOL REGION_bMakeSimpleFrameRgn (_Inout_ PREGION prgn, _In_ PRECTL prclSrc, _In_ INT cx, _In_ INT cy)
 
static BOOL REGION_bMakeFrameRegion (_Inout_ PREGION prgnDest, _Inout_ PREGION prgnSrc, _In_ INT cx, _In_ INT cy)
 
HRGN FASTCALL GreCreateFrameRgn (HRGN hrgn, INT cx, INT cy)
 
BOOL FASTCALL REGION_bXformRgn (_Inout_ PREGION prgn, _In_ PMATRIX pmx)
 
PREGION FASTCALL REGION_AllocRgnWithHandle (INT nReg)
 
BOOL NTAPI REGION_bAllocRgnAttr (PREGION prgn)
 
PREGION FASTCALL REGION_AllocUserRgnWithHandle (INT nRgn)
 
static VOID REGION_vSyncRegion (_In_ PREGION prgn)
 
PREGION FASTCALL REGION_LockRgn (_In_ HRGN hrgn)
 
VOID FASTCALL REGION_UnlockRgn (_In_ PREGION prgn)
 
PREGION FASTCALL IntSysCreateRectpRgn (INT LeftRect, INT TopRect, INT RightRect, INT BottomRect)
 
VOID NTAPI REGION_vCleanup (PVOID ObjectBody)
 
VOID FASTCALL REGION_Delete (PREGION pRgn)
 
BOOL FASTCALL IntGdiSetRegionOwner (HRGN hRgn, DWORD OwnerMask)
 
INT FASTCALL IntGdiCombineRgn (PREGION prgnDest, PREGION prgnSrc1, PREGION prgnSrc2, INT iCombineMode)
 
INT FASTCALL REGION_GetRgnBox (PREGION Rgn, PRECTL pRect)
 
INT APIENTRY IntGdiGetRgnBox (HRGN hRgn, PRECTL pRect)
 
BOOL FASTCALL REGION_PtInRegion (PREGION prgn, INT X, INT Y)
 
BOOL FASTCALL REGION_RectInRegion (PREGION Rgn, const RECTL *rect)
 
VOID FASTCALL REGION_SetRectRgn (PREGION rgn, INT LeftRect, INT TopRect, INT RightRect, INT BottomRect)
 
BOOL FASTCALL REGION_bOffsetRgn (_Inout_ PREGION prgn, _In_ INT cx, _In_ INT cy)
 
static VOID FASTCALL REGION_InsertEdgeInET (EDGE_TABLE *ET, EDGE_TABLE_ENTRY *ETE, INT scanline, SCANLINE_LISTBLOCK **SLLBlock, INT *iSLLBlock)
 
static VOID FASTCALL REGION_loadAET (EDGE_TABLE_ENTRY *AET, EDGE_TABLE_ENTRY *ETEs)
 
static VOID FASTCALL REGION_computeWAET (EDGE_TABLE_ENTRY *AET)
 
static BOOL FASTCALL REGION_InsertionSort (EDGE_TABLE_ENTRY *AET)
 
static VOID FASTCALL REGION_FreeStorage (SCANLINE_LISTBLOCK *pSLLBlock)
 
static INT FASTCALL REGION_PtsToRegion (INT numFullPtBlocks, INT iCurPtBlock, POINTBLOCK *FirstPtBlock, PREGION reg)
 
static VOID FASTCALL REGION_CreateETandAET (const ULONG *Count, INT nbpolygons, const POINT *pts, EDGE_TABLE *ET, EDGE_TABLE_ENTRY *AET, EDGE_TABLE_ENTRY *pETEs, SCANLINE_LISTBLOCK *pSLLBlock)
 
BOOL FASTCALL REGION_SetPolyPolygonRgn (_Inout_ PREGION prgn, _In_ const POINT *ppt, _In_ const ULONG *pcPoints, _In_ ULONG cPolygons, _In_ INT iMode)
 
HRGN NTAPI GreCreatePolyPolygonRgn (_In_ const POINT *ppt, _In_ const ULONG *pcPoints, _In_ ULONG cPolygons, _In_ INT iMode)
 
BOOL FASTCALL IntRectInRegion (HRGN hRgn, LPRECTL rc)
 
INT APIENTRY NtGdiCombineRgn (IN HRGN hrgnDst, IN HRGN hrgnSrc1, IN HRGN hrgnSrc2, IN INT iMode)
 
HRGN APIENTRY NtGdiCreateEllipticRgn (INT Left, INT Top, INT Right, INT Bottom)
 
HRGN APIENTRY NtGdiCreateRectRgn (INT LeftRect, INT TopRect, INT RightRect, INT BottomRect)
 
HRGN APIENTRY NtGdiCreateRoundRectRgn (INT left, INT top, INT right, INT bottom, INT ellipse_width, INT ellipse_height)
 
BOOL APIENTRY NtGdiEqualRgn (HRGN hSrcRgn1, HRGN hSrcRgn2)
 
HRGN APIENTRY NtGdiExtCreateRegion (OPTIONAL LPXFORM Xform, DWORD Count, LPRGNDATA RgnData)
 
INT APIENTRY NtGdiGetRgnBox (HRGN hRgn, PRECTL pRect)
 
INT APIENTRY NtGdiOffsetRgn (_In_ HRGN hrgn, _In_ INT cx, _In_ INT cy)
 
BOOL APIENTRY NtGdiPtInRegion (_In_ HRGN hrgn, _In_ INT x, _In_ INT y)
 
__kernel_entry BOOL APIENTRY NtGdiRectInRegion (_In_ HRGN hrgn, _Inout_ LPRECT prclUnsafe)
 
BOOL APIENTRY NtGdiSetRectRgn (_In_ HRGN hrgn, _In_ INT xLeft, _In_ INT yTop, _In_ INT xRight, _In_ INT yBottom)
 
 _Success_ (return!=0)
 

Variables

PREGION prgnDefault = NULL
 
HRGN hrgnDefault = NULL
 

Macro Definition Documentation

◆ BRESINCRPGON

#define BRESINCRPGON (   d,
  minval,
  m,
  m1,
  incr1,
  incr2 
)
Value:
{ \
if (m1 > 0) { \
if (d > 0) { \
minval += m1; \
d += incr1; \
} \
else { \
minval += m; \
d += incr2; \
} \
} else {\
if (d >= 0) { \
minval += m1; \
d += incr1; \
} \
else { \
minval += m; \
d += incr2; \
} \
} \
}
const GLfloat * m
Definition: glext.h:10848
#define d
Definition: ke_i.h:81

Definition at line 218 of file region.c.

◆ BRESINCRPGONSTRUCT

#define BRESINCRPGONSTRUCT (   bres)    BRESINCRPGON(bres.d, bres.minor_axis, bres.m, bres.m1, bres.incr1, bres.incr2)

Definition at line 260 of file region.c.

◆ BRESINITPGON

#define BRESINITPGON (   dy,
  x1,
  x2,
  xStart,
  d,
  m,
  m1,
  incr1,
  incr2 
)
Value:
{ \
int dx; /* Local storage */ \
\
/* \
* If the edge is horizontal, then it is ignored \
* and assumed not to be processed. Otherwise, do this stuff. \
*/ \
if ((dy) != 0) { \
xStart = (x1); \
dx = (x2) - xStart; \
if (dx < 0) { \
m = dx / (dy); \
m1 = m - 1; \
incr1 = -2 * dx + 2 * (dy) * m1; \
incr2 = -2 * dx + 2 * (dy) * m; \
d = 2 * m * (dy) - 2 * dx - 2 * (dy); \
} else { \
m = dx / (dy); \
m1 = m + 1; \
incr1 = 2 * dx - 2 * (dy) * m1; \
incr2 = 2 * dx - 2 * (dy) * m; \
d = -2 * m * (dy) + 2 * dx; \
} \
} \
}
GLint dy
Definition: linetemp.h:97
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG x1
Definition: winddi.h:3706
const GLfloat * m
Definition: glext.h:10848
GLint dx
Definition: linetemp.h:97
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG _In_ LONG x2
Definition: winddi.h:3706

Definition at line 192 of file region.c.

◆ BRESINITPGONSTRUCT

#define BRESINITPGONSTRUCT (   dmaj,
  min1,
  min2,
  bres 
)
Value:
BRESINITPGON(dmaj, min1, min2, bres.minor_axis, bres.d, \
bres.m, bres.m1, bres.incr1, bres.incr2)
#define BRESINITPGON(dy, x1, x2, xStart, d, m, m1, incr1, incr2)
Definition: region.c:192

Definition at line 256 of file region.c.

◆ CLOCKWISE

#define CLOCKWISE   1

Definition at line 314 of file region.c.

◆ COPY_RECTS

#define COPY_RECTS (   dest,
  src,
  nRects 
)
Value:
do { \
PRECTL xDest = (dest); \
PRECTL xSrc = (src); \
UINT xRects = (nRects); \
while (xRects-- > 0) { \
*(xDest++) = *(xSrc++); \
} \
} while (0)
GLenum src
Definition: glext.h:6340
static char * dest
Definition: rtl.c:135

Definition at line 136 of file region.c.

◆ COUNTERCLOCKWISE

#define COUNTERCLOCKWISE   -1

Definition at line 315 of file region.c.

◆ EMPTY_REGION

#define EMPTY_REGION (   pReg)
Value:
{ \
(pReg)->rdh.nCount = 0; \
(pReg)->rdh.rcBound.left = (pReg)->rdh.rcBound.top = 0; \
(pReg)->rdh.rcBound.right = (pReg)->rdh.rcBound.bottom = 0; \
(pReg)->rdh.iType = RDH_RECTANGLES; \
}
#define RDH_RECTANGLES
Definition: wingdi.h:668

Definition at line 149 of file region.c.

◆ EVALUATEEDGEEVENODD

#define EVALUATEEDGEEVENODD (   pAET,
  pPrevAET,
  y 
)
Value:
{ \
if (pAET->ymax == y) { /* Leaving this edge */ \
pPrevAET->next = pAET->next; \
pAET = pPrevAET->next; \
if (pAET) \
pAET->back = pPrevAET; \
} \
else { \
BRESINCRPGONSTRUCT(pAET->bres); \
pPrevAET = pAET; \
pAET = pAET->next; \
} \
}
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548

Definition at line 393 of file region.c.

◆ EVALUATEEDGEWINDING

#define EVALUATEEDGEWINDING (   pAET,
  pPrevAET,
  y,
  fixWAET 
)
Value:
{ \
if (pAET->ymax == y) { /* Leaving this edge */ \
pPrevAET->next = pAET->next; \
pAET = pPrevAET->next; \
fixWAET = 1; \
if (pAET) \
pAET->back = pPrevAET; \
} \
else { \
BRESINCRPGONSTRUCT(pAET->bres); \
pPrevAET = pAET; \
pAET = pAET->next; \
} \
}
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548

Definition at line 370 of file region.c.

◆ EXTENTCHECK

#define EXTENTCHECK (   r1,
  r2 
)
Value:
((r1)->right > (r2)->left && \
(r1)->left < (r2)->right && \
(r1)->bottom > (r2)->top && \
(r1)->top < (r2)->bottom)
static DNS_RECORDW r1
Definition: record.c:37
GLint GLint bottom
Definition: glext.h:7726
static DNS_RECORDW r2
Definition: record.c:38
GLint left
Definition: glext.h:7726
GLdouble GLdouble right
Definition: glext.h:10859
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:10859

Definition at line 167 of file region.c.

◆ INRECT

#define INRECT (   r,
  x,
  y 
)
Value:
( ( ((r).right > x)) && \
( ((r).left <= x)) && \
( ((r).bottom > y)) && \
( ((r).top <= y)) )
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLint GLint bottom
Definition: glext.h:7726
GLdouble GLdouble right
Definition: glext.h:10859
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548

Definition at line 158 of file region.c.

◆ LARGE_COORDINATE

#define LARGE_COORDINATE   INT_MAX

Definition at line 413 of file region.c.

◆ NDEBUG

#define NDEBUG

Definition at line 127 of file region.c.

◆ NUMPTSTOBUFFER

#define NUMPTSTOBUFFER   200

Definition at line 524 of file region.c.

◆ REGION_NOT_EMPTY

#define REGION_NOT_EMPTY (   pReg)    pReg->rdh.nCount

Definition at line 156 of file region.c.

◆ RGN_DEFAULT_RECTS

#define RGN_DEFAULT_RECTS   2

Definition at line 526 of file region.c.

◆ SLLSPERBLOCK

#define SLLSPERBLOCK   25

Definition at line 349 of file region.c.

◆ SMALL_COORDINATE

#define SMALL_COORDINATE   INT_MIN

Definition at line 414 of file region.c.

Typedef Documentation

◆ EDGE_TABLE_ENTRY

◆ nonOverlapProcp

typedef BOOL(FASTCALL * nonOverlapProcp) (PREGION, PRECT, PRECT, INT, INT)

Definition at line 521 of file region.c.

◆ overlapProcp

typedef BOOL(FASTCALL * overlapProcp) (PREGION, PRECT, PRECT, PRECT, PRECT, INT, INT)

Definition at line 520 of file region.c.

◆ POINTBLOCK

◆ SCANLINE_LIST

◆ SCANLINE_LISTBLOCK

Function Documentation

◆ _Success_()

_Success_ ( return!  = 0)

MSDN: GetRegionData, Return Values:

"If the function succeeds and dwCount specifies an adequate number of bytes, the return value is always dwCount. If dwCount is too small or the function fails, the return value is 0. If lpRgnData is NULL, the return value is the required number of bytes.

If the function fails, the return value is zero."

Definition at line 4102 of file region.c.

4110 {
4111  ULONG cjRects, cjSize;
4112  PREGION prgn;
4113 
4114  /* Lock the region */
4115  prgn = REGION_LockRgn(hrgn);
4116  if (prgn == NULL)
4117  {
4119  return 0;
4120  }
4121 
4122  /* Calculate the region sizes */
4123  cjRects = prgn->rdh.nCount * sizeof(RECT);
4124  cjSize = cjRects + sizeof(RGNDATAHEADER);
4125 
4126  /* Check if region data is requested */
4127  if (lpRgnData)
4128  {
4129  /* Check if the buffer is large enough */
4130  if (cjBuffer >= cjSize)
4131  {
4132  /* Probe the buffer and copy the data */
4133  _SEH2_TRY
4134  {
4135  ProbeForWrite(lpRgnData, cjSize, sizeof(ULONG));
4136  RtlCopyMemory(lpRgnData, &prgn->rdh, sizeof(RGNDATAHEADER));
4137  RtlCopyMemory(lpRgnData->Buffer, prgn->Buffer, cjRects);
4138  lpRgnData->rdh.iType = RDH_RECTANGLES;
4139  lpRgnData->rdh.nRgnSize = cjRects;
4140  }
4142  {
4144  cjSize = 0;
4145  }
4146  _SEH2_END;
4147  }
4148  else
4149  {
4150  /* Buffer is too small */
4152  cjSize = 0;
4153  }
4154  }
4155 
4156  /* Unlock the region and return the size */
4157  REGION_UnlockRgn(prgn);
4158  return cjSize;
4159 }
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
struct _RGNDATAHEADER RGNDATAHEADER
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define ERROR_INVALID_HANDLE
Definition: compat.h:88
PREGION FASTCALL REGION_LockRgn(_In_ HRGN hrgn)
Definition: region.c:2377
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
_SEH2_TRY
Definition: create.c:4250
struct tagRECT RECT
RECTL * Buffer
Definition: region.h:16
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
smooth NULL
Definition: ftsmooth.c:416
Definition: region.h:7
#define RDH_RECTANGLES
Definition: wingdi.h:668
static HRGN hrgn
Definition: win.c:55
RGNDATAHEADER rdh
Definition: region.h:15
_SEH2_END
Definition: create.c:4424
VOID FASTCALL REGION_UnlockRgn(_In_ PREGION prgn)
Definition: region.c:2392
unsigned int ULONG
Definition: retypes.h:1
_In_ ULONG cjSize
Definition: winddi.h:3634
_In_ ULONG cjBuffer
Definition: ntgdi.h:2860
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:27

◆ GreCreateFrameRgn()

HRGN FASTCALL GreCreateFrameRgn ( HRGN  hrgn,
INT  cx,
INT  cy 
)

Definition at line 2041 of file region.c.

2045 {
2046  PREGION prgnFrame, prgnSrc;
2047  HRGN hrgnFrame;
2048 
2049  /* Allocate a new region */
2050  prgnFrame = REGION_AllocUserRgnWithHandle(1);
2051  if (prgnFrame == NULL)
2052  {
2054  return NULL;
2055  }
2056 
2057  /* Lock the source region */
2058  prgnSrc = REGION_LockRgn(hrgn);
2059  if (prgnSrc == NULL)
2060  {
2061  REGION_Delete(prgnFrame);
2062  return FALSE;
2063  }
2064 
2065  if (REGION_bMakeFrameRegion(prgnFrame, prgnSrc, cx, cy))
2066  {
2067  hrgnFrame = prgnFrame->BaseObject.hHmgr;
2068  REGION_UnlockRgn(prgnFrame);
2069  }
2070  else
2071  {
2072  REGION_Delete(prgnFrame);
2073  hrgnFrame = NULL;
2074  }
2075 
2076  REGION_UnlockRgn(prgnSrc);
2077  return hrgnFrame;
2078 }
BASEOBJECT BaseObject
Definition: region.h:11
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
PREGION FASTCALL REGION_LockRgn(_In_ HRGN hrgn)
Definition: region.c:2377
_Out_opt_ int _Out_opt_ int * cy
Definition: commctrl.h:570
HGDIOBJ hHmgr(VOID)
Definition: baseobj.hpp:95
smooth NULL
Definition: ftsmooth.c:416
Definition: region.h:7
static BOOL REGION_bMakeFrameRegion(_Inout_ PREGION prgnDest, _Inout_ PREGION prgnSrc, _In_ INT cx, _In_ INT cy)
Definition: region.c:1956
static HRGN hrgn
Definition: win.c:55
VOID FASTCALL REGION_UnlockRgn(_In_ PREGION prgn)
Definition: region.c:2392
_Out_opt_ int * cx
Definition: commctrl.h:570
PREGION FASTCALL REGION_AllocUserRgnWithHandle(INT nRgn)
Definition: region.c:2313
VOID FASTCALL REGION_Delete(PREGION pRgn)
Definition: region.c:2468
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:27

Referenced by NtGdiFrameRgn().

◆ GreCreatePolyPolygonRgn()

HRGN NTAPI GreCreatePolyPolygonRgn ( _In_ const POINT ppt,
_In_ const ULONG pcPoints,
_In_ ULONG  cPolygons,
_In_ INT  iMode 
)

Definition at line 3471 of file region.c.

3476 {
3477  PREGION prgn;
3478  HRGN hrgn;
3479 
3480  /* Allocate a new region */
3482  if (prgn == NULL)
3483  {
3485  return NULL;
3486  }
3487 
3488  /* Call the internal function and check for success */
3489  if (REGION_SetPolyPolygonRgn(prgn, ppt, pcPoints, cPolygons, iMode))
3490  {
3491  /* Success, get the handle and unlock the region */
3492  hrgn = prgn->BaseObject.hHmgr;
3493  REGION_UnlockRgn(prgn);
3494  }
3495  else
3496  {
3497  /* Failure, delete the region */
3498  REGION_Delete(prgn);
3499  hrgn = NULL;
3500  }
3501 
3502  return hrgn;
3503 }
BASEOBJECT BaseObject
Definition: region.h:11
BOOL FASTCALL REGION_SetPolyPolygonRgn(_Inout_ PREGION prgn, _In_ const POINT *ppt, _In_ const ULONG *pcPoints, _In_ ULONG cPolygons, _In_ INT iMode)
Definition: region.c:3275
_In_ ULONG iMode
Definition: winddi.h:3520
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
HGDIOBJ hHmgr(VOID)
Definition: baseobj.hpp:95
smooth NULL
Definition: ftsmooth.c:416
Definition: region.h:7
static HRGN hrgn
Definition: win.c:55
VOID FASTCALL REGION_UnlockRgn(_In_ PREGION prgn)
Definition: region.c:2392
PREGION FASTCALL REGION_AllocUserRgnWithHandle(INT nRgn)
Definition: region.c:2313
VOID FASTCALL REGION_Delete(PREGION pRgn)
Definition: region.c:2468
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:27

Referenced by NtGdiPolyPolyDraw().

◆ IntGdiCombineRgn()

INT FASTCALL IntGdiCombineRgn ( PREGION  prgnDest,
PREGION  prgnSrc1,
PREGION  prgnSrc2,
INT  iCombineMode 
)

Definition at line 2506 of file region.c.

2511 {
2512  BOOL Ret = TRUE;
2513 
2514  if (prgnDest == NULL)
2515  {
2516  DPRINT("IntGdiCombineRgn: hDest unavailable\n");
2517  return ERROR;
2518  }
2519 
2520  if (prgnSrc1 == NULL)
2521  {
2522  DPRINT("IntGdiCombineRgn: hSrc1 unavailable\n");
2523  return ERROR;
2524  }
2525 
2526  if (iCombineMode == RGN_COPY)
2527  {
2528  if (!REGION_CopyRegion(prgnDest, prgnSrc1))
2529  return ERROR;
2530 
2531  return REGION_Complexity(prgnDest);
2532  }
2533 
2534  if (prgnSrc2 == NULL)
2535  {
2536  DPRINT1("IntGdiCombineRgn requires hSrc2 != NULL for combine mode %d!\n", iCombineMode);
2537  ASSERT(FALSE);
2538  return ERROR;
2539  }
2540 
2541  switch (iCombineMode)
2542  {
2543  case RGN_AND:
2544  Ret = REGION_IntersectRegion(prgnDest, prgnSrc1, prgnSrc2);
2545  break;
2546  case RGN_OR:
2547  Ret = REGION_UnionRegion(prgnDest, prgnSrc1, prgnSrc2);
2548  break;
2549  case RGN_XOR:
2550  Ret = REGION_XorRegion(prgnDest, prgnSrc1, prgnSrc2);
2551  break;
2552  case RGN_DIFF:
2553  Ret = REGION_SubtractRegion(prgnDest, prgnSrc1, prgnSrc2);
2554  break;
2555  }
2556 
2557  return Ret ? REGION_Complexity(prgnDest) : ERROR;
2558 }
static BOOL FASTCALL REGION_CopyRegion(PREGION dst, PREGION src)
Definition: region.c:587
#define TRUE
Definition: types.h:120
#define ERROR(name)
Definition: error_private.h:53
static BOOL FASTCALL REGION_XorRegion(PREGION dr, PREGION sra, PREGION srb)
Definition: region.c:1768
#define RGN_AND
Definition: wingdi.h:355
unsigned int BOOL
Definition: ntddk_ex.h:94
#define RGN_XOR
Definition: wingdi.h:359
smooth NULL
Definition: ftsmooth.c:416
#define RGN_OR
Definition: wingdi.h:358
void DPRINT(...)
Definition: polytest.cpp:61
static BOOL FASTCALL REGION_UnionRegion(PREGION newReg, PREGION reg1, PREGION reg2)
Definition: region.c:1478
static BOOL FASTCALL REGION_SubtractRegion(PREGION regD, PREGION regM, PREGION regS)
Definition: region.c:1732
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define RGN_COPY
Definition: wingdi.h:356
#define RGN_DIFF
Definition: wingdi.h:357
#define DPRINT1
Definition: precomp.h:8
INT FASTCALL REGION_Complexity(PREGION prgn)
Definition: region.c:567
static BOOL FASTCALL REGION_IntersectRegion(PREGION newReg, PREGION reg1, PREGION reg2)
Definition: region.c:1306

Referenced by _Success_(), co_IntGetUpdateRgn(), co_UserRedrawWindow(), co_VIS_WindowLayoutChanged(), co_WinPosSetWindowPos(), DC_vCopyState(), DceUpdateVisRgn(), ForceNCPaintErase(), IntGdiBitBltRgn(), IntGdiFillRgn(), IntInvalidateWindows(), IntScrollWindowEx(), IntValidateParents(), NtGdiCombineRgn(), NtGdiGetRandomRgn(), REGION_LPTODP(), UserScrollDC(), and VIS_ComputeVisibleRegion().

◆ IntGdiGetRgnBox()

INT APIENTRY IntGdiGetRgnBox ( HRGN  hRgn,
PRECTL  pRect 
)

Definition at line 2580 of file region.c.

2583 {
2584  PREGION Rgn;
2585  DWORD ret;
2586 
2587  Rgn = REGION_LockRgn(hRgn);
2588  if (Rgn == NULL)
2589  {
2590  return ERROR;
2591  }
2592 
2593  ret = REGION_GetRgnBox(Rgn, pRect);
2594  REGION_UnlockRgn(Rgn);
2595 
2596  return ret;
2597 }
#define ERROR(name)
Definition: error_private.h:53
static HRGN hRgn
Definition: mapping.c:33
PREGION FASTCALL REGION_LockRgn(_In_ HRGN hrgn)
Definition: region.c:2377
smooth NULL
Definition: ftsmooth.c:416
Definition: region.h:7
unsigned long DWORD
Definition: ntddk_ex.h:95
int ret
VOID FASTCALL REGION_UnlockRgn(_In_ PREGION prgn)
Definition: region.c:2392
INT FASTCALL REGION_GetRgnBox(PREGION Rgn, PRECTL pRect)
Definition: region.c:2562

Referenced by co_UserGetUpdateRect(), and IntGetNCUpdateRgn().

◆ IntGdiSetRegionOwner()

BOOL FASTCALL IntGdiSetRegionOwner ( HRGN  hRgn,
DWORD  OwnerMask 
)

Definition at line 2478 of file region.c.

2479 {
2480  PREGION prgn;
2481  PRGN_ATTR prgnattr;
2482  PPROCESSINFO ppi;
2483 
2484  prgn = REGION_LockRgn(hRgn);
2485  if (prgn == NULL)
2486  {
2487  return FALSE;
2488  }
2489 
2490  prgnattr = prgn->prgnattr;
2491  if (prgnattr != &prgn->rgnattr)
2492  {
2494  prgn->prgnattr = &prgn->rgnattr;
2496  GdiPoolFree(ppi->pPoolRgnAttr, prgnattr);
2497  }
2498 
2499  REGION_UnlockRgn(prgn);
2500 
2501  return GreSetObjectOwner(hRgn, OwnerMask);
2502 }
BASEOBJECT BaseObject
Definition: region.h:11
BOOL NTAPI GreSetObjectOwner(HGDIOBJ hobj, ULONG ulOwner)
Definition: gdiobj.c:1252
VOID NTAPI GdiPoolFree(PGDI_POOL pPool, PVOID pvAlloc)
Definition: gdipool.c:233
static HRGN hRgn
Definition: mapping.c:33
PREGION FASTCALL REGION_LockRgn(_In_ HRGN hrgn)
Definition: region.c:2377
_Notnull_ PRGN_ATTR prgnattr
Definition: region.h:12
smooth NULL
Definition: ftsmooth.c:416
Definition: region.h:7
RGN_ATTR rgnattr
Definition: region.h:13
VOID NTAPI GDIOBJ_vSetObjectAttr(POBJ pobj, PVOID pvObjAttr)
Definition: gdiobj.c:1093
struct _GDI_POOL * pPoolRgnAttr
Definition: win32.h:284
PVOID NTAPI PsGetCurrentProcessWin32Process(VOID)
Definition: process.c:1183
VOID FASTCALL REGION_UnlockRgn(_In_ PREGION prgn)
Definition: region.c:2392

Referenced by co_UserFreeWindow(), ForceNCPaintErase(), IntBeginPaint(), IntGetNCUpdateRgn(), IntInvalidateWindows(), SelectWindowRgn(), and UserUpdateMonitorSize().

◆ IntRectInRegion()

BOOL FASTCALL IntRectInRegion ( HRGN  hRgn,
LPRECTL  rc 
)

Definition at line 3507 of file region.c.

3510 {
3511  PREGION Rgn;
3512  BOOL Ret;
3513 
3514  Rgn = REGION_LockRgn(hRgn);
3515  if (Rgn == NULL)
3516  {
3517  return ERROR;
3518  }
3519 
3520  Ret = REGION_RectInRegion(Rgn, rc);
3521  REGION_UnlockRgn(Rgn);
3522  return Ret;
3523 }
#define ERROR(name)
Definition: error_private.h:53
static HRGN hRgn
Definition: mapping.c:33
PREGION FASTCALL REGION_LockRgn(_In_ HRGN hrgn)
Definition: region.c:2377
unsigned int BOOL
Definition: ntddk_ex.h:94
smooth NULL
Definition: ftsmooth.c:416
BOOL FASTCALL REGION_RectInRegion(PREGION Rgn, const RECTL *rect)
Definition: region.c:2625
Definition: region.h:7
VOID FASTCALL REGION_UnlockRgn(_In_ PREGION prgn)
Definition: region.c:2392

Referenced by NtGdiRectInRegion().

◆ IntSysCreateRectpRgn()

PREGION FASTCALL IntSysCreateRectpRgn ( INT  LeftRect,
INT  TopRect,
INT  RightRect,
INT  BottomRect 
)

Definition at line 2426 of file region.c.

2431 {
2432  PREGION prgn;
2433 
2434  /* Allocate a region, without a handle */
2436  if (prgn == NULL)
2437  {
2438  return NULL;
2439  }
2440 
2441  /* Initialize it */
2442  prgn->Buffer = &prgn->rdh.rcBound;
2443  prgn->prgnattr = &prgn->rgnattr;
2445  REGION_SetRectRgn(prgn, LeftRect, TopRect, RightRect, BottomRect);
2446 
2447  return prgn;
2448 }
#define ATTR_RGN_VALID
Definition: ntgdihdl.h:210
_Notnull_ PRGN_ATTR prgnattr
Definition: region.h:12
RECTL * Buffer
Definition: region.h:16
smooth NULL
Definition: ftsmooth.c:416
Definition: region.h:7
ULONG AttrFlags
Definition: ntgdihdl.h:269
RGN_ATTR rgnattr
Definition: region.h:13
RGNDATAHEADER rdh
Definition: region.h:15
struct _REGION * PREGION
VOID FASTCALL REGION_SetRectRgn(PREGION rgn, INT LeftRect, INT TopRect, INT RightRect, INT BottomRect)
Definition: region.c:2685
POBJ NTAPI GDIOBJ_AllocateObject(UCHAR objt, ULONG cjSize, FLONG fl)
Definition: gdiobj.c:559

Referenced by _Success_(), CLIPPING_UpdateGCRegion(), co_UserRedrawWindow(), co_VIS_WindowLayoutChanged(), co_WinPosSetWindowPos(), DC_InitHack(), DC_vCopyState(), DC_vInitDc(), DC_vUpdateDC(), DceGetVisRgn(), DceUpdateVisRgn(), IntGdiBitBltRgn(), IntGdiFillRgn(), IntGdiSetMetaRgn(), IntInvalidateWindows(), IntScrollWindowEx(), IntSetDefaultRegion(), NtGdiExcludeClipRect(), NtGdiSelectClipPath(), and PATH_FillPathEx().

◆ NtGdiCombineRgn()

INT APIENTRY NtGdiCombineRgn ( IN HRGN  hrgnDst,
IN HRGN  hrgnSrc1,
IN HRGN  hrgnSrc2,
IN INT  iMode 
)

Definition at line 3531 of file region.c.

3536 {
3537  HRGN ahrgn[3];
3538  PREGION aprgn[3];
3539  INT iResult;
3540 
3541  /* Validate the combine mode */
3542  if ((iMode < RGN_AND) || (iMode > RGN_COPY))
3543  {
3544  return ERROR;
3545  }
3546 
3547  /* Validate that we have the required regions */
3548  if ((hrgnDst == NULL) ||
3549  (hrgnSrc1 == NULL) ||
3550  ((iMode != RGN_COPY) && (hrgnSrc2 == NULL)))
3551  {
3552  DPRINT1("NtGdiCombineRgn invalid parameters: %p, %p, %p, %d\n",
3553  hrgnDst, hrgnSrc1, hrgnSrc2, iMode);
3555  return ERROR;
3556  }
3557 
3558  /* Lock all regions */
3559  ahrgn[0] = hrgnDst;
3560  ahrgn[1] = hrgnSrc1;
3561  ahrgn[2] = iMode != RGN_COPY ? hrgnSrc2 : NULL;
3562  if (!GDIOBJ_bLockMultipleObjects(3, (HGDIOBJ*)ahrgn, (PVOID*)aprgn, GDIObjType_RGN_TYPE))
3563  {
3564  DPRINT1("NtGdiCombineRgn failed to lock regions: %p, %p, %p, %d\n",
3565  hrgnDst, hrgnSrc1, hrgnSrc2, iMode);
3566  return ERROR;
3567  }
3568 
3569  /* HACK: Sync usermode attributes */
3570  REGION_vSyncRegion(aprgn[0]);
3571  if (aprgn[1] != aprgn[0])
3572  REGION_vSyncRegion(aprgn[1]);
3573  if ((aprgn[2] != NULL) && (aprgn[2] != aprgn[0]) && (aprgn[2] != aprgn[1]))
3574  REGION_vSyncRegion(aprgn[2]);
3575 
3576  /* Call the internal function */
3577  iResult = IntGdiCombineRgn(aprgn[0], aprgn[1], aprgn[2], iMode);
3578 
3579  /* Unlock and return */
3580  REGION_UnlockRgn(aprgn[0]);
3581  REGION_UnlockRgn(aprgn[1]);
3582  if (aprgn[2] != NULL)
3583  REGION_UnlockRgn(aprgn[2]);
3584 
3585  return iResult;
3586 }
_In_ ULONG iMode
Definition: winddi.h:3520
#define ERROR(name)
Definition: error_private.h:53
_In_ HANDLE _In_ HANDLE hrgnSrc2
Definition: winddi.h:4295
#define ERROR_INVALID_HANDLE
Definition: compat.h:88
int32_t INT
Definition: typedefs.h:56
#define RGN_AND
Definition: wingdi.h:355
_In_ HANDLE hrgnSrc1
Definition: winddi.h:4295
smooth NULL
Definition: ftsmooth.c:416
Definition: region.h:7
BOOL NTAPI GDIOBJ_bLockMultipleObjects(IN ULONG ulCount, IN HGDIOBJ *ahObj, OUT PGDIOBJ *apObj, IN UCHAR objt)
Definition: gdiobj.c:1028
INT FASTCALL IntGdiCombineRgn(PREGION prgnDest, PREGION prgnSrc1, PREGION prgnSrc2, INT iCombineMode)
Definition: region.c:2506
#define RGN_COPY
Definition: wingdi.h:356
#define DPRINT1
Definition: precomp.h:8
VOID FASTCALL REGION_UnlockRgn(_In_ PREGION prgn)
Definition: region.c:2392
static VOID REGION_vSyncRegion(_In_ PREGION prgn)
Definition: region.c:2334
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:27

Referenced by CombineRgn().

◆ NtGdiCreateEllipticRgn()

HRGN APIENTRY NtGdiCreateEllipticRgn ( INT  Left,
INT  Top,
INT  Right,
INT  Bottom 
)

Definition at line 3590 of file region.c.

3595 {
3596  return NtGdiCreateRoundRectRgn(Left,
3597  Top,
3598  Right, Bottom,
3599  Right - Left,
3600  Bottom - Top);
3601 }
HRGN APIENTRY NtGdiCreateRoundRectRgn(INT left, INT top, INT right, INT bottom, INT ellipse_width, INT ellipse_height)
Definition: region.c:3634
static LPHIST_ENTRY Bottom
Definition: history.c:54
static LPHIST_ENTRY Top
Definition: history.c:53

Referenced by CreateEllipticRgnIndirect().

◆ NtGdiCreateRectRgn()

HRGN APIENTRY NtGdiCreateRectRgn ( INT  LeftRect,
INT  TopRect,
INT  RightRect,
INT  BottomRect 
)

Definition at line 3605 of file region.c.

3610 {
3611  PREGION pRgn;
3612  HRGN hRgn;
3613 
3614  /* Allocate region data structure with space for 1 RECTL */
3616  if (pRgn == NULL)
3617  {
3619  return NULL;
3620  }
3621 
3622  hRgn = pRgn->BaseObject.hHmgr;
3623 
3624  REGION_SetRectRgn(pRgn, LeftRect, TopRect, RightRect, BottomRect);
3625  REGION_UnlockRgn(pRgn);
3626 
3627  DPRINT("Returning %p.\n", hRgn);
3628 
3629  return hRgn;
3630 }
BASEOBJECT BaseObject
Definition: region.h:11
static HRGN hRgn
Definition: mapping.c:33
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
HGDIOBJ hHmgr(VOID)
Definition: baseobj.hpp:95
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
Definition: region.h:7
VOID FASTCALL REGION_UnlockRgn(_In_ PREGION prgn)
Definition: region.c:2392
VOID FASTCALL REGION_SetRectRgn(PREGION rgn, INT LeftRect, INT TopRect, INT RightRect, INT BottomRect)
Definition: region.c:2685
PREGION FASTCALL REGION_AllocUserRgnWithHandle(INT nRgn)
Definition: region.c:2313
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:27

Referenced by CreateRectRgn(), and NtGdiCreateRoundRectRgn().

◆ NtGdiCreateRoundRectRgn()

HRGN APIENTRY NtGdiCreateRoundRectRgn ( INT  left,
INT  top,
INT  right,
INT  bottom,
INT  ellipse_width,
INT  ellipse_height 
)

Definition at line 3634 of file region.c.

3641 {
3642  PREGION obj;
3643  HRGN hrgn;
3644  int a, b, i, x, y;
3645  INT64 asq, bsq, dx, dy, err;
3646  RECT *rects;
3647 
3648  /* Make the dimensions sensible */
3649  if (left > right)
3650  {
3651  INT tmp = left;
3652  left = right;
3653  right = tmp;
3654  }
3655 
3656  if (top > bottom)
3657  {
3658  INT tmp = top;
3659  top = bottom;
3660  bottom = tmp;
3661  }
3662 
3663  /* the region is for the rectangle interior, but only at right and bottom for some reason */
3664  right--;
3665  bottom--;
3666 
3667  ellipse_width = min( right - left, abs( ellipse_width ));
3668  ellipse_height = min( bottom - top, abs( ellipse_height ));
3669 
3670  /* Check if we can do a normal rectangle instead */
3671 
3672  if ((ellipse_width < 2) || (ellipse_height < 2))
3673  return NtGdiCreateRectRgn(left, top, right, bottom);
3674 
3675  obj = REGION_AllocUserRgnWithHandle( ellipse_height );
3676  if (obj == NULL)
3677  return 0;
3678 
3679  hrgn = obj->BaseObject.hHmgr;
3680 
3681  obj->rdh.rcBound.left = left;
3682  obj->rdh.rcBound.top = top;
3683  obj->rdh.rcBound.right = right;
3684  obj->rdh.rcBound.bottom = bottom;
3685  rects = obj->Buffer;
3686 
3687  /* based on an algorithm by Alois Zingl */
3688 
3689  a = ellipse_width - 1;
3690  b = ellipse_height - 1;
3691  asq = (INT64)8 * a * a;
3692  bsq = (INT64)8 * b * b;
3693  dx = (INT64)4 * b * b * (1 - a);
3694  dy = (INT64)4 * a * a * (1 + (b % 2));
3695  err = dx + dy + a * a * (b % 2);
3696 
3697  x = 0;
3698  y = ellipse_height / 2;
3699 
3700  rects[y].left = left;
3701  rects[y].right = right;
3702 
3703  while (x <= ellipse_width / 2)
3704  {
3705  INT64 e2 = 2 * err;
3706  if (e2 >= dx)
3707  {
3708  x++;
3709  err += dx += bsq;
3710  }
3711  if (e2 <= dy)
3712  {
3713  y++;
3714  err += dy += asq;
3715  rects[y].left = left + x;
3716  rects[y].right = right - x;
3717  }
3718  }
3719  for (i = 0; i < ellipse_height / 2; i++)
3720  {
3721  rects[i].left = rects[b - i].left;
3722  rects[i].right = rects[b - i].right;
3723  rects[i].top = top + i;
3724  rects[i].bottom = rects[i].top + 1;
3725  }
3726  for (; i < ellipse_height; i++)
3727  {
3728  rects[i].top = bottom - ellipse_height + i;
3729  rects[i].bottom = rects[i].top + 1;
3730  }
3731  rects[ellipse_height / 2].top = top + ellipse_height / 2; /* extend to top of rectangle */
3732 
3734  return hrgn;
3735 }
#define abs(i)
Definition: fconv.c:206
GLint dy
Definition: linetemp.h:97
LONG top
Definition: windef.h:292
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
LONG left
Definition: windef.h:291
LONG right
Definition: windef.h:293
HRGN APIENTRY NtGdiCreateRectRgn(INT LeftRect, INT TopRect, INT RightRect, INT BottomRect)
Definition: region.c:3605
int32_t INT
Definition: typedefs.h:56
GLsizei GLsizei GLuint * obj
Definition: glext.h:6042
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define a
Definition: ke_i.h:78
smooth NULL
Definition: ftsmooth.c:416
GLint GLint bottom
Definition: glext.h:7726
Definition: region.h:7
#define b
Definition: ke_i.h:79
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLint left
Definition: glext.h:7726
GLdouble GLdouble right
Definition: glext.h:10859
static HRGN hrgn
Definition: win.c:55
signed long long INT64
#define err(...)
#define min(a, b)
Definition: monoChain.cc:55
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLint dx
Definition: linetemp.h:97
VOID FASTCALL REGION_UnlockRgn(_In_ PREGION prgn)
Definition: region.c:2392
LONG bottom
Definition: windef.h:294
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:10859
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
PREGION FASTCALL REGION_AllocUserRgnWithHandle(INT nRgn)
Definition: region.c:2313

Referenced by NtGdiCreateEllipticRgn().

◆ NtGdiEqualRgn()

BOOL APIENTRY NtGdiEqualRgn ( HRGN  hSrcRgn1,
HRGN  hSrcRgn2 
)

Definition at line 3739 of file region.c.

3742 {
3743  HRGN ahrgn[2];
3744  PREGION aprgn[2];
3745  PREGION rgn1, rgn2;
3746  PRECTL tRect1, tRect2;
3747  ULONG i;
3748  BOOL bRet = FALSE;
3749 
3750  /* Check if we got 2 regions */
3751  if ((hSrcRgn1 == NULL) || (hSrcRgn2 == NULL))
3752  {
3753  return FALSE;
3754  }
3755 
3756  /* Check if these are the same regions */
3757  if (hSrcRgn1 == hSrcRgn2)
3758  {
3759  /* Make sure this region is valid */
3760  if ((GDI_HANDLE_GET_TYPE(hSrcRgn1) == GDILoObjType_LO_REGION_TYPE) &&
3761  GreIsHandleValid(hSrcRgn1))
3762  {
3763  return TRUE;
3764  }
3765  return FALSE;
3766  }
3767 
3768  /* Lock both regions */
3769  ahrgn[0] = hSrcRgn1;
3770  ahrgn[1] = hSrcRgn2;
3771  if (!GDIOBJ_bLockMultipleObjects(2, (HGDIOBJ*)ahrgn, (PVOID*)aprgn, GDIObjType_RGN_TYPE))
3772  {
3773  DPRINT1("NtGdiEqualRgn failed to lock regions: %p, %p\n",
3774  hSrcRgn1, hSrcRgn2);
3775  return FALSE;
3776  }
3777 
3778  REGION_vSyncRegion(aprgn[0]);
3779  REGION_vSyncRegion(aprgn[1]);
3780 
3781  rgn1 = aprgn[0];
3782  rgn2 = aprgn[1];
3783 
3784  if (rgn1->rdh.nCount != rgn2->rdh.nCount)
3785  goto exit;
3786 
3787  if (rgn1->rdh.nCount == 0)
3788  {
3789  bRet = TRUE;
3790  goto exit;
3791  }
3792 
3793  if ((rgn1->rdh.rcBound.left != rgn2->rdh.rcBound.left) ||
3794  (rgn1->rdh.rcBound.right != rgn2->rdh.rcBound.right) ||
3795  (rgn1->rdh.rcBound.top != rgn2->rdh.rcBound.top) ||
3796  (rgn1->rdh.rcBound.bottom != rgn2->rdh.rcBound.bottom))
3797  goto exit;
3798 
3799  tRect1 = rgn1->Buffer;
3800  tRect2 = rgn2->Buffer;
3801 
3802  if ((tRect1 == NULL) || (tRect2 == NULL))
3803  goto exit;
3804 
3805  for (i=0; i < rgn1->rdh.nCount; i++)
3806  {
3807  if ((tRect1[i].left != tRect2[i].left) ||
3808  (tRect1[i].right != tRect2[i].right) ||
3809  (tRect1[i].top != tRect2[i].top) ||
3810  (tRect1[i].bottom != tRect2[i].bottom))
3811  goto exit;
3812  }
3813 
3814  bRet = TRUE;
3815 
3816 exit:
3817  REGION_UnlockRgn(rgn1);
3818  REGION_UnlockRgn(rgn2);
3819  return bRet;
3820 }
#define TRUE
Definition: types.h:120
BOOL NTAPI GreIsHandleValid(HGDIOBJ hobj)
Definition: gdiobj.c:1143
LONG top
Definition: windef.h:292
LONG left
Definition: windef.h:291
LONG right
Definition: windef.h:293
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
unsigned int BOOL
Definition: ntddk_ex.h:94
RECTL * Buffer
Definition: region.h:16
smooth NULL
Definition: ftsmooth.c:416
GLint GLint bottom
Definition: glext.h:7726
Definition: region.h:7
BOOL NTAPI GDIOBJ_bLockMultipleObjects(IN ULONG ulCount, IN HGDIOBJ *ahObj, OUT PGDIOBJ *apObj, IN UCHAR objt)
Definition: gdiobj.c:1028
#define GDI_HANDLE_GET_TYPE(h)
Definition: gdi.h:31
GLint left
Definition: glext.h:7726
GLdouble GLdouble right
Definition: glext.h:10859
RGNDATAHEADER rdh
Definition: region.h:15
#define DPRINT1
Definition: precomp.h:8
VOID FASTCALL REGION_UnlockRgn(_In_ PREGION prgn)
Definition: region.c:2392
unsigned int ULONG
Definition: retypes.h:1
LONG bottom
Definition: windef.h:294
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:10859
void exit(int exitcode)
Definition: _exit.c:33
static VOID REGION_vSyncRegion(_In_ PREGION prgn)
Definition: region.c:2334

◆ NtGdiExtCreateRegion()

HRGN APIENTRY NtGdiExtCreateRegion ( OPTIONAL LPXFORM  Xform,
DWORD  Count,
LPRGNDATA  RgnData 
)

Definition at line 3824 of file region.c.

3828 {
3829  HRGN hRgn;
3830  PREGION Region;
3831  DWORD nCount = 0;
3832  DWORD iType = 0;
3833  DWORD dwSize = 0;
3834  UINT i;
3835  RECT* rects;
3837  MATRIX matrix;
3838  XFORMOBJ xo;
3839 
3840  DPRINT("NtGdiExtCreateRegion\n");
3841  _SEH2_TRY
3842  {
3843  ProbeForRead(RgnData, Count, 1);
3844  nCount = RgnData->rdh.nCount;
3845  iType = RgnData->rdh.iType;
3846  dwSize = RgnData->rdh.dwSize;
3847  rects = (RECT*)RgnData->Buffer;
3848  }
3850  {
3852  }
3853  _SEH2_END;
3854 
3855  if (!NT_SUCCESS(Status))
3856  {
3858  return NULL;
3859  }
3860 
3861  /* Check parameters, but don't set last error here */
3862  if ((Count < sizeof(RGNDATAHEADER) + nCount * sizeof(RECT)) ||
3863  (iType != RDH_RECTANGLES) ||
3864  (dwSize != sizeof(RGNDATAHEADER)))
3865  {
3866  return NULL;
3867  }
3868 
3870 
3871  if (Region == NULL)
3872  {
3874  return FALSE;
3875  }
3876  hRgn = Region->BaseObject.hHmgr;
3877 
3878  _SEH2_TRY
3879  {
3880  /* Insert the rectangles one by one */
3881  for(i=0; i<nCount; i++)
3882  {
3883  if ( rects[i].left < rects[i].right && rects[i].top < rects[i].bottom )
3884  {
3885  if (!REGION_UnionRectWithRgn(Region, &rects[i]))
3886  {
3889  hRgn = NULL;
3890  _SEH2_LEAVE;
3891  }
3892  }
3893  }
3894 
3895  if (Xform != NULL)
3896  {
3897  ULONG ret;
3898 
3899  /* Init the XFORMOBJ from the Xform struct */
3901  XFORMOBJ_vInit(&xo, &matrix);
3902  ret = XFORMOBJ_iSetXform(&xo, (XFORML*)Xform);
3903 
3904  /* Check for error */
3905  if (ret != DDI_ERROR)
3906  {
3907  /* Apply the coordinate transformation on the rects */
3908  if (XFORMOBJ_bApplyXform(&xo,
3909  XF_LTOL,
3910  Region->rdh.nCount * 2,
3911  Region->Buffer,
3912  Region->Buffer))
3913  {
3915  }
3916  }
3917  }
3918  }
3920  {
3922  }
3923  _SEH2_END;
3924  if (!NT_SUCCESS(Status))
3925  {
3929  return NULL;
3930  }
3931 
3933 
3934  return hRgn;
3935 }
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
BOOL NTAPI GreDeleteObject(HGDIOBJ hobj)
Definition: gdiobj.c:1155
#define XFORMOBJ_bApplyXform
Definition: xformobj.h:11
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
GLuint GLenum matrix
Definition: glext.h:9407
_In_ ULONG iType
Definition: winddi.h:3748
LONG NTSTATUS
Definition: precomp.h:26
char Buffer[1]
Definition: axextend.idl:395
static HRGN hRgn
Definition: mapping.c:33
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
#define XFORMOBJ_iSetXform
Definition: xformobj.h:14
FORCEINLINE VOID XFORMOBJ_vInit(OUT XFORMOBJ *pxo, IN MATRIX *pmx)
Definition: xformobj.h:21
_SEH2_TRY
Definition: create.c:4250
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
smooth NULL
Definition: ftsmooth.c:416
#define DDI_ERROR
Definition: winddi.h:154
void DPRINT(...)
Definition: polytest.cpp:61
GLint GLint bottom
Definition: glext.h:7726
Definition: region.h:7
#define XF_LTOL
Definition: winddi.h:3109
BOOL FASTCALL REGION_UnionRectWithRgn(PREGION rgn, const RECTL *rect)
Definition: region.c:1812
#define RDH_RECTANGLES
Definition: wingdi.h:668
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Definition: matrix.h:43
unsigned long DWORD
Definition: ntddk_ex.h:95
GLint left
Definition: glext.h:7726
GLdouble GLdouble right
Definition: glext.h:10859
int ret
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
VOID FASTCALL SetLastNtError(NTSTATUS Status)
Definition: error.c:36
Status
Definition: gdiplustypes.h:24
_SEH2_END
Definition: create.c:4424
unsigned int UINT
Definition: ndis.h:50
RGNDATAHEADER rdh
Definition: axextend.idl:394
VOID FASTCALL REGION_UnlockRgn(_In_ PREGION prgn)
Definition: region.c:2392
unsigned int ULONG
Definition: retypes.h:1
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:10859
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
#define _SEH2_LEAVE
Definition: filesup.c:20
PREGION FASTCALL REGION_AllocUserRgnWithHandle(INT nRgn)
Definition: region.c:2313
return STATUS_SUCCESS
Definition: btrfs.c:2966
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:54
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:27

Referenced by ExtCreateRegion().

◆ NtGdiGetRgnBox()

INT APIENTRY NtGdiGetRgnBox ( HRGN  hRgn,
PRECTL  pRect 
)

Definition at line 3939 of file region.c.

3942 {
3943  PREGION Rgn;
3944  RECTL SafeRect;
3945  DWORD ret;
3947 
3948  Rgn = REGION_LockRgn(hRgn);
3949  if (Rgn == NULL)
3950  {
3951  return ERROR;
3952  }
3953 
3954  ret = REGION_GetRgnBox(Rgn, &SafeRect);
3955  REGION_UnlockRgn(Rgn);
3956  if (ret == ERROR)
3957  {
3958  return ret;
3959  }
3960 
3961  _SEH2_TRY
3962  {
3963  ProbeForWrite(pRect, sizeof(RECT), 1);
3964  *pRect = SafeRect;
3965  }
3967  {
3969  }
3970  _SEH2_END;
3971  if (!NT_SUCCESS(Status))
3972  {
3973  return ERROR;
3974  }
3975 
3976  return ret;
3977 }
#define ERROR(name)
Definition: error_private.h:53
LONG NTSTATUS
Definition: precomp.h:26
static HRGN hRgn
Definition: mapping.c:33
PREGION FASTCALL REGION_LockRgn(_In_ HRGN hrgn)
Definition: region.c:2377
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
_SEH2_TRY
Definition: create.c:4250
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
smooth NULL
Definition: ftsmooth.c:416
Definition: region.h:7
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
unsigned long DWORD
Definition: ntddk_ex.h:95
int ret
Status
Definition: gdiplustypes.h:24
_SEH2_END
Definition: create.c:4424
VOID FASTCALL REGION_UnlockRgn(_In_ PREGION prgn)
Definition: region.c:2392
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
INT FASTCALL REGION_GetRgnBox(PREGION Rgn, PRECTL pRect)
Definition: region.c:2562
return STATUS_SUCCESS
Definition: btrfs.c:2966

Referenced by GetRgnBox().

◆ NtGdiOffsetRgn()

INT APIENTRY NtGdiOffsetRgn ( _In_ HRGN  hrgn,
_In_ INT  cx,
_In_ INT  cy 
)

Definition at line 3981 of file region.c.

3985 {
3986  PREGION prgn;
3987  INT iResult;
3988 
3989  DPRINT("NtGdiOffsetRgn: hrgn %p cx %d cy %d\n", hrgn, cx, cy);
3990 
3991  /* Lock the region */
3992  prgn = REGION_LockRgn(hrgn);
3993  if (prgn == NULL)
3994  {
3995  DPRINT1("NtGdiOffsetRgn: failed to lock region %p\n", hrgn);
3996  return ERROR;
3997  }
3998 
3999  /* Call the internal function */
4000  if (!REGION_bOffsetRgn(prgn, cx, cy))
4001  {
4002  iResult = ERROR;
4003  }
4004  else
4005  {
4006  iResult = REGION_Complexity(prgn);
4007  }
4008 
4009  /* Unlock and return the result */
4010  REGION_UnlockRgn(prgn);
4011  return iResult;
4012 }
#define ERROR(name)
Definition: error_private.h:53
BOOL FASTCALL REGION_bOffsetRgn(_Inout_ PREGION prgn, _In_ INT cx, _In_ INT cy)
Definition: region.c:2727
PREGION FASTCALL REGION_LockRgn(_In_ HRGN hrgn)
Definition: region.c:2377
int32_t INT
Definition: typedefs.h:56
_Out_opt_ int _Out_opt_ int * cy
Definition: commctrl.h:570
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
Definition: region.h:7
static HRGN hrgn
Definition: win.c:55
#define DPRINT1
Definition: precomp.h:8
VOID FASTCALL REGION_UnlockRgn(_In_ PREGION prgn)
Definition: region.c:2392
_Out_opt_ int * cx
Definition: commctrl.h:570
INT FASTCALL REGION_Complexity(PREGION prgn)
Definition: region.c:567

Referenced by co_UserExcludeUpdateRgn(), co_UserGetUpdateRgn(), co_WinPosSetWindowPos(), DceResetActiveDCEs(), IntCalcWindowRgn(), and OffsetRgn().

◆ NtGdiPtInRegion()

BOOL APIENTRY NtGdiPtInRegion ( _In_ HRGN  hrgn,
_In_ INT  x,
_In_ INT  y 
)

Definition at line 4016 of file region.c.

4020 {
4021  PREGION prgn;
4022  BOOL bResult;
4023 
4024  /* Lock the region */
4025  prgn = REGION_LockRgn(hrgn);
4026  if (prgn == NULL)
4027  {
4028  DPRINT1("NtGdiPtInRegion: hrgn error\n");
4029  return FALSE;
4030  }
4031 
4032  /* Call the internal function */
4033  bResult = REGION_PtInRegion(prgn, x, y);
4034 
4035  /* Unlock and return the result */
4036  REGION_UnlockRgn(prgn);
4037  return bResult;
4038 }
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
PREGION FASTCALL REGION_LockRgn(_In_ HRGN hrgn)
Definition: region.c:2377
unsigned int BOOL
Definition: ntddk_ex.h:94
smooth NULL
Definition: ftsmooth.c:416
Definition: region.h:7
static HRGN hrgn
Definition: win.c:55
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
#define DPRINT1
Definition: precomp.h:8
VOID FASTCALL REGION_UnlockRgn(_In_ PREGION prgn)
Definition: region.c:2392
BOOL FASTCALL REGION_PtInRegion(PREGION prgn, INT X, INT Y)
Definition: region.c:2602

Referenced by IntPtInWindow(), and PtInRegion().

◆ NtGdiRectInRegion()

__kernel_entry BOOL APIENTRY NtGdiRectInRegion ( _In_ HRGN  hrgn,
_Inout_ LPRECT  prclUnsafe 
)

Definition at line 4043 of file region.c.

4046 {
4047  RECTL rcTemp;
4048 
4049  /* Probe and copy the rect */
4050  _SEH2_TRY
4051  {
4052  ProbeForRead(prclUnsafe, sizeof(RECT), 1);
4053  rcTemp = *prclUnsafe;
4054  }
4056  {
4057  DPRINT1("NtGdiRectInRegion: Exception accessing the rect\n");
4058  return FALSE;
4059  }
4060  _SEH2_END;
4061 
4062  /* Call the internal function */
4063  return IntRectInRegion(hrgn, &rcTemp);
4064 }
_SEH2_TRY
Definition: create.c:4250
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
BOOL FASTCALL IntRectInRegion(HRGN hRgn, LPRECTL rc)
Definition: region.c:3507
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
static HRGN hrgn
Definition: win.c:55
_SEH2_END
Definition: create.c:4424
#define DPRINT1
Definition: precomp.h:8
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6

Referenced by RectInRegion().

◆ NtGdiSetRectRgn()

BOOL APIENTRY NtGdiSetRectRgn ( _In_ HRGN  hrgn,
_In_ INT  xLeft,
_In_ INT  yTop,
_In_ INT  xRight,
_In_ INT  yBottom 
)

Definition at line 4068 of file region.c.

4074 {
4075  PREGION prgn;
4076 
4077  /* Lock the region */
4078  prgn = REGION_LockRgn(hrgn);
4079  if (prgn == NULL)
4080  {
4081  return FALSE;
4082  }
4083 
4084  /* Call the internal API */
4085  REGION_SetRectRgn(prgn, xLeft, yTop, xRight, yBottom);
4086 
4087  /* Unlock the region and return success */
4088  REGION_UnlockRgn(prgn);
4089  return TRUE;
4090 }
#define TRUE
Definition: types.h:120
PREGION FASTCALL REGION_LockRgn(_In_ HRGN hrgn)
Definition: region.c:2377
smooth NULL
Definition: ftsmooth.c:416
Definition: region.h:7
static HRGN hrgn
Definition: win.c:55
VOID FASTCALL REGION_UnlockRgn(_In_ PREGION prgn)
Definition: region.c:2392
VOID FASTCALL REGION_SetRectRgn(PREGION rgn, INT LeftRect, INT TopRect, INT RightRect, INT BottomRect)
Definition: region.c:2685

Referenced by co_UserGetUpdateRgn(), and SetRectRgn().

◆ REGION_AllocRgnWithHandle()

PREGION FASTCALL REGION_AllocRgnWithHandle ( INT  nReg)

Definition at line 2219 of file region.c.

2221 {
2222  //HRGN hReg;
2223  PREGION pReg;
2224 
2226  sizeof(REGION),
2228  if (pReg == NULL)
2229  {
2230  DPRINT1("Could not allocate a palette.\n");
2231  return NULL;
2232  }
2233 
2234  //hReg = pReg->BaseObject.hHmgr;
2235 
2236  if ((nReg == 0) || (nReg == 1))
2237  {
2238  /* Testing shows that > 95% of all regions have only 1 rect.
2239  Including that here saves us from having to do another allocation */
2240  pReg->Buffer = &pReg->rdh.rcBound;
2241  }
2242  else
2243  {
2245  nReg * sizeof(RECT),
2246  TAG_REGION);
2247  if (pReg->Buffer == NULL)
2248  {
2249  DPRINT1("Could not allocate region buffer\n");
2251  return NULL;
2252  }
2253  }
2254 
2255  EMPTY_REGION(pReg);
2256  pReg->rdh.dwSize = sizeof(RGNDATAHEADER);
2257  pReg->rdh.nCount = nReg;
2258  pReg->rdh.nRgnSize = nReg * sizeof(RECT);
2259  pReg->prgnattr = &pReg->rgnattr;
2260 
2261  /* Initialize the region attribute */
2262  pReg->rgnattr.AttrFlags = 0;
2264  pReg->rgnattr.Rect = pReg->rdh.rcBound;
2265 
2266  /* Finally insert the region into the handle table */
2268  {
2269  DPRINT1("Could not insert palette into handle table.\n");
2271  return NULL;
2272  }
2273 
2274  return pReg;
2275 }
BASEOBJECT BaseObject
Definition: region.h:11
struct _RGNDATAHEADER RGNDATAHEADER
#define TAG_REGION
Definition: tags.h:22
struct tagRECT RECT
_Notnull_ PRGN_ATTR prgnattr
Definition: region.h:12
RECTL * Buffer
Definition: region.h:16
smooth NULL
Definition: ftsmooth.c:416
Definition: region.h:7
ULONG AttrFlags
Definition: ntgdihdl.h:269
VOID NTAPI GDIOBJ_vDeleteObject(POBJ pobj)
Definition: gdiobj.c:1108
RGN_ATTR rgnattr
Definition: region.h:13
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define GDI_OBJ_HMGR_POWNED
Definition: ntgdihdl.h:117
ULONG iComplexity
Definition: ntgdihdl.h:270
RGNDATAHEADER rdh
Definition: region.h:15
#define SIMPLEREGION
Definition: wingdi.h:361
#define EMPTY_REGION(pReg)
Definition: region.c:149
#define DPRINT1
Definition: precomp.h:8
RECTL Rect
Definition: ntgdihdl.h:271
struct _REGION * PREGION
POBJ NTAPI GDIOBJ_AllocateObject(UCHAR objt, ULONG cjSize, FLONG fl)
Definition: gdiobj.c:559
VOID NTAPI GDIOBJ_vFreeObject(POBJ pobj)
Definition: gdiobj.c:593
HGDIOBJ NTAPI GDIOBJ_hInsertObject(POBJ pobj, ULONG ulOwner)
Definition: gdiobj.c:909

Referenced by REGION_AllocUserRgnWithHandle(), and REGION_XorRegion().

◆ REGION_AllocUserRgnWithHandle()

PREGION FASTCALL REGION_AllocUserRgnWithHandle ( INT  nRgn)

Definition at line 2313 of file region.c.

2315 {
2316  PREGION prgn;
2317 
2318  prgn = REGION_AllocRgnWithHandle(nRgn);
2319  if (prgn == NULL)
2320  {
2321  return NULL;
2322  }
2323 
2324  if (!REGION_bAllocRgnAttr(prgn))
2325  {
2326  ASSERT(FALSE);
2327  }
2328 
2329  return prgn;
2330 }
smooth NULL
Definition: ftsmooth.c:416
Definition: region.h:7
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
BOOL NTAPI REGION_bAllocRgnAttr(PREGION prgn)
Definition: region.c:2279
PREGION FASTCALL REGION_AllocRgnWithHandle(INT nReg)
Definition: region.c:2219

Referenced by GreCreateFrameRgn(), GreCreatePolyPolygonRgn(), NtGdiCreateRectRgn(), NtGdiCreateRoundRectRgn(), NtGdiExtCreateRegion(), and NtGdiPathToRegion().

◆ REGION_bAddRect()

static __inline BOOL REGION_bAddRect ( _Inout_ PREGION  prgn,
_In_ LONG  left,
_In_ LONG  top,
_In_ LONG  right,
_In_ LONG  bottom 
)
static

Definition at line 504 of file region.c.

510 {
511  if (!REGION_bEnsureBufferSize(prgn, prgn->rdh.nCount + 1))
512  {
513  return FALSE;
514  }
515 
516  REGION_vAddRect(prgn, left, top, right, bottom);
517  return TRUE;
518 }
#define TRUE
Definition: types.h:120
GLint GLint bottom
Definition: glext.h:7726
static __inline BOOL REGION_bEnsureBufferSize(_Inout_ PREGION prgn, _In_ UINT cRects)
Definition: region.c:468
GLint left
Definition: glext.h:7726
GLdouble GLdouble right
Definition: glext.h:10859
FORCEINLINE VOID REGION_vAddRect(_Inout_ PREGION prgn, _In_ LONG left, _In_ LONG top, _In_ LONG right, _In_ LONG bottom)
Definition: region.c:484
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:10859

Referenced by REGION_bMergeRect(), REGION_IntersectO(), and REGION_SubtractO().

◆ REGION_bAllocRgnAttr()

BOOL NTAPI REGION_bAllocRgnAttr ( PREGION  prgn)

Definition at line 2279 of file region.c.

2281 {
2282  PPROCESSINFO ppi;
2283  PRGN_ATTR prgnattr;
2284 
2285  NT_ASSERT(prgn->prgnattr == &prgn->rgnattr);
2286 
2288  ASSERT(ppi);
2289 
2290  prgnattr = GdiPoolAllocate(ppi->pPoolRgnAttr);
2291  if (prgnattr == NULL)
2292  {
2293  DPRINT1("Could not allocate RGN attr\n");
2294  return FALSE;
2295  }
2296 
2297  /* Copy the current region attribute */
2298  *prgnattr = prgn->rgnattr;
2299 
2300  /* Set the object attribute in the handle table */
2301  prgn->prgnattr = prgnattr;
2302  GDIOBJ_vSetObjectAttr(&prgn->BaseObject, prgnattr);
2303 
2304  return TRUE;
2305 }
BASEOBJECT BaseObject
Definition: region.h:11
#define TRUE
Definition: types.h:120
_Notnull_ PRGN_ATTR prgnattr
Definition: region.h:12
smooth NULL
Definition: ftsmooth.c:416
PVOID NTAPI GdiPoolAllocate(PGDI_POOL pPool)
Definition: gdipool.c:122
RGN_ATTR rgnattr
Definition: region.h:13
VOID NTAPI GDIOBJ_vSetObjectAttr(POBJ pobj, PVOID pvObjAttr)
Definition: gdiobj.c:1093
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
struct _GDI_POOL * pPoolRgnAttr
Definition: win32.h:284
PVOID NTAPI PsGetCurrentProcessWin32Process(VOID)
Definition: process.c:1183
#define DPRINT1
Definition: precomp.h:8
#define NT_ASSERT
Definition: rtlfuncs.h:3312

Referenced by REGION_AllocUserRgnWithHandle().

◆ REGION_bCopy()

BOOL FASTCALL REGION_bCopy ( PREGION  dst,
PREGION  src 
)

Definition at line 1844 of file region.c.

1847 {
1848  if ( !dst || !src ) return FALSE;
1849  return REGION_CopyRegion( dst, src);
1850 }
static BOOL FASTCALL REGION_CopyRegion(PREGION dst, PREGION src)
Definition: region.c:587
GLenum src
Definition: glext.h:6340
GLenum GLenum dst
Definition: glext.h:6340

Referenced by _Success_(), CLIPPING_UpdateGCRegion(), and GdiSelectVisRgn().

◆ REGION_bEnsureBufferSize()

static __inline BOOL REGION_bEnsureBufferSize ( _Inout_ PREGION  prgn,
_In_ UINT  cRects 
)
static

Definition at line 468 of file region.c.

471 {
472  /* Check if the current region size is too small */
473  if (cRects > prgn->rdh.nRgnSize / sizeof(RECTL))
474  {
475  /* Allocate a new buffer */
476  return REGION_bGrowBufferSize(prgn, cRects);
477  }
478 
479  return TRUE;
480 }
#define TRUE
Definition: types.h:120
static BOOL REGION_bGrowBufferSize(_Inout_ PREGION prgn, _In_ UINT cRects)
Definition: region.c:418

Referenced by REGION_bAddRect(), REGION_SubtractNonO1(), REGION_SubtractO(), and REGION_UnionNonO().

◆ REGION_bGrowBufferSize()

static BOOL REGION_bGrowBufferSize ( _Inout_ PREGION  prgn,
_In_ UINT  cRects 
)
static

Definition at line 418 of file region.c.

421 {
422  ULONG cjNewSize;
423  PVOID pvBuffer;
424  NT_ASSERT(cRects > 0);
425 
426  /* Make sure we don't overflow */
427  if (cRects > MAXULONG / sizeof(RECTL))
428  {
429  return FALSE;
430  }
431 
432  /* Calculate new buffer size */
433  cjNewSize = cRects * sizeof(RECTL);
434 
435  /* Avoid allocating too often, by duplicating the old buffer size
436  Note: we don't do an overflow check, since the old size will never
437  get that large before running out of memory. */
438  if (2 * prgn->rdh.nRgnSize > cjNewSize)
439  {
440  cjNewSize = 2 * prgn->rdh.nRgnSize;
441  }
442 
443  /* Allocate the new buffer */
444  pvBuffer = ExAllocatePoolWithTag(PagedPool, cjNewSize, TAG_REGION);
445  if (pvBuffer == NULL)
446  {
447  return FALSE;
448  }
449 
450  /* Copy the rects into the new buffer */
451  COPY_RECTS(pvBuffer, prgn->Buffer, prgn->rdh.nCount);
452 
453  /* Free the old buffer */
454  if (prgn->Buffer != &prgn->rdh.rcBound)
455  {
456  ExFreePoolWithTag(prgn->Buffer, TAG_REGION);
457  }
458 
459  /* Set the new buffer */
460  prgn->Buffer = pvBuffer;
461  prgn->rdh.nRgnSize = cjNewSize;
462 
463  return TRUE;
464 }
#define TRUE
Definition: types.h:120
#define TAG_REGION
Definition: tags.h:22
smooth NULL
Definition: ftsmooth.c:416
#define COPY_RECTS(dest, src, nRects)
Definition: region.c:136
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define MAXULONG
Definition: typedefs.h:250
unsigned int ULONG
Definition: retypes.h:1
struct RECTL RECTL
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define NT_ASSERT
Definition: rtlfuncs.h:3312

Referenced by REGION_bEnsureBufferSize().

◆ REGION_bIntersectRegion()

BOOL FASTCALL REGION_bIntersectRegion ( PREGION  newReg,
PREGION  reg1,
PREGION  reg2 
)

Definition at line 1854 of file region.c.

1858 {
1859  if ( !newReg || !reg1 || !reg2 ) return FALSE;
1860  return REGION_IntersectRegion( newReg, reg1, reg2);
1861 }
static BOOL FASTCALL REGION_IntersectRegion(PREGION newReg, PREGION reg1, PREGION reg2)
Definition: region.c:1306

Referenced by CLIPPING_UpdateGCRegion(), and IntGdiSetMetaRgn().

◆ REGION_bMakeFrameRegion()

static BOOL REGION_bMakeFrameRegion ( _Inout_ PREGION  prgnDest,
_Inout_ PREGION  prgnSrc,
_In_ INT  cx,
_In_ INT  cy 
)
static

Definition at line 1956 of file region.c.

1961 {
1962  /* Handle negative cx / cy */
1963  cx = abs(cx);
1964  cy = abs(cy);
1965 
1966  /* Check border size (the cast is necessary to catch cx/cy == INT_MIN!) */
1967  if (((UINT)cx > MAX_COORD) || ((UINT)cy > MAX_COORD))
1968  {
1969  return FALSE;
1970  }
1971 
1972  /* Fail on empty source region */
1973  if (!REGION_NOT_EMPTY(prgnSrc))
1974  {
1975  return FALSE;
1976  }
1977 
1978  /* Handle trivial case */
1979  if ((cx == 0) && (cy == 0))
1980  {
1981  EMPTY_REGION(prgnDest);
1982  return TRUE;
1983  }
1984 
1985  /* Handle simple source region */
1986  if (REGION_Complexity(prgnSrc) == SIMPLEREGION)
1987  {
1988  return REGION_bMakeSimpleFrameRgn(prgnDest, &prgnSrc->rdh.rcBound, cx, cy);
1989  }
1990 
1991  /* Check if we can move the region to create the frame region */
1992  if ((prgnSrc->rdh.rcBound.left < (MIN_COORD + cx)) ||
1993  (prgnSrc->rdh.rcBound.top < (MIN_COORD + cy)) ||
1994  (prgnSrc->rdh.rcBound.right > (MAX_COORD - cx)) ||
1995  (prgnSrc->rdh.rcBound.bottom > (MAX_COORD - cy)))
1996  {
1997  return FALSE;
1998  }
1999 
2000  /* Copy the source region */
2001  if (!REGION_CopyRegion(prgnDest, prgnSrc))
2002  {
2003  return FALSE;
2004  }
2005 
2006  /* Move the source region to the bottom-right */
2007  NT_VERIFY(REGION_bOffsetRgn(prgnSrc, cx, cy));
2008 
2009  /* Intersect with the source region (this crops the top-left frame) */
2010  REGION_IntersectRegion(prgnDest, prgnDest, prgnSrc);
2011 
2012  /* Move the source region to the bottom-left */
2013  NT_VERIFY(REGION_bOffsetRgn(prgnSrc, -2 * cx, 0));
2014 
2015  /* Intersect with the source region (this crops the top-right frame) */
2016  REGION_IntersectRegion(prgnDest, prgnDest, prgnSrc);
2017 
2018  /* Move the source region to the top-left */
2019  NT_VERIFY(REGION_bOffsetRgn(prgnSrc, 0, -2 * cy));
2020 
2021  /* Intersect with the source region (this crops the bottom-right frame) */
2022  REGION_IntersectRegion(prgnDest, prgnDest, prgnSrc);
2023 
2024  /* Move the source region to the top-right */
2025  NT_VERIFY(REGION_bOffsetRgn(prgnSrc, 2 * cx, 0));
2026 
2027  /* Intersect with the source region (this crops the bottom-left frame) */
2028  REGION_IntersectRegion(prgnDest, prgnDest, prgnSrc);
2029 
2030  /* Move the source region back to the original position */
2031  NT_VERIFY(REGION_bOffsetRgn(prgnSrc, -cx, cy));
2032 
2033  /* Finally subtract the cropped region from the source */
2034  REGION_SubtractRegion(prgnDest, prgnSrc, prgnDest);
2035 
2036  return TRUE;
2037 }
static BOOL FASTCALL REGION_CopyRegion(PREGION dst, PREGION src)
Definition: region.c:587
#define abs(i)
Definition: fconv.c:206
#define TRUE
Definition: types.h:120
#define REGION_NOT_EMPTY(pReg)
Definition: region.c:156
BOOL FASTCALL REGION_bOffsetRgn(_Inout_ PREGION prgn, _In_ INT cx, _In_ INT cy)
Definition: region.c:2727
#define NT_VERIFY(exp)
Definition: rtlfuncs.h:3289
#define MAX_COORD
Definition: region.c:12
_Out_opt_ int _Out_opt_ int * cy
Definition: commctrl.h:570
static BOOL FASTCALL REGION_SubtractRegion(PREGION regD, PREGION regM, PREGION regS)
Definition: region.c:1732
static BOOL REGION_bMakeSimpleFrameRgn(_Inout_ PREGION prgn, _In_ PRECTL prclSrc, _In_ INT cx, _In_ INT cy)
Definition: region.c:1865
#define SIMPLEREGION
Definition: wingdi.h:361
#define EMPTY_REGION(pReg)
Definition: region.c:149
unsigned int UINT
Definition: ndis.h:50
_Out_opt_ int * cx
Definition: commctrl.h:570
INT FASTCALL REGION_Complexity(PREGION prgn)
Definition: region.c:567
static BOOL FASTCALL REGION_IntersectRegion(PREGION newReg, PREGION reg1, PREGION reg2)
Definition: region.c:1306
#define MIN_COORD
Definition: region.c:11

Referenced by GreCreateFrameRgn().

◆ REGION_bMakeSimpleFrameRgn()

static BOOL REGION_bMakeSimpleFrameRgn ( _Inout_ PREGION  prgn,
_In_ PRECTL  prclSrc,
_In_ INT  cx,
_In_ INT  cy 
)
static

Definition at line 1865 of file region.c.

1870 {
1871  RECTL arcl[4];
1872  UINT i;
1873 
1874  NT_ASSERT((cx >= 0) && (cy >= 0));
1875  NT_ASSERT((prclSrc->bottom > prclSrc->top) &&
1876  (prclSrc->right > prclSrc->left));
1877 
1878  /* Start with an empty region */
1879  EMPTY_REGION(prgn);
1880 
1881  /* Check for the case where the frame covers the whole rect */
1882  if (((prclSrc->bottom - prclSrc->top) <= cy * 2) ||
1883  ((prclSrc->right - prclSrc->left) <= cx * 2))
1884  {
1885  prgn->rdh.rcBound = *prclSrc;
1886  prgn->Buffer[0] = *prclSrc;
1887  prgn->rdh.nCount = 1;
1888  return TRUE;
1889  }
1890 
1891  i = 0;
1892 
1893  if (cy != 0)
1894  {
1895  /* Top rectangle */
1896  arcl[i].left = prclSrc->left;
1897  arcl[i].top = prclSrc->top;
1898  arcl[i].right = prclSrc->right;
1899  arcl[i].bottom = prclSrc->top + cy;
1900  i++;
1901  }
1902 
1903  if (cx != 0)
1904  {
1905  /* Left rectangle */
1906  arcl[i].left = prclSrc->left;
1907  arcl[i].top = prclSrc->top + cy;
1908  arcl[i].right = prclSrc->left + cx;
1909  arcl[i].bottom = prclSrc->bottom - cy;
1910  i++;
1911 
1912  /* Right rectangle */
1913  arcl[i].left = prclSrc->right - cx;
1914  arcl[i].top = prclSrc->top + cy;
1915  arcl[i].right = prclSrc->right;
1916  arcl[i].bottom = prclSrc->bottom - cy;
1917  i++;
1918  }
1919 
1920  if (cy != 0)
1921  {
1922  /* Bottom rectangle */
1923  arcl[i].left = prclSrc->left;
1924  arcl[i].top = prclSrc->bottom - cy;
1925  arcl[i].right = prclSrc->right;
1926  arcl[i].bottom = prclSrc->bottom;
1927  i++;
1928  }
1929 
1930  if (i != 0)
1931  {
1932  /* The frame results in a complex region. rcBounds remains
1933  the same, though. */
1934  prgn->rdh.nCount = i;
1935  NT_ASSERT(prgn->rdh.nCount > 1);
1936  prgn->rdh.nRgnSize = prgn->rdh.nCount * sizeof(RECT);
1937  NT_ASSERT(prgn->Buffer == &prgn->rdh.rcBound);
1938  prgn->Buffer = ExAllocatePoolWithTag(PagedPool,
1939  prgn->rdh.nRgnSize,
1940  TAG_REGION);
1941  if (prgn->Buffer == NULL)
1942  {
1943  prgn->rdh.nRgnSize = 0;
1944  return FALSE;
1945  }
1946 
1948  COPY_RECTS(prgn->Buffer, arcl, prgn->rdh.nCount);
1949  }
1950 
1951  return TRUE;
1952 }
#define TRUE
Definition: types.h:120
#define TAG_REGION
Definition: tags.h:22
long bottom
Definition: polytest.cpp:53
struct tagRECT RECT
long right
Definition: polytest.cpp:53
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
long top
Definition: polytest.cpp:53
_Out_opt_ int _Out_opt_ int * cy
Definition: commctrl.h:570
smooth NULL
Definition: ftsmooth.c:416
long left
Definition: polytest.cpp:53
_In_ SURFOBJ _In_ CLIPOBJ _In_opt_ XLATEOBJ _In_ RECTL _In_ RECTL * prclSrc
Definition: winddi.h:3414
#define COPY_RECTS(dest, src, nRects)
Definition: region.c:136
#define __WARNING_MAYBE_UNINIT_VAR
Definition: suppress.h:598
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define EMPTY_REGION(pReg)
Definition: region.c:149
unsigned int UINT
Definition: ndis.h:50
_Out_opt_ int * cx
Definition: commctrl.h:570
#define _PRAGMA_WARNING_SUPPRESS(x)
Definition: suppress.h:28
#define NT_ASSERT
Definition: rtlfuncs.h:3312

Referenced by REGION_bMakeFrameRegion().

◆ REGION_bMergeRect()

static __inline BOOL REGION_bMergeRect ( _Inout_ PREGION  prgn,
_In_ LONG  left,
_In_ LONG  top,
_In_ LONG  right,
_In_ LONG  bottom 
)
static

Definition at line 1385 of file region.c.

1391 {
1392  if ((prgn->rdh.nCount != 0) &&
1393  (prgn->Buffer[prgn->rdh.nCount - 1].top == top) &&
1394  (prgn->Buffer[prgn->rdh.nCount - 1].bottom == bottom) &&
1395  (prgn->Buffer[prgn->rdh.nCount - 1].right >= left))
1396  {
1397  if (prgn->Buffer[prgn->rdh.nCount - 1].right < right)
1398  {
1399  prgn->Buffer[prgn->rdh.nCount - 1].right = right;
1400  }
1401  }
1402  else
1403  {
1404  if (!REGION_bAddRect(prgn, left, top, right, bottom))
1405  {
1406  return FALSE;
1407  }
1408  }
1409 
1410  return TRUE;
1411 }
#define TRUE
Definition: types.h:120
static __inline BOOL REGION_bAddRect(_Inout_ PREGION prgn, _In_ LONG left, _In_ LONG top, _In_ LONG right, _In_ LONG bottom)
Definition: region.c:504
GLint GLint bottom
Definition: glext.h:7726
GLint left
Definition: glext.h:7726
GLdouble GLdouble right
Definition: glext.h:10859
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:10859

Referenced by REGION_UnionO().

◆ REGION_bOffsetRgn()

BOOL FASTCALL REGION_bOffsetRgn ( _Inout_ PREGION  prgn,
_In_ INT  cx,
_In_ INT  cy 
)

Definition at line 2727 of file region.c.

2731 {
2732  PRECTL prcl;
2733  UINT i;
2734 
2735  NT_ASSERT(prgn != NULL);
2736 
2737  /* Check for trivial case */
2738  if ((cx == 0) && (cy == 0))
2739  {
2740  return TRUE;
2741  }
2742 
2743  /* Check for empty regions, we ignore the offset values here */
2744  if (prgn->rdh.nCount == 0)
2745  {
2746  return TRUE;
2747  }
2748 
2749  /* Make sure the offset is within the legal range */
2750  if ((cx > MAX_COORD) || (cx < MIN_COORD) ||
2751  (cy > MAX_COORD) || (cy < MIN_COORD))
2752  {
2753  return FALSE;
2754  }
2755 
2756  /* Are we moving right? */
2757  if (cx > 0)
2758  {
2759  /* Check if we stay inside the bounds on the right side */
2760  if (prgn->rdh.rcBound.right > (MAX_COORD - cx))
2761  {
2762  return FALSE;
2763  }
2764  }
2765  else
2766  {
2767  /* Check if we stay inside the bounds on the left side */
2768  if (prgn->rdh.rcBound.left < (MIN_COORD - cx))
2769  {
2770  return FALSE;
2771  }
2772  }
2773 
2774  /* Are we moving down? */
2775  if (cy > 0)
2776  {
2777  /* Check if we stay inside the bounds on the right side */
2778  if (prgn->rdh.rcBound.bottom > (MAX_COORD - cy))
2779  {
2780  return FALSE;
2781  }
2782  }
2783  else
2784  {
2785  /* Check if we stay inside the bounds on the left side */
2786  if (prgn->rdh.rcBound.top < (MIN_COORD - cy))
2787  {
2788  return FALSE;
2789  }
2790  }
2791 
2792  /* Loop to move the rects */
2793  prcl = prgn->Buffer;
2794  for (i = 0; i < prgn->rdh.nCount; i++)
2795  {
2796  prcl[i].left += cx;
2797  prcl[i].right += cx;
2798  prcl[i].top += cy;
2799  prcl[i].bottom += cy;
2800  }
2801 
2802  /* Finally update the bounds rect */
2803  if (prgn->Buffer != &prgn->rdh.rcBound)
2804  {
2805  prgn->rdh.rcBound.left += cx;
2806  prgn->rdh.rcBound.right += cx;
2807  prgn->rdh.rcBound.top += cy;
2808  prgn->rdh.rcBound.bottom += cy;
2809  }
2810 
2811  return TRUE;
2812 }
#define TRUE
Definition: types.h:120
#define MAX_COORD
Definition: region.c:12
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
_Out_opt_ int _Out_opt_ int * cy
Definition: commctrl.h:570
smooth NULL
Definition: ftsmooth.c:416
unsigned int UINT
Definition: ndis.h:50
_In_ ULONG _In_ CLIPOBJ _In_ RECTL * prcl
Definition: winddi.h:3529
_Out_opt_ int * cx
Definition: commctrl.h:570
#define MIN_COORD
Definition: region.c:11
#define NT_ASSERT
Definition: rtlfuncs.h:3312

Referenced by CLIPPING_UpdateGCRegion(), co_IntGetUpdateRgn(), co_UserRedrawWindow(), co_VIS_WindowLayoutChanged(), co_WinPosSetWindowPos(), DceResetActiveDCEs(), GdiSelectVisRgn(), IntGdiBitBltRgn(), IntGdiFillRgn(), IntInvalidateWindows(), IntScrollWindowEx(), NtGdiGetRandomRgn(), NtGdiOffsetClipRgn(), NtGdiOffsetRgn(), REGION_bMakeFrameRegion(), REGION_bXformRgn(), UserScrollDC(), and VIS_ComputeVisibleRegion().

◆ REGION_bXformRgn()

BOOL FASTCALL REGION_bXformRgn ( _Inout_ PREGION  prgn,
_In_ PMATRIX  pmx 
)

Definition at line 2082 of file region.c.

2085 {
2086  XFORMOBJ xo;
2087  ULONG i, cjSize;
2088  PPOINT ppt;
2089  PULONG pcPoints;
2090  RECT rect;
2091  BOOL bResult;
2092 
2093  /* Check for zero rectangles and return TRUE for translation only matrices */
2094  if (prgn->rdh.nCount < 1)
2095  return (pmx->flAccel & XFORM_UNITY) != 0;
2096 
2097  /* Check if this is a scaling only matrix (off-diagonal elements are 0 */
2098  if (pmx->flAccel & XFORM_SCALE)
2099  {
2100  /* Check if this is a translation only matrix */
2101  if (pmx->flAccel & XFORM_UNITY)
2102  {
2103  /* Just offset the region */
2104  return REGION_bOffsetRgn(prgn, (pmx->fxDx + 8) / 16, (pmx->fxDy + 8) / 16);
2105  }
2106  else
2107  {
2108  /* Initialize the xform object */
2109  XFORMOBJ_vInit(&xo, pmx);
2110 
2111  /* Scaling can move the rects out of the coordinate space, so
2112  * we first need to check whether we can apply the transformation
2113  * on the bounds rect without modifying the region */
2114  if (!XFORMOBJ_bApplyXform(&xo, XF_LTOL, 2, &prgn->rdh.rcBound, &rect))
2115  {
2116  return FALSE;
2117  }
2118 
2119  /* Apply the xform to the rects in the region */
2120  if (!XFORMOBJ_bApplyXform(&xo,
2121  XF_LTOL,
2122  prgn->rdh.nCount * 2,
2123  prgn->Buffer,
2124  prgn->Buffer))
2125  {
2126  /* This can not happen, since we already checked the bounds! */
2127  NT_ASSERT(FALSE);
2128  }
2129 
2130  /* Reset bounds */
2131  RECTL_vSetEmptyRect(&prgn->rdh.rcBound);
2132 
2133  /* Loop all rects in the region */
2134  for (i = 0; i < prgn->rdh.nCount; i++)
2135  {
2136  /* Make sure the rect is well-ordered after the xform */
2137  RECTL_vMakeWellOrdered(&prgn->Buffer[i]);
2138 
2139  /* Update bounds */
2140  if (!RECTL_bUnionRect(&prgn->rdh.rcBound,
2141  &prgn->rdh.rcBound,
2142  &prgn->Buffer[i]))
2143  {
2144  DPRINT1("NULL Set in Union Rects\n");
2145  return FALSE;
2146  }
2147  }
2148 
2149  /* Loop all rects in the region */
2150  for (i = 0; i < prgn->rdh.nCount - 1; i++)
2151  {
2152  NT_ASSERT(prgn->Buffer[i].top <= prgn->Buffer[i].bottom);
2153  NT_ASSERT(prgn->Buffer[i + 1].top >= prgn->Buffer[i].top);
2154  }
2155 
2156  return TRUE;
2157  }
2158  }
2159  else
2160  {
2161  /* Allocate a buffer for the polygons */
2162  cjSize = prgn->rdh.nCount * (4 * sizeof(POINT) + sizeof(ULONG));
2164  if (ppt == NULL)
2165  {
2166  return FALSE;
2167  }
2168 
2169  /* Fill the buffer with the rects */
2170  pcPoints = (PULONG)&ppt[4 * prgn->rdh.nCount];
2171  for (i = 0; i < prgn->rdh.nCount; i++)
2172  {
2173  /* Make sure the rect is within the legal range */
2174  pcPoints[i] = 4;
2175  ppt[4 * i + 0].x = prgn->Buffer[i].left;
2176  ppt[4 * i + 0].y = prgn->Buffer[i].top;
2177  ppt[4 * i + 1].x = prgn->Buffer[i].right;
2178  ppt[4 * i + 1].y = prgn->Buffer[i].top;
2179  ppt[4 * i + 2].x = prgn->Buffer[i].right;
2180  ppt[4 * i + 2].y = prgn->Buffer[i].bottom;
2181  ppt[4 * i + 3].x = prgn->Buffer[i].left;
2182  ppt[4 * i + 3].y = prgn->Buffer[i].bottom;
2183  }
2184 
2185  /* Initialize the xform object */
2186  XFORMOBJ_vInit(&xo, pmx);
2187 
2188  /* Apply the xform to the rects in the buffer */
2189  if (!XFORMOBJ_bApplyXform(&xo,
2190  XF_LTOL,
2191  prgn->rdh.nCount * 2,
2192  ppt,
2193  ppt))
2194  {
2195  /* This means, there were coordinates that would go outside of
2196  the coordinate space after the transformation */
2198  return FALSE;
2199  }
2200 
2201  /* Now use the polygons to create a polygon region */
2202  bResult = REGION_SetPolyPolygonRgn(prgn,
2203  ppt,
2204  pcPoints,
2205  prgn->rdh.nCount,
2206  WINDING);
2207 
2208  /* Free the polygon buffer */
2210 
2211  return bResult;
2212  }
2213 
2214 }
#define WINDING
Definition: constants.h:279
#define TRUE
Definition: types.h:120
BOOL FASTCALL REGION_SetPolyPolygonRgn(_Inout_ PREGION prgn, _In_ const POINT *ppt, _In_ const ULONG *pcPoints, _In_ ULONG cPolygons, _In_ INT iMode)
Definition: region.c:3275
long y
Definition: polytest.cpp:48
FORCEINLINE VOID RECTL_vSetEmptyRect(_Out_ RECTL *prcl)
Definition: rect.h:20
#define XFORMOBJ_bApplyXform
Definition: xformobj.h:11
long x
Definition: polytest.cpp:48
BOOL FASTCALL REGION_bOffsetRgn(_Inout_ PREGION prgn, _In_ INT cx, _In_ INT cy)
Definition: region.c:2727
FORCEINLINE VOID XFORMOBJ_vInit(OUT XFORMOBJ *pxo, IN MATRIX *pmx)
Definition: xformobj.h:21
& rect
Definition: startmenu.cpp:1413
#define GDITAG_REGION
Definition: tags.h:157
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
unsigned int BOOL
Definition: ntddk_ex.h:94
smooth NULL
Definition: ftsmooth.c:416
#define POINT
Definition: precomp.h:30
#define XF_LTOL
Definition: winddi.h:3109
BOOL FASTCALL RECTL_bUnionRect(_Out_ RECTL *prclDst, _In_ const RECTL *prcl1, _In_ const RECTL *prcl2)
Definition: rect.c:18
#define for
Definition: utility.h:88
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
unsigned int * PULONG
Definition: retypes.h:1
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
_In_ ULONG cjSize
Definition: winddi.h:3634
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
VOID FASTCALL RECTL_vMakeWellOrdered(_Inout_ RECTL *prcl)
Definition: rect.c:81
#define NT_ASSERT
Definition: rtlfuncs.h:3312

Referenced by REGION_LPTODP().

◆ REGION_Coalesce()

static INT FASTCALL REGION_Coalesce ( PREGION  pReg,
INT  prevStart,
INT  curStart 
)
static
 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.

Note
Side Effects: If coalescing takes place:
  • rectangles in the previous band will have their bottom fields altered.
  • pReg->numRects will be decreased.

Definition at line 822 of file region.c.

826 {
827  RECTL *pPrevRect; /* Current rect in previous band */
828  RECTL *pCurRect; /* Current rect in current band */
829  RECTL *pRegEnd; /* End of region */
830  INT curNumRects; /* Number of rectangles in current band */
831  INT prevNumRects; /* Number of rectangles in previous band */
832  INT bandtop; /* Top coordinate for current band */
833 
834  pRegEnd = pReg->Buffer + pReg->rdh.nCount;
835  pPrevRect = pReg->Buffer + prevStart;
836  prevNumRects = curStart - prevStart;
837 
838  /* Figure out how many rectangles are in the current band. Have to do
839  * this because multiple bands could have been added in REGION_RegionOp
840  * at the end when one region has been exhausted. */
841  pCurRect = pReg->Buffer + curStart;
842  bandtop = pCurRect->top;
843  for (curNumRects = 0;
844  (pCurRect != pRegEnd) && (pCurRect->top == bandtop);
845  curNumRects++)
846  {
847  pCurRect++;
848  }
849 
850  if (pCurRect != pRegEnd)
851  {
852  /* If more than one band was added, we have to find the start
853  * of the last band added so the next coalescing job can start
854  * at the right place... (given when multiple bands are added,
855  * this may be pointless -- see above). */
856  pRegEnd--;
857  while ((pRegEnd-1)->top == pRegEnd->top)
858  {
859  pRegEnd--;
860  }
861 
862  curStart = pRegEnd - pReg->Buffer;
863  pRegEnd = pReg->Buffer + pReg->rdh.nCount;
864  }
865 
866  if ((curNumRects == prevNumRects) && (curNumRects != 0))
867  {
868  pCurRect -= curNumRects;
869 
870  /* The bands may only be coalesced if the bottom of the previous
871  * matches the top scanline of the current. */
872  if (pPrevRect->bottom == pCurRect->top)
873  {
874  /* Make sure the bands have rects in the same places. This
875  * assumes that rects have been added in such a way that they
876  * cover the most area possible. I.e. two rects in a band must
877  * have some horizontal space between them. */
878  do
879  {
880  if ((pPrevRect->left != pCurRect->left) ||
881  (pPrevRect->right != pCurRect->right))
882  {
883  /* The bands don't line up so they can't be coalesced. */
884  return (curStart);
885  }
886 
887  pPrevRect++;
888  pCurRect++;
889  prevNumRects -= 1;
890  }
891  while (prevNumRects != 0);
892 
893  pReg->rdh.nCount -= curNumRects;
894  pCurRect -= curNumRects;
895  pPrevRect -= curNumRects;
896 
897  /* The bands may be merged, so set the bottom of each rect
898  * in the previous band to that of the corresponding rect in
899  * the current band. */
900  do
901  {
902  pPrevRect->bottom = pCurRect->bottom;
903  pPrevRect++;
904  pCurRect++;
905  curNumRects -= 1;
906  }
907  while (curNumRects != 0);
908 
909  /* If only one band was added to the region, we have to backup
910  * curStart to the start of the previous band.
911  *
912  * If more than one band was added to the region, copy the
913  * other bands down. The assumption here is that the other bands
914  * came from the same region as the current one and no further
915  * coalescing can be done on them since it's all been done
916  * already... curStart is already in the right place. */
917  if (pCurRect == pRegEnd)
918  {
919  curStart = prevStart;
920  }
921  else
922  {
923  do
924  {
925  *pPrevRect++ = *pCurRect++;
926  }
927  while (pCurRect != pRegEnd);
928  }
929  }
930  }
931 
932  return (curStart);
933 }
long bottom
Definition: polytest.cpp:53
int32_t INT
Definition: typedefs.h:56
long right
Definition: polytest.cpp:53
long top
Definition: polytest.cpp:53
RECTL * Buffer
Definition: region.h:16
long left
Definition: polytest.cpp:53
RGNDATAHEADER rdh
Definition: region.h:15

Referenced by REGION_RegionOp().

◆ REGION_Complexity()

INT FASTCALL REGION_Complexity ( PREGION  prgn)

Definition at line 567 of file region.c.

568 {
569  if (prgn == NULL)
570  return NULLREGION;
571 
572  DPRINT("Region Complexity -> %lu", prgn->rdh.nCount);
573  switch (prgn->rdh.nCount)
574  {
575  case 0:
576  return NULLREGION;
577  case 1:
578  return SIMPLEREGION;
579  default:
580  return COMPLEXREGION;
581  }
582 }
#define COMPLEXREGION
Definition: wingdi.h:362
#define NULLREGION
Definition: wingdi.h:360
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
RGNDATAHEADER rdh
Definition: region.h:15
#define SIMPLEREGION
Definition: wingdi.h:361

Referenced by _Success_(), co_WinPosSetWindowPos(), IntGdiCombineRgn(), IntGdiSetMetaRgn(), NtGdiOffsetClipRgn(), NtGdiOffsetRgn(), REGION_bMakeFrameRegion(), REGION_CropRegion(), REGION_GetRgnBox(), REGION_SubtractRectFromRgn(), and REGION_UnlockRgn().

◆ REGION_computeWAET()

static VOID FASTCALL REGION_computeWAET ( EDGE_TABLE_ENTRY AET)
static

Definition at line 2957 of file region.c.

2959 {
2960  register EDGE_TABLE_ENTRY *pWETE;
2961  register INT inside = 1;
2962  register INT isInside = 0;
2963 
2964  AET->nextWETE = (EDGE_TABLE_ENTRY *)NULL;
2965  pWETE = AET;
2966  AET = AET->next;
2967  while (AET)
2968  {
2969  if (AET->ClockWise)
2970  isInside++;
2971  else
2972  isInside--;
2973 
2974  if ((!inside && !isInside) ||
2975  ( inside && isInside))
2976  {
2977  pWETE->nextWETE = AET;
2978  pWETE = AET;
2979  inside = !inside;
2980  }
2981  AET = AET->next;
2982  }
2983 
2984  pWETE->nextWETE = (EDGE_TABLE_ENTRY *)NULL;
2985 }
int32_t INT
Definition: typedefs.h:56
INT ClockWise
Definition: region.c:324
struct _EDGE_TABLE_ENTRY * nextWETE
Definition: region.c:323
smooth NULL
Definition: ftsmooth.c:416
Definition: region.c:317
struct _EDGE_TABLE_ENTRY * next
Definition: region.c:321

Referenced by REGION_SetPolyPolygonRgn().

◆ REGION_CopyRegion()

static BOOL FASTCALL REGION_CopyRegion ( PREGION  dst,
PREGION  src 
)
static

Definition at line 587 of file region.c.

590 {
591  /* Only copy if source and dest are not equal */
592  if (dst != src)
593  {
594  /* Check if we need to increase our buffer */
595  if (dst->rdh.nRgnSize < src->rdh.nCount * sizeof(RECT))
596  {
597  PRECTL temp;
598 
599  /* Allocate a new buffer */
601  src->rdh.nCount * sizeof(RECT),
602  TAG_REGION);
603  if (temp == NULL)
604  return FALSE;
605 
606  /* Free the old buffer */
607  if ((dst->Buffer != NULL) && (dst->Buffer != &dst->rdh.rcBound))
608  ExFreePoolWithTag(dst->Buffer, TAG_REGION);
609 
610  /* Set the new buffer and the size */
611  dst->Buffer = temp;
612  dst->rdh.nRgnSize = src->rdh.nCount * sizeof(RECT);
613  }
614 
615  dst->rdh.nCount = src->rdh.nCount;
616  dst->rdh.rcBound.left = src->rdh.rcBound.left;
617  dst->rdh.rcBound.top = src->rdh.rcBound.top;
618  dst->rdh.rcBound.right = src->rdh.rcBound.right;
619  dst->rdh.rcBound.bottom = src->rdh.rcBound.bottom;
620  dst->rdh.iType = src->rdh.iType;
621  COPY_RECTS(dst->Buffer, src->Buffer, src->rdh.nCount);
622  }
623 
624  return TRUE;
625 }
#define TRUE
Definition: types.h:120
#define TAG_REGION
Definition: tags.h:22
struct tagRECT RECT
smooth NULL
Definition: ftsmooth.c:416
#define COPY_RECTS(dest, src, nRects)
Definition: region.c:136
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
GLenum src
Definition: glext.h:6340
static calc_node_t temp
Definition: rpn_ieee.c:38
GLenum GLenum dst
Definition: glext.h:6340
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099

Referenced by IntGdiCombineRgn(), REGION_bCopy(), REGION_bMakeFrameRegion(), REGION_SubtractRegion(), and REGION_UnionRegion().

◆ REGION_CreateETandAET()

static VOID FASTCALL REGION_CreateETandAET ( const ULONG Count,
INT  nbpolygons,
const POINT pts,
EDGE_TABLE ET,
EDGE_TABLE_ENTRY AET,
EDGE_TABLE_ENTRY pETEs,
SCANLINE_LISTBLOCK pSLLBlock 
)
static

Definition at line 3189 of file region.c.

3197 {
3198  const POINT *top, *bottom;
3199  const POINT *PrevPt, *CurrPt, *EndPt;
3200  INT poly, count;
3201  INT iSLLBlock = 0;
3202  INT dy;
3203 
3204  /* Initialize the Active Edge Table */
3205  AET->next = (EDGE_TABLE_ENTRY *)NULL;
3206  AET->back = (EDGE_TABLE_ENTRY *)NULL;
3207  AET->nextWETE = (EDGE_TABLE_ENTRY *)NULL;
3209 
3210  /* Initialize the Edge Table. */
3211  ET->scanlines.next = (SCANLINE_LIST *)NULL;
3212  ET->ymax = SMALL_COORDINATE;
3213  ET->ymin = LARGE_COORDINATE;
3214  pSLLBlock->next = (SCANLINE_LISTBLOCK *)NULL;
3215 
3216  EndPt = pts - 1;
3217  for (poly = 0; poly < nbpolygons; poly++)
3218  {
3219  count = Count[poly];
3220  EndPt += count;
3221  if (count < 2)
3222  continue;
3223 
3224  PrevPt = EndPt;
3225 
3226  /* For each vertex in the array of points.
3227  * In this loop we are dealing with two vertices at
3228  * a time -- these make up one edge of the polygon. */
3229  while (count--)
3230  {
3231  CurrPt = pts++;
3232 
3233  /* Find out which point is above and which is below. */
3234  if (PrevPt->y > CurrPt->y)
3235  {
3236  bottom = PrevPt, top = CurrPt;
3237  pETEs->ClockWise = 0;
3238  }
3239  else
3240  {
3241  bottom = CurrPt, top = PrevPt;
3242  pETEs->ClockWise = 1;
3243  }
3244 
3245  /* Don't add horizontal edges to the Edge table. */
3246  if (bottom->y != top->y)
3247  {
3248  /* -1 so we don't get last scanline */
3249  pETEs->ymax = bottom->y - 1;
3250 
3251  /* Initialize integer edge algorithm */
3252  dy = bottom->y - top->y;
3253  BRESINITPGONSTRUCT(dy, top->x, bottom->x, pETEs->bres);
3254 
3256  pETEs,
3257  top->y,
3258  &pSLLBlock,
3259  &iSLLBlock);
3260 
3261  if (PrevPt->y > ET->ymax)
3262  ET->ymax = PrevPt->y;
3263  if (PrevPt->y < ET->ymin)
3264  ET->ymin = PrevPt->y;
3265  pETEs++;
3266  }
3267 
3268  PrevPt = CurrPt;
3269  }
3270  }
3271 }
#define BRESINITPGONSTRUCT(dmaj, min1, min2, bres)
Definition: region.c:256
INT ymax
Definition: region.c:319
long y
Definition: polytest.cpp:48
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint dy
Definition: linetemp.h:97
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
Definition: bidi.c:79
int32_t INT
Definition: typedefs.h:56
INT ClockWise
Definition: region.c:324
struct _EDGE_TABLE_ENTRY * nextWETE
Definition: region.c:323
#define SMALL_COORDINATE
Definition: region.c:414
smooth NULL
Definition: ftsmooth.c:416
Definition: region.c:317
GLint GLint bottom
Definition: glext.h:7726
INT minor_axis
Definition: region.c:249
struct _SCANLINE_LISTBLOCK * next
Definition: region.c:354
#define LARGE_COORDINATE
Definition: region.c:413
struct _EDGE_TABLE_ENTRY * back
Definition: region.c:322
BRESINFO bres
Definition: region.c:320
struct _EDGE_TABLE_ENTRY * next
Definition: region.c:321
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:10859
static VOID FASTCALL REGION_InsertEdgeInET(EDGE_TABLE *ET, EDGE_TABLE_ENTRY *ETE, INT scanline, SCANLINE_LISTBLOCK **SLLBlock, INT *iSLLBlock)
Definition: region.c:2826

Referenced by REGION_SetPolyPolygonRgn().

◆ REGION_CropRegion()

INT FASTCALL REGION_CropRegion ( PREGION  rgnDst,
PREGION  rgnSrc,
const RECTL rect 
)

Definition at line 678 of file region.c.

682 {
683  PRECTL lpr, rpr;
684  ULONG i, j, clipa, clipb, nRgnSize;
685  INT left = MAXLONG;
686  INT right = MINLONG;
687  INT top = MAXLONG;
688  INT bottom = MINLONG;
689 
690  if ((rect->left >= rect->right) ||
691  (rect->top >= rect->bottom) ||
692  (EXTENTCHECK(rect, &rgnSrc->rdh.rcBound) == 0))
693  {
694  goto empty;
695  }
696 
697  /* Skip all rects that are completely above our intersect rect */
698  for (clipa = 0; clipa < rgnSrc->rdh.nCount; clipa++)
699  {
700  /* bottom is exclusive, so break when we go above it */
701  if (rgnSrc->Buffer[clipa].bottom > rect->top) break;
702  }
703 
704  /* Bail out, if there is nothing left */
705  if (clipa == rgnSrc->rdh.nCount) goto empty;
706 
707  /* Find the last rect that is still within the intersect rect (exclusive) */
708  for (clipb = clipa; clipb < rgnSrc->rdh.nCount; clipb++)
709  {
710  /* bottom is exclusive, so stop, when we start at that y pos */
711  if (rgnSrc->Buffer[clipb].top >= rect->bottom) break;
712  }
713 
714  /* Bail out, if there is nothing left */
715  if (clipb == clipa) goto empty;
716 
717  // clipa - index of the first rect in the first intersecting band
718  // clipb - index of the last rect in the last intersecting band plus 1
719 
720  /* Check if the buffer in the dest region is large enough,
721  otherwise allocate a new one */
722  nRgnSize = (clipb - clipa) * sizeof(RECT);
723  if ((rgnDst != rgnSrc) && (rgnDst->rdh.nRgnSize < nRgnSize))
724  {
725  PRECTL temp;
727  if (temp == NULL)
728  return ERROR;
729 
730  /* Free the old buffer */
731  if (rgnDst->Buffer && (rgnDst->Buffer != &rgnDst->rdh.rcBound))
733 
734  rgnDst->Buffer = temp;
735  rgnDst->rdh.nCount = 0;
736  rgnDst->rdh.nRgnSize = nRgnSize;
737  rgnDst->rdh.iType = RDH_RECTANGLES;
738  }
739 
740  /* Loop all rects within the intersect rect from the y perspective */
741  for (i = clipa, j = 0; i < clipb ; i++)
742  {
743  /* i - src index, j - dst index, j is always <= i for obvious reasons */
744 
745  lpr = &rgnSrc->Buffer[i];
746 
747  /* Make sure the source rect is not retarded */
748  ASSERT(lpr->bottom > lpr->top);
749  ASSERT(lpr->right > lpr->left);
750 
751  /* We already checked above, this should hold true */
752  ASSERT(lpr->bottom > rect->top);
753  ASSERT(lpr->top < rect->bottom);
754 
755  /* Check if this rect is really inside the intersect rect */
756  if ((lpr->left < rect->right) && (lpr->right > rect->left))
757  {
758  rpr = &rgnDst->Buffer[j];
759 
760  /* Crop the rect with the intersect rect */
761  rpr->top = max(lpr->top, rect->top);
762  rpr->bottom = min(lpr->bottom, rect->bottom);
763  rpr->left = max(lpr->left, rect->left);
764  rpr->right = min(lpr->right, rect->right);
765 
766  /* Make sure the resulting rect is not retarded */
767  ASSERT(rpr->bottom > rpr->top);
768  ASSERT(rpr->right > rpr->left);
769 
770  /* Track new bounds */
771  if (rpr->left < left) left = rpr->left;
772  if (rpr->right > right) right = rpr->right;
773  if (rpr->top < top) top = rpr->top;
774  if (rpr->bottom > bottom) bottom = rpr->bottom;
775 
776  /* Next target rect */
777  j++;
778  }
779  }
780 
781  if (j == 0) goto empty;
782 
783  /* Update the bounds rect */
784  rgnDst->rdh.rcBound.left = left;
785  rgnDst->rdh.rcBound.right = right;
786  rgnDst->rdh.rcBound.top = top;
787  rgnDst->rdh.rcBound.bottom = bottom;
788 
789  /* Set new rect count */
790  rgnDst->rdh.nCount = j;
791 
792  return REGION_Complexity(rgnDst);
793 
794 empty:
795  if (rgnDst->Buffer == NULL)
796  {
797  rgnDst->Buffer = &rgnDst->rdh.rcBound;
798  }
799 
800  EMPTY_REGION(rgnDst);
801  return NULLREGION;
802 }
#define max(a, b)
Definition: svc.c:63
#define MAXLONG
Definition: umtypes.h:116
#define ERROR(name)
Definition: error_private.h:53
static const WCHAR empty[]
Definition: main.c:49
#define TAG_REGION
Definition: tags.h:22
#define NULLREGION
Definition: wingdi.h:360
LONG top
Definition: windef.h:292
long bottom
Definition: polytest.cpp:53
LONG left
Definition: windef.h:291
LONG right
Definition: windef.h:293
int32_t INT
Definition: typedefs.h:56
& rect
Definition: startmenu.cpp:1413
long right
Definition: polytest.cpp:53
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
long top
Definition: polytest.cpp:53
RECTL * Buffer
Definition: region.h:16
smooth NULL
Definition: ftsmooth.c:416
GLint GLint bottom
Definition: glext.h:7726
long left
Definition: polytest.cpp:53
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define EXTENTCHECK(r1, r2)
Definition: region.c:167
#define RDH_RECTANGLES
Definition: wingdi.h:668
GLint left
Definition: glext.h:7726
GLdouble GLdouble right
Definition: glext.h:10859
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define MINLONG
Definition: umtypes.h:115
RGNDATAHEADER rdh
Definition: region.h:15
#define EMPTY_REGION(pReg)
Definition: region.c:149
static calc_node_t temp
Definition: rpn_ieee.c:38
#define min(a, b)
Definition: monoChain.cc:55
unsigned int ULONG
Definition: retypes.h:1
LONG bottom
Definition: windef.h:294
INT FASTCALL REGION_Complexity(PREGION prgn)
Definition: region.c:567
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:10859
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099

Referenced by NtGdiIntersectClipRect().

◆ REGION_Delete()

◆ REGION_FreeStorage()

static VOID FASTCALL REGION_FreeStorage ( SCANLINE_LISTBLOCK pSLLBlock)
static

Definition at line 3041 of file region.c.

3043 {
3044  SCANLINE_LISTBLOCK *tmpSLLBlock;
3045 
3046  while (pSLLBlock)
3047  {
3048  tmpSLLBlock = pSLLBlock->next;
3049  ExFreePoolWithTag(pSLLBlock, TAG_REGION);
3050  pSLLBlock = tmpSLLBlock;
3051  }
3052 }
#define TAG_REGION
Definition: tags.h:22
struct _SCANLINE_LISTBLOCK * next
Definition: region.c:354
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099

Referenced by REGION_SetPolyPolygonRgn().

◆ REGION_GetRgnBox()

INT FASTCALL REGION_GetRgnBox ( PREGION  Rgn,
PRECTL  pRect 
)

Definition at line 2562 of file region.c.

2565 {
2566  DWORD ret;
2567 
2568  if (Rgn != NULL)
2569  {
2570  *pRect = Rgn->rdh.rcBound;
2571  ret = REGION_Complexity(Rgn);
2572 
2573  return ret;
2574  }
2575  return 0; // If invalid region return zero
2576 }
smooth NULL
Definition: ftsmooth.c:416
unsigned long DWORD
Definition: ntddk_ex.h:95
int ret
RGNDATAHEADER rdh
Definition: region.h:15
INT FASTCALL REGION_Complexity(PREGION prgn)
Definition: region.c:567

Referenced by co_WinPosSetWindowPos(), IntGdiBitBltRgn(), IntGdiFillRgn(), IntGdiGetRgnBox(), NtGdiExtFloodFill(), NtGdiExtSelectClipRgn(), NtGdiGetBoundsRect(), NtGdiGetRgnBox(), NtUserEnumDisplayMonitors(), UpdateVisRgn(), and UserScrollDC().

◆ REGION_InsertEdgeInET()

static VOID FASTCALL REGION_InsertEdgeInET ( EDGE_TABLE ET,
EDGE_TABLE_ENTRY ETE,
INT  scanline,
SCANLINE_LISTBLOCK **  SLLBlock,
INT iSLLBlock 
)
static

Definition at line 2826 of file region.c.

2832 {
2833  EDGE_TABLE_ENTRY *start, *prev;
2834  SCANLINE_LIST *pSLL, *pPrevSLL;
2835  SCANLINE_LISTBLOCK *tmpSLLBlock;
2836 
2837  /* Find the right bucket to put the edge into */
2838  pPrevSLL = &ET->scanlines;
2839  pSLL = pPrevSLL->next;
2840  while (pSLL && (pSLL->scanline < scanline))
2841  {
2842  pPrevSLL = pSLL;
2843  pSLL = pSLL->next;
2844  }
2845 
2846  /* Reassign pSLL (pointer to SCANLINE_LIST) if necessary */
2847  if ((!pSLL) || (pSLL->scanline > scanline))
2848  {
2849  if (*iSLLBlock > SLLSPERBLOCK-1)
2850  {
2851  tmpSLLBlock = ExAllocatePoolWithTag(PagedPool,
2852  sizeof(SCANLINE_LISTBLOCK),
2853  TAG_REGION);
2854  if (tmpSLLBlock == NULL)
2855  {
2856  DPRINT1("REGION_InsertEdgeInETL(): Can't alloc SLLB\n");
2857  /* FIXME: Free resources? */
2858  return;
2859  }
2860 
2861  (*SLLBlock)->next = tmpSLLBlock;
2862  tmpSLLBlock->next = (SCANLINE_LISTBLOCK *)NULL;
2863  *SLLBlock = tmpSLLBlock;
2864  *iSLLBlock = 0;
2865  }
2866 
2867  pSLL = &((*SLLBlock)->SLLs[(*iSLLBlock)++]);
2868 
2869  pSLL->next = pPrevSLL->next;
2870  pSLL->edgelist = (EDGE_TABLE_ENTRY *)NULL;
2871  pPrevSLL->next = pSLL;
2872  }
2873 
2874  pSLL->scanline = scanline;
2875 
2876  /* Now insert the edge in the right bucket */
2877  prev = (EDGE_TABLE_ENTRY *)NULL;
2878  start = pSLL->edgelist;
2879  while (start && (start->bres.minor_axis < ETE->bres.minor_axis))
2880  {
2881  prev = start;
2882  start = start->next;
2883  }
2884 
2885  ETE->next = start;
2886 
2887  if (prev)
2888  prev->next = ETE;
2889  else
2890  pSLL->edgelist = ETE;
2891 }
EDGE_TABLE_ENTRY * edgelist
Definition: region.c:331
#define TAG_REGION
Definition: tags.h:22
struct _SCANLINE_LIST * next
Definition: region.c:332
Definition: bidi.c:79
smooth NULL
Definition: ftsmooth.c:416
Definition: region.c:317
INT minor_axis
Definition: region.c:249
struct _SCANLINE_LISTBLOCK * next
Definition: region.c:354
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
BRESINFO bres
Definition: region.c:320
GLuint start
Definition: gl.h:1545
#define DPRINT1
Definition: precomp.h:8
INT scanline
Definition: region.c:330
struct _EDGE_TABLE_ENTRY * next
Definition: region.c:321
#define SLLSPERBLOCK
Definition: region.c:349

Referenced by REGION_CreateETandAET().

◆ REGION_InsertionSort()

static BOOL FASTCALL REGION_InsertionSort ( EDGE_TABLE_ENTRY AET)
static

Definition at line 2998 of file region.c.

3000 {
3001  EDGE_TABLE_ENTRY *pETEchase;
3002  EDGE_TABLE_ENTRY *pETEinsert;
3003  EDGE_TABLE_ENTRY *pETEchaseBackTMP;
3004  BOOL changed = FALSE;
3005 
3006  AET = AET->next;
3007  while (AET)
3008  {
3009  pETEinsert = AET;
3010  pETEchase = AET;
3011  while (pETEchase->back->bres.minor_axis > AET->bres.minor_axis)
3012  pETEchase = pETEchase->back;
3013 
3014  AET = AET->next;
3015  if (pETEchase != pETEinsert)
3016  {
3017  pETEchaseBackTMP = pETEchase->back;
3018  pETEinsert->back->next = AET;
3019  if (AET)
3020  AET->back = pETEinsert->back;
3021 
3022  pETEinsert->next = pETEchase;
3023  pETEchase->back->next = pETEinsert;
3024  pETEchase->back = pETEinsert;
3025  pETEinsert->back = pETEchaseBackTMP;
3026  changed = TRUE;
3027  }
3028  }
3029 
3030  return changed;
3031 }
#define TRUE
Definition: types.h:120
unsigned int BOOL
Definition: ntddk_ex.h:94
Definition: region.c:317
INT minor_axis
Definition: region.c:249
struct _EDGE_TABLE_ENTRY * back
Definition: region.c:322
BRESINFO bres
Definition: region.c:320
struct _EDGE_TABLE_ENTRY * next
Definition: region.c:321

Referenced by REGION_SetPolyPolygonRgn().

◆ REGION_IntersectO()

static BOOL FASTCALL REGION_IntersectO ( PREGION  pReg,
PRECTL  r1,
PRECTL  r1End,
PRECTL  r2,
PRECTL  r2End,
INT  top,
INT  bottom 
)
static

Handle an overlapping band for REGION_Intersect.

Results: None.

Note
Side Effects: Rectangles may be added to the region.

Definition at line 1250 of file region.c.

1258 {
1259  INT left, right;
1260 
1261  while ((r1 != r1End) && (r2 != r2End))
1262  {
1263  left = max(r1->left, r2->left);
1264  right = min(r1->right, r2->right);
1265 
1266  /* If there's any overlap between the two rectangles, add that
1267  * overlap to the new region.
1268  * There's no need to check for subsumption because the only way
1269  * such a need could arise is if some region has two rectangles
1270  * right next to each other. Since that should never happen... */
1271  if (left < right)
1272  {
1273  if (!REGION_bAddRect(pReg, left, top, right, bottom))
1274  {
1275  return FALSE;
1276  }
1277  }
1278 
1279  /* Need to advance the pointers. Shift the one that extends
1280  * to the right the least, since the other still has a chance to
1281  * overlap with that region's next rectangle, if you see what I mean. */
1282  if (r1->right < r2->right)
1283  {
1284  r1++;
1285  }
1286  else if (r2->right < r1->right)
1287  {
1288  r2++;
1289  }
1290  else
1291  {
1292  r1++;
1293  r2++;
1294  }
1295  }
1296 
1297  return TRUE;
1298 }
#define max(a, b)
Definition: svc.c:63
#define TRUE
Definition: types.h:120
static DNS_RECORDW r1
Definition: record.c:37
int32_t INT
Definition: typedefs.h:56
static __inline BOOL REGION_bAddRect(_Inout_ PREGION prgn, _In_ LONG left, _In_ LONG top, _In_ LONG right, _In_ LONG bottom)
Definition: region.c:504
GLint GLint bottom
Definition: glext.h:7726
static DNS_RECORDW r2
Definition: record.c:38
GLint left
Definition: glext.h:7726
GLdouble GLdouble right
Definition: glext.h:10859
#define min(a, b)
Definition: monoChain.cc:55
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:10859

Referenced by REGION_IntersectRegion().

◆ REGION_IntersectRegion()

static BOOL FASTCALL REGION_IntersectRegion ( PREGION  newReg,
PREGION  reg1,
PREGION  reg2 
)
static

Definition at line 1306 of file region.c.

1310 {
1311  /* Check for trivial reject */
1312  if ((reg1->rdh.nCount == 0) ||
1313  (reg2->rdh.nCount == 0) ||
1314  (EXTENTCHECK(&reg1->rdh.rcBound, &reg2->rdh.rcBound) == 0))
1315  {
1316  newReg->rdh.nCount = 0;
1317  }
1318  else
1319  {
1320  if (!REGION_RegionOp(newReg,
1321  reg1,
1322  reg2,
1324  NULL,
1325  NULL))
1326  return FALSE;
1327  }
1328 
1329  /* Can't alter newReg's extents before we call miRegionOp because
1330  * it might be one of the source regions and miRegionOp depends
1331  * on the extents of those regions being the same. Besides, this
1332  * way there's no checking against rectangles that will be nuked
1333  * due to coalescing, so we have to examine fewer rectangles. */
1334  REGION_SetExtents(newReg);
1335  return TRUE;
1336 }
static VOID FASTCALL REGION_SetExtents(PREGION pReg)
Definition: region.c:630
static BOOL FASTCALL REGION_RegionOp(PREGION newReg, PREGION reg1, PREGION reg2, overlapProcp overlapFunc, nonOverlapProcp nonOverlap1Func, nonOverlapProcp nonOverlap2Func)
Definition: region.c:960
static BOOL FASTCALL REGION_IntersectO(PREGION pReg, PRECTL r1, PRECTL r1End, PRECTL r2, PRECTL r2End, INT top, INT bottom)
Definition: region.c:1250
#define TRUE
Definition: types.h:120
smooth NULL
Definition: ftsmooth.c:416
#define EXTENTCHECK(r1, r2)
Definition: region.c:167
RGNDATAHEADER rdh
Definition: region.h:15

Referenced by IntGdiCombineRgn(), REGION_bIntersectRegion(), and REGION_bMakeFrameRegion().

◆ REGION_loadAET()

static VOID FASTCALL REGION_loadAET ( EDGE_TABLE_ENTRY AET,
EDGE_TABLE_ENTRY ETEs 
)
static

Definition at line 2904 of file region.c.

2907 {
2908  EDGE_TABLE_ENTRY *pPrevAET;
2909  EDGE_TABLE_ENTRY *tmp;
2910 
2911  pPrevAET = AET;
2912  AET = AET->next;
2913  while (ETEs)
2914  {
2915  while (AET && (AET->bres.minor_axis < ETEs->bres.minor_axis))
2916  {
2917  pPrevAET = AET;
2918  AET = AET->next;
2919  }
2920 
2921  tmp = ETEs->next;
2922  ETEs->next = AET;
2923  if (AET)
2924  AET->back = ETEs;
2925 
2926  ETEs->back = pPrevAET;
2927  pPrevAET->next = ETEs;
2928  pPrevAET = ETEs;
2929 
2930  ETEs = tmp;
2931  }
2932 }
Definition: region.c:317
INT minor_axis
Definition: region.c:249
struct _EDGE_TABLE_ENTRY * back
Definition: region.c:322
BRESINFO bres
Definition: region.c:320
struct _EDGE_TABLE_ENTRY * next
Definition: region.c:321

Referenced by REGION_SetPolyPolygonRgn().

◆ REGION_LockRgn()

◆ REGION_PtInRegion()

BOOL FASTCALL REGION_PtInRegion ( PREGION  prgn,
INT  X,
INT  Y 
)

Definition at line 2602 of file region.c.

2606 {
2607  ULONG i;
2608  PRECT r;
2609 
2610  if (prgn->rdh.nCount > 0 && INRECT(prgn->rdh.rcBound, X, Y))
2611  {
2612  r = prgn->Buffer;
2613  for (i = 0; i < prgn->rdh.nCount; i++)
2614  {
2615  if (INRECT(r[i], X, Y))
2616  return TRUE;
2617  }
2618  }
2619 
2620  return FALSE;
2621 }
#define TRUE
Definition: types.h:120
#define Y(I)
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define INRECT(r, x, y)
Definition: region.c:158
RECTL * Buffer
Definition: region.h:16
RGNDATAHEADER rdh
Definition: region.h:15
unsigned int ULONG
Definition: retypes.h:1

Referenced by NtGdiExtFloodFill(), NtGdiPtInRegion(), and NtGdiPtVisible().

◆ REGION_PtsToRegion()

static INT FASTCALL REGION_PtsToRegion ( INT  numFullPtBlocks,
INT  iCurPtBlock,
POINTBLOCK FirstPtBlock,
PREGION  reg 
)
static

Definition at line 3063 of file region.c.

3068 {
3069  RECTL *rects;
3070  POINT *pts;
3071  POINTBLOCK *CurPtBlock;
3072  INT i;
3073  RECTL *extents, *temp;
3074  INT numRects;
3075 
3076  extents = &reg->rdh.rcBound;
3077 
3078  numRects = ((numFullPtBlocks * NUMPTSTOBUFFER) + iCurPtBlock) >> 1;
3079 
3080  /* Make sure, we have at least one rect */
3081  if (numRects == 0)
3082  {
3083  numRects = 1;
3084  }
3085 
3086  temp = ExAllocatePoolWithTag(PagedPool, numRects * sizeof(RECT), TAG_REGION);
3087  if (temp == NULL)
3088  {
3089  return 0;
3090  }
3091 
3092  if (reg->Buffer != NULL)
3093  {
3094  COPY_RECTS(temp, reg->Buffer, reg->rdh.nCount);
3095  if (reg->Buffer != &reg->rdh.rcBound)
3096  ExFreePoolWithTag(reg->Buffer, TAG_REGION);
3097  }
3098  reg->Buffer = temp;
3099 
3100  reg->rdh.nCount = numRects;
3101  CurPtBlock = FirstPtBlock;
3102  rects = reg->Buffer - 1;
3103  numRects = 0;
3104  extents->left = LARGE_COORDINATE, extents->right = SMALL_COORDINATE;
3105 
3106  for ( ; numFullPtBlocks >= 0; numFullPtBlocks--)
3107  {
3108  /* The loop uses 2 points per iteration */
3109  i = NUMPTSTOBUFFER >> 1;
3110  if (numFullPtBlocks == 0)
3111  i = iCurPtBlock >> 1;
3112 
3113  for (pts = CurPtBlock->pts; i--; pts += 2)
3114  {
3115  if (pts->x == pts[1].x)
3116  continue;
3117 
3118  if ((numRects && pts->x == rects->left) &&
3119  (pts->y == rects->bottom) &&
3120  (pts[1].x == rects->right) &&
3121  ((numRects == 1) || (rects[-1].top != rects->top)) &&
3122  (i && pts[2].y > pts[1].y))
3123  {
3124  rects->bottom = pts[1].y + 1;
3125  continue;
3126  }
3127 
3128  numRects++;
3129  rects++;
3130  rects->left = pts->x;
3131  rects->top = pts->y;
3132  rects->right = pts[1].x;
3133  rects->bottom = pts[1].y + 1;
3134 
3135  if (rects->left < extents->left)
3136  extents->left = rects->left;
3137  if (rects->right > extents->right)
3138  extents->right = rects->right;
3139  }
3140 
3141  CurPtBlock = CurPtBlock->next;
3142  }
3143 
3144  if (numRects)
3145  {
3146  extents->top = reg->Buffer->top;
3147  extents->bottom = rects->bottom;
3148  }
3149  else
3150  {
3151  extents->left = 0;
3152  extents->top = 0;
3153  extents->right = 0;
3154  extents->bottom = 0;
3155  }
3156 
3157  reg->rdh.nCount = numRects;
3158 
3159  return(TRUE);
3160 }
#define TRUE
Definition: types.h:120
long y
Definition: polytest.cpp:48
long x
Definition: polytest.cpp:48
#define TAG_REGION
Definition: tags.h:22
long bottom
Definition: polytest.cpp:53
int32_t INT
Definition: typedefs.h:56
struct _POINTBLOCK * next
Definition: region.c:532
long right
Definition: polytest.cpp:53
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define SMALL_COORDINATE
Definition: region.c:414
long top
Definition: polytest.cpp:53
smooth NULL
Definition: ftsmooth.c:416
long left
Definition: polytest.cpp:53
POINT pts[NUMPTSTOBUFFER]
Definition: region.c:531
#define COPY_RECTS(dest, src, nRects)
Definition: region.c:136
#define LARGE_COORDINATE
Definition: region.c:413
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define NUMPTSTOBUFFER
Definition: region.c:524
static calc_node_t temp
Definition: rpn_ieee.c:38
static int reg
Definition: i386-dis.c:1275
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099

Referenced by REGION_SetPolyPolygonRgn().

◆ REGION_RectInRegion()

BOOL FASTCALL REGION_RectInRegion ( PREGION  Rgn,
const RECTL rect 
)

Definition at line 2625 of file region.c.

2628 {
2629  PRECTL pCurRect, pRectEnd;
2630  RECT rc;
2631 
2632  /* Swap the coordinates to make right >= left and bottom >= top */
2633  /* (region building rectangles are normalized the same way) */
2634  if (rect->top > rect->bottom)
2635  {
2636  rc.top = rect->bottom;
2637  rc.bottom = rect->top;
2638  }
2639  else
2640  {
2641  rc.top = rect->top;
2642  rc.bottom = rect->bottom;
2643  }
2644 
2645  if (rect->right < rect->left)
2646  {
2647  rc.right = rect->left;
2648  rc.left = rect->right;
2649  }
2650  else
2651  {
2652  rc.right = rect->right;
2653  rc.left = rect->left;
2654  }
2655 
2656  /* This is (just) a useful optimization */
2657  if ((Rgn->rdh.nCount > 0) && EXTENTCHECK(&Rgn->rdh.rcBound, &rc))
2658  {
2659  for (pCurRect = Rgn->Buffer, pRectEnd = pCurRect +
2660  Rgn->rdh.nCount; pCurRect < pRectEnd; pCurRect++)
2661  {
2662  if (pCurRect->bottom <= rc.top)
2663  continue; /* Not far enough down yet */
2664 
2665  if (pCurRect->top >= rc.bottom)
2666  break; /* Too far down */
2667 
2668  if (pCurRect->right <= rc.left)
2669  continue; /* Not far enough over yet */
2670 
2671  if (pCurRect->left >= rc.right)
2672  {
2673  continue;
2674  }
2675 
2676  return TRUE;
2677  }
2678  }
2679 
2680  return FALSE;
2681 }
#define TRUE
Definition: types.h:120
LONG top
Definition: windef.h:292
long bottom
Definition: polytest.cpp:53
LONG left
Definition: windef.h:291
LONG right
Definition: windef.h:293
& rect
Definition: startmenu.cpp:1413
long right
Definition: polytest.cpp:53
long top
Definition: polytest.cpp:53
RECTL * Buffer
Definition: region.h:16
long left
Definition: polytest.cpp:53
#define EXTENTCHECK(r1, r2)
Definition: region.c:167
RGNDATAHEADER rdh
Definition: region.h:15
LONG bottom
Definition: windef.h:294

Referenced by IntRectInRegion(), and NtGdiRectVisible().

◆ REGION_RegionOp()

static BOOL FASTCALL REGION_RegionOp ( PREGION  newReg,
PREGION  reg1,
PREGION  reg2,
overlapProcp  overlapFunc,
nonOverlapProcp  nonOverlap1Func,
nonOverlapProcp  nonOverlap2Func 
)
static
  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.

Note
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.

Definition at line 960 of file region.c.

967 {
968  RECTL *r1; /* Pointer into first region */
969  RECTL *r2; /* Pointer into 2d region */
970  RECTL *r1End; /* End of 1st region */
971  RECTL *r2End; /* End of 2d region */
972  INT ybot; /* Bottom of intersection */
973  INT ytop; /* Top of intersection */
974  RECTL *oldRects; /* Old rects for newReg */
975  ULONG prevBand; /* Index of start of
976  * Previous band in newReg */
977  ULONG curBand; /* Index of start of current band in newReg */
978  RECTL *r1BandEnd; /* End of current band in r1 */
979  RECTL *r2BandEnd; /* End of current band in r2 */
980  ULONG top; /* Top of non-overlapping band */
981  ULONG bot; /* Bottom of non-overlapping band */
982 
983  /* Initialization:
984  * set r1, r2, r1End and r2End appropriately, preserve the important
985  * parts of the destination region until the end in case it's one of
986  * the two source regions, then mark the "new" region empty, allocating
987  * another array of rectangles for it to use. */
988  r1 = reg1->Buffer;
989  r2 = reg2->Buffer;
990  r1End = r1 + reg1->rdh.nCount;
991  r2End = r2 + reg2->rdh.nCount;
992 
993  /* newReg may be one of the src regions so we can't empty it. We keep a
994  * note of its rects pointer (so that we can free them later), preserve its
995  * extents and simply set numRects to zero. */
996  oldRects = newReg->Buffer;
997  newReg->rdh.nCount = 0;
998 
999  /* Allocate a reasonable number of rectangles for the new region. The idea
1000  * is to allocate enough so the individual functions don't need to
1001  * reallocate and copy the array, which is time consuming, yet we don't
1002  * have to worry about using too much memory. I hope to be able to
1003  * nuke the Xrealloc() at the end of this function eventually. */
1004  newReg->rdh.nRgnSize = max(reg1->rdh.nCount + 1, reg2->rdh.nCount) * 2 * sizeof(RECT);
1005 
1007  newReg->rdh.nRgnSize,
1008  TAG_REGION);
1009  if (newReg->Buffer == NULL)
1010  {
1011  newReg->rdh.nRgnSize = 0;
1012  return FALSE;
1013  }
1014 
1015  /* Initialize ybot and ytop.
1016  * In the upcoming loop, ybot and ytop serve different functions depending
1017  * on whether the band being handled is an overlapping or non-overlapping
1018  * band.
1019  * In the case of a non-overlapping band (only one of the regions
1020  * has points in the band), ybot is the bottom of the most recent
1021  * intersection and thus clips the top of the rectangles in that band.
1022  * ytop is the top of the next intersection between the two regions and
1023  * serves to clip the bottom of the rectangles in the current band.
1024  * For an overlapping band (where the two regions intersect), ytop clips
1025  * the top of the rectangles of both regions and ybot clips the bottoms. */
1026  if (reg1->rdh.rcBound.top < reg2->rdh.rcBound.top)
1027  ybot = reg1->rdh.rcBound.top;
1028  else
1029  ybot = reg2->rdh.rcBound.top;
1030 
1031  /* prevBand serves to mark the start of the previous band so rectangles
1032  * can be coalesced into larger rectangles. qv. miCoalesce, above.
1033  * In the beginning, there is no previous band, so prevBand == curBand
1034  * (curBand is set later on, of course, but the first band will always
1035  * start at index 0). prevBand and curBand must be indices because of
1036  * the possible expansion, and resultant moving, of the new region's
1037  * array of rectangles. */
1038  prevBand = 0;
1039  do
1040  {
1041  curBand = newReg->rdh.nCount;
1042 
1043  /* This algorithm proceeds one source-band (as opposed to a
1044  * destination band, which is determined by where the two regions
1045  * intersect) at a time. r1BandEnd and r2BandEnd serve to mark the
1046  * rectangle after the last one in the current band for their
1047  * respective regions. */
1048  r1BandEnd = r1;
1049  while ((r1BandEnd != r1End) && (r1BandEnd->top == r1->top))
1050  {
1051  r1BandEnd++;
1052  }
1053 
1054  r2BandEnd = r2;
1055  while ((r2BandEnd != r2End) && (r2BandEnd->top == r2->top))
1056  {
1057  r2BandEnd++;
1058  }
1059 
1060  /* First handle the band that doesn't intersect, if any.
1061  *
1062  * Note that attention is restricted to one band in the
1063  * non-intersecting region at once, so if a region has n
1064  * bands between the current position and the next place it overlaps
1065  * the other, this entire loop will be passed through n times. */
1066  if (r1->top < r2->top)
1067  {
1068  top = max(r1->top,ybot);
1069  bot = min(r1->bottom,r2->top);
1070 
1071  if ((top != bot) && (nonOverlap1Func != NULL))
1072  {
1073  if (!(*nonOverlap1Func)(newReg, r1, r1BandEnd, top, bot)) return FALSE;
1074  }
1075 
1076  ytop = r2->top;
1077  }
1078  else if (r2->top < r1->top)
1079  {
1080  top = max(r2->top,ybot);
1081  bot = min(r2->bottom,r1->top);
1082 
1083  if ((top != bot) && (nonOverlap2Func != NULL))
1084  {
1085  if (!(*nonOverlap2Func)(newReg, r2, r2BandEnd, top, bot) ) return FALSE;
1086  }
1087 
1088  ytop = r1->top;
1089  }
1090  else
1091  {
1092  ytop = r1->top;
1093  }
1094 
1095  /* If any rectangles got added to the region, try and coalesce them
1096  * with rectangles from the previous band. Note we could just do
1097  * this test in miCoalesce, but some machines incur a not
1098  * inconsiderable cost for function calls, so... */
1099  if (newReg->rdh.nCount != curBand)
1100  {
1101  prevBand = REGION_Coalesce(newReg, prevBand, curBand);
1102  }
1103 
1104  /* Now see if we've hit an intersecting band. The two bands only
1105  * intersect if ybot > ytop */
1106  ybot = min(r1->bottom, r2->bottom);
1107  curBand = newReg->rdh.nCount;
1108  if (ybot > ytop)
1109  {
1110  if (!(*overlapFunc)(newReg, r1, r1BandEnd, r2, r2BandEnd, ytop, ybot)) return FALSE;
1111  }
1112 
1113  if (newReg->rdh.nCount != curBand)
1114  {
1115  prevBand = REGION_Coalesce(newReg, prevBand, curBand);
1116  }
1117 
1118  /* If we've finished with a band (bottom == ybot) we skip forward
1119  * in the region to the next band. */
1120  if (r1->bottom == ybot)
1121  {
1122  r1 = r1BandEnd;
1123  }
1124  if (r2->bottom == ybot)
1125  {
1126  r2 = r2BandEnd;
1127  }
1128  }
1129  while ((r1 != r1End) && (r2 != r2End));
1130 
1131  /* Deal with whichever region still has rectangles left. */
1132  curBand = newReg->rdh.nCount;
1133  if (r1 != r1End)
1134  {
1135  if (nonOverlap1Func != NULL)
1136  {
1137  do
1138  {
1139  r1BandEnd = r1;
1140  while ((r1BandEnd < r1End) && (r1BandEnd->top == r1->top))
1141  {
1142  r1BandEnd++;
1143  }
1144 
1145  if (!(*nonOverlap1Func)(newReg,
1146  r1,
1147  r1BandEnd,
1148  max(r1->top,ybot),
1149  r1->bottom))
1150  return FALSE;
1151  r1 = r1BandEnd;
1152  }
1153  while (r1 != r1End);
1154  }
1155  }
1156  else if ((r2 != r2End) && (nonOverlap2Func != NULL))
1157  {
1158  do
1159  {
1160  r2BandEnd = r2;
1161  while ((r2BandEnd < r2End) && (r2BandEnd->top == r2->top))
1162  {
1163  r2BandEnd++;
1164  }
1165 
1166  if (!(*nonOverlap2Func)(newReg,
1167  r2,
1168  r2BandEnd,
1169  max(r2->top,ybot),
1170  r2->bottom))
1171  return FALSE;
1172  r2 = r2BandEnd;
1173  }
1174  while (r2 != r2End);
1175  }
1176 
1177  if (newReg->rdh.nCount != curBand)
1178  {
1179  (VOID)REGION_Coalesce(newReg, prevBand, curBand);
1180  }
1181 
1182  /* A bit of cleanup. To keep regions from growing without bound,
1183  * we shrink the array of rectangles to match the new number of
1184  * rectangles in the region. This never goes to 0, however...
1185  *
1186  * Only do this stuff if the number of rectangles allocated is more than
1187  * twice the number of rectangles in the region (a simple optimization...). */
1188  if ((newReg->rdh.nRgnSize > (2 * newReg->rdh.nCount * sizeof(RECT))) &&
1189  (newReg->rdh.nCount > 2))
1190  {
1191  if (REGION_NOT_EMPTY(newReg))
1192  {
1193  RECTL *prev_rects = newReg->Buffer;
1195  newReg->rdh.nCount * sizeof(RECT),
1196  TAG_REGION);
1197 
1198  if (newReg->Buffer == NULL)
1199  {
1200  newReg->Buffer = prev_rects;
1201  }
1202  else
1203  {
1204  newReg->rdh.nRgnSize = newReg->rdh.nCount*sizeof(RECT);
1205  COPY_RECTS(newReg->Buffer, prev_rects, newReg->rdh.nCount);
1206  if (prev_rects != &newReg->rdh.rcBound)
1207  ExFreePoolWithTag(prev_rects, TAG_REGION);
1208  }
1209  }
1210  else
1211  {
1212  /* No point in doing the extra work involved in an Xrealloc if
1213  * the region is empty */
1214  newReg->rdh.nRgnSize = sizeof(RECT);
1215  if (newReg->Buffer != &newReg->rdh.rcBound)
1217 
1219  sizeof(RECT),
1220  TAG_REGION);
1221  ASSERT(newReg->Buffer);
1222  }
1223  }
1224 
1225  newReg->rdh.iType = RDH_RECTANGLES;
1226 
1227  if (oldRects != &newReg->rdh.rcBound)
1228  ExFreePoolWithTag(oldRects, TAG_REGION);
1229  return TRUE;
1230 }
#define max(a, b)
Definition: svc.c:63
#define TRUE
Definition: types.h:120
#define TAG_REGION
Definition: tags.h:22
static DNS_RECORDW r1
Definition: record.c:37
#define REGION_NOT_EMPTY(pReg)
Definition: region.c:156
LONG top
Definition: windef.h:292
int32_t INT
Definition: typedefs.h:56
struct tagRECT RECT
static INT FASTCALL REGION_Coalesce(PREGION pReg, INT prevStart, INT curStart)
Definition: region.c:822
long top
Definition: polytest.cpp:53
RECTL * Buffer
Definition: region.h:16
smooth NULL
Definition: ftsmooth.c:416
#define RDH_RECTANGLES
Definition: wingdi.h:668
static DNS_RECORDW r2
Definition: record.c:38
#define COPY_RECTS(dest, src, nRects)
Definition: region.c:136
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define VOID
Definition: acefi.h:82
RGNDATAHEADER rdh
Definition: region.h:15
#define min(a, b)
Definition: monoChain.cc:55
unsigned int ULONG
Definition: retypes.h:1
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:10859
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099

Referenced by REGION_IntersectRegion(), REGION_SubtractRegion(), and REGION_UnionRegion().

◆ REGION_SetExtents()

static VOID FASTCALL REGION_SetExtents ( PREGION  pReg)
static

Definition at line 630 of file region.c.

632 {
633  RECTL *pRect, *pRectEnd, *pExtents;
634 
635  /* Quick check for NULLREGION */
636  if (pReg->rdh.nCount == 0)
637  {
638  pReg->rdh.rcBound.left = 0;
639  pReg->rdh.rcBound.top = 0;
640  pReg->rdh.rcBound.right = 0;
641  pReg->rdh.rcBound.bottom = 0;
642  pReg->rdh.iType = RDH_RECTANGLES;
643  return;
644  }
645 
646  pExtents = &pReg->rdh.rcBound;
647  pRect = pReg->Buffer;