Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

6959 lines
236 KiB

///////////////////////////////////////////////////////////////////////
//
// 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);
}