|
|
///////////////////////////////////////////////////////////////////////
//
// 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; j<iNumUnalignedDstBytes; j++) *pDstPixel++ = crValue;
// set up pointers to the first 4-pixel chunks
// on src and dst scanlines, and last chunk on
// dst scanline
pBigDstPixel = (DWORD*) pDstPixel; pBigEndDstPixel = pBigDstPixel + iNumDwordsPerLine;
// copy scanline one 4-pixel chunk at a time
while (pBigDstPixel != pBigEndDstPixel) { *pBigDstPixel++ = dwValue; }
// take care of remaining pixels on scanline
if (iNumBytesLeftDst) { pDstPixel = (BYTE*) pBigDstPixel; for(j=0; j<iNumBytesLeftDst; j++){ *pDstPixel++ = crValue; } }
// advance to next scanline
pDstScanline += iDstDeltaScan; }
return NO_ERROR; }
///////////////////////////////////////////////////////////////////////
//
// Private BlitLib_FillRect16 -
// 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
// WORD crValue - ColorRef value (RGB 5-6-5)
//
// 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_FillRect16(PDIBINFO pbiDst, PDIBBITS pDst, int XDst, int YDst, int nWidthDst, int nHeightDst, WORD crValue) { DWORD *pBigDstPixel, *pBigEndDstPixel; WORD *pDstScanline, *pDstPixel = (WORD *)pDst, *pAlignedDstPixel; int iNumDwordsPerLine = nWidthDst / 2, iNumWordsLeftDst = nWidthDst % 2, iNumUnalignedDstWords = 0, i,j, iDstDeltaScan; register DWORD dwValue = (DWORD)(crValue | (crValue << 16));
// Calculate the delta scan amount
iDstDeltaScan = (long)(pbiDst->bmiHeader.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<iNumUnalignedDstWords; j++) *pDstPixel++ = crValue;
// set up pointers to the first 4-pixel chunks
// on src and dst scanlines, and last chunk on
// dst scanline
pBigDstPixel = (DWORD*) pDstPixel; pBigEndDstPixel = pBigDstPixel + iNumDwordsPerLine;
// copy scanline one 4-pixel chunk at a time
while (pBigDstPixel != pBigEndDstPixel) { *pBigDstPixel++ = dwValue; }
// take care of remaining pixels on scanline
if (iNumWordsLeftDst) { pDstPixel = (WORD *) pBigDstPixel; for(j=0; j<iNumWordsLeftDst; j++){ *pDstPixel++ = crValue; } }
// advance to next scanline
pDstScanline += iDstDeltaScan; }
return NO_ERROR; }
///////////////////////////////////////////////////////////////////////
//
// Private BlitLib_FillRect24 -
// 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
// RGBTRIPLE rgb - RGBTRIPLE representing the fill color
//
// 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_FillRect24(PDIBINFO pbiDst, PDIBBITS pDst, int XDst, int YDst, int nWidthDst, int nHeightDst, DWORD rgb) { SCODE sc = NOERROR; long DstDeltaScan; char *pDstScanline = NULL; int x = 0; int y = 0; RGBTRIPLE *pDstPixel; RGBTRIPLE *pEndPixel; RGBTRIPLE rgbt; DWORD d1,d2,d3;
// Set up rgbt (ignore the color names - they are meaningless)
rgbt.rgbtBlue = (BYTE)(rgb & 0x0000ff); rgbt.rgbtGreen = (BYTE)((rgb & 0x00ff00) >> 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<sizeof(RGBTRIPLE); i++){ dwSrc = (DWORD)*pbSrc++; dwDst = (DWORD)*pbDst;
dwDst = ((dwSrc * alpha + dwDst * alphacomp) >> 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); }
|