ReactOS  0.4.13-dev-73-gcfe54aa
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 4105 of file region.c.

4113 {
4114  ULONG cjRects, cjSize;
4115  PREGION prgn;
4116 
4117  /* Lock the region */
4118  prgn = REGION_LockRgn(hrgn);
4119  if (prgn == NULL)
4120  {
4122  return 0;
4123  }
4124 
4125  /* Calculate the region sizes */
4126  cjRects = prgn->rdh.nCount * sizeof(RECT);
4127  cjSize = cjRects + sizeof(RGNDATAHEADER);
4128 
4129  /* Check if region data is requested */
4130  if (lpRgnData)
4131  {
4132  /* Check if the buffer is large enough */
4133  if (cjBuffer >= cjSize)
4134  {
4135  /* Probe the buffer and copy the data */
4136  _SEH2_TRY
4137  {
4138  ProbeForWrite(lpRgnData, cjSize, sizeof(ULONG));
4139  RtlCopyMemory(lpRgnData, &prgn->rdh, sizeof(RGNDATAHEADER));
4140  RtlCopyMemory(lpRgnData->Buffer, prgn->Buffer, cjRects);
4141  lpRgnData->rdh.iType = RDH_RECTANGLES;
4142  lpRgnData->rdh.nRgnSize = cjRects;
4143  }
4145  {
4147  cjSize = 0;
4148  }
4149  _SEH2_END;
4150  }
4151  else
4152  {
4153  /* Buffer is too small */
4155  cjSize = 0;
4156  }
4157  }
4158 
4159  /* Unlock the region and return the size */
4160  REGION_UnlockRgn(prgn);
4161  return cjSize;
4162 }
#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:2380
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:2395
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:2380
_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:2395
_Out_opt_ int * cx
Definition: commctrl.h:570
PREGION FASTCALL REGION_AllocUserRgnWithHandle(INT nRgn)
Definition: region.c:2316
VOID FASTCALL REGION_Delete(PREGION pRgn)
Definition: region.c:2471
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 3474 of file region.c.

3479 {
3480  PREGION prgn;
3481  HRGN hrgn;
3482 
3483  /* Allocate a new region */
3485  if (prgn == NULL)
3486  {
3488  return NULL;
3489  }
3490 
3491  /* Call the internal function and check for success */
3492  if (REGION_SetPolyPolygonRgn(prgn, ppt, pcPoints, cPolygons, iMode))
3493  {
3494  /* Success, get the handle and unlock the region */
3495  hrgn = prgn->BaseObject.hHmgr;
3496  REGION_UnlockRgn(prgn);
3497  }
3498  else
3499  {
3500  /* Failure, delete the region */
3501  REGION_Delete(prgn);
3502  hrgn = NULL;
3503  }
3504 
3505  return hrgn;
3506 }
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:3278
_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:2395
PREGION FASTCALL REGION_AllocUserRgnWithHandle(INT nRgn)
Definition: region.c:2316
VOID FASTCALL REGION_Delete(PREGION pRgn)
Definition: region.c:2471
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 2509 of file region.c.

2514 {
2515  BOOL Ret = TRUE;
2516 
2517  if (prgnDest == NULL)
2518  {
2519  DPRINT("IntGdiCombineRgn: hDest unavailable\n");
2520  return ERROR;
2521  }
2522 
2523  if (prgnSrc1 == NULL)
2524  {
2525  DPRINT("IntGdiCombineRgn: hSrc1 unavailable\n");
2526  return ERROR;
2527  }
2528 
2529  if (iCombineMode == RGN_COPY)
2530  {
2531  if (!REGION_CopyRegion(prgnDest, prgnSrc1))
2532  return ERROR;
2533 
2534  return REGION_Complexity(prgnDest);
2535  }
2536 
2537  if (prgnSrc2 == NULL)
2538  {
2539  DPRINT1("IntGdiCombineRgn requires hSrc2 != NULL for combine mode %d!\n", iCombineMode);
2540  ASSERT(FALSE);
2541  return ERROR;
2542  }
2543 
2544  switch (iCombineMode)
2545  {
2546  case RGN_AND:
2547  Ret = REGION_IntersectRegion(prgnDest, prgnSrc1, prgnSrc2);
2548  break;
2549  case RGN_OR:
2550  Ret = REGION_UnionRegion(prgnDest, prgnSrc1, prgnSrc2);
2551  break;
2552  case RGN_XOR:
2553  Ret = REGION_XorRegion(prgnDest, prgnSrc1, prgnSrc2);
2554  break;
2555  case RGN_DIFF:
2556  Ret = REGION_SubtractRegion(prgnDest, prgnSrc1, prgnSrc2);
2557  break;
2558  }
2559 
2560  return Ret ? REGION_Complexity(prgnDest) : ERROR;
2561 }
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 CLIPPING_UpdateGCRegion(), co_IntGetUpdateRgn(), co_UserRedrawWindow(), co_VIS_WindowLayoutChanged(), co_WinPosSetWindowPos(), DC_vCopyState(), DceUpdateVisRgn(), GdiSelectVisRgn(), IntGdiBitBltRgn(), IntGdiExtSelectClipRgn(), IntGdiFillRgn(), IntGdiSetMetaRgn(), IntInvalidateWindows(), IntScrollWindowEx(), IntValidateParents(), NtGdiCombineRgn(), NtGdiGetRandomRgn(), REGION_LPTODP(), UserScrollDC(), and VIS_ComputeVisibleRegion().

◆ IntGdiGetRgnBox()

INT APIENTRY IntGdiGetRgnBox ( HRGN  hRgn,
PRECTL  pRect 
)

Definition at line 2583 of file region.c.

2586 {
2587  PREGION Rgn;
2588  DWORD ret;
2589 
2590  Rgn = REGION_LockRgn(hRgn);
2591  if (Rgn == NULL)
2592  {
2593  return ERROR;
2594  }
2595 
2596  ret = REGION_GetRgnBox(Rgn, pRect);
2597  REGION_UnlockRgn(Rgn);
2598 
2599  return ret;
2600 }
#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:2380
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:2395
INT FASTCALL REGION_GetRgnBox(PREGION Rgn, PRECTL pRect)
Definition: region.c:2565

Referenced by co_UserGetUpdateRect(), and IntGetNCUpdateRgn().

◆ IntGdiSetRegionOwner()

BOOL FASTCALL IntGdiSetRegionOwner ( HRGN  hRgn,
DWORD  OwnerMask 
)

Definition at line 2481 of file region.c.

