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.

1865 lines
52 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 cxBytes,
  21. ULONG ulPat
  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. * DefaultSaturationTable
  87. *
  88. * map to default colors (0,128,255) (does not use "magic" colors)
  89. *
  90. * IdentitySaturationTable
  91. *
  92. * prevent overflow
  93. *
  94. * History:
  95. *
  96. * 3/4/1997 Mark Enstrom [marke]
  97. *
  98. \**************************************************************************/
  99. BYTE HalftoneSaturationTable[256 + 128] = {
  100. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  101. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  102. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  103. 0, 0, 0, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
  104. 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
  105. 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
  106. 51, 51, 51, 51, 51, 51,102,102,102,102,102,102,102,102,102,102,
  107. 102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,
  108. 102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,
  109. 102,102,102,102,102,102,102,102,102,153,153,153,153,153,153,153,
  110. 153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
  111. 153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
  112. 153,153,153,153,153,153,153,153,153,153,153,153,204,204,204,204,
  113. 204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
  114. 204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
  115. 204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,255,
  116. 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
  117. 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
  118. 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
  119. 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
  120. 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
  121. 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
  122. 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
  123. 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255
  124. };
  125. BYTE DefaultSaturationTable[256 + 128] = {
  126. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  127. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  128. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  129. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  130. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  131. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  132. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  133. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  134. 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
  135. 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
  136. 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
  137. 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
  138. 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
  139. 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
  140. 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
  141. 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,255,
  142. 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
  143. 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
  144. 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
  145. 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
  146. 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
  147. 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
  148. 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
  149. 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255
  150. };
  151. BYTE Saturation16_5[64] = {
  152. 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
  153. 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,
  154. 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
  155. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
  156. };
  157. BYTE Saturation16_6[128] = {
  158. 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
  159. 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,
  160. 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,
  161. 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
  162. 0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
  163. 0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
  164. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  165. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
  166. };
  167. /**************************************************************************\
  168. * gulDither32 - 4-4 dither matrix
  169. *
  170. *
  171. * History:
  172. *
  173. * 1/31/1997 Mark Enstrom [marke]
  174. *
  175. \**************************************************************************/
  176. ULONG gulDither32[] =
  177. {
  178. 0x00000000,
  179. 0x00008000,
  180. 0x00002000,
  181. 0x0000a000,
  182. 0x0000c000,
  183. 0x00004000,
  184. 0x0000e000,
  185. 0x00006000,
  186. 0x00003000,
  187. 0x0000b000,
  188. 0x00001000,
  189. 0x00009000,
  190. 0x0000f000,
  191. 0x00007000,
  192. 0x0000d000,
  193. 0x00005000
  194. };
  195. //*******************************************************************************
  196. //
  197. //
  198. //
  199. //
  200. // Triangel drawing routines
  201. //
  202. //
  203. //
  204. //
  205. //
  206. //*******************************************************************************
  207. /******************************Public*Routine******************************\
  208. * vFillTriDIBUnreadable
  209. *
  210. * If a surface can't be read, draw triangle to a scan line, then call
  211. * BitBlt on each scan line. BitBlt is called to take advantage of
  212. * cached 32bpp to 8bpp lookup table (memphis)
  213. *
  214. * Arguments:
  215. *
  216. * pDibInfo - surface information
  217. * ptData - triangle information
  218. *
  219. * Return Value:
  220. *
  221. * none
  222. *
  223. * History:
  224. *
  225. * 11/21/1996 Mark Enstrom [marke]
  226. *
  227. \**************************************************************************/
  228. VOID
  229. vFillTriDIBUnreadable(
  230. PDIBINFO pDibInfo,
  231. PTRIANGLEDATA ptData
  232. )
  233. {
  234. LONG lDelta = pDibInfo->stride;
  235. LONG yScan = ptData->y0;
  236. LONG yScanBottom;
  237. LONG cxClip = ptData->rcl.right - ptData->rcl.left;
  238. PTRIEDGE pEdge = &ptData->TriEdge[0];
  239. LONGLONG lldRdX = ptData->lldRdX;
  240. LONGLONG lldGdX = ptData->lldGdX;
  241. LONGLONG lldBdX = ptData->lldBdX;
  242. COLOR_INTERP clrRed,clrGreen,clrBlue,clrAlpha;
  243. PBYTE pDst = NULL;
  244. HDC hdc32;
  245. PBYTE pDitherMatrix = gDitherMatrix16x16Halftone;
  246. PBYTE pSaturationTable = HalftoneSaturationTable;
  247. LONG yDitherOrg = ptData->ptDitherOrg.y;
  248. LONG xDitherOrg = ptData->ptDitherOrg.x;
  249. BOOL b1bpp = (pDibInfo->pbmi->bmiHeader.biBitCount == 1);
  250. //
  251. // WINBUG #365339 4-10-2001 jasonha Investigate using default dither table
  252. // Old Comment:
  253. // - should use default dither table for 8bpp w/o
  254. // halftone palette
  255. //
  256. if (
  257. (pDibInfo->pbmi->bmiHeader.biBitCount == 4) ||
  258. (b1bpp)
  259. )
  260. {
  261. pDitherMatrix = gDitherMatrix16x16Default;
  262. pSaturationTable = DefaultSaturationTable;
  263. }
  264. //
  265. // allocate temp storage
  266. //
  267. hdc32 = hdcAllocateScanLineDC(cxClip,(PULONG *)&pDst);
  268. if (hdc32 == NULL)
  269. {
  270. return;
  271. }
  272. yScanBottom = MIN(ptData->rcl.bottom,ptData->y1);
  273. while(yScan < yScanBottom)
  274. {
  275. PULONG pulDstX;
  276. LONG xScanRight;
  277. LONG xScanLeft;
  278. clrRed.ullColor = pEdge->llRed;
  279. clrGreen.ullColor = pEdge->llGreen;
  280. clrBlue.ullColor = pEdge->llBlue;
  281. PBYTE pDitherLevel = &pDitherMatrix[(16 * ((yScan+yDitherOrg) & DITHER_8_MASK_Y))];
  282. xScanLeft = MAX(pEdge->xLeft,ptData->rcl.left);
  283. xScanRight = MIN(pEdge->xRight,ptData->rcl.right);
  284. if (xScanLeft < xScanRight)
  285. {
  286. pulDstX = (PULONG)pDst + xScanLeft - ptData->rcl.left;
  287. LONG xScan = xScanLeft;
  288. //
  289. // skip span from left edge scan to left edge clip rect
  290. //
  291. LONG GradientLeft = ptData->rcl.left - pEdge->xLeft;
  292. if (GradientLeft > 0)
  293. {
  294. clrRed.ullColor += lldRdX * GradientLeft;
  295. clrGreen.ullColor += lldGdX * GradientLeft;
  296. clrBlue.ullColor += lldBdX * GradientLeft;
  297. }
  298. //
  299. // fill span within clipping boundary
  300. //
  301. while (xScan < xScanRight)
  302. {
  303. BYTE jDitherMatrix = *(pDitherLevel + ((xScan + xDitherOrg) & DITHER_8_MASK_X));
  304. ULONG iRed = clrRed.b[7];
  305. ULONG iGreen = clrGreen.b[7];
  306. ULONG iBlue = clrBlue.b[7];
  307. if (b1bpp)
  308. {
  309. jDitherMatrix *= 2;
  310. iRed = iRed + jDitherMatrix;
  311. if (iRed >= 255)
  312. {
  313. iRed = 255;
  314. }
  315. else
  316. {
  317. iRed = 0;
  318. }
  319. iGreen = iGreen + jDitherMatrix;
  320. if (iGreen >= 255)
  321. {
  322. iGreen = 255;
  323. }
  324. else
  325. {
  326. iGreen = 0;
  327. }
  328. iBlue = iBlue + jDitherMatrix;
  329. if (iBlue >= 255)
  330. {
  331. iBlue = 255;
  332. }
  333. else
  334. {
  335. iBlue = 0;
  336. }
  337. }
  338. else
  339. {
  340. iRed = pSaturationTable[iRed + jDitherMatrix];
  341. iGreen = pSaturationTable[iGreen + jDitherMatrix];
  342. iBlue = pSaturationTable[iBlue + jDitherMatrix];
  343. }
  344. *pulDstX = (iRed << 16) |
  345. (iGreen << 8) |
  346. (iBlue );
  347. pulDstX++;
  348. xScan++;
  349. clrRed.ullColor += lldRdX;
  350. clrGreen.ullColor += lldGdX;
  351. clrBlue.ullColor += lldBdX;
  352. }
  353. //
  354. // write span to device
  355. //
  356. BitBlt(pDibInfo->hdc,
  357. xScanLeft,
  358. yScan,
  359. xScanRight-xScanLeft,
  360. 1,
  361. hdc32,
  362. xScanLeft - ptData->rcl.left,
  363. 0,
  364. SRCCOPY);
  365. }
  366. pEdge++;
  367. yScan++;
  368. }
  369. if (hdc32 != NULL)
  370. {
  371. vFreeScanLineDC(hdc32);
  372. }
  373. }
  374. /******************************Public*Routine******************************\
  375. * vFillTriDIB32BGRA
  376. *
  377. *
  378. * Arguments:
  379. *
  380. * pDibInfo - surface information
  381. * ptData - triangle information
  382. *
  383. * Return Value:
  384. *
  385. *
  386. *
  387. * History:
  388. *
  389. * 11/21/1996 Mark Enstrom [marke]
  390. *
  391. \**************************************************************************/
  392. VOID
  393. vFillTriDIB32BGRA(
  394. PDIBINFO pDibInfo,
  395. PTRIANGLEDATA ptData
  396. )
  397. {
  398. LONG lDelta = pDibInfo->stride;
  399. LONG yScan = ptData->y0;
  400. LONG yScanBottom;
  401. PBYTE pDst = (PBYTE)pDibInfo->pvBase + lDelta * yScan;
  402. PTRIEDGE pEdge = &ptData->TriEdge[0];
  403. LONGLONG lldRdX = ptData->lldRdX;
  404. LONGLONG lldGdX = ptData->lldGdX;
  405. LONGLONG lldBdX = ptData->lldBdX;
  406. LONGLONG lldAdX = ptData->lldAdX;
  407. COLOR_INTERP clrRed,clrGreen,clrBlue,clrAlpha;
  408. yScanBottom = MIN(ptData->rcl.bottom,ptData->y1);
  409. while(yScan < yScanBottom)
  410. {
  411. PULONG pulDstX;
  412. PULONG pulDstScanRight,pulDstScanLeft;
  413. clrRed.ullColor = pEdge->llRed;
  414. clrGreen.ullColor = pEdge->llGreen;
  415. clrBlue.ullColor = pEdge->llBlue;
  416. clrAlpha.ullColor = pEdge->llAlpha;
  417. LONG xScanLeft = MAX(pEdge->xLeft,ptData->rcl.left);
  418. LONG xScanRight = MIN(pEdge->xRight,ptData->rcl.right);
  419. if (xScanLeft < xScanRight)
  420. {
  421. pulDstX = (PULONG)pDst + xScanLeft;
  422. pulDstScanRight = (PULONG)pDst + xScanRight;
  423. //
  424. // skip pixels from left edge to left clip, while
  425. // incrementing gradient
  426. //
  427. LONG GradientLeft = ptData->rcl.left - pEdge->xLeft;
  428. if (GradientLeft > 0)
  429. {
  430. clrRed.ullColor += lldRdX * GradientLeft;
  431. clrGreen.ullColor += lldGdX * GradientLeft;
  432. clrBlue.ullColor += lldBdX * GradientLeft;
  433. clrAlpha.ullColor += lldAdX * GradientLeft;
  434. }
  435. //
  436. // fill span
  437. //
  438. while (pulDstX < pulDstScanRight)
  439. {
  440. *pulDstX = (clrAlpha.b[7] << 24) |
  441. (clrRed.b[7] << 16) |
  442. (clrGreen.b[7] << 8) |
  443. (clrBlue.b[7]);
  444. pulDstX++;
  445. clrRed.ullColor += lldRdX;
  446. clrGreen.ullColor += lldGdX;
  447. clrBlue.ullColor += lldBdX;
  448. clrAlpha.ullColor += lldAdX;
  449. }
  450. }
  451. pDst += lDelta;
  452. pEdge++;
  453. yScan++;
  454. }
  455. }
  456. /******************************Public*Routine******************************\
  457. * vFillTriDIB32RGB
  458. *
  459. *
  460. * Arguments:
  461. *
  462. * pDibInfo - surface information
  463. * ptData - triangle information
  464. *
  465. * Return Value:
  466. *
  467. *
  468. *
  469. * History:
  470. *
  471. * 11/21/1996 Mark Enstrom [marke]
  472. *
  473. \**************************************************************************/
  474. VOID
  475. vFillTriDIB32RGB(
  476. PDIBINFO pDibInfo,
  477. PTRIANGLEDATA ptData
  478. )
  479. {
  480. LONG lDelta = pDibInfo->stride;
  481. LONG yScan = ptData->y0;
  482. LONG yScanBottom;
  483. PBYTE pDst = (PBYTE)pDibInfo->pvBase + lDelta * yScan;
  484. PTRIEDGE pEdge = &ptData->TriEdge[0];
  485. LONGLONG lldRdX = ptData->lldRdX;
  486. LONGLONG lldGdX = ptData->lldGdX;
  487. LONGLONG lldBdX = ptData->lldBdX;
  488. COLOR_INTERP clrRed,clrGreen,clrBlue;
  489. yScanBottom = MIN(ptData->rcl.bottom,ptData->y1);
  490. while(yScan < yScanBottom)
  491. {
  492. PULONG pulDstX;
  493. PULONG pulDstScanRight,pulDstScanLeft;
  494. clrRed.ullColor = pEdge->llRed;
  495. clrGreen.ullColor = pEdge->llGreen;
  496. clrBlue.ullColor = pEdge->llBlue;
  497. LONG xScanLeft = MAX(pEdge->xLeft,ptData->rcl.left);
  498. LONG xScanRight = MIN(pEdge->xRight,ptData->rcl.right);
  499. if (xScanLeft < xScanRight)
  500. {
  501. pulDstX = (PULONG)pDst + xScanLeft;
  502. pulDstScanRight = (PULONG)pDst + xScanRight;
  503. //
  504. // skip pixels from left edge to left clip, while
  505. // incrementing gradient
  506. //
  507. LONG GradientLeft = ptData->rcl.left - pEdge->xLeft;
  508. if (GradientLeft > 0)
  509. {
  510. clrRed.ullColor += lldRdX * GradientLeft;
  511. clrGreen.ullColor += lldGdX * GradientLeft;
  512. clrBlue.ullColor += lldBdX * GradientLeft;
  513. }
  514. //
  515. // fill span
  516. //
  517. while (pulDstX < pulDstScanRight)
  518. {
  519. *pulDstX =
  520. (clrBlue.b[7] << 16) |
  521. (clrGreen.b[7] << 8) |
  522. (clrRed.b[7]);
  523. pulDstX++;
  524. clrRed.ullColor += lldRdX;
  525. clrGreen.ullColor += lldGdX;
  526. clrBlue.ullColor += lldBdX;
  527. }
  528. }
  529. pDst += lDelta;
  530. pEdge++;
  531. yScan++;
  532. }
  533. }
  534. /******************************Public*Routine******************************\
  535. * vFillTriDIB24RGB
  536. *
  537. *
  538. * Arguments:
  539. *
  540. * pDibInfo - surface information
  541. * ptData - triangle information
  542. *
  543. * Return Value:
  544. *
  545. *
  546. *
  547. * History:
  548. *
  549. * 11/21/1996 Mark Enstrom [marke]
  550. *
  551. \**************************************************************************/
  552. VOID
  553. vFillTriDIB24RGB(
  554. PDIBINFO pDibInfo,
  555. PTRIANGLEDATA ptData
  556. )
  557. {
  558. LONG lDelta = pDibInfo->stride;
  559. LONG yScan = ptData->y0;
  560. LONG yScanBottom;
  561. PBYTE pDst = (PBYTE)pDibInfo->pvBase + lDelta * yScan;
  562. PTRIEDGE pEdge = &ptData->TriEdge[0];
  563. LONGLONG lldRdX = ptData->lldRdX;
  564. LONGLONG lldGdX = ptData->lldGdX;
  565. LONGLONG lldBdX = ptData->lldBdX;
  566. COLOR_INTERP clrRed,clrGreen,clrBlue;
  567. yScanBottom = MIN(ptData->rcl.bottom,ptData->y1);
  568. while(yScan < yScanBottom)
  569. {
  570. PBYTE pDstX;
  571. PBYTE pDstScanRight;
  572. clrRed.ullColor = pEdge->llRed;
  573. clrGreen.ullColor = pEdge->llGreen;
  574. clrBlue.ullColor = pEdge->llBlue;
  575. LONG xScanLeft = MAX(pEdge->xLeft,ptData->rcl.left);
  576. LONG xScanRight = MIN(pEdge->xRight,ptData->rcl.right);
  577. if (xScanLeft < xScanRight)
  578. {
  579. pDstX = pDst + 3 * xScanLeft;
  580. pDstScanRight = pDst + 3 * xScanRight;
  581. //
  582. // skip pixels from left edge to left clip, while
  583. // incrementing gradient
  584. //
  585. LONG GradientLeft = ptData->rcl.left - pEdge->xLeft;
  586. if (GradientLeft > 0)
  587. {
  588. clrRed.ullColor += lldRdX * GradientLeft;
  589. clrGreen.ullColor += lldGdX * GradientLeft;
  590. clrBlue.ullColor += lldBdX * GradientLeft;
  591. }
  592. while (pDstX < pDstScanRight)
  593. {
  594. *pDstX = clrBlue.b[7];
  595. *(pDstX+1) = clrGreen.b[7];
  596. *(pDstX+2) = clrRed.b[7];
  597. clrRed.ullColor += lldRdX;
  598. clrGreen.ullColor += lldGdX;
  599. clrBlue.ullColor += lldBdX;
  600. pDstX+=3;
  601. }
  602. }
  603. pDst += lDelta;
  604. pEdge++;
  605. yScan++;
  606. }
  607. }
  608. /******************************Public*Routine******************************\
  609. * vFillDIB16_565
  610. *
  611. *
  612. * Arguments:
  613. *
  614. * pDibInfo - surface information
  615. * ptData - triangle information
  616. *
  617. * Return Value:
  618. *
  619. *
  620. *
  621. * History:
  622. *
  623. * 11/21/1996 Mark Enstrom [marke]
  624. *
  625. \**************************************************************************/
  626. VOID
  627. vFillTriDIB16_565(
  628. PDIBINFO pDibInfo,
  629. PTRIANGLEDATA ptData
  630. )
  631. {
  632. LONG lDelta = pDibInfo->stride;
  633. LONG yScan = ptData->y0;
  634. LONG yScanBottom;
  635. PBYTE pDst = (PBYTE)pDibInfo->pvBase + lDelta * yScan;
  636. PTRIEDGE pEdge = &ptData->TriEdge[0];
  637. LONGLONG lldRdX = ptData->lldRdX;
  638. LONGLONG lldGdX = ptData->lldGdX;
  639. LONGLONG lldBdX = ptData->lldBdX;
  640. COLOR_INTERP clrRed,clrGreen,clrBlue;
  641. yScanBottom = MIN(ptData->rcl.bottom,ptData->y1);
  642. LONG yDitherOrg = ptData->ptDitherOrg.y;
  643. LONG xDitherOrg = ptData->ptDitherOrg.x;
  644. while(yScan < yScanBottom)
  645. {
  646. PUSHORT pusDstX,pusDstScanRight;
  647. PULONG pulDither = &gulDither32[0] + 4 * ((yScan+yDitherOrg) & 3);
  648. clrRed.ullColor = pEdge->llRed;
  649. clrGreen.ullColor = pEdge->llGreen;
  650. clrBlue.ullColor = pEdge->llBlue;
  651. LONG xScanRight = MIN(pEdge->xRight,ptData->rcl.right);
  652. LONG xScanLeft = MAX(pEdge->xLeft,ptData->rcl.left);
  653. if (xScanLeft < xScanRight)
  654. {
  655. pusDstX = (PUSHORT)pDst + xScanLeft;
  656. pusDstScanRight = (PUSHORT)pDst + xScanRight;
  657. //
  658. // skip pixels from left edge to left clip, while
  659. // incrementing gradient
  660. //
  661. LONG GradientLeft = ptData->rcl.left - pEdge->xLeft;
  662. if (GradientLeft > 0)
  663. {
  664. clrRed.ullColor += lldRdX * GradientLeft;
  665. clrGreen.ullColor += lldGdX * GradientLeft;
  666. clrBlue.ullColor += lldBdX * GradientLeft;
  667. }
  668. //
  669. // Gradient fill scan line with dither
  670. //
  671. while (pusDstX < pusDstScanRight)
  672. {
  673. ULONG ulDither = pulDither[(xScanLeft + xDitherOrg) & 3];
  674. ULONG iRed = Saturation16_5[((clrRed.ul[1] >> (8+3)) + ulDither) >> 16];
  675. ULONG iGreen = Saturation16_6[((clrGreen.ul[1] >> (8+2)) + ulDither) >> 16];
  676. ULONG iBlue = Saturation16_5[((clrBlue.ul[1] >> (8+3)) + ulDither) >> 16];
  677. *pusDstX = rgb565(iRed,iGreen,iBlue);
  678. xScanLeft++;
  679. pusDstX++;
  680. clrRed.ullColor += lldRdX;
  681. clrGreen.ullColor += lldGdX;
  682. clrBlue.ullColor += lldBdX;
  683. }
  684. }
  685. pDst += lDelta;
  686. pEdge++;
  687. yScan++;
  688. }
  689. }
  690. /******************************Public*Routine******************************\
  691. * vFillTriDIB16_555
  692. *
  693. *
  694. * Arguments:
  695. *
  696. * pDibInfo - surface information
  697. * ptData - triangle information
  698. *
  699. * Return Value:
  700. *
  701. *
  702. *
  703. * History:
  704. *
  705. * 11/21/1996 Mark Enstrom [marke]
  706. *
  707. \**************************************************************************/
  708. VOID
  709. vFillTriDIB16_555(
  710. PDIBINFO pDibInfo,
  711. PTRIANGLEDATA ptData
  712. )
  713. {
  714. LONG lDelta = pDibInfo->stride;
  715. LONG yScan = ptData->y0;
  716. LONG yScanBottom;
  717. PBYTE pDst = (PBYTE)pDibInfo->pvBase + lDelta * yScan;
  718. PTRIEDGE pEdge = &ptData->TriEdge[0];
  719. LONGLONG lldRdX = ptData->lldRdX;
  720. LONGLONG lldGdX = ptData->lldGdX;
  721. LONGLONG lldBdX = ptData->lldBdX;
  722. COLOR_INTERP clrRed,clrGreen,clrBlue;
  723. yScanBottom = MIN(ptData->rcl.bottom,ptData->y1);
  724. LONG yDitherOrg = ptData->ptDitherOrg.y;
  725. LONG xDitherOrg = ptData->ptDitherOrg.x;
  726. while(yScan < yScanBottom)
  727. {
  728. PUSHORT pusDstX,pusDstScanRight;
  729. PULONG pulDither = &gulDither32[0] + 4 * ((yScan+yDitherOrg) & 3);
  730. clrRed.ullColor = pEdge->llRed;
  731. clrGreen.ullColor = pEdge->llGreen;
  732. clrBlue.ullColor = pEdge->llBlue;
  733. LONG xScanRight = MIN(pEdge->xRight,ptData->rcl.right);
  734. LONG xScanLeft = MAX(pEdge->xLeft,ptData->rcl.left);
  735. if (xScanLeft < xScanRight)
  736. {
  737. pusDstX = (PUSHORT)pDst + xScanLeft;
  738. pusDstScanRight = (PUSHORT)pDst + xScanRight;
  739. //
  740. // skip pixels from left edge to left clip, while
  741. // incrementing gradient
  742. //
  743. LONG GradientLeft = ptData->rcl.left - pEdge->xLeft;
  744. if (GradientLeft > 0)
  745. {
  746. clrRed.ullColor += lldRdX * GradientLeft;
  747. clrGreen.ullColor += lldGdX * GradientLeft;
  748. clrBlue.ullColor += lldBdX * GradientLeft;
  749. }
  750. //
  751. // Gradient fill scan line with dither
  752. //
  753. while (pusDstX < pusDstScanRight)
  754. {
  755. ULONG ulDither = pulDither[(xScanLeft + xDitherOrg) & 3];
  756. ULONG iRed = Saturation16_5[((clrRed.ul[1] >> (8+3)) + ulDither) >> 16];
  757. ULONG iGreen = Saturation16_5[((clrGreen.ul[1] >> (8+3)) + ulDither) >> 16];
  758. ULONG iBlue = Saturation16_5[((clrBlue.ul[1] >> (8+3)) + ulDither) >> 16];
  759. *pusDstX = rgb555(iRed,iGreen,iBlue);
  760. xScanLeft++;
  761. pusDstX++;
  762. clrRed.ullColor += lldRdX;
  763. clrGreen.ullColor += lldGdX;
  764. clrBlue.ullColor += lldBdX;
  765. }
  766. }
  767. pDst += lDelta;
  768. pEdge++;
  769. yScan++;
  770. }
  771. }
  772. //*******************************************************************************
  773. //
  774. //
  775. //
  776. //
  777. // Rectangle drawing routines
  778. //
  779. //
  780. //
  781. //
  782. //
  783. //*******************************************************************************
  784. /******************************Public*Routine******************************\
  785. * vFillGRectDIB32BGRA
  786. *
  787. *
  788. * Arguments:
  789. *
  790. *
  791. *
  792. * Return Value:
  793. *
  794. *
  795. *
  796. * History:
  797. *
  798. * 11/21/1996 Mark Enstrom [marke]
  799. *
  800. \**************************************************************************/
  801. VOID
  802. vFillGRectDIB32BGRA(
  803. PDIBINFO pDibInfo,
  804. PGRADIENTRECTDATA pgData
  805. )
  806. {
  807. LONG lDelta = pDibInfo->stride;
  808. LONG cyClip = pgData->szDraw.cy;
  809. //
  810. // fill rect with gradient fill. if this is horizontal mode then
  811. // draw one scan line and replicate in v, if this is vertical mode then
  812. // draw one vertical stripe and replicate in h
  813. //
  814. COLOR_INTERP clrR,clrG,clrB,clrA;
  815. if (pgData->ulMode == GRADIENT_FILL_RECT_H)
  816. {
  817. PBYTE pjDst = (PBYTE)pDibInfo->pvBase + lDelta * pgData->ptDraw.y;
  818. PULONG pulBuffer = (PULONG)LOCALALLOC(4 * pgData->szDraw.cx);
  819. if (pulBuffer)
  820. {
  821. clrR.ullColor = pgData->llRed;
  822. clrG.ullColor = pgData->llGreen;
  823. clrB.ullColor = pgData->llBlue;
  824. clrA.ullColor = pgData->llAlpha;
  825. LONGLONG lldRdX = pgData->lldRdX;
  826. LONGLONG lldGdX = pgData->lldGdX;
  827. LONGLONG lldBdX = pgData->lldBdX;
  828. LONGLONG lldAdX = pgData->lldAdX;
  829. //
  830. // adjust gradient fill for clipped portion
  831. //
  832. if (pgData->xScanAdjust > 0)
  833. {
  834. clrR.ullColor += lldRdX * (pgData->xScanAdjust);
  835. clrG.ullColor += lldGdX * (pgData->xScanAdjust);
  836. clrB.ullColor += lldBdX * (pgData->xScanAdjust);
  837. clrA.ullColor += lldAdX * (pgData->xScanAdjust);
  838. }
  839. //
  840. // draw 1 scan line
  841. //
  842. PULONG pulDstX = pulBuffer;
  843. PULONG pulEndX = pulDstX + pgData->szDraw.cx;
  844. while (pulDstX != pulEndX)
  845. {
  846. *pulDstX = (ULONG)(((clrA.b[6]) << 24) |
  847. ((clrR.b[6]) << 16) |
  848. ((clrG.b[6]) << 8) |
  849. ((clrB.b[6])));
  850. clrR.ullColor += lldRdX;
  851. clrG.ullColor += lldGdX;
  852. clrB.ullColor += lldBdX;
  853. clrA.ullColor += lldAdX;
  854. pulDstX++;
  855. }
  856. //
  857. // replicate
  858. //
  859. PULONG pulDstY = (PULONG)pjDst + pgData->ptDraw.x;
  860. PULONG pulEndY = (PULONG)((PBYTE)pulDstY + lDelta * cyClip);
  861. while (pulDstY != pulEndY)
  862. {
  863. memcpy(pulDstY,pulBuffer,4*pgData->szDraw.cx);
  864. pulDstY = (PULONG)((PBYTE)pulDstY + lDelta);
  865. }
  866. LOCALFREE(pulBuffer);
  867. }
  868. }
  869. else
  870. {
  871. clrR.ullColor = pgData->llRed;
  872. clrG.ullColor = pgData->llGreen;
  873. clrB.ullColor = pgData->llBlue;
  874. clrA.ullColor = pgData->llAlpha;
  875. LONGLONG lldRdY = pgData->lldRdY;
  876. LONGLONG lldGdY = pgData->lldGdY;
  877. LONGLONG lldBdY = pgData->lldBdY;
  878. LONGLONG lldAdY = pgData->lldAdY;
  879. //
  880. // vertical gradient.
  881. // replicate each x value accross whole scan line
  882. //
  883. if (pgData->yScanAdjust > 0)
  884. {
  885. clrR.ullColor += lldRdY * (pgData->yScanAdjust);
  886. clrG.ullColor += lldGdY * (pgData->yScanAdjust);
  887. clrB.ullColor += lldBdY * (pgData->yScanAdjust);
  888. clrA.ullColor += lldAdY * (pgData->yScanAdjust);
  889. }
  890. PBYTE pDst = (PBYTE)pDibInfo->pvBase + lDelta * pgData->ptDraw.y;
  891. pDst = pDst + 4 * pgData->ptDraw.x;
  892. while (cyClip--)
  893. {
  894. ULONG ul = (ULONG)(((clrA.b[6]) << 24) |
  895. ((clrR.b[6]) << 16) |
  896. ((clrG.b[6]) << 8) |
  897. ((clrB.b[6])));
  898. ImgFillMemoryULONG(pDst,pgData->szDraw.cx*4,ul);
  899. clrR.ullColor += lldRdY;
  900. clrG.ullColor += lldGdY;
  901. clrB.ullColor += lldBdY;
  902. clrA.ullColor += lldAdY;
  903. pDst += lDelta;
  904. }
  905. }
  906. }
  907. /******************************Public*Routine******************************\
  908. * vFillGRectDIB32RGB
  909. *
  910. *
  911. * Arguments:
  912. *
  913. *
  914. *
  915. * Return Value:
  916. *
  917. *
  918. *
  919. * History:
  920. *
  921. * 11/21/1996 Mark Enstrom [marke]
  922. *
  923. \**************************************************************************/
  924. VOID
  925. vFillGRectDIB32RGB(
  926. PDIBINFO pDibInfo,
  927. PGRADIENTRECTDATA pgData
  928. )
  929. {
  930. LONG lDelta = pDibInfo->stride;
  931. LONG cyClip = pgData->szDraw.cy;
  932. //
  933. // fill rect with gradient fill. if this is horizontal mode then
  934. // draw one scan line and replicate in v, if this is vertical mode then
  935. // draw one vertical stripe and replicate in h
  936. //
  937. COLOR_INTERP clrR,clrG,clrB,clrA;
  938. clrR.ullColor = pgData->llRed;
  939. clrG.ullColor = pgData->llGreen;
  940. clrB.ullColor = pgData->llBlue;
  941. if (pgData->ulMode == GRADIENT_FILL_RECT_H)
  942. {
  943. PBYTE pjDst = (PBYTE)pDibInfo->pvBase + lDelta * pgData->ptDraw.y;
  944. PULONG pulBuffer = (PULONG)LOCALALLOC(4 * pgData->szDraw.cx);
  945. if (pulBuffer)
  946. {
  947. LONGLONG lldRed = pgData->lldRdX;
  948. LONGLONG lldGreen = pgData->lldGdX;
  949. LONGLONG lldBlue = pgData->lldBdX;
  950. //
  951. // adjust gradient fill for clipped portion
  952. //
  953. if (pgData->xScanAdjust > 0)
  954. {
  955. clrR.ullColor += lldRed * (pgData->xScanAdjust);
  956. clrG.ullColor += lldGreen * (pgData->xScanAdjust);
  957. clrB.ullColor += lldBlue * (pgData->xScanAdjust);
  958. }
  959. //
  960. // draw 1 scan line to temp buffer
  961. //
  962. PULONG pulDstX = pulBuffer;
  963. PULONG pulEndX = pulDstX + pgData->szDraw.cx;
  964. while (pulDstX != pulEndX)
  965. {
  966. *pulDstX = (ULONG)(
  967. ((clrR.b[6])) |
  968. ((clrG.b[6]) << 8) |
  969. ((clrB.b[6]) << 16));
  970. clrR.ullColor += lldRed;
  971. clrG.ullColor += lldGreen;
  972. clrB.ullColor += lldBlue;
  973. pulDstX++;
  974. }
  975. //
  976. // replicate
  977. //
  978. PULONG pulDstY = (PULONG)pjDst + pgData->ptDraw.x;
  979. PULONG pulEndY = (PULONG)((PBYTE)pulDstY + lDelta * cyClip);
  980. while (pulDstY != pulEndY)
  981. {
  982. memcpy(pulDstY,pulBuffer,4*pgData->szDraw.cx);
  983. pulDstY = (PULONG)((PBYTE)pulDstY + lDelta);
  984. }
  985. LOCALFREE(pulBuffer);
  986. }
  987. }
  988. else
  989. {
  990. LONGLONG lldRed = pgData->lldRdY;
  991. LONGLONG lldGreen = pgData->lldGdY;
  992. LONGLONG lldBlue = pgData->lldBdY;
  993. //
  994. // vertical gradient.
  995. // replicate each x value accross whole scan line
  996. //
  997. if (pgData->yScanAdjust > 0)
  998. {
  999. clrR.ullColor += lldRed * (pgData->yScanAdjust);
  1000. clrG.ullColor += lldGreen * (pgData->yScanAdjust);
  1001. clrB.ullColor += lldBlue * (pgData->yScanAdjust);
  1002. }
  1003. PBYTE pDst = (PBYTE)pDibInfo->pvBase + lDelta * pgData->ptDraw.y;
  1004. pDst = pDst + 4 * pgData->ptDraw.x;
  1005. while (cyClip--)
  1006. {
  1007. ULONG ul = (ULONG)(
  1008. ((clrR.b[6]) ) |
  1009. ((clrG.b[6]) << 8) |
  1010. ((clrB.b[6]) << 16));
  1011. ImgFillMemoryULONG(pDst,pgData->szDraw.cx*4,ul);
  1012. clrR.ullColor += lldRed;
  1013. clrG.ullColor += lldGreen;
  1014. clrB.ullColor += lldBlue;
  1015. pDst += lDelta;
  1016. }
  1017. }
  1018. }
  1019. /******************************Public*Routine******************************\
  1020. * vFillGRectDIB24RGB
  1021. *
  1022. *
  1023. * Arguments:
  1024. *
  1025. *
  1026. *
  1027. * Return Value:
  1028. *
  1029. *
  1030. *
  1031. * History:
  1032. *
  1033. * 11/21/1996 Mark Enstrom [marke]
  1034. *
  1035. \**************************************************************************/
  1036. VOID
  1037. vFillGRectDIB24RGB(
  1038. PDIBINFO pDibInfo,
  1039. PGRADIENTRECTDATA pgData
  1040. )
  1041. {
  1042. LONG lDelta = pDibInfo->stride;
  1043. LONG cyClip = pgData->szDraw.cy;
  1044. PBYTE pDst = (PBYTE)pDibInfo->pvBase + lDelta * pgData->ptDraw.y;
  1045. COLOR_INTERP clrR,clrG,clrB,clrAlpha;
  1046. clrR.ullColor = pgData->llRed;
  1047. clrG.ullColor = pgData->llGreen;
  1048. clrB.ullColor = pgData->llBlue;
  1049. //
  1050. // fill rect with gradient fill. if this is horizontal mode then
  1051. // draw one scan line and replicate in v, if this is vertical mode then
  1052. // draw one vertical stripe and replicate in h
  1053. //
  1054. if (pgData->ulMode == GRADIENT_FILL_RECT_H)
  1055. {
  1056. LONGLONG lldRed = pgData->lldRdX;
  1057. LONGLONG lldGreen = pgData->lldGdX;
  1058. LONGLONG lldBlue = pgData->lldBdX;
  1059. //
  1060. // adjust gradient fill for clipped portion
  1061. //
  1062. if (pgData->xScanAdjust > 0)
  1063. {
  1064. clrR.ullColor += lldRed * (pgData->xScanAdjust);
  1065. clrG.ullColor += lldGreen * (pgData->xScanAdjust);
  1066. clrB.ullColor += lldBlue * (pgData->xScanAdjust);
  1067. }
  1068. PBYTE pBuffer = (PBYTE)LOCALALLOC(3 * pgData->szDraw.cx);
  1069. if (pBuffer)
  1070. {
  1071. if (pBuffer)
  1072. {
  1073. PBYTE pDstX = pBuffer;
  1074. PBYTE pLast = pDstX + 3 * pgData->szDraw.cx;
  1075. while (pDstX != pLast)
  1076. {
  1077. *pDstX = (clrB.b[6]);
  1078. *(pDstX+1) = (clrG.b[6]);
  1079. *(pDstX+2) = (clrR.b[6]);
  1080. clrR.ullColor += lldRed;
  1081. clrG.ullColor += lldGreen;
  1082. clrB.ullColor += lldBlue;
  1083. pDstX+=3;
  1084. }
  1085. //
  1086. // Replicate the scan line. It would be much better to write the scan line
  1087. // out to a memory buffer for drawing to a device surface
  1088. //
  1089. PBYTE pDst = (PBYTE)pDibInfo->pvBase +
  1090. lDelta * pgData->ptDraw.y +
  1091. 3 * pgData->ptDraw.x;
  1092. while (cyClip--)
  1093. {
  1094. memcpy(pDst,pBuffer,3*pgData->szDraw.cx);
  1095. pDst += lDelta;
  1096. }
  1097. LOCALFREE(pBuffer);
  1098. }
  1099. }
  1100. }
  1101. else
  1102. {
  1103. //
  1104. // vertical gradient.
  1105. // replicate each x value accross whole scan line
  1106. //
  1107. PBYTE pDst = (PBYTE)pDibInfo->pvBase + lDelta * pgData->ptDraw.y;
  1108. LONGLONG lldRed = pgData->lldRdY;
  1109. LONGLONG lldGreen = pgData->lldGdY;
  1110. LONGLONG lldBlue = pgData->lldBdY;
  1111. //
  1112. // vertical gradient.
  1113. // replicate each x value accross whole scan line
  1114. //
  1115. if (pgData->yScanAdjust > 0)
  1116. {
  1117. clrR.ullColor += lldRed * (pgData->yScanAdjust);
  1118. clrG.ullColor += lldGreen * (pgData->yScanAdjust);
  1119. clrB.ullColor += lldBlue * (pgData->yScanAdjust);
  1120. }
  1121. pDst = pDst + 3 * pgData->ptDraw.x;
  1122. while (cyClip--)
  1123. {
  1124. //
  1125. // fill scan line with solid color
  1126. //
  1127. PBYTE pTemp = pDst;
  1128. PBYTE pEnd = pDst + 3 * pgData->szDraw.cx;
  1129. while (pTemp != pEnd)
  1130. {
  1131. *pTemp = clrB.b[6];
  1132. *(pTemp+1) = clrG.b[6];
  1133. *(pTemp+2) = clrR.b[6];
  1134. pTemp+=3;
  1135. }
  1136. //
  1137. // increment colors for next scan line
  1138. //
  1139. clrR.ullColor += lldRed;
  1140. clrG.ullColor += lldGreen;
  1141. clrB.ullColor += lldBlue;
  1142. //
  1143. // inc pointer to next scan line
  1144. //
  1145. pDst += lDelta;
  1146. }
  1147. }
  1148. }
  1149. /******************************Public*Routine******************************\
  1150. * vFillGRectDIB16_565
  1151. *
  1152. *
  1153. * Arguments:
  1154. *
  1155. *
  1156. *
  1157. * Return Value:
  1158. *
  1159. *
  1160. *
  1161. * History:
  1162. *
  1163. * 11/21/1996 Mark Enstrom [marke]
  1164. *
  1165. \**************************************************************************/
  1166. VOID
  1167. vFillGRectDIB16_565(
  1168. PDIBINFO pDibInfo,
  1169. PGRADIENTRECTDATA pgData
  1170. )
  1171. {
  1172. LONG lDelta = pDibInfo->stride;
  1173. LONG cxClip = pgData->szDraw.cx;
  1174. LONG yScan = pgData->ptDraw.y;
  1175. LONG yScanBottom = yScan + pgData->szDraw.cy;
  1176. PBYTE pDst = (PBYTE)pDibInfo->pvBase + lDelta * pgData->ptDraw.y;
  1177. LONGLONG lldxRed = pgData->lldRdX;
  1178. LONGLONG lldxGreen = pgData->lldGdX;
  1179. LONGLONG lldxBlue = pgData->lldBdX;
  1180. LONGLONG lldyRed = pgData->lldRdY;
  1181. LONGLONG lldyGreen = pgData->lldGdY;
  1182. LONGLONG lldyBlue = pgData->lldBdY;
  1183. //
  1184. // lleRed,Green,Blue keep track of color gradient
  1185. // in y. This may be repeated each scan line for different
  1186. // dither values. PERF could allocate temp scan line
  1187. // buffer, run gradient 1 time and dither from this source
  1188. //
  1189. ULONGLONG lleRed;
  1190. ULONGLONG lleGreen;
  1191. ULONGLONG lleBlue;
  1192. lleRed = pgData->llRed;
  1193. lleGreen = pgData->llGreen;
  1194. lleBlue = pgData->llBlue;
  1195. PULONG pulDither;
  1196. //
  1197. // skip down to left edge
  1198. //
  1199. if (pgData->yScanAdjust)
  1200. {
  1201. lleRed += lldyRed * (pgData->yScanAdjust);
  1202. lleGreen += lldyGreen * (pgData->yScanAdjust);
  1203. lleBlue += lldyBlue * (pgData->yScanAdjust);
  1204. }
  1205. LONG yDitherOrg = pgData->ptDitherOrg.y;
  1206. LONG xDitherOrg = pgData->ptDitherOrg.x;
  1207. while(yScan < yScanBottom)
  1208. {
  1209. PUSHORT pusDstX;
  1210. PUSHORT pusDstScanRight,pusDstScanLeft;
  1211. LONG xScan;
  1212. COLOR_INTERP clrR,clrG,clrB,clrAlpha;
  1213. pulDither = &gulDither32[0] + 4 * ((yScan + yDitherOrg) & 3);
  1214. clrR.ullColor = lleRed;
  1215. clrG.ullColor = lleGreen;
  1216. clrB.ullColor = lleBlue;
  1217. if (pgData->xScanAdjust)
  1218. {
  1219. clrR.ullColor += lldxRed * (pgData->xScanAdjust);
  1220. clrG.ullColor += lldxGreen * (pgData->xScanAdjust);
  1221. clrB.ullColor += lldxBlue * (pgData->xScanAdjust);
  1222. }
  1223. xScan = pgData->ptDraw.x + xDitherOrg;
  1224. pusDstX = (PUSHORT)pDst + pgData->ptDraw.x;
  1225. pusDstScanRight = pusDstX + pgData->szDraw.cx;
  1226. while (pusDstX < pusDstScanRight)
  1227. {
  1228. ULONG ulDither = pulDither[xScan & 3];
  1229. ULONG iRed = Saturation16_5[((clrR.ul[1] >> (3)) + ulDither) >> 16];
  1230. ULONG iGreen = Saturation16_6[((clrG.ul[1] >> (2)) + ulDither) >> 16];
  1231. ULONG iBlue = Saturation16_5[((clrB.ul[1] >> (3)) + ulDither) >> 16];
  1232. *pusDstX = rgb565(iRed,iGreen,iBlue);
  1233. pusDstX++;
  1234. xScan++;
  1235. clrR.ullColor += lldxRed;
  1236. clrG.ullColor += lldxGreen;
  1237. clrB.ullColor += lldxBlue;
  1238. }
  1239. lleRed += lldyRed;
  1240. lleGreen += lldyGreen;
  1241. lleBlue += lldyBlue;
  1242. yScan++;
  1243. pDst += lDelta;
  1244. }
  1245. }
  1246. /******************************Public*Routine******************************\
  1247. * vFillGRectDIB16_555
  1248. *
  1249. *
  1250. * Arguments:
  1251. *
  1252. *
  1253. *
  1254. * Return Value:
  1255. *
  1256. *
  1257. *
  1258. * History:
  1259. *
  1260. * 11/21/1996 Mark Enstrom [marke]
  1261. *
  1262. \**************************************************************************/
  1263. VOID
  1264. vFillGRectDIB16_555(
  1265. PDIBINFO pDibInfo,
  1266. PGRADIENTRECTDATA pgData
  1267. )
  1268. {
  1269. LONG lDelta = pDibInfo->stride;
  1270. LONG cxClip = pgData->szDraw.cx;
  1271. LONG yScan = pgData->ptDraw.y;
  1272. LONG yScanBottom = yScan + pgData->szDraw.cy;
  1273. PBYTE pDst = (PBYTE)pDibInfo->pvBase + lDelta * pgData->ptDraw.y;
  1274. LONGLONG lldxRed = pgData->lldRdX;
  1275. LONGLONG lldxGreen = pgData->lldGdX;
  1276. LONGLONG lldxBlue = pgData->lldBdX;
  1277. LONGLONG lldyRed = pgData->lldRdY;
  1278. LONGLONG lldyGreen = pgData->lldGdY;
  1279. LONGLONG lldyBlue = pgData->lldBdY;
  1280. //
  1281. // lleRed,Green,Blue keep track of color gradient
  1282. // in y. This may be repeated each scan line for different
  1283. // dither values. PERF could allocate temp scan line
  1284. // buffer, run gradient 1 time and dither from this source
  1285. //
  1286. ULONGLONG lleRed;
  1287. ULONGLONG lleGreen;
  1288. ULONGLONG lleBlue;
  1289. PULONG pulDither;
  1290. //
  1291. // skip down to left edge
  1292. //
  1293. lleRed = pgData->llRed;
  1294. lleGreen = pgData->llGreen;
  1295. lleBlue = pgData->llBlue;
  1296. if (pgData->yScanAdjust)
  1297. {
  1298. lleRed += lldyRed * (pgData->yScanAdjust);
  1299. lleGreen += lldyGreen * (pgData->yScanAdjust);
  1300. lleBlue += lldyBlue * (pgData->yScanAdjust);
  1301. }
  1302. LONG yDitherOrg = pgData->ptDitherOrg.y;
  1303. while(yScan < yScanBottom)
  1304. {
  1305. PUSHORT pusDstX;
  1306. PUSHORT pusDstScanRight,pusDstScanLeft;
  1307. COLOR_INTERP clrR,clrG,clrB,clrAlpha;
  1308. LONG xScan;
  1309. pulDither = &gulDither32[0] + 4 * ((yScan + yDitherOrg) & 3);
  1310. clrR.ullColor = lleRed;
  1311. clrG.ullColor = lleGreen;
  1312. clrB.ullColor = lleBlue;
  1313. if (pgData->xScanAdjust)
  1314. {
  1315. clrR.ullColor += lldxRed * (pgData->xScanAdjust);
  1316. clrG.ullColor += lldxGreen * (pgData->xScanAdjust);
  1317. clrB.ullColor += lldxBlue * (pgData->xScanAdjust);
  1318. }
  1319. xScan = pgData->ptDraw.x + pgData->ptDitherOrg.x;
  1320. pusDstX = (PUSHORT)pDst + pgData->ptDraw.x;
  1321. pusDstScanRight = pusDstX + pgData->szDraw.cx;
  1322. while (pusDstX < pusDstScanRight)
  1323. {
  1324. ULONG ulDither = pulDither[xScan & 3];
  1325. ULONG iRed = Saturation16_5[((clrR.ul[1] >> (3)) + ulDither) >> 16];
  1326. ULONG iGreen = Saturation16_5[((clrG.ul[1] >> (3)) + ulDither) >> 16];
  1327. ULONG iBlue = Saturation16_5[((clrB.ul[1] >> (3)) + ulDither) >> 16];
  1328. *pusDstX = rgb555(iRed,iGreen,iBlue);
  1329. pusDstX++;
  1330. xScan++;
  1331. clrR.ullColor += lldxRed;
  1332. clrG.ullColor += lldxGreen;
  1333. clrB.ullColor += lldxBlue;
  1334. }
  1335. lleRed += lldyRed;
  1336. lleGreen += lldyGreen;
  1337. lleBlue += lldyBlue;
  1338. yScan ++;
  1339. pDst += lDelta;
  1340. }
  1341. }
  1342. /******************************Public*Routine******************************\
  1343. * vFillGRectDIB32Direct
  1344. *
  1345. * This routine draws in dithered 32 bpp and is used to diplay on 8,4,1
  1346. * surfaces
  1347. *
  1348. * Arguments:
  1349. *
  1350. * pDibInfo - surface information
  1351. * pgData - gradient rectange information
  1352. *
  1353. * Return Value:
  1354. *
  1355. * none
  1356. *
  1357. * History:
  1358. *
  1359. * 11/21/1996 Mark Enstrom [marke]
  1360. *
  1361. \**************************************************************************/
  1362. VOID
  1363. vFillGRectDIB32Direct(
  1364. PDIBINFO pDibInfo,
  1365. PGRADIENTRECTDATA pgData
  1366. )
  1367. {
  1368. LONG lDelta = pDibInfo->stride;
  1369. LONG yScan = pgData->ptDraw.y;
  1370. LONG yScanBottom = yScan + pgData->szDraw.cy;
  1371. PULONG pulDst;
  1372. HDC hdc32;
  1373. LONGLONG lldxRed = pgData->lldRdX;
  1374. LONGLONG lldxGreen = pgData->lldGdX;
  1375. LONGLONG lldxBlue = pgData->lldBdX;
  1376. LONGLONG lldyRed = pgData->lldRdY;
  1377. LONGLONG lldyGreen = pgData->lldGdY;
  1378. LONGLONG lldyBlue = pgData->lldBdY;
  1379. //
  1380. // lleRed,Green,Blue keep track of color gradient
  1381. // in y. This may be repeated each scan line for different
  1382. // dither values. PERF could allocate temp scan line
  1383. // buffer, run gradient 1 time and dither from this source
  1384. //
  1385. ULONGLONG lleRed;
  1386. ULONGLONG lleGreen;
  1387. ULONGLONG lleBlue;
  1388. PBYTE pDitherMatrix = gDitherMatrix16x16Halftone;
  1389. PBYTE pSaturationTable = HalftoneSaturationTable;
  1390. BOOL b1bpp = (pDibInfo->pbmi->bmiHeader.biBitCount == 1);
  1391. // WINBUG #365339 4-10-2001 jasonha Investigate using default dither table
  1392. //
  1393. // Old Comment:
  1394. // - should use default dither table for 8bpp w/o
  1395. // halftone palette
  1396. //
  1397. if (
  1398. (pDibInfo->pbmi->bmiHeader.biBitCount == 4) ||
  1399. (b1bpp)
  1400. )
  1401. {
  1402. pDitherMatrix = gDitherMatrix16x16Default;
  1403. pSaturationTable = DefaultSaturationTable;
  1404. }
  1405. //
  1406. // get scan line buffer with 32 bpp DC
  1407. //
  1408. hdc32 = hdcAllocateScanLineDC(pgData->szDraw.cx,&pulDst);
  1409. if (hdc32 == NULL)
  1410. {
  1411. return;
  1412. }
  1413. //
  1414. // skip down to left edge
  1415. //
  1416. lleRed = pgData->llRed;
  1417. lleGreen = pgData->llGreen;
  1418. lleBlue = pgData->llBlue;
  1419. if (pgData->yScanAdjust)
  1420. {
  1421. lleRed += lldyRed * (pgData->yScanAdjust);
  1422. lleGreen += lldyGreen * (pgData->yScanAdjust);
  1423. lleBlue += lldyBlue * (pgData->yScanAdjust);
  1424. }
  1425. LONG yDitherOrg = pgData->ptDitherOrg.y;
  1426. LONG xDitherOrg = pgData->ptDitherOrg.x;
  1427. while(yScan < yScanBottom)
  1428. {
  1429. PULONG pulDstX;
  1430. LONG xScanLeft = pgData->ptDraw.x;
  1431. LONG xScan = xScanLeft;
  1432. LONG xScanRight = xScanLeft + pgData->szDraw.cx;
  1433. ULONG Red;
  1434. ULONG Green;
  1435. ULONG Blue;
  1436. COLOR_INTERP clrR,clrG,clrB,clrAlpha;
  1437. clrR.ullColor = lleRed;
  1438. clrG.ullColor = lleGreen;
  1439. clrB.ullColor = lleBlue;
  1440. if (pgData->xScanAdjust)
  1441. {
  1442. clrR.ullColor += lldxRed * (pgData->xScanAdjust);
  1443. clrG.ullColor += lldxGreen * (pgData->xScanAdjust);
  1444. clrB.ullColor += lldxBlue * (pgData->xScanAdjust);
  1445. }
  1446. pulDstX = pulDst + xScanLeft;
  1447. PBYTE pDitherLevel = &pDitherMatrix[(16 * ((yScan+yDitherOrg) & DITHER_8_MASK_Y))];
  1448. while (xScan < xScanRight)
  1449. {
  1450. //
  1451. // calculate x component of dither
  1452. //
  1453. ULONG iRed = clrR.b[6];
  1454. ULONG iGreen = clrG.b[6];
  1455. ULONG iBlue = clrB.b[6];
  1456. BYTE jDitherMatrix = *(pDitherLevel + ((xScan + xDitherOrg) & DITHER_8_MASK_X));
  1457. if (b1bpp)
  1458. {
  1459. jDitherMatrix *= 2;
  1460. iRed = iRed + jDitherMatrix;
  1461. if (iRed >= 255)
  1462. {
  1463. iRed = 255;
  1464. }
  1465. else
  1466. {
  1467. iRed = 0;
  1468. }
  1469. iGreen = iGreen + jDitherMatrix;
  1470. if (iGreen >= 255)
  1471. {
  1472. iGreen = 255;
  1473. }
  1474. else
  1475. {
  1476. iGreen = 0;
  1477. }
  1478. iBlue = iBlue + jDitherMatrix;
  1479. if (iBlue >= 255)
  1480. {
  1481. iBlue = 255;
  1482. }
  1483. else
  1484. {
  1485. iBlue = 0;
  1486. }
  1487. }
  1488. else
  1489. {
  1490. iRed = pSaturationTable[iRed + jDitherMatrix];
  1491. iGreen = pSaturationTable[iGreen + jDitherMatrix];
  1492. iBlue = pSaturationTable[iBlue + jDitherMatrix];
  1493. }
  1494. *pulDstX = ((iRed << 16) | (iGreen << 8) | iBlue);
  1495. xScan++;
  1496. pulDstX++;
  1497. clrR.ullColor += lldxRed;
  1498. clrG.ullColor += lldxGreen;
  1499. clrB.ullColor += lldxBlue;
  1500. }
  1501. //
  1502. // write span to device
  1503. //
  1504. BitBlt(pDibInfo->hdc,
  1505. xScanLeft,
  1506. yScan,
  1507. xScanRight-xScanLeft,
  1508. 1,
  1509. hdc32,
  1510. xScanLeft,
  1511. 0,
  1512. SRCCOPY);
  1513. //
  1514. // add y color increment
  1515. //
  1516. lleRed += lldyRed;
  1517. lleGreen += lldyGreen;
  1518. lleBlue += lldyBlue;
  1519. yScan++;
  1520. }
  1521. if (hdc32)
  1522. {
  1523. vFreeScanLineDC(hdc32);
  1524. }
  1525. }
  1526. #endif