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.

2653 lines
60 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: rotate.cxx
  3. *
  4. * Internal DDAs for EngPlgBlt
  5. *
  6. * Created: 06-Aug-1992 15:35:02
  7. * Author: Donald Sidoroff [donalds]
  8. *
  9. * Copyright (c) 1992-1999 Microsoft Corporation
  10. \**************************************************************************/
  11. #include "precomp.hxx"
  12. #include "rotate.hxx"
  13. #ifdef DBG_PLGBLT
  14. extern BOOL gflPlgBlt;
  15. #endif
  16. int aiPlgConst[][6] = {
  17. { 1, 0, 0, 0, 1, 0 },
  18. { 0, 1, 0, 1, 0, 0 },
  19. { -1, 0, 1, 0, 1, 0 },
  20. { 0, 1, 0, -1, 0, 1 },
  21. { 0, -1, 1, 1, 0, 0 },
  22. { 1, 0, 0, 0, -1, 1 },
  23. { 0, -1, 1, -1, 0, 1 },
  24. { -1, 0, 1, 0, -1, 1 }
  25. };
  26. int aiPlgSort[][4] = {
  27. { 0, 1, 2, 3 },
  28. { 0, 2, 1, 3 },
  29. { 1, 0, 3, 2 },
  30. { 1, 3, 0, 2 },
  31. { 2, 0, 3, 1 },
  32. { 2, 3, 0, 1 },
  33. { 3, 1, 2, 0 },
  34. { 3, 2, 1, 0 }
  35. };
  36. static VOID ROT_DIV(
  37. DIV_T *pdt,
  38. LONG lNum,
  39. LONG lDen)
  40. {
  41. pdt->lQuo = lNum / lDen;
  42. pdt->lRem = lNum % lDen;
  43. if (pdt->lRem < 0)
  44. {
  45. pdt->lQuo -= 1;
  46. pdt->lRem += lDen;
  47. }
  48. #ifdef DBG_PLGBLT
  49. if (gflPlgBlt & PLGBLT_SHOW_INIT)
  50. DbgPrint("%ld / %ld = %ld R %ld\n", lNum, lDen, pdt->lQuo, pdt->lRem);
  51. #endif
  52. }
  53. static VOID QDIV(
  54. DIV_T *pdt,
  55. LONGLONG *peqNum,
  56. LONG lDen)
  57. {
  58. ULONGLONG liQuo;
  59. ULONG ul;
  60. BOOL bSigned;
  61. bSigned = *peqNum < 0;
  62. if (bSigned)
  63. {
  64. liQuo = (ULONGLONG) (- (LONGLONG) *peqNum);
  65. }
  66. else
  67. liQuo = *peqNum;
  68. pdt->lQuo = DIVREM(liQuo, lDen, &ul);
  69. if (bSigned)
  70. {
  71. pdt->lQuo = - pdt->lQuo;
  72. if (ul == 0)
  73. pdt->lRem = 0;
  74. else
  75. {
  76. pdt->lQuo -= 1;
  77. pdt->lRem = lDen - ((LONG) ul);
  78. }
  79. }
  80. else
  81. {
  82. pdt->lRem = (LONG) ul;
  83. }
  84. #ifdef DBG_PLGBLT
  85. if (gflPlgBlt & PLGBLT_SHOW_INIT)
  86. DbgPrint("%ld,%ld / %ld = %ld R %ld\n", peqNum->HighPart, peqNum->LowPart, lDen, pdt->lQuo, pdt->lRem);
  87. #endif
  88. }
  89. /******************************Public*Routine******************************\
  90. * VOID vInitPlgDDA(pdda, pptl)
  91. *
  92. * Initialize the DDA
  93. *
  94. * History:
  95. * 08-Aug-1992 -by- Donald Sidoroff [donalds]
  96. * Wrote it.
  97. \**************************************************************************/
  98. BOOL bInitPlgDDA(
  99. PLGDDA *pdda,
  100. RECTL *prclScan,
  101. RECTL *prcl,
  102. POINTFIX *pptfx)
  103. {
  104. POINTFIX aptfx[4];
  105. RECTL rclScan;
  106. RECTL rcl;
  107. aptfx[0] = pptfx[0];
  108. aptfx[1] = pptfx[1];
  109. aptfx[2] = pptfx[2];
  110. aptfx[3].x = aptfx[1].x + aptfx[2].x - aptfx[0].x;
  111. aptfx[3].y = aptfx[1].y + aptfx[2].y - aptfx[0].y;
  112. // If the source surface does not have a 0,0 origin, deal with it here.
  113. if ((prcl->left != 0) || (prcl->top != 0))
  114. {
  115. rclScan.left = prclScan->left - prcl->left;
  116. rclScan.top = prclScan->top - prcl->top;
  117. rclScan.right = prclScan->right - prcl->left;
  118. rclScan.bottom = prclScan->bottom - prcl->top;
  119. prclScan = &rclScan;
  120. rcl.left = 0;
  121. rcl.top = 0;
  122. rcl.right = prcl->right - prcl->left;
  123. rcl.bottom = prcl->bottom - prcl->top;
  124. prcl = &rcl;
  125. }
  126. #ifdef DBG_PLGBLT
  127. if (gflPlgBlt & PLGBLT_SHOW_INIT)
  128. {
  129. DbgPrint("prclScan = [(%ld,%ld) (%ld,%ld)]\n",
  130. prclScan->left, prclScan->top, prclScan->right, prclScan->bottom);
  131. DbgPrint("prcl = [(%ld,%ld) (%ld,%ld)]\n",
  132. prcl->left, prcl->top, prcl->right, prcl->bottom);
  133. DbgPrint("aptfx[0] = (%ld,%ld)\n", aptfx[0].x, aptfx[0].y);
  134. DbgPrint("aptfx[1] = (%ld,%ld)\n", aptfx[1].x, aptfx[1].y);
  135. DbgPrint("aptfx[2] = (%ld,%ld)\n", aptfx[2].x, aptfx[2].y);
  136. DbgPrint("aptfx[3] = (%ld,%ld)\n", aptfx[3].x, aptfx[3].y);
  137. }
  138. #endif
  139. int iTop = (aptfx[1].y > aptfx[0].y) == (aptfx[1].y > aptfx[3].y);
  140. int iCase;
  141. if (aptfx[iTop].y > aptfx[iTop ^ 3].y)
  142. iTop ^= 3;
  143. switch (iTop) {
  144. case 0:
  145. if (aptfx[1].y < aptfx[2].y)
  146. iCase = 0;
  147. else
  148. if (aptfx[1].y > aptfx[2].y)
  149. iCase = 1;
  150. else
  151. if (aptfx[1].x < aptfx[2].x)
  152. iCase = 0;
  153. else
  154. iCase = 1;
  155. break;
  156. case 1:
  157. if (aptfx[0].y < aptfx[3].y)
  158. iCase = 2;
  159. else
  160. if (aptfx[0].y > aptfx[3].y)
  161. iCase = 3;
  162. else
  163. if (aptfx[0].x < aptfx[3].x)
  164. iCase = 2;
  165. else
  166. iCase = 3;
  167. break;
  168. case 2:
  169. if (aptfx[0].y < aptfx[3].y)
  170. iCase = 4;
  171. else
  172. if (aptfx[0].y > aptfx[3].y)
  173. iCase = 5;
  174. else
  175. if (aptfx[0].x < aptfx[3].x)
  176. iCase = 4;
  177. else
  178. iCase = 5;
  179. break;
  180. case 3:
  181. if (aptfx[1].y < aptfx[2].y)
  182. iCase = 6;
  183. else
  184. if (aptfx[1].y > aptfx[2].y)
  185. iCase = 7;
  186. else
  187. if (aptfx[1].x < aptfx[2].x)
  188. iCase = 6;
  189. else
  190. iCase = 7;
  191. break;
  192. }
  193. #ifdef DBG_PLGBLT
  194. if (gflPlgBlt & PLGBLT_SHOW_INIT)
  195. DbgPrint("iTop = %ld, iCase = %ld\n", iTop, iCase);
  196. #endif
  197. LONG DELTA_1;
  198. LONG DELTA_2;
  199. switch (iCase) {
  200. case 0:
  201. case 2:
  202. case 5:
  203. case 7:
  204. DELTA_1 = prcl->right - prcl->left;
  205. DELTA_2 = prcl->bottom - prcl->top;
  206. break;
  207. case 1:
  208. case 3:
  209. case 4:
  210. case 6:
  211. DELTA_1 = prcl->bottom - prcl->top;
  212. DELTA_2 = prcl->right - prcl->left;
  213. break;
  214. }
  215. LONG ci1 = aiPlgConst[iCase][0];
  216. LONG cj1 = aiPlgConst[iCase][1];
  217. LONG c1 = aiPlgConst[iCase][2];
  218. LONG ci2 = aiPlgConst[iCase][3];
  219. LONG cj2 = aiPlgConst[iCase][4];
  220. LONG c2 = aiPlgConst[iCase][5];
  221. #ifdef DBG_PLGBLT
  222. if (gflPlgBlt & PLGBLT_SHOW_INIT)
  223. DbgPrint("Global constants: %ld %ld %ld %ld %ld %ld %ld %ld\n",
  224. DELTA_1, DELTA_2, ci1, cj1, c1, ci2, cj2, c2);
  225. #endif
  226. LONG V1 = ci1 * prclScan->left + cj1 * prclScan->top + c1 * (DELTA_1 - 1);
  227. LONG V2 = ci2 * prclScan->left + cj2 * prclScan->top + c2 * (DELTA_2 - 1);
  228. #ifdef DBG_PLGBLT
  229. if (gflPlgBlt & PLGBLT_SHOW_INIT)
  230. DbgPrint("V1 = %ld, V2 = %ld\n", V1, V2);
  231. #endif
  232. LONG I0 = aptfx[aiPlgSort[iCase][0]].x;
  233. LONG J0 = aptfx[aiPlgSort[iCase][0]].y;
  234. LONG I1 = aptfx[aiPlgSort[iCase][1]].x;
  235. LONG J1 = aptfx[aiPlgSort[iCase][1]].y;
  236. LONG I2 = aptfx[aiPlgSort[iCase][2]].x;
  237. LONG J2 = aptfx[aiPlgSort[iCase][2]].y;
  238. LONG I3 = aptfx[aiPlgSort[iCase][3]].x;
  239. LONG J3 = aptfx[aiPlgSort[iCase][3]].y;
  240. I1 -= I0;
  241. I2 -= I0;
  242. I3 -= I0;
  243. J1 -= J0;
  244. J2 -= J0;
  245. J3 -= J0;
  246. #ifdef DBG_PLGBLT
  247. if (gflPlgBlt & PLGBLT_SHOW_INIT)
  248. {
  249. DbgPrint("I0, I1, I2, I3 = %8ld %8ld %8ld %8ld\n", I0, I1, I2, I3);
  250. DbgPrint("J0, J1, J2, J3 = %8ld %8ld %8ld %8ld\n", J0, J1, J2, J3);
  251. }
  252. #endif
  253. LONG X1 = DELTA_2 * I1;
  254. LONG Y1 = DELTA_2 * J1;
  255. LONG X2 = DELTA_1 * I2;
  256. LONG Y2 = DELTA_1 * J2;
  257. // avoid divide by 0's. In some way shape or form, all divides are based on
  258. // these two values. Note that by checking Y2, DELTA_1 is also validated. We
  259. // can't just validate Y1 as well because it is special cased below to be 0.
  260. // Also beware of overflows given large numbers where multipications can
  261. // potentially shift off all set bits leaving you with a zero value. In the case
  262. // where we just lose bits but don't end up with all zeros we will have
  263. // undefined but non-exception (divide by zero) behavior
  264. if ((Y2 == 0) || (DELTA_2 == 0))
  265. return(FALSE);
  266. LONG T = DELTA_1 * DELTA_2;
  267. LONGLONG N = Int32x32To64(T, (J0 + 16));
  268. LONGLONG eqTmp = Int32x32To64(V1, Y1);
  269. N += eqTmp;
  270. eqTmp = Int32x32To64(V2, Y2);
  271. N += eqTmp;
  272. N -= 1;
  273. // LONG N = T * (J0 + 16) + V1 * Y1 + V2 * Y2 - 1;
  274. #ifdef DBG_PLGBLT
  275. if (gflPlgBlt & PLGBLT_SHOW_INIT)
  276. {
  277. DbgPrint("X1 = %ld, Y1 = %ld, X2 = %ld, Y2 = %ld\n", X1, Y1, X2, Y2);
  278. DbgPrint("T = %ld, N = %ld,%ld\n", T, N.HighPart, N.LowPart);
  279. }
  280. #endif
  281. T *= 16;
  282. // overflow check: avoid divide by 0's
  283. if ( T == 0 )
  284. return(FALSE);
  285. DDA_STEP dp1;
  286. DDA_STEP dp2;
  287. ROT_DIV(&dp1.dt, Y1, T);
  288. dp1.lDen = T;
  289. ROT_DIV(&dp2.dt, Y2, T);
  290. dp2.lDen = T;
  291. QDIV(&pdda->ds.dt0, &N, T);
  292. pdda->ds.dt1 = pdda->ds.dt0;
  293. DDA(&pdda->ds.dt1, &dp1)
  294. pdda->ds.dt2 = pdda->ds.dt0;
  295. DDA(&pdda->ds.dt2, &dp2)
  296. pdda->ds.dt3 = pdda->ds.dt2;
  297. DDA(&pdda->ds.dt3, &dp1)
  298. #ifdef DBG_PLGBLT
  299. if (gflPlgBlt & PLGBLT_SHOW_INIT)
  300. {
  301. DbgPrint("N0, N1, N2, N3 = %8ld %8ld %8ld %8ld\n",
  302. pdda->ds.dt0.lQuo, pdda->ds.dt1.lQuo, pdda->ds.dt2.lQuo, pdda->ds.dt3.lQuo);
  303. DbgPrint("R0, R1, R2, R3 = %8ld %8ld %8ld %8ld\n",
  304. pdda->ds.dt0.lRem, pdda->ds.dt1.lRem, pdda->ds.dt2.lRem, pdda->ds.dt3.lRem);
  305. }
  306. #endif
  307. ROT_DIV(&pdda->dp0_i.dt, ci1 * Y1 + ci2 * Y2, T);
  308. pdda->dp0_i.lDen = T;
  309. pdda->dp1_i = pdda->dp0_i;
  310. pdda->dp2_i = pdda->dp0_i;
  311. pdda->dp3_i = pdda->dp0_i;
  312. ROT_DIV(&pdda->dp0_j.dt, cj1 * Y1 + cj2 * Y2, T);
  313. pdda->dp0_j.lDen = T;
  314. pdda->dp1_j = pdda->dp0_j;
  315. pdda->dp2_j = pdda->dp0_j;
  316. pdda->dp3_j = pdda->dp0_j;
  317. LONGLONG Q = Int32x32To64(I1, J2);
  318. eqTmp = Int32x32To64(J1, I2);
  319. Q -= eqTmp;
  320. // LONG Q = I1 * J2 - J1 * I2;
  321. #ifdef DBG_PLGBLT
  322. if (gflPlgBlt & PLGBLT_SHOW_INIT)
  323. DbgPrint("Q = %ld,%ld\n", Q.HighPart, Q.LowPart);
  324. #endif
  325. DIV_T dt1;
  326. DIV_T dt2;
  327. //overflow check: avoid divide by 0's
  328. if ((16 * DELTA_1) == 0 || (16 * DELTA_2) == 0)
  329. return(FALSE);
  330. ROT_DIV(&dt1, ci1 * J1, 16 * DELTA_1);
  331. ROT_DIV(&dt2, ci2 * J2, 16 * DELTA_2);
  332. LONG dn_i = dt1.lQuo + dt2.lQuo;
  333. ROT_DIV(&dt1, cj1 * J1, 16 * DELTA_1);
  334. ROT_DIV(&dt2, cj2 * J2, 16 * DELTA_2);
  335. LONG dn_j = dt1.lQuo + dt2.lQuo;
  336. if (Y1 == 0)
  337. {
  338. pdda->dp01.dt.lQuo = 0;
  339. pdda->dp01.dt.lRem = 0;
  340. pdda->dp01.lDen = 0;
  341. pdda->dp01_i.dt.lQuo = 0;
  342. pdda->dp01_i.dt.lRem = 0;
  343. pdda->dp01_i.lDen = 0;
  344. pdda->dp01_j.dt.lQuo = 0;
  345. pdda->dp01_j.dt.lRem = 0;
  346. pdda->dp01_j.lDen = 0;
  347. pdda->ds.dt01.lQuo = 0;
  348. pdda->ds.dt01.lRem = 0;
  349. pdda->ds.dt23.lQuo = 0;
  350. pdda->ds.dt23.lRem = 0;
  351. pdda->dpP01.dt.lQuo = 0;
  352. pdda->dpP01.dt.lRem = 0;
  353. pdda->dpP01.lDen = 0;
  354. }
  355. else
  356. {
  357. N= Int32x32To64(X1, 16 * pdda->ds.dt0.lQuo - J0);
  358. eqTmp= Int32x32To64(Y1, (I0 + 16));
  359. N += eqTmp;
  360. eqTmp= Int32x32To64(V2, I1 * J2);
  361. N -= eqTmp;
  362. eqTmp= Int32x32To64(V2, I2 * J1);
  363. N += eqTmp;
  364. N -= 1;
  365. // N = X1 * (16 * pdda->ds.dt0.lQuo - J0) + Y1 * (I0 + 16) - V2 * Q - 1;
  366. pdda->dp01.lDen = 16 * Y1;
  367. pdda->dp01_i.lDen = pdda->dp01.lDen;
  368. pdda->dp01_j.lDen = pdda->dp01.lDen;
  369. // overflow check: avoid divide by 0's.
  370. if (pdda->dp01.lDen == 0)
  371. return(FALSE);
  372. QDIV(&pdda->ds.dt01, &N, pdda->dp01.lDen);
  373. eqTmp= Int32x32To64(16 * X1, pdda->ds.dt2.lQuo - pdda->ds.dt0.lQuo);
  374. eqTmp -= Q;
  375. N += eqTmp;
  376. // N += 16 * X1 * (pdda->ds.dt2.lQuo - pdda->ds.dt0.lQuo) - Q;
  377. QDIV(&pdda->ds.dt23, &N, pdda->dp01.lDen);
  378. ROT_DIV(&pdda->dp01.dt, 16 * X1, pdda->dp01.lDen);
  379. N= Int32x32To64(ci2 * I1,J2);
  380. eqTmp= Int32x32To64(ci2 * I2, J1);
  381. N -= eqTmp; // Q * ci2
  382. eqTmp= Int32x32To64(16 * dn_i, X1);
  383. eqTmp -= N;
  384. QDIV(&pdda->dp01_i.dt, &eqTmp, pdda->dp01_i.lDen);
  385. N= Int32x32To64(cj2 * I1,J2);
  386. eqTmp= Int32x32To64(cj2 * I2, J1);
  387. N -= eqTmp; // Q * cj2
  388. eqTmp= Int32x32To64(16 * dn_j, X1);
  389. eqTmp -= N;
  390. QDIV(&pdda->dp01_j.dt, &eqTmp, pdda->dp01_j.lDen);
  391. // ROT_DIV(&pdda->dp01_i.dt, 16 * X1 * dn_i - ci2 * Q, pdda->dp01_i.lDen);
  392. // ROT_DIV(&pdda->dp01_j.dt, 16 * X1 * dn_j - cj2 * Q, pdda->dp01_j.lDen);
  393. // overflow check: avoid divide by 0's
  394. // 16*Y1 was already checked above computing pdda->dp01.lDen
  395. ROT_DIV(&pdda->dpP01.dt, 16 * X1, 16 * Y1);
  396. pdda->dpP01.lDen = 16 * Y1;
  397. }
  398. N= Int32x32To64(X2, 16 * pdda->ds.dt0.lQuo - J0);
  399. eqTmp= Int32x32To64(Y2, I0 + 16);
  400. N += eqTmp;
  401. eqTmp= Int32x32To64(V1, I1 * J2);
  402. N += eqTmp;
  403. eqTmp= Int32x32To64(V1, I2 * J1);
  404. N -= eqTmp;
  405. N -= 1;
  406. // N = Y1 * (16 * pdda->ds.dt0.lQuo - J0) + Y2 * (I0 + 16) + V1 * Q - 1;
  407. pdda->dp02.lDen = 16 * Y2;
  408. pdda->dp02_i.lDen = pdda->dp02.lDen;
  409. pdda->dp02_j.lDen = pdda->dp02.lDen;
  410. // overflow check: avoid divide by 0's.
  411. if (pdda->dp02.lDen == 0)
  412. return(FALSE);
  413. QDIV(&pdda->ds.dt02, &N, pdda->dp02.lDen);
  414. eqTmp= Int32x32To64(16 * X2, pdda->ds.dt1.lQuo - pdda->ds.dt0.lQuo);
  415. eqTmp += Q;
  416. N += eqTmp;
  417. // N += 16 * Y1 * (pdda->ds.dt1.lQuo - pdda->ds.dt0.lQuo) + Q;
  418. QDIV(&pdda->ds.dt13, &N, pdda->dp02.lDen);
  419. ROT_DIV(&pdda->dp02.dt, 16 * X2, pdda->dp02.lDen);
  420. N= Int32x32To64(ci1 * I1,J2);
  421. eqTmp= Int32x32To64(ci1 * I2, J1);
  422. N -= eqTmp; // Q * ci1
  423. eqTmp= Int32x32To64(16 * dn_i, X2);
  424. eqTmp += N;
  425. QDIV(&pdda->dp02_i.dt, &eqTmp, pdda->dp02_i.lDen);
  426. N= Int32x32To64(cj1 * I1,J2);
  427. eqTmp= Int32x32To64(cj1 * I2, J1);
  428. N -= eqTmp; // Q * cj1
  429. eqTmp= Int32x32To64(16 * dn_j, X2);
  430. eqTmp += N;
  431. QDIV(&pdda->dp02_j.dt, &eqTmp, pdda->dp02_j.lDen);
  432. // DIV(&pdda->dp02_i.dt, 16 * X2 * dn_i + ci1 * Q, pdda->dp02_i.lDen);
  433. // DIV(&pdda->dp02_j.dt, 16 * X2 * dn_j + cj1 * Q, pdda->dp02_j.lDen);
  434. pdda->dp13 = pdda->dp02;
  435. pdda->dp13_i = pdda->dp02_i;
  436. pdda->dp13_j = pdda->dp02_j;
  437. pdda->dp23 = pdda->dp01;
  438. pdda->dp23_i = pdda->dp01_i;
  439. pdda->dp23_j = pdda->dp01_j;
  440. // overflow check: avoid divide by 0's
  441. // 16*Y2 was already checked above computing pdda->dp02.lDen
  442. ROT_DIV(&pdda->dpP02.dt, 16 * X2, 16 * Y2);
  443. pdda->dpP02.lDen = 16 * Y2;
  444. return(TRUE);
  445. }
  446. /******************************Public*Routine******************************\
  447. * LONG lSizeDDA(pdda)
  448. *
  449. * Return the space needed to run the DDA for a scan
  450. *
  451. * History:
  452. * 08-Aug-1992 -by- Donald Sidoroff [donalds]
  453. * Wrote it.
  454. \**************************************************************************/
  455. LONG lSizeDDA(PLGDDA *pdda)
  456. {
  457. LONG dt[4];
  458. LONG max, min, i;
  459. // Bug #336058:
  460. // Prior to this fix, this function assumed that dt0 contains the
  461. // top-most vertex and dt3 contains the bottom-most vertex in the
  462. // parallelogram. However, under some calls to EngPlgBlt this appears
  463. // to not be true (the bug includes a test program that can
  464. // demonstrate this). That caused the allocated buffer to not be large
  465. // enough which resulted in an AV (i.e. when doing the run from dt1
  466. // to dt2). The fix is to find the smallest and largest vertices (with
  467. // respect to y-values) and allocate enough space for a run from the
  468. // smallest to the largest.
  469. dt[0] = pdda->ds.dt0.lQuo;
  470. dt[1] = pdda->ds.dt1.lQuo;
  471. dt[2] = pdda->ds.dt2.lQuo;
  472. dt[3] = pdda->ds.dt3.lQuo;
  473. max = min = dt[0];
  474. for (i=1; i<4; i++)
  475. {
  476. if (min > dt[i])
  477. {
  478. min = dt[i];
  479. }
  480. if (max < dt[i])
  481. {
  482. max = dt[i];
  483. }
  484. }
  485. //LONG lTmp = pdda->ds.dt3.lQuo - pdda->ds.dt0.lQuo;
  486. LONG lTmp = max-min;
  487. if (lTmp == 0)
  488. lTmp = 1;
  489. return((lTmp + 4) * sizeof(CNTPOS) + sizeof(ULONG));
  490. }
  491. /******************************Public*Routine******************************\
  492. * VOID vAdvXDDA(pdda)
  493. *
  494. * Advance the DDA in X.
  495. *
  496. * History:
  497. * 08-Aug-1992 -by- Donald Sidoroff [donalds]
  498. * Wrote it.
  499. \**************************************************************************/
  500. VOID vAdvXDDA(PLGDDA *pdda)
  501. {
  502. pdda->dsX.dt0.lQuo += pdda->dp0_i.dt.lQuo;
  503. pdda->dsX.dt0.lRem += pdda->dp0_i.dt.lRem;
  504. if (pdda->dsX.dt0.lRem >= pdda->dp0_i.lDen)
  505. {
  506. pdda->dsX.dt0.lRem -= pdda->dp0_i.lDen;
  507. pdda->dsX.dt0.lQuo++;
  508. DDA(&pdda->dsX.dt01, &pdda->dpP01);
  509. DDA(&pdda->dsX.dt02, &pdda->dpP02);
  510. }
  511. pdda->dsX.dt1.lQuo += pdda->dp1_i.dt.lQuo;
  512. pdda->dsX.dt1.lRem += pdda->dp1_i.dt.lRem;
  513. if (pdda->dsX.dt1.lRem >= pdda->dp1_i.lDen)
  514. {
  515. pdda->dsX.dt1.lRem -= pdda->dp1_i.lDen;
  516. pdda->dsX.dt1.lQuo++;
  517. DDA(&pdda->dsX.dt13, &pdda->dpP02);
  518. }
  519. pdda->dsX.dt2.lQuo += pdda->dp2_i.dt.lQuo;
  520. pdda->dsX.dt2.lRem += pdda->dp2_i.dt.lRem;
  521. if (pdda->dsX.dt2.lRem >= pdda->dp2_i.lDen)
  522. {
  523. pdda->dsX.dt2.lRem -= pdda->dp2_i.lDen;
  524. pdda->dsX.dt2.lQuo++;
  525. DDA(&pdda->dsX.dt23, &pdda->dpP01);
  526. }
  527. DDA(&pdda->dsX.dt3, &pdda->dp3_i);
  528. DDA(&pdda->dsX.dt01, &pdda->dp01_i);
  529. DDA(&pdda->dsX.dt02, &pdda->dp02_i);
  530. DDA(&pdda->dsX.dt13, &pdda->dp13_i);
  531. DDA(&pdda->dsX.dt23, &pdda->dp23_i);
  532. }
  533. /******************************Public*Routine******************************\
  534. * VOID vAdvYDDA(pdda)
  535. *
  536. * Advance the DDA in Y.
  537. *
  538. * History:
  539. * 08-Aug-1992 -by- Donald Sidoroff [donalds]
  540. * Wrote it.
  541. \**************************************************************************/
  542. VOID vAdvYDDA(PLGDDA *pdda)
  543. {
  544. pdda->ds.dt0.lQuo += pdda->dp0_j.dt.lQuo;
  545. pdda->ds.dt0.lRem += pdda->dp0_j.dt.lRem;
  546. if (pdda->ds.dt0.lRem >= pdda->dp0_j.lDen)
  547. {
  548. pdda->ds.dt0.lRem -= pdda->dp0_j.lDen;
  549. pdda->ds.dt0.lQuo++;
  550. DDA(&pdda->ds.dt01, &pdda->dpP01);
  551. DDA(&pdda->ds.dt02, &pdda->dpP02);
  552. }
  553. pdda->ds.dt1.lQuo += pdda->dp1_j.dt.lQuo;
  554. pdda->ds.dt1.lRem += pdda->dp1_j.dt.lRem;
  555. if (pdda->ds.dt1.lRem >= pdda->dp1_j.lDen)
  556. {
  557. pdda->ds.dt1.lRem -= pdda->dp1_j.lDen;
  558. pdda->ds.dt1.lQuo++;
  559. DDA(&pdda->ds.dt13, &pdda->dpP02);
  560. }
  561. pdda->ds.dt2.lQuo += pdda->dp2_j.dt.lQuo;
  562. pdda->ds.dt2.lRem += pdda->dp2_j.dt.lRem;
  563. if (pdda->ds.dt2.lRem >= pdda->dp2_j.lDen)
  564. {
  565. pdda->ds.dt2.lRem -= pdda->dp2_j.lDen;
  566. pdda->ds.dt2.lQuo++;
  567. DDA(&pdda->ds.dt23, &pdda->dpP01);
  568. }
  569. DDA(&pdda->ds.dt3, &pdda->dp3_j);
  570. DDA(&pdda->ds.dt01, &pdda->dp01_j);
  571. DDA(&pdda->ds.dt02, &pdda->dp02_j);
  572. DDA(&pdda->ds.dt13, &pdda->dp13_j);
  573. DDA(&pdda->ds.dt23, &pdda->dp23_j);
  574. }
  575. /******************************Public*Routine******************************\
  576. * PLGRUN *prunPumpDDA(pdda, prun)
  577. *
  578. * 'Pump' out the target point run for the source point.
  579. *
  580. * History:
  581. * 08-Aug-1992 -by- Donald Sidoroff [donalds]
  582. * Wrote it.
  583. \**************************************************************************/
  584. PLGRUN *prunPumpDDA(
  585. PLGDDA *pdda,
  586. PLGRUN *prun)
  587. {
  588. DIV_T dt01 = pdda->dsX.dt01;
  589. DIV_T dt02 = pdda->dsX.dt02;
  590. DIV_T dt13 = pdda->dsX.dt13;
  591. DIV_T dt23 = pdda->dsX.dt23;
  592. CNTPOS *pcp;
  593. LONG n = pdda->dsX.dt0.lQuo;
  594. prun->cpY.iPos = n;
  595. pcp = &prun->cpX[0];
  596. #ifdef DBG_PLGBLT
  597. if (gflPlgBlt & PLGBLT_SHOW_PUMP)
  598. {
  599. DbgPrint("Pumping pel\n");
  600. DbgPrint("N0 = %ld\n", n);
  601. DbgPrint("N1 = %ld\n", pdda->dsX.dt1.lQuo);
  602. DbgPrint("N2 = %ld\n", pdda->dsX.dt2.lQuo);
  603. DbgPrint("N3 = %ld\n", pdda->dsX.dt3.lQuo);
  604. DbgPrint("DDA 01 = %ld, %ld\n", dt01.lQuo, dt01.lRem);
  605. DbgPrint("DDA 02 = %ld, %ld\n", dt02.lQuo, dt02.lRem);
  606. DbgPrint("DDA 13 = %ld, %ld\n", dt13.lQuo, dt13.lRem);
  607. DbgPrint("DDA 23 = %ld, %ld\n", dt23.lQuo, dt23.lRem);
  608. DbgPrint("Step 01 = %ld, %ld, %ld\n",
  609. pdda->dp01.dt.lQuo, pdda->dp01.dt.lRem, pdda->dp01.lDen);
  610. DbgPrint("Step 02 = %ld, %ld, %ld\n",
  611. pdda->dp02.dt.lQuo, pdda->dp02.dt.lRem, pdda->dp02.lDen);
  612. DbgPrint("Step 13 = %ld, %ld, %ld\n",
  613. pdda->dp13.dt.lQuo, pdda->dp13.dt.lRem, pdda->dp13.lDen);
  614. DbgPrint("Step 23 = %ld, %ld, %ld\n",
  615. pdda->dp23.dt.lQuo, pdda->dp23.dt.lRem, pdda->dp23.lDen);
  616. }
  617. #endif
  618. while(n < pdda->dsX.dt1.lQuo)
  619. {
  620. #ifdef DBG_PLGBLT
  621. if (gflPlgBlt & PLGBLT_SHOW_PUMP)
  622. DbgPrint("@ Y = %ld, X0 = %ld, X1 = %ld\n", n, dt01.lQuo, dt02.lQuo);
  623. #endif
  624. if (dt01.lQuo < dt02.lQuo)
  625. {
  626. pcp->iPos = dt01.lQuo;
  627. pcp->cCnt = dt02.lQuo - dt01.lQuo;
  628. }
  629. else
  630. {
  631. pcp->iPos = dt02.lQuo;
  632. pcp->cCnt = dt01.lQuo - dt02.lQuo;
  633. }
  634. prun->cpY.cCnt++;
  635. DDA(&dt01, &pdda->dp01);
  636. DDA(&dt02, &pdda->dp02);
  637. pcp++;
  638. n++;
  639. }
  640. #ifdef DBG_PLGBLT
  641. if (gflPlgBlt & PLGBLT_SHOW_PUMP)
  642. DbgPrint("Switching LHS to 13\n");
  643. #endif
  644. while(n < pdda->dsX.dt2.lQuo)
  645. {
  646. #ifdef DBG_PLGBLT
  647. if (gflPlgBlt & PLGBLT_SHOW_PUMP)
  648. DbgPrint("@ Y = %ld, X0 = %ld, X1 = %ld\n", n, dt13.lQuo, dt02.lQuo);
  649. #endif
  650. if (dt13.lQuo < dt02.lQuo)
  651. {
  652. pcp->iPos = dt13.lQuo;
  653. pcp->cCnt = dt02.lQuo - dt13.lQuo;
  654. }
  655. else
  656. {
  657. pcp->iPos = dt02.lQuo;
  658. pcp->cCnt = dt13.lQuo - dt02.lQuo;
  659. }
  660. prun->cpY.cCnt++;
  661. DDA(&dt13, &pdda->dp13);
  662. DDA(&dt02, &pdda->dp02);
  663. pcp++;
  664. n++;
  665. }
  666. #ifdef DBG_PLGBLT
  667. if (gflPlgBlt & PLGBLT_SHOW_PUMP)
  668. DbgPrint("Switching RHS to 23\n");
  669. #endif
  670. while(n < pdda->dsX.dt3.lQuo)
  671. {
  672. #ifdef DBG_PLGBLT
  673. if (gflPlgBlt & PLGBLT_SHOW_PUMP)
  674. DbgPrint("@ Y = %ld, X0 = %ld, X1 = %ld\n", n, dt13.lQuo, dt23.lQuo);
  675. #endif
  676. if (dt13.lQuo < dt23.lQuo)
  677. {
  678. pcp->iPos = dt13.lQuo;
  679. pcp->cCnt = dt23.lQuo - dt13.lQuo;
  680. }
  681. else
  682. {
  683. pcp->iPos = dt23.lQuo;
  684. pcp->cCnt = dt13.lQuo - dt23.lQuo;
  685. }
  686. prun->cpY.cCnt++;
  687. DDA(&dt13, &pdda->dp13);
  688. DDA(&dt23, &pdda->dp23);
  689. pcp++;
  690. n++;
  691. }
  692. #ifdef DBG_PLGBLT
  693. if (gflPlgBlt & PLGBLT_SHOW_PUMP)
  694. DbgPrint("Done.\n");
  695. #endif
  696. prun->cpY.cCnt = n - prun->cpY.iPos;
  697. // Always put at least one X pair in the list. This handles the BLACKONWHITE
  698. // and WHITEONBLACK compression. Notice that the size of the X run is zero.
  699. if ((pdda->bOverwrite) && (prun->cpY.cCnt == 0))
  700. {
  701. if (dt13.lQuo < dt02.lQuo)
  702. {
  703. pcp->iPos = dt13.lQuo;
  704. pcp->cCnt = dt02.lQuo - dt13.lQuo;
  705. }
  706. else
  707. {
  708. pcp->iPos = dt02.lQuo;
  709. pcp->cCnt = dt13.lQuo - dt02.lQuo;
  710. }
  711. prun->cpY.cCnt = 1;
  712. pcp++;
  713. }
  714. return((PLGRUN *) pcp);
  715. }
  716. static ULONG gaulMaskMono[] =
  717. {
  718. 0x00000080, 0x00000040, 0x00000020, 0x00000010,
  719. 0x00000008, 0x00000004, 0x00000002, 0x00000001,
  720. 0x00008000, 0x00004000, 0x00002000, 0x00001000,
  721. 0x00000800, 0x00000400, 0x00000200, 0x00000100,
  722. 0x00800000, 0x00400000, 0x00200000, 0x00100000,
  723. 0x00080000, 0x00040000, 0x00020000, 0x00010000,
  724. 0x80000000, 0x40000000, 0x20000000, 0x10000000,
  725. 0x08000000, 0x04000000, 0x02000000, 0x01000000
  726. };
  727. static ULONG gaulMaskQuad[] =
  728. {
  729. 0x000000F0, 0x0000000F, 0x0000F000, 0x00000F00,
  730. 0x00F00000, 0x000F0000, 0xF0000000, 0x0F000000
  731. };
  732. static ULONG gaulShftQuad[] =
  733. {
  734. 0x00000004, 0x00000000, 0x0000000C, 0x00000008,
  735. 0x00000014, 0x00000010, 0x0000001C, 0x00000018
  736. };
  737. /******************************Public*Routine******************************\
  738. * PLGRUN *prunPlgRead1(prun, pjSrc, pjMask, pxlo, xLeft, xRght, xMask)
  739. *
  740. * Read the source, mask it, xlate colors and produce a run list
  741. * for a row of a 1BPP surface.
  742. *
  743. * History:
  744. * 12-Feb-1993 -by- Donald Sidoroff [donalds]
  745. * Fixed a LOT of bugs in monochrome sources
  746. *
  747. * 08-Aug-1992 -by- Donald Sidoroff [donalds]
  748. * Wrote it.
  749. \**************************************************************************/
  750. PLGRUN *prunPlgRead1(
  751. PLGDDA *pdda,
  752. PLGRUN *prun,
  753. BYTE *pjSrc,
  754. BYTE *pjMask,
  755. XLATEOBJ *pxlo,
  756. LONG xLeft,
  757. LONG xRght,
  758. LONG xMask)
  759. {
  760. ULONG *pulMsk;
  761. ULONG *pulSrc;
  762. ULONG ulMsk;
  763. ULONG ulSrc;
  764. ULONG iBlack;
  765. ULONG iWhite;
  766. LONG cLeft;
  767. LONG iLeft;
  768. LONG iMask;
  769. cLeft = xLeft >> 5; // Index of leftmost DWORD
  770. iLeft = xLeft & 31; // Bits used in leftmost DWORD
  771. pulSrc = ((DWORD *) pjSrc) + cLeft; // Adjust base address
  772. ulSrc = *pulSrc;
  773. // To prevent derefences of the XLATE, do it upfront. We can easily do
  774. // this on monochrome bitmaps.
  775. if (pxlo == NULL)
  776. {
  777. iBlack = 0;
  778. iWhite = 1;
  779. }
  780. else
  781. {
  782. iBlack = pxlo->pulXlate[0];
  783. iWhite = pxlo->pulXlate[1];
  784. }
  785. if (pjMask == (BYTE *) NULL)
  786. {
  787. if (xLeft < xRght)
  788. {
  789. while (TRUE)
  790. {
  791. if (ulSrc & gaulMaskMono[iLeft])
  792. prun->iColor = iWhite;
  793. else
  794. prun->iColor = iBlack;
  795. prun = prunPumpDDA(pdda, prun);
  796. vAdvXDDA(pdda);
  797. xLeft++;
  798. iLeft++;
  799. if (xLeft >= xRght)
  800. break;
  801. if (iLeft & 32)
  802. {
  803. pulSrc++;
  804. ulSrc = *pulSrc;
  805. iLeft = 0;
  806. }
  807. }
  808. }
  809. return(prun);
  810. }
  811. // Compute initial state of mask
  812. pulMsk = ((DWORD *) pjMask) + (xMask >> 5);
  813. iMask = xMask & 31;
  814. ulMsk = *pulMsk;
  815. if (xLeft < xRght)
  816. {
  817. while (TRUE)
  818. {
  819. if (ulMsk & gaulMaskMono[iMask])
  820. {
  821. if (ulSrc & gaulMaskMono[iLeft])
  822. prun->iColor = iWhite;
  823. else
  824. prun->iColor = iBlack;
  825. prun = prunPumpDDA(pdda, prun);
  826. }
  827. vAdvXDDA(pdda);
  828. xLeft++;
  829. iLeft++;
  830. iMask++;
  831. if (xLeft >= xRght)
  832. break;
  833. if (iLeft & 32)
  834. {
  835. pulSrc++;
  836. ulSrc = *pulSrc;
  837. iLeft = 0;
  838. }
  839. if (iMask & 32)
  840. {
  841. pulMsk++;
  842. ulMsk = *pulMsk;
  843. iMask = 0;
  844. }
  845. }
  846. }
  847. return(prun);
  848. }
  849. /******************************Public*Routine******************************\
  850. * PLGRUN *prunPlgRead4(prun, pjSrc, pjMask, pxlo, xLeft, xRght, xMask)
  851. *
  852. * Read the source, mask it, xlate colors and produce a run list
  853. * for a row of a 4BPP surface.
  854. *
  855. * History:
  856. * 08-Aug-1992 -by- Donald Sidoroff [donalds]
  857. * Wrote it.
  858. \**************************************************************************/
  859. PLGRUN *prunPlgRead4(
  860. PLGDDA *pdda,
  861. PLGRUN *prun,
  862. BYTE *pjSrc,
  863. BYTE *pjMask,
  864. XLATEOBJ *pxlo,
  865. LONG xLeft,
  866. LONG xRght,
  867. LONG xMask)
  868. {
  869. ULONG *pulMsk;
  870. ULONG *pulSrc;
  871. ULONG ulMsk;
  872. ULONG ulSrc;
  873. ULONG iColor;
  874. LONG cLeft;
  875. LONG iLeft;
  876. LONG iMask;
  877. cLeft = xLeft >> 3; // Index of leftmost DWORD
  878. iLeft = xLeft & 7; // Bits used in leftmost DWORD
  879. pulSrc = ((DWORD *) pjSrc) + cLeft; // Adjust base address
  880. ulSrc = *pulSrc;
  881. if (pjMask == (BYTE *) NULL)
  882. {
  883. if (xLeft < xRght)
  884. {
  885. while (TRUE)
  886. {
  887. iColor = (ulSrc & gaulMaskQuad[iLeft]) >> gaulShftQuad[iLeft];
  888. if (pxlo == NULL)
  889. prun->iColor = iColor;
  890. else
  891. prun->iColor = pxlo->pulXlate[iColor];
  892. prun = prunPumpDDA(pdda, prun);
  893. vAdvXDDA(pdda);
  894. xLeft++;
  895. iLeft++;
  896. if (xLeft >= xRght)
  897. break;
  898. if (iLeft & 8)
  899. {
  900. pulSrc++;
  901. ulSrc = *pulSrc;
  902. iLeft = 0;
  903. }
  904. }
  905. }
  906. return(prun);
  907. }
  908. // Compute initial state of mask
  909. pulMsk = ((DWORD *) pjMask) + (xMask >> 5);
  910. iMask = xMask & 31;
  911. ulMsk = *pulMsk;
  912. if (xLeft < xRght)
  913. {
  914. while (TRUE)
  915. {
  916. if (ulMsk & gaulMaskMono[iMask])
  917. {
  918. iColor = (ulSrc & gaulMaskQuad[iLeft]) >> gaulShftQuad[iLeft];
  919. if (pxlo == NULL)
  920. prun->iColor = iColor;
  921. else
  922. prun->iColor = pxlo->pulXlate[iColor];
  923. prun = prunPumpDDA(pdda, prun);
  924. }
  925. vAdvXDDA(pdda);
  926. xLeft++;
  927. iLeft++;
  928. iMask++;
  929. if (xLeft >= xRght)
  930. break;
  931. if (iLeft & 8)
  932. {
  933. pulSrc++;
  934. ulSrc = *pulSrc;
  935. iLeft = 0;
  936. }
  937. if (iMask & 32)
  938. {
  939. pulMsk++;
  940. ulMsk = *pulMsk;
  941. iMask = 0;
  942. }
  943. }
  944. }
  945. return(prun);
  946. }
  947. /******************************Public*Routine******************************\
  948. * PLGRUN *prunPlgRead8(prun, pjSrc, pjMask, pxlo, xLeft, xRght, xMask)
  949. *
  950. * Read the source, mask it, xlate colors and produce a run list
  951. * for a row of a 8BPP surface.
  952. *
  953. * History:
  954. * 08-Aug-1992 -by- Donald Sidoroff [donalds]
  955. * Wrote it.
  956. \**************************************************************************/
  957. PLGRUN *prunPlgRead8(
  958. PLGDDA *pdda,
  959. PLGRUN *prun,
  960. BYTE *pjSrc,
  961. BYTE *pjMask,
  962. XLATEOBJ *pxlo,
  963. LONG xLeft,
  964. LONG xRght,
  965. LONG xMask)
  966. {
  967. ULONG *pulMsk;
  968. ULONG ulMsk;
  969. ULONG iColor;
  970. LONG iMask;
  971. pjSrc += xLeft;
  972. if (pjMask == (BYTE *) NULL)
  973. {
  974. if (pxlo == NULL)
  975. while (xLeft != xRght)
  976. {
  977. prun->iColor = *pjSrc;
  978. prun = prunPumpDDA(pdda, prun);
  979. vAdvXDDA(pdda);
  980. pjSrc++;
  981. xLeft++;
  982. }
  983. else
  984. while (xLeft != xRght)
  985. {
  986. prun->iColor = pxlo->pulXlate[*pjSrc];
  987. prun = prunPumpDDA(pdda, prun);
  988. vAdvXDDA(pdda);
  989. pjSrc++;
  990. xLeft++;
  991. }
  992. return(prun);
  993. }
  994. // Compute initial state of mask
  995. pulMsk = ((DWORD *) pjMask) + (xMask >> 5);
  996. iMask = xMask & 31;
  997. ulMsk = *pulMsk;
  998. while (xLeft != xRght)
  999. {
  1000. if (ulMsk & gaulMaskMono[iMask])
  1001. {
  1002. iColor = *pjSrc;
  1003. if (pxlo == NULL)
  1004. prun->iColor = iColor;
  1005. else
  1006. prun->iColor = pxlo->pulXlate[iColor];
  1007. prun = prunPumpDDA(pdda, prun);
  1008. }
  1009. vAdvXDDA(pdda);
  1010. pjSrc++;
  1011. xLeft++;
  1012. iMask++;
  1013. if (iMask & 32)
  1014. {
  1015. pulMsk++;
  1016. ulMsk = *pulMsk;
  1017. iMask = 0;
  1018. }
  1019. }
  1020. return(prun);
  1021. }
  1022. /******************************Public*Routine******************************\
  1023. * PLGRUN *prunPlgRead16(prun, pjSrc, pjMask, pxlo, xLeft, xRght, xMask)
  1024. *
  1025. * Read the source, mask it, xlate colors and produce a run list
  1026. * for a row of a 16BPP surface.
  1027. *
  1028. * History:
  1029. * 08-Aug-1992 -by- Donald Sidoroff [donalds]
  1030. * Wrote it.
  1031. \**************************************************************************/
  1032. PLGRUN *prunPlgRead16(
  1033. PLGDDA *pdda,
  1034. PLGRUN *prun,
  1035. BYTE *pjSrc,
  1036. BYTE *pjMask,
  1037. XLATEOBJ *pxlo,
  1038. LONG xLeft,
  1039. LONG xRght,
  1040. LONG xMask)
  1041. {
  1042. WORD *pwSrc = (WORD *) pjSrc;
  1043. ULONG *pulMsk;
  1044. ULONG ulMsk;
  1045. ULONG iColor;
  1046. LONG iMask;
  1047. pwSrc += xLeft;
  1048. if (pjMask == (BYTE *) NULL)
  1049. {
  1050. if (pxlo == NULL)
  1051. while (xLeft != xRght)
  1052. {
  1053. prun->iColor = *pwSrc;
  1054. prun = prunPumpDDA(pdda, prun);
  1055. vAdvXDDA(pdda);
  1056. pwSrc++;
  1057. xLeft++;
  1058. }
  1059. else
  1060. while (xLeft != xRght)
  1061. {
  1062. prun->iColor = ((XLATE *) pxlo)->ulTranslate((ULONG) *pwSrc);
  1063. prun = prunPumpDDA(pdda, prun);
  1064. vAdvXDDA(pdda);
  1065. pwSrc++;
  1066. xLeft++;
  1067. }
  1068. return(prun);
  1069. }
  1070. // Compute initial state of mask
  1071. pulMsk = ((DWORD *) pjMask) + (xMask >> 5);
  1072. iMask = xMask & 31;
  1073. ulMsk = *pulMsk;
  1074. while (xLeft != xRght)
  1075. {
  1076. if (ulMsk & gaulMaskMono[iMask])
  1077. {
  1078. iColor = *pwSrc;
  1079. if (pxlo == NULL)
  1080. prun->iColor = iColor;
  1081. else
  1082. prun->iColor = ((XLATE *) pxlo)->ulTranslate(iColor);
  1083. prun = prunPumpDDA(pdda, prun);
  1084. }
  1085. vAdvXDDA(pdda);
  1086. pwSrc++;
  1087. xLeft++;
  1088. iMask++;
  1089. if (iMask & 32)
  1090. {
  1091. pulMsk++;
  1092. ulMsk = *pulMsk;
  1093. iMask = 0;
  1094. }
  1095. }
  1096. return(prun);
  1097. }
  1098. /******************************Public*Routine******************************\
  1099. * PLGRUN *prunPlgRead24(prun, pjSrc, pjMask, pxlo, xLeft, xRght, xMask)
  1100. *
  1101. * Read the source, mask it, xlate colors and produce a run list
  1102. * for a row of a 24BPP surface.
  1103. *
  1104. * History:
  1105. * 08-Aug-1992 -by- Donald Sidoroff [donalds]
  1106. * Wrote it.
  1107. \**************************************************************************/
  1108. PLGRUN *prunPlgRead24(
  1109. PLGDDA *pdda,
  1110. PLGRUN *prun,
  1111. BYTE *pjSrc,
  1112. BYTE *pjMask,
  1113. XLATEOBJ *pxlo,
  1114. LONG xLeft,
  1115. LONG xRght,
  1116. LONG xMask)
  1117. {
  1118. RGBTRIPLE *prgbSrc = (RGBTRIPLE *) pjSrc;
  1119. ULONG *pulMsk;
  1120. ULONG ulMsk;
  1121. ULONG iColor = 0;
  1122. LONG iMask;
  1123. prgbSrc += xLeft;
  1124. if (pjMask == (BYTE *) NULL)
  1125. {
  1126. if (pxlo == NULL)
  1127. while (xLeft != xRght)
  1128. {
  1129. *((RGBTRIPLE *) &iColor) = *prgbSrc;
  1130. prun->iColor = iColor;
  1131. prun = prunPumpDDA(pdda, prun);
  1132. vAdvXDDA(pdda);
  1133. prgbSrc++;
  1134. xLeft++;
  1135. }
  1136. else
  1137. while (xLeft != xRght)
  1138. {
  1139. *((RGBTRIPLE *) &iColor) = *prgbSrc;
  1140. prun->iColor = ((XLATE *) pxlo)->ulTranslate(iColor);
  1141. prun = prunPumpDDA(pdda, prun);
  1142. vAdvXDDA(pdda);
  1143. prgbSrc++;
  1144. xLeft++;
  1145. }
  1146. return(prun);
  1147. }
  1148. // Compute initial state of mask
  1149. pulMsk = ((DWORD *) pjMask) + (xMask >> 5);
  1150. iMask = xMask & 31;
  1151. ulMsk = *pulMsk;
  1152. while (xLeft != xRght)
  1153. {
  1154. if (ulMsk & gaulMaskMono[iMask])
  1155. {
  1156. *((RGBTRIPLE *) &iColor) = *prgbSrc;
  1157. if (pxlo == NULL)
  1158. prun->iColor = iColor;
  1159. else
  1160. prun->iColor = ((XLATE *) pxlo)->ulTranslate(iColor);
  1161. prun = prunPumpDDA(pdda, prun);
  1162. }
  1163. vAdvXDDA(pdda);
  1164. prgbSrc++;
  1165. xLeft++;
  1166. iMask++;
  1167. if (iMask & 32)
  1168. {
  1169. pulMsk++;
  1170. ulMsk = *pulMsk;
  1171. iMask = 0;
  1172. }
  1173. }
  1174. return(prun);
  1175. }
  1176. /******************************Public*Routine******************************\
  1177. * PLGRUN *prunPlgRead32(prun, pjSrc, pjMask, pxlo, xLeft, xRght, xMask)
  1178. *
  1179. * Read the source, mask it, xlate colors and produce a run list
  1180. * for a row of a 32BPP surface.
  1181. *
  1182. * History:
  1183. * 08-Aug-1992 -by- Donald Sidoroff [donalds]
  1184. * Wrote it.
  1185. \**************************************************************************/
  1186. PLGRUN *prunPlgRead32(
  1187. PLGDDA *pdda,
  1188. PLGRUN *prun,
  1189. BYTE *pjSrc,
  1190. BYTE *pjMask,
  1191. XLATEOBJ *pxlo,
  1192. LONG xLeft,
  1193. LONG xRght,
  1194. LONG xMask)
  1195. {
  1196. DWORD *pdwSrc = (DWORD *) pjSrc;
  1197. ULONG *pulMsk;
  1198. ULONG ulMsk;
  1199. ULONG iColor;
  1200. LONG iMask;
  1201. pdwSrc += xLeft;
  1202. if (pjMask == (BYTE *) NULL)
  1203. {
  1204. if (pxlo == NULL)
  1205. while (xLeft != xRght)
  1206. {
  1207. prun->iColor = *pdwSrc;
  1208. prun = prunPumpDDA(pdda, prun);
  1209. vAdvXDDA(pdda);
  1210. pdwSrc++;
  1211. xLeft++;
  1212. }
  1213. else
  1214. while (xLeft != xRght)
  1215. {
  1216. prun->iColor = ((XLATE *) pxlo)->ulTranslate(*pdwSrc);
  1217. prun = prunPumpDDA(pdda, prun);
  1218. vAdvXDDA(pdda);
  1219. pdwSrc++;
  1220. xLeft++;
  1221. }
  1222. return(prun);
  1223. }
  1224. // Compute initial state of mask
  1225. pulMsk = ((DWORD *) pjMask) + (xMask >> 5);
  1226. iMask = xMask & 31;
  1227. ulMsk = *pulMsk;
  1228. while (xLeft != xRght)
  1229. {
  1230. if (ulMsk & gaulMaskMono[iMask])
  1231. {
  1232. iColor = *pdwSrc;
  1233. if (pxlo == NULL)
  1234. prun->iColor = iColor;
  1235. else
  1236. prun->iColor = ((XLATE *) pxlo)->ulTranslate(iColor);
  1237. prun = prunPumpDDA(pdda, prun);
  1238. }
  1239. vAdvXDDA(pdda);
  1240. pdwSrc++;
  1241. xLeft++;
  1242. iMask++;
  1243. if (iMask & 32)
  1244. {
  1245. pulMsk++;
  1246. ulMsk = *pulMsk;
  1247. iMask = 0;
  1248. }
  1249. }
  1250. return(prun);
  1251. }
  1252. static BYTE gajMask[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
  1253. /******************************Public*Routine******************************\
  1254. * VOID vPlgWrite1(prun, prunEnd, pSurf, pco)
  1255. *
  1256. * Write the clipped run list of pels to the target 1BPP surface.
  1257. *
  1258. * History:
  1259. * 08-Aug-1992 -by- Donald Sidoroff [donalds]
  1260. * Wrote it.
  1261. \**************************************************************************/
  1262. VOID vPlgWrite1(
  1263. PLGRUN *prun,
  1264. PLGRUN *prunEnd,
  1265. SURFACE *pSurf,
  1266. CLIPOBJ *pco)
  1267. {
  1268. BYTE *pjBase;
  1269. BYTE *pjOff;
  1270. CNTPOS *pcp;
  1271. ULONG iColor;
  1272. LONG yCurr;
  1273. LONG yDist;
  1274. LONG xCurr;
  1275. LONG xDist;
  1276. BYTE jMask;
  1277. BYTE jTemp;
  1278. BOOL bValid;
  1279. // See if this can be handled without clipping.
  1280. if (pco == (CLIPOBJ *) NULL)
  1281. {
  1282. while (prun != prunEnd)
  1283. {
  1284. iColor = prun->iColor ? (ULONG) -1L : 0L;
  1285. yCurr = prun->cpY.iPos;
  1286. yDist = prun->cpY.cCnt;
  1287. pjBase = (BYTE *) pSurf->pvScan0() + pSurf->lDelta() * yCurr;
  1288. pcp = &prun->cpX[0];
  1289. while (yDist != 0)
  1290. {
  1291. xCurr = pcp->iPos;
  1292. xDist = pcp->cCnt;
  1293. pjOff = pjBase + (xCurr >> 3);
  1294. jMask = gajMask[xCurr & 7];
  1295. jTemp = *pjOff;
  1296. while (xDist != 0)
  1297. {
  1298. jTemp = (BYTE) ((jTemp & ~jMask) | (iColor & jMask));
  1299. xDist--;
  1300. xCurr++;
  1301. jMask >>= 1;
  1302. if (jMask == (BYTE) 0)
  1303. {
  1304. *pjOff = jTemp;
  1305. pjOff++;
  1306. jTemp = *pjOff;
  1307. jMask = gajMask[xCurr & 7];
  1308. }
  1309. }
  1310. *pjOff = jTemp;
  1311. pjBase += pSurf->lDelta();
  1312. yDist--;
  1313. pcp++;
  1314. }
  1315. prun = (PLGRUN *) pcp;
  1316. }
  1317. return;
  1318. }
  1319. // There is a clip region. Set up the clipping code.
  1320. ((ECLIPOBJ *) pco)->cEnumStart(FALSE, CT_RECTANGLES, CD_ANY, 100);
  1321. RECTL rclClip;
  1322. rclClip.left = POS_INFINITY;
  1323. rclClip.top = POS_INFINITY;
  1324. rclClip.right = NEG_INFINITY;
  1325. rclClip.bottom = NEG_INFINITY;
  1326. while (prun != prunEnd)
  1327. {
  1328. iColor = prun->iColor ? (ULONG) -1L : 0L;
  1329. yCurr = prun->cpY.iPos;
  1330. yDist = prun->cpY.cCnt;
  1331. pjBase = (BYTE *) pSurf->pvScan0() + pSurf->lDelta() * yCurr;
  1332. pcp = &prun->cpX[0];
  1333. while (yDist != 0)
  1334. {
  1335. if ((yCurr < rclClip.top) || (yCurr >= rclClip.bottom))
  1336. ((ECLIPOBJ *) pco)->vFindScan(&rclClip, yCurr);
  1337. if ((yCurr >= rclClip.top) && (yCurr < rclClip.bottom))
  1338. {
  1339. xCurr = pcp->iPos;
  1340. xDist = pcp->cCnt;
  1341. pjOff = pjBase + (xCurr >> 3);
  1342. jMask = gajMask[xCurr & 7];
  1343. bValid = ((xCurr >= 0) && (xCurr < pSurf->sizl().cx));
  1344. jTemp = bValid ? *pjOff : (BYTE) 0;
  1345. while (xDist != 0)
  1346. {
  1347. if ((xCurr < rclClip.left) || (xCurr >= rclClip.right))
  1348. ((ECLIPOBJ *) pco)->vFindSegment(&rclClip, xCurr, yCurr);
  1349. if ((xCurr >= rclClip.left) && (xCurr < rclClip.right))
  1350. jTemp = (BYTE) ((jTemp & ~jMask) | (iColor & jMask));
  1351. xDist--;
  1352. xCurr++;
  1353. jMask >>= 1;
  1354. if (jMask == (BYTE) 0)
  1355. {
  1356. if (bValid)
  1357. *pjOff = jTemp;
  1358. jMask = gajMask[xCurr & 7];
  1359. pjOff++;
  1360. bValid = ((xCurr >= 0) && (xCurr < pSurf->sizl().cx));
  1361. jTemp = bValid ? *pjOff : (BYTE) 0;
  1362. }
  1363. }
  1364. if (bValid)
  1365. *pjOff = jTemp;
  1366. }
  1367. pjBase += pSurf->lDelta();
  1368. yCurr++;
  1369. yDist--;
  1370. pcp++;
  1371. }
  1372. prun = (PLGRUN *) pcp;
  1373. }
  1374. }
  1375. /******************************Public*Routine******************************\
  1376. * VOID vPlgWrite4(prun, prunEnd, pSurf, pco)
  1377. *
  1378. * Write the clipped run list of pels to the target 4BPP surface.
  1379. *
  1380. * History:
  1381. * 08-Aug-1992 -by- Donald Sidoroff [donalds]
  1382. * Wrote it.
  1383. \**************************************************************************/
  1384. VOID vPlgWrite4(
  1385. PLGRUN *prun,
  1386. PLGRUN *prunEnd,
  1387. SURFACE *pSurf,
  1388. CLIPOBJ *pco)
  1389. {
  1390. BYTE *pjBase;
  1391. BYTE *pjOff;
  1392. CNTPOS *pcp;
  1393. ULONG iColor;
  1394. LONG yCurr;
  1395. LONG yDist;
  1396. LONG xCurr;
  1397. LONG xDist;
  1398. BYTE jMask;
  1399. // See if this can be handled without clipping.
  1400. if (pco == (CLIPOBJ *) NULL)
  1401. {
  1402. while (prun != prunEnd)
  1403. {
  1404. iColor = prun->iColor | (prun->iColor << 4);
  1405. yCurr = prun->cpY.iPos;
  1406. yDist = prun->cpY.cCnt;
  1407. pjBase = (BYTE *) pSurf->pvScan0() + pSurf->lDelta() * yCurr;
  1408. pcp = &prun->cpX[0];
  1409. while (yDist != 0)
  1410. {
  1411. xCurr = pcp->iPos;
  1412. xDist = pcp->cCnt;
  1413. pjOff = pjBase + (xCurr >> 1);
  1414. jMask = (xCurr & 1) ? 0x0F : 0xF0;
  1415. while (xDist != 0)
  1416. {
  1417. *pjOff = (BYTE) ((*pjOff & ~jMask) | (iColor & jMask));
  1418. jMask ^= 0xFF;
  1419. if (jMask == 0xF0)
  1420. pjOff++;
  1421. xDist--;
  1422. }
  1423. pjBase += pSurf->lDelta();
  1424. yDist--;
  1425. pcp++;
  1426. }
  1427. prun = (PLGRUN *) pcp;
  1428. }
  1429. return;
  1430. }
  1431. // There maybe a single rectangle to clip against.
  1432. RECTL rclClip;
  1433. if (pco->iDComplexity == DC_RECT)
  1434. {
  1435. rclClip = pco->rclBounds;
  1436. while (prun != prunEnd)
  1437. {
  1438. yCurr = prun->cpY.iPos;
  1439. yDist = prun->cpY.cCnt;
  1440. iColor = prun->iColor | (prun->iColor << 4);
  1441. pjBase = (BYTE *) pSurf->pvScan0() + pSurf->lDelta() * yCurr;
  1442. pcp = &prun->cpX[0];
  1443. while (yDist != 0)
  1444. {
  1445. if ((yCurr >= rclClip.top) && (yCurr < rclClip.bottom))
  1446. {
  1447. xCurr = pcp->iPos;
  1448. xDist = pcp->cCnt;
  1449. pjOff = pjBase + (xCurr >> 1);
  1450. jMask = (xCurr & 1) ? 0x0F : 0xF0;
  1451. while (xDist != 0)
  1452. {
  1453. if ((xCurr >= rclClip.left) && (xCurr < rclClip.right))
  1454. *pjOff = (BYTE) ((*pjOff & ~jMask) | (iColor & jMask));
  1455. xDist--;
  1456. xCurr++;
  1457. jMask ^= 0xFF;
  1458. if (jMask == 0xF0)
  1459. pjOff++;
  1460. }
  1461. }
  1462. pjBase += pSurf->lDelta();
  1463. yCurr++;
  1464. yDist--;
  1465. pcp++;
  1466. }
  1467. prun = (PLGRUN *) pcp;
  1468. }
  1469. return;
  1470. }
  1471. // There is complex clipping. Set up the clipping code.
  1472. ((ECLIPOBJ *) pco)->cEnumStart(FALSE, CT_RECTANGLES, CD_ANY, 100);
  1473. rclClip.left = POS_INFINITY;
  1474. rclClip.top = POS_INFINITY;
  1475. rclClip.right = NEG_INFINITY;
  1476. rclClip.bottom = NEG_INFINITY;
  1477. while (prun != prunEnd)
  1478. {
  1479. yCurr = prun->cpY.iPos;
  1480. yDist = prun->cpY.cCnt;
  1481. iColor = prun->iColor | (prun->iColor << 4);
  1482. pjBase = (BYTE *) pSurf->pvScan0() + pSurf->lDelta() * yCurr;
  1483. pcp = &prun->cpX[0];
  1484. while (yDist != 0)
  1485. {
  1486. if ((yCurr < rclClip.top) || (yCurr >= rclClip.bottom))
  1487. ((ECLIPOBJ *) pco)->vFindScan(&rclClip, yCurr);
  1488. if ((yCurr >= rclClip.top) && (yCurr < rclClip.bottom))
  1489. {
  1490. xCurr = pcp->iPos;
  1491. xDist = pcp->cCnt;
  1492. pjOff = pjBase + (xCurr >> 1);
  1493. jMask = (xCurr & 1) ? 0x0F : 0xF0;
  1494. while (xDist != 0)
  1495. {
  1496. if ((xCurr < rclClip.left) || (xCurr >= rclClip.right))
  1497. ((ECLIPOBJ *) pco)->vFindSegment(&rclClip, xCurr, yCurr);
  1498. if ((xCurr >= rclClip.left) && (xCurr < rclClip.right))
  1499. *pjOff = (BYTE) ((*pjOff & ~jMask) | (iColor & jMask));
  1500. xDist--;
  1501. xCurr++;
  1502. jMask ^= 0xFF;
  1503. if (jMask == 0xF0)
  1504. pjOff++;
  1505. }
  1506. }
  1507. pjBase += pSurf->lDelta();
  1508. yCurr++;
  1509. yDist--;
  1510. pcp++;
  1511. }
  1512. prun = (PLGRUN *) pcp;
  1513. }
  1514. }
  1515. /******************************Public*Routine******************************\
  1516. * VOID vPlgWrite8(prun, prunEnd, pso, pco)
  1517. *
  1518. * Write the clipped run list of pels to the target 8BPP surface.
  1519. *
  1520. * History:
  1521. * 08-Aug-1992 -by- Donald Sidoroff [donalds]
  1522. * Wrote it.
  1523. \**************************************************************************/
  1524. VOID vPlgWrite8(
  1525. PLGRUN *prun,
  1526. PLGRUN *prunEnd,
  1527. SURFACE *pSurf,
  1528. CLIPOBJ *pco)
  1529. {
  1530. BYTE *pjBase;
  1531. BYTE *pjOff;
  1532. CNTPOS *pcp;
  1533. ULONG iColor;
  1534. LONG yCurr;
  1535. LONG yDist;
  1536. LONG xCurr;
  1537. LONG xDist;
  1538. // See if this can be handled without clipping.
  1539. if (pco == (CLIPOBJ *) NULL)
  1540. {
  1541. while (prun != prunEnd)
  1542. {
  1543. iColor = prun->iColor;
  1544. yCurr = prun->cpY.iPos;
  1545. yDist = prun->cpY.cCnt;
  1546. pjBase = (BYTE *) pSurf->pvScan0() + pSurf->lDelta() * yCurr;
  1547. pcp = &prun->cpX[0];
  1548. while (yDist != 0)
  1549. {
  1550. pjOff = pjBase + pcp->iPos;
  1551. xDist = pcp->cCnt;
  1552. while (xDist != 0)
  1553. {
  1554. *pjOff = (BYTE) iColor;
  1555. pjOff++;
  1556. xDist--;
  1557. }
  1558. pjBase += pSurf->lDelta();
  1559. yDist--;
  1560. pcp++;
  1561. }
  1562. prun = (PLGRUN *) pcp;
  1563. }
  1564. return;
  1565. }
  1566. // There maybe a single rectangle to clip against.
  1567. RECTL rclClip;
  1568. if (pco->iDComplexity == DC_RECT)
  1569. {
  1570. rclClip = pco->rclBounds;
  1571. while (prun != prunEnd)
  1572. {
  1573. yCurr = prun->cpY.iPos;
  1574. yDist = prun->cpY.cCnt;
  1575. iColor = prun->iColor;
  1576. pjBase = (BYTE *) pSurf->pvScan0() + pSurf->lDelta() * yCurr;
  1577. pcp = &prun->cpX[0];
  1578. while (yDist != 0)
  1579. {
  1580. if ((yCurr >= rclClip.top) && (yCurr < rclClip.bottom))
  1581. {
  1582. xCurr = pcp->iPos;
  1583. xDist = pcp->cCnt;
  1584. pjOff = pjBase + xCurr;
  1585. while (xDist != 0)
  1586. {
  1587. if ((xCurr >= rclClip.left) && (xCurr < rclClip.right))
  1588. *pjOff = (BYTE) iColor;
  1589. xDist--;
  1590. xCurr++;
  1591. pjOff++;
  1592. }
  1593. }
  1594. pjBase += pSurf->lDelta();
  1595. yCurr++;
  1596. yDist--;
  1597. pcp++;
  1598. }
  1599. prun = (PLGRUN *) pcp;
  1600. }
  1601. return;
  1602. }
  1603. // There is complex clipping. Set up the clipping code.
  1604. ((ECLIPOBJ *) pco)->cEnumStart(FALSE, CT_RECTANGLES, CD_ANY, 100);
  1605. rclClip.left = POS_INFINITY;
  1606. rclClip.top = POS_INFINITY;
  1607. rclClip.right = NEG_INFINITY;
  1608. rclClip.bottom = NEG_INFINITY;
  1609. while (prun != prunEnd)
  1610. {
  1611. yCurr = prun->cpY.iPos;
  1612. yDist = prun->cpY.cCnt;
  1613. iColor = prun->iColor;
  1614. pjBase = (BYTE *) pSurf->pvScan0() + pSurf->lDelta() * yCurr;
  1615. pcp = &prun->cpX[0];
  1616. while (yDist != 0)
  1617. {
  1618. if ((yCurr < rclClip.top) || (yCurr >= rclClip.bottom))
  1619. ((ECLIPOBJ *) pco)->vFindScan(&rclClip, yCurr);
  1620. if ((yCurr >= rclClip.top) && (yCurr < rclClip.bottom))
  1621. {
  1622. xCurr = pcp->iPos;
  1623. xDist = pcp->cCnt;
  1624. pjOff = pjBase + xCurr;
  1625. while (xDist != 0)
  1626. {
  1627. if ((xCurr < rclClip.left) || (xCurr >= rclClip.right))
  1628. ((ECLIPOBJ *) pco)->vFindSegment(&rclClip, xCurr, yCurr);
  1629. if ((xCurr >= rclClip.left) && (xCurr < rclClip.right))
  1630. *pjOff = (BYTE) iColor;
  1631. xDist--;
  1632. xCurr++;
  1633. pjOff++;
  1634. }
  1635. }
  1636. pjBase += pSurf->lDelta();
  1637. yCurr++;
  1638. yDist--;
  1639. pcp++;
  1640. }
  1641. prun = (PLGRUN *) pcp;
  1642. }
  1643. }
  1644. /******************************Public*Routine******************************\
  1645. * VOID vPlgWrite16(prun, prunEnd, pSurf, pco)
  1646. *
  1647. * Write the clipped run list of pels to the target 16BPP surface.
  1648. *
  1649. * History:
  1650. * 08-Aug-1992 -by- Donald Sidoroff [donalds]
  1651. * Wrote it.
  1652. \**************************************************************************/
  1653. VOID vPlgWrite16(
  1654. PLGRUN *prun,
  1655. PLGRUN *prunEnd,
  1656. SURFACE *pSurf,
  1657. CLIPOBJ *pco)
  1658. {
  1659. BYTE *pjBase;
  1660. WORD *pwOff;
  1661. CNTPOS *pcp;
  1662. ULONG iColor;
  1663. LONG yCurr;
  1664. LONG yDist;
  1665. LONG xCurr;
  1666. LONG xDist;
  1667. // See if this can be handled without clipping.
  1668. if (pco == (CLIPOBJ *) NULL)
  1669. {
  1670. while (prun != prunEnd)
  1671. {
  1672. iColor = prun->iColor;
  1673. yCurr = prun->cpY.iPos;
  1674. yDist = prun->cpY.cCnt;
  1675. pjBase = (BYTE *) pSurf->pvScan0() + pSurf->lDelta() * yCurr;
  1676. pcp = &prun->cpX[0];
  1677. while (yDist != 0)
  1678. {
  1679. pwOff = ((WORD *) pjBase) + pcp->iPos;
  1680. xDist = pcp->cCnt;
  1681. while (xDist != 0)
  1682. {
  1683. *pwOff = (WORD) iColor;
  1684. xDist--;
  1685. pwOff++;
  1686. }
  1687. pjBase += pSurf->lDelta();
  1688. yDist--;
  1689. pcp++;
  1690. }
  1691. prun = (PLGRUN *) pcp;
  1692. }
  1693. return;
  1694. }
  1695. // There is a clip region. Set up the clipping code.
  1696. ((ECLIPOBJ *) pco)->cEnumStart(FALSE, CT_RECTANGLES, CD_ANY, 100);
  1697. RECTL rclClip;
  1698. rclClip.left = POS_INFINITY;
  1699. rclClip.top = POS_INFINITY;
  1700. rclClip.right = NEG_INFINITY;
  1701. rclClip.bottom = NEG_INFINITY;
  1702. while (prun != prunEnd)
  1703. {
  1704. yCurr = prun->cpY.iPos;
  1705. yDist = prun->cpY.cCnt;
  1706. iColor = prun->iColor;
  1707. pjBase = (BYTE *) pSurf->pvScan0() + pSurf->lDelta() * yCurr;
  1708. pcp = &prun->cpX[0];
  1709. while (yDist != 0)
  1710. {
  1711. if ((yCurr < rclClip.top) || (yCurr >= rclClip.bottom))
  1712. ((ECLIPOBJ *) pco)->vFindScan(&rclClip, yCurr);
  1713. if ((yCurr >= rclClip.top) && (yCurr < rclClip.bottom))
  1714. {
  1715. xCurr = pcp->iPos;
  1716. xDist = pcp->cCnt;
  1717. pwOff = ((WORD *) pjBase) + xCurr;
  1718. while (xDist != 0)
  1719. {
  1720. if ((xCurr < rclClip.left) || (xCurr >= rclClip.right))
  1721. ((ECLIPOBJ *) pco)->vFindSegment(&rclClip, xCurr, yCurr);
  1722. if ((xCurr >= rclClip.left) && (xCurr < rclClip.right))
  1723. *pwOff = (WORD) iColor;
  1724. xDist--;
  1725. xCurr++;
  1726. pwOff++;
  1727. }
  1728. }
  1729. pjBase += pSurf->lDelta();
  1730. yCurr++;
  1731. yDist--;
  1732. pcp++;
  1733. }
  1734. prun = (PLGRUN *) pcp;
  1735. }
  1736. }
  1737. /******************************Public*Routine******************************\
  1738. * VOID vPlgWrite24(prun, prunEnd, pSurf, pco)
  1739. *
  1740. * Write the clipped run list of pels to the target 24BPP surface.
  1741. *
  1742. * History:
  1743. * 08-Aug-1992 -by- Donald Sidoroff [donalds]
  1744. * Wrote it.
  1745. \**************************************************************************/
  1746. VOID vPlgWrite24(
  1747. PLGRUN *prun,
  1748. PLGRUN *prunEnd,
  1749. SURFACE *pSurf,
  1750. CLIPOBJ *pco)
  1751. {
  1752. BYTE *pjBase;
  1753. RGBTRIPLE *prgbOff;
  1754. CNTPOS *pcp;
  1755. ULONG iColor;
  1756. LONG yCurr;
  1757. LONG yDist;
  1758. LONG xCurr;
  1759. LONG xDist;
  1760. // See if this can be handled without clipping.
  1761. if (pco == (CLIPOBJ *) NULL)
  1762. {
  1763. while (prun != prunEnd)
  1764. {
  1765. iColor = prun->iColor;
  1766. yCurr = prun->cpY.iPos;
  1767. yDist = prun->cpY.cCnt;
  1768. pjBase = (BYTE *) pSurf->pvScan0() + pSurf->lDelta() * yCurr;
  1769. pcp = &prun->cpX[0];
  1770. while (yDist != 0)
  1771. {
  1772. prgbOff = ((RGBTRIPLE *) pjBase) + pcp->iPos;
  1773. xDist = pcp->cCnt;
  1774. while (xDist != 0)
  1775. {
  1776. *prgbOff = *((RGBTRIPLE *) &iColor);
  1777. prgbOff++;
  1778. xDist--;
  1779. }
  1780. pjBase += pSurf->lDelta();
  1781. yDist--;
  1782. pcp++;
  1783. }
  1784. prun = (PLGRUN *) pcp;
  1785. }
  1786. return;
  1787. }
  1788. // There is a clip region. Set up the clipping code.
  1789. ((ECLIPOBJ *) pco)->cEnumStart(FALSE, CT_RECTANGLES, CD_ANY, 100);
  1790. RECTL rclClip;
  1791. rclClip.left = POS_INFINITY;
  1792. rclClip.top = POS_INFINITY;
  1793. rclClip.right = NEG_INFINITY;
  1794. rclClip.bottom = NEG_INFINITY;
  1795. while (prun != prunEnd)
  1796. {
  1797. yCurr = prun->cpY.iPos;
  1798. yDist = prun->cpY.cCnt;
  1799. iColor = prun->iColor;
  1800. pjBase = (BYTE *) pSurf->pvScan0() + pSurf->lDelta() * yCurr;
  1801. pcp = &prun->cpX[0];
  1802. while (yDist != 0)
  1803. {
  1804. if ((yCurr < rclClip.top) || (yCurr >= rclClip.bottom))
  1805. ((ECLIPOBJ *) pco)->vFindScan(&rclClip, yCurr);
  1806. if ((yCurr >= rclClip.top) && (yCurr < rclClip.bottom))
  1807. {
  1808. xCurr = pcp->iPos;
  1809. xDist = pcp->cCnt;
  1810. prgbOff = ((RGBTRIPLE *) pjBase) + xCurr;
  1811. while (xDist != 0)
  1812. {
  1813. if ((xCurr < rclClip.left) || (xCurr >= rclClip.right))
  1814. ((ECLIPOBJ *) pco)->vFindSegment(&rclClip, xCurr, yCurr);
  1815. if ((xCurr >= rclClip.left) && (xCurr < rclClip.right))
  1816. *prgbOff = *((RGBTRIPLE *) &iColor);
  1817. xDist--;
  1818. xCurr++;
  1819. prgbOff++;
  1820. }
  1821. }
  1822. pjBase += pSurf->lDelta();
  1823. yCurr++;
  1824. yDist--;
  1825. pcp++;
  1826. }
  1827. prun = (PLGRUN *) pcp;
  1828. }
  1829. }
  1830. /******************************Public*Routine******************************\
  1831. * VOID vPlgWrite32(prun, prunEnd, pSurf, pco)
  1832. *
  1833. * Write the clipped run list of pels to the target 32BPP surface.
  1834. *
  1835. * History:
  1836. * 08-Aug-1992 -by- Donald Sidoroff [donalds]
  1837. * Wrote it.
  1838. \**************************************************************************/
  1839. VOID vPlgWrite32(
  1840. PLGRUN *prun,
  1841. PLGRUN *prunEnd,
  1842. SURFACE *pSurf,
  1843. CLIPOBJ *pco)
  1844. {
  1845. BYTE *pjBase;
  1846. DWORD *pdwOff;
  1847. CNTPOS *pcp;
  1848. ULONG iColor;
  1849. LONG yCurr;
  1850. LONG yDist;
  1851. LONG xCurr;
  1852. LONG xDist;
  1853. // See if this can be handled without clipping.
  1854. if (pco == (CLIPOBJ *) NULL)
  1855. {
  1856. while (prun != prunEnd)
  1857. {
  1858. iColor = prun->iColor;
  1859. yCurr = prun->cpY.iPos;
  1860. yDist = prun->cpY.cCnt;
  1861. pjBase = (BYTE *) pSurf->pvScan0() + pSurf->lDelta() * yCurr;
  1862. pcp = &prun->cpX[0];
  1863. while (yDist != 0)
  1864. {
  1865. pdwOff = ((DWORD *) pjBase) + pcp->iPos;
  1866. xDist = pcp->cCnt;
  1867. while (xDist != 0)
  1868. {
  1869. *pdwOff = iColor;
  1870. xDist--;
  1871. pdwOff++;
  1872. }
  1873. pjBase += pSurf->lDelta();
  1874. yDist--;
  1875. pcp++;
  1876. }
  1877. prun = (PLGRUN *) pcp;
  1878. }
  1879. return;
  1880. }
  1881. // There is a clip region. Set up the clipping code.
  1882. ((ECLIPOBJ *) pco)->cEnumStart(FALSE, CT_RECTANGLES, CD_ANY, 100);
  1883. RECTL rclClip;
  1884. rclClip.left = POS_INFINITY;
  1885. rclClip.top = POS_INFINITY;
  1886. rclClip.right = NEG_INFINITY;
  1887. rclClip.bottom = NEG_INFINITY;
  1888. while (prun != prunEnd)
  1889. {
  1890. yCurr = prun->cpY.iPos;
  1891. yDist = prun->cpY.cCnt;
  1892. iColor = prun->iColor;
  1893. pjBase = (BYTE *) pSurf->pvScan0() + pSurf->lDelta() * yCurr;
  1894. pcp = &prun->cpX[0];
  1895. while (yDist != 0)
  1896. {
  1897. if ((yCurr < rclClip.top) || (yCurr >= rclClip.bottom))
  1898. ((ECLIPOBJ *) pco)->vFindScan(&rclClip, yCurr);
  1899. if ((yCurr >= rclClip.top) && (yCurr < rclClip.bottom))
  1900. {
  1901. xCurr = pcp->iPos;
  1902. xDist = pcp->cCnt;
  1903. pdwOff = ((DWORD *) pjBase) + xCurr;
  1904. while (xDist != 0)
  1905. {
  1906. if ((xCurr < rclClip.left) || (xCurr >= rclClip.right))
  1907. ((ECLIPOBJ *) pco)->vFindSegment(&rclClip, xCurr, yCurr);
  1908. if ((xCurr >= rclClip.left) && (xCurr < rclClip.right))
  1909. *pdwOff = iColor;
  1910. xDist--;
  1911. xCurr++;
  1912. pdwOff++;
  1913. }
  1914. }
  1915. pjBase += pSurf->lDelta();
  1916. yCurr++;
  1917. yDist--;
  1918. pcp++;
  1919. }
  1920. prun = (PLGRUN *) pcp;
  1921. }
  1922. }
  1923. /******************************Public*Routine******************************\
  1924. * VOID vPlgWriteAND(prun, prunEnd, pSurf, pco)
  1925. *
  1926. * AND the clipped run list of pels to the target 1BPP surface. This can
  1927. * be made much faster by noting that ANDing with 1's is a NOP.
  1928. *
  1929. * History:
  1930. * 25-Aug-1992 -by- Donald Sidoroff [donalds]
  1931. * Wrote it.
  1932. \**************************************************************************/
  1933. VOID vPlgWriteAND(
  1934. PLGRUN *prun,
  1935. PLGRUN *prunEnd,
  1936. SURFACE *pSurf,
  1937. CLIPOBJ *pco)
  1938. {
  1939. BYTE *pjBase;
  1940. BYTE *pjOff;
  1941. CNTPOS *pcp;
  1942. ULONG iColor;
  1943. LONG yCurr;
  1944. LONG yDist;
  1945. LONG xCurr;
  1946. LONG xDist;
  1947. BYTE jMask;
  1948. BYTE jTemp;
  1949. BOOL bValid;
  1950. // See if this can be handled without clipping.
  1951. if (pco == (CLIPOBJ *) NULL)
  1952. {
  1953. while (prun != prunEnd)
  1954. {
  1955. iColor = prun->iColor == 0 ? ~0L : 0L;
  1956. yCurr = prun->cpY.iPos;
  1957. yDist = prun->cpY.cCnt;
  1958. pjBase = (BYTE *) pSurf->pvScan0() + pSurf->lDelta() * yCurr;
  1959. pcp = &prun->cpX[0];
  1960. while (yDist != 0)
  1961. {
  1962. xCurr = pcp->iPos;
  1963. xDist = pcp->cCnt;
  1964. pjOff = pjBase + (xCurr >> 3);
  1965. jMask = gajMask[xCurr & 7];
  1966. jTemp = *pjOff;
  1967. while (xDist >= 0)
  1968. {
  1969. jTemp &= ~((BYTE) (iColor & jMask));
  1970. xDist--;
  1971. xCurr++;
  1972. jMask >>= 1;
  1973. if (jMask == (BYTE) 0)
  1974. {
  1975. *pjOff = jTemp;
  1976. pjOff++;
  1977. jTemp = *pjOff;
  1978. jMask = gajMask[xCurr & 7];
  1979. }
  1980. }
  1981. *pjOff = jTemp;
  1982. pjBase += pSurf->lDelta();
  1983. yDist--;
  1984. pcp++;
  1985. }
  1986. prun = (PLGRUN *) pcp;
  1987. }
  1988. return;
  1989. }
  1990. // There is a clip region. Set up the clipping code.
  1991. ((ECLIPOBJ *) pco)->cEnumStart(FALSE, CT_RECTANGLES, CD_ANY, 100);
  1992. RECTL rclClip;
  1993. rclClip.left = POS_INFINITY;
  1994. rclClip.top = POS_INFINITY;
  1995. rclClip.right = NEG_INFINITY;
  1996. rclClip.bottom = NEG_INFINITY;
  1997. while (prun != prunEnd)
  1998. {
  1999. iColor = prun->iColor == 0 ? ~0L : 0L;
  2000. yCurr = prun->cpY.iPos;
  2001. yDist = prun->cpY.cCnt;
  2002. pjBase = (BYTE *) pSurf->pvScan0() + pSurf->lDelta() * yCurr;
  2003. pcp = &prun->cpX[0];
  2004. while (yDist != 0)
  2005. {
  2006. if ((yCurr < rclClip.top) || (yCurr >= rclClip.bottom))
  2007. ((ECLIPOBJ *) pco)->vFindScan(&rclClip, yCurr);
  2008. if ((yCurr >= rclClip.top) && (yCurr < rclClip.bottom))
  2009. {
  2010. xCurr = pcp->iPos;
  2011. xDist = pcp->cCnt;
  2012. pjOff = pjBase + (xCurr >> 3);
  2013. jMask = gajMask[xCurr & 7];
  2014. bValid = ((xCurr >= 0) && (xCurr < pSurf->sizl().cx));
  2015. jTemp = bValid ? *pjOff : (BYTE) 0;
  2016. while (xDist >= 0)
  2017. {
  2018. if ((xCurr < rclClip.left) || (xCurr >= rclClip.right))
  2019. ((ECLIPOBJ *) pco)->vFindSegment(&rclClip, xCurr, yCurr);
  2020. if ((xCurr >= rclClip.left) && (xCurr < rclClip.right))
  2021. jTemp &= ~((BYTE) (iColor & jMask));
  2022. xDist--;
  2023. xCurr++;
  2024. jMask >>= 1;
  2025. if (jMask == (BYTE) 0)
  2026. {
  2027. if (bValid)
  2028. *pjOff = jTemp;
  2029. pjOff++;
  2030. jMask = gajMask[xCurr & 7];
  2031. bValid = ((xCurr >= 0) && (xCurr < pSurf->sizl().cx));
  2032. jTemp = bValid ? *pjOff : (BYTE) 0;
  2033. }
  2034. }
  2035. if (bValid)
  2036. *pjOff = jTemp;
  2037. }
  2038. pjBase += pSurf->lDelta();
  2039. yCurr++;
  2040. yDist--;
  2041. pcp++;
  2042. }
  2043. prun = (PLGRUN *) pcp;
  2044. }
  2045. }
  2046. /******************************Public*Routine******************************\
  2047. * VOID vPlgWriteOR(prun, prunEnd, pso, pco)
  2048. *
  2049. * OR the clipped run list of pels to the target 1BPP surface. This can
  2050. * be much faster by noting that ORing with 0's is a NOP.
  2051. *
  2052. * History:
  2053. * 25-Aug-1992 -by- Donald Sidoroff [donalds]
  2054. * Wrote it.
  2055. \**************************************************************************/
  2056. VOID vPlgWriteOR(
  2057. PLGRUN *prun,
  2058. PLGRUN *prunEnd,
  2059. SURFACE *pSurf,
  2060. CLIPOBJ *pco)
  2061. {
  2062. BYTE *pjBase;
  2063. BYTE *pjOff;
  2064. CNTPOS *pcp;
  2065. ULONG iColor;
  2066. LONG yCurr;
  2067. LONG yDist;
  2068. LONG xCurr;
  2069. LONG xDist;
  2070. BYTE jMask;
  2071. BYTE jTemp;
  2072. BOOL bValid;
  2073. // See if this can be handled without clipping.
  2074. if (pco == (CLIPOBJ *) NULL)
  2075. {
  2076. while (prun != prunEnd)
  2077. {
  2078. iColor = prun->iColor == 0 ? 0L : ~0L;
  2079. yCurr = prun->cpY.iPos;
  2080. yDist = prun->cpY.cCnt;
  2081. pjBase = (BYTE *) pSurf->pvScan0() + pSurf->lDelta() * yCurr;
  2082. pcp = &prun->cpX[0];
  2083. while (yDist != 0)
  2084. {
  2085. xCurr = pcp->iPos;
  2086. xDist = pcp->cCnt;
  2087. pjOff = pjBase + (xCurr >> 3);
  2088. jMask = gajMask[xCurr & 7];
  2089. jTemp = *pjOff;
  2090. while (xDist >= 0)
  2091. {
  2092. jTemp |= ((BYTE) (iColor & jMask));
  2093. xDist--;
  2094. xCurr++;
  2095. jMask >>= 1;
  2096. if (jMask == (BYTE) 0)
  2097. {
  2098. *pjOff = jTemp;
  2099. pjOff++;
  2100. jTemp = *pjOff;
  2101. jMask = gajMask[xCurr & 7];
  2102. }
  2103. }
  2104. *pjOff = jTemp;
  2105. pjBase += pSurf->lDelta();
  2106. yDist--;
  2107. pcp++;
  2108. }
  2109. prun = (PLGRUN *) pcp;
  2110. }
  2111. return;
  2112. }
  2113. // There is a clip region. Set up the clipping code.
  2114. ((ECLIPOBJ *) pco)->cEnumStart(FALSE, CT_RECTANGLES, CD_ANY, 100);
  2115. RECTL rclClip;
  2116. rclClip.left = POS_INFINITY;
  2117. rclClip.top = POS_INFINITY;
  2118. rclClip.right = NEG_INFINITY;
  2119. rclClip.bottom = NEG_INFINITY;
  2120. while (prun != prunEnd)
  2121. {
  2122. iColor = prun->iColor == 0 ? 0L : ~0L;
  2123. yCurr = prun->cpY.iPos;
  2124. yDist = prun->cpY.cCnt;
  2125. pjBase = (BYTE *) pSurf->pvScan0() + pSurf->lDelta() * yCurr;
  2126. pcp = &prun->cpX[0];
  2127. while (yDist != 0)
  2128. {
  2129. if ((yCurr < rclClip.top) || (yCurr >= rclClip.bottom))
  2130. ((ECLIPOBJ *) pco)->vFindScan(&rclClip, yCurr);
  2131. if ((yCurr >= rclClip.top) && (yCurr < rclClip.bottom))
  2132. {
  2133. xCurr = pcp->iPos;
  2134. xDist = pcp->cCnt;
  2135. pjOff = pjBase + (xCurr >> 3);
  2136. jMask = gajMask[xCurr & 7];
  2137. bValid = ((xCurr >= 0) && (xCurr < pSurf->sizl().cx));
  2138. jTemp = bValid ? *pjOff : (BYTE) 0;
  2139. while (xDist >= 0)
  2140. {
  2141. if ((xCurr < rclClip.left) || (xCurr >= rclClip.right))
  2142. ((ECLIPOBJ *) pco)->vFindSegment(&rclClip, xCurr, yCurr);
  2143. if ((xCurr >= rclClip.left) && (xCurr < rclClip.right))
  2144. jTemp |= ((BYTE) (iColor & jMask));
  2145. xDist--;
  2146. xCurr++;
  2147. jMask >>= 1;
  2148. if (jMask == (BYTE) 0)
  2149. {
  2150. if (bValid)
  2151. *pjOff = jTemp;
  2152. pjOff++;
  2153. jMask = gajMask[xCurr & 7];
  2154. bValid = ((xCurr >= 0) && (xCurr < pSurf->sizl().cx));
  2155. jTemp = bValid ? *pjOff : (BYTE) 0;
  2156. }
  2157. }
  2158. if (bValid)
  2159. *pjOff = jTemp;
  2160. }
  2161. pjBase += pSurf->lDelta();
  2162. yCurr++;
  2163. yDist--;
  2164. pcp++;
  2165. }
  2166. prun = (PLGRUN *) pcp;
  2167. }
  2168. }