2482 {
2483  PREGION prgn;
2484  PRGN_ATTR prgnattr;
2485  PPROCESSINFO ppi;
2486 
2487  prgn = REGION_LockRgn(hRgn);
2488  if (prgn == NULL)
2489  {
2490  return FALSE;
2491  }
2492 
2493  prgnattr = prgn->prgnattr;
2494  if (prgnattr != &prgn->rgnattr)
2495  {
2497  prgn->prgnattr = &prgn->rgnattr;
2499  GdiPoolFree(ppi->pPoolRgnAttr, prgnattr);
2500  }
2501 
2502  REGION_UnlockRgn(prgn);
2503 
2504  return GreSetObjectOwner(hRgn, OwnerMask);
2505 }
BASEOBJECT BaseObject
Definition: region.h:11
BOOL NTAPI GreSetObjectOwner(HGDIOBJ hobj, ULONG ulOwner)
Definition: gdiobj.c:1250
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:2380
_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:1091
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:2395

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

◆ IntRectInRegion()

BOOL FASTCALL IntRectInRegion ( HRGN  hRgn,
LPRECTL  rc 
)

Definition at line 3510 of file region.c.

3513 {
3514  PREGION Rgn;
3515  BOOL Ret;
3516 
3517  Rgn = REGION_LockRgn(hRgn);
3518  if (Rgn == NULL)
3519  {
3520  return ERROR;
3521  }
3522 
3523  Ret = REGION_RectInRegion(Rgn, rc);
3524  REGION_UnlockRgn(Rgn);
3525  return Ret;
3526 }
#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:2380
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:2628
Definition: region.h:7
VOID FASTCALL REGION_UnlockRgn(_In_ PREGION prgn)
Definition: region.c:2395

Referenced by NtGdiRectInRegion().

◆ IntSysCreateRectpRgn()

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

Definition at line 2429 of file region.c.

2434 {
2435  PREGION prgn;
2436 
2437  /* Allocate a region, without a handle */
2439  if (prgn == NULL)
2440  {
2441  return NULL;
2442  }
2443 
2444  /* Initialize it */
2445  prgn->Buffer = &prgn->rdh.rcBound;
2446  prgn->prgnattr = &prgn->rgnattr;
2448  REGION_SetRectRgn(prgn, LeftRect, TopRect, RightRect, BottomRect);
2449 
2450  return prgn;
2451 }
#define ATTR_RGN_VALID
Definition: ntgdihdl.h:206
_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:265
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:2688
POBJ NTAPI GDIOBJ_AllocateObject(UCHAR objt, ULONG cjSize, FLONG fl)
Definition: gdiobj.c:557

Referenced by CLIPPING_UpdateGCRegion(), co_UserRedrawWindow(), co_VIS_WindowLayoutChanged(), co_WinPosSetWindowPos(), DC_vCopyState(), DC_vInitDc(), DC_vUpdateDC(), DceGetVisRgn(), DceUpdateVisRgn(), IntGdiBitBltRgn(), IntGdiExtSelectClipRgn(), IntGdiFillRgn(), 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 3534 of file region.c.

3539 {
3540  HRGN ahrgn[3];
3541  PREGION aprgn[3];
3542  INT iResult;
3543 
3544  /* Validate the combine mode */
3545  if ((iMode < RGN_AND) || (iMode > RGN_COPY))
3546  {
3547  return ERROR;
3548  }
3549 
3550  /* Validate that we have the required regions */
3551  if ((hrgnDst == NULL) ||
3552  (hrgnSrc1 == NULL) ||
3553  ((iMode != RGN_COPY) && (hrgnSrc2 == NULL)))
3554  {
3555  DPRINT1("NtGdiCombineRgn invalid parameters: %p, %p, %p, %d\n",
3556  hrgnDst, hrgnSrc1, hrgnSrc2, iMode);
3558  return ERROR;
3559  }
3560 
3561  /* Lock all regions */
3562  ahrgn[0] = hrgnDst;
3563  ahrgn[1] = hrgnSrc1;
3564  ahrgn[2] = iMode != RGN_COPY ? hrgnSrc2 : NULL;
3565  if (!GDIOBJ_bLockMultipleObjects(3, (HGDIOBJ*)ahrgn, (PVOID*)aprgn, GDIObjType_RGN_TYPE))
3566  {
3567  DPRINT1("NtGdiCombineRgn failed to lock regions: %p, %p, %p, %d\n",
3568  hrgnDst, hrgnSrc1, hrgnSrc2, iMode);
3569  return ERROR;
3570  }
3571 
3572  /* HACK: Sync usermode attributes */
3573  REGION_vSyncRegion(aprgn[0]);
3574  if (aprgn[1] != aprgn[0])
3575  REGION_vSyncRegion(aprgn[1]);
3576  if ((aprgn[2] != NULL) && (aprgn[2] != aprgn[0]) && (aprgn[2] != aprgn[1]))
3577  REGION_vSyncRegion(aprgn[2]);
3578 
3579  /* Call the internal function */
3580  iResult = IntGdiCombineRgn(aprgn[0], aprgn[1], aprgn[2], iMode);
3581 
3582  /* Unlock and return */
3583  REGION_UnlockRgn(aprgn[0]);
3584  REGION_UnlockRgn(aprgn[1]);
3585  if (aprgn[2] != NULL)
3586  REGION_UnlockRgn(aprgn[2]);
3587 
3588  return iResult;
3589 }
_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:1026
INT FASTCALL IntGdiCombineRgn(PREGION prgnDest, PREGION prgnSrc1, PREGION prgnSrc2, INT iCombineMode)
Definition: region.c:2509
#define RGN_COPY
Definition: wingdi.h:356
#define DPRINT1
Definition: precomp.h:8
VOID FASTCALL REGION_UnlockRgn(_In_ PREGION prgn)
Definition: region.c:2395
static VOID REGION_vSyncRegion(_In_ PREGION prgn)
Definition: region.c:2337
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 3593 of file region.c.

3598 {
3599  return NtGdiCreateRoundRectRgn(Left,
3600  Top,
3601  Right, Bottom,
3602  Right - Left,
3603  Bottom - Top);
3604 }
HRGN APIENTRY NtGdiCreateRoundRectRgn(INT left, INT top, INT right, INT bottom, INT ellipse_width, INT ellipse_height)
Definition: region.c:3637
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 3608 of file region.c.

