/******************************Module*Header*******************************\ * Module Name: engine.hxx * * Copyright (c) 1989-1999 Microsoft Corporation \**************************************************************************/ #if defined(_AMD64_) #include "..\math\daytona\amd64\efloat.hxx" #elif defined(_IA64_) #include "..\math\daytona\ia64\efloat.hxx" #elif defined(BUILD_WOW6432) && defined(_X86_) #include "..\math\wow6432\i386\efloat.hxx" #else #include "..\math\daytona\i386\efloat.hxx" #endif #include "mutex.hxx" #include "epointfl.hxx" // has to be here since it uses ASSERTGDI #include "hmgr.hxx" class RFONT; class RFONTOBJ; class XDCOBJ; class DCOBJ; // Make a foward reference typedef DCOBJ *PDCOBJ; class SURFACE; class EBRUSHOBJ; class EFONTOBJ; class CACHEOBJ; class ECLIPOBJ; class EPATHOBJ; class EXFORMOBJ; class PALETTE; typedef PALETTE *PPALETTE; class REGION; class PFE; typedef PFE *PPFE; class PFF; typedef PFF *PPFF; class DC; typedef DC *PDC; class XLATE; typedef XLATE *PXLATE; class PDEV; typedef PDEV *PPDEV; class MATRIX { public: EFLOAT efM11; EFLOAT efM12; EFLOAT efM21; EFLOAT efM22; EFLOAT efDx; EFLOAT efDy; FIX fxDx; FIX fxDy; FLONG flAccel; // accelerators }; typedef MATRIX *PMATRIX; /**************************************************************************\ * \**************************************************************************/ typedef union { LONG l; FLOAT_LONG el; } LONG_FLOAT; /******************************Class***************************************\ * EPOINTFIX * * This is an "energized" version of the common POINTFIX. * * History: * * Tue 06-Nov-1990 -by- Paul Butzi [paulb] * Shamelessly stole code from POINTL class * \**************************************************************************/ class EPOINTFIX : public _POINTFIX /* eptfx */ { public: // Constructor -- This one is to allow EPOINTFIX inside other classes. EPOINTFIX() {} // Constructor -- Fills the EPOINTFIX. If want to produce EPOINTFIX from // LONG's x1 and y1, those ought to be converted to FIX using // LTOFX macro before being passed to this constructor EPOINTFIX(FIX x1,FIX y1) { x = x1; y = y1; } // Constructor -- Fills the EPOINTFIX. EPOINTFIX(POINTFIX& ptfx) { x = ptfx.x; y = ptfx.y; } // Destructor -- Does nothing. ~EPOINTFIX() {} // Operator= -- Create from a POINTL VOID operator=(POINTL ptl) { x = LTOFX(ptl.x); y = LTOFX(ptl.y); } // Operator= -- Create from a POINTFIX VOID operator=(POINTFIX ptfx) { x = ptfx.x; y = ptfx.y; } // Operator+= -- Add to another POINTFIX. VOID operator+=(POINTFIX& ptfx) { x += ptfx.x; y += ptfx.y; } // Operator += -- Add in a POINTL VOID operator+=(POINTL& ptl) { x += LTOFX(ptl.x); y += LTOFX(ptl.y); } // Operator-= -- subtract another POINTFIX. VOID operator-=(POINTFIX& ptfx) { x -= ptfx.x; y -= ptfx.y; } }; /*********************************Class************************************\ * EVECTORL * * Energized class for VECTORL. * * History: * 24-Jan-1992 -by- Wendy Wu [wendywu] * Wrote it. \**************************************************************************/ class EVECTORL : public _VECTORL /* evecl */ { public: // Constructor. EVECTORL(LONG x1, LONG y1) { x = x1; y = y1; } }; /*********************************Class************************************\ * EVECTORFX * * Energized class for VECTORFX. * * History: * 11-Feb-1992 -by- J. Andrew Goossen [andrewgo] * Wrote it. \**************************************************************************/ class EVECTORFX : public _VECTORFX /* evec */ { public: VOID operator=(const VECTORFX& vec) { x = vec.x; y = vec.y; } VOID operator=(const POINTFIX& ptfx) { x = ptfx.x; y = ptfx.y; } BOOL operator==(const VECTORFX& vec) { return(x == vec.x && y == vec.y); } BOOL operator!=(const VECTORFX& vec) { return(x != vec.x || y != vec.y); } VOID operator+=(const VECTORFX& vec) { x += vec.x; y += vec.y; } VOID operator+=(const POINTFIX& ptfx) { x += ptfx.x; y += ptfx.y; } VOID operator-=(const VECTORFX& vec) { x -= vec.x; y -= vec.y; } VOID operator-=(const POINTFIX& ptfx) { x -= ptfx.x; y -= ptfx.y; } }; typedef EVECTORFX *PEVECTORFX; /* pevec */ /******************************Class***************************************\ * ERECTFX * * Parallel of ERECTL but for POINTFIX coordinates * * History: * Thu 25-Oct-1990 13:10:00 -by- Paul Butzi [paulb] * Shamelessly stole Chuck Whitmer's code from ERECTL.HXX. * * Thu 25-Oct-1990 13:40:00 -by- Paul Butzi [paulb] * Added vInclude to make bounds erectfx computation simple \**************************************************************************/ class ERECTFX : public _RECTFX { public: // Constructor -- Allows ERECTFXs inside other classes. ERECTFX() {} // Constructor -- Initialize the rectangle. ERECTFX(FIX x1,FIX y1,FIX x2,FIX y2) { xLeft = x1; yTop = y1; xRight = x2; yBottom = y2; } // Destructor -- Does nothing. ~ERECTFX() {} // bEmpty -- Check if the RECTFX is empty. BOOL bEmpty() { return((xLeft == xRight) || (yTop == yBottom)); } // Operator+= -- Offset the RECTFX. VOID operator+=(POINTFIX& ptfx) { xLeft += ptfx.x; xRight += ptfx.x; yTop += ptfx.y; yBottom += ptfx.y; } // Operator+= -- Offset the RECTFX by a POINTL VOID operator+=(POINTL& ptl) { xLeft += LTOFX(ptl.x); xRight += LTOFX(ptl.x); yTop += LTOFX(ptl.y); yBottom += LTOFX(ptl.y); } // Operator-= -- Offset the RECTFX by a POINTL VOID operator-=(POINTL& ptl) { xLeft -= LTOFX(ptl.x); xRight -= LTOFX(ptl.x); yTop -= LTOFX(ptl.y); yBottom -= LTOFX(ptl.y); } // Operator+= -- Add another RECTFX. Only the destination may be empty. VOID operator+=(RECTFX& rcl) { if (xLeft == xRight || yTop == yBottom) *(RECTFX *)this = rcl; else { if (rcl.xLeft < xLeft) xLeft = rcl.xLeft; if (rcl.yTop < yTop) yTop = rcl.yTop; if (rcl.xRight > xRight) xRight = rcl.xRight; if (rcl.yBottom > yBottom) yBottom = rcl.yBottom; } } // vOrder -- Make the rectangle well ordered. VOID vOrder() { FIX l; if (xLeft > xRight) { l = xLeft; xLeft = xRight; xRight = l; } if (yTop > yBottom) { l = yTop; yTop = yBottom; yBottom = l; } } // vInclude -- stretch the rectangle to include a given point VOID vInclude(POINTFIX& ptfx) { if (xLeft > ptfx.x) xLeft = ptfx.x; else if (xRight < ptfx.x) xRight = ptfx.x; if (yBottom < ptfx.y) yBottom = ptfx.y; else if (yTop > ptfx.y) yTop = ptfx.y; } }; /******************************Class***************************************\ * EPOINTL. * * This is an "energized" version of the common POINTL. * * History: * * Fri 05-Oct-1990 -by- Bodin Dresevic [BodinD] * update: added one more constructor and -= overloaded operators * * Thu 13-Sep-1990 15:11:42 -by- Charles Whitmer [chuckwh] * Wrote it. \**************************************************************************/ class EPOINTL : public _POINTL /* eptl */ { public: // Constructor -- This one is to allow EPOINTLs inside other classes. EPOINTL() {} // Constructor -- Fills the EPOINTL. EPOINTL(LONG x1,LONG y1) { x = x1; y = y1; } // Constructor -- Fills the EPOINTL. EPOINTL(POINTL& ptl) { x = ptl.x; y = ptl.y; } // Constructor -- Fills the EPOINTL. EPOINTL(POINTFIX& ptfx) { x = FXTOL(ptfx.x); y = FXTOL(ptfx.y); } // Destructor -- Does nothing. ~EPOINTL() {} // Operator+= -- Add to another POINTL. VOID operator+=(POINTL& ptl) { x += ptl.x; y += ptl.y; } // Operator-= -- Add to another POINTL. VOID operator-=(POINTL& ptl) { x -= ptl.x; y -= ptl.y; } // operator== -- checks that the two coordinates are equal BOOL operator==(POINTL& ptl) { return(x == ptl.x && y == ptl.y); } }; /******************************Class***************************************\ * ERECTL * * This is an "energized" version of the common RECTL. * * History: * * Fri 05-Oct-1990 -by- Bodin Dresevic [BodinD] * update: added one more constructor and -= overloaded operators * * Thu 13-Sep-1990 15:11:42 -by- Charles Whitmer [chuckwh] * Wrote it. \**************************************************************************/ class ERECTL : public _RECTL { public: // Constructor -- Allows ERECTLs inside other classes. ERECTL() {} // Constructor -- Initialize the rectangle. ERECTL(LONG x1,LONG y1,LONG x2,LONG y2) { left = x1; top = y1; right = x2; bottom = y2; } // Constructor -- energize given rectangle so that it can be manipulated ERECTL(RECTL& rcl) { left = rcl.left ; top = rcl.top ; right = rcl.right ; bottom = rcl.bottom ; } // Constructor -- Create given a RECTFX ERECTL(RECTFX& rcfx) { left = FXTOLFLOOR(rcfx.xLeft); top = FXTOLFLOOR(rcfx.yTop); right = FXTOLCEILING(rcfx.xRight); bottom = FXTOLCEILING(rcfx.yBottom); } // Destructor -- Does nothing. ~ERECTL() {} // bEmpty -- Check if the RECTL is empty. BOOL bEmpty() { return((left == right) || (top == bottom)); } // bWrapped -- Check if the RECTL is empty or not well-ordered BOOL bWrapped() { return((left >= right) || (top >= bottom)); } // Operator+= -- Offset the RECTL. VOID operator+=(POINTL& ptl) { left += ptl.x; right += ptl.x; top += ptl.y; bottom += ptl.y; } // Operator-= -- Offset the RECTL. VOID operator-=(POINTL& ptl) { left -= ptl.x; right -= ptl.x; top -= ptl.y; bottom -= ptl.y; } // Operator+= -- Add another RECTL. Only the destination may be empty. VOID operator+=(RECTL& rcl) { if (left == right || top == bottom) *((RECTL *) this) = rcl; else { if (rcl.left < left) left = rcl.left; if (rcl.top < top) top = rcl.top; if (rcl.right > right) right = rcl.right; if (rcl.bottom > bottom) bottom = rcl.bottom; } } // Operator |= -- Accumulate bounds VOID operator|=(RECTL& rcl) { if (rcl.left < left) left = rcl.left; if (rcl.top < top) top = rcl.top; if (rcl.right > right) right = rcl.right; if (rcl.bottom > bottom) bottom = rcl.bottom; } // Operator*= -- Intersect another RECTL. The result may be empty. ERECTL& operator*= (RECTL& rcl) { { if (rcl.left > left) left = rcl.left; if (rcl.top > top) top = rcl.top; if (rcl.right < right) right = rcl.right; if (rcl.bottom < bottom) bottom = rcl.bottom; if (right < left) left = right; // Only need to collapse one pair else if (bottom < top) top = bottom; } return(*this); } // vOrder -- Make the rectangle well ordered. VOID vOrder() { LONG l; if (left > right) { l = left; left = right; right = l; } if (top > bottom) { l = top; top = bottom; bottom = l; } } // bContain -- Test if it contains another rectangle BOOL bContain(RECTL& rcl) { return ((left <= rcl.left) && (right >= rcl.right) && (top <= rcl.top) && (bottom >= rcl.bottom)); } // bEqual -- Test if two ERECTLs are equal to each other BOOL bEqual(ERECTL &ercl) { return ((left == ercl.left) && (right == ercl.right) && (top == ercl.top) && (bottom == ercl.bottom)); } }; // bIntersect -- Test if two rectangles intersect BOOL FASTCALL bIntersect( CONST RECTL* prcl1, CONST RECTL* prcl2); // bIntersect -- Test if two rectangles intersect, and return intersection BOOL FASTCALL bIntersect( CONST RECTL* prcl1, CONST RECTL* prcl2, RECTL* prclResult); // May point to same as 'prcl1' or 'prcl2' // cIntersect -- Intersect a rectangle with a list of rectangles ULONG cIntersect( RECTL* prclClip, RECTL* prclList, LONG c); /*********************************Class************************************\ * class MALLOCOBJ * * A memory allocator that clean up after itself. * * Public Interface: * * History: * Fri 21-Feb-1992 08:08:35 by Kirk Olynyk [kirko] * Wrote it. \**************************************************************************/ class MALLOCOBJ { private: PVOID pv_; public: MALLOCOBJ(ULONGSIZE_T cb) { pv_ = PALLOCMEM(cb, 'pmtG'); if (!(pv_)) { SAVE_ERROR_CODE(ERROR_NOT_ENOUGH_MEMORY); } } ~MALLOCOBJ() { if (pv_) VFREEMEM(pv_); } PVOID bValid() { return(pv_); } PVOID pv() { return(pv_); } }; /*********************************class************************************\ * class SEMOBJ * * Semaphore Class * * Public Interface: * SEMOBJ(HSEMAPHORE) // Acquire semaphore * ~SEMOBJ() // Release semaphore * * History: * 05-Jul-1990 14:57:20 -by- Donald Sidoroff [donalds] * Wrote it. \**************************************************************************/ class SEMOBJ { private: HSEMAPHORE hsem; public: SEMOBJ(HSEMAPHORE hsem_) { hsem = hsem_; GreAcquireSemaphore(hsem); } ~SEMOBJ() { GreReleaseSemaphore(hsem); } }; // Useful macro. #define SETFLAG(b,fl,FLAG) if (b) fl|=FLAG; else fl&=~FLAG #define INC_SURF_UNIQ(pSurfTrg) ((SURFACE *) pSurfTrg)->vStamp() /**************************************************************************\ * ulGetNewUniqueness * * Increments the specified uniqueness in a multithreaded-safe way, and * returns the new uniqueness. * * History: * 29-Dec-1993 by Michael Abrash [mikeab] * Wrote it. \**************************************************************************/ ULONG ulGetNewUniquenessF(ULONG& ulUnique); inline ULONG ulGetNewUniqueness(ULONG volatile &ulUnique) { return(InterlockedIncrement((LPLONG)&ulUnique)); } #define USE_NINEGRID_STATIC #if defined(USE_NINEGRID_STATIC) extern HSEMAPHORE gNineGridSem; #endif /**************************************************************************\ * * Support stuff for per process AVL table of User Mode Memory allocations * made via EngUserMemAlloc. * \**************************************************************************/ RTL_GENERIC_COMPARE_RESULTS GDIEngUserMemAllocNodeCompare(RTL_AVL_TABLE *Table, PVOID FirstStruct, PVOID SecondStruct); PVOID GDIEngUserMemAllocNodeAlloc(RTL_AVL_TABLE *Table, ULONG size); VOID GDIEngUserMemAllocNodeFree(RTL_AVL_TABLE *Table, PVOID Buffer); typedef struct _GDIENGUSERMEMALLOCNODE { PVOID pUserMem; SIZE_T cj; HANDLE hSecure; } GDIENGUSERMEMALLOCNODE, *PGDIENGUSERMEMALLOCNODE; /*************************************************************************\ * * CModeChangeInProgress * * Used to indicate a ModeChange in progress. * \*************************************************************************/ class CModeChangeInProgress { public: static LONG lInModeChange; static LONG lNeedSyncFlush; static LONG lNeedTimerFlush; CModeChangeInProgress() { InterlockedIncrement(&lInModeChange); } void vDone(); ~CModeChangeInProgress() { } };