374 lines
11 KiB
C++
374 lines
11 KiB
C++
#include <common/pathfnd.hpp>
|
|
#include <common/wingblt.hpp>
|
|
#include <common/except.hpp>
|
|
|
|
WINGBlt::WINGBlt(WORD width,WORD height,PurePalette &somePurePalette)
|
|
: mhWINGDC(0), mDisposition(InvalidDC), mhWINGBitmap(0), mIsOkay(FALSE), mhLibrary(0),
|
|
mlpfnWINGCreateDC(0), mlpfnWINGCreateBitmap(0), mlpWINGData(0), mlpfnWINGBitBlt(0),
|
|
mlpfnWINGStretchBlt(0), mOrientation(BottomUp), mWINGBitmapExtent(0L), mhOldBitmap(0)
|
|
{
|
|
if(!initWING())return;
|
|
getDIBFormat();
|
|
mWINGPalette=somePurePalette;
|
|
mWINGPalette.identityPalette();
|
|
mWINGBitmapInfo=mWINGPalette;
|
|
createWINGBitmap(width,height);
|
|
}
|
|
|
|
WINGBlt::~WINGBlt()
|
|
{
|
|
destroyBitmap();
|
|
destroyDevice();
|
|
freeLibrary();
|
|
}
|
|
|
|
WORD WINGBlt::size(WORD width,WORD height)
|
|
{
|
|
if(!isOkay())return FALSE;
|
|
return createWINGBitmap(width,height);
|
|
}
|
|
|
|
void WINGBlt::getDIBFormat(void)
|
|
{
|
|
BitmapInfo bitmapInfo;
|
|
|
|
(*mlpfnWINGRecommendDIBFormat)(bitmapInfo);
|
|
mOrientation=(Orientation)bitmapInfo.height();
|
|
}
|
|
|
|
WORD WINGBlt::createWINGBitmap(WORD width,WORD height)
|
|
{
|
|
destroyBitmap();
|
|
createDevice();
|
|
getRequiredWidth(width,height);
|
|
mWINGBitmapExtent=(DWORD)width*(DWORD)height;
|
|
mWINGBitmapInfo.width(width);
|
|
mWINGBitmapInfo.height(height*(int)mOrientation);
|
|
mhWINGBitmap=(*mlpfnWINGCreateBitmap)(mhWINGDC,mWINGBitmapInfo,(void**)&mlpWINGData);
|
|
if(!mhWINGBitmap)return mIsOkay=FALSE;
|
|
setBits(mlpWINGData,mWINGBitmapExtent,0);
|
|
mhOldBitmap=(HBITMAP)::SelectObject(mhWINGDC,mhWINGBitmap);
|
|
return mIsOkay=TRUE;
|
|
}
|
|
|
|
WINGBlt &WINGBlt::operator+=(BitmapOverlay &someBitmapOverlay)
|
|
{
|
|
Point placementPoint;
|
|
DWORD newSrcY;
|
|
DWORD newDstY;
|
|
DWORD srcIndex;
|
|
DWORD dstIndex;
|
|
UINT srcRow;
|
|
UINT srcCol;
|
|
|
|
if(!isOkay())return *this;
|
|
placementPoint=someBitmapOverlay.placementPoint();
|
|
switch(mOrientation)
|
|
{
|
|
case TopDown :
|
|
for(srcRow=0;srcRow<someBitmapOverlay.bitmap().height();srcRow++)
|
|
{
|
|
for(srcCol=0;srcCol<someBitmapOverlay.bitmap().width();srcCol++)
|
|
{
|
|
newSrcY=someBitmapOverlay.bitmap().height();
|
|
srcIndex=newSrcY*someBitmapOverlay.bitmap().width()+srcCol;
|
|
newDstY=srcRow+placementPoint.y();
|
|
dstIndex=newDstY*mWINGBitmapInfo.width()+srcCol+placementPoint.x();
|
|
*(mlpWINGData+dstIndex)=*(someBitmapOverlay.bitmap().getDataPtr()+srcIndex);
|
|
}
|
|
}
|
|
break;
|
|
case BottomUp :
|
|
for(srcRow=0;srcRow<someBitmapOverlay.bitmap().height();srcRow++)
|
|
{
|
|
for(srcCol=0;srcCol<someBitmapOverlay.bitmap().width();srcCol++)
|
|
{
|
|
newSrcY=srcRow;
|
|
srcIndex=newSrcY*someBitmapOverlay.bitmap().width()+srcCol;
|
|
newDstY=mWINGBitmapInfo.height()-someBitmapOverlay.bitmap().height()-placementPoint.y()+srcRow;
|
|
dstIndex=newDstY*mWINGBitmapInfo.width()+srcCol+placementPoint.x();
|
|
*(mlpWINGData+dstIndex)=*(someBitmapOverlay.bitmap().getDataPtr()+srcIndex);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
WINGBlt &WINGBlt::operator=(Bitmap &someBitmap)
|
|
{
|
|
if(!isOkay())return *this;
|
|
if(!createWINGBitmap(someBitmap.width(),someBitmap.height()))return *this;
|
|
copyBits(mlpWINGData,someBitmap.getDataPtr(),mWINGBitmapExtent);
|
|
return *this;
|
|
}
|
|
|
|
WINGBlt &WINGBlt::operator=(PurePalette &somePurePalette)
|
|
{
|
|
mWINGPalette=somePurePalette;
|
|
mWINGPalette.identityPalette();
|
|
return *this;
|
|
}
|
|
|
|
void WINGBlt::createDevice(void)
|
|
{
|
|
destroyDevice();
|
|
mhWINGDC=(*mlpfnWINGCreateDC)();
|
|
mDisposition=DeleteDC;
|
|
}
|
|
|
|
void WINGBlt::copyBits(UHUGE *destination,UHUGE *source,DWORD length)const
|
|
{
|
|
for(DWORD count=0;count<length;count++)*destination++=*source++;
|
|
}
|
|
|
|
void WINGBlt::setBits(UHUGE *lpSrcPtr,DWORD srcExtent,BYTE charByte)
|
|
{
|
|
for(DWORD count=0;count<srcExtent;count++)*lpSrcPtr++=charByte;
|
|
}
|
|
|
|
void WINGBlt::setByte(WORD row,WORD col,BYTE byteValue)
|
|
{
|
|
if(!isOkay())return;
|
|
if(row>=mWINGBitmapInfo.height()||col>=mWINGBitmapInfo.width())return;
|
|
if(TopDown==mOrientation)setByteTopDown(row,col,byteValue);
|
|
else setByteBottomUp(row,col,byteValue);
|
|
}
|
|
|
|
BYTE WINGBlt::getByte(WORD row,WORD col)const
|
|
{
|
|
if(!isOkay())return (BYTE)FALSE;
|
|
if(row>=mWINGBitmapInfo.height()||col>=mWINGBitmapInfo.width())return (BYTE)FALSE;
|
|
if(TopDown==mOrientation)return getByteTopDown(row,col);
|
|
else return getByteBottomUp(row,col);
|
|
}
|
|
|
|
void WINGBlt::line(const Point &firstPoint,const Point &secondPoint,BYTE byteValue)
|
|
{
|
|
LONG xRunning((LONG)firstPoint.x()<<0x10);
|
|
LONG yRunning((LONG)firstPoint.y()<<0x10);
|
|
LONG xDelta;
|
|
LONG yDelta;
|
|
short xDir(1);
|
|
short yDir(1);
|
|
short steps;
|
|
|
|
if(secondPoint.x()<firstPoint.x())xDir=-1;
|
|
if(secondPoint.y()<firstPoint.y())yDir=-1;
|
|
xDelta=secondPoint.x()-firstPoint.x();
|
|
yDelta=secondPoint.y()-firstPoint.y();
|
|
if(xDelta<0)xDelta=-xDelta;
|
|
if(yDelta<0)yDelta=-yDelta;
|
|
if(xDelta<yDelta)
|
|
{
|
|
xDelta<<=0x10;
|
|
if(yDelta)xDelta/=yDelta;
|
|
else xDelta=1L;
|
|
steps=yDelta;
|
|
yDelta=0x10000;
|
|
}
|
|
else
|
|
{
|
|
yDelta<<=0x10;
|
|
if(xDelta)yDelta/=xDelta;
|
|
else yDelta=1L;
|
|
steps=xDelta;
|
|
xDelta=0x10000;
|
|
}
|
|
if(-1==xDir&&-1==yDir)
|
|
{
|
|
for(short stepIndex=0;stepIndex<steps;stepIndex++)
|
|
{
|
|
setByte(yRunning>>0x10,xRunning>>0x10,byteValue);
|
|
xRunning-=xDelta;
|
|
yRunning-=yDelta;
|
|
}
|
|
}
|
|
else if(-1==xDir&&1==yDir)
|
|
{
|
|
for(short stepIndex=0;stepIndex<steps;stepIndex++)
|
|
{
|
|
setByte(yRunning>>0x10,xRunning>>0x10,byteValue);
|
|
xRunning-=xDelta;
|
|
yRunning+=yDelta;
|
|
}
|
|
}
|
|
else if(1==xDir&&-1==yDir)
|
|
{
|
|
for(short itemIndex=0;itemIndex<steps;itemIndex++)
|
|
{
|
|
setByte(yRunning>>0x10,xRunning>>0x10,byteValue);
|
|
xRunning+=xDelta;
|
|
yRunning-=yDelta;
|
|
}
|
|
}
|
|
else if(1==xDir&&1==yDir)
|
|
{
|
|
for(short itemIndex=0;itemIndex<steps;itemIndex++)
|
|
{
|
|
setByte(yRunning>>0x10,xRunning>>0x10,byteValue);
|
|
xRunning+=xDelta;
|
|
yRunning+=yDelta;
|
|
}
|
|
}
|
|
}
|
|
|
|
void WINGBlt::setColTopDown(WORD col,WORD row,char FAR *lpColData,WORD wDataLength)
|
|
{
|
|
UHUGE *lpImage=mlpWINGData+(LONG)col;
|
|
lpImage+=((LONG)row*mWINGBitmapInfo.width());
|
|
for(;(short)row>=0&&wDataLength;row--)
|
|
{
|
|
*lpImage=*lpColData;
|
|
lpImage-=mWINGBitmapInfo.width();
|
|
lpColData--;
|
|
wDataLength--;
|
|
}
|
|
return;
|
|
}
|
|
|
|
void WINGBlt::setColBottomUp(WORD col,WORD row,char FAR *lpColData,WORD wDataLength)
|
|
{
|
|
UHUGE *lpImage=mlpWINGData+(LONG)col;
|
|
lpImage+=(mWINGBitmapInfo.width()*((mWINGBitmapInfo.height()-1L)-(LONG)row));
|
|
for(;(short)row>=0&&wDataLength;row--)
|
|
{
|
|
*lpImage=*lpColData;
|
|
lpImage+=mWINGBitmapInfo.width();
|
|
lpColData--;
|
|
wDataLength--;
|
|
}
|
|
}
|
|
|
|
void WINGBlt::setColBottomUp(WORD col,char FAR *lpColData)
|
|
{
|
|
UHUGE *lpImage=mlpWINGData+mWINGBitmapInfo.width()*mWINGBitmapInfo.height();
|
|
lpImage=(lpImage-mWINGBitmapInfo.width())+(LONG)col;
|
|
for(short rowIndex=0;rowIndex<mWINGBitmapInfo.height();rowIndex++)
|
|
{
|
|
*lpImage=*lpColData;
|
|
lpImage-=mWINGBitmapInfo.width();
|
|
lpColData++;
|
|
}
|
|
}
|
|
|
|
void WINGBlt::getColBottomUp(WORD col,char FAR *lpColData)const
|
|
{
|
|
UHUGE *lpImage=mlpWINGData+mWINGBitmapInfo.width()*mWINGBitmapInfo.height();
|
|
lpImage=(lpImage-mWINGBitmapInfo.width())+(LONG)col;
|
|
for(short rowIndex=0;rowIndex<mWINGBitmapInfo.height();rowIndex++)
|
|
{
|
|
*lpColData=*lpImage;
|
|
lpImage-=mWINGBitmapInfo.width();
|
|
lpColData++;
|
|
}
|
|
}
|
|
|
|
void WINGBlt::setRowBottomUp(WORD row,char FAR *lpRowData)
|
|
{
|
|
UHUGE *lpImage=mlpWINGData+mWINGBitmapInfo.width()*mWINGBitmapInfo.height();
|
|
copyBits((lpImage-(((LONG)row*mWINGBitmapInfo.width())+mWINGBitmapInfo.width())),(UHUGE*)lpRowData,mWINGBitmapInfo.width());
|
|
}
|
|
|
|
void WINGBlt::getRowBottomUp(WORD row,char FAR *lpRowData)const
|
|
{
|
|
UHUGE *lpImage=mlpWINGData+mWINGBitmapInfo.width()*mWINGBitmapInfo.height();
|
|
copyBits((UHUGE*)lpRowData,(lpImage-(((LONG)row*mWINGBitmapInfo.width())+mWINGBitmapInfo.width())),mWINGBitmapInfo.width());
|
|
}
|
|
|
|
void WINGBlt::setColTopDown(WORD col,char FAR *lpColData)
|
|
{
|
|
UHUGE *lpImage=mlpWINGData+(LONG)col;
|
|
for(short rowIndex=0;rowIndex<mWINGBitmapInfo.height();rowIndex++)
|
|
{
|
|
*lpImage=*lpColData;
|
|
lpImage+=mWINGBitmapInfo.width();
|
|
lpColData++;
|
|
}
|
|
}
|
|
|
|
void WINGBlt::getColTopDown(WORD col,char FAR *lpColData)const
|
|
{
|
|
UHUGE *lpImage=mlpWINGData+(LONG)col;
|
|
for(short rowIndex=0;rowIndex<mWINGBitmapInfo.height();rowIndex++)
|
|
{
|
|
*lpColData=*lpImage;
|
|
lpImage+=mWINGBitmapInfo.width();
|
|
lpColData++;
|
|
}
|
|
}
|
|
|
|
void WINGBlt::setRowTopDown(WORD row,char FAR *lpRowData)
|
|
{
|
|
UHUGE *lpImage=mlpWINGData+((LONG)row*mWINGBitmapInfo.width());
|
|
copyBits(lpImage,(UHUGE*)lpRowData,mWINGBitmapInfo.width());
|
|
}
|
|
|
|
void WINGBlt::getRowTopDown(WORD row,char FAR *lpRowData)const
|
|
{
|
|
UHUGE *lpImage=mlpWINGData+((LONG)row*mWINGBitmapInfo.width());
|
|
copyBits((UHUGE*)lpRowData,lpImage,mWINGBitmapInfo.width());
|
|
}
|
|
|
|
void WINGBlt::getRequiredWidth(WORD &desiredWidth,WORD desiredHeight)
|
|
{
|
|
DWORD imageExtent;
|
|
|
|
imageExtent=(((((LONG)desiredWidth*8)+31)&~31)>>3)*(LONG)desiredHeight;
|
|
if(imageExtent==(LONG)desiredWidth*(LONG)desiredHeight)return;
|
|
desiredWidth=(WORD)(imageExtent/(LONG)desiredHeight);
|
|
}
|
|
|
|
#if defined(__FLAT__)
|
|
WORD WINGBlt::initWING(void)
|
|
{
|
|
String wingDLLFileName("WING32.DLL");
|
|
String wingDLLPathFileName;
|
|
DWORD wingBitBltOrdinal(1L);
|
|
DWORD wingStretchBltOrdinal(10L);
|
|
DWORD wingCreateBitmapOrdinal(2L);
|
|
DWORD wingCreateDCOrdinal(3L);
|
|
DWORD wingRecommendDIBFormatOrdinal(8);
|
|
PathFind pathFind;
|
|
|
|
if(!pathFind.findFile(wingDLLFileName,wingDLLPathFileName))return FALSE;
|
|
if((mhLibrary=::LoadLibrary(wingDLLPathFileName))<(HINSTANCE)HINSTANCE_ERROR)return FALSE;
|
|
mlpfnWINGCreateDC=(LPFNWINGCREATEDC)::GetProcAddress(mhLibrary,(LPCSTR)wingCreateDCOrdinal);
|
|
mlpfnWINGCreateBitmap=(LPFNWINGCREATEBITMAP)::GetProcAddress(mhLibrary,(LPCSTR)wingCreateBitmapOrdinal);
|
|
mlpfnWINGBitBlt=(LPFNWINGBITBLT)::GetProcAddress(mhLibrary,(LPCSTR)wingBitBltOrdinal);
|
|
mlpfnWINGStretchBlt=(LPFNWINGSTRETCHBLT)::GetProcAddress(mhLibrary,(LPCSTR)wingStretchBltOrdinal);
|
|
mlpfnWINGRecommendDIBFormat=(LPFNWINGRECOMMENDDIBFORMAT)::GetProcAddress(mhLibrary,(LPCSTR)wingRecommendDIBFormatOrdinal);
|
|
if(!mlpfnWINGCreateDC)throw(NullError());
|
|
if(!mlpfnWINGCreateBitmap)throw(NullError());
|
|
if(!mlpfnWINGBitBlt)throw(NullError());
|
|
if(!mlpfnWINGStretchBlt)throw(NullError());
|
|
if(!mlpfnWINGRecommendDIBFormat)throw(NullError());
|
|
return TRUE;
|
|
}
|
|
#else
|
|
WORD WINGBlt::initWING(void)
|
|
{
|
|
String wingDLLFileName("WING.DLL");
|
|
String wingDLLPathFileName;
|
|
DWORD wingBitBltOrdinal(1010L);
|
|
DWORD wingStretchBltOrdinal(1009L);
|
|
DWORD wingCreateBitmapOrdinal(1003L);
|
|
DWORD wingCreateDCOrdinal(1001L);
|
|
DWORD wingRecommendDIBFormatOrdinal(1002);
|
|
PathFind pathFind;
|
|
|
|
if(!pathFind.findFile(wingDLLFileName,wingDLLPathFileName))return FALSE;
|
|
if((mhLibrary=::LoadLibrary(wingDLLPathFileName))<HINSTANCE_ERROR)return FALSE;
|
|
mlpfnWINGCreateDC=(LPFNWINGCREATEDC)::GetProcAddress(mhLibrary,(LPCSTR)wingCreateDCOrdinal);
|
|
mlpfnWINGCreateBitmap=(LPFNWINGCREATEBITMAP)::GetProcAddress(mhLibrary,(LPCSTR)wingCreateBitmapOrdinal);
|
|
mlpfnWINGBitBlt=(LPFNWINGBITBLT)::GetProcAddress(mhLibrary,(LPCSTR)wingBitBltOrdinal);
|
|
mlpfnWINGStretchBlt=(LPFNWINGSTRETCHBLT)::GetProcAddress(mhLibrary,(LPCSTR)wingStretchBltOrdinal);
|
|
mlpfnWINGRecommendDIBFormat=(LPFNWINGRECOMMENDDIBFORMAT)::GetProcAddress(mhLibrary,(LPCSTR)wingRecommendDIBFormatOrdinal);
|
|
if(!mlpfnWINGCreateDC)throw(NullError());
|
|
if(!mlpfnWINGCreateBitmap)throw(NullError());
|
|
if(!mlpfnWINGBitBlt)throw(NullError());
|
|
if(!mlpfnWINGStretchBlt)throw(NullError());
|
|
return TRUE;
|
|
}
|
|
#endif
|