3613 {
3614  PREGION pRgn;
3615  HRGN hRgn;
3616 
3617  /* Allocate region data structure with space for 1 RECTL */
3619  if (pRgn == NULL)
3620  {
3622  return NULL;
3623  }
3624 
3625  hRgn = pRgn->BaseObject.hHmgr;
3626 
3627  REGION_SetRectRgn(pRgn, LeftRect, TopRect, RightRect, BottomRect);
3628  REGION_UnlockRgn(pRgn);
3629 
3630  DPRINT("Returning %p.\n", hRgn);
3631 
3632  return hRgn;
3633 }
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:2395
VOID FASTCALL REGION_SetRectRgn(PREGION rgn, INT LeftRect, INT TopRect, INT RightRect, INT BottomRect)
Definition: region.c:2688
PREGION FASTCALL REGION_AllocUserRgnWithHandle(INT nRgn)
Definition: region.c:2316
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 3637 of file region.c.

3644 {
3645  PREGION obj;
3646  HRGN hrgn;
3647  int a, b, i, x, y;
3648  INT64 asq, bsq, dx, dy, err;
3649  RECT *rects;
3650 
3651  /* Make the dimensions sensible */
3652  if (left > right)
3653  {
3654  INT tmp = left;
3655  left = right;
3656  right = tmp;
3657  }
3658 
3659  if (top > bottom)
3660  {
3661  INT tmp = top;
3662  top = bottom;
3663  bottom = tmp;
3664  }
3665 
3666  /* the region is for the rectangle interior, but only at right and bottom for some reason */
3667  right--;
3668  bottom--;
3669 
3670  ellipse_width = min( right - left, abs( ellipse_width ));
3671  ellipse_height = min( bottom - top, abs( ellipse_height ));
3672 
3673  /* Check if we can do a normal rectangle instead */
3674 
3675  if ((ellipse_width < 2) || (ellipse_height < 2))
3676  return NtGdiCreateRectRgn(left, top, right, bottom);
3677 
3678  obj = REGION_AllocUserRgnWithHandle( ellipse_height );
3679  if (obj == NULL)
3680  return 0;
3681 
3682  hrgn = obj->BaseObject.hHmgr;
3683 
3684  obj->rdh.rcBound.left = left;
3685  obj->rdh.rcBound.top = top;
3686  obj->rdh.rcBound.right = right;
3687  obj->rdh.rcBound.bottom = bottom;
3688  rects = obj->Buffer;
3689 
3690  /* based on an algorithm by Alois Zingl */
3691 
3692  a = ellipse_width - 1;
3693  b = ellipse_height - 1;
3694  asq = (INT64)8 * a * a;
3695  bsq = (INT64)8 * b * b;
3696  dx = (INT64)4 * b * b * (1 - a);
3697  dy = (INT64)4 * a * a * (1 + (b % 2));
3698  err = dx + dy + a * a * (b % 2);
3699 
3700  x = 0;
3701  y = ellipse_height / 2;
3702 
3703  rects[y].left = left;
3704  rects[y].right = right;
3705 
3706  while (x <= ellipse_width / 2)
3707  {
3708  INT64 e2 = 2 * err;
3709  if (e2 >= dx)
3710  {
3711  x++;
3712  err += dx += bsq;
3713  }
3714  if (e2 <= dy)
3715  {
3716  y++;
3717  err += dy += asq;
3718  rects[y].left = left + x;
3719  rects[y].right = right - x;
3720  }
3721  }
3722  for (i = 0; i < ellipse_height / 2; i++)
3723  {
3724  rects[i].left = rects[b - i].left;
3725  rects[i].right = rects[b - i].right;
3726  rects[i].top = top + i;
3727  rects[i].bottom = rects[i].top + 1;
3728  }
3729  for (; i < ellipse_height; i++)
3730  {
3731  rects[i].top = bottom - ellipse_height + i;
3732  rects[i].bottom = rects[i].top + 1;
3733  }
3734  rects[ellipse_height / 2].top = top + ellipse_height / 2; /* extend to top of rectangle */
3735 
3737  return hrgn;
3738 }
#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:3608
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:2395
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:2316

Referenced by NtGdiCreateEllipticRgn().

◆ NtGdiEqualRgn()

BOOL APIENTRY NtGdiEqualRgn ( HRGN  hSrcRgn1,
HRGN  hSrcRgn2 
)

Definition at line 3742 of file region.c.

3745 {
3746  HRGN ahrgn[2];
3747  PREGION aprgn[2];
3748  PREGION rgn1, rgn2;
3749  PRECTL tRect1, tRect2;
3750  ULONG i;
3751  BOOL bRet = FALSE;
3752 
3753  /* Check if we got 2 regions */
3754  if ((hSrcRgn1 == NULL) || (hSrcRgn2 == NULL))
3755  {
3756  return FALSE;
3757  }
3758 
3759  /* Check if these are the same regions */
3760  if (hSrcRgn1 == hSrcRgn2)
3761  {
3762  /* Make sure this region is valid */
3763  if ((GDI_HANDLE_GET_TYPE(hSrcRgn1) == GDILoObjType_LO_REGION_TYPE) &&
3764  GreIsHandleValid(hSrcRgn1))
3765  {
3766  return TRUE;
3767  }
3768  return FALSE;
3769  }
3770 
3771  /* Lock both regions */
3772  ahrgn[0] = hSrcRgn1;
3773  ahrgn[1] = hSrcRgn2;
3774  if (!GDIOBJ_bLockMultipleObjects(2, (HGDIOBJ*)ahrgn, (PVOID*)aprgn, GDIObjType_RGN_TYPE))
3775  {
3776  DPRINT1("NtGdiEqualRgn failed to lock regions: %p, %p\n",
3777  hSrcRgn1, hSrcRgn2);
3778  return FALSE;
3779  }
3780 
3781  REGION_vSyncRegion(aprgn[0]);
3782  REGION_vSyncRegion(aprgn[1]);
3783 
3784  rgn1 = aprgn[0];
3785  rgn2 = aprgn[1];
3786 
3787  if (rgn1->rdh.nCount != rgn2->rdh.nCount)
3788  goto exit;
3789 
3790  if (rgn1->rdh.nCount == 0)
3791  {
3792  bRet = TRUE;
3793  goto exit;
3794  }
3795 
3796  if ((rgn1->rdh.rcBound.left != rgn2->rdh.rcBound.left) ||
3797  (rgn1->rdh.rcBound.right != rgn2->rdh.rcBound.right) ||
3798  (rgn1->rdh.rcBound.top != rgn2->rdh.rcBound.top) ||
3799  (rgn1->rdh.rcBound.bottom != rgn2->rdh.rcBound.bottom))
3800  goto exit;
3801 
3802  tRect1 = rgn1->Buffer;
3803  tRect2 = rgn2->Buffer;
3804 
3805  if ((tRect1 == NULL) || (tRect2 == NULL))
3806  goto exit;
3807 
3808  for (i=0; i < rgn1->rdh.nCount; i++)
3809  {
3810  if ((tRect1[i].left != tRect2[i].left) ||
3811  (tRect1[i].right != tRect2[i].right) ||
3812  (tRect1[i].top != tRect2[i].top) ||
3813  (tRect1[i].bottom != tRect2[i].bottom))
3814  goto exit;
3815  }
3816 
3817  bRet = TRUE;
3818 
3819 exit:
3820  REGION_UnlockRgn(rgn1);
3821  REGION_UnlockRgn(rgn2);
3822  return bRet;
3823 }
#define TRUE
Definition: types.h:120
BOOL NTAPI GreIsHandleValid(HGDIOBJ hobj)
Definition: gdiobj.c:1141
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:1026
#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:2395
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:2337

