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.

870 lines
20 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: solid.cxx
  3. *
  4. * This contains the special case blting code for P, Pn, DPx and Dn rops
  5. * with solid colors.
  6. *
  7. * Created: 03-Mar-1991 22:01:14
  8. * Author: Patrick Haluptzok patrickh
  9. *
  10. * Copyright (c) 1991-1999 Microsoft Corporation
  11. \**************************************************************************/
  12. #include "precomp.hxx"
  13. // Array of masks for blting
  14. ULONG aulMsk[] =
  15. {
  16. 0xFFFFFFFF,
  17. 0xFFFFFF7F,
  18. 0xFFFFFF3F,
  19. 0xFFFFFF1F,
  20. 0xFFFFFF0F,
  21. 0xFFFFFF07,
  22. 0xFFFFFF03,
  23. 0xFFFFFF01,
  24. 0xFFFFFF00,
  25. 0xFFFF7F00,
  26. 0xFFFF3F00,
  27. 0xFFFF1F00,
  28. 0xFFFF0F00,
  29. 0xFFFF0700,
  30. 0xFFFF0300,
  31. 0xFFFF0100,
  32. 0xFFFF0000,
  33. 0xFF7F0000,
  34. 0xFF3F0000,
  35. 0xFF1F0000,
  36. 0xFF0F0000,
  37. 0xFF070000,
  38. 0xFF030000,
  39. 0xFF010000,
  40. 0xFF000000,
  41. 0x7F000000,
  42. 0x3F000000,
  43. 0x1F000000,
  44. 0x0F000000,
  45. 0x07000000,
  46. 0x03000000,
  47. 0x01000000,
  48. };
  49. #define DBG_SOLID 0
  50. #if DBG_SOLID
  51. ULONG DbgSolid = 0;
  52. #endif
  53. /******************************Public*Routine******************************\
  54. * vSolidFillRect1
  55. *
  56. * Does a solid blt to a DIB of 1, 4, 8, 16 or 32 bpp.
  57. *
  58. * History:
  59. *
  60. * 17-Nov-1992 -by- Jim Thomas [jimt]
  61. * Change call to work on list of rectangles.
  62. * Change center loop to call RtlFillMemory only for wide
  63. * scan lines
  64. *
  65. * 03-Feb-1992 -by- Donald Sidoroff [donalds]
  66. * Rewrote it.
  67. *
  68. * 01-Mar-1991 -by- Patrick Haluptzok patrickh
  69. * Wrote it.
  70. \**************************************************************************/
  71. VOID vSolidFillRect1(
  72. PRECTL prcl,
  73. ULONG cRcl,
  74. PBYTE pjDst,
  75. LONG lDeltaDst,
  76. ULONG iColor,
  77. ULONG cShift)
  78. {
  79. ULONG ulMskLeft;
  80. ULONG ulMskRight;
  81. ULONG cLeft;
  82. ULONG cRight;
  83. ULONG cxDword;
  84. ULONG yRow;
  85. ULONG ulColor;
  86. PULONG pulTmp;
  87. PULONG pulDst;
  88. ULONG cx;
  89. ULONG cy;
  90. ULONG xDstStart;
  91. #if DBG_SOLID
  92. if (DbgSolid >= 1) {
  93. DbgPrint("SolidFillRect1:\n");
  94. DbgPrint(" pjDst = 0x%08lx\n",pjDst);
  95. if (DbgSolid >= 2) {
  96. DbgPrint(" prcl = 0x%08lx\n",prcl);
  97. DbgPrint(" cRcl = %li\n",cRcl);
  98. DbgPrint(" lDeltaDst = %li\n",lDeltaDst);
  99. DbgPrint(" iColor = 0x%08lx\n",iColor);
  100. DbgPrint(" cShift = %li\n",cShift);
  101. }
  102. }
  103. #endif
  104. //
  105. // loop through each rectangle
  106. //
  107. for ( ;cRcl > 0;cRcl--, prcl++ )
  108. {
  109. //
  110. // make sure rectangle is well ordered
  111. //
  112. ASSERTGDI(prcl != NULL,"ERROR: prcl = NULL");
  113. ASSERTGDI(prcl->right > prcl->left,"ERROR: left >= right");
  114. ASSERTGDI(prcl->bottom > prcl->top, "ERROR: top >= bottom");
  115. #if DBG_SOLID
  116. if (DbgSolid >= 1) {
  117. DbgPrint(" Rect: %li,%li to %li,%li\n",
  118. prcl->left,prcl->top,
  119. prcl->right,prcl->bottom);
  120. }
  121. #endif
  122. pulDst = (PULONG)(pjDst + prcl->top * lDeltaDst);
  123. cy = prcl->bottom - prcl->top;
  124. //
  125. // cx is the number of bits in the scan line to fill
  126. //
  127. cx = (prcl->right - prcl->left) << cShift;
  128. //
  129. // Starting bit
  130. //
  131. xDstStart = prcl->left << cShift;
  132. //
  133. // starting and ending DWORD offset
  134. //
  135. cLeft = xDstStart >> 5;
  136. cRight = (xDstStart + cx) >> 5;
  137. //
  138. // generate left and right bit masks
  139. //
  140. ulMskLeft = aulMsk[xDstStart & 0x1f];
  141. ulMskRight = aulMsk[(xDstStart+cx) & 0x1f];
  142. //
  143. // if cLeft equals cRight then onyl 1 DWORD needs to be modified,
  144. // combine left and right masks. Do entire strip.
  145. //
  146. if (cLeft == cRight) {
  147. ulMskLeft &= ~ulMskRight;
  148. ulColor = iColor & ulMskLeft;
  149. ulMskLeft = ~ulMskLeft;
  150. pulTmp = pulDst + cLeft;
  151. while (cy--) {
  152. *pulTmp = (*pulTmp & ulMskLeft) | ulColor;
  153. pulTmp = (PULONG)((PBYTE)pulTmp + lDeltaDst);
  154. }
  155. } else {
  156. //
  157. // do solid fill in three portions,
  158. //
  159. // left edge (partial DWORD)
  160. // center (full DWORD)
  161. // right edge (partial DWORD)
  162. //
  163. //
  164. // left strip
  165. //
  166. if (ulMskLeft != ~0) {
  167. pulTmp = pulDst + cLeft;
  168. ulColor = iColor & ulMskLeft;
  169. ulMskLeft = ~ulMskLeft;
  170. yRow = cy;
  171. while (yRow--) {
  172. *pulTmp = (*pulTmp & ulMskLeft) | ulColor;
  173. pulTmp = (PULONG)((PBYTE)pulTmp + lDeltaDst);
  174. }
  175. cLeft++;
  176. }
  177. //
  178. // center calc number of DWORDS
  179. //
  180. cxDword = cRight - cLeft;
  181. pulTmp = pulDst + cLeft;
  182. if (cxDword != 0) {
  183. yRow = cy;
  184. while (yRow--) {
  185. switch (cxDword) {
  186. case 7:
  187. *(pulTmp+6) = iColor;
  188. case 6:
  189. *(pulTmp+5) = iColor;
  190. case 5:
  191. *(pulTmp+4) = iColor;
  192. case 4:
  193. *(pulTmp+3) = iColor;
  194. case 3:
  195. *(pulTmp+2) = iColor;
  196. case 2:
  197. *(pulTmp+1) = iColor;
  198. case 1:
  199. *(pulTmp) = iColor;
  200. break;
  201. default:
  202. RtlFillMemoryUlong((PVOID)pulTmp,cxDword<<2,iColor);
  203. }
  204. pulTmp = (PULONG)((PBYTE)pulTmp + lDeltaDst);
  205. }
  206. }
  207. //
  208. // right edge
  209. //
  210. if (ulMskRight != ~0) {
  211. pulTmp = pulDst + cRight;
  212. ulColor = iColor & ~ulMskRight;
  213. while (cy--) {
  214. *pulTmp = (*pulTmp & ulMskRight) | ulColor;
  215. pulTmp = (PULONG)((PBYTE)pulTmp + lDeltaDst);
  216. }
  217. }
  218. }
  219. }
  220. }
  221. /******************************Public*Routine******************************\
  222. * vSolidFillRect24
  223. *
  224. * Does a solid blt to a 24 bpp DIB.
  225. *
  226. * History:
  227. *
  228. * 17-Nov-1992 -by- Jim Thomas [jimt]
  229. * Change call to list of rects
  230. *
  231. * 02-Mar-1991 -by- Patrick Haluptzok patrickh
  232. * Wrote it.
  233. \**************************************************************************/
  234. VOID vSolidFillRect24(
  235. PRECTL prcl,
  236. ULONG cRcl,
  237. PBYTE pjDst,
  238. LONG lDeltaDst,
  239. ULONG iColor,
  240. ULONG cShift)
  241. {
  242. PBYTE pjDstRow;
  243. BYTE jRed,jGreen,jBlue;
  244. ULONG cxTemp;
  245. ULONG cx;
  246. ULONG cy;
  247. LONG lDelta;
  248. DONTUSE(cShift);
  249. //
  250. // place any asserts here
  251. //
  252. jRed = (BYTE)iColor;
  253. jGreen = (BYTE)(iColor >> 8);
  254. jBlue = (BYTE)(iColor >> 16);
  255. //
  256. // loop through each rectangle
  257. //
  258. for ( ;cRcl > 0;cRcl--, prcl++ )
  259. {
  260. pjDstRow = pjDst + (prcl->top * lDeltaDst) + 3 * prcl->left;
  261. cy = prcl->bottom - prcl->top;
  262. cx = prcl->right - prcl->left;
  263. //
  264. // lDelta is adjusted to go from the end of one scan
  265. // line to the start of the next.
  266. //
  267. lDelta = lDeltaDst - 3*cx;
  268. while (cy--) {
  269. cxTemp = cx;
  270. while (cxTemp--) {
  271. *(pjDstRow) = jRed;
  272. *(pjDstRow+1) = jGreen;
  273. *(pjDstRow+2) = jBlue;
  274. pjDstRow += 3;
  275. }
  276. pjDstRow += lDelta;
  277. }
  278. }
  279. }
  280. /******************************Public*Routine******************************\
  281. * vSolidXorRect1
  282. *
  283. * Does an xor blt to a DIB or 1, 4, 8, 16 or 32 bpp.
  284. *
  285. * History:
  286. *
  287. * 17-Nov-1992 -by- Jim Thomas [jimt]
  288. * Change call to list of rects
  289. *
  290. *
  291. * 03-Feb-1992 -by- Donald Sidoroff [donalds]
  292. * Rewrote it.
  293. *
  294. * 01-Mar-1991 -by- Patrick Haluptzok patrickh
  295. * Wrote it.
  296. \**************************************************************************/
  297. VOID vSolidXorRect1(
  298. PRECTL prcl,
  299. ULONG cRcl,
  300. PBYTE pjDst,
  301. LONG lDeltaDst,
  302. ULONG iColor,
  303. ULONG cShift)
  304. {
  305. ULONG ulMskLeft;
  306. ULONG ulMskRight;
  307. ULONG iLeft;
  308. ULONG iRight;
  309. ULONG cLeft;
  310. ULONG cRight;
  311. ULONG culFill;
  312. ULONG yRow;
  313. PULONG pulTmp;
  314. PULONG pulDst;
  315. ULONG cx;
  316. ULONG cy;
  317. ULONG xDstStart;
  318. BOOL bSimple;
  319. #if DBG_SOLID
  320. if (DbgSolid >= 1) {
  321. DbgPrint("SolidXorRect1:\n");
  322. DbgPrint(" pjDst = 0x%08lx\n",pjDst);
  323. if (DbgSolid >= 2) {
  324. DbgPrint(" prcl = 0x%08lx\n",prcl);
  325. DbgPrint(" cRcl = %li\n",cRcl);
  326. DbgPrint(" lDeltaDst = %li\n",lDeltaDst);
  327. DbgPrint(" iColor = 0x%08lx\n",iColor);
  328. DbgPrint(" cShift = %li\n",cShift);
  329. }
  330. }
  331. #endif
  332. //
  333. // loop through each rectangle
  334. //
  335. for ( ; cRcl > 0;cRcl--, prcl++ )
  336. {
  337. //
  338. // init rect params
  339. //
  340. ASSERTGDI(prcl != NULL,"ERROR: prcl = NULL");
  341. ASSERTGDI(prcl->right > prcl->left,"ERROR: left >= right");
  342. ASSERTGDI(prcl->bottom > prcl->top, "ERROR: top >= bottom");
  343. pulDst = (PULONG)(pjDst + prcl->top * lDeltaDst);
  344. cx = (prcl->right - prcl->left) << cShift;
  345. cy = prcl->bottom - prcl->top;
  346. xDstStart = (prcl->left << cShift);
  347. //
  348. // calc index of leftmost and rightmost DWORDS
  349. //
  350. cLeft = xDstStart >> 5;
  351. cRight = (xDstStart + cx) >> 5;
  352. //
  353. // calc number of bits used in leftmost and rightmost DWORDs
  354. //
  355. iLeft = xDstStart & 31;
  356. iRight = (xDstStart + cx) & 31;
  357. //
  358. // generate DWORD store masks
  359. //
  360. ulMskLeft = aulMsk[iLeft];
  361. ulMskRight = ~aulMsk[iRight];
  362. //
  363. // If the leftmost and rightmost DWORDs are the same, then only one
  364. // strip is needed. Merge the two masks together and note this.
  365. //
  366. bSimple = FALSE;
  367. if (cLeft == cRight)
  368. {
  369. ulMskLeft &= ulMskRight;
  370. bSimple = TRUE;
  371. }
  372. #if DBG_SOLID
  373. if (DbgSolid >= 1) {
  374. DbgPrint(" Rect: %li,%li to %li,%li\n",
  375. prcl->left,prcl->top,
  376. prcl->right,prcl->bottom);
  377. }
  378. #endif
  379. //
  380. // Lay down the left edge, if needed.
  381. //
  382. if (bSimple || (iLeft != 0))
  383. {
  384. pulTmp = pulDst + cLeft;
  385. ulMskLeft &= iColor;
  386. for (yRow = 0; yRow != cy; yRow++)
  387. {
  388. *pulTmp ^= ulMskLeft;
  389. pulTmp = (ULONG *) ((BYTE *) pulTmp + lDeltaDst);
  390. }
  391. cLeft++;
  392. }
  393. if (!bSimple) {
  394. //
  395. // Lay down the center strip, if needed.
  396. //
  397. culFill = cRight - cLeft;
  398. if (culFill != 0)
  399. {
  400. pulTmp = pulDst + cLeft;
  401. for (yRow = 0; yRow != cy; yRow++)
  402. {
  403. cx = culFill;
  404. while (cx--)
  405. *pulTmp++ ^= iColor;
  406. pulTmp -= culFill;
  407. pulTmp = (ULONG *) ((BYTE *) pulTmp + lDeltaDst);
  408. }
  409. }
  410. //
  411. // Lay down the right edge, if needed.
  412. //
  413. if (iRight != 0)
  414. {
  415. pulTmp = pulDst + cRight;
  416. ulMskRight &= iColor;
  417. for (yRow = 0; yRow != cy; yRow++)
  418. {
  419. *pulTmp ^= ulMskRight;
  420. pulTmp = (ULONG *) ((BYTE *) pulTmp + lDeltaDst);
  421. }
  422. }
  423. }
  424. }
  425. }
  426. /******************************Public*Routine******************************\
  427. * vSolidXorRect24
  428. *
  429. * Does a solid blt to a 24 bpp DIB.
  430. *
  431. * History:
  432. *
  433. * 17-Nov-1992 -by- Jim Thomes [jimt]
  434. * change call to list of rects
  435. *
  436. * 03-Feb-1992 -by- Donald Sidoroff [donalds]
  437. * Rewrote it.
  438. *
  439. * 02-Mar-1991 -by- Patrick Haluptzok patrickh
  440. * Wrote it.
  441. \**************************************************************************/
  442. VOID vSolidXorRect24(
  443. PRECTL prcl,
  444. ULONG cRcl,
  445. PBYTE pjDst,
  446. LONG lDeltaDst,
  447. ULONG iColor,
  448. ULONG cShift)
  449. {
  450. PBYTE pjDstTmp;
  451. BYTE jRed, jGreen, jBlue;
  452. ULONG cxTemp;
  453. ULONG cx;
  454. ULONG cy;
  455. LONG lDelta;
  456. DONTUSE(cShift);
  457. //
  458. // lDelta is adjusted to go from the end of one scan
  459. // line to the start of the next.
  460. //
  461. jRed = (BYTE) iColor;
  462. jGreen = (BYTE) (iColor >> 8);
  463. jBlue = (BYTE) (iColor >> 16);
  464. for ( ;cRcl > 0;cRcl--, prcl++ )
  465. {
  466. //
  467. // init rect params
  468. //
  469. pjDstTmp = pjDst + prcl->top * lDeltaDst + prcl->left * 3;
  470. cx = prcl->right - prcl->left;
  471. cy = prcl->bottom - prcl->top;
  472. lDelta = lDeltaDst - (3 * cx);
  473. ASSERTGDI(cx != 0, "ERROR vDibSolidBlt32");
  474. ASSERTGDI(cy != 0, "ERROR vDibSolidBlt32");
  475. while(cy--)
  476. {
  477. cxTemp = cx;
  478. while(cxTemp--)
  479. {
  480. *(pjDstTmp) ^= jRed;
  481. *(pjDstTmp+1) ^= jGreen;
  482. *(pjDstTmp+2) ^= jBlue;
  483. pjDstTmp += 3;
  484. }
  485. pjDstTmp = pjDstTmp + lDelta;
  486. }
  487. }
  488. }
  489. /******************************Public*Routine******************************\
  490. * vSolidFillRow1
  491. *
  492. * Blt a list of adjacent rows to a DIB of of 1, 4, 8, 16 or 32 bpp.
  493. *
  494. * History:
  495. * 11-Oct-1993 -by- Eric Kutter [erick]
  496. * Wrote it.
  497. \**************************************************************************/
  498. VOID vSolidFillRow1(
  499. PROW prow,
  500. ULONG crow,
  501. LONG yTop,
  502. PBYTE pjBits,
  503. ULONG iColor,
  504. LONG lDelta,
  505. ULONG cShift)
  506. {
  507. pjBits += yTop * lDelta;
  508. for (UINT i = 0; i < crow; i++, prow++, pjBits += lDelta)
  509. {
  510. ULONG *pulDst = (PULONG)pjBits;
  511. LONG cx = (prow->right - prow->left) << cShift;
  512. ULONG xDstStart = prow->left << cShift;
  513. BOOL bSimple = FALSE;
  514. ULONG cLeft = xDstStart >> 5; // Index of leftmost DWORD
  515. ULONG cRght = (xDstStart + cx) >> 5; // Index of rightmost DWORD
  516. ULONG iLeft = xDstStart & 31; // Bits used in leftmost DWORD
  517. ULONG iRght = (xDstStart + cx) & 31; // Bits used in rightmost DWORD
  518. ULONG ulMskLeft = aulMsk[iLeft];
  519. ULONG ulMskRght = ~aulMsk[iRght];
  520. // If the leftmost and rightmost DWORDs are the same, then only one
  521. // strip is needed. Merge the two masks together and note this.
  522. if (cLeft == cRght)
  523. {
  524. ulMskLeft &= ulMskRght;
  525. bSimple = TRUE;
  526. }
  527. // Lay down the left edge, if needed.
  528. if (bSimple || (iLeft != 0))
  529. {
  530. pulDst[cLeft] = (pulDst[cLeft] & ~ulMskLeft) | (iColor & ulMskLeft);
  531. if (bSimple)
  532. continue;
  533. cLeft++;
  534. }
  535. // Lay down the center strip, if needed.
  536. ULONG cjFill = (cRght - cLeft) << 2;
  537. if (cjFill != 0)
  538. RtlFillMemoryUlong((PVOID) (pulDst+cLeft), cjFill, iColor);
  539. // Lay down the right edge, if needed.
  540. if (iRght != 0)
  541. pulDst[cRght] = (pulDst[cRght] & ~ulMskRght) | (iColor & ulMskRght);
  542. }
  543. }
  544. /******************************Public*Routine******************************\
  545. * vSolidFillRow24
  546. *
  547. * Blt a list of adjacent rows to a 24 bpp DIB.
  548. *
  549. * History:
  550. * 12-Oct-1993 -by- Eric Kutter [erick]
  551. * Wrote it.
  552. \**************************************************************************/
  553. VOID vSolidFillRow24(
  554. PROW prow,
  555. ULONG crow,
  556. LONG yTop,
  557. PBYTE pjBits,
  558. ULONG iColor,
  559. LONG lDelta,
  560. ULONG cShift)
  561. {
  562. BYTE jRed, jGreen, jBlue;
  563. jRed = (BYTE) iColor;
  564. jGreen = (BYTE) (iColor >> 8);
  565. jBlue = (BYTE) (iColor >> 16);
  566. pjBits += (yTop * lDelta);
  567. for (UINT i = 0; i < crow; i++, prow++, pjBits += lDelta)
  568. {
  569. LONG cx = (prow->right - prow->left) << cShift;
  570. ULONG xDstStart = prow->left << cShift;
  571. BYTE* pjDst = pjBits + (3 * xDstStart);
  572. ULONG cxTemp = cx;
  573. while(cxTemp--)
  574. {
  575. *(pjDst++) = jRed;
  576. *(pjDst++) = jGreen;
  577. *(pjDst++) = jBlue;
  578. }
  579. }
  580. }
  581. /******************************Public*Routine******************************\
  582. * vSolidXorRow1
  583. *
  584. * Does an xor blt of a list of adjacent rows to a DIB or 1, 4, 8, 16 or 32 bpp.
  585. *
  586. * History:
  587. * 12-Oct-1993 -by- Eric Kutter [erick]
  588. * Wrote it.
  589. \**************************************************************************/
  590. VOID vSolidXorRow1(
  591. PROW prow,
  592. ULONG crow,
  593. LONG yTop,
  594. PBYTE pjBits,
  595. ULONG iColor,
  596. LONG lDelta,
  597. ULONG cShift)
  598. {
  599. pjBits += yTop * lDelta;
  600. for (UINT i = 0; i < crow; i++, prow++,pjBits += lDelta)
  601. {
  602. ULONG* pulDst = (ULONG *) pjBits;
  603. LONG cx = (prow->right - prow->left) << cShift;
  604. ULONG xDstStart = prow->left << cShift;
  605. ULONG ulMskLeft;
  606. ULONG ulMskRght;
  607. ULONG iLeft;
  608. ULONG iRght;
  609. ULONG cLeft;
  610. ULONG cRght;
  611. ULONG culFill;
  612. BOOL bSimple = FALSE;
  613. cLeft = xDstStart >> 5; // Index of leftmost DWORD
  614. cRght = (xDstStart + cx) >> 5; // Index of rightmost DWORD
  615. iLeft = xDstStart & 31; // Bits used in leftmost DWORD
  616. iRght = (xDstStart + cx) & 31; // Bits used in rightmost DWORD
  617. ulMskLeft = aulMsk[iLeft];
  618. ulMskRght = ~aulMsk[iRght];
  619. // If the leftmost and rightmost DWORDs are the same, then only one
  620. // strip is needed. Merge the two masks together and note this.
  621. if (cLeft == cRght)
  622. {
  623. ulMskLeft &= ulMskRght;
  624. bSimple = TRUE;
  625. }
  626. // Lay down the left edge, if needed.
  627. if (bSimple || (iLeft != 0))
  628. {
  629. ulMskLeft &= iColor;
  630. pulDst[cLeft] ^= ulMskLeft;
  631. if (bSimple)
  632. continue;
  633. cLeft++;
  634. }
  635. // Lay down the center strip, if needed.
  636. culFill = cRght - cLeft;
  637. if (culFill != 0)
  638. {
  639. PULONG pulTmp = pulDst + cLeft;
  640. cx = culFill;
  641. while (cx--)
  642. *pulTmp++ ^= iColor;
  643. }
  644. // Lay down the right edge, if needed.
  645. if (iRght != 0)
  646. {
  647. ulMskRght &= iColor;
  648. pulDst[cRght] ^= ulMskRght;
  649. }
  650. }
  651. }
  652. /******************************Public*Routine******************************\
  653. * vSolidXorRow24
  654. *
  655. * Does a solid blt with a list of adjacent rows to a 24 bpp DIB.
  656. *
  657. * History:
  658. * 12-Oct-1993 -by- Eric Kutter [erick]
  659. * Wrote it.
  660. \**************************************************************************/
  661. VOID vSolidXorRow24(
  662. PROW prow,
  663. ULONG crow,
  664. LONG yTop,
  665. PBYTE pjBits,
  666. ULONG iColor,
  667. LONG lDelta,
  668. ULONG cShift)
  669. {
  670. BYTE jRed, jGreen, jBlue;
  671. jRed = (BYTE) iColor;
  672. jGreen = (BYTE) (iColor >> 8);
  673. jBlue = (BYTE) (iColor >> 16);
  674. pjBits += yTop * lDelta;
  675. for (UINT i = 0; i < crow; i++, prow++, pjBits += lDelta)
  676. {
  677. LONG cx = (prow->right - prow->left) << cShift;
  678. ULONG xDstStart = prow->left << cShift;
  679. BYTE* pjDst = pjBits + (3 * xDstStart);
  680. ULONG cxTemp = cx;
  681. while(cxTemp--)
  682. {
  683. *(pjDst++) ^= jRed;
  684. *(pjDst++) ^= jGreen;
  685. *(pjDst++) ^= jBlue;
  686. }
  687. }
  688. }