#include "StdAfx.h"
#include <math.h>
using namespace GE_::Operators;
namespace GE_{namespace Mfc{
//CSize and CPoint operators
CSize& operator*=(CSize& s, const int& m)
{s.cx*=m; s.cy*=m; return s;}
CSize& operator/=(CSize& s, const int& m)
{s.cx/=m; s.cy/=m; return s;}
CSize& operator*=(CSize& s, const CSize& m)
{s.cx*=m.cx; s.cy*=m.cy; return s;}
CSize& operator/=(CSize& s, const CSize& m)
{s.cx/=m.cx; s.cy/=m.cy; return s;}
CPoint& operator*=(CPoint& p, const int& m)
{p.x*=m; p.y*=m; return p;}
CPoint& operator/=(CPoint& p, const int& m)
{p.x/=m; p.y/=m; return p;}
CPoint& operator*=(CPoint& p, const CSize& m)
{p.x*=m.cx; p.y*=m.cy; return p;}
CPoint& operator/=(CPoint& p, const CSize& m)
{p.x/=m.cx; p.y/=m.cy; return p;}
bool operator!(const CSize& s)
{return !s.cx && !s.cy;};
int PointToInt(const CPoint& p, const CSize& s)
{ return p.y*s.cx + p.x; }
CPoint IntToPoint(int i, const CSize& s)
{
CPoint p;
p.y = i/s.cx;
p.x = i%s.cx;
return p;
}
void Start(CPoint& p, const CSize& s)
{
p.x=-1;
p.y=0;
}
void Start(CPoint& p, const CRect& r)
{
p.x = r.left-1;
p.y = r.top;
}
bool Next(CPoint& p, const CSize& s)
{
p.x++;
if(p.x >= s.cx)
p.x=0, p.y++;
if (p.y >= s.cy)
return false;
return true;
}
bool Next(CPoint& p, const CRect& r)
{
p.x++;
if (p.x >= r.right)
p.x = r.left, p.y++;
if (p.y >= r.bottom)
return false;
return true;
}
bool PtInSize(const CPoint& p, const CSize& s)
{
return p.x<s.cx && p.y < s.cy;
}
CSize MulDiv(CSize szNumber, CSize szNumerator, CSize szDenominator)
{
return CSize(
::MulDiv(szNumber.cx, szNumerator.cx, szDenominator.cx),
::MulDiv(szNumber.cy, szNumerator.cy, szDenominator.cy)
);
}
CPoint InterpolatePoints(CPoint p1, CPoint p2, LONG t, LONG step)
{
using namespace Mfc;
using namespace Operators;
return (p1*(step-t) + p2*t) / step;
}
LONG Length(const CSize& sz)
{ return (long)sqrt(sz.cx*sz.cx+sz.cy*sz.cy); }
LONG& Openess(CSize& sz, bool bHorz) {return (bHorz)? sz.cx: sz.cy;};
LONG& Amplitude(CSize& sz, bool bHorz) {return (bHorz)? sz.cy: sz.cx;};
LONG& Openess(CPoint& pt, bool bHorz) {return (bHorz)? pt.x: pt.y;};
LONG& Amplitude(CPoint& pt, bool bHorz) {return (bHorz)? pt.y: pt.x;};
void CalcBorders(const CRect& rcFrom, CSize szWidth, CRect* rcTo)
{
for(int i=site_left; i<site__count; i++)
rcTo[i] = rcFrom;
rcTo[site_top].bottom = rcTo[site_top].top + szWidth.cy;
rcTo[site_bottom].top= rcTo[site_bottom].bottom - szWidth.cy;
rcTo[site_left].right = rcTo[site_left].left + szWidth.cy;
rcTo[site_right].left= rcTo[site_right].right - szWidth.cy;
rcTo[site_left].top = rcTo[site_right].top = rcTo[site_top].bottom;
rcTo[site_left].bottom = rcTo[site_right].bottom= rcTo[site_bottom].top;
}
CPoint CLine::Intersect(const CLine& line) const
{
LONG a1,b1,c1,a2,b2,c2;
GetABC(a1,b1,c1);
line.GetABC(a2,b2,c2);
return CPoint(
(b1*c2-c1*b2)/(a1*b2-a2*b1),
(a1*c2-a2*c1)/(a2*b1-a1*b2)
);
}
LONG CLine::LDistance(const CPoint& point) const
{
LONG a,b,c; GetABC(a,b,c);
return (a*point.x + b*point.x + c)/(LONG)(sqrt(a*a+b*b));
}
}}
namespace GE_{ namespace Draw{
CDrwRect::XData::XData()
{
clrPen = RGB(0,0,0);
clrBrush = RGB(192,192,192);
uPenSize = 1;
uPenStyle = PS_INSIDEFRAME;
}
CDrwRect::CDrwRect(LPCRECT pr, COLORREF fill, COLORREF border, UINT borderSize, UINT borderStyle)
{
//initialize members
CopyRect(pr);
m_.clrBrush = fill;
m_.clrPen = border;
m_.uPenSize = borderSize;
m_.uPenStyle = borderStyle;
}
void CDrwRect::Draw(CDC* pDC)
{
// create pen and brush
CPen pen(m_.uPenStyle, m_.uPenSize, m_.clrPen & 0x00FFFFFF);
CBrush brs(m_.clrBrush & 0x00FFFFFF);
// save dc state (restore on return)
Mfc::CAutoDC dc(pDC->GetSafeHdc());
if(m_.clrBrush == -1) dc.SelectStockObject(HOLLOW_BRUSH);
else dc.SelectObject(&brs);
if(m_.clrPen == -1) dc.SelectStockObject(NULL_PEN);
else dc.SelectObject(&pen);
dc.Rectangle(this);
}
CDrwLine::XData::XData()
{
uPenSize = 1;
uPenStyle = PS_SOLID;
clrPen = RGB(0,0,0);
}
CDrwLine::CDrwLine(POINT point1, POINT point2)
{ _p1 = point1; _p2 = point2; }
CDrwLine::CDrwLine(POINT point1, POINT point2, COLORREF clr, UINT size, UINT style)
{
_p1 = point1; _p2 = point2;
m_.clrPen = clr;
m_.uPenSize = size;
m_.uPenStyle = style;
}
void CDrwLine::Draw(CDC* pDC)
{
// create pen (delete on return)
CPen pen(m_.uPenStyle, m_.uPenSize, m_.clrPen & 0x00FFFFFF);
//save DC state (restore on return)
Mfc::CAutoDC dc(pDC->GetSafeHdc());
if(m_.clrPen == -1) dc.SelectStockObject(NULL_PEN);
else dc.SelectObject(&pen);
dc.MoveTo(_p1); dc.LineTo(_p2);
}
CDrwArrow::XData2::XData2()
{
clrFill = RGB(128,128,128);
cowide = 5000; //30 degrees
basepush = 0;
bDirection = true;
placement = 8000;
len = 8;
}
void CDrwArrow::Draw(CDC* pDC)
{
CPoint points[4]; //will be used as a plygon
CPoint& ptStart = points[0]; //arrow point
CPoint& ptBase = points[2]; //base point
CPoint& ptCorner1 = points[1]; //external corners
CPoint& ptCorner2 = points[3];
using namespace Mfc;
using namespace Operators;
ptStart = Mfc::InterpolatePoints(_p1,_p2,n.placement);
LONG linelen = Length(_p2-_p1);
LONG sinline = (_p2.y - _p1.y)*10000/linelen;
LONG cosline = (_p2.x - _p1.x)*10000/linelen;
LONG basedelta = n.len - n.basepush*n.len/10000;
ptBase = ptStart - CSize(basedelta*cosline/10000, basedelta*sinline/10000)*((n.bDirection)?1:-1);
CPoint ptprojection = ptStart - CSize(n.len*cosline/10000, n.len*sinline/10000)*((n.bDirection)?1:-1);
LONG widelen = n.len*n.cowide/10000;
ptCorner1.x = ptprojection.x - widelen*sinline/10000;
ptCorner2.x = ptprojection.x + widelen*sinline/10000;
ptCorner1.y = ptprojection.y + widelen*cosline/10000;
ptCorner2.y = ptprojection.y - widelen*cosline/10000;
CBrush brs(n.clrFill & 0x00FFFFFF);
CPen pen(m.uPenStyle,1,m.clrPen & 0x00FFFFFF);
CAutoDC dc(pDC->GetSafeHdc());
if(m.clrPen == -1) dc.SelectStockObject(NULL_PEN);
else dc.SelectObject(&pen);
if(n.clrFill == -1) dc.SelectStockObject(NULL_BRUSH);
else dc.SelectObject(&brs);
dc.Polygon(points,4);
}
}}