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.

1787 lines
46 KiB

  1. /*++
  2. Copyright (c) 1996-1999 Microsoft Corporation
  3. Module Name
  4. trimesh.cxx
  5. Abstract:
  6. Implement triangle mesh API
  7. Author:
  8. Mark Enstrom (marke) 23-Jun-1996
  9. Enviornment:
  10. User Mode
  11. Revision History:
  12. --*/
  13. #include "precomp.hxx"
  14. #include "dciman.h"
  15. #pragma hdrstop
  16. #if !(_WIN32_WINNT >= 0x500)
  17. VOID
  18. ImgFillMemoryULONG(
  19. PBYTE pDst,
  20. ULONG ulPat,
  21. ULONG cxBytes
  22. )
  23. {
  24. PULONG pulDst = (PULONG)pDst;
  25. PULONG pulEnd = (PULONG)(pDst + ((cxBytes * 4)/4));
  26. while (pulDst != pulEnd)
  27. {
  28. *pulDst = ulPat;
  29. pulDst++;
  30. }
  31. }
  32. /**************************************************************************\
  33. *
  34. * Dither information for 8bpp. This is customized for dithering to
  35. * the halftone palette [6,6,6] color cube.
  36. *
  37. * History:
  38. *
  39. * 2/24/1997 Mark Enstrom [marke]
  40. *
  41. \**************************************************************************/
  42. BYTE gDitherMatrix16x16Halftone[256] = {
  43. 3, 28, 9, 35, 4, 30, 11, 36, 3, 29, 10, 35, 5, 30, 11, 37,
  44. 41, 16, 48, 22, 43, 17, 49, 24, 42, 16, 48, 22, 43, 18, 50, 24,
  45. 6, 32, 0, 25, 8, 33, 1, 27, 6, 32, 0, 26, 8, 34, 2, 27,
  46. 44, 19, 38, 12, 46, 20, 40, 14, 45, 19, 38, 13, 46, 21, 40, 14,
  47. 5, 31, 12, 37, 4, 29, 10, 36, 6, 31, 12, 38, 4, 30, 10, 36,
  48. 44, 18, 50, 24, 42, 16, 48, 23, 44, 18, 50, 25, 42, 17, 49, 23,
  49. 8, 34, 2, 28, 7, 32, 0, 26, 9, 34, 2, 28, 7, 33, 1, 26,
  50. 47, 21, 40, 15, 45, 20, 39, 13, 47, 22, 41, 15, 46, 20, 39, 14,
  51. 3, 29, 9, 35, 5, 30, 11, 37, 3, 28, 9, 35, 4, 30, 11, 36,
  52. 41, 16, 48, 22, 43, 17, 49, 24, 41, 15, 47, 22, 43, 17, 49, 23,
  53. 6, 32, 0, 25, 8, 33, 1, 27, 6, 31, 0, 25, 7, 33, 1, 27,
  54. 45, 19, 38, 13, 46, 21, 40, 14, 44, 19, 38, 12, 46, 20, 39, 14,
  55. 5, 31, 12, 37, 4, 29, 10, 36, 5, 31, 11, 37, 3, 29, 10, 35,
  56. 44, 18, 50, 25, 42, 17, 49, 23, 43, 18, 50, 24, 42, 16, 48, 23,
  57. 9, 34, 2, 28, 7, 33, 1, 26, 8, 34, 2, 27, 7, 32, 0, 26,
  58. 47, 21, 41, 15, 45, 20, 39, 13, 47, 21, 40, 15, 45, 19, 39, 13
  59. };
  60. BYTE gDitherMatrix16x16Default[256] = {
  61. 8, 72, 24, 88, 12, 76, 28, 92, 9, 73, 25, 89, 13, 77, 29, 93,
  62. 104, 40,120, 56,108, 44,124, 60,105, 41,121, 57,109, 45,125, 61,
  63. 16, 80, 0, 64, 20, 84, 4, 68, 17, 81, 1, 65, 21, 85, 5, 69,
  64. 112, 48, 96, 32,116, 52,100, 36,113, 49, 97, 33,117, 53,101, 37,
  65. 14, 78, 30, 94, 10, 74, 26, 90, 15, 79, 31, 95, 11, 75, 27, 91,
  66. 110, 46,126, 62,106, 42,122, 58,111, 47,126, 63,107, 43,123, 59,
  67. 22, 86, 6, 70, 18, 82, 2, 66, 23, 87, 7, 71, 19, 83, 3, 67,
  68. 118, 54,102, 38,114, 50, 98, 34,119, 55,103, 39,115, 51, 99, 35,
  69. 9, 73, 25, 89, 13, 77, 29, 93, 8, 72, 24, 88, 12, 76, 28, 92,
  70. 105, 41,121, 57,109, 45,125, 61,104, 40,120, 56,108, 44,124, 60,
  71. 17, 81, 1, 65, 21, 85, 5, 69, 16, 80, 0, 64, 20, 84, 4, 68,
  72. 113, 49, 97, 33,117, 53,101, 37,112, 48, 96, 32,116, 52,100, 36,
  73. 15, 79, 31, 95, 11, 75, 27, 91, 14, 78, 30, 94, 10, 74, 26, 90,
  74. 111, 47,126, 63,107, 43,123, 59,110, 46,126, 62,106, 42,122, 58,
  75. 23, 87, 7, 71, 19, 83, 3, 67, 22, 86, 6, 70, 18, 82, 2, 66,
  76. 119, 55,103, 39,115, 51, 99, 35,118, 54,102, 38,114, 50, 98, 34
  77. };
  78. /**************************************************************************\
  79. * HalftoneSaturationTable
  80. *
  81. * This table maps a 8 bit pixel plus a dither error term in the range
  82. * of 0 to 51 onto a 8 bit pixel. Overflow of up to 31 is considered
  83. * saturated (255+51 = 255). The level 51 (0x33) is used to map pixels
  84. * and error values to the halftone palette
  85. *
  86. * History:
  87. *
  88. * 3/4/1997 Mark Enstrom [marke]
  89. *
  90. \**************************************************************************/
  91. BYTE HalftoneSaturationTable[256+64] = {
  92. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  93. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  94. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  95. 0, 0, 0, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
  96. 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
  97. 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
  98. 51, 51, 51, 51, 51, 51,102,102,102,102,102,102,102,102,102,102,
  99. 102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,
  100. 102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,
  101. 102,102,102,102,102,102,102,102,102,153,153,153,153,153,153,153,
  102. 153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
  103. 153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
  104. 153,153,153,153,153,153,153,153,153,153,153,153,204,204,204,204,
  105. 204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
  106. 204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
  107. 204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,255,
  108. 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
  109. 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
  110. 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
  111. 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255
  112. };
  113. BYTE DefaultSaturationTable[] = {
  114. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  115. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  116. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  117. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  118. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  119. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  120. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  121. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  122. 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
  123. 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
  124. 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
  125. 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
  126. 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
  127. 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
  128. 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
  129. 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,255,
  130. 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
  131. 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
  132. 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
  133. 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
  134. 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
  135. 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
  136. 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
  137. 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255
  138. };
  139. /**************************************************************************\
  140. * vCalcRectOffsets
  141. *
  142. *
  143. * Arguments:
  144. *
  145. *
  146. *
  147. * Return Value:
  148. *
  149. *
  150. *
  151. * History:
  152. *
  153. * 2/14/1997 Mark Enstrom [marke]
  154. *
  155. \**************************************************************************/
  156. BOOL
  157. bCalcGradientRectOffsets(PGRADIENTRECTDATA pGradRect)
  158. {
  159. LONG yScanTop = MAX(pGradRect->rclClip.top,pGradRect->rclGradient.top);
  160. LONG yScanBottom = MIN(pGradRect->rclClip.bottom,pGradRect->rclGradient.bottom);
  161. LONG yScanLeft = MAX(pGradRect->rclClip.left,pGradRect->rclGradient.left);
  162. LONG yScanRight = MIN(pGradRect->rclClip.right,pGradRect->rclGradient.right);
  163. //
  164. // calc actual widht, check for early out
  165. //
  166. pGradRect->ptDraw.x = yScanLeft;
  167. pGradRect->ptDraw.y = yScanTop;
  168. pGradRect->szDraw.cx = yScanRight - yScanLeft;
  169. pGradRect->szDraw.cy = yScanBottom - yScanTop;
  170. LONG ltemp = pGradRect->rclClip.left - pGradRect->rclGradient.left;
  171. if (ltemp <= 0)
  172. {
  173. ltemp = 0;
  174. }
  175. pGradRect->xScanAdjust = ltemp;
  176. ltemp = pGradRect->rclClip.top - pGradRect->rclGradient.top;
  177. if (ltemp <= 0)
  178. {
  179. ltemp = 0;
  180. }
  181. pGradRect->yScanAdjust = ltemp;
  182. return((pGradRect->szDraw.cx > 0) && (pGradRect->szDraw.cy > 0));
  183. }
  184. /******************************Public*Routine******************************\
  185. * vFillGRectDIB32BGRA
  186. *
  187. *
  188. * Arguments:
  189. *
  190. *
  191. *
  192. * Return Value:
  193. *
  194. *
  195. *
  196. * History:
  197. *
  198. * 11/21/1996 Mark Enstrom [marke]
  199. *
  200. \**************************************************************************/
  201. VOID
  202. vFillGRectDIB32BGRA(
  203. PDIBINFO pDibInfo,
  204. PGRADIENTRECTDATA pgData
  205. )
  206. {
  207. LONG lDelta = pDibInfo->stride;
  208. LONG cyClip = pgData->szDraw.cy;
  209. //
  210. // fill rect with gradient fill. if this is horizontal mode then
  211. // draw one scan line and replicate in v, if this is vertical mode then
  212. // draw one vertical stripe and replicate in h
  213. //
  214. ULONG Red = pgData->Red;
  215. ULONG Green = pgData->Green;
  216. ULONG Blue = pgData->Blue;
  217. ULONG Alpha = pgData->Alpha;
  218. if (pgData->ulMode & GRADIENT_FILL_RECT_H)
  219. {
  220. PBYTE pDst = (PBYTE)pDibInfo->pvBase + lDelta * pgData->ptDraw.y;
  221. LONG dRed = pgData->dRdX;
  222. LONG dGreen = pgData->dGdX;
  223. LONG dBlue = pgData->dBdX;
  224. LONG dAlpha = pgData->dAdX;
  225. //
  226. // adjust gradient fill for clipped portion
  227. //
  228. if (pgData->xScanAdjust > 0)
  229. {
  230. Red += dRed * (pgData->xScanAdjust);
  231. Green += dGreen * (pgData->xScanAdjust);
  232. Blue += dBlue * (pgData->xScanAdjust);
  233. Alpha += dAlpha * (pgData->xScanAdjust);
  234. }
  235. //
  236. // draw 1 scan line
  237. //
  238. PULONG pulDstX = (PULONG)pDst + pgData->ptDraw.x;
  239. PULONG pulEndX = pulDstX + pgData->szDraw.cx;
  240. PULONG pulScanX = pulDstX;
  241. PBYTE pScan = (PBYTE)pulDstX;
  242. while (pulDstX != pulEndX)
  243. {
  244. *pulDstX = ((Alpha & 0x00ff0000) << 8) |
  245. ((Red & 0x00ff0000) ) |
  246. ((Green & 0x00ff0000) >> 8) |
  247. ((Blue & 0x00ff0000) >> 16);
  248. Red += dRed;
  249. Green += dGreen;
  250. Blue += dBlue;
  251. Alpha += dAlpha;
  252. pulDstX++;
  253. }
  254. cyClip--;
  255. pScan += lDelta;
  256. //
  257. // replicate
  258. //
  259. while (cyClip-- > 0)
  260. {
  261. memcpy(pScan,pulScanX,4*pgData->szDraw.cx);
  262. pScan += lDelta;
  263. }
  264. }
  265. else
  266. {
  267. LONG dRed = pgData->dRdY;
  268. LONG dGreen = pgData->dGdY;
  269. LONG dBlue = pgData->dBdY;
  270. LONG dAlpha = pgData->dAdY;
  271. //
  272. // vertical gradient.
  273. // replicate each x value accross whole scan line
  274. //
  275. if (pgData->yScanAdjust > 0)
  276. {
  277. Red += dRed * (pgData->yScanAdjust);
  278. Green += dGreen * (pgData->yScanAdjust);
  279. Blue += dBlue * (pgData->yScanAdjust);
  280. Alpha += dAlpha * (pgData->yScanAdjust);
  281. }
  282. PBYTE pDst = (PBYTE)pDibInfo->pvBase + lDelta * pgData->ptDraw.y;
  283. pDst = pDst + 4 * pgData->ptDraw.x;
  284. while (cyClip--)
  285. {
  286. ULONG ul = ((Alpha & 0x00ff0000) << 8) |
  287. ((Red & 0x00ff0000) ) |
  288. ((Green & 0x00ff0000) >> 8) |
  289. ((Blue & 0x00ff0000) >> 16);
  290. ImgFillMemoryULONG(pDst,ul,pgData->szDraw.cx*4);
  291. Red += dRed;
  292. Green += dGreen;
  293. Blue += dBlue;
  294. Alpha += dAlpha;
  295. pDst += lDelta;
  296. }
  297. }
  298. }
  299. /******************************Public*Routine******************************\
  300. * vFillGRectDIB32RGB
  301. *
  302. *
  303. * Arguments:
  304. *
  305. *
  306. *
  307. * Return Value:
  308. *
  309. *
  310. *
  311. * History:
  312. *
  313. * 11/21/1996 Mark Enstrom [marke]
  314. *
  315. \**************************************************************************/
  316. VOID
  317. vFillGRectDIB32RGB(
  318. PDIBINFO pDibInfo,
  319. PGRADIENTRECTDATA pgData
  320. )
  321. {
  322. LONG lDelta = pDibInfo->stride;
  323. LONG cyClip = pgData->szDraw.cy;
  324. //
  325. // fill rect with gradient fill. if this is horizontal mode then
  326. // draw one scan line and replicate in v, if this is vertical mode then
  327. // draw one vertical stripe and replicate in h
  328. //
  329. ULONG Red = pgData->Red;
  330. ULONG Green = pgData->Green;
  331. ULONG Blue = pgData->Blue;
  332. if (pgData->ulMode & GRADIENT_FILL_RECT_H)
  333. {
  334. PBYTE pDst = (PBYTE)pDibInfo->pvBase + lDelta * pgData->ptDraw.y;
  335. LONG dRed = pgData->dRdX;
  336. LONG dGreen = pgData->dGdX;
  337. LONG dBlue = pgData->dBdX;
  338. //
  339. // adjust gradient fill for clipped portion
  340. //
  341. if (pgData->xScanAdjust > 0)
  342. {
  343. Red += dRed * (pgData->xScanAdjust);
  344. Green += dGreen * (pgData->xScanAdjust);
  345. Blue += dBlue * (pgData->xScanAdjust);
  346. }
  347. //
  348. // draw 1 scan line
  349. //
  350. PULONG pulDstX = (PULONG)pDst + pgData->ptDraw.x;
  351. PULONG pulEndX = pulDstX + pgData->szDraw.cx;
  352. PULONG pulScanX = pulDstX;
  353. PBYTE pScan = (PBYTE)pulDstX;
  354. while (pulDstX != pulEndX)
  355. {
  356. *pulDstX =
  357. ((Red & 0x00ff0000) ) |
  358. ((Green & 0x00ff0000) >> 8) |
  359. ((Blue & 0x00ff0000) >> 16);
  360. Red += dRed;
  361. Green += dGreen;
  362. Blue += dBlue;
  363. pulDstX++;
  364. }
  365. cyClip--;
  366. pScan += lDelta;
  367. //
  368. // replicate
  369. //
  370. while (cyClip-- > 0)
  371. {
  372. memcpy(pScan,pulScanX,4*pgData->szDraw.cx);
  373. pScan += lDelta;
  374. }
  375. }
  376. else
  377. {
  378. LONG dRed = pgData->dRdY;
  379. LONG dGreen = pgData->dGdY;
  380. LONG dBlue = pgData->dBdY;
  381. //
  382. // vertical gradient.
  383. // replicate each x value accross whole scan line
  384. //
  385. if (pgData->yScanAdjust > 0)
  386. {
  387. Red += dRed * (pgData->yScanAdjust);
  388. Green += dGreen * (pgData->yScanAdjust);
  389. Blue += dBlue * (pgData->yScanAdjust);
  390. }
  391. PBYTE pDst = (PBYTE)pDibInfo->pvBase + lDelta * pgData->ptDraw.y;
  392. pDst = pDst + 4 * pgData->ptDraw.x;
  393. while (cyClip--)
  394. {
  395. ULONG ul = ((Red & 0x00ff0000) ) |
  396. ((Green & 0x00ff0000) >> 8) |
  397. ((Blue & 0x00ff0000) >> 16);
  398. ImgFillMemoryULONG(pDst,ul,pgData->szDraw.cx*4);
  399. Red += dRed;
  400. Green += dGreen;
  401. Blue += dBlue;
  402. pDst += lDelta;
  403. }
  404. }
  405. }
  406. /******************************Public*Routine******************************\
  407. * vFillGRectDIB24RGB
  408. *
  409. *
  410. * Arguments:
  411. *
  412. *
  413. *
  414. * Return Value:
  415. *
  416. *
  417. *
  418. * History:
  419. *
  420. * 11/21/1996 Mark Enstrom [marke]
  421. *
  422. \**************************************************************************/
  423. VOID
  424. vFillGRectDIB24RGB(
  425. PDIBINFO pDibInfo,
  426. PGRADIENTRECTDATA pgData
  427. )
  428. {
  429. LONG lDelta = pDibInfo->stride;
  430. LONG cyClip = pgData->szDraw.cy;
  431. ULONG Red = pgData->Red;
  432. ULONG Green = pgData->Green;
  433. ULONG Blue = pgData->Blue;
  434. //
  435. // fill rect with gradient fill. if this is horizontal mode then
  436. // draw one scan line and replicate in v, if this is vertical mode then
  437. // draw one vertical stripe and replicate in h
  438. //
  439. if (pgData->ulMode & GRADIENT_FILL_RECT_H)
  440. {
  441. PBYTE pDst = (PBYTE)pDibInfo->pvBase +
  442. lDelta * pgData->ptDraw.y +
  443. 3 * pgData->ptDraw.x;
  444. LONG dRed = pgData->dRdX;
  445. LONG dGreen = pgData->dGdX;
  446. LONG dBlue = pgData->dBdX;
  447. //
  448. // adjust gradient fill for clipped portion
  449. //
  450. if (pgData->xScanAdjust > 0)
  451. {
  452. Red += dRed * (pgData->xScanAdjust);
  453. Green += dGreen * (pgData->xScanAdjust);
  454. Blue += dBlue * (pgData->xScanAdjust);
  455. }
  456. PBYTE pBuffer = (PBYTE)LOCALALLOC(3 * pgData->szDraw.cx);
  457. if (pBuffer)
  458. {
  459. PBYTE pDstX = pBuffer;
  460. PBYTE pLast = pDstX + 3 * pgData->szDraw.cx;
  461. while (pDstX != pLast)
  462. {
  463. *pDstX = (BYTE)(Blue >> 16);
  464. *(pDstX+1) = (BYTE)(Green >> 16);
  465. *(pDstX+2) = (BYTE)(Red >> 16);
  466. Red += dRed;
  467. Green += dGreen;
  468. Blue += dBlue;
  469. pDstX+=3;
  470. }
  471. //
  472. // Replicate the scan line. It would be much better to write the scan line
  473. // out to a memory buffer for drawing to a device surface!!!
  474. //
  475. while (cyClip--)
  476. {
  477. memcpy(pDst,pBuffer,3*pgData->szDraw.cx);
  478. pDst += lDelta;
  479. }
  480. LOCALFREE(pBuffer);
  481. }
  482. }
  483. else
  484. {
  485. //
  486. // vertical gradient.
  487. // replicate each x value accross whole scan line
  488. //
  489. PBYTE pDst = (PBYTE)pDibInfo->pvBase + lDelta * pgData->ptDraw.y;
  490. LONG dRed = pgData->dRdY;
  491. LONG dGreen = pgData->dGdY;
  492. LONG dBlue = pgData->dBdY;
  493. //
  494. // vertical gradient.
  495. // replicate each x value accross whole scan line
  496. //
  497. if (pgData->yScanAdjust > 0)
  498. {
  499. Red += dRed * (pgData->yScanAdjust);
  500. Green += dGreen * (pgData->yScanAdjust);
  501. Blue += dBlue * (pgData->yScanAdjust);
  502. }
  503. pDst = pDst + 3 * pgData->ptDraw.x;
  504. while (cyClip--)
  505. {
  506. //
  507. // fill scan line with solid color
  508. //
  509. PBYTE pTemp = pDst;
  510. PBYTE pEnd = pDst + 3 * pgData->szDraw.cx;
  511. BYTE jRed = (BYTE)((Red & 0x00ff0000) >> 16);
  512. BYTE jGreen = (BYTE)((Green & 0x00ff0000) >> 16);
  513. BYTE jBlue = (BYTE)((Blue & 0x00ff0000) >> 16);
  514. while (pTemp != pEnd)
  515. {
  516. *pTemp = jBlue;
  517. *(pTemp+1) = jGreen;
  518. *(pTemp+2) = jRed;
  519. pTemp+=3;
  520. }
  521. //
  522. // increment colors for next scan line
  523. //
  524. Red += dRed;
  525. Green += dGreen;
  526. Blue += dBlue;
  527. //
  528. // inc pointer to next scan line
  529. //
  530. pDst += lDelta;
  531. }
  532. }
  533. }
  534. /******************************Public*Routine******************************\
  535. * vFillGRectDIB16_565
  536. *
  537. *
  538. * Arguments:
  539. *
  540. *
  541. *
  542. * Return Value:
  543. *
  544. *
  545. *
  546. * History:
  547. *
  548. * 11/21/1996 Mark Enstrom [marke]
  549. *
  550. \**************************************************************************/
  551. VOID
  552. vFillGRectDIB16_565(
  553. PDIBINFO pDibInfo,
  554. PGRADIENTRECTDATA pgData
  555. )
  556. {
  557. LONG lDelta = pDibInfo->stride;
  558. LONG cxClip = pgData->szDraw.cx;
  559. LONG yScan = pgData->ptDraw.y;
  560. LONG yScanBottom = yScan + pgData->szDraw.cy;
  561. PBYTE pDst = (PBYTE)pDibInfo->pvBase + lDelta * pgData->ptDraw.y;
  562. LONG dxRed = pgData->dRdX;
  563. LONG dxGreen = pgData->dGdX;
  564. LONG dxBlue = pgData->dBdX;
  565. LONG dyRed = pgData->dRdY;
  566. LONG dyGreen = pgData->dGdY;
  567. LONG dyBlue = pgData->dBdY;
  568. ULONG eRed;
  569. ULONG eGreen;
  570. ULONG eBlue;
  571. PULONG pulDither;
  572. //
  573. // skip down to left edge
  574. //
  575. eRed = pgData->Red;
  576. eGreen = pgData->Green;
  577. eBlue = pgData->Blue;
  578. if (pgData->yScanAdjust)
  579. {
  580. eRed += dyRed * (pgData->yScanAdjust);
  581. eGreen += dyGreen * (pgData->yScanAdjust);
  582. eBlue += dyBlue * (pgData->yScanAdjust);
  583. }
  584. LONG yDitherOrg = pgData->ptDitherOrg.y;
  585. LONG xDitherOrg = pgData->ptDitherOrg.x;
  586. while(yScan < yScanBottom)
  587. {
  588. PUSHORT pusDstX;
  589. PUSHORT pusDstScanRight,pusDstScanLeft;
  590. LONG xScanRight;
  591. ULONG Red;
  592. ULONG Green;
  593. ULONG Blue;
  594. pulDither = &gulDither32[0] + 4 * ((yScan+yDitherOrg) & 3);
  595. Red = eRed;
  596. Green = eGreen;
  597. Blue = eBlue;
  598. if (pgData->xScanAdjust)
  599. {
  600. Red += dxRed * (pgData->xScanAdjust);
  601. Green += dxGreen * (pgData->xScanAdjust);
  602. Blue += dxBlue * (pgData->xScanAdjust);
  603. }
  604. pusDstX = (PUSHORT)pDst + pgData->ptDraw.x;
  605. pusDstScanRight = pusDstX + pgData->szDraw.cx;
  606. while (pusDstX < pusDstScanRight)
  607. {
  608. ULONG ulDither = pulDither[(((ULONG)pusDstX >> 1)+xDitherOrg) & 3];
  609. ULONG iRed = (((Red >> 3) + ulDither) >> 16);
  610. ULONG iGreen = (((Green >> 2) + ulDither) >> 16);
  611. ULONG iBlue = (((Blue >> 3) + ulDither) >> 16);
  612. //
  613. // check for overflow
  614. //
  615. if ((iRed | iBlue) & 0x20)
  616. {
  617. if (iRed & 0x20)
  618. {
  619. iRed = 0x1f;
  620. }
  621. if (iBlue & 0x20)
  622. {
  623. iBlue = 0x1f;
  624. }
  625. }
  626. if (iGreen & 0x40)
  627. {
  628. iGreen = 0x3f;
  629. }
  630. *pusDstX = rgb565(iRed,iGreen,iBlue);
  631. pusDstX++;
  632. Red += dxRed;
  633. Green += dxGreen;
  634. Blue += dxBlue;
  635. }
  636. eRed += dyRed;
  637. eGreen += dyGreen;
  638. eBlue += dyBlue;
  639. yScan ++;
  640. pDst += lDelta;
  641. }
  642. }
  643. /******************************Public*Routine******************************\
  644. * vFillGRectDIB16_555
  645. *
  646. *
  647. * Arguments:
  648. *
  649. *
  650. *
  651. * Return Value:
  652. *
  653. *
  654. *
  655. * History:
  656. *
  657. * 11/21/1996 Mark Enstrom [marke]
  658. *
  659. \**************************************************************************/
  660. VOID
  661. vFillGRectDIB16_555(
  662. PDIBINFO pDibInfo,
  663. PGRADIENTRECTDATA pgData
  664. )
  665. {
  666. LONG lDelta = pDibInfo->stride;
  667. LONG cxClip = pgData->szDraw.cx;
  668. LONG yScan = pgData->ptDraw.y;
  669. LONG yScanBottom = yScan + pgData->szDraw.cy;
  670. PBYTE pDst = (PBYTE)pDibInfo->pvBase + lDelta * pgData->ptDraw.y;
  671. LONG dxRed = pgData->dRdX;
  672. LONG dxGreen = pgData->dGdX;
  673. LONG dxBlue = pgData->dBdX;
  674. LONG dyRed = pgData->dRdY;
  675. LONG dyGreen = pgData->dGdY;
  676. LONG dyBlue = pgData->dBdY;
  677. ULONG eRed;
  678. ULONG eGreen;
  679. ULONG eBlue;
  680. PULONG pulDither;
  681. //
  682. // skip down to left edge
  683. //
  684. eRed = pgData->Red;
  685. eGreen = pgData->Green;
  686. eBlue = pgData->Blue;
  687. if (pgData->yScanAdjust)
  688. {
  689. eRed += dyRed * (pgData->yScanAdjust);
  690. eGreen += dyGreen * (pgData->yScanAdjust);
  691. eBlue += dyBlue * (pgData->yScanAdjust);
  692. }
  693. LONG yDitherOrg = pgData->ptDitherOrg.y;
  694. LONG xDitherOrg = pgData->ptDitherOrg.x;
  695. while(yScan < yScanBottom)
  696. {
  697. PUSHORT pusDstX;
  698. PUSHORT pusDstScanRight,pusDstScanLeft;
  699. LONG xScanRight;
  700. ULONG Red;
  701. ULONG Green;
  702. ULONG Blue;
  703. pulDither = &gulDither32[0] + 4 * ((yScan+yDitherOrg) & 3);
  704. Red = eRed;
  705. Green = eGreen;
  706. Blue = eBlue;
  707. if (pgData->xScanAdjust)
  708. {
  709. Red += dxRed * (pgData->xScanAdjust);
  710. Green += dxGreen * (pgData->xScanAdjust);
  711. Blue += dxBlue * (pgData->xScanAdjust);
  712. }
  713. pusDstX = (PUSHORT)pDst + pgData->ptDraw.x;
  714. pusDstScanRight = pusDstX + pgData->szDraw.cx;
  715. while (pusDstX < pusDstScanRight)
  716. {
  717. ULONG ulDither = pulDither[(((ULONG)pusDstX >> 1)+xDitherOrg) & 3];
  718. ULONG iRed = (((Red >> 3) + ulDither) >> 16);
  719. ULONG iGreen = (((Green >> 3) + ulDither) >> 16);
  720. ULONG iBlue = (((Blue >> 3) + ulDither) >> 16);
  721. //
  722. // check for overflow
  723. //
  724. if ((iRed | iBlue | iGreen) & 0x20)
  725. {
  726. if (iRed & 0x20)
  727. {
  728. iRed = 0x1f;
  729. }
  730. if (iBlue & 0x20)
  731. {
  732. iBlue = 0x1f;
  733. }
  734. if (iGreen & 0x20)
  735. {
  736. iGreen = 0x1f;
  737. }
  738. }
  739. *pusDstX = rgb555(iRed,iGreen,iBlue);
  740. pusDstX++;
  741. Red += dxRed;
  742. Green += dxGreen;
  743. Blue += dxBlue;
  744. }
  745. eRed += dyRed;
  746. eGreen += dyGreen;
  747. eBlue += dyBlue;
  748. yScan ++;
  749. pDst += lDelta;
  750. }
  751. }
  752. /******************************Public*Routine******************************\
  753. * vFillGRectDIB8
  754. *
  755. *
  756. * Arguments:
  757. *
  758. *
  759. *
  760. * Return Value:
  761. *
  762. *
  763. *
  764. * History:
  765. *
  766. * 11/21/1996 Mark Enstrom [marke]
  767. *
  768. \**************************************************************************/
  769. VOID
  770. vFillGRectDIB8(
  771. PDIBINFO pDibInfo,
  772. PGRADIENTRECTDATA pgData
  773. )
  774. {
  775. LONG lDelta = pDibInfo->stride;
  776. LONG cxClip = pgData->szDraw.cx;
  777. LONG yScan = pgData->ptDraw.y;
  778. LONG yScanBottom = yScan + pgData->szDraw.cy;
  779. PBYTE pDst = (PBYTE)pDibInfo->pvBase + lDelta * pgData->ptDraw.y;
  780. LONG dxRed = pgData->dRdX;
  781. LONG dxGreen = pgData->dGdX;
  782. LONG dxBlue = pgData->dBdX;
  783. LONG dyRed = pgData->dRdY;
  784. LONG dyGreen = pgData->dGdY;
  785. LONG dyBlue = pgData->dBdY;
  786. ULONG eRed;
  787. ULONG eGreen;
  788. ULONG eBlue;
  789. PBYTE pDitherMatrix;
  790. PBYTE pSaturationTable;
  791. PBYTE pxlate = pDibInfo->pxlate332;
  792. //
  793. // either use default palette or halftone palette dither
  794. //
  795. if (pxlate == NULL)
  796. {
  797. WARNING("Failed to generate rgb333 xlate table\n");
  798. return;
  799. }
  800. if (pxlate == gHalftoneColorXlate332)
  801. {
  802. pDitherMatrix = gDitherMatrix16x16Halftone;
  803. pSaturationTable = HalftoneSaturationTable;
  804. }
  805. else
  806. {
  807. pDitherMatrix = gDitherMatrix16x16Default;
  808. pSaturationTable = DefaultSaturationTable;
  809. }
  810. //
  811. // skip down to left edge
  812. //
  813. eRed = pgData->Red;
  814. eGreen = pgData->Green;
  815. eBlue = pgData->Blue;
  816. if (pgData->yScanAdjust)
  817. {
  818. eRed += dyRed * (pgData->yScanAdjust);
  819. eGreen += dyGreen * (pgData->yScanAdjust);
  820. eBlue += dyBlue * (pgData->yScanAdjust);
  821. }
  822. LONG yDitherOrg = pgData->ptDitherOrg.y;
  823. LONG xDitherOrg = pgData->ptDitherOrg.x;
  824. while(yScan < yScanBottom)
  825. {
  826. PBYTE pjDstX;
  827. PBYTE pjDstScanRight,pjDstScanLeft;
  828. LONG xScanRight;
  829. ULONG Red;
  830. ULONG Green;
  831. ULONG Blue;
  832. Red = eRed;
  833. Green = eGreen;
  834. Blue = eBlue;
  835. if (pgData->xScanAdjust)
  836. {
  837. Red += dxRed * (pgData->xScanAdjust);
  838. Green += dxGreen * (pgData->xScanAdjust);
  839. Blue += dxBlue * (pgData->xScanAdjust);
  840. }
  841. pjDstX = pDst + pgData->ptDraw.x;
  842. pjDstScanRight = pjDstX + cxClip;
  843. PBYTE pDitherLevel = &pDitherMatrix[(16 * ((yScan+yDitherOrg) & DITHER_8_MASK_Y))];
  844. while (pjDstX < pjDstScanRight)
  845. {
  846. //
  847. // calculate x component of dither
  848. //
  849. ULONG iRed = (ULONG)(Red >> 16);
  850. ULONG iGreen = (ULONG)(Green >> 16);
  851. ULONG iBlue = (ULONG)(Blue >> 16);
  852. BYTE jDitherMatrix = *(pDitherLevel + (((ULONG)pjDstX + xDitherOrg) & DITHER_8_MASK_X));
  853. iRed = pSaturationTable[iRed + jDitherMatrix];
  854. iGreen = pSaturationTable[iGreen + jDitherMatrix];
  855. iBlue = pSaturationTable[iBlue + jDitherMatrix];
  856. BYTE jIndex;
  857. GRAD_PALETTE_MATCH(jIndex,pxlate,((BYTE)iRed),((BYTE)iGreen),((BYTE)iBlue));
  858. *pjDstX = jIndex;
  859. pjDstX++;
  860. Red += dxRed;
  861. Green += dxGreen;
  862. Blue += dxBlue;
  863. }
  864. pDst += lDelta;
  865. //
  866. // add y color increment
  867. //
  868. eRed += dyRed;
  869. eGreen += dyGreen;
  870. eBlue += dyBlue;
  871. yScan++;
  872. }
  873. }
  874. /******************************Public*Routine******************************\
  875. * vFillGRectDIB4
  876. *
  877. *
  878. * Arguments:
  879. *
  880. *
  881. *
  882. * Return Value:
  883. *
  884. *
  885. *
  886. * History:
  887. *
  888. * 11/21/1996 Mark Enstrom [marke]
  889. *
  890. \**************************************************************************/
  891. VOID
  892. vFillGRectDIB4(
  893. PDIBINFO pDibInfo,
  894. PGRADIENTRECTDATA pgData
  895. )
  896. {
  897. LONG lDelta = pDibInfo->stride;
  898. PBYTE pDst = (PBYTE)pDibInfo->pvBase + lDelta * pgData->ptDraw.y;
  899. LONG cxClip = pgData->szDraw.cx;
  900. LONG cyClip = pgData->szDraw.cy;
  901. LONG yScan = pgData->ptDraw.y;
  902. LONG yScanBottom = yScan + cyClip;
  903. LONG dxRed = pgData->dRdX;
  904. LONG dxGreen = pgData->dGdX;
  905. LONG dxBlue = pgData->dBdX;
  906. LONG dyRed = pgData->dRdY;
  907. LONG dyGreen = pgData->dGdY;
  908. LONG dyBlue = pgData->dBdY;
  909. ULONG eRed;
  910. ULONG eGreen;
  911. ULONG eBlue;
  912. PBYTE pxlate = pDibInfo->pxlate332;
  913. PBYTE pDitherMatrix = gDitherMatrix16x16Default;
  914. PBYTE pSaturationTable = DefaultSaturationTable;
  915. //
  916. // get/build rgb555 to palette table
  917. //
  918. if (pxlate == NULL)
  919. {
  920. WARNING("Failed to generate rgb333 xlate table\n");
  921. return;
  922. }
  923. //
  924. // skip down to left edge
  925. //
  926. eRed = pgData->Red;
  927. eGreen = pgData->Green;
  928. eBlue = pgData->Blue;
  929. if (pgData->yScanAdjust)
  930. {
  931. eRed += dyRed * (pgData->yScanAdjust);
  932. eGreen += dyGreen * (pgData->yScanAdjust);
  933. eBlue += dyBlue * (pgData->yScanAdjust);
  934. }
  935. LONG yDitherOrg = pgData->ptDitherOrg.y;
  936. LONG xDitherOrg = pgData->ptDitherOrg.x;
  937. while(yScan < yScanBottom)
  938. {
  939. PBYTE pjDstX;
  940. LONG ixDst;
  941. LONG cx = cxClip;
  942. LONG xScanRight;
  943. ULONG Red;
  944. ULONG Green;
  945. ULONG Blue;
  946. Red = eRed;
  947. Green = eGreen;
  948. Blue = eBlue;
  949. PBYTE pDitherLevel = &pDitherMatrix[(16 * ((yScan+yDitherOrg) & DITHER_8_MASK_Y))];
  950. if (pgData->xScanAdjust)
  951. {
  952. Red += dxRed * (pgData->xScanAdjust);
  953. Green += dxGreen * (pgData->xScanAdjust);
  954. Blue += dxBlue * (pgData->xScanAdjust);
  955. }
  956. pjDstX = pDst + pgData->ptDraw.x/2;
  957. ixDst = pgData->ptDraw.x;
  958. while (cx--)
  959. {
  960. //
  961. // offset into dither array
  962. //
  963. BYTE jDitherMatrix = *(pDitherLevel + ((ixDst+xDitherOrg) & DITHER_8_MASK_X));
  964. ULONG iRed = (ULONG)(Red >> 16);
  965. ULONG iGreen = (ULONG)(Green >> 16);
  966. ULONG iBlue = (ULONG)(Blue >> 16);
  967. iRed = pSaturationTable[iRed + jDitherMatrix];
  968. iGreen = pSaturationTable[iGreen + jDitherMatrix];
  969. iBlue = pSaturationTable[iBlue + jDitherMatrix];
  970. BYTE jIndex;
  971. GRAD_PALETTE_MATCH(jIndex,pxlate,((BYTE)iRed),((BYTE)iGreen),((BYTE)iBlue));
  972. if (ixDst & 1)
  973. {
  974. *pjDstX = (*pjDstX & 0xf0) | jIndex;
  975. pjDstX++;
  976. }
  977. else
  978. {
  979. *pjDstX = (*pjDstX & 0x0f) | (jIndex << 4);
  980. }
  981. ixDst++;
  982. Red += dxRed;
  983. Green += dxGreen;
  984. Blue += dxBlue;
  985. }
  986. pDst += lDelta;
  987. //
  988. // add y color increment
  989. //
  990. eRed += dyRed;
  991. eGreen += dyGreen;
  992. eBlue += dyBlue;
  993. yScan++;
  994. }
  995. }
  996. /******************************Public*Routine******************************\
  997. * vFillGRectDIB1
  998. *
  999. *
  1000. * Arguments:
  1001. *
  1002. *
  1003. *
  1004. * Return Value:
  1005. *
  1006. *
  1007. *
  1008. * History:
  1009. *
  1010. * 11/21/1996 Mark Enstrom [marke]
  1011. *
  1012. \**************************************************************************/
  1013. VOID
  1014. vFillGRectDIB1(
  1015. PDIBINFO pDibInfo,
  1016. PGRADIENTRECTDATA pgData
  1017. )
  1018. {
  1019. LONG lDelta = pDibInfo->stride;
  1020. LONG cxClip = pgData->szDraw.cx;
  1021. LONG cyClip = pgData->szDraw.cy;
  1022. PBYTE pDst = (PBYTE)pDibInfo->pvBase + lDelta * pgData->ptDraw.y;
  1023. LONG yScan = pgData->ptDraw.y;
  1024. LONG yScanBottom = yScan + cyClip;
  1025. LONG dxRed = pgData->dRdX;
  1026. LONG dxGreen = pgData->dGdX;
  1027. LONG dxBlue = pgData->dBdX;
  1028. LONG dyRed = pgData->dRdY;
  1029. LONG dyGreen = pgData->dGdY;
  1030. LONG dyBlue = pgData->dBdY;
  1031. ULONG eRed;
  1032. ULONG eGreen;
  1033. ULONG eBlue;
  1034. PBYTE pxlate = pDibInfo->pxlate332;
  1035. PBYTE pDitherMatrix = gDitherMatrix16x16Default;
  1036. //
  1037. // get/build rgb555 to palette table
  1038. //
  1039. if (pxlate == NULL)
  1040. {
  1041. WARNING("Failed to generate rgb555 xlate table\n");
  1042. return;
  1043. }
  1044. //
  1045. // skip down to left edge
  1046. //
  1047. eRed = pgData->Red;
  1048. eGreen = pgData->Green;
  1049. eBlue = pgData->Blue;
  1050. if (pgData->yScanAdjust)
  1051. {
  1052. eRed += dyRed * (pgData->yScanAdjust);
  1053. eGreen += dyGreen * (pgData->yScanAdjust);
  1054. eBlue += dyBlue * (pgData->yScanAdjust);
  1055. }
  1056. LONG yDitherOrg = pgData->ptDitherOrg.y;
  1057. LONG xDitherOrg = pgData->ptDitherOrg.x;
  1058. while(yScan < yScanBottom)
  1059. {
  1060. PBYTE pjDstX;
  1061. LONG ixDst;
  1062. LONG cx = cxClip;
  1063. LONG xScanLeft = pgData->ptDraw.x;
  1064. LONG xScanRight = xScanLeft + cx;
  1065. ULONG Red;
  1066. ULONG Green;
  1067. ULONG Blue;
  1068. Red = eRed;
  1069. Green = eGreen;
  1070. Blue = eBlue;
  1071. PBYTE pDitherLevel = &pDitherMatrix[(16 * ((yScan+yDitherOrg) & DITHER_8_MASK_Y))];
  1072. if (pgData->xScanAdjust)
  1073. {
  1074. Red += dxRed * (pgData->xScanAdjust);
  1075. Green += dxGreen * (pgData->xScanAdjust);
  1076. Blue += dxBlue * (pgData->xScanAdjust);
  1077. }
  1078. pjDstX = pDst + pgData->ptDraw.x/8;
  1079. ixDst = pgData->ptDraw.x & 7;
  1080. while (xScanLeft < xScanRight)
  1081. {
  1082. //
  1083. // offset into dither array
  1084. //
  1085. BYTE jDitherMatrix = 2 * (*(pDitherLevel + ((xScanLeft+xDitherOrg) & DITHER_8_MASK_X)));
  1086. ULONG iRed = (ULONG)(Red >> 16);
  1087. ULONG iGreen = (ULONG)(Green >> 16);
  1088. ULONG iBlue = (ULONG)(Blue >> 16);
  1089. //
  1090. // add dither and saturate. 1bpp non-optimized
  1091. //
  1092. iRed = iRed + jDitherMatrix;
  1093. if (iRed >= 255)
  1094. {
  1095. iRed = 255;
  1096. }
  1097. else
  1098. {
  1099. iRed = 0;
  1100. }
  1101. iGreen = iGreen + jDitherMatrix;
  1102. if (iGreen >= 255)
  1103. {
  1104. iGreen = 255;
  1105. }
  1106. else
  1107. {
  1108. iGreen = 0;
  1109. }
  1110. iBlue = iBlue + jDitherMatrix;
  1111. if (iBlue >= 255)
  1112. {
  1113. iBlue = 255;
  1114. }
  1115. else
  1116. {
  1117. iBlue = 0;
  1118. }
  1119. BYTE jIndex;
  1120. //
  1121. // pjVector is known to be identity, so could make new macro for
  1122. // palette_match_1 if perf ever an issue
  1123. //
  1124. GRAD_PALETTE_MATCH(jIndex,pxlate,((BYTE)iRed),((BYTE)iGreen),((BYTE)iBlue));
  1125. LONG iShift = 7 - ixDst;
  1126. BYTE OrMask = 1 << iShift;
  1127. BYTE AndMask = ~OrMask;
  1128. jIndex = jIndex << iShift;
  1129. *pjDstX = (*pjDstX & AndMask) | jIndex;
  1130. ixDst++;
  1131. if (ixDst == 8)
  1132. {
  1133. ixDst = 0;
  1134. pjDstX++;
  1135. }
  1136. Red += dxRed;
  1137. Green += dxGreen;
  1138. Blue += dxBlue;
  1139. xScanLeft++;
  1140. }
  1141. pDst += lDelta;
  1142. //
  1143. // add y color increment
  1144. //
  1145. eRed += dyRed;
  1146. eGreen += dyGreen;
  1147. eBlue += dyBlue;
  1148. yScan++;
  1149. }
  1150. }
  1151. /******************************Public*Routine******************************\
  1152. * pfnGradientRectFillFunction
  1153. *
  1154. * look at format to decide if DIBSection should be drawn directly
  1155. *
  1156. * 32 bpp RGB
  1157. * 32 bpp BGR
  1158. * 24 bpp
  1159. * 16 bpp 565
  1160. * 16 bpp 555
  1161. *
  1162. * Trangles are only filled in high color (no palette) surfaces
  1163. *
  1164. * Arguments:
  1165. *
  1166. * pDibInfo - information about destination surface
  1167. *
  1168. * Return Value:
  1169. *
  1170. * PFN_GRADRECT - triangle filling routine
  1171. *
  1172. * History:
  1173. *
  1174. * 12/6/1996 Mark Enstrom [marke]
  1175. *
  1176. \**************************************************************************/
  1177. PFN_GRADRECT
  1178. pfnGradientRectFillFunction(
  1179. PDIBINFO pDibInfo
  1180. )
  1181. {
  1182. PFN_GRADRECT pfnRet = NULL;
  1183. PULONG pulMasks = (PULONG)&pDibInfo->pbmi->bmiColors[0];
  1184. //
  1185. // 32 bpp RGB
  1186. //
  1187. if (
  1188. (pDibInfo->pbmi->bmiHeader.biBitCount == 32) &&
  1189. (pDibInfo->pbmi->bmiHeader.biCompression == BI_RGB)
  1190. )
  1191. {
  1192. pfnRet = vFillGRectDIB32BGRA;
  1193. }
  1194. else if (
  1195. (pDibInfo->pbmi->bmiHeader.biBitCount == 32) &&
  1196. (pDibInfo->pbmi->bmiHeader.biCompression == BI_BITFIELDS) &&
  1197. (pulMasks[0] == 0xff0000) &&
  1198. (pulMasks[1] == 0x00ff00) &&
  1199. (pulMasks[2] == 0x0000ff)
  1200. )
  1201. {
  1202. pfnRet = vFillGRectDIB32BGRA;
  1203. }
  1204. else if (
  1205. (pDibInfo->pbmi->bmiHeader.biBitCount == 32) &&
  1206. (pDibInfo->pbmi->bmiHeader.biCompression == BI_BITFIELDS) &&
  1207. (pulMasks[0] == 0x0000ff) &&
  1208. (pulMasks[1] == 0x00ff00) &&
  1209. (pulMasks[2] == 0xff0000)
  1210. )
  1211. {
  1212. pfnRet = vFillGRectDIB32RGB;
  1213. }
  1214. else if (
  1215. (pDibInfo->pbmi->bmiHeader.biBitCount == 24) &&
  1216. (pDibInfo->pbmi->bmiHeader.biCompression == BI_RGB)
  1217. )
  1218. {
  1219. pfnRet = vFillGRectDIB24RGB;
  1220. }
  1221. //
  1222. // 16 BPP
  1223. //
  1224. else if (
  1225. (pDibInfo->pbmi->bmiHeader.biBitCount == 16) &&
  1226. (pDibInfo->pbmi->bmiHeader.biCompression == BI_BITFIELDS)
  1227. )
  1228. {
  1229. //
  1230. // 565,555
  1231. //
  1232. if (
  1233. (pulMasks[0] == 0xf800) &&
  1234. (pulMasks[1] == 0x07e0) &&
  1235. (pulMasks[2] == 0x001f)
  1236. )
  1237. {
  1238. pfnRet = vFillGRectDIB16_565;
  1239. }
  1240. else if (
  1241. (pulMasks[0] == 0x7c00) &&
  1242. (pulMasks[1] == 0x03e0) &&
  1243. (pulMasks[2] == 0x001f)
  1244. )
  1245. {
  1246. pfnRet = vFillGRectDIB16_555;
  1247. }
  1248. }
  1249. else if (
  1250. (pDibInfo->pbmi->bmiHeader.biBitCount == 8)
  1251. )
  1252. {
  1253. pfnRet = vFillGRectDIB8;
  1254. }
  1255. else if (
  1256. (pDibInfo->pbmi->bmiHeader.biBitCount == 4)
  1257. )
  1258. {
  1259. pfnRet = vFillGRectDIB4;
  1260. }
  1261. else if (
  1262. (pDibInfo->pbmi->bmiHeader.biBitCount == 1)
  1263. )
  1264. {
  1265. pfnRet = vFillGRectDIB1;
  1266. }
  1267. return(pfnRet);
  1268. }
  1269. /**************************************************************************\
  1270. * DIBGradientRect
  1271. *
  1272. *
  1273. * Arguments:
  1274. *
  1275. *
  1276. *
  1277. * Return Value:
  1278. *
  1279. *
  1280. *
  1281. * History:
  1282. *
  1283. * 2/11/1997 Mark Enstrom [marke]
  1284. *
  1285. \**************************************************************************/
  1286. BOOL
  1287. DIBGradientRect(
  1288. HDC hdc,
  1289. PTRIVERTEX pVertex,
  1290. ULONG nVertex,
  1291. PGRADIENT_RECT pMesh,
  1292. ULONG nMesh,
  1293. ULONG ulMode,
  1294. PRECTL prclPhysExt,
  1295. PDIBINFO pDibInfo,
  1296. PPOINTL pptlDitherOrg
  1297. )
  1298. {
  1299. BOOL bStatus = TRUE;
  1300. PFN_GRADRECT pfnGradRect = NULL;
  1301. ULONG ulIndex;
  1302. pfnGradRect = pfnGradientRectFillFunction(pDibInfo);
  1303. if (pfnGradRect == NULL)
  1304. {
  1305. WARNING("DIBGradientRect:Can't draw to surface\n");
  1306. return(TRUE);
  1307. }
  1308. //
  1309. // work in physical map mode, restore before return
  1310. //
  1311. ULONG OldMode = SetMapMode(hdc,MM_TEXT);
  1312. //
  1313. // fake up scale !!!
  1314. //
  1315. for (ulIndex=0;ulIndex<nVertex;ulIndex++)
  1316. {
  1317. pVertex[ulIndex].x = pVertex[ulIndex].x * 16;
  1318. pVertex[ulIndex].y = pVertex[ulIndex].y * 16;
  1319. }
  1320. //
  1321. // limit rectangle output to clipped output
  1322. //
  1323. LONG dxRect = prclPhysExt->right - prclPhysExt->left;
  1324. LONG dyRect = prclPhysExt->bottom - prclPhysExt->top;
  1325. //
  1326. // check for clipped out
  1327. //
  1328. if ((dyRect > 0) && (dxRect > 0))
  1329. {
  1330. GRADIENTRECTDATA grData;
  1331. //
  1332. // clip output
  1333. //
  1334. grData.rclClip = *prclPhysExt;
  1335. grData.ptDitherOrg = *pptlDitherOrg;
  1336. for (ulIndex=0;ulIndex<nMesh;ulIndex++)
  1337. {
  1338. ULONG ulRect0 = pMesh[ulIndex].UpperLeft;
  1339. ULONG ulRect1 = pMesh[ulIndex].LowerRight;
  1340. //
  1341. // make sure index are in array
  1342. //
  1343. if (
  1344. (ulRect0 > nVertex) ||
  1345. (ulRect1 > nVertex)
  1346. )
  1347. {
  1348. bStatus = FALSE;
  1349. break;
  1350. }
  1351. TRIVERTEX tvert0 = pVertex[ulRect0];
  1352. TRIVERTEX tvert1 = pVertex[ulRect1];
  1353. PTRIVERTEX pv0 = &tvert0;
  1354. PTRIVERTEX pv1 = &tvert1;
  1355. PTRIVERTEX pvt;
  1356. //
  1357. // make sure rectangle endpoints are properly ordered
  1358. //
  1359. if (ulMode & GRADIENT_FILL_RECT_H)
  1360. {
  1361. if (pv0->x > pv1->x)
  1362. {
  1363. SWAP_VERTEX(pv0,pv1,pvt);
  1364. }
  1365. if (pv0->y > pv1->y)
  1366. {
  1367. //
  1368. // must swap y
  1369. //
  1370. LONG ltemp = pv1->y;
  1371. pv1->y = pv0->y;
  1372. pv0->y = ltemp;
  1373. }
  1374. }
  1375. else
  1376. {
  1377. if (pv0->y > pv1->y)
  1378. {
  1379. SWAP_VERTEX(pv0,pv1,pvt);
  1380. }
  1381. if (pv0->x > pv1->x)
  1382. {
  1383. //
  1384. // must swap x
  1385. //
  1386. LONG ltemp = pv1->x;
  1387. pv1->x = pv0->x;
  1388. pv0->x = ltemp;
  1389. }
  1390. }
  1391. //
  1392. // gradient definition rectangle
  1393. //
  1394. grData.rclGradient.left = pv0->x >> 4;
  1395. grData.rclGradient.top = pv0->y >> 4;
  1396. grData.rclGradient.right = pv1->x >> 4;
  1397. grData.rclGradient.bottom = pv1->y >> 4;
  1398. LONG dxGrad = grData.rclGradient.right - grData.rclGradient.left;
  1399. LONG dyGrad = grData.rclGradient.bottom - grData.rclGradient.top;
  1400. //
  1401. // make sure this is not an empty rectangle
  1402. //
  1403. if ((dxGrad > 0) && (dyGrad > 0))
  1404. {
  1405. grData.ulMode = ulMode;
  1406. //
  1407. // calculate color gradients for x and y
  1408. //
  1409. grData.Red = pv0->Red << 8;
  1410. grData.Green = pv0->Green << 8;
  1411. grData.Blue = pv0->Blue << 8;
  1412. grData.Alpha = pv0->Alpha << 8;
  1413. if (ulMode & GRADIENT_FILL_RECT_H)
  1414. {
  1415. grData.dRdY = 0;
  1416. grData.dGdY = 0;
  1417. grData.dBdY = 0;
  1418. grData.dAdY = 0;
  1419. LONG dRed = (pv1->Red << 8) - (pv0->Red << 8);
  1420. LONG dGreen = (pv1->Green << 8) - (pv0->Green << 8);
  1421. LONG dBlue = (pv1->Blue << 8) - (pv0->Blue << 8);
  1422. LONG dAlpha = (pv1->Alpha << 8) - (pv0->Alpha << 8);
  1423. grData.dRdX = dRed / dxGrad;
  1424. grData.dGdX = dGreen / dxGrad;
  1425. grData.dBdX = dBlue / dxGrad;
  1426. grData.dAdX = dAlpha / dxGrad;
  1427. }
  1428. else
  1429. {
  1430. grData.dRdX = 0;
  1431. grData.dGdX = 0;
  1432. grData.dBdX = 0;
  1433. grData.dAdX = 0;
  1434. LONG dRed = (pv1->Red << 8) - (pv0->Red << 8);
  1435. LONG dGreen = (pv1->Green << 8) - (pv0->Green << 8);
  1436. LONG dBlue = (pv1->Blue << 8) - (pv0->Blue << 8);
  1437. LONG dAlpha = (pv1->Alpha << 8) - (pv0->Alpha << 8);
  1438. grData.dRdY = dRed / dyGrad;
  1439. grData.dGdY = dGreen / dyGrad;
  1440. grData.dBdY = dBlue / dyGrad;
  1441. grData.dAdY = dAlpha / dyGrad;
  1442. }
  1443. //
  1444. // calculate common offsets
  1445. //
  1446. if (bCalcGradientRectOffsets(&grData))
  1447. {
  1448. //
  1449. // call specific drawing routine if output
  1450. // not totally clipped
  1451. //
  1452. (*pfnGradRect)(pDibInfo,&grData);
  1453. }
  1454. }
  1455. }
  1456. }
  1457. SetMapMode(hdc,OldMode);
  1458. return(bStatus);
  1459. }
  1460. #endif
  1461.