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