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

437 lines
10 KiB
C++

#include <common/math.hpp>
#include <common/purehdc.hpp>
#include <common/window.hpp>
#include <common/brush.hpp>
PureDevice::PureDevice(const Window &someWindow)
: mhDC(0), mhParent((HWND)someWindow), mDisposition(ReleaseDC), mGDIObjPrev(0), mPrevDrawMode(INVALIDROP)
{
if(!mhParent||!::IsWindow(mhParent))return;
mhDC=::GetDC(mhParent);
}
PureDevice::~PureDevice()
{
unselect();
destroyDevice();
}
WORD PureDevice::isOkay(void)const
{
switch(mDisposition)
{
case DeleteDC :
case AssumedDC :
return (mhDC?TRUE:FALSE);
case ReleaseDC :
return (mhDC&&(mhParent?::IsWindow(mhParent):TRUE));
case InvalidDC :
default :
return FALSE;
}
}
void PureDevice::destroyDevice(void)
{
if(mhDC)
{
setDrawMode(INVALIDROP);
if(DeleteDC==mDisposition&&isOkay())::DeleteDC(mhDC);
else if(ReleaseDC==mDisposition&&isOkay())::ReleaseDC(mhParent,mhDC);
mhDC=0;
mhParent=0;
mDisposition=InvalidDC;
}
}
WORD PureDevice::select(const GDIObj someGDIObj,WORD selState)
{
if(!isOkay()||!someGDIObj)return FALSE;
if(selState)
{
if(mGDIObjPrev)::SelectObject(mhDC,mGDIObjPrev);
mGDIObjPrev=::SelectObject(mhDC,someGDIObj);
return TRUE;
}
if(!mGDIObjPrev)return FALSE;
::SelectObject(mhDC,mGDIObjPrev);
mGDIObjPrev=0;
return TRUE;
}
WORD PureDevice::compatibleDevice(const PureDevice &somePureDevice)
{
if(!somePureDevice.isOkay())return FALSE;
destroyDevice();
mhDC=::CreateCompatibleDC((HDC)somePureDevice);
mDisposition=DeleteDC;
return isOkay();
}
WORD PureDevice::compatibleDevice(void)
{
destroyDevice();
mhDC=::CreateCompatibleDC(0);
mDisposition=DeleteDC;
return isOkay();
}
WORD PureDevice::displayDevice(void)
{
destroyDevice();
mhDC=::CreateDC("DISPLAY",0,0,0);
mDisposition=DeleteDC;
return isOkay();
}
WORD PureDevice::screenDevice(void)
{
destroyDevice();
mhDC=::GetDC(0);
mDisposition=ReleaseDC;
return isOkay();
}
WORD PureDevice::roundRectangle(const Point &centerPoint,int radius)
{
if(!isOkay())return false;
Point upperLeft;
Point lowerRight;
int diameter;
diameter=radius*2;
upperLeft.x(centerPoint.x()-radius);
upperLeft.y(centerPoint.y()-radius);
lowerRight.x(centerPoint.x()+radius);
lowerRight.y(centerPoint.y()+radius);
return roundRectangle(upperLeft,lowerRight,diameter,diameter);
}
WORD PureDevice::floodFill(const Point &xyPoint,const RGBColor &fillColor,const RGBColor &boundaryColor)const
{
HBRUSH hFillBrush(::CreateSolidBrush(fillColor));
HBRUSH hPrevBrush((HBRUSH)::SelectObject(mhDC,hFillBrush));
WORD returnCode;
returnCode=::FloodFill(mhDC,xyPoint.x(),xyPoint.y(),boundaryColor);
::SelectObject(mhDC,hPrevBrush);
::DeleteObject(hFillBrush);
return returnCode;
}
BOOL PureDevice::fillRect(const Rect &rect,Brush &brush)
{
if(!isOkay())return FALSE;
return ::FillRect(mhDC,(RECT*)((Rect&)rect),(HBRUSH)(GDIObj)brush);
}
WORD PureDevice::colorRect(const Rect &rect,const RGBColor &lineColor)const
{
if(!isOkay())return FALSE;
for(short index=rect.left();index<=rect.right();index++)
line(Point(index,rect.bottom()),Point(index,rect.top()),lineColor);
return TRUE;
}
WORD PureDevice::circle(Window &displayWindow,const Point &xyPoint,WORD radius,const RGBColor &someRGBColor)const
{
return circle(aspectValue(displayWindow),xyPoint,radius,someRGBColor);
}
WORD PureDevice::outlineRect(const Rect &rect,const Pen &pen)
{
Point p1;
Point p2;
if(!isOkay())return FALSE;
p1.x(rect.left());
p1.y(rect.top());
p2.x(rect.right());
p2.y(rect.top());
line(p1,p2,pen);
p1.x(rect.right());
p1.y(rect.top());
p2.x(rect.right());
p2.y(rect.bottom());
line(p1,p2,pen);
p1.x(rect.right());
p1.y(rect.bottom());
p2.x(rect.left());
p2.y(rect.bottom());
line(p1,p2,pen);
p1.x(rect.left());
p1.y(rect.bottom());
p2.x(rect.left());
p2.y(rect.top());
line(p1,p2,pen);
return TRUE;
}
WORD PureDevice::line(const Point &firstPoint,const Point &secondPoint,const Pen &somePen)const
{
if(!isOkay())return FALSE;
HPEN hPrevPen((HPEN)::SelectObject(mhDC,(HPEN)somePen));
lineDraw(firstPoint,secondPoint);
::SelectObject(mhDC,hPrevPen);
return TRUE;
}
WORD PureDevice::line(const Point &firstPoint,const Point &secondPoint)const
{
if(!isOkay())return FALSE;
lineDraw(firstPoint,secondPoint);
return TRUE;
}
WORD PureDevice::crossHair(const Point &midPoint,WORD sectionLength,const Pen &somePen)
{
Point leftPoint(midPoint);
Point topPoint(midPoint);
Point rightPoint(midPoint);
Point bottomPoint(midPoint);
HPEN hPrevPen;
if(!isOkay())return FALSE;
hPrevPen=(HPEN)::SelectObject(mhDC,(HPEN)somePen);
leftPoint.x(leftPoint.x()-sectionLength);
rightPoint.x(rightPoint.x()+sectionLength);
topPoint.y(topPoint.y()-sectionLength);
bottomPoint.y(bottomPoint.y()+sectionLength);
lineDraw(leftPoint,rightPoint);
lineDraw(topPoint,bottomPoint);
::SelectObject(mhDC,hPrevPen);
return TRUE;
}
WORD PureDevice::crossHairs(Array<Point> &midPoints,WORD sectionLength,const Pen &somePen)
{
WORD itemCount;
Point leftPoint;
Point topPoint;
Point rightPoint;
Point bottomPoint;
HPEN hPrevPen;
if(!isOkay()||!(itemCount=midPoints.size()))return FALSE;
hPrevPen=(HPEN)::SelectObject(mhDC,(HPEN)somePen);
for(short itemIndex=0;itemIndex<itemCount;itemIndex++)
{
leftPoint=midPoints[itemIndex];
topPoint=leftPoint;
rightPoint=leftPoint;
bottomPoint=leftPoint;
leftPoint.x(leftPoint.x()-sectionLength);
rightPoint.x(rightPoint.x()+sectionLength);
topPoint.y(topPoint.y()-sectionLength);
bottomPoint.y(bottomPoint.y()+sectionLength);
lineDraw(leftPoint,rightPoint);
lineDraw(topPoint,bottomPoint);
}
::SelectObject(mhDC,hPrevPen);
return TRUE;
}
WORD PureDevice::crossHairs(Array<Point> &midPoints,WORD sectionLength,RGBColor rgbColor)
{
WORD itemCount;
Point leftPoint;
Point topPoint;
Point rightPoint;
Point bottomPoint;
if(!isOkay()||!(itemCount=midPoints.size()))return FALSE;
for(short itemIndex=0;itemIndex<itemCount;itemIndex++)
{
leftPoint=midPoints[itemIndex];
topPoint=leftPoint;
rightPoint=leftPoint;
bottomPoint=leftPoint;
leftPoint.x(leftPoint.x()-sectionLength);
rightPoint.x(rightPoint.x()+sectionLength);
topPoint.y(topPoint.y()-sectionLength);
bottomPoint.y(bottomPoint.y()+sectionLength);
line(leftPoint,rightPoint,rgbColor);
line(topPoint,bottomPoint,rgbColor);
}
return TRUE;
}
WORD PureDevice::circle(WORD aspectValue,const Point &xyPoint,WORD radius,const RGBColor &someRGBColor)const
{
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;
setPixel(Point(xyPoint.x()+af,xyPoint.y()+b),someRGBColor);
setPixel(Point(xyPoint.x()+bf,xyPoint.y()+a),someRGBColor);
setPixel(Point(xyPoint.x()-af,xyPoint.y()+b),someRGBColor);
setPixel(Point(xyPoint.x()-bf,xyPoint.y()+a),someRGBColor);
setPixel(Point(xyPoint.x()-af,xyPoint.y()-b),someRGBColor);
setPixel(Point(xyPoint.x()-bf,xyPoint.y()-a),someRGBColor);
setPixel(Point(xyPoint.x()+af,xyPoint.y()-b),someRGBColor);
setPixel(Point(xyPoint.x()+bf,xyPoint.y()-a),someRGBColor);
++b;
}
--a;
}
return TRUE;
}
PureDevice &PureDevice::operator=(const PureDevice &somePureDevice)
{
if(!somePureDevice.isOkay())return *this;
destroyDevice();
mDisposition=AssumedDC;
mhDC=(HDC)somePureDevice;
return *this;
}
PureDevice &PureDevice::operator=(const Window &someWindow)
{
return *this=(HWND)someWindow;
}
PureDevice &PureDevice::operator=(HWND hWnd)
{
if(!hWnd)return *this;
destroyDevice();
mhParent=hWnd;
mhDC=::GetDC(mhParent);
mDisposition=ReleaseDC;
return *this;
}
WORD PureDevice::horizontalResolution(void)const
{
if(!isOkay())return FALSE;
return ::GetDeviceCaps(mhDC,HORZRES);
}
WORD PureDevice::verticalResolution(void)const
{
if(!isOkay())return FALSE;
return ::GetDeviceCaps(mhDC,VERTRES);
}
WORD PureDevice::aspectValue(const Window &someWindow)const
{
if(!isOkay())return FALSE;
return (((1.00/((float)horizontalResolution()/(float)verticalResolution()))*((float)someWindow.width()/(float)someWindow.height()))*100);
}
WORD PureDevice::square(const Point &centerPoint,WORD lineLength,RGBColor rgbColor)
{
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,rgbColor);
line(topRight,bottomRight,rgbColor);
line(bottomRight,bottomLeft,rgbColor);
line(bottomLeft,topLeft,rgbColor);
return TRUE;
}
WORD PureDevice::line(const Point &firstPoint,const Point &secondPoint,const RGBColor &rgbColor)const
{
LONG xRunning(firstPoint.x());
LONG yRunning(firstPoint.y());
LONG xDelta;
LONG yDelta;
short xDir(1);
short yDir(1);
short steps;
if(!isOkay())return FALSE;
xRunning<<=0x10;
yRunning<<=0x10;
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<0L)xDelta=-xDelta;
if(yDelta<0L)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++)
{
setPixel(Point(xRunning>>0x10,yRunning>>0x10),rgbColor);
xRunning-=xDelta;
yRunning-=yDelta;
}
}
else if(-1==xDir&&1==yDir)
{
for(short stepIndex=0;stepIndex<steps;stepIndex++)
{
setPixel(Point(xRunning>>0x10,yRunning>>0x10),rgbColor);
xRunning-=xDelta;
yRunning+=yDelta;
}
}
else if(1==xDir&&-1==yDir)
{
for(short itemIndex=0;itemIndex<steps;itemIndex++)
{
setPixel(Point(xRunning>>0x10,yRunning>>0x10),rgbColor);
xRunning+=xDelta;
yRunning-=yDelta;
}
}
else if(1==xDir&&1==yDir)
{
for(short itemIndex=0;itemIndex<steps;itemIndex++)
{
setPixel(Point(xRunning>>0x10,yRunning>>0x10),rgbColor);
xRunning+=xDelta;
yRunning+=yDelta;
}
}
return TRUE;
}