311 lines
8.1 KiB
C++
311 lines
8.1 KiB
C++
#include <common/dib.hpp>
|
|
#include <common/vector2d.hpp>
|
|
#include <common/bitmap.hpp>
|
|
#include <common/boverlay.hpp>
|
|
#include <common/resbmp.hpp>
|
|
#include <common/math.hpp>
|
|
|
|
void DIBitmap::createBitmap(const PureDevice &somePureDevice)
|
|
{
|
|
destroyBitmap();
|
|
mhBitmap=::CreateDIBSection(somePureDevice,(BITMAPINFO*)(static_cast<BitmapInfo&>(*this)),DIB_RGB_COLORS,&mlpBmBits,(HANDLE)0,0L);
|
|
if(!mhBitmap)::GetLastError();
|
|
if(mhBitmap)mImageExtent=BitmapInfo::imageExtent();
|
|
}
|
|
|
|
void DIBitmap::createBitmap(void)
|
|
{
|
|
destroyBitmap();
|
|
mhBitmap=::CreateDIBSection((HDC)0,(BITMAPINFO*)(static_cast<BitmapInfo&>(*this)),DIB_RGB_COLORS,&mlpBmBits,(HANDLE)0,0L);
|
|
if(mhBitmap)mImageExtent=BitmapInfo::imageExtent();
|
|
}
|
|
|
|
WORD DIBitmap::size(DWORD newWidth,DWORD newHeight)
|
|
{
|
|
if(!isOkay())return FALSE;
|
|
verifyDimensions(newWidth,newHeight);
|
|
width(newWidth);
|
|
height(newHeight);
|
|
createBitmap(mBitmapDevice);
|
|
mBitmapDevice.select(mhBitmap);
|
|
return isOkay();
|
|
}
|
|
|
|
void DIBitmap::verifyDimensions(DWORD &desiredWidth,DWORD desiredHeight)const
|
|
{
|
|
DWORD imageExtent;
|
|
|
|
imageExtent=(((((LONG)desiredWidth*8)+31)&~31)>>3)*(LONG)desiredHeight;
|
|
if(imageExtent==(LONG)desiredWidth*(LONG)desiredHeight)return;
|
|
desiredWidth=(WORD)(imageExtent/(LONG)desiredHeight);
|
|
}
|
|
|
|
void DIBitmap::setBits(BYTE charByte)
|
|
{
|
|
if(!charByte)clearBits();
|
|
BYTE *lpImagePtr=(BYTE*)mlpBmBits;
|
|
for(DWORD ptrIndex=0;ptrIndex<imageExtent();ptrIndex++)*lpImagePtr++=charByte;
|
|
}
|
|
|
|
void DIBitmap::clearBits(void)
|
|
{
|
|
DWORD *lpImagePtr=(DWORD*)mlpBmBits;
|
|
DWORD extent(imageExtent()/sizeof(DWORD));
|
|
for(unsigned long ptrIndex=0;ptrIndex<extent;ptrIndex++)*lpImagePtr++=0L;
|
|
}
|
|
|
|
bool DIBitmap::copyBits(unsigned char *ptrDataChar,DWORD length)
|
|
{
|
|
DWORD writeExtent=length<=imageExtent()?length:imageExtent();
|
|
DWORD numDWORDS=writeExtent>>2;
|
|
DWORD numBytes=0;
|
|
int *ptrSrcDataInt=0;
|
|
int *ptrDstDataInt=0;
|
|
char *ptrSrcDataChar;
|
|
char *ptrDstDataChar;
|
|
|
|
if(!writeExtent)return false;
|
|
numBytes=(writeExtent%writeExtent);
|
|
ptrSrcDataInt=(int*)ptrDataChar;
|
|
ptrDstDataInt=(int*)mlpBmBits;
|
|
for(DWORD count=0;count<numDWORDS;count++)*ptrDstDataInt++=*ptrSrcDataInt++;
|
|
ptrSrcDataChar=(char*)ptrSrcDataInt;
|
|
ptrDstDataChar=(char*)ptrDstDataInt;
|
|
for(count=0;count<numBytes;count++)*ptrDstDataChar++=*ptrSrcDataChar++;
|
|
return true;
|
|
}
|
|
|
|
void DIBitmap::copyBits(unsigned char *lpDstPtr,unsigned char *lpSrcPtr,DWORD length)const
|
|
{
|
|
for(DWORD count=0;count<length;count++)*lpDstPtr++=*lpSrcPtr++;
|
|
}
|
|
|
|
DIBitmap &DIBitmap::operator+=(BitmapOverlay &someBitmapOverlay)
|
|
{
|
|
overlay(someBitmapOverlay.placementPoint(),someBitmapOverlay.bitmap().width(),someBitmapOverlay.bitmap().height(),someBitmapOverlay.bitmap().getDataPtr());
|
|
return *this;
|
|
}
|
|
|
|
bool DIBitmap::getAt(SmartPointer<DIBitmap> &bitmap,const Rect &areaRect)
|
|
{
|
|
bitmap.destroy();
|
|
bitmap=::new DIBitmap(getDevice(),areaRect.width(),areaRect.height(),getPalette());
|
|
bitmap.disposition(PointerDisposition::Delete);
|
|
for(int col=areaRect.left(),dstCol=0;col<=areaRect.right();col++,dstCol++)
|
|
{
|
|
for(int row=areaRect.top(),dstRow=0;row<=areaRect.bottom();row++,dstRow++)
|
|
{
|
|
bitmap->setByte(dstRow,dstCol,getByte(row,col));
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool DIBitmap::overlay(Bitmap &bitmap,const Point &placementPoint)
|
|
{
|
|
return overlay(placementPoint,bitmap.width(),bitmap.height(),bitmap.getDataPtr());
|
|
}
|
|
|
|
bool DIBitmap::overlay(ResBitmap &resBitmap,const Point &placementPoint)
|
|
{
|
|
return overlay(placementPoint,resBitmap.width(),resBitmap.height(),resBitmap.ptrData());
|
|
}
|
|
|
|
bool DIBitmap::overlay(DIBitmap &bitmap,const Point &placementPoint)
|
|
{
|
|
return overlay(placementPoint,bitmap.width(),bitmap.height(),(unsigned char*)bitmap.ptrData());
|
|
}
|
|
|
|
bool DIBitmap::overlay(const Point &placementPoint,int srcWidth,int srcHeight,UCHAR *pBmBits)
|
|
{
|
|
DWORD newSrcY;
|
|
DWORD newDstY;
|
|
DWORD srcIndex;
|
|
DWORD dstIndex;
|
|
UINT srcRow;
|
|
UINT srcCol;
|
|
|
|
if(!isOkay())return false;
|
|
if(srcWidth>width())srcWidth=width();
|
|
if(srcHeight>height())srcHeight=height();
|
|
for(srcRow=0;srcRow<srcHeight;srcRow++)
|
|
{
|
|
for(srcCol=0;srcCol<srcWidth;srcCol++)
|
|
{
|
|
newSrcY=srcRow;
|
|
srcIndex=newSrcY*srcWidth+srcCol;
|
|
newDstY=height()-srcHeight-placementPoint.y()+srcRow;
|
|
dstIndex=newDstY*width()+srcCol+placementPoint.x();
|
|
*((char*)mlpBmBits+dstIndex)=*(pBmBits+srcIndex);
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void DIBitmap::colorRect(const Rect &rect,BYTE byteValue)
|
|
{
|
|
int bmHeight=rect.height();
|
|
for(int row=0;row<bmHeight;row++)
|
|
{
|
|
line(Point(rect.left(),rect.top()+row),Point(rect.right(),rect.top()+row),byteValue);
|
|
}
|
|
}
|
|
|
|
void DIBitmap::outlineRect(const Rect &outlineRect,BYTE byteValue)
|
|
{
|
|
Point p1;
|
|
Point p2;
|
|
|
|
p1.x(outlineRect.left());
|
|
p1.y(outlineRect.top());
|
|
p2.x(outlineRect.right());
|
|
p2.y(outlineRect.top());
|
|
line(p1,p2,byteValue);
|
|
p1.x(outlineRect.right());
|
|
p1.y(outlineRect.top());
|
|
p2.x(outlineRect.right());
|
|
p2.y(outlineRect.bottom());
|
|
line(p1,p2,byteValue);
|
|
p1.x(outlineRect.left());
|
|
p1.y(outlineRect.bottom());
|
|
p2.x(outlineRect.right());
|
|
p2.y(outlineRect.bottom());
|
|
line(p1,p2,byteValue);
|
|
p1.x(outlineRect.left());
|
|
p1.y(outlineRect.top());
|
|
p2.x(outlineRect.left());
|
|
p2.y(outlineRect.bottom());
|
|
line(p1,p2,byteValue);
|
|
}
|
|
|
|
void DIBitmap::line(const Point &firstPoint,const Point &secondPoint,BYTE byteValue)
|
|
{
|
|
int xRunning((LONG)firstPoint.x()<<0x10);
|
|
int yRunning((LONG)firstPoint.y()<<0x10);
|
|
int xDelta;
|
|
int yDelta;
|
|
short xDir(1);
|
|
short yDir(1);
|
|
short steps;
|
|
|
|
if(secondPoint.x()<firstPoint.x())xDir=-1;
|
|
if(secondPoint.y()<firstPoint.y())yDir=-1;
|
|
xDelta=(int)secondPoint.x()-(int)firstPoint.x();
|
|
yDelta=(int)secondPoint.y()-(int)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;
|
|
}
|
|
}
|
|
}
|
|
|
|
WORD DIBitmap::square(const Point ¢erPoint,WORD lineLength,BYTE palIndex)
|
|
{
|
|
WORD halfLength(lineLength>>0x01);
|
|
Point topLeft;
|
|
Point topRight;
|
|
Point bottomLeft;
|
|
Point bottomRight;
|
|
|
|
if(!isOkay())return FALSE;
|
|
topLeft.x(centerPoint.x()-halfLength);
|
|
topLeft.y(centerPoint.y()-halfLength);
|
|
topRight.x(centerPoint.x()+halfLength);
|
|
topRight.y(centerPoint.y()-halfLength);
|
|
bottomRight.x(centerPoint.x()+halfLength);
|
|
bottomRight.y(centerPoint.y()+halfLength);
|
|
bottomLeft.x(centerPoint.x()-halfLength);
|
|
bottomLeft.y(centerPoint.y()+halfLength);
|
|
line(topLeft,topRight,palIndex);
|
|
line(topRight,bottomRight,palIndex);
|
|
line(bottomRight,bottomLeft,palIndex);
|
|
line(bottomLeft,topLeft,palIndex);
|
|
return TRUE;
|
|
}
|
|
|
|
WORD DIBitmap::circle(WORD aspectValue,const Point &xyPoint,WORD radius,WORD palIndex)
|
|
{
|
|
int a(radius);
|
|
int af;
|
|
int bf;
|
|
int b(0);
|
|
int target(1);
|
|
int radiusSquared(radius*radius);
|
|
|
|
if(!isOkay())return FALSE;
|
|
while(a>=b)
|
|
{
|
|
b=(int)(Math::sqrt(radiusSquared-(a*a))+.50);
|
|
int temp(target);
|
|
target=b;
|
|
b=temp;
|
|
while(b<target)
|
|
{
|
|
if(100.00!=aspectValue)af=(aspectValue*a)/100.00,bf=(aspectValue*b)/100.00;
|
|
else af=a,bf=b;
|
|
setByte(xyPoint.x()+af,xyPoint.y()+b,palIndex);
|
|
setByte(xyPoint.x()+bf,xyPoint.y()+a,palIndex);
|
|
setByte(xyPoint.x()-af,xyPoint.y()+b,palIndex);
|
|
setByte(xyPoint.x()-bf,xyPoint.y()+a,palIndex);
|
|
setByte(xyPoint.x()-af,xyPoint.y()-b,palIndex);
|
|
setByte(xyPoint.x()-bf,xyPoint.y()-a,palIndex);
|
|
setByte(xyPoint.x()+af,xyPoint.y()-b,palIndex);
|
|
setByte(xyPoint.x()+bf,xyPoint.y()-a,palIndex);
|
|
++b;
|
|
}
|
|
--a;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|