◆ NtGdiExtCreateRegion()

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

Definition at line 3827 of file region.c.

3831 {
3832  HRGN hRgn;
3833  PREGION Region;
3834  DWORD nCount = 0;
3835  DWORD iType = 0;
3836  DWORD dwSize = 0;
3837  UINT i;
3838  RECT* rects;
3840  MATRIX matrix;
3841  XFORMOBJ xo;
3842 
3843  DPRINT("NtGdiExtCreateRegion\n");
3844  _SEH2_TRY
3845  {
3846  ProbeForRead(RgnData, Count, 1);
3847  nCount = RgnData->rdh.nCount;
3848  iType = RgnData->rdh.iType;
3849  dwSize = RgnData->rdh.dwSize;
3850  rects = (RECT*)RgnData->Buffer;
3851  }
3853  {
3855  }
3856  _SEH2_END;
3857 
3858  if (!NT_SUCCESS(Status))
3859  {
3861  return NULL;
3862  }
3863 
3864  /* Check parameters, but don't set last error here */
3865  if ((Count < sizeof(RGNDATAHEADER) + nCount * sizeof(RECT)) ||
3866  (iType != RDH_RECTANGLES) ||
3867  (dwSize != sizeof(RGNDATAHEADER)))
3868  {
3869  return NULL;
3870  }
3871 
3873 
3874  if (Region == NULL)
3875  {
3877  return FALSE;
3878  }
3879  hRgn = Region->BaseObject.hHmgr;
3880 
3881  _SEH2_TRY
3882  {
3883  /* Insert the rectangles one by one */
3884  for(i=0; i<nCount; i++)
3885  {
3886  if ( rects[i].left < rects[i].right && rects[i].top < rects[i].bottom )
3887  {
3888  if (!REGION_UnionRectWithRgn(Region, &rects[i]))
3889  {
3892  hRgn = NULL;
3893  _SEH2_LEAVE;
3894  }
3895  }
3896  }
3897 
3898  if (Xform != NULL)
3899  {
3900  ULONG ret;
3901 
3902  /* Init the XFORMOBJ from the Xform struct */
3904  XFORMOBJ_vInit(&xo, &matrix);
3905  ret = XFORMOBJ_iSetXform(&xo, (XFORML*)Xform);
3906 
3907  /* Check for error */
3908  if (ret != DDI_ERROR)
3909  {
3910  /* Apply the coordinate transformation on the rects */
3911  if (XFORMOBJ_bApplyXform(&xo,
3912  XF_LTOL,
3913  Region->rdh.nCount * 2,
3914  Region->Buffer,
3915  Region->Buffer))
3916  {
3918  }
3919  }
3920  }
3921  }
3923  {
3925  }
3926  _SEH2_END;
3927  if (!NT_SUCCESS(Status))
3928  {
3932  return NULL;
3933  }
3934 
3936 
3937  return hRgn;
3938 }
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
BOOL NTAPI GreDeleteObject(HGDIOBJ hobj)
Definition: gdiobj.c:1153
#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:2395
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:2316
return STATUS_SUCCESS
Definition: btrfs.c:2725
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 3942 of file region.c.

3945 {
3946  PREGION Rgn;
3947  RECTL SafeRect;
3948  DWORD ret;
3950 
3951  Rgn = REGION_LockRgn(hRgn);
3952  if (Rgn == NULL)
3953  {
3954  return ERROR;
3955  }
3956 
3957  ret = REGION_GetRgnBox(Rgn, &SafeRect);
3958  REGION_UnlockRgn(Rgn);
3959  if (ret == ERROR)
3960  {
3961  return ret;
3962  }
3963 
3964  _SEH2_TRY
3965  {
3966  ProbeForWrite(pRect, sizeof(RECT), 1);
3967  *pRect = SafeRect;
3968  }
3970  {
3972  }
3973  _SEH2_END;
3974  if (!NT_SUCCESS(Status))
3975  {
3976  return ERROR;
3977  }
3978 
3979  return ret;
3980 }
#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:2380
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:2395
#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:2565
return STATUS_SUCCESS
Definition: btrfs.c:2725

Referenced by GetRgnBox().

◆ NtGdiOffsetRgn()

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

Definition at line 3984 of file region.c.

3988 {
3989  PREGION prgn;
3990  INT iResult;
3991 
3992  DPRINT("NtGdiOffsetRgn: hrgn %p cx %d cy %d\n", hrgn, cx, cy);
3993 
3994  /* Lock the region */
3995  prgn = REGION_LockRgn(hrgn);
3996  if (prgn == NULL)
3997  {
3998  DPRINT1("NtGdiOffsetRgn: failed to lock region %p\n", hrgn);
3999  return ERROR;
4000  }
4001 
4002  /* Call the internal function */
4003  if (!REGION_bOffsetRgn(prgn, cx, cy))
4004  {
4005  iResult = ERROR;
4006  }
4007  else
4008  {
4009  iResult = REGION_Complexity(prgn);
4010  }
4011 
4012  /* Unlock and return the result */
4013  REGION_UnlockRgn(prgn);
4014  return iResult;
4015 }
#define ERROR(name)
Definition: error_private.h:53
BOOL FASTCALL REGION_bOffsetRgn(_Inout_ PREGION prgn, _In_ INT cx, _In_ INT cy)
Definition: region.c:2730
PREGION FASTCALL REGION_LockRgn(_In_ HRGN hrgn)
Definition: region.c:2380
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:2395
_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 4019 of file region.c.

