Files
Work/common/WINGBLT.CPP
2024-08-07 09:09:36 -04:00

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