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.

3562 lines
98 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: tranblt.cxx
  3. *
  4. * Transparent BLT
  5. *
  6. * Created: 21-Jun-1996
  7. * Author: Mark Enstrom [marke]
  8. *
  9. * Copyright (c) 1996-1999 Microsoft Corporation
  10. \**************************************************************************/
  11. #include "precomp.hxx"
  12. #include "solline.hxx"
  13. /**************************************************************************\
  14. * gulDither32 - 4-4 dither matrix
  15. *
  16. *
  17. * History:
  18. *
  19. * 1/31/1997 Mark Enstrom [marke]
  20. *
  21. \**************************************************************************/
  22. ULONG gulDither32[] =
  23. {
  24. 0x00000000,
  25. 0x00008000,
  26. 0x00002000,
  27. 0x0000a000,
  28. 0x0000c000,
  29. 0x00004000,
  30. 0x0000e000,
  31. 0x00006000,
  32. 0x00003000,
  33. 0x0000b000,
  34. 0x00001000,
  35. 0x00009000,
  36. 0x0000f000,
  37. 0x00007000,
  38. 0x0000d000,
  39. 0x00005000
  40. };
  41. /**************************************************************************\
  42. *
  43. * Dither information for 8bpp. This is customized for dithering to
  44. * the halftone palette [6,6,6] color cube.
  45. *
  46. * History:
  47. *
  48. * 2/24/1997 Mark Enstrom [marke]
  49. *
  50. \**************************************************************************/
  51. #define DITHER_8_MASK_Y 0x0F
  52. #define DITHER_8_MASK_X 0x0F
  53. BYTE gDitherMatrix16x16Halftone[256] = {
  54. 3, 28, 9, 35, 4, 30, 11, 36, 3, 29, 10, 35, 5, 30, 11, 37,
  55. 41, 16, 48, 22, 43, 17, 49, 24, 42, 16, 48, 22, 43, 18, 50, 24,
  56. 6, 32, 0, 25, 8, 33, 1, 27, 6, 32, 0, 26, 8, 34, 2, 27,
  57. 44, 19, 38, 12, 46, 20, 40, 14, 45, 19, 38, 13, 46, 21, 40, 14,
  58. 5, 31, 12, 37, 4, 29, 10, 36, 6, 31, 12, 38, 4, 30, 10, 36,
  59. 44, 18, 50, 24, 42, 16, 48, 23, 44, 18, 50, 25, 42, 17, 49, 23,
  60. 8, 34, 2, 28, 7, 32, 0, 26, 9, 34, 2, 28, 7, 33, 1, 26,
  61. 47, 21, 40, 15, 45, 20, 39, 13, 47, 22, 41, 15, 46, 20, 39, 14,
  62. 3, 29, 9, 35, 5, 30, 11, 37, 3, 28, 9, 35, 4, 30, 11, 36,
  63. 41, 16, 48, 22, 43, 17, 49, 24, 41, 15, 47, 22, 43, 17, 49, 23,
  64. 6, 32, 0, 25, 8, 33, 1, 27, 6, 31, 0, 25, 7, 33, 1, 27,
  65. 45, 19, 38, 13, 46, 21, 40, 14, 44, 19, 38, 12, 46, 20, 39, 14,
  66. 5, 31, 12, 37, 4, 29, 10, 36, 5, 31, 11, 37, 3, 29, 10, 35,
  67. 44, 18, 50, 25, 42, 17, 49, 23, 43, 18, 50, 24, 42, 16, 48, 23,
  68. 9, 34, 2, 28, 7, 33, 1, 26, 8, 34, 2, 27, 7, 32, 0, 26,
  69. 47, 21, 41, 15, 45, 20, 39, 13, 47, 21, 40, 15, 45, 19, 39, 13
  70. };
  71. BYTE gDitherMatrix16x16Default[256] = {
  72. 8, 72, 24, 88, 12, 76, 28, 92, 9, 73, 25, 89, 13, 77, 29, 93,
  73. 104, 40,120, 56,108, 44,124, 60,105, 41,121, 57,109, 45,125, 61,
  74. 16, 80, 0, 64, 20, 84, 4, 68, 17, 81, 1, 65, 21, 85, 5, 69,
  75. 112, 48, 96, 32,116, 52,100, 36,113, 49, 97, 33,117, 53,101, 37,
  76. 14, 78, 30, 94, 10, 74, 26, 90, 15, 79, 31, 95, 11, 75, 27, 91,
  77. 110, 46,126, 62,106, 42,122, 58,111, 47,126, 63,107, 43,123, 59,
  78. 22, 86, 6, 70, 18, 82, 2, 66, 23, 87, 7, 71, 19, 83, 3, 67,
  79. 118, 54,102, 38,114, 50, 98, 34,119, 55,103, 39,115, 51, 99, 35,
  80. 9, 73, 25, 89, 13, 77, 29, 93, 8, 72, 24, 88, 12, 76, 28, 92,
  81. 105, 41,121, 57,109, 45,125, 61,104, 40,120, 56,108, 44,124, 60,
  82. 17, 81, 1, 65, 21, 85, 5, 69, 16, 80, 0, 64, 20, 84, 4, 68,
  83. 113, 49, 97, 33,117, 53,101, 37,112, 48, 96, 32,116, 52,100, 36,
  84. 15, 79, 31, 95, 11, 75, 27, 91, 14, 78, 30, 94, 10, 74, 26, 90,
  85. 111, 47,126, 63,107, 43,123, 59,110, 46,126, 62,106, 42,122, 58,
  86. 23, 87, 7, 71, 19, 83, 3, 67, 22, 86, 6, 70, 18, 82, 2, 66,
  87. 119, 55,103, 39,115, 51, 99, 35,118, 54,102, 38,114, 50, 98, 34
  88. };
  89. //
  90. // identity translate vector for use in non palmanaged 8bpp surfaces
  91. //
  92. /**************************************************************************\
  93. * vTranslateIdentity
  94. *
  95. * identity translate vector for use in non-palmanaged 8bpp surfaces
  96. *
  97. *
  98. * History:
  99. *
  100. * 3/4/1997 Mark Enstrom [marke]
  101. *
  102. \**************************************************************************/
  103. BYTE vTranslateIdentity[256] = {
  104. 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
  105. 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,
  106. 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,
  107. 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
  108. 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,
  109. 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f,
  110. 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,
  111. 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f,
  112. 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f,
  113. 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f,
  114. 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf,
  115. 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf,
  116. 0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,
  117. 0xd0,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdd,0xde,0xdf,
  118. 0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xeb,0xec,0xed,0xee,0xef,
  119. 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff
  120. };
  121. /**************************************************************************\
  122. * HalftoneSaturationTable
  123. *
  124. * This table maps a 8 bit pixel plus a dither error term in the range
  125. * of 0 to 51 onto a 8 bit pixel. Overflow of up to 31 is considered
  126. * saturated (255+51 = 255). The level 51 (0x33) is used to map pixels
  127. * and error values to the halftone palette
  128. *
  129. * History:
  130. *
  131. * 3/4/1997 Mark Enstrom [marke]
  132. *
  133. \**************************************************************************/
  134. BYTE HalftoneSaturationTable[256 + 128] = {
  135. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  136. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  137. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  138. 0, 0, 0, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
  139. 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
  140. 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
  141. 51, 51, 51, 51, 51, 51,102,102,102,102,102,102,102,102,102,102,
  142. 102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,
  143. 102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,
  144. 102,102,102,102,102,102,102,102,102,153,153,153,153,153,153,153,
  145. 153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
  146. 153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
  147. 153,153,153,153,153,153,153,153,153,153,153,153,204,204,204,204,
  148. 204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
  149. 204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
  150. 204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,255,
  151. 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
  152. 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
  153. 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
  154. 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
  155. 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
  156. 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
  157. 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
  158. 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255
  159. };
  160. BYTE DefaultSaturationTable[256 + 128] = {
  161. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  162. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  163. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  164. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  165. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  166. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  167. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  168. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  169. 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
  170. 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
  171. 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
  172. 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
  173. 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
  174. 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
  175. 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
  176. 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,255,
  177. 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
  178. 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
  179. 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
  180. 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
  181. 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
  182. 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
  183. 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
  184. 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255
  185. };
  186. BYTE Saturation16_5[64] = {
  187. 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
  188. 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,
  189. 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
  190. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
  191. };
  192. BYTE Saturation16_6[128] = {
  193. 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
  194. 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,
  195. 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,
  196. 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
  197. 0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
  198. 0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
  199. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  200. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
  201. };
  202. /******************************Public*Routine******************************\
  203. * vGradientFill32BGRA
  204. *
  205. * Fill scan lines of triangle structure
  206. *
  207. * Arguments:
  208. *
  209. * pSurfDst - destination surface
  210. * ptData - triangle data
  211. *
  212. * Return Value:
  213. *
  214. * none
  215. *
  216. * History:
  217. *
  218. * 11/21/1996 Mark Enstrom [marke]
  219. *
  220. \**************************************************************************/
  221. VOID
  222. vGradientFill32BGRA(
  223. SURFACE *pSurfDst,
  224. PTRIANGLEDATA ptData
  225. )
  226. {
  227. LONG lDelta = pSurfDst->lDelta();
  228. LONG yScan = ptData->y0;
  229. LONG yScanBottom;
  230. PBYTE pDst = ((PBYTE)pSurfDst->pvScan0() + lDelta * yScan);
  231. PTRIEDGE pEdge = &ptData->TriEdge[0];
  232. LONGLONG lldRdX = ptData->lldRdX;
  233. LONGLONG lldGdX = ptData->lldGdX;
  234. LONGLONG lldBdX = ptData->lldBdX;
  235. LONGLONG lldAdX = ptData->lldAdX;
  236. COLOR_INTERP clrRed,clrGreen,clrBlue,clrAlpha;
  237. yScanBottom = MIN(ptData->rcl.bottom,ptData->y1);
  238. while(yScan < yScanBottom)
  239. {
  240. PULONG pulDstX;
  241. PULONG pulDstScanRight,pulDstScanLeft;
  242. clrRed.ullColor = pEdge->llRed;
  243. clrGreen.ullColor = pEdge->llGreen;
  244. clrBlue.ullColor = pEdge->llBlue;
  245. clrAlpha.ullColor = pEdge->llAlpha;
  246. LONG xScanLeft = MAX(pEdge->xLeft,ptData->rcl.left);
  247. LONG xScanRight = MIN(pEdge->xRight,ptData->rcl.right);
  248. if (xScanLeft < xScanRight)
  249. {
  250. pulDstX = (PULONG)pDst + xScanLeft;
  251. pulDstScanRight = (PULONG)pDst + xScanRight;
  252. //
  253. // skip pixels from left edge to left clip, while
  254. // incrementing gradient
  255. //
  256. LONG GradientLeft = ptData->rcl.left - pEdge->xLeft;
  257. if (GradientLeft > 0)
  258. {
  259. clrRed.ullColor += lldRdX * GradientLeft;
  260. clrGreen.ullColor += lldGdX * GradientLeft;
  261. clrBlue.ullColor += lldBdX * GradientLeft;
  262. clrAlpha.ullColor += lldAdX * GradientLeft;
  263. }
  264. //
  265. // fill span
  266. //
  267. while (pulDstX < pulDstScanRight)
  268. {
  269. *pulDstX = (clrAlpha.b[7] << 24) |
  270. (clrRed.b[7] << 16) |
  271. (clrGreen.b[7] << 8) |
  272. (clrBlue.b[7]);
  273. pulDstX++;
  274. clrRed.ullColor += lldRdX;
  275. clrGreen.ullColor += lldGdX;
  276. clrBlue.ullColor += lldBdX;
  277. clrAlpha.ullColor += lldAdX;
  278. }
  279. }
  280. pDst += lDelta;
  281. pEdge++;
  282. yScan++;
  283. }
  284. }
  285. /******************************Public*Routine******************************\
  286. * vGradientFill32RGB
  287. *
  288. * Fill scan lines of triangle structure
  289. *
  290. * Arguments:
  291. *
  292. * pSurfDst - destination surface
  293. * ptData - triangle data
  294. *
  295. * Return Value:
  296. *
  297. * none
  298. *
  299. * History:
  300. *
  301. * 11/21/1996 Mark Enstrom [marke]
  302. *
  303. \**************************************************************************/
  304. VOID
  305. vGradientFill32RGB(
  306. SURFACE *pSurfDst,
  307. PTRIANGLEDATA ptData
  308. )
  309. {
  310. LONG lDelta = pSurfDst->lDelta();
  311. LONG yScan = ptData->y0;
  312. LONG yScanBottom;
  313. PBYTE pDst = ((PBYTE)pSurfDst->pvScan0() + lDelta * yScan);
  314. PTRIEDGE pEdge = &ptData->TriEdge[0];
  315. LONGLONG lldRdX = ptData->lldRdX;
  316. LONGLONG lldGdX = ptData->lldGdX;
  317. LONGLONG lldBdX = ptData->lldBdX;
  318. COLOR_INTERP clrRed,clrGreen,clrBlue;
  319. yScanBottom = MIN(ptData->rcl.bottom,ptData->y1);
  320. while(yScan < yScanBottom)
  321. {
  322. PULONG pulDstX;
  323. PULONG pulDstScanRight,pulDstScanLeft;
  324. clrRed.ullColor = pEdge->llRed;
  325. clrGreen.ullColor = pEdge->llGreen;
  326. clrBlue.ullColor = pEdge->llBlue;
  327. LONG xScanLeft = MAX(pEdge->xLeft,ptData->rcl.left);
  328. LONG xScanRight = MIN(pEdge->xRight,ptData->rcl.right);
  329. if (xScanLeft < xScanRight)
  330. {
  331. pulDstX = (PULONG)pDst + xScanLeft;
  332. pulDstScanRight = (PULONG)pDst + xScanRight;
  333. //
  334. // skip pixels from left edge to left clip, while
  335. // incrementing gradient
  336. //
  337. LONG GradientLeft = ptData->rcl.left - pEdge->xLeft;
  338. if (GradientLeft > 0)
  339. {
  340. clrRed.ullColor += lldRdX * GradientLeft;
  341. clrGreen.ullColor += lldGdX * GradientLeft;
  342. clrBlue.ullColor += lldBdX * GradientLeft;
  343. }
  344. //
  345. // fill span
  346. //
  347. while (pulDstX < pulDstScanRight)
  348. {
  349. *pulDstX =
  350. (clrBlue.b[7] << 16) |
  351. (clrGreen.b[7] << 8) |
  352. (clrRed.b[7]);
  353. pulDstX++;
  354. clrRed.ullColor += lldRdX;
  355. clrGreen.ullColor += lldGdX;
  356. clrBlue.ullColor += lldBdX;
  357. }
  358. }
  359. pDst += lDelta;
  360. pEdge++;
  361. yScan++;
  362. }
  363. }
  364. /******************************Public*Routine******************************\
  365. * vGradientFill32Bitfields
  366. *
  367. * Fill scan lines of triangle structure
  368. *
  369. * Arguments:
  370. *
  371. * pSurfDst - destination surface
  372. * ptData - triangle data
  373. *
  374. * Return Value:
  375. *
  376. * none
  377. *
  378. * History:
  379. *
  380. * 11/21/1996 Mark Enstrom [marke]
  381. *
  382. \**************************************************************************/
  383. VOID
  384. vGradientFill32Bitfields(
  385. SURFACE *pSurfDst,
  386. PTRIANGLEDATA ptData
  387. )
  388. {
  389. LONG lDelta = pSurfDst->lDelta();
  390. LONG yScan = ptData->y0;
  391. LONG yScanBottom;
  392. PBYTE pDst = ((PBYTE)pSurfDst->pvScan0() + lDelta * yScan);
  393. PTRIEDGE pEdge = &ptData->TriEdge[0];
  394. LONGLONG lldRdX = ptData->lldRdX;
  395. LONGLONG lldGdX = ptData->lldGdX;
  396. LONGLONG lldBdX = ptData->lldBdX;
  397. COLOR_INTERP clrRed,clrGreen,clrBlue;
  398. XEPALOBJ *ppalDstSurf = ptData->ppalDstSurf;
  399. yScanBottom = MIN(ptData->rcl.bottom,ptData->y1);
  400. while(yScan < yScanBottom)
  401. {
  402. PULONG pulDstX;
  403. PULONG pulDstScanRight,pulDstScanLeft;
  404. clrRed.ullColor = pEdge->llRed;
  405. clrGreen.ullColor = pEdge->llGreen;
  406. clrBlue.ullColor = pEdge->llBlue;
  407. LONG xScanLeft = MAX(pEdge->xLeft,ptData->rcl.left);
  408. LONG xScanRight = MIN(pEdge->xRight,ptData->rcl.right);
  409. if (xScanLeft < xScanRight)
  410. {
  411. pulDstX = (PULONG)pDst + xScanLeft;
  412. pulDstScanRight = (PULONG)pDst + xScanRight;
  413. //
  414. // skip pixels from left edge to left clip, while
  415. // incrementing gradient
  416. //
  417. LONG GradientLeft = ptData->rcl.left - pEdge->xLeft;
  418. if (GradientLeft > 0)
  419. {
  420. clrRed.ullColor += lldRdX * GradientLeft;
  421. clrGreen.ullColor += lldGdX * GradientLeft;
  422. clrBlue.ullColor += lldBdX * GradientLeft;
  423. }
  424. while (pulDstX < pulDstScanRight)
  425. {
  426. ULONG ulTemp =
  427. (clrRed.b[7] ) |
  428. (clrGreen.b[7] << 8) |
  429. (clrBlue.b[7] << 16);
  430. *pulDstX = ppalDstSurf->ulGetMatchFromPalentry(ulTemp);
  431. pulDstX++;
  432. clrRed.ullColor += lldRdX;
  433. clrGreen.ullColor += lldGdX;
  434. clrBlue.ullColor += lldBdX;
  435. }
  436. }
  437. pDst += lDelta;
  438. pEdge++;
  439. yScan++;
  440. }
  441. }
  442. /**************************************************************************\
  443. * vGradientFill24BGR
  444. *
  445. * Fill scan lines of triangle structure
  446. *
  447. * Arguments:
  448. *
  449. * pSurfDst - destination surface
  450. * ptData - triangle data
  451. *
  452. * Return Value:
  453. *
  454. * none
  455. *
  456. * History:
  457. *
  458. * 11/21/1996 Mark Enstrom [marke]
  459. *
  460. \**************************************************************************/
  461. VOID
  462. vGradientFill24BGR(
  463. SURFACE *pSurfDst,
  464. PTRIANGLEDATA ptData
  465. )
  466. {
  467. LONG lDelta = pSurfDst->lDelta();
  468. LONG yScan = ptData->y0;
  469. PBYTE pDst = ((PBYTE)pSurfDst->pvScan0() + lDelta * yScan);
  470. PTRIEDGE pEdge = &ptData->TriEdge[0];
  471. LONG yScanBottom;
  472. LONGLONG lldRdX = ptData->lldRdX;
  473. LONGLONG lldGdX = ptData->lldGdX;
  474. LONGLONG lldBdX = ptData->lldBdX;
  475. COLOR_INTERP clrRed,clrGreen,clrBlue;
  476. yScanBottom = MIN(ptData->rcl.bottom,ptData->y1);
  477. while(yScan < yScanBottom)
  478. {
  479. PBYTE pDstX;
  480. PBYTE pDstScanRight;
  481. clrRed.ullColor = pEdge->llRed;
  482. clrGreen.ullColor = pEdge->llGreen;
  483. clrBlue.ullColor = pEdge->llBlue;
  484. LONG xScanLeft = MAX(pEdge->xLeft,ptData->rcl.left);
  485. LONG xScanRight = MIN(pEdge->xRight,ptData->rcl.right);
  486. if (xScanLeft < xScanRight)
  487. {
  488. pDstX = pDst + 3 * xScanLeft;
  489. pDstScanRight = pDst + 3 * xScanRight;
  490. //
  491. // skip pixels from left edge to left clip, while
  492. // incrementing gradient
  493. //
  494. LONG GradientLeft = ptData->rcl.left - pEdge->xLeft;
  495. if (GradientLeft > 0)
  496. {
  497. clrRed.ullColor += lldRdX * GradientLeft;
  498. clrGreen.ullColor += lldGdX * GradientLeft;
  499. clrBlue.ullColor += lldBdX * GradientLeft;
  500. }
  501. while (pDstX < pDstScanRight)
  502. {
  503. *pDstX = clrBlue.b[7];
  504. *(pDstX+1) = clrGreen.b[7];
  505. *(pDstX+2) = clrRed.b[7];
  506. clrRed.ullColor += lldRdX;
  507. clrGreen.ullColor += lldGdX;
  508. clrBlue.ullColor += lldBdX;
  509. pDstX+=3;
  510. }
  511. }
  512. pDst += lDelta;
  513. pEdge++;
  514. yScan++;
  515. }
  516. }
  517. /**************************************************************************\
  518. * vGradientFill24RGB
  519. *
  520. * Fill scan lines of triangle structure
  521. *
  522. * Arguments:
  523. *
  524. * pSurfDst - destination surface
  525. * ptData - triangle data
  526. *
  527. * Return Value:
  528. *
  529. * none
  530. *
  531. * History:
  532. *
  533. * 08/28/2000 Pravin Santiago [pravins]. Adapted from vGradientFill24BGR
  534. *
  535. \**************************************************************************/
  536. VOID
  537. vGradientFill24RGB(
  538. SURFACE *pSurfDst,
  539. PTRIANGLEDATA ptData
  540. )
  541. {
  542. LONG lDelta = pSurfDst->lDelta();
  543. LONG yScan = ptData->y0;
  544. PBYTE pDst = ((PBYTE)pSurfDst->pvScan0() + lDelta * yScan);
  545. PTRIEDGE pEdge = &ptData->TriEdge[0];
  546. LONG yScanBottom;
  547. LONGLONG lldRdX = ptData->lldRdX;
  548. LONGLONG lldGdX = ptData->lldGdX;
  549. LONGLONG lldBdX = ptData->lldBdX;
  550. COLOR_INTERP clrRed,clrGreen,clrBlue;
  551. yScanBottom = MIN(ptData->rcl.bottom,ptData->y1);
  552. while(yScan < yScanBottom)
  553. {
  554. PBYTE pDstX;
  555. PBYTE pDstScanRight;
  556. clrRed.ullColor = pEdge->llRed;
  557. clrGreen.ullColor = pEdge->llGreen;
  558. clrBlue.ullColor = pEdge->llBlue;
  559. LONG xScanLeft = MAX(pEdge->xLeft,ptData->rcl.left);
  560. LONG xScanRight = MIN(pEdge->xRight,ptData->rcl.right);
  561. if (xScanLeft < xScanRight)
  562. {
  563. pDstX = pDst + 3 * xScanLeft;
  564. pDstScanRight = pDst + 3 * xScanRight;
  565. //
  566. // skip pixels from left edge to left clip, while
  567. // incrementing gradient
  568. //
  569. LONG GradientLeft = ptData->rcl.left - pEdge->xLeft;
  570. if (GradientLeft > 0)
  571. {
  572. clrRed.ullColor += lldRdX * GradientLeft;
  573. clrGreen.ullColor += lldGdX * GradientLeft;
  574. clrBlue.ullColor += lldBdX * GradientLeft;
  575. }
  576. while (pDstX < pDstScanRight)
  577. {
  578. *pDstX = clrRed.b[7];
  579. *(pDstX+1) = clrGreen.b[7];
  580. *(pDstX+2) = clrBlue.b[7];
  581. clrRed.ullColor += lldRdX;
  582. clrGreen.ullColor += lldGdX;
  583. clrBlue.ullColor += lldBdX;
  584. pDstX+=3;
  585. }
  586. }
  587. pDst += lDelta;
  588. pEdge++;
  589. yScan++;
  590. }
  591. }
  592. /******************************Public*Routine******************************\
  593. * vGradientFill24Bitfields
  594. *
  595. * Fill scan lines of triangle structure
  596. *
  597. * Arguments:
  598. *
  599. * pSurfDst - destination surface
  600. * ptData - triangle data
  601. *
  602. * Return Value:
  603. *
  604. * none
  605. *
  606. * History:
  607. *
  608. * 08/28/2000 Pravin Santiago [pravins]. Adapted from vGradientFill32Bitfields
  609. *
  610. \**************************************************************************/
  611. VOID
  612. vGradientFill24Bitfields(
  613. SURFACE *pSurfDst,
  614. PTRIANGLEDATA ptData
  615. )
  616. {
  617. LONG lDelta = pSurfDst->lDelta();
  618. LONG yScan = ptData->y0;
  619. LONG yScanBottom;
  620. PBYTE pDst = ((PBYTE)pSurfDst->pvScan0() + lDelta * yScan);
  621. PTRIEDGE pEdge = &ptData->TriEdge[0];
  622. LONGLONG lldRdX = ptData->lldRdX;
  623. LONGLONG lldGdX = ptData->lldGdX;
  624. LONGLONG lldBdX = ptData->lldBdX;
  625. COLOR_INTERP clrRed,clrGreen,clrBlue;
  626. XEPALOBJ *ppalDstSurf = ptData->ppalDstSurf;
  627. yScanBottom = MIN(ptData->rcl.bottom,ptData->y1);
  628. while(yScan < yScanBottom)
  629. {
  630. PBYTE pbDstX;
  631. PBYTE pbDstScanRight,pbDstScanLeft;
  632. clrRed.ullColor = pEdge->llRed;
  633. clrGreen.ullColor = pEdge->llGreen;
  634. clrBlue.ullColor = pEdge->llBlue;
  635. LONG xScanLeft = MAX(pEdge->xLeft,ptData->rcl.left);
  636. LONG xScanRight = MIN(pEdge->xRight,ptData->rcl.right);
  637. if (xScanLeft < xScanRight)
  638. {
  639. pbDstX = (PBYTE)pDst + xScanLeft*3;
  640. pbDstScanRight = (PBYTE)pDst + xScanRight*3;
  641. //
  642. // skip pixels from left edge to left clip, while
  643. // incrementing gradient
  644. //
  645. LONG GradientLeft = ptData->rcl.left - pEdge->xLeft;
  646. if (GradientLeft > 0)
  647. {
  648. clrRed.ullColor += lldRdX * GradientLeft;
  649. clrGreen.ullColor += lldGdX * GradientLeft;
  650. clrBlue.ullColor += lldBdX * GradientLeft;
  651. }
  652. while (pbDstX < pbDstScanRight)
  653. {
  654. ULONG ulTemp =
  655. (clrRed.b[7] ) |
  656. (clrGreen.b[7] << 8) |
  657. (clrBlue.b[7] << 16);
  658. ulTemp = ppalDstSurf->ulGetMatchFromPalentry(ulTemp);
  659. *pbDstX = ((PBYTE)&ulTemp)[0];
  660. *(pbDstX+1) = ((PBYTE)&ulTemp)[1];
  661. *(pbDstX+2) = ((PBYTE)&ulTemp)[2];
  662. pbDstX += 3;
  663. clrRed.ullColor += lldRdX;
  664. clrGreen.ullColor += lldGdX;
  665. clrBlue.ullColor += lldBdX;
  666. }
  667. }
  668. pDst += lDelta;
  669. pEdge++;
  670. yScan++;
  671. }
  672. }
  673. /******************************Public*Routine******************************\
  674. * vGradientFill16_565
  675. *
  676. * Fill scan lines of triangle structure
  677. *
  678. * Arguments:
  679. *
  680. * pSurfDst - destination surface
  681. * ptData - triangle data
  682. *
  683. * Return Value:
  684. *
  685. * none
  686. *
  687. * History:
  688. *
  689. * 11/21/1996 Mark Enstrom [marke]
  690. *
  691. \**************************************************************************/
  692. VOID
  693. vGradientFill16_565(
  694. SURFACE *pSurfDst,
  695. PTRIANGLEDATA ptData
  696. )
  697. {
  698. LONG lDelta = pSurfDst->lDelta();
  699. LONG yScan = ptData->y0;
  700. LONG yScanBottom;
  701. PBYTE pDst = ((PBYTE)pSurfDst->pvScan0() + lDelta * yScan);
  702. PTRIEDGE pEdge = &ptData->TriEdge[0];
  703. LONGLONG lldRdX = ptData->lldRdX;
  704. LONGLONG lldGdX = ptData->lldGdX;
  705. LONGLONG lldBdX = ptData->lldBdX;
  706. COLOR_INTERP clrRed,clrGreen,clrBlue;
  707. yScanBottom = MIN(ptData->rcl.bottom,ptData->y1);
  708. LONG yDitherOrg = ptData->ptDitherOrg.y;
  709. LONG xDitherOrg = ptData->ptDitherOrg.x;
  710. while(yScan < yScanBottom)
  711. {
  712. PUSHORT pusDstX,pusDstScanRight;
  713. PULONG pulDither = &gulDither32[0] + 4 * ((yScan+yDitherOrg) & 3);
  714. clrRed.ullColor = pEdge->llRed;
  715. clrGreen.ullColor = pEdge->llGreen;
  716. clrBlue.ullColor = pEdge->llBlue;
  717. LONG xScanRight = MIN(pEdge->xRight,ptData->rcl.right);
  718. LONG xScanLeft = MAX(pEdge->xLeft,ptData->rcl.left);
  719. if (xScanLeft < xScanRight)
  720. {
  721. pusDstX = (PUSHORT)pDst + xScanLeft;
  722. pusDstScanRight = (PUSHORT)pDst + xScanRight;
  723. //
  724. // skip pixels from left edge to left clip, while
  725. // incrementing gradient
  726. //
  727. LONG GradientLeft = ptData->rcl.left - pEdge->xLeft;
  728. if (GradientLeft > 0)
  729. {
  730. clrRed.ullColor += lldRdX * GradientLeft;
  731. clrGreen.ullColor += lldGdX * GradientLeft;
  732. clrBlue.ullColor += lldBdX * GradientLeft;
  733. }
  734. //
  735. // Gradient fill scan line with dither
  736. //
  737. while (pusDstX < pusDstScanRight)
  738. {
  739. ULONG ulDither = pulDither[(xScanLeft + xDitherOrg) & 3];
  740. ULONG iRed = Saturation16_5[((clrRed.ul[1] >> (8+3)) + ulDither) >> 16];
  741. ULONG iGreen = Saturation16_6[((clrGreen.ul[1] >> (8+2)) + ulDither) >> 16];
  742. ULONG iBlue = Saturation16_5[((clrBlue.ul[1] >> (8+3)) + ulDither) >> 16];
  743. *pusDstX = rgb565(iRed,iGreen,iBlue);
  744. xScanLeft++;
  745. pusDstX++;
  746. clrRed.ullColor += lldRdX;
  747. clrGreen.ullColor += lldGdX;
  748. clrBlue.ullColor += lldBdX;
  749. }
  750. }
  751. pDst += lDelta;
  752. pEdge++;
  753. yScan++;
  754. }
  755. }
  756. /******************************Public*Routine******************************\
  757. * vGradientFill16_555
  758. *
  759. * Fill scan lines of triangle structure
  760. *
  761. * Arguments:
  762. *
  763. * pSurfDst - destination surface
  764. * ptData - triangle data
  765. *
  766. * Return Value:
  767. *
  768. * none
  769. *
  770. * History:
  771. *
  772. * 11/21/1996 Mark Enstrom [marke]
  773. *
  774. \**************************************************************************/
  775. VOID
  776. vGradientFill16_555(
  777. SURFACE *pSurfDst,
  778. PTRIANGLEDATA ptData
  779. )
  780. {
  781. LONG lDelta = pSurfDst->lDelta();
  782. LONG yScan = ptData->y0;
  783. LONG yScanBottom;
  784. PBYTE pDst = ((PBYTE)pSurfDst->pvScan0() + lDelta * yScan);
  785. PTRIEDGE pEdge = &ptData->TriEdge[0];
  786. LONGLONG lldRdX = ptData->lldRdX;
  787. LONGLONG lldGdX = ptData->lldGdX;
  788. LONGLONG lldBdX = ptData->lldBdX;
  789. COLOR_INTERP clrRed,clrGreen,clrBlue;
  790. yScanBottom = MIN(ptData->rcl.bottom,ptData->y1);
  791. LONG yDitherOrg = ptData->ptDitherOrg.y;
  792. LONG xDitherOrg = ptData->ptDitherOrg.x;
  793. while(yScan < yScanBottom)
  794. {
  795. PUSHORT pusDstX,pusDstScanRight;
  796. PULONG pulDither = &gulDither32[0] + 4 * ((yScan+yDitherOrg) & 3);
  797. clrRed.ullColor = pEdge->llRed;
  798. clrGreen.ullColor = pEdge->llGreen;
  799. clrBlue.ullColor = pEdge->llBlue;
  800. LONG xScanRight = MIN(pEdge->xRight,ptData->rcl.right);
  801. LONG xScanLeft = MAX(pEdge->xLeft,ptData->rcl.left);
  802. if (xScanLeft < xScanRight)
  803. {
  804. pusDstX = (PUSHORT)pDst + xScanLeft;
  805. pusDstScanRight = (PUSHORT)pDst + xScanRight;
  806. //
  807. // skip pixels from left edge to left clip, while
  808. // incrementing gradient
  809. //
  810. LONG GradientLeft = ptData->rcl.left - pEdge->xLeft;
  811. if (GradientLeft > 0)
  812. {
  813. clrRed.ullColor += lldRdX * GradientLeft;
  814. clrGreen.ullColor += lldGdX * GradientLeft;
  815. clrBlue.ullColor += lldBdX * GradientLeft;
  816. }
  817. //
  818. // Gradient fill scan line with dither
  819. //
  820. while (pusDstX < pusDstScanRight)
  821. {
  822. ULONG ulDither = pulDither[(xScanLeft + xDitherOrg) & 3];
  823. ULONG iRed = Saturation16_5[((clrRed.ul[1] >> (8+3)) + ulDither) >> 16];
  824. ULONG iGreen = Saturation16_5[((clrGreen.ul[1] >> (8+3)) + ulDither) >> 16];
  825. ULONG iBlue = Saturation16_5[((clrBlue.ul[1] >> (8+3)) + ulDither) >> 16];
  826. *pusDstX = rgb555(iRed,iGreen,iBlue);
  827. xScanLeft++;
  828. pusDstX++;
  829. clrRed.ullColor += lldRdX;
  830. clrGreen.ullColor += lldGdX;
  831. clrBlue.ullColor += lldBdX;
  832. }
  833. }
  834. pDst += lDelta;
  835. pEdge++;
  836. yScan++;
  837. }
  838. }
  839. /******************************Public*Routine******************************\
  840. * vGradientFill16Bitfields
  841. *
  842. * Fill scan lines of triangle structure
  843. *
  844. * Arguments:
  845. *
  846. * pSurfDst - destination surface
  847. * ptData - triangle data
  848. *
  849. * Return Value:
  850. *
  851. * none
  852. *
  853. * History:
  854. *
  855. * 11/21/1996 Mark Enstrom [marke]
  856. *
  857. \**************************************************************************/
  858. VOID
  859. vGradientFill16Bitfields(
  860. SURFACE *pSurfDst,
  861. PTRIANGLEDATA ptData
  862. )
  863. {
  864. LONG lDelta = pSurfDst->lDelta();
  865. LONG yScan = ptData->y0;
  866. LONG yScanBottom;
  867. PBYTE pDst = ((PBYTE)pSurfDst->pvScan0() + lDelta * yScan);
  868. PTRIEDGE pEdge = &ptData->TriEdge[0];
  869. XEPALOBJ *ppalDstSurf = ptData->ppalDstSurf;
  870. PULONG pulDither;
  871. LONGLONG lldRdX = ptData->lldRdX;
  872. LONGLONG lldGdX = ptData->lldGdX;
  873. LONGLONG lldBdX = ptData->lldBdX;
  874. COLOR_INTERP clrRed,clrGreen,clrBlue;
  875. yScanBottom = MIN(ptData->rcl.bottom,ptData->y1);
  876. LONG yDitherOrg = ptData->ptDitherOrg.y;
  877. LONG xDitherOrg = ptData->ptDitherOrg.x;
  878. while(yScan < yScanBottom)
  879. {
  880. PUSHORT pusDstX,pusDstScanRight;
  881. pulDither = &gulDither32[0] + 4 * ((yScan+yDitherOrg) & 3);
  882. clrRed.ullColor = pEdge->llRed;
  883. clrGreen.ullColor = pEdge->llGreen;
  884. clrBlue.ullColor = pEdge->llBlue;
  885. LONG xScanRight = MIN(pEdge->xRight,ptData->rcl.right);
  886. LONG xScanLeft = MAX(pEdge->xLeft,ptData->rcl.left);
  887. if (xScanLeft < xScanRight)
  888. {
  889. pusDstX = (PUSHORT)pDst + xScanLeft;
  890. pusDstScanRight = (PUSHORT)pDst + xScanRight;
  891. //
  892. // skip pixels from left edge to left clip, while
  893. // incrementing gradient
  894. //
  895. LONG GradientLeft = ptData->rcl.left - pEdge->xLeft;
  896. if (GradientLeft > 0)
  897. {
  898. clrRed.ullColor += lldRdX * GradientLeft;
  899. clrGreen.ullColor += lldGdX * GradientLeft;
  900. clrBlue.ullColor += lldBdX * GradientLeft;
  901. }
  902. while (pusDstX < pusDstScanRight)
  903. {
  904. ULONG ulDither = pulDither[(xScanLeft + xDitherOrg) & 3];
  905. ULONG iRed = Saturation16_5[((clrRed.ul[1] >> (8+3)) + ulDither) >> 16];
  906. ULONG iGreen = Saturation16_5[((clrGreen.ul[1] >> (8+3)) + ulDither) >> 16];
  907. ULONG iBlue = Saturation16_5[((clrBlue.ul[1] >> (8+3)) + ulDither) >> 16];
  908. ULONG ulTemp = (iRed << ( 3)) |
  909. (iGreen << (8 +3)) |
  910. (iBlue << (8+8+3));
  911. *pusDstX = (USHORT)ppalDstSurf->ulGetMatchFromPalentry(ulTemp);
  912. clrRed.ullColor += lldRdX;
  913. clrGreen.ullColor += lldGdX;
  914. clrBlue.ullColor += lldBdX;
  915. xScanLeft++;
  916. pusDstX++;
  917. }
  918. }
  919. pDst += lDelta;
  920. pEdge++;
  921. yScan++;
  922. }
  923. }
  924. /**************************************************************************\
  925. * GRAD_PALETTE_MATCH
  926. *
  927. *
  928. * Arguments:
  929. *
  930. * palIndex - return surface palette index
  931. * pjVector - translation from DC to surface palette. Identity for non
  932. * palette managed
  933. * pxlate555 - rgb555 to palette index table
  934. * r,g,b - byte colors
  935. *
  936. * Return Value:
  937. *
  938. *
  939. *
  940. * History:
  941. *
  942. * 3/3/1997 Mark Enstrom [marke]
  943. *
  944. \**************************************************************************/
  945. #define GRAD_PALETTE_MATCH(palIndex,pjVector,pxlate555,r,g,b) \
  946. \
  947. palIndex = pxlate555[((r & 0xf8) << 7) | \
  948. ((g & 0xf8) << 2) | \
  949. ((b & 0xf8) >> 3)]; \
  950. \
  951. palIndex = pjVector[palIndex];
  952. /******************************Public*Routine******************************\
  953. * vGradientFill8
  954. *
  955. * Fill scan lines of triangle structure
  956. *
  957. * Arguments:
  958. *
  959. * pSurfDst - destination surface
  960. * ptData - triangle data
  961. *
  962. * Return Value:
  963. *
  964. * none
  965. *
  966. * History:
  967. *
  968. * 11/21/1996 Mark Enstrom [marke]
  969. *
  970. \**************************************************************************/
  971. VOID
  972. vGradientFill8(
  973. SURFACE *pSurfDst,
  974. PTRIANGLEDATA ptData
  975. )
  976. {
  977. LONG lDelta = pSurfDst->lDelta();
  978. LONG yScan = ptData->y0;
  979. LONG yScanBottom;
  980. PBYTE pDst = ((PBYTE)pSurfDst->pvScan0() + lDelta * yScan);
  981. PTRIEDGE pEdge = &ptData->TriEdge[0];
  982. XLATEOBJ *pxlo = ptData->pxlo;
  983. PBYTE pxlate = NULL;
  984. PBYTE pjVector;
  985. PBYTE pDitherMatrix;
  986. PBYTE pSaturationTable;
  987. LONGLONG lldRdX = ptData->lldRdX;
  988. LONGLONG lldGdX = ptData->lldGdX;
  989. LONGLONG lldBdX = ptData->lldBdX;
  990. COLOR_INTERP clrRed,clrGreen,clrBlue;
  991. //
  992. // either use default palette or halftone palette dither
  993. //
  994. if (((XEPALOBJ) (((XLATE *) pxlo)->ppalDstDC)).bIsHalftone())
  995. {
  996. pDitherMatrix = gDitherMatrix16x16Halftone;
  997. pSaturationTable = HalftoneSaturationTable;
  998. }
  999. else
  1000. {
  1001. pDitherMatrix = gDitherMatrix16x16Default;
  1002. pSaturationTable = DefaultSaturationTable;
  1003. }
  1004. //
  1005. // determine DC to surface palette translate
  1006. //
  1007. if (((XLATE *) pxlo)->flPrivate & XLATE_PAL_MANAGED)
  1008. {
  1009. if (((XLATE *) pxlo)->ppalDstDC == ppalDefault)
  1010. {
  1011. pjVector = &defaultTranslate.ajVector[0];
  1012. }
  1013. else
  1014. {
  1015. if (((XLATE *) pxlo)->flPrivate & XLATE_USE_CURRENT)
  1016. {
  1017. pjVector = &((XLATE *) pxlo)->ppalDstDC->ptransCurrent->ajVector[0];
  1018. }
  1019. else
  1020. {
  1021. pjVector = &((XLATE *) pxlo)->ppalDstDC->ptransFore->ajVector[0];
  1022. }
  1023. }
  1024. }
  1025. else
  1026. {
  1027. pjVector = vTranslateIdentity;
  1028. }
  1029. //
  1030. // get/build rgb555 to palette table
  1031. //
  1032. pxlate = XLATEOBJ_pGetXlate555(pxlo);
  1033. if (pxlate == NULL)
  1034. {
  1035. WARNING("vGradientFill8:Failed to generate rgb555 xlate table\n");
  1036. return;
  1037. }
  1038. //
  1039. // scan from top to bottom of triangle scan lines
  1040. //
  1041. yScanBottom = MIN(ptData->rcl.bottom,ptData->y1);
  1042. LONG yDitherOrg = ptData->ptDitherOrg.y;
  1043. LONG xDitherOrg = ptData->ptDitherOrg.x;
  1044. while(yScan < yScanBottom)
  1045. {
  1046. PBYTE pjDstX,pjDstScanRight;
  1047. clrRed.ullColor = pEdge->llRed;
  1048. clrGreen.ullColor = pEdge->llGreen;
  1049. clrBlue.ullColor = pEdge->llBlue;
  1050. LONG xScanLeft = MAX(pEdge->xLeft,ptData->rcl.left);
  1051. LONG xScanRight = MIN(pEdge->xRight,ptData->rcl.right);
  1052. PBYTE pDitherLevel = &pDitherMatrix[(16 * ((yScan+yDitherOrg) & DITHER_8_MASK_Y))];
  1053. if (xScanLeft < xScanRight)
  1054. {
  1055. pjDstX = pDst + xScanLeft;
  1056. pjDstScanRight = pDst + xScanRight;
  1057. //
  1058. // skip pixels from left edge to left clip, while
  1059. // incrementing gradient
  1060. //
  1061. LONG GradientLeft = ptData->rcl.left - pEdge->xLeft;
  1062. if (GradientLeft > 0)
  1063. {
  1064. clrRed.ullColor += lldRdX * GradientLeft;
  1065. clrGreen.ullColor += lldGdX * GradientLeft;
  1066. clrBlue.ullColor += lldBdX * GradientLeft;
  1067. }
  1068. //
  1069. // gradient fill scan with dither
  1070. //
  1071. while (pjDstX < pjDstScanRight)
  1072. {
  1073. BYTE jIndex;
  1074. //
  1075. // offset into dither array
  1076. //
  1077. BYTE jDitherMatrix = *(pDitherLevel + ((xScanLeft+xDitherOrg) & DITHER_8_MASK_X));
  1078. ULONG iRed = pSaturationTable[clrRed.b[7] + jDitherMatrix];
  1079. ULONG iGreen = pSaturationTable[clrGreen.b[7] + jDitherMatrix];
  1080. ULONG iBlue = pSaturationTable[clrBlue.b[7] + jDitherMatrix];
  1081. GRAD_PALETTE_MATCH(jIndex,pjVector,pxlate,((BYTE)iRed),((BYTE)iGreen),((BYTE)iBlue));
  1082. *pjDstX = jIndex;
  1083. xScanLeft++;
  1084. pjDstX++;
  1085. clrRed.ullColor += lldRdX;
  1086. clrGreen.ullColor += lldGdX;
  1087. clrBlue.ullColor += lldBdX;
  1088. }
  1089. }
  1090. pDst += lDelta;
  1091. pEdge++;
  1092. yScan++;
  1093. }
  1094. }
  1095. /******************************Public*Routine******************************\
  1096. * vGradientFill4
  1097. *
  1098. * Fill scan lines of triangle structure
  1099. *
  1100. * Arguments:
  1101. *
  1102. * pSurfDst - destination surface
  1103. * ptData - triangle data
  1104. *
  1105. * Return Value:
  1106. *
  1107. * none
  1108. *
  1109. * History:
  1110. *
  1111. * 11/21/1996 Mark Enstrom [marke]
  1112. *
  1113. \**************************************************************************/
  1114. VOID
  1115. vGradientFill4(
  1116. SURFACE *pSurfDst,
  1117. PTRIANGLEDATA ptData
  1118. )
  1119. {
  1120. LONG lDelta = pSurfDst->lDelta();
  1121. LONG yScan = ptData->y0;
  1122. LONG yScanBottom;
  1123. PBYTE pDst = ((PBYTE)pSurfDst->pvScan0() + lDelta * yScan);
  1124. PTRIEDGE pEdge = &ptData->TriEdge[0];
  1125. XLATEOBJ *pxlo = ptData->pxlo;
  1126. PBYTE pxlate = NULL;
  1127. PBYTE pjVector;
  1128. PBYTE pDitherMatrix = gDitherMatrix16x16Default;
  1129. PBYTE pSaturationTable = DefaultSaturationTable;
  1130. LONGLONG lldRdX = ptData->lldRdX;
  1131. LONGLONG lldGdX = ptData->lldGdX;
  1132. LONGLONG lldBdX = ptData->lldBdX;
  1133. COLOR_INTERP clrRed,clrGreen,clrBlue;
  1134. //
  1135. // determine DC to surface palette translate
  1136. //
  1137. if (((XLATE *) pxlo)->flPrivate & XLATE_PAL_MANAGED)
  1138. {
  1139. if (((XLATE *) pxlo)->ppalDstDC == ppalDefault)
  1140. {
  1141. pjVector = &defaultTranslate.ajVector[0];
  1142. }
  1143. else
  1144. {
  1145. if (((XLATE *) pxlo)->flPrivate & XLATE_USE_CURRENT)
  1146. {
  1147. pjVector = &((XLATE *) pxlo)->ppalDstDC->ptransCurrent->ajVector[0];
  1148. }
  1149. else
  1150. {
  1151. pjVector = &((XLATE *) pxlo)->ppalDstDC->ptransFore->ajVector[0];
  1152. }
  1153. }
  1154. }
  1155. else
  1156. {
  1157. pjVector = vTranslateIdentity;
  1158. }
  1159. //
  1160. // get/build rgb555 to palette table
  1161. //
  1162. pxlate = XLATEOBJ_pGetXlate555(pxlo);
  1163. if (pxlate == NULL)
  1164. {
  1165. WARNING("Failed to generate rgb555 xlate table\n");
  1166. return;
  1167. }
  1168. yScanBottom = MIN(ptData->rcl.bottom,ptData->y1);
  1169. LONG yDitherOrg = ptData->ptDitherOrg.y;
  1170. LONG xDitherOrg = ptData->ptDitherOrg.x;
  1171. while(yScan < yScanBottom)
  1172. {
  1173. PBYTE pjDstX;
  1174. LONG iDstX;
  1175. clrRed.ullColor = pEdge->llRed;
  1176. clrGreen.ullColor = pEdge->llGreen;
  1177. clrBlue.ullColor = pEdge->llBlue;
  1178. LONG xScanLeft = MAX(pEdge->xLeft,ptData->rcl.left);
  1179. LONG xScanRight = MIN(pEdge->xRight,ptData->rcl.right);
  1180. PBYTE pDitherLevel = &pDitherMatrix[(16 * ((yScan+yDitherOrg) & DITHER_8_MASK_Y))];
  1181. if (xScanLeft < xScanRight)
  1182. {
  1183. pjDstX = pDst + (xScanLeft/2);
  1184. iDstX = xScanLeft & 1;
  1185. //
  1186. // skip pixels from left edge to left clip, while
  1187. // incrementing gradient
  1188. //
  1189. LONG GradientLeft = ptData->rcl.left - pEdge->xLeft;
  1190. if (GradientLeft > 0)
  1191. {
  1192. clrRed.ullColor += lldRdX * GradientLeft;
  1193. clrGreen.ullColor += lldGdX * GradientLeft;
  1194. clrBlue.ullColor += lldBdX * GradientLeft;
  1195. }
  1196. //
  1197. // fill scan line with dither
  1198. //
  1199. PALETTEENTRY palEntry;
  1200. palEntry.peFlags = 2;
  1201. while (xScanLeft < xScanRight)
  1202. {
  1203. //
  1204. // offset into dither array
  1205. //
  1206. BYTE jDitherMatrix = *(pDitherLevel + ((xScanLeft+xDitherOrg) & DITHER_8_MASK_X));
  1207. ULONG iRed = pSaturationTable[clrRed.b[7] + jDitherMatrix];
  1208. ULONG iGreen = pSaturationTable[clrGreen.b[7] + jDitherMatrix];
  1209. ULONG iBlue = pSaturationTable[clrBlue.b[7] + jDitherMatrix];
  1210. BYTE jIndex;
  1211. GRAD_PALETTE_MATCH(jIndex,pjVector,pxlate,((BYTE)iRed),((BYTE)iGreen),((BYTE)iBlue));
  1212. //
  1213. // write nibble
  1214. //
  1215. if (iDstX)
  1216. {
  1217. iDstX = 0;
  1218. *pjDstX = (*pjDstX & 0xf0) | jIndex;
  1219. pjDstX++;
  1220. }
  1221. else
  1222. {
  1223. *pjDstX = (*pjDstX & 0x0f) | (jIndex << 4);
  1224. iDstX = 1;
  1225. }
  1226. xScanLeft++;
  1227. clrRed.ullColor += lldRdX;
  1228. clrGreen.ullColor += lldGdX;
  1229. clrBlue.ullColor += lldBdX;
  1230. }
  1231. }
  1232. pDst += lDelta;
  1233. pEdge++;
  1234. yScan++;
  1235. }
  1236. }
  1237. /******************************Public*Routine******************************\
  1238. * vGradientFill1
  1239. *
  1240. * Fill scan lines of triangle structure
  1241. *
  1242. * Arguments:
  1243. *
  1244. * pSurfDst - destination surface
  1245. * ptData - triangle data
  1246. *
  1247. * Return Value:
  1248. *
  1249. * none
  1250. *
  1251. * History:
  1252. *
  1253. * 11/21/1996 Mark Enstrom [marke]
  1254. *
  1255. \**************************************************************************/
  1256. VOID
  1257. vGradientFill1(
  1258. SURFACE *pSurfDst,
  1259. PTRIANGLEDATA ptData
  1260. )
  1261. {
  1262. LONG lDelta = pSurfDst->lDelta();
  1263. LONG yScan = ptData->y0;
  1264. LONG yScanBottom;
  1265. PBYTE pDst = ((PBYTE)pSurfDst->pvScan0() + lDelta * yScan);
  1266. PTRIEDGE pEdge = &ptData->TriEdge[0];
  1267. XLATEOBJ *pxlo = ptData->pxlo;
  1268. PBYTE pxlate = NULL;
  1269. PBYTE pjVector = vTranslateIdentity;
  1270. PBYTE pDitherMatrix = gDitherMatrix16x16Default;
  1271. LONGLONG lldRdX = ptData->lldRdX;
  1272. LONGLONG lldGdX = ptData->lldGdX;
  1273. LONGLONG lldBdX = ptData->lldBdX;
  1274. COLOR_INTERP clrRed,clrGreen,clrBlue;
  1275. //
  1276. // get/build rgb555 to palette table
  1277. //
  1278. pxlate = XLATEOBJ_pGetXlate555(pxlo);
  1279. if (pxlate == NULL)
  1280. {
  1281. WARNING("Failed to generate rgb555 xlate table\n");
  1282. return;
  1283. }
  1284. //
  1285. // must have palette xlate
  1286. //
  1287. yScanBottom = MIN(ptData->rcl.bottom,ptData->y1);
  1288. LONG yDitherOrg = ptData->ptDitherOrg.y;
  1289. LONG xDitherOrg = ptData->ptDitherOrg.x;
  1290. while(yScan < yScanBottom)
  1291. {
  1292. PBYTE pjDstX;
  1293. LONG iDstX;
  1294. LONG ScanRight;
  1295. LONG ScanLeft;
  1296. LONG xScan;
  1297. clrRed.ullColor = pEdge->llRed;
  1298. clrGreen.ullColor = pEdge->llGreen;
  1299. clrBlue.ullColor = pEdge->llBlue;
  1300. LONG xScanLeft = MAX(pEdge->xLeft,ptData->rcl.left);
  1301. LONG xScanRight = MIN(pEdge->xRight,ptData->rcl.right);
  1302. PBYTE pDitherLevel = &pDitherMatrix[(16 * ((yScan+yDitherOrg) & DITHER_8_MASK_Y))];
  1303. if (xScanLeft < xScanRight)
  1304. {
  1305. pjDstX = pDst + (xScanLeft/8);
  1306. iDstX = xScanLeft & 7;
  1307. //
  1308. // skip clipped out portion of scan line whille
  1309. // running color gradient
  1310. //
  1311. LONG GradientLeft = ptData->rcl.left - pEdge->xLeft;
  1312. if (GradientLeft > 0)
  1313. {
  1314. clrRed.ullColor += lldRdX * GradientLeft;
  1315. clrGreen.ullColor += lldGdX * GradientLeft;
  1316. clrBlue.ullColor += lldBdX * GradientLeft;
  1317. }
  1318. PALETTEENTRY palEntry;
  1319. palEntry.peFlags = 2;
  1320. while (xScanLeft < xScanRight)
  1321. {
  1322. //
  1323. // offset into dither array
  1324. //
  1325. BYTE jDitherMatrix = 2 * (*(pDitherLevel + ((xScanLeft+xDitherOrg) & DITHER_8_MASK_X)));
  1326. ULONG iRed = clrRed.b[7];
  1327. ULONG iGreen = clrGreen.b[7];
  1328. ULONG iBlue = clrBlue.b[7];
  1329. //
  1330. // add dither and saturate. 1bpp non-optimized (overflow will not be noticable in a dither
  1331. // case it would at higher color depth
  1332. //
  1333. iRed = iRed + jDitherMatrix;
  1334. if (iRed >= 255)
  1335. {
  1336. iRed = 255;
  1337. }
  1338. else
  1339. {
  1340. iRed = 0;
  1341. }
  1342. iGreen = iGreen + jDitherMatrix;
  1343. if (iGreen >= 255)
  1344. {
  1345. iGreen = 255;
  1346. }
  1347. else
  1348. {
  1349. iGreen = 0;
  1350. }
  1351. iBlue = iBlue + jDitherMatrix;
  1352. if (iBlue >= 255)
  1353. {
  1354. iBlue = 255;
  1355. }
  1356. else
  1357. {
  1358. iBlue = 0;
  1359. }
  1360. BYTE jIndex;
  1361. //
  1362. // pjVector is known to be identity, so could make new macro for
  1363. // palette_match_1 if perf ever an issue
  1364. //
  1365. GRAD_PALETTE_MATCH(jIndex,pjVector,pxlate,((BYTE)iRed),((BYTE)iGreen),((BYTE)iBlue));
  1366. LONG iShift = 7 - iDstX;
  1367. BYTE OrMask = 1 << iShift;
  1368. BYTE AndMask = ~OrMask;
  1369. jIndex = jIndex << iShift;
  1370. *pjDstX = (*pjDstX & AndMask) | jIndex;
  1371. iDstX++;
  1372. if (iDstX == 8)
  1373. {
  1374. iDstX = 0;
  1375. pjDstX++;
  1376. }
  1377. xScanLeft++;
  1378. clrRed.ullColor += lldRdX;
  1379. clrGreen.ullColor += lldGdX;
  1380. clrBlue.ullColor += lldBdX;
  1381. }
  1382. }
  1383. pDst += lDelta;
  1384. pEdge++;
  1385. yScan++;
  1386. }
  1387. }
  1388. //
  1389. // Gradient fill rectangle routines
  1390. //
  1391. //
  1392. // Gradient Rectangles us 8.48 fixed point color
  1393. // as oppesed to triangles that use 8.56
  1394. //
  1395. //
  1396. //
  1397. //
  1398. //
  1399. //
  1400. //
  1401. //
  1402. //
  1403. //
  1404. //
  1405. //
  1406. //
  1407. /******************************Public*Routine******************************\
  1408. * vFillGRectDIB32BGRA
  1409. *
  1410. * Fill gradient rect from structure
  1411. *
  1412. * Arguments:
  1413. *
  1414. * pSurfDst - destination surface
  1415. * pgData - gradient rect data
  1416. *
  1417. * Return Value:
  1418. *
  1419. * none
  1420. *
  1421. * History:
  1422. *
  1423. * 11/21/1996 Mark Enstrom [marke]
  1424. *
  1425. \**************************************************************************/
  1426. VOID
  1427. vFillGRectDIB32BGRA(
  1428. SURFACE *pSurfDst,
  1429. PGRADIENTRECTDATA pgData
  1430. )
  1431. {
  1432. LONG lDelta = pSurfDst->lDelta();
  1433. LONG cyClip = pgData->szDraw.cy;
  1434. //
  1435. // fill rect with gradient fill. if this is horizontal mode then
  1436. // draw one scan line and replicate in v, if this is vertical mode then
  1437. // draw one vertical stripe and replicate in h
  1438. //
  1439. COLOR_INTERP clrR,clrG,clrB,clrA;
  1440. if (pgData->ulMode == GRADIENT_FILL_RECT_H)
  1441. {
  1442. PBYTE pjDst = (PBYTE)pSurfDst->pvScan0() + lDelta * pgData->ptDraw.y;
  1443. PULONG pulBuffer = (PULONG)AllocFreeTmpBuffer(4 * pgData->szDraw.cx);
  1444. if (pulBuffer)
  1445. {
  1446. clrR.ullColor = pgData->llRed;
  1447. clrG.ullColor = pgData->llGreen;
  1448. clrB.ullColor = pgData->llBlue;
  1449. clrA.ullColor = pgData->llAlpha;
  1450. LONGLONG lldRdX = pgData->lldRdX;
  1451. LONGLONG lldGdX = pgData->lldGdX;
  1452. LONGLONG lldBdX = pgData->lldBdX;
  1453. LONGLONG lldAdX = pgData->lldAdX;
  1454. //
  1455. // adjust gradient fill for clipped portion
  1456. //
  1457. if (pgData->xScanAdjust > 0)
  1458. {
  1459. clrR.ullColor += lldRdX * (pgData->xScanAdjust);
  1460. clrG.ullColor += lldGdX * (pgData->xScanAdjust);
  1461. clrB.ullColor += lldBdX * (pgData->xScanAdjust);
  1462. clrA.ullColor += lldAdX * (pgData->xScanAdjust);
  1463. }
  1464. //
  1465. // draw 1 scan line
  1466. //
  1467. PULONG pulDstX = pulBuffer;
  1468. PULONG pulEndX = pulDstX + pgData->szDraw.cx;
  1469. while (pulDstX != pulEndX)
  1470. {
  1471. *pulDstX = (ULONG)(((clrA.b[6]) << 24) |
  1472. ((clrR.b[6]) << 16) |
  1473. ((clrG.b[6]) << 8) |
  1474. ((clrB.b[6])));
  1475. clrR.ullColor += lldRdX;
  1476. clrG.ullColor += lldGdX;
  1477. clrB.ullColor += lldBdX;
  1478. clrA.ullColor += lldAdX;
  1479. pulDstX++;
  1480. }
  1481. //
  1482. // replicate
  1483. //
  1484. PULONG pulDstY = (PULONG)pjDst + pgData->ptDraw.x;
  1485. PULONG pulEndY = (PULONG)((PBYTE)pulDstY + lDelta * cyClip);
  1486. while (pulDstY != pulEndY)
  1487. {
  1488. memcpy(pulDstY,pulBuffer,4*pgData->szDraw.cx);
  1489. pulDstY = (PULONG)((PBYTE)pulDstY + lDelta);
  1490. }
  1491. FreeTmpBuffer(pulBuffer);
  1492. }
  1493. }
  1494. else
  1495. {
  1496. clrR.ullColor = pgData->llRed;
  1497. clrG.ullColor = pgData->llGreen;
  1498. clrB.ullColor = pgData->llBlue;
  1499. clrA.ullColor = pgData->llAlpha;
  1500. LONGLONG lldRdY = pgData->lldRdY;
  1501. LONGLONG lldGdY = pgData->lldGdY;
  1502. LONGLONG lldBdY = pgData->lldBdY;
  1503. LONGLONG lldAdY = pgData->lldAdY;
  1504. //
  1505. // vertical gradient.
  1506. // replicate each x value accross whole scan line
  1507. //
  1508. if (pgData->yScanAdjust > 0)
  1509. {
  1510. clrR.ullColor += lldRdY * (pgData->yScanAdjust);
  1511. clrG.ullColor += lldGdY * (pgData->yScanAdjust);
  1512. clrB.ullColor += lldBdY * (pgData->yScanAdjust);
  1513. clrA.ullColor += lldAdY * (pgData->yScanAdjust);
  1514. }
  1515. PBYTE pDst = (PBYTE)pSurfDst->pvScan0() + lDelta * pgData->ptDraw.y;
  1516. pDst = pDst + 4 * pgData->ptDraw.x;
  1517. while (cyClip--)
  1518. {
  1519. ULONG ul = (ULONG)(((clrA.b[6]) << 24) |
  1520. ((clrR.b[6]) << 16) |
  1521. ((clrG.b[6]) << 8) |
  1522. ((clrB.b[6])));
  1523. RtlFillMemoryUlong(pDst,pgData->szDraw.cx*4,ul);
  1524. clrR.ullColor += lldRdY;
  1525. clrG.ullColor += lldGdY;
  1526. clrB.ullColor += lldBdY;
  1527. clrA.ullColor += lldAdY;
  1528. pDst += lDelta;
  1529. }
  1530. }
  1531. }
  1532. /******************************Public*Routine******************************\
  1533. * vFillGRectDIB32RGB
  1534. *
  1535. *
  1536. * Arguments:
  1537. *
  1538. * pSurfDst - destination surface
  1539. * pgData - gradient rect data
  1540. *
  1541. * Return Value:
  1542. *
  1543. * None
  1544. *
  1545. * History:
  1546. *
  1547. * 11/21/1996 Mark Enstrom [marke]
  1548. *
  1549. \**************************************************************************/
  1550. VOID
  1551. vFillGRectDIB32RGB(
  1552. SURFACE *pSurfDst,
  1553. PGRADIENTRECTDATA pgData
  1554. )
  1555. {
  1556. LONG lDelta = pSurfDst->lDelta();
  1557. LONG cyClip = pgData->szDraw.cy;
  1558. //
  1559. // fill rect with gradient fill. if this is horizontal mode then
  1560. // draw one scan line and replicate in v, if this is vertical mode then
  1561. // draw one vertical stripe and replicate in h
  1562. //
  1563. COLOR_INTERP clrR,clrG,clrB,clrA;
  1564. clrR.ullColor = pgData->llRed;
  1565. clrG.ullColor = pgData->llGreen;
  1566. clrB.ullColor = pgData->llBlue;
  1567. if (pgData->ulMode == GRADIENT_FILL_RECT_H)
  1568. {
  1569. PBYTE pjDst = (PBYTE)pSurfDst->pvScan0() + lDelta * pgData->ptDraw.y;
  1570. PULONG pulBuffer = (PULONG)AllocFreeTmpBuffer(4 * pgData->szDraw.cx);
  1571. if (pulBuffer)
  1572. {
  1573. LONGLONG lldRed = pgData->lldRdX;
  1574. LONGLONG lldGreen = pgData->lldGdX;
  1575. LONGLONG lldBlue = pgData->lldBdX;
  1576. //
  1577. // adjust gradient fill for clipped portion
  1578. //
  1579. if (pgData->xScanAdjust > 0)
  1580. {
  1581. clrR.ullColor += lldRed * (pgData->xScanAdjust);
  1582. clrG.ullColor += lldGreen * (pgData->xScanAdjust);
  1583. clrB.ullColor += lldBlue * (pgData->xScanAdjust);
  1584. }
  1585. //
  1586. // draw 1 scan line to temp buffer
  1587. //
  1588. PULONG pulDstX = pulBuffer;
  1589. PULONG pulEndX = pulDstX + pgData->szDraw.cx;
  1590. while (pulDstX != pulEndX)
  1591. {
  1592. *pulDstX = (ULONG)(
  1593. ((clrR.b[6])) |
  1594. ((clrG.b[6]) << 8) |
  1595. ((clrB.b[6]) << 16));
  1596. clrR.ullColor += lldRed;
  1597. clrG.ullColor += lldGreen;
  1598. clrB.ullColor += lldBlue;
  1599. pulDstX++;
  1600. }
  1601. //
  1602. // replicate
  1603. //
  1604. PULONG pulDstY = (PULONG)pjDst + pgData->ptDraw.x;
  1605. PULONG pulEndY = (PULONG)((PBYTE)pulDstY + lDelta * cyClip);
  1606. while (pulDstY != pulEndY)
  1607. {
  1608. memcpy(pulDstY,pulBuffer,4*pgData->szDraw.cx);
  1609. pulDstY = (PULONG)((PBYTE)pulDstY + lDelta);
  1610. }
  1611. FreeTmpBuffer(pulBuffer);
  1612. }
  1613. }
  1614. else
  1615. {
  1616. LONGLONG lldRed = pgData->lldRdY;
  1617. LONGLONG lldGreen = pgData->lldGdY;
  1618. LONGLONG lldBlue = pgData->lldBdY;
  1619. //
  1620. // vertical gradient.
  1621. // replicate each x value accross whole scan line
  1622. //
  1623. if (pgData->yScanAdjust > 0)
  1624. {
  1625. clrR.ullColor += lldRed * (pgData->yScanAdjust);
  1626. clrG.ullColor += lldGreen * (pgData->yScanAdjust);
  1627. clrB.ullColor += lldBlue * (pgData->yScanAdjust);
  1628. }
  1629. PBYTE pDst = (PBYTE)pSurfDst->pvScan0() + lDelta * pgData->ptDraw.y;
  1630. pDst = pDst + 4 * pgData->ptDraw.x;
  1631. while (cyClip--)
  1632. {
  1633. ULONG ul = (ULONG)(
  1634. ((clrR.b[6]) ) |
  1635. ((clrG.b[6]) << 8) |
  1636. ((clrB.b[6]) << 16));
  1637. RtlFillMemoryUlong(pDst,pgData->szDraw.cx*4,ul);
  1638. clrR.ullColor += lldRed;
  1639. clrG.ullColor += lldGreen;
  1640. clrB.ullColor += lldBlue;
  1641. pDst += lDelta;
  1642. }
  1643. }
  1644. }
  1645. /**************************************************************************\
  1646. * vFillGRectDIB32Bitfields
  1647. *
  1648. *
  1649. * Arguments:
  1650. *
  1651. * pSurfDst - destination surface
  1652. * pgData - gradient rect data
  1653. *
  1654. * Return Value:
  1655. *
  1656. * None
  1657. *
  1658. * History:
  1659. *
  1660. * 2/18/1997 Mark Enstrom [marke]
  1661. *
  1662. \**************************************************************************/
  1663. VOID
  1664. vFillGRectDIB32Bitfields(
  1665. SURFACE *pSurfDst,
  1666. PGRADIENTRECTDATA pgData
  1667. )
  1668. {
  1669. LONG lDelta = pSurfDst->lDelta();
  1670. LONG cyClip = pgData->szDraw.cy;
  1671. XEPALOBJ *ppalDstSurf = pgData->ppalDstSurf;
  1672. //
  1673. // fill rect with gradient fill. if this is horizontal mode then
  1674. // draw one scan line and replicate in v, if this is vertical mode then
  1675. // draw one vertical stripe and replicate in h
  1676. //
  1677. COLOR_INTERP clrR,clrG,clrB,clrAlpha;
  1678. clrR.ullColor = pgData->llRed;
  1679. clrG.ullColor = pgData->llGreen;
  1680. clrB.ullColor = pgData->llBlue;
  1681. if (pgData->ulMode == GRADIENT_FILL_RECT_H)
  1682. {
  1683. PBYTE pDst = (PBYTE)pSurfDst->pvScan0() + lDelta * pgData->ptDraw.y;
  1684. LONGLONG lldRed = pgData->lldRdX;
  1685. LONGLONG lldGreen = pgData->lldGdX;
  1686. LONGLONG lldBlue = pgData->lldBdX;
  1687. //
  1688. // adjust gradient fill for clipped portion
  1689. //
  1690. if (pgData->xScanAdjust > 0)
  1691. {
  1692. clrR.ullColor += lldRed * (pgData->xScanAdjust);
  1693. clrG.ullColor += lldGreen * (pgData->xScanAdjust);
  1694. clrB.ullColor += lldBlue * (pgData->xScanAdjust);
  1695. }
  1696. //
  1697. // draw 1 scan line
  1698. //
  1699. PULONG pulDstX = (PULONG)pDst + pgData->ptDraw.x;
  1700. PULONG pulEndX = pulDstX + pgData->szDraw.cx;
  1701. PULONG pulScanX = pulDstX;
  1702. PBYTE pScan = (PBYTE)pulDstX;
  1703. while (pulDstX != pulEndX)
  1704. {
  1705. ULONG ulPix = (ULONG)(
  1706. ((clrR.b[6] )) |
  1707. ((clrG.b[6]) << 8) |
  1708. ((clrB.b[6] ) << 16));
  1709. *pulDstX = ppalDstSurf->ulGetMatchFromPalentry(ulPix);
  1710. clrR.ullColor += lldRed;
  1711. clrG.ullColor += lldGreen;
  1712. clrB.ullColor += lldBlue;
  1713. pulDstX++;
  1714. }
  1715. cyClip--;
  1716. pScan += lDelta;
  1717. //
  1718. // replicate
  1719. //
  1720. while (cyClip-- > 0)
  1721. {
  1722. memcpy(pScan,pulScanX,4*pgData->szDraw.cx);
  1723. pScan += lDelta;
  1724. }
  1725. }
  1726. else
  1727. {
  1728. LONGLONG lldRed = pgData->lldRdY;
  1729. LONGLONG lldGreen = pgData->lldGdY;
  1730. LONGLONG lldBlue = pgData->lldBdY;
  1731. //
  1732. // vertical gradient.
  1733. // replicate each x value accross whole scan line
  1734. //
  1735. if (pgData->yScanAdjust > 0)
  1736. {
  1737. clrR.ullColor += lldRed * (pgData->yScanAdjust);
  1738. clrG.ullColor += lldGreen * (pgData->yScanAdjust);
  1739. clrB.ullColor += lldBlue * (pgData->yScanAdjust);
  1740. }
  1741. PBYTE pDst = (PBYTE)pSurfDst->pvScan0() + lDelta * pgData->ptDraw.y;
  1742. pDst = pDst + 4 * pgData->ptDraw.x;
  1743. while (cyClip--)
  1744. {
  1745. ULONG ul = (ULONG)(
  1746. ((clrR.b[6])) |
  1747. ((clrG.b[6]) << 8) |
  1748. ((clrB.b[6]) << 16));
  1749. ul = ppalDstSurf->ulGetMatchFromPalentry(ul);
  1750. RtlFillMemoryUlong(pDst,pgData->szDraw.cx*4,ul);
  1751. clrR.ullColor += lldRed;
  1752. clrG.ullColor += lldGreen;
  1753. clrB.ullColor += lldBlue;
  1754. pDst += lDelta;
  1755. }
  1756. }
  1757. }
  1758. /**************************************************************************\
  1759. * vFillGRectDIB24Bitfields
  1760. *
  1761. *
  1762. * Arguments:
  1763. *
  1764. * pSurfDst - destination surface
  1765. * pgData - gradient rect data
  1766. *
  1767. * Return Value:
  1768. *
  1769. * None
  1770. *
  1771. * History:
  1772. *
  1773. * 08/28/2000 Pravin Santiago [pravins]. Adapted from vFillGRectDIB32Bitfields
  1774. *
  1775. \**************************************************************************/
  1776. VOID
  1777. vFillGRectDIB24Bitfields(
  1778. SURFACE *pSurfDst,
  1779. PGRADIENTRECTDATA pgData
  1780. )
  1781. {
  1782. LONG lDelta = pSurfDst->lDelta();
  1783. LONG cyClip = pgData->szDraw.cy;
  1784. XEPALOBJ *ppalDstSurf = pgData->ppalDstSurf;
  1785. //
  1786. // fill rect with gradient fill. if this is horizontal mode then
  1787. // draw one scan line and replicate in v, if this is vertical mode then
  1788. // draw one vertical stripe and replicate in h
  1789. //
  1790. COLOR_INTERP clrR,clrG,clrB,clrAlpha;
  1791. clrR.ullColor = pgData->llRed;
  1792. clrG.ullColor = pgData->llGreen;
  1793. clrB.ullColor = pgData->llBlue;
  1794. if (pgData->ulMode == GRADIENT_FILL_RECT_H)
  1795. {
  1796. PBYTE pDst = (PBYTE)pSurfDst->pvScan0() + lDelta * pgData->ptDraw.y;
  1797. LONGLONG lldRed = pgData->lldRdX;
  1798. LONGLONG lldGreen = pgData->lldGdX;
  1799. LONGLONG lldBlue = pgData->lldBdX;
  1800. //
  1801. // adjust gradient fill for clipped portion
  1802. //
  1803. if (pgData->xScanAdjust > 0)
  1804. {
  1805. clrR.ullColor += lldRed * (pgData->xScanAdjust);
  1806. clrG.ullColor += lldGreen * (pgData->xScanAdjust);
  1807. clrB.ullColor += lldBlue * (pgData->xScanAdjust);
  1808. }
  1809. //
  1810. // draw 1 scan line
  1811. //
  1812. PBYTE pbDstX = pDst + pgData->ptDraw.x*3;
  1813. PBYTE pbEndX = pbDstX + pgData->szDraw.cx*3;
  1814. PBYTE pbScanX = pbDstX;
  1815. PBYTE pScan = pbDstX;
  1816. while (pbDstX != pbEndX)
  1817. {
  1818. ULONG ulPix = (ULONG)(
  1819. ((clrR.b[6] )) |
  1820. ((clrG.b[6]) << 8) |
  1821. ((clrB.b[6] ) << 16));
  1822. ulPix = ppalDstSurf->ulGetMatchFromPalentry(ulPix);
  1823. *pbDstX = ((PBYTE)&ulPix)[0];
  1824. *(pbDstX+1) = ((PBYTE)&ulPix)[1];
  1825. *(pbDstX+2) = ((PBYTE)&ulPix)[2];
  1826. clrR.ullColor += lldRed;
  1827. clrG.ullColor += lldGreen;
  1828. clrB.ullColor += lldBlue;
  1829. pbDstX += 3;
  1830. }
  1831. cyClip--;
  1832. pScan += lDelta;
  1833. //
  1834. // replicate
  1835. //
  1836. while (cyClip-- > 0)
  1837. {
  1838. memcpy(pScan,pbScanX,3*pgData->szDraw.cx);
  1839. pScan += lDelta;
  1840. }
  1841. }
  1842. else
  1843. {
  1844. LONGLONG lldRed = pgData->lldRdY;
  1845. LONGLONG lldGreen = pgData->lldGdY;
  1846. LONGLONG lldBlue = pgData->lldBdY;
  1847. //
  1848. // vertical gradient.
  1849. // replicate each x value accross whole scan line
  1850. //
  1851. if (pgData->yScanAdjust > 0)
  1852. {
  1853. clrR.ullColor += lldRed * (pgData->yScanAdjust);
  1854. clrG.ullColor += lldGreen * (pgData->yScanAdjust);
  1855. clrB.ullColor += lldBlue * (pgData->yScanAdjust);
  1856. }
  1857. PBYTE pDst = (PBYTE)pSurfDst->pvScan0() + lDelta * pgData->ptDraw.y;
  1858. pDst = pDst + 3 * pgData->ptDraw.x;
  1859. while (cyClip--)
  1860. {
  1861. PBYTE pTemp = pDst;
  1862. PBYTE pEnd = pDst + 3 * pgData->szDraw.cx;
  1863. ULONG ul = (ULONG)(
  1864. ((clrR.b[6])) |
  1865. ((clrG.b[6]) << 8) |
  1866. ((clrB.b[6]) << 16));
  1867. ul = ppalDstSurf->ulGetMatchFromPalentry(ul);
  1868. while(pTemp != pEnd)
  1869. {
  1870. *pTemp = ((PBYTE)&ul)[0];
  1871. *(pTemp+1) = ((PBYTE)&ul)[1];
  1872. *(pTemp+2) = ((PBYTE)&ul)[2];
  1873. pTemp += 3;
  1874. }
  1875. clrR.ullColor += lldRed;
  1876. clrG.ullColor += lldGreen;
  1877. clrB.ullColor += lldBlue;
  1878. pDst += lDelta;
  1879. }
  1880. }
  1881. }
  1882. /******************************Public*Routine******************************\
  1883. * vFillGRectDIB24BGR
  1884. *
  1885. *
  1886. * Arguments:
  1887. *
  1888. * pSurfDst - destination surface
  1889. * pgData - gradient rect data
  1890. *
  1891. * Return Value:
  1892. *
  1893. * None
  1894. *
  1895. * History:
  1896. *
  1897. * 11/21/1996 Mark Enstrom [marke]
  1898. *
  1899. \**************************************************************************/
  1900. VOID
  1901. vFillGRectDIB24BGR(
  1902. SURFACE *pSurfDst,
  1903. PGRADIENTRECTDATA pgData
  1904. )
  1905. {
  1906. LONG lDelta = pSurfDst->lDelta();
  1907. LONG cyClip = pgData->szDraw.cy;
  1908. COLOR_INTERP clrR,clrG,clrB,clrAlpha;
  1909. clrR.ullColor = pgData->llRed;
  1910. clrG.ullColor = pgData->llGreen;
  1911. clrB.ullColor = pgData->llBlue;
  1912. //
  1913. // fill rect with gradient fill. if this is horizontal mode then
  1914. // draw one scan line and replicate in v, if this is vertical mode then
  1915. // draw one vertical stripe and replicate in h
  1916. //
  1917. if (pgData->ulMode == GRADIENT_FILL_RECT_H)
  1918. {
  1919. LONGLONG lldRed = pgData->lldRdX;
  1920. LONGLONG lldGreen = pgData->lldGdX;
  1921. LONGLONG lldBlue = pgData->lldBdX;
  1922. //
  1923. // adjust gradient fill for clipped portion
  1924. //
  1925. if (pgData->xScanAdjust > 0)
  1926. {
  1927. clrR.ullColor += lldRed * (pgData->xScanAdjust);
  1928. clrG.ullColor += lldGreen * (pgData->xScanAdjust);
  1929. clrB.ullColor += lldBlue * (pgData->xScanAdjust);
  1930. }
  1931. PBYTE pBuffer = (PBYTE)AllocFreeTmpBuffer(3 * pgData->szDraw.cx);
  1932. if (pBuffer)
  1933. {
  1934. if (pBuffer)
  1935. {
  1936. PBYTE pDstX = pBuffer;
  1937. PBYTE pLast = pDstX + 3 * pgData->szDraw.cx;
  1938. while (pDstX != pLast)
  1939. {
  1940. *pDstX = (clrB.b[6]);
  1941. *(pDstX+1) = (clrG.b[6]);
  1942. *(pDstX+2) = (clrR.b[6]);
  1943. clrR.ullColor += lldRed;
  1944. clrG.ullColor += lldGreen;
  1945. clrB.ullColor += lldBlue;
  1946. pDstX+=3;
  1947. }
  1948. //
  1949. // Replicate the scan line. It would be much better to write the scan line
  1950. // out to a memory buffer for drawing to a device surface
  1951. //
  1952. PBYTE pDst = (PBYTE)pSurfDst->pvScan0() +
  1953. lDelta * pgData->ptDraw.y +
  1954. 3 * pgData->ptDraw.x;
  1955. while (cyClip--)
  1956. {
  1957. memcpy(pDst,pBuffer,3*pgData->szDraw.cx);
  1958. pDst += lDelta;
  1959. }
  1960. FreeTmpBuffer(pBuffer);
  1961. }
  1962. }
  1963. }
  1964. else
  1965. {
  1966. //
  1967. // vertical gradient.
  1968. // replicate each x value accross whole scan line
  1969. //
  1970. PBYTE pDst = (PBYTE)pSurfDst->pvScan0() + lDelta * pgData->ptDraw.y;
  1971. LONGLONG lldRed = pgData->lldRdY;
  1972. LONGLONG lldGreen = pgData->lldGdY;
  1973. LONGLONG lldBlue = pgData->lldBdY;
  1974. //
  1975. // vertical gradient.
  1976. // replicate each x value accross whole scan line
  1977. //
  1978. if (pgData->yScanAdjust > 0)
  1979. {
  1980. clrR.ullColor += lldRed * (pgData->yScanAdjust);
  1981. clrG.ullColor += lldGreen * (pgData->yScanAdjust);
  1982. clrB.ullColor += lldBlue * (pgData->yScanAdjust);
  1983. }
  1984. pDst = pDst + 3 * pgData->ptDraw.x;
  1985. while (cyClip--)
  1986. {
  1987. //
  1988. // fill scan line with solid color
  1989. //
  1990. PBYTE pTemp = pDst;
  1991. PBYTE pEnd = pDst + 3 * pgData->szDraw.cx;
  1992. while (pTemp != pEnd)
  1993. {
  1994. *pTemp = clrB.b[6];
  1995. *(pTemp+1) = clrG.b[6];
  1996. *(pTemp+2) = clrR.b[6];
  1997. pTemp+=3;
  1998. }
  1999. //
  2000. // increment colors for next scan line
  2001. //
  2002. clrR.ullColor += lldRed;
  2003. clrG.ullColor += lldGreen;
  2004. clrB.ullColor += lldBlue;
  2005. //
  2006. // inc pointer to next scan line
  2007. //
  2008. pDst += lDelta;
  2009. }
  2010. }
  2011. }
  2012. /******************************Public*Routine******************************\
  2013. * vFillGRectDIB24RGB
  2014. *
  2015. *
  2016. * Arguments:
  2017. *
  2018. * pSurfDst - destination surface
  2019. * pgData - gradient rect data
  2020. *
  2021. * Return Value:
  2022. *
  2023. * None
  2024. *
  2025. * History:
  2026. *
  2027. * 08/28/2000 Pravin Santiago [pravins]. Adapted from vFillGrectDIB24BGR
  2028. *
  2029. \**************************************************************************/
  2030. VOID
  2031. vFillGRectDIB24RGB(
  2032. SURFACE *pSurfDst,
  2033. PGRADIENTRECTDATA pgData
  2034. )
  2035. {
  2036. LONG lDelta = pSurfDst->lDelta();
  2037. LONG cyClip = pgData->szDraw.cy;
  2038. COLOR_INTERP clrR,clrG,clrB,clrAlpha;
  2039. clrR.ullColor = pgData->llRed;
  2040. clrG.ullColor = pgData->llGreen;
  2041. clrB.ullColor = pgData->llBlue;
  2042. //
  2043. // fill rect with gradient fill. if this is horizontal mode then
  2044. // draw one scan line and replicate in v, if this is vertical mode then
  2045. // draw one vertical stripe and replicate in h
  2046. //
  2047. if (pgData->ulMode == GRADIENT_FILL_RECT_H)
  2048. {
  2049. LONGLONG lldRed = pgData->lldRdX;
  2050. LONGLONG lldGreen = pgData->lldGdX;
  2051. LONGLONG lldBlue = pgData->lldBdX;
  2052. //
  2053. // adjust gradient fill for clipped portion
  2054. //
  2055. if (pgData->xScanAdjust > 0)
  2056. {
  2057. clrR.ullColor += lldRed * (pgData->xScanAdjust);
  2058. clrG.ullColor += lldGreen * (pgData->xScanAdjust);
  2059. clrB.ullColor += lldBlue * (pgData->xScanAdjust);
  2060. }
  2061. PBYTE pBuffer = (PBYTE)AllocFreeTmpBuffer(3 * pgData->szDraw.cx);
  2062. if (pBuffer)
  2063. {
  2064. if (pBuffer)
  2065. {
  2066. PBYTE pDstX = pBuffer;
  2067. PBYTE pLast = pDstX + 3 * pgData->szDraw.cx;
  2068. while (pDstX != pLast)
  2069. {
  2070. *pDstX = (clrR.b[6]);
  2071. *(pDstX+1) = (clrG.b[6]);
  2072. *(pDstX+2) = (clrB.b[6]);
  2073. clrR.ullColor += lldRed;
  2074. clrG.ullColor += lldGreen;
  2075. clrB.ullColor += lldBlue;
  2076. pDstX+=3;
  2077. }
  2078. //
  2079. // Replicate the scan line. It would be much better to write the scan line
  2080. // out to a memory buffer for drawing to a device surface
  2081. //
  2082. PBYTE pDst = (PBYTE)pSurfDst->pvScan0() +
  2083. lDelta * pgData->ptDraw.y +
  2084. 3 * pgData->ptDraw.x;
  2085. while (cyClip--)
  2086. {
  2087. memcpy(pDst,pBuffer,3*pgData->szDraw.cx);
  2088. pDst += lDelta;
  2089. }
  2090. FreeTmpBuffer(pBuffer);
  2091. }
  2092. }
  2093. }
  2094. else
  2095. {
  2096. //
  2097. // vertical gradient.
  2098. // replicate each x value accross whole scan line
  2099. //
  2100. PBYTE pDst = (PBYTE)pSurfDst->pvScan0() + lDelta * pgData->ptDraw.y;
  2101. LONGLONG lldRed = pgData->lldRdY;
  2102. LONGLONG lldGreen = pgData->lldGdY;
  2103. LONGLONG lldBlue = pgData->lldBdY;
  2104. //
  2105. // vertical gradient.
  2106. // replicate each x value accross whole scan line
  2107. //
  2108. if (pgData->yScanAdjust > 0)
  2109. {
  2110. clrR.ullColor += lldRed * (pgData->yScanAdjust);
  2111. clrG.ullColor += lldGreen * (pgData->yScanAdjust);
  2112. clrB.ullColor += lldBlue * (pgData->yScanAdjust);
  2113. }
  2114. pDst = pDst + 3 * pgData->ptDraw.x;
  2115. while (cyClip--)
  2116. {
  2117. //
  2118. // fill scan line with solid color
  2119. //
  2120. PBYTE pTemp = pDst;
  2121. PBYTE pEnd = pDst + 3 * pgData->szDraw.cx;
  2122. while (pTemp != pEnd)
  2123. {
  2124. *pTemp = clrR.b[6];
  2125. *(pTemp+1) = clrG.b[6];
  2126. *(pTemp+2) = clrB.b[6];
  2127. pTemp+=3;
  2128. }
  2129. //
  2130. // increment colors for next scan line
  2131. //
  2132. clrR.ullColor += lldRed;
  2133. clrG.ullColor += lldGreen;
  2134. clrB.ullColor += lldBlue;
  2135. //
  2136. // inc pointer to next scan line
  2137. //
  2138. pDst += lDelta;
  2139. }
  2140. }
  2141. }
  2142. /******************************Public*Routine******************************\
  2143. * vFillGRectDIB16_565
  2144. *
  2145. *
  2146. * Arguments:
  2147. *
  2148. * pSurfDst - destination surface
  2149. * pgData - gradient rect data
  2150. *
  2151. * Return Value:
  2152. *
  2153. * None
  2154. *
  2155. * History:
  2156. *
  2157. * 11/21/1996 Mark Enstrom [marke]
  2158. *
  2159. \**************************************************************************/
  2160. VOID
  2161. vFillGRectDIB16_565(
  2162. SURFACE *pSurfDst,
  2163. PGRADIENTRECTDATA pgData
  2164. )
  2165. {
  2166. LONG lDelta = pSurfDst->lDelta();
  2167. LONG cxClip = pgData->szDraw.cx;
  2168. LONG yScan = pgData->ptDraw.y;
  2169. LONG yScanBottom = yScan + pgData->szDraw.cy;
  2170. PBYTE pDst = (PBYTE)pSurfDst->pvScan0() + lDelta * pgData->ptDraw.y;
  2171. LONGLONG lldxRed = pgData->lldRdX;
  2172. LONGLONG lldxGreen = pgData->lldGdX;
  2173. LONGLONG lldxBlue = pgData->lldBdX;
  2174. LONGLONG lldyRed = pgData->lldRdY;
  2175. LONGLONG lldyGreen = pgData->lldGdY;
  2176. LONGLONG lldyBlue = pgData->lldBdY;
  2177. //
  2178. // lleRed,Green,Blue keep track of color gradient
  2179. // in y. This may be repeated each scan line for different
  2180. // dither values. PERF could allocate temp scan line
  2181. // buffer, run gradient 1 time and dither from this source
  2182. //
  2183. ULONGLONG lleRed;
  2184. ULONGLONG lleGreen;
  2185. ULONGLONG lleBlue;
  2186. lleRed = pgData->llRed;
  2187. lleGreen = pgData->llGreen;
  2188. lleBlue = pgData->llBlue;
  2189. PULONG pulDither;
  2190. //
  2191. // skip down to left edge
  2192. //
  2193. if (pgData->yScanAdjust)
  2194. {
  2195. lleRed += lldyRed * (pgData->yScanAdjust);
  2196. lleGreen += lldyGreen * (pgData->yScanAdjust);
  2197. lleBlue += lldyBlue * (pgData->yScanAdjust);
  2198. }
  2199. LONG yDitherOrg = pgData->ptDitherOrg.y;
  2200. LONG xDitherOrg = pgData->ptDitherOrg.x;
  2201. while(yScan < yScanBottom)
  2202. {
  2203. PUSHORT pusDstX;
  2204. PUSHORT pusDstScanRight,pusDstScanLeft;
  2205. LONG xScan;
  2206. COLOR_INTERP clrR,clrG,clrB,clrAlpha;
  2207. pulDither = &gulDither32[0] + 4 * ((yScan + yDitherOrg) & 3);
  2208. clrR.ullColor = lleRed;
  2209. clrG.ullColor = lleGreen;
  2210. clrB.ullColor = lleBlue;
  2211. if (pgData->xScanAdjust)
  2212. {
  2213. clrR.ullColor += lldxRed * (pgData->xScanAdjust);
  2214. clrG.ullColor += lldxGreen * (pgData->xScanAdjust);
  2215. clrB.ullColor += lldxBlue * (pgData->xScanAdjust);
  2216. }
  2217. xScan = pgData->ptDraw.x + xDitherOrg;
  2218. pusDstX = (PUSHORT)pDst + pgData->ptDraw.x;
  2219. pusDstScanRight = pusDstX + pgData->szDraw.cx;
  2220. while (pusDstX < pusDstScanRight)
  2221. {
  2222. ULONG ulDither = pulDither[xScan & 3];
  2223. ULONG iRed = Saturation16_5[((clrR.ul[1] >> (3)) + ulDither) >> 16];
  2224. ULONG iGreen = Saturation16_6[((clrG.ul[1] >> (2)) + ulDither) >> 16];
  2225. ULONG iBlue = Saturation16_5[((clrB.ul[1] >> (3)) + ulDither) >> 16];
  2226. *pusDstX = rgb565(iRed,iGreen,iBlue);
  2227. pusDstX++;
  2228. xScan++;
  2229. clrR.ullColor += lldxRed;
  2230. clrG.ullColor += lldxGreen;
  2231. clrB.ullColor += lldxBlue;
  2232. }
  2233. lleRed += lldyRed;
  2234. lleGreen += lldyGreen;
  2235. lleBlue += lldyBlue;
  2236. yScan++;
  2237. pDst += lDelta;
  2238. }
  2239. }
  2240. /******************************Public*Routine******************************\
  2241. * vFillGRectDIB16_555
  2242. *
  2243. *
  2244. * Arguments:
  2245. *
  2246. * pSurfDst - destination surface
  2247. * pgData - gradient rect data
  2248. *
  2249. * Return Value:
  2250. *
  2251. * None
  2252. *
  2253. * History:
  2254. *
  2255. * 11/21/1996 Mark Enstrom [marke]
  2256. *
  2257. \**************************************************************************/
  2258. VOID
  2259. vFillGRectDIB16_555(
  2260. SURFACE *pSurfDst,
  2261. PGRADIENTRECTDATA pgData
  2262. )
  2263. {
  2264. LONG lDelta = pSurfDst->lDelta();
  2265. LONG cxClip = pgData->szDraw.cx;
  2266. LONG yScan = pgData->ptDraw.y;
  2267. LONG yScanBottom = yScan + pgData->szDraw.cy;
  2268. PBYTE pDst = (PBYTE)pSurfDst->pvScan0() + lDelta * pgData->ptDraw.y;
  2269. LONGLONG lldxRed = pgData->lldRdX;
  2270. LONGLONG lldxGreen = pgData->lldGdX;
  2271. LONGLONG lldxBlue = pgData->lldBdX;
  2272. LONGLONG lldyRed = pgData->lldRdY;
  2273. LONGLONG lldyGreen = pgData->lldGdY;
  2274. LONGLONG lldyBlue = pgData->lldBdY;
  2275. //
  2276. // lleRed,Green,Blue keep track of color gradient
  2277. // in y. This may be repeated each scan line for different
  2278. // dither values. PERF could allocate temp scan line
  2279. // buffer, run gradient 1 time and dither from this source
  2280. //
  2281. ULONGLONG lleRed;
  2282. ULONGLONG lleGreen;
  2283. ULONGLONG lleBlue;
  2284. PULONG pulDither;
  2285. //
  2286. // skip down to left edge
  2287. //
  2288. lleRed = pgData->llRed;
  2289. lleGreen = pgData->llGreen;
  2290. lleBlue = pgData->llBlue;
  2291. if (pgData->yScanAdjust)
  2292. {
  2293. lleRed += lldyRed * (pgData->yScanAdjust);
  2294. lleGreen += lldyGreen * (pgData->yScanAdjust);
  2295. lleBlue += lldyBlue * (pgData->yScanAdjust);
  2296. }
  2297. LONG yDitherOrg = pgData->ptDitherOrg.y;
  2298. while(yScan < yScanBottom)
  2299. {
  2300. PUSHORT pusDstX;
  2301. PUSHORT pusDstScanRight,pusDstScanLeft;
  2302. COLOR_INTERP clrR,clrG,clrB,clrAlpha;
  2303. LONG xScan;
  2304. pulDither = &gulDither32[0] + 4 * ((yScan + yDitherOrg) & 3);
  2305. clrR.ullColor = lleRed;
  2306. clrG.ullColor = lleGreen;
  2307. clrB.ullColor = lleBlue;
  2308. if (pgData->xScanAdjust)
  2309. {
  2310. clrR.ullColor += lldxRed * (pgData->xScanAdjust);
  2311. clrG.ullColor += lldxGreen * (pgData->xScanAdjust);
  2312. clrB.ullColor += lldxBlue * (pgData->xScanAdjust);
  2313. }
  2314. xScan = pgData->ptDraw.x + pgData->ptDitherOrg.x;
  2315. pusDstX = (PUSHORT)pDst + pgData->ptDraw.x;
  2316. pusDstScanRight = pusDstX + pgData->szDraw.cx;
  2317. while (pusDstX < pusDstScanRight)
  2318. {
  2319. ULONG ulDither = pulDither[xScan & 3];
  2320. ULONG iRed = Saturation16_5[((clrR.ul[1] >> (3)) + ulDither) >> 16];
  2321. ULONG iGreen = Saturation16_5[((clrG.ul[1] >> (3)) + ulDither) >> 16];
  2322. ULONG iBlue = Saturation16_5[((clrB.ul[1] >> (3)) + ulDither) >> 16];
  2323. *pusDstX = rgb555(iRed,iGreen,iBlue);
  2324. pusDstX++;
  2325. xScan++;
  2326. clrR.ullColor += lldxRed;
  2327. clrG.ullColor += lldxGreen;
  2328. clrB.ullColor += lldxBlue;
  2329. }
  2330. lleRed += lldyRed;
  2331. lleGreen += lldyGreen;
  2332. lleBlue += lldyBlue;
  2333. yScan ++;
  2334. pDst += lDelta;
  2335. }
  2336. }
  2337. /**************************************************************************\
  2338. * vFillGRectDIB16Bitfields
  2339. *
  2340. * Run gradient at 16bpp and use 555 dither
  2341. *
  2342. * Arguments:
  2343. *
  2344. * pSurfDst - destination surface
  2345. * pgData - gradient rect data
  2346. *
  2347. * Return Value:
  2348. *
  2349. * None
  2350. *
  2351. * History:
  2352. *
  2353. * 2/18/1997 Mark Enstrom [marke]
  2354. *
  2355. \**************************************************************************/
  2356. VOID
  2357. vFillGRectDIB16Bitfields(
  2358. SURFACE *pSurfDst,
  2359. PGRADIENTRECTDATA pgData
  2360. )
  2361. {
  2362. LONG lDelta = pSurfDst->lDelta();
  2363. LONG yScan = pgData->ptDraw.y;
  2364. LONG yScanBottom = yScan + pgData->szDraw.cy;
  2365. PBYTE pDst = (PBYTE)pSurfDst->pvScan0() + lDelta * pgData->ptDraw.y;
  2366. LONGLONG lldxRed = pgData->lldRdX;
  2367. LONGLONG lldxGreen = pgData->lldGdX;
  2368. LONGLONG lldxBlue = pgData->lldBdX;
  2369. LONGLONG lldyRed = pgData->lldRdY;
  2370. LONGLONG lldyGreen = pgData->lldGdY;
  2371. LONGLONG lldyBlue = pgData->lldBdY;
  2372. ULONGLONG lleRed;
  2373. ULONGLONG lleGreen;
  2374. ULONGLONG lleBlue;
  2375. PULONG pulDither;
  2376. XEPALOBJ *ppalDstSurf = pgData->ppalDstSurf;
  2377. //
  2378. // skip down to left edge
  2379. //
  2380. lleRed = pgData->llRed;
  2381. lleGreen = pgData->llGreen;
  2382. lleBlue = pgData->llBlue;
  2383. if (pgData->yScanAdjust)
  2384. {
  2385. lleRed += lldyRed * (pgData->yScanAdjust);
  2386. lleGreen += lldyGreen * (pgData->yScanAdjust);
  2387. lleBlue += lldyBlue * (pgData->yScanAdjust);
  2388. }
  2389. LONG yDitherOrg = pgData->ptDitherOrg.y;
  2390. LONG xDitherOrg = pgData->ptDitherOrg.x;
  2391. while(yScan < yScanBottom)
  2392. {
  2393. PUSHORT pusDstX;
  2394. PUSHORT pusDstScanRight,pusDstScanLeft;
  2395. LONG xScan;
  2396. COLOR_INTERP clrR,clrG,clrB,clrAlpha;
  2397. pulDither = &gulDither32[0] + 4 * ((yScan + yDitherOrg) & 3);
  2398. clrR.ullColor = lleRed;
  2399. clrG.ullColor = lleGreen;
  2400. clrB.ullColor = lleBlue;
  2401. if (pgData->xScanAdjust)
  2402. {
  2403. clrR.ullColor += lldxRed * (pgData->xScanAdjust);
  2404. clrG.ullColor += lldxGreen * (pgData->xScanAdjust);
  2405. clrB.ullColor += lldxBlue * (pgData->xScanAdjust);
  2406. }
  2407. xScan = pgData->ptDraw.x + pgData->ptDitherOrg.x;
  2408. pusDstX = (PUSHORT)pDst + pgData->ptDraw.x;
  2409. pusDstScanRight = pusDstX + pgData->szDraw.cx;
  2410. while (pusDstX < pusDstScanRight)
  2411. {
  2412. ULONG ulDither = pulDither[xScan & 3];
  2413. ULONG iRed = Saturation16_5[((clrR.ul[1] >> (3)) + ulDither) >> 16];
  2414. ULONG iGreen = Saturation16_5[((clrG.ul[1] >> (3)) + ulDither) >> 16];
  2415. ULONG iBlue = Saturation16_5[((clrB.ul[1] >> (3)) + ulDither) >> 16];
  2416. //
  2417. // convert to 8 bit RGB for translation to bitfields
  2418. //
  2419. ULONG ulTemp = (iRed << ( 3)) |
  2420. (iGreen << (8 +3)) |
  2421. (iBlue << (8+8+3));
  2422. *pusDstX = (USHORT)ppalDstSurf->ulGetMatchFromPalentry(ulTemp);
  2423. pusDstX++;
  2424. xScan++;
  2425. clrR.ullColor += lldxRed;
  2426. clrG.ullColor += lldxGreen;
  2427. clrB.ullColor += lldxBlue;
  2428. }
  2429. lleRed += lldyRed;
  2430. lleGreen += lldyGreen;
  2431. lleBlue += lldyBlue;
  2432. yScan ++;
  2433. pDst += lDelta;
  2434. }
  2435. }
  2436. /******************************Public*Routine******************************\
  2437. * vFillGRectDIB8
  2438. *
  2439. *
  2440. * Arguments:
  2441. *
  2442. * pSurfDst - destination surface
  2443. * pgData - gradient rect data
  2444. *
  2445. *
  2446. * Return Value:
  2447. *
  2448. * None
  2449. *
  2450. * History:
  2451. *
  2452. * 11/21/1996 Mark Enstrom [marke]
  2453. *
  2454. \**************************************************************************/
  2455. VOID
  2456. vFillGRectDIB8(
  2457. SURFACE *pSurfDst,
  2458. PGRADIENTRECTDATA pgData
  2459. )
  2460. {
  2461. LONG lDelta = pSurfDst->lDelta();
  2462. LONG cxClip = pgData->szDraw.cx;
  2463. LONG yScan = pgData->ptDraw.y;
  2464. LONG yScanBottom = yScan + pgData->szDraw.cy;
  2465. PBYTE pDst = (PBYTE)pSurfDst->pvScan0() + lDelta * pgData->ptDraw.y;
  2466. LONGLONG lldxRed = pgData->lldRdX;
  2467. LONGLONG lldxGreen = pgData->lldGdX;
  2468. LONGLONG lldxBlue = pgData->lldBdX;
  2469. LONGLONG lldyRed = pgData->lldRdY;
  2470. LONGLONG lldyGreen = pgData->lldGdY;
  2471. LONGLONG lldyBlue = pgData->lldBdY;
  2472. //
  2473. // lleRed,Green,Blue keep track of color gradient
  2474. // in y. This may be repeated each scan line for different
  2475. // dither values. PERF could allocate temp scan line
  2476. // buffer, run gradient 1 time and dither from this source
  2477. //
  2478. ULONGLONG lleRed;
  2479. ULONGLONG lleGreen;
  2480. ULONGLONG lleBlue;
  2481. XLATEOBJ *pxlo = pgData->pxlo;
  2482. PBYTE pxlate = NULL;
  2483. PBYTE pjVector;
  2484. PBYTE pDitherMatrix;
  2485. PBYTE pSaturationTable;
  2486. //
  2487. // either use default palette or halftone palette dither
  2488. //
  2489. if (((XEPALOBJ) (((XLATE *) pxlo)->ppalDstDC)).bIsHalftone())
  2490. {
  2491. pDitherMatrix = gDitherMatrix16x16Halftone;
  2492. pSaturationTable = HalftoneSaturationTable;
  2493. }
  2494. else
  2495. {
  2496. pDitherMatrix = gDitherMatrix16x16Default;
  2497. pSaturationTable = DefaultSaturationTable;
  2498. }
  2499. //
  2500. // get/build rgb555 to palette table
  2501. //
  2502. pxlate = XLATEOBJ_pGetXlate555(pxlo);
  2503. if (pxlate == NULL)
  2504. {
  2505. WARNING("Failed to generate rgb333 xlate table\n");
  2506. return;
  2507. }
  2508. //
  2509. // determine DC to surface palette translate
  2510. //
  2511. if (((XLATE *) pxlo)->flPrivate & XLATE_PAL_MANAGED)
  2512. {
  2513. if (((XLATE *) pxlo)->ppalDstDC == ppalDefault)
  2514. {
  2515. pjVector = &defaultTranslate.ajVector[0];
  2516. pDitherMatrix = gDitherMatrix16x16Default;
  2517. pSaturationTable = DefaultSaturationTable;
  2518. }
  2519. else
  2520. {
  2521. if (((XLATE *) pxlo)->flPrivate & XLATE_USE_CURRENT)
  2522. {
  2523. pjVector = &((XLATE *) pxlo)->ppalDstDC->ptransCurrent->ajVector[0];
  2524. }
  2525. else
  2526. {
  2527. pjVector = &((XLATE *) pxlo)->ppalDstDC->ptransFore->ajVector[0];
  2528. }
  2529. }
  2530. }
  2531. else
  2532. {
  2533. pjVector = vTranslateIdentity;
  2534. }
  2535. //
  2536. // skip down to left edge
  2537. //
  2538. lleRed = pgData->llRed;
  2539. lleGreen = pgData->llGreen;
  2540. lleBlue = pgData->llBlue;
  2541. if (pgData->yScanAdjust)
  2542. {
  2543. lleRed += lldyRed * (pgData->yScanAdjust);
  2544. lleGreen += lldyGreen * (pgData->yScanAdjust);
  2545. lleBlue += lldyBlue * (pgData->yScanAdjust);
  2546. }
  2547. LONG xDitherOrg = pgData->ptDitherOrg.x;
  2548. LONG yDitherOrg = pgData->ptDitherOrg.y;
  2549. while(yScan < yScanBottom)
  2550. {
  2551. PBYTE pjDstX;
  2552. PBYTE pjDstScanRight;
  2553. COLOR_INTERP clrR,clrG,clrB,clrAlpha;
  2554. clrR.ullColor = lleRed;
  2555. clrG.ullColor = lleGreen;
  2556. clrB.ullColor = lleBlue;
  2557. if (pgData->xScanAdjust)
  2558. {
  2559. clrR.ullColor += lldxRed * (pgData->xScanAdjust);
  2560. clrG.ullColor += lldxGreen * (pgData->xScanAdjust);
  2561. clrB.ullColor += lldxBlue * (pgData->xScanAdjust);
  2562. }
  2563. pjDstX = pDst + pgData->ptDraw.x;
  2564. LONG xScan = pgData->ptDraw.x;
  2565. LONG xScanRight = xScan + pgData->szDraw.cx;
  2566. PBYTE pDitherLevel = &pDitherMatrix[(16 * ((yScan + yDitherOrg) & DITHER_8_MASK_Y))];
  2567. while (xScan < xScanRight)
  2568. {
  2569. //
  2570. // calculate x component of dither
  2571. //
  2572. BYTE jDitherMatrix = *(pDitherLevel + ((xScan + xDitherOrg) & DITHER_8_MASK_X));
  2573. ULONG iRed = pSaturationTable[clrR.b[6] + jDitherMatrix];
  2574. ULONG iGreen = pSaturationTable[clrG.b[6] + jDitherMatrix];
  2575. ULONG iBlue = pSaturationTable[clrB.b[6] + jDitherMatrix];
  2576. BYTE jIndex;
  2577. GRAD_PALETTE_MATCH(jIndex,pjVector,pxlate,((BYTE)iRed),((BYTE)iGreen),((BYTE)iBlue));
  2578. *pjDstX = jIndex;
  2579. pjDstX++;
  2580. xScan++;
  2581. clrR.ullColor += lldxRed;
  2582. clrG.ullColor += lldxGreen;
  2583. clrB.ullColor += lldxBlue;
  2584. }
  2585. pDst += lDelta;
  2586. //
  2587. // add y color increment
  2588. //
  2589. lleRed += lldyRed;
  2590. lleGreen += lldyGreen;
  2591. lleBlue += lldyBlue;
  2592. yScan++;
  2593. }
  2594. }
  2595. /******************************Public*Routine******************************\
  2596. * vFillGRectDIB4
  2597. *
  2598. *
  2599. * Arguments:
  2600. *
  2601. * pSurfDst - destination surface
  2602. * pgData - gradient rect data
  2603. *
  2604. *
  2605. * Return Value:
  2606. *
  2607. * None
  2608. *
  2609. * History:
  2610. *
  2611. * 11/21/1996 Mark Enstrom [marke]
  2612. *
  2613. \**************************************************************************/
  2614. VOID
  2615. vFillGRectDIB4(
  2616. SURFACE *pSurfDst,
  2617. PGRADIENTRECTDATA pgData
  2618. )
  2619. {
  2620. LONG lDelta = pSurfDst->lDelta();
  2621. LONG cxClip = pgData->szDraw.cx;
  2622. LONG cyClip = pgData->szDraw.cy;
  2623. LONG yScan = pgData->ptDraw.y;
  2624. LONG yScanBottom = yScan + cyClip;
  2625. PBYTE pDst = (PBYTE)pSurfDst->pvScan0() + lDelta * pgData->ptDraw.y;
  2626. LONGLONG lldxRed = pgData->lldRdX;
  2627. LONGLONG lldxGreen = pgData->lldGdX;
  2628. LONGLONG lldxBlue = pgData->lldBdX;
  2629. LONGLONG lldyRed = pgData->lldRdY;
  2630. LONGLONG lldyGreen = pgData->lldGdY;
  2631. LONGLONG lldyBlue = pgData->lldBdY;
  2632. //
  2633. // lleRed,Green,Blue keep track of color gradient
  2634. // in y. This may be repeated each scan line for different
  2635. // dither values. PERF could allocate temp scan line
  2636. // buffer, run gradient 1 time and dither from this source
  2637. //
  2638. ULONGLONG lleRed;
  2639. ULONGLONG lleGreen;
  2640. ULONGLONG lleBlue;
  2641. XLATEOBJ *pxlo = pgData->pxlo;
  2642. PBYTE pxlate = NULL;
  2643. PBYTE pjVector;
  2644. PBYTE pDitherMatrix = gDitherMatrix16x16Default;
  2645. PBYTE pSaturationTable = DefaultSaturationTable;
  2646. //
  2647. // determine DC to surface palette translate
  2648. //
  2649. if (((XLATE *) pxlo)->flPrivate & XLATE_PAL_MANAGED)
  2650. {
  2651. if (((XLATE *) pxlo)->ppalDstDC == ppalDefault)
  2652. {
  2653. pjVector = &defaultTranslate.ajVector[0];
  2654. }
  2655. else
  2656. {
  2657. if (((XLATE *) pxlo)->flPrivate & XLATE_USE_CURRENT)
  2658. {
  2659. pjVector = &((XLATE *) pxlo)->ppalDstDC->ptransCurrent->ajVector[0];
  2660. }
  2661. else
  2662. {
  2663. pjVector = &((XLATE *) pxlo)->ppalDstDC->ptransFore->ajVector[0];
  2664. }
  2665. }
  2666. }
  2667. else
  2668. {
  2669. pjVector = vTranslateIdentity;
  2670. }
  2671. //
  2672. // get/build rgb555 to palette table
  2673. //
  2674. pxlate = XLATEOBJ_pGetXlate555(pxlo);
  2675. if (pxlate == NULL)
  2676. {
  2677. WARNING("Failed to generate rgb333 xlate table\n");
  2678. return;
  2679. }
  2680. //
  2681. // skip down to left edge
  2682. //
  2683. lleRed = pgData->llRed;
  2684. lleGreen = pgData->llGreen;
  2685. lleBlue = pgData->llBlue;
  2686. if (pgData->yScanAdjust)
  2687. {
  2688. lleRed += lldyRed * (pgData->yScanAdjust);
  2689. lleGreen += lldyGreen * (pgData->yScanAdjust);
  2690. lleBlue += lldyBlue * (pgData->yScanAdjust);
  2691. }
  2692. LONG yDitherOrg = pgData->ptDitherOrg.y;
  2693. LONG xDitherOrg = pgData->ptDitherOrg.x;
  2694. while(yScan < yScanBottom)
  2695. {
  2696. PBYTE pjDstX;
  2697. PBYTE pDitherLevel = &pDitherMatrix[(16 * ((yScan + yDitherOrg) & DITHER_8_MASK_Y))];
  2698. COLOR_INTERP clrR,clrG,clrB,clrAlpha;
  2699. clrR.ullColor = lleRed;
  2700. clrG.ullColor = lleGreen;
  2701. clrB.ullColor = lleBlue;
  2702. if (pgData->xScanAdjust)
  2703. {
  2704. clrR.ullColor += lldxRed * (pgData->xScanAdjust);
  2705. clrG.ullColor += lldxGreen * (pgData->xScanAdjust);
  2706. clrB.ullColor += lldxBlue * (pgData->xScanAdjust);
  2707. }
  2708. pjDstX = pDst + pgData->ptDraw.x/2;
  2709. LONG xScan = pgData->ptDraw.x;
  2710. LONG xScanRight = xScan + pgData->szDraw.cx;
  2711. while (xScan < xScanRight)
  2712. {
  2713. //
  2714. // offset into dither array
  2715. //
  2716. BYTE jDitherMatrix;
  2717. jDitherMatrix = *(pDitherLevel + ((xScan + xDitherOrg) & DITHER_8_MASK_X));
  2718. ULONG iRed = pSaturationTable[clrR.b[6] + jDitherMatrix];
  2719. ULONG iGreen = pSaturationTable[clrG.b[6] + jDitherMatrix];
  2720. ULONG iBlue = pSaturationTable[clrB.b[6] + jDitherMatrix];
  2721. BYTE jIndex;
  2722. GRAD_PALETTE_MATCH(jIndex,pjVector,pxlate,((BYTE)iRed),((BYTE)iGreen),((BYTE)iBlue));
  2723. if (xScan & 1)
  2724. {
  2725. *pjDstX = (*pjDstX & 0xf0) | jIndex;
  2726. pjDstX++;
  2727. }
  2728. else
  2729. {
  2730. *pjDstX = (*pjDstX & 0x0f) | (jIndex << 4);
  2731. }
  2732. xScan++;
  2733. clrR.ullColor += lldxRed;
  2734. clrG.ullColor += lldxGreen;
  2735. clrB.ullColor += lldxBlue;
  2736. }
  2737. pDst += lDelta;
  2738. //
  2739. // add y color increment
  2740. //
  2741. lleRed += lldyRed;
  2742. lleGreen += lldyGreen;
  2743. lleBlue += lldyBlue;
  2744. yScan++;
  2745. }
  2746. }
  2747. /******************************Public*Routine******************************\
  2748. * vFillGRectDIB1
  2749. *
  2750. * Fill gradient rect
  2751. *
  2752. * Arguments:
  2753. *
  2754. * pSurfDst - destination surface
  2755. * pgData - gradient rect data
  2756. *
  2757. * Return Value:
  2758. *
  2759. * None
  2760. *
  2761. * History:
  2762. *
  2763. * 11/21/1996 Mark Enstrom [marke]
  2764. *
  2765. \**************************************************************************/
  2766. VOID
  2767. vFillGRectDIB1(
  2768. SURFACE *pSurfDst,
  2769. PGRADIENTRECTDATA pgData
  2770. )
  2771. {
  2772. LONG lDelta = pSurfDst->lDelta();
  2773. LONG cxClip = pgData->szDraw.cx;
  2774. LONG cyClip = pgData->szDraw.cy;
  2775. LONG yScan = pgData->ptDraw.y;
  2776. LONG yScanBottom = yScan + cyClip;
  2777. PBYTE pDst = (PBYTE)pSurfDst->pvScan0() + lDelta * pgData->ptDraw.y;
  2778. LONGLONG lldxRed = pgData->lldRdX;
  2779. LONGLONG lldxGreen = pgData->lldGdX;
  2780. LONGLONG lldxBlue = pgData->lldBdX;
  2781. LONGLONG lldyRed = pgData->lldRdY;
  2782. LONGLONG lldyGreen = pgData->lldGdY;
  2783. LONGLONG lldyBlue = pgData->lldBdY;
  2784. //
  2785. // lleRed,Green,Blue keep track of color gradient
  2786. // in y. This may be repeated each scan line for different
  2787. // dither values. PERF could allocate temp scan line
  2788. // buffer, run gradient 1 time and dither from this source
  2789. //
  2790. ULONGLONG lleRed;
  2791. ULONGLONG lleGreen;
  2792. ULONGLONG lleBlue;
  2793. XLATEOBJ *pxlo = pgData->pxlo;
  2794. PBYTE pxlate = NULL;
  2795. PBYTE pjVector = vTranslateIdentity;
  2796. PBYTE pDitherMatrix = gDitherMatrix16x16Default;
  2797. //
  2798. // get/build rgb555 to palette table
  2799. //
  2800. pxlate = XLATEOBJ_pGetXlate555(pxlo);
  2801. if (pxlate == NULL)
  2802. {
  2803. WARNING("Failed to generate rgb555 xlate table\n");
  2804. return;
  2805. }
  2806. //
  2807. // skip down to left edge
  2808. //
  2809. lleRed = pgData->llRed;
  2810. lleGreen = pgData->llGreen;
  2811. lleBlue = pgData->llBlue;
  2812. if (pgData->yScanAdjust)
  2813. {
  2814. lleRed += lldyRed * (pgData->yScanAdjust);
  2815. lleGreen += lldyGreen * (pgData->yScanAdjust);
  2816. lleBlue += lldyBlue * (pgData->yScanAdjust);
  2817. }
  2818. LONG yDitherOrg = pgData->ptDitherOrg.y;
  2819. LONG xDitherOrg = pgData->ptDitherOrg.x;
  2820. while(yScan < yScanBottom)
  2821. {
  2822. PBYTE pjDstX;
  2823. LONG ixDst;
  2824. LONG cx = cxClip;
  2825. LONG xScanLeft = pgData->ptDraw.x;
  2826. LONG xScanRight = xScanLeft + cx;
  2827. PBYTE pDitherLevel = &pDitherMatrix[(16 * ((yScan + yDitherOrg) & DITHER_8_MASK_Y))];
  2828. COLOR_INTERP clrR,clrG,clrB,clrAlpha;
  2829. clrR.ullColor = lleRed;
  2830. clrG.ullColor = lleGreen;
  2831. clrB.ullColor = lleBlue;
  2832. if (pgData->xScanAdjust)
  2833. {
  2834. clrR.ullColor += lldxRed * (pgData->xScanAdjust);
  2835. clrG.ullColor += lldxGreen * (pgData->xScanAdjust);
  2836. clrB.ullColor += lldxBlue * (pgData->xScanAdjust);
  2837. }
  2838. pjDstX = pDst + pgData->ptDraw.x/8;
  2839. ixDst = pgData->ptDraw.x & 7;
  2840. while (xScanLeft < xScanRight)
  2841. {
  2842. //
  2843. // offset into dither array
  2844. //
  2845. BYTE jDitherMatrix = 2 * (*(pDitherLevel + ((xScanLeft + xDitherOrg) & DITHER_8_MASK_X)));
  2846. ULONG iRed = (ULONG)(clrR.b[6]);
  2847. ULONG iGreen = (ULONG)(clrG.b[6]);
  2848. ULONG iBlue = (ULONG)(clrB.b[6]);
  2849. //
  2850. // add dither and saturate. 1bpp non-optimized
  2851. //
  2852. iRed = iRed + jDitherMatrix;
  2853. if (iRed >= 255)
  2854. {
  2855. iRed = 255;
  2856. }
  2857. else
  2858. {
  2859. iRed = 0;
  2860. }
  2861. iGreen = iGreen + jDitherMatrix;
  2862. if (iGreen >= 255)
  2863. {
  2864. iGreen = 255;
  2865. }
  2866. else
  2867. {
  2868. iGreen = 0;
  2869. }
  2870. iBlue = iBlue + jDitherMatrix;
  2871. if (iBlue >= 255)
  2872. {
  2873. iBlue = 255;
  2874. }
  2875. else
  2876. {
  2877. iBlue = 0;
  2878. }
  2879. BYTE jIndex;
  2880. //
  2881. // pjVector is known to be identity, so could make new macro for
  2882. // palette_match_1 if perf ever an issue
  2883. //
  2884. GRAD_PALETTE_MATCH(jIndex,pjVector,pxlate,((BYTE)iRed),((BYTE)iGreen),((BYTE)iBlue));
  2885. LONG iShift = 7 - ixDst;
  2886. BYTE OrMask = 1 << iShift;
  2887. BYTE AndMask = ~OrMask;
  2888. jIndex = jIndex << iShift;
  2889. *pjDstX = (*pjDstX & AndMask) | jIndex;
  2890. ixDst++;
  2891. if (ixDst == 8)
  2892. {
  2893. ixDst = 0;
  2894. pjDstX++;
  2895. }
  2896. clrR.ullColor += lldxRed;
  2897. clrG.ullColor += lldxGreen;
  2898. clrB.ullColor += lldxBlue;
  2899. xScanLeft++;
  2900. }
  2901. pDst += lDelta;
  2902. //
  2903. // add y color increment
  2904. //
  2905. lleRed += lldyRed;
  2906. lleGreen += lldyGreen;
  2907. lleBlue += lldyBlue;
  2908. yScan++;
  2909. }
  2910. }