4023 {
4024  PREGION prgn;
4025  BOOL bResult;
4026 
4027  /* Lock the region */
4028  prgn = REGION_LockRgn(hrgn);
4029  if (prgn == NULL)
4030  {
4031  DPRINT1("NtGdiPtInRegion: hrgn error\n");
4032  return FALSE;
4033  }
4034 
4035  /* Call the internal function */
4036  bResult = REGION_PtInRegion(prgn, x, y);
4037 
4038  /* Unlock and return the result */
4039  REGION_UnlockRgn(prgn);
4040  return bResult;
4041 }
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
PREGION FASTCALL REGION_LockRgn(_In_ HRGN hrgn)
Definition: region.c:2380
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:2395
BOOL FASTCALL REGION_PtInRegion(PREGION prgn, INT X, INT Y)
Definition: region.c:2605

Referenced by IntPtInWindow(), and PtInRegion().

◆ NtGdiRectInRegion()

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

Definition at line 4046 of file region.c.

4049 {
4050  RECTL rcTemp;
4051 
4052  /* Probe and copy the rect */
4053  _SEH2_TRY
4054  {
4055  ProbeForRead(prclUnsafe, sizeof(RECT), 1);
4056  rcTemp = *prclUnsafe;
4057  }
4059  {
4060  DPRINT1("NtGdiRectInRegion: Exception accessing the rect\n");
4061  return FALSE;
4062  }
4063  _SEH2_END;
4064 
4065  /* Call the internal function */
4066  return IntRectInRegion(hrgn, &rcTemp);
4067 }
_SEH2_TRY
Definition: create.c:4250
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
BOOL FASTCALL IntRectInRegion(HRGN hRgn, LPRECTL rc)
Definition: region.c:3510
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 4071 of file region.c.

4077 {
4078  PREGION prgn;
4079 
4080  /* Lock the region */
4081  prgn = REGION_LockRgn(hrgn);
4082  if (prgn == NULL)
4083  {
4084  return FALSE;
4085  }
4086 
4087  /* Call the internal API */
4088  REGION_SetRectRgn(prgn, xLeft, yTop, xRight, yBottom);
4089 
4090  /* Unlock the region and return success */
4091  REGION_UnlockRgn(prgn);
4092  return TRUE;
4093 }
#define TRUE
Definition: types.h:120
PREGION FASTCALL REGION_LockRgn(_In_ HRGN hrgn)
Definition: region.c:2380
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:2395
VOID FASTCALL REGION_SetRectRgn(PREGION rgn, INT LeftRect, INT TopRect, INT RightRect, INT BottomRect)
Definition: region.c:2688

Referenced by co_UserGetUpdateRgn(), and SetRectRgn().

◆ REGION_AllocRgnWithHandle()

PREGION FASTCALL REGION_AllocRgnWithHandle ( INT  nReg)

Definition at line 2222 of file region.c.

2224 {
2225  //HRGN hReg;
2226  PREGION pReg;
2227 
2229  sizeof(REGION),
2231  if (pReg == NULL)
2232  {
2233  DPRINT1("Could not allocate a palette.\n");
2234  return NULL;
2235  }
2236 
2237  //hReg = pReg->BaseObject.hHmgr;
2238 
2239  if ((nReg == 0) || (nReg == 1))
2240  {
2241  /* Testing shows that > 95% of all regions have only 1 rect.
2242  Including that here saves us from having to do another allocation */
2243  pReg->Buffer = &pReg->rdh.rcBound;
2244  }
2245  else
2246  {
2248  nReg * sizeof(RECT),
2249  TAG_REGION);
2250  if (pReg->Buffer == NULL)
2251  {
2252  DPRINT1("Could not allocate region buffer\n");
2254  return NULL;
2255  }
2256  }
2257 
2258  EMPTY_REGION(pReg);
2259  pReg->rdh.dwSize = sizeof(RGNDATAHEADER);
2260  pReg->rdh.nCount = nReg;
2261  pReg->rdh.nRgnSize = nReg * sizeof(RECT);
2262  pReg->prgnattr = &pReg->rgnattr;
2263 
2264  /* Initialize the region attribute */
2265  pReg->rgnattr.AttrFlags = 0;
2267  pReg->rgnattr.Rect = pReg->rdh.rcBound;
2268 
2269  /* Finally insert the region into the handle table */
2271  {
2272  DPRINT1("Could not insert palette into handle table.\n");
2274  return NULL;
2275  }
2276 
2277  return pReg;
2278 }
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:265
VOID NTAPI GDIOBJ_vDeleteObject(POBJ pobj)
Definition: gdiobj.c:1106
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:266
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:267
struct _REGION * PREGION
POBJ NTAPI GDIOBJ_AllocateObject(UCHAR objt, ULONG cjSize, FLONG fl)
Definition: gdiobj.c:557
VOID NTAPI GDIOBJ_vFreeObject(POBJ pobj)
Definition: gdiobj.c:591
HGDIOBJ NTAPI GDIOBJ_hInsertObject(POBJ pobj, ULONG ulOwner)
Definition: gdiobj.c:907

Referenced by REGION_AllocUserRgnWithHandle(), and REGION_XorRegion().

◆ REGION_AllocUserRgnWithHandle()

PREGION FASTCALL REGION_AllocUserRgnWithHandle ( INT  nRgn)

Definition at line 2316 of file region.c.

2318 {
2319  PREGION prgn;
2320 
2321  prgn = REGION_AllocRgnWithHandle(nRgn);
2322  if (prgn == NULL)
2323  {
2324  return NULL;
2325  }
2326 
2327  if (!REGION_bAllocRgnAttr(prgn))
2328  {
2329  ASSERT(FALSE);
2330  }
2331 
2332  return prgn;
2333 }
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:2282
PREGION FASTCALL REGION_AllocRgnWithHandle(INT nReg)
Definition: region.c:2222

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 2282 of file region.c.

2284 {
2285  PPROCESSINFO ppi;
2286  PRGN_ATTR prgnattr;
2287 
2288  NT_ASSERT(prgn->prgnattr == &prgn->rgnattr);
2289 
2291  ASSERT(ppi);
2292 
2293  prgnattr = GdiPoolAllocate(ppi->pPoolRgnAttr);
2294  if (prgnattr == NULL)
2295  {
2296  DPRINT1("Could not allocate RGN attr\n");
2297  return FALSE;
2298  }
2299 
2300  /* Copy the current region attribute */
2301  *prgnattr = prgn->rgnattr;
2302 
2303  /* Set the object attribute in the handle table */
2304  prgn->prgnattr = prgnattr;
2305  GDIOBJ_vSetObjectAttr(&prgn->BaseObject, prgnattr);
2306 
2307  return TRUE;
2308 }
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:1091
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

