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.

6959 lines
236 KiB

  1. ///////////////////////////////////////////////////////////////////////
  2. //
  3. // BitBlt.CXX - Contains the BitBlt Library functions
  4. //
  5. // Copyright (c) 1994 Microsoft Corporation
  6. //
  7. // Notes:
  8. // Conditional Compiliation Definitions:
  9. // DESKTOP = Penguin platform emulation on the Desktop
  10. // platform (32 bit).
  11. // PENGUIN = Penguin H/W platform support.
  12. // PULSAR = Pulsar platform support.
  13. // DDRAW = DirectDraw support
  14. //
  15. // History:
  16. // 10/18/94 - Scott Leatham Created it w/8BPP support only
  17. // 10/26/94 - Olivier Garamfalvi Rewrote blitting code
  18. // Added SRCINVERT ROP support
  19. // 10/30/94 - Olivier Garamfalvi Added 24 to 24 bit blitting
  20. // 05/08/95 - Myron Thomas Added 8+Alpha to 24 bit blitting
  21. // Added 24+Alpha to 24 bit blitting
  22. // 07/19/95 - Myron Thomas Ripped out SRCINVERT ROP support
  23. // 09/05/95 - Myron Thomas Added 24P to 8 bit blitting
  24. // 01/15/96 - Michael McDaniel changed conditional compilation
  25. // for DirectDraw
  26. // 04/16/96 - Michael McDaniel removed FillRect's test for
  27. // CLR_INVALID so Z-Buffer filling will work.
  28. //
  29. //
  30. ///////////////////////////////////////////////////////////////////////
  31. #include "precomp.hxx"
  32. #include "bltos.h"
  33. #include "blt0101.hxx"
  34. #include "blt0108.hxx"
  35. #include "blt0124.hxx"
  36. #include "blt0801.hxx"
  37. #include "blt0808.hxx"
  38. #include "blt0824.hxx"
  39. #include "blt0824p.hxx"
  40. #include "blt08a24.hxx"
  41. #include "blt8a24p.hxx"
  42. #include "blt1616.hxx"
  43. #include "blt1624.hxx"
  44. #include "blt1624p.hxx"
  45. #include "blt2401.hxx"
  46. #include "blt24p01.hxx"
  47. #include "blt24p08.hxx"
  48. #include "blt2408.hxx"
  49. #include "blt2424.hxx"
  50. #include "blt2424p.hxx"
  51. #include "blt24a24.hxx"
  52. #include "bt24a24p.hxx"
  53. #include "bt24p24p.hxx"
  54. #if 0
  55. #if defined( WIN95 ) || defined(WINNT)
  56. #define DDRAW
  57. #endif // WIN95
  58. #ifdef DDRAW
  59. #if defined ( WIN95 ) && !defined( NT_BUILD_ENVIRONMENT )
  60. #include "..\ddraw\ddrawp.h"
  61. #else
  62. /*
  63. * This is parsed if NT build or win95 build under NT environment
  64. */
  65. #include "..\..\ddraw\ddrawp.h"
  66. #endif
  67. #ifdef __cplusplus
  68. extern "C" {
  69. #endif // c++
  70. #include "dpf.h"
  71. #ifdef __cplusplus
  72. }
  73. #endif // c++
  74. #endif // DDRAW
  75. #endif
  76. ///////////////////////////////////////////////////////////////////////
  77. //
  78. // Local Declarations
  79. //
  80. ///////////////////////////////////////////////////////////////////////
  81. void FlipRectHorizontal (RECT *rc)
  82. {
  83. int temp;
  84. temp = rc->right;
  85. rc->right = rc->left;
  86. rc->left = temp;
  87. }
  88. void FlipRectVertical (RECT *rc)
  89. {
  90. int temp;
  91. temp = rc->bottom;
  92. rc->bottom = rc->top;
  93. rc->top = temp;
  94. }
  95. ///////////////////////////////////////////////////////////////////////
  96. //
  97. // Private BlitLib_BitBlt01to01 -
  98. // BitBlit from source bitmap to destination bitmap
  99. // with optional transparency and/or alpha blending using the
  100. // specified raster operation.
  101. //
  102. // Parameters:
  103. // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB
  104. // pDibBitsDst Pointer to the bits for the Destination DIB
  105. // prcDst Pointer to the Destination rectangle
  106. // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB
  107. // pDibBitsSrc Pointer to the bits for the Source DIB
  108. // prcSrc Pointer to the Source rectangle
  109. // crTransparent Tranparent color value
  110. // arAlpha Per-surface Alpha value
  111. // dwRop Raster Operation for the blit
  112. //
  113. // Return Value:
  114. // NO_ERROR or E_* value as specified in the .H file.
  115. //
  116. // Status: Incomplete
  117. //
  118. ///////////////////////////////////////////////////////////////////////
  119. SCODE BlitLib_BitBlt01to01(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst,
  120. PRECT prcDst, PDIBINFO pDibInfoSrc, PDIBBITS pDibBitsSrc,
  121. PRECT prcSrc, COLORREF crTransparent, ALPHAREF arAlpha, DWORD dwRop)
  122. {
  123. SCODE sc = NOERROR;
  124. int iNumSrcRows,
  125. iNumSrcCols,
  126. iBytesPerSrcScanLine,
  127. iSrcBitOffset,
  128. iNumDstRows,
  129. iNumDstCols,
  130. iBytesPerDstScanLine,
  131. iDstBitOffset,
  132. iHorizMirror = 1,
  133. iVertMirror = 1;
  134. BYTE *pbSrcScanLine,
  135. *pbDstScanLine;
  136. // alpha blending not currently supported in the 1 to 1 bpp blits
  137. if (arAlpha != ALPHA_INVALID) {
  138. return E_UNEXPECTED; // !!!! need better error codes
  139. }
  140. // normalize orientation of source and destination rectangles, and
  141. // compute sizes and relative orientations of source and destination rects
  142. if ((iNumSrcCols = BLITLIB_RECTWIDTH(prcSrc)) < 0) {
  143. iNumSrcCols = -iNumSrcCols;
  144. FlipRectHorizontal(prcSrc);
  145. FlipRectHorizontal(prcDst);
  146. }
  147. if ((iNumSrcRows = BLITLIB_RECTHEIGHT(prcSrc)) < 0) {
  148. iNumSrcRows = -iNumSrcRows;
  149. FlipRectVertical(prcSrc);
  150. FlipRectVertical(prcDst);
  151. }
  152. if ((iNumDstCols = BLITLIB_RECTWIDTH(prcDst)) < 0) {
  153. prcDst->left--;
  154. prcDst->right--;
  155. iNumDstCols = -iNumDstCols;
  156. iHorizMirror = -1;
  157. }
  158. if ((iNumDstRows = BLITLIB_RECTHEIGHT(prcDst)) < 0) {
  159. prcDst->top--;
  160. prcDst->bottom--;
  161. iNumDstRows = -iNumDstRows;
  162. iVertMirror = -1;
  163. }
  164. // compute pointers to the starting rows in the src and dst bitmaps
  165. // taking care to invert y values, since DIBs are upside-down
  166. pbSrcScanLine = (BYTE*) pDibBitsSrc + prcSrc->top * (iBytesPerSrcScanLine
  167. = DibWidthBytes(pDibInfoSrc)) + (prcSrc->left / 8);
  168. iSrcBitOffset = prcSrc->left % 8;
  169. pbDstScanLine = (BYTE*) pDibBitsDst + prcDst->top * (iBytesPerDstScanLine
  170. = DibWidthBytes(pDibInfoDst)) + (prcDst->left / 8);
  171. iDstBitOffset = prcDst->left % 8;
  172. // check to see if we need to worry about transparency
  173. if (crTransparent == CLR_INVALID) {
  174. // check if we can do a straight copy from src row to dst row
  175. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  176. // check what ROP we'll be performing
  177. if (dwRop == SRCCOPY) {
  178. // check if we can do a straight copy vertically,
  179. // or if we have to stretch, shrink, or mirror
  180. #if 0 // OGaramfa - bug workaround for now, Hcopy versions seem to
  181. // have a problem with the last few pixels of each
  182. // scanline
  183. if ((iNumSrcRows == iNumDstRows) && (iVertMirror == 1)) {
  184. Blt01to01_NoTrans_Hcopy_SRCCOPY_Vcopy(pbSrcScanLine,iSrcBitOffset,iBytesPerSrcScanLine,
  185. pbDstScanLine,iDstBitOffset,iBytesPerDstScanLine,
  186. iNumDstCols,iNumDstRows);
  187. } else {
  188. Blt01to01_NoTrans_Hcopy_SRCCOPY_NoVcopy(pbSrcScanLine,iSrcBitOffset,iBytesPerSrcScanLine,
  189. iNumSrcRows,pbDstScanLine,iDstBitOffset,
  190. iBytesPerDstScanLine * iVertMirror,
  191. iNumDstCols,iNumDstRows);
  192. }
  193. #else
  194. Blt01to01_NoTrans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcBitOffset,iBytesPerSrcScanLine,
  195. iNumSrcCols,iNumSrcRows,
  196. pbDstScanLine,iDstBitOffset,iBytesPerDstScanLine * iVertMirror,
  197. iNumDstCols,iNumDstRows,iHorizMirror);
  198. #endif
  199. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  200. } else {
  201. // check what ROP we'll be performing
  202. if (dwRop == SRCCOPY) {
  203. Blt01to01_NoTrans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcBitOffset,iBytesPerSrcScanLine,
  204. iNumSrcCols,iNumSrcRows,
  205. pbDstScanLine,iDstBitOffset,iBytesPerDstScanLine * iVertMirror,
  206. iNumDstCols,iNumDstRows,iHorizMirror);
  207. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  208. }
  209. } else {
  210. BYTE bTransparentIndex = (BYTE)crTransparent;
  211. // check what ROP we'll be performing
  212. if (dwRop == SRCCOPY) {
  213. Blt01to01_Trans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcBitOffset,iBytesPerSrcScanLine,
  214. iNumSrcCols,iNumSrcRows,
  215. pbDstScanLine,iDstBitOffset,iBytesPerDstScanLine * iVertMirror,
  216. iNumDstCols,iNumDstRows,iHorizMirror,
  217. bTransparentIndex);
  218. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  219. }
  220. return sc;
  221. }
  222. #ifndef DDRAW
  223. ///////////////////////////////////////////////////////////////////////
  224. //
  225. // Private BlitLib_BitBlt01to08 -
  226. // BitBlit from source bitmap to destination bitmap
  227. // with optional transparency and/or alpha blending using the
  228. // specified raster operation.
  229. //
  230. // Parameters:
  231. // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB
  232. // pDibBitsDst Pointer to the bits for the Destination DIB
  233. // prcDst Pointer to the Destination rectangle
  234. // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB
  235. // pDibBitsSrc Pointer to the bits for the Source DIB
  236. // prcSrc Pointer to the Source rectangle
  237. // crTransparent Tranparent color value
  238. // arAlpha Per-surface Alpha value
  239. // dwRop Raster Operation for the blit
  240. //
  241. // Return Value:
  242. // NO_ERROR or E_* value as specified in the .H file.
  243. //
  244. // Status: Incomplete
  245. //
  246. ///////////////////////////////////////////////////////////////////////
  247. SCODE BlitLib_BitBlt01to08(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst,
  248. PRECT prcDst, PDIBINFO pDibInfoSrc, PDIBBITS pDibBitsSrc,
  249. PRECT prcSrc, COLORREF crTransparent, ALPHAREF arAlpha, DWORD dwRop)
  250. {
  251. SCODE sc = NOERROR;
  252. int iNumSrcRows,
  253. iNumSrcCols,
  254. iBytesPerSrcScanLine,
  255. iSrcBitOffset,
  256. iNumDstRows,
  257. iNumDstCols,
  258. iDstScanLength,
  259. iHorizMirror = 1,
  260. iVertMirror = 1;
  261. BYTE *pbSrcScanLine,
  262. *pbDstScanLine,
  263. bOnColorIndex,
  264. bOffColorIndex;
  265. // alpha blending not currently supported in the 1 to 8 bpp blits
  266. if (arAlpha != ALPHA_INVALID) {
  267. return E_UNEXPECTED; // !!!! need better error codes
  268. }
  269. // normalize orientation of source and destination rectangles, and
  270. // compute sizes and relative orientations of source and destination rects
  271. if ((iNumSrcCols = BLITLIB_RECTWIDTH(prcSrc)) < 0) {
  272. iNumSrcCols = -iNumSrcCols;
  273. FlipRectHorizontal(prcSrc);
  274. FlipRectHorizontal(prcDst);
  275. }
  276. if ((iNumSrcRows = BLITLIB_RECTHEIGHT(prcSrc)) < 0) {
  277. iNumSrcRows = -iNumSrcRows;
  278. FlipRectVertical(prcSrc);
  279. FlipRectVertical(prcDst);
  280. }
  281. if ((iNumDstCols = BLITLIB_RECTWIDTH(prcDst)) < 0) {
  282. prcDst->left--;
  283. prcDst->right--;
  284. iNumDstCols = -iNumDstCols;
  285. iHorizMirror = -1;
  286. }
  287. if ((iNumDstRows = BLITLIB_RECTHEIGHT(prcDst)) < 0) {
  288. prcDst->top--;
  289. prcDst->bottom--;
  290. iNumDstRows = -iNumDstRows;
  291. iVertMirror = -1;
  292. }
  293. // get background and foreground palette indices out of src bitmap's header
  294. // !!!! this is a total hack and must be fixed!
  295. bOffColorIndex = BlitLib_PalIndexFromRGB(
  296. *((COLORREF*)(pDibInfoSrc->bmiColors)),
  297. (COLORREF*) pDibInfoDst->bmiColors,256);
  298. bOnColorIndex = BlitLib_PalIndexFromRGB(
  299. *((COLORREF*) (pDibInfoSrc->bmiColors) + 1),
  300. (COLORREF*) pDibInfoDst->bmiColors,256);
  301. // compute pointers to the starting rows in the src and dst bitmaps
  302. // taking care to invert y values, since DIBs are upside-down
  303. pbSrcScanLine = (BYTE*) pDibBitsSrc + prcSrc->top * (iBytesPerSrcScanLine
  304. = DibWidthBytes(pDibInfoSrc)) + (prcSrc->left / 8);
  305. iSrcBitOffset = prcSrc->left % 8;
  306. pbDstScanLine = (BYTE*) pDibBitsDst + prcDst->top * (iDstScanLength =
  307. DibWidthBytes(pDibInfoDst)) + prcDst->left;
  308. // check to see if we need to worry about transparency
  309. if (crTransparent == CLR_INVALID) {
  310. // check if we can do a straight copy from src row to dst row
  311. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  312. // check what ROP we'll be performing
  313. if (dwRop == SRCCOPY) {
  314. // check if we can do a straight copy vertically,
  315. // or if we have to stretch, shrink, or mirror
  316. if ((iNumSrcRows == iNumDstRows) && (iVertMirror == 1)) {
  317. Blt01to08_NoTrans_Hcopy_SRCCOPY_Vcopy(pbSrcScanLine,iSrcBitOffset,iBytesPerSrcScanLine,
  318. pbDstScanLine,iDstScanLength,
  319. iNumDstCols,iNumDstRows,
  320. bOffColorIndex,bOnColorIndex);
  321. } else {
  322. Blt01to08_NoTrans_Hcopy_SRCCOPY_NoVcopy(pbSrcScanLine,iSrcBitOffset,iBytesPerSrcScanLine,
  323. iNumSrcRows,pbDstScanLine,
  324. iDstScanLength * iVertMirror,
  325. iNumDstCols,iNumDstRows,
  326. bOffColorIndex,bOnColorIndex);
  327. }
  328. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  329. } else {
  330. // check what ROP we'll be performing
  331. if (dwRop == SRCCOPY) {
  332. Blt01to08_NoTrans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcBitOffset,iBytesPerSrcScanLine,
  333. iNumSrcCols,iNumSrcRows,
  334. pbDstScanLine,iDstScanLength * iVertMirror,
  335. iNumDstCols,iNumDstRows,iHorizMirror,
  336. bOffColorIndex,bOnColorIndex);
  337. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  338. }
  339. } else {
  340. BYTE bTransparentIndex = (BYTE)crTransparent;
  341. // check if we can do a straight copy from src row to dst row
  342. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  343. // check what ROP we'll be performing
  344. if (dwRop == SRCCOPY) {
  345. Blt01to08_Trans_Hcopy_SRCCOPY(pbSrcScanLine,iSrcBitOffset,iBytesPerSrcScanLine,
  346. iNumSrcRows,pbDstScanLine,
  347. iDstScanLength * iVertMirror,
  348. iNumDstCols,iNumDstRows,
  349. bTransparentIndex,
  350. bOffColorIndex,bOnColorIndex);
  351. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  352. } else {
  353. // check what ROP we'll be performing
  354. if (dwRop == SRCCOPY) {
  355. Blt01to08_Trans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcBitOffset,iBytesPerSrcScanLine,
  356. iNumSrcCols,iNumSrcRows,
  357. pbDstScanLine,iDstScanLength * iVertMirror,
  358. iNumDstCols,iNumDstRows,iHorizMirror,
  359. bTransparentIndex,
  360. bOffColorIndex,bOnColorIndex);
  361. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  362. }
  363. }
  364. return sc;
  365. }
  366. ///////////////////////////////////////////////////////////////////////
  367. //
  368. // Private BlitLib_BitBlt01to24 -
  369. // BitBlit from source bitmap to destination bitmap
  370. // with optional transparency and/or alpha blending using the
  371. // specified raster operation.
  372. //
  373. // Parameters:
  374. // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB
  375. // pDibBitsDst Pointer to the bits for the Destination DIB
  376. // prcDst Pointer to the Destination rectangle
  377. // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB
  378. // pDibBitsSrc Pointer to the bits for the Source DIB
  379. // prcSrc Pointer to the Source rectangle
  380. // crTransparent Tranparent color value
  381. // arAlpha Per-surface Alpha value
  382. // dwRop Raster Operation for the blit
  383. //
  384. // Return Value:
  385. // NO_ERROR or E_* value as specified in the .H file.
  386. //
  387. // Status: Incomplete
  388. //
  389. ///////////////////////////////////////////////////////////////////////
  390. SCODE BlitLib_BitBlt01to24(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst,
  391. PRECT prcDst, PDIBINFO pDibInfoSrc, PDIBBITS pDibBitsSrc,
  392. PRECT prcSrc, COLORREF crTransparent, ALPHAREF arAlpha, DWORD dwRop)
  393. {
  394. SCODE sc = NOERROR;
  395. int iNumSrcRows,
  396. iNumSrcCols,
  397. iBytesPerSrcScanLine,
  398. iSrcBitOffset,
  399. iNumDstRows,
  400. iNumDstCols,
  401. iDstScanLength,
  402. iHorizMirror = 1,
  403. iVertMirror = 1;
  404. BYTE *pbSrcScanLine;
  405. DWORD *pdDstScanLine;
  406. COLORREF crOnColor,
  407. crOffColor;
  408. // normalize orientation of source and destination rectangles, and
  409. // compute sizes and relative orientations of source and destination rects
  410. if ((iNumSrcCols = BLITLIB_RECTWIDTH(prcSrc)) < 0) {
  411. iNumSrcCols = -iNumSrcCols;
  412. FlipRectHorizontal(prcSrc);
  413. FlipRectHorizontal(prcDst);
  414. }
  415. if ((iNumSrcRows = BLITLIB_RECTHEIGHT(prcSrc)) < 0) {
  416. iNumSrcRows = -iNumSrcRows;
  417. FlipRectVertical(prcSrc);
  418. FlipRectVertical(prcDst);
  419. }
  420. if ((iNumDstCols = BLITLIB_RECTWIDTH(prcDst)) < 0) {
  421. prcDst->left--;
  422. prcDst->right--;
  423. iNumDstCols = -iNumDstCols;
  424. iHorizMirror = -1;
  425. }
  426. if ((iNumDstRows = BLITLIB_RECTHEIGHT(prcDst)) < 0) {
  427. prcDst->top--;
  428. prcDst->bottom--;
  429. iNumDstRows = -iNumDstRows;
  430. iVertMirror = -1;
  431. }
  432. // get background and foreground colors out of src bitmap's header
  433. crOffColor = *((COLORREF*) &(pDibInfoSrc->bmiColors[0]));
  434. crOnColor = *((COLORREF*) &(pDibInfoSrc->bmiColors[1]));
  435. // compute pointers to the starting rows in the src and dst bitmaps
  436. // taking care to invert y values, since DIBs are upside-down
  437. pbSrcScanLine = (BYTE*) pDibBitsSrc + prcSrc->top * (iBytesPerSrcScanLine
  438. = DibWidthBytes(pDibInfoSrc)) + (prcSrc->left / 8);
  439. iSrcBitOffset = prcSrc->left % 8;
  440. pdDstScanLine = (DWORD*) pDibBitsDst + prcDst->top * (iDstScanLength =
  441. DibWidthBytes(pDibInfoDst) / 4) + prcDst->left;
  442. // check if we're doing blending
  443. if (arAlpha == ALPHA_INVALID) {
  444. // check to see if we need to worry about transparency
  445. if (crTransparent == CLR_INVALID) {
  446. // check if we can do a straight copy from src row to dst row
  447. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  448. // check what ROP we'll be performing
  449. if (dwRop == SRCCOPY) {
  450. // check if we can do a straight copy vertically,
  451. // or if we have to stretch, shrink, or mirror
  452. if ((iNumSrcRows == iNumDstRows) && (iVertMirror == 1)) {
  453. Blt01to24_NoBlend_NoTrans_Hcopy_SRCCOPY_Vcopy(pbSrcScanLine,iSrcBitOffset,iBytesPerSrcScanLine,
  454. pdDstScanLine,iDstScanLength,
  455. iNumDstCols,iNumDstRows,
  456. crOffColor,crOnColor);
  457. } else {
  458. Blt01to24_NoBlend_NoTrans_Hcopy_SRCCOPY_NoVcopy(pbSrcScanLine,iSrcBitOffset,iBytesPerSrcScanLine,
  459. iNumSrcRows,pdDstScanLine,
  460. iDstScanLength * iVertMirror,
  461. iNumDstCols,iNumDstRows,
  462. crOffColor,crOnColor);
  463. }
  464. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  465. } else {
  466. // check what ROP we'll be performing
  467. if (dwRop == SRCCOPY) {
  468. Blt01to24_NoBlend_NoTrans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcBitOffset,iBytesPerSrcScanLine,
  469. iNumSrcCols,iNumSrcRows,
  470. pdDstScanLine,iDstScanLength * iVertMirror,
  471. iNumDstCols,iNumDstRows,iHorizMirror,
  472. crOffColor,crOnColor);
  473. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  474. }
  475. } else {
  476. BYTE bTransparentIndex = (BYTE)crTransparent;
  477. // check if we can do a straight copy from src row to dst row
  478. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  479. // check what ROP we'll be performing
  480. if (dwRop == SRCCOPY) {
  481. Blt01to24_NoBlend_Trans_Hcopy_SRCCOPY(pbSrcScanLine,iSrcBitOffset,iBytesPerSrcScanLine,
  482. iNumSrcRows,pdDstScanLine,
  483. iDstScanLength * iVertMirror,
  484. iNumDstCols,iNumDstRows,
  485. bTransparentIndex,
  486. crOffColor,crOnColor);
  487. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  488. } else {
  489. // check what ROP we'll be performing
  490. if (dwRop == SRCCOPY) {
  491. Blt01to24_NoBlend_Trans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcBitOffset,iBytesPerSrcScanLine,
  492. iNumSrcCols,iNumSrcRows,
  493. pdDstScanLine,iDstScanLength * iVertMirror,
  494. iNumDstCols,iNumDstRows,iHorizMirror,
  495. bTransparentIndex,
  496. crOffColor,crOnColor);
  497. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  498. }
  499. }
  500. } else { // doing alpha blending
  501. // if alpha value is zero, we do no work since the source bitmap
  502. // contributes nothing to the destination bitmap
  503. if (!(arAlpha & ALPHA_MASK)) {
  504. return sc;
  505. }
  506. // check to see if we need to worry about transparency
  507. if (crTransparent == CLR_INVALID) {
  508. // check if we can do a straight copy from src row to dst row
  509. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  510. // check what ROP we'll be performing
  511. if (dwRop == SRCCOPY) {
  512. Blt01to24_Blend_NoTrans_Hcopy_SRCCOPY(pbSrcScanLine,iSrcBitOffset,iBytesPerSrcScanLine,
  513. iNumSrcRows,pdDstScanLine,
  514. iDstScanLength * iVertMirror,
  515. iNumDstCols,iNumDstRows,
  516. arAlpha,crOffColor,crOnColor);
  517. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  518. } else {
  519. // check what ROP we'll be performing
  520. if (dwRop == SRCCOPY) {
  521. Blt01to24_Blend_NoTrans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcBitOffset,iBytesPerSrcScanLine,
  522. iNumSrcCols,iNumSrcRows,
  523. pdDstScanLine,iDstScanLength * iVertMirror,
  524. iNumDstCols,iNumDstRows,iHorizMirror,
  525. arAlpha,crOffColor,crOnColor);
  526. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  527. }
  528. } else {
  529. BYTE bTransparentIndex = (BYTE)crTransparent;
  530. // check if we can do a straight copy from src row to dst row
  531. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  532. // check what ROP we'll be performing
  533. if (dwRop == SRCCOPY) {
  534. Blt01to24_Blend_Trans_Hcopy_SRCCOPY(pbSrcScanLine,iSrcBitOffset,iBytesPerSrcScanLine,
  535. iNumSrcRows,pdDstScanLine,
  536. iDstScanLength * iVertMirror,
  537. iNumDstCols,iNumDstRows,
  538. bTransparentIndex,
  539. arAlpha,crOffColor,crOnColor);
  540. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  541. } else {
  542. // check what ROP we'll be performing
  543. if (dwRop == SRCCOPY) {
  544. Blt01to24_Blend_Trans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcBitOffset,iBytesPerSrcScanLine,
  545. iNumSrcCols,iNumSrcRows,
  546. pdDstScanLine,iDstScanLength * iVertMirror,
  547. iNumDstCols,iNumDstRows,iHorizMirror,
  548. bTransparentIndex,
  549. arAlpha,crOffColor,crOnColor);
  550. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  551. }
  552. }
  553. }
  554. return sc;
  555. }
  556. ///////////////////////////////////////////////////////////////////////
  557. //
  558. // Private BlitLib_BitBlt08to01 -
  559. // BitBlit from source bitmap to destination bitmap
  560. // with optional transparency and/or alpha blending using the
  561. // specified raster operation.
  562. //
  563. // Parameters:
  564. // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB
  565. // pDibBitsDst Pointer to the bits for the Destination DIB
  566. // prcDst Pointer to the Destination rectangle
  567. // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB
  568. // pDibBitsSrc Pointer to the bits for the Source DIB
  569. // prcSrc Pointer to the Source rectangle
  570. // crTransparent Tranparent color value
  571. // arAlpha Per-surface Alpha value
  572. // dwRop Raster Operation for the blit
  573. //
  574. // Return Value:
  575. // NO_ERROR or E_* value as specified in the .H file.
  576. //
  577. // Status: Incomplete
  578. //
  579. ///////////////////////////////////////////////////////////////////////
  580. SCODE BlitLib_BitBlt08to01(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst,
  581. PRECT prcDst, PDIBINFO pDibInfoSrc, PDIBBITS pDibBitsSrc,
  582. PRECT prcSrc, COLORREF crTransparent, ALPHAREF arAlpha, DWORD dwRop)
  583. {
  584. SCODE sc = NOERROR;
  585. int iNumSrcRows,
  586. iNumSrcCols,
  587. iSrcScanLength,
  588. iNumDstRows,
  589. iNumDstCols,
  590. iBytesPerDstScanLine,
  591. iHorizMirror = 1,
  592. iVertMirror = 1,
  593. iDstBitOffset;
  594. BYTE *pbSrcScanLine,
  595. *pbDstScanLine,
  596. bFillVal;
  597. // alpha blending not currently supported in the 8 to 1 bpp blits
  598. if (arAlpha != ALPHA_INVALID) {
  599. return E_UNEXPECTED; // !!!! need better error codes
  600. }
  601. // the only ROPs supported are BLACKNESS and WHITENESS
  602. if (dwRop == BLACKNESS) {
  603. bFillVal = 0;
  604. } else if (dwRop == WHITENESS) {
  605. bFillVal = 0xFF;
  606. } else {
  607. return E_UNEXPECTED; // !!!! need better error codes
  608. }
  609. // normalize orientation of source and destination rectangles, and
  610. // compute sizes and relative orientations of source and destination rects
  611. if ((iNumSrcCols = BLITLIB_RECTWIDTH(prcSrc)) < 0) {
  612. iNumSrcCols = -iNumSrcCols;
  613. FlipRectHorizontal(prcSrc);
  614. FlipRectHorizontal(prcDst);
  615. }
  616. if ((iNumSrcRows = BLITLIB_RECTHEIGHT(prcSrc)) < 0) {
  617. iNumSrcRows = -iNumSrcRows;
  618. FlipRectVertical(prcSrc);
  619. FlipRectVertical(prcDst);
  620. }
  621. if ((iNumDstCols = BLITLIB_RECTWIDTH(prcDst)) < 0) {
  622. prcDst->left--;
  623. prcDst->right--;
  624. iNumDstCols = -iNumDstCols;
  625. iHorizMirror = -1;
  626. }
  627. if ((iNumDstRows = BLITLIB_RECTHEIGHT(prcDst)) < 0) {
  628. prcDst->top--;
  629. prcDst->bottom--;
  630. iNumDstRows = -iNumDstRows;
  631. iVertMirror = -1;
  632. }
  633. // compute pointers to the starting rows in the src and dst bitmaps
  634. // taking care to invert y values, since DIBs are upside-down
  635. pbSrcScanLine = (BYTE*) pDibBitsSrc + prcSrc->top * (iSrcScanLength =
  636. DibWidthBytes(pDibInfoSrc)) + prcSrc->left;
  637. pbDstScanLine = (BYTE*) pDibBitsDst + prcDst->top * (iBytesPerDstScanLine
  638. = DibWidthBytes(pDibInfoDst)) + (prcDst->left / 8);
  639. iDstBitOffset = prcDst->left % 8;
  640. // check to see if we need to worry about transparency
  641. if (crTransparent == CLR_INVALID) {
  642. // no transparency plus a constant ROP equals a rectangle fill!
  643. // first we have to normalize destination rectangle orientation -
  644. // FillRect01() expects it
  645. if (BLITLIB_RECTWIDTH(prcDst) < 0) {
  646. prcDst->left++;
  647. prcDst->right++;
  648. FlipRectHorizontal(prcDst);
  649. }
  650. if (BLITLIB_RECTHEIGHT(prcDst) < 0) {
  651. prcDst->top--;
  652. prcDst->bottom--;
  653. FlipRectVertical(prcDst);
  654. }
  655. sc |= BlitLib_FillRect01(pDibInfoDst,pDibBitsDst,prcDst->left,prcDst->top,
  656. iNumDstCols,iNumDstRows,bFillVal);
  657. } else {
  658. BYTE bTransparentIndex = (BYTE)crTransparent;
  659. // check if we can do a straight copy from src row to dst row
  660. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  661. Blt08to01_Trans_Hcopy_ConstRop(pbSrcScanLine,iSrcScanLength,iNumSrcRows,
  662. pbDstScanLine,iDstBitOffset,
  663. iBytesPerDstScanLine * iVertMirror,
  664. iNumDstCols,iNumDstRows,bTransparentIndex,
  665. bFillVal);
  666. } else {
  667. Blt08to01_Trans_NoHcopy_ConstRop(pbSrcScanLine,iSrcScanLength,iNumSrcCols,
  668. iNumSrcRows,pbDstScanLine,iDstBitOffset,
  669. iBytesPerDstScanLine * iVertMirror,
  670. iNumDstCols,iNumDstRows,iHorizMirror,
  671. bTransparentIndex,bFillVal);
  672. }
  673. }
  674. return sc;
  675. }
  676. #endif // DDRAW
  677. ///////////////////////////////////////////////////////////////////////
  678. //
  679. // Private BlitLib_BitBlt08to08 -
  680. // BitBlit from source bitmap to destination bitmap
  681. // with optional transparency and/or alpha blending using the
  682. // specified raster operation.
  683. //
  684. // Parameters:
  685. // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB
  686. // pDibBitsDst Pointer to the bits for the Destination DIB
  687. // prcDst Pointer to the Destination rectangle
  688. // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB
  689. // pDibBitsSrc Pointer to the bits for the Source DIB
  690. // prcSrc Pointer to the Source rectangle
  691. // crTransparent Tranparent color value
  692. // arAlpha Per-surface Alpha value
  693. // dwRop Raster Operation for the blit
  694. //
  695. // Return Value:
  696. // NO_ERROR or E_* value as specified in the .H file.
  697. //
  698. // Status: Incomplete
  699. //
  700. ///////////////////////////////////////////////////////////////////////
  701. SCODE BlitLib_BitBlt08to08(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst,
  702. PRECT prcDst, PDIBINFO pDibInfoSrc, PDIBBITS pDibBitsSrc,
  703. PRECT prcSrc, COLORREF crTransparent, ALPHAREF arAlpha, DWORD dwRop)
  704. {
  705. SCODE sc = NOERROR;
  706. int iNumSrcRows,
  707. iNumSrcCols,
  708. iSrcScanLength,
  709. iNumDstRows,
  710. iNumDstCols,
  711. iDstScanLength,
  712. iHorizMirror = 1,
  713. iVertMirror = 1;
  714. BYTE *pbSrcScanLine,
  715. *pbDstScanLine;
  716. // alpha blending not currently supported in the 8 to 8 bpp blits
  717. if (arAlpha != ALPHA_INVALID) {
  718. return E_UNEXPECTED; // !!!! need better error codes
  719. }
  720. // If the bitmaps overlap, we need to use overlapping code
  721. if(BlitLib_Detect_Intersection(pDibBitsDst, prcDst, pDibBitsSrc, prcSrc))
  722. return BlitLib_BitBlt08to08_Intersect(pDibInfoDst, pDibBitsDst, prcDst,
  723. pDibInfoSrc, pDibBitsSrc, prcSrc, crTransparent, dwRop);
  724. // normalize orientation of source and destination rectangles, and
  725. // compute sizes and relative orientations of source and destination rects
  726. if ((iNumSrcCols = BLITLIB_RECTWIDTH(prcSrc)) < 0) {
  727. iNumSrcCols = -iNumSrcCols;
  728. FlipRectHorizontal(prcSrc);
  729. FlipRectHorizontal(prcDst);
  730. }
  731. if ((iNumSrcRows = BLITLIB_RECTHEIGHT(prcSrc)) < 0) {
  732. iNumSrcRows = -iNumSrcRows;
  733. FlipRectVertical(prcSrc);
  734. FlipRectVertical(prcDst);
  735. }
  736. if ((iNumDstCols = BLITLIB_RECTWIDTH(prcDst)) < 0) {
  737. prcDst->left--;
  738. prcDst->right--;
  739. iNumDstCols = -iNumDstCols;
  740. iHorizMirror = -1;
  741. }
  742. if ((iNumDstRows = BLITLIB_RECTHEIGHT(prcDst)) < 0) {
  743. prcDst->top--;
  744. prcDst->bottom--;
  745. iNumDstRows = -iNumDstRows;
  746. iVertMirror = -1;
  747. }
  748. // compute pointers to the starting rows in the src and dst bitmaps
  749. // taking care to invert y values, since DIBs are upside-down
  750. pbSrcScanLine = (BYTE*) pDibBitsSrc + (prcSrc->top) * (iSrcScanLength
  751. = DibWidthBytes(pDibInfoSrc)) + prcSrc->left;
  752. pbDstScanLine = (BYTE*) pDibBitsDst + (prcDst->top) * (iDstScanLength
  753. = DibWidthBytes(pDibInfoDst)) + prcDst->left;
  754. // check to see if we need to worry about transparency
  755. if (crTransparent == CLR_INVALID) {
  756. // check if we can do a straight copy from src row to dst row
  757. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  758. // check what ROP we'll be performing
  759. if (dwRop == SRCCOPY) {
  760. // check if we can do a straight copy vertically,
  761. // or if we have to stretch, shrink, or mirror
  762. if ((iNumSrcRows == iNumDstRows) && (iVertMirror == 1)) {
  763. Blt08to08_NoTrans_Hcopy_SRCCOPY_Vcopy(pbSrcScanLine,iSrcScanLength,
  764. pbDstScanLine,iDstScanLength,
  765. iNumDstCols,iNumDstRows);
  766. } else {
  767. Blt08to08_NoTrans_Hcopy_SRCCOPY_NoVcopy(pbSrcScanLine,iSrcScanLength,
  768. iNumSrcRows,pbDstScanLine,
  769. iDstScanLength * iVertMirror,
  770. iNumDstCols,iNumDstRows);
  771. }
  772. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  773. } else {
  774. // check what ROP we'll be performing
  775. if (dwRop == SRCCOPY) {
  776. Blt08to08_NoTrans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength,
  777. iNumSrcCols,iNumSrcRows,
  778. pbDstScanLine,iDstScanLength * iVertMirror,
  779. iNumDstCols,iNumDstRows,iHorizMirror);
  780. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  781. }
  782. } else {
  783. // myronth -- changed for DDraw Transparent colors (always a palette index)
  784. BYTE bTransparentIndex = (BYTE)crTransparent;
  785. // check if we can do a straight copy from src row to dst row
  786. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  787. // check what ROP we'll be performing
  788. if (dwRop == SRCCOPY) {
  789. Blt08to08_Trans_Hcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength,
  790. iNumSrcRows,pbDstScanLine,
  791. iDstScanLength * iVertMirror,
  792. iNumDstCols,iNumDstRows,
  793. bTransparentIndex);
  794. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  795. } else {
  796. // check what ROP we'll be performing
  797. if (dwRop == SRCCOPY) {
  798. Blt08to08_Trans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength,
  799. iNumSrcCols,iNumSrcRows,
  800. pbDstScanLine,iDstScanLength * iVertMirror,
  801. iNumDstCols,iNumDstRows,iHorizMirror,
  802. bTransparentIndex);
  803. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  804. }
  805. }
  806. return sc;
  807. }
  808. ///////////////////////////////////////////////////////////////////////
  809. //
  810. // Private BlitLib_BitBlt08to08_Intersect -
  811. // BitBlit from source bitmap to destination bitmap (and these
  812. // bitmaps overlap each other) with optional transparency and/or
  813. // alpha blending using the specified raster operation.
  814. //
  815. // Parameters:
  816. // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB
  817. // pDibBitsDst Pointer to the bits for the Destination DIB
  818. // prcDst Pointer to the Destination rectangle
  819. // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB
  820. // pDibBitsSrc Pointer to the bits for the Source DIB
  821. // prcSrc Pointer to the Source rectangle
  822. // crTransparent Tranparent color value
  823. // arAlpha Per-surface Alpha value
  824. // dwRop Raster Operation for the blit
  825. //
  826. // Return Value:
  827. // NO_ERROR or E_* value as specified in the .H file.
  828. //
  829. // Status: Incomplete
  830. //
  831. ///////////////////////////////////////////////////////////////////////
  832. SCODE BlitLib_BitBlt08to08_Intersect(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst,
  833. PRECT prcDst, PDIBINFO pDibInfoSrc, PDIBBITS pDibBitsSrc, PRECT prcSrc,
  834. COLORREF crTransparent, DWORD dwRop)
  835. {
  836. SCODE sc = NOERROR;
  837. int iNumSrcRows,
  838. iNumSrcCols,
  839. iSrcScanLength,
  840. iNumDstRows,
  841. iNumDstCols,
  842. iDstScanLength,
  843. iHorizMirror = 1,
  844. iVertMirror = 1;
  845. BYTE *pbSrcScanLine,
  846. *pbDstScanLine,
  847. *pbTempScanLine,
  848. bTransparentIndex;
  849. PDIBBITS pDibBitsTemp;
  850. // normalize orientation of source and destination rectangles, and
  851. // compute sizes and relative orientations of source and destination rects
  852. if ((iNumSrcCols = BLITLIB_RECTWIDTH(prcSrc)) < 0) {
  853. iNumSrcCols = -iNumSrcCols;
  854. FlipRectHorizontal(prcSrc);
  855. FlipRectHorizontal(prcDst);
  856. }
  857. if ((iNumSrcRows = BLITLIB_RECTHEIGHT(prcSrc)) < 0) {
  858. iNumSrcRows = -iNumSrcRows;
  859. FlipRectVertical(prcSrc);
  860. FlipRectVertical(prcDst);
  861. }
  862. if ((iNumDstCols = BLITLIB_RECTWIDTH(prcDst)) < 0) {
  863. prcDst->left--;
  864. prcDst->right--;
  865. iNumDstCols = -iNumDstCols;
  866. iHorizMirror = -1;
  867. }
  868. if ((iNumDstRows = BLITLIB_RECTHEIGHT(prcDst)) < 0) {
  869. prcDst->top--;
  870. prcDst->bottom--;
  871. iNumDstRows = -iNumDstRows;
  872. iVertMirror = -1;
  873. }
  874. // We aren't currently support any ROP's besides SRCCOPY
  875. if(dwRop != SRCCOPY)
  876. return E_UNEXPECTED;
  877. //
  878. // Here are all the stretching and mirroring blits for overlapping rects
  879. //
  880. // REVIEW!!! -- The following code could be optimized for the caching
  881. // cases. Currently, it allocates a second bitmap that is the same
  882. // size as the original destination, and then uses the original blit
  883. // rectangle to do the caching. To save space, this blit should
  884. // eventually be changed to only allocate the size of the overlapped
  885. // rectangle, and the blit rects should be adjusted accordingly.
  886. // Check if we are stretching (horiz or vert), or if we are mirroring --
  887. // In all of these cases, we must create a cache bitmap and double blit
  888. if((iNumDstCols != iNumSrcCols) || (iNumDstRows != iNumSrcRows) ||
  889. (iHorizMirror != 1) || (iVertMirror != 1))
  890. {
  891. // Allocate memory for the cache bitmap -- We will blit into this
  892. // temporary bitmap and then re-blit back to the original source
  893. pDibBitsTemp = (PDIBBITS)osMemAlloc(DibSizeImage((LPBITMAPINFOHEADER)pDibInfoDst));
  894. if (pDibBitsTemp == NULL)
  895. return E_UNEXPECTED;
  896. // compute pointers to the starting rows in the src and temp bitmaps
  897. pbSrcScanLine = (BYTE*) pDibBitsSrc + (prcSrc->top) * (iSrcScanLength
  898. = DibWidthBytes(pDibInfoSrc)) + prcSrc->left;
  899. pbTempScanLine = (BYTE*) pDibBitsTemp + (prcDst->top) * (iDstScanLength
  900. = DibWidthBytes(pDibInfoDst)) + prcDst->left;
  901. // check if we can do a straight copy from src row to dst row
  902. if((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)){
  903. // check if we can do a straight copy vertically,
  904. // or if we have to stretch, shrink, or mirror
  905. if ((iNumSrcRows == iNumDstRows) && (iVertMirror == 1)) {
  906. Blt08to08_NoTrans_Hcopy_SRCCOPY_Vcopy(pbSrcScanLine,iSrcScanLength,
  907. pbTempScanLine,iDstScanLength,
  908. iNumDstCols,iNumDstRows);
  909. } else {
  910. Blt08to08_NoTrans_Hcopy_SRCCOPY_NoVcopy(pbSrcScanLine,iSrcScanLength,
  911. iNumSrcRows,pbTempScanLine,
  912. iDstScanLength * iVertMirror,
  913. iNumDstCols,iNumDstRows);
  914. }
  915. }
  916. else
  917. {
  918. Blt08to08_NoTrans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength,
  919. iNumSrcCols,iNumSrcRows,
  920. pbTempScanLine,iDstScanLength * iVertMirror,
  921. iNumDstCols,iNumDstRows,iHorizMirror);
  922. }
  923. // Recalculate the scan line pointers for the second blit
  924. if(BLITLIB_RECTWIDTH(prcDst) < 0){
  925. prcDst->left++;
  926. prcDst->right++;
  927. FlipRectHorizontal(prcDst);
  928. }
  929. if(BLITLIB_RECTHEIGHT(prcDst) < 0){
  930. prcDst->top++;
  931. prcDst->bottom++;
  932. FlipRectVertical(prcDst);
  933. }
  934. // compute pointers to the starting rows in the temp and dest bitmaps
  935. pbTempScanLine = (BYTE*) pDibBitsTemp + (prcDst->top) * (iDstScanLength
  936. = DibWidthBytes(pDibInfoDst)) + prcDst->left;
  937. pbDstScanLine = (BYTE*) pDibBitsDst + (prcDst->top) * (iDstScanLength
  938. = DibWidthBytes(pDibInfoDst)) + prcDst->left;
  939. // Now blit from the temporary bitmap back to the original source,
  940. // checking for transparency if necessary
  941. if(crTransparent == CLR_INVALID){
  942. Blt08to08_NoTrans_Hcopy_SRCCOPY_Vcopy(pbTempScanLine,iDstScanLength,
  943. pbDstScanLine,iDstScanLength,
  944. iNumDstCols,iNumDstRows);
  945. }
  946. else{
  947. bTransparentIndex = (BYTE)crTransparent;
  948. Blt08to08_Trans_Hcopy_SRCCOPY(pbTempScanLine,iDstScanLength,
  949. iNumDstRows,pbDstScanLine,
  950. iDstScanLength, iNumDstCols,
  951. iNumDstRows, bTransparentIndex);
  952. }
  953. // Free the memory from the temporary bitmap
  954. if(pDibBitsTemp)
  955. osMemFree(pDibBitsTemp);
  956. return sc;
  957. }
  958. //
  959. // Here are all the non-stretching and non-mirroring blits for overlapping rects
  960. //
  961. // check to see if we need to worry about transparency
  962. if (crTransparent == CLR_INVALID) {
  963. // Simplest case, they are the same rectangles
  964. if((prcDst->left == prcSrc->left) && (prcDst->top == prcSrc->top) &&
  965. (prcDst->right == prcSrc->right) && (prcDst->bottom == prcSrc->bottom))
  966. return sc;
  967. // Next case, the destination rectangle is vertically greater in
  968. // magnitude than the source rectangle
  969. else if(prcDst->top > prcSrc->top){
  970. // compute pointers to the starting rows in the src and dst bitmaps
  971. // taking care to decrement the bottom rect edge since we are
  972. // going from bottom to top
  973. pbSrcScanLine = (BYTE*) pDibBitsSrc + (prcSrc->bottom - 1) * (iSrcScanLength
  974. = DibWidthBytes(pDibInfoSrc)) + prcSrc->left;
  975. pbDstScanLine = (BYTE*) pDibBitsDst + (prcDst->bottom - 1) * (iDstScanLength
  976. = DibWidthBytes(pDibInfoDst)) + prcDst->left;
  977. // Call the appropriate blit
  978. Blt08to08_LeftToRight_BottomToTop_SRCCOPY(pbSrcScanLine,
  979. iSrcScanLength, pbDstScanLine, iDstScanLength, iNumDstCols,
  980. iNumDstRows);
  981. }
  982. // Next case, the destination rectangle is horizontally less than
  983. // or equal in magnitude to the source rectangle
  984. else if(prcDst->left <= prcSrc->left){
  985. // compute pointers to the starting rows in the src and dst bitmaps
  986. pbSrcScanLine = (BYTE*) pDibBitsSrc + (prcSrc->top) * (iSrcScanLength
  987. = DibWidthBytes(pDibInfoSrc)) + prcSrc->left;
  988. pbDstScanLine = (BYTE*) pDibBitsDst + (prcDst->top) * (iDstScanLength
  989. = DibWidthBytes(pDibInfoDst)) + prcDst->left;
  990. // Call the appropriate blit
  991. Blt08to08_NoTrans_Hcopy_SRCCOPY_Vcopy(pbSrcScanLine,iSrcScanLength,
  992. pbDstScanLine,iDstScanLength,
  993. iNumDstCols,iNumDstRows);
  994. }
  995. // Last case, the destination rectangle is horizontally greater
  996. // in magnitude than the source rectangle
  997. else{
  998. // compute pointers to the starting rows in the src and dst bitmaps
  999. // taking care to decrement the right rect edge since we are
  1000. // going from right to left
  1001. pbSrcScanLine = (BYTE*) pDibBitsSrc + (prcSrc->top) * (iSrcScanLength
  1002. = DibWidthBytes(pDibInfoSrc)) + (prcSrc->right - 1);
  1003. pbDstScanLine = (BYTE*) pDibBitsDst + (prcDst->top) * (iDstScanLength
  1004. = DibWidthBytes(pDibInfoDst)) + (prcDst->right - 1);
  1005. // Call the appropriate blit
  1006. Blt08to08_RightToLeft_TopToBottom_SRCCOPY(pbSrcScanLine,
  1007. iSrcScanLength, pbDstScanLine, iDstScanLength, iNumDstCols,
  1008. iNumDstRows);
  1009. }
  1010. }
  1011. else{
  1012. bTransparentIndex = (BYTE)crTransparent;
  1013. // Simplest case, they are the same rectangles
  1014. if((prcDst->left == prcSrc->left) && (prcDst->top == prcSrc->top) &&
  1015. (prcDst->right == prcSrc->right) && (prcDst->bottom == prcSrc->bottom))
  1016. return sc;
  1017. // Next case, the destination rectangle is vertically greater in
  1018. // magnitude than the source rectangle
  1019. else if(prcDst->top > prcSrc->top){
  1020. // compute pointers to the starting rows in the src and dst bitmaps
  1021. // taking care to decrement the bottom rect edge since we are
  1022. // going from bottom to top
  1023. pbSrcScanLine = (BYTE*) pDibBitsSrc + (prcSrc->bottom - 1) * (iSrcScanLength
  1024. = DibWidthBytes(pDibInfoSrc)) + prcSrc->left;
  1025. pbDstScanLine = (BYTE*) pDibBitsDst + (prcDst->bottom - 1) * (iDstScanLength
  1026. = DibWidthBytes(pDibInfoDst)) + prcDst->left;
  1027. // Call the appropriate blit
  1028. Blt08to08_LeftToRight_BottomToTop_Trans_SRCCOPY(pbSrcScanLine,
  1029. iSrcScanLength, pbDstScanLine, iDstScanLength, iNumDstCols,
  1030. iNumDstRows, bTransparentIndex);
  1031. }
  1032. // Next case, the destination rectangle is horizontally less than
  1033. // or equal in magnitude to the source rectangle
  1034. else if(prcDst->left <= prcSrc->left){
  1035. // compute pointers to the starting rows in the src and dst bitmaps
  1036. pbSrcScanLine = (BYTE*) pDibBitsSrc + (prcSrc->top) * (iSrcScanLength
  1037. = DibWidthBytes(pDibInfoSrc)) + prcSrc->left;
  1038. pbDstScanLine = (BYTE*) pDibBitsDst + (prcDst->top) * (iDstScanLength
  1039. = DibWidthBytes(pDibInfoDst)) + prcDst->left;
  1040. // Call the appropriate blit
  1041. Blt08to08_Trans_Hcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength,
  1042. iNumSrcRows, pbDstScanLine,
  1043. iDstScanLength, iNumDstCols,
  1044. iNumDstRows, bTransparentIndex);
  1045. }
  1046. // Last case, the destination rectangle is horizontally greater
  1047. // in magnitude than the source rectangle
  1048. else{
  1049. // compute pointers to the starting rows in the src and dst bitmaps
  1050. // taking care to decrement the right rect edge since we are
  1051. // going from right to left
  1052. pbSrcScanLine = (BYTE*) pDibBitsSrc + (prcSrc->top) * (iSrcScanLength
  1053. = DibWidthBytes(pDibInfoSrc)) + (prcSrc->right - 1);
  1054. pbDstScanLine = (BYTE*) pDibBitsDst + (prcDst->top) * (iDstScanLength
  1055. = DibWidthBytes(pDibInfoDst)) + (prcDst->right - 1);
  1056. // Call the appropriate blit
  1057. Blt08to08_RightToLeft_TopToBottom_Trans_SRCCOPY(pbSrcScanLine,
  1058. iSrcScanLength, pbDstScanLine, iDstScanLength, iNumDstCols,
  1059. iNumDstRows, bTransparentIndex);
  1060. }
  1061. }
  1062. return sc;
  1063. }
  1064. #ifndef DDRAW
  1065. ///////////////////////////////////////////////////////////////////////
  1066. //
  1067. // Private BlitLib_BitBlt08to24 -
  1068. // BitBlit from source bitmap to Dstination bitmap
  1069. // with optional transparency and/or alpha blending using the
  1070. // specified raster operation.
  1071. //
  1072. // Parameters:
  1073. // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB
  1074. // pDibBitsDst Pointer to the bits for the Destination DIB
  1075. // prcDst Pointer to the Destination rectangle
  1076. // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB
  1077. // pDibBitsSrc Pointer to the bits for the Source DIB
  1078. // prcSrc Pointer to the Source rectangle
  1079. // crTransparent Tranparent color value
  1080. // arAlpha Per-surface Alpha value
  1081. // dwRop Raster Operation for the blit
  1082. //
  1083. // Return Value:
  1084. // NO_ERROR or E_* value as specified in the .H file.
  1085. //
  1086. // Status: Incomplete
  1087. //
  1088. ///////////////////////////////////////////////////////////////////////
  1089. SCODE BlitLib_BitBlt08to24(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst,
  1090. PRECT prcDst, PDIBINFO pDibInfoSrc, PDIBBITS pDibBitsSrc,
  1091. PRECT prcSrc, COLORREF crTransparent, ALPHAREF arAlpha, DWORD dwRop)
  1092. {
  1093. SCODE sc = NOERROR;
  1094. int iNumSrcRows,
  1095. iNumSrcCols,
  1096. iSrcScanLength,
  1097. iNumDstRows,
  1098. iNumDstCols,
  1099. iDstScanLength,
  1100. iHorizMirror = 1,
  1101. iVertMirror = 1;
  1102. BYTE *pbSrcScanLine;
  1103. DWORD *pdDstScanLine;
  1104. // normalize orientation of source and destination rectangles, and
  1105. // compute sizes and relative orientations of source and destination rects
  1106. if ((iNumSrcCols = BLITLIB_RECTWIDTH(prcSrc)) < 0) {
  1107. iNumSrcCols = -iNumSrcCols;
  1108. FlipRectHorizontal(prcSrc);
  1109. FlipRectHorizontal(prcDst);
  1110. }
  1111. if ((iNumSrcRows = BLITLIB_RECTHEIGHT(prcSrc)) < 0) {
  1112. iNumSrcRows = -iNumSrcRows;
  1113. FlipRectVertical(prcSrc);
  1114. FlipRectVertical(prcDst);
  1115. }
  1116. if ((iNumDstCols = BLITLIB_RECTWIDTH(prcDst)) < 0) {
  1117. prcDst->left--;
  1118. prcDst->right--;
  1119. iNumDstCols = -iNumDstCols;
  1120. iHorizMirror = -1;
  1121. }
  1122. if ((iNumDstRows = BLITLIB_RECTHEIGHT(prcDst)) < 0) {
  1123. prcDst->top--;
  1124. prcDst->bottom--;
  1125. iNumDstRows = -iNumDstRows;
  1126. iVertMirror = -1;
  1127. }
  1128. // compute pointers to the starting rows in the src and dst bitmaps
  1129. // taking care to invert y values, since DIBs are upside-down
  1130. pbSrcScanLine = (BYTE*) pDibBitsSrc + prcSrc->top * (iSrcScanLength =
  1131. DibWidthBytes(pDibInfoSrc)) + prcSrc->left;
  1132. pdDstScanLine = (DWORD*) pDibBitsDst + prcDst->top * (iDstScanLength =
  1133. DibWidthBytes(pDibInfoDst) / 4) + prcDst->left;
  1134. // check if we're doing blending
  1135. if (arAlpha == ALPHA_INVALID) { // no blending desired
  1136. // check to see if we need to worry about transparency
  1137. if (crTransparent == CLR_INVALID) {
  1138. // check if we can do a straight copy from src row to dst row
  1139. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  1140. // check what ROP we'll be performing
  1141. if (dwRop == SRCCOPY) {
  1142. // check if we can do a straight copy vertically,
  1143. // or if we have to stretch, shrink, or mirror
  1144. if ((iNumSrcRows == iNumDstRows) && (iVertMirror == 1)) {
  1145. Blt08to24_NoBlend_NoTrans_Hcopy_SRCCOPY_Vcopy(pbSrcScanLine,iSrcScanLength,
  1146. pdDstScanLine,iDstScanLength,
  1147. iNumDstCols,iNumDstRows,(COLORREF*) pDibInfoSrc->bmiColors);
  1148. } else {
  1149. Blt08to24_NoBlend_NoTrans_Hcopy_SRCCOPY_NoVcopy(pbSrcScanLine,iSrcScanLength,
  1150. iNumSrcRows,pdDstScanLine,
  1151. iDstScanLength * iVertMirror,
  1152. iNumDstCols,iNumDstRows,(COLORREF*) pDibInfoSrc->bmiColors);
  1153. }
  1154. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  1155. } else { // we have to stretch or shrink horizontally
  1156. // check what ROP we'll be performing
  1157. if (dwRop == SRCCOPY) {
  1158. Blt08to24_NoBlend_NoTrans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength,
  1159. iNumSrcCols,iNumSrcRows,
  1160. pdDstScanLine,iDstScanLength * iVertMirror,
  1161. iNumDstCols,iNumDstRows,iHorizMirror,(COLORREF*) pDibInfoSrc->bmiColors);
  1162. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  1163. }
  1164. } else {
  1165. BYTE bTransparentIndex = (BYTE)crTransparent;
  1166. // check if we can do a straight copy from src row to dst row
  1167. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  1168. // check what ROP we'll be performing
  1169. if (dwRop == SRCCOPY) {
  1170. Blt08to24_NoBlend_Trans_Hcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength,
  1171. iNumSrcRows,pdDstScanLine,
  1172. iDstScanLength * iVertMirror,
  1173. iNumDstCols,iNumDstRows,
  1174. bTransparentIndex,(COLORREF*) pDibInfoSrc->bmiColors);
  1175. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  1176. } else { // we have to shrink or stretch horizontally
  1177. // check what ROP we'll be performing
  1178. if (dwRop == SRCCOPY) {
  1179. Blt08to24_NoBlend_Trans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength,
  1180. iNumSrcCols,iNumSrcRows,
  1181. pdDstScanLine,iDstScanLength * iVertMirror,
  1182. iNumDstCols,iNumDstRows,iHorizMirror,
  1183. bTransparentIndex,(COLORREF*) pDibInfoSrc->bmiColors);
  1184. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  1185. }
  1186. }
  1187. } else { // blending desired
  1188. // if alpha value is zero, we do no work since the source bitmap
  1189. // contributes nothing to the destination bitmap
  1190. if (!(arAlpha & ALPHA_MASK)) {
  1191. return sc;
  1192. }
  1193. // check to see if we need to worry about transparency
  1194. if (crTransparent == CLR_INVALID) {
  1195. // check if we can do a straight copy from src row to dst row
  1196. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  1197. // check what ROP we'll be performing
  1198. if (dwRop == SRCCOPY) {
  1199. Blt08to24_Blend_NoTrans_Hcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength,
  1200. iNumSrcRows,pdDstScanLine,
  1201. iDstScanLength * iVertMirror,
  1202. iNumDstCols,iNumDstRows,
  1203. arAlpha,(COLORREF*) pDibInfoSrc->bmiColors);
  1204. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  1205. } else { // we need to shrink or stretch horizontally
  1206. // check what ROP we'll be performing
  1207. if (dwRop == SRCCOPY) {
  1208. Blt08to24_Blend_NoTrans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength,
  1209. iNumSrcCols,iNumSrcRows,
  1210. pdDstScanLine,iDstScanLength * iVertMirror,
  1211. iNumDstCols,iNumDstRows,iHorizMirror,
  1212. arAlpha,(COLORREF*) pDibInfoSrc->bmiColors);
  1213. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  1214. }
  1215. } else {
  1216. BYTE bTransparentIndex = (BYTE)crTransparent;
  1217. // check if we can do a straight copy from src row to dst row
  1218. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  1219. // check what ROP we'll be performing
  1220. if (dwRop == SRCCOPY) {
  1221. Blt08to24_Blend_Trans_Hcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength,
  1222. iNumSrcRows,pdDstScanLine,
  1223. iDstScanLength * iVertMirror,
  1224. iNumDstCols,iNumDstRows,
  1225. bTransparentIndex,arAlpha,(COLORREF*) pDibInfoSrc->bmiColors);
  1226. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  1227. } else { // we have to shrink or stretch horizontally
  1228. // check what ROP we'll be performing
  1229. if (dwRop == SRCCOPY) {
  1230. Blt08to24_Blend_Trans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength,
  1231. iNumSrcCols,iNumSrcRows,
  1232. pdDstScanLine,iDstScanLength * iVertMirror,
  1233. iNumDstCols,iNumDstRows,iHorizMirror,
  1234. bTransparentIndex,arAlpha,(COLORREF*) pDibInfoSrc->bmiColors);
  1235. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  1236. }
  1237. }
  1238. }
  1239. return sc;
  1240. }
  1241. ///////////////////////////////////////////////////////////////////////
  1242. //
  1243. // Private BlitLib_BitBlt08to24P -
  1244. // BitBlit from source bitmap to Dstination bitmap
  1245. // with optional transparency and/or alpha blending using the
  1246. // specified raster operation.
  1247. //
  1248. // Parameters:
  1249. // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB
  1250. // pDibBitsDst Pointer to the bits for the Destination DIB
  1251. // prcDst Pointer to the Destination rectangle
  1252. // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB
  1253. // pDibBitsSrc Pointer to the bits for the Source DIB
  1254. // prcSrc Pointer to the Source rectangle
  1255. // crTransparent Tranparent color value
  1256. // arAlpha Per-surface Alpha value
  1257. // dwRop Raster Operation for the blit
  1258. //
  1259. // Return Value:
  1260. // NO_ERROR or E_* value as specified in the .H file.
  1261. //
  1262. // Status: Incomplete
  1263. //
  1264. ///////////////////////////////////////////////////////////////////////
  1265. SCODE BlitLib_BitBlt08to24P(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst,
  1266. PRECT prcDst, PDIBINFO pDibInfoSrc, PDIBBITS pDibBitsSrc,
  1267. PRECT prcSrc, COLORREF crTransparent, ALPHAREF arAlpha, DWORD dwRop)
  1268. {
  1269. SCODE sc = NOERROR;
  1270. int iNumSrcRows,
  1271. iNumSrcCols,
  1272. iSrcScanLength,
  1273. iNumDstRows,
  1274. iNumDstCols,
  1275. iDstScanLength,
  1276. iHorizMirror = 1,
  1277. iVertMirror = 1;
  1278. BYTE *pbSrcScanLine,
  1279. *pdDstScanLine;
  1280. // normalize orientation of source and destination rectangles, and
  1281. // compute sizes and relative orientations of source and destination rects
  1282. if ((iNumSrcCols = BLITLIB_RECTWIDTH(prcSrc)) < 0) {
  1283. iNumSrcCols = -iNumSrcCols;
  1284. FlipRectHorizontal(prcSrc);
  1285. FlipRectHorizontal(prcDst);
  1286. }
  1287. if ((iNumSrcRows = BLITLIB_RECTHEIGHT(prcSrc)) < 0) {
  1288. iNumSrcRows = -iNumSrcRows;
  1289. FlipRectVertical(prcSrc);
  1290. FlipRectVertical(prcDst);
  1291. }
  1292. if ((iNumDstCols = BLITLIB_RECTWIDTH(prcDst)) < 0) {
  1293. prcDst->left--;
  1294. prcDst->right--;
  1295. iNumDstCols = -iNumDstCols;
  1296. iHorizMirror = -1;
  1297. }
  1298. if ((iNumDstRows = BLITLIB_RECTHEIGHT(prcDst)) < 0) {
  1299. prcDst->top--;
  1300. prcDst->bottom--;
  1301. iNumDstRows = -iNumDstRows;
  1302. iVertMirror = -1;
  1303. }
  1304. // compute pointers to the starting rows in the src and dst bitmaps
  1305. // taking care to invert y values, since DIBs are upside-down
  1306. pbSrcScanLine = (BYTE *) pDibBitsSrc + prcSrc->top * (iSrcScanLength =
  1307. DibWidthBytes(pDibInfoSrc)) + prcSrc->left;
  1308. pdDstScanLine = (BYTE *) pDibBitsDst + prcDst->top * (iDstScanLength =
  1309. DibWidthBytes(pDibInfoDst)) + (prcDst->left * 3);
  1310. // check if we're doing blending
  1311. if (arAlpha == ALPHA_INVALID) { // no blending desired
  1312. // check to see if we need to worry about transparency
  1313. if (crTransparent == CLR_INVALID) {
  1314. // check if we can do a straight copy from src row to dst row
  1315. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  1316. // check what ROP we'll be performing
  1317. if (dwRop == SRCCOPY) {
  1318. // check if we can do a straight copy vertically,
  1319. // or if we have to stretch, shrink, or mirror
  1320. if ((iNumSrcRows == iNumDstRows) && (iVertMirror == 1)) {
  1321. Blt08to24P_NoBlend_NoTrans_Hcopy_SRCCOPY_Vcopy(pbSrcScanLine,iSrcScanLength,
  1322. pdDstScanLine,iDstScanLength,
  1323. iNumDstCols,iNumDstRows,(COLORREF*) pDibInfoSrc->bmiColors);
  1324. } else {
  1325. Blt08to24P_NoBlend_NoTrans_Hcopy_SRCCOPY_NoVcopy(pbSrcScanLine,iSrcScanLength,
  1326. iNumSrcRows,pdDstScanLine,
  1327. iDstScanLength * iVertMirror,
  1328. iNumDstCols,iNumDstRows,(COLORREF*) pDibInfoSrc->bmiColors);
  1329. }
  1330. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  1331. } else { // we have to stretch or shrink horizontally
  1332. // check what ROP we'll be performing
  1333. if (dwRop == SRCCOPY) {
  1334. Blt08to24P_NoBlend_NoTrans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength,
  1335. iNumSrcCols,iNumSrcRows,
  1336. pdDstScanLine,iDstScanLength * iVertMirror,
  1337. iNumDstCols,iNumDstRows,iHorizMirror,(COLORREF*) pDibInfoSrc->bmiColors);
  1338. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  1339. }
  1340. } else {
  1341. BYTE bTransparentIndex = (BYTE)crTransparent;
  1342. // check if we can do a straight copy from src row to dst row
  1343. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  1344. // check what ROP we'll be performing
  1345. if (dwRop == SRCCOPY) {
  1346. Blt08to24P_NoBlend_Trans_Hcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength,
  1347. iNumSrcRows,pdDstScanLine,
  1348. iDstScanLength * iVertMirror,
  1349. iNumDstCols,iNumDstRows,
  1350. bTransparentIndex,(COLORREF*) pDibInfoSrc->bmiColors);
  1351. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  1352. } else { // we have to shrink or stretch horizontally
  1353. // check what ROP we'll be performing
  1354. if (dwRop == SRCCOPY) {
  1355. Blt08to24P_NoBlend_Trans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength,
  1356. iNumSrcCols,iNumSrcRows,
  1357. pdDstScanLine,iDstScanLength * iVertMirror,
  1358. iNumDstCols,iNumDstRows,iHorizMirror,
  1359. bTransparentIndex,(COLORREF*) pDibInfoSrc->bmiColors);
  1360. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  1361. }
  1362. }
  1363. } else { // blending desired
  1364. // if alpha value is zero, we do no work since the source bitmap
  1365. // contributes nothing to the destination bitmap
  1366. if (!(arAlpha & ALPHA_MASK)) {
  1367. return sc;
  1368. }
  1369. // check to see if we need to worry about transparency
  1370. if (crTransparent == CLR_INVALID) {
  1371. // check if we can do a straight copy from src row to dst row
  1372. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  1373. // check what ROP we'll be performing
  1374. if (dwRop == SRCCOPY) {
  1375. Blt08to24P_Blend_NoTrans_Hcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength,
  1376. iNumSrcRows,pdDstScanLine,
  1377. iDstScanLength * iVertMirror,
  1378. iNumDstCols,iNumDstRows,
  1379. arAlpha,(COLORREF*) pDibInfoSrc->bmiColors);
  1380. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  1381. } else { // we need to shrink or stretch horizontally
  1382. // check what ROP we'll be performing
  1383. if (dwRop == SRCCOPY) {
  1384. Blt08to24P_Blend_NoTrans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength,
  1385. iNumSrcCols,iNumSrcRows,
  1386. pdDstScanLine,iDstScanLength * iVertMirror,
  1387. iNumDstCols,iNumDstRows,iHorizMirror,
  1388. arAlpha,(COLORREF*) pDibInfoSrc->bmiColors);
  1389. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  1390. }
  1391. } else {
  1392. BYTE bTransparentIndex = (BYTE)crTransparent;
  1393. // check if we can do a straight copy from src row to dst row
  1394. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  1395. // check what ROP we'll be performing
  1396. if (dwRop == SRCCOPY) {
  1397. Blt08to24P_Blend_Trans_Hcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength,
  1398. iNumSrcRows,pdDstScanLine,
  1399. iDstScanLength * iVertMirror,
  1400. iNumDstCols,iNumDstRows,
  1401. bTransparentIndex,arAlpha,(COLORREF*) pDibInfoSrc->bmiColors);
  1402. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  1403. } else { // we have to shrink or stretch horizontally
  1404. // check what ROP we'll be performing
  1405. if (dwRop == SRCCOPY) {
  1406. Blt08to24P_Blend_Trans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength,
  1407. iNumSrcCols,iNumSrcRows,
  1408. pdDstScanLine,iDstScanLength * iVertMirror,
  1409. iNumDstCols,iNumDstRows,iHorizMirror,
  1410. bTransparentIndex,arAlpha,(COLORREF*) pDibInfoSrc->bmiColors);
  1411. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  1412. }
  1413. }
  1414. }
  1415. return sc;
  1416. }
  1417. ///////////////////////////////////////////////////////////////////////
  1418. //
  1419. // Private BlitLib_BitBlt08Ato24 -
  1420. // BitBlit from source bitmap to Dstination bitmap
  1421. // with optional transparency and/or alpha blending using the
  1422. // specified raster operation.
  1423. //
  1424. // Parameters:
  1425. // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB
  1426. // pDibBitsDst Pointer to the bits for the Destination DIB
  1427. // prcDst Pointer to the Destination rectangle
  1428. // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB
  1429. // pDibBitsSrc Pointer to the bits for the Source DIB
  1430. // prcSrc Pointer to the Source rectangle
  1431. // crTransparent Tranparent color value
  1432. // arAlpha Per-surface Alpha value
  1433. // dwRop Raster Operation for the blit
  1434. //
  1435. // Return Value:
  1436. // NO_ERROR or E_* value as specified in the .H file.
  1437. //
  1438. // Status: Incomplete
  1439. //
  1440. ///////////////////////////////////////////////////////////////////////
  1441. SCODE BlitLib_BitBlt08Ato24(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst,
  1442. PRECT prcDst, PDIBINFO pDibInfoSrc, PDIBBITS pDibBitsSrc,
  1443. PRECT prcSrc, COLORREF crTransparent, ALPHAREF arAlpha, DWORD dwRop)
  1444. {
  1445. SCODE sc = NOERROR;
  1446. int iNumSrcRows,
  1447. iNumSrcCols,
  1448. iSrcScanLength,
  1449. iNumDstRows,
  1450. iNumDstCols,
  1451. iDstScanLength,
  1452. iHorizMirror = 1,
  1453. iVertMirror = 1;
  1454. BYTE *pbSrcScanLine;
  1455. DWORD *pdDstScanLine;
  1456. // normalize orientation of source and destination rectangles, and
  1457. // compute sizes and relative orientations of source and destination rects
  1458. if ((iNumSrcCols = BLITLIB_RECTWIDTH(prcSrc)) < 0) {
  1459. iNumSrcCols = -iNumSrcCols;
  1460. FlipRectHorizontal(prcSrc);
  1461. FlipRectHorizontal(prcDst);
  1462. }
  1463. if ((iNumSrcRows = BLITLIB_RECTHEIGHT(prcSrc)) < 0) {
  1464. iNumSrcRows = -iNumSrcRows;
  1465. FlipRectVertical(prcSrc);
  1466. FlipRectVertical(prcDst);
  1467. }
  1468. if ((iNumDstCols = BLITLIB_RECTWIDTH(prcDst)) < 0) {
  1469. prcDst->left--;
  1470. prcDst->right--;
  1471. iNumDstCols = -iNumDstCols;
  1472. iHorizMirror = -1;
  1473. }
  1474. if ((iNumDstRows = BLITLIB_RECTHEIGHT(prcDst)) < 0) {
  1475. prcDst->top--;
  1476. prcDst->bottom--;
  1477. iNumDstRows = -iNumDstRows;
  1478. iVertMirror = -1;
  1479. }
  1480. // compute pointers to the starting rows in the src and dst bitmaps
  1481. // taking care to invert y values, since DIBs are upside-down
  1482. pbSrcScanLine = (BYTE*) pDibBitsSrc + prcSrc->top * (iSrcScanLength
  1483. = DibWidthBytes(pDibInfoSrc)) + prcSrc->left;
  1484. pdDstScanLine = (DWORD*) pDibBitsDst + prcDst->top * (iDstScanLength
  1485. = DibWidthBytes(pDibInfoDst) / 4) + prcDst->left;
  1486. // check if we're doing blending
  1487. if (arAlpha == ALPHA_INVALID) { // no blending desired
  1488. // check to see if we need to worry about transparency
  1489. if (crTransparent == CLR_INVALID) {
  1490. // check if we can do a straight copy from src row to dst row
  1491. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  1492. // check what ROP we'll be performing
  1493. if (dwRop == SRCCOPY) {
  1494. // check if we can do a straight copy vertically,
  1495. // or if we have to stretch, shrink, or mirror
  1496. if ((iNumSrcRows == iNumDstRows) && (iVertMirror == 1)) {
  1497. Blt08Ato24_NoBlend_NoTrans_Hcopy_SRCCOPY_Vcopy(pbSrcScanLine,iSrcScanLength,
  1498. pdDstScanLine,iDstScanLength,
  1499. iNumDstCols,iNumDstRows,(COLORREF*) pDibInfoSrc->bmiColors);
  1500. } else {
  1501. Blt08Ato24_NoBlend_NoTrans_Hcopy_SRCCOPY_NoVcopy(pbSrcScanLine,iSrcScanLength,
  1502. iNumSrcRows,pdDstScanLine,
  1503. iDstScanLength * iVertMirror,
  1504. iNumDstCols,iNumDstRows,(COLORREF*) pDibInfoSrc->bmiColors);
  1505. }
  1506. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  1507. } else { // we have to stretch or shrink horizontally
  1508. // check what ROP we'll be performing
  1509. if (dwRop == SRCCOPY) {
  1510. Blt08Ato24_NoBlend_NoTrans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength,
  1511. iNumSrcCols,iNumSrcRows,
  1512. pdDstScanLine,iDstScanLength * iVertMirror,
  1513. iNumDstCols,iNumDstRows,iHorizMirror,(COLORREF*) pDibInfoSrc->bmiColors);
  1514. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  1515. }
  1516. } else {
  1517. BYTE bTransparentIndex = (BYTE)crTransparent;
  1518. // check if we can do a straight copy from src row to dst row
  1519. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  1520. // check what ROP we'll be performing
  1521. if (dwRop == SRCCOPY) {
  1522. Blt08Ato24_NoBlend_Trans_Hcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength,
  1523. iNumSrcRows,pdDstScanLine,
  1524. iDstScanLength * iVertMirror,
  1525. iNumDstCols,iNumDstRows,
  1526. bTransparentIndex,(COLORREF*) pDibInfoSrc->bmiColors);
  1527. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  1528. } else { // we have to shrink or stretch horizontally
  1529. // check what ROP we'll be performing
  1530. if (dwRop == SRCCOPY) {
  1531. Blt08Ato24_NoBlend_Trans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength,
  1532. iNumSrcCols,iNumSrcRows,
  1533. pdDstScanLine,iDstScanLength * iVertMirror,
  1534. iNumDstCols,iNumDstRows,iHorizMirror,
  1535. bTransparentIndex,(COLORREF*) pDibInfoSrc->bmiColors);
  1536. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  1537. }
  1538. }
  1539. } else { // blending desired
  1540. // REVIEW!!!! -- This is a temporary hack based on the following premises:
  1541. //
  1542. // 1) In theory, per-pixel alpha should be overridable by per-surface alpha
  1543. // 2) In practice, Burma does not allow per-surface alpha to override a per-
  1544. // pixel bitmap.
  1545. // 3) The following code for all the per-surface alpha blending bliting is
  1546. // temporarily commented out so that we can verify DirectDraw NEVER EVER
  1547. // calls BlitLib with both a per-pixel bitmap and a per-surface alpha
  1548. // value other than ALPHA_INVALID.
  1549. //
  1550. // Therefore, we are currently return E_UNEXPECTED if this condition occurs.
  1551. //
  1552. // Although the following commented code is contrary to the Burma hardware,
  1553. // we are not going to change BlitLib to Burma's implementation because we
  1554. // believe it's implementation is a bug.
  1555. //
  1556. return E_UNEXPECTED;
  1557. /* // if alpha value is zero, we do no work since the source bitmap
  1558. // contributes nothing to the destination bitmap
  1559. if (!(arAlpha & ALPHA_MASK)) {
  1560. return sc;
  1561. }
  1562. // check to see if we need to worry about transparency
  1563. if (crTransparent == CLR_INVALID) {
  1564. // check if we can do a straight copy from src row to dst row
  1565. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  1566. // check what ROP we'll be performing
  1567. if (dwRop == SRCCOPY) {
  1568. Blt08Ato24_Blend_NoTrans_Hcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength,
  1569. iNumSrcRows,pdDstScanLine,
  1570. iDstScanLength * iVertMirror,
  1571. iNumDstCols,iNumDstRows,
  1572. arAlpha,(COLORREF*) pDibInfoSrc->bmiColors);
  1573. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  1574. } else { // we need to shrink or stretch horizontally
  1575. // check what ROP we'll be performing
  1576. if (dwRop == SRCCOPY) {
  1577. Blt08Ato24_Blend_NoTrans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength,
  1578. iNumSrcCols,iNumSrcRows,
  1579. pdDstScanLine,iDstScanLength * iVertMirror,
  1580. iNumDstCols,iNumDstRows,iHorizMirror,
  1581. arAlpha,(COLORREF*) pDibInfoSrc->bmiColors);
  1582. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  1583. }
  1584. } else {
  1585. BYTE bTransparentIndex = (BYTE)crTransparent;
  1586. // check if we can do a straight copy from src row to dst row
  1587. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  1588. // check what ROP we'll be performing
  1589. if (dwRop == SRCCOPY) {
  1590. Blt08Ato24_Blend_Trans_Hcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength,
  1591. iNumSrcRows,pdDstScanLine,
  1592. iDstScanLength * iVertMirror,
  1593. iNumDstCols,iNumDstRows,
  1594. bTransparentIndex,arAlpha,(COLORREF*) pDibInfoSrc->bmiColors);
  1595. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  1596. } else { // we have to shrink or stretch horizontally
  1597. // check what ROP we'll be performing
  1598. if (dwRop == SRCCOPY) {
  1599. Blt08Ato24_Blend_Trans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength,
  1600. iNumSrcCols,iNumSrcRows,
  1601. pdDstScanLine,iDstScanLength * iVertMirror,
  1602. iNumDstCols,iNumDstRows,iHorizMirror,
  1603. bTransparentIndex,arAlpha,(COLORREF*) pDibInfoSrc->bmiColors);
  1604. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  1605. }
  1606. }*/
  1607. }
  1608. return sc;
  1609. }
  1610. ///////////////////////////////////////////////////////////////////////
  1611. //
  1612. // Private BlitLib_BitBlt08Ato24P -
  1613. // BitBlit from source bitmap to Dstination bitmap
  1614. // with optional transparency and/or alpha blending using the
  1615. // specified raster operation.
  1616. //
  1617. // Parameters:
  1618. // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB
  1619. // pDibBitsDst Pointer to the bits for the Destination DIB
  1620. // prcDst Pointer to the Destination rectangle
  1621. // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB
  1622. // pDibBitsSrc Pointer to the bits for the Source DIB
  1623. // prcSrc Pointer to the Source rectangle
  1624. // crTransparent Tranparent color value
  1625. // arAlpha Per-surface Alpha value
  1626. // dwRop Raster Operation for the blit
  1627. //
  1628. // Return Value:
  1629. // NO_ERROR or E_* value as specified in the .H file.
  1630. //
  1631. // Status: Incomplete
  1632. //
  1633. ///////////////////////////////////////////////////////////////////////
  1634. SCODE BlitLib_BitBlt08Ato24P(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst,
  1635. PRECT prcDst, PDIBINFO pDibInfoSrc, PDIBBITS pDibBitsSrc,
  1636. PRECT prcSrc, COLORREF crTransparent, ALPHAREF arAlpha, DWORD dwRop)
  1637. {
  1638. SCODE sc = NOERROR;
  1639. int iNumSrcRows,
  1640. iNumSrcCols,
  1641. iSrcScanLength,
  1642. iNumDstRows,
  1643. iNumDstCols,
  1644. iDstScanLength,
  1645. iHorizMirror = 1,
  1646. iVertMirror = 1;
  1647. BYTE *pbSrcScanLine;
  1648. BYTE *pdDstScanLine;
  1649. // normalize orientation of source and destination rectangles, and
  1650. // compute sizes and relative orientations of source and destination rects
  1651. if ((iNumSrcCols = BLITLIB_RECTWIDTH(prcSrc)) < 0) {
  1652. iNumSrcCols = -iNumSrcCols;
  1653. FlipRectHorizontal(prcSrc);
  1654. FlipRectHorizontal(prcDst);
  1655. }
  1656. if ((iNumSrcRows = BLITLIB_RECTHEIGHT(prcSrc)) < 0) {
  1657. iNumSrcRows = -iNumSrcRows;
  1658. FlipRectVertical(prcSrc);
  1659. FlipRectVertical(prcDst);
  1660. }
  1661. if ((iNumDstCols = BLITLIB_RECTWIDTH(prcDst)) < 0) {
  1662. prcDst->left--;
  1663. prcDst->right--;
  1664. iNumDstCols = -iNumDstCols;
  1665. iHorizMirror = -1;
  1666. }
  1667. if ((iNumDstRows = BLITLIB_RECTHEIGHT(prcDst)) < 0) {
  1668. prcDst->top--;
  1669. prcDst->bottom--;
  1670. iNumDstRows = -iNumDstRows;
  1671. iVertMirror = -1;
  1672. }
  1673. // compute pointers to the starting rows in the src and dst bitmaps
  1674. // taking care to invert y values, since DIBs are upside-down
  1675. pbSrcScanLine = (BYTE*) pDibBitsSrc + prcSrc->top * (iSrcScanLength
  1676. = DibWidthBytes(pDibInfoSrc)) + prcSrc->left;
  1677. pdDstScanLine = (BYTE*) pDibBitsDst + prcDst->top * (iDstScanLength
  1678. = DibWidthBytes(pDibInfoDst)) + (prcDst->left * 3);
  1679. // check if we're doing blending
  1680. if (arAlpha == ALPHA_INVALID) { // no blending desired
  1681. // check to see if we need to worry about transparency
  1682. if (crTransparent == CLR_INVALID) {
  1683. // check if we can do a straight copy from src row to dst row
  1684. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  1685. // check what ROP we'll be performing
  1686. if (dwRop == SRCCOPY) {
  1687. // check if we can do a straight copy vertically,
  1688. // or if we have to stretch, shrink, or mirror
  1689. if ((iNumSrcRows == iNumDstRows) && (iVertMirror == 1)) {
  1690. Blt08Ato24P_NoBlend_NoTrans_Hcopy_SRCCOPY_Vcopy(pbSrcScanLine,iSrcScanLength,
  1691. pdDstScanLine,iDstScanLength,
  1692. iNumDstCols,iNumDstRows,(COLORREF*) pDibInfoSrc->bmiColors);
  1693. } else {
  1694. Blt08Ato24P_NoBlend_NoTrans_Hcopy_SRCCOPY_NoVcopy(pbSrcScanLine,iSrcScanLength,
  1695. iNumSrcRows,pdDstScanLine,
  1696. iDstScanLength * iVertMirror,
  1697. iNumDstCols,iNumDstRows,(COLORREF*) pDibInfoSrc->bmiColors);
  1698. }
  1699. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  1700. } else { // we have to stretch or shrink horizontally
  1701. // check what ROP we'll be performing
  1702. if (dwRop == SRCCOPY) {
  1703. Blt08Ato24P_NoBlend_NoTrans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength,
  1704. iNumSrcCols,iNumSrcRows,
  1705. pdDstScanLine,iDstScanLength * iVertMirror,
  1706. iNumDstCols,iNumDstRows,iHorizMirror,(COLORREF*) pDibInfoSrc->bmiColors);
  1707. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  1708. }
  1709. } else {
  1710. BYTE bTransparentIndex = (BYTE)crTransparent;
  1711. // check if we can do a straight copy from src row to dst row
  1712. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  1713. // check what ROP we'll be performing
  1714. if (dwRop == SRCCOPY) {
  1715. Blt08Ato24P_NoBlend_Trans_Hcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength,
  1716. iNumSrcRows,pdDstScanLine,
  1717. iDstScanLength * iVertMirror,
  1718. iNumDstCols,iNumDstRows,
  1719. bTransparentIndex,(COLORREF*) pDibInfoSrc->bmiColors);
  1720. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  1721. } else { // we have to shrink or stretch horizontally
  1722. // check what ROP we'll be performing
  1723. if (dwRop == SRCCOPY) {
  1724. Blt08Ato24P_NoBlend_Trans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength,
  1725. iNumSrcCols,iNumSrcRows,
  1726. pdDstScanLine,iDstScanLength * iVertMirror,
  1727. iNumDstCols,iNumDstRows,iHorizMirror,
  1728. bTransparentIndex,(COLORREF*) pDibInfoSrc->bmiColors);
  1729. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  1730. }
  1731. }
  1732. } else { // blending desired
  1733. // REVIEW!!!! -- This is a temporary hack based on the following premises:
  1734. //
  1735. // 1) In theory, per-pixel alpha should be overridable by per-surface alpha
  1736. // 2) In practice, Burma does not allow per-surface alpha to override a per-
  1737. // pixel bitmap.
  1738. // 3) The following code for all the per-surface alpha blending bliting is
  1739. // temporarily commented out so that we can verify DirectDraw NEVER EVER
  1740. // calls BlitLib with both a per-pixel bitmap and a per-surface alpha
  1741. // value other than ALPHA_INVALID.
  1742. //
  1743. // Therefore, we are currently return E_UNEXPECTED if this condition occurs.
  1744. //
  1745. // Although the following commented code is contrary to the Burma hardware,
  1746. // we are not going to change BlitLib to Burma's implementation because we
  1747. // believe it's implementation is a bug.
  1748. //
  1749. return E_UNEXPECTED;
  1750. /* // if alpha value is zero, we do no work since the source bitmap
  1751. // contributes nothing to the destination bitmap
  1752. if (!(arAlpha & ALPHA_MASK)) {
  1753. return sc;
  1754. }
  1755. // check to see if we need to worry about transparency
  1756. if (crTransparent == CLR_INVALID) {
  1757. // check if we can do a straight copy from src row to dst row
  1758. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  1759. // check what ROP we'll be performing
  1760. if (dwRop == SRCCOPY) {
  1761. Blt08Ato24P_Blend_NoTrans_Hcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength,
  1762. iNumSrcRows,pdDstScanLine,
  1763. iDstScanLength * iVertMirror,
  1764. iNumDstCols,iNumDstRows,
  1765. arAlpha,(COLORREF*) pDibInfoSrc->bmiColors);
  1766. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  1767. } else { // we need to shrink or stretch horizontally
  1768. // check what ROP we'll be performing
  1769. if (dwRop == SRCCOPY) {
  1770. Blt08Ato24P_Blend_NoTrans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength,
  1771. iNumSrcCols,iNumSrcRows,
  1772. pdDstScanLine,iDstScanLength * iVertMirror,
  1773. iNumDstCols,iNumDstRows,iHorizMirror,
  1774. arAlpha,(COLORREF*) pDibInfoSrc->bmiColors);
  1775. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  1776. }
  1777. } else {
  1778. BYTE bTransparentIndex = (BYTE)crTransparent;
  1779. // check if we can do a straight copy from src row to dst row
  1780. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  1781. // check what ROP we'll be performing
  1782. if (dwRop == SRCCOPY) {
  1783. Blt08Ato24P_Blend_Trans_Hcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength,
  1784. iNumSrcRows,pdDstScanLine,
  1785. iDstScanLength * iVertMirror,
  1786. iNumDstCols,iNumDstRows,
  1787. bTransparentIndex,arAlpha,(COLORREF*) pDibInfoSrc->bmiColors);
  1788. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  1789. } else { // we have to shrink or stretch horizontally
  1790. // check what ROP we'll be performing
  1791. if (dwRop == SRCCOPY) {
  1792. Blt08Ato24P_Blend_Trans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength,
  1793. iNumSrcCols,iNumSrcRows,
  1794. pdDstScanLine,iDstScanLength * iVertMirror,
  1795. iNumDstCols,iNumDstRows,iHorizMirror,
  1796. bTransparentIndex,arAlpha,(COLORREF*) pDibInfoSrc->bmiColors);
  1797. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  1798. }
  1799. }*/
  1800. }
  1801. return sc;
  1802. }
  1803. ///////////////////////////////////////////////////////////////////////
  1804. //
  1805. // Private BlitLib_BitBlt08Ato08A -
  1806. // BitBlit from source bitmap to Dstination bitmap
  1807. // with optional transparency using the
  1808. // specified raster operation.
  1809. //
  1810. // This blit is special because it uses the 16to16 blits for
  1811. // all of it's non-transparent color blits. This can be
  1812. // accomplished because we are ignoring the 8-bit alpha channel
  1813. // and just copying 16 bits to the destination. For the blits
  1814. // with a transparent color, new functions are called which check
  1815. // for only a transparent color palette index (8 bits) and then
  1816. // copies 16 bits where the color doesn't match. This is a COPY
  1817. // ONLY blit, thus, it does NOT do any alpha blending.
  1818. //
  1819. // Note: The 08Ato08A routines are located with the other 16to16
  1820. // blits because it is just an extension of them. (These currently
  1821. // reside in blt1616.cxx).
  1822. //
  1823. // Parameters:
  1824. // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB
  1825. // pDibBitsDst Pointer to the bits for the Destination DIB
  1826. // prcDst Pointer to the Destination rectangle
  1827. // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB
  1828. // pDibBitsSrc Pointer to the bits for the Source DIB
  1829. // prcSrc Pointer to the Source rectangle
  1830. // crTransparent Tranparent color value
  1831. // arAlpha Per-surface Alpha value
  1832. // dwRop Raster Operation for the blit
  1833. //
  1834. // Return Value:
  1835. // NO_ERROR or E_* value as specified in the .H file.
  1836. //
  1837. // Status: Incomplete
  1838. //
  1839. ///////////////////////////////////////////////////////////////////////
  1840. SCODE BlitLib_BitBlt08Ato08A(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst,
  1841. PRECT prcDst, PDIBINFO pDibInfoSrc, PDIBBITS pDibBitsSrc,
  1842. PRECT prcSrc, COLORREF crTransparent, ALPHAREF arAlpha, DWORD dwRop)
  1843. {
  1844. SCODE sc = NOERROR;
  1845. int iNumSrcRows,
  1846. iNumSrcCols,
  1847. iSrcScanLength,
  1848. iNumDstRows,
  1849. iNumDstCols,
  1850. iDstScanLength,
  1851. iHorizMirror = 1,
  1852. iVertMirror = 1;
  1853. WORD *pwSrcScanLine,
  1854. *pwDstScanLine;
  1855. // normalize orientation of source and destination rectangles, and
  1856. // compute sizes and relative orientations of source and destination rects
  1857. if ((iNumSrcCols = BLITLIB_RECTWIDTH(prcSrc)) < 0) {
  1858. iNumSrcCols = -iNumSrcCols;
  1859. FlipRectHorizontal(prcSrc);
  1860. FlipRectHorizontal(prcDst);
  1861. }
  1862. if ((iNumSrcRows = BLITLIB_RECTHEIGHT(prcSrc)) < 0) {
  1863. iNumSrcRows = -iNumSrcRows;
  1864. FlipRectVertical(prcSrc);
  1865. FlipRectVertical(prcDst);
  1866. }
  1867. if ((iNumDstCols = BLITLIB_RECTWIDTH(prcDst)) < 0) {
  1868. prcDst->left--;
  1869. prcDst->right--;
  1870. iNumDstCols = -iNumDstCols;
  1871. iHorizMirror = -1;
  1872. }
  1873. if ((iNumDstRows = BLITLIB_RECTHEIGHT(prcDst)) < 0) {
  1874. prcDst->top--;
  1875. prcDst->bottom--;
  1876. iNumDstRows = -iNumDstRows;
  1877. iVertMirror = -1;
  1878. }
  1879. // compute pointers to the starting rows in the src and dst bitmaps
  1880. // taking care to invert y values, since DIBs are upside-down
  1881. pwSrcScanLine = (WORD*) pDibBitsSrc + prcSrc->top * (iSrcScanLength
  1882. = DibWidthBytes(pDibInfoSrc) / 2) + prcSrc->left;
  1883. pwDstScanLine = (WORD*) pDibBitsDst + prcDst->top * (iDstScanLength
  1884. = DibWidthBytes(pDibInfoDst) / 2) + prcDst->left;
  1885. // Make sure we are not doing any blending. This is ONLY a copy blit!
  1886. if (arAlpha != ALPHA_INVALID)
  1887. return E_INVALIDARG;
  1888. // check to see if we need to worry about transparency
  1889. if (crTransparent == CLR_INVALID) {
  1890. // check if we can do a straight copy from src row to dst row
  1891. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  1892. // check what ROP we'll be performing
  1893. if (dwRop == SRCCOPY) {
  1894. // check if we can do a straight copy vertically,
  1895. // or if we have to stretch, shrink, or mirror
  1896. if ((iNumSrcRows == iNumDstRows) && (iVertMirror == 1)) {
  1897. Blt16to16_NoBlend_NoTrans_Hcopy_SRCCOPY_Vcopy(pwSrcScanLine,iSrcScanLength,
  1898. pwDstScanLine,iDstScanLength,
  1899. iNumDstCols,iNumDstRows);
  1900. } else {
  1901. Blt16to16_NoBlend_NoTrans_Hcopy_SRCCOPY_NoVcopy(pwSrcScanLine,iSrcScanLength,
  1902. iNumSrcRows,pwDstScanLine,
  1903. iDstScanLength * iVertMirror,
  1904. iNumDstCols,iNumDstRows);
  1905. }
  1906. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  1907. } else {
  1908. // check what ROP we'll be performing
  1909. if (dwRop == SRCCOPY) {
  1910. Blt16to16_NoBlend_NoTrans_NoHcopy_SRCCOPY(pwSrcScanLine,iSrcScanLength,
  1911. iNumSrcCols,iNumSrcRows,
  1912. pwDstScanLine,iDstScanLength * iVertMirror,
  1913. iNumDstCols,iNumDstRows,iHorizMirror);
  1914. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  1915. }
  1916. }
  1917. else { // transparency desired
  1918. BYTE bTransparentColor = (BYTE)crTransparent;
  1919. // check if we can do a straight copy from src row to dst row
  1920. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  1921. // check what ROP we'll be performing
  1922. if (dwRop == SRCCOPY) {
  1923. Blt08Ato08A_NoBlend_Trans_Hcopy_SRCCOPY(pwSrcScanLine,iSrcScanLength,
  1924. iNumSrcRows,pwDstScanLine,
  1925. iDstScanLength * iVertMirror,
  1926. iNumDstCols,iNumDstRows,
  1927. bTransparentColor);
  1928. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  1929. } else {
  1930. // check what ROP we'll be performing
  1931. if (dwRop == SRCCOPY) {
  1932. Blt08Ato08A_NoBlend_Trans_NoHcopy_SRCCOPY(pwSrcScanLine,iSrcScanLength,
  1933. iNumSrcCols,iNumSrcRows,
  1934. pwDstScanLine,iDstScanLength * iVertMirror,
  1935. iNumDstCols,iNumDstRows,iHorizMirror,
  1936. bTransparentColor);
  1937. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  1938. }
  1939. }
  1940. return sc;
  1941. }
  1942. #endif // DDRAW
  1943. ///////////////////////////////////////////////////////////////////////
  1944. //
  1945. // Private BlitLib_BitBlt16to16 -
  1946. // BitBlit from source bitmap to Dstination bitmap
  1947. // with optional transparency and/or alpha blending using the
  1948. // specified raster operation.
  1949. //
  1950. // Parameters:
  1951. // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB
  1952. // pDibBitsDst Pointer to the bits for the Destination DIB
  1953. // prcDst Pointer to the Destination rectangle
  1954. // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB
  1955. // pDibBitsSrc Pointer to the bits for the Source DIB
  1956. // prcSrc Pointer to the Source rectangle
  1957. // crTransparent Tranparent color value
  1958. // arAlpha Per-surface Alpha value
  1959. // dwRop Raster Operation for the blit
  1960. //
  1961. // Return Value:
  1962. // NO_ERROR or E_* value as specified in the .H file.
  1963. //
  1964. // Status: Incomplete
  1965. //
  1966. ///////////////////////////////////////////////////////////////////////
  1967. SCODE BlitLib_BitBlt16to16(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst,
  1968. PRECT prcDst, PDIBINFO pDibInfoSrc, PDIBBITS pDibBitsSrc,
  1969. PRECT prcSrc, COLORREF crTransparent, ALPHAREF arAlpha, DWORD dwRop)
  1970. {
  1971. SCODE sc = NOERROR;
  1972. int iNumSrcRows,
  1973. iNumSrcCols,
  1974. iSrcScanLength,
  1975. iNumDstRows,
  1976. iNumDstCols,
  1977. iDstScanLength,
  1978. iHorizMirror = 1,
  1979. iVertMirror = 1;
  1980. WORD *pwSrcScanLine,
  1981. *pwDstScanLine;
  1982. // If the bitmaps overlap, we need to use overlapping code
  1983. if(BlitLib_Detect_Intersection(pDibBitsDst, prcDst, pDibBitsSrc, prcSrc))
  1984. return BlitLib_BitBlt16to16_Intersect(pDibInfoDst, pDibBitsDst, prcDst,
  1985. pDibInfoSrc, pDibBitsSrc, prcSrc, crTransparent, dwRop);
  1986. // normalize orientation of source and destination rectangles, and
  1987. // compute sizes and relative orientations of source and destination rects
  1988. if ((iNumSrcCols = BLITLIB_RECTWIDTH(prcSrc)) < 0) {
  1989. iNumSrcCols = -iNumSrcCols;
  1990. FlipRectHorizontal(prcSrc);
  1991. FlipRectHorizontal(prcDst);
  1992. }
  1993. if ((iNumSrcRows = BLITLIB_RECTHEIGHT(prcSrc)) < 0) {
  1994. iNumSrcRows = -iNumSrcRows;
  1995. FlipRectVertical(prcSrc);
  1996. FlipRectVertical(prcDst);
  1997. }
  1998. if ((iNumDstCols = BLITLIB_RECTWIDTH(prcDst)) < 0) {
  1999. prcDst->left--;
  2000. prcDst->right--;
  2001. iNumDstCols = -iNumDstCols;
  2002. iHorizMirror = -1;
  2003. }
  2004. if ((iNumDstRows = BLITLIB_RECTHEIGHT(prcDst)) < 0) {
  2005. prcDst->top--;
  2006. prcDst->bottom--;
  2007. iNumDstRows = -iNumDstRows;
  2008. iVertMirror = -1;
  2009. }
  2010. // compute pointers to the starting rows in the src and dst bitmaps
  2011. // taking care to invert y values, since DIBs are upside-down
  2012. pwSrcScanLine = (WORD*) pDibBitsSrc + prcSrc->top * (iSrcScanLength
  2013. = DibWidthBytes(pDibInfoSrc) / 2) + prcSrc->left;
  2014. pwDstScanLine = (WORD*) pDibBitsDst + prcDst->top * (iDstScanLength
  2015. = DibWidthBytes(pDibInfoDst) / 2) + prcDst->left;
  2016. // check if we're doing blending
  2017. if (arAlpha == ALPHA_INVALID) { // no blending desired
  2018. // check to see if we need to worry about transparency
  2019. if (crTransparent == CLR_INVALID) {
  2020. // check if we can do a straight copy from src row to dst row
  2021. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  2022. // check what ROP we'll be performing
  2023. if (dwRop == SRCCOPY) {
  2024. // check if we can do a straight copy vertically,
  2025. // or if we have to stretch, shrink, or mirror
  2026. if ((iNumSrcRows == iNumDstRows) && (iVertMirror == 1)) {
  2027. Blt16to16_NoBlend_NoTrans_Hcopy_SRCCOPY_Vcopy(pwSrcScanLine,iSrcScanLength,
  2028. pwDstScanLine,iDstScanLength,
  2029. iNumDstCols,iNumDstRows);
  2030. } else {
  2031. Blt16to16_NoBlend_NoTrans_Hcopy_SRCCOPY_NoVcopy(pwSrcScanLine,iSrcScanLength,
  2032. iNumSrcRows,pwDstScanLine,
  2033. iDstScanLength * iVertMirror,
  2034. iNumDstCols,iNumDstRows);
  2035. }
  2036. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  2037. } else {
  2038. // check what ROP we'll be performing
  2039. if (dwRop == SRCCOPY) {
  2040. Blt16to16_NoBlend_NoTrans_NoHcopy_SRCCOPY(pwSrcScanLine,iSrcScanLength,
  2041. iNumSrcCols,iNumSrcRows,
  2042. pwDstScanLine,iDstScanLength * iVertMirror,
  2043. iNumDstCols,iNumDstRows,iHorizMirror);
  2044. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  2045. }
  2046. } else { // transparency desired
  2047. WORD wTransparentColor = (WORD)crTransparent;
  2048. // check if we can do a straight copy from src row to dst row
  2049. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  2050. // check what ROP we'll be performing
  2051. if (dwRop == SRCCOPY)
  2052. {
  2053. Blt16to16_NoBlend_Trans_Hcopy_SRCCOPY(pwSrcScanLine,iSrcScanLength,
  2054. iNumSrcRows,pwDstScanLine,
  2055. iDstScanLength * iVertMirror,
  2056. iNumDstCols,iNumDstRows,
  2057. wTransparentColor);
  2058. }
  2059. else
  2060. sc |= E_UNEXPECTED; // !!!! we need better error codes
  2061. } else {
  2062. // check what ROP we'll be performing
  2063. if (dwRop == SRCCOPY) {
  2064. Blt16to16_NoBlend_Trans_NoHcopy_SRCCOPY(pwSrcScanLine,iSrcScanLength,
  2065. iNumSrcCols,iNumSrcRows,
  2066. pwDstScanLine,iDstScanLength * iVertMirror,
  2067. iNumDstCols,iNumDstRows,iHorizMirror,
  2068. wTransparentColor);
  2069. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  2070. }
  2071. }
  2072. }
  2073. #ifndef DDRAW
  2074. #ifndef WIN95
  2075. else { // blending desired
  2076. // if alpha value is zero, we do no work since the source bitmap
  2077. // contributes nothing to the destination bitmap
  2078. if (!(arAlpha & ALPHA_MASK)) {
  2079. return sc;
  2080. }
  2081. // check to see if we need to worry about transparency
  2082. if (crTransparent == CLR_INVALID) {
  2083. // check if we can do a straight copy from src row to dst row
  2084. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  2085. // check what ROP we'll be performing
  2086. if (dwRop == SRCCOPY) {
  2087. Blt16to16_Blend_NoTrans_Hcopy_SRCCOPY(pwSrcScanLine,iSrcScanLength,
  2088. iNumSrcRows,pwDstScanLine,
  2089. iDstScanLength * iVertMirror,
  2090. iNumDstCols,iNumDstRows,
  2091. arAlpha);
  2092. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  2093. } else {
  2094. // check what ROP we'll be performing
  2095. if (dwRop == SRCCOPY) {
  2096. Blt16to16_Blend_NoTrans_NoHcopy_SRCCOPY(pwSrcScanLine,iSrcScanLength,
  2097. iNumSrcCols,iNumSrcRows,
  2098. pwDstScanLine,iDstScanLength * iVertMirror,
  2099. iNumDstCols,iNumDstRows,iHorizMirror,
  2100. arAlpha);
  2101. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  2102. }
  2103. } else { // transparency desired
  2104. WORD wTransparentColor = (WORD)crTransparent;
  2105. // check if we can do a straight copy from src row to dst row
  2106. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  2107. // check what ROP we'll be performing
  2108. if (dwRop == SRCCOPY) {
  2109. Blt16to16_Blend_Trans_Hcopy_SRCCOPY(pwSrcScanLine,iSrcScanLength,
  2110. iNumSrcRows,pwDstScanLine,
  2111. iDstScanLength * iVertMirror,
  2112. iNumDstCols,iNumDstRows,
  2113. wTransparentColor,arAlpha);
  2114. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  2115. } else {
  2116. // check what ROP we'll be performing
  2117. if (dwRop == SRCCOPY) {
  2118. Blt16to16_Blend_Trans_NoHcopy_SRCCOPY(pwSrcScanLine,iSrcScanLength,
  2119. iNumSrcCols,iNumSrcRows,
  2120. pwDstScanLine,iDstScanLength * iVertMirror,
  2121. iNumDstCols,iNumDstRows,iHorizMirror,
  2122. wTransparentColor,arAlpha);
  2123. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  2124. }
  2125. }
  2126. }
  2127. #endif
  2128. #endif
  2129. return sc;
  2130. }
  2131. ///////////////////////////////////////////////////////////////////////
  2132. //
  2133. // Private BlitLib_BitBlt16to16_Intersect -
  2134. // BitBlit from source bitmap to destination bitmap (and these
  2135. // bitmaps overlap each other) with optional transparency
  2136. // using the specified raster operation.
  2137. //
  2138. // Parameters:
  2139. // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB
  2140. // pDibBitsDst Pointer to the bits for the Destination DIB
  2141. // prcDst Pointer to the Destination rectangle
  2142. // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB
  2143. // pDibBitsSrc Pointer to the bits for the Source DIB
  2144. // prcSrc Pointer to the Source rectangle
  2145. // crTransparent Tranparent color value
  2146. // dwRop Raster Operation for the blit
  2147. //
  2148. // Return Value:
  2149. // NO_ERROR or E_* value as specified in the .H file.
  2150. //
  2151. // Status: Incomplete
  2152. //
  2153. ///////////////////////////////////////////////////////////////////////
  2154. SCODE BlitLib_BitBlt16to16_Intersect(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst,
  2155. PRECT prcDst, PDIBINFO pDibInfoSrc, PDIBBITS pDibBitsSrc, PRECT prcSrc,
  2156. COLORREF crTransparent, DWORD dwRop)
  2157. {
  2158. SCODE sc = NOERROR;
  2159. int iNumSrcRows,
  2160. iNumSrcCols,
  2161. iSrcScanLength,
  2162. iNumDstRows,
  2163. iNumDstCols,
  2164. iDstScanLength,
  2165. iHorizMirror = 1,
  2166. iVertMirror = 1;
  2167. WORD *pwSrcScanLine,
  2168. *pwDstScanLine,
  2169. *pwTempScanLine,
  2170. wTransparentIndex;
  2171. PDIBBITS pDibBitsTemp;
  2172. // normalize orientation of source and destination rectangles, and
  2173. // compute sizes and relative orientations of source and destination rects
  2174. if ((iNumSrcCols = BLITLIB_RECTWIDTH(prcSrc)) < 0)
  2175. {
  2176. iNumSrcCols = -iNumSrcCols;
  2177. FlipRectHorizontal(prcSrc);
  2178. FlipRectHorizontal(prcDst);
  2179. }
  2180. if ((iNumSrcRows = BLITLIB_RECTHEIGHT(prcSrc)) < 0)
  2181. {
  2182. iNumSrcRows = -iNumSrcRows;
  2183. FlipRectVertical(prcSrc);
  2184. FlipRectVertical(prcDst);
  2185. }
  2186. if ((iNumDstCols = BLITLIB_RECTWIDTH(prcDst)) < 0)
  2187. {
  2188. prcDst->left--;
  2189. prcDst->right--;
  2190. iNumDstCols = -iNumDstCols;
  2191. iHorizMirror = -1;
  2192. }
  2193. if ((iNumDstRows = BLITLIB_RECTHEIGHT(prcDst)) < 0)
  2194. {
  2195. prcDst->top--;
  2196. prcDst->bottom--;
  2197. iNumDstRows = -iNumDstRows;
  2198. iVertMirror = -1;
  2199. }
  2200. // We aren't currently support any ROP's besides SRCCOPY
  2201. if(dwRop != SRCCOPY)
  2202. return E_UNEXPECTED;
  2203. //
  2204. // Here are all the stretching and mirroring blits for overlapping rects
  2205. //
  2206. // REVIEW!!! -- The following code could be optimized for the caching
  2207. // cases. Currently, it allocates a second bitmap that is the same
  2208. // size as the original destination, and then uses the original blit
  2209. // rectangle to do the caching. To save space, this blit should
  2210. // eventually be changed to only allocate the size of the overlapped
  2211. // rectangle, and the blit rects should be adjusted accordingly.
  2212. // Check if we are stretching (horiz or vert), or if we are mirroring --
  2213. // In all of these cases, we must create a cache bitmap and double blit
  2214. if((iNumDstCols != iNumSrcCols) || (iNumDstRows != iNumSrcRows) ||
  2215. (iHorizMirror != 1) || (iVertMirror != 1))
  2216. {
  2217. // Allocate memory for the cache bitmap -- We will blit into this
  2218. // temporary bitmap and then re-blit back to the original source
  2219. pDibBitsTemp = (PDIBBITS)osMemAlloc(DibSizeImage((LPBITMAPINFOHEADER)pDibInfoDst));
  2220. if (pDibBitsTemp == NULL)
  2221. return E_UNEXPECTED;
  2222. // compute pointers to the starting rows in the src and temp bitmaps
  2223. pwSrcScanLine = (WORD*) pDibBitsSrc + (prcSrc->top) * (iSrcScanLength
  2224. = DibWidthBytes(pDibInfoSrc) / 2) + prcSrc->left;
  2225. pwTempScanLine = (WORD*) pDibBitsTemp + (prcDst->top) * (iDstScanLength
  2226. = DibWidthBytes(pDibInfoDst) / 2) + prcDst->left;
  2227. // check if we can do a straight copy from src row to dst row
  2228. if((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1))
  2229. {
  2230. // check if we can do a straight copy vertically,
  2231. // or if we have to stretch, shrink, or mirror
  2232. if ((iNumSrcRows == iNumDstRows) && (iVertMirror == 1))
  2233. {
  2234. Blt16to16_NoBlend_NoTrans_Hcopy_SRCCOPY_Vcopy(pwSrcScanLine,iSrcScanLength,
  2235. pwTempScanLine,iDstScanLength,
  2236. iNumDstCols,iNumDstRows);
  2237. }
  2238. else
  2239. {
  2240. Blt16to16_NoBlend_NoTrans_Hcopy_SRCCOPY_NoVcopy(pwSrcScanLine,iSrcScanLength,
  2241. iNumSrcRows,pwTempScanLine,
  2242. iDstScanLength * iVertMirror,
  2243. iNumDstCols,iNumDstRows);
  2244. }
  2245. }
  2246. else
  2247. {
  2248. Blt16to16_NoBlend_NoTrans_NoHcopy_SRCCOPY(pwSrcScanLine,iSrcScanLength,
  2249. iNumSrcCols,iNumSrcRows,
  2250. pwTempScanLine,iDstScanLength * iVertMirror,
  2251. iNumDstCols,iNumDstRows,iHorizMirror);
  2252. }
  2253. // Recalculate the scan line pointers for the second blit
  2254. if(BLITLIB_RECTWIDTH(prcDst) < 0)
  2255. {
  2256. prcDst->left++;
  2257. prcDst->right++;
  2258. FlipRectHorizontal(prcDst);
  2259. }
  2260. if(BLITLIB_RECTHEIGHT(prcDst) < 0)
  2261. {
  2262. prcDst->top++;
  2263. prcDst->bottom++;
  2264. FlipRectVertical(prcDst);
  2265. }
  2266. // compute pointers to the starting rows in the temp and dest bitmaps
  2267. pwTempScanLine = (WORD*) pDibBitsTemp + (prcDst->top) * (iDstScanLength
  2268. = DibWidthBytes(pDibInfoDst) / 2) + prcDst->left;
  2269. pwDstScanLine = (WORD*) pDibBitsDst + (prcDst->top) * (iDstScanLength
  2270. = DibWidthBytes(pDibInfoDst) / 2) + prcDst->left;
  2271. // Now blit from the temporary bitmap back to the original source,
  2272. // checking for transparency if necessary
  2273. if(crTransparent == CLR_INVALID)
  2274. {
  2275. Blt16to16_NoBlend_NoTrans_Hcopy_SRCCOPY_Vcopy(pwTempScanLine,iDstScanLength,
  2276. pwDstScanLine,iDstScanLength,
  2277. iNumDstCols,iNumDstRows);
  2278. }
  2279. else
  2280. {
  2281. wTransparentIndex = (WORD)crTransparent;
  2282. Blt16to16_NoBlend_Trans_Hcopy_SRCCOPY(pwTempScanLine,iDstScanLength,
  2283. iNumDstRows,pwDstScanLine,
  2284. iDstScanLength, iNumDstCols,
  2285. iNumDstRows, wTransparentIndex);
  2286. }
  2287. // Free the memory from the temporary bitmap
  2288. if(pDibBitsTemp)
  2289. osMemFree(pDibBitsTemp);
  2290. return sc;
  2291. }
  2292. //
  2293. // Here are all the non-stretching and non-mirroring blits for overlapping rects
  2294. //
  2295. // check to see if we need to worry about transparency
  2296. if (crTransparent == CLR_INVALID) {
  2297. // Simplest case, they are the same rectangles
  2298. if((prcDst->left == prcSrc->left) && (prcDst->top == prcSrc->top) &&
  2299. (prcDst->right == prcSrc->right) && (prcDst->bottom == prcSrc->bottom))
  2300. {
  2301. return sc;
  2302. }
  2303. // Next case, the destination rectangle is vertically greater in
  2304. // magnitude than the source rectangle
  2305. else if(prcDst->top > prcSrc->top)
  2306. {
  2307. // compute pointers to the starting rows in the src and dst bitmaps
  2308. // taking care to invert y values, since DIBs are upside-down
  2309. pwSrcScanLine = (WORD*) pDibBitsSrc + (prcSrc->bottom - 1) * (iSrcScanLength
  2310. = DibWidthBytes(pDibInfoSrc) / 2) + prcSrc->left;
  2311. pwDstScanLine = (WORD*) pDibBitsDst + (prcDst->bottom - 1) * (iDstScanLength
  2312. = DibWidthBytes(pDibInfoDst) / 2) + prcDst->left;
  2313. // Call the appropriate blit
  2314. Blt16to16_LeftToRight_BottomToTop_SRCCOPY(pwSrcScanLine,
  2315. iSrcScanLength, pwDstScanLine, iDstScanLength, iNumDstCols,
  2316. iNumDstRows);
  2317. }
  2318. // Next case, the destination rectangle is horizontally less than
  2319. // or equal in magnitude to the source rectangle
  2320. else if(prcDst->left <= prcSrc->left){
  2321. // compute pointers to the starting rows in the src and dst bitmaps
  2322. // taking care to invert y values, since DIBs are upside-down
  2323. pwSrcScanLine = (WORD*) pDibBitsSrc + (prcSrc->top) * (iSrcScanLength
  2324. = DibWidthBytes(pDibInfoSrc) / 2) + prcSrc->left;
  2325. pwDstScanLine = (WORD*) pDibBitsDst + (prcDst->top) * (iDstScanLength
  2326. = DibWidthBytes(pDibInfoDst) / 2) + prcDst->left;
  2327. // Call the appropriate blit
  2328. Blt16to16_NoBlend_NoTrans_Hcopy_SRCCOPY_Vcopy(pwSrcScanLine,iSrcScanLength,
  2329. pwDstScanLine,iDstScanLength,
  2330. iNumDstCols,iNumDstRows);
  2331. }
  2332. // Last case, the destination rectangle is horizontally greater
  2333. // in magnitude than the source rectangle
  2334. else{
  2335. // compute pointers to the starting rows in the src and dst bitmaps
  2336. // taking care to invert y values, since DIBs are upside-down
  2337. pwSrcScanLine = (WORD*) pDibBitsSrc + (prcSrc->top) * (iSrcScanLength
  2338. = DibWidthBytes(pDibInfoSrc) / 2) + (prcSrc->right - 1);
  2339. pwDstScanLine = (WORD*) pDibBitsDst + (prcDst->top) * (iDstScanLength
  2340. = DibWidthBytes(pDibInfoDst) / 2) + (prcDst->right - 1);
  2341. // Call the appropriate blit
  2342. Blt16to16_RightToLeft_TopToBottom_SRCCOPY(pwSrcScanLine,
  2343. iSrcScanLength, pwDstScanLine, iDstScanLength, iNumDstCols,
  2344. iNumDstRows);
  2345. }
  2346. }
  2347. else{
  2348. wTransparentIndex = (WORD)crTransparent;
  2349. // Simplest case, they are the same rectangles
  2350. if((prcDst->left == prcSrc->left) && (prcDst->top == prcSrc->top) &&
  2351. (prcDst->right == prcSrc->right) && (prcDst->bottom == prcSrc->bottom))
  2352. return sc;
  2353. // Next case, the destination rectangle is vertically greater in
  2354. // magnitude than the source rectangle
  2355. else if(prcDst->top > prcSrc->top){
  2356. // compute pointers to the starting rows in the src and dst bitmaps
  2357. // taking care to invert y values, since DIBs are upside-down
  2358. pwSrcScanLine = (WORD*) pDibBitsSrc + (prcSrc->bottom - 1) * (iSrcScanLength
  2359. = DibWidthBytes(pDibInfoSrc) / 2) + prcSrc->left;
  2360. pwDstScanLine = (WORD*) pDibBitsDst + (prcDst->bottom - 1) * (iDstScanLength
  2361. = DibWidthBytes(pDibInfoDst) / 2) + prcDst->left;
  2362. // Call the appropriate blit
  2363. Blt16to16_LeftToRight_BottomToTop_Trans_SRCCOPY(pwSrcScanLine,
  2364. iSrcScanLength, pwDstScanLine, iDstScanLength, iNumDstCols,
  2365. iNumDstRows, wTransparentIndex);
  2366. }
  2367. // Next case, the destination rectangle is horizontally less than
  2368. // or equal in magnitude to the source rectangle
  2369. else if(prcDst->left <= prcSrc->left){
  2370. // compute pointers to the starting rows in the src and dst bitmaps
  2371. // taking care to invert y values, since DIBs are upside-down
  2372. pwSrcScanLine = (WORD*) pDibBitsSrc + (prcSrc->top) * (iSrcScanLength
  2373. = DibWidthBytes(pDibInfoSrc) / 2) + prcSrc->left;
  2374. pwDstScanLine = (WORD*) pDibBitsDst + (prcDst->top) * (iDstScanLength
  2375. = DibWidthBytes(pDibInfoDst) / 2) + prcDst->left;
  2376. // Call the appropriate blit
  2377. Blt16to16_NoBlend_Trans_Hcopy_SRCCOPY(pwSrcScanLine,iSrcScanLength,
  2378. iNumSrcRows,pwDstScanLine,
  2379. iDstScanLength, iNumDstCols,iNumDstRows,
  2380. wTransparentIndex);
  2381. }
  2382. // Last case, the destination rectangle is horizontally greater
  2383. // in magnitude than the source rectangle
  2384. else{
  2385. // compute pointers to the starting rows in the src and dst bitmaps
  2386. // taking care to invert y values, since DIBs are upside-down
  2387. pwSrcScanLine = (WORD*) pDibBitsSrc + (prcSrc->top) * (iSrcScanLength
  2388. = DibWidthBytes(pDibInfoSrc) / 2) + (prcSrc->right - 1);
  2389. pwDstScanLine = (WORD*) pDibBitsDst + (prcDst->top) * (iDstScanLength
  2390. = DibWidthBytes(pDibInfoDst) / 2) + (prcDst->right - 1);
  2391. // Call the appropriate blit
  2392. Blt16to16_RightToLeft_TopToBottom_Trans_SRCCOPY(pwSrcScanLine,
  2393. iSrcScanLength, pwDstScanLine, iDstScanLength, iNumDstCols,
  2394. iNumDstRows, wTransparentIndex);
  2395. }
  2396. }
  2397. return sc;
  2398. }
  2399. #ifndef DDRAW
  2400. ///////////////////////////////////////////////////////////////////////
  2401. //
  2402. // Private BlitLib_BitBlt16to24 -
  2403. // BitBlit from source bitmap to Dstination bitmap
  2404. // with optional transparency and/or alpha blending using the
  2405. // specified raster operation.
  2406. //
  2407. // Parameters:
  2408. // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB
  2409. // pDibBitsDst Pointer to the bits for the Destination DIB
  2410. // prcDst Pointer to the Destination rectangle
  2411. // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB
  2412. // pDibBitsSrc Pointer to the bits for the Source DIB
  2413. // prcSrc Pointer to the Source rectangle
  2414. // crTransparent Tranparent color value
  2415. // arAlpha Per-surface Alpha value
  2416. // dwRop Raster Operation for the blit
  2417. //
  2418. // Return Value:
  2419. // NO_ERROR or E_* value as specified in the .H file.
  2420. //
  2421. // Status: Incomplete
  2422. //
  2423. ///////////////////////////////////////////////////////////////////////
  2424. SCODE BlitLib_BitBlt16to24(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst,
  2425. PRECT prcDst, PDIBINFO pDibInfoSrc, PDIBBITS pDibBitsSrc,
  2426. PRECT prcSrc, COLORREF crTransparent, ALPHAREF arAlpha, DWORD dwRop)
  2427. {
  2428. SCODE sc = NOERROR;
  2429. int iNumSrcRows,
  2430. iNumSrcCols,
  2431. iSrcScanLength,
  2432. iNumDstRows,
  2433. iNumDstCols,
  2434. iDstScanLength,
  2435. iHorizMirror = 1,
  2436. iVertMirror = 1;
  2437. WORD *pwSrcScanLine;
  2438. DWORD *pdDstScanLine;
  2439. // normalize orientation of source and destination rectangles, and
  2440. // compute sizes and relative orientations of source and destination rects
  2441. if ((iNumSrcCols = BLITLIB_RECTWIDTH(prcSrc)) < 0) {
  2442. iNumSrcCols = -iNumSrcCols;
  2443. FlipRectHorizontal(prcSrc);
  2444. FlipRectHorizontal(prcDst);
  2445. }
  2446. if ((iNumSrcRows = BLITLIB_RECTHEIGHT(prcSrc)) < 0) {
  2447. iNumSrcRows = -iNumSrcRows;
  2448. FlipRectVertical(prcSrc);
  2449. FlipRectVertical(prcDst);
  2450. }
  2451. if ((iNumDstCols = BLITLIB_RECTWIDTH(prcDst)) < 0) {
  2452. prcDst->left--;
  2453. prcDst->right--;
  2454. iNumDstCols = -iNumDstCols;
  2455. iHorizMirror = -1;
  2456. }
  2457. if ((iNumDstRows = BLITLIB_RECTHEIGHT(prcDst)) < 0) {
  2458. prcDst->top--;
  2459. prcDst->bottom--;
  2460. iNumDstRows = -iNumDstRows;
  2461. iVertMirror = -1;
  2462. }
  2463. // compute pointers to the starting rows in the src and dst bitmaps
  2464. // taking care to invert y values, since DIBs are upside-down
  2465. pwSrcScanLine = (WORD*) pDibBitsSrc + prcSrc->top * (iSrcScanLength
  2466. = DibWidthBytes(pDibInfoSrc) / 2) + prcSrc->left;
  2467. pdDstScanLine = (DWORD*) pDibBitsDst + prcDst->top * (iDstScanLength
  2468. = DibWidthBytes(pDibInfoDst) / 4) + prcDst->left;
  2469. // check if we're doing blending
  2470. if (arAlpha == ALPHA_INVALID) { // no blending desired
  2471. // check to see if we need to worry about transparency
  2472. if (crTransparent == CLR_INVALID) {
  2473. // check if we can do a straight copy from src row to dst row
  2474. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  2475. // check what ROP we'll be performing
  2476. if (dwRop == SRCCOPY) {
  2477. // check if we can do a straight copy vertically,
  2478. // or if we have to stretch, shrink, or mirror
  2479. if ((iNumSrcRows == iNumDstRows) && (iVertMirror == 1)) {
  2480. Blt16to24_NoBlend_NoTrans_Hcopy_SRCCOPY_Vcopy(pwSrcScanLine,iSrcScanLength,
  2481. pdDstScanLine,iDstScanLength,
  2482. iNumDstCols,iNumDstRows);
  2483. } else {
  2484. Blt16to24_NoBlend_NoTrans_Hcopy_SRCCOPY_NoVcopy(pwSrcScanLine,iSrcScanLength,
  2485. iNumSrcRows,pdDstScanLine,
  2486. iDstScanLength * iVertMirror,
  2487. iNumDstCols,iNumDstRows);
  2488. }
  2489. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  2490. } else {
  2491. // check what ROP we'll be performing
  2492. if (dwRop == SRCCOPY) {
  2493. Blt16to24_NoBlend_NoTrans_NoHcopy_SRCCOPY(pwSrcScanLine,iSrcScanLength,
  2494. iNumSrcCols,iNumSrcRows,
  2495. pdDstScanLine,iDstScanLength * iVertMirror,
  2496. iNumDstCols,iNumDstRows,iHorizMirror);
  2497. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  2498. }
  2499. } else { // transparency desired
  2500. WORD wTransparentColor = (WORD)crTransparent;
  2501. // check if we can do a straight copy from src row to dst row
  2502. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  2503. // check what ROP we'll be performing
  2504. if (dwRop == SRCCOPY) {
  2505. Blt16to24_NoBlend_Trans_Hcopy_SRCCOPY(pwSrcScanLine,iSrcScanLength,
  2506. iNumSrcRows,pdDstScanLine,
  2507. iDstScanLength * iVertMirror,
  2508. iNumDstCols,iNumDstRows,
  2509. wTransparentColor);
  2510. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  2511. } else {
  2512. // check what ROP we'll be performing
  2513. if (dwRop == SRCCOPY) {
  2514. Blt16to24_NoBlend_Trans_NoHcopy_SRCCOPY(pwSrcScanLine,iSrcScanLength,
  2515. iNumSrcCols,iNumSrcRows,
  2516. pdDstScanLine,iDstScanLength * iVertMirror,
  2517. iNumDstCols,iNumDstRows,iHorizMirror,
  2518. wTransparentColor);
  2519. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  2520. }
  2521. }
  2522. } else { // blending desired
  2523. // if alpha value is zero, we do no work since the source bitmap
  2524. // contributes nothing to the destination bitmap
  2525. if (!(arAlpha & ALPHA_MASK)) {
  2526. return sc;
  2527. }
  2528. // check to see if we need to worry about transparency
  2529. if (crTransparent == CLR_INVALID) {
  2530. // check if we can do a straight copy from src row to dst row
  2531. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  2532. // check what ROP we'll be performing
  2533. if (dwRop == SRCCOPY) {
  2534. Blt16to24_Blend_NoTrans_Hcopy_SRCCOPY(pwSrcScanLine,iSrcScanLength,
  2535. iNumSrcRows,pdDstScanLine,
  2536. iDstScanLength * iVertMirror,
  2537. iNumDstCols,iNumDstRows,
  2538. arAlpha);
  2539. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  2540. } else {
  2541. // check what ROP we'll be performing
  2542. if (dwRop == SRCCOPY) {
  2543. Blt16to24_Blend_NoTrans_NoHcopy_SRCCOPY(pwSrcScanLine,iSrcScanLength,
  2544. iNumSrcCols,iNumSrcRows,
  2545. pdDstScanLine,iDstScanLength * iVertMirror,
  2546. iNumDstCols,iNumDstRows,iHorizMirror,
  2547. arAlpha);
  2548. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  2549. }
  2550. } else { // transparency desired
  2551. WORD wTransparentColor = (WORD)crTransparent;
  2552. // check if we can do a straight copy from src row to dst row
  2553. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  2554. // check what ROP we'll be performing
  2555. if (dwRop == SRCCOPY) {
  2556. Blt16to24_Blend_Trans_Hcopy_SRCCOPY(pwSrcScanLine,iSrcScanLength,
  2557. iNumSrcRows,pdDstScanLine,
  2558. iDstScanLength * iVertMirror,
  2559. iNumDstCols,iNumDstRows,
  2560. wTransparentColor,arAlpha);
  2561. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  2562. } else {
  2563. // check what ROP we'll be performing
  2564. if (dwRop == SRCCOPY) {
  2565. Blt16to24_Blend_Trans_NoHcopy_SRCCOPY(pwSrcScanLine,iSrcScanLength,
  2566. iNumSrcCols,iNumSrcRows,
  2567. pdDstScanLine,iDstScanLength * iVertMirror,
  2568. iNumDstCols,iNumDstRows,iHorizMirror,
  2569. wTransparentColor,arAlpha);
  2570. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  2571. }
  2572. }
  2573. }
  2574. return sc;
  2575. }
  2576. ///////////////////////////////////////////////////////////////////////
  2577. //
  2578. // Private BlitLib_BitBlt16to24P -
  2579. // BitBlit from source bitmap to Dstination bitmap
  2580. // with optional transparency and/or alpha blending using the
  2581. // specified raster operation.
  2582. //
  2583. // Parameters:
  2584. // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB
  2585. // pDibBitsDst Pointer to the bits for the Destination DIB
  2586. // prcDst Pointer to the Destination rectangle
  2587. // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB
  2588. // pDibBitsSrc Pointer to the bits for the Source DIB
  2589. // prcSrc Pointer to the Source rectangle
  2590. // crTransparent Tranparent color value
  2591. // arAlpha Per-surface Alpha value
  2592. // dwRop Raster Operation for the blit
  2593. //
  2594. // Return Value:
  2595. // NO_ERROR or E_* value as specified in the .H file.
  2596. //
  2597. // Status: Incomplete
  2598. //
  2599. ///////////////////////////////////////////////////////////////////////
  2600. SCODE BlitLib_BitBlt16to24P(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst,
  2601. PRECT prcDst, PDIBINFO pDibInfoSrc, PDIBBITS pDibBitsSrc,
  2602. PRECT prcSrc, COLORREF crTransparent, ALPHAREF arAlpha, DWORD dwRop)
  2603. {
  2604. SCODE sc = NOERROR;
  2605. int iNumSrcRows,
  2606. iNumSrcCols,
  2607. iSrcScanLength,
  2608. iNumDstRows,
  2609. iNumDstCols,
  2610. iDstScanLength,
  2611. iHorizMirror = 1,
  2612. iVertMirror = 1;
  2613. WORD *pwSrcScanLine;
  2614. BYTE *pdDstScanLine;
  2615. // normalize orientation of source and destination rectangles, and
  2616. // compute sizes and relative orientations of source and destination rects
  2617. if ((iNumSrcCols = BLITLIB_RECTWIDTH(prcSrc)) < 0) {
  2618. iNumSrcCols = -iNumSrcCols;
  2619. FlipRectHorizontal(prcSrc);
  2620. FlipRectHorizontal(prcDst);
  2621. }
  2622. if ((iNumSrcRows = BLITLIB_RECTHEIGHT(prcSrc)) < 0) {
  2623. iNumSrcRows = -iNumSrcRows;
  2624. FlipRectVertical(prcSrc);
  2625. FlipRectVertical(prcDst);
  2626. }
  2627. if ((iNumDstCols = BLITLIB_RECTWIDTH(prcDst)) < 0) {
  2628. prcDst->left--;
  2629. prcDst->right--;
  2630. iNumDstCols = -iNumDstCols;
  2631. iHorizMirror = -1;
  2632. }
  2633. if ((iNumDstRows = BLITLIB_RECTHEIGHT(prcDst)) < 0) {
  2634. prcDst->top--;
  2635. prcDst->bottom--;
  2636. iNumDstRows = -iNumDstRows;
  2637. iVertMirror = -1;
  2638. }
  2639. // compute pointers to the starting rows in the src and dst bitmaps
  2640. // taking care to invert y values, since DIBs are upside-down
  2641. pwSrcScanLine = (WORD *) pDibBitsSrc + prcSrc->top * (iSrcScanLength
  2642. = DibWidthBytes(pDibInfoSrc) / 2) + prcSrc->left;
  2643. pdDstScanLine = (BYTE *) pDibBitsDst + prcDst->top * (iDstScanLength
  2644. = DibWidthBytes(pDibInfoDst)) + (prcDst->left * 3);
  2645. // check if we're doing blending
  2646. if (arAlpha == ALPHA_INVALID) { // no blending desired
  2647. // check to see if we need to worry about transparency
  2648. if (crTransparent == CLR_INVALID) {
  2649. // check if we can do a straight copy from src row to dst row
  2650. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  2651. // check what ROP we'll be performing
  2652. if (dwRop == SRCCOPY) {
  2653. // check if we can do a straight copy vertically,
  2654. // or if we have to stretch, shrink, or mirror
  2655. if ((iNumSrcRows == iNumDstRows) && (iVertMirror == 1)) {
  2656. Blt16to24P_NoBlend_NoTrans_Hcopy_SRCCOPY_Vcopy(pwSrcScanLine,iSrcScanLength,
  2657. pdDstScanLine,iDstScanLength,
  2658. iNumDstCols,iNumDstRows);
  2659. } else {
  2660. Blt16to24P_NoBlend_NoTrans_Hcopy_SRCCOPY_NoVcopy(pwSrcScanLine,iSrcScanLength,
  2661. iNumSrcRows,pdDstScanLine,
  2662. iDstScanLength * iVertMirror,
  2663. iNumDstCols,iNumDstRows);
  2664. }
  2665. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  2666. } else {
  2667. // check what ROP we'll be performing
  2668. if (dwRop == SRCCOPY) {
  2669. Blt16to24P_NoBlend_NoTrans_NoHcopy_SRCCOPY(pwSrcScanLine,iSrcScanLength,
  2670. iNumSrcCols,iNumSrcRows,
  2671. pdDstScanLine,iDstScanLength * iVertMirror,
  2672. iNumDstCols,iNumDstRows,iHorizMirror);
  2673. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  2674. }
  2675. } else { // transparency desired
  2676. WORD wTransparentColor = (WORD)crTransparent;
  2677. // check if we can do a straight copy from src row to dst row
  2678. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  2679. // check what ROP we'll be performing
  2680. if (dwRop == SRCCOPY) {
  2681. Blt16to24P_NoBlend_Trans_Hcopy_SRCCOPY(pwSrcScanLine,iSrcScanLength,
  2682. iNumSrcRows,pdDstScanLine,
  2683. iDstScanLength * iVertMirror,
  2684. iNumDstCols,iNumDstRows,
  2685. wTransparentColor);
  2686. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  2687. } else {
  2688. // check what ROP we'll be performing
  2689. if (dwRop == SRCCOPY) {
  2690. Blt16to24P_NoBlend_Trans_NoHcopy_SRCCOPY(pwSrcScanLine,iSrcScanLength,
  2691. iNumSrcCols,iNumSrcRows,
  2692. pdDstScanLine,iDstScanLength * iVertMirror,
  2693. iNumDstCols,iNumDstRows,iHorizMirror,
  2694. wTransparentColor);
  2695. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  2696. }
  2697. }
  2698. } else { // blending desired
  2699. // if alpha value is zero, we do no work since the source bitmap
  2700. // contributes nothing to the destination bitmap
  2701. if (!(arAlpha & ALPHA_MASK)) {
  2702. return sc;
  2703. }
  2704. // check to see if we need to worry about transparency
  2705. if (crTransparent == CLR_INVALID) {
  2706. // check if we can do a straight copy from src row to dst row
  2707. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  2708. // check what ROP we'll be performing
  2709. if (dwRop == SRCCOPY) {
  2710. Blt16to24P_Blend_NoTrans_Hcopy_SRCCOPY(pwSrcScanLine,iSrcScanLength,
  2711. iNumSrcRows,pdDstScanLine,
  2712. iDstScanLength * iVertMirror,
  2713. iNumDstCols,iNumDstRows,
  2714. arAlpha);
  2715. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  2716. } else {
  2717. // check what ROP we'll be performing
  2718. if (dwRop == SRCCOPY) {
  2719. Blt16to24P_Blend_NoTrans_NoHcopy_SRCCOPY(pwSrcScanLine,iSrcScanLength,
  2720. iNumSrcCols,iNumSrcRows,
  2721. pdDstScanLine,iDstScanLength * iVertMirror,
  2722. iNumDstCols,iNumDstRows,iHorizMirror,
  2723. arAlpha);
  2724. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  2725. }
  2726. } else { // transparency desired
  2727. WORD wTransparentColor = (WORD)crTransparent;
  2728. // check if we can do a straight copy from src row to dst row
  2729. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  2730. // check what ROP we'll be performing
  2731. if (dwRop == SRCCOPY) {
  2732. Blt16to24P_Blend_Trans_Hcopy_SRCCOPY(pwSrcScanLine,iSrcScanLength,
  2733. iNumSrcRows,pdDstScanLine,
  2734. iDstScanLength * iVertMirror,
  2735. iNumDstCols,iNumDstRows,
  2736. wTransparentColor,arAlpha);
  2737. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  2738. } else {
  2739. // check what ROP we'll be performing
  2740. if (dwRop == SRCCOPY) {
  2741. Blt16to24P_Blend_Trans_NoHcopy_SRCCOPY(pwSrcScanLine,iSrcScanLength,
  2742. iNumSrcCols,iNumSrcRows,
  2743. pdDstScanLine,iDstScanLength * iVertMirror,
  2744. iNumDstCols,iNumDstRows,iHorizMirror,
  2745. wTransparentColor,arAlpha);
  2746. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  2747. }
  2748. }
  2749. }
  2750. return sc;
  2751. }
  2752. ///////////////////////////////////////////////////////////////////////
  2753. //
  2754. // Private BlitLib_BitBlt24to01 -
  2755. // BitBlit from source bitmap to destination bitmap
  2756. // with optional transparency and/or alpha blending using the
  2757. // specified raster operation.
  2758. //
  2759. // Parameters:
  2760. // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB
  2761. // pDibBitsDst Pointer to the bits for the Destination DIB
  2762. // prcDst Pointer to the Destination rectangle
  2763. // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB
  2764. // pDibBitsSrc Pointer to the bits for the Source DIB
  2765. // prcSrc Pointer to the Source rectangle
  2766. // crTransparent Tranparent color value
  2767. // arAlpha Per-surface Alpha value
  2768. // dwRop Raster Operation for the blit
  2769. //
  2770. // Return Value:
  2771. // NO_ERROR or E_* value as specified in the .H file.
  2772. //
  2773. // Status: Incomplete
  2774. //
  2775. ///////////////////////////////////////////////////////////////////////
  2776. SCODE BlitLib_BitBlt24to01(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst,
  2777. PRECT prcDst, PDIBINFO pDibInfoSrc, PDIBBITS pDibBitsSrc,
  2778. PRECT prcSrc, COLORREF crTransparent, ALPHAREF arAlpha, DWORD dwRop)
  2779. {
  2780. SCODE sc = NOERROR;
  2781. int iNumSrcRows,
  2782. iNumSrcCols,
  2783. iSrcScanLength,
  2784. iNumDstRows,
  2785. iNumDstCols,
  2786. iBytesPerDstScanLine,
  2787. iHorizMirror = 1,
  2788. iVertMirror = 1,
  2789. iDstBitOffset;
  2790. DWORD *pdSrcScanLine;
  2791. BYTE *pbDstScanLine,
  2792. bFillVal;
  2793. // alpha blending not currently supported in the 24 to 1 bpp blits
  2794. if (arAlpha != ALPHA_INVALID) {
  2795. return E_UNEXPECTED; // !!!! need better error codes
  2796. }
  2797. // the only ROPs supported are BLACKNESS and WHITENESS
  2798. if (dwRop == BLACKNESS) {
  2799. bFillVal = 0;
  2800. } else if (dwRop == WHITENESS) {
  2801. bFillVal = 0xFF;
  2802. } else {
  2803. return E_UNEXPECTED; // !!!! need better error codes
  2804. }
  2805. // normalize orientation of source and destination rectangles, and
  2806. // compute sizes and relative orientations of source and destination rects
  2807. if ((iNumSrcCols = BLITLIB_RECTWIDTH(prcSrc)) < 0) {
  2808. iNumSrcCols = -iNumSrcCols;
  2809. FlipRectHorizontal(prcSrc);
  2810. FlipRectHorizontal(prcDst);
  2811. }
  2812. if ((iNumSrcRows = BLITLIB_RECTHEIGHT(prcSrc)) < 0) {
  2813. iNumSrcRows = -iNumSrcRows;
  2814. FlipRectVertical(prcSrc);
  2815. FlipRectVertical(prcDst);
  2816. }
  2817. if ((iNumDstCols = BLITLIB_RECTWIDTH(prcDst)) < 0) {
  2818. prcDst->left--;
  2819. prcDst->right--;
  2820. iNumDstCols = -iNumDstCols;
  2821. iHorizMirror = -1;
  2822. }
  2823. if ((iNumDstRows = BLITLIB_RECTHEIGHT(prcDst)) < 0) {
  2824. prcDst->top--;
  2825. prcDst->bottom--;
  2826. iNumDstRows = -iNumDstRows;
  2827. iVertMirror = -1;
  2828. }
  2829. // compute pointers to the starting rows in the src and dst bitmaps
  2830. // taking care to invert y values, since DIBs are upside-down
  2831. pdSrcScanLine = (DWORD*) pDibBitsSrc + prcSrc->top * (iSrcScanLength
  2832. = DibWidthBytes(pDibInfoSrc) / 4) + prcSrc->left;
  2833. pbDstScanLine = (BYTE*) pDibBitsDst + prcDst->top * (iBytesPerDstScanLine
  2834. = DibWidthBytes(pDibInfoDst)) + (prcDst->left / 8);
  2835. iDstBitOffset = prcDst->left % 8;
  2836. // check to see if we need to worry about transparency
  2837. if (crTransparent == CLR_INVALID) {
  2838. // no transparency plus a constant ROP equals a rectangle fill!
  2839. // first we have to normalize dst rect orientation
  2840. // - FillRect01() expects it
  2841. if (BLITLIB_RECTWIDTH(prcDst) < 0) {
  2842. prcDst->left++;
  2843. prcDst->right++;
  2844. FlipRectHorizontal(prcDst);
  2845. }
  2846. if (BLITLIB_RECTHEIGHT(prcDst) < 0) {
  2847. prcDst->top--;
  2848. prcDst->bottom--;
  2849. FlipRectVertical(prcDst);
  2850. }
  2851. sc |= BlitLib_FillRect01(pDibInfoDst,pDibBitsDst,prcDst->left,prcDst->top,
  2852. iNumDstCols,iNumDstRows,bFillVal);
  2853. } else {
  2854. // check if we can do a straight copy from src row to dst row
  2855. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  2856. Blt24to01_Trans_Hcopy_ConstRop(pdSrcScanLine,iSrcScanLength,iNumSrcRows,
  2857. pbDstScanLine,iDstBitOffset,
  2858. iBytesPerDstScanLine * iVertMirror,
  2859. iNumDstCols,iNumDstRows,crTransparent,
  2860. bFillVal);
  2861. } else {
  2862. Blt24to01_Trans_NoHcopy_ConstRop(pdSrcScanLine,iSrcScanLength,iNumSrcCols,
  2863. iNumSrcRows,pbDstScanLine,iDstBitOffset,
  2864. iBytesPerDstScanLine * iVertMirror,
  2865. iNumDstCols,iNumDstRows,iHorizMirror,
  2866. crTransparent,bFillVal);
  2867. }
  2868. }
  2869. return sc;
  2870. }
  2871. ///////////////////////////////////////////////////////////////////////
  2872. //
  2873. // Private BlitLib_BitBlt24Pto01 -
  2874. // BitBlit from source bitmap to destination bitmap
  2875. // with optional transparency and/or alpha blending using the
  2876. // specified raster operation.
  2877. //
  2878. // Parameters:
  2879. // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB
  2880. // pDibBitsDst Pointer to the bits for the Destination DIB
  2881. // prcDst Pointer to the Destination rectangle
  2882. // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB
  2883. // pDibBitsSrc Pointer to the bits for the Source DIB
  2884. // prcSrc Pointer to the Source rectangle
  2885. // crTransparent Tranparent color value
  2886. // arAlpha Per-surface Alpha value
  2887. // dwRop Raster Operation for the blit
  2888. //
  2889. // Return Value:
  2890. // NO_ERROR or E_* value as specified in the .H file.
  2891. //
  2892. // Status: Incomplete
  2893. //
  2894. ///////////////////////////////////////////////////////////////////////
  2895. SCODE BlitLib_BitBlt24Pto01(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst,
  2896. PRECT prcDst, PDIBINFO pDibInfoSrc, PDIBBITS pDibBitsSrc,
  2897. PRECT prcSrc, COLORREF crTransparent, ALPHAREF arAlpha, DWORD dwRop)
  2898. {
  2899. SCODE sc = NOERROR;
  2900. int iNumSrcRows,
  2901. iNumSrcCols,
  2902. iSrcScanLength,
  2903. iNumDstRows,
  2904. iNumDstCols,
  2905. iBytesPerDstScanLine,
  2906. iHorizMirror = 1,
  2907. iVertMirror = 1,
  2908. iDstBitOffset;
  2909. BYTE *pdSrcScanLine;
  2910. BYTE *pbDstScanLine,
  2911. bFillVal;
  2912. // alpha blending not currently supported in the 24 to 1 bpp blits
  2913. if (arAlpha != ALPHA_INVALID) {
  2914. return E_UNEXPECTED; // !!!! need better error codes
  2915. }
  2916. // the only ROPs supported are BLACKNESS and WHITENESS
  2917. if (dwRop == BLACKNESS) {
  2918. bFillVal = 0;
  2919. } else if (dwRop == WHITENESS) {
  2920. bFillVal = 0xFF;
  2921. } else {
  2922. return E_UNEXPECTED; // !!!! need better error codes
  2923. }
  2924. // normalize orientation of source and destination rectangles, and
  2925. // compute sizes and relative orientations of source and destination rects
  2926. if ((iNumSrcCols = BLITLIB_RECTWIDTH(prcSrc)) < 0) {
  2927. iNumSrcCols = -iNumSrcCols;
  2928. FlipRectHorizontal(prcSrc);
  2929. FlipRectHorizontal(prcDst);
  2930. }
  2931. if ((iNumSrcRows = BLITLIB_RECTHEIGHT(prcSrc)) < 0) {
  2932. iNumSrcRows = -iNumSrcRows;
  2933. FlipRectVertical(prcSrc);
  2934. FlipRectVertical(prcDst);
  2935. }
  2936. if ((iNumDstCols = BLITLIB_RECTWIDTH(prcDst)) < 0) {
  2937. prcDst->left--;
  2938. prcDst->right--;
  2939. iNumDstCols = -iNumDstCols;
  2940. iHorizMirror = -1;
  2941. }
  2942. if ((iNumDstRows = BLITLIB_RECTHEIGHT(prcDst)) < 0) {
  2943. prcDst->top--;
  2944. prcDst->bottom--;
  2945. iNumDstRows = -iNumDstRows;
  2946. iVertMirror = -1;
  2947. }
  2948. // compute pointers to the starting rows in the src and dst bitmaps
  2949. // taking care to invert y values, since DIBs are upside-down
  2950. pdSrcScanLine = (BYTE*) pDibBitsSrc + prcSrc->top * (iSrcScanLength
  2951. = DibWidthBytes(pDibInfoSrc)) + (prcSrc->left * 3);
  2952. pbDstScanLine = (BYTE*) pDibBitsDst + prcDst->top * (iBytesPerDstScanLine
  2953. = DibWidthBytes(pDibInfoDst)) + (prcDst->left / 8);
  2954. iDstBitOffset = prcDst->left % 8;
  2955. // check to see if we need to worry about transparency
  2956. if (crTransparent == CLR_INVALID) {
  2957. // no transparency plus a constant ROP equals a rectangle fill!
  2958. // first we have to normalize dst rect orientation
  2959. // - FillRect01() expects it
  2960. if (BLITLIB_RECTWIDTH(prcDst) < 0) {
  2961. prcDst->left++;
  2962. prcDst->right++;
  2963. FlipRectHorizontal(prcDst);
  2964. }
  2965. if (BLITLIB_RECTHEIGHT(prcDst) < 0) {
  2966. prcDst->top--;
  2967. prcDst->bottom--;
  2968. FlipRectVertical(prcDst);
  2969. }
  2970. sc |= BlitLib_FillRect01(pDibInfoDst,pDibBitsDst,prcDst->left,prcDst->top,
  2971. iNumDstCols,iNumDstRows,bFillVal);
  2972. } else {
  2973. // check if we can do a straight copy from src row to dst row
  2974. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  2975. Blt24Pto01_Trans_Hcopy_ConstRop(pdSrcScanLine,iSrcScanLength,iNumSrcRows,
  2976. pbDstScanLine,iDstBitOffset,
  2977. iBytesPerDstScanLine * iVertMirror,
  2978. iNumDstCols,iNumDstRows,crTransparent,
  2979. bFillVal);
  2980. } else {
  2981. Blt24Pto01_Trans_NoHcopy_ConstRop(pdSrcScanLine,iSrcScanLength,iNumSrcCols,
  2982. iNumSrcRows,pbDstScanLine,iDstBitOffset,
  2983. iBytesPerDstScanLine * iVertMirror,
  2984. iNumDstCols,iNumDstRows,iHorizMirror,
  2985. crTransparent,bFillVal);
  2986. }
  2987. }
  2988. return sc;
  2989. }
  2990. ///////////////////////////////////////////////////////////////////////
  2991. //
  2992. // Private BlitLib_BitBlt24to08 -
  2993. // BitBlit from source bitmap to Dstination bitmap
  2994. // with optional transparency and/or alpha blending using the
  2995. // specified raster operation.
  2996. //
  2997. // Parameters:
  2998. // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB
  2999. // pDibBitsDst Pointer to the bits for the Destination DIB
  3000. // prcDst Pointer to the Destination rectangle
  3001. // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB
  3002. // pDibBitsSrc Pointer to the bits for the Source DIB
  3003. // prcSrc Pointer to the Source rectangle
  3004. // crTransparent Tranparent color value
  3005. // arAlpha Per-surface Alpha value
  3006. // dwRop Raster Operation for the blit
  3007. //
  3008. // Return Value:
  3009. // NO_ERROR or E_* value as specified in the .H file.
  3010. //
  3011. // Status: Incomplete
  3012. //
  3013. ///////////////////////////////////////////////////////////////////////
  3014. SCODE BlitLib_BitBlt24to08(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst,
  3015. PRECT prcDst, PDIBINFO pDibInfoSrc, PDIBBITS pDibBitsSrc,
  3016. PRECT prcSrc, COLORREF crTransparent, ALPHAREF arAlpha, DWORD dwRop)
  3017. {
  3018. SCODE sc = NOERROR;
  3019. int iNumSrcRows,
  3020. iNumSrcCols,
  3021. iSrcScanLength,
  3022. iNumDstRows,
  3023. iNumDstCols,
  3024. iDstScanLength,
  3025. iHorizMirror = 1,
  3026. iVertMirror = 1;
  3027. DWORD *pdSrcScanLine;
  3028. BYTE *pbDstScanLine;
  3029. // normalize orientation of source and destination rectangles, and
  3030. // compute sizes and relative orientations of source and destination rects
  3031. if ((iNumSrcCols = BLITLIB_RECTWIDTH(prcSrc)) < 0) {
  3032. iNumSrcCols = -iNumSrcCols;
  3033. FlipRectHorizontal(prcSrc);
  3034. FlipRectHorizontal(prcDst);
  3035. }
  3036. if ((iNumSrcRows = BLITLIB_RECTHEIGHT(prcSrc)) < 0) {
  3037. iNumSrcRows = -iNumSrcRows;
  3038. FlipRectVertical(prcSrc);
  3039. FlipRectVertical(prcDst);
  3040. }
  3041. if ((iNumDstCols = BLITLIB_RECTWIDTH(prcDst)) < 0) {
  3042. prcDst->left--;
  3043. prcDst->right--;
  3044. iNumDstCols = -iNumDstCols;
  3045. iHorizMirror = -1;
  3046. }
  3047. if ((iNumDstRows = BLITLIB_RECTHEIGHT(prcDst)) < 0) {
  3048. prcDst->top--;
  3049. prcDst->bottom--;
  3050. iNumDstRows = -iNumDstRows;
  3051. iVertMirror = -1;
  3052. }
  3053. // compute pointers to the starting rows in the src and dst bitmaps
  3054. // taking care to invert y values, since DIBs are upside-down
  3055. pdSrcScanLine = (DWORD*) pDibBitsSrc + prcSrc->top * (iSrcScanLength
  3056. = DibWidthBytes(pDibInfoSrc) / 4) + prcSrc->left;
  3057. pbDstScanLine = (BYTE*) pDibBitsDst + prcDst->top * (iDstScanLength
  3058. = DibWidthBytes(pDibInfoDst)) + prcDst->left;
  3059. // check if we're doing blending
  3060. if (arAlpha == ALPHA_INVALID) { // no blending desired
  3061. // check to see if we need to worry about transparency
  3062. if (crTransparent == CLR_INVALID) {
  3063. // check if we can do a straight copy from src row to dst row
  3064. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  3065. // check what ROP we'll be performing
  3066. if (dwRop == SRCCOPY) {
  3067. // check if we can do a straight copy vertically,
  3068. // or if we have to stretch, shrink, or mirror
  3069. if ((iNumSrcRows == iNumDstRows) && (iVertMirror == 1)) {
  3070. Blt24to08_NoBlend_NoTrans_Hcopy_SRCCOPY_Vcopy(pdSrcScanLine,iSrcScanLength,
  3071. pbDstScanLine,iDstScanLength,
  3072. iNumDstCols,iNumDstRows,(COLORREF*) pDibInfoDst->bmiColors,DibNumColors(&(pDibInfoDst->bmiHeader)));
  3073. } else {
  3074. Blt24to08_NoBlend_NoTrans_Hcopy_SRCCOPY_NoVcopy(pdSrcScanLine,iSrcScanLength,
  3075. iNumSrcRows,pbDstScanLine,
  3076. iDstScanLength * iVertMirror,
  3077. iNumDstCols,iNumDstRows,(COLORREF*) pDibInfoDst->bmiColors,DibNumColors(&(pDibInfoDst->bmiHeader)));
  3078. }
  3079. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  3080. } else {
  3081. // check what ROP we'll be performing
  3082. if (dwRop == SRCCOPY) {
  3083. Blt24to08_NoBlend_NoTrans_NoHcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength,
  3084. iNumSrcCols,iNumSrcRows,
  3085. pbDstScanLine,iDstScanLength * iVertMirror,
  3086. iNumDstCols,iNumDstRows,iHorizMirror,(COLORREF*) pDibInfoDst->bmiColors,DibNumColors(&(pDibInfoDst->bmiHeader)));
  3087. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  3088. }
  3089. } else {
  3090. // check if we can do a straight copy from src row to dst row
  3091. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  3092. // check what ROP we'll be performing
  3093. if (dwRop == SRCCOPY) {
  3094. Blt24to08_NoBlend_Trans_Hcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength,
  3095. iNumSrcRows,pbDstScanLine,
  3096. iDstScanLength * iVertMirror,
  3097. iNumDstCols,iNumDstRows,
  3098. crTransparent,(COLORREF*) pDibInfoDst->bmiColors,DibNumColors(&(pDibInfoDst->bmiHeader)));
  3099. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  3100. } else {
  3101. // check what ROP we'll be performing
  3102. if (dwRop == SRCCOPY) {
  3103. Blt24to08_NoBlend_Trans_NoHcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength,
  3104. iNumSrcCols,iNumSrcRows,
  3105. pbDstScanLine,iDstScanLength * iVertMirror,
  3106. iNumDstCols,iNumDstRows,iHorizMirror,
  3107. crTransparent,(COLORREF*) pDibInfoDst->bmiColors,DibNumColors(&(pDibInfoDst->bmiHeader)));
  3108. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  3109. }
  3110. }
  3111. } else { // blending desired
  3112. // if alpha value is zero, we do no work since the source bitmap
  3113. // contributes nothing to the destination bitmap
  3114. if (!(arAlpha & ALPHA_MASK)) {
  3115. return sc;
  3116. }
  3117. // check to see if we need to worry about transparency
  3118. if (crTransparent == CLR_INVALID) {
  3119. // check if we can do a straight copy from src row to dst row
  3120. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  3121. // check what ROP we'll be performing
  3122. if (dwRop == SRCCOPY) {
  3123. Blt24to08_Blend_NoTrans_Hcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength,
  3124. iNumSrcRows,pbDstScanLine,
  3125. iDstScanLength * iVertMirror,
  3126. iNumDstCols,iNumDstRows,
  3127. arAlpha,(COLORREF*) pDibInfoDst->bmiColors,DibNumColors(&(pDibInfoDst->bmiHeader)));
  3128. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  3129. } else {
  3130. // check what ROP we'll be performing
  3131. if (dwRop == SRCCOPY) {
  3132. Blt24to08_Blend_NoTrans_NoHcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength,
  3133. iNumSrcCols,iNumSrcRows,
  3134. pbDstScanLine,iDstScanLength * iVertMirror,
  3135. iNumDstCols,iNumDstRows,iHorizMirror,
  3136. arAlpha,(COLORREF*) pDibInfoDst->bmiColors,DibNumColors(&(pDibInfoDst->bmiHeader)));
  3137. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  3138. }
  3139. } else {
  3140. // check if we can do a straight copy from src row to dst row
  3141. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  3142. // check what ROP we'll be performing
  3143. if (dwRop == SRCCOPY) {
  3144. Blt24to08_Blend_Trans_Hcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength,
  3145. iNumSrcRows,pbDstScanLine,
  3146. iDstScanLength * iVertMirror,
  3147. iNumDstCols,iNumDstRows,
  3148. crTransparent,arAlpha,(COLORREF*) pDibInfoDst->bmiColors,DibNumColors(&(pDibInfoDst->bmiHeader)));
  3149. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  3150. } else {
  3151. // check what ROP we'll be performing
  3152. if (dwRop == SRCCOPY) {
  3153. Blt24to08_Blend_Trans_NoHcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength,
  3154. iNumSrcCols,iNumSrcRows,
  3155. pbDstScanLine,iDstScanLength * iVertMirror,
  3156. iNumDstCols,iNumDstRows,iHorizMirror,
  3157. crTransparent,arAlpha,(COLORREF*) pDibInfoDst->bmiColors,DibNumColors(&(pDibInfoDst->bmiHeader)));
  3158. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  3159. }
  3160. }
  3161. }
  3162. return sc;
  3163. }
  3164. ///////////////////////////////////////////////////////////////////////
  3165. //
  3166. // Private BlitLib_BitBlt24Pto08 -
  3167. // BitBlit from source bitmap to Dstination bitmap
  3168. // with optional transparency and/or alpha blending using the
  3169. // specified raster operation.
  3170. //
  3171. // Parameters:
  3172. // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB
  3173. // pDibBitsDst Pointer to the bits for the Destination DIB
  3174. // prcDst Pointer to the Destination rectangle
  3175. // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB
  3176. // pDibBitsSrc Pointer to the bits for the Source DIB
  3177. // prcSrc Pointer to the Source rectangle
  3178. // crTransparent Tranparent color value
  3179. // arAlpha Per-surface Alpha value
  3180. // dwRop Raster Operation for the blit
  3181. //
  3182. // Return Value:
  3183. // NO_ERROR or E_* value as specified in the .H file.
  3184. //
  3185. // Status: Incomplete
  3186. //
  3187. ///////////////////////////////////////////////////////////////////////
  3188. SCODE BlitLib_BitBlt24Pto08(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst,
  3189. PRECT prcDst, PDIBINFO pDibInfoSrc, PDIBBITS pDibBitsSrc,
  3190. PRECT prcSrc, COLORREF crTransparent, ALPHAREF arAlpha, DWORD dwRop)
  3191. {
  3192. SCODE sc = NOERROR;
  3193. int iNumSrcRows,
  3194. iNumSrcCols,
  3195. iSrcScanLength,
  3196. iNumDstRows,
  3197. iNumDstCols,
  3198. iDstScanLength,
  3199. iHorizMirror = 1,
  3200. iVertMirror = 1;
  3201. BYTE *pbSrcScanLine;
  3202. BYTE *pbDstScanLine;
  3203. // normalize orientation of source and destination rectangles, and
  3204. // compute sizes and relative orientations of source and destination rects
  3205. if ((iNumSrcCols = BLITLIB_RECTWIDTH(prcSrc)) < 0) {
  3206. iNumSrcCols = -iNumSrcCols;
  3207. FlipRectHorizontal(prcSrc);
  3208. FlipRectHorizontal(prcDst);
  3209. }
  3210. if ((iNumSrcRows = BLITLIB_RECTHEIGHT(prcSrc)) < 0) {
  3211. iNumSrcRows = -iNumSrcRows;
  3212. FlipRectVertical(prcSrc);
  3213. FlipRectVertical(prcDst);
  3214. }
  3215. if ((iNumDstCols = BLITLIB_RECTWIDTH(prcDst)) < 0) {
  3216. prcDst->left--;
  3217. prcDst->right--;
  3218. iNumDstCols = -iNumDstCols;
  3219. iHorizMirror = -1;
  3220. }
  3221. if ((iNumDstRows = BLITLIB_RECTHEIGHT(prcDst)) < 0) {
  3222. prcDst->top--;
  3223. prcDst->bottom--;
  3224. iNumDstRows = -iNumDstRows;
  3225. iVertMirror = -1;
  3226. }
  3227. // compute pointers to the starting rows in the src and dst bitmaps
  3228. // taking care to invert y values, since DIBs are upside-down
  3229. pbSrcScanLine = (BYTE*) pDibBitsSrc + prcSrc->top * (iSrcScanLength
  3230. = DibWidthBytes(pDibInfoSrc)) + (prcSrc->left * 3);
  3231. pbDstScanLine = (BYTE*) pDibBitsDst + prcDst->top * (iDstScanLength
  3232. = DibWidthBytes(pDibInfoDst)) + prcDst->left;
  3233. // check if we're doing blending
  3234. if (arAlpha == ALPHA_INVALID) { // no blending desired
  3235. // check to see if we need to worry about transparency
  3236. if (crTransparent == CLR_INVALID) {
  3237. // check if we can do a straight copy from src row to dst row
  3238. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  3239. // check what ROP we'll be performing
  3240. if (dwRop == SRCCOPY) {
  3241. // check if we can do a straight copy vertically,
  3242. // or if we have to stretch, shrink, or mirror
  3243. if ((iNumSrcRows == iNumDstRows) && (iVertMirror == 1)) {
  3244. Blt24Pto08_NoBlend_NoTrans_Hcopy_SRCCOPY_Vcopy(pbSrcScanLine,iSrcScanLength,
  3245. pbDstScanLine,iDstScanLength,
  3246. iNumDstCols,iNumDstRows,(COLORREF*) pDibInfoDst->bmiColors,DibNumColors(&(pDibInfoDst->bmiHeader)));
  3247. } else {
  3248. Blt24Pto08_NoBlend_NoTrans_Hcopy_SRCCOPY_NoVcopy(pbSrcScanLine,iSrcScanLength,
  3249. iNumSrcRows,pbDstScanLine,
  3250. iDstScanLength * iVertMirror,
  3251. iNumDstCols,iNumDstRows,(COLORREF*) pDibInfoDst->bmiColors,DibNumColors(&(pDibInfoDst->bmiHeader)));
  3252. }
  3253. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  3254. } else {
  3255. // check what ROP we'll be performing
  3256. if (dwRop == SRCCOPY) {
  3257. Blt24Pto08_NoBlend_NoTrans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength,
  3258. iNumSrcCols,iNumSrcRows,
  3259. pbDstScanLine,iDstScanLength * iVertMirror,
  3260. iNumDstCols,iNumDstRows,iHorizMirror,(COLORREF*) pDibInfoDst->bmiColors,DibNumColors(&(pDibInfoDst->bmiHeader)));
  3261. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  3262. }
  3263. } else {
  3264. // check if we can do a straight copy from src row to dst row
  3265. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  3266. // check what ROP we'll be performing
  3267. if (dwRop == SRCCOPY) {
  3268. Blt24Pto08_NoBlend_Trans_Hcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength,
  3269. iNumSrcRows,pbDstScanLine,
  3270. iDstScanLength * iVertMirror,
  3271. iNumDstCols,iNumDstRows,
  3272. crTransparent,(COLORREF*) pDibInfoDst->bmiColors,DibNumColors(&(pDibInfoDst->bmiHeader)));
  3273. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  3274. } else {
  3275. // check what ROP we'll be performing
  3276. if (dwRop == SRCCOPY) {
  3277. Blt24Pto08_NoBlend_Trans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength,
  3278. iNumSrcCols,iNumSrcRows,
  3279. pbDstScanLine,iDstScanLength * iVertMirror,
  3280. iNumDstCols,iNumDstRows,iHorizMirror,
  3281. crTransparent,(COLORREF*) pDibInfoDst->bmiColors,DibNumColors(&(pDibInfoDst->bmiHeader)));
  3282. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  3283. }
  3284. }
  3285. } else { // blending desired
  3286. // if alpha value is zero, we do no work since the source bitmap
  3287. // contributes nothing to the destination bitmap
  3288. if (!(arAlpha & ALPHA_MASK)) {
  3289. return sc;
  3290. }
  3291. // check to see if we need to worry about transparency
  3292. if (crTransparent == CLR_INVALID) {
  3293. // check if we can do a straight copy from src row to dst row
  3294. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  3295. // check what ROP we'll be performing
  3296. if (dwRop == SRCCOPY) {
  3297. Blt24Pto08_Blend_NoTrans_Hcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength,
  3298. iNumSrcRows,pbDstScanLine,
  3299. iDstScanLength * iVertMirror,
  3300. iNumDstCols,iNumDstRows,
  3301. arAlpha,(COLORREF*) pDibInfoDst->bmiColors,DibNumColors(&(pDibInfoDst->bmiHeader)));
  3302. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  3303. } else {
  3304. // check what ROP we'll be performing
  3305. if (dwRop == SRCCOPY) {
  3306. Blt24Pto08_Blend_NoTrans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength,
  3307. iNumSrcCols,iNumSrcRows,
  3308. pbDstScanLine,iDstScanLength * iVertMirror,
  3309. iNumDstCols,iNumDstRows,iHorizMirror,
  3310. arAlpha,(COLORREF*) pDibInfoDst->bmiColors,DibNumColors(&(pDibInfoDst->bmiHeader)));
  3311. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  3312. }
  3313. } else {
  3314. // check if we can do a straight copy from src row to dst row
  3315. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  3316. // check what ROP we'll be performing
  3317. if (dwRop == SRCCOPY) {
  3318. Blt24Pto08_Blend_Trans_Hcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength,
  3319. iNumSrcRows,pbDstScanLine,
  3320. iDstScanLength * iVertMirror,
  3321. iNumDstCols,iNumDstRows,
  3322. crTransparent,arAlpha,(COLORREF*) pDibInfoDst->bmiColors,DibNumColors(&(pDibInfoDst->bmiHeader)));
  3323. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  3324. } else {
  3325. // check what ROP we'll be performing
  3326. if (dwRop == SRCCOPY) {
  3327. Blt24Pto08_Blend_Trans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength,
  3328. iNumSrcCols,iNumSrcRows,
  3329. pbDstScanLine,iDstScanLength * iVertMirror,
  3330. iNumDstCols,iNumDstRows,iHorizMirror,
  3331. crTransparent,arAlpha,(COLORREF*) pDibInfoDst->bmiColors,DibNumColors(&(pDibInfoDst->bmiHeader)));
  3332. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  3333. }
  3334. }
  3335. }
  3336. return sc;
  3337. }
  3338. #endif // DDRAW
  3339. ///////////////////////////////////////////////////////////////////////
  3340. //
  3341. // Private BlitLib_BitBlt24to24 -
  3342. // BitBlit from source bitmap to Dstination bitmap
  3343. // with optional transparency and/or alpha blending using the
  3344. // specified raster operation.
  3345. //
  3346. // Parameters:
  3347. // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB
  3348. // pDibBitsDst Pointer to the bits for the Destination DIB
  3349. // prcDst Pointer to the Destination rectangle
  3350. // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB
  3351. // pDibBitsSrc Pointer to the bits for the Source DIB
  3352. // prcSrc Pointer to the Source rectangle
  3353. // crTransparent Tranparent color value
  3354. // arAlpha Per-surface Alpha value
  3355. // dwRop Raster Operation for the blit
  3356. //
  3357. // Return Value:
  3358. // NO_ERROR or E_* value as specified in the .H file.
  3359. //
  3360. // Status: Incomplete
  3361. //
  3362. ///////////////////////////////////////////////////////////////////////
  3363. SCODE BlitLib_BitBlt24to24(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst,
  3364. PRECT prcDst, PDIBINFO pDibInfoSrc, PDIBBITS pDibBitsSrc,
  3365. PRECT prcSrc, COLORREF crTransparent, ALPHAREF arAlpha, DWORD dwRop)
  3366. {
  3367. SCODE sc = NOERROR;
  3368. int iNumSrcRows,
  3369. iNumSrcCols,
  3370. iSrcScanLength,
  3371. iNumDstRows,
  3372. iNumDstCols,
  3373. iDstScanLength,
  3374. iHorizMirror = 1,
  3375. iVertMirror = 1;
  3376. DWORD *pdSrcScanLine,
  3377. *pdDstScanLine,
  3378. *pdTempScanLine;
  3379. PDIBBITS pDibBitsTemp;
  3380. if(dwRop != SRCCOPY)
  3381. return DDERR_INVALIDPARAMS;
  3382. // normalize orientation of source and destination rectangles, and compute sizes
  3383. // and relative orientations of source and destination rects
  3384. if ((iNumSrcCols = BLITLIB_RECTWIDTH(prcSrc)) < 0)
  3385. {
  3386. iNumSrcCols = -iNumSrcCols;
  3387. FlipRectHorizontal(prcSrc);
  3388. FlipRectHorizontal(prcDst);
  3389. }
  3390. if ((iNumSrcRows = BLITLIB_RECTHEIGHT(prcSrc)) < 0)
  3391. {
  3392. iNumSrcRows = -iNumSrcRows;
  3393. FlipRectVertical(prcSrc);
  3394. FlipRectVertical(prcDst);
  3395. }
  3396. if ((iNumDstCols = BLITLIB_RECTWIDTH(prcDst)) < 0)
  3397. {
  3398. prcDst->left--;
  3399. prcDst->right--;
  3400. iNumDstCols = -iNumDstCols;
  3401. iHorizMirror = -1;
  3402. }
  3403. if ((iNumDstRows = BLITLIB_RECTHEIGHT(prcDst)) < 0)
  3404. {
  3405. prcDst->top--;
  3406. prcDst->bottom--;
  3407. iNumDstRows = -iNumDstRows;
  3408. iVertMirror = -1;
  3409. }
  3410. // Handle intersecting blits in a completely unintelegent manner.
  3411. if(BlitLib_Detect_Intersection(pDibBitsDst, prcDst, pDibBitsSrc, prcSrc))
  3412. {
  3413. // Allocate memory for the cache bitmap -- We will blit into this
  3414. // temporary bitmap and then re-blit back to the original source
  3415. pDibBitsTemp = (PDIBBITS)osMemAlloc(DibSizeImage((LPBITMAPINFOHEADER)pDibInfoDst));
  3416. if(pDibBitsTemp == NULL)
  3417. return DDERR_OUTOFMEMORY;
  3418. // compute pointers to the starting rows in the src and temp bitmaps
  3419. pdSrcScanLine = (DWORD *) pDibBitsSrc + (prcSrc->top) * (iSrcScanLength
  3420. = DibWidthBytes(pDibInfoSrc)/4) + prcSrc->left;
  3421. pdTempScanLine = (DWORD *) pDibBitsTemp + (prcDst->top) * (iDstScanLength
  3422. = DibWidthBytes(pDibInfoDst)/4) + prcDst->left;
  3423. // check if we can do a straight copy from src row to dst row
  3424. if((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1))
  3425. {
  3426. // check if we can do a straight copy vertically,
  3427. // or if we have to stretch, shrink, or mirror
  3428. if ((iNumSrcRows == iNumDstRows) && (iVertMirror == 1))
  3429. {
  3430. Blt24to24_NoBlend_NoTrans_Hcopy_SRCCOPY_Vcopy(pdSrcScanLine,iSrcScanLength,
  3431. pdTempScanLine,iDstScanLength,
  3432. iNumDstCols,iNumDstRows);
  3433. }
  3434. else
  3435. {
  3436. Blt24to24_NoBlend_NoTrans_Hcopy_SRCCOPY_NoVcopy(pdSrcScanLine,iSrcScanLength,
  3437. iNumSrcRows,pdTempScanLine,
  3438. iDstScanLength * iVertMirror,
  3439. iNumDstCols,iNumDstRows);
  3440. }
  3441. }
  3442. else
  3443. {
  3444. Blt24to24_NoBlend_NoTrans_NoHcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength,
  3445. iNumSrcCols,iNumSrcRows,
  3446. pdTempScanLine,iDstScanLength * iVertMirror,
  3447. iNumDstCols,iNumDstRows,iHorizMirror);
  3448. }
  3449. // Recalculate the scan line pointers for the second blit
  3450. if(BLITLIB_RECTWIDTH(prcDst) < 0)
  3451. {
  3452. prcDst->left++;
  3453. prcDst->right++;
  3454. FlipRectHorizontal(prcDst);
  3455. }
  3456. if(BLITLIB_RECTHEIGHT(prcDst) < 0)
  3457. {
  3458. prcDst->top++;
  3459. prcDst->bottom++;
  3460. FlipRectVertical(prcDst);
  3461. }
  3462. // compute pointers to the starting rows in the temp and dest bitmaps
  3463. pdTempScanLine = (DWORD*) pDibBitsTemp + (prcDst->top) * (iDstScanLength
  3464. = DibWidthBytes(pDibInfoDst)/4) + prcDst->left;
  3465. pdDstScanLine = (DWORD*) pDibBitsDst + (prcDst->top) * (iDstScanLength
  3466. = DibWidthBytes(pDibInfoDst)/4) + prcDst->left;
  3467. // Now blit from the temporary bitmap back to the original source,
  3468. // checking for transparency if necessary
  3469. if(crTransparent == CLR_INVALID)
  3470. {
  3471. Blt24to24_NoBlend_NoTrans_Hcopy_SRCCOPY_Vcopy(pdTempScanLine,iDstScanLength,
  3472. pdDstScanLine,iDstScanLength,
  3473. iNumDstCols,iNumDstRows);
  3474. }
  3475. else
  3476. {
  3477. Blt24to24_NoBlend_Trans_Hcopy_SRCCOPY(pdTempScanLine,iDstScanLength,
  3478. iNumDstRows,pdDstScanLine,
  3479. iDstScanLength,
  3480. iNumDstCols,iNumDstRows,
  3481. crTransparent);
  3482. }
  3483. // Free the memory from the temporary bitmap
  3484. if(pDibBitsTemp)
  3485. {
  3486. osMemFree(pDibBitsTemp);
  3487. }
  3488. pDibBitsTemp = NULL;
  3489. return sc;
  3490. }
  3491. // compute pointers to the starting rows in the src and dst bitmaps
  3492. // taking care to invert y values, since DIBs are upside-down
  3493. pdSrcScanLine = (DWORD*) pDibBitsSrc + prcSrc->top * (iSrcScanLength
  3494. = DibWidthBytes(pDibInfoSrc) / 4) + prcSrc->left;
  3495. pdDstScanLine = (DWORD*) pDibBitsDst + prcDst->top * (iDstScanLength
  3496. = DibWidthBytes(pDibInfoDst) / 4) + prcDst->left;
  3497. // check if we're doing blending
  3498. if (arAlpha == ALPHA_INVALID)
  3499. { // no blending desired
  3500. // check to see if we need to worry about transparency
  3501. if (crTransparent == CLR_INVALID)
  3502. {
  3503. // check if we can do a straight copy from src row to dst row
  3504. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1))
  3505. {
  3506. // check what ROP we'll be performing
  3507. if (dwRop == SRCCOPY)
  3508. {
  3509. // check if we can do a straight copy vertically,
  3510. // or if we have to stretch, shrink, or mirror
  3511. if ((iNumSrcRows == iNumDstRows) && (iVertMirror == 1))
  3512. {
  3513. Blt24to24_NoBlend_NoTrans_Hcopy_SRCCOPY_Vcopy(pdSrcScanLine,iSrcScanLength,
  3514. pdDstScanLine,iDstScanLength,
  3515. iNumDstCols,iNumDstRows);
  3516. }
  3517. else // must stretch/mirror vertically
  3518. {
  3519. Blt24to24_NoBlend_NoTrans_Hcopy_SRCCOPY_NoVcopy(pdSrcScanLine,iSrcScanLength,
  3520. iNumSrcRows,pdDstScanLine,
  3521. iDstScanLength * iVertMirror,
  3522. iNumDstCols,iNumDstRows);
  3523. }
  3524. }
  3525. else // not SRCCOPY
  3526. sc |= E_UNEXPECTED; // !!!! we need better error codes
  3527. }
  3528. else // must stretch/mirror horizontally
  3529. {
  3530. // check what ROP we'll be performing
  3531. if (dwRop == SRCCOPY)
  3532. {
  3533. Blt24to24_NoBlend_NoTrans_NoHcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength,
  3534. iNumSrcCols,iNumSrcRows,
  3535. pdDstScanLine,iDstScanLength * iVertMirror,
  3536. iNumDstCols,iNumDstRows,iHorizMirror);
  3537. }
  3538. else // not SRCCOPY
  3539. sc |= E_UNEXPECTED; // !!!! we need better error codes
  3540. }
  3541. }
  3542. else // transparent blit
  3543. {
  3544. // check if we can do a straight copy from src row to dst row
  3545. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1))
  3546. {
  3547. // check what ROP we'll be performing
  3548. if (dwRop == SRCCOPY)
  3549. {
  3550. Blt24to24_NoBlend_Trans_Hcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength,
  3551. iNumSrcRows,pdDstScanLine,
  3552. iDstScanLength * iVertMirror,
  3553. iNumDstCols,iNumDstRows,
  3554. crTransparent);
  3555. }
  3556. else // not SRCCOPY
  3557. sc |= E_UNEXPECTED; // !!!! we need better error codes
  3558. }
  3559. else // must stretch/mirror horizontally
  3560. {
  3561. // check what ROP we'll be performing
  3562. if (dwRop == SRCCOPY)
  3563. {
  3564. Blt24to24_NoBlend_Trans_NoHcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength,
  3565. iNumSrcCols,iNumSrcRows,
  3566. pdDstScanLine,iDstScanLength * iVertMirror,
  3567. iNumDstCols,iNumDstRows,iHorizMirror,
  3568. crTransparent);
  3569. }
  3570. else // not srccopy
  3571. sc |= E_UNEXPECTED; // !!!! we need better error codes
  3572. }
  3573. }
  3574. }
  3575. else // blending desired
  3576. {
  3577. #ifdef DDRAW
  3578. return E_UNEXPECTED;
  3579. #else
  3580. // if alpha value is zero, we do no work since the source bitmap
  3581. // contributes nothing to the destination bitmap
  3582. if (!(arAlpha & ALPHA_MASK))
  3583. {
  3584. return sc;
  3585. }
  3586. // check to see if we need to worry about transparency
  3587. if (crTransparent == CLR_INVALID)
  3588. {
  3589. // check if we can do a straight copy from src row to dst row
  3590. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1))
  3591. {
  3592. // check what ROP we'll be performing
  3593. if (dwRop == SRCCOPY)
  3594. {
  3595. Blt24to24_Blend_NoTrans_Hcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength,
  3596. iNumSrcRows,pdDstScanLine,
  3597. iDstScanLength * iVertMirror,
  3598. iNumDstCols,iNumDstRows,
  3599. arAlpha);
  3600. }
  3601. else // not SRCCOPY
  3602. sc |= E_UNEXPECTED; // !!!! we need better error codes
  3603. }
  3604. else // must mirror/stretch horizontally
  3605. {
  3606. // check what ROP we'll be performing
  3607. if (dwRop == SRCCOPY)
  3608. {
  3609. Blt24to24_Blend_NoTrans_NoHcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength,
  3610. iNumSrcCols,iNumSrcRows,
  3611. pdDstScanLine,iDstScanLength * iVertMirror,
  3612. iNumDstCols,iNumDstRows,iHorizMirror,
  3613. arAlpha);
  3614. }
  3615. else // not SRCCOPY
  3616. sc |= E_UNEXPECTED; // !!!! we need better error codes
  3617. }
  3618. }
  3619. else // transparent blit
  3620. {
  3621. // check if we can do a straight copy from src row to dst row
  3622. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1))
  3623. {
  3624. // check what ROP we'll be performing
  3625. if (dwRop == SRCCOPY)
  3626. {
  3627. Blt24to24_Blend_Trans_Hcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength,
  3628. iNumSrcRows,pdDstScanLine,
  3629. iDstScanLength * iVertMirror,
  3630. iNumDstCols,iNumDstRows,
  3631. crTransparent,arAlpha);
  3632. }
  3633. else // not SRCCOPY
  3634. sc |= E_UNEXPECTED; // !!!! we need better error codes
  3635. }
  3636. else // must stretch/mirror horizontally
  3637. {
  3638. // check what ROP we'll be performing
  3639. if (dwRop == SRCCOPY)
  3640. {
  3641. Blt24to24_Blend_Trans_NoHcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength,
  3642. iNumSrcCols,iNumSrcRows,
  3643. pdDstScanLine,iDstScanLength * iVertMirror,
  3644. iNumDstCols,iNumDstRows,iHorizMirror,
  3645. crTransparent,arAlpha);
  3646. }
  3647. else // not SRCCOPY
  3648. sc |= E_UNEXPECTED; // !!!! we need better error codes
  3649. }
  3650. }
  3651. #endif /* !DDRAW */
  3652. }
  3653. return sc;
  3654. }
  3655. #ifndef DDRAW
  3656. ///////////////////////////////////////////////////////////////////////
  3657. //
  3658. // Private BlitLib_BitBlt24to24P -
  3659. // BitBlit from source bitmap to Dstination bitmap
  3660. // with optional transparency and/or alpha blending using the
  3661. // specified raster operation.
  3662. //
  3663. // Parameters:
  3664. // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB
  3665. // pDibBitsDst Pointer to the bits for the Destination DIB
  3666. // prcDst Pointer to the Destination rectangle
  3667. // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB
  3668. // pDibBitsSrc Pointer to the bits for the Source DIB
  3669. // prcSrc Pointer to the Source rectangle
  3670. // crTransparent Tranparent color value
  3671. // arAlpha Per-surface Alpha value
  3672. // dwRop Raster Operation for the blit
  3673. //
  3674. // Return Value:
  3675. // NO_ERROR or E_* value as specified in the .H file.
  3676. //
  3677. // Status: Incomplete
  3678. //
  3679. ///////////////////////////////////////////////////////////////////////
  3680. SCODE BlitLib_BitBlt24to24P(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst,
  3681. PRECT prcDst, PDIBINFO pDibInfoSrc, PDIBBITS pDibBitsSrc,
  3682. PRECT prcSrc, COLORREF crTransparent, ALPHAREF arAlpha, DWORD dwRop)
  3683. {
  3684. SCODE sc = NOERROR;
  3685. int iNumSrcRows,
  3686. iNumSrcCols,
  3687. iSrcScanLength,
  3688. iNumDstRows,
  3689. iNumDstCols,
  3690. iDstScanLength,
  3691. iHorizMirror = 1,
  3692. iVertMirror = 1;
  3693. DWORD *pdSrcScanLine;
  3694. BYTE *pdDstScanLine;
  3695. // normalize orientation of source and destination rectangles, and compute sizes
  3696. // and relative orientations of source and destination rects
  3697. if ((iNumSrcCols = BLITLIB_RECTWIDTH(prcSrc)) < 0) {
  3698. iNumSrcCols = -iNumSrcCols;
  3699. FlipRectHorizontal(prcSrc);
  3700. FlipRectHorizontal(prcDst);
  3701. }
  3702. if ((iNumSrcRows = BLITLIB_RECTHEIGHT(prcSrc)) < 0) {
  3703. iNumSrcRows = -iNumSrcRows;
  3704. FlipRectVertical(prcSrc);
  3705. FlipRectVertical(prcDst);
  3706. }
  3707. if ((iNumDstCols = BLITLIB_RECTWIDTH(prcDst)) < 0) {
  3708. prcDst->left--;
  3709. prcDst->right--;
  3710. iNumDstCols = -iNumDstCols;
  3711. iHorizMirror = -1;
  3712. }
  3713. if ((iNumDstRows = BLITLIB_RECTHEIGHT(prcDst)) < 0) {
  3714. prcDst->top--;
  3715. prcDst->bottom--;
  3716. iNumDstRows = -iNumDstRows;
  3717. iVertMirror = -1;
  3718. }
  3719. // compute pointers to the starting rows in the src and dst bitmaps
  3720. // taking care to invert y values, since DIBs are upside-down
  3721. pdSrcScanLine = (DWORD*) pDibBitsSrc + prcSrc->top * (iSrcScanLength
  3722. = DibWidthBytes(pDibInfoSrc) / 4) + prcSrc->left;
  3723. pdDstScanLine = (BYTE *) pDibBitsDst + prcDst->top * (iDstScanLength
  3724. = DibWidthBytes(pDibInfoDst)) + (prcDst->left * 3);
  3725. // check if we're doing blending
  3726. if (arAlpha == ALPHA_INVALID) { // no blending desired
  3727. // check to see if we need to worry about transparency
  3728. if (crTransparent == CLR_INVALID) {
  3729. // check if we can do a straight copy from src row to dst row
  3730. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  3731. // check what ROP we'll be performing
  3732. if (dwRop == SRCCOPY) {
  3733. // check if we can do a straight copy vertically,
  3734. // or if we have to stretch, shrink, or mirror
  3735. if ((iNumSrcRows == iNumDstRows) && (iVertMirror == 1)) {
  3736. Blt24to24P_NoBlend_NoTrans_Hcopy_SRCCOPY_Vcopy(pdSrcScanLine,iSrcScanLength,
  3737. pdDstScanLine,iDstScanLength,
  3738. iNumDstCols,iNumDstRows);
  3739. } else {
  3740. Blt24to24P_NoBlend_NoTrans_Hcopy_SRCCOPY_NoVcopy(pdSrcScanLine,iSrcScanLength,
  3741. iNumSrcRows,pdDstScanLine,
  3742. iDstScanLength * iVertMirror,
  3743. iNumDstCols,iNumDstRows);
  3744. }
  3745. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  3746. } else {
  3747. // check what ROP we'll be performing
  3748. if (dwRop == SRCCOPY) {
  3749. Blt24to24P_NoBlend_NoTrans_NoHcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength,
  3750. iNumSrcCols,iNumSrcRows,
  3751. pdDstScanLine,iDstScanLength * iVertMirror,
  3752. iNumDstCols,iNumDstRows,iHorizMirror);
  3753. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  3754. }
  3755. } else {
  3756. // check if we can do a straight copy from src row to dst row
  3757. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  3758. // check what ROP we'll be performing
  3759. if (dwRop == SRCCOPY) {
  3760. Blt24to24P_NoBlend_Trans_Hcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength,
  3761. iNumSrcRows,pdDstScanLine,
  3762. iDstScanLength * iVertMirror,
  3763. iNumDstCols,iNumDstRows,
  3764. crTransparent);
  3765. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  3766. } else {
  3767. // check what ROP we'll be performing
  3768. if (dwRop == SRCCOPY) {
  3769. Blt24to24P_NoBlend_Trans_NoHcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength,
  3770. iNumSrcCols,iNumSrcRows,
  3771. pdDstScanLine,iDstScanLength * iVertMirror,
  3772. iNumDstCols,iNumDstRows,iHorizMirror,
  3773. crTransparent);
  3774. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  3775. }
  3776. }
  3777. } else { // blending desired
  3778. // if alpha value is zero, we do no work since the source bitmap
  3779. // contributes nothing to the destination bitmap
  3780. if (!(arAlpha & ALPHA_MASK)) {
  3781. return sc;
  3782. }
  3783. // check to see if we need to worry about transparency
  3784. if (crTransparent == CLR_INVALID) {
  3785. // check if we can do a straight copy from src row to dst row
  3786. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  3787. // check what ROP we'll be performing
  3788. if (dwRop == SRCCOPY) {
  3789. Blt24to24P_Blend_NoTrans_Hcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength,
  3790. iNumSrcRows,pdDstScanLine,
  3791. iDstScanLength * iVertMirror,
  3792. iNumDstCols,iNumDstRows,
  3793. arAlpha);
  3794. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  3795. } else {
  3796. // check what ROP we'll be performing
  3797. if (dwRop == SRCCOPY) {
  3798. Blt24to24P_Blend_NoTrans_NoHcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength,
  3799. iNumSrcCols,iNumSrcRows,
  3800. pdDstScanLine,iDstScanLength * iVertMirror,
  3801. iNumDstCols,iNumDstRows,iHorizMirror,
  3802. arAlpha);
  3803. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  3804. }
  3805. } else {
  3806. // check if we can do a straight copy from src row to dst row
  3807. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  3808. // check what ROP we'll be performing
  3809. if (dwRop == SRCCOPY) {
  3810. Blt24to24P_Blend_Trans_Hcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength,
  3811. iNumSrcRows,pdDstScanLine,
  3812. iDstScanLength * iVertMirror,
  3813. iNumDstCols,iNumDstRows,
  3814. crTransparent,arAlpha);
  3815. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  3816. } else {
  3817. // check what ROP we'll be performing
  3818. if (dwRop == SRCCOPY) {
  3819. Blt24to24P_Blend_Trans_NoHcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength,
  3820. iNumSrcCols,iNumSrcRows,
  3821. pdDstScanLine,iDstScanLength * iVertMirror,
  3822. iNumDstCols,iNumDstRows,iHorizMirror,
  3823. crTransparent,arAlpha);
  3824. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  3825. }
  3826. }
  3827. }
  3828. return sc;
  3829. }
  3830. #endif // DDRAW
  3831. ///////////////////////////////////////////////////////////////////////
  3832. //
  3833. // Private BlitLib_BitBlt24Pto24P -
  3834. // BitBlit from source bitmap to Dstination bitmap
  3835. // with optional transparency and/or alpha blending using the
  3836. // specified raster operation.
  3837. //
  3838. // Parameters:
  3839. // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB
  3840. // pDibBitsDst Pointer to the bits for the Destination DIB
  3841. // prcDst Pointer to the Destination rectangle
  3842. // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB
  3843. // pDibBitsSrc Pointer to the bits for the Source DIB
  3844. // prcSrc Pointer to the Source rectangle
  3845. // crTransparent Tranparent color value
  3846. // arAlpha Per-surface Alpha value
  3847. // dwRop Raster Operation for the blit
  3848. //
  3849. // Return Value:
  3850. // NO_ERROR or E_* value as specified in the .H file.
  3851. //
  3852. // Status: Incomplete
  3853. //
  3854. ///////////////////////////////////////////////////////////////////////
  3855. SCODE BlitLib_BitBlt24Pto24P(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst,
  3856. PRECT prcDst, PDIBINFO pDibInfoSrc, PDIBBITS pDibBitsSrc,
  3857. PRECT prcSrc, COLORREF crTransparent, ALPHAREF arAlpha, DWORD dwRop)
  3858. {
  3859. SCODE sc = NOERROR;
  3860. int iNumSrcRows,
  3861. iNumSrcCols,
  3862. iSrcScanLength,
  3863. iNumDstRows,
  3864. iNumDstCols,
  3865. iDstScanLength,
  3866. iHorizMirror = 1,
  3867. iVertMirror = 1;
  3868. BYTE *pdSrcScanLine;
  3869. BYTE *pdDstScanLine;
  3870. // If the bitmaps overlap, we need to use overlapping code
  3871. if(BlitLib_Detect_Intersection(pDibBitsDst, prcDst, pDibBitsSrc, prcSrc))
  3872. return BlitLib_BitBlt24Pto24P_Intersect(pDibInfoDst, pDibBitsDst, prcDst,
  3873. pDibInfoSrc, pDibBitsSrc, prcSrc, crTransparent, arAlpha, dwRop);
  3874. // normalize orientation of source and destination rectangles, and compute sizes
  3875. // and relative orientations of source and destination rects
  3876. if ((iNumSrcCols = BLITLIB_RECTWIDTH(prcSrc)) < 0)
  3877. {
  3878. iNumSrcCols = -iNumSrcCols;
  3879. FlipRectHorizontal(prcSrc);
  3880. FlipRectHorizontal(prcDst);
  3881. }
  3882. if ((iNumSrcRows = BLITLIB_RECTHEIGHT(prcSrc)) < 0)
  3883. {
  3884. iNumSrcRows = -iNumSrcRows;
  3885. FlipRectVertical(prcSrc);
  3886. FlipRectVertical(prcDst);
  3887. }
  3888. if ((iNumDstCols = BLITLIB_RECTWIDTH(prcDst)) < 0)
  3889. {
  3890. prcDst->left--;
  3891. prcDst->right--;
  3892. iNumDstCols = -iNumDstCols;
  3893. iHorizMirror = -1;
  3894. }
  3895. if ((iNumDstRows = BLITLIB_RECTHEIGHT(prcDst)) < 0)
  3896. {
  3897. prcDst->top--;
  3898. prcDst->bottom--;
  3899. iNumDstRows = -iNumDstRows;
  3900. iVertMirror = -1;
  3901. }
  3902. // compute pointers to the starting rows in the src and dst bitmaps
  3903. // taking care to invert y values, since DIBs are upside-down
  3904. pdSrcScanLine = (BYTE*) pDibBitsSrc + prcSrc->top * (iSrcScanLength
  3905. = DibWidthBytes(pDibInfoSrc)) + (prcSrc->left * 3);
  3906. pdDstScanLine = (BYTE *) pDibBitsDst + prcDst->top * (iDstScanLength
  3907. = DibWidthBytes(pDibInfoDst)) + (prcDst->left * 3);
  3908. // check if we're doing blending
  3909. if (arAlpha == ALPHA_INVALID)
  3910. { // no blending desired
  3911. // check to see if we need to worry about transparency
  3912. if (crTransparent == CLR_INVALID)
  3913. {
  3914. // check if we can do a straight copy from src row to dst row
  3915. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1))
  3916. {
  3917. // check what ROP we'll be performing
  3918. if (dwRop == SRCCOPY)
  3919. {
  3920. // check if we can do a straight copy vertically,
  3921. // or if we have to stretch, shrink, or mirror
  3922. if ((iNumSrcRows == iNumDstRows) && (iVertMirror == 1))
  3923. {
  3924. // This is the 8->8 blit with 3 times as many columns
  3925. Blt08to08_NoTrans_Hcopy_SRCCOPY_Vcopy(pdSrcScanLine,iSrcScanLength,
  3926. pdDstScanLine,iDstScanLength,
  3927. iNumDstCols * 3,iNumDstRows);
  3928. }
  3929. else // must stretch/mirror vertically
  3930. {
  3931. Blt24Pto24P_NoBlend_NoTrans_Hcopy_SRCCOPY_NoVcopy(pdSrcScanLine,iSrcScanLength,
  3932. iNumSrcRows,pdDstScanLine,
  3933. iDstScanLength * iVertMirror,
  3934. iNumDstCols,iNumDstRows);
  3935. }
  3936. }
  3937. else // not SRCCOPY
  3938. sc |= E_UNEXPECTED; // non-SRCCOPY unsupported!!!! we need better error codes
  3939. }
  3940. else // must stretch/mirror horizontally (and maybe vertically)
  3941. {
  3942. if (dwRop == SRCCOPY)
  3943. {
  3944. Blt24Pto24P_NoBlend_NoTrans_NoHcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength,
  3945. iNumSrcCols,iNumSrcRows,
  3946. pdDstScanLine,iDstScanLength * iVertMirror,
  3947. iNumDstCols,iNumDstRows,iHorizMirror);
  3948. }
  3949. else
  3950. sc |= E_UNEXPECTED; // !!!! we need better error codes
  3951. }
  3952. }
  3953. else // Transparent blt
  3954. {
  3955. // check if we can do a straight copy from src row to dst row
  3956. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1))
  3957. {
  3958. // check what ROP we'll be performing
  3959. if (dwRop == SRCCOPY)
  3960. {
  3961. // check if we can do a straight copy vertically,
  3962. // or if we have to stretch, shrink, or mirror
  3963. if ((iNumSrcRows == iNumDstRows) && (iVertMirror == 1))
  3964. {
  3965. Blt24Pto24P_NoBlend_Trans_Hcopy_SRCCOPY_VCopy(pdSrcScanLine,iSrcScanLength,
  3966. pdDstScanLine,iDstScanLength,
  3967. iNumDstCols,iNumDstRows,
  3968. crTransparent);
  3969. }
  3970. else // must stretch/mirror vertically
  3971. {
  3972. Blt24Pto24P_NoBlend_Trans_Hcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength,
  3973. iNumSrcRows,
  3974. pdDstScanLine,iDstScanLength * iVertMirror,
  3975. iNumDstCols,iNumDstRows,
  3976. crTransparent);
  3977. }
  3978. }
  3979. else // not SRCCOPY
  3980. sc |= E_UNEXPECTED; // !!!! we need better error codes
  3981. }
  3982. else // must stretch/mirror horizontally and maybe vertically
  3983. {
  3984. // check what ROP we'll be performing
  3985. if (dwRop == SRCCOPY)
  3986. {
  3987. Blt24Pto24P_NoBlend_Trans_NoHcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength,
  3988. iNumSrcCols,iNumSrcRows,
  3989. pdDstScanLine,iDstScanLength * iVertMirror,
  3990. iNumDstCols,iNumDstRows,iHorizMirror,
  3991. crTransparent);
  3992. }
  3993. else // not SRCCOPY
  3994. sc |= E_UNEXPECTED; // !!!! we need better error codes
  3995. }
  3996. }
  3997. }
  3998. else // blending desired
  3999. {
  4000. #ifdef DDRAW
  4001. return E_UNEXPECTED;
  4002. #else
  4003. // if alpha value is zero, we do no work since the source bitmap
  4004. // contributes nothing to the destination bitmap
  4005. if (!(arAlpha & ALPHA_MASK))
  4006. {
  4007. return sc;
  4008. }
  4009. // check to see if we need to worry about transparency
  4010. if (crTransparent == CLR_INVALID)
  4011. {
  4012. // check if we can do a straight copy from src row to dst row
  4013. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1))
  4014. {
  4015. // check what ROP we'll be performing
  4016. if (dwRop == SRCCOPY)
  4017. {
  4018. // check if we can do a straight copy vertically,
  4019. // or if we have to stretch, shrink, or mirror
  4020. if ((iNumSrcRows == iNumDstRows) && (iVertMirror == 1))
  4021. {
  4022. Blt24Pto24P_Blend_NoTrans_Hcopy_SRCCOPY_VCopy(pdSrcScanLine,iSrcScanLength,
  4023. pdDstScanLine,iDstScanLength,
  4024. iNumDstCols,iNumDstRows,
  4025. arAlpha);
  4026. }
  4027. else // must stretch/mirror vertically
  4028. {
  4029. sc |= E_UNEXPECTED; // !!!! we need better error codes
  4030. }
  4031. }
  4032. else // not SRCCOPY
  4033. sc |= E_UNEXPECTED; // !!!! we need better error codes
  4034. }
  4035. else // must mirror/stretch horizontally
  4036. {
  4037. sc |= E_UNEXPECTED; // !!!! we need better error codes
  4038. }
  4039. }
  4040. else // transparent blit
  4041. {
  4042. // check if we can do a straight copy from src row to dst row
  4043. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1))
  4044. {
  4045. // check what ROP we'll be performing
  4046. if (dwRop == SRCCOPY)
  4047. {
  4048. // check if we can do a straight copy vertically,
  4049. // or if we have to stretch, shrink, or mirror
  4050. if ((iNumSrcRows == iNumDstRows) && (iVertMirror == 1))
  4051. {
  4052. Blt24Pto24P_Blend_Trans_Hcopy_SRCCOPY_VCopy(pdSrcScanLine,iSrcScanLength,
  4053. pdDstScanLine,iDstScanLength,
  4054. iNumDstCols,iNumDstRows,
  4055. crTransparent,arAlpha);
  4056. }
  4057. else // must stretch/mirror vertically
  4058. {
  4059. sc |= E_UNEXPECTED; // !!!! we need better error codes
  4060. }
  4061. }
  4062. else // not SRCCOPY
  4063. sc |= E_UNEXPECTED; // !!!! we need better error codes
  4064. }
  4065. else // must stretch/mirror horizontally
  4066. {
  4067. sc |= E_UNEXPECTED; // !!!! we need better error codes
  4068. }
  4069. }
  4070. #endif
  4071. }
  4072. return sc;
  4073. }
  4074. ///////////////////////////////////////////////////////////////////////
  4075. //
  4076. // Private BlitLib_BitBlt24Pto24P_Intersect -
  4077. // BitBlit from source bitmap to destination bitmap (and these
  4078. // bitmaps overlap each other) with optional transparency and/or
  4079. // alpha blending using the specified raster operation.
  4080. //
  4081. // Parameters:
  4082. // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB
  4083. // pDibBitsDst Pointer to the bits for the Destination DIB
  4084. // prcDst Pointer to the Destination rectangle
  4085. // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB
  4086. // pDibBitsSrc Pointer to the bits for the Source DIB
  4087. // prcSrc Pointer to the Source rectangle
  4088. // crTransparent Tranparent color value
  4089. // arAlpha Per-surface Alpha value
  4090. // dwRop Raster Operation for the blit
  4091. //
  4092. // Return Value:
  4093. // NO_ERROR or E_* value as specified in the .H file.
  4094. //
  4095. // Status: Incomplete
  4096. //
  4097. ///////////////////////////////////////////////////////////////////////
  4098. SCODE BlitLib_BitBlt24Pto24P_Intersect(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst,
  4099. PRECT prcDst, PDIBINFO pDibInfoSrc, PDIBBITS pDibBitsSrc, PRECT prcSrc,
  4100. COLORREF crTransparent, ALPHAREF arAlpha, DWORD dwRop)
  4101. {
  4102. SCODE sc = NOERROR;
  4103. int iNumSrcRows,
  4104. iNumSrcCols,
  4105. iSrcScanLength,
  4106. iNumDstRows,
  4107. iNumDstCols,
  4108. iDstScanLength,
  4109. iHorizMirror = 1,
  4110. iVertMirror = 1;
  4111. BYTE *pbSrcScanLine,
  4112. *pbDstScanLine,
  4113. *pbTempScanLine;
  4114. PDIBBITS pDibBitsTemp;
  4115. // normalize orientation of source and destination rectangles, and
  4116. // compute sizes and relative orientations of source and destination rects
  4117. if ((iNumSrcCols = BLITLIB_RECTWIDTH(prcSrc)) < 0)
  4118. {
  4119. iNumSrcCols = -iNumSrcCols;
  4120. FlipRectHorizontal(prcSrc);
  4121. FlipRectHorizontal(prcDst);
  4122. }
  4123. if ((iNumSrcRows = BLITLIB_RECTHEIGHT(prcSrc)) < 0)
  4124. {
  4125. iNumSrcRows = -iNumSrcRows;
  4126. FlipRectVertical(prcSrc);
  4127. FlipRectVertical(prcDst);
  4128. }
  4129. if ((iNumDstCols = BLITLIB_RECTWIDTH(prcDst)) < 0)
  4130. {
  4131. prcDst->left--;
  4132. prcDst->right--;
  4133. iNumDstCols = -iNumDstCols;
  4134. iHorizMirror = -1;
  4135. }
  4136. if ((iNumDstRows = BLITLIB_RECTHEIGHT(prcDst)) < 0)
  4137. {
  4138. prcDst->top--;
  4139. prcDst->bottom--;
  4140. iNumDstRows = -iNumDstRows;
  4141. iVertMirror = -1;
  4142. }
  4143. // We aren't currently support any ROP's besides SRCCOPY
  4144. if(dwRop != SRCCOPY)
  4145. return E_UNEXPECTED;
  4146. //
  4147. // Here are all the stretching and mirroring blits for overlapping rects
  4148. //
  4149. // REVIEW!!! -- The following code could be optimized for the caching
  4150. // cases. Currently, it allocates a second bitmap that is the same
  4151. // size as the original destination, and then uses the original blit
  4152. // rectangle to do the caching. To save space, this blit should
  4153. // eventually be changed to only allocate the size of the overlapped
  4154. // rectangle, and the blit rects should be adjusted accordingly.
  4155. // Check if we are stretching (horiz or vert), or if we are mirroring --
  4156. // In all of these cases, we must create a cache bitmap and double blit
  4157. if((iNumDstCols != iNumSrcCols) || (iNumDstRows != iNumSrcRows) ||
  4158. (iHorizMirror != 1) || (iVertMirror != 1))
  4159. {
  4160. // Allocate memory for the cache bitmap -- We will blit into this
  4161. // temporary bitmap and then re-blit back to the original source
  4162. pDibBitsTemp = (PDIBBITS)osMemAlloc(DibSizeImage((LPBITMAPINFOHEADER)pDibInfoDst));
  4163. if(pDibBitsTemp == NULL)
  4164. return DDERR_OUTOFMEMORY;
  4165. // compute pointers to the starting rows in the src and temp bitmaps
  4166. pbSrcScanLine = (BYTE *) pDibBitsSrc + (prcSrc->top) * (iSrcScanLength
  4167. = DibWidthBytes(pDibInfoSrc)) + prcSrc->left*3;
  4168. pbTempScanLine = (BYTE *) pDibBitsTemp + (prcDst->top) * (iDstScanLength
  4169. = DibWidthBytes(pDibInfoDst)) + prcDst->left*3;
  4170. // check if we can do a straight copy from src row to dst row
  4171. if((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1))
  4172. {
  4173. // check if we can do a straight copy vertically,
  4174. // or if we have to stretch, shrink, or mirror
  4175. if ((iNumSrcRows == iNumDstRows) && (iVertMirror == 1))
  4176. {
  4177. Blt08to08_NoTrans_Hcopy_SRCCOPY_Vcopy(pbSrcScanLine,iSrcScanLength,
  4178. pbTempScanLine,iDstScanLength,
  4179. iNumDstCols*3,iNumDstRows);
  4180. }
  4181. else
  4182. {
  4183. Blt24Pto24P_NoBlend_NoTrans_Hcopy_SRCCOPY_NoVcopy(pbSrcScanLine,iSrcScanLength,
  4184. iNumSrcRows,pbTempScanLine,
  4185. iDstScanLength * iVertMirror,
  4186. iNumDstCols,iNumDstRows);
  4187. }
  4188. }
  4189. else
  4190. {
  4191. Blt24Pto24P_NoBlend_NoTrans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength,
  4192. iNumSrcCols,iNumSrcRows,
  4193. pbTempScanLine,iDstScanLength * iVertMirror,
  4194. iNumDstCols,iNumDstRows,iHorizMirror);
  4195. }
  4196. // Recalculate the scan line pointers for the second blit
  4197. if(BLITLIB_RECTWIDTH(prcDst) < 0)
  4198. {
  4199. prcDst->left++;
  4200. prcDst->right++;
  4201. FlipRectHorizontal(prcDst);
  4202. }
  4203. if(BLITLIB_RECTHEIGHT(prcDst) < 0)
  4204. {
  4205. prcDst->top++;
  4206. prcDst->bottom++;
  4207. FlipRectVertical(prcDst);
  4208. }
  4209. // compute pointers to the starting rows in the temp and dest bitmaps
  4210. pbTempScanLine = (BYTE*) pDibBitsTemp + (prcDst->top) * (iDstScanLength
  4211. = DibWidthBytes(pDibInfoDst)) + prcDst->left*3;
  4212. pbDstScanLine = (BYTE*) pDibBitsDst + (prcDst->top) * (iDstScanLength
  4213. = DibWidthBytes(pDibInfoDst)) + prcDst->left*3;
  4214. // Now blit from the temporary bitmap back to the original source,
  4215. // checking for transparency if necessary
  4216. if(crTransparent == CLR_INVALID)
  4217. {
  4218. Blt08to08_NoTrans_Hcopy_SRCCOPY_Vcopy(pbTempScanLine,iDstScanLength,
  4219. pbDstScanLine,iDstScanLength,
  4220. 3*iNumDstCols,iNumDstRows);
  4221. }
  4222. else
  4223. {
  4224. Blt24Pto24P_NoBlend_Trans_Hcopy_SRCCOPY(pbTempScanLine,iDstScanLength,
  4225. iNumDstRows,pbDstScanLine,
  4226. iDstScanLength, iNumDstCols,
  4227. iNumDstRows, crTransparent);
  4228. }
  4229. // Free the memory from the temporary bitmap
  4230. if(pDibBitsTemp)
  4231. {
  4232. osMemFree(pDibBitsTemp);
  4233. }
  4234. pDibBitsTemp = NULL;
  4235. return sc;
  4236. }
  4237. //
  4238. // Here are all the non-stretching and non-mirroring blits for overlapping rects
  4239. //
  4240. // check if we're doing blending
  4241. if (arAlpha == ALPHA_INVALID)
  4242. { // no blending desired
  4243. // check to see if we need to worry about transparency
  4244. if (crTransparent == CLR_INVALID)
  4245. {
  4246. // Simplest case, they are the same rectangles
  4247. if((prcDst->left == prcSrc->left) && (prcDst->top == prcSrc->top) &&
  4248. (prcDst->right == prcSrc->right) && (prcDst->bottom == prcSrc->bottom))
  4249. return sc;
  4250. // Next case, the destination rectangle is vertically greater in
  4251. // magnitude than the source rectangle
  4252. else if(prcDst->top > prcSrc->top)
  4253. {
  4254. // compute pointers to the starting rows in the src and dst bitmaps
  4255. // taking care to decrement the bottom rect edge since we are
  4256. // going from bottom to top
  4257. pbSrcScanLine = (BYTE*) pDibBitsSrc + (prcSrc->bottom - 1) * (iSrcScanLength
  4258. = DibWidthBytes(pDibInfoSrc)) + (prcSrc->left * 3);
  4259. pbDstScanLine = (BYTE*) pDibBitsDst + (prcDst->bottom - 1) * (iDstScanLength
  4260. = DibWidthBytes(pDibInfoDst)) + (prcDst->left * 3);
  4261. // Call the appropriate blit
  4262. Blt08to08_LeftToRight_BottomToTop_SRCCOPY(pbSrcScanLine,
  4263. iSrcScanLength, pbDstScanLine, iDstScanLength, iNumDstCols * 3,
  4264. iNumDstRows);
  4265. }
  4266. // Next case, the destination rectangle is horizontally less than
  4267. // or equal in magnitude to the source rectangle
  4268. else if(prcDst->left <= prcSrc->left)
  4269. {
  4270. // compute pointers to the starting rows in the src and dst bitmaps
  4271. pbSrcScanLine = (BYTE*) pDibBitsSrc + (prcSrc->top) * (iSrcScanLength
  4272. = DibWidthBytes(pDibInfoSrc)) + (prcSrc->left * 3);
  4273. pbDstScanLine = (BYTE*) pDibBitsDst + (prcDst->top) * (iDstScanLength
  4274. = DibWidthBytes(pDibInfoDst)) + (prcDst->left * 3);
  4275. // Call the appropriate blit
  4276. Blt08to08_NoTrans_Hcopy_SRCCOPY_Vcopy(pbSrcScanLine,iSrcScanLength,
  4277. pbDstScanLine,iDstScanLength,
  4278. iNumDstCols * 3,iNumDstRows);
  4279. }
  4280. // Last case, the destination rectangle is horizontally greater
  4281. // in magnitude than the source rectangle
  4282. else
  4283. {
  4284. // compute pointers to the starting rows in the src and dst bitmaps
  4285. // taking care to decrement the right rect edge since we are
  4286. // going from right to left
  4287. pbSrcScanLine = (BYTE*) pDibBitsSrc + (prcSrc->top) * (iSrcScanLength
  4288. = DibWidthBytes(pDibInfoSrc)) + (((prcSrc->right - 1) * 3) + 2);
  4289. pbDstScanLine = (BYTE*) pDibBitsDst + (prcDst->top) * (iDstScanLength
  4290. = DibWidthBytes(pDibInfoDst)) + (((prcDst->right - 1) * 3) + 2);
  4291. // Call the appropriate blit
  4292. Blt08to08_RightToLeft_TopToBottom_SRCCOPY(pbSrcScanLine,
  4293. iSrcScanLength, pbDstScanLine, iDstScanLength, iNumDstCols * 3,
  4294. iNumDstRows);
  4295. }
  4296. }
  4297. else // transparent blt
  4298. {
  4299. // Simplest case, they are the same rectangles
  4300. if((prcDst->left == prcSrc->left) && (prcDst->top == prcSrc->top) &&
  4301. (prcDst->right == prcSrc->right) && (prcDst->bottom == prcSrc->bottom))
  4302. return sc;
  4303. // Next case, the destination rectangle is vertically greater in
  4304. // magnitude than the source rectangle
  4305. else if(prcDst->top > prcSrc->top)
  4306. {
  4307. // compute pointers to the starting rows in the src and dst bitmaps
  4308. // taking care to decrement the bottom rect edge since we are
  4309. // going from bottom to top
  4310. pbSrcScanLine = (BYTE*) pDibBitsSrc + (prcSrc->bottom - 1) * (iSrcScanLength
  4311. = DibWidthBytes(pDibInfoSrc)) + (prcSrc->left * 3);
  4312. pbDstScanLine = (BYTE*) pDibBitsDst + (prcDst->bottom - 1) * (iDstScanLength
  4313. = DibWidthBytes(pDibInfoDst)) + (prcDst->left * 3);
  4314. // Call the appropriate blit
  4315. Blt24Pto24P_LeftToRight_BottomToTop_Trans_SRCCOPY(pbSrcScanLine,
  4316. iSrcScanLength, pbDstScanLine, iDstScanLength, iNumDstCols,
  4317. iNumDstRows, crTransparent);
  4318. }
  4319. // Next case, the destination rectangle is horizontally less than
  4320. // or equal in magnitude to the source rectangle
  4321. else if(prcDst->left <= prcSrc->left)
  4322. {
  4323. // compute pointers to the starting rows in the src and dst bitmaps
  4324. pbSrcScanLine = (BYTE*) pDibBitsSrc + (prcSrc->top) * (iSrcScanLength
  4325. = DibWidthBytes(pDibInfoSrc)) + (prcSrc->left * 3);
  4326. pbDstScanLine = (BYTE*) pDibBitsDst + (prcDst->top) * (iDstScanLength
  4327. = DibWidthBytes(pDibInfoDst)) + (prcDst->left * 3);
  4328. // Call the appropriate blit
  4329. Blt24Pto24P_NoBlend_Trans_Hcopy_SRCCOPY_VCopy(pbSrcScanLine,iSrcScanLength,
  4330. pbDstScanLine,
  4331. iDstScanLength, iNumDstCols,
  4332. iNumDstRows, crTransparent);
  4333. }
  4334. // Last case, the destination rectangle is horizontally greater
  4335. // in magnitude than the source rectangle
  4336. else
  4337. {
  4338. // compute pointers to the starting rows in the src and dst bitmaps
  4339. // taking care to decrement the right rect edge since we are
  4340. // going from right to left
  4341. pbSrcScanLine = (BYTE*) pDibBitsSrc + (prcSrc->top) * (iSrcScanLength
  4342. = DibWidthBytes(pDibInfoSrc)) + ((prcSrc->right - 1) * 3);
  4343. pbDstScanLine = (BYTE*) pDibBitsDst + (prcDst->top) * (iDstScanLength
  4344. = DibWidthBytes(pDibInfoDst)) + ((prcDst->right - 1) * 3);
  4345. // Call the appropriate blit
  4346. Blt24Pto24P_RightToLeft_TopToBottom_Trans_SRCCOPY(pbSrcScanLine,
  4347. iSrcScanLength, pbDstScanLine, iDstScanLength, iNumDstCols,
  4348. iNumDstRows, crTransparent);
  4349. }
  4350. }
  4351. }
  4352. else
  4353. { // We're doing alpha blending
  4354. #ifdef DDRAW
  4355. return E_UNEXPECTED;
  4356. #else
  4357. // check to see if we need to worry about transparency
  4358. if (crTransparent == CLR_INVALID)
  4359. {
  4360. // Simplest case, they are the same rectangles
  4361. if((prcDst->left == prcSrc->left) && (prcDst->top == prcSrc->top) &&
  4362. (prcDst->right == prcSrc->right) && (prcDst->bottom == prcSrc->bottom))
  4363. return sc;
  4364. // Next case, the destination rectangle is vertically greater in
  4365. // magnitude than the source rectangle
  4366. else if(prcDst->top > prcSrc->top)
  4367. {
  4368. // compute pointers to the starting rows in the src and dst bitmaps
  4369. // taking care to decrement the bottom rect edge since we are
  4370. // going from bottom to top
  4371. pbSrcScanLine = (BYTE*) pDibBitsSrc + (prcSrc->bottom - 1) * (iSrcScanLength
  4372. = DibWidthBytes(pDibInfoSrc)) + (prcSrc->left * 3);
  4373. pbDstScanLine = (BYTE*) pDibBitsDst + (prcDst->bottom - 1) * (iDstScanLength
  4374. = DibWidthBytes(pDibInfoDst)) + (prcDst->left * 3);
  4375. // Call the appropriate blit
  4376. Blt24Pto24P_LeftToRight_BottomToTop_Alpha_SRCCOPY(pbSrcScanLine,
  4377. iSrcScanLength, pbDstScanLine, iDstScanLength, iNumDstCols,
  4378. iNumDstRows, arAlpha);
  4379. }
  4380. // Next case, the destination rectangle is horizontally less than
  4381. // or equal in magnitude to the source rectangle
  4382. else if(prcDst->left <= prcSrc->left)
  4383. {
  4384. // compute pointers to the starting rows in the src and dst bitmaps
  4385. pbSrcScanLine = (BYTE*) pDibBitsSrc + (prcSrc->top) * (iSrcScanLength
  4386. = DibWidthBytes(pDibInfoSrc)) + (prcSrc->left * 3);
  4387. pbDstScanLine = (BYTE*) pDibBitsDst + (prcDst->top) * (iDstScanLength
  4388. = DibWidthBytes(pDibInfoDst)) + (prcDst->left * 3);
  4389. // Call the appropriate blit
  4390. Blt24Pto24P_Blend_NoTrans_Hcopy_SRCCOPY_VCopy(pbSrcScanLine,iSrcScanLength,
  4391. pbDstScanLine,iDstScanLength,
  4392. iNumDstCols,iNumDstRows,arAlpha);
  4393. }
  4394. // Last case, the destination rectangle is horizontally greater
  4395. // in magnitude than the source rectangle
  4396. else
  4397. {
  4398. // compute pointers to the starting rows in the src and dst bitmaps
  4399. // taking care to decrement the right rect edge since we are
  4400. // going from right to left
  4401. pbSrcScanLine = (BYTE*) pDibBitsSrc + (prcSrc->top) * (iSrcScanLength
  4402. = DibWidthBytes(pDibInfoSrc)) + ((prcSrc->right - 1) * 3);
  4403. pbDstScanLine = (BYTE*) pDibBitsDst + (prcDst->top) * (iDstScanLength
  4404. = DibWidthBytes(pDibInfoDst)) + ((prcDst->right - 1) * 3);
  4405. // Call the appropriate blit
  4406. Blt24Pto24P_RightToLeft_TopToBottom_Alpha_SRCCOPY(pbSrcScanLine,
  4407. iSrcScanLength, pbDstScanLine, iDstScanLength, iNumDstCols,
  4408. iNumDstRows, arAlpha);
  4409. }
  4410. }
  4411. else
  4412. {
  4413. // Simplest case, they are the same rectangles
  4414. if((prcDst->left == prcSrc->left) && (prcDst->top == prcSrc->top) &&
  4415. (prcDst->right == prcSrc->right) && (prcDst->bottom == prcSrc->bottom))
  4416. return sc;
  4417. // Next case, the destination rectangle is vertically greater in
  4418. // magnitude than the source rectangle
  4419. else if(prcDst->top > prcSrc->top)
  4420. {
  4421. // compute pointers to the starting rows in the src and dst bitmaps
  4422. // taking care to decrement the bottom rect edge since we are
  4423. // going from bottom to top
  4424. pbSrcScanLine = (BYTE*) pDibBitsSrc + (prcSrc->bottom - 1) * (iSrcScanLength
  4425. = DibWidthBytes(pDibInfoSrc)) + (prcSrc->left * 3);
  4426. pbDstScanLine = (BYTE*) pDibBitsDst + (prcDst->bottom - 1) * (iDstScanLength
  4427. = DibWidthBytes(pDibInfoDst)) + (prcDst->left * 3);
  4428. // Call the appropriate blit
  4429. Blt24Pto24P_LeftToRight_BottomToTop_Trans_Alpha_SRCCOPY(pbSrcScanLine,
  4430. iSrcScanLength, pbDstScanLine, iDstScanLength, iNumDstCols,
  4431. iNumDstRows, crTransparent, arAlpha);
  4432. }
  4433. // Next case, the destination rectangle is horizontally less than
  4434. // or equal in magnitude to the source rectangle
  4435. else if(prcDst->left <= prcSrc->left)
  4436. {
  4437. // compute pointers to the starting rows in the src and dst bitmaps
  4438. pbSrcScanLine = (BYTE*) pDibBitsSrc + (prcSrc->top) * (iSrcScanLength
  4439. = DibWidthBytes(pDibInfoSrc)) + (prcSrc->left * 3);
  4440. pbDstScanLine = (BYTE*) pDibBitsDst + (prcDst->top) * (iDstScanLength
  4441. = DibWidthBytes(pDibInfoDst)) + (prcDst->left * 3);
  4442. // Call the appropriate blit
  4443. Blt24Pto24P_Blend_Trans_Hcopy_SRCCOPY_VCopy(pbSrcScanLine,iSrcScanLength,
  4444. pbDstScanLine,
  4445. iDstScanLength, iNumDstCols,
  4446. iNumDstRows, crTransparent, arAlpha);
  4447. }
  4448. // Last case, the destination rectangle is horizontally greater
  4449. // in magnitude than the source rectangle
  4450. else
  4451. {
  4452. // compute pointers to the starting rows in the src and dst bitmaps
  4453. // taking care to decrement the right rect edge since we are
  4454. // going from right to left
  4455. pbSrcScanLine = (BYTE*) pDibBitsSrc + (prcSrc->top) * (iSrcScanLength
  4456. = DibWidthBytes(pDibInfoSrc)) + ((prcSrc->right - 1) * 3);
  4457. pbDstScanLine = (BYTE*) pDibBitsDst + (prcDst->top) * (iDstScanLength
  4458. = DibWidthBytes(pDibInfoDst)) + ((prcDst->right - 1) * 3);
  4459. // Call the appropriate blit
  4460. Blt24Pto24P_RightToLeft_TopToBottom_Trans_Alpha_SRCCOPY(pbSrcScanLine,
  4461. iSrcScanLength, pbDstScanLine, iDstScanLength, iNumDstCols,
  4462. iNumDstRows, crTransparent, arAlpha);
  4463. }
  4464. }
  4465. #endif /* !DDRAW */
  4466. }
  4467. return sc;
  4468. }
  4469. #ifndef DDRAW
  4470. ///////////////////////////////////////////////////////////////////////
  4471. //
  4472. // Private BlitLib_BitBlt24Ato24 -
  4473. // BitBlit from source bitmap to Dstination bitmap
  4474. // with optional transparency and/or alpha blending using the
  4475. // specified raster operation.
  4476. //
  4477. // Parameters:
  4478. // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB
  4479. // pDibBitsDst Pointer to the bits for the Destination DIB
  4480. // prcDst Pointer to the Destination rectangle
  4481. // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB
  4482. // pDibBitsSrc Pointer to the bits for the Source DIB
  4483. // prcSrc Pointer to the Source rectangle
  4484. // crTransparent Tranparent color value
  4485. // arAlpha Per-surface Alpha value
  4486. // dwRop Raster Operation for the blit
  4487. //
  4488. // Return Value:
  4489. // NO_ERROR or E_* value as specified in the .H file.
  4490. //
  4491. // Status: Incomplete
  4492. //
  4493. ///////////////////////////////////////////////////////////////////////
  4494. SCODE BlitLib_BitBlt24Ato24(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst,
  4495. PRECT prcDst, PDIBINFO pDibInfoSrc, PDIBBITS pDibBitsSrc,
  4496. PRECT prcSrc, COLORREF crTransparent, ALPHAREF arAlpha, DWORD dwRop)
  4497. {
  4498. SCODE sc = NOERROR;
  4499. int iNumSrcRows,
  4500. iNumSrcCols,
  4501. iSrcScanLength,
  4502. iNumDstRows,
  4503. iNumDstCols,
  4504. iDstScanLength,
  4505. iHorizMirror = 1,
  4506. iVertMirror = 1;
  4507. DWORD *pdSrcScanLine,
  4508. *pdDstScanLine;
  4509. // normalize orientation of source and destination rectangles, and compute sizes
  4510. // and relative orientations of source and destination rects
  4511. if ((iNumSrcCols = BLITLIB_RECTWIDTH(prcSrc)) < 0) {
  4512. iNumSrcCols = -iNumSrcCols;
  4513. FlipRectHorizontal(prcSrc);
  4514. FlipRectHorizontal(prcDst);
  4515. }
  4516. if ((iNumSrcRows = BLITLIB_RECTHEIGHT(prcSrc)) < 0) {
  4517. iNumSrcRows = -iNumSrcRows;
  4518. FlipRectVertical(prcSrc);
  4519. FlipRectVertical(prcDst);
  4520. }
  4521. if ((iNumDstCols = BLITLIB_RECTWIDTH(prcDst)) < 0) {
  4522. prcDst->left--;
  4523. prcDst->right--;
  4524. iNumDstCols = -iNumDstCols;
  4525. iHorizMirror = -1;
  4526. }
  4527. if ((iNumDstRows = BLITLIB_RECTHEIGHT(prcDst)) < 0) {
  4528. prcDst->top--;
  4529. prcDst->bottom--;
  4530. iNumDstRows = -iNumDstRows;
  4531. iVertMirror = -1;
  4532. }
  4533. // compute pointers to the starting rows in the src and dst bitmaps
  4534. // taking care to invert y values, since DIBs are upside-down
  4535. pdSrcScanLine = (DWORD*) pDibBitsSrc + prcSrc->top * (iSrcScanLength
  4536. = DibWidthBytes(pDibInfoSrc) / 4) + prcSrc->left;
  4537. pdDstScanLine = (DWORD*) pDibBitsDst + prcDst->top * (iDstScanLength
  4538. = DibWidthBytes(pDibInfoDst) / 4) + prcDst->left;
  4539. // check if we're doing blending
  4540. if (arAlpha == ALPHA_INVALID) { // no blending desired
  4541. // check to see if we need to worry about transparency
  4542. if (crTransparent == CLR_INVALID) {
  4543. // check if we can do a straight copy from src row to dst row
  4544. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  4545. // check what ROP we'll be performing
  4546. if (dwRop == SRCCOPY) {
  4547. // check if we can do a straight copy vertically,
  4548. // or if we have to stretch, shrink, or mirror
  4549. if ((iNumSrcRows == iNumDstRows) && (iVertMirror == 1)) {
  4550. Blt24Ato24_NoBlend_NoTrans_Hcopy_SRCCOPY_Vcopy(pdSrcScanLine,iSrcScanLength,
  4551. pdDstScanLine,iDstScanLength,
  4552. iNumDstCols,iNumDstRows);
  4553. } else {
  4554. Blt24Ato24_NoBlend_NoTrans_Hcopy_SRCCOPY_NoVcopy(pdSrcScanLine,iSrcScanLength,
  4555. iNumSrcRows,pdDstScanLine,
  4556. iDstScanLength * iVertMirror,
  4557. iNumDstCols,iNumDstRows);
  4558. }
  4559. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  4560. } else {
  4561. // check what ROP we'll be performing
  4562. if (dwRop == SRCCOPY) {
  4563. Blt24Ato24_NoBlend_NoTrans_NoHcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength,
  4564. iNumSrcCols,iNumSrcRows,
  4565. pdDstScanLine,iDstScanLength * iVertMirror,
  4566. iNumDstCols,iNumDstRows,iHorizMirror);
  4567. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  4568. }
  4569. } else {
  4570. // check if we can do a straight copy from src row to dst row
  4571. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  4572. // check what ROP we'll be performing
  4573. if (dwRop == SRCCOPY) {
  4574. Blt24Ato24_NoBlend_Trans_Hcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength,
  4575. iNumSrcRows,pdDstScanLine,
  4576. iDstScanLength * iVertMirror,
  4577. iNumDstCols,iNumDstRows,
  4578. crTransparent);
  4579. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  4580. } else {
  4581. // check what ROP we'll be performing
  4582. if (dwRop == SRCCOPY) {
  4583. Blt24Ato24_NoBlend_Trans_NoHcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength,
  4584. iNumSrcCols,iNumSrcRows,
  4585. pdDstScanLine,iDstScanLength * iVertMirror,
  4586. iNumDstCols,iNumDstRows,iHorizMirror,
  4587. crTransparent);
  4588. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  4589. }
  4590. }
  4591. } else { // blending desired
  4592. // REVIEW!!!! -- This is a temporary hack based on the following premises:
  4593. //
  4594. // 1) In theory, per-pixel alpha should be overridable by per-surface alpha
  4595. // 2) In practice, Burma does not allow per-surface alpha to override a per-
  4596. // pixel bitmap.
  4597. // 3) The following code for all the per-surface alpha blending bliting is
  4598. // temporarily commented out so that we can verify DirectDraw NEVER EVER
  4599. // calls BlitLib with both a per-pixel bitmap and a per-surface alpha
  4600. // value other than ALPHA_INVALID.
  4601. //
  4602. // Therefore, we are currently return E_UNEXPECTED if this condition occurs.
  4603. //
  4604. // Although the following commented code is contrary to the Burma hardware,
  4605. // we are not going to change BlitLib to Burma's implementation because we
  4606. // believe it's implementation is a bug.
  4607. //
  4608. return E_UNEXPECTED;
  4609. /* // if alpha value is zero, we do no work since the source bitmap
  4610. // contributes nothing to the destination bitmap
  4611. if (!(arAlpha & ALPHA_MASK)) {
  4612. return sc;
  4613. }
  4614. // check to see if we need to worry about transparency
  4615. if (crTransparent == CLR_INVALID) {
  4616. // check if we can do a straight copy from src row to dst row
  4617. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  4618. // check what ROP we'll be performing
  4619. if (dwRop == SRCCOPY) {
  4620. Blt24Ato24_Blend_NoTrans_Hcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength,
  4621. iNumSrcRows,pdDstScanLine,
  4622. iDstScanLength * iVertMirror,
  4623. iNumDstCols,iNumDstRows,
  4624. arAlpha);
  4625. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  4626. } else {
  4627. // check what ROP we'll be performing
  4628. if (dwRop == SRCCOPY) {
  4629. Blt24Ato24_Blend_NoTrans_NoHcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength,
  4630. iNumSrcCols,iNumSrcRows,
  4631. pdDstScanLine,iDstScanLength * iVertMirror,
  4632. iNumDstCols,iNumDstRows,iHorizMirror,
  4633. arAlpha);
  4634. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  4635. }
  4636. } else {
  4637. // check if we can do a straight copy from src row to dst row
  4638. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  4639. // check what ROP we'll be performing
  4640. if (dwRop == SRCCOPY) {
  4641. Blt24Ato24_Blend_Trans_Hcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength,
  4642. iNumSrcRows,pdDstScanLine,
  4643. iDstScanLength * iVertMirror,
  4644. iNumDstCols,iNumDstRows,
  4645. crTransparent,arAlpha);
  4646. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  4647. } else {
  4648. // check what ROP we'll be performing
  4649. if (dwRop == SRCCOPY) {
  4650. Blt24Ato24_Blend_Trans_NoHcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength,
  4651. iNumSrcCols,iNumSrcRows,
  4652. pdDstScanLine,iDstScanLength * iVertMirror,
  4653. iNumDstCols,iNumDstRows,iHorizMirror,
  4654. crTransparent,arAlpha);
  4655. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  4656. }
  4657. }*/
  4658. }
  4659. return sc;
  4660. }
  4661. ///////////////////////////////////////////////////////////////////////
  4662. //
  4663. // Private BlitLib_BitBlt24Ato24P -
  4664. // BitBlit from source bitmap to Dstination bitmap
  4665. // with optional transparency and/or alpha blending using the
  4666. // specified raster operation.
  4667. //
  4668. // Parameters:
  4669. // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB
  4670. // pDibBitsDst Pointer to the bits for the Destination DIB
  4671. // prcDst Pointer to the Destination rectangle
  4672. // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB
  4673. // pDibBitsSrc Pointer to the bits for the Source DIB
  4674. // prcSrc Pointer to the Source rectangle
  4675. // crTransparent Tranparent color value
  4676. // arAlpha Per-surface Alpha value
  4677. // dwRop Raster Operation for the blit
  4678. //
  4679. // Return Value:
  4680. // NO_ERROR or E_* value as specified in the .H file.
  4681. //
  4682. // Status: Incomplete
  4683. //
  4684. ///////////////////////////////////////////////////////////////////////
  4685. SCODE BlitLib_BitBlt24Ato24P(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst,
  4686. PRECT prcDst, PDIBINFO pDibInfoSrc, PDIBBITS pDibBitsSrc,
  4687. PRECT prcSrc, COLORREF crTransparent, ALPHAREF arAlpha, DWORD dwRop)
  4688. {
  4689. SCODE sc = NOERROR;
  4690. int iNumSrcRows,
  4691. iNumSrcCols,
  4692. iSrcScanLength,
  4693. iNumDstRows,
  4694. iNumDstCols,
  4695. iDstScanLength,
  4696. iHorizMirror = 1,
  4697. iVertMirror = 1;
  4698. DWORD *pdSrcScanLine;
  4699. BYTE *pdDstScanLine;
  4700. // normalize orientation of source and destination rectangles, and compute sizes
  4701. // and relative orientations of source and destination rects
  4702. if ((iNumSrcCols = BLITLIB_RECTWIDTH(prcSrc)) < 0) {
  4703. iNumSrcCols = -iNumSrcCols;
  4704. FlipRectHorizontal(prcSrc);
  4705. FlipRectHorizontal(prcDst);
  4706. }
  4707. if ((iNumSrcRows = BLITLIB_RECTHEIGHT(prcSrc)) < 0) {
  4708. iNumSrcRows = -iNumSrcRows;
  4709. FlipRectVertical(prcSrc);
  4710. FlipRectVertical(prcDst);
  4711. }
  4712. if ((iNumDstCols = BLITLIB_RECTWIDTH(prcDst)) < 0) {
  4713. prcDst->left--;
  4714. prcDst->right--;
  4715. iNumDstCols = -iNumDstCols;
  4716. iHorizMirror = -1;
  4717. }
  4718. if ((iNumDstRows = BLITLIB_RECTHEIGHT(prcDst)) < 0) {
  4719. prcDst->top--;
  4720. prcDst->bottom--;
  4721. iNumDstRows = -iNumDstRows;
  4722. iVertMirror = -1;
  4723. }
  4724. // compute pointers to the starting rows in the src and dst bitmaps
  4725. // taking care to invert y values, since DIBs are upside-down
  4726. pdSrcScanLine = (DWORD*) pDibBitsSrc + prcSrc->top * (iSrcScanLength
  4727. = DibWidthBytes(pDibInfoSrc) / 4) + prcSrc->left;
  4728. pdDstScanLine = (BYTE *) pDibBitsDst + prcDst->top * (iDstScanLength
  4729. = DibWidthBytes(pDibInfoDst)) + (prcDst->left * 3);
  4730. // check if we're doing blending
  4731. if (arAlpha == ALPHA_INVALID) { // no blending desired
  4732. // check to see if we need to worry about transparency
  4733. if (crTransparent == CLR_INVALID) {
  4734. // check if we can do a straight copy from src row to dst row
  4735. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  4736. // check what ROP we'll be performing
  4737. if (dwRop == SRCCOPY) {
  4738. // check if we can do a straight copy vertically,
  4739. // or if we have to stretch, shrink, or mirror
  4740. if ((iNumSrcRows == iNumDstRows) && (iVertMirror == 1)) {
  4741. Blt24Ato24P_NoBlend_NoTrans_Hcopy_SRCCOPY_Vcopy(pdSrcScanLine,iSrcScanLength,
  4742. pdDstScanLine,iDstScanLength,
  4743. iNumDstCols,iNumDstRows);
  4744. } else {
  4745. Blt24Ato24P_NoBlend_NoTrans_Hcopy_SRCCOPY_NoVcopy(pdSrcScanLine,iSrcScanLength,
  4746. iNumSrcRows,pdDstScanLine,
  4747. iDstScanLength * iVertMirror,
  4748. iNumDstCols,iNumDstRows);
  4749. }
  4750. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  4751. } else {
  4752. // check what ROP we'll be performing
  4753. if (dwRop == SRCCOPY) {
  4754. Blt24Ato24P_NoBlend_NoTrans_NoHcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength,
  4755. iNumSrcCols,iNumSrcRows,
  4756. pdDstScanLine,iDstScanLength * iVertMirror,
  4757. iNumDstCols,iNumDstRows,iHorizMirror);
  4758. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  4759. }
  4760. } else {
  4761. // check if we can do a straight copy from src row to dst row
  4762. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  4763. // check what ROP we'll be performing
  4764. if (dwRop == SRCCOPY) {
  4765. Blt24Ato24P_NoBlend_Trans_Hcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength,
  4766. iNumSrcRows,pdDstScanLine,
  4767. iDstScanLength * iVertMirror,
  4768. iNumDstCols,iNumDstRows,
  4769. crTransparent);
  4770. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  4771. } else {
  4772. // check what ROP we'll be performing
  4773. if (dwRop == SRCCOPY) {
  4774. Blt24Ato24P_NoBlend_Trans_NoHcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength,
  4775. iNumSrcCols,iNumSrcRows,
  4776. pdDstScanLine,iDstScanLength * iVertMirror,
  4777. iNumDstCols,iNumDstRows,iHorizMirror,
  4778. crTransparent);
  4779. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  4780. }
  4781. }
  4782. } else { // blending desired
  4783. // REVIEW!!!! -- This is a temporary hack based on the following premises:
  4784. //
  4785. // 1) In theory, per-pixel alpha should be overridable by per-surface alpha
  4786. // 2) In practice, Burma does not allow per-surface alpha to override a per-
  4787. // pixel bitmap.
  4788. // 3) The following code for all the per-surface alpha blending bliting is
  4789. // temporarily commented out so that we can verify DirectDraw NEVER EVER
  4790. // calls BlitLib with both a per-pixel bitmap and a per-surface alpha
  4791. // value other than ALPHA_INVALID.
  4792. //
  4793. // Therefore, we are currently return E_UNEXPECTED if this condition occurs.
  4794. //
  4795. // Although the following commented code is contrary to the Burma hardware,
  4796. // we are not going to change BlitLib to Burma's implementation because we
  4797. // believe it's implementation is a bug.
  4798. //
  4799. return E_UNEXPECTED;
  4800. /* // if alpha value is zero, we do no work since the source bitmap
  4801. // contributes nothing to the destination bitmap
  4802. if (!(arAlpha & ALPHA_MASK)) {
  4803. return sc;
  4804. }
  4805. // check to see if we need to worry about transparency
  4806. if (crTransparent == CLR_INVALID) {
  4807. // check if we can do a straight copy from src row to dst row
  4808. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  4809. // check what ROP we'll be performing
  4810. if (dwRop == SRCCOPY) {
  4811. Blt24Ato24P_Blend_NoTrans_Hcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength,
  4812. iNumSrcRows,pdDstScanLine,
  4813. iDstScanLength * iVertMirror,
  4814. iNumDstCols,iNumDstRows,
  4815. arAlpha);
  4816. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  4817. } else {
  4818. // check what ROP we'll be performing
  4819. if (dwRop == SRCCOPY) {
  4820. Blt24Ato24P_Blend_NoTrans_NoHcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength,
  4821. iNumSrcCols,iNumSrcRows,
  4822. pdDstScanLine,iDstScanLength * iVertMirror,
  4823. iNumDstCols,iNumDstRows,iHorizMirror,
  4824. arAlpha);
  4825. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  4826. }
  4827. } else {
  4828. // check if we can do a straight copy from src row to dst row
  4829. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  4830. // check what ROP we'll be performing
  4831. if (dwRop == SRCCOPY) {
  4832. Blt24Ato24P_Blend_Trans_Hcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength,
  4833. iNumSrcRows,pdDstScanLine,
  4834. iDstScanLength * iVertMirror,
  4835. iNumDstCols,iNumDstRows,
  4836. crTransparent,arAlpha);
  4837. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  4838. } else {
  4839. // check what ROP we'll be performing
  4840. if (dwRop == SRCCOPY) {
  4841. Blt24Ato24P_Blend_Trans_NoHcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength,
  4842. iNumSrcCols,iNumSrcRows,
  4843. pdDstScanLine,iDstScanLength * iVertMirror,
  4844. iNumDstCols,iNumDstRows,iHorizMirror,
  4845. crTransparent,arAlpha);
  4846. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  4847. }
  4848. }*/
  4849. }
  4850. return sc;
  4851. }
  4852. ///////////////////////////////////////////////////////////////////////
  4853. //
  4854. // Private BlitLib_BitBlt24Ato24A -
  4855. // BitBlit from source bitmap to Dstination bitmap
  4856. // with optional transparency and/or alpha blending using the
  4857. // specified raster operation.
  4858. //
  4859. // This blit is special because it uses the regular 24to24 blits
  4860. // to do all of its work. This blit is a COPY ONLY blit, thus,
  4861. // it does NOT do any alpha blending. However, it does copy the
  4862. // alpha channel value for each pixel to the destination.
  4863. //
  4864. // Parameters:
  4865. // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB
  4866. // pDibBitsDst Pointer to the bits for the Destination DIB
  4867. // prcDst Pointer to the Destination rectangle
  4868. // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB
  4869. // pDibBitsSrc Pointer to the bits for the Source DIB
  4870. // prcSrc Pointer to the Source rectangle
  4871. // crTransparent Tranparent color value
  4872. // arAlpha Per-surface Alpha value
  4873. // dwRop Raster Operation for the blit
  4874. //
  4875. // Return Value:
  4876. // NO_ERROR or E_* value as specified in the .H file.
  4877. //
  4878. // Status: Incomplete
  4879. //
  4880. ///////////////////////////////////////////////////////////////////////
  4881. SCODE BlitLib_BitBlt24Ato24A(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst,
  4882. PRECT prcDst, PDIBINFO pDibInfoSrc, PDIBBITS pDibBitsSrc,
  4883. PRECT prcSrc, COLORREF crTransparent, ALPHAREF arAlpha, DWORD dwRop)
  4884. {
  4885. SCODE sc = NOERROR;
  4886. int iNumSrcRows,
  4887. iNumSrcCols,
  4888. iSrcScanLength,
  4889. iNumDstRows,
  4890. iNumDstCols,
  4891. iDstScanLength,
  4892. iHorizMirror = 1,
  4893. iVertMirror = 1;
  4894. DWORD *pdSrcScanLine,
  4895. *pdDstScanLine;
  4896. // normalize orientation of source and destination rectangles, and compute sizes
  4897. // and relative orientations of source and destination rects
  4898. if ((iNumSrcCols = BLITLIB_RECTWIDTH(prcSrc)) < 0) {
  4899. iNumSrcCols = -iNumSrcCols;
  4900. FlipRectHorizontal(prcSrc);
  4901. FlipRectHorizontal(prcDst);
  4902. }
  4903. if ((iNumSrcRows = BLITLIB_RECTHEIGHT(prcSrc)) < 0) {
  4904. iNumSrcRows = -iNumSrcRows;
  4905. FlipRectVertical(prcSrc);
  4906. FlipRectVertical(prcDst);
  4907. }
  4908. if ((iNumDstCols = BLITLIB_RECTWIDTH(prcDst)) < 0) {
  4909. prcDst->left--;
  4910. prcDst->right--;
  4911. iNumDstCols = -iNumDstCols;
  4912. iHorizMirror = -1;
  4913. }
  4914. if ((iNumDstRows = BLITLIB_RECTHEIGHT(prcDst)) < 0) {
  4915. prcDst->top--;
  4916. prcDst->bottom--;
  4917. iNumDstRows = -iNumDstRows;
  4918. iVertMirror = -1;
  4919. }
  4920. // compute pointers to the starting rows in the src and dst bitmaps
  4921. // taking care to invert y values, since DIBs are upside-down
  4922. pdSrcScanLine = (DWORD*) pDibBitsSrc + prcSrc->top * (iSrcScanLength
  4923. = DibWidthBytes(pDibInfoSrc) / 4) + prcSrc->left;
  4924. pdDstScanLine = (DWORD*) pDibBitsDst + prcDst->top * (iDstScanLength
  4925. = DibWidthBytes(pDibInfoDst) / 4) + prcDst->left;
  4926. // Make sure we are not trying to alpha blend. This is a COPY ONLY blit
  4927. if (arAlpha != ALPHA_INVALID)
  4928. return E_INVALIDARG;
  4929. // check to see if we need to worry about transparency
  4930. if (crTransparent == CLR_INVALID) {
  4931. // check if we can do a straight copy from src row to dst row
  4932. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  4933. // check what ROP we'll be performing
  4934. if (dwRop == SRCCOPY) {
  4935. // check if we can do a straight copy vertically,
  4936. // or if we have to stretch, shrink, or mirror
  4937. if ((iNumSrcRows == iNumDstRows) && (iVertMirror == 1)) {
  4938. Blt24Ato24_NoBlend_NoTrans_Hcopy_SRCCOPY_Vcopy(pdSrcScanLine,iSrcScanLength,
  4939. pdDstScanLine,iDstScanLength,
  4940. iNumDstCols,iNumDstRows);
  4941. } else {
  4942. Blt24Ato24_NoBlend_NoTrans_Hcopy_SRCCOPY_NoVcopy(pdSrcScanLine,iSrcScanLength,
  4943. iNumSrcRows,pdDstScanLine,
  4944. iDstScanLength * iVertMirror,
  4945. iNumDstCols,iNumDstRows);
  4946. }
  4947. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  4948. } else {
  4949. // check what ROP we'll be performing
  4950. if (dwRop == SRCCOPY) {
  4951. Blt24Ato24_NoBlend_NoTrans_NoHcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength,
  4952. iNumSrcCols,iNumSrcRows,
  4953. pdDstScanLine,iDstScanLength * iVertMirror,
  4954. iNumDstCols,iNumDstRows,iHorizMirror);
  4955. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  4956. }
  4957. } else {
  4958. // check if we can do a straight copy from src row to dst row
  4959. if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) {
  4960. // check what ROP we'll be performing
  4961. if (dwRop == SRCCOPY) {
  4962. Blt24Ato24_NoBlend_Trans_Hcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength,
  4963. iNumSrcRows,pdDstScanLine,
  4964. iDstScanLength * iVertMirror,
  4965. iNumDstCols,iNumDstRows,
  4966. crTransparent);
  4967. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  4968. } else {
  4969. // check what ROP we'll be performing
  4970. if (dwRop == SRCCOPY) {
  4971. Blt24Ato24_NoBlend_Trans_NoHcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength,
  4972. iNumSrcCols,iNumSrcRows,
  4973. pdDstScanLine,iDstScanLength * iVertMirror,
  4974. iNumDstCols,iNumDstRows,iHorizMirror,
  4975. crTransparent);
  4976. } else sc |= E_UNEXPECTED; // !!!! we need better error codes
  4977. }
  4978. }
  4979. return sc;
  4980. }
  4981. #endif // DDRAW
  4982. ///////////////////////////////////////////////////////////////////////
  4983. //
  4984. // Private BlitLib_FillRect01 -
  4985. // Fill a rectangle in the specified DIB with the desired color.
  4986. //
  4987. // Parameters:
  4988. // PDIBINFO pbiDst - Pointer to DIB header
  4989. // PDIBBITS pDst - Pointer to DIB Bits
  4990. // int XDst - X Destination Start Position
  4991. // int YDst - Y Destination Start Position
  4992. // int nWidthDst - Width
  4993. // int nHeightDst - Height
  4994. // BYTE crValue - Color index
  4995. //
  4996. // Return Value:
  4997. // NO_ERROR or E_* value as specified in the .H file.
  4998. //
  4999. // Status: Complete
  5000. // NOTES: Put in a call to Gunter's super fast fill code instead!
  5001. //
  5002. ///////////////////////////////////////////////////////////////////////
  5003. static const BYTE bTopMask[8] = {0x00, 0x80, 0xC0, 0xE0,
  5004. 0xF0, 0xF8, 0xFC, 0xFE};
  5005. static const BYTE bBottomMask[8] = {0xFF, 0x7F, 0x3F, 0x1F,
  5006. 0x0F, 0x07, 0x03, 0x01};
  5007. SCODE BlitLib_FillRect01(PDIBINFO pbiDst, PDIBBITS pDst, int XDst, int YDst,
  5008. int nWidthDst, int nHeightDst, BYTE crValue)
  5009. {
  5010. SCODE sc = NOERROR;
  5011. long DstDeltaScan,
  5012. WidthBytes;
  5013. int y,
  5014. iPixelOffset,
  5015. iStartPixels,
  5016. iFullBytes,
  5017. iEndPixels;
  5018. BYTE *pbDst,
  5019. *pbEndDst,
  5020. *pbDstScanline = (BYTE*) 0,
  5021. bFillVal;
  5022. // Calculate the delta scan amount
  5023. DstDeltaScan = DibWidthBytes(pbiDst);
  5024. WidthBytes = DstDeltaScan;
  5025. // Calculate the starting pixel address
  5026. pbDstScanline = (BYTE*) pDst + XDst / 8 + YDst * WidthBytes;
  5027. iPixelOffset = XDst % 8;
  5028. // set up memory fill value
  5029. if (crValue) {
  5030. bFillVal = 0xFF;
  5031. } else {
  5032. bFillVal = 0;
  5033. }
  5034. // calculate how many bits of first byte we have to set, how many
  5035. // full bytes to set, and how many bits of last byte to set on
  5036. // each scanline
  5037. if (iPixelOffset) {
  5038. iStartPixels = 8 - iPixelOffset;
  5039. iFullBytes = (nWidthDst - iStartPixels) / 8;
  5040. iEndPixels = (nWidthDst - iStartPixels) % 8;
  5041. } else {
  5042. iStartPixels = 0;
  5043. iFullBytes = nWidthDst / 8;
  5044. iEndPixels = nWidthDst % 8;
  5045. }
  5046. // loop to fill one scanline at a time
  5047. for (y = 0; y < nHeightDst; y++) {
  5048. // set pointer to beginning of scanline
  5049. pbDst = pbDstScanline;
  5050. // take care of pixels lying on a byte not entirely
  5051. // in the scanline
  5052. if (iStartPixels) {
  5053. if (nWidthDst >= iStartPixels) {
  5054. if (bFillVal) {
  5055. *pbDst++ |= bBottomMask[iPixelOffset];
  5056. } else {
  5057. *pbDst++ &= bTopMask[iPixelOffset];
  5058. }
  5059. } else {
  5060. if (bFillVal) {
  5061. *pbDst++ |= (bBottomMask[iPixelOffset] &
  5062. bTopMask[iPixelOffset + nWidthDst]);
  5063. } else {
  5064. *pbDst++ &= (bTopMask[iPixelOffset] |
  5065. bBottomMask[iPixelOffset + nWidthDst]);
  5066. }
  5067. }
  5068. }
  5069. // fill bytes filled entirely with pixels to be set
  5070. pbEndDst = pbDst + iFullBytes;
  5071. for (; pbDst != pbEndDst; pbDst++) {
  5072. *pbDst = bFillVal;
  5073. }
  5074. // take care of pixels hanging off other end into byte
  5075. // not entirely on scanline
  5076. if (iEndPixels) {
  5077. if (bFillVal) {
  5078. *pbDst |= bTopMask[iEndPixels];
  5079. } else {
  5080. *pbDst &= bBottomMask[iEndPixels];
  5081. }
  5082. }
  5083. pbDstScanline += DstDeltaScan;
  5084. }
  5085. return sc;
  5086. }
  5087. ///////////////////////////////////////////////////////////////////////
  5088. //
  5089. // Private BlitLib_FillRect08 -
  5090. // Fill a rectangle in the specified DIB with the desired color.
  5091. //
  5092. // Parameters:
  5093. // PDIBINFO pbiDst - Pointer to DIB header
  5094. // PDIBBITS pDst - Pointer to DIB Bits
  5095. // int XDst - X Destination Start Position
  5096. // int YDst - Y Destination Start Position
  5097. // int nWidthDst - Width
  5098. // int nHeightDst - Height
  5099. // BYTE crValue - Color index
  5100. //
  5101. // Return Value:
  5102. // NO_ERROR or E_* value as specified in the .H file.
  5103. //
  5104. // Status: Complete
  5105. // NOTES: Put in a call to Gunter's super fast fill code instead!
  5106. //
  5107. ///////////////////////////////////////////////////////////////////////
  5108. SCODE BlitLib_FillRect08(PDIBINFO pbiDst, PDIBBITS pDst, int XDst, int YDst,
  5109. int nWidthDst, int nHeightDst, BYTE crValue)
  5110. {
  5111. DWORD *pBigDstPixel,
  5112. *pBigEndDstPixel;
  5113. BYTE *pDstScanline,
  5114. *pDstPixel = (BYTE *)pDst,
  5115. *pAlignedDstPixel;
  5116. int iNumDwordsPerLine = nWidthDst / 4,
  5117. iNumBytesLeftDst = nWidthDst % 4,
  5118. iNumUnalignedDstBytes = 0,
  5119. i,j,
  5120. iDstDeltaScan;
  5121. register DWORD dwValue = (DWORD)(crValue | (crValue << 8) | (crValue << 16) | (crValue <<24));
  5122. // Calculate the delta scan amount
  5123. iDstDeltaScan = (long)(pbiDst->bmiHeader.biWidth) * 8;
  5124. iDstDeltaScan = ((iDstDeltaScan + 31) & (~31)) / 8;
  5125. // Calculate the starting pixel address
  5126. pDstScanline = (BYTE *)pDst + XDst + YDst * iDstDeltaScan;
  5127. // If the num dwords per line is less than 0, then we will just
  5128. // do a byte wise fill for the < 4 bytes
  5129. if(iNumDwordsPerLine){
  5130. // Find out if the src and dest pointers are dword aligned
  5131. pAlignedDstPixel = (BYTE *)((((ULONG_PTR)pDstScanline) + 3) & (~3));
  5132. iNumUnalignedDstBytes = (int)(pAlignedDstPixel - pDstScanline);
  5133. // Now decrement the number of dwords per line and the
  5134. // number of bytes left over as appropriate
  5135. if(iNumUnalignedDstBytes <= iNumBytesLeftDst)
  5136. iNumBytesLeftDst -= iNumUnalignedDstBytes;
  5137. else{
  5138. iNumBytesLeftDst = sizeof(DWORD) - iNumUnalignedDstBytes + iNumBytesLeftDst;
  5139. if(iNumBytesLeftDst != sizeof(DWORD))
  5140. iNumDwordsPerLine--;
  5141. }
  5142. }
  5143. // Do the fill
  5144. for (i = 0; i < nHeightDst; i++) {
  5145. // Set up the first pointer
  5146. pDstPixel = pDstScanline;
  5147. // First we need to copy the bytes to get to an aligned dword
  5148. for(j=0; j<iNumUnalignedDstBytes; j++)
  5149. *pDstPixel++ = crValue;
  5150. // set up pointers to the first 4-pixel chunks
  5151. // on src and dst scanlines, and last chunk on
  5152. // dst scanline
  5153. pBigDstPixel = (DWORD*) pDstPixel;
  5154. pBigEndDstPixel = pBigDstPixel + iNumDwordsPerLine;
  5155. // copy scanline one 4-pixel chunk at a time
  5156. while (pBigDstPixel != pBigEndDstPixel) {
  5157. *pBigDstPixel++ = dwValue;
  5158. }
  5159. // take care of remaining pixels on scanline
  5160. if (iNumBytesLeftDst) {
  5161. pDstPixel = (BYTE*) pBigDstPixel;
  5162. for(j=0; j<iNumBytesLeftDst; j++){
  5163. *pDstPixel++ = crValue;
  5164. }
  5165. }
  5166. // advance to next scanline
  5167. pDstScanline += iDstDeltaScan;
  5168. }
  5169. return NO_ERROR;
  5170. }
  5171. ///////////////////////////////////////////////////////////////////////
  5172. //
  5173. // Private BlitLib_FillRect16 -
  5174. // Fill a rectangle in the specified DIB with the desired color.
  5175. //
  5176. // Parameters:
  5177. // PDIBINFO pbiDst - Pointer to DIB header
  5178. // PDIBBITS pDst - Pointer to DIB Bits
  5179. // int XDst - X Destination Start Position
  5180. // int YDst - Y Destination Start Position
  5181. // int nWidthDst - Width
  5182. // int nHeightDst - Height
  5183. // WORD crValue - ColorRef value (RGB 5-6-5)
  5184. //
  5185. // Return Value:
  5186. // NO_ERROR or E_* value as specified in the .H file.
  5187. //
  5188. // Status: Complete / UNTESTED!!!!
  5189. // NOTES: Put in a call to Gunter's super fast fill code instead!
  5190. //
  5191. ///////////////////////////////////////////////////////////////////////
  5192. SCODE BlitLib_FillRect16(PDIBINFO pbiDst, PDIBBITS pDst, int XDst, int YDst,
  5193. int nWidthDst, int nHeightDst, WORD crValue)
  5194. {
  5195. DWORD *pBigDstPixel,
  5196. *pBigEndDstPixel;
  5197. WORD *pDstScanline,
  5198. *pDstPixel = (WORD *)pDst,
  5199. *pAlignedDstPixel;
  5200. int iNumDwordsPerLine = nWidthDst / 2,
  5201. iNumWordsLeftDst = nWidthDst % 2,
  5202. iNumUnalignedDstWords = 0,
  5203. i,j,
  5204. iDstDeltaScan;
  5205. register DWORD dwValue = (DWORD)(crValue | (crValue << 16));
  5206. // Calculate the delta scan amount
  5207. iDstDeltaScan = (long)(pbiDst->bmiHeader.biWidth) * 16;
  5208. iDstDeltaScan = ((iDstDeltaScan + 31) & (~31)) / 16;
  5209. // Calculate the starting pixel address
  5210. pDstScanline = (WORD *)pDst + XDst + YDst * iDstDeltaScan;
  5211. // If the num dwords per line is less than 0, then we will just
  5212. // do a word wise fill for the single pixel
  5213. if(iNumDwordsPerLine){
  5214. // Find out if the dest pointer is dword aligned
  5215. pAlignedDstPixel = (WORD *)((((ULONG_PTR)pDstScanline) + 3) & (~3));
  5216. iNumUnalignedDstWords = (int)(pAlignedDstPixel - pDstScanline);
  5217. // Now decrement the number of dwords per line and the
  5218. // number of bytes left over as appropriate
  5219. if(iNumUnalignedDstWords <= iNumWordsLeftDst)
  5220. iNumWordsLeftDst -= iNumUnalignedDstWords;
  5221. else{
  5222. iNumWordsLeftDst = (sizeof(DWORD)/2) - iNumUnalignedDstWords;
  5223. if(iNumWordsLeftDst != (sizeof(DWORD)/2))
  5224. iNumDwordsPerLine--;
  5225. }
  5226. }
  5227. // Do the fill
  5228. for (i = 0; i < nHeightDst; i++) {
  5229. // Set up the first pointer
  5230. pDstPixel = pDstScanline;
  5231. // First we need to copy the bytes to get to an aligned dword
  5232. for(j=0; j<iNumUnalignedDstWords; j++)
  5233. *pDstPixel++ = crValue;
  5234. // set up pointers to the first 4-pixel chunks
  5235. // on src and dst scanlines, and last chunk on
  5236. // dst scanline
  5237. pBigDstPixel = (DWORD*) pDstPixel;
  5238. pBigEndDstPixel = pBigDstPixel + iNumDwordsPerLine;
  5239. // copy scanline one 4-pixel chunk at a time
  5240. while (pBigDstPixel != pBigEndDstPixel) {
  5241. *pBigDstPixel++ = dwValue;
  5242. }
  5243. // take care of remaining pixels on scanline
  5244. if (iNumWordsLeftDst) {
  5245. pDstPixel = (WORD *) pBigDstPixel;
  5246. for(j=0; j<iNumWordsLeftDst; j++){
  5247. *pDstPixel++ = crValue;
  5248. }
  5249. }
  5250. // advance to next scanline
  5251. pDstScanline += iDstDeltaScan;
  5252. }
  5253. return NO_ERROR;
  5254. }
  5255. ///////////////////////////////////////////////////////////////////////
  5256. //
  5257. // Private BlitLib_FillRect24 -
  5258. // Fill a rectangle in the specified DIB with the desired color.
  5259. //
  5260. // Parameters:
  5261. // PDIBINFO pbiDst - Pointer to DIB header
  5262. // PDIBBITS pDst - Pointer to DIB Bits
  5263. // int XDst - X Destination Start Position
  5264. // int YDst - Y Destination Start Position
  5265. // int nWidthDst - Width
  5266. // int nHeightDst - Height
  5267. // RGBTRIPLE rgb - RGBTRIPLE representing the fill color
  5268. //
  5269. // Return Value:
  5270. // NO_ERROR or E_* value as specified in the .H file.
  5271. //
  5272. // Status: Complete / UNTESTED!!!!
  5273. // NOTES: Put in a call to Gunter's super fast fill code instead!
  5274. //
  5275. ///////////////////////////////////////////////////////////////////////
  5276. SCODE BlitLib_FillRect24(PDIBINFO pbiDst, PDIBBITS pDst, int XDst, int YDst,
  5277. int nWidthDst, int nHeightDst, DWORD rgb)
  5278. {
  5279. SCODE sc = NOERROR;
  5280. long DstDeltaScan;
  5281. char *pDstScanline = NULL;
  5282. int x = 0;
  5283. int y = 0;
  5284. RGBTRIPLE *pDstPixel;
  5285. RGBTRIPLE *pEndPixel;
  5286. RGBTRIPLE rgbt;
  5287. DWORD d1,d2,d3;
  5288. // Set up rgbt (ignore the color names - they are meaningless)
  5289. rgbt.rgbtBlue = (BYTE)(rgb & 0x0000ff);
  5290. rgbt.rgbtGreen = (BYTE)((rgb & 0x00ff00) >> 8);
  5291. rgbt.rgbtRed = (BYTE)((rgb & 0xff0000) >> 16);
  5292. // Calculate the number of pixels per scan line
  5293. DstDeltaScan = DibWidthBytes(pbiDst);
  5294. // Calculate the starting pixel address
  5295. pDstScanline = ((char*)pDst) + (XDst*sizeof(RGBTRIPLE) + YDst * DstDeltaScan);
  5296. // Set up aligned stores
  5297. d1 = rgb | (rgb << 24);
  5298. d2 = (rgb << 16) | (rgb >> 8);
  5299. d3 = (rgb << 8) | (rgb >> 16);
  5300. // Do the fill
  5301. while (y < nHeightDst)
  5302. {
  5303. pDstPixel = (RGBTRIPLE*)pDstScanline;
  5304. pEndPixel = pDstPixel + nWidthDst;
  5305. while ( ((ULONG_PTR)pDstPixel & 0x03) && (pDstPixel < pEndPixel) )
  5306. {
  5307. ((BYTE*)pDstPixel)[0] = ((BYTE*)&rgbt)[0];
  5308. ((BYTE*)pDstPixel)[1] = ((BYTE*)&rgbt)[1];
  5309. ((BYTE*)pDstPixel)[2] = ((BYTE*)&rgbt)[2];
  5310. pDstPixel++;
  5311. }
  5312. while (((ULONG_PTR)pDstPixel) <= (((ULONG_PTR)(pEndPixel-4)) & ~0x03))
  5313. {
  5314. *(((DWORD*)pDstPixel)) = d1;
  5315. *(((DWORD*)pDstPixel)+1) = d2;
  5316. *(((DWORD*)pDstPixel)+2) = d3;
  5317. pDstPixel +=4;
  5318. }
  5319. while (pDstPixel < pEndPixel)
  5320. {
  5321. ((BYTE*)pDstPixel)[0] = ((BYTE*)&rgbt)[0];
  5322. ((BYTE*)pDstPixel)[1] = ((BYTE*)&rgbt)[1];
  5323. ((BYTE*)pDstPixel)[2] = ((BYTE*)&rgbt)[2];
  5324. pDstPixel++;
  5325. }
  5326. ++y;
  5327. pDstScanline += DstDeltaScan;
  5328. }
  5329. return sc;
  5330. }
  5331. ///////////////////////////////////////////////////////////////////////
  5332. //
  5333. // Private BlitLib_FillRect32 -
  5334. // Fill a rectangle in the specified DIB with the desired color.
  5335. //
  5336. // Parameters:
  5337. // PDIBINFO pbiDst - Pointer to DIB header
  5338. // PDIBBITS pDst - Pointer to DIB Bits
  5339. // int XDst - X Destination Start Position
  5340. // int YDst - Y Destination Start Position
  5341. // int nWidthDst - Width
  5342. // int nHeightDst - Height
  5343. // COLORREF crValue - ColorRef value (RGB Quad)
  5344. //
  5345. // Return Value:
  5346. // NO_ERROR or E_* value as specified in the .H file.
  5347. //
  5348. // Status: Complete / UNTESTED!!!!
  5349. // NOTES: Put in a call to Gunter's super fast fill code instead!
  5350. //
  5351. ///////////////////////////////////////////////////////////////////////
  5352. SCODE BlitLib_FillRect32(PDIBINFO pbiDst, PDIBBITS pDst, int XDst, int YDst,
  5353. int nWidthDst, int nHeightDst, DWORD crValue)
  5354. {
  5355. SCODE sc = NOERROR;
  5356. long DstDeltaScan;
  5357. long WidthDWords;
  5358. DWORD *pDstScanline = (DWORD *) 0;
  5359. int y = 0;
  5360. DWORD *pDstPixel;
  5361. DWORD *pEndPixel;
  5362. // Calculate the delta scan amount
  5363. DstDeltaScan = DibWidthBytes(pbiDst) >> 2; // don't trust the compile to deal with "/4"
  5364. WidthDWords = DstDeltaScan;
  5365. // Calculate the starting pixel address
  5366. pDstScanline = (DWORD *)pDst + XDst + YDst * WidthDWords;
  5367. // Do the fill
  5368. while (y < nHeightDst)
  5369. {
  5370. pDstPixel = pDstScanline;
  5371. pEndPixel = pDstPixel + nWidthDst;
  5372. while (pDstPixel < pEndPixel)
  5373. {
  5374. *pDstPixel = crValue;
  5375. pDstPixel++;
  5376. }
  5377. ++y;
  5378. pDstScanline += DstDeltaScan;
  5379. }
  5380. return sc;
  5381. }
  5382. ///////////////////////////////////////////////////////////////////////
  5383. //
  5384. // Private BlitLib_WriteMaskFillRect32 -
  5385. // Fill a rectangle in the specified DIB with the desired color using a writemask
  5386. //
  5387. // Parameters:
  5388. // PDIBINFO pbiDst - Pointer to DIB header
  5389. // PDIBBITS pDst - Pointer to DIB Bits
  5390. // int XDst - X Destination Start Position
  5391. // int YDst - Y Destination Start Position
  5392. // int nWidthDst - Width
  5393. // int nHeightDst - Height
  5394. // COLORREF crValue - ColorRef value (RGB Quad)
  5395. // dwWriteMask - write only those pixel bits that are turned on
  5396. //
  5397. // Return Value:
  5398. // NO_ERROR or E_* value as specified in the .H file.
  5399. //
  5400. // Status: Complete / UNTESTED!!!!
  5401. // NOTES: Put in a call to Gunter's super fast fill code instead!
  5402. //
  5403. ///////////////////////////////////////////////////////////////////////
  5404. SCODE BlitLib_WriteMaskFillRect32(PDIBINFO pbiDst, PDIBBITS pDst, int XDst, int YDst,
  5405. int nWidthDst, int nHeightDst, DWORD crValue,DWORD dwWriteMask)
  5406. {
  5407. SCODE sc = NOERROR;
  5408. long DstDeltaScan;
  5409. long WidthDWords;
  5410. DWORD *pDstScanline = (DWORD *) 0;
  5411. int y = 0;
  5412. DWORD *pDstPixel;
  5413. DWORD *pEndPixel;
  5414. DWORD dwInvWriteMask;
  5415. // Calculate the delta scan amount
  5416. DstDeltaScan = DibWidthBytes(pbiDst) >> 2; // don't trust the compiler to deal with "/4"
  5417. WidthDWords = DstDeltaScan;
  5418. // Calculate the starting pixel address
  5419. pDstScanline = (DWORD *)pDst + XDst + YDst * WidthDWords;
  5420. crValue&=dwWriteMask; // turn off bits in fill value that wont be used
  5421. dwInvWriteMask= ~dwWriteMask; // will turn off bits to be overwritten in DstPixel
  5422. // Do the fill
  5423. while (y < nHeightDst)
  5424. {
  5425. pDstPixel = pDstScanline;
  5426. pEndPixel = pDstPixel + nWidthDst;
  5427. while (pDstPixel < pEndPixel)
  5428. {
  5429. *pDstPixel = (*pDstPixel & dwInvWriteMask) | crValue;
  5430. pDstPixel++;
  5431. }
  5432. ++y;
  5433. pDstScanline += DstDeltaScan;
  5434. }
  5435. return sc;
  5436. }
  5437. ///////////////////////////////////////////////////////////////////////
  5438. //
  5439. // Private BlitLib_WriteMaskFillRect16 -
  5440. // Fill a rectangle in the specified DIB with the desired color using a writemask
  5441. //
  5442. // Parameters:
  5443. // PDIBINFO pbiDst - Pointer to DIB header
  5444. // PDIBBITS pDst - Pointer to DIB Bits
  5445. // int XDst - X Destination Start Position
  5446. // int YDst - Y Destination Start Position
  5447. // int nWidthDst - Width
  5448. // int nHeightDst - Height
  5449. // COLORREF crValue - ColorRef value (RGB Quad)
  5450. // wWriteMask - write only those pixel bits that are turned on
  5451. //
  5452. // Return Value:
  5453. // NO_ERROR or E_* value as specified in the .H file.
  5454. //
  5455. // Status: Complete / UNTESTED!!!!
  5456. // NOTES: Put in a call to Gunter's super fast fill code instead!
  5457. //
  5458. ///////////////////////////////////////////////////////////////////////
  5459. SCODE BlitLib_WriteMaskFillRect16(PDIBINFO pbiDst, PDIBBITS pDst, int XDst, int YDst,
  5460. int nWidthDst, int nHeightDst, WORD crValue,WORD wWriteMask)
  5461. {
  5462. SCODE sc = NOERROR;
  5463. long DstDeltaScan;
  5464. long WidthDWords;
  5465. WORD *pDstScanline = (WORD *) 0;
  5466. int y = 0;
  5467. WORD *pDstPixel;
  5468. WORD *pEndPixel;
  5469. WORD wInvWriteMask;
  5470. // Calculate the delta scan amount
  5471. DstDeltaScan = DibWidthBytes(pbiDst) >> 1; // don't trust the compiler to deal with "/2"
  5472. WidthDWords = DstDeltaScan;
  5473. // Calculate the starting pixel address
  5474. pDstScanline = (WORD *)pDst + XDst + YDst * WidthDWords;
  5475. crValue &= wWriteMask; // turn off bits in fill value that wont be used
  5476. wInvWriteMask= ~wWriteMask; // will turn off bits to be overwritten in DstPixel
  5477. // Do the fill
  5478. while (y < nHeightDst)
  5479. {
  5480. pDstPixel = pDstScanline;
  5481. pEndPixel = pDstPixel + nWidthDst;
  5482. while (pDstPixel < pEndPixel)
  5483. {
  5484. *pDstPixel = (*pDstPixel & wInvWriteMask) | crValue;
  5485. pDstPixel++;
  5486. }
  5487. ++y;
  5488. pDstScanline += DstDeltaScan;
  5489. }
  5490. return sc;
  5491. }
  5492. ///////////////////////////////////////////////////////////////////////
  5493. //
  5494. // Private BlitLib_BitBlt -
  5495. // Select the correct BitBlit and call it.
  5496. //
  5497. // Parameters:
  5498. // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB
  5499. // pDibBitsDst Pointer to the bits for the Destination DIB
  5500. // prcDst Pointer to the Destination rectangle
  5501. // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB
  5502. // pDibBitsSrc Pointer to the bits for the Source DIB
  5503. // prcSrc Pointer to the Source rectangle
  5504. // crTransparent Tranparent color value
  5505. // arAlpha Per-surface Alpha value
  5506. // dwRop Raster Operation for the blit
  5507. //
  5508. // Return Value:
  5509. // NO_ERROR or E_* value as specified in the .H file.
  5510. //
  5511. // Status: Incomplete
  5512. //
  5513. ///////////////////////////////////////////////////////////////////////
  5514. DWORD gdwUnusedBitsMask;
  5515. SCODE BlitLib_BitBlt(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst,
  5516. PRECT prcDst, PDIBINFO pDibInfoSrc, PDIBBITS pDibBitsSrc,
  5517. PRECT prcSrc, COLORREF crTransparent, ALPHAREF arAlpha, DWORD dwRop)
  5518. {
  5519. SCODE sc = NOERROR;
  5520. DWORD dwBltConvType;
  5521. RECT rcSrc = *prcSrc,
  5522. rcDst = *prcDst;
  5523. // Make sure that destination rect is at least one pixel wide and tall.
  5524. // Important! Without this check we're vulnerable to divide by zero
  5525. // errors in the blit routines.
  5526. if ((BLITLIB_RECTWIDTH(&rcDst) == 0) ||
  5527. (BLITLIB_RECTHEIGHT(&rcDst) == 0)) {
  5528. return sc;
  5529. }
  5530. /*
  5531. * Set unused pixel mask to default for all non RGBA blts"
  5532. */
  5533. gdwUnusedBitsMask = 0xffffff;
  5534. if (((LPBITMAPINFO)pDibInfoSrc)->bmiHeader.biCompression==BI_BITFIELDS &&
  5535. ((LPBITMAPINFO)pDibInfoSrc)->bmiHeader.biBitCount==32)
  5536. {
  5537. gdwUnusedBitsMask =
  5538. *(DWORD*)&((LPBITMAPINFO)pDibInfoSrc)->bmiColors[0] |
  5539. *(DWORD*)&((LPBITMAPINFO)pDibInfoSrc)->bmiColors[1] |
  5540. *(DWORD*)&((LPBITMAPINFO)pDibInfoSrc)->bmiColors[2];
  5541. }
  5542. // Figure out the Blt Conversion type
  5543. dwBltConvType = MAKELONG(GetImageFormatSpecifier(DibCompression(pDibInfoDst),
  5544. DibBitCount(pDibInfoDst)),
  5545. GetImageFormatSpecifier(DibCompression(pDibInfoSrc),
  5546. DibBitCount(pDibInfoSrc)));
  5547. switch (dwBltConvType) {
  5548. case BLT_01TO01:
  5549. sc |= BlitLib_BitBlt01to01(pDibInfoDst,pDibBitsDst,&rcDst,
  5550. pDibInfoSrc,pDibBitsSrc,&rcSrc,
  5551. crTransparent,arAlpha,dwRop);
  5552. break;
  5553. #ifndef DDRAW
  5554. case BLT_01TO08:
  5555. sc |= BlitLib_BitBlt01to08(pDibInfoDst,pDibBitsDst,&rcDst,
  5556. pDibInfoSrc,pDibBitsSrc,&rcSrc,
  5557. crTransparent,arAlpha,dwRop);
  5558. break;
  5559. case BLT_01TO24:
  5560. sc |= BlitLib_BitBlt01to24(pDibInfoDst,pDibBitsDst,&rcDst,
  5561. pDibInfoSrc,pDibBitsSrc,&rcSrc,
  5562. crTransparent,arAlpha,dwRop);
  5563. break;
  5564. case BLT_08TO01:
  5565. sc |= BlitLib_BitBlt08to01(pDibInfoDst,pDibBitsDst,&rcDst,
  5566. pDibInfoSrc,pDibBitsSrc,&rcSrc,
  5567. crTransparent,arAlpha,dwRop);
  5568. break;
  5569. #endif // DDRAW
  5570. case BLT_08TO08:
  5571. sc |= BlitLib_BitBlt08to08(pDibInfoDst,pDibBitsDst,&rcDst,
  5572. pDibInfoSrc,pDibBitsSrc,&rcSrc,
  5573. crTransparent,arAlpha,dwRop);
  5574. break;
  5575. #ifndef DDRAW
  5576. case BLT_08TO24:
  5577. sc |= BlitLib_BitBlt08to24(pDibInfoDst,pDibBitsDst,&rcDst,
  5578. pDibInfoSrc,pDibBitsSrc,&rcSrc,
  5579. crTransparent,arAlpha,dwRop);
  5580. break;
  5581. case BLT_08TO24P:
  5582. sc |= BlitLib_BitBlt08to24P(pDibInfoDst,pDibBitsDst,&rcDst,
  5583. pDibInfoSrc,pDibBitsSrc,&rcSrc,
  5584. crTransparent,arAlpha,dwRop);
  5585. break;
  5586. case BLT_08ATO08A:
  5587. sc |= BlitLib_BitBlt08Ato08A(pDibInfoDst,pDibBitsDst,&rcDst,
  5588. pDibInfoSrc,pDibBitsSrc,&rcSrc,
  5589. crTransparent,arAlpha,dwRop);
  5590. break;
  5591. case BLT_08ATO24:
  5592. sc |= BlitLib_BitBlt08Ato24(pDibInfoDst,pDibBitsDst,&rcDst,
  5593. pDibInfoSrc,pDibBitsSrc,&rcSrc,
  5594. crTransparent,arAlpha,dwRop);
  5595. break;
  5596. case BLT_08ATO24P:
  5597. sc |= BlitLib_BitBlt08Ato24P(pDibInfoDst,pDibBitsDst,&rcDst,
  5598. pDibInfoSrc,pDibBitsSrc,&rcSrc,
  5599. crTransparent,arAlpha,dwRop);
  5600. break;
  5601. #endif // DDRAW
  5602. case BLT_16TO16:
  5603. sc |= BlitLib_BitBlt16to16(pDibInfoDst,pDibBitsDst,&rcDst,
  5604. pDibInfoSrc,pDibBitsSrc,&rcSrc,
  5605. crTransparent,arAlpha,dwRop);
  5606. break;
  5607. #ifndef DDRAW
  5608. case BLT_16TO24:
  5609. sc |= BlitLib_BitBlt16to24(pDibInfoDst,pDibBitsDst,&rcDst,
  5610. pDibInfoSrc,pDibBitsSrc,&rcSrc,
  5611. crTransparent,arAlpha,dwRop);
  5612. break;
  5613. case BLT_16TO24P:
  5614. sc |= BlitLib_BitBlt16to24P(pDibInfoDst,pDibBitsDst,&rcDst,
  5615. pDibInfoSrc,pDibBitsSrc,&rcSrc,
  5616. crTransparent,arAlpha,dwRop);
  5617. break;
  5618. case BLT_24TO01:
  5619. sc |= BlitLib_BitBlt24to01(pDibInfoDst,pDibBitsDst,&rcDst,
  5620. pDibInfoSrc,pDibBitsSrc,&rcSrc,
  5621. crTransparent,arAlpha,dwRop);
  5622. break;
  5623. case BLT_24PTO01:
  5624. sc |= BlitLib_BitBlt24Pto01(pDibInfoDst,pDibBitsDst,&rcDst,
  5625. pDibInfoSrc,pDibBitsSrc,&rcSrc,
  5626. crTransparent,arAlpha,dwRop);
  5627. break;
  5628. case BLT_24TO08:
  5629. sc |= BlitLib_BitBlt24to08(pDibInfoDst,pDibBitsDst,&rcDst,
  5630. pDibInfoSrc,pDibBitsSrc,&rcSrc,
  5631. crTransparent,arAlpha,dwRop);
  5632. break;
  5633. case BLT_24PTO08:
  5634. sc |= BlitLib_BitBlt24Pto08(pDibInfoDst,pDibBitsDst,&rcDst,
  5635. pDibInfoSrc,pDibBitsSrc,&rcSrc,
  5636. crTransparent,arAlpha,dwRop);
  5637. break;
  5638. #endif // DDRAW
  5639. case BLT_24TO24:
  5640. sc |= BlitLib_BitBlt24to24(pDibInfoDst,pDibBitsDst,&rcDst,
  5641. pDibInfoSrc,pDibBitsSrc,&rcSrc,
  5642. crTransparent,arAlpha,dwRop);
  5643. break;
  5644. #ifndef DDRAW
  5645. case BLT_24TO24P:
  5646. sc |= BlitLib_BitBlt24to24P(pDibInfoDst,pDibBitsDst,&rcDst,
  5647. pDibInfoSrc,pDibBitsSrc,&rcSrc,
  5648. crTransparent,arAlpha,dwRop);
  5649. break;
  5650. case BLT_24ATO24:
  5651. sc |= BlitLib_BitBlt24Ato24(pDibInfoDst,pDibBitsDst,&rcDst,
  5652. pDibInfoSrc,pDibBitsSrc,&rcSrc,
  5653. crTransparent,arAlpha,dwRop);
  5654. break;
  5655. case BLT_24ATO24P:
  5656. sc |= BlitLib_BitBlt24Ato24P(pDibInfoDst,pDibBitsDst,&rcDst,
  5657. pDibInfoSrc,pDibBitsSrc,&rcSrc,
  5658. crTransparent,arAlpha,dwRop);
  5659. break;
  5660. case BLT_24ATO24A:
  5661. sc |= BlitLib_BitBlt24Ato24A(pDibInfoDst,pDibBitsDst,&rcDst,
  5662. pDibInfoSrc,pDibBitsSrc,&rcSrc,
  5663. crTransparent,arAlpha,dwRop);
  5664. break;
  5665. #endif // DDRAW
  5666. case BLT_24PTO24P:
  5667. sc |= BlitLib_BitBlt24Pto24P(pDibInfoDst,pDibBitsDst,&rcDst,
  5668. pDibInfoSrc,pDibBitsSrc,&rcSrc,
  5669. crTransparent,arAlpha,dwRop);
  5670. break;
  5671. default:
  5672. sc |= E_UNEXPECTED; // !!!! Need better error codes!
  5673. }
  5674. return sc;
  5675. }
  5676. #define DPF_MODNAME BlitLib_WriteMaskFillRect
  5677. ///////////////////////////////////////////////////////////////////////
  5678. //
  5679. // Private BlitLib_WriteMaskFillRect -
  5680. // Select the correct WriteMaskFillRect and call it.
  5681. //
  5682. // Parameters:
  5683. // PDIBINFO pbiDst - Pointer to DIB header
  5684. // PDIBBITS pDst - Pointer to DIB Bits
  5685. // int XDst - X Destination Start Position
  5686. // int YDst - Y Destination Start Position
  5687. // int nWidthDst - Width
  5688. // int nHeightDst - Height
  5689. // COLORREF crValue - ColorRef value (RGB Quad)
  5690. // DWORD - dwWriteMask: 1's indicate bits that can be overwritten in pixel
  5691. //
  5692. // Return Value:
  5693. // NO_ERROR or E_* value as specified in the .H file.
  5694. //
  5695. // Status: Complete
  5696. //
  5697. ///////////////////////////////////////////////////////////////////////
  5698. SCODE BlitLib_WriteMaskFillRect(PDIBINFO pbiDst, PDIBBITS pDst,
  5699. RECT * pRect, COLORREF crColor, DWORD dwWriteMask)
  5700. {
  5701. SCODE sc = NOERROR;
  5702. int nWidthDst, nHeightDst;
  5703. if (!pbiDst || !pDst || !pRect) {
  5704. sc |= E_UNEXPECTED;
  5705. goto ERROR_EXIT;
  5706. }
  5707. nWidthDst = BLITLIB_RECTWIDTH(pRect);
  5708. nHeightDst = BLITLIB_RECTHEIGHT(pRect);
  5709. switch (GetImageFormatSpecifier(DibCompression(pbiDst),
  5710. DibBitCount(pbiDst)))
  5711. {
  5712. case BPP_24_RGB:
  5713. sc |= BlitLib_WriteMaskFillRect32(pbiDst, pDst, pRect->left,
  5714. pRect->top, nWidthDst, nHeightDst, crColor,dwWriteMask);
  5715. break;
  5716. case BPP_16_RGB:
  5717. sc |= BlitLib_WriteMaskFillRect16(pbiDst, pDst, pRect->left,
  5718. pRect->top, nWidthDst, nHeightDst, (WORD) crColor, (WORD) dwWriteMask);
  5719. break;
  5720. case BPP_8_PALETTEIDX:
  5721. case BPP_24_RGBPACKED: // dont need these now because only stencil fmt is 32-bit (24-8)
  5722. return E_NOTIMPL;
  5723. case BPP_1_MONOCHROME:
  5724. case BPP_16_8WALPHA:
  5725. case BPP_32_24WALPHA:
  5726. case BPP_16_YCRCB:
  5727. case BPP_INVALID:
  5728. default:
  5729. sc |= E_UNEXPECTED;
  5730. }
  5731. // fall through
  5732. ERROR_EXIT:
  5733. return sc;
  5734. }
  5735. #undef DPF_MODNAME
  5736. ///////////////////////////////////////////////////////////////////////
  5737. //
  5738. // Private BlitLib_FillRect -
  5739. // Select the correct FillRect and call it.
  5740. //
  5741. // Parameters:
  5742. // PDIBINFO pbiDst - Pointer to DIB header
  5743. // PDIBBITS pDst - Pointer to DIB Bits
  5744. // int XDst - X Destination Start Position
  5745. // int YDst - Y Destination Start Position
  5746. // int nWidthDst - Width
  5747. // int nHeightDst - Height
  5748. // COLORREF crValue - ColorRef value (RGB Quad)
  5749. //
  5750. // Return Value:
  5751. // NO_ERROR or E_* value as specified in the .H file.
  5752. //
  5753. // Status: Complete
  5754. // NOTES: Put in a call to Gunter's super fast fill code instead!
  5755. //
  5756. ///////////////////////////////////////////////////////////////////////
  5757. SCODE BlitLib_FillRect(PDIBINFO pbiDst, PDIBBITS pDst,
  5758. RECT * pRect, COLORREF crColor)
  5759. {
  5760. SCODE sc = NOERROR;
  5761. int nWidthDst, nHeightDst;
  5762. if (!pbiDst || !pDst || !pRect) {
  5763. sc |= E_UNEXPECTED;
  5764. goto ERROR_EXIT;
  5765. }
  5766. nWidthDst = BLITLIB_RECTWIDTH(pRect);
  5767. nHeightDst = BLITLIB_RECTHEIGHT(pRect);
  5768. switch (GetImageFormatSpecifier(DibCompression(pbiDst),
  5769. DibBitCount(pbiDst)))
  5770. {
  5771. case BPP_1_MONOCHROME:
  5772. {
  5773. BYTE crValue = (BYTE)crColor;
  5774. sc |= BlitLib_FillRect01(pbiDst, pDst, pRect->left,
  5775. pRect->top, nWidthDst,nHeightDst, crValue);
  5776. }
  5777. break;
  5778. case BPP_8_PALETTEIDX:
  5779. {
  5780. BYTE crValue = (BYTE)crColor;
  5781. sc |= BlitLib_FillRect08(pbiDst, pDst, pRect->left,
  5782. pRect->top, nWidthDst, nHeightDst, crValue);
  5783. }
  5784. break;
  5785. case BPP_16_RGB:
  5786. {
  5787. WORD crValue = (WORD)crColor;
  5788. sc |= BlitLib_FillRect16(pbiDst, pDst, pRect->left,
  5789. pRect->top, nWidthDst, nHeightDst, crValue);
  5790. }
  5791. break;
  5792. case BPP_24_RGBPACKED:
  5793. sc |= BlitLib_FillRect24(pbiDst, pDst, pRect->left,
  5794. pRect->top, nWidthDst, nHeightDst, crColor);
  5795. break;
  5796. case BPP_24_RGB:
  5797. sc |= BlitLib_FillRect32(pbiDst, pDst, pRect->left,
  5798. pRect->top, nWidthDst, nHeightDst, crColor);
  5799. break;
  5800. case BPP_16_8WALPHA:
  5801. case BPP_32_24WALPHA:
  5802. case BPP_16_YCRCB:
  5803. case BPP_INVALID:
  5804. default:
  5805. sc |= E_UNEXPECTED;
  5806. }
  5807. // fall through
  5808. ERROR_EXIT:
  5809. return sc;
  5810. }
  5811. ///////////////////////////////////////////////////////////////////////
  5812. //
  5813. // Private BlitLib_PatBlt -
  5814. // Fill an entire destination rectangle by tiling a given bitmap
  5815. //
  5816. // Parameters:
  5817. // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB
  5818. // pDibBitsDst Pointer to the bits for the Destination DIB
  5819. // prcDst Pointer to the Destination rectangle
  5820. // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB
  5821. // pDibBitsSrc Pointer to the bits for the Source DIB
  5822. // prcSrc Pointer to the Source rectangle
  5823. // dwRop Raster Operation for the blit
  5824. //
  5825. // Return Value:
  5826. // NO_ERROR or E_* value as specified in the .H file.
  5827. //
  5828. // Status: Incomplete
  5829. //
  5830. ///////////////////////////////////////////////////////////////////////
  5831. SCODE BlitLib_PatBlt(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst,
  5832. PRECT prcDst, PDIBINFO pDibInfoPat, PDIBBITS pDibBitsPat,
  5833. PRECT prcPat, COLORREF crTransparent, ALPHAREF arAlpha,
  5834. DWORD dwRop)
  5835. {
  5836. SCODE sc = NOERROR;
  5837. long iPatWidth;
  5838. long iPatHeight;
  5839. long iCurXPos;
  5840. long iCurYPos;
  5841. long iBlitWidth;
  5842. long iBlitHeight;
  5843. long iWidthLeft;
  5844. long iHeightLeft;
  5845. RECT rcPat = {0,0,0,0};
  5846. RECT rcDst = {0,0,0,0};
  5847. // Check for invalid rectangles -- PatBlt only works for rects that
  5848. // are both (src and dest) right-side up (positive height and width).
  5849. // Also set our bounding rectangle sizes in the process
  5850. if(((iPatWidth = BLITLIB_RECTWIDTH(prcPat)) < 0)
  5851. || ((iPatHeight = BLITLIB_RECTHEIGHT(prcPat)) < 0)
  5852. || (BLITLIB_RECTWIDTH(prcDst) < 0)
  5853. || (BLITLIB_RECTHEIGHT(prcDst) < 0))
  5854. return E_INVALIDARG;
  5855. // Reset the Y postion to the top edge of the dest
  5856. iCurYPos = prcDst->top;
  5857. // Tile the pattern into the destination rectangle
  5858. while (iCurYPos < prcDst->bottom){
  5859. // Set up the source rectangle heights
  5860. rcPat.top = iCurYPos % iPatHeight;
  5861. iHeightLeft = (prcDst->bottom - iCurYPos);
  5862. // Calculate the height we are actually going to blit
  5863. iBlitHeight = min(iHeightLeft, (iPatHeight - rcPat.top));
  5864. rcPat.bottom = rcPat.top + iBlitHeight;
  5865. // Set up the destination rectangle heights
  5866. rcDst.top = iCurYPos;
  5867. rcDst.bottom = iCurYPos + iBlitHeight;
  5868. // Reset the current X position to the left edge of the dest
  5869. iCurXPos = prcDst->left;
  5870. // Tile the pattern into the destination rectangle
  5871. while (iCurXPos < prcDst->right){
  5872. // Set up the source rectangle width
  5873. rcPat.left = iCurXPos % iPatWidth;
  5874. iWidthLeft = (prcDst->right - iCurXPos);
  5875. // Calculate the width we are actually going to blit
  5876. iBlitWidth = min(iWidthLeft, (iPatWidth - rcPat.left));
  5877. rcPat.right = rcPat.left + iBlitWidth;
  5878. // Set up the destination rectangle heights
  5879. rcDst.left = iCurXPos;
  5880. rcDst.right = iCurXPos + iBlitWidth;
  5881. // REVIEW!!!! -- Do we want to check sc after each blit and return on an error?
  5882. sc = BlitLib_BitBlt(pDibInfoDst, pDibBitsDst, &rcDst, pDibInfoPat,
  5883. pDibBitsPat, &rcPat, crTransparent, arAlpha,
  5884. dwRop);
  5885. // Increment the current index value
  5886. iCurXPos += iBlitWidth;
  5887. }
  5888. // Increment the current index value
  5889. iCurYPos += iBlitHeight;
  5890. }
  5891. return sc;
  5892. }
  5893. ///////////////////////////////////////////////////////////////////////
  5894. //
  5895. // Private GetImageFormatSpecifier -
  5896. // Select the correct bitmap format based on the compression and
  5897. // bit count.
  5898. //
  5899. // Parameters:
  5900. // dwDibComp - The DIB's compression
  5901. // wdBitCount - The DIB's bit count
  5902. //
  5903. // Return Value:
  5904. // BPP_INVALID or a valid bitmap format
  5905. //
  5906. // Status: Incomplete
  5907. //
  5908. ///////////////////////////////////////////////////////////////////////
  5909. WORD GetImageFormatSpecifier(DWORD dwDibComp, WORD wdBitCount)
  5910. {
  5911. // Bit count could have Penguin codes in the high byte, mask them
  5912. // out for a correct comparison.
  5913. wdBitCount &= 0x00ff;
  5914. switch (dwDibComp)
  5915. {
  5916. case BI_RGB:
  5917. switch (wdBitCount)
  5918. {
  5919. case 1:
  5920. return BPP_1_MONOCHROME;
  5921. case 8:
  5922. return BPP_8_PALETTEIDX;
  5923. case 16:
  5924. return BPP_16_RGB;
  5925. case 24:
  5926. return BPP_24_RGBPACKED;
  5927. case 32:
  5928. return BPP_24_RGB;
  5929. default:
  5930. return BPP_INVALID;
  5931. }
  5932. case BI_RGBA:
  5933. switch (wdBitCount)
  5934. {
  5935. case 16:
  5936. return BPP_16_8WALPHA;
  5937. case 32:
  5938. return BPP_32_24WALPHA;
  5939. default:
  5940. return BPP_INVALID;
  5941. }
  5942. case BI_BITFIELDS:
  5943. switch (wdBitCount)
  5944. {
  5945. case 16:
  5946. return BPP_16_RGB; // BlitLib assumes 5-6-5 RGB
  5947. case 32:
  5948. return BPP_24_RGB;
  5949. default:
  5950. return BPP_INVALID;
  5951. }
  5952. case BI_YCRCB:
  5953. return BPP_16_YCRCB;
  5954. default:
  5955. switch (wdBitCount)
  5956. {
  5957. case 1:
  5958. return BPP_1_MONOCHROME;
  5959. default:
  5960. return BPP_INVALID;
  5961. }
  5962. }
  5963. return BPP_INVALID;
  5964. }
  5965. #ifndef DDRAW
  5966. ///////////////////////////////////////////////////////////////////////
  5967. //
  5968. // Private BlitLib_PalIndexFromRGB -
  5969. // Calculates the closest entry in an array of COLORREF's to a
  5970. // given COLORREF
  5971. //
  5972. // Parameters:
  5973. // crColor - Color to match
  5974. // rgcrPal - Array of colors to match to
  5975. // iNumPalColors - Number of colors in the array
  5976. //
  5977. // Return Value:
  5978. // Palette index of the nearest color
  5979. //
  5980. // Status: Incomplete
  5981. //
  5982. ///////////////////////////////////////////////////////////////////////
  5983. BYTE BlitLib_PalIndexFromRGB(COLORREF crColor,COLORREF* rgcrPal,
  5984. unsigned int iNumPalColors)
  5985. {
  5986. BYTE bIndex = 0;
  5987. int iRed = crColor & RED_MASK,
  5988. iRedError,
  5989. iGreen = (crColor & GREEN_MASK) >> 8,
  5990. iGreenError,
  5991. iBlue = (crColor & BLUE_MASK) >> 16,
  5992. iBlueError,
  5993. iError,
  5994. iLeastError = MAX_POS_INT;
  5995. for (unsigned int i = 0; i < iNumPalColors; i++) {
  5996. iRedError = iRed - (rgcrPal[i] & RED_MASK);
  5997. iGreenError = iGreen - ((rgcrPal[i] & GREEN_MASK) >> 8);
  5998. iBlueError = iBlue - ((rgcrPal[i] & BLUE_MASK) >> 16);
  5999. iError = iRedError * iRedError + iGreenError * iGreenError +
  6000. iBlueError * iBlueError;
  6001. if (iError < iLeastError) {
  6002. iLeastError = iError;
  6003. bIndex = (BYTE) i;
  6004. }
  6005. }
  6006. return bIndex;
  6007. }
  6008. #endif // DDRAW
  6009. #ifndef DDRAW
  6010. ///////////////////////////////////////////////////////////////////////
  6011. //
  6012. // Private BlitLib_BLIT_BLEND24 -
  6013. // Performs alpha blending on 24bpp(packed) blits.
  6014. //
  6015. // Parameters:
  6016. // ptSrc - Pointer to the Source RGBTRIPLE
  6017. // ptDst - Pointer to the Destination RGBTRIPLE
  6018. // alpha - Alpha value (Range: 1 - 256)
  6019. // alphacomp - Alpha complement (256 - alpha)
  6020. //
  6021. // Return Value:
  6022. // None
  6023. //
  6024. ///////////////////////////////////////////////////////////////////////
  6025. void BlitLib_BLIT_BLEND24(COLORREF crSrc, RGBTRIPLE * ptDst,
  6026. UINT alpha, UINT alphacomp)
  6027. {
  6028. BYTE * pbSrc = (BYTE *)&crSrc;
  6029. BYTE * pbDst = (BYTE *)ptDst;
  6030. DWORD dwSrc;
  6031. DWORD dwDst;
  6032. UINT i;
  6033. for(i=0; i<sizeof(RGBTRIPLE); i++){
  6034. dwSrc = (DWORD)*pbSrc++;
  6035. dwDst = (DWORD)*pbDst;
  6036. dwDst = ((dwSrc * alpha + dwDst * alphacomp) >> 8);
  6037. *pbDst++ = (BYTE)dwDst;
  6038. }
  6039. }
  6040. #endif
  6041. ///////////////////////////////////////////////////////////////////////
  6042. //
  6043. // Private BlitLib_Detect_Intersection -
  6044. // Detects if both the source and destination bitmaps overlap
  6045. //
  6046. // Parameters:
  6047. // pdibbitsDst - Pointer to the Destination Bits
  6048. // prcDst - Pointer to the Destination Rectangle
  6049. // pdibbitsSrc - Pointer to the Source Bits
  6050. // prcSrc - Pointer to the Source Rectangle
  6051. //
  6052. //
  6053. // Return Value:
  6054. // TRUE if the bitmaps overlap, FALSE if they do not
  6055. //
  6056. ///////////////////////////////////////////////////////////////////////
  6057. BOOL BlitLib_Detect_Intersection (PDIBBITS pdibbitsDst, PRECT prcDst,
  6058. PDIBBITS pdibbitsSrc, PRECT prcSrc)
  6059. {
  6060. RECT rc,
  6061. rcSrc,
  6062. rcDst;
  6063. // First check to see if the pdibbits pointers point to the same bitmap
  6064. if(pdibbitsDst != pdibbitsSrc)
  6065. return FALSE;
  6066. // REVIEW!!! - This is just a hack because IntersectRect expects
  6067. // bitmaps to be oriented correctly, but I can't afford to do
  6068. // it to my original prects yet
  6069. rcSrc.left = prcSrc->left;
  6070. rcSrc.top = prcSrc->top;
  6071. rcSrc.right = prcSrc->right;
  6072. rcSrc.bottom = prcSrc->bottom;
  6073. rcDst.left = prcDst->left;
  6074. rcDst.top = prcDst->top;
  6075. rcDst.right = prcDst->right;
  6076. rcDst.bottom = prcDst->bottom;
  6077. if (BLITLIB_RECTWIDTH(&rcSrc) < 0)
  6078. FlipRectHorizontal(&rcSrc);
  6079. if (BLITLIB_RECTHEIGHT(&rcSrc) < 0)
  6080. FlipRectVertical(&rcSrc);
  6081. if (BLITLIB_RECTWIDTH(&rcDst) < 0)
  6082. FlipRectHorizontal(&rcDst);
  6083. if (BLITLIB_RECTHEIGHT(&rcDst) < 0)
  6084. FlipRectVertical(&rcDst);
  6085. // Now check for rectangle intersection
  6086. return IntersectRect(&rc, &rcDst, &rcSrc);
  6087. }