/////////////////////////////////////////////////////////////////////// // // BitBlt.CXX - Contains the BitBlt Library functions // // Copyright (c) 1994 Microsoft Corporation // // Notes: // Conditional Compiliation Definitions: // DESKTOP = Penguin platform emulation on the Desktop // platform (32 bit). // PENGUIN = Penguin H/W platform support. // PULSAR = Pulsar platform support. // DDRAW = DirectDraw support // // History: // 10/18/94 - Scott Leatham Created it w/8BPP support only // 10/26/94 - Olivier Garamfalvi Rewrote blitting code // Added SRCINVERT ROP support // 10/30/94 - Olivier Garamfalvi Added 24 to 24 bit blitting // 05/08/95 - Myron Thomas Added 8+Alpha to 24 bit blitting // Added 24+Alpha to 24 bit blitting // 07/19/95 - Myron Thomas Ripped out SRCINVERT ROP support // 09/05/95 - Myron Thomas Added 24P to 8 bit blitting // 01/15/96 - Michael McDaniel changed conditional compilation // for DirectDraw // 04/16/96 - Michael McDaniel removed FillRect's test for // CLR_INVALID so Z-Buffer filling will work. // // /////////////////////////////////////////////////////////////////////// #include "precomp.hxx" #include "bltos.h" #include "blt0101.hxx" #include "blt0108.hxx" #include "blt0124.hxx" #include "blt0801.hxx" #include "blt0808.hxx" #include "blt0824.hxx" #include "blt0824p.hxx" #include "blt08a24.hxx" #include "blt8a24p.hxx" #include "blt1616.hxx" #include "blt1624.hxx" #include "blt1624p.hxx" #include "blt2401.hxx" #include "blt24p01.hxx" #include "blt24p08.hxx" #include "blt2408.hxx" #include "blt2424.hxx" #include "blt2424p.hxx" #include "blt24a24.hxx" #include "bt24a24p.hxx" #include "bt24p24p.hxx" #if 0 #if defined( WIN95 ) || defined(WINNT) #define DDRAW #endif // WIN95 #ifdef DDRAW #if defined ( WIN95 ) && !defined( NT_BUILD_ENVIRONMENT ) #include "..\ddraw\ddrawp.h" #else /* * This is parsed if NT build or win95 build under NT environment */ #include "..\..\ddraw\ddrawp.h" #endif #ifdef __cplusplus extern "C" { #endif // c++ #include "dpf.h" #ifdef __cplusplus } #endif // c++ #endif // DDRAW #endif /////////////////////////////////////////////////////////////////////// // // Local Declarations // /////////////////////////////////////////////////////////////////////// void FlipRectHorizontal (RECT *rc) { int temp; temp = rc->right; rc->right = rc->left; rc->left = temp; } void FlipRectVertical (RECT *rc) { int temp; temp = rc->bottom; rc->bottom = rc->top; rc->top = temp; } /////////////////////////////////////////////////////////////////////// // // Private BlitLib_BitBlt01to01 - // BitBlit from source bitmap to destination bitmap // with optional transparency and/or alpha blending using the // specified raster operation. // // Parameters: // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB // pDibBitsDst Pointer to the bits for the Destination DIB // prcDst Pointer to the Destination rectangle // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB // pDibBitsSrc Pointer to the bits for the Source DIB // prcSrc Pointer to the Source rectangle // crTransparent Tranparent color value // arAlpha Per-surface Alpha value // dwRop Raster Operation for the blit // // Return Value: // NO_ERROR or E_* value as specified in the .H file. // // Status: Incomplete // /////////////////////////////////////////////////////////////////////// SCODE BlitLib_BitBlt01to01(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst, PRECT prcDst, PDIBINFO pDibInfoSrc, PDIBBITS pDibBitsSrc, PRECT prcSrc, COLORREF crTransparent, ALPHAREF arAlpha, DWORD dwRop) { SCODE sc = NOERROR; int iNumSrcRows, iNumSrcCols, iBytesPerSrcScanLine, iSrcBitOffset, iNumDstRows, iNumDstCols, iBytesPerDstScanLine, iDstBitOffset, iHorizMirror = 1, iVertMirror = 1; BYTE *pbSrcScanLine, *pbDstScanLine; // alpha blending not currently supported in the 1 to 1 bpp blits if (arAlpha != ALPHA_INVALID) { return E_UNEXPECTED; // !!!! need better error codes } // normalize orientation of source and destination rectangles, and // compute sizes and relative orientations of source and destination rects if ((iNumSrcCols = BLITLIB_RECTWIDTH(prcSrc)) < 0) { iNumSrcCols = -iNumSrcCols; FlipRectHorizontal(prcSrc); FlipRectHorizontal(prcDst); } if ((iNumSrcRows = BLITLIB_RECTHEIGHT(prcSrc)) < 0) { iNumSrcRows = -iNumSrcRows; FlipRectVertical(prcSrc); FlipRectVertical(prcDst); } if ((iNumDstCols = BLITLIB_RECTWIDTH(prcDst)) < 0) { prcDst->left--; prcDst->right--; iNumDstCols = -iNumDstCols; iHorizMirror = -1; } if ((iNumDstRows = BLITLIB_RECTHEIGHT(prcDst)) < 0) { prcDst->top--; prcDst->bottom--; iNumDstRows = -iNumDstRows; iVertMirror = -1; } // compute pointers to the starting rows in the src and dst bitmaps // taking care to invert y values, since DIBs are upside-down pbSrcScanLine = (BYTE*) pDibBitsSrc + prcSrc->top * (iBytesPerSrcScanLine = DibWidthBytes(pDibInfoSrc)) + (prcSrc->left / 8); iSrcBitOffset = prcSrc->left % 8; pbDstScanLine = (BYTE*) pDibBitsDst + prcDst->top * (iBytesPerDstScanLine = DibWidthBytes(pDibInfoDst)) + (prcDst->left / 8); iDstBitOffset = prcDst->left % 8; // check to see if we need to worry about transparency if (crTransparent == CLR_INVALID) { // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { // check if we can do a straight copy vertically, // or if we have to stretch, shrink, or mirror #if 0 // OGaramfa - bug workaround for now, Hcopy versions seem to // have a problem with the last few pixels of each // scanline if ((iNumSrcRows == iNumDstRows) && (iVertMirror == 1)) { Blt01to01_NoTrans_Hcopy_SRCCOPY_Vcopy(pbSrcScanLine,iSrcBitOffset,iBytesPerSrcScanLine, pbDstScanLine,iDstBitOffset,iBytesPerDstScanLine, iNumDstCols,iNumDstRows); } else { Blt01to01_NoTrans_Hcopy_SRCCOPY_NoVcopy(pbSrcScanLine,iSrcBitOffset,iBytesPerSrcScanLine, iNumSrcRows,pbDstScanLine,iDstBitOffset, iBytesPerDstScanLine * iVertMirror, iNumDstCols,iNumDstRows); } #else Blt01to01_NoTrans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcBitOffset,iBytesPerSrcScanLine, iNumSrcCols,iNumSrcRows, pbDstScanLine,iDstBitOffset,iBytesPerDstScanLine * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror); #endif } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt01to01_NoTrans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcBitOffset,iBytesPerSrcScanLine, iNumSrcCols,iNumSrcRows, pbDstScanLine,iDstBitOffset,iBytesPerDstScanLine * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } else { BYTE bTransparentIndex = (BYTE)crTransparent; // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt01to01_Trans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcBitOffset,iBytesPerSrcScanLine, iNumSrcCols,iNumSrcRows, pbDstScanLine,iDstBitOffset,iBytesPerDstScanLine * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror, bTransparentIndex); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } return sc; } #ifndef DDRAW /////////////////////////////////////////////////////////////////////// // // Private BlitLib_BitBlt01to08 - // BitBlit from source bitmap to destination bitmap // with optional transparency and/or alpha blending using the // specified raster operation. // // Parameters: // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB // pDibBitsDst Pointer to the bits for the Destination DIB // prcDst Pointer to the Destination rectangle // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB // pDibBitsSrc Pointer to the bits for the Source DIB // prcSrc Pointer to the Source rectangle // crTransparent Tranparent color value // arAlpha Per-surface Alpha value // dwRop Raster Operation for the blit // // Return Value: // NO_ERROR or E_* value as specified in the .H file. // // Status: Incomplete // /////////////////////////////////////////////////////////////////////// SCODE BlitLib_BitBlt01to08(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst, PRECT prcDst, PDIBINFO pDibInfoSrc, PDIBBITS pDibBitsSrc, PRECT prcSrc, COLORREF crTransparent, ALPHAREF arAlpha, DWORD dwRop) { SCODE sc = NOERROR; int iNumSrcRows, iNumSrcCols, iBytesPerSrcScanLine, iSrcBitOffset, iNumDstRows, iNumDstCols, iDstScanLength, iHorizMirror = 1, iVertMirror = 1; BYTE *pbSrcScanLine, *pbDstScanLine, bOnColorIndex, bOffColorIndex; // alpha blending not currently supported in the 1 to 8 bpp blits if (arAlpha != ALPHA_INVALID) { return E_UNEXPECTED; // !!!! need better error codes } // normalize orientation of source and destination rectangles, and // compute sizes and relative orientations of source and destination rects if ((iNumSrcCols = BLITLIB_RECTWIDTH(prcSrc)) < 0) { iNumSrcCols = -iNumSrcCols; FlipRectHorizontal(prcSrc); FlipRectHorizontal(prcDst); } if ((iNumSrcRows = BLITLIB_RECTHEIGHT(prcSrc)) < 0) { iNumSrcRows = -iNumSrcRows; FlipRectVertical(prcSrc); FlipRectVertical(prcDst); } if ((iNumDstCols = BLITLIB_RECTWIDTH(prcDst)) < 0) { prcDst->left--; prcDst->right--; iNumDstCols = -iNumDstCols; iHorizMirror = -1; } if ((iNumDstRows = BLITLIB_RECTHEIGHT(prcDst)) < 0) { prcDst->top--; prcDst->bottom--; iNumDstRows = -iNumDstRows; iVertMirror = -1; } // get background and foreground palette indices out of src bitmap's header // !!!! this is a total hack and must be fixed! bOffColorIndex = BlitLib_PalIndexFromRGB( *((COLORREF*)(pDibInfoSrc->bmiColors)), (COLORREF*) pDibInfoDst->bmiColors,256); bOnColorIndex = BlitLib_PalIndexFromRGB( *((COLORREF*) (pDibInfoSrc->bmiColors) + 1), (COLORREF*) pDibInfoDst->bmiColors,256); // compute pointers to the starting rows in the src and dst bitmaps // taking care to invert y values, since DIBs are upside-down pbSrcScanLine = (BYTE*) pDibBitsSrc + prcSrc->top * (iBytesPerSrcScanLine = DibWidthBytes(pDibInfoSrc)) + (prcSrc->left / 8); iSrcBitOffset = prcSrc->left % 8; pbDstScanLine = (BYTE*) pDibBitsDst + prcDst->top * (iDstScanLength = DibWidthBytes(pDibInfoDst)) + prcDst->left; // check to see if we need to worry about transparency if (crTransparent == CLR_INVALID) { // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { // check if we can do a straight copy vertically, // or if we have to stretch, shrink, or mirror if ((iNumSrcRows == iNumDstRows) && (iVertMirror == 1)) { Blt01to08_NoTrans_Hcopy_SRCCOPY_Vcopy(pbSrcScanLine,iSrcBitOffset,iBytesPerSrcScanLine, pbDstScanLine,iDstScanLength, iNumDstCols,iNumDstRows, bOffColorIndex,bOnColorIndex); } else { Blt01to08_NoTrans_Hcopy_SRCCOPY_NoVcopy(pbSrcScanLine,iSrcBitOffset,iBytesPerSrcScanLine, iNumSrcRows,pbDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows, bOffColorIndex,bOnColorIndex); } } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt01to08_NoTrans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcBitOffset,iBytesPerSrcScanLine, iNumSrcCols,iNumSrcRows, pbDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror, bOffColorIndex,bOnColorIndex); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } else { BYTE bTransparentIndex = (BYTE)crTransparent; // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt01to08_Trans_Hcopy_SRCCOPY(pbSrcScanLine,iSrcBitOffset,iBytesPerSrcScanLine, iNumSrcRows,pbDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows, bTransparentIndex, bOffColorIndex,bOnColorIndex); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt01to08_Trans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcBitOffset,iBytesPerSrcScanLine, iNumSrcCols,iNumSrcRows, pbDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror, bTransparentIndex, bOffColorIndex,bOnColorIndex); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } return sc; } /////////////////////////////////////////////////////////////////////// // // Private BlitLib_BitBlt01to24 - // BitBlit from source bitmap to destination bitmap // with optional transparency and/or alpha blending using the // specified raster operation. // // Parameters: // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB // pDibBitsDst Pointer to the bits for the Destination DIB // prcDst Pointer to the Destination rectangle // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB // pDibBitsSrc Pointer to the bits for the Source DIB // prcSrc Pointer to the Source rectangle // crTransparent Tranparent color value // arAlpha Per-surface Alpha value // dwRop Raster Operation for the blit // // Return Value: // NO_ERROR or E_* value as specified in the .H file. // // Status: Incomplete // /////////////////////////////////////////////////////////////////////// SCODE BlitLib_BitBlt01to24(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst, PRECT prcDst, PDIBINFO pDibInfoSrc, PDIBBITS pDibBitsSrc, PRECT prcSrc, COLORREF crTransparent, ALPHAREF arAlpha, DWORD dwRop) { SCODE sc = NOERROR; int iNumSrcRows, iNumSrcCols, iBytesPerSrcScanLine, iSrcBitOffset, iNumDstRows, iNumDstCols, iDstScanLength, iHorizMirror = 1, iVertMirror = 1; BYTE *pbSrcScanLine; DWORD *pdDstScanLine; COLORREF crOnColor, crOffColor; // normalize orientation of source and destination rectangles, and // compute sizes and relative orientations of source and destination rects if ((iNumSrcCols = BLITLIB_RECTWIDTH(prcSrc)) < 0) { iNumSrcCols = -iNumSrcCols; FlipRectHorizontal(prcSrc); FlipRectHorizontal(prcDst); } if ((iNumSrcRows = BLITLIB_RECTHEIGHT(prcSrc)) < 0) { iNumSrcRows = -iNumSrcRows; FlipRectVertical(prcSrc); FlipRectVertical(prcDst); } if ((iNumDstCols = BLITLIB_RECTWIDTH(prcDst)) < 0) { prcDst->left--; prcDst->right--; iNumDstCols = -iNumDstCols; iHorizMirror = -1; } if ((iNumDstRows = BLITLIB_RECTHEIGHT(prcDst)) < 0) { prcDst->top--; prcDst->bottom--; iNumDstRows = -iNumDstRows; iVertMirror = -1; } // get background and foreground colors out of src bitmap's header crOffColor = *((COLORREF*) &(pDibInfoSrc->bmiColors[0])); crOnColor = *((COLORREF*) &(pDibInfoSrc->bmiColors[1])); // compute pointers to the starting rows in the src and dst bitmaps // taking care to invert y values, since DIBs are upside-down pbSrcScanLine = (BYTE*) pDibBitsSrc + prcSrc->top * (iBytesPerSrcScanLine = DibWidthBytes(pDibInfoSrc)) + (prcSrc->left / 8); iSrcBitOffset = prcSrc->left % 8; pdDstScanLine = (DWORD*) pDibBitsDst + prcDst->top * (iDstScanLength = DibWidthBytes(pDibInfoDst) / 4) + prcDst->left; // check if we're doing blending if (arAlpha == ALPHA_INVALID) { // check to see if we need to worry about transparency if (crTransparent == CLR_INVALID) { // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { // check if we can do a straight copy vertically, // or if we have to stretch, shrink, or mirror if ((iNumSrcRows == iNumDstRows) && (iVertMirror == 1)) { Blt01to24_NoBlend_NoTrans_Hcopy_SRCCOPY_Vcopy(pbSrcScanLine,iSrcBitOffset,iBytesPerSrcScanLine, pdDstScanLine,iDstScanLength, iNumDstCols,iNumDstRows, crOffColor,crOnColor); } else { Blt01to24_NoBlend_NoTrans_Hcopy_SRCCOPY_NoVcopy(pbSrcScanLine,iSrcBitOffset,iBytesPerSrcScanLine, iNumSrcRows,pdDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows, crOffColor,crOnColor); } } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt01to24_NoBlend_NoTrans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcBitOffset,iBytesPerSrcScanLine, iNumSrcCols,iNumSrcRows, pdDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror, crOffColor,crOnColor); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } else { BYTE bTransparentIndex = (BYTE)crTransparent; // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt01to24_NoBlend_Trans_Hcopy_SRCCOPY(pbSrcScanLine,iSrcBitOffset,iBytesPerSrcScanLine, iNumSrcRows,pdDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows, bTransparentIndex, crOffColor,crOnColor); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt01to24_NoBlend_Trans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcBitOffset,iBytesPerSrcScanLine, iNumSrcCols,iNumSrcRows, pdDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror, bTransparentIndex, crOffColor,crOnColor); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } } else { // doing alpha blending // if alpha value is zero, we do no work since the source bitmap // contributes nothing to the destination bitmap if (!(arAlpha & ALPHA_MASK)) { return sc; } // check to see if we need to worry about transparency if (crTransparent == CLR_INVALID) { // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt01to24_Blend_NoTrans_Hcopy_SRCCOPY(pbSrcScanLine,iSrcBitOffset,iBytesPerSrcScanLine, iNumSrcRows,pdDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows, arAlpha,crOffColor,crOnColor); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt01to24_Blend_NoTrans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcBitOffset,iBytesPerSrcScanLine, iNumSrcCols,iNumSrcRows, pdDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror, arAlpha,crOffColor,crOnColor); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } else { BYTE bTransparentIndex = (BYTE)crTransparent; // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt01to24_Blend_Trans_Hcopy_SRCCOPY(pbSrcScanLine,iSrcBitOffset,iBytesPerSrcScanLine, iNumSrcRows,pdDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows, bTransparentIndex, arAlpha,crOffColor,crOnColor); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt01to24_Blend_Trans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcBitOffset,iBytesPerSrcScanLine, iNumSrcCols,iNumSrcRows, pdDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror, bTransparentIndex, arAlpha,crOffColor,crOnColor); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } } return sc; } /////////////////////////////////////////////////////////////////////// // // Private BlitLib_BitBlt08to01 - // BitBlit from source bitmap to destination bitmap // with optional transparency and/or alpha blending using the // specified raster operation. // // Parameters: // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB // pDibBitsDst Pointer to the bits for the Destination DIB // prcDst Pointer to the Destination rectangle // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB // pDibBitsSrc Pointer to the bits for the Source DIB // prcSrc Pointer to the Source rectangle // crTransparent Tranparent color value // arAlpha Per-surface Alpha value // dwRop Raster Operation for the blit // // Return Value: // NO_ERROR or E_* value as specified in the .H file. // // Status: Incomplete // /////////////////////////////////////////////////////////////////////// SCODE BlitLib_BitBlt08to01(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst, PRECT prcDst, PDIBINFO pDibInfoSrc, PDIBBITS pDibBitsSrc, PRECT prcSrc, COLORREF crTransparent, ALPHAREF arAlpha, DWORD dwRop) { SCODE sc = NOERROR; int iNumSrcRows, iNumSrcCols, iSrcScanLength, iNumDstRows, iNumDstCols, iBytesPerDstScanLine, iHorizMirror = 1, iVertMirror = 1, iDstBitOffset; BYTE *pbSrcScanLine, *pbDstScanLine, bFillVal; // alpha blending not currently supported in the 8 to 1 bpp blits if (arAlpha != ALPHA_INVALID) { return E_UNEXPECTED; // !!!! need better error codes } // the only ROPs supported are BLACKNESS and WHITENESS if (dwRop == BLACKNESS) { bFillVal = 0; } else if (dwRop == WHITENESS) { bFillVal = 0xFF; } else { return E_UNEXPECTED; // !!!! need better error codes } // normalize orientation of source and destination rectangles, and // compute sizes and relative orientations of source and destination rects if ((iNumSrcCols = BLITLIB_RECTWIDTH(prcSrc)) < 0) { iNumSrcCols = -iNumSrcCols; FlipRectHorizontal(prcSrc); FlipRectHorizontal(prcDst); } if ((iNumSrcRows = BLITLIB_RECTHEIGHT(prcSrc)) < 0) { iNumSrcRows = -iNumSrcRows; FlipRectVertical(prcSrc); FlipRectVertical(prcDst); } if ((iNumDstCols = BLITLIB_RECTWIDTH(prcDst)) < 0) { prcDst->left--; prcDst->right--; iNumDstCols = -iNumDstCols; iHorizMirror = -1; } if ((iNumDstRows = BLITLIB_RECTHEIGHT(prcDst)) < 0) { prcDst->top--; prcDst->bottom--; iNumDstRows = -iNumDstRows; iVertMirror = -1; } // compute pointers to the starting rows in the src and dst bitmaps // taking care to invert y values, since DIBs are upside-down pbSrcScanLine = (BYTE*) pDibBitsSrc + prcSrc->top * (iSrcScanLength = DibWidthBytes(pDibInfoSrc)) + prcSrc->left; pbDstScanLine = (BYTE*) pDibBitsDst + prcDst->top * (iBytesPerDstScanLine = DibWidthBytes(pDibInfoDst)) + (prcDst->left / 8); iDstBitOffset = prcDst->left % 8; // check to see if we need to worry about transparency if (crTransparent == CLR_INVALID) { // no transparency plus a constant ROP equals a rectangle fill! // first we have to normalize destination rectangle orientation - // FillRect01() expects it if (BLITLIB_RECTWIDTH(prcDst) < 0) { prcDst->left++; prcDst->right++; FlipRectHorizontal(prcDst); } if (BLITLIB_RECTHEIGHT(prcDst) < 0) { prcDst->top--; prcDst->bottom--; FlipRectVertical(prcDst); } sc |= BlitLib_FillRect01(pDibInfoDst,pDibBitsDst,prcDst->left,prcDst->top, iNumDstCols,iNumDstRows,bFillVal); } else { BYTE bTransparentIndex = (BYTE)crTransparent; // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { Blt08to01_Trans_Hcopy_ConstRop(pbSrcScanLine,iSrcScanLength,iNumSrcRows, pbDstScanLine,iDstBitOffset, iBytesPerDstScanLine * iVertMirror, iNumDstCols,iNumDstRows,bTransparentIndex, bFillVal); } else { Blt08to01_Trans_NoHcopy_ConstRop(pbSrcScanLine,iSrcScanLength,iNumSrcCols, iNumSrcRows,pbDstScanLine,iDstBitOffset, iBytesPerDstScanLine * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror, bTransparentIndex,bFillVal); } } return sc; } #endif // DDRAW /////////////////////////////////////////////////////////////////////// // // Private BlitLib_BitBlt08to08 - // BitBlit from source bitmap to destination bitmap // with optional transparency and/or alpha blending using the // specified raster operation. // // Parameters: // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB // pDibBitsDst Pointer to the bits for the Destination DIB // prcDst Pointer to the Destination rectangle // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB // pDibBitsSrc Pointer to the bits for the Source DIB // prcSrc Pointer to the Source rectangle // crTransparent Tranparent color value // arAlpha Per-surface Alpha value // dwRop Raster Operation for the blit // // Return Value: // NO_ERROR or E_* value as specified in the .H file. // // Status: Incomplete // /////////////////////////////////////////////////////////////////////// SCODE BlitLib_BitBlt08to08(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst, PRECT prcDst, PDIBINFO pDibInfoSrc, PDIBBITS pDibBitsSrc, PRECT prcSrc, COLORREF crTransparent, ALPHAREF arAlpha, DWORD dwRop) { SCODE sc = NOERROR; int iNumSrcRows, iNumSrcCols, iSrcScanLength, iNumDstRows, iNumDstCols, iDstScanLength, iHorizMirror = 1, iVertMirror = 1; BYTE *pbSrcScanLine, *pbDstScanLine; // alpha blending not currently supported in the 8 to 8 bpp blits if (arAlpha != ALPHA_INVALID) { return E_UNEXPECTED; // !!!! need better error codes } // If the bitmaps overlap, we need to use overlapping code if(BlitLib_Detect_Intersection(pDibBitsDst, prcDst, pDibBitsSrc, prcSrc)) return BlitLib_BitBlt08to08_Intersect(pDibInfoDst, pDibBitsDst, prcDst, pDibInfoSrc, pDibBitsSrc, prcSrc, crTransparent, dwRop); // normalize orientation of source and destination rectangles, and // compute sizes and relative orientations of source and destination rects if ((iNumSrcCols = BLITLIB_RECTWIDTH(prcSrc)) < 0) { iNumSrcCols = -iNumSrcCols; FlipRectHorizontal(prcSrc); FlipRectHorizontal(prcDst); } if ((iNumSrcRows = BLITLIB_RECTHEIGHT(prcSrc)) < 0) { iNumSrcRows = -iNumSrcRows; FlipRectVertical(prcSrc); FlipRectVertical(prcDst); } if ((iNumDstCols = BLITLIB_RECTWIDTH(prcDst)) < 0) { prcDst->left--; prcDst->right--; iNumDstCols = -iNumDstCols; iHorizMirror = -1; } if ((iNumDstRows = BLITLIB_RECTHEIGHT(prcDst)) < 0) { prcDst->top--; prcDst->bottom--; iNumDstRows = -iNumDstRows; iVertMirror = -1; } // compute pointers to the starting rows in the src and dst bitmaps // taking care to invert y values, since DIBs are upside-down pbSrcScanLine = (BYTE*) pDibBitsSrc + (prcSrc->top) * (iSrcScanLength = DibWidthBytes(pDibInfoSrc)) + prcSrc->left; pbDstScanLine = (BYTE*) pDibBitsDst + (prcDst->top) * (iDstScanLength = DibWidthBytes(pDibInfoDst)) + prcDst->left; // check to see if we need to worry about transparency if (crTransparent == CLR_INVALID) { // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { // check if we can do a straight copy vertically, // or if we have to stretch, shrink, or mirror if ((iNumSrcRows == iNumDstRows) && (iVertMirror == 1)) { Blt08to08_NoTrans_Hcopy_SRCCOPY_Vcopy(pbSrcScanLine,iSrcScanLength, pbDstScanLine,iDstScanLength, iNumDstCols,iNumDstRows); } else { Blt08to08_NoTrans_Hcopy_SRCCOPY_NoVcopy(pbSrcScanLine,iSrcScanLength, iNumSrcRows,pbDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows); } } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt08to08_NoTrans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pbDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } else { // myronth -- changed for DDraw Transparent colors (always a palette index) BYTE bTransparentIndex = (BYTE)crTransparent; // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt08to08_Trans_Hcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength, iNumSrcRows,pbDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows, bTransparentIndex); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt08to08_Trans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pbDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror, bTransparentIndex); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } return sc; } /////////////////////////////////////////////////////////////////////// // // Private BlitLib_BitBlt08to08_Intersect - // BitBlit from source bitmap to destination bitmap (and these // bitmaps overlap each other) with optional transparency and/or // alpha blending using the specified raster operation. // // Parameters: // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB // pDibBitsDst Pointer to the bits for the Destination DIB // prcDst Pointer to the Destination rectangle // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB // pDibBitsSrc Pointer to the bits for the Source DIB // prcSrc Pointer to the Source rectangle // crTransparent Tranparent color value // arAlpha Per-surface Alpha value // dwRop Raster Operation for the blit // // Return Value: // NO_ERROR or E_* value as specified in the .H file. // // Status: Incomplete // /////////////////////////////////////////////////////////////////////// SCODE BlitLib_BitBlt08to08_Intersect(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst, PRECT prcDst, PDIBINFO pDibInfoSrc, PDIBBITS pDibBitsSrc, PRECT prcSrc, COLORREF crTransparent, DWORD dwRop) { SCODE sc = NOERROR; int iNumSrcRows, iNumSrcCols, iSrcScanLength, iNumDstRows, iNumDstCols, iDstScanLength, iHorizMirror = 1, iVertMirror = 1; BYTE *pbSrcScanLine, *pbDstScanLine, *pbTempScanLine, bTransparentIndex; PDIBBITS pDibBitsTemp; // normalize orientation of source and destination rectangles, and // compute sizes and relative orientations of source and destination rects if ((iNumSrcCols = BLITLIB_RECTWIDTH(prcSrc)) < 0) { iNumSrcCols = -iNumSrcCols; FlipRectHorizontal(prcSrc); FlipRectHorizontal(prcDst); } if ((iNumSrcRows = BLITLIB_RECTHEIGHT(prcSrc)) < 0) { iNumSrcRows = -iNumSrcRows; FlipRectVertical(prcSrc); FlipRectVertical(prcDst); } if ((iNumDstCols = BLITLIB_RECTWIDTH(prcDst)) < 0) { prcDst->left--; prcDst->right--; iNumDstCols = -iNumDstCols; iHorizMirror = -1; } if ((iNumDstRows = BLITLIB_RECTHEIGHT(prcDst)) < 0) { prcDst->top--; prcDst->bottom--; iNumDstRows = -iNumDstRows; iVertMirror = -1; } // We aren't currently support any ROP's besides SRCCOPY if(dwRop != SRCCOPY) return E_UNEXPECTED; // // Here are all the stretching and mirroring blits for overlapping rects // // REVIEW!!! -- The following code could be optimized for the caching // cases. Currently, it allocates a second bitmap that is the same // size as the original destination, and then uses the original blit // rectangle to do the caching. To save space, this blit should // eventually be changed to only allocate the size of the overlapped // rectangle, and the blit rects should be adjusted accordingly. // Check if we are stretching (horiz or vert), or if we are mirroring -- // In all of these cases, we must create a cache bitmap and double blit if((iNumDstCols != iNumSrcCols) || (iNumDstRows != iNumSrcRows) || (iHorizMirror != 1) || (iVertMirror != 1)) { // Allocate memory for the cache bitmap -- We will blit into this // temporary bitmap and then re-blit back to the original source pDibBitsTemp = (PDIBBITS)osMemAlloc(DibSizeImage((LPBITMAPINFOHEADER)pDibInfoDst)); if (pDibBitsTemp == NULL) return E_UNEXPECTED; // compute pointers to the starting rows in the src and temp bitmaps pbSrcScanLine = (BYTE*) pDibBitsSrc + (prcSrc->top) * (iSrcScanLength = DibWidthBytes(pDibInfoSrc)) + prcSrc->left; pbTempScanLine = (BYTE*) pDibBitsTemp + (prcDst->top) * (iDstScanLength = DibWidthBytes(pDibInfoDst)) + prcDst->left; // check if we can do a straight copy from src row to dst row if((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)){ // check if we can do a straight copy vertically, // or if we have to stretch, shrink, or mirror if ((iNumSrcRows == iNumDstRows) && (iVertMirror == 1)) { Blt08to08_NoTrans_Hcopy_SRCCOPY_Vcopy(pbSrcScanLine,iSrcScanLength, pbTempScanLine,iDstScanLength, iNumDstCols,iNumDstRows); } else { Blt08to08_NoTrans_Hcopy_SRCCOPY_NoVcopy(pbSrcScanLine,iSrcScanLength, iNumSrcRows,pbTempScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows); } } else { Blt08to08_NoTrans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pbTempScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror); } // Recalculate the scan line pointers for the second blit if(BLITLIB_RECTWIDTH(prcDst) < 0){ prcDst->left++; prcDst->right++; FlipRectHorizontal(prcDst); } if(BLITLIB_RECTHEIGHT(prcDst) < 0){ prcDst->top++; prcDst->bottom++; FlipRectVertical(prcDst); } // compute pointers to the starting rows in the temp and dest bitmaps pbTempScanLine = (BYTE*) pDibBitsTemp + (prcDst->top) * (iDstScanLength = DibWidthBytes(pDibInfoDst)) + prcDst->left; pbDstScanLine = (BYTE*) pDibBitsDst + (prcDst->top) * (iDstScanLength = DibWidthBytes(pDibInfoDst)) + prcDst->left; // Now blit from the temporary bitmap back to the original source, // checking for transparency if necessary if(crTransparent == CLR_INVALID){ Blt08to08_NoTrans_Hcopy_SRCCOPY_Vcopy(pbTempScanLine,iDstScanLength, pbDstScanLine,iDstScanLength, iNumDstCols,iNumDstRows); } else{ bTransparentIndex = (BYTE)crTransparent; Blt08to08_Trans_Hcopy_SRCCOPY(pbTempScanLine,iDstScanLength, iNumDstRows,pbDstScanLine, iDstScanLength, iNumDstCols, iNumDstRows, bTransparentIndex); } // Free the memory from the temporary bitmap if(pDibBitsTemp) osMemFree(pDibBitsTemp); return sc; } // // Here are all the non-stretching and non-mirroring blits for overlapping rects // // check to see if we need to worry about transparency if (crTransparent == CLR_INVALID) { // Simplest case, they are the same rectangles if((prcDst->left == prcSrc->left) && (prcDst->top == prcSrc->top) && (prcDst->right == prcSrc->right) && (prcDst->bottom == prcSrc->bottom)) return sc; // Next case, the destination rectangle is vertically greater in // magnitude than the source rectangle else if(prcDst->top > prcSrc->top){ // compute pointers to the starting rows in the src and dst bitmaps // taking care to decrement the bottom rect edge since we are // going from bottom to top pbSrcScanLine = (BYTE*) pDibBitsSrc + (prcSrc->bottom - 1) * (iSrcScanLength = DibWidthBytes(pDibInfoSrc)) + prcSrc->left; pbDstScanLine = (BYTE*) pDibBitsDst + (prcDst->bottom - 1) * (iDstScanLength = DibWidthBytes(pDibInfoDst)) + prcDst->left; // Call the appropriate blit Blt08to08_LeftToRight_BottomToTop_SRCCOPY(pbSrcScanLine, iSrcScanLength, pbDstScanLine, iDstScanLength, iNumDstCols, iNumDstRows); } // Next case, the destination rectangle is horizontally less than // or equal in magnitude to the source rectangle else if(prcDst->left <= prcSrc->left){ // compute pointers to the starting rows in the src and dst bitmaps pbSrcScanLine = (BYTE*) pDibBitsSrc + (prcSrc->top) * (iSrcScanLength = DibWidthBytes(pDibInfoSrc)) + prcSrc->left; pbDstScanLine = (BYTE*) pDibBitsDst + (prcDst->top) * (iDstScanLength = DibWidthBytes(pDibInfoDst)) + prcDst->left; // Call the appropriate blit Blt08to08_NoTrans_Hcopy_SRCCOPY_Vcopy(pbSrcScanLine,iSrcScanLength, pbDstScanLine,iDstScanLength, iNumDstCols,iNumDstRows); } // Last case, the destination rectangle is horizontally greater // in magnitude than the source rectangle else{ // compute pointers to the starting rows in the src and dst bitmaps // taking care to decrement the right rect edge since we are // going from right to left pbSrcScanLine = (BYTE*) pDibBitsSrc + (prcSrc->top) * (iSrcScanLength = DibWidthBytes(pDibInfoSrc)) + (prcSrc->right - 1); pbDstScanLine = (BYTE*) pDibBitsDst + (prcDst->top) * (iDstScanLength = DibWidthBytes(pDibInfoDst)) + (prcDst->right - 1); // Call the appropriate blit Blt08to08_RightToLeft_TopToBottom_SRCCOPY(pbSrcScanLine, iSrcScanLength, pbDstScanLine, iDstScanLength, iNumDstCols, iNumDstRows); } } else{ bTransparentIndex = (BYTE)crTransparent; // Simplest case, they are the same rectangles if((prcDst->left == prcSrc->left) && (prcDst->top == prcSrc->top) && (prcDst->right == prcSrc->right) && (prcDst->bottom == prcSrc->bottom)) return sc; // Next case, the destination rectangle is vertically greater in // magnitude than the source rectangle else if(prcDst->top > prcSrc->top){ // compute pointers to the starting rows in the src and dst bitmaps // taking care to decrement the bottom rect edge since we are // going from bottom to top pbSrcScanLine = (BYTE*) pDibBitsSrc + (prcSrc->bottom - 1) * (iSrcScanLength = DibWidthBytes(pDibInfoSrc)) + prcSrc->left; pbDstScanLine = (BYTE*) pDibBitsDst + (prcDst->bottom - 1) * (iDstScanLength = DibWidthBytes(pDibInfoDst)) + prcDst->left; // Call the appropriate blit Blt08to08_LeftToRight_BottomToTop_Trans_SRCCOPY(pbSrcScanLine, iSrcScanLength, pbDstScanLine, iDstScanLength, iNumDstCols, iNumDstRows, bTransparentIndex); } // Next case, the destination rectangle is horizontally less than // or equal in magnitude to the source rectangle else if(prcDst->left <= prcSrc->left){ // compute pointers to the starting rows in the src and dst bitmaps pbSrcScanLine = (BYTE*) pDibBitsSrc + (prcSrc->top) * (iSrcScanLength = DibWidthBytes(pDibInfoSrc)) + prcSrc->left; pbDstScanLine = (BYTE*) pDibBitsDst + (prcDst->top) * (iDstScanLength = DibWidthBytes(pDibInfoDst)) + prcDst->left; // Call the appropriate blit Blt08to08_Trans_Hcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength, iNumSrcRows, pbDstScanLine, iDstScanLength, iNumDstCols, iNumDstRows, bTransparentIndex); } // Last case, the destination rectangle is horizontally greater // in magnitude than the source rectangle else{ // compute pointers to the starting rows in the src and dst bitmaps // taking care to decrement the right rect edge since we are // going from right to left pbSrcScanLine = (BYTE*) pDibBitsSrc + (prcSrc->top) * (iSrcScanLength = DibWidthBytes(pDibInfoSrc)) + (prcSrc->right - 1); pbDstScanLine = (BYTE*) pDibBitsDst + (prcDst->top) * (iDstScanLength = DibWidthBytes(pDibInfoDst)) + (prcDst->right - 1); // Call the appropriate blit Blt08to08_RightToLeft_TopToBottom_Trans_SRCCOPY(pbSrcScanLine, iSrcScanLength, pbDstScanLine, iDstScanLength, iNumDstCols, iNumDstRows, bTransparentIndex); } } return sc; } #ifndef DDRAW /////////////////////////////////////////////////////////////////////// // // Private BlitLib_BitBlt08to24 - // BitBlit from source bitmap to Dstination bitmap // with optional transparency and/or alpha blending using the // specified raster operation. // // Parameters: // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB // pDibBitsDst Pointer to the bits for the Destination DIB // prcDst Pointer to the Destination rectangle // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB // pDibBitsSrc Pointer to the bits for the Source DIB // prcSrc Pointer to the Source rectangle // crTransparent Tranparent color value // arAlpha Per-surface Alpha value // dwRop Raster Operation for the blit // // Return Value: // NO_ERROR or E_* value as specified in the .H file. // // Status: Incomplete // /////////////////////////////////////////////////////////////////////// SCODE BlitLib_BitBlt08to24(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst, PRECT prcDst, PDIBINFO pDibInfoSrc, PDIBBITS pDibBitsSrc, PRECT prcSrc, COLORREF crTransparent, ALPHAREF arAlpha, DWORD dwRop) { SCODE sc = NOERROR; int iNumSrcRows, iNumSrcCols, iSrcScanLength, iNumDstRows, iNumDstCols, iDstScanLength, iHorizMirror = 1, iVertMirror = 1; BYTE *pbSrcScanLine; DWORD *pdDstScanLine; // normalize orientation of source and destination rectangles, and // compute sizes and relative orientations of source and destination rects if ((iNumSrcCols = BLITLIB_RECTWIDTH(prcSrc)) < 0) { iNumSrcCols = -iNumSrcCols; FlipRectHorizontal(prcSrc); FlipRectHorizontal(prcDst); } if ((iNumSrcRows = BLITLIB_RECTHEIGHT(prcSrc)) < 0) { iNumSrcRows = -iNumSrcRows; FlipRectVertical(prcSrc); FlipRectVertical(prcDst); } if ((iNumDstCols = BLITLIB_RECTWIDTH(prcDst)) < 0) { prcDst->left--; prcDst->right--; iNumDstCols = -iNumDstCols; iHorizMirror = -1; } if ((iNumDstRows = BLITLIB_RECTHEIGHT(prcDst)) < 0) { prcDst->top--; prcDst->bottom--; iNumDstRows = -iNumDstRows; iVertMirror = -1; } // compute pointers to the starting rows in the src and dst bitmaps // taking care to invert y values, since DIBs are upside-down pbSrcScanLine = (BYTE*) pDibBitsSrc + prcSrc->top * (iSrcScanLength = DibWidthBytes(pDibInfoSrc)) + prcSrc->left; pdDstScanLine = (DWORD*) pDibBitsDst + prcDst->top * (iDstScanLength = DibWidthBytes(pDibInfoDst) / 4) + prcDst->left; // check if we're doing blending if (arAlpha == ALPHA_INVALID) { // no blending desired // check to see if we need to worry about transparency if (crTransparent == CLR_INVALID) { // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { // check if we can do a straight copy vertically, // or if we have to stretch, shrink, or mirror if ((iNumSrcRows == iNumDstRows) && (iVertMirror == 1)) { Blt08to24_NoBlend_NoTrans_Hcopy_SRCCOPY_Vcopy(pbSrcScanLine,iSrcScanLength, pdDstScanLine,iDstScanLength, iNumDstCols,iNumDstRows,(COLORREF*) pDibInfoSrc->bmiColors); } else { Blt08to24_NoBlend_NoTrans_Hcopy_SRCCOPY_NoVcopy(pbSrcScanLine,iSrcScanLength, iNumSrcRows,pdDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,(COLORREF*) pDibInfoSrc->bmiColors); } } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // we have to stretch or shrink horizontally // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt08to24_NoBlend_NoTrans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pdDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror,(COLORREF*) pDibInfoSrc->bmiColors); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } else { BYTE bTransparentIndex = (BYTE)crTransparent; // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt08to24_NoBlend_Trans_Hcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength, iNumSrcRows,pdDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows, bTransparentIndex,(COLORREF*) pDibInfoSrc->bmiColors); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // we have to shrink or stretch horizontally // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt08to24_NoBlend_Trans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pdDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror, bTransparentIndex,(COLORREF*) pDibInfoSrc->bmiColors); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } } else { // blending desired // if alpha value is zero, we do no work since the source bitmap // contributes nothing to the destination bitmap if (!(arAlpha & ALPHA_MASK)) { return sc; } // check to see if we need to worry about transparency if (crTransparent == CLR_INVALID) { // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt08to24_Blend_NoTrans_Hcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength, iNumSrcRows,pdDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows, arAlpha,(COLORREF*) pDibInfoSrc->bmiColors); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // we need to shrink or stretch horizontally // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt08to24_Blend_NoTrans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pdDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror, arAlpha,(COLORREF*) pDibInfoSrc->bmiColors); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } else { BYTE bTransparentIndex = (BYTE)crTransparent; // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt08to24_Blend_Trans_Hcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength, iNumSrcRows,pdDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows, bTransparentIndex,arAlpha,(COLORREF*) pDibInfoSrc->bmiColors); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // we have to shrink or stretch horizontally // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt08to24_Blend_Trans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pdDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror, bTransparentIndex,arAlpha,(COLORREF*) pDibInfoSrc->bmiColors); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } } return sc; } /////////////////////////////////////////////////////////////////////// // // Private BlitLib_BitBlt08to24P - // BitBlit from source bitmap to Dstination bitmap // with optional transparency and/or alpha blending using the // specified raster operation. // // Parameters: // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB // pDibBitsDst Pointer to the bits for the Destination DIB // prcDst Pointer to the Destination rectangle // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB // pDibBitsSrc Pointer to the bits for the Source DIB // prcSrc Pointer to the Source rectangle // crTransparent Tranparent color value // arAlpha Per-surface Alpha value // dwRop Raster Operation for the blit // // Return Value: // NO_ERROR or E_* value as specified in the .H file. // // Status: Incomplete // /////////////////////////////////////////////////////////////////////// SCODE BlitLib_BitBlt08to24P(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst, PRECT prcDst, PDIBINFO pDibInfoSrc, PDIBBITS pDibBitsSrc, PRECT prcSrc, COLORREF crTransparent, ALPHAREF arAlpha, DWORD dwRop) { SCODE sc = NOERROR; int iNumSrcRows, iNumSrcCols, iSrcScanLength, iNumDstRows, iNumDstCols, iDstScanLength, iHorizMirror = 1, iVertMirror = 1; BYTE *pbSrcScanLine, *pdDstScanLine; // normalize orientation of source and destination rectangles, and // compute sizes and relative orientations of source and destination rects if ((iNumSrcCols = BLITLIB_RECTWIDTH(prcSrc)) < 0) { iNumSrcCols = -iNumSrcCols; FlipRectHorizontal(prcSrc); FlipRectHorizontal(prcDst); } if ((iNumSrcRows = BLITLIB_RECTHEIGHT(prcSrc)) < 0) { iNumSrcRows = -iNumSrcRows; FlipRectVertical(prcSrc); FlipRectVertical(prcDst); } if ((iNumDstCols = BLITLIB_RECTWIDTH(prcDst)) < 0) { prcDst->left--; prcDst->right--; iNumDstCols = -iNumDstCols; iHorizMirror = -1; } if ((iNumDstRows = BLITLIB_RECTHEIGHT(prcDst)) < 0) { prcDst->top--; prcDst->bottom--; iNumDstRows = -iNumDstRows; iVertMirror = -1; } // compute pointers to the starting rows in the src and dst bitmaps // taking care to invert y values, since DIBs are upside-down pbSrcScanLine = (BYTE *) pDibBitsSrc + prcSrc->top * (iSrcScanLength = DibWidthBytes(pDibInfoSrc)) + prcSrc->left; pdDstScanLine = (BYTE *) pDibBitsDst + prcDst->top * (iDstScanLength = DibWidthBytes(pDibInfoDst)) + (prcDst->left * 3); // check if we're doing blending if (arAlpha == ALPHA_INVALID) { // no blending desired // check to see if we need to worry about transparency if (crTransparent == CLR_INVALID) { // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { // check if we can do a straight copy vertically, // or if we have to stretch, shrink, or mirror if ((iNumSrcRows == iNumDstRows) && (iVertMirror == 1)) { Blt08to24P_NoBlend_NoTrans_Hcopy_SRCCOPY_Vcopy(pbSrcScanLine,iSrcScanLength, pdDstScanLine,iDstScanLength, iNumDstCols,iNumDstRows,(COLORREF*) pDibInfoSrc->bmiColors); } else { Blt08to24P_NoBlend_NoTrans_Hcopy_SRCCOPY_NoVcopy(pbSrcScanLine,iSrcScanLength, iNumSrcRows,pdDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,(COLORREF*) pDibInfoSrc->bmiColors); } } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // we have to stretch or shrink horizontally // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt08to24P_NoBlend_NoTrans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pdDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror,(COLORREF*) pDibInfoSrc->bmiColors); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } else { BYTE bTransparentIndex = (BYTE)crTransparent; // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt08to24P_NoBlend_Trans_Hcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength, iNumSrcRows,pdDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows, bTransparentIndex,(COLORREF*) pDibInfoSrc->bmiColors); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // we have to shrink or stretch horizontally // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt08to24P_NoBlend_Trans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pdDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror, bTransparentIndex,(COLORREF*) pDibInfoSrc->bmiColors); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } } else { // blending desired // if alpha value is zero, we do no work since the source bitmap // contributes nothing to the destination bitmap if (!(arAlpha & ALPHA_MASK)) { return sc; } // check to see if we need to worry about transparency if (crTransparent == CLR_INVALID) { // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt08to24P_Blend_NoTrans_Hcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength, iNumSrcRows,pdDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows, arAlpha,(COLORREF*) pDibInfoSrc->bmiColors); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // we need to shrink or stretch horizontally // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt08to24P_Blend_NoTrans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pdDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror, arAlpha,(COLORREF*) pDibInfoSrc->bmiColors); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } else { BYTE bTransparentIndex = (BYTE)crTransparent; // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt08to24P_Blend_Trans_Hcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength, iNumSrcRows,pdDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows, bTransparentIndex,arAlpha,(COLORREF*) pDibInfoSrc->bmiColors); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // we have to shrink or stretch horizontally // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt08to24P_Blend_Trans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pdDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror, bTransparentIndex,arAlpha,(COLORREF*) pDibInfoSrc->bmiColors); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } } return sc; } /////////////////////////////////////////////////////////////////////// // // Private BlitLib_BitBlt08Ato24 - // BitBlit from source bitmap to Dstination bitmap // with optional transparency and/or alpha blending using the // specified raster operation. // // Parameters: // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB // pDibBitsDst Pointer to the bits for the Destination DIB // prcDst Pointer to the Destination rectangle // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB // pDibBitsSrc Pointer to the bits for the Source DIB // prcSrc Pointer to the Source rectangle // crTransparent Tranparent color value // arAlpha Per-surface Alpha value // dwRop Raster Operation for the blit // // Return Value: // NO_ERROR or E_* value as specified in the .H file. // // Status: Incomplete // /////////////////////////////////////////////////////////////////////// SCODE BlitLib_BitBlt08Ato24(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst, PRECT prcDst, PDIBINFO pDibInfoSrc, PDIBBITS pDibBitsSrc, PRECT prcSrc, COLORREF crTransparent, ALPHAREF arAlpha, DWORD dwRop) { SCODE sc = NOERROR; int iNumSrcRows, iNumSrcCols, iSrcScanLength, iNumDstRows, iNumDstCols, iDstScanLength, iHorizMirror = 1, iVertMirror = 1; BYTE *pbSrcScanLine; DWORD *pdDstScanLine; // normalize orientation of source and destination rectangles, and // compute sizes and relative orientations of source and destination rects if ((iNumSrcCols = BLITLIB_RECTWIDTH(prcSrc)) < 0) { iNumSrcCols = -iNumSrcCols; FlipRectHorizontal(prcSrc); FlipRectHorizontal(prcDst); } if ((iNumSrcRows = BLITLIB_RECTHEIGHT(prcSrc)) < 0) { iNumSrcRows = -iNumSrcRows; FlipRectVertical(prcSrc); FlipRectVertical(prcDst); } if ((iNumDstCols = BLITLIB_RECTWIDTH(prcDst)) < 0) { prcDst->left--; prcDst->right--; iNumDstCols = -iNumDstCols; iHorizMirror = -1; } if ((iNumDstRows = BLITLIB_RECTHEIGHT(prcDst)) < 0) { prcDst->top--; prcDst->bottom--; iNumDstRows = -iNumDstRows; iVertMirror = -1; } // compute pointers to the starting rows in the src and dst bitmaps // taking care to invert y values, since DIBs are upside-down pbSrcScanLine = (BYTE*) pDibBitsSrc + prcSrc->top * (iSrcScanLength = DibWidthBytes(pDibInfoSrc)) + prcSrc->left; pdDstScanLine = (DWORD*) pDibBitsDst + prcDst->top * (iDstScanLength = DibWidthBytes(pDibInfoDst) / 4) + prcDst->left; // check if we're doing blending if (arAlpha == ALPHA_INVALID) { // no blending desired // check to see if we need to worry about transparency if (crTransparent == CLR_INVALID) { // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { // check if we can do a straight copy vertically, // or if we have to stretch, shrink, or mirror if ((iNumSrcRows == iNumDstRows) && (iVertMirror == 1)) { Blt08Ato24_NoBlend_NoTrans_Hcopy_SRCCOPY_Vcopy(pbSrcScanLine,iSrcScanLength, pdDstScanLine,iDstScanLength, iNumDstCols,iNumDstRows,(COLORREF*) pDibInfoSrc->bmiColors); } else { Blt08Ato24_NoBlend_NoTrans_Hcopy_SRCCOPY_NoVcopy(pbSrcScanLine,iSrcScanLength, iNumSrcRows,pdDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,(COLORREF*) pDibInfoSrc->bmiColors); } } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // we have to stretch or shrink horizontally // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt08Ato24_NoBlend_NoTrans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pdDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror,(COLORREF*) pDibInfoSrc->bmiColors); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } else { BYTE bTransparentIndex = (BYTE)crTransparent; // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt08Ato24_NoBlend_Trans_Hcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength, iNumSrcRows,pdDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows, bTransparentIndex,(COLORREF*) pDibInfoSrc->bmiColors); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // we have to shrink or stretch horizontally // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt08Ato24_NoBlend_Trans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pdDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror, bTransparentIndex,(COLORREF*) pDibInfoSrc->bmiColors); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } } else { // blending desired // REVIEW!!!! -- This is a temporary hack based on the following premises: // // 1) In theory, per-pixel alpha should be overridable by per-surface alpha // 2) In practice, Burma does not allow per-surface alpha to override a per- // pixel bitmap. // 3) The following code for all the per-surface alpha blending bliting is // temporarily commented out so that we can verify DirectDraw NEVER EVER // calls BlitLib with both a per-pixel bitmap and a per-surface alpha // value other than ALPHA_INVALID. // // Therefore, we are currently return E_UNEXPECTED if this condition occurs. // // Although the following commented code is contrary to the Burma hardware, // we are not going to change BlitLib to Burma's implementation because we // believe it's implementation is a bug. // return E_UNEXPECTED; /* // if alpha value is zero, we do no work since the source bitmap // contributes nothing to the destination bitmap if (!(arAlpha & ALPHA_MASK)) { return sc; } // check to see if we need to worry about transparency if (crTransparent == CLR_INVALID) { // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt08Ato24_Blend_NoTrans_Hcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength, iNumSrcRows,pdDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows, arAlpha,(COLORREF*) pDibInfoSrc->bmiColors); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // we need to shrink or stretch horizontally // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt08Ato24_Blend_NoTrans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pdDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror, arAlpha,(COLORREF*) pDibInfoSrc->bmiColors); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } else { BYTE bTransparentIndex = (BYTE)crTransparent; // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt08Ato24_Blend_Trans_Hcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength, iNumSrcRows,pdDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows, bTransparentIndex,arAlpha,(COLORREF*) pDibInfoSrc->bmiColors); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // we have to shrink or stretch horizontally // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt08Ato24_Blend_Trans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pdDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror, bTransparentIndex,arAlpha,(COLORREF*) pDibInfoSrc->bmiColors); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } }*/ } return sc; } /////////////////////////////////////////////////////////////////////// // // Private BlitLib_BitBlt08Ato24P - // BitBlit from source bitmap to Dstination bitmap // with optional transparency and/or alpha blending using the // specified raster operation. // // Parameters: // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB // pDibBitsDst Pointer to the bits for the Destination DIB // prcDst Pointer to the Destination rectangle // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB // pDibBitsSrc Pointer to the bits for the Source DIB // prcSrc Pointer to the Source rectangle // crTransparent Tranparent color value // arAlpha Per-surface Alpha value // dwRop Raster Operation for the blit // // Return Value: // NO_ERROR or E_* value as specified in the .H file. // // Status: Incomplete // /////////////////////////////////////////////////////////////////////// SCODE BlitLib_BitBlt08Ato24P(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst, PRECT prcDst, PDIBINFO pDibInfoSrc, PDIBBITS pDibBitsSrc, PRECT prcSrc, COLORREF crTransparent, ALPHAREF arAlpha, DWORD dwRop) { SCODE sc = NOERROR; int iNumSrcRows, iNumSrcCols, iSrcScanLength, iNumDstRows, iNumDstCols, iDstScanLength, iHorizMirror = 1, iVertMirror = 1; BYTE *pbSrcScanLine; BYTE *pdDstScanLine; // normalize orientation of source and destination rectangles, and // compute sizes and relative orientations of source and destination rects if ((iNumSrcCols = BLITLIB_RECTWIDTH(prcSrc)) < 0) { iNumSrcCols = -iNumSrcCols; FlipRectHorizontal(prcSrc); FlipRectHorizontal(prcDst); } if ((iNumSrcRows = BLITLIB_RECTHEIGHT(prcSrc)) < 0) { iNumSrcRows = -iNumSrcRows; FlipRectVertical(prcSrc); FlipRectVertical(prcDst); } if ((iNumDstCols = BLITLIB_RECTWIDTH(prcDst)) < 0) { prcDst->left--; prcDst->right--; iNumDstCols = -iNumDstCols; iHorizMirror = -1; } if ((iNumDstRows = BLITLIB_RECTHEIGHT(prcDst)) < 0) { prcDst->top--; prcDst->bottom--; iNumDstRows = -iNumDstRows; iVertMirror = -1; } // compute pointers to the starting rows in the src and dst bitmaps // taking care to invert y values, since DIBs are upside-down pbSrcScanLine = (BYTE*) pDibBitsSrc + prcSrc->top * (iSrcScanLength = DibWidthBytes(pDibInfoSrc)) + prcSrc->left; pdDstScanLine = (BYTE*) pDibBitsDst + prcDst->top * (iDstScanLength = DibWidthBytes(pDibInfoDst)) + (prcDst->left * 3); // check if we're doing blending if (arAlpha == ALPHA_INVALID) { // no blending desired // check to see if we need to worry about transparency if (crTransparent == CLR_INVALID) { // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { // check if we can do a straight copy vertically, // or if we have to stretch, shrink, or mirror if ((iNumSrcRows == iNumDstRows) && (iVertMirror == 1)) { Blt08Ato24P_NoBlend_NoTrans_Hcopy_SRCCOPY_Vcopy(pbSrcScanLine,iSrcScanLength, pdDstScanLine,iDstScanLength, iNumDstCols,iNumDstRows,(COLORREF*) pDibInfoSrc->bmiColors); } else { Blt08Ato24P_NoBlend_NoTrans_Hcopy_SRCCOPY_NoVcopy(pbSrcScanLine,iSrcScanLength, iNumSrcRows,pdDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,(COLORREF*) pDibInfoSrc->bmiColors); } } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // we have to stretch or shrink horizontally // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt08Ato24P_NoBlend_NoTrans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pdDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror,(COLORREF*) pDibInfoSrc->bmiColors); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } else { BYTE bTransparentIndex = (BYTE)crTransparent; // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt08Ato24P_NoBlend_Trans_Hcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength, iNumSrcRows,pdDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows, bTransparentIndex,(COLORREF*) pDibInfoSrc->bmiColors); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // we have to shrink or stretch horizontally // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt08Ato24P_NoBlend_Trans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pdDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror, bTransparentIndex,(COLORREF*) pDibInfoSrc->bmiColors); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } } else { // blending desired // REVIEW!!!! -- This is a temporary hack based on the following premises: // // 1) In theory, per-pixel alpha should be overridable by per-surface alpha // 2) In practice, Burma does not allow per-surface alpha to override a per- // pixel bitmap. // 3) The following code for all the per-surface alpha blending bliting is // temporarily commented out so that we can verify DirectDraw NEVER EVER // calls BlitLib with both a per-pixel bitmap and a per-surface alpha // value other than ALPHA_INVALID. // // Therefore, we are currently return E_UNEXPECTED if this condition occurs. // // Although the following commented code is contrary to the Burma hardware, // we are not going to change BlitLib to Burma's implementation because we // believe it's implementation is a bug. // return E_UNEXPECTED; /* // if alpha value is zero, we do no work since the source bitmap // contributes nothing to the destination bitmap if (!(arAlpha & ALPHA_MASK)) { return sc; } // check to see if we need to worry about transparency if (crTransparent == CLR_INVALID) { // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt08Ato24P_Blend_NoTrans_Hcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength, iNumSrcRows,pdDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows, arAlpha,(COLORREF*) pDibInfoSrc->bmiColors); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // we need to shrink or stretch horizontally // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt08Ato24P_Blend_NoTrans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pdDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror, arAlpha,(COLORREF*) pDibInfoSrc->bmiColors); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } else { BYTE bTransparentIndex = (BYTE)crTransparent; // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt08Ato24P_Blend_Trans_Hcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength, iNumSrcRows,pdDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows, bTransparentIndex,arAlpha,(COLORREF*) pDibInfoSrc->bmiColors); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // we have to shrink or stretch horizontally // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt08Ato24P_Blend_Trans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pdDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror, bTransparentIndex,arAlpha,(COLORREF*) pDibInfoSrc->bmiColors); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } }*/ } return sc; } /////////////////////////////////////////////////////////////////////// // // Private BlitLib_BitBlt08Ato08A - // BitBlit from source bitmap to Dstination bitmap // with optional transparency using the // specified raster operation. // // This blit is special because it uses the 16to16 blits for // all of it's non-transparent color blits. This can be // accomplished because we are ignoring the 8-bit alpha channel // and just copying 16 bits to the destination. For the blits // with a transparent color, new functions are called which check // for only a transparent color palette index (8 bits) and then // copies 16 bits where the color doesn't match. This is a COPY // ONLY blit, thus, it does NOT do any alpha blending. // // Note: The 08Ato08A routines are located with the other 16to16 // blits because it is just an extension of them. (These currently // reside in blt1616.cxx). // // Parameters: // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB // pDibBitsDst Pointer to the bits for the Destination DIB // prcDst Pointer to the Destination rectangle // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB // pDibBitsSrc Pointer to the bits for the Source DIB // prcSrc Pointer to the Source rectangle // crTransparent Tranparent color value // arAlpha Per-surface Alpha value // dwRop Raster Operation for the blit // // Return Value: // NO_ERROR or E_* value as specified in the .H file. // // Status: Incomplete // /////////////////////////////////////////////////////////////////////// SCODE BlitLib_BitBlt08Ato08A(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst, PRECT prcDst, PDIBINFO pDibInfoSrc, PDIBBITS pDibBitsSrc, PRECT prcSrc, COLORREF crTransparent, ALPHAREF arAlpha, DWORD dwRop) { SCODE sc = NOERROR; int iNumSrcRows, iNumSrcCols, iSrcScanLength, iNumDstRows, iNumDstCols, iDstScanLength, iHorizMirror = 1, iVertMirror = 1; WORD *pwSrcScanLine, *pwDstScanLine; // normalize orientation of source and destination rectangles, and // compute sizes and relative orientations of source and destination rects if ((iNumSrcCols = BLITLIB_RECTWIDTH(prcSrc)) < 0) { iNumSrcCols = -iNumSrcCols; FlipRectHorizontal(prcSrc); FlipRectHorizontal(prcDst); } if ((iNumSrcRows = BLITLIB_RECTHEIGHT(prcSrc)) < 0) { iNumSrcRows = -iNumSrcRows; FlipRectVertical(prcSrc); FlipRectVertical(prcDst); } if ((iNumDstCols = BLITLIB_RECTWIDTH(prcDst)) < 0) { prcDst->left--; prcDst->right--; iNumDstCols = -iNumDstCols; iHorizMirror = -1; } if ((iNumDstRows = BLITLIB_RECTHEIGHT(prcDst)) < 0) { prcDst->top--; prcDst->bottom--; iNumDstRows = -iNumDstRows; iVertMirror = -1; } // compute pointers to the starting rows in the src and dst bitmaps // taking care to invert y values, since DIBs are upside-down pwSrcScanLine = (WORD*) pDibBitsSrc + prcSrc->top * (iSrcScanLength = DibWidthBytes(pDibInfoSrc) / 2) + prcSrc->left; pwDstScanLine = (WORD*) pDibBitsDst + prcDst->top * (iDstScanLength = DibWidthBytes(pDibInfoDst) / 2) + prcDst->left; // Make sure we are not doing any blending. This is ONLY a copy blit! if (arAlpha != ALPHA_INVALID) return E_INVALIDARG; // check to see if we need to worry about transparency if (crTransparent == CLR_INVALID) { // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { // check if we can do a straight copy vertically, // or if we have to stretch, shrink, or mirror if ((iNumSrcRows == iNumDstRows) && (iVertMirror == 1)) { Blt16to16_NoBlend_NoTrans_Hcopy_SRCCOPY_Vcopy(pwSrcScanLine,iSrcScanLength, pwDstScanLine,iDstScanLength, iNumDstCols,iNumDstRows); } else { Blt16to16_NoBlend_NoTrans_Hcopy_SRCCOPY_NoVcopy(pwSrcScanLine,iSrcScanLength, iNumSrcRows,pwDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows); } } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt16to16_NoBlend_NoTrans_NoHcopy_SRCCOPY(pwSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pwDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } else { // transparency desired BYTE bTransparentColor = (BYTE)crTransparent; // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt08Ato08A_NoBlend_Trans_Hcopy_SRCCOPY(pwSrcScanLine,iSrcScanLength, iNumSrcRows,pwDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows, bTransparentColor); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt08Ato08A_NoBlend_Trans_NoHcopy_SRCCOPY(pwSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pwDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror, bTransparentColor); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } return sc; } #endif // DDRAW /////////////////////////////////////////////////////////////////////// // // Private BlitLib_BitBlt16to16 - // BitBlit from source bitmap to Dstination bitmap // with optional transparency and/or alpha blending using the // specified raster operation. // // Parameters: // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB // pDibBitsDst Pointer to the bits for the Destination DIB // prcDst Pointer to the Destination rectangle // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB // pDibBitsSrc Pointer to the bits for the Source DIB // prcSrc Pointer to the Source rectangle // crTransparent Tranparent color value // arAlpha Per-surface Alpha value // dwRop Raster Operation for the blit // // Return Value: // NO_ERROR or E_* value as specified in the .H file. // // Status: Incomplete // /////////////////////////////////////////////////////////////////////// SCODE BlitLib_BitBlt16to16(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst, PRECT prcDst, PDIBINFO pDibInfoSrc, PDIBBITS pDibBitsSrc, PRECT prcSrc, COLORREF crTransparent, ALPHAREF arAlpha, DWORD dwRop) { SCODE sc = NOERROR; int iNumSrcRows, iNumSrcCols, iSrcScanLength, iNumDstRows, iNumDstCols, iDstScanLength, iHorizMirror = 1, iVertMirror = 1; WORD *pwSrcScanLine, *pwDstScanLine; // If the bitmaps overlap, we need to use overlapping code if(BlitLib_Detect_Intersection(pDibBitsDst, prcDst, pDibBitsSrc, prcSrc)) return BlitLib_BitBlt16to16_Intersect(pDibInfoDst, pDibBitsDst, prcDst, pDibInfoSrc, pDibBitsSrc, prcSrc, crTransparent, dwRop); // normalize orientation of source and destination rectangles, and // compute sizes and relative orientations of source and destination rects if ((iNumSrcCols = BLITLIB_RECTWIDTH(prcSrc)) < 0) { iNumSrcCols = -iNumSrcCols; FlipRectHorizontal(prcSrc); FlipRectHorizontal(prcDst); } if ((iNumSrcRows = BLITLIB_RECTHEIGHT(prcSrc)) < 0) { iNumSrcRows = -iNumSrcRows; FlipRectVertical(prcSrc); FlipRectVertical(prcDst); } if ((iNumDstCols = BLITLIB_RECTWIDTH(prcDst)) < 0) { prcDst->left--; prcDst->right--; iNumDstCols = -iNumDstCols; iHorizMirror = -1; } if ((iNumDstRows = BLITLIB_RECTHEIGHT(prcDst)) < 0) { prcDst->top--; prcDst->bottom--; iNumDstRows = -iNumDstRows; iVertMirror = -1; } // compute pointers to the starting rows in the src and dst bitmaps // taking care to invert y values, since DIBs are upside-down pwSrcScanLine = (WORD*) pDibBitsSrc + prcSrc->top * (iSrcScanLength = DibWidthBytes(pDibInfoSrc) / 2) + prcSrc->left; pwDstScanLine = (WORD*) pDibBitsDst + prcDst->top * (iDstScanLength = DibWidthBytes(pDibInfoDst) / 2) + prcDst->left; // check if we're doing blending if (arAlpha == ALPHA_INVALID) { // no blending desired // check to see if we need to worry about transparency if (crTransparent == CLR_INVALID) { // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { // check if we can do a straight copy vertically, // or if we have to stretch, shrink, or mirror if ((iNumSrcRows == iNumDstRows) && (iVertMirror == 1)) { Blt16to16_NoBlend_NoTrans_Hcopy_SRCCOPY_Vcopy(pwSrcScanLine,iSrcScanLength, pwDstScanLine,iDstScanLength, iNumDstCols,iNumDstRows); } else { Blt16to16_NoBlend_NoTrans_Hcopy_SRCCOPY_NoVcopy(pwSrcScanLine,iSrcScanLength, iNumSrcRows,pwDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows); } } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt16to16_NoBlend_NoTrans_NoHcopy_SRCCOPY(pwSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pwDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } else { // transparency desired WORD wTransparentColor = (WORD)crTransparent; // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt16to16_NoBlend_Trans_Hcopy_SRCCOPY(pwSrcScanLine,iSrcScanLength, iNumSrcRows,pwDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows, wTransparentColor); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt16to16_NoBlend_Trans_NoHcopy_SRCCOPY(pwSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pwDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror, wTransparentColor); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } } #ifndef DDRAW #ifndef WIN95 else { // blending desired // if alpha value is zero, we do no work since the source bitmap // contributes nothing to the destination bitmap if (!(arAlpha & ALPHA_MASK)) { return sc; } // check to see if we need to worry about transparency if (crTransparent == CLR_INVALID) { // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt16to16_Blend_NoTrans_Hcopy_SRCCOPY(pwSrcScanLine,iSrcScanLength, iNumSrcRows,pwDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows, arAlpha); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt16to16_Blend_NoTrans_NoHcopy_SRCCOPY(pwSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pwDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror, arAlpha); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } else { // transparency desired WORD wTransparentColor = (WORD)crTransparent; // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt16to16_Blend_Trans_Hcopy_SRCCOPY(pwSrcScanLine,iSrcScanLength, iNumSrcRows,pwDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows, wTransparentColor,arAlpha); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt16to16_Blend_Trans_NoHcopy_SRCCOPY(pwSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pwDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror, wTransparentColor,arAlpha); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } } #endif #endif return sc; } /////////////////////////////////////////////////////////////////////// // // Private BlitLib_BitBlt16to16_Intersect - // BitBlit from source bitmap to destination bitmap (and these // bitmaps overlap each other) with optional transparency // using the specified raster operation. // // Parameters: // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB // pDibBitsDst Pointer to the bits for the Destination DIB // prcDst Pointer to the Destination rectangle // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB // pDibBitsSrc Pointer to the bits for the Source DIB // prcSrc Pointer to the Source rectangle // crTransparent Tranparent color value // dwRop Raster Operation for the blit // // Return Value: // NO_ERROR or E_* value as specified in the .H file. // // Status: Incomplete // /////////////////////////////////////////////////////////////////////// SCODE BlitLib_BitBlt16to16_Intersect(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst, PRECT prcDst, PDIBINFO pDibInfoSrc, PDIBBITS pDibBitsSrc, PRECT prcSrc, COLORREF crTransparent, DWORD dwRop) { SCODE sc = NOERROR; int iNumSrcRows, iNumSrcCols, iSrcScanLength, iNumDstRows, iNumDstCols, iDstScanLength, iHorizMirror = 1, iVertMirror = 1; WORD *pwSrcScanLine, *pwDstScanLine, *pwTempScanLine, wTransparentIndex; PDIBBITS pDibBitsTemp; // normalize orientation of source and destination rectangles, and // compute sizes and relative orientations of source and destination rects if ((iNumSrcCols = BLITLIB_RECTWIDTH(prcSrc)) < 0) { iNumSrcCols = -iNumSrcCols; FlipRectHorizontal(prcSrc); FlipRectHorizontal(prcDst); } if ((iNumSrcRows = BLITLIB_RECTHEIGHT(prcSrc)) < 0) { iNumSrcRows = -iNumSrcRows; FlipRectVertical(prcSrc); FlipRectVertical(prcDst); } if ((iNumDstCols = BLITLIB_RECTWIDTH(prcDst)) < 0) { prcDst->left--; prcDst->right--; iNumDstCols = -iNumDstCols; iHorizMirror = -1; } if ((iNumDstRows = BLITLIB_RECTHEIGHT(prcDst)) < 0) { prcDst->top--; prcDst->bottom--; iNumDstRows = -iNumDstRows; iVertMirror = -1; } // We aren't currently support any ROP's besides SRCCOPY if(dwRop != SRCCOPY) return E_UNEXPECTED; // // Here are all the stretching and mirroring blits for overlapping rects // // REVIEW!!! -- The following code could be optimized for the caching // cases. Currently, it allocates a second bitmap that is the same // size as the original destination, and then uses the original blit // rectangle to do the caching. To save space, this blit should // eventually be changed to only allocate the size of the overlapped // rectangle, and the blit rects should be adjusted accordingly. // Check if we are stretching (horiz or vert), or if we are mirroring -- // In all of these cases, we must create a cache bitmap and double blit if((iNumDstCols != iNumSrcCols) || (iNumDstRows != iNumSrcRows) || (iHorizMirror != 1) || (iVertMirror != 1)) { // Allocate memory for the cache bitmap -- We will blit into this // temporary bitmap and then re-blit back to the original source pDibBitsTemp = (PDIBBITS)osMemAlloc(DibSizeImage((LPBITMAPINFOHEADER)pDibInfoDst)); if (pDibBitsTemp == NULL) return E_UNEXPECTED; // compute pointers to the starting rows in the src and temp bitmaps pwSrcScanLine = (WORD*) pDibBitsSrc + (prcSrc->top) * (iSrcScanLength = DibWidthBytes(pDibInfoSrc) / 2) + prcSrc->left; pwTempScanLine = (WORD*) pDibBitsTemp + (prcDst->top) * (iDstScanLength = DibWidthBytes(pDibInfoDst) / 2) + prcDst->left; // check if we can do a straight copy from src row to dst row if((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check if we can do a straight copy vertically, // or if we have to stretch, shrink, or mirror if ((iNumSrcRows == iNumDstRows) && (iVertMirror == 1)) { Blt16to16_NoBlend_NoTrans_Hcopy_SRCCOPY_Vcopy(pwSrcScanLine,iSrcScanLength, pwTempScanLine,iDstScanLength, iNumDstCols,iNumDstRows); } else { Blt16to16_NoBlend_NoTrans_Hcopy_SRCCOPY_NoVcopy(pwSrcScanLine,iSrcScanLength, iNumSrcRows,pwTempScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows); } } else { Blt16to16_NoBlend_NoTrans_NoHcopy_SRCCOPY(pwSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pwTempScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror); } // Recalculate the scan line pointers for the second blit if(BLITLIB_RECTWIDTH(prcDst) < 0) { prcDst->left++; prcDst->right++; FlipRectHorizontal(prcDst); } if(BLITLIB_RECTHEIGHT(prcDst) < 0) { prcDst->top++; prcDst->bottom++; FlipRectVertical(prcDst); } // compute pointers to the starting rows in the temp and dest bitmaps pwTempScanLine = (WORD*) pDibBitsTemp + (prcDst->top) * (iDstScanLength = DibWidthBytes(pDibInfoDst) / 2) + prcDst->left; pwDstScanLine = (WORD*) pDibBitsDst + (prcDst->top) * (iDstScanLength = DibWidthBytes(pDibInfoDst) / 2) + prcDst->left; // Now blit from the temporary bitmap back to the original source, // checking for transparency if necessary if(crTransparent == CLR_INVALID) { Blt16to16_NoBlend_NoTrans_Hcopy_SRCCOPY_Vcopy(pwTempScanLine,iDstScanLength, pwDstScanLine,iDstScanLength, iNumDstCols,iNumDstRows); } else { wTransparentIndex = (WORD)crTransparent; Blt16to16_NoBlend_Trans_Hcopy_SRCCOPY(pwTempScanLine,iDstScanLength, iNumDstRows,pwDstScanLine, iDstScanLength, iNumDstCols, iNumDstRows, wTransparentIndex); } // Free the memory from the temporary bitmap if(pDibBitsTemp) osMemFree(pDibBitsTemp); return sc; } // // Here are all the non-stretching and non-mirroring blits for overlapping rects // // check to see if we need to worry about transparency if (crTransparent == CLR_INVALID) { // Simplest case, they are the same rectangles if((prcDst->left == prcSrc->left) && (prcDst->top == prcSrc->top) && (prcDst->right == prcSrc->right) && (prcDst->bottom == prcSrc->bottom)) { return sc; } // Next case, the destination rectangle is vertically greater in // magnitude than the source rectangle else if(prcDst->top > prcSrc->top) { // compute pointers to the starting rows in the src and dst bitmaps // taking care to invert y values, since DIBs are upside-down pwSrcScanLine = (WORD*) pDibBitsSrc + (prcSrc->bottom - 1) * (iSrcScanLength = DibWidthBytes(pDibInfoSrc) / 2) + prcSrc->left; pwDstScanLine = (WORD*) pDibBitsDst + (prcDst->bottom - 1) * (iDstScanLength = DibWidthBytes(pDibInfoDst) / 2) + prcDst->left; // Call the appropriate blit Blt16to16_LeftToRight_BottomToTop_SRCCOPY(pwSrcScanLine, iSrcScanLength, pwDstScanLine, iDstScanLength, iNumDstCols, iNumDstRows); } // Next case, the destination rectangle is horizontally less than // or equal in magnitude to the source rectangle else if(prcDst->left <= prcSrc->left){ // compute pointers to the starting rows in the src and dst bitmaps // taking care to invert y values, since DIBs are upside-down pwSrcScanLine = (WORD*) pDibBitsSrc + (prcSrc->top) * (iSrcScanLength = DibWidthBytes(pDibInfoSrc) / 2) + prcSrc->left; pwDstScanLine = (WORD*) pDibBitsDst + (prcDst->top) * (iDstScanLength = DibWidthBytes(pDibInfoDst) / 2) + prcDst->left; // Call the appropriate blit Blt16to16_NoBlend_NoTrans_Hcopy_SRCCOPY_Vcopy(pwSrcScanLine,iSrcScanLength, pwDstScanLine,iDstScanLength, iNumDstCols,iNumDstRows); } // Last case, the destination rectangle is horizontally greater // in magnitude than the source rectangle else{ // compute pointers to the starting rows in the src and dst bitmaps // taking care to invert y values, since DIBs are upside-down pwSrcScanLine = (WORD*) pDibBitsSrc + (prcSrc->top) * (iSrcScanLength = DibWidthBytes(pDibInfoSrc) / 2) + (prcSrc->right - 1); pwDstScanLine = (WORD*) pDibBitsDst + (prcDst->top) * (iDstScanLength = DibWidthBytes(pDibInfoDst) / 2) + (prcDst->right - 1); // Call the appropriate blit Blt16to16_RightToLeft_TopToBottom_SRCCOPY(pwSrcScanLine, iSrcScanLength, pwDstScanLine, iDstScanLength, iNumDstCols, iNumDstRows); } } else{ wTransparentIndex = (WORD)crTransparent; // Simplest case, they are the same rectangles if((prcDst->left == prcSrc->left) && (prcDst->top == prcSrc->top) && (prcDst->right == prcSrc->right) && (prcDst->bottom == prcSrc->bottom)) return sc; // Next case, the destination rectangle is vertically greater in // magnitude than the source rectangle else if(prcDst->top > prcSrc->top){ // compute pointers to the starting rows in the src and dst bitmaps // taking care to invert y values, since DIBs are upside-down pwSrcScanLine = (WORD*) pDibBitsSrc + (prcSrc->bottom - 1) * (iSrcScanLength = DibWidthBytes(pDibInfoSrc) / 2) + prcSrc->left; pwDstScanLine = (WORD*) pDibBitsDst + (prcDst->bottom - 1) * (iDstScanLength = DibWidthBytes(pDibInfoDst) / 2) + prcDst->left; // Call the appropriate blit Blt16to16_LeftToRight_BottomToTop_Trans_SRCCOPY(pwSrcScanLine, iSrcScanLength, pwDstScanLine, iDstScanLength, iNumDstCols, iNumDstRows, wTransparentIndex); } // Next case, the destination rectangle is horizontally less than // or equal in magnitude to the source rectangle else if(prcDst->left <= prcSrc->left){ // compute pointers to the starting rows in the src and dst bitmaps // taking care to invert y values, since DIBs are upside-down pwSrcScanLine = (WORD*) pDibBitsSrc + (prcSrc->top) * (iSrcScanLength = DibWidthBytes(pDibInfoSrc) / 2) + prcSrc->left; pwDstScanLine = (WORD*) pDibBitsDst + (prcDst->top) * (iDstScanLength = DibWidthBytes(pDibInfoDst) / 2) + prcDst->left; // Call the appropriate blit Blt16to16_NoBlend_Trans_Hcopy_SRCCOPY(pwSrcScanLine,iSrcScanLength, iNumSrcRows,pwDstScanLine, iDstScanLength, iNumDstCols,iNumDstRows, wTransparentIndex); } // Last case, the destination rectangle is horizontally greater // in magnitude than the source rectangle else{ // compute pointers to the starting rows in the src and dst bitmaps // taking care to invert y values, since DIBs are upside-down pwSrcScanLine = (WORD*) pDibBitsSrc + (prcSrc->top) * (iSrcScanLength = DibWidthBytes(pDibInfoSrc) / 2) + (prcSrc->right - 1); pwDstScanLine = (WORD*) pDibBitsDst + (prcDst->top) * (iDstScanLength = DibWidthBytes(pDibInfoDst) / 2) + (prcDst->right - 1); // Call the appropriate blit Blt16to16_RightToLeft_TopToBottom_Trans_SRCCOPY(pwSrcScanLine, iSrcScanLength, pwDstScanLine, iDstScanLength, iNumDstCols, iNumDstRows, wTransparentIndex); } } return sc; } #ifndef DDRAW /////////////////////////////////////////////////////////////////////// // // Private BlitLib_BitBlt16to24 - // BitBlit from source bitmap to Dstination bitmap // with optional transparency and/or alpha blending using the // specified raster operation. // // Parameters: // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB // pDibBitsDst Pointer to the bits for the Destination DIB // prcDst Pointer to the Destination rectangle // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB // pDibBitsSrc Pointer to the bits for the Source DIB // prcSrc Pointer to the Source rectangle // crTransparent Tranparent color value // arAlpha Per-surface Alpha value // dwRop Raster Operation for the blit // // Return Value: // NO_ERROR or E_* value as specified in the .H file. // // Status: Incomplete // /////////////////////////////////////////////////////////////////////// SCODE BlitLib_BitBlt16to24(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst, PRECT prcDst, PDIBINFO pDibInfoSrc, PDIBBITS pDibBitsSrc, PRECT prcSrc, COLORREF crTransparent, ALPHAREF arAlpha, DWORD dwRop) { SCODE sc = NOERROR; int iNumSrcRows, iNumSrcCols, iSrcScanLength, iNumDstRows, iNumDstCols, iDstScanLength, iHorizMirror = 1, iVertMirror = 1; WORD *pwSrcScanLine; DWORD *pdDstScanLine; // normalize orientation of source and destination rectangles, and // compute sizes and relative orientations of source and destination rects if ((iNumSrcCols = BLITLIB_RECTWIDTH(prcSrc)) < 0) { iNumSrcCols = -iNumSrcCols; FlipRectHorizontal(prcSrc); FlipRectHorizontal(prcDst); } if ((iNumSrcRows = BLITLIB_RECTHEIGHT(prcSrc)) < 0) { iNumSrcRows = -iNumSrcRows; FlipRectVertical(prcSrc); FlipRectVertical(prcDst); } if ((iNumDstCols = BLITLIB_RECTWIDTH(prcDst)) < 0) { prcDst->left--; prcDst->right--; iNumDstCols = -iNumDstCols; iHorizMirror = -1; } if ((iNumDstRows = BLITLIB_RECTHEIGHT(prcDst)) < 0) { prcDst->top--; prcDst->bottom--; iNumDstRows = -iNumDstRows; iVertMirror = -1; } // compute pointers to the starting rows in the src and dst bitmaps // taking care to invert y values, since DIBs are upside-down pwSrcScanLine = (WORD*) pDibBitsSrc + prcSrc->top * (iSrcScanLength = DibWidthBytes(pDibInfoSrc) / 2) + prcSrc->left; pdDstScanLine = (DWORD*) pDibBitsDst + prcDst->top * (iDstScanLength = DibWidthBytes(pDibInfoDst) / 4) + prcDst->left; // check if we're doing blending if (arAlpha == ALPHA_INVALID) { // no blending desired // check to see if we need to worry about transparency if (crTransparent == CLR_INVALID) { // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { // check if we can do a straight copy vertically, // or if we have to stretch, shrink, or mirror if ((iNumSrcRows == iNumDstRows) && (iVertMirror == 1)) { Blt16to24_NoBlend_NoTrans_Hcopy_SRCCOPY_Vcopy(pwSrcScanLine,iSrcScanLength, pdDstScanLine,iDstScanLength, iNumDstCols,iNumDstRows); } else { Blt16to24_NoBlend_NoTrans_Hcopy_SRCCOPY_NoVcopy(pwSrcScanLine,iSrcScanLength, iNumSrcRows,pdDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows); } } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt16to24_NoBlend_NoTrans_NoHcopy_SRCCOPY(pwSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pdDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } else { // transparency desired WORD wTransparentColor = (WORD)crTransparent; // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt16to24_NoBlend_Trans_Hcopy_SRCCOPY(pwSrcScanLine,iSrcScanLength, iNumSrcRows,pdDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows, wTransparentColor); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt16to24_NoBlend_Trans_NoHcopy_SRCCOPY(pwSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pdDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror, wTransparentColor); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } } else { // blending desired // if alpha value is zero, we do no work since the source bitmap // contributes nothing to the destination bitmap if (!(arAlpha & ALPHA_MASK)) { return sc; } // check to see if we need to worry about transparency if (crTransparent == CLR_INVALID) { // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt16to24_Blend_NoTrans_Hcopy_SRCCOPY(pwSrcScanLine,iSrcScanLength, iNumSrcRows,pdDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows, arAlpha); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt16to24_Blend_NoTrans_NoHcopy_SRCCOPY(pwSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pdDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror, arAlpha); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } else { // transparency desired WORD wTransparentColor = (WORD)crTransparent; // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt16to24_Blend_Trans_Hcopy_SRCCOPY(pwSrcScanLine,iSrcScanLength, iNumSrcRows,pdDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows, wTransparentColor,arAlpha); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt16to24_Blend_Trans_NoHcopy_SRCCOPY(pwSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pdDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror, wTransparentColor,arAlpha); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } } return sc; } /////////////////////////////////////////////////////////////////////// // // Private BlitLib_BitBlt16to24P - // BitBlit from source bitmap to Dstination bitmap // with optional transparency and/or alpha blending using the // specified raster operation. // // Parameters: // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB // pDibBitsDst Pointer to the bits for the Destination DIB // prcDst Pointer to the Destination rectangle // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB // pDibBitsSrc Pointer to the bits for the Source DIB // prcSrc Pointer to the Source rectangle // crTransparent Tranparent color value // arAlpha Per-surface Alpha value // dwRop Raster Operation for the blit // // Return Value: // NO_ERROR or E_* value as specified in the .H file. // // Status: Incomplete // /////////////////////////////////////////////////////////////////////// SCODE BlitLib_BitBlt16to24P(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst, PRECT prcDst, PDIBINFO pDibInfoSrc, PDIBBITS pDibBitsSrc, PRECT prcSrc, COLORREF crTransparent, ALPHAREF arAlpha, DWORD dwRop) { SCODE sc = NOERROR; int iNumSrcRows, iNumSrcCols, iSrcScanLength, iNumDstRows, iNumDstCols, iDstScanLength, iHorizMirror = 1, iVertMirror = 1; WORD *pwSrcScanLine; BYTE *pdDstScanLine; // normalize orientation of source and destination rectangles, and // compute sizes and relative orientations of source and destination rects if ((iNumSrcCols = BLITLIB_RECTWIDTH(prcSrc)) < 0) { iNumSrcCols = -iNumSrcCols; FlipRectHorizontal(prcSrc); FlipRectHorizontal(prcDst); } if ((iNumSrcRows = BLITLIB_RECTHEIGHT(prcSrc)) < 0) { iNumSrcRows = -iNumSrcRows; FlipRectVertical(prcSrc); FlipRectVertical(prcDst); } if ((iNumDstCols = BLITLIB_RECTWIDTH(prcDst)) < 0) { prcDst->left--; prcDst->right--; iNumDstCols = -iNumDstCols; iHorizMirror = -1; } if ((iNumDstRows = BLITLIB_RECTHEIGHT(prcDst)) < 0) { prcDst->top--; prcDst->bottom--; iNumDstRows = -iNumDstRows; iVertMirror = -1; } // compute pointers to the starting rows in the src and dst bitmaps // taking care to invert y values, since DIBs are upside-down pwSrcScanLine = (WORD *) pDibBitsSrc + prcSrc->top * (iSrcScanLength = DibWidthBytes(pDibInfoSrc) / 2) + prcSrc->left; pdDstScanLine = (BYTE *) pDibBitsDst + prcDst->top * (iDstScanLength = DibWidthBytes(pDibInfoDst)) + (prcDst->left * 3); // check if we're doing blending if (arAlpha == ALPHA_INVALID) { // no blending desired // check to see if we need to worry about transparency if (crTransparent == CLR_INVALID) { // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { // check if we can do a straight copy vertically, // or if we have to stretch, shrink, or mirror if ((iNumSrcRows == iNumDstRows) && (iVertMirror == 1)) { Blt16to24P_NoBlend_NoTrans_Hcopy_SRCCOPY_Vcopy(pwSrcScanLine,iSrcScanLength, pdDstScanLine,iDstScanLength, iNumDstCols,iNumDstRows); } else { Blt16to24P_NoBlend_NoTrans_Hcopy_SRCCOPY_NoVcopy(pwSrcScanLine,iSrcScanLength, iNumSrcRows,pdDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows); } } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt16to24P_NoBlend_NoTrans_NoHcopy_SRCCOPY(pwSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pdDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } else { // transparency desired WORD wTransparentColor = (WORD)crTransparent; // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt16to24P_NoBlend_Trans_Hcopy_SRCCOPY(pwSrcScanLine,iSrcScanLength, iNumSrcRows,pdDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows, wTransparentColor); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt16to24P_NoBlend_Trans_NoHcopy_SRCCOPY(pwSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pdDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror, wTransparentColor); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } } else { // blending desired // if alpha value is zero, we do no work since the source bitmap // contributes nothing to the destination bitmap if (!(arAlpha & ALPHA_MASK)) { return sc; } // check to see if we need to worry about transparency if (crTransparent == CLR_INVALID) { // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt16to24P_Blend_NoTrans_Hcopy_SRCCOPY(pwSrcScanLine,iSrcScanLength, iNumSrcRows,pdDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows, arAlpha); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt16to24P_Blend_NoTrans_NoHcopy_SRCCOPY(pwSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pdDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror, arAlpha); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } else { // transparency desired WORD wTransparentColor = (WORD)crTransparent; // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt16to24P_Blend_Trans_Hcopy_SRCCOPY(pwSrcScanLine,iSrcScanLength, iNumSrcRows,pdDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows, wTransparentColor,arAlpha); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt16to24P_Blend_Trans_NoHcopy_SRCCOPY(pwSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pdDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror, wTransparentColor,arAlpha); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } } return sc; } /////////////////////////////////////////////////////////////////////// // // Private BlitLib_BitBlt24to01 - // BitBlit from source bitmap to destination bitmap // with optional transparency and/or alpha blending using the // specified raster operation. // // Parameters: // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB // pDibBitsDst Pointer to the bits for the Destination DIB // prcDst Pointer to the Destination rectangle // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB // pDibBitsSrc Pointer to the bits for the Source DIB // prcSrc Pointer to the Source rectangle // crTransparent Tranparent color value // arAlpha Per-surface Alpha value // dwRop Raster Operation for the blit // // Return Value: // NO_ERROR or E_* value as specified in the .H file. // // Status: Incomplete // /////////////////////////////////////////////////////////////////////// SCODE BlitLib_BitBlt24to01(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst, PRECT prcDst, PDIBINFO pDibInfoSrc, PDIBBITS pDibBitsSrc, PRECT prcSrc, COLORREF crTransparent, ALPHAREF arAlpha, DWORD dwRop) { SCODE sc = NOERROR; int iNumSrcRows, iNumSrcCols, iSrcScanLength, iNumDstRows, iNumDstCols, iBytesPerDstScanLine, iHorizMirror = 1, iVertMirror = 1, iDstBitOffset; DWORD *pdSrcScanLine; BYTE *pbDstScanLine, bFillVal; // alpha blending not currently supported in the 24 to 1 bpp blits if (arAlpha != ALPHA_INVALID) { return E_UNEXPECTED; // !!!! need better error codes } // the only ROPs supported are BLACKNESS and WHITENESS if (dwRop == BLACKNESS) { bFillVal = 0; } else if (dwRop == WHITENESS) { bFillVal = 0xFF; } else { return E_UNEXPECTED; // !!!! need better error codes } // normalize orientation of source and destination rectangles, and // compute sizes and relative orientations of source and destination rects if ((iNumSrcCols = BLITLIB_RECTWIDTH(prcSrc)) < 0) { iNumSrcCols = -iNumSrcCols; FlipRectHorizontal(prcSrc); FlipRectHorizontal(prcDst); } if ((iNumSrcRows = BLITLIB_RECTHEIGHT(prcSrc)) < 0) { iNumSrcRows = -iNumSrcRows; FlipRectVertical(prcSrc); FlipRectVertical(prcDst); } if ((iNumDstCols = BLITLIB_RECTWIDTH(prcDst)) < 0) { prcDst->left--; prcDst->right--; iNumDstCols = -iNumDstCols; iHorizMirror = -1; } if ((iNumDstRows = BLITLIB_RECTHEIGHT(prcDst)) < 0) { prcDst->top--; prcDst->bottom--; iNumDstRows = -iNumDstRows; iVertMirror = -1; } // compute pointers to the starting rows in the src and dst bitmaps // taking care to invert y values, since DIBs are upside-down pdSrcScanLine = (DWORD*) pDibBitsSrc + prcSrc->top * (iSrcScanLength = DibWidthBytes(pDibInfoSrc) / 4) + prcSrc->left; pbDstScanLine = (BYTE*) pDibBitsDst + prcDst->top * (iBytesPerDstScanLine = DibWidthBytes(pDibInfoDst)) + (prcDst->left / 8); iDstBitOffset = prcDst->left % 8; // check to see if we need to worry about transparency if (crTransparent == CLR_INVALID) { // no transparency plus a constant ROP equals a rectangle fill! // first we have to normalize dst rect orientation // - FillRect01() expects it if (BLITLIB_RECTWIDTH(prcDst) < 0) { prcDst->left++; prcDst->right++; FlipRectHorizontal(prcDst); } if (BLITLIB_RECTHEIGHT(prcDst) < 0) { prcDst->top--; prcDst->bottom--; FlipRectVertical(prcDst); } sc |= BlitLib_FillRect01(pDibInfoDst,pDibBitsDst,prcDst->left,prcDst->top, iNumDstCols,iNumDstRows,bFillVal); } else { // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { Blt24to01_Trans_Hcopy_ConstRop(pdSrcScanLine,iSrcScanLength,iNumSrcRows, pbDstScanLine,iDstBitOffset, iBytesPerDstScanLine * iVertMirror, iNumDstCols,iNumDstRows,crTransparent, bFillVal); } else { Blt24to01_Trans_NoHcopy_ConstRop(pdSrcScanLine,iSrcScanLength,iNumSrcCols, iNumSrcRows,pbDstScanLine,iDstBitOffset, iBytesPerDstScanLine * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror, crTransparent,bFillVal); } } return sc; } /////////////////////////////////////////////////////////////////////// // // Private BlitLib_BitBlt24Pto01 - // BitBlit from source bitmap to destination bitmap // with optional transparency and/or alpha blending using the // specified raster operation. // // Parameters: // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB // pDibBitsDst Pointer to the bits for the Destination DIB // prcDst Pointer to the Destination rectangle // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB // pDibBitsSrc Pointer to the bits for the Source DIB // prcSrc Pointer to the Source rectangle // crTransparent Tranparent color value // arAlpha Per-surface Alpha value // dwRop Raster Operation for the blit // // Return Value: // NO_ERROR or E_* value as specified in the .H file. // // Status: Incomplete // /////////////////////////////////////////////////////////////////////// SCODE BlitLib_BitBlt24Pto01(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst, PRECT prcDst, PDIBINFO pDibInfoSrc, PDIBBITS pDibBitsSrc, PRECT prcSrc, COLORREF crTransparent, ALPHAREF arAlpha, DWORD dwRop) { SCODE sc = NOERROR; int iNumSrcRows, iNumSrcCols, iSrcScanLength, iNumDstRows, iNumDstCols, iBytesPerDstScanLine, iHorizMirror = 1, iVertMirror = 1, iDstBitOffset; BYTE *pdSrcScanLine; BYTE *pbDstScanLine, bFillVal; // alpha blending not currently supported in the 24 to 1 bpp blits if (arAlpha != ALPHA_INVALID) { return E_UNEXPECTED; // !!!! need better error codes } // the only ROPs supported are BLACKNESS and WHITENESS if (dwRop == BLACKNESS) { bFillVal = 0; } else if (dwRop == WHITENESS) { bFillVal = 0xFF; } else { return E_UNEXPECTED; // !!!! need better error codes } // normalize orientation of source and destination rectangles, and // compute sizes and relative orientations of source and destination rects if ((iNumSrcCols = BLITLIB_RECTWIDTH(prcSrc)) < 0) { iNumSrcCols = -iNumSrcCols; FlipRectHorizontal(prcSrc); FlipRectHorizontal(prcDst); } if ((iNumSrcRows = BLITLIB_RECTHEIGHT(prcSrc)) < 0) { iNumSrcRows = -iNumSrcRows; FlipRectVertical(prcSrc); FlipRectVertical(prcDst); } if ((iNumDstCols = BLITLIB_RECTWIDTH(prcDst)) < 0) { prcDst->left--; prcDst->right--; iNumDstCols = -iNumDstCols; iHorizMirror = -1; } if ((iNumDstRows = BLITLIB_RECTHEIGHT(prcDst)) < 0) { prcDst->top--; prcDst->bottom--; iNumDstRows = -iNumDstRows; iVertMirror = -1; } // compute pointers to the starting rows in the src and dst bitmaps // taking care to invert y values, since DIBs are upside-down pdSrcScanLine = (BYTE*) pDibBitsSrc + prcSrc->top * (iSrcScanLength = DibWidthBytes(pDibInfoSrc)) + (prcSrc->left * 3); pbDstScanLine = (BYTE*) pDibBitsDst + prcDst->top * (iBytesPerDstScanLine = DibWidthBytes(pDibInfoDst)) + (prcDst->left / 8); iDstBitOffset = prcDst->left % 8; // check to see if we need to worry about transparency if (crTransparent == CLR_INVALID) { // no transparency plus a constant ROP equals a rectangle fill! // first we have to normalize dst rect orientation // - FillRect01() expects it if (BLITLIB_RECTWIDTH(prcDst) < 0) { prcDst->left++; prcDst->right++; FlipRectHorizontal(prcDst); } if (BLITLIB_RECTHEIGHT(prcDst) < 0) { prcDst->top--; prcDst->bottom--; FlipRectVertical(prcDst); } sc |= BlitLib_FillRect01(pDibInfoDst,pDibBitsDst,prcDst->left,prcDst->top, iNumDstCols,iNumDstRows,bFillVal); } else { // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { Blt24Pto01_Trans_Hcopy_ConstRop(pdSrcScanLine,iSrcScanLength,iNumSrcRows, pbDstScanLine,iDstBitOffset, iBytesPerDstScanLine * iVertMirror, iNumDstCols,iNumDstRows,crTransparent, bFillVal); } else { Blt24Pto01_Trans_NoHcopy_ConstRop(pdSrcScanLine,iSrcScanLength,iNumSrcCols, iNumSrcRows,pbDstScanLine,iDstBitOffset, iBytesPerDstScanLine * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror, crTransparent,bFillVal); } } return sc; } /////////////////////////////////////////////////////////////////////// // // Private BlitLib_BitBlt24to08 - // BitBlit from source bitmap to Dstination bitmap // with optional transparency and/or alpha blending using the // specified raster operation. // // Parameters: // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB // pDibBitsDst Pointer to the bits for the Destination DIB // prcDst Pointer to the Destination rectangle // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB // pDibBitsSrc Pointer to the bits for the Source DIB // prcSrc Pointer to the Source rectangle // crTransparent Tranparent color value // arAlpha Per-surface Alpha value // dwRop Raster Operation for the blit // // Return Value: // NO_ERROR or E_* value as specified in the .H file. // // Status: Incomplete // /////////////////////////////////////////////////////////////////////// SCODE BlitLib_BitBlt24to08(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst, PRECT prcDst, PDIBINFO pDibInfoSrc, PDIBBITS pDibBitsSrc, PRECT prcSrc, COLORREF crTransparent, ALPHAREF arAlpha, DWORD dwRop) { SCODE sc = NOERROR; int iNumSrcRows, iNumSrcCols, iSrcScanLength, iNumDstRows, iNumDstCols, iDstScanLength, iHorizMirror = 1, iVertMirror = 1; DWORD *pdSrcScanLine; BYTE *pbDstScanLine; // normalize orientation of source and destination rectangles, and // compute sizes and relative orientations of source and destination rects if ((iNumSrcCols = BLITLIB_RECTWIDTH(prcSrc)) < 0) { iNumSrcCols = -iNumSrcCols; FlipRectHorizontal(prcSrc); FlipRectHorizontal(prcDst); } if ((iNumSrcRows = BLITLIB_RECTHEIGHT(prcSrc)) < 0) { iNumSrcRows = -iNumSrcRows; FlipRectVertical(prcSrc); FlipRectVertical(prcDst); } if ((iNumDstCols = BLITLIB_RECTWIDTH(prcDst)) < 0) { prcDst->left--; prcDst->right--; iNumDstCols = -iNumDstCols; iHorizMirror = -1; } if ((iNumDstRows = BLITLIB_RECTHEIGHT(prcDst)) < 0) { prcDst->top--; prcDst->bottom--; iNumDstRows = -iNumDstRows; iVertMirror = -1; } // compute pointers to the starting rows in the src and dst bitmaps // taking care to invert y values, since DIBs are upside-down pdSrcScanLine = (DWORD*) pDibBitsSrc + prcSrc->top * (iSrcScanLength = DibWidthBytes(pDibInfoSrc) / 4) + prcSrc->left; pbDstScanLine = (BYTE*) pDibBitsDst + prcDst->top * (iDstScanLength = DibWidthBytes(pDibInfoDst)) + prcDst->left; // check if we're doing blending if (arAlpha == ALPHA_INVALID) { // no blending desired // check to see if we need to worry about transparency if (crTransparent == CLR_INVALID) { // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { // check if we can do a straight copy vertically, // or if we have to stretch, shrink, or mirror if ((iNumSrcRows == iNumDstRows) && (iVertMirror == 1)) { Blt24to08_NoBlend_NoTrans_Hcopy_SRCCOPY_Vcopy(pdSrcScanLine,iSrcScanLength, pbDstScanLine,iDstScanLength, iNumDstCols,iNumDstRows,(COLORREF*) pDibInfoDst->bmiColors,DibNumColors(&(pDibInfoDst->bmiHeader))); } else { Blt24to08_NoBlend_NoTrans_Hcopy_SRCCOPY_NoVcopy(pdSrcScanLine,iSrcScanLength, iNumSrcRows,pbDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,(COLORREF*) pDibInfoDst->bmiColors,DibNumColors(&(pDibInfoDst->bmiHeader))); } } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt24to08_NoBlend_NoTrans_NoHcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pbDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror,(COLORREF*) pDibInfoDst->bmiColors,DibNumColors(&(pDibInfoDst->bmiHeader))); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } else { // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt24to08_NoBlend_Trans_Hcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength, iNumSrcRows,pbDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows, crTransparent,(COLORREF*) pDibInfoDst->bmiColors,DibNumColors(&(pDibInfoDst->bmiHeader))); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt24to08_NoBlend_Trans_NoHcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pbDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror, crTransparent,(COLORREF*) pDibInfoDst->bmiColors,DibNumColors(&(pDibInfoDst->bmiHeader))); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } } else { // blending desired // if alpha value is zero, we do no work since the source bitmap // contributes nothing to the destination bitmap if (!(arAlpha & ALPHA_MASK)) { return sc; } // check to see if we need to worry about transparency if (crTransparent == CLR_INVALID) { // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt24to08_Blend_NoTrans_Hcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength, iNumSrcRows,pbDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows, arAlpha,(COLORREF*) pDibInfoDst->bmiColors,DibNumColors(&(pDibInfoDst->bmiHeader))); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt24to08_Blend_NoTrans_NoHcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pbDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror, arAlpha,(COLORREF*) pDibInfoDst->bmiColors,DibNumColors(&(pDibInfoDst->bmiHeader))); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } else { // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt24to08_Blend_Trans_Hcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength, iNumSrcRows,pbDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows, crTransparent,arAlpha,(COLORREF*) pDibInfoDst->bmiColors,DibNumColors(&(pDibInfoDst->bmiHeader))); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt24to08_Blend_Trans_NoHcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pbDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror, crTransparent,arAlpha,(COLORREF*) pDibInfoDst->bmiColors,DibNumColors(&(pDibInfoDst->bmiHeader))); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } } return sc; } /////////////////////////////////////////////////////////////////////// // // Private BlitLib_BitBlt24Pto08 - // BitBlit from source bitmap to Dstination bitmap // with optional transparency and/or alpha blending using the // specified raster operation. // // Parameters: // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB // pDibBitsDst Pointer to the bits for the Destination DIB // prcDst Pointer to the Destination rectangle // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB // pDibBitsSrc Pointer to the bits for the Source DIB // prcSrc Pointer to the Source rectangle // crTransparent Tranparent color value // arAlpha Per-surface Alpha value // dwRop Raster Operation for the blit // // Return Value: // NO_ERROR or E_* value as specified in the .H file. // // Status: Incomplete // /////////////////////////////////////////////////////////////////////// SCODE BlitLib_BitBlt24Pto08(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst, PRECT prcDst, PDIBINFO pDibInfoSrc, PDIBBITS pDibBitsSrc, PRECT prcSrc, COLORREF crTransparent, ALPHAREF arAlpha, DWORD dwRop) { SCODE sc = NOERROR; int iNumSrcRows, iNumSrcCols, iSrcScanLength, iNumDstRows, iNumDstCols, iDstScanLength, iHorizMirror = 1, iVertMirror = 1; BYTE *pbSrcScanLine; BYTE *pbDstScanLine; // normalize orientation of source and destination rectangles, and // compute sizes and relative orientations of source and destination rects if ((iNumSrcCols = BLITLIB_RECTWIDTH(prcSrc)) < 0) { iNumSrcCols = -iNumSrcCols; FlipRectHorizontal(prcSrc); FlipRectHorizontal(prcDst); } if ((iNumSrcRows = BLITLIB_RECTHEIGHT(prcSrc)) < 0) { iNumSrcRows = -iNumSrcRows; FlipRectVertical(prcSrc); FlipRectVertical(prcDst); } if ((iNumDstCols = BLITLIB_RECTWIDTH(prcDst)) < 0) { prcDst->left--; prcDst->right--; iNumDstCols = -iNumDstCols; iHorizMirror = -1; } if ((iNumDstRows = BLITLIB_RECTHEIGHT(prcDst)) < 0) { prcDst->top--; prcDst->bottom--; iNumDstRows = -iNumDstRows; iVertMirror = -1; } // compute pointers to the starting rows in the src and dst bitmaps // taking care to invert y values, since DIBs are upside-down pbSrcScanLine = (BYTE*) pDibBitsSrc + prcSrc->top * (iSrcScanLength = DibWidthBytes(pDibInfoSrc)) + (prcSrc->left * 3); pbDstScanLine = (BYTE*) pDibBitsDst + prcDst->top * (iDstScanLength = DibWidthBytes(pDibInfoDst)) + prcDst->left; // check if we're doing blending if (arAlpha == ALPHA_INVALID) { // no blending desired // check to see if we need to worry about transparency if (crTransparent == CLR_INVALID) { // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { // check if we can do a straight copy vertically, // or if we have to stretch, shrink, or mirror if ((iNumSrcRows == iNumDstRows) && (iVertMirror == 1)) { Blt24Pto08_NoBlend_NoTrans_Hcopy_SRCCOPY_Vcopy(pbSrcScanLine,iSrcScanLength, pbDstScanLine,iDstScanLength, iNumDstCols,iNumDstRows,(COLORREF*) pDibInfoDst->bmiColors,DibNumColors(&(pDibInfoDst->bmiHeader))); } else { Blt24Pto08_NoBlend_NoTrans_Hcopy_SRCCOPY_NoVcopy(pbSrcScanLine,iSrcScanLength, iNumSrcRows,pbDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,(COLORREF*) pDibInfoDst->bmiColors,DibNumColors(&(pDibInfoDst->bmiHeader))); } } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt24Pto08_NoBlend_NoTrans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pbDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror,(COLORREF*) pDibInfoDst->bmiColors,DibNumColors(&(pDibInfoDst->bmiHeader))); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } else { // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt24Pto08_NoBlend_Trans_Hcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength, iNumSrcRows,pbDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows, crTransparent,(COLORREF*) pDibInfoDst->bmiColors,DibNumColors(&(pDibInfoDst->bmiHeader))); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt24Pto08_NoBlend_Trans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pbDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror, crTransparent,(COLORREF*) pDibInfoDst->bmiColors,DibNumColors(&(pDibInfoDst->bmiHeader))); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } } else { // blending desired // if alpha value is zero, we do no work since the source bitmap // contributes nothing to the destination bitmap if (!(arAlpha & ALPHA_MASK)) { return sc; } // check to see if we need to worry about transparency if (crTransparent == CLR_INVALID) { // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt24Pto08_Blend_NoTrans_Hcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength, iNumSrcRows,pbDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows, arAlpha,(COLORREF*) pDibInfoDst->bmiColors,DibNumColors(&(pDibInfoDst->bmiHeader))); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt24Pto08_Blend_NoTrans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pbDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror, arAlpha,(COLORREF*) pDibInfoDst->bmiColors,DibNumColors(&(pDibInfoDst->bmiHeader))); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } else { // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt24Pto08_Blend_Trans_Hcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength, iNumSrcRows,pbDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows, crTransparent,arAlpha,(COLORREF*) pDibInfoDst->bmiColors,DibNumColors(&(pDibInfoDst->bmiHeader))); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt24Pto08_Blend_Trans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pbDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror, crTransparent,arAlpha,(COLORREF*) pDibInfoDst->bmiColors,DibNumColors(&(pDibInfoDst->bmiHeader))); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } } return sc; } #endif // DDRAW /////////////////////////////////////////////////////////////////////// // // Private BlitLib_BitBlt24to24 - // BitBlit from source bitmap to Dstination bitmap // with optional transparency and/or alpha blending using the // specified raster operation. // // Parameters: // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB // pDibBitsDst Pointer to the bits for the Destination DIB // prcDst Pointer to the Destination rectangle // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB // pDibBitsSrc Pointer to the bits for the Source DIB // prcSrc Pointer to the Source rectangle // crTransparent Tranparent color value // arAlpha Per-surface Alpha value // dwRop Raster Operation for the blit // // Return Value: // NO_ERROR or E_* value as specified in the .H file. // // Status: Incomplete // /////////////////////////////////////////////////////////////////////// SCODE BlitLib_BitBlt24to24(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst, PRECT prcDst, PDIBINFO pDibInfoSrc, PDIBBITS pDibBitsSrc, PRECT prcSrc, COLORREF crTransparent, ALPHAREF arAlpha, DWORD dwRop) { SCODE sc = NOERROR; int iNumSrcRows, iNumSrcCols, iSrcScanLength, iNumDstRows, iNumDstCols, iDstScanLength, iHorizMirror = 1, iVertMirror = 1; DWORD *pdSrcScanLine, *pdDstScanLine, *pdTempScanLine; PDIBBITS pDibBitsTemp; if(dwRop != SRCCOPY) return DDERR_INVALIDPARAMS; // normalize orientation of source and destination rectangles, and compute sizes // and relative orientations of source and destination rects if ((iNumSrcCols = BLITLIB_RECTWIDTH(prcSrc)) < 0) { iNumSrcCols = -iNumSrcCols; FlipRectHorizontal(prcSrc); FlipRectHorizontal(prcDst); } if ((iNumSrcRows = BLITLIB_RECTHEIGHT(prcSrc)) < 0) { iNumSrcRows = -iNumSrcRows; FlipRectVertical(prcSrc); FlipRectVertical(prcDst); } if ((iNumDstCols = BLITLIB_RECTWIDTH(prcDst)) < 0) { prcDst->left--; prcDst->right--; iNumDstCols = -iNumDstCols; iHorizMirror = -1; } if ((iNumDstRows = BLITLIB_RECTHEIGHT(prcDst)) < 0) { prcDst->top--; prcDst->bottom--; iNumDstRows = -iNumDstRows; iVertMirror = -1; } // Handle intersecting blits in a completely unintelegent manner. if(BlitLib_Detect_Intersection(pDibBitsDst, prcDst, pDibBitsSrc, prcSrc)) { // Allocate memory for the cache bitmap -- We will blit into this // temporary bitmap and then re-blit back to the original source pDibBitsTemp = (PDIBBITS)osMemAlloc(DibSizeImage((LPBITMAPINFOHEADER)pDibInfoDst)); if(pDibBitsTemp == NULL) return DDERR_OUTOFMEMORY; // compute pointers to the starting rows in the src and temp bitmaps pdSrcScanLine = (DWORD *) pDibBitsSrc + (prcSrc->top) * (iSrcScanLength = DibWidthBytes(pDibInfoSrc)/4) + prcSrc->left; pdTempScanLine = (DWORD *) pDibBitsTemp + (prcDst->top) * (iDstScanLength = DibWidthBytes(pDibInfoDst)/4) + prcDst->left; // check if we can do a straight copy from src row to dst row if((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check if we can do a straight copy vertically, // or if we have to stretch, shrink, or mirror if ((iNumSrcRows == iNumDstRows) && (iVertMirror == 1)) { Blt24to24_NoBlend_NoTrans_Hcopy_SRCCOPY_Vcopy(pdSrcScanLine,iSrcScanLength, pdTempScanLine,iDstScanLength, iNumDstCols,iNumDstRows); } else { Blt24to24_NoBlend_NoTrans_Hcopy_SRCCOPY_NoVcopy(pdSrcScanLine,iSrcScanLength, iNumSrcRows,pdTempScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows); } } else { Blt24to24_NoBlend_NoTrans_NoHcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pdTempScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror); } // Recalculate the scan line pointers for the second blit if(BLITLIB_RECTWIDTH(prcDst) < 0) { prcDst->left++; prcDst->right++; FlipRectHorizontal(prcDst); } if(BLITLIB_RECTHEIGHT(prcDst) < 0) { prcDst->top++; prcDst->bottom++; FlipRectVertical(prcDst); } // compute pointers to the starting rows in the temp and dest bitmaps pdTempScanLine = (DWORD*) pDibBitsTemp + (prcDst->top) * (iDstScanLength = DibWidthBytes(pDibInfoDst)/4) + prcDst->left; pdDstScanLine = (DWORD*) pDibBitsDst + (prcDst->top) * (iDstScanLength = DibWidthBytes(pDibInfoDst)/4) + prcDst->left; // Now blit from the temporary bitmap back to the original source, // checking for transparency if necessary if(crTransparent == CLR_INVALID) { Blt24to24_NoBlend_NoTrans_Hcopy_SRCCOPY_Vcopy(pdTempScanLine,iDstScanLength, pdDstScanLine,iDstScanLength, iNumDstCols,iNumDstRows); } else { Blt24to24_NoBlend_Trans_Hcopy_SRCCOPY(pdTempScanLine,iDstScanLength, iNumDstRows,pdDstScanLine, iDstScanLength, iNumDstCols,iNumDstRows, crTransparent); } // Free the memory from the temporary bitmap if(pDibBitsTemp) { osMemFree(pDibBitsTemp); } pDibBitsTemp = NULL; return sc; } // compute pointers to the starting rows in the src and dst bitmaps // taking care to invert y values, since DIBs are upside-down pdSrcScanLine = (DWORD*) pDibBitsSrc + prcSrc->top * (iSrcScanLength = DibWidthBytes(pDibInfoSrc) / 4) + prcSrc->left; pdDstScanLine = (DWORD*) pDibBitsDst + prcDst->top * (iDstScanLength = DibWidthBytes(pDibInfoDst) / 4) + prcDst->left; // check if we're doing blending if (arAlpha == ALPHA_INVALID) { // no blending desired // check to see if we need to worry about transparency if (crTransparent == CLR_INVALID) { // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { // check if we can do a straight copy vertically, // or if we have to stretch, shrink, or mirror if ((iNumSrcRows == iNumDstRows) && (iVertMirror == 1)) { Blt24to24_NoBlend_NoTrans_Hcopy_SRCCOPY_Vcopy(pdSrcScanLine,iSrcScanLength, pdDstScanLine,iDstScanLength, iNumDstCols,iNumDstRows); } else // must stretch/mirror vertically { Blt24to24_NoBlend_NoTrans_Hcopy_SRCCOPY_NoVcopy(pdSrcScanLine,iSrcScanLength, iNumSrcRows,pdDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows); } } else // not SRCCOPY sc |= E_UNEXPECTED; // !!!! we need better error codes } else // must stretch/mirror horizontally { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt24to24_NoBlend_NoTrans_NoHcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pdDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror); } else // not SRCCOPY sc |= E_UNEXPECTED; // !!!! we need better error codes } } else // transparent blit { // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt24to24_NoBlend_Trans_Hcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength, iNumSrcRows,pdDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows, crTransparent); } else // not SRCCOPY sc |= E_UNEXPECTED; // !!!! we need better error codes } else // must stretch/mirror horizontally { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt24to24_NoBlend_Trans_NoHcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pdDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror, crTransparent); } else // not srccopy sc |= E_UNEXPECTED; // !!!! we need better error codes } } } else // blending desired { #ifdef DDRAW return E_UNEXPECTED; #else // if alpha value is zero, we do no work since the source bitmap // contributes nothing to the destination bitmap if (!(arAlpha & ALPHA_MASK)) { return sc; } // check to see if we need to worry about transparency if (crTransparent == CLR_INVALID) { // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt24to24_Blend_NoTrans_Hcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength, iNumSrcRows,pdDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows, arAlpha); } else // not SRCCOPY sc |= E_UNEXPECTED; // !!!! we need better error codes } else // must mirror/stretch horizontally { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt24to24_Blend_NoTrans_NoHcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pdDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror, arAlpha); } else // not SRCCOPY sc |= E_UNEXPECTED; // !!!! we need better error codes } } else // transparent blit { // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt24to24_Blend_Trans_Hcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength, iNumSrcRows,pdDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows, crTransparent,arAlpha); } else // not SRCCOPY sc |= E_UNEXPECTED; // !!!! we need better error codes } else // must stretch/mirror horizontally { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt24to24_Blend_Trans_NoHcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pdDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror, crTransparent,arAlpha); } else // not SRCCOPY sc |= E_UNEXPECTED; // !!!! we need better error codes } } #endif /* !DDRAW */ } return sc; } #ifndef DDRAW /////////////////////////////////////////////////////////////////////// // // Private BlitLib_BitBlt24to24P - // BitBlit from source bitmap to Dstination bitmap // with optional transparency and/or alpha blending using the // specified raster operation. // // Parameters: // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB // pDibBitsDst Pointer to the bits for the Destination DIB // prcDst Pointer to the Destination rectangle // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB // pDibBitsSrc Pointer to the bits for the Source DIB // prcSrc Pointer to the Source rectangle // crTransparent Tranparent color value // arAlpha Per-surface Alpha value // dwRop Raster Operation for the blit // // Return Value: // NO_ERROR or E_* value as specified in the .H file. // // Status: Incomplete // /////////////////////////////////////////////////////////////////////// SCODE BlitLib_BitBlt24to24P(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst, PRECT prcDst, PDIBINFO pDibInfoSrc, PDIBBITS pDibBitsSrc, PRECT prcSrc, COLORREF crTransparent, ALPHAREF arAlpha, DWORD dwRop) { SCODE sc = NOERROR; int iNumSrcRows, iNumSrcCols, iSrcScanLength, iNumDstRows, iNumDstCols, iDstScanLength, iHorizMirror = 1, iVertMirror = 1; DWORD *pdSrcScanLine; BYTE *pdDstScanLine; // normalize orientation of source and destination rectangles, and compute sizes // and relative orientations of source and destination rects if ((iNumSrcCols = BLITLIB_RECTWIDTH(prcSrc)) < 0) { iNumSrcCols = -iNumSrcCols; FlipRectHorizontal(prcSrc); FlipRectHorizontal(prcDst); } if ((iNumSrcRows = BLITLIB_RECTHEIGHT(prcSrc)) < 0) { iNumSrcRows = -iNumSrcRows; FlipRectVertical(prcSrc); FlipRectVertical(prcDst); } if ((iNumDstCols = BLITLIB_RECTWIDTH(prcDst)) < 0) { prcDst->left--; prcDst->right--; iNumDstCols = -iNumDstCols; iHorizMirror = -1; } if ((iNumDstRows = BLITLIB_RECTHEIGHT(prcDst)) < 0) { prcDst->top--; prcDst->bottom--; iNumDstRows = -iNumDstRows; iVertMirror = -1; } // compute pointers to the starting rows in the src and dst bitmaps // taking care to invert y values, since DIBs are upside-down pdSrcScanLine = (DWORD*) pDibBitsSrc + prcSrc->top * (iSrcScanLength = DibWidthBytes(pDibInfoSrc) / 4) + prcSrc->left; pdDstScanLine = (BYTE *) pDibBitsDst + prcDst->top * (iDstScanLength = DibWidthBytes(pDibInfoDst)) + (prcDst->left * 3); // check if we're doing blending if (arAlpha == ALPHA_INVALID) { // no blending desired // check to see if we need to worry about transparency if (crTransparent == CLR_INVALID) { // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { // check if we can do a straight copy vertically, // or if we have to stretch, shrink, or mirror if ((iNumSrcRows == iNumDstRows) && (iVertMirror == 1)) { Blt24to24P_NoBlend_NoTrans_Hcopy_SRCCOPY_Vcopy(pdSrcScanLine,iSrcScanLength, pdDstScanLine,iDstScanLength, iNumDstCols,iNumDstRows); } else { Blt24to24P_NoBlend_NoTrans_Hcopy_SRCCOPY_NoVcopy(pdSrcScanLine,iSrcScanLength, iNumSrcRows,pdDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows); } } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt24to24P_NoBlend_NoTrans_NoHcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pdDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } else { // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt24to24P_NoBlend_Trans_Hcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength, iNumSrcRows,pdDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows, crTransparent); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt24to24P_NoBlend_Trans_NoHcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pdDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror, crTransparent); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } } else { // blending desired // if alpha value is zero, we do no work since the source bitmap // contributes nothing to the destination bitmap if (!(arAlpha & ALPHA_MASK)) { return sc; } // check to see if we need to worry about transparency if (crTransparent == CLR_INVALID) { // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt24to24P_Blend_NoTrans_Hcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength, iNumSrcRows,pdDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows, arAlpha); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt24to24P_Blend_NoTrans_NoHcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pdDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror, arAlpha); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } else { // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt24to24P_Blend_Trans_Hcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength, iNumSrcRows,pdDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows, crTransparent,arAlpha); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt24to24P_Blend_Trans_NoHcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pdDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror, crTransparent,arAlpha); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } } return sc; } #endif // DDRAW /////////////////////////////////////////////////////////////////////// // // Private BlitLib_BitBlt24Pto24P - // BitBlit from source bitmap to Dstination bitmap // with optional transparency and/or alpha blending using the // specified raster operation. // // Parameters: // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB // pDibBitsDst Pointer to the bits for the Destination DIB // prcDst Pointer to the Destination rectangle // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB // pDibBitsSrc Pointer to the bits for the Source DIB // prcSrc Pointer to the Source rectangle // crTransparent Tranparent color value // arAlpha Per-surface Alpha value // dwRop Raster Operation for the blit // // Return Value: // NO_ERROR or E_* value as specified in the .H file. // // Status: Incomplete // /////////////////////////////////////////////////////////////////////// SCODE BlitLib_BitBlt24Pto24P(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst, PRECT prcDst, PDIBINFO pDibInfoSrc, PDIBBITS pDibBitsSrc, PRECT prcSrc, COLORREF crTransparent, ALPHAREF arAlpha, DWORD dwRop) { SCODE sc = NOERROR; int iNumSrcRows, iNumSrcCols, iSrcScanLength, iNumDstRows, iNumDstCols, iDstScanLength, iHorizMirror = 1, iVertMirror = 1; BYTE *pdSrcScanLine; BYTE *pdDstScanLine; // If the bitmaps overlap, we need to use overlapping code if(BlitLib_Detect_Intersection(pDibBitsDst, prcDst, pDibBitsSrc, prcSrc)) return BlitLib_BitBlt24Pto24P_Intersect(pDibInfoDst, pDibBitsDst, prcDst, pDibInfoSrc, pDibBitsSrc, prcSrc, crTransparent, arAlpha, dwRop); // normalize orientation of source and destination rectangles, and compute sizes // and relative orientations of source and destination rects if ((iNumSrcCols = BLITLIB_RECTWIDTH(prcSrc)) < 0) { iNumSrcCols = -iNumSrcCols; FlipRectHorizontal(prcSrc); FlipRectHorizontal(prcDst); } if ((iNumSrcRows = BLITLIB_RECTHEIGHT(prcSrc)) < 0) { iNumSrcRows = -iNumSrcRows; FlipRectVertical(prcSrc); FlipRectVertical(prcDst); } if ((iNumDstCols = BLITLIB_RECTWIDTH(prcDst)) < 0) { prcDst->left--; prcDst->right--; iNumDstCols = -iNumDstCols; iHorizMirror = -1; } if ((iNumDstRows = BLITLIB_RECTHEIGHT(prcDst)) < 0) { prcDst->top--; prcDst->bottom--; iNumDstRows = -iNumDstRows; iVertMirror = -1; } // compute pointers to the starting rows in the src and dst bitmaps // taking care to invert y values, since DIBs are upside-down pdSrcScanLine = (BYTE*) pDibBitsSrc + prcSrc->top * (iSrcScanLength = DibWidthBytes(pDibInfoSrc)) + (prcSrc->left * 3); pdDstScanLine = (BYTE *) pDibBitsDst + prcDst->top * (iDstScanLength = DibWidthBytes(pDibInfoDst)) + (prcDst->left * 3); // check if we're doing blending if (arAlpha == ALPHA_INVALID) { // no blending desired // check to see if we need to worry about transparency if (crTransparent == CLR_INVALID) { // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { // check if we can do a straight copy vertically, // or if we have to stretch, shrink, or mirror if ((iNumSrcRows == iNumDstRows) && (iVertMirror == 1)) { // This is the 8->8 blit with 3 times as many columns Blt08to08_NoTrans_Hcopy_SRCCOPY_Vcopy(pdSrcScanLine,iSrcScanLength, pdDstScanLine,iDstScanLength, iNumDstCols * 3,iNumDstRows); } else // must stretch/mirror vertically { Blt24Pto24P_NoBlend_NoTrans_Hcopy_SRCCOPY_NoVcopy(pdSrcScanLine,iSrcScanLength, iNumSrcRows,pdDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows); } } else // not SRCCOPY sc |= E_UNEXPECTED; // non-SRCCOPY unsupported!!!! we need better error codes } else // must stretch/mirror horizontally (and maybe vertically) { if (dwRop == SRCCOPY) { Blt24Pto24P_NoBlend_NoTrans_NoHcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pdDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } else // Transparent blt { // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { // check if we can do a straight copy vertically, // or if we have to stretch, shrink, or mirror if ((iNumSrcRows == iNumDstRows) && (iVertMirror == 1)) { Blt24Pto24P_NoBlend_Trans_Hcopy_SRCCOPY_VCopy(pdSrcScanLine,iSrcScanLength, pdDstScanLine,iDstScanLength, iNumDstCols,iNumDstRows, crTransparent); } else // must stretch/mirror vertically { Blt24Pto24P_NoBlend_Trans_Hcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength, iNumSrcRows, pdDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows, crTransparent); } } else // not SRCCOPY sc |= E_UNEXPECTED; // !!!! we need better error codes } else // must stretch/mirror horizontally and maybe vertically { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt24Pto24P_NoBlend_Trans_NoHcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pdDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror, crTransparent); } else // not SRCCOPY sc |= E_UNEXPECTED; // !!!! we need better error codes } } } else // blending desired { #ifdef DDRAW return E_UNEXPECTED; #else // if alpha value is zero, we do no work since the source bitmap // contributes nothing to the destination bitmap if (!(arAlpha & ALPHA_MASK)) { return sc; } // check to see if we need to worry about transparency if (crTransparent == CLR_INVALID) { // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { // check if we can do a straight copy vertically, // or if we have to stretch, shrink, or mirror if ((iNumSrcRows == iNumDstRows) && (iVertMirror == 1)) { Blt24Pto24P_Blend_NoTrans_Hcopy_SRCCOPY_VCopy(pdSrcScanLine,iSrcScanLength, pdDstScanLine,iDstScanLength, iNumDstCols,iNumDstRows, arAlpha); } else // must stretch/mirror vertically { sc |= E_UNEXPECTED; // !!!! we need better error codes } } else // not SRCCOPY sc |= E_UNEXPECTED; // !!!! we need better error codes } else // must mirror/stretch horizontally { sc |= E_UNEXPECTED; // !!!! we need better error codes } } else // transparent blit { // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { // check if we can do a straight copy vertically, // or if we have to stretch, shrink, or mirror if ((iNumSrcRows == iNumDstRows) && (iVertMirror == 1)) { Blt24Pto24P_Blend_Trans_Hcopy_SRCCOPY_VCopy(pdSrcScanLine,iSrcScanLength, pdDstScanLine,iDstScanLength, iNumDstCols,iNumDstRows, crTransparent,arAlpha); } else // must stretch/mirror vertically { sc |= E_UNEXPECTED; // !!!! we need better error codes } } else // not SRCCOPY sc |= E_UNEXPECTED; // !!!! we need better error codes } else // must stretch/mirror horizontally { sc |= E_UNEXPECTED; // !!!! we need better error codes } } #endif } return sc; } /////////////////////////////////////////////////////////////////////// // // Private BlitLib_BitBlt24Pto24P_Intersect - // BitBlit from source bitmap to destination bitmap (and these // bitmaps overlap each other) with optional transparency and/or // alpha blending using the specified raster operation. // // Parameters: // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB // pDibBitsDst Pointer to the bits for the Destination DIB // prcDst Pointer to the Destination rectangle // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB // pDibBitsSrc Pointer to the bits for the Source DIB // prcSrc Pointer to the Source rectangle // crTransparent Tranparent color value // arAlpha Per-surface Alpha value // dwRop Raster Operation for the blit // // Return Value: // NO_ERROR or E_* value as specified in the .H file. // // Status: Incomplete // /////////////////////////////////////////////////////////////////////// SCODE BlitLib_BitBlt24Pto24P_Intersect(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst, PRECT prcDst, PDIBINFO pDibInfoSrc, PDIBBITS pDibBitsSrc, PRECT prcSrc, COLORREF crTransparent, ALPHAREF arAlpha, DWORD dwRop) { SCODE sc = NOERROR; int iNumSrcRows, iNumSrcCols, iSrcScanLength, iNumDstRows, iNumDstCols, iDstScanLength, iHorizMirror = 1, iVertMirror = 1; BYTE *pbSrcScanLine, *pbDstScanLine, *pbTempScanLine; PDIBBITS pDibBitsTemp; // normalize orientation of source and destination rectangles, and // compute sizes and relative orientations of source and destination rects if ((iNumSrcCols = BLITLIB_RECTWIDTH(prcSrc)) < 0) { iNumSrcCols = -iNumSrcCols; FlipRectHorizontal(prcSrc); FlipRectHorizontal(prcDst); } if ((iNumSrcRows = BLITLIB_RECTHEIGHT(prcSrc)) < 0) { iNumSrcRows = -iNumSrcRows; FlipRectVertical(prcSrc); FlipRectVertical(prcDst); } if ((iNumDstCols = BLITLIB_RECTWIDTH(prcDst)) < 0) { prcDst->left--; prcDst->right--; iNumDstCols = -iNumDstCols; iHorizMirror = -1; } if ((iNumDstRows = BLITLIB_RECTHEIGHT(prcDst)) < 0) { prcDst->top--; prcDst->bottom--; iNumDstRows = -iNumDstRows; iVertMirror = -1; } // We aren't currently support any ROP's besides SRCCOPY if(dwRop != SRCCOPY) return E_UNEXPECTED; // // Here are all the stretching and mirroring blits for overlapping rects // // REVIEW!!! -- The following code could be optimized for the caching // cases. Currently, it allocates a second bitmap that is the same // size as the original destination, and then uses the original blit // rectangle to do the caching. To save space, this blit should // eventually be changed to only allocate the size of the overlapped // rectangle, and the blit rects should be adjusted accordingly. // Check if we are stretching (horiz or vert), or if we are mirroring -- // In all of these cases, we must create a cache bitmap and double blit if((iNumDstCols != iNumSrcCols) || (iNumDstRows != iNumSrcRows) || (iHorizMirror != 1) || (iVertMirror != 1)) { // Allocate memory for the cache bitmap -- We will blit into this // temporary bitmap and then re-blit back to the original source pDibBitsTemp = (PDIBBITS)osMemAlloc(DibSizeImage((LPBITMAPINFOHEADER)pDibInfoDst)); if(pDibBitsTemp == NULL) return DDERR_OUTOFMEMORY; // compute pointers to the starting rows in the src and temp bitmaps pbSrcScanLine = (BYTE *) pDibBitsSrc + (prcSrc->top) * (iSrcScanLength = DibWidthBytes(pDibInfoSrc)) + prcSrc->left*3; pbTempScanLine = (BYTE *) pDibBitsTemp + (prcDst->top) * (iDstScanLength = DibWidthBytes(pDibInfoDst)) + prcDst->left*3; // check if we can do a straight copy from src row to dst row if((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check if we can do a straight copy vertically, // or if we have to stretch, shrink, or mirror if ((iNumSrcRows == iNumDstRows) && (iVertMirror == 1)) { Blt08to08_NoTrans_Hcopy_SRCCOPY_Vcopy(pbSrcScanLine,iSrcScanLength, pbTempScanLine,iDstScanLength, iNumDstCols*3,iNumDstRows); } else { Blt24Pto24P_NoBlend_NoTrans_Hcopy_SRCCOPY_NoVcopy(pbSrcScanLine,iSrcScanLength, iNumSrcRows,pbTempScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows); } } else { Blt24Pto24P_NoBlend_NoTrans_NoHcopy_SRCCOPY(pbSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pbTempScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror); } // Recalculate the scan line pointers for the second blit if(BLITLIB_RECTWIDTH(prcDst) < 0) { prcDst->left++; prcDst->right++; FlipRectHorizontal(prcDst); } if(BLITLIB_RECTHEIGHT(prcDst) < 0) { prcDst->top++; prcDst->bottom++; FlipRectVertical(prcDst); } // compute pointers to the starting rows in the temp and dest bitmaps pbTempScanLine = (BYTE*) pDibBitsTemp + (prcDst->top) * (iDstScanLength = DibWidthBytes(pDibInfoDst)) + prcDst->left*3; pbDstScanLine = (BYTE*) pDibBitsDst + (prcDst->top) * (iDstScanLength = DibWidthBytes(pDibInfoDst)) + prcDst->left*3; // Now blit from the temporary bitmap back to the original source, // checking for transparency if necessary if(crTransparent == CLR_INVALID) { Blt08to08_NoTrans_Hcopy_SRCCOPY_Vcopy(pbTempScanLine,iDstScanLength, pbDstScanLine,iDstScanLength, 3*iNumDstCols,iNumDstRows); } else { Blt24Pto24P_NoBlend_Trans_Hcopy_SRCCOPY(pbTempScanLine,iDstScanLength, iNumDstRows,pbDstScanLine, iDstScanLength, iNumDstCols, iNumDstRows, crTransparent); } // Free the memory from the temporary bitmap if(pDibBitsTemp) { osMemFree(pDibBitsTemp); } pDibBitsTemp = NULL; return sc; } // // Here are all the non-stretching and non-mirroring blits for overlapping rects // // check if we're doing blending if (arAlpha == ALPHA_INVALID) { // no blending desired // check to see if we need to worry about transparency if (crTransparent == CLR_INVALID) { // Simplest case, they are the same rectangles if((prcDst->left == prcSrc->left) && (prcDst->top == prcSrc->top) && (prcDst->right == prcSrc->right) && (prcDst->bottom == prcSrc->bottom)) return sc; // Next case, the destination rectangle is vertically greater in // magnitude than the source rectangle else if(prcDst->top > prcSrc->top) { // compute pointers to the starting rows in the src and dst bitmaps // taking care to decrement the bottom rect edge since we are // going from bottom to top pbSrcScanLine = (BYTE*) pDibBitsSrc + (prcSrc->bottom - 1) * (iSrcScanLength = DibWidthBytes(pDibInfoSrc)) + (prcSrc->left * 3); pbDstScanLine = (BYTE*) pDibBitsDst + (prcDst->bottom - 1) * (iDstScanLength = DibWidthBytes(pDibInfoDst)) + (prcDst->left * 3); // Call the appropriate blit Blt08to08_LeftToRight_BottomToTop_SRCCOPY(pbSrcScanLine, iSrcScanLength, pbDstScanLine, iDstScanLength, iNumDstCols * 3, iNumDstRows); } // Next case, the destination rectangle is horizontally less than // or equal in magnitude to the source rectangle else if(prcDst->left <= prcSrc->left) { // compute pointers to the starting rows in the src and dst bitmaps pbSrcScanLine = (BYTE*) pDibBitsSrc + (prcSrc->top) * (iSrcScanLength = DibWidthBytes(pDibInfoSrc)) + (prcSrc->left * 3); pbDstScanLine = (BYTE*) pDibBitsDst + (prcDst->top) * (iDstScanLength = DibWidthBytes(pDibInfoDst)) + (prcDst->left * 3); // Call the appropriate blit Blt08to08_NoTrans_Hcopy_SRCCOPY_Vcopy(pbSrcScanLine,iSrcScanLength, pbDstScanLine,iDstScanLength, iNumDstCols * 3,iNumDstRows); } // Last case, the destination rectangle is horizontally greater // in magnitude than the source rectangle else { // compute pointers to the starting rows in the src and dst bitmaps // taking care to decrement the right rect edge since we are // going from right to left pbSrcScanLine = (BYTE*) pDibBitsSrc + (prcSrc->top) * (iSrcScanLength = DibWidthBytes(pDibInfoSrc)) + (((prcSrc->right - 1) * 3) + 2); pbDstScanLine = (BYTE*) pDibBitsDst + (prcDst->top) * (iDstScanLength = DibWidthBytes(pDibInfoDst)) + (((prcDst->right - 1) * 3) + 2); // Call the appropriate blit Blt08to08_RightToLeft_TopToBottom_SRCCOPY(pbSrcScanLine, iSrcScanLength, pbDstScanLine, iDstScanLength, iNumDstCols * 3, iNumDstRows); } } else // transparent blt { // Simplest case, they are the same rectangles if((prcDst->left == prcSrc->left) && (prcDst->top == prcSrc->top) && (prcDst->right == prcSrc->right) && (prcDst->bottom == prcSrc->bottom)) return sc; // Next case, the destination rectangle is vertically greater in // magnitude than the source rectangle else if(prcDst->top > prcSrc->top) { // compute pointers to the starting rows in the src and dst bitmaps // taking care to decrement the bottom rect edge since we are // going from bottom to top pbSrcScanLine = (BYTE*) pDibBitsSrc + (prcSrc->bottom - 1) * (iSrcScanLength = DibWidthBytes(pDibInfoSrc)) + (prcSrc->left * 3); pbDstScanLine = (BYTE*) pDibBitsDst + (prcDst->bottom - 1) * (iDstScanLength = DibWidthBytes(pDibInfoDst)) + (prcDst->left * 3); // Call the appropriate blit Blt24Pto24P_LeftToRight_BottomToTop_Trans_SRCCOPY(pbSrcScanLine, iSrcScanLength, pbDstScanLine, iDstScanLength, iNumDstCols, iNumDstRows, crTransparent); } // Next case, the destination rectangle is horizontally less than // or equal in magnitude to the source rectangle else if(prcDst->left <= prcSrc->left) { // compute pointers to the starting rows in the src and dst bitmaps pbSrcScanLine = (BYTE*) pDibBitsSrc + (prcSrc->top) * (iSrcScanLength = DibWidthBytes(pDibInfoSrc)) + (prcSrc->left * 3); pbDstScanLine = (BYTE*) pDibBitsDst + (prcDst->top) * (iDstScanLength = DibWidthBytes(pDibInfoDst)) + (prcDst->left * 3); // Call the appropriate blit Blt24Pto24P_NoBlend_Trans_Hcopy_SRCCOPY_VCopy(pbSrcScanLine,iSrcScanLength, pbDstScanLine, iDstScanLength, iNumDstCols, iNumDstRows, crTransparent); } // Last case, the destination rectangle is horizontally greater // in magnitude than the source rectangle else { // compute pointers to the starting rows in the src and dst bitmaps // taking care to decrement the right rect edge since we are // going from right to left pbSrcScanLine = (BYTE*) pDibBitsSrc + (prcSrc->top) * (iSrcScanLength = DibWidthBytes(pDibInfoSrc)) + ((prcSrc->right - 1) * 3); pbDstScanLine = (BYTE*) pDibBitsDst + (prcDst->top) * (iDstScanLength = DibWidthBytes(pDibInfoDst)) + ((prcDst->right - 1) * 3); // Call the appropriate blit Blt24Pto24P_RightToLeft_TopToBottom_Trans_SRCCOPY(pbSrcScanLine, iSrcScanLength, pbDstScanLine, iDstScanLength, iNumDstCols, iNumDstRows, crTransparent); } } } else { // We're doing alpha blending #ifdef DDRAW return E_UNEXPECTED; #else // check to see if we need to worry about transparency if (crTransparent == CLR_INVALID) { // Simplest case, they are the same rectangles if((prcDst->left == prcSrc->left) && (prcDst->top == prcSrc->top) && (prcDst->right == prcSrc->right) && (prcDst->bottom == prcSrc->bottom)) return sc; // Next case, the destination rectangle is vertically greater in // magnitude than the source rectangle else if(prcDst->top > prcSrc->top) { // compute pointers to the starting rows in the src and dst bitmaps // taking care to decrement the bottom rect edge since we are // going from bottom to top pbSrcScanLine = (BYTE*) pDibBitsSrc + (prcSrc->bottom - 1) * (iSrcScanLength = DibWidthBytes(pDibInfoSrc)) + (prcSrc->left * 3); pbDstScanLine = (BYTE*) pDibBitsDst + (prcDst->bottom - 1) * (iDstScanLength = DibWidthBytes(pDibInfoDst)) + (prcDst->left * 3); // Call the appropriate blit Blt24Pto24P_LeftToRight_BottomToTop_Alpha_SRCCOPY(pbSrcScanLine, iSrcScanLength, pbDstScanLine, iDstScanLength, iNumDstCols, iNumDstRows, arAlpha); } // Next case, the destination rectangle is horizontally less than // or equal in magnitude to the source rectangle else if(prcDst->left <= prcSrc->left) { // compute pointers to the starting rows in the src and dst bitmaps pbSrcScanLine = (BYTE*) pDibBitsSrc + (prcSrc->top) * (iSrcScanLength = DibWidthBytes(pDibInfoSrc)) + (prcSrc->left * 3); pbDstScanLine = (BYTE*) pDibBitsDst + (prcDst->top) * (iDstScanLength = DibWidthBytes(pDibInfoDst)) + (prcDst->left * 3); // Call the appropriate blit Blt24Pto24P_Blend_NoTrans_Hcopy_SRCCOPY_VCopy(pbSrcScanLine,iSrcScanLength, pbDstScanLine,iDstScanLength, iNumDstCols,iNumDstRows,arAlpha); } // Last case, the destination rectangle is horizontally greater // in magnitude than the source rectangle else { // compute pointers to the starting rows in the src and dst bitmaps // taking care to decrement the right rect edge since we are // going from right to left pbSrcScanLine = (BYTE*) pDibBitsSrc + (prcSrc->top) * (iSrcScanLength = DibWidthBytes(pDibInfoSrc)) + ((prcSrc->right - 1) * 3); pbDstScanLine = (BYTE*) pDibBitsDst + (prcDst->top) * (iDstScanLength = DibWidthBytes(pDibInfoDst)) + ((prcDst->right - 1) * 3); // Call the appropriate blit Blt24Pto24P_RightToLeft_TopToBottom_Alpha_SRCCOPY(pbSrcScanLine, iSrcScanLength, pbDstScanLine, iDstScanLength, iNumDstCols, iNumDstRows, arAlpha); } } else { // Simplest case, they are the same rectangles if((prcDst->left == prcSrc->left) && (prcDst->top == prcSrc->top) && (prcDst->right == prcSrc->right) && (prcDst->bottom == prcSrc->bottom)) return sc; // Next case, the destination rectangle is vertically greater in // magnitude than the source rectangle else if(prcDst->top > prcSrc->top) { // compute pointers to the starting rows in the src and dst bitmaps // taking care to decrement the bottom rect edge since we are // going from bottom to top pbSrcScanLine = (BYTE*) pDibBitsSrc + (prcSrc->bottom - 1) * (iSrcScanLength = DibWidthBytes(pDibInfoSrc)) + (prcSrc->left * 3); pbDstScanLine = (BYTE*) pDibBitsDst + (prcDst->bottom - 1) * (iDstScanLength = DibWidthBytes(pDibInfoDst)) + (prcDst->left * 3); // Call the appropriate blit Blt24Pto24P_LeftToRight_BottomToTop_Trans_Alpha_SRCCOPY(pbSrcScanLine, iSrcScanLength, pbDstScanLine, iDstScanLength, iNumDstCols, iNumDstRows, crTransparent, arAlpha); } // Next case, the destination rectangle is horizontally less than // or equal in magnitude to the source rectangle else if(prcDst->left <= prcSrc->left) { // compute pointers to the starting rows in the src and dst bitmaps pbSrcScanLine = (BYTE*) pDibBitsSrc + (prcSrc->top) * (iSrcScanLength = DibWidthBytes(pDibInfoSrc)) + (prcSrc->left * 3); pbDstScanLine = (BYTE*) pDibBitsDst + (prcDst->top) * (iDstScanLength = DibWidthBytes(pDibInfoDst)) + (prcDst->left * 3); // Call the appropriate blit Blt24Pto24P_Blend_Trans_Hcopy_SRCCOPY_VCopy(pbSrcScanLine,iSrcScanLength, pbDstScanLine, iDstScanLength, iNumDstCols, iNumDstRows, crTransparent, arAlpha); } // Last case, the destination rectangle is horizontally greater // in magnitude than the source rectangle else { // compute pointers to the starting rows in the src and dst bitmaps // taking care to decrement the right rect edge since we are // going from right to left pbSrcScanLine = (BYTE*) pDibBitsSrc + (prcSrc->top) * (iSrcScanLength = DibWidthBytes(pDibInfoSrc)) + ((prcSrc->right - 1) * 3); pbDstScanLine = (BYTE*) pDibBitsDst + (prcDst->top) * (iDstScanLength = DibWidthBytes(pDibInfoDst)) + ((prcDst->right - 1) * 3); // Call the appropriate blit Blt24Pto24P_RightToLeft_TopToBottom_Trans_Alpha_SRCCOPY(pbSrcScanLine, iSrcScanLength, pbDstScanLine, iDstScanLength, iNumDstCols, iNumDstRows, crTransparent, arAlpha); } } #endif /* !DDRAW */ } return sc; } #ifndef DDRAW /////////////////////////////////////////////////////////////////////// // // Private BlitLib_BitBlt24Ato24 - // BitBlit from source bitmap to Dstination bitmap // with optional transparency and/or alpha blending using the // specified raster operation. // // Parameters: // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB // pDibBitsDst Pointer to the bits for the Destination DIB // prcDst Pointer to the Destination rectangle // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB // pDibBitsSrc Pointer to the bits for the Source DIB // prcSrc Pointer to the Source rectangle // crTransparent Tranparent color value // arAlpha Per-surface Alpha value // dwRop Raster Operation for the blit // // Return Value: // NO_ERROR or E_* value as specified in the .H file. // // Status: Incomplete // /////////////////////////////////////////////////////////////////////// SCODE BlitLib_BitBlt24Ato24(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst, PRECT prcDst, PDIBINFO pDibInfoSrc, PDIBBITS pDibBitsSrc, PRECT prcSrc, COLORREF crTransparent, ALPHAREF arAlpha, DWORD dwRop) { SCODE sc = NOERROR; int iNumSrcRows, iNumSrcCols, iSrcScanLength, iNumDstRows, iNumDstCols, iDstScanLength, iHorizMirror = 1, iVertMirror = 1; DWORD *pdSrcScanLine, *pdDstScanLine; // normalize orientation of source and destination rectangles, and compute sizes // and relative orientations of source and destination rects if ((iNumSrcCols = BLITLIB_RECTWIDTH(prcSrc)) < 0) { iNumSrcCols = -iNumSrcCols; FlipRectHorizontal(prcSrc); FlipRectHorizontal(prcDst); } if ((iNumSrcRows = BLITLIB_RECTHEIGHT(prcSrc)) < 0) { iNumSrcRows = -iNumSrcRows; FlipRectVertical(prcSrc); FlipRectVertical(prcDst); } if ((iNumDstCols = BLITLIB_RECTWIDTH(prcDst)) < 0) { prcDst->left--; prcDst->right--; iNumDstCols = -iNumDstCols; iHorizMirror = -1; } if ((iNumDstRows = BLITLIB_RECTHEIGHT(prcDst)) < 0) { prcDst->top--; prcDst->bottom--; iNumDstRows = -iNumDstRows; iVertMirror = -1; } // compute pointers to the starting rows in the src and dst bitmaps // taking care to invert y values, since DIBs are upside-down pdSrcScanLine = (DWORD*) pDibBitsSrc + prcSrc->top * (iSrcScanLength = DibWidthBytes(pDibInfoSrc) / 4) + prcSrc->left; pdDstScanLine = (DWORD*) pDibBitsDst + prcDst->top * (iDstScanLength = DibWidthBytes(pDibInfoDst) / 4) + prcDst->left; // check if we're doing blending if (arAlpha == ALPHA_INVALID) { // no blending desired // check to see if we need to worry about transparency if (crTransparent == CLR_INVALID) { // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { // check if we can do a straight copy vertically, // or if we have to stretch, shrink, or mirror if ((iNumSrcRows == iNumDstRows) && (iVertMirror == 1)) { Blt24Ato24_NoBlend_NoTrans_Hcopy_SRCCOPY_Vcopy(pdSrcScanLine,iSrcScanLength, pdDstScanLine,iDstScanLength, iNumDstCols,iNumDstRows); } else { Blt24Ato24_NoBlend_NoTrans_Hcopy_SRCCOPY_NoVcopy(pdSrcScanLine,iSrcScanLength, iNumSrcRows,pdDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows); } } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt24Ato24_NoBlend_NoTrans_NoHcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pdDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } else { // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt24Ato24_NoBlend_Trans_Hcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength, iNumSrcRows,pdDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows, crTransparent); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt24Ato24_NoBlend_Trans_NoHcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pdDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror, crTransparent); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } } else { // blending desired // REVIEW!!!! -- This is a temporary hack based on the following premises: // // 1) In theory, per-pixel alpha should be overridable by per-surface alpha // 2) In practice, Burma does not allow per-surface alpha to override a per- // pixel bitmap. // 3) The following code for all the per-surface alpha blending bliting is // temporarily commented out so that we can verify DirectDraw NEVER EVER // calls BlitLib with both a per-pixel bitmap and a per-surface alpha // value other than ALPHA_INVALID. // // Therefore, we are currently return E_UNEXPECTED if this condition occurs. // // Although the following commented code is contrary to the Burma hardware, // we are not going to change BlitLib to Burma's implementation because we // believe it's implementation is a bug. // return E_UNEXPECTED; /* // if alpha value is zero, we do no work since the source bitmap // contributes nothing to the destination bitmap if (!(arAlpha & ALPHA_MASK)) { return sc; } // check to see if we need to worry about transparency if (crTransparent == CLR_INVALID) { // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt24Ato24_Blend_NoTrans_Hcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength, iNumSrcRows,pdDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows, arAlpha); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt24Ato24_Blend_NoTrans_NoHcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pdDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror, arAlpha); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } else { // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt24Ato24_Blend_Trans_Hcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength, iNumSrcRows,pdDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows, crTransparent,arAlpha); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt24Ato24_Blend_Trans_NoHcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pdDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror, crTransparent,arAlpha); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } }*/ } return sc; } /////////////////////////////////////////////////////////////////////// // // Private BlitLib_BitBlt24Ato24P - // BitBlit from source bitmap to Dstination bitmap // with optional transparency and/or alpha blending using the // specified raster operation. // // Parameters: // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB // pDibBitsDst Pointer to the bits for the Destination DIB // prcDst Pointer to the Destination rectangle // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB // pDibBitsSrc Pointer to the bits for the Source DIB // prcSrc Pointer to the Source rectangle // crTransparent Tranparent color value // arAlpha Per-surface Alpha value // dwRop Raster Operation for the blit // // Return Value: // NO_ERROR or E_* value as specified in the .H file. // // Status: Incomplete // /////////////////////////////////////////////////////////////////////// SCODE BlitLib_BitBlt24Ato24P(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst, PRECT prcDst, PDIBINFO pDibInfoSrc, PDIBBITS pDibBitsSrc, PRECT prcSrc, COLORREF crTransparent, ALPHAREF arAlpha, DWORD dwRop) { SCODE sc = NOERROR; int iNumSrcRows, iNumSrcCols, iSrcScanLength, iNumDstRows, iNumDstCols, iDstScanLength, iHorizMirror = 1, iVertMirror = 1; DWORD *pdSrcScanLine; BYTE *pdDstScanLine; // normalize orientation of source and destination rectangles, and compute sizes // and relative orientations of source and destination rects if ((iNumSrcCols = BLITLIB_RECTWIDTH(prcSrc)) < 0) { iNumSrcCols = -iNumSrcCols; FlipRectHorizontal(prcSrc); FlipRectHorizontal(prcDst); } if ((iNumSrcRows = BLITLIB_RECTHEIGHT(prcSrc)) < 0) { iNumSrcRows = -iNumSrcRows; FlipRectVertical(prcSrc); FlipRectVertical(prcDst); } if ((iNumDstCols = BLITLIB_RECTWIDTH(prcDst)) < 0) { prcDst->left--; prcDst->right--; iNumDstCols = -iNumDstCols; iHorizMirror = -1; } if ((iNumDstRows = BLITLIB_RECTHEIGHT(prcDst)) < 0) { prcDst->top--; prcDst->bottom--; iNumDstRows = -iNumDstRows; iVertMirror = -1; } // compute pointers to the starting rows in the src and dst bitmaps // taking care to invert y values, since DIBs are upside-down pdSrcScanLine = (DWORD*) pDibBitsSrc + prcSrc->top * (iSrcScanLength = DibWidthBytes(pDibInfoSrc) / 4) + prcSrc->left; pdDstScanLine = (BYTE *) pDibBitsDst + prcDst->top * (iDstScanLength = DibWidthBytes(pDibInfoDst)) + (prcDst->left * 3); // check if we're doing blending if (arAlpha == ALPHA_INVALID) { // no blending desired // check to see if we need to worry about transparency if (crTransparent == CLR_INVALID) { // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { // check if we can do a straight copy vertically, // or if we have to stretch, shrink, or mirror if ((iNumSrcRows == iNumDstRows) && (iVertMirror == 1)) { Blt24Ato24P_NoBlend_NoTrans_Hcopy_SRCCOPY_Vcopy(pdSrcScanLine,iSrcScanLength, pdDstScanLine,iDstScanLength, iNumDstCols,iNumDstRows); } else { Blt24Ato24P_NoBlend_NoTrans_Hcopy_SRCCOPY_NoVcopy(pdSrcScanLine,iSrcScanLength, iNumSrcRows,pdDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows); } } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt24Ato24P_NoBlend_NoTrans_NoHcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pdDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } else { // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt24Ato24P_NoBlend_Trans_Hcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength, iNumSrcRows,pdDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows, crTransparent); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt24Ato24P_NoBlend_Trans_NoHcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pdDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror, crTransparent); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } } else { // blending desired // REVIEW!!!! -- This is a temporary hack based on the following premises: // // 1) In theory, per-pixel alpha should be overridable by per-surface alpha // 2) In practice, Burma does not allow per-surface alpha to override a per- // pixel bitmap. // 3) The following code for all the per-surface alpha blending bliting is // temporarily commented out so that we can verify DirectDraw NEVER EVER // calls BlitLib with both a per-pixel bitmap and a per-surface alpha // value other than ALPHA_INVALID. // // Therefore, we are currently return E_UNEXPECTED if this condition occurs. // // Although the following commented code is contrary to the Burma hardware, // we are not going to change BlitLib to Burma's implementation because we // believe it's implementation is a bug. // return E_UNEXPECTED; /* // if alpha value is zero, we do no work since the source bitmap // contributes nothing to the destination bitmap if (!(arAlpha & ALPHA_MASK)) { return sc; } // check to see if we need to worry about transparency if (crTransparent == CLR_INVALID) { // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt24Ato24P_Blend_NoTrans_Hcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength, iNumSrcRows,pdDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows, arAlpha); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt24Ato24P_Blend_NoTrans_NoHcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pdDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror, arAlpha); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } else { // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt24Ato24P_Blend_Trans_Hcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength, iNumSrcRows,pdDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows, crTransparent,arAlpha); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt24Ato24P_Blend_Trans_NoHcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pdDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror, crTransparent,arAlpha); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } }*/ } return sc; } /////////////////////////////////////////////////////////////////////// // // Private BlitLib_BitBlt24Ato24A - // BitBlit from source bitmap to Dstination bitmap // with optional transparency and/or alpha blending using the // specified raster operation. // // This blit is special because it uses the regular 24to24 blits // to do all of its work. This blit is a COPY ONLY blit, thus, // it does NOT do any alpha blending. However, it does copy the // alpha channel value for each pixel to the destination. // // Parameters: // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB // pDibBitsDst Pointer to the bits for the Destination DIB // prcDst Pointer to the Destination rectangle // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB // pDibBitsSrc Pointer to the bits for the Source DIB // prcSrc Pointer to the Source rectangle // crTransparent Tranparent color value // arAlpha Per-surface Alpha value // dwRop Raster Operation for the blit // // Return Value: // NO_ERROR or E_* value as specified in the .H file. // // Status: Incomplete // /////////////////////////////////////////////////////////////////////// SCODE BlitLib_BitBlt24Ato24A(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst, PRECT prcDst, PDIBINFO pDibInfoSrc, PDIBBITS pDibBitsSrc, PRECT prcSrc, COLORREF crTransparent, ALPHAREF arAlpha, DWORD dwRop) { SCODE sc = NOERROR; int iNumSrcRows, iNumSrcCols, iSrcScanLength, iNumDstRows, iNumDstCols, iDstScanLength, iHorizMirror = 1, iVertMirror = 1; DWORD *pdSrcScanLine, *pdDstScanLine; // normalize orientation of source and destination rectangles, and compute sizes // and relative orientations of source and destination rects if ((iNumSrcCols = BLITLIB_RECTWIDTH(prcSrc)) < 0) { iNumSrcCols = -iNumSrcCols; FlipRectHorizontal(prcSrc); FlipRectHorizontal(prcDst); } if ((iNumSrcRows = BLITLIB_RECTHEIGHT(prcSrc)) < 0) { iNumSrcRows = -iNumSrcRows; FlipRectVertical(prcSrc); FlipRectVertical(prcDst); } if ((iNumDstCols = BLITLIB_RECTWIDTH(prcDst)) < 0) { prcDst->left--; prcDst->right--; iNumDstCols = -iNumDstCols; iHorizMirror = -1; } if ((iNumDstRows = BLITLIB_RECTHEIGHT(prcDst)) < 0) { prcDst->top--; prcDst->bottom--; iNumDstRows = -iNumDstRows; iVertMirror = -1; } // compute pointers to the starting rows in the src and dst bitmaps // taking care to invert y values, since DIBs are upside-down pdSrcScanLine = (DWORD*) pDibBitsSrc + prcSrc->top * (iSrcScanLength = DibWidthBytes(pDibInfoSrc) / 4) + prcSrc->left; pdDstScanLine = (DWORD*) pDibBitsDst + prcDst->top * (iDstScanLength = DibWidthBytes(pDibInfoDst) / 4) + prcDst->left; // Make sure we are not trying to alpha blend. This is a COPY ONLY blit if (arAlpha != ALPHA_INVALID) return E_INVALIDARG; // check to see if we need to worry about transparency if (crTransparent == CLR_INVALID) { // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { // check if we can do a straight copy vertically, // or if we have to stretch, shrink, or mirror if ((iNumSrcRows == iNumDstRows) && (iVertMirror == 1)) { Blt24Ato24_NoBlend_NoTrans_Hcopy_SRCCOPY_Vcopy(pdSrcScanLine,iSrcScanLength, pdDstScanLine,iDstScanLength, iNumDstCols,iNumDstRows); } else { Blt24Ato24_NoBlend_NoTrans_Hcopy_SRCCOPY_NoVcopy(pdSrcScanLine,iSrcScanLength, iNumSrcRows,pdDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows); } } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt24Ato24_NoBlend_NoTrans_NoHcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pdDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } else { // check if we can do a straight copy from src row to dst row if ((iNumSrcCols == iNumDstCols) && (iHorizMirror == 1)) { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt24Ato24_NoBlend_Trans_Hcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength, iNumSrcRows,pdDstScanLine, iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows, crTransparent); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } else { // check what ROP we'll be performing if (dwRop == SRCCOPY) { Blt24Ato24_NoBlend_Trans_NoHcopy_SRCCOPY(pdSrcScanLine,iSrcScanLength, iNumSrcCols,iNumSrcRows, pdDstScanLine,iDstScanLength * iVertMirror, iNumDstCols,iNumDstRows,iHorizMirror, crTransparent); } else sc |= E_UNEXPECTED; // !!!! we need better error codes } } return sc; } #endif // DDRAW /////////////////////////////////////////////////////////////////////// // // Private BlitLib_FillRect01 - // Fill a rectangle in the specified DIB with the desired color. // // Parameters: // PDIBINFO pbiDst - Pointer to DIB header // PDIBBITS pDst - Pointer to DIB Bits // int XDst - X Destination Start Position // int YDst - Y Destination Start Position // int nWidthDst - Width // int nHeightDst - Height // BYTE crValue - Color index // // Return Value: // NO_ERROR or E_* value as specified in the .H file. // // Status: Complete // NOTES: Put in a call to Gunter's super fast fill code instead! // /////////////////////////////////////////////////////////////////////// static const BYTE bTopMask[8] = {0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE}; static const BYTE bBottomMask[8] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F, 0x07, 0x03, 0x01}; SCODE BlitLib_FillRect01(PDIBINFO pbiDst, PDIBBITS pDst, int XDst, int YDst, int nWidthDst, int nHeightDst, BYTE crValue) { SCODE sc = NOERROR; long DstDeltaScan, WidthBytes; int y, iPixelOffset, iStartPixels, iFullBytes, iEndPixels; BYTE *pbDst, *pbEndDst, *pbDstScanline = (BYTE*) 0, bFillVal; // Calculate the delta scan amount DstDeltaScan = DibWidthBytes(pbiDst); WidthBytes = DstDeltaScan; // Calculate the starting pixel address pbDstScanline = (BYTE*) pDst + XDst / 8 + YDst * WidthBytes; iPixelOffset = XDst % 8; // set up memory fill value if (crValue) { bFillVal = 0xFF; } else { bFillVal = 0; } // calculate how many bits of first byte we have to set, how many // full bytes to set, and how many bits of last byte to set on // each scanline if (iPixelOffset) { iStartPixels = 8 - iPixelOffset; iFullBytes = (nWidthDst - iStartPixels) / 8; iEndPixels = (nWidthDst - iStartPixels) % 8; } else { iStartPixels = 0; iFullBytes = nWidthDst / 8; iEndPixels = nWidthDst % 8; } // loop to fill one scanline at a time for (y = 0; y < nHeightDst; y++) { // set pointer to beginning of scanline pbDst = pbDstScanline; // take care of pixels lying on a byte not entirely // in the scanline if (iStartPixels) { if (nWidthDst >= iStartPixels) { if (bFillVal) { *pbDst++ |= bBottomMask[iPixelOffset]; } else { *pbDst++ &= bTopMask[iPixelOffset]; } } else { if (bFillVal) { *pbDst++ |= (bBottomMask[iPixelOffset] & bTopMask[iPixelOffset + nWidthDst]); } else { *pbDst++ &= (bTopMask[iPixelOffset] | bBottomMask[iPixelOffset + nWidthDst]); } } } // fill bytes filled entirely with pixels to be set pbEndDst = pbDst + iFullBytes; for (; pbDst != pbEndDst; pbDst++) { *pbDst = bFillVal; } // take care of pixels hanging off other end into byte // not entirely on scanline if (iEndPixels) { if (bFillVal) { *pbDst |= bTopMask[iEndPixels]; } else { *pbDst &= bBottomMask[iEndPixels]; } } pbDstScanline += DstDeltaScan; } return sc; } /////////////////////////////////////////////////////////////////////// // // Private BlitLib_FillRect08 - // Fill a rectangle in the specified DIB with the desired color. // // Parameters: // PDIBINFO pbiDst - Pointer to DIB header // PDIBBITS pDst - Pointer to DIB Bits // int XDst - X Destination Start Position // int YDst - Y Destination Start Position // int nWidthDst - Width // int nHeightDst - Height // BYTE crValue - Color index // // Return Value: // NO_ERROR or E_* value as specified in the .H file. // // Status: Complete // NOTES: Put in a call to Gunter's super fast fill code instead! // /////////////////////////////////////////////////////////////////////// SCODE BlitLib_FillRect08(PDIBINFO pbiDst, PDIBBITS pDst, int XDst, int YDst, int nWidthDst, int nHeightDst, BYTE crValue) { DWORD *pBigDstPixel, *pBigEndDstPixel; BYTE *pDstScanline, *pDstPixel = (BYTE *)pDst, *pAlignedDstPixel; int iNumDwordsPerLine = nWidthDst / 4, iNumBytesLeftDst = nWidthDst % 4, iNumUnalignedDstBytes = 0, i,j, iDstDeltaScan; register DWORD dwValue = (DWORD)(crValue | (crValue << 8) | (crValue << 16) | (crValue <<24)); // Calculate the delta scan amount iDstDeltaScan = (long)(pbiDst->bmiHeader.biWidth) * 8; iDstDeltaScan = ((iDstDeltaScan + 31) & (~31)) / 8; // Calculate the starting pixel address pDstScanline = (BYTE *)pDst + XDst + YDst * iDstDeltaScan; // If the num dwords per line is less than 0, then we will just // do a byte wise fill for the < 4 bytes if(iNumDwordsPerLine){ // Find out if the src and dest pointers are dword aligned pAlignedDstPixel = (BYTE *)((((ULONG_PTR)pDstScanline) + 3) & (~3)); iNumUnalignedDstBytes = (int)(pAlignedDstPixel - pDstScanline); // Now decrement the number of dwords per line and the // number of bytes left over as appropriate if(iNumUnalignedDstBytes <= iNumBytesLeftDst) iNumBytesLeftDst -= iNumUnalignedDstBytes; else{ iNumBytesLeftDst = sizeof(DWORD) - iNumUnalignedDstBytes + iNumBytesLeftDst; if(iNumBytesLeftDst != sizeof(DWORD)) iNumDwordsPerLine--; } } // Do the fill for (i = 0; i < nHeightDst; i++) { // Set up the first pointer pDstPixel = pDstScanline; // First we need to copy the bytes to get to an aligned dword for(j=0; jbmiHeader.biWidth) * 16; iDstDeltaScan = ((iDstDeltaScan + 31) & (~31)) / 16; // Calculate the starting pixel address pDstScanline = (WORD *)pDst + XDst + YDst * iDstDeltaScan; // If the num dwords per line is less than 0, then we will just // do a word wise fill for the single pixel if(iNumDwordsPerLine){ // Find out if the dest pointer is dword aligned pAlignedDstPixel = (WORD *)((((ULONG_PTR)pDstScanline) + 3) & (~3)); iNumUnalignedDstWords = (int)(pAlignedDstPixel - pDstScanline); // Now decrement the number of dwords per line and the // number of bytes left over as appropriate if(iNumUnalignedDstWords <= iNumWordsLeftDst) iNumWordsLeftDst -= iNumUnalignedDstWords; else{ iNumWordsLeftDst = (sizeof(DWORD)/2) - iNumUnalignedDstWords; if(iNumWordsLeftDst != (sizeof(DWORD)/2)) iNumDwordsPerLine--; } } // Do the fill for (i = 0; i < nHeightDst; i++) { // Set up the first pointer pDstPixel = pDstScanline; // First we need to copy the bytes to get to an aligned dword for(j=0; j> 8); rgbt.rgbtRed = (BYTE)((rgb & 0xff0000) >> 16); // Calculate the number of pixels per scan line DstDeltaScan = DibWidthBytes(pbiDst); // Calculate the starting pixel address pDstScanline = ((char*)pDst) + (XDst*sizeof(RGBTRIPLE) + YDst * DstDeltaScan); // Set up aligned stores d1 = rgb | (rgb << 24); d2 = (rgb << 16) | (rgb >> 8); d3 = (rgb << 8) | (rgb >> 16); // Do the fill while (y < nHeightDst) { pDstPixel = (RGBTRIPLE*)pDstScanline; pEndPixel = pDstPixel + nWidthDst; while ( ((ULONG_PTR)pDstPixel & 0x03) && (pDstPixel < pEndPixel) ) { ((BYTE*)pDstPixel)[0] = ((BYTE*)&rgbt)[0]; ((BYTE*)pDstPixel)[1] = ((BYTE*)&rgbt)[1]; ((BYTE*)pDstPixel)[2] = ((BYTE*)&rgbt)[2]; pDstPixel++; } while (((ULONG_PTR)pDstPixel) <= (((ULONG_PTR)(pEndPixel-4)) & ~0x03)) { *(((DWORD*)pDstPixel)) = d1; *(((DWORD*)pDstPixel)+1) = d2; *(((DWORD*)pDstPixel)+2) = d3; pDstPixel +=4; } while (pDstPixel < pEndPixel) { ((BYTE*)pDstPixel)[0] = ((BYTE*)&rgbt)[0]; ((BYTE*)pDstPixel)[1] = ((BYTE*)&rgbt)[1]; ((BYTE*)pDstPixel)[2] = ((BYTE*)&rgbt)[2]; pDstPixel++; } ++y; pDstScanline += DstDeltaScan; } return sc; } /////////////////////////////////////////////////////////////////////// // // Private BlitLib_FillRect32 - // Fill a rectangle in the specified DIB with the desired color. // // Parameters: // PDIBINFO pbiDst - Pointer to DIB header // PDIBBITS pDst - Pointer to DIB Bits // int XDst - X Destination Start Position // int YDst - Y Destination Start Position // int nWidthDst - Width // int nHeightDst - Height // COLORREF crValue - ColorRef value (RGB Quad) // // Return Value: // NO_ERROR or E_* value as specified in the .H file. // // Status: Complete / UNTESTED!!!! // NOTES: Put in a call to Gunter's super fast fill code instead! // /////////////////////////////////////////////////////////////////////// SCODE BlitLib_FillRect32(PDIBINFO pbiDst, PDIBBITS pDst, int XDst, int YDst, int nWidthDst, int nHeightDst, DWORD crValue) { SCODE sc = NOERROR; long DstDeltaScan; long WidthDWords; DWORD *pDstScanline = (DWORD *) 0; int y = 0; DWORD *pDstPixel; DWORD *pEndPixel; // Calculate the delta scan amount DstDeltaScan = DibWidthBytes(pbiDst) >> 2; // don't trust the compile to deal with "/4" WidthDWords = DstDeltaScan; // Calculate the starting pixel address pDstScanline = (DWORD *)pDst + XDst + YDst * WidthDWords; // Do the fill while (y < nHeightDst) { pDstPixel = pDstScanline; pEndPixel = pDstPixel + nWidthDst; while (pDstPixel < pEndPixel) { *pDstPixel = crValue; pDstPixel++; } ++y; pDstScanline += DstDeltaScan; } return sc; } /////////////////////////////////////////////////////////////////////// // // Private BlitLib_WriteMaskFillRect32 - // Fill a rectangle in the specified DIB with the desired color using a writemask // // Parameters: // PDIBINFO pbiDst - Pointer to DIB header // PDIBBITS pDst - Pointer to DIB Bits // int XDst - X Destination Start Position // int YDst - Y Destination Start Position // int nWidthDst - Width // int nHeightDst - Height // COLORREF crValue - ColorRef value (RGB Quad) // dwWriteMask - write only those pixel bits that are turned on // // Return Value: // NO_ERROR or E_* value as specified in the .H file. // // Status: Complete / UNTESTED!!!! // NOTES: Put in a call to Gunter's super fast fill code instead! // /////////////////////////////////////////////////////////////////////// SCODE BlitLib_WriteMaskFillRect32(PDIBINFO pbiDst, PDIBBITS pDst, int XDst, int YDst, int nWidthDst, int nHeightDst, DWORD crValue,DWORD dwWriteMask) { SCODE sc = NOERROR; long DstDeltaScan; long WidthDWords; DWORD *pDstScanline = (DWORD *) 0; int y = 0; DWORD *pDstPixel; DWORD *pEndPixel; DWORD dwInvWriteMask; // Calculate the delta scan amount DstDeltaScan = DibWidthBytes(pbiDst) >> 2; // don't trust the compiler to deal with "/4" WidthDWords = DstDeltaScan; // Calculate the starting pixel address pDstScanline = (DWORD *)pDst + XDst + YDst * WidthDWords; crValue&=dwWriteMask; // turn off bits in fill value that wont be used dwInvWriteMask= ~dwWriteMask; // will turn off bits to be overwritten in DstPixel // Do the fill while (y < nHeightDst) { pDstPixel = pDstScanline; pEndPixel = pDstPixel + nWidthDst; while (pDstPixel < pEndPixel) { *pDstPixel = (*pDstPixel & dwInvWriteMask) | crValue; pDstPixel++; } ++y; pDstScanline += DstDeltaScan; } return sc; } /////////////////////////////////////////////////////////////////////// // // Private BlitLib_WriteMaskFillRect16 - // Fill a rectangle in the specified DIB with the desired color using a writemask // // Parameters: // PDIBINFO pbiDst - Pointer to DIB header // PDIBBITS pDst - Pointer to DIB Bits // int XDst - X Destination Start Position // int YDst - Y Destination Start Position // int nWidthDst - Width // int nHeightDst - Height // COLORREF crValue - ColorRef value (RGB Quad) // wWriteMask - write only those pixel bits that are turned on // // Return Value: // NO_ERROR or E_* value as specified in the .H file. // // Status: Complete / UNTESTED!!!! // NOTES: Put in a call to Gunter's super fast fill code instead! // /////////////////////////////////////////////////////////////////////// SCODE BlitLib_WriteMaskFillRect16(PDIBINFO pbiDst, PDIBBITS pDst, int XDst, int YDst, int nWidthDst, int nHeightDst, WORD crValue,WORD wWriteMask) { SCODE sc = NOERROR; long DstDeltaScan; long WidthDWords; WORD *pDstScanline = (WORD *) 0; int y = 0; WORD *pDstPixel; WORD *pEndPixel; WORD wInvWriteMask; // Calculate the delta scan amount DstDeltaScan = DibWidthBytes(pbiDst) >> 1; // don't trust the compiler to deal with "/2" WidthDWords = DstDeltaScan; // Calculate the starting pixel address pDstScanline = (WORD *)pDst + XDst + YDst * WidthDWords; crValue &= wWriteMask; // turn off bits in fill value that wont be used wInvWriteMask= ~wWriteMask; // will turn off bits to be overwritten in DstPixel // Do the fill while (y < nHeightDst) { pDstPixel = pDstScanline; pEndPixel = pDstPixel + nWidthDst; while (pDstPixel < pEndPixel) { *pDstPixel = (*pDstPixel & wInvWriteMask) | crValue; pDstPixel++; } ++y; pDstScanline += DstDeltaScan; } return sc; } /////////////////////////////////////////////////////////////////////// // // Private BlitLib_BitBlt - // Select the correct BitBlit and call it. // // Parameters: // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB // pDibBitsDst Pointer to the bits for the Destination DIB // prcDst Pointer to the Destination rectangle // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB // pDibBitsSrc Pointer to the bits for the Source DIB // prcSrc Pointer to the Source rectangle // crTransparent Tranparent color value // arAlpha Per-surface Alpha value // dwRop Raster Operation for the blit // // Return Value: // NO_ERROR or E_* value as specified in the .H file. // // Status: Incomplete // /////////////////////////////////////////////////////////////////////// DWORD gdwUnusedBitsMask; SCODE BlitLib_BitBlt(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst, PRECT prcDst, PDIBINFO pDibInfoSrc, PDIBBITS pDibBitsSrc, PRECT prcSrc, COLORREF crTransparent, ALPHAREF arAlpha, DWORD dwRop) { SCODE sc = NOERROR; DWORD dwBltConvType; RECT rcSrc = *prcSrc, rcDst = *prcDst; // Make sure that destination rect is at least one pixel wide and tall. // Important! Without this check we're vulnerable to divide by zero // errors in the blit routines. if ((BLITLIB_RECTWIDTH(&rcDst) == 0) || (BLITLIB_RECTHEIGHT(&rcDst) == 0)) { return sc; } /* * Set unused pixel mask to default for all non RGBA blts" */ gdwUnusedBitsMask = 0xffffff; if (((LPBITMAPINFO)pDibInfoSrc)->bmiHeader.biCompression==BI_BITFIELDS && ((LPBITMAPINFO)pDibInfoSrc)->bmiHeader.biBitCount==32) { gdwUnusedBitsMask = *(DWORD*)&((LPBITMAPINFO)pDibInfoSrc)->bmiColors[0] | *(DWORD*)&((LPBITMAPINFO)pDibInfoSrc)->bmiColors[1] | *(DWORD*)&((LPBITMAPINFO)pDibInfoSrc)->bmiColors[2]; } // Figure out the Blt Conversion type dwBltConvType = MAKELONG(GetImageFormatSpecifier(DibCompression(pDibInfoDst), DibBitCount(pDibInfoDst)), GetImageFormatSpecifier(DibCompression(pDibInfoSrc), DibBitCount(pDibInfoSrc))); switch (dwBltConvType) { case BLT_01TO01: sc |= BlitLib_BitBlt01to01(pDibInfoDst,pDibBitsDst,&rcDst, pDibInfoSrc,pDibBitsSrc,&rcSrc, crTransparent,arAlpha,dwRop); break; #ifndef DDRAW case BLT_01TO08: sc |= BlitLib_BitBlt01to08(pDibInfoDst,pDibBitsDst,&rcDst, pDibInfoSrc,pDibBitsSrc,&rcSrc, crTransparent,arAlpha,dwRop); break; case BLT_01TO24: sc |= BlitLib_BitBlt01to24(pDibInfoDst,pDibBitsDst,&rcDst, pDibInfoSrc,pDibBitsSrc,&rcSrc, crTransparent,arAlpha,dwRop); break; case BLT_08TO01: sc |= BlitLib_BitBlt08to01(pDibInfoDst,pDibBitsDst,&rcDst, pDibInfoSrc,pDibBitsSrc,&rcSrc, crTransparent,arAlpha,dwRop); break; #endif // DDRAW case BLT_08TO08: sc |= BlitLib_BitBlt08to08(pDibInfoDst,pDibBitsDst,&rcDst, pDibInfoSrc,pDibBitsSrc,&rcSrc, crTransparent,arAlpha,dwRop); break; #ifndef DDRAW case BLT_08TO24: sc |= BlitLib_BitBlt08to24(pDibInfoDst,pDibBitsDst,&rcDst, pDibInfoSrc,pDibBitsSrc,&rcSrc, crTransparent,arAlpha,dwRop); break; case BLT_08TO24P: sc |= BlitLib_BitBlt08to24P(pDibInfoDst,pDibBitsDst,&rcDst, pDibInfoSrc,pDibBitsSrc,&rcSrc, crTransparent,arAlpha,dwRop); break; case BLT_08ATO08A: sc |= BlitLib_BitBlt08Ato08A(pDibInfoDst,pDibBitsDst,&rcDst, pDibInfoSrc,pDibBitsSrc,&rcSrc, crTransparent,arAlpha,dwRop); break; case BLT_08ATO24: sc |= BlitLib_BitBlt08Ato24(pDibInfoDst,pDibBitsDst,&rcDst, pDibInfoSrc,pDibBitsSrc,&rcSrc, crTransparent,arAlpha,dwRop); break; case BLT_08ATO24P: sc |= BlitLib_BitBlt08Ato24P(pDibInfoDst,pDibBitsDst,&rcDst, pDibInfoSrc,pDibBitsSrc,&rcSrc, crTransparent,arAlpha,dwRop); break; #endif // DDRAW case BLT_16TO16: sc |= BlitLib_BitBlt16to16(pDibInfoDst,pDibBitsDst,&rcDst, pDibInfoSrc,pDibBitsSrc,&rcSrc, crTransparent,arAlpha,dwRop); break; #ifndef DDRAW case BLT_16TO24: sc |= BlitLib_BitBlt16to24(pDibInfoDst,pDibBitsDst,&rcDst, pDibInfoSrc,pDibBitsSrc,&rcSrc, crTransparent,arAlpha,dwRop); break; case BLT_16TO24P: sc |= BlitLib_BitBlt16to24P(pDibInfoDst,pDibBitsDst,&rcDst, pDibInfoSrc,pDibBitsSrc,&rcSrc, crTransparent,arAlpha,dwRop); break; case BLT_24TO01: sc |= BlitLib_BitBlt24to01(pDibInfoDst,pDibBitsDst,&rcDst, pDibInfoSrc,pDibBitsSrc,&rcSrc, crTransparent,arAlpha,dwRop); break; case BLT_24PTO01: sc |= BlitLib_BitBlt24Pto01(pDibInfoDst,pDibBitsDst,&rcDst, pDibInfoSrc,pDibBitsSrc,&rcSrc, crTransparent,arAlpha,dwRop); break; case BLT_24TO08: sc |= BlitLib_BitBlt24to08(pDibInfoDst,pDibBitsDst,&rcDst, pDibInfoSrc,pDibBitsSrc,&rcSrc, crTransparent,arAlpha,dwRop); break; case BLT_24PTO08: sc |= BlitLib_BitBlt24Pto08(pDibInfoDst,pDibBitsDst,&rcDst, pDibInfoSrc,pDibBitsSrc,&rcSrc, crTransparent,arAlpha,dwRop); break; #endif // DDRAW case BLT_24TO24: sc |= BlitLib_BitBlt24to24(pDibInfoDst,pDibBitsDst,&rcDst, pDibInfoSrc,pDibBitsSrc,&rcSrc, crTransparent,arAlpha,dwRop); break; #ifndef DDRAW case BLT_24TO24P: sc |= BlitLib_BitBlt24to24P(pDibInfoDst,pDibBitsDst,&rcDst, pDibInfoSrc,pDibBitsSrc,&rcSrc, crTransparent,arAlpha,dwRop); break; case BLT_24ATO24: sc |= BlitLib_BitBlt24Ato24(pDibInfoDst,pDibBitsDst,&rcDst, pDibInfoSrc,pDibBitsSrc,&rcSrc, crTransparent,arAlpha,dwRop); break; case BLT_24ATO24P: sc |= BlitLib_BitBlt24Ato24P(pDibInfoDst,pDibBitsDst,&rcDst, pDibInfoSrc,pDibBitsSrc,&rcSrc, crTransparent,arAlpha,dwRop); break; case BLT_24ATO24A: sc |= BlitLib_BitBlt24Ato24A(pDibInfoDst,pDibBitsDst,&rcDst, pDibInfoSrc,pDibBitsSrc,&rcSrc, crTransparent,arAlpha,dwRop); break; #endif // DDRAW case BLT_24PTO24P: sc |= BlitLib_BitBlt24Pto24P(pDibInfoDst,pDibBitsDst,&rcDst, pDibInfoSrc,pDibBitsSrc,&rcSrc, crTransparent,arAlpha,dwRop); break; default: sc |= E_UNEXPECTED; // !!!! Need better error codes! } return sc; } #define DPF_MODNAME BlitLib_WriteMaskFillRect /////////////////////////////////////////////////////////////////////// // // Private BlitLib_WriteMaskFillRect - // Select the correct WriteMaskFillRect and call it. // // Parameters: // PDIBINFO pbiDst - Pointer to DIB header // PDIBBITS pDst - Pointer to DIB Bits // int XDst - X Destination Start Position // int YDst - Y Destination Start Position // int nWidthDst - Width // int nHeightDst - Height // COLORREF crValue - ColorRef value (RGB Quad) // DWORD - dwWriteMask: 1's indicate bits that can be overwritten in pixel // // Return Value: // NO_ERROR or E_* value as specified in the .H file. // // Status: Complete // /////////////////////////////////////////////////////////////////////// SCODE BlitLib_WriteMaskFillRect(PDIBINFO pbiDst, PDIBBITS pDst, RECT * pRect, COLORREF crColor, DWORD dwWriteMask) { SCODE sc = NOERROR; int nWidthDst, nHeightDst; if (!pbiDst || !pDst || !pRect) { sc |= E_UNEXPECTED; goto ERROR_EXIT; } nWidthDst = BLITLIB_RECTWIDTH(pRect); nHeightDst = BLITLIB_RECTHEIGHT(pRect); switch (GetImageFormatSpecifier(DibCompression(pbiDst), DibBitCount(pbiDst))) { case BPP_24_RGB: sc |= BlitLib_WriteMaskFillRect32(pbiDst, pDst, pRect->left, pRect->top, nWidthDst, nHeightDst, crColor,dwWriteMask); break; case BPP_16_RGB: sc |= BlitLib_WriteMaskFillRect16(pbiDst, pDst, pRect->left, pRect->top, nWidthDst, nHeightDst, (WORD) crColor, (WORD) dwWriteMask); break; case BPP_8_PALETTEIDX: case BPP_24_RGBPACKED: // dont need these now because only stencil fmt is 32-bit (24-8) return E_NOTIMPL; case BPP_1_MONOCHROME: case BPP_16_8WALPHA: case BPP_32_24WALPHA: case BPP_16_YCRCB: case BPP_INVALID: default: sc |= E_UNEXPECTED; } // fall through ERROR_EXIT: return sc; } #undef DPF_MODNAME /////////////////////////////////////////////////////////////////////// // // Private BlitLib_FillRect - // Select the correct FillRect and call it. // // Parameters: // PDIBINFO pbiDst - Pointer to DIB header // PDIBBITS pDst - Pointer to DIB Bits // int XDst - X Destination Start Position // int YDst - Y Destination Start Position // int nWidthDst - Width // int nHeightDst - Height // COLORREF crValue - ColorRef value (RGB Quad) // // Return Value: // NO_ERROR or E_* value as specified in the .H file. // // Status: Complete // NOTES: Put in a call to Gunter's super fast fill code instead! // /////////////////////////////////////////////////////////////////////// SCODE BlitLib_FillRect(PDIBINFO pbiDst, PDIBBITS pDst, RECT * pRect, COLORREF crColor) { SCODE sc = NOERROR; int nWidthDst, nHeightDst; if (!pbiDst || !pDst || !pRect) { sc |= E_UNEXPECTED; goto ERROR_EXIT; } nWidthDst = BLITLIB_RECTWIDTH(pRect); nHeightDst = BLITLIB_RECTHEIGHT(pRect); switch (GetImageFormatSpecifier(DibCompression(pbiDst), DibBitCount(pbiDst))) { case BPP_1_MONOCHROME: { BYTE crValue = (BYTE)crColor; sc |= BlitLib_FillRect01(pbiDst, pDst, pRect->left, pRect->top, nWidthDst,nHeightDst, crValue); } break; case BPP_8_PALETTEIDX: { BYTE crValue = (BYTE)crColor; sc |= BlitLib_FillRect08(pbiDst, pDst, pRect->left, pRect->top, nWidthDst, nHeightDst, crValue); } break; case BPP_16_RGB: { WORD crValue = (WORD)crColor; sc |= BlitLib_FillRect16(pbiDst, pDst, pRect->left, pRect->top, nWidthDst, nHeightDst, crValue); } break; case BPP_24_RGBPACKED: sc |= BlitLib_FillRect24(pbiDst, pDst, pRect->left, pRect->top, nWidthDst, nHeightDst, crColor); break; case BPP_24_RGB: sc |= BlitLib_FillRect32(pbiDst, pDst, pRect->left, pRect->top, nWidthDst, nHeightDst, crColor); break; case BPP_16_8WALPHA: case BPP_32_24WALPHA: case BPP_16_YCRCB: case BPP_INVALID: default: sc |= E_UNEXPECTED; } // fall through ERROR_EXIT: return sc; } /////////////////////////////////////////////////////////////////////// // // Private BlitLib_PatBlt - // Fill an entire destination rectangle by tiling a given bitmap // // Parameters: // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB // pDibBitsDst Pointer to the bits for the Destination DIB // prcDst Pointer to the Destination rectangle // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB // pDibBitsSrc Pointer to the bits for the Source DIB // prcSrc Pointer to the Source rectangle // dwRop Raster Operation for the blit // // Return Value: // NO_ERROR or E_* value as specified in the .H file. // // Status: Incomplete // /////////////////////////////////////////////////////////////////////// SCODE BlitLib_PatBlt(PDIBINFO pDibInfoDst, PDIBBITS pDibBitsDst, PRECT prcDst, PDIBINFO pDibInfoPat, PDIBBITS pDibBitsPat, PRECT prcPat, COLORREF crTransparent, ALPHAREF arAlpha, DWORD dwRop) { SCODE sc = NOERROR; long iPatWidth; long iPatHeight; long iCurXPos; long iCurYPos; long iBlitWidth; long iBlitHeight; long iWidthLeft; long iHeightLeft; RECT rcPat = {0,0,0,0}; RECT rcDst = {0,0,0,0}; // Check for invalid rectangles -- PatBlt only works for rects that // are both (src and dest) right-side up (positive height and width). // Also set our bounding rectangle sizes in the process if(((iPatWidth = BLITLIB_RECTWIDTH(prcPat)) < 0) || ((iPatHeight = BLITLIB_RECTHEIGHT(prcPat)) < 0) || (BLITLIB_RECTWIDTH(prcDst) < 0) || (BLITLIB_RECTHEIGHT(prcDst) < 0)) return E_INVALIDARG; // Reset the Y postion to the top edge of the dest iCurYPos = prcDst->top; // Tile the pattern into the destination rectangle while (iCurYPos < prcDst->bottom){ // Set up the source rectangle heights rcPat.top = iCurYPos % iPatHeight; iHeightLeft = (prcDst->bottom - iCurYPos); // Calculate the height we are actually going to blit iBlitHeight = min(iHeightLeft, (iPatHeight - rcPat.top)); rcPat.bottom = rcPat.top + iBlitHeight; // Set up the destination rectangle heights rcDst.top = iCurYPos; rcDst.bottom = iCurYPos + iBlitHeight; // Reset the current X position to the left edge of the dest iCurXPos = prcDst->left; // Tile the pattern into the destination rectangle while (iCurXPos < prcDst->right){ // Set up the source rectangle width rcPat.left = iCurXPos % iPatWidth; iWidthLeft = (prcDst->right - iCurXPos); // Calculate the width we are actually going to blit iBlitWidth = min(iWidthLeft, (iPatWidth - rcPat.left)); rcPat.right = rcPat.left + iBlitWidth; // Set up the destination rectangle heights rcDst.left = iCurXPos; rcDst.right = iCurXPos + iBlitWidth; // REVIEW!!!! -- Do we want to check sc after each blit and return on an error? sc = BlitLib_BitBlt(pDibInfoDst, pDibBitsDst, &rcDst, pDibInfoPat, pDibBitsPat, &rcPat, crTransparent, arAlpha, dwRop); // Increment the current index value iCurXPos += iBlitWidth; } // Increment the current index value iCurYPos += iBlitHeight; } return sc; } /////////////////////////////////////////////////////////////////////// // // Private GetImageFormatSpecifier - // Select the correct bitmap format based on the compression and // bit count. // // Parameters: // dwDibComp - The DIB's compression // wdBitCount - The DIB's bit count // // Return Value: // BPP_INVALID or a valid bitmap format // // Status: Incomplete // /////////////////////////////////////////////////////////////////////// WORD GetImageFormatSpecifier(DWORD dwDibComp, WORD wdBitCount) { // Bit count could have Penguin codes in the high byte, mask them // out for a correct comparison. wdBitCount &= 0x00ff; switch (dwDibComp) { case BI_RGB: switch (wdBitCount) { case 1: return BPP_1_MONOCHROME; case 8: return BPP_8_PALETTEIDX; case 16: return BPP_16_RGB; case 24: return BPP_24_RGBPACKED; case 32: return BPP_24_RGB; default: return BPP_INVALID; } case BI_RGBA: switch (wdBitCount) { case 16: return BPP_16_8WALPHA; case 32: return BPP_32_24WALPHA; default: return BPP_INVALID; } case BI_BITFIELDS: switch (wdBitCount) { case 16: return BPP_16_RGB; // BlitLib assumes 5-6-5 RGB case 32: return BPP_24_RGB; default: return BPP_INVALID; } case BI_YCRCB: return BPP_16_YCRCB; default: switch (wdBitCount) { case 1: return BPP_1_MONOCHROME; default: return BPP_INVALID; } } return BPP_INVALID; } #ifndef DDRAW /////////////////////////////////////////////////////////////////////// // // Private BlitLib_PalIndexFromRGB - // Calculates the closest entry in an array of COLORREF's to a // given COLORREF // // Parameters: // crColor - Color to match // rgcrPal - Array of colors to match to // iNumPalColors - Number of colors in the array // // Return Value: // Palette index of the nearest color // // Status: Incomplete // /////////////////////////////////////////////////////////////////////// BYTE BlitLib_PalIndexFromRGB(COLORREF crColor,COLORREF* rgcrPal, unsigned int iNumPalColors) { BYTE bIndex = 0; int iRed = crColor & RED_MASK, iRedError, iGreen = (crColor & GREEN_MASK) >> 8, iGreenError, iBlue = (crColor & BLUE_MASK) >> 16, iBlueError, iError, iLeastError = MAX_POS_INT; for (unsigned int i = 0; i < iNumPalColors; i++) { iRedError = iRed - (rgcrPal[i] & RED_MASK); iGreenError = iGreen - ((rgcrPal[i] & GREEN_MASK) >> 8); iBlueError = iBlue - ((rgcrPal[i] & BLUE_MASK) >> 16); iError = iRedError * iRedError + iGreenError * iGreenError + iBlueError * iBlueError; if (iError < iLeastError) { iLeastError = iError; bIndex = (BYTE) i; } } return bIndex; } #endif // DDRAW #ifndef DDRAW /////////////////////////////////////////////////////////////////////// // // Private BlitLib_BLIT_BLEND24 - // Performs alpha blending on 24bpp(packed) blits. // // Parameters: // ptSrc - Pointer to the Source RGBTRIPLE // ptDst - Pointer to the Destination RGBTRIPLE // alpha - Alpha value (Range: 1 - 256) // alphacomp - Alpha complement (256 - alpha) // // Return Value: // None // /////////////////////////////////////////////////////////////////////// void BlitLib_BLIT_BLEND24(COLORREF crSrc, RGBTRIPLE * ptDst, UINT alpha, UINT alphacomp) { BYTE * pbSrc = (BYTE *)&crSrc; BYTE * pbDst = (BYTE *)ptDst; DWORD dwSrc; DWORD dwDst; UINT i; for(i=0; i> 8); *pbDst++ = (BYTE)dwDst; } } #endif /////////////////////////////////////////////////////////////////////// // // Private BlitLib_Detect_Intersection - // Detects if both the source and destination bitmaps overlap // // Parameters: // pdibbitsDst - Pointer to the Destination Bits // prcDst - Pointer to the Destination Rectangle // pdibbitsSrc - Pointer to the Source Bits // prcSrc - Pointer to the Source Rectangle // // // Return Value: // TRUE if the bitmaps overlap, FALSE if they do not // /////////////////////////////////////////////////////////////////////// BOOL BlitLib_Detect_Intersection (PDIBBITS pdibbitsDst, PRECT prcDst, PDIBBITS pdibbitsSrc, PRECT prcSrc) { RECT rc, rcSrc, rcDst; // First check to see if the pdibbits pointers point to the same bitmap if(pdibbitsDst != pdibbitsSrc) return FALSE; // REVIEW!!! - This is just a hack because IntersectRect expects // bitmaps to be oriented correctly, but I can't afford to do // it to my original prects yet rcSrc.left = prcSrc->left; rcSrc.top = prcSrc->top; rcSrc.right = prcSrc->right; rcSrc.bottom = prcSrc->bottom; rcDst.left = prcDst->left; rcDst.top = prcDst->top; rcDst.right = prcDst->right; rcDst.bottom = prcDst->bottom; if (BLITLIB_RECTWIDTH(&rcSrc) < 0) FlipRectHorizontal(&rcSrc); if (BLITLIB_RECTHEIGHT(&rcSrc) < 0) FlipRectVertical(&rcSrc); if (BLITLIB_RECTWIDTH(&rcDst) < 0) FlipRectHorizontal(&rcDst); if (BLITLIB_RECTHEIGHT(&rcDst) < 0) FlipRectVertical(&rcDst); // Now check for rectangle intersection return IntersectRect(&rc, &rcDst, &rcSrc); }