◆ 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

◆ 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:2730
#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 2730 of file region.c.

2734 {
2735  PRECTL prcl;
2736  UINT i;
2737 
2738  NT_ASSERT(prgn != NULL);
2739 
2740  /* Check for trivial case */
2741  if ((cx == 0) && (cy == 0))
2742  {
2743  return TRUE;
2744  }
2745 
2746  /* Check for empty regions, we ignore the offset values here */
2747  if (prgn->rdh.nCount == 0)
2748  {
2749  return TRUE;
2750  }
2751 
2752  /* Make sure the offset is within the legal range */
2753  if ((cx > MAX_COORD) || (cx < MIN_COORD) ||
2754  (cy > MAX_COORD) || (cy < MIN_COORD))
2755  {
2756  return FALSE;
2757  }
2758 
2759  /* Are we moving right? */
2760  if (cx > 0)
2761  {
2762  /* Check if we stay inside the bounds on the right side */
2763  if (prgn->rdh.rcBound.right > (MAX_COORD - cx))
2764  {
2765  return FALSE;
2766  }
2767  }
2768  else
2769  {
2770  /* Check if we stay inside the bounds on the left side */
2771  if (prgn->rdh.rcBound.left < (MIN_COORD - cx))
2772  {
2773  return FALSE;
2774  }
2775  }
2776 
2777  /* Are we moving down? */
2778  if (cy > 0)
2779  {
2780  /* Check if we stay inside the bounds on the right side */
2781  if (prgn->rdh.rcBound.bottom > (MAX_COORD - cy))
2782  {
2783  return FALSE;
2784  }
2785  }
2786  else
2787  {
2788  /* Check if we stay inside the bounds on the left side */
2789  if (prgn->rdh.rcBound.top < (MIN_COORD - cy))
2790  {
2791  return FALSE;
2792  }
2793  }
2794 
2795  /* Loop to move the rects */
2796  prcl = prgn->Buffer;
2797  for (i = 0; i < prgn->rdh.nCount; i++)
2798  {
2799  prcl[i].left += cx;
2800  prcl[i].right += cx;
2801  prcl[i].top += cy;
2802  prcl[i].bottom += cy;
2803  }
2804 
2805  /* Finally update the bounds rect */
2806  if (prgn->Buffer != &prgn->rdh.rcBound)
2807  {
2808  prgn->rdh.rcBound.left += cx;
2809  prgn->rdh.rcBound.right += cx;
2810  prgn->rdh.rcBound.top += cy;
2811  prgn->rdh.rcBound.bottom += cy;
2812  }
2813 
2814  return TRUE;
2815 }
#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, j, 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  for (j = i; i < prgn->rdh.nCount; i++)
2153  {
2154  NT_ASSERT(prgn->Buffer[i].top < prgn->Buffer[i].bottom);
2155  NT_ASSERT(prgn->Buffer[j].top >= prgn->Buffer[i].top);
2156  }
2157  }
2158 
2159  return TRUE;
2160  }
2161  }
2162  else
2163  {
2164  /* Allocate a buffer for the polygons */
2165  cjSize = prgn->rdh.nCount * (4 * sizeof(POINT) + sizeof(ULONG));
2167  if (ppt == NULL)
2168  {
2169  return FALSE;
2170  }
2171 
2172  /* Fill the buffer with the rects */
2173  pcPoints = (PULONG)&ppt[4 * prgn->rdh.nCount];
2174  for (i = 0; i < prgn->rdh.nCount; i++)
2175  {
2176  /* Make sure the rect is within the legal range */
2177  pcPoints[i] = 4;
2178  ppt[4 * i + 0].x = prgn->Buffer[i].left;
2179  ppt[4 * i + 0].y = prgn->Buffer[i].top;
2180  ppt[4 * i + 1].x = prgn->Buffer[i].right;
2181  ppt[4 * i + 1].y = prgn->Buffer[i].top;
2182  ppt[4 * i + 2].x = prgn->Buffer[i].right;
2183  ppt[4 * i + 2].y = prgn->Buffer[i].bottom;
2184  ppt[4 * i + 3].x = prgn->Buffer[i].left;
2185  ppt[4 * i + 3].y = prgn->Buffer[i].bottom;
2186  }
2187 
2188  /* Initialize the xform object */
2189  XFORMOBJ_vInit(&xo, pmx);
2190 
2191  /* Apply the xform to the rects in the buffer */
2192  if (!XFORMOBJ_bApplyXform(&xo,
2193  XF_LTOL,
2194  prgn->rdh.nCount * 2,
2195  ppt,
2196  ppt))
2197  {
2198  /* This means, there were coordinates that would go outside of
2199  the coordinate space after the transformation */
2201  return FALSE;
2202  }
2203 
2204  /* Now use the polygons to create a polygon region */
2205  bResult = REGION_SetPolyPolygonRgn(prgn,
2206  ppt,
2207  pcPoints,
2208  prgn->rdh.nCount,
2209  WINDING);
2210 
2211  /* Free the polygon buffer */
2213 
2214  return bResult;
2215  }
2216 
2217 }
#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:3278
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:2730
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
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 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 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 2960 of file region.c.

2962 {
2963  register EDGE_TABLE_ENTRY *pWETE;
2964  register INT inside = 1;
2965  register INT isInside = 0;
2966 
2967  AET->nextWETE = (EDGE_TABLE_ENTRY *)NULL;
2968  pWETE = AET;
2969  AET = AET->next;
2970  while (AET)
2971  {
2972  if (AET->ClockWise)
2973  isInside++;
2974  else
2975  isInside--;
2976 
2977  if ((!inside && !isInside) ||
2978  ( inside && isInside))
2979  {
2980  pWETE->nextWETE = AET;
2981  pWETE = AET;
2982  inside = !inside;
2983  }
2984  AET = AET->next;
2985  }
2986 
2987  pWETE->nextWETE = (EDGE_TABLE_ENTRY *)NULL;
2988 }
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 3192 of file region.c.

