You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
270 lines
8.1 KiB
270 lines
8.1 KiB
/******************************Module*Header*******************************\
|
|
* Module Name: region.hxx
|
|
*
|
|
* Definition for REGION object
|
|
*
|
|
* Created: 29-Aug-1990 10:35:44
|
|
* Author: Donald Sidoroff [donalds]
|
|
*
|
|
* Tue 10-Mar-1992 - by - Eric Kutter [erick]
|
|
* cleaned up macros a bit.
|
|
*
|
|
* Copyright (c) 1990-1999 Microsoft Corporation
|
|
\**************************************************************************/
|
|
|
|
#ifndef _REGION_HXX
|
|
|
|
#define _REGION_HXX
|
|
|
|
#define NEG_INFINITY 0x80000000
|
|
#define POS_INFINITY 0x7fffffff
|
|
|
|
#define MIN_REGION_COORD ((LONG) 0xF8000000)
|
|
#define MAX_REGION_COORD ((LONG) 0x07FFFFFF)
|
|
|
|
#define REGION_POINT_OUTSIDE 1L
|
|
#define REGION_POINT_INSIDE 2L
|
|
|
|
#define REGION_RECT_OUTSIDE 1L
|
|
#define REGION_RECT_INTERSECT 2L
|
|
|
|
#ifndef GDIFLAGS_ONLY
|
|
|
|
#define VALID_SCR(X) (!((X) & 0xF8000000) || (((X) & 0xF8000000) == 0xF8000000))
|
|
#define VALID_SCRPT(P) ((VALID_SCR((P).x)) && (VALID_SCR((P).y)))
|
|
#define VALID_SCRPPT(P) ((VALID_SCR((P)->x)) && (VALID_SCR((P)->y)))
|
|
#define VALID_SCRRC(R) ((VALID_SCR((R).left)) && (VALID_SCR((R).bottom)) && \
|
|
(VALID_SCR((R).right)) && (VALID_SCR((R).top)))
|
|
#define VALID_SCRPRC(R) ((VALID_SCR((R)->left)) && (VALID_SCR((R)->bottom)) && \
|
|
(VALID_SCR((R)->right)) && (VALID_SCR((R)->top)))
|
|
|
|
// Private REGION data structures
|
|
|
|
typedef struct _INDEX_LONG
|
|
{
|
|
LONG x;
|
|
} INDEX_LONG;
|
|
|
|
// The scans are saved in a rather odd variable sized structure. What makes
|
|
// it odd is it is traversed in two directions. Because of this the sizing
|
|
// information has to be stored at both the beginning and the end of the
|
|
// structure.
|
|
//
|
|
// Offset Field
|
|
// +00 cWalls
|
|
// +04 yTop
|
|
// +08 yBottom
|
|
// +12 ai_x[0]
|
|
// +16 ai_x[1]
|
|
// ... ...
|
|
// +?? cWalls2
|
|
//
|
|
// But since the size of the structure is unknown, the cWalls2 field is
|
|
// actually unnamed. The following scheme can be used to move through the
|
|
// list. If you have the address of the cWalls field and want to go forwards
|
|
// in the list:
|
|
//
|
|
// pscn = (PSCAN) (((PBYTE) pscn) + pscn->sizeGet());
|
|
//
|
|
// If you have the address of the cWalls field and want to go backwards in
|
|
// the list:
|
|
//
|
|
// pscn = (PSCAN) &((PTRDIFF *) pscn)[-1]; // Get prev scan's cWalls2 field
|
|
// pscn = (PSCAN) (((PBYTE) pscn) - (pscn->sizeGet() - sizeof(PTRDIFF)));
|
|
//
|
|
// There is a special scan, the 'null' scan which looks like this:
|
|
//
|
|
// cWalls = 0;
|
|
// yTop = NEG_INFINITY;
|
|
// yBottom = POS_INFINITY;
|
|
// cWalls2 = 0;
|
|
//
|
|
// We need it often and it's size is useful, so its put in a constant here
|
|
|
|
#define NULL_SCAN_SIZE (offsetof(SCAN,ai_x) + sizeof(LONG))
|
|
#define PSCNGET(pscn) ((PSCAN)(((PBYTE) pscn) + pscn->sizeGet()))
|
|
|
|
class SCAN /* scn */
|
|
{
|
|
public:
|
|
COUNT cWalls;
|
|
LONG yTop;
|
|
LONG yBottom;
|
|
INDEX_LONG ai_x[1];
|
|
|
|
public:
|
|
SCAN() {}
|
|
~SCAN() {}
|
|
|
|
ULONGSIZE_T sizeGet()
|
|
{
|
|
return(NULL_SCAN_SIZE + (sizeof(INDEX_LONG) * cWalls));
|
|
}
|
|
};
|
|
|
|
typedef SCAN *PSCAN;
|
|
|
|
// The region structure also has an unnamed field. There may be two array
|
|
// of unknown size. If the region is defined by trapezoids, we need to save
|
|
// a list of lines that define the trapezoids. After this array (which may
|
|
// be empty) we save the list of scans that define the region. We also save
|
|
// the 'head' and 'tail' of the list of scans so we can easily traverse the
|
|
// list in either direction. Also note there is a 'null' region. It only
|
|
// has a 'null' scan in it. Other useful region sizes are the single rect
|
|
// region and the 'quantum' region. Since most of our rectangular regions
|
|
// are smaller then this we will never allocate an object smaller then this.
|
|
// It looks like:
|
|
//
|
|
// +-------------------------------+
|
|
// | scan 3 |
|
|
// | scan 3 |
|
|
// | scan 3 |
|
|
// | scan 3 |
|
|
// | scan 3 |
|
|
// +-----------+-------+-----------+
|
|
// | scan 2 | | scan 2 |
|
|
// | scan 2 | not | scan 2 |
|
|
// | scan 2 | in | scan 2 |
|
|
// | scan 2 | rgn | scan 2 |
|
|
// | scan 2 | | scan 2 |
|
|
// +-----------+-------+-----------+
|
|
// | scan 1 |
|
|
// | scan 1 |
|
|
// | scan 1 |
|
|
// | scan 1 |
|
|
// | scan 1 |
|
|
// +-------------------------------+
|
|
//
|
|
// Also note that this object can only be defined for rectagular regions.
|
|
|
|
#define NULL_REGION_SIZE (offsetof(REGION,scan) + NULL_SCAN_SIZE)
|
|
|
|
#define SINGLE_REGION_SIZE (NULL_REGION_SIZE + \
|
|
NULL_SCAN_SIZE + (sizeof(INDEX_LONG) * 2) + \
|
|
NULL_SCAN_SIZE)
|
|
|
|
#define QUANTUM_REGION_SIZE (NULL_REGION_SIZE + \
|
|
NULL_SCAN_SIZE + (sizeof(INDEX_LONG) * 2) + \
|
|
NULL_SCAN_SIZE + (sizeof(INDEX_LONG) * 4) + \
|
|
NULL_SCAN_SIZE + (sizeof(INDEX_LONG) * 2) + \
|
|
NULL_SCAN_SIZE)
|
|
|
|
|
|
#define RGN_COPYOFFSET offsetof(REGION,sizeRgn)
|
|
|
|
class REGION;
|
|
typedef REGION *PREGION;
|
|
|
|
class RGNOBJ;
|
|
typedef RGNOBJ *PRGNOBJ;
|
|
|
|
/**************************************************************************\
|
|
*
|
|
\**************************************************************************/
|
|
|
|
class RGNLOGENTRY
|
|
{
|
|
public:
|
|
PVOID teb;
|
|
HOBJ hrgn;
|
|
PREGION prgn;
|
|
PSZ pszOperation;
|
|
ULONG_PTR lRes; // used to return ULONG or HANDLE or pointer
|
|
ULONG_PTR lParm1; // used to pass in HANDLE or pointer or ULONG
|
|
ULONG_PTR lParm2;
|
|
ULONG_PTR lParm3;
|
|
|
|
PVOID pvCaller;
|
|
PVOID pvCallersCaller;
|
|
};
|
|
|
|
class RGNLOG
|
|
{
|
|
public:
|
|
#if DBG
|
|
RGNLOGENTRY *plog;
|
|
|
|
RGNLOG(HRGN hrgn,PREGION prgn,PSZ psz,ULONG_PTR l1 = 0, ULONG_PTR l2 = 0, ULONG_PTR l3 = 0);
|
|
RGNLOG(PREGION prgn,PSZ psz,ULONG_PTR l1 = 0, ULONG_PTR l2 = 0, ULONG_PTR l3 = 0);
|
|
|
|
VOID vRet(ULONG_PTR l) {plog->lRes = l;}
|
|
#else
|
|
RGNLOG(HRGN hrgn,PREGION prgn,PSZ psz,ULONG_PTR l1 = 0, ULONG_PTR l2 = 0, ULONG_PTR l3 = 0) {}
|
|
RGNLOG(PREGION prgn,PSZ psz,ULONG_PTR l1 = 0, ULONG_PTR l2 = 0, ULONG_PTR l3 = 0) {}
|
|
VOID vRet(ULONG_PTR l) {}
|
|
#endif
|
|
};
|
|
|
|
extern "C" LONG iLog;
|
|
|
|
extern HRGN hrgnDefault;
|
|
extern REGION *prgnDefault;
|
|
|
|
|
|
/********************************Structure*********************************\
|
|
*
|
|
* REGION
|
|
*
|
|
* Description:
|
|
*
|
|
* Size and unique infoemation followed by a variable length array
|
|
* of SCAN data
|
|
*
|
|
* Fields:
|
|
*
|
|
* sizeObj - Size of object
|
|
* iUnique - Uniqueness stamp
|
|
* cRefs - Region is saved this many levels deep
|
|
* pscnTail - Points past last scan
|
|
* sizeRgn - Size of region
|
|
* cScans - Number of scans
|
|
* rcl - Bounding box
|
|
* scan - variable length array of scans
|
|
*
|
|
\**************************************************************************/
|
|
|
|
class REGION : public OBJECT /* rgn */
|
|
{
|
|
private:
|
|
static ULONG ulUniqueREGION;
|
|
friend BOOLEAN InitializeGre(VOID);
|
|
|
|
public:
|
|
ULONGSIZE_T sizeObj;
|
|
ULONG iUnique;
|
|
COUNT cRefs;
|
|
PSCAN pscnTail;
|
|
|
|
// fields below here get copied in vCopy, fields above here are untouched.
|
|
|
|
ULONGSIZE_T sizeRgn;
|
|
COUNT cScans;
|
|
RECTL rcl;
|
|
SCAN scan;
|
|
|
|
public:
|
|
REGION() {}
|
|
~REGION() {}
|
|
|
|
PSCAN pscnHead() {return(&scan);}
|
|
|
|
VOID vStamp()
|
|
{
|
|
iUnique = ulGetNewUniqueness(ulUniqueREGION);
|
|
}
|
|
|
|
VOID vDeleteREGION()
|
|
{
|
|
RGNLOG rl(this,"REGION::vDeleteREGION");
|
|
|
|
if ((this != NULL) &&
|
|
(this != prgnDefault))
|
|
{
|
|
FREEOBJ(this,RGN_TYPE);
|
|
}
|
|
}
|
|
};
|
|
|
|
#endif GDIFLAGS_ONLY
|
|
|
|
#endif // #ifndef _REGION_HXX
|