Leaked source code of windows server 2003
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.

774 lines
18 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: engine.hxx
  3. *
  4. * Copyright (c) 1989-1999 Microsoft Corporation
  5. \**************************************************************************/
  6. #if defined(_AMD64_)
  7. #include "..\math\daytona\amd64\efloat.hxx"
  8. #elif defined(_IA64_)
  9. #include "..\math\daytona\ia64\efloat.hxx"
  10. #elif defined(BUILD_WOW6432) && defined(_X86_)
  11. #include "..\math\wow6432\i386\efloat.hxx"
  12. #else
  13. #include "..\math\daytona\i386\efloat.hxx"
  14. #endif
  15. #include "mutex.hxx"
  16. #include "epointfl.hxx" // has to be here since it uses ASSERTGDI
  17. #include "hmgr.hxx"
  18. class RFONT;
  19. class RFONTOBJ;
  20. class XDCOBJ;
  21. class DCOBJ; // Make a foward reference
  22. typedef DCOBJ *PDCOBJ;
  23. class SURFACE;
  24. class EBRUSHOBJ;
  25. class EFONTOBJ;
  26. class CACHEOBJ;
  27. class ECLIPOBJ;
  28. class EPATHOBJ;
  29. class EXFORMOBJ;
  30. class PALETTE;
  31. typedef PALETTE *PPALETTE;
  32. class REGION;
  33. class PFE;
  34. typedef PFE *PPFE;
  35. class PFF;
  36. typedef PFF *PPFF;
  37. class DC;
  38. typedef DC *PDC;
  39. class XLATE;
  40. typedef XLATE *PXLATE;
  41. class PDEV;
  42. typedef PDEV *PPDEV;
  43. class MATRIX
  44. {
  45. public:
  46. EFLOAT efM11;
  47. EFLOAT efM12;
  48. EFLOAT efM21;
  49. EFLOAT efM22;
  50. EFLOAT efDx;
  51. EFLOAT efDy;
  52. FIX fxDx;
  53. FIX fxDy;
  54. FLONG flAccel; // accelerators
  55. };
  56. typedef MATRIX *PMATRIX;
  57. /**************************************************************************\
  58. *
  59. \**************************************************************************/
  60. typedef union {
  61. LONG l;
  62. FLOAT_LONG el;
  63. } LONG_FLOAT;
  64. /******************************Class***************************************\
  65. * EPOINTFIX
  66. *
  67. * This is an "energized" version of the common POINTFIX.
  68. *
  69. * History:
  70. *
  71. * Tue 06-Nov-1990 -by- Paul Butzi [paulb]
  72. * Shamelessly stole code from POINTL class
  73. *
  74. \**************************************************************************/
  75. class EPOINTFIX : public _POINTFIX /* eptfx */
  76. {
  77. public:
  78. // Constructor -- This one is to allow EPOINTFIX inside other classes.
  79. EPOINTFIX() {}
  80. // Constructor -- Fills the EPOINTFIX. If want to produce EPOINTFIX from
  81. // LONG's x1 and y1, those ought to be converted to FIX using
  82. // LTOFX macro before being passed to this constructor
  83. EPOINTFIX(FIX x1,FIX y1)
  84. {
  85. x = x1;
  86. y = y1;
  87. }
  88. // Constructor -- Fills the EPOINTFIX.
  89. EPOINTFIX(POINTFIX& ptfx)
  90. {
  91. x = ptfx.x;
  92. y = ptfx.y;
  93. }
  94. // Destructor -- Does nothing.
  95. ~EPOINTFIX() {}
  96. // Operator= -- Create from a POINTL
  97. VOID operator=(POINTL ptl)
  98. {
  99. x = LTOFX(ptl.x);
  100. y = LTOFX(ptl.y);
  101. }
  102. // Operator= -- Create from a POINTFIX
  103. VOID operator=(POINTFIX ptfx)
  104. {
  105. x = ptfx.x;
  106. y = ptfx.y;
  107. }
  108. // Operator+= -- Add to another POINTFIX.
  109. VOID operator+=(POINTFIX& ptfx)
  110. {
  111. x += ptfx.x;
  112. y += ptfx.y;
  113. }
  114. // Operator += -- Add in a POINTL
  115. VOID operator+=(POINTL& ptl)
  116. {
  117. x += LTOFX(ptl.x);
  118. y += LTOFX(ptl.y);
  119. }
  120. // Operator-= -- subtract another POINTFIX.
  121. VOID operator-=(POINTFIX& ptfx)
  122. {
  123. x -= ptfx.x;
  124. y -= ptfx.y;
  125. }
  126. };
  127. /*********************************Class************************************\
  128. * EVECTORL
  129. *
  130. * Energized class for VECTORL.
  131. *
  132. * History:
  133. * 24-Jan-1992 -by- Wendy Wu [wendywu]
  134. * Wrote it.
  135. \**************************************************************************/
  136. class EVECTORL : public _VECTORL /* evecl */
  137. {
  138. public:
  139. // Constructor.
  140. EVECTORL(LONG x1, LONG y1) { x = x1; y = y1; }
  141. };
  142. /*********************************Class************************************\
  143. * EVECTORFX
  144. *
  145. * Energized class for VECTORFX.
  146. *
  147. * History:
  148. * 11-Feb-1992 -by- J. Andrew Goossen [andrewgo]
  149. * Wrote it.
  150. \**************************************************************************/
  151. class EVECTORFX : public _VECTORFX /* evec */
  152. {
  153. public:
  154. VOID operator=(const VECTORFX& vec)
  155. {
  156. x = vec.x;
  157. y = vec.y;
  158. }
  159. VOID operator=(const POINTFIX& ptfx)
  160. {
  161. x = ptfx.x;
  162. y = ptfx.y;
  163. }
  164. BOOL operator==(const VECTORFX& vec)
  165. {
  166. return(x == vec.x && y == vec.y);
  167. }
  168. BOOL operator!=(const VECTORFX& vec)
  169. {
  170. return(x != vec.x || y != vec.y);
  171. }
  172. VOID operator+=(const VECTORFX& vec)
  173. {
  174. x += vec.x;
  175. y += vec.y;
  176. }
  177. VOID operator+=(const POINTFIX& ptfx)
  178. {
  179. x += ptfx.x;
  180. y += ptfx.y;
  181. }
  182. VOID operator-=(const VECTORFX& vec)
  183. {
  184. x -= vec.x;
  185. y -= vec.y;
  186. }
  187. VOID operator-=(const POINTFIX& ptfx)
  188. {
  189. x -= ptfx.x;
  190. y -= ptfx.y;
  191. }
  192. };
  193. typedef EVECTORFX *PEVECTORFX; /* pevec */
  194. /******************************Class***************************************\
  195. * ERECTFX
  196. *
  197. * Parallel of ERECTL but for POINTFIX coordinates
  198. *
  199. * History:
  200. * Thu 25-Oct-1990 13:10:00 -by- Paul Butzi [paulb]
  201. * Shamelessly stole Chuck Whitmer's code from ERECTL.HXX.
  202. *
  203. * Thu 25-Oct-1990 13:40:00 -by- Paul Butzi [paulb]
  204. * Added vInclude to make bounds erectfx computation simple
  205. \**************************************************************************/
  206. class ERECTFX : public _RECTFX
  207. {
  208. public:
  209. // Constructor -- Allows ERECTFXs inside other classes.
  210. ERECTFX() {}
  211. // Constructor -- Initialize the rectangle.
  212. ERECTFX(FIX x1,FIX y1,FIX x2,FIX y2)
  213. {
  214. xLeft = x1;
  215. yTop = y1;
  216. xRight = x2;
  217. yBottom = y2;
  218. }
  219. // Destructor -- Does nothing.
  220. ~ERECTFX() {}
  221. // bEmpty -- Check if the RECTFX is empty.
  222. BOOL bEmpty()
  223. {
  224. return((xLeft == xRight) || (yTop == yBottom));
  225. }
  226. // Operator+= -- Offset the RECTFX.
  227. VOID operator+=(POINTFIX& ptfx)
  228. {
  229. xLeft += ptfx.x;
  230. xRight += ptfx.x;
  231. yTop += ptfx.y;
  232. yBottom += ptfx.y;
  233. }
  234. // Operator+= -- Offset the RECTFX by a POINTL
  235. VOID operator+=(POINTL& ptl)
  236. {
  237. xLeft += LTOFX(ptl.x);
  238. xRight += LTOFX(ptl.x);
  239. yTop += LTOFX(ptl.y);
  240. yBottom += LTOFX(ptl.y);
  241. }
  242. // Operator-= -- Offset the RECTFX by a POINTL
  243. VOID operator-=(POINTL& ptl)
  244. {
  245. xLeft -= LTOFX(ptl.x);
  246. xRight -= LTOFX(ptl.x);
  247. yTop -= LTOFX(ptl.y);
  248. yBottom -= LTOFX(ptl.y);
  249. }
  250. // Operator+= -- Add another RECTFX. Only the destination may be empty.
  251. VOID operator+=(RECTFX& rcl)
  252. {
  253. if (xLeft == xRight || yTop == yBottom)
  254. *(RECTFX *)this = rcl;
  255. else
  256. {
  257. if (rcl.xLeft < xLeft)
  258. xLeft = rcl.xLeft;
  259. if (rcl.yTop < yTop)
  260. yTop = rcl.yTop;
  261. if (rcl.xRight > xRight)
  262. xRight = rcl.xRight;
  263. if (rcl.yBottom > yBottom)
  264. yBottom = rcl.yBottom;
  265. }
  266. }
  267. // vOrder -- Make the rectangle well ordered.
  268. VOID vOrder()
  269. {
  270. FIX l;
  271. if (xLeft > xRight)
  272. {
  273. l = xLeft;
  274. xLeft = xRight;
  275. xRight = l;
  276. }
  277. if (yTop > yBottom)
  278. {
  279. l = yTop;
  280. yTop = yBottom;
  281. yBottom = l;
  282. }
  283. }
  284. // vInclude -- stretch the rectangle to include a given point
  285. VOID vInclude(POINTFIX& ptfx)
  286. {
  287. if (xLeft > ptfx.x)
  288. xLeft = ptfx.x;
  289. else if (xRight < ptfx.x)
  290. xRight = ptfx.x;
  291. if (yBottom < ptfx.y)
  292. yBottom = ptfx.y;
  293. else if (yTop > ptfx.y)
  294. yTop = ptfx.y;
  295. }
  296. };
  297. /******************************Class***************************************\
  298. * EPOINTL.
  299. *
  300. * This is an "energized" version of the common POINTL.
  301. *
  302. * History:
  303. *
  304. * Fri 05-Oct-1990 -by- Bodin Dresevic [BodinD]
  305. * update: added one more constructor and -= overloaded operators
  306. *
  307. * Thu 13-Sep-1990 15:11:42 -by- Charles Whitmer [chuckwh]
  308. * Wrote it.
  309. \**************************************************************************/
  310. class EPOINTL : public _POINTL /* eptl */
  311. {
  312. public:
  313. // Constructor -- This one is to allow EPOINTLs inside other classes.
  314. EPOINTL() {}
  315. // Constructor -- Fills the EPOINTL.
  316. EPOINTL(LONG x1,LONG y1)
  317. {
  318. x = x1;
  319. y = y1;
  320. }
  321. // Constructor -- Fills the EPOINTL.
  322. EPOINTL(POINTL& ptl)
  323. {
  324. x = ptl.x;
  325. y = ptl.y;
  326. }
  327. // Constructor -- Fills the EPOINTL.
  328. EPOINTL(POINTFIX& ptfx)
  329. {
  330. x = FXTOL(ptfx.x);
  331. y = FXTOL(ptfx.y);
  332. }
  333. // Destructor -- Does nothing.
  334. ~EPOINTL() {}
  335. // Operator+= -- Add to another POINTL.
  336. VOID operator+=(POINTL& ptl)
  337. {
  338. x += ptl.x;
  339. y += ptl.y;
  340. }
  341. // Operator-= -- Add to another POINTL.
  342. VOID operator-=(POINTL& ptl)
  343. {
  344. x -= ptl.x;
  345. y -= ptl.y;
  346. }
  347. // operator== -- checks that the two coordinates are equal
  348. BOOL operator==(POINTL& ptl)
  349. {
  350. return(x == ptl.x && y == ptl.y);
  351. }
  352. };
  353. /******************************Class***************************************\
  354. * ERECTL
  355. *
  356. * This is an "energized" version of the common RECTL.
  357. *
  358. * History:
  359. *
  360. * Fri 05-Oct-1990 -by- Bodin Dresevic [BodinD]
  361. * update: added one more constructor and -= overloaded operators
  362. *
  363. * Thu 13-Sep-1990 15:11:42 -by- Charles Whitmer [chuckwh]
  364. * Wrote it.
  365. \**************************************************************************/
  366. class ERECTL : public _RECTL
  367. {
  368. public:
  369. // Constructor -- Allows ERECTLs inside other classes.
  370. ERECTL() {}
  371. // Constructor -- Initialize the rectangle.
  372. ERECTL(LONG x1,LONG y1,LONG x2,LONG y2)
  373. {
  374. left = x1;
  375. top = y1;
  376. right = x2;
  377. bottom = y2;
  378. }
  379. // Constructor -- energize given rectangle so that it can be manipulated
  380. ERECTL(RECTL& rcl)
  381. {
  382. left = rcl.left ;
  383. top = rcl.top ;
  384. right = rcl.right ;
  385. bottom = rcl.bottom ;
  386. }
  387. // Constructor -- Create given a RECTFX
  388. ERECTL(RECTFX& rcfx)
  389. {
  390. left = FXTOLFLOOR(rcfx.xLeft);
  391. top = FXTOLFLOOR(rcfx.yTop);
  392. right = FXTOLCEILING(rcfx.xRight);
  393. bottom = FXTOLCEILING(rcfx.yBottom);
  394. }
  395. // Destructor -- Does nothing.
  396. ~ERECTL() {}
  397. // bEmpty -- Check if the RECTL is empty.
  398. BOOL bEmpty()
  399. {
  400. return((left == right) || (top == bottom));
  401. }
  402. // bWrapped -- Check if the RECTL is empty or not well-ordered
  403. BOOL bWrapped()
  404. {
  405. return((left >= right) || (top >= bottom));
  406. }
  407. // Operator+= -- Offset the RECTL.
  408. VOID operator+=(POINTL& ptl)
  409. {
  410. left += ptl.x;
  411. right += ptl.x;
  412. top += ptl.y;
  413. bottom += ptl.y;
  414. }
  415. // Operator-= -- Offset the RECTL.
  416. VOID operator-=(POINTL& ptl)
  417. {
  418. left -= ptl.x;
  419. right -= ptl.x;
  420. top -= ptl.y;
  421. bottom -= ptl.y;
  422. }
  423. // Operator+= -- Add another RECTL. Only the destination may be empty.
  424. VOID operator+=(RECTL& rcl)
  425. {
  426. if (left == right || top == bottom)
  427. *((RECTL *) this) = rcl;
  428. else
  429. {
  430. if (rcl.left < left)
  431. left = rcl.left;
  432. if (rcl.top < top)
  433. top = rcl.top;
  434. if (rcl.right > right)
  435. right = rcl.right;
  436. if (rcl.bottom > bottom)
  437. bottom = rcl.bottom;
  438. }
  439. }
  440. // Operator |= -- Accumulate bounds
  441. VOID operator|=(RECTL& rcl)
  442. {
  443. if (rcl.left < left)
  444. left = rcl.left;
  445. if (rcl.top < top)
  446. top = rcl.top;
  447. if (rcl.right > right)
  448. right = rcl.right;
  449. if (rcl.bottom > bottom)
  450. bottom = rcl.bottom;
  451. }
  452. // Operator*= -- Intersect another RECTL. The result may be empty.
  453. ERECTL& operator*= (RECTL& rcl)
  454. {
  455. {
  456. if (rcl.left > left)
  457. left = rcl.left;
  458. if (rcl.top > top)
  459. top = rcl.top;
  460. if (rcl.right < right)
  461. right = rcl.right;
  462. if (rcl.bottom < bottom)
  463. bottom = rcl.bottom;
  464. if (right < left)
  465. left = right; // Only need to collapse one pair
  466. else
  467. if (bottom < top)
  468. top = bottom;
  469. }
  470. return(*this);
  471. }
  472. // vOrder -- Make the rectangle well ordered.
  473. VOID vOrder()
  474. {
  475. LONG l;
  476. if (left > right)
  477. {
  478. l = left;
  479. left = right;
  480. right = l;
  481. }
  482. if (top > bottom)
  483. {
  484. l = top;
  485. top = bottom;
  486. bottom = l;
  487. }
  488. }
  489. // bContain -- Test if it contains another rectangle
  490. BOOL bContain(RECTL& rcl)
  491. {
  492. return ((left <= rcl.left) &&
  493. (right >= rcl.right) &&
  494. (top <= rcl.top) &&
  495. (bottom >= rcl.bottom));
  496. }
  497. // bEqual -- Test if two ERECTLs are equal to each other
  498. BOOL bEqual(ERECTL &ercl)
  499. {
  500. return ((left == ercl.left) &&
  501. (right == ercl.right) &&
  502. (top == ercl.top) &&
  503. (bottom == ercl.bottom));
  504. }
  505. };
  506. // bIntersect -- Test if two rectangles intersect
  507. BOOL FASTCALL bIntersect(
  508. CONST RECTL* prcl1,
  509. CONST RECTL* prcl2);
  510. // bIntersect -- Test if two rectangles intersect, and return intersection
  511. BOOL FASTCALL bIntersect(
  512. CONST RECTL* prcl1,
  513. CONST RECTL* prcl2,
  514. RECTL* prclResult); // May point to same as 'prcl1' or 'prcl2'
  515. // cIntersect -- Intersect a rectangle with a list of rectangles
  516. ULONG cIntersect(
  517. RECTL* prclClip,
  518. RECTL* prclList,
  519. LONG c);
  520. /*********************************Class************************************\
  521. * class MALLOCOBJ
  522. *
  523. * A memory allocator that clean up after itself.
  524. *
  525. * Public Interface:
  526. *
  527. * History:
  528. * Fri 21-Feb-1992 08:08:35 by Kirk Olynyk [kirko]
  529. * Wrote it.
  530. \**************************************************************************/
  531. class MALLOCOBJ {
  532. private:
  533. PVOID pv_;
  534. public:
  535. MALLOCOBJ(ULONGSIZE_T cb)
  536. {
  537. pv_ = PALLOCMEM(cb, 'pmtG');
  538. if (!(pv_))
  539. {
  540. SAVE_ERROR_CODE(ERROR_NOT_ENOUGH_MEMORY);
  541. }
  542. }
  543. ~MALLOCOBJ() { if (pv_) VFREEMEM(pv_); }
  544. PVOID bValid() { return(pv_); }
  545. PVOID pv() { return(pv_); }
  546. };
  547. /*********************************class************************************\
  548. * class SEMOBJ
  549. *
  550. * Semaphore Class
  551. *
  552. * Public Interface:
  553. * SEMOBJ(HSEMAPHORE) // Acquire semaphore
  554. * ~SEMOBJ() // Release semaphore
  555. *
  556. * History:
  557. * 05-Jul-1990 14:57:20 -by- Donald Sidoroff [donalds]
  558. * Wrote it.
  559. \**************************************************************************/
  560. class SEMOBJ
  561. {
  562. private:
  563. HSEMAPHORE hsem;
  564. public:
  565. SEMOBJ(HSEMAPHORE hsem_)
  566. {
  567. hsem = hsem_;
  568. GreAcquireSemaphore(hsem);
  569. }
  570. ~SEMOBJ()
  571. {
  572. GreReleaseSemaphore(hsem);
  573. }
  574. };
  575. // Useful macro.
  576. #define SETFLAG(b,fl,FLAG) if (b) fl|=FLAG; else fl&=~FLAG
  577. #define INC_SURF_UNIQ(pSurfTrg) ((SURFACE *) pSurfTrg)->vStamp()
  578. /**************************************************************************\
  579. * ulGetNewUniqueness
  580. *
  581. * Increments the specified uniqueness in a multithreaded-safe way, and
  582. * returns the new uniqueness.
  583. *
  584. * History:
  585. * 29-Dec-1993 by Michael Abrash [mikeab]
  586. * Wrote it.
  587. \**************************************************************************/
  588. ULONG ulGetNewUniquenessF(ULONG& ulUnique);
  589. inline ULONG ulGetNewUniqueness(ULONG volatile &ulUnique)
  590. {
  591. return(InterlockedIncrement((LPLONG)&ulUnique));
  592. }
  593. #define USE_NINEGRID_STATIC
  594. #if defined(USE_NINEGRID_STATIC)
  595. extern HSEMAPHORE gNineGridSem;
  596. #endif
  597. /**************************************************************************\
  598. *
  599. * Support stuff for per process AVL table of User Mode Memory allocations
  600. * made via EngUserMemAlloc.
  601. *
  602. \**************************************************************************/
  603. RTL_GENERIC_COMPARE_RESULTS GDIEngUserMemAllocNodeCompare(RTL_AVL_TABLE *Table,
  604. PVOID FirstStruct,
  605. PVOID SecondStruct);
  606. PVOID GDIEngUserMemAllocNodeAlloc(RTL_AVL_TABLE *Table, ULONG size);
  607. VOID GDIEngUserMemAllocNodeFree(RTL_AVL_TABLE *Table, PVOID Buffer);
  608. typedef struct _GDIENGUSERMEMALLOCNODE
  609. {
  610. PVOID pUserMem;
  611. SIZE_T cj;
  612. HANDLE hSecure;
  613. } GDIENGUSERMEMALLOCNODE, *PGDIENGUSERMEMALLOCNODE;
  614. /*************************************************************************\
  615. *
  616. * CModeChangeInProgress
  617. *
  618. * Used to indicate a ModeChange in progress.
  619. *
  620. \*************************************************************************/
  621. class CModeChangeInProgress
  622. {
  623. public:
  624. static LONG lInModeChange;
  625. static LONG lNeedSyncFlush;
  626. static LONG lNeedTimerFlush;
  627. CModeChangeInProgress()
  628. {
  629. InterlockedIncrement(&lInModeChange);
  630. }
  631. void vDone();
  632. ~CModeChangeInProgress()
  633. {
  634. }
  635. };