3200 {
3201  const POINT *top, *bottom;
3202  const POINT *PrevPt, *CurrPt, *EndPt;
3203  INT poly, count;
3204  INT iSLLBlock = 0;
3205  INT dy;
3206 
3207  /* Initialize the Active Edge Table */
3208  AET->next = (EDGE_TABLE_ENTRY *)NULL;
3209  AET->back = (EDGE_TABLE_ENTRY *)NULL;
3210  AET->nextWETE = (EDGE_TABLE_ENTRY *)NULL;
3212 
3213  /* Initialize the Edge Table. */
3214  ET->scanlines.next = (SCANLINE_LIST *)NULL;
3215  ET->ymax = SMALL_COORDINATE;
3216  ET->ymin = LARGE_COORDINATE;
3217  pSLLBlock->next = (SCANLINE_LISTBLOCK *)NULL;
3218 
3219  EndPt = pts - 1;
3220  for (poly = 0; poly < nbpolygons; poly++)
3221  {
3222  count = Count[poly];
3223  EndPt += count;
3224  if (count < 2)
3225  continue;
3226 
3227  PrevPt = EndPt;
3228 
3229  /* For each vertex in the array of points.
3230  * In this loop we are dealing with two vertices at
3231  * a time -- these make up one edge of the polygon. */
3232  while (count--)
3233  {
3234  CurrPt = pts++;
3235 
3236  /* Find out which point is above and which is below. */
3237  if (PrevPt->y > CurrPt->y)
3238  {
3239  bottom = PrevPt, top = CurrPt;
3240  pETEs->ClockWise = 0;
3241  }
3242  else
3243  {
3244  bottom = CurrPt, top = PrevPt;
3245  pETEs->ClockWise = 1;
3246  }
3247 
3248  /* Don't add horizontal edges to the Edge table. */
3249  if (bottom->y != top->y)
3250  {
3251  /* -1 so we don't get last scanline */
3252  pETEs->ymax = bottom->y - 1;
3253 
3254  /* Initialize integer edge algorithm */
3255  dy = bottom->y - top->y;
3256  BRESINITPGONSTRUCT(dy, top->x, bottom->x, pETEs->bres);
3257 
3259  pETEs,
3260  top->y,
3261  &pSLLBlock,
3262  &iSLLBlock);
3263 
3264  if (PrevPt->y > ET->ymax)
3265  ET->ymax = PrevPt->y;
3266  if (PrevPt->y < ET->ymin)
3267  ET->ymin = PrevPt->y;
3268  pETEs++;
3269  }
3270 
3271  PrevPt = CurrPt;
3272  }
3273  }
3274 }
#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:2829

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 3044 of file region.c.

3046 {
3047  SCANLINE_LISTBLOCK *tmpSLLBlock;
3048 
3049  while (pSLLBlock)
3050  {
3051  tmpSLLBlock = pSLLBlock->next;
3052  ExFreePoolWithTag(pSLLBlock, TAG_REGION);
3053  pSLLBlock = tmpSLLBlock;
3054  }
3055 }
#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 2565 of file region.c.

2568 {
2569  DWORD ret;
2570 
2571  if (Rgn != NULL)
2572  {
2573  *pRect = Rgn->rdh.rcBound;
2574  ret = REGION_Complexity(Rgn);
2575 
2576  return ret;
2577  }
2578  return 0; // If invalid region return zero
2579 }
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 _Success_(), AddPenLinesBounds(), co_WinPosSetWindowPos(), IntGdiBitBltRgn(), IntGdiExtSelectClipRgn(), IntGdiFillRgn(), IntGdiGetRgnBox(), NtGdiExtFloodFill(), NtGdiGetBoundsRect(), NtGdiGetRgnBox(), NtUserEnumDisplayMonitors(), 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 2829 of file region.c.

2835 {
2836  EDGE_TABLE_ENTRY *start, *prev;
2837  SCANLINE_LIST *pSLL, *pPrevSLL;
2838  SCANLINE_LISTBLOCK *tmpSLLBlock;
2839 
2840  /* Find the right bucket to put the edge into */
2841  pPrevSLL = &ET->scanlines;
2842  pSLL = pPrevSLL->next;
2843  while (pSLL && (pSLL->scanline < scanline))
2844  {
2845  pPrevSLL = pSLL;
2846  pSLL = pSLL->next;
2847  }
2848 
2849  /* Reassign pSLL (pointer to SCANLINE_LIST) if necessary */
2850  if ((!pSLL) || (pSLL->scanline > scanline))
2851  {
2852  if (*iSLLBlock > SLLSPERBLOCK-1)
2853  {
2854  tmpSLLBlock = ExAllocatePoolWithTag(PagedPool,
2855  sizeof(SCANLINE_LISTBLOCK),
2856  TAG_REGION);
2857  if (tmpSLLBlock == NULL)
2858  {
2859  DPRINT1("REGION_InsertEdgeInETL(): Can't alloc SLLB\n");
2860  /* FIXME: Free resources? */
2861  return;
2862  }
2863 
2864  (*SLLBlock)->next = tmpSLLBlock;
2865  tmpSLLBlock->next = (SCANLINE_LISTBLOCK *)NULL;
2866  *SLLBlock = tmpSLLBlock;
2867  *iSLLBlock = 0;
2868  }
2869 
2870  pSLL = &((*SLLBlock)->SLLs[(*iSLLBlock)++]);
2871 
2872  pSLL->next = pPrevSLL->next;
2873  pSLL->edgelist = (EDGE_TABLE_ENTRY *)NULL;
2874  pPrevSLL->next = pSLL;
2875  }
2876 
2877  pSLL->scanline = scanline;
2878 
2879  /* Now insert the edge in the right bucket */
2880  prev = (EDGE_TABLE_ENTRY *)NULL;
2881  start = pSLL->edgelist;
2882  while (start && (start->bres.minor_axis < ETE->bres.minor_axis))
2883  {
2884  prev = start;
2885  start = start->next;
2886  }
2887 
2888  ETE->next = start;
2889 
2890  if (prev)
2891  prev->next = ETE;
2892  else
2893  pSLL->edgelist = ETE;
2894 }
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 3001 of file region.c.

3003 {
3004  EDGE_TABLE_ENTRY *pETEchase;
3005  EDGE_TABLE_ENTRY *pETEinsert;
3006  EDGE_TABLE_ENTRY *pETEchaseBackTMP;
3007  BOOL changed = FALSE;
3008 
3009  AET = AET->next;
3010  while (AET)
3011  {
3012  pETEinsert = AET;
3013  pETEchase = AET;
3014  while (pETEchase->back->bres.minor_axis > AET->bres.minor_axis)
3015  pETEchase = pETEchase->back;
3016 
3017  AET = AET->next;
3018  if (pETEchase != pETEinsert)
3019  {
3020  pETEchaseBackTMP = pETEchase->back;
3021  pETEinsert->back->next = AET;
3022  if (AET)
3023  AET->back = pETEinsert->back;
3024 
3025  pETEinsert->next = pETEchase;
3026  pETEchase->back->next = pETEinsert;
3027  pETEchase->back = pETEinsert;
3028  pETEinsert->back = pETEchaseBackTMP;
3029  changed = TRUE;
3030  }
3031  }
3032 
3033  return changed;
3034 }
#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 2907 of file region.c.

2910 {
2911  EDGE_TABLE_ENTRY *pPrevAET;
2912  EDGE_TABLE_ENTRY *tmp;
2913 
2914  pPrevAET = AET;
2915  AET = AET->next;
2916  while (ETEs)
2917  {
2918  while (AET && (AET->bres.minor_axis < ETEs->bres.minor_axis))
2919  {
2920  pPrevAET = AET;
2921  AET = AET->next;
2922  }
2923 
2924  tmp = ETEs->next;
2925  ETEs->next = AET;
2926  if (AET)
2927  AET->back = ETEs;
2928 
2929  ETEs->back = pPrevAET;
2930  pPrevAET->next = ETEs;
2931  pPrevAET = ETEs;
2932 
2933  ETEs = tmp;
2934  }
2935 }
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()

PREGION FASTCALL REGION_LockRgn ( _In_ HRGN  hrgn)

◆ REGION_PtInRegion()

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

Definition at line 2605 of file region.c.

2609 {
2610  ULONG i;
2611  PRECT r;
2612 
2613  if (prgn->rdh.nCount > 0 && INRECT(prgn->rdh.rcBound, X, Y))
2614  {
2615  r = prgn->Buffer;
2616  for (i = 0; i < prgn->rdh.nCount; i++)
2617  {
2618  if (INRECT(r[i], X, Y))
2619  return TRUE;
2620  }
2621  }
2622 
2623  return FALSE;
2624 }
#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 3066 of file region.c.

3071 {
3072  RECTL *rects;
3073  POINT *pts;
3074  POINTBLOCK *CurPtBlock;
3075  INT i;
3076  RECTL *extents, *temp;
3077  INT numRects;
3078 
3079  extents = &reg->rdh.rcBound;
3080 
3081  numRects = ((numFullPtBlocks * NUMPTSTOBUFFER) + iCurPtBlock) >> 1;
3082 
3083  /* Make sure, we have at least one rect */
3084  if (numRects == 0)
3085  {
3086  numRects = 1;
3087  }
3088 
3089  temp = ExAllocatePoolWithTag(PagedPool, numRects * sizeof(RECT), TAG_REGION);
3090  if (temp == NULL)
3091  {
3092  return 0;
3093  }
3094 
3095  if (reg->Buffer != NULL)
3096  {
3097  COPY_RECTS(temp, reg->Buffer, reg->rdh.nCount);
3098  if (reg->Buffer != &reg->rdh.rcBound)
3099  ExFreePoolWithTag(reg->Buffer, TAG_REGION);
3100  }
3101  reg->Buffer = temp;
3102 
3103  reg->rdh.nCount = numRects;
3104  CurPtBlock = FirstPtBlock;
3105  rects = reg->Buffer - 1;
3106  numRects = 0;
3107  extents->left = LARGE_COORDINATE, extents->right = SMALL_COORDINATE;
3108 
3109  for ( ; numFullPtBlocks >= 0; numFullPtBlocks--)
3110  {
3111  /* The loop uses 2 points per iteration */
3112  i = NUMPTSTOBUFFER >> 1;
3113  if (numFullPtBlocks == 0)
3114  i = iCurPtBlock >> 1;
3115 
3116  for (pts = CurPtBlock->pts; i--; pts += 2)
3117  {
3118  if (pts->x == pts[1].x)
3119  continue;
3120 
3121  if ((numRects && pts->x == rects->left) &&
3122  (pts->y == rects->bottom) &&
3123  (pts[1].x == rects->right) &&
3124  ((numRects == 1) || (rects[-1].top != rects->top)) &&
3125  (i && pts[2].y > pts[1].y))
3126  {
3127  rects->bottom = pts[1].y + 1;
3128  continue;
3129  }
3130 
3131  numRects++;
3132  rects++;
3133  rects->left = pts->x;
3134  rects->top = pts->y;
3135  rects->right = pts[1].x;
3136  rects->bottom = pts[1].y + 1;
3137 
3138  if (rects->left < extents->left)
3139  extents->left = rects->left;
3140  if (rects->right > extents->right)
3141  extents->right = rects->right;
3142  }
3143 
3144  CurPtBlock = CurPtBlock->next;
3145  }
3146 
3147  if (numRects)
3148  {
3149  extents->top = reg->Buffer->top;
3150  extents->bottom = rects->bottom;
3151  }
3152  else
3153  {
3154  extents->left = 0;
3155  extents->top = 0;
3156  extents->right = 0;
3157  extents->bottom = 0;
3158  }
3159 
3160  reg->rdh.nCount = numRects;
3161 
3162  return(TRUE);
3163 }
#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 2628 of file region.c.

2631 {
2632  PRECTL pCurRect, pRectEnd;
2633  RECT rc;
2634 
2635  /* Swap the coordinates to make right >= left and bottom >= top */
2636  /* (region building rectangles are normalized the same way) */
2637  if (rect->top > rect->bottom)
2638  {
2639  rc.top = rect->bottom;
2640  rc.bottom = rect->top;
2641  }
2642  else
2643  {
2644  rc.top = rect->top;
2645  rc.bottom = rect->bottom;
2646  }
2647 
2648  if (rect->right < rect->left)
2649  {
2650  rc.right = rect->left;
2651  rc.left = rect->right;
2652  }
2653  else
2654  {
2655  rc.right = rect->right;
2656  rc.left = rect->left;
2657  }
2658 
2659  /* This is (just) a useful optimization */
2660  if ((Rgn->rdh.nCount > 0) && EXTENTCHECK(&Rgn->rdh.rcBound, &rc))
2661  {
2662  for (pCurRect = Rgn->Buffer, pRectEnd = pCurRect +
2663  Rgn->rdh.nCount; pCurRect < pRectEnd; pCurRect++)
2664  {
2665  if (pCurRect->bottom <= rc.top)
2666  continue; /* Not far enough down yet */
2667 
2668  if (pCurRect->top >= rc.bottom)
2669  break; /* Too far down */
2670 
2671  if (pCurRect->right <= rc.left)
2672  continue; /* Not far enough over yet */
2673 
2674  if (pCurRect->left >= rc.right)
2675  {
2676  continue;
2677  }
2678 
2679  return TRUE;
2680  }
2681  }
2682 
2683  return FALSE;
2684 }
#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.