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.

1425 lines
37 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: srcblt1.cxx
  3. *
  4. * This contains the bitmap simulation functions that blt to a 1 bit/pel
  5. * DIB surface.
  6. *
  7. * Created: 07-Feb-1991 19:27:49
  8. * Author: Patrick Haluptzok patrickh
  9. *
  10. * Copyright (c) 1990-1999 Microsoft Corporation
  11. *
  12. \**************************************************************************/
  13. #include "precomp.hxx"
  14. /*******************Public*Routine*****************\
  15. * vSrcCopyS1D1LtoR
  16. *
  17. * There are three main loops in this function.
  18. *
  19. * The first loop deals with the full bytes part of
  20. * the Dst while fetching/shifting the matching 8 bits
  21. * from the Src.
  22. *
  23. * The second loop deals with the left most strip
  24. * of the partial bytes.
  25. *
  26. * The third loop deals with the right most strip
  27. * of the partial bytes.
  28. *
  29. * Special case:
  30. * when the Src and Dst are aligned, we enter
  31. * a different loop to use rltcopymem to avoid
  32. * shifting
  33. *
  34. * History:
  35. * 17-Oct-1994 -by- Lingyun Wang [lingyunw]
  36. * Wrote it.
  37. *
  38. \**************************************************/
  39. VOID vSrcCopyS1D1LtoR(PBLTINFO psb)
  40. {
  41. BYTE jSrc; // holds a source byte
  42. BYTE jDst; // holds a dest byte
  43. INT iSrc; // bit position in the first Src byte
  44. INT iDst; // bit position in the first Dst byte
  45. INT ixlate; // set flag to indicate if it is
  46. // source invert, source copy or
  47. // all 0's or all 1's
  48. PBYTE pjDst; // pointer to the Src bytes
  49. PBYTE pjSrc; // pointer to the Dst bytes
  50. PBYTE pjLDst; // pointer to the last Dst byte
  51. LONG xSrcEnd = psb->xSrcEnd;
  52. LONG cy; // number of pixels
  53. LONG cx; // number of rows
  54. BYTE jAlignL; // alignment bits to the left
  55. BYTE jAlignR; // alignment bits to the right
  56. BYTE jMask; // Masks used for shifting
  57. BYTE jEndMask;
  58. LONG cFullBytes; //number of full bytes to deal with
  59. BOOL bNextByte;
  60. LONG xDstEnd;
  61. LONG lDeltaDst;
  62. LONG lDeltaSrc;
  63. BOOL bNextSrc = TRUE;
  64. // We assume we are doing left to right top to bottom blting
  65. ASSERTGDI(psb->xDir == 1, "vSrcCopyS1D1LtoR - direction not left to right");
  66. ASSERTGDI(psb->cy != 0, "ERROR: Src Move cy == 0");
  67. //DbgPrint ("vsrccopys1d1ltor\n");
  68. // if ixlate is 0x00, all 0's
  69. // if ixlate is 0x01, src copy
  70. // if ixlate is 0x10, src invert
  71. // if ixlate is 0x11, all 1's
  72. ixlate = (psb->pxlo->pulXlate[0]<<1) | psb->pxlo->pulXlate[1];
  73. //Get Src and Dst start positions
  74. iSrc = psb->xSrcStart & 0x0007;
  75. iDst = psb->xDstStart & 0x0007;
  76. // Checking alignment
  77. // If Src starting point is ahead of Dst
  78. if (iSrc < iDst)
  79. jAlignL = 8 - (iDst - iSrc);
  80. // If Dst starting point is ahead of Src
  81. else
  82. jAlignL = iSrc - iDst;
  83. //jAlignR = (8 - jAlignL) & 0x07;
  84. jAlignR = 8 - jAlignL;
  85. cx=psb->cx;
  86. xDstEnd = psb->xDstStart + cx;
  87. lDeltaDst = psb->lDeltaDst;
  88. lDeltaSrc = psb->lDeltaSrc;
  89. //check if there is a next byte
  90. bNextByte = !((xDstEnd>>3) ==
  91. (psb->xDstStart>>3));
  92. // The following loop is the inner loop part
  93. // where we deals with a byte at a time
  94. // when this main part is done, we deal
  95. // with the begin and end partial bytes
  96. //
  97. // if Src and Dst are aligned, use a separete loop
  98. // to obtain better performance;
  99. // If not, we shift the Src bytes to match with
  100. // the Dst byte one at a time
  101. if (bNextByte)
  102. {
  103. long iStrideSrc;
  104. long iStrideDst;
  105. PBYTE pjSrcEnd;
  106. //Get first Dst full byte
  107. pjDst = psb->pjDst + ((psb->xDstStart+7)>>3);
  108. //Get the Src byte that matches the first Dst
  109. // full byte
  110. pjSrc = psb->pjSrc + ((psb->xSrcStart+((8-iDst)&0x07)) >> 3);
  111. //Get last full byte
  112. pjLDst = psb->pjDst + (xDstEnd>>3);
  113. //Get the number of full bytes
  114. // Sundown: xSrcStart and xSrcEnd are both LONG, safe to truncate
  115. cFullBytes = (ULONG)(pjLDst - pjDst);
  116. //the increment to the full byte on the next scan line
  117. iStrideDst = lDeltaDst - cFullBytes;
  118. iStrideSrc = lDeltaSrc - cFullBytes;
  119. // deal with our special case
  120. cy = psb->cy;
  121. if (!jAlignL || (ixlate == 0) || (ixlate == 3))
  122. {
  123. BYTE jConstant;
  124. switch (ixlate)
  125. {
  126. case 0:
  127. case 3:
  128. jConstant = (!ixlate)?0:0xFF;
  129. while (cy--)
  130. {
  131. int i;
  132. i = cFullBytes;
  133. while (i--)
  134. *pjDst++ = jConstant;
  135. //move to the beginning full byte
  136. // on the next scan line
  137. pjDst += iStrideDst;
  138. pjSrc += iStrideSrc;
  139. };
  140. break;
  141. case 1:
  142. while (cy--)
  143. {
  144. RtlCopyMemory(pjDst,pjSrc,cFullBytes);
  145. // move to the beginning full byte
  146. // on the next scan line
  147. pjDst += lDeltaDst;
  148. pjSrc += lDeltaSrc;
  149. };
  150. break;
  151. case 2:
  152. while (cy--)
  153. {
  154. int i;
  155. i = cFullBytes;
  156. while (i--)
  157. *pjDst++ = ~*pjSrc++;
  158. //move to the beginning full byte
  159. // on the next scan line
  160. pjDst += iStrideDst;
  161. pjSrc += iStrideSrc;
  162. };
  163. break;
  164. default:;
  165. } //switch
  166. } //end of if (!jAlignL)
  167. else
  168. // if neither aligned nor all 0's or all 1's
  169. {
  170. BYTE jRem; //remainder
  171. switch (ixlate)
  172. {
  173. case 1:
  174. while (cy--)
  175. {
  176. jRem = *pjSrc << jAlignL;
  177. pjSrcEnd = pjSrc+cFullBytes;
  178. while (pjSrc != pjSrcEnd)
  179. {
  180. jSrc = *(++pjSrc);
  181. jDst = (jSrc>>jAlignR) | jRem;
  182. *pjDst++ = jDst;
  183. //next remainder
  184. jRem = jSrc << jAlignL;
  185. }
  186. // go to the beginging full byte of
  187. // next scan line
  188. pjDst += iStrideDst;
  189. pjSrc += iStrideSrc;
  190. };
  191. break;
  192. case 2:
  193. while (cy--)
  194. {
  195. jRem = *pjSrc << jAlignL;
  196. pjSrcEnd = pjSrc+cFullBytes;
  197. while (pjSrc != pjSrcEnd)
  198. {
  199. jSrc = *(++pjSrc);
  200. jDst = (jSrc>>jAlignR) | jRem;
  201. *pjDst++ = ~jDst;
  202. //next remainder
  203. jRem = jSrc << jAlignL;
  204. }
  205. // go to the beginging full byte of
  206. // next scan line
  207. pjDst += iStrideDst;
  208. pjSrc += iStrideSrc;
  209. }; //while
  210. break;
  211. default: ;
  212. } //switch
  213. } //else
  214. } //if
  215. // End of our dealing with the full bytes
  216. //build our masks
  217. jMask = 0xFF >> iDst;
  218. // if there are only one partial left byte,
  219. // the mask is special
  220. // for example, when we have 00111000 for
  221. // Dst
  222. if (!bNextByte)
  223. {
  224. jEndMask = 0XFF << (8-(xDstEnd & 0x0007));
  225. jMask = jMask & jEndMask;
  226. bNextSrc = ((iSrc + cx) > 8);
  227. }
  228. // Begin dealing with the left strip of the first
  229. // partial byte
  230. // First check if there are any partial
  231. // left byte. Otherwise don't bother
  232. if (iDst | !bNextByte)
  233. {
  234. pjDst = psb->pjDst + (psb->xDstStart>>3);
  235. pjSrc = psb->pjSrc + (psb->xSrcStart>>3);
  236. cy = psb->cy;
  237. switch (ixlate)
  238. {
  239. case 0:
  240. while (cy--)
  241. {
  242. *pjDst = *pjDst & ~jMask;
  243. pjDst += lDeltaDst;
  244. }
  245. break;
  246. case 1:
  247. if (iSrc > iDst)
  248. {
  249. if (bNextSrc)
  250. while (cy--)
  251. {
  252. jSrc = *pjSrc << jAlignL;
  253. jSrc |= *(pjSrc+1) >> jAlignR;
  254. jSrc &= jMask;
  255. *pjDst = (*pjDst & (~jMask)) | jSrc;
  256. pjDst += lDeltaDst;
  257. pjSrc += lDeltaSrc;
  258. }
  259. else //if !bNextSrc
  260. while (cy--)
  261. {
  262. jSrc = *pjSrc << jAlignL;
  263. jSrc &= jMask;
  264. *pjDst = (*pjDst & (~jMask)) | jSrc;
  265. pjDst += lDeltaDst;
  266. pjSrc += lDeltaSrc;
  267. }
  268. }
  269. else if (iSrc < iDst)
  270. {
  271. while (cy--)
  272. {
  273. jSrc = *pjSrc >> jAlignR;
  274. jSrc &= jMask;
  275. *pjDst = (*pjDst & (~jMask)) | jSrc;
  276. pjDst += lDeltaDst;
  277. pjSrc += lDeltaSrc;
  278. }
  279. }
  280. else // iSrc = iDst
  281. {
  282. while (cy--)
  283. {
  284. jSrc = *pjSrc;
  285. jSrc &= jMask;
  286. *pjDst = (*pjDst & (~jMask)) | jSrc;
  287. pjDst += lDeltaDst;
  288. pjSrc += lDeltaSrc;
  289. }
  290. }
  291. break;
  292. case 2:
  293. if (iSrc > iDst)
  294. {
  295. while (cy--)
  296. {
  297. jSrc = *pjSrc << jAlignL;
  298. jSrc |= *(pjSrc+1) >> jAlignR;
  299. jSrc = ~jSrc & jMask;
  300. *pjDst = (*pjDst & (~jMask)) | jSrc;
  301. //go to next scan line
  302. pjDst += lDeltaDst;
  303. pjSrc += lDeltaSrc;
  304. }
  305. }
  306. else if (iSrc < iDst)
  307. {
  308. while (cy--)
  309. {
  310. jSrc = *pjSrc >> jAlignR;
  311. jSrc = ~jSrc & jMask;
  312. *pjDst = (*pjDst & (~jMask)) | jSrc;
  313. //go to next scan line
  314. pjDst += lDeltaDst;
  315. pjSrc += lDeltaSrc;
  316. }
  317. }
  318. else // iSrc = iDst
  319. {
  320. while (cy--)
  321. {
  322. jSrc = *pjSrc;
  323. jSrc = ~jSrc & jMask;
  324. *pjDst = (*pjDst & (~jMask)) | jSrc;
  325. //go to next scan line
  326. pjDst += lDeltaDst;
  327. pjSrc += lDeltaSrc;
  328. }
  329. }
  330. break;
  331. case 3:
  332. while (cy--)
  333. {
  334. *pjDst = *pjDst | jMask;
  335. pjDst += lDeltaDst;
  336. }
  337. break;
  338. default: ;
  339. } //switch
  340. } //if
  341. // Begin dealing with the right edge
  342. // of partial bytes
  343. jMask = 0xFF >> ((BYTE)(psb->xDstStart+cx) & 0x0007);
  344. // first check if there is any partial
  345. // byte left
  346. // and has next byte
  347. if ((xDstEnd & 0x0007)
  348. && bNextByte)
  349. {
  350. // Get the last partial bytes on the
  351. // scan line
  352. pjDst = pjLDst;
  353. // Get the Src byte that matches the
  354. // right partial Dst byte
  355. // since xSrcEnd always point one
  356. // pixel after the last pixel, minus 1
  357. // from it
  358. pjSrc = psb->pjSrc + ((psb->xSrcEnd-1) >>3);
  359. // Get the ending position in the last
  360. // Src and Dst bytes
  361. iSrc = (psb->xSrcEnd-1) & 0x0007;
  362. iDst = (xDstEnd-1) & 0x0007;
  363. cy = psb->cy;
  364. switch (ixlate)
  365. {
  366. case 0:
  367. while (cy--)
  368. {
  369. *pjDst &= jMask;
  370. pjDst += lDeltaDst;
  371. }
  372. break;
  373. case 1:
  374. if (iSrc > iDst)
  375. {
  376. while (cy--)
  377. {
  378. jSrc = *pjSrc << jAlignL;
  379. jSrc &= ~jMask;
  380. *pjDst = (*pjDst & jMask) | jSrc;
  381. //go to next scan line
  382. pjDst += lDeltaDst;
  383. pjSrc += lDeltaSrc;
  384. }
  385. }
  386. else if (iSrc < iDst)
  387. {
  388. while (cy--)
  389. {
  390. jSrc = *(pjSrc-1) << jAlignL;
  391. jSrc |= *pjSrc >> jAlignR;
  392. jSrc &= ~jMask;
  393. *pjDst = (*pjDst & jMask) | jSrc;
  394. //go to next scan line
  395. pjDst += lDeltaDst;
  396. pjSrc += lDeltaSrc;
  397. }
  398. }
  399. else // iSrc = iDst
  400. {
  401. while (cy--)
  402. {
  403. jSrc = *pjSrc;
  404. jSrc &= ~jMask;
  405. *pjDst = (*pjDst & jMask) | jSrc;
  406. //go to next scan line
  407. pjDst += lDeltaDst;
  408. pjSrc += lDeltaSrc;
  409. }
  410. }
  411. break;
  412. case 2:
  413. if (iSrc > iDst)
  414. {
  415. while (cy--)
  416. {
  417. jSrc = *pjSrc << jAlignL;
  418. jSrc = ~jSrc & ~jMask;
  419. *pjDst = (*pjDst & jMask) | jSrc;
  420. //go to next scan line
  421. pjDst += lDeltaDst;
  422. pjSrc += lDeltaSrc;
  423. }
  424. }
  425. else if (iSrc < iDst)
  426. {
  427. while (cy--)
  428. {
  429. jSrc = *(pjSrc-1) << jAlignL;
  430. jSrc |= *pjSrc >> jAlignR;
  431. jSrc = ~jSrc & ~jMask;
  432. *pjDst = (*pjDst & jMask) | jSrc;
  433. //go to next scan line
  434. pjDst += lDeltaDst;
  435. pjSrc += lDeltaSrc;
  436. }
  437. }
  438. else // iSrc = iDst
  439. {
  440. while (cy--)
  441. {
  442. jSrc = *pjSrc;
  443. jSrc = ~jSrc & ~jMask;
  444. *pjDst = (*pjDst & jMask) | jSrc;
  445. //go to next scan line
  446. pjDst += lDeltaDst;
  447. pjSrc += lDeltaSrc;
  448. }
  449. }
  450. break;
  451. case 3:
  452. while (cy--)
  453. {
  454. *pjDst = *pjDst | ~jMask;
  455. pjDst += lDeltaDst;
  456. }
  457. break;
  458. default: ;
  459. } //switch
  460. } //if
  461. }
  462. /*******************Public*Routine*****************\
  463. * vSrcCopyS1D1RtoL
  464. *
  465. * this function is only called when copy to the
  466. * same surface and has overlapping.
  467. *
  468. * There are three main loops in this function.
  469. *
  470. * The first loop deals with the starting pixels on the
  471. * right most partial bytes. This must
  472. * come first because it is Right to Left and overlapping.
  473. *
  474. * The second loop deals with the full bytes part of
  475. * the Dst while fetching/shifting the matching 8 bits
  476. * from the Src.
  477. *
  478. * The third loop deals with the ending pixles on the
  479. * left most partial bytes.
  480. *
  481. * Special case:
  482. * when the Src and Dst are aligned, we enter
  483. * a different loop to use RltMoveMem to avoid
  484. * shifting. RltMoveMemory gurantee the overlapping
  485. * parts to be correct.
  486. *
  487. * History:
  488. * 26-Oct-1994 -by- Lingyun Wang [lingyunw]
  489. * Wrote it.
  490. \**************************************************/
  491. VOID vSrcCopyS1D1RtoL(PBLTINFO psb)
  492. {
  493. BYTE jSrc; // holds a source byte
  494. BYTE jDst; // holds a dest byte
  495. INT iSrc; // bit position in the first Src byte
  496. INT iDst; // bit position in the first Dst byte
  497. PBYTE pjDst; // pointer to the Src bytes
  498. PBYTE pjSrc; // pointer to the Dst bytes
  499. PBYTE pjLDst; // pointer to the last Dst byte
  500. LONG xSrcEnd = psb->xSrcEnd;
  501. LONG cy; // number of pixels
  502. LONG cx; // number of rows
  503. BYTE jAlignL; // alignment bits to the left
  504. BYTE jAlignR; // alignment bits to the right
  505. BYTE jMask; // Masks used for shifting
  506. BYTE jEndMask;
  507. LONG cFullBytes; //number of full bytes to deal with
  508. BOOL bNextByte;
  509. LONG xDstEnd;
  510. LONG lDeltaDst;
  511. LONG lDeltaSrc;
  512. BOOL bNextSrc = TRUE;
  513. // We assume we are doing right to left top to bottom blting
  514. ASSERTGDI(psb->xDir == -1, "vSrcCopyS1D1RtoL - direction not right to left");
  515. ASSERTGDI(psb->cy != 0, "ERROR: Src Move cy == 0");
  516. ASSERTGDI (psb->pxlo->pulXlate[0] == 0, "vSrcCopyS1D1RtoL - should be straight copy");
  517. ASSERTGDI (psb->pxlo->pulXlate[1] == 1, "vSrcCopyS1D1RtoL - should be straight copy");
  518. //DbgPrint ("vsrccopys1d1rtol\n");
  519. //Get Src and Dst start positions
  520. iSrc = psb->xSrcStart & 0x0007;
  521. iDst = psb->xDstStart & 0x0007;
  522. // Checking alignment
  523. // If Src starting point is ahead of Dst
  524. if (iSrc < iDst)
  525. jAlignL = 8-(iDst - iSrc);
  526. // If Dst starting point is ahead of Src
  527. else
  528. jAlignL = iSrc - iDst;
  529. jAlignR = 8 - jAlignL;
  530. cx=psb->cx;
  531. xDstEnd = psb->xDstStart - cx;
  532. lDeltaDst = psb->lDeltaDst;
  533. lDeltaSrc = psb->lDeltaSrc;
  534. //check if there is a next byte
  535. bNextByte = !((xDstEnd>>3) ==
  536. (psb->xDstStart>>3));
  537. // prepare our mask for the beggining
  538. // partial bytes (this is on the right
  539. // hand side)
  540. jMask = 0xFF << (7-(psb->xDstStart&0x07));
  541. // if there are only one partial byte, the
  542. // mask is special, for example, when
  543. // we have 00111000 for dst.
  544. if (!bNextByte)
  545. {
  546. jEndMask = 0XFF >> ((1+xDstEnd) & 0x0007);
  547. jMask = jMask & jEndMask;
  548. // test if src needs to go to 1 byte left
  549. // for example, iSrc == 0, cx==1, does
  550. // not need to fetch the byte to the left
  551. if (iSrc < iDst)
  552. bNextSrc = ((iSrc-cx) < -1);
  553. }
  554. // Dealing with the starting pixels
  555. // first, since we are doing right
  556. // to left.
  557. if (((iDst+1)&0x07) | !bNextByte)
  558. {
  559. pjDst = psb->pjDst + (psb->xDstStart>>3);
  560. pjSrc = psb->pjSrc + (psb->xSrcStart>>3);
  561. cy = psb->cy;
  562. if (iSrc > iDst)
  563. {
  564. while (cy--)
  565. {
  566. jSrc = *pjSrc << jAlignL;
  567. jSrc = jSrc & jMask;
  568. *pjDst = (*pjDst & (~jMask)) | jSrc;
  569. //go to next scan line
  570. pjDst += lDeltaDst;
  571. pjSrc += lDeltaSrc;
  572. }
  573. }
  574. else if (iSrc < iDst)
  575. {
  576. if (bNextSrc)
  577. while (cy--)
  578. {
  579. jSrc = *pjSrc >> jAlignR;
  580. jSrc |= *(pjSrc-1) << jAlignL;
  581. jSrc = jSrc & jMask;
  582. *pjDst = (*pjDst & (~jMask)) | jSrc;
  583. //go to next scan line
  584. pjDst += lDeltaDst;
  585. pjSrc += lDeltaSrc;
  586. }
  587. else
  588. // if there is no next src byte,
  589. // accessing pjSrc-1 will cause
  590. // access violation.
  591. // this only happens on the starting
  592. // partial byte when bNextByte is False
  593. while (cy--)
  594. {
  595. jSrc = *pjSrc >> jAlignR;
  596. jSrc = jSrc & jMask;
  597. *pjDst = (*pjDst & (~jMask)) | jSrc;
  598. //go to next scan line
  599. pjDst += lDeltaDst;
  600. pjSrc += lDeltaSrc;
  601. }
  602. }
  603. else // iSrc = iDst
  604. {
  605. while (cy--)
  606. {
  607. jSrc = *pjSrc;
  608. jSrc = jSrc & jMask;
  609. *pjDst = (*pjDst & (~jMask)) | jSrc;
  610. pjDst += lDeltaDst;
  611. pjSrc += lDeltaSrc;
  612. }
  613. }
  614. }
  615. // The following loop is the inner loop part
  616. // where we deals with a byte at a time
  617. // when this main part is done, we deal
  618. // with the begin and end partial bytes
  619. //
  620. if (bNextByte)
  621. {
  622. long iStrideSrc;
  623. long iStrideDst;
  624. PBYTE pjSrcEnd;
  625. //Get first Dst full byte
  626. pjDst = psb->pjDst + ((psb->xDstStart-7)>>3);
  627. //Get the Src byte that matches the first Dst
  628. // full byte
  629. pjSrc = psb->pjSrc + ((psb->xSrcStart-((iDst+1)&0x07))>>3);
  630. //Get last byte
  631. pjLDst = psb->pjDst + (xDstEnd>>3);
  632. //Get the number of full bytes
  633. // Sundown safe truncation
  634. cFullBytes = (ULONG)(pjDst - pjLDst);
  635. //the increment to the full byte on the next scan line
  636. iStrideDst = lDeltaDst + cFullBytes;
  637. iStrideSrc = lDeltaSrc + cFullBytes;
  638. // deal with our special case
  639. cy = psb->cy;
  640. if (!jAlignL)
  641. {
  642. while (cy--)
  643. {
  644. RtlMoveMemory(pjDst-(cFullBytes-1),pjSrc-(cFullBytes-1),cFullBytes);
  645. // move to the beginning full byte
  646. // on the next scan line
  647. pjDst += lDeltaDst;
  648. pjSrc += lDeltaSrc;
  649. }
  650. } //end of if (!jAlignL)
  651. else
  652. {
  653. BYTE jRem;
  654. while (cy--)
  655. {
  656. jRem = *pjSrc >> jAlignR;
  657. pjSrcEnd = pjSrc-cFullBytes;
  658. while (pjSrc != pjSrcEnd)
  659. {
  660. jSrc = *(--pjSrc);
  661. jDst = (jSrc<<jAlignL) | jRem;
  662. *pjDst-- = jDst;
  663. //next remainder
  664. jRem = jSrc >> jAlignR;
  665. }
  666. // go to the beginging full byte of
  667. // next scan line
  668. pjDst += iStrideDst;
  669. pjSrc += iStrideSrc;
  670. }
  671. }
  672. } //if
  673. // Begin dealing with the ending pixels
  674. jMask = 0xFF << (8-((1+xDstEnd) & 0x0007));
  675. // first check if there is any partial
  676. // byte left
  677. // and has next byte
  678. if (((1+xDstEnd) & 0x0007)
  679. && bNextByte)
  680. {
  681. // Get the last partial bytes on the
  682. // scan line
  683. pjDst = pjLDst;
  684. // Get the Src byte that matches the
  685. // right partial Dst byte
  686. //
  687. pjSrc = psb->pjSrc + ((psb->xSrcEnd+1) >>3);
  688. // Get the ending position in the last
  689. // Src and Dst bytes
  690. iSrc = (psb->xSrcEnd+1) & 0x0007;
  691. iDst = (xDstEnd + 1)& 0x0007;
  692. cy = psb->cy;
  693. if (iSrc > iDst)
  694. {
  695. while (cy--)
  696. {
  697. jSrc = *pjSrc << jAlignL;
  698. jSrc |= *(pjSrc+1) >> jAlignR;
  699. jSrc &= ~jMask;
  700. *pjDst = (*pjDst & jMask) | jSrc;
  701. pjDst += lDeltaDst;
  702. pjSrc += lDeltaSrc;
  703. }
  704. }
  705. else if (iSrc < iDst)
  706. {
  707. while (cy--)
  708. {
  709. jSrc = *pjSrc >> jAlignR;
  710. jSrc &= ~jMask;
  711. *pjDst = (*pjDst & jMask) | jSrc;
  712. pjDst += lDeltaDst;
  713. pjSrc += lDeltaSrc;
  714. }
  715. }
  716. else // iSrc = iDst
  717. {
  718. while (cy--)
  719. {
  720. jSrc = *pjSrc;
  721. jSrc &= ~jMask;
  722. *pjDst = (*pjDst & jMask) | jSrc;
  723. pjDst += lDeltaDst;
  724. pjSrc += lDeltaSrc;
  725. }
  726. }
  727. } //if
  728. }
  729. /******************************Public*Routine******************************\
  730. * vSrcCopyS4D1
  731. *
  732. * Note we use pxlo to translate rather than looking at the foreground
  733. * or background color. This is to keep the PM/Windows differences
  734. * transparent to the blt code.
  735. *
  736. * History:
  737. * 18-Feb-1991 -by- Patrick Haluptzok patrickh
  738. * Wrote it.
  739. \**************************************************************************/
  740. VOID vSrcCopyS4D1(PBLTINFO psb)
  741. {
  742. // We assume we are doing left to right top to bottom blting
  743. ASSERTGDI(psb->xDir == 1, "vSrcCopyS4D1 - direction not left to right");
  744. ASSERTGDI(psb->yDir == 1, "vSrcCopyS4D1 - direction not up to down");
  745. BYTE jSrc;
  746. BYTE jDst;
  747. LONG iSrc;
  748. LONG iDst;
  749. PBYTE pjDstTemp;
  750. PBYTE pjSrcTemp;
  751. PBYTE pjDst = psb->pjDst + (psb->xDstStart >> 3);
  752. PBYTE pjSrc = psb->pjSrc + (psb->xSrcStart >> 1);
  753. ULONG cy = psb->cy;
  754. PULONG pulXlate = psb->pxlo->pulXlate;
  755. ASSERTGDI(cy != 0, "ERROR: Src Move cy == 0");
  756. while(1)
  757. {
  758. // Initialize all the variables
  759. pjDstTemp = pjDst;
  760. pjSrcTemp = pjSrc;
  761. iSrc = psb->xSrcStart;
  762. iDst = psb->xDstStart;
  763. // Set up the Src. Left to Right.
  764. if (iSrc & 0x00000001)
  765. jSrc = *(pjSrcTemp++);
  766. // Set up the Dst. We just keep adding bits to the right and
  767. // shifting left.
  768. if (iDst & 0x00000007)
  769. {
  770. // We're gonna need some bits from the 1st byte of Dst.
  771. jDst = (BYTE) ( ((ULONG) (*pjDstTemp)) >> (8 - (iDst & 0x00000007)) );
  772. }
  773. // Do the inner loop on a scanline
  774. while(iSrc != psb->xSrcEnd)
  775. {
  776. jDst <<= 1;
  777. if (iSrc & 0x00000001)
  778. {
  779. if (pulXlate[(jSrc & 0x0F)])
  780. jDst |= 0x01;
  781. }
  782. else
  783. {
  784. jSrc = *(pjSrcTemp++);
  785. if (pulXlate[((jSrc & 0xF0) >> 4)])
  786. jDst |= 0x01;
  787. }
  788. iDst++;
  789. iSrc++;
  790. if (!(iDst & 0x07))
  791. *(pjDstTemp++) = jDst;
  792. }
  793. // Clean up after the inner loop
  794. if (iDst & 0x00000007)
  795. {
  796. // We need to build up the last pel correctly.
  797. jSrc = (BYTE) (0x000000FF >> (iDst & 0x00000007));
  798. jDst = (BYTE) (jDst << (8 - (iDst & 0x00000007)));
  799. *pjDstTemp = (BYTE) ((*pjDstTemp & jSrc) | (jDst & ~jSrc));
  800. }
  801. // Check if we have anymore scanlines to do
  802. if (--cy)
  803. {
  804. pjSrc += psb->lDeltaSrc;
  805. pjDst += psb->lDeltaDst;
  806. }
  807. else
  808. break;
  809. }
  810. }
  811. /******************************Public*Routine******************************\
  812. * vSrcCopyS8D1
  813. *
  814. * Note we use pxlo to translate rather than looking at the foreground
  815. * or background color. This is to keep the PM/Windows differences
  816. * transparent to the blt code.
  817. *
  818. * History:
  819. * 18-Feb-1991 -by- Patrick Haluptzok patrickh
  820. * Wrote it.
  821. \**************************************************************************/
  822. VOID vSrcCopyS8D1(PBLTINFO psb)
  823. {
  824. // We assume we are doing left to right top to bottom blting
  825. ASSERTGDI(psb->xDir == 1, "vSrcCopyS8D1 - direction not left to right");
  826. ASSERTGDI(psb->yDir == 1, "vSrcCopyS8D1 - direction not up to down");
  827. BYTE jDst;
  828. LONG iDst;
  829. PBYTE pjDstTemp;
  830. PBYTE pjSrcTemp;
  831. LONG xDstEnd = psb->xDstStart + psb->cx;
  832. PULONG pulXlate = psb->pxlo->pulXlate;
  833. PBYTE pjDst = psb->pjDst + (psb->xDstStart >> 3);
  834. PBYTE pjSrc = psb->pjSrc + psb->xSrcStart;
  835. ULONG cy = psb->cy;
  836. BYTE jMask;
  837. ASSERTGDI(cy != 0, "ERROR: Src Move cy == 0");
  838. while(1)
  839. {
  840. // Initialize the variables
  841. pjDstTemp = pjDst;
  842. pjSrcTemp = pjSrc;
  843. iDst = psb->xDstStart;
  844. // Set up jDst. We just keep adding bits to the right and
  845. // shifting left.
  846. if (iDst & 0x00000007)
  847. {
  848. // We're gonna need some bits from the 1st byte of Dst.
  849. jDst = (BYTE) ( ((ULONG) (*pjDstTemp)) >> (8 - (iDst & 0x00000007)) );
  850. }
  851. // Do the inner loop on a scanline
  852. while(iDst != xDstEnd)
  853. {
  854. jDst <<= 1;
  855. if (pulXlate[(*(pjSrcTemp++))])
  856. jDst |= 0x01;
  857. iDst++;
  858. if (!(iDst & 0x07))
  859. *(pjDstTemp++) = jDst;
  860. }
  861. // Clean up after the inner loop
  862. if (iDst & 0x00000007)
  863. {
  864. // We need to build up the last pel correctly.
  865. jMask = (BYTE) (0x000000FF >> (iDst & 0x00000007));
  866. jDst = (BYTE) (jDst << (8 - (iDst & 0x00000007)));
  867. *pjDstTemp = (BYTE) ((*pjDstTemp & jMask) | (jDst & ~jMask));
  868. }
  869. // Check if we have anymore scanlines to do
  870. if (--cy)
  871. {
  872. pjSrc += psb->lDeltaSrc;
  873. pjDst += psb->lDeltaDst;
  874. }
  875. else
  876. break;
  877. }
  878. }
  879. /******************************Public*Routine******************************\
  880. * vSrcCopyS16D1
  881. *
  882. * Note we use pxlo to translate rather than looking at the foreground
  883. * or background color. This is to keep the PM/Windows differences
  884. * transparent to the blt code.
  885. *
  886. * History:
  887. * 18-Feb-1991 -by- Patrick Haluptzok patrickh
  888. * Wrote it.
  889. \**************************************************************************/
  890. VOID vSrcCopyS16D1(PBLTINFO psb)
  891. {
  892. // We assume we are doing left to right top to bottom blting
  893. ASSERTGDI(psb->xDir == 1, "vSrcCopyS16D1 - direction not left to right");
  894. ASSERTGDI(psb->yDir == 1, "vSrcCopyS16D1 - direction not up to down");
  895. BYTE jDst;
  896. LONG iDst;
  897. PBYTE pjDstTemp;
  898. PUSHORT pusSrcTemp;
  899. LONG xDstEnd = psb->xDstStart + psb->cx;
  900. XLATE *pxlo = (XLATE *) psb->pxlo;
  901. PBYTE pjDst = psb->pjDst + (psb->xDstStart >> 3);
  902. PUSHORT pusSrc = (PUSHORT) (psb->pjSrc + (psb->xSrcStart << 1));
  903. ULONG cy = psb->cy;
  904. BYTE jMask;
  905. ASSERTGDI(cy != 0, "ERROR: Src Move cy == 0");
  906. while(1)
  907. {
  908. // Initialize the variables
  909. pjDstTemp = pjDst;
  910. pusSrcTemp = pusSrc;
  911. iDst = psb->xDstStart;
  912. // Set up jDst. We just keep adding bits to the right and
  913. // shifting left.
  914. if (iDst & 0x00000007)
  915. {
  916. // We're gonna need some bits from the 1st byte of Dst.
  917. jDst = (BYTE) ( ((ULONG) (*pjDstTemp)) >> (8 - (iDst & 0x00000007)) );
  918. }
  919. // Do the inner loop on a scanline
  920. while(iDst != xDstEnd)
  921. {
  922. jDst <<= 1;
  923. if (pxlo->ulTranslate(*(pusSrcTemp++)))
  924. jDst |= 0x01;
  925. iDst++;
  926. if (!(iDst & 0x07))
  927. *(pjDstTemp++) = jDst;
  928. }
  929. // Clean up after the inner loop
  930. if (iDst & 0x00000007)
  931. {
  932. // We need to build up the last pel correctly.
  933. jMask = (BYTE) (0x000000FF >> (iDst & 0x00000007));
  934. jDst = (BYTE) (jDst << (8 - (iDst & 0x00000007)));
  935. *pjDstTemp = (BYTE) ((*pjDstTemp & jMask) | (jDst & ~jMask));
  936. }
  937. // Check if we have anymore scanlines to do
  938. if (--cy)
  939. {
  940. pusSrc = (PUSHORT) (((PBYTE) pusSrc) + psb->lDeltaSrc);
  941. pjDst += psb->lDeltaDst;
  942. }
  943. else
  944. break;
  945. }
  946. }
  947. /******************************Public*Routine******************************\
  948. * vSrcCopyS24D1
  949. *
  950. * Note we use pxlo to translate rather than looking at the foreground
  951. * or background color. This is to keep the PM/Windows differences
  952. * transparent to the blt code.
  953. *
  954. * History:
  955. * 18-Feb-1991 -by- Patrick Haluptzok patrickh
  956. * Wrote it.
  957. \**************************************************************************/
  958. VOID vSrcCopyS24D1(PBLTINFO psb)
  959. {
  960. // We assume we are doing left to right top to bottom blting
  961. ASSERTGDI(psb->xDir == 1, "vSrcCopyS24D1 - direction not left to right");
  962. ASSERTGDI(psb->yDir == 1, "vSrcCopyS24D1 - direction not up to down");
  963. BYTE jDst;
  964. LONG iDst;
  965. ULONG ulDink; // variable to dink around with bytes
  966. PBYTE pjDstTemp;
  967. PBYTE pjSrcTemp;
  968. LONG xDstEnd = psb->xDstStart + psb->cx;
  969. XLATE *pxlo = (XLATE *) psb->pxlo;
  970. PBYTE pjDst = psb->pjDst + (psb->xDstStart >> 3);
  971. PBYTE pjSrc = psb->pjSrc + (psb->xSrcStart * 3);
  972. ULONG cy = psb->cy;
  973. BYTE jMask;
  974. ASSERTGDI(cy != 0, "ERROR: Src Move cy == 0");
  975. while(1)
  976. {
  977. // Initialize the variables
  978. pjDstTemp = pjDst;
  979. pjSrcTemp = pjSrc;
  980. iDst = psb->xDstStart;
  981. // Set up jDst. We just keep adding bits to the right and
  982. // shifting left.
  983. if (iDst & 0x00000007)
  984. {
  985. // We're gonna need some bits from the 1st byte of Dst.
  986. jDst = (BYTE) ( ((ULONG) (*pjDstTemp)) >> (8 - (iDst & 0x00000007)) );
  987. }
  988. // Do the inner loop on a scanline
  989. while(iDst != xDstEnd)
  990. {
  991. jDst <<= 1;
  992. ulDink = *(pjSrcTemp + 2);
  993. ulDink = ulDink << 8;
  994. ulDink |= (ULONG) *(pjSrcTemp + 1);
  995. ulDink = ulDink << 8;
  996. ulDink |= (ULONG) *pjSrcTemp;
  997. pjSrcTemp += 3;
  998. if (pxlo->ulTranslate(ulDink))
  999. jDst |= 0x01;
  1000. iDst++;
  1001. if (!(iDst & 0x07))
  1002. *(pjDstTemp++) = jDst;
  1003. }
  1004. // Clean up after the inner loop
  1005. if (iDst & 0x00000007)
  1006. {
  1007. // We need to build up the last pel correctly.
  1008. jMask = (BYTE) (0x000000FF >> (iDst & 0x00000007));
  1009. jDst = (BYTE) (jDst << (8 - (iDst & 0x00000007)));
  1010. *pjDstTemp = (BYTE) ((*pjDstTemp & jMask) | (jDst & ~jMask));
  1011. }
  1012. // Check if we have anymore scanlines to do
  1013. if (--cy)
  1014. {
  1015. pjSrc += psb->lDeltaSrc;
  1016. pjDst += psb->lDeltaDst;
  1017. }
  1018. else
  1019. break;
  1020. }
  1021. }
  1022. /******************************Public*Routine******************************\
  1023. * vSrcCopyS32D1
  1024. *
  1025. * Note we use pxlo to translate rather than looking at the foreground
  1026. * or background color. This is to keep the PM/Windows differences
  1027. * transparent to the blt code.
  1028. *
  1029. * History:
  1030. * 18-Feb-1991 -by- Patrick Haluptzok patrickh
  1031. * Wrote it.
  1032. \**************************************************************************/
  1033. VOID vSrcCopyS32D1(PBLTINFO psb)
  1034. {
  1035. // We assume we are doing left to right top to bottom blting
  1036. ASSERTGDI(psb->xDir == 1, "vSrcCopyS32D1 - direction not left to right");
  1037. ASSERTGDI(psb->yDir == 1, "vSrcCopyS32D1 - direction not up to down");
  1038. BYTE jDst;
  1039. LONG iDst;
  1040. PBYTE pjDstTemp;
  1041. PULONG pulSrcTemp;
  1042. LONG xDstEnd = psb->xDstStart + psb->cx;
  1043. XLATE *pxlo = (XLATE *) psb->pxlo;
  1044. PBYTE pjDst = psb->pjDst + (psb->xDstStart >> 3);
  1045. PULONG pulSrc = (PULONG) (psb->pjSrc + (psb->xSrcStart << 2));
  1046. ULONG cy = psb->cy;
  1047. BYTE jMask;
  1048. ASSERTGDI(cy != 0, "ERROR: Src Move cy == 0");
  1049. while(1)
  1050. {
  1051. // Initialize the variables
  1052. pjDstTemp = pjDst;
  1053. pulSrcTemp = pulSrc;
  1054. iDst = psb->xDstStart;
  1055. // Set up jDst. We just keep adding bits to the right and
  1056. // shifting left.
  1057. if (iDst & 0x00000007)
  1058. {
  1059. // We're gonna need some bits from the 1st byte of Dst.
  1060. jDst = (BYTE) ( ((ULONG) (*pjDstTemp)) >> (8 - (iDst & 0x00000007)) );
  1061. }
  1062. // Do the inner loop on a scanline
  1063. while(iDst != xDstEnd)
  1064. {
  1065. jDst <<= 1;
  1066. if (pxlo->ulTranslate(*(pulSrcTemp++)))
  1067. jDst |= 0x01;
  1068. iDst++;
  1069. if (!(iDst & 0x07))
  1070. *(pjDstTemp++) = jDst;
  1071. }
  1072. // Clean up after the inner loop
  1073. if (iDst & 0x00000007)
  1074. {
  1075. // We need to build up the last pel correctly.
  1076. jMask = (BYTE) (0x000000FF >> (iDst & 0x00000007));
  1077. jDst = (BYTE) (jDst << (8 - (iDst & 0x00000007)));
  1078. *pjDstTemp = (BYTE) ((*pjDstTemp & jMask) | (jDst & ~jMask));
  1079. }
  1080. // Check if we have anymore scanlines to do
  1081. if (--cy)
  1082. {
  1083. pulSrc = (PULONG) (((PBYTE) pulSrc) + psb->lDeltaSrc);
  1084. pjDst += psb->lDeltaDst;
  1085. }
  1086. else
  1087. break;
  1088. }
  1089. }