📄 drawn.cpp
字号:
{
m_x1 = expr->Nth(1)->RealValue();
m_y1 = expr->Nth(2)->RealValue();
m_x2 = expr->Nth(3)->RealValue();
m_y2 = expr->Nth(4)->RealValue();
m_x3 = expr->Nth(5)->RealValue();
m_y3 = expr->Nth(6)->RealValue();
break;
}
default:
{
break;
}
}
}
#endif
/*
* Draw polygon, polyline, spline
*
*/
wxOpPolyDraw::wxOpPolyDraw(int theOp, int n, wxRealPoint *thePoints):wxDrawOp(theOp)
{
m_noPoints = n;
m_points = thePoints;
}
wxOpPolyDraw::~wxOpPolyDraw()
{
delete[] m_points;
}
wxDrawOp *wxOpPolyDraw::Copy(wxPseudoMetaFile *WXUNUSED(newImage))
{
wxRealPoint *newPoints = new wxRealPoint[m_noPoints];
for (int i = 0; i < m_noPoints; i++)
{
newPoints[i].x = m_points[i].x;
newPoints[i].y = m_points[i].y;
}
wxOpPolyDraw *newOp = new wxOpPolyDraw(m_op, m_noPoints, newPoints);
return newOp;
}
void wxOpPolyDraw::Do(wxDC& dc, double xoffset, double yoffset)
{
switch (m_op)
{
case DRAWOP_DRAW_POLYLINE:
{
wxPoint *actualPoints = new wxPoint[m_noPoints];
int i;
for (i = 0; i < m_noPoints; i++)
{
actualPoints[i].x = WXROUND(m_points[i].x);
actualPoints[i].y = WXROUND(m_points[i].y);
}
dc.DrawLines(m_noPoints, actualPoints, WXROUND(xoffset), WXROUND(yoffset));
delete[] actualPoints;
break;
}
case DRAWOP_DRAW_POLYGON:
{
wxPoint *actualPoints = new wxPoint[m_noPoints];
int i;
for (i = 0; i < m_noPoints; i++)
{
actualPoints[i].x = WXROUND(m_points[i].x);
actualPoints[i].y = WXROUND(m_points[i].y);
}
dc.DrawPolygon(m_noPoints, actualPoints, WXROUND(xoffset), WXROUND(yoffset));
delete[] actualPoints;
break;
}
case DRAWOP_DRAW_SPLINE:
{
wxPoint *actualPoints = new wxPoint[m_noPoints];
int i;
for (i = 0; i < m_noPoints; i++)
{
actualPoints[i].x = WXROUND(m_points[i].x);
actualPoints[i].y = WXROUND(m_points[i].y);
}
dc.DrawSpline(m_noPoints, actualPoints); // no offsets in DrawSpline // , xoffset, yoffset);
delete[] actualPoints;
break;
}
default:
break;
}
}
void wxOpPolyDraw::Scale(double scaleX, double scaleY)
{
for (int i = 0; i < m_noPoints; i++)
{
m_points[i].x *= scaleX;
m_points[i].y *= scaleY;
}
}
void wxOpPolyDraw::Translate(double x, double y)
{
for (int i = 0; i < m_noPoints; i++)
{
m_points[i].x += x;
m_points[i].y += y;
}
}
void wxOpPolyDraw::Rotate(double x, double y, double WXUNUSED(theta), double sinTheta, double cosTheta)
{
for (int i = 0; i < m_noPoints; i++)
{
double x1 = m_points[i].x;
double y1 = m_points[i].y;
m_points[i].x = x1*cosTheta - y1*sinTheta + x*(1.0 - cosTheta) + y*sinTheta;
m_points[i].y = x1*sinTheta + y1*cosTheta + y*(1.0 - cosTheta) + x*sinTheta;
}
}
#if wxUSE_PROLOGIO
wxExpr *wxOpPolyDraw::WriteExpr(wxPseudoMetaFile *WXUNUSED(image))
{
wxExpr *expr = new wxExpr(wxExprList);
expr->Append(new wxExpr((long)m_op));
expr->Append(new wxExpr((long)m_noPoints));
// char buf1[9];
wxChar buf2[5];
wxChar buf3[5];
oglBuffer[0] = 0;
/*
* Store each coordinate pair in a hex string to save space.
* E.g. "1B9080CD". 4 hex digits per coordinate pair.
*
*/
for (int i = 0; i < m_noPoints; i++)
{
long signedX = (long)(m_points[i].x*100.0);
long signedY = (long)(m_points[i].y*100.0);
// Scale to 0 -> 64K
unsigned int unSignedX = (unsigned int)(signedX + 32767.0);
unsigned int unSignedY = (unsigned int)(signedY + 32767.0);
IntToHex(unSignedX, buf2);
IntToHex(unSignedY, buf3);
// Don't overrun the buffer
if ((i*8) < 3000)
{
wxStrcat(oglBuffer, buf2);
wxStrcat(oglBuffer, buf3);
}
}
expr->Append(new wxExpr(wxExprString, oglBuffer));
return expr;
}
void wxOpPolyDraw::ReadExpr(wxPseudoMetaFile *WXUNUSED(image), wxExpr *expr)
{
m_noPoints = (int)expr->Nth(1)->IntegerValue();
wxChar buf1[5];
wxChar buf2[5];
m_points = new wxRealPoint[m_noPoints];
int i = 0;
int bufPtr = 0;
wxString hexString = expr->Nth(2)->StringValue();
while (i < m_noPoints)
{
buf1[0] = hexString[(size_t)bufPtr];
buf1[1] = hexString[(size_t)(bufPtr + 1)];
buf1[2] = hexString[(size_t)(bufPtr + 2)];
buf1[3] = hexString[(size_t)(bufPtr + 3)];
buf1[4] = 0;
buf2[0] = hexString[(size_t)(bufPtr + 4)];
buf2[1] = hexString[(size_t)(bufPtr + 5)];
buf2[2] = hexString[(size_t)(bufPtr + 6)];
buf2[3] = hexString[(size_t)(bufPtr + 7)];
buf2[4] = 0;
bufPtr += 8;
// int signedX = (signed int)HexToInt(buf1);
// int signedY = (signed int)HexToInt(buf2);
long unSignedX = HexToInt(buf1);
long unSignedY = HexToInt(buf2);
// Scale -32K -> +32K
long signedX = unSignedX - 32767;
long signedY = unSignedY - 32767;
#if defined(__WXMSW__) && 0
int testX = (signed int)unSignedX;
int testY = (signed int)unSignedY;
#endif
m_points[i].x = (double)(signedX / 100.0);
m_points[i].y = (double)(signedY / 100.0);
i ++;
}
}
#endif
// Draw an outline using the current operation.
bool wxOpPolyDraw::OnDrawOutline(wxDC& dc, double x, double y, double w, double h, double oldW, double oldH)
{
dc.SetBrush(* wxTRANSPARENT_BRUSH);
// Multiply all points by proportion of new size to old size
double x_proportion = (double)(fabs(w/oldW));
double y_proportion = (double)(fabs(h/oldH));
int n = m_noPoints;
wxPoint *intPoints = new wxPoint[n];
int i;
for (i = 0; i < n; i++)
{
intPoints[i].x = WXROUND (x_proportion * m_points[i].x);
intPoints[i].y = WXROUND (y_proportion * m_points[i].y);
}
dc.DrawPolygon(n, intPoints, (long) x, (long) y);
delete[] intPoints;
return true;
}
// Assume (x1, y1) is centre of box (most generally, line end at box)
bool wxOpPolyDraw::GetPerimeterPoint(double x1, double y1,
double x2, double y2,
double *x3, double *y3,
double xOffset, double yOffset,
int attachmentMode)
{
int n = m_noPoints;
// First check for situation where the line is vertical,
// and we would want to connect to a point on that vertical --
// oglFindEndForPolyline can't cope with this (the arrow
// gets drawn to the wrong place).
if ((attachmentMode == ATTACHMENT_MODE_NONE) && (x1 == x2))
{
// Look for the point we'd be connecting to. This is
// a heuristic...
int i;
for (i = 0; i < n; i++)
{
wxRealPoint *point = & (m_points[i]);
if (point->x == 0.0)
{
if ((y2 > y1) && (point->y > 0.0))
{
*x3 = point->x + xOffset;
*y3 = point->y + yOffset;
return true;
}
else if ((y2 < y1) && (point->y < 0.0))
{
*x3 = point->x + xOffset;
*y3 = point->y + yOffset;
return true;
}
}
}
}
double *xpoints = new double[n];
double *ypoints = new double[n];
for (int i = 0; i < n; i++)
{
wxRealPoint *point = & (m_points[i]);
xpoints[i] = point->x + xOffset;
ypoints[i] = point->y + yOffset;
}
oglFindEndForPolyline(n, xpoints, ypoints,
x1, y1, x2, y2, x3, y3);
delete[] xpoints;
delete[] ypoints;
return true;
}
/*
* Utilities
*
*/
#if wxUSE_PROLOGIO
static char hexArray[] = {
_T('0'), _T('1'), _T('2'), _T('3'), _T('4'), _T('5'), _T('6'), _T('7'),
_T('8'), _T('9'), _T('A'), _T('B'), _T('C'), _T('D'), _T('E'), _T('F') };
// Convert unsigned 16-bit integer to 4-character hex string
static void IntToHex(unsigned int dec, wxChar *buf)
{
int digit1 = (int)(dec/4096);
int digit2 = (int)((dec - (digit1*4096))/256);
int digit3 = (int)((dec - (digit1*4096) - (digit2*256))/16);
int digit4 = dec - (digit1*4096 + digit2*256 + digit3*16);
buf[0] = hexArray[digit1];
buf[1] = hexArray[digit2];
buf[2] = hexArray[digit3];
buf[3] = hexArray[digit4];
buf[4] = 0;
}
// One hex digit to decimal number
static int HexToInt1(wxChar hex)
{
switch (hex)
{
case _T('0'):
return 0;
case _T('1'):
return 1;
case _T('2'):
return 2;
case _T('3'):
return 3;
case _T('4'):
return 4;
case _T('5'):
return 5;
case _T('6'):
return 6;
case _T('7'):
return 7;
case _T('8'):
return 8;
case _T('9'):
return 9;
case _T('A'):
return 10;
case _T('B'):
return 11;
case _T('C'):
return 12;
case _T('D'):
return 13;
case _T('E'):
return 14;
case _T('F'):
return 15;
}
return 0;
}
// 4-digit hex string to unsigned integer
static unsigned long HexToInt(wxChar *buf)
{
long d1 = (long)(HexToInt1(buf[0])*4096.0) ;
long d2 = (long)(HexToInt1(buf[1])*256.0) ;
long d3 = (long)(HexToInt1(buf[2])*16.0) ;
long d4 = (long)(HexToInt1(buf[3])) ;
unsigned long n = (long)(d1 + d2 + d3 + d4) ;
return n;
}
#endif // wxUSE_PROLOGIO
/*
* wxPseudo meta-file
*
*/
IMPLEMENT_DYNAMIC_CLASS(wxPseudoMetaFile, wxObject)
wxPseudoMetaFile::wxPseudoMetaFile()
{
m_currentRotation = 0;
m_rotateable = true;
m_width = 0.0;
m_height = 0.0;
m_outlinePen = NULL;
m_fillBrush = NULL;
m_outlineOp = -1;
}
wxPseudoMetaFile::wxPseudoMetaFile(wxPseudoMetaFile& mf):wxObject()
{
mf.Copy(*this);
}
wxPseudoMetaFile::~wxPseudoMetaFile()
{
Clear();
}
void wxPseudoMetaFile::Clear()
{
wxNode *node = m_ops.GetFirst();
while (node)
{
wxDrawOp *op = (wxDrawOp *)node->GetData();
delete op;
node = node->GetNext();
}
m_ops.Clear();
m_gdiObjects.Clear();
m_outlineColours.Clear();
m_fillColours.Clear();
m_outlineOp = -1;
}
void wxPseudoMetaFile::Draw(wxDC& dc, double xoffset, double yoffset)
{
wxNode *node = m_ops.GetFirst();
while (node)
{
wxDrawOp *op = (wxDrawOp *)node->GetData();
op->Do(dc, xoffset, yoffset);
node = node->GetNext();
}
}
void wxPseudoMetaFile::Scale(double sx, double sy)
{
wxNode *node = m_ops.GetFirst();
while (node)
{
wxDrawOp *op = (wxDrawOp *)node->GetData();
op->Scale(sx, sy);
node = node->GetNext();
}
m_width *= sx;
m_height *= sy;
}
void wxPseudoMetaFile::Translate(double x, double y)
{
wxNode *node = m_ops.GetFirst();
while (node)
{
wxDrawOp *op = (wxDrawOp *)node->GetData();
op->Translate(x, y);
node = node->GetNext();
}
}
void wxPseudoMetaFile::Rotate(double x, double y, double theta)
{
double theta1 = theta-m_currentRotation;
if (theta1 == 0.0) return;
double cosTheta = (double)cos(theta1);
double sinTheta = (double)sin(theta1);
wxNode *node = m_ops.GetFirst();
while (node)
{
wxDrawOp *op = (wxDrawOp *)node->GetData();
op->Rotate(x, y, theta, sinTheta, cosTheta);
node = node->GetNext();
}
m_currentRotation = theta;
}
#if wxUSE_PROLOGIO
void wxPseudoMetaFile::WriteAttributes(wxExpr *clause, int whichAngle)
{
wxString widthStr;
widthStr.Printf(wxT("meta_width%d"), whichAngle);
wxString heightStr;
heightStr.Printf(wxT("meta_height%d"), whichAngle);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -