X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/0fc1a7137cccc829a34b3527c768db7d7ac83437..335a8b43e952afe037ce77bc4d52e5a688086853:/utils/ogl/src/drawn.cpp diff --git a/utils/ogl/src/drawn.cpp b/utils/ogl/src/drawn.cpp index d71a144f3c..178dcfaf9a 100644 --- a/utils/ogl/src/drawn.cpp +++ b/utils/ogl/src/drawn.cpp @@ -38,7 +38,7 @@ static void IntToHex(unsigned int dec, char *buf); static unsigned long HexToInt(char *buf); -extern char *GraphicsBuffer; +extern char *oglBuffer; #define gyTYPE_PEN 40 #define gyTYPE_BRUSH 41 @@ -49,11 +49,12 @@ extern char *GraphicsBuffer; * */ -IMPLEMENT_DYNAMIC_CLASS(wxDrawnShape, wxShape) +IMPLEMENT_DYNAMIC_CLASS(wxDrawnShape, wxRectangleShape) wxDrawnShape::wxDrawnShape():wxRectangleShape(100.0, 50.0) { m_saveToFile = TRUE; + m_currentAngle = oglDRAWN_ANGLE_0; } wxDrawnShape::~wxDrawnShape() @@ -67,22 +68,22 @@ void wxDrawnShape::OnDraw(wxDC& dc) if (m_shadowMode != SHADOW_NONE) { if (m_shadowBrush) - m_metafile.m_fillBrush = m_shadowBrush; - m_metafile.m_outlinePen = transparent_pen; - m_metafile.Draw(dc, m_xpos + m_shadowOffsetX, m_ypos + m_shadowOffsetY); + m_metafiles[m_currentAngle].m_fillBrush = m_shadowBrush; + m_metafiles[m_currentAngle].m_outlinePen = g_oglTransparentPen; + m_metafiles[m_currentAngle].Draw(dc, m_xpos + m_shadowOffsetX, m_ypos + m_shadowOffsetY); } - m_metafile.m_outlinePen = m_pen; - m_metafile.m_fillBrush = m_brush; - m_metafile.Draw(dc, m_xpos, m_ypos); + m_metafiles[m_currentAngle].m_outlinePen = m_pen; + m_metafiles[m_currentAngle].m_fillBrush = m_brush; + m_metafiles[m_currentAngle].Draw(dc, m_xpos, m_ypos); } -void wxDrawnShape::SetSize(float w, float h, bool recursive) +void wxDrawnShape::SetSize(double w, double h, bool recursive) { SetAttachmentSize(w, h); - float scaleX; - float scaleY; + double scaleX; + double scaleY; if (GetWidth() == 0.0) scaleX = 1.0; else scaleX = w/GetWidth(); @@ -90,98 +91,316 @@ void wxDrawnShape::SetSize(float w, float h, bool recursive) scaleY = 1.0; else scaleY = h/GetHeight(); - m_metafile.Scale(scaleX, scaleY); + int i = 0; + for (i = 0; i < 4; i++) + { + if (m_metafiles[i].IsValid()) + m_metafiles[i].Scale(scaleX, scaleY); + } m_width = w; m_height = h; SetDefaultRegionSize(); } -void wxDrawnShape::Scale(float sx, float sy) +void wxDrawnShape::Scale(double sx, double sy) { - m_metafile.Scale(sx, sy); + int i; + for (i = 0; i < 4; i++) + { + if (m_metafiles[i].IsValid()) + { + m_metafiles[i].Scale(sx, sy); + m_metafiles[i].CalculateSize(this); + } + } } -void wxDrawnShape::Translate(float x, float y) +void wxDrawnShape::Translate(double x, double y) { - m_metafile.Translate(x, y); + int i; + for (i = 0; i < 4; i++) + { + if (m_metafiles[i].IsValid()) + { + m_metafiles[i].Translate(x, y); + m_metafiles[i].CalculateSize(this); + } + } } -void wxDrawnShape::Rotate(float x, float y, float theta) +// theta is absolute rotation from the zero position +void wxDrawnShape::Rotate(double x, double y, double theta) { - if (!m_metafile.GetRotateable()) - return; + m_currentAngle = DetermineMetaFile(theta); + + if (m_currentAngle == 0) + { + // Rotate metafile + if (!m_metafiles[0].GetRotateable()) + return; - float actualTheta = theta-m_metafile.m_currentRotation; + m_metafiles[0].Rotate(x, y, theta); + } - // Rotate metafile - m_metafile.Rotate(x, y, theta); + double actualTheta = theta-m_rotation; // Rotate attachment points - float sinTheta = (float)sin(actualTheta); - float cosTheta = (float)cos(actualTheta); + double sinTheta = (double)sin(actualTheta); + double cosTheta = (double)cos(actualTheta); wxNode *node = m_attachmentPoints.First(); while (node) { wxAttachmentPoint *point = (wxAttachmentPoint *)node->Data(); - float x1 = point->m_x; - float y1 = point->m_y; - point->m_x = x1*cosTheta - y1*sinTheta + x*(1 - cosTheta) + y*sinTheta; - point->m_y = x1*sinTheta + y1*cosTheta + y*(1 - cosTheta) + x*sinTheta; + double x1 = point->m_x; + double y1 = point->m_y; + point->m_x = x1*cosTheta - y1*sinTheta + x*(1.0 - cosTheta) + y*sinTheta; + point->m_y = x1*sinTheta + y1*cosTheta + y*(1.0 - cosTheta) + x*sinTheta; node = node->Next(); } m_rotation = theta; + + m_metafiles[m_currentAngle].CalculateSize(this); } -#ifdef PROLOGIO -// Prolog database stuff -char *wxDrawnShape::GetFunctor() +// Which metafile do we use now? Based on current rotation and validity +// of metafiles. + +int wxDrawnShape::DetermineMetaFile(double rotation) +{ + double tolerance = 0.0001; + const double pi = 3.1415926535897932384626433832795 ; + double angle1 = 0.0; + double angle2 = pi/2.0; + double angle3 = pi; + double angle4 = 3.0*pi/2.0; + + int whichMetafile = 0; + + if (oglRoughlyEqual(rotation, angle1, tolerance)) + { + whichMetafile = 0; + } + else if (oglRoughlyEqual(rotation, angle2, tolerance)) + { + whichMetafile = 1; + } + else if (oglRoughlyEqual(rotation, angle3, tolerance)) + { + whichMetafile = 2; + } + else if (oglRoughlyEqual(rotation, angle4, tolerance)) + { + whichMetafile = 3; + } + + if ((whichMetafile > 0) && !m_metafiles[whichMetafile].IsValid()) + whichMetafile = 0; + + return whichMetafile; +} + +void wxDrawnShape::OnDrawOutline(wxDC& dc, double x, double y, double w, double h) { - return "node_image"; + if (m_metafiles[m_currentAngle].GetOutlineOp() != -1) + { + wxNode* node = m_metafiles[m_currentAngle].GetOps().Nth(m_metafiles[m_currentAngle].GetOutlineOp()); + wxASSERT (node != NULL); + wxDrawOp* op = (wxDrawOp*) node->Data(); + + if (op->OnDrawOutline(dc, x, y, w, h, m_width, m_height)) + return; + } + + // Default... just use a rectangle + wxRectangleShape::OnDrawOutline(dc, x, y, w, h); } -void wxDrawnShape::WritePrologAttributes(wxExpr *clause) +// Get the perimeter point using the special outline op, if there is one, +// otherwise use default wxRectangleShape scheme +bool wxDrawnShape::GetPerimeterPoint(double x1, double y1, + double x2, double y2, + double *x3, double *y3) { - wxRectangleShape::WritePrologAttributes(clause); + if (m_metafiles[m_currentAngle].GetOutlineOp() != -1) + { + wxNode* node = m_metafiles[m_currentAngle].GetOps().Nth(m_metafiles[m_currentAngle].GetOutlineOp()); + wxASSERT (node != NULL); + wxDrawOp* op = (wxDrawOp*) node->Data(); + + if (op->GetPerimeterPoint(x1, y1, x2, y2, x3, y3, GetX(), GetY(), GetAttachmentMode())) + return TRUE; + } + + // Default... just use a rectangle + return wxRectangleShape::GetPerimeterPoint(x1, y1, x2, y2, x3, y3); +} + +#ifdef PROLOGIO +void wxDrawnShape::WriteAttributes(wxExpr *clause) +{ + wxRectangleShape::WriteAttributes(clause); clause->AddAttributeValue("save_metafile", (long)m_saveToFile); if (m_saveToFile) - m_metafile.WritePrologAttributes(clause); + { + int i = 0; + for (i = 0; i < 4; i++) + { + if (m_metafiles[i].IsValid()) + m_metafiles[i].WriteAttributes(clause, i); + } + } } -void wxDrawnShape::ReadPrologAttributes(wxExpr *clause) +void wxDrawnShape::ReadAttributes(wxExpr *clause) { - wxRectangleShape::ReadPrologAttributes(clause); + wxRectangleShape::ReadAttributes(clause); int iVal = (int) m_saveToFile; clause->AssignAttributeValue("save_metafile", &iVal); m_saveToFile = (iVal != 0); if (m_saveToFile) - m_metafile.ReadPrologAttributes(clause); + { + int i = 0; + for (i = 0; i < 4; i++) + { + m_metafiles[i].ReadAttributes(clause, i); + } + } } #endif // Does the copying for this object -void wxDrawnShape::Copy(wxDrawnShape& copy) +void wxDrawnShape::Copy(wxShape& copy) { wxRectangleShape::Copy(copy); - m_metafile.Copy(copy.m_metafile); - copy.m_saveToFile = m_saveToFile; + + wxASSERT( copy.IsKindOf(CLASSINFO(wxDrawnShape)) ) ; + + wxDrawnShape& drawnCopy = (wxDrawnShape&) copy; + + int i = 0; + for (i = 0; i < 4; i++) + { + m_metafiles[i].Copy(drawnCopy.m_metafiles[i]); + } + drawnCopy.m_saveToFile = m_saveToFile; + drawnCopy.m_currentAngle = m_currentAngle; } -// Returns a new instance, and does the copy for this class. Define for each class. -wxShape *wxDrawnShape::PrivateCopy() +bool wxDrawnShape::LoadFromMetaFile(char *filename) { - wxDrawnShape *obj = new wxDrawnShape; - Copy(*obj); - return obj; + return m_metafiles[0].LoadFromMetaFile(filename, &m_width, &m_height); } -bool wxDrawnShape::LoadFromMetaFile(char *filename) +// Set of functions for drawing into a pseudo metafile. +// They use integers, but doubles are used internally for accuracy +// when scaling. + +void wxDrawnShape::DrawLine(const wxPoint& pt1, const wxPoint& pt2) +{ + m_metafiles[m_currentAngle].DrawLine(pt1, pt2); +} + +void wxDrawnShape::DrawRectangle(const wxRect& rect) +{ + m_metafiles[m_currentAngle].DrawRectangle(rect); +} + +void wxDrawnShape::DrawRoundedRectangle(const wxRect& rect, double radius) +{ + m_metafiles[m_currentAngle].DrawRoundedRectangle(rect, radius); +} + +void wxDrawnShape::DrawEllipse(const wxRect& rect) +{ + m_metafiles[m_currentAngle].DrawEllipse(rect); +} + +void wxDrawnShape::DrawArc(const wxPoint& centrePt, const wxPoint& startPt, const wxPoint& endPt) +{ + m_metafiles[m_currentAngle].DrawArc(centrePt, startPt, endPt); +} + +void wxDrawnShape::DrawEllipticArc(const wxRect& rect, double startAngle, double endAngle) +{ + m_metafiles[m_currentAngle].DrawEllipticArc(rect, startAngle, endAngle); +} + +void wxDrawnShape::DrawPoint(const wxPoint& pt) +{ + m_metafiles[m_currentAngle].DrawPoint(pt); +} + +void wxDrawnShape::DrawText(const wxString& text, const wxPoint& pt) +{ + m_metafiles[m_currentAngle].DrawText(text, pt); +} + +void wxDrawnShape::DrawLines(int n, wxPoint pts[]) +{ + m_metafiles[m_currentAngle].DrawLines(n, pts); +} + +void wxDrawnShape::DrawPolygon(int n, wxPoint pts[], int flags) +{ + if (flags & oglMETAFLAGS_ATTACHMENTS) + { + ClearAttachments(); + int i; + for (i = 0; i < n; i++) + m_attachmentPoints.Append(new wxAttachmentPoint(i, pts[i].x, pts[i].y)); + } + m_metafiles[m_currentAngle].DrawPolygon(n, pts, flags); +} + +void wxDrawnShape::DrawSpline(int n, wxPoint pts[]) +{ + m_metafiles[m_currentAngle].DrawSpline(n, pts); +} + +void wxDrawnShape::SetClippingRect(const wxRect& rect) +{ + m_metafiles[m_currentAngle].SetClippingRect(rect); +} + +void wxDrawnShape::DestroyClippingRect() +{ + m_metafiles[m_currentAngle].DestroyClippingRect(); +} + +void wxDrawnShape::SetDrawnPen(wxPen* pen, bool isOutline) +{ + m_metafiles[m_currentAngle].SetPen(pen, isOutline); +} + +void wxDrawnShape::SetDrawnBrush(wxBrush* brush, bool isFill) +{ + m_metafiles[m_currentAngle].SetBrush(brush, isFill); +} + +void wxDrawnShape::SetDrawnFont(wxFont* font) +{ + m_metafiles[m_currentAngle].SetFont(font); +} + +void wxDrawnShape::SetDrawnTextColour(const wxColour& colour) +{ + m_metafiles[m_currentAngle].SetTextColour(colour); +} + +void wxDrawnShape::SetDrawnBackgroundColour(const wxColour& colour) { - return m_metafile.LoadFromMetaFile(filename, &m_width, &m_height); + m_metafiles[m_currentAngle].SetBackgroundColour(colour); } +void wxDrawnShape::SetDrawnBackgroundMode(int mode) +{ + m_metafiles[m_currentAngle].SetBackgroundMode(mode); +} + + /* * Individual operations * @@ -195,27 +414,27 @@ bool wxDrawnShape::LoadFromMetaFile(char *filename) wxOpSetGDI::wxOpSetGDI(int theOp, wxPseudoMetaFile *theImage, int theGdiIndex, int theMode): wxDrawOp(theOp) { - gdiIndex = theGdiIndex; - image = theImage; - mode = theMode; + m_gdiIndex = theGdiIndex; + m_image = theImage; + m_mode = theMode; } -void wxOpSetGDI::Do(wxDC& dc, float xoffset, float yoffset) +void wxOpSetGDI::Do(wxDC& dc, double xoffset, double yoffset) { - switch (op) + switch (m_op) { case DRAWOP_SET_PEN: { // Check for overriding this operation for outline // colour - if (image->m_outlineColours.Member((wxObject *)gdiIndex)) + if (m_image->m_outlineColours.Member((wxObject *)m_gdiIndex)) { - if (image->m_outlinePen) - dc.SetPen(image->m_outlinePen); + if (m_image->m_outlinePen) + dc.SetPen(m_image->m_outlinePen); } else { - wxNode *node = image->m_gdiObjects.Nth(gdiIndex); + wxNode *node = m_image->m_gdiObjects.Nth(m_gdiIndex); if (node) { wxPen *pen = (wxPen *)node->Data(); @@ -229,26 +448,26 @@ void wxOpSetGDI::Do(wxDC& dc, float xoffset, float yoffset) { // Check for overriding this operation for outline or fill // colour - if (image->m_outlineColours.Member((wxObject *)gdiIndex)) + if (m_image->m_outlineColours.Member((wxObject *)m_gdiIndex)) { // Need to construct a brush to match the outline pen's colour - if (image->m_outlinePen) + if (m_image->m_outlinePen) { - wxBrush *br = wxTheBrushList->FindOrCreateBrush(image->m_outlinePen->GetColour(), wxSOLID); + wxBrush *br = wxTheBrushList->FindOrCreateBrush(m_image->m_outlinePen->GetColour(), wxSOLID); if (br) dc.SetBrush(br); } } - else if (image->m_fillColours.Member((wxObject *)gdiIndex)) + else if (m_image->m_fillColours.Member((wxObject *)m_gdiIndex)) { - if (image->m_fillBrush) + if (m_image->m_fillBrush) { - dc.SetBrush(image->m_fillBrush); + dc.SetBrush(m_image->m_fillBrush); } } else { - wxNode *node = image->m_gdiObjects.Nth(gdiIndex); + wxNode *node = m_image->m_gdiObjects.Nth(m_gdiIndex); if (node) { wxBrush *brush = (wxBrush *)node->Data(); @@ -260,7 +479,7 @@ void wxOpSetGDI::Do(wxDC& dc, float xoffset, float yoffset) } case DRAWOP_SET_FONT: { - wxNode *node = image->m_gdiObjects.Nth(gdiIndex); + wxNode *node = m_image->m_gdiObjects.Nth(m_gdiIndex); if (node) { wxFont *font = (wxFont *)node->Data(); @@ -271,19 +490,19 @@ void wxOpSetGDI::Do(wxDC& dc, float xoffset, float yoffset) } case DRAWOP_SET_TEXT_COLOUR: { - wxColour col(r,g,b); + wxColour col(m_r,m_g,m_b); dc.SetTextForeground(col); break; } case DRAWOP_SET_BK_COLOUR: { - wxColour col(r,g,b); + wxColour col(m_r,m_g,m_b); dc.SetTextBackground(col); break; } case DRAWOP_SET_BK_MODE: { - dc.SetBackgroundMode(mode); + dc.SetBackgroundMode(m_mode); break; } default: @@ -293,37 +512,37 @@ void wxOpSetGDI::Do(wxDC& dc, float xoffset, float yoffset) wxDrawOp *wxOpSetGDI::Copy(wxPseudoMetaFile *newImage) { - wxOpSetGDI *newOp = new wxOpSetGDI(op, newImage, gdiIndex, mode); - newOp->r = r; - newOp->g = g; - newOp->b = b; + wxOpSetGDI *newOp = new wxOpSetGDI(m_op, newImage, m_gdiIndex, m_mode); + newOp->m_r = m_r; + newOp->m_g = m_g; + newOp->m_b = m_b; return newOp; } -wxExpr *wxOpSetGDI::WritewxExpr(wxPseudoMetaFile *image) +wxExpr *wxOpSetGDI::WriteExpr(wxPseudoMetaFile *image) { wxExpr *expr = new wxExpr(PrologList); - expr->Append(new wxExpr((long)op)); - switch (op) + expr->Append(new wxExpr((long)m_op)); + switch (m_op) { case DRAWOP_SET_PEN: case DRAWOP_SET_BRUSH: case DRAWOP_SET_FONT: { - expr->Append(new wxExpr((long)gdiIndex)); + expr->Append(new wxExpr((long)m_gdiIndex)); break; } case DRAWOP_SET_TEXT_COLOUR: case DRAWOP_SET_BK_COLOUR: { - expr->Append(new wxExpr((long)r)); - expr->Append(new wxExpr((long)g)); - expr->Append(new wxExpr((long)b)); + expr->Append(new wxExpr((long)m_r)); + expr->Append(new wxExpr((long)m_g)); + expr->Append(new wxExpr((long)m_b)); break; } case DRAWOP_SET_BK_MODE: { - expr->Append(new wxExpr((long)mode)); + expr->Append(new wxExpr((long)m_mode)); break; } default: @@ -332,28 +551,28 @@ wxExpr *wxOpSetGDI::WritewxExpr(wxPseudoMetaFile *image) return expr; } -void wxOpSetGDI::ReadwxExpr(wxPseudoMetaFile *image, wxExpr *expr) +void wxOpSetGDI::ReadExpr(wxPseudoMetaFile *image, wxExpr *expr) { - switch (op) + switch (m_op) { case DRAWOP_SET_PEN: case DRAWOP_SET_BRUSH: case DRAWOP_SET_FONT: { - gdiIndex = (int)expr->Nth(1)->IntegerValue(); + m_gdiIndex = (int)expr->Nth(1)->IntegerValue(); break; } case DRAWOP_SET_TEXT_COLOUR: case DRAWOP_SET_BK_COLOUR: { - r = (unsigned char)expr->Nth(1)->IntegerValue(); - g = (unsigned char)expr->Nth(2)->IntegerValue(); - b = (unsigned char)expr->Nth(3)->IntegerValue(); + m_r = (unsigned char)expr->Nth(1)->IntegerValue(); + m_g = (unsigned char)expr->Nth(2)->IntegerValue(); + m_b = (unsigned char)expr->Nth(3)->IntegerValue(); break; } case DRAWOP_SET_BK_MODE: { - mode = (int)expr->Nth(1)->IntegerValue(); + m_mode = (int)expr->Nth(1)->IntegerValue(); break; } default: @@ -366,28 +585,28 @@ void wxOpSetGDI::ReadwxExpr(wxPseudoMetaFile *image, wxExpr *expr) * */ -wxOpSetClipping::wxOpSetClipping(int theOp, float theX1, float theY1, - float theX2, float theY2):wxDrawOp(theOp) +wxOpSetClipping::wxOpSetClipping(int theOp, double theX1, double theY1, + double theX2, double theY2):wxDrawOp(theOp) { - x1 = theX1; - y1 = theY1; - x2 = theX2; - y2 = theY2; + m_x1 = theX1; + m_y1 = theY1; + m_x2 = theX2; + m_y2 = theY2; } wxDrawOp *wxOpSetClipping::Copy(wxPseudoMetaFile *newImage) { - wxOpSetClipping *newOp = new wxOpSetClipping(op, x1, y1, x2, y2); + wxOpSetClipping *newOp = new wxOpSetClipping(m_op, m_x1, m_y1, m_x2, m_y2); return newOp; } -void wxOpSetClipping::Do(wxDC& dc, float xoffset, float yoffset) +void wxOpSetClipping::Do(wxDC& dc, double xoffset, double yoffset) { - switch (op) + switch (m_op) { case DRAWOP_SET_CLIPPING_RECT: { - dc.SetClippingRegion(x1 + xoffset, y1 + yoffset, x2 + xoffset, y2 + yoffset); + dc.SetClippingRegion(m_x1 + xoffset, m_y1 + yoffset, m_x2 + xoffset, m_y2 + yoffset); break; } case DRAWOP_DESTROY_CLIPPING_RECT: @@ -400,32 +619,32 @@ void wxOpSetClipping::Do(wxDC& dc, float xoffset, float yoffset) } } -void wxOpSetClipping::Scale(float xScale, float yScale) +void wxOpSetClipping::Scale(double xScale, double yScale) { - x1 *= xScale; - y1 *= yScale; - x2 *= xScale; - y2 *= yScale; + m_x1 *= xScale; + m_y1 *= yScale; + m_x2 *= xScale; + m_y2 *= yScale; } -void wxOpSetClipping::Translate(float x, float y) +void wxOpSetClipping::Translate(double x, double y) { - x1 += x; - y1 += y; + m_x1 += x; + m_y1 += y; } -wxExpr *wxOpSetClipping::WritewxExpr(wxPseudoMetaFile *image) +wxExpr *wxOpSetClipping::WriteExpr(wxPseudoMetaFile *image) { wxExpr *expr = new wxExpr(PrologList); - expr->Append(new wxExpr((long)op)); - switch (op) + expr->Append(new wxExpr((long)m_op)); + switch (m_op) { case DRAWOP_SET_CLIPPING_RECT: { - expr->Append(new wxExpr(x1)); - expr->Append(new wxExpr(y1)); - expr->Append(new wxExpr(x2)); - expr->Append(new wxExpr(y2)); + expr->Append(new wxExpr(m_x1)); + expr->Append(new wxExpr(m_y1)); + expr->Append(new wxExpr(m_x2)); + expr->Append(new wxExpr(m_y2)); break; } default: @@ -434,16 +653,16 @@ wxExpr *wxOpSetClipping::WritewxExpr(wxPseudoMetaFile *image) return expr; } -void wxOpSetClipping::ReadwxExpr(wxPseudoMetaFile *image, wxExpr *expr) +void wxOpSetClipping::ReadExpr(wxPseudoMetaFile *image, wxExpr *expr) { - switch (op) + switch (m_op) { case DRAWOP_SET_CLIPPING_RECT: { - x1 = expr->Nth(1)->RealValue(); - y1 = expr->Nth(2)->RealValue(); - x2 = expr->Nth(3)->RealValue(); - y2 = expr->Nth(4)->RealValue(); + m_x1 = expr->Nth(1)->RealValue(); + m_y1 = expr->Nth(2)->RealValue(); + m_x2 = expr->Nth(3)->RealValue(); + m_y2 = expr->Nth(4)->RealValue(); break; } default: @@ -456,61 +675,83 @@ void wxOpSetClipping::ReadwxExpr(wxPseudoMetaFile *image, wxExpr *expr) * */ -wxOpDraw::wxOpDraw(int theOp, float theX1, float theY1, float theX2, float theY2, - float theRadius, char *s):wxDrawOp(theOp) +wxOpDraw::wxOpDraw(int theOp, double theX1, double theY1, double theX2, double theY2, + double theRadius, char *s):wxDrawOp(theOp) { - x1 = theX1; - y1 = theY1; - x2 = theX2; - y2 = theY2; - radius = theRadius; - if (s) textString = copystring(s); - else textString = NULL; + m_x1 = theX1; + m_y1 = theY1; + m_x2 = theX2; + m_y2 = theY2; + m_x3 = 0.0; + m_y3 = 0.0; + m_radius = theRadius; + if (s) m_textString = copystring(s); + else m_textString = NULL; } wxOpDraw::~wxOpDraw() { - if (textString) delete[] textString; + if (m_textString) delete[] m_textString; } wxDrawOp *wxOpDraw::Copy(wxPseudoMetaFile *newImage) { - wxOpDraw *newOp = new wxOpDraw(op, x1, y1, x2, y2, radius, textString); + wxOpDraw *newOp = new wxOpDraw(m_op, m_x1, m_y1, m_x2, m_y2, m_radius, m_textString); + newOp->m_x3 = m_x3; + newOp->m_y3 = m_y3; return newOp; } -void wxOpDraw::Do(wxDC& dc, float xoffset, float yoffset) +void wxOpDraw::Do(wxDC& dc, double xoffset, double yoffset) { - switch (op) + switch (m_op) { case DRAWOP_DRAW_LINE: { - dc.DrawLine(x1+xoffset, y1+yoffset, x2+xoffset, y2+yoffset); + dc.DrawLine(WXROUND(m_x1+xoffset), WXROUND(m_y1+yoffset), WXROUND(m_x2+xoffset), WXROUND(m_y2+yoffset)); break; } case DRAWOP_DRAW_RECT: { - dc.DrawRectangle(x1+xoffset, y1+yoffset, x2+xoffset, y2+yoffset); + dc.DrawRectangle(WXROUND(m_x1+xoffset), WXROUND(m_y1+yoffset), WXROUND(m_x2), WXROUND(m_y2)); break; } case DRAWOP_DRAW_ROUNDED_RECT: { - dc.DrawRoundedRectangle(x1+xoffset, y1+yoffset, x2+xoffset, y2+yoffset, radius); + dc.DrawRoundedRectangle(WXROUND(m_x1+xoffset), WXROUND(m_y1+yoffset), WXROUND(m_x2), WXROUND(m_y2), m_radius); break; } case DRAWOP_DRAW_ELLIPSE: { - dc.DrawEllipse(x1+xoffset, y1+yoffset, x2+xoffset, y2+yoffset); + dc.DrawEllipse(WXROUND(m_x1+xoffset), WXROUND(m_y1+yoffset), WXROUND(m_x2), WXROUND(m_y2)); + break; + } + case DRAWOP_DRAW_ARC: + { + dc.DrawArc(WXROUND(m_x2+xoffset), WXROUND(m_y2+yoffset), + WXROUND(m_x3+xoffset), WXROUND(m_y3+yoffset), + WXROUND(m_x1+xoffset), WXROUND(m_y1+yoffset)); + break; + } + case DRAWOP_DRAW_ELLIPTIC_ARC: + { + const double pi = 3.1415926535897932384626433832795 ; + + // Convert back to degrees + dc.DrawEllipticArc( + WXROUND(m_x1+xoffset), WXROUND(m_y1+yoffset), + WXROUND(m_x2), WXROUND(m_y2), + WXROUND(m_x3*(360.0/(2.0*pi))), WXROUND(m_y3*(360.0/(2.0*pi)))); break; } case DRAWOP_DRAW_POINT: { - dc.DrawPoint(x1+xoffset, y1+yoffset); + dc.DrawPoint(WXROUND(m_x1+xoffset), WXROUND(m_y1+yoffset)); break; } case DRAWOP_DRAW_TEXT: { - dc.DrawText(textString, x1+xoffset, y1+yoffset); + dc.DrawText(m_textString, WXROUND(m_x1+xoffset), WXROUND(m_y1+yoffset)); break; } default: @@ -518,32 +759,117 @@ void wxOpDraw::Do(wxDC& dc, float xoffset, float yoffset) } } -void wxOpDraw::Scale(float scaleX, float scaleY) +void wxOpDraw::Scale(double scaleX, double scaleY) { - x1 *= scaleX; - y1 *= scaleY; - x2 *= scaleX; - y2 *= scaleY; - radius *= scaleX; + m_x1 *= scaleX; + m_y1 *= scaleY; + m_x2 *= scaleX; + m_y2 *= scaleY; + + if (m_op != DRAWOP_DRAW_ELLIPTIC_ARC) + { + m_x3 *= scaleX; + m_y3 *= scaleY; + } + + m_radius *= scaleX; } -void wxOpDraw::Translate(float x, float y) +void wxOpDraw::Translate(double x, double y) { - x1 += x; - y1 += y; + m_x1 += x; + m_y1 += y; + + switch (m_op) + { + case DRAWOP_DRAW_LINE: + { + m_x2 += x; + m_y2 += y; + break; + } + case DRAWOP_DRAW_ARC: + { + m_x2 += x; + m_y2 += y; + m_x3 += x; + m_y3 += y; + break; + } + case DRAWOP_DRAW_ELLIPTIC_ARC: + { + break; + } + default: + break; + } } -void wxOpDraw::Rotate(float x, float y, float sinTheta, float cosTheta) +void wxOpDraw::Rotate(double x, double y, double theta, double sinTheta, double cosTheta) { - x1 = x1*cosTheta - y1*sinTheta + x*(1 - cosTheta) + y*sinTheta; - y1 = x1*sinTheta + y1*cosTheta + y*(1 - cosTheta) + x*sinTheta; - - switch (op) + double newX1 = m_x1*cosTheta - m_y1*sinTheta + x*(1.0 - cosTheta) + y*sinTheta; + double newY1 = m_x1*sinTheta + m_y1*cosTheta + y*(1.0 - cosTheta) + x*sinTheta; + + switch (m_op) { case DRAWOP_DRAW_LINE: { - x2 = x2*cosTheta - y2*sinTheta + x*(1 - cosTheta) + y*sinTheta; - y2 = x2*sinTheta + y2*cosTheta + y*(1 - cosTheta) + x*sinTheta; + double newX2 = m_x2*cosTheta - m_y2*sinTheta + x*(1.0 - cosTheta) + y*sinTheta; + double newY2 = m_x2*sinTheta + m_y2*cosTheta + y*(1.0 - cosTheta) + x*sinTheta; + + m_x1 = newX1; + m_y1 = newY1; + m_x2 = newX2; + m_y2 = newY2; + break; + } + case DRAWOP_DRAW_RECT: + case DRAWOP_DRAW_ROUNDED_RECT: + case DRAWOP_DRAW_ELLIPTIC_ARC: + { + // Assume only 0, 90, 180, 270 degree rotations. + // oldX1, oldY1 represents the top left corner. Find the + // bottom right, and rotate that. Then the width/height is the difference + // between x/y values. + double oldBottomRightX = m_x1 + m_x2; + double oldBottomRightY = m_y1 + m_y2; + double newBottomRightX = oldBottomRightX*cosTheta - oldBottomRightY*sinTheta + x*(1.0 - cosTheta) + y*sinTheta; + double newBottomRightY = oldBottomRightX*sinTheta + oldBottomRightY*cosTheta + y*(1.0 - cosTheta) + x*sinTheta; + + // Now find the new top-left, bottom-right coordinates. + double minX = wxMin(newX1, newBottomRightX); + double minY = wxMin(newY1, newBottomRightY); + double maxX = wxMax(newX1, newBottomRightX); + double maxY = wxMax(newY1, newBottomRightY); + + m_x1 = minX; + m_y1 = minY; + m_x2 = maxX - minX; // width + m_y2 = maxY - minY; // height + + if (m_op == DRAWOP_DRAW_ELLIPTIC_ARC) + { + // Add rotation to angles + m_x3 += theta; + m_y3 += theta; + } + + break; + } + case DRAWOP_DRAW_ARC: + { + double newX2 = m_x2*cosTheta - m_y2*sinTheta + x*(1.0 - cosTheta) + y*sinTheta; + double newY2 = m_x2*sinTheta + m_y2*cosTheta + y*(1.0 - cosTheta) + x*sinTheta; + double newX3 = m_x3*cosTheta - m_y3*sinTheta + x*(1.0 - cosTheta) + y*sinTheta; + double newY3 = m_x3*sinTheta + m_y3*cosTheta + y*(1.0 - cosTheta) + x*sinTheta; + + m_x1 = newX1; + m_y1 = newY1; + m_x2 = newX2; + m_y2 = newY2; + m_x3 = newX3; + m_y3 = newY3; + break; } default: @@ -551,45 +877,55 @@ void wxOpDraw::Rotate(float x, float y, float sinTheta, float cosTheta) } } -wxExpr *wxOpDraw::WritewxExpr(wxPseudoMetaFile *image) +wxExpr *wxOpDraw::WriteExpr(wxPseudoMetaFile *image) { wxExpr *expr = new wxExpr(PrologList); - expr->Append(new wxExpr((long)op)); - switch (op) + expr->Append(new wxExpr((long)m_op)); + switch (m_op) { case DRAWOP_DRAW_LINE: case DRAWOP_DRAW_RECT: case DRAWOP_DRAW_ELLIPSE: { - expr->Append(new wxExpr(x1)); - expr->Append(new wxExpr(y1)); - expr->Append(new wxExpr(x2)); - expr->Append(new wxExpr(y2)); + expr->Append(new wxExpr(m_x1)); + expr->Append(new wxExpr(m_y1)); + expr->Append(new wxExpr(m_x2)); + expr->Append(new wxExpr(m_y2)); break; } case DRAWOP_DRAW_ROUNDED_RECT: { - expr->Append(new wxExpr(x1)); - expr->Append(new wxExpr(y1)); - expr->Append(new wxExpr(x2)); - expr->Append(new wxExpr(y2)); - expr->Append(new wxExpr(radius)); + expr->Append(new wxExpr(m_x1)); + expr->Append(new wxExpr(m_y1)); + expr->Append(new wxExpr(m_x2)); + expr->Append(new wxExpr(m_y2)); + expr->Append(new wxExpr(m_radius)); break; } case DRAWOP_DRAW_POINT: { - expr->Append(new wxExpr(x1)); - expr->Append(new wxExpr(y1)); + expr->Append(new wxExpr(m_x1)); + expr->Append(new wxExpr(m_y1)); break; } case DRAWOP_DRAW_TEXT: { - expr->Append(new wxExpr(x1)); - expr->Append(new wxExpr(y1)); - expr->Append(new wxExpr(PrologString, textString)); + expr->Append(new wxExpr(m_x1)); + expr->Append(new wxExpr(m_y1)); + expr->Append(new wxExpr(PrologString, m_textString)); break; } case DRAWOP_DRAW_ARC: + case DRAWOP_DRAW_ELLIPTIC_ARC: + { + expr->Append(new wxExpr(m_x1)); + expr->Append(new wxExpr(m_y1)); + expr->Append(new wxExpr(m_x2)); + expr->Append(new wxExpr(m_y2)); + expr->Append(new wxExpr(m_x3)); + expr->Append(new wxExpr(m_y3)); + break; + } default: { break; @@ -598,43 +934,54 @@ wxExpr *wxOpDraw::WritewxExpr(wxPseudoMetaFile *image) return expr; } -void wxOpDraw::ReadwxExpr(wxPseudoMetaFile *image, wxExpr *expr) +void wxOpDraw::ReadExpr(wxPseudoMetaFile *image, wxExpr *expr) { - switch (op) + switch (m_op) { case DRAWOP_DRAW_LINE: case DRAWOP_DRAW_RECT: case DRAWOP_DRAW_ELLIPSE: { - x1 = expr->Nth(1)->RealValue(); - y1 = expr->Nth(2)->RealValue(); - x2 = expr->Nth(3)->RealValue(); - y2 = expr->Nth(4)->RealValue(); + m_x1 = expr->Nth(1)->RealValue(); + m_y1 = expr->Nth(2)->RealValue(); + m_x2 = expr->Nth(3)->RealValue(); + m_y2 = expr->Nth(4)->RealValue(); break; } case DRAWOP_DRAW_ROUNDED_RECT: { - x1 = expr->Nth(1)->RealValue(); - y1 = expr->Nth(2)->RealValue(); - x2 = expr->Nth(3)->RealValue(); - y2 = expr->Nth(4)->RealValue(); - radius = expr->Nth(5)->RealValue(); + 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_radius = expr->Nth(5)->RealValue(); break; } case DRAWOP_DRAW_POINT: { - x1 = expr->Nth(1)->RealValue(); - y1 = expr->Nth(2)->RealValue(); + m_x1 = expr->Nth(1)->RealValue(); + m_y1 = expr->Nth(2)->RealValue(); break; } case DRAWOP_DRAW_TEXT: { - x1 = expr->Nth(1)->RealValue(); - y1 = expr->Nth(2)->RealValue(); - textString = copystring(expr->Nth(3)->StringValue()); + m_x1 = expr->Nth(1)->RealValue(); + m_y1 = expr->Nth(2)->RealValue(); + wxString str(expr->Nth(3)->StringValue()); + m_textString = copystring((const char*) str); break; } case DRAWOP_DRAW_ARC: + case DRAWOP_DRAW_ELLIPTIC_ARC: + { + 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; @@ -649,64 +996,75 @@ void wxOpDraw::ReadwxExpr(wxPseudoMetaFile *image, wxExpr *expr) wxOpPolyDraw::wxOpPolyDraw(int theOp, int n, wxRealPoint *thePoints):wxDrawOp(theOp) { - noPoints = n; - points = thePoints; + m_noPoints = n; + m_points = thePoints; } wxOpPolyDraw::~wxOpPolyDraw() { - delete[] points; + delete[] m_points; } wxDrawOp *wxOpPolyDraw::Copy(wxPseudoMetaFile *newImage) { - wxRealPoint *newPoints = new wxRealPoint[noPoints]; - for (int i = 0; i < noPoints; i++) + wxRealPoint *newPoints = new wxRealPoint[m_noPoints]; + for (int i = 0; i < m_noPoints; i++) { - newPoints[i].x = points[i].x; - newPoints[i].y = points[i].y; + newPoints[i].x = m_points[i].x; + newPoints[i].y = m_points[i].y; } - wxOpPolyDraw *newOp = new wxOpPolyDraw(op, noPoints, newPoints); + wxOpPolyDraw *newOp = new wxOpPolyDraw(m_op, m_noPoints, newPoints); return newOp; } -void wxOpPolyDraw::Do(wxDC& dc, float xoffset, float yoffset) +void wxOpPolyDraw::Do(wxDC& dc, double xoffset, double yoffset) { - switch (op) + switch (m_op) { case DRAWOP_DRAW_POLYLINE: { - wxPoint *actualPoints = new wxPoint[noPoints]; + wxPoint *actualPoints = new wxPoint[m_noPoints]; int i; - for (i = 0; i < noPoints; i++) + for (i = 0; i < m_noPoints; i++) { - actualPoints[i].x = (long) points[i].x; - actualPoints[i].y = (long) points[i].y; + actualPoints[i].x = WXROUND(m_points[i].x); + actualPoints[i].y = WXROUND(m_points[i].y); } - dc.DrawLines(noPoints, actualPoints, xoffset, yoffset); + dc.DrawLines(m_noPoints, actualPoints, WXROUND(xoffset), WXROUND(yoffset)); delete[] actualPoints; break; } case DRAWOP_DRAW_POLYGON: { - wxPoint *actualPoints = new wxPoint[noPoints]; + wxPoint *actualPoints = new wxPoint[m_noPoints]; int i; - for (i = 0; i < noPoints; i++) + for (i = 0; i < m_noPoints; i++) { - actualPoints[i].x = (long) points[i].x; - actualPoints[i].y = (long) points[i].y; + actualPoints[i].x = WXROUND(m_points[i].x); + actualPoints[i].y = WXROUND(m_points[i].y); } - dc.DrawPolygon(noPoints, actualPoints, xoffset, yoffset); + dc.DrawPolygon(m_noPoints, actualPoints, WXROUND(xoffset), WXROUND(yoffset)); delete[] actualPoints; break; } case DRAWOP_DRAW_SPLINE: { -// dc.DrawSpline(noPoints, points, xoffset, yoffset); + 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; break; } default: @@ -714,57 +1072,57 @@ void wxOpPolyDraw::Do(wxDC& dc, float xoffset, float yoffset) } } -void wxOpPolyDraw::Scale(float scaleX, float scaleY) +void wxOpPolyDraw::Scale(double scaleX, double scaleY) { - for (int i = 0; i < noPoints; i++) + for (int i = 0; i < m_noPoints; i++) { - points[i].x *= scaleX; - points[i].y *= scaleY; + m_points[i].x *= scaleX; + m_points[i].y *= scaleY; } } -void wxOpPolyDraw::Translate(float x, float y) +void wxOpPolyDraw::Translate(double x, double y) { - for (int i = 0; i < noPoints; i++) + for (int i = 0; i < m_noPoints; i++) { - points[i].x += x; - points[i].y += y; + m_points[i].x += x; + m_points[i].y += y; } } -void wxOpPolyDraw::Rotate(float x, float y, float sinTheta, float cosTheta) +void wxOpPolyDraw::Rotate(double x, double y, double theta, double sinTheta, double cosTheta) { - for (int i = 0; i < noPoints; i++) + for (int i = 0; i < m_noPoints; i++) { - float x1 = points[i].x; - float y1 = points[i].y; - points[i].x = x1*cosTheta - y1*sinTheta + x*(1 - cosTheta) + y*sinTheta; - points[i].y = x1*sinTheta + y1*cosTheta + y*(1 - cosTheta) + x*sinTheta; + 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; } } -wxExpr *wxOpPolyDraw::WritewxExpr(wxPseudoMetaFile *image) +wxExpr *wxOpPolyDraw::WriteExpr(wxPseudoMetaFile *image) { wxExpr *expr = new wxExpr(PrologList); - expr->Append(new wxExpr((long)op)); - expr->Append(new wxExpr((long)noPoints)); + expr->Append(new wxExpr((long)m_op)); + expr->Append(new wxExpr((long)m_noPoints)); // char buf1[9]; char buf2[5]; char buf3[5]; - GraphicsBuffer[0] = 0; - + 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 < noPoints; i++) + for (int i = 0; i < m_noPoints; i++) { - long signedX = (long)(points[i].x*100.0); - long signedY = (long)(points[i].y*100.0); + long signedX = (long)(m_points[i].x*100.0); + long signedY = (long)(m_points[i].y*100.0); // Scale to 0 -> 64K long unSignedX = (long)(signedX + 32767.0); @@ -778,26 +1136,26 @@ wxExpr *wxOpPolyDraw::WritewxExpr(wxPseudoMetaFile *image) // Don't overrun the buffer if ((i*8) < 3000) { - strcat(GraphicsBuffer, buf2); - strcat(GraphicsBuffer, buf3); + strcat(oglBuffer, buf2); + strcat(oglBuffer, buf3); } } - expr->Append(new wxExpr(PrologString, GraphicsBuffer)); + expr->Append(new wxExpr(PrologString, oglBuffer)); return expr; } -void wxOpPolyDraw::ReadwxExpr(wxPseudoMetaFile *image, wxExpr *expr) +void wxOpPolyDraw::ReadExpr(wxPseudoMetaFile *image, wxExpr *expr) { - noPoints = (int)expr->Nth(1)->IntegerValue(); + m_noPoints = (int)expr->Nth(1)->IntegerValue(); char buf1[5]; char buf2[5]; - points = new wxRealPoint[noPoints]; + m_points = new wxRealPoint[m_noPoints]; int i = 0; int bufPtr = 0; wxString hexString = expr->Nth(2)->StringValue(); - while (i < noPoints) + while (i < m_noPoints) { buf1[0] = hexString[bufPtr]; buf1[1] = hexString[bufPtr + 1]; @@ -825,13 +1183,94 @@ void wxOpPolyDraw::ReadwxExpr(wxPseudoMetaFile *image, wxExpr *expr) int testY = (signed int)unSignedY; #endif - points[i].x = (float)(signedX / 100.0); - points[i].y = (float)(signedY / 100.0); + m_points[i].x = (double)(signedX / 100.0); + m_points[i].y = (double)(signedY / 100.0); i ++; } } +// 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, x, 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, + bool 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) && (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]; + + int i = 0; + for (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 @@ -923,6 +1362,9 @@ wxPseudoMetaFile::wxPseudoMetaFile() m_rotateable = TRUE; m_width = 0.0; m_height = 0.0; + m_outlinePen = NULL; + m_fillBrush = NULL; + m_outlineOp = -1; } wxPseudoMetaFile::wxPseudoMetaFile(wxPseudoMetaFile& mf) @@ -946,9 +1388,12 @@ void wxPseudoMetaFile::Clear() } m_ops.Clear(); m_gdiObjects.Clear(); + m_outlineColours.Clear(); + m_fillColours.Clear(); + m_outlineOp = -1; } -void wxPseudoMetaFile::Draw(wxDC& dc, float xoffset, float yoffset) +void wxPseudoMetaFile::Draw(wxDC& dc, double xoffset, double yoffset) { wxNode *node = m_ops.First(); while (node) @@ -959,7 +1404,7 @@ void wxPseudoMetaFile::Draw(wxDC& dc, float xoffset, float yoffset) } } -void wxPseudoMetaFile::Scale(float sx, float sy) +void wxPseudoMetaFile::Scale(double sx, double sy) { wxNode *node = m_ops.First(); while (node) @@ -972,7 +1417,7 @@ void wxPseudoMetaFile::Scale(float sx, float sy) m_height *= sy; } -void wxPseudoMetaFile::Translate(float x, float y) +void wxPseudoMetaFile::Translate(double x, double y) { wxNode *node = m_ops.First(); while (node) @@ -983,30 +1428,43 @@ void wxPseudoMetaFile::Translate(float x, float y) } } -void wxPseudoMetaFile::Rotate(float x, float y, float theta) +void wxPseudoMetaFile::Rotate(double x, double y, double theta) { - float theta1 = theta-m_currentRotation; + double theta1 = theta-m_currentRotation; if (theta1 == 0.0) return; - float cosTheta = (float)cos(theta1); - float sinTheta = (float)sin(theta1); + double cosTheta = (double)cos(theta1); + double sinTheta = (double)sin(theta1); wxNode *node = m_ops.First(); while (node) { wxDrawOp *op = (wxDrawOp *)node->Data(); - op->Rotate(x, y, sinTheta, cosTheta); + op->Rotate(x, y, theta, sinTheta, cosTheta); node = node->Next(); } m_currentRotation = theta; } #ifdef PROLOGIO -void wxPseudoMetaFile::WritePrologAttributes(wxExpr *clause) +void wxPseudoMetaFile::WriteAttributes(wxExpr *clause, int whichAngle) { + wxString widthStr; + widthStr.Printf("meta_width%d", whichAngle); + + wxString heightStr; + heightStr.Printf("meta_height%d", whichAngle); + + wxString outlineStr; + outlineStr.Printf("outline_op%d", whichAngle); + + wxString rotateableStr; + rotateableStr.Printf("meta_rotateable%d", whichAngle); + // Write width and height - clause->AddAttributeValue("meta_width", m_width); - clause->AddAttributeValue("meta_height", m_height); - clause->AddAttributeValue("meta_rotateable", (long)m_rotateable); + clause->AddAttributeValue(widthStr, m_width); + clause->AddAttributeValue(heightStr, m_height); + clause->AddAttributeValue(rotateableStr, (long)m_rotateable); + clause->AddAttributeValue(outlineStr, (long)m_outlineOp); // Write GDI objects char buf[50]; @@ -1014,7 +1472,7 @@ void wxPseudoMetaFile::WritePrologAttributes(wxExpr *clause) wxNode *node = m_gdiObjects.First(); while (node) { - sprintf(buf, "gdi%d", i); + sprintf(buf, "gdi%d_%d", whichAngle, i); wxObject *obj = (wxObject *)node->Data(); wxExpr *expr = NULL; if (obj) @@ -1072,9 +1530,9 @@ void wxPseudoMetaFile::WritePrologAttributes(wxExpr *clause) node = m_ops.First(); while (node) { - sprintf(buf, "op%d", i); + sprintf(buf, "op%d_%d", whichAngle, i); wxDrawOp *op = (wxDrawOp *)node->Data(); - wxExpr *expr = op->WritewxExpr(this); + wxExpr *expr = op->WriteExpr(this); if (expr) { clause->AddAttributeValue(buf, expr); @@ -1093,7 +1551,10 @@ void wxPseudoMetaFile::WritePrologAttributes(wxExpr *clause) outlineExpr->Append(new wxExpr((long)node->Data())); node = node->Next(); } - clause->AddAttributeValue("outline_objects", outlineExpr); + wxString outlineObjectsStr; + outlineObjectsStr.Printf("outline_objects%d", whichAngle); + + clause->AddAttributeValue(outlineObjectsStr, outlineExpr); } if (m_fillColours.Number() > 0) { @@ -1104,18 +1565,34 @@ void wxPseudoMetaFile::WritePrologAttributes(wxExpr *clause) fillExpr->Append(new wxExpr((long)node->Data())); node = node->Next(); } - clause->AddAttributeValue("fill_objects", fillExpr); + wxString fillObjectsStr; + fillObjectsStr.Printf("fill_objects%d", whichAngle); + + clause->AddAttributeValue(fillObjectsStr, fillExpr); } } -void wxPseudoMetaFile::ReadPrologAttributes(wxExpr *clause) +void wxPseudoMetaFile::ReadAttributes(wxExpr *clause, int whichAngle) { - clause->AssignAttributeValue("meta_width", &m_width); - clause->AssignAttributeValue("meta_height", &m_height); + wxString widthStr; + widthStr.Printf("meta_width%d", whichAngle); + + wxString heightStr; + heightStr.Printf("meta_height%d", whichAngle); + + wxString outlineStr; + outlineStr.Printf("outline_op%d", whichAngle); + + wxString rotateableStr; + rotateableStr.Printf("meta_rotateable%d", whichAngle); + + clause->GetAttributeValue(widthStr, m_width); + clause->GetAttributeValue(heightStr, m_height); + clause->GetAttributeValue(outlineStr, m_outlineOp); int iVal = (int) m_rotateable; - clause->AssignAttributeValue("meta_rotateable", &iVal); + clause->GetAttributeValue(rotateableStr, iVal); m_rotateable = (iVal != 0); // Read GDI objects @@ -1124,9 +1601,9 @@ void wxPseudoMetaFile::ReadPrologAttributes(wxExpr *clause) bool keepGoing = TRUE; while (keepGoing) { - sprintf(buf, "gdi%d", i); + sprintf(buf, "gdi%d_%d", whichAngle, i); wxExpr *expr = NULL; - clause->AssignAttributeValue(buf, &expr); + clause->GetAttributeValue(buf, &expr); if (!expr) { keepGoing = FALSE; @@ -1190,9 +1667,9 @@ void wxPseudoMetaFile::ReadPrologAttributes(wxExpr *clause) i = 1; while (keepGoing) { - sprintf(buf, "op%d", i); + sprintf(buf, "op%d_%d", whichAngle, i); wxExpr *expr = NULL; - clause->AssignAttributeValue(buf, &expr); + clause->GetAttributeValue(buf, &expr); if (!expr) { keepGoing = FALSE; @@ -1211,7 +1688,7 @@ void wxPseudoMetaFile::ReadPrologAttributes(wxExpr *clause) case DRAWOP_SET_BK_MODE: { wxOpSetGDI *theOp = new wxOpSetGDI(opId, this, 0); - theOp->ReadwxExpr(this, expr); + theOp->ReadExpr(this, expr); m_ops.Append(theOp); break; } @@ -1220,7 +1697,7 @@ void wxPseudoMetaFile::ReadPrologAttributes(wxExpr *clause) case DRAWOP_DESTROY_CLIPPING_RECT: { wxOpSetClipping *theOp = new wxOpSetClipping(opId, 0.0, 0.0, 0.0, 0.0); - theOp->ReadwxExpr(this, expr); + theOp->ReadExpr(this, expr); m_ops.Append(theOp); break; } @@ -1234,7 +1711,7 @@ void wxPseudoMetaFile::ReadPrologAttributes(wxExpr *clause) case DRAWOP_DRAW_TEXT: { wxOpDraw *theOp = new wxOpDraw(opId, 0.0, 0.0, 0.0, 0.0); - theOp->ReadwxExpr(this, expr); + theOp->ReadExpr(this, expr); m_ops.Append(theOp); break; } @@ -1243,7 +1720,7 @@ void wxPseudoMetaFile::ReadPrologAttributes(wxExpr *clause) case DRAWOP_DRAW_POLYGON: { wxOpPolyDraw *theOp = new wxOpPolyDraw(opId, 0, NULL); - theOp->ReadwxExpr(this, expr); + theOp->ReadExpr(this, expr); m_ops.Append(theOp); break; } @@ -1254,8 +1731,11 @@ void wxPseudoMetaFile::ReadPrologAttributes(wxExpr *clause) i ++; } + wxString outlineObjectsStr; + outlineObjectsStr.Printf("outline_objects%d", whichAngle); + // Now read in the list of outline and fill operations, if any - wxExpr *expr1 = clause->AttributeValue("outline_objects"); + wxExpr *expr1 = clause->AttributeValue(outlineObjectsStr); if (expr1) { wxExpr *eachExpr = expr1->GetFirst(); @@ -1265,7 +1745,11 @@ void wxPseudoMetaFile::ReadPrologAttributes(wxExpr *clause) eachExpr = eachExpr->GetNext(); } } - expr1 = clause->AttributeValue("fill_objects"); + + wxString fillObjectsStr; + fillObjectsStr.Printf("fill_objects%d", whichAngle); + + expr1 = clause->AttributeValue(fillObjectsStr); if (expr1) { wxExpr *eachExpr = expr1->GetFirst(); @@ -1281,10 +1765,15 @@ void wxPseudoMetaFile::ReadPrologAttributes(wxExpr *clause) // Does the copying for this object void wxPseudoMetaFile::Copy(wxPseudoMetaFile& copy) { + copy.Clear(); + copy.m_currentRotation = m_currentRotation; copy.m_width = m_width; copy.m_height = m_height; copy.m_rotateable = m_rotateable; + copy.m_fillBrush = m_fillBrush; + copy.m_outlinePen = m_outlinePen; + copy.m_outlineOp = m_outlineOp; // Copy the GDI objects wxNode *node = m_gdiObjects.First(); @@ -1305,14 +1794,12 @@ void wxPseudoMetaFile::Copy(wxPseudoMetaFile& copy) } // Copy the outline/fill operations - copy.m_outlineColours.Clear(); node = m_outlineColours.First(); while (node) { copy.m_outlineColours.Append((wxObject *)node->Data()); node = node->Next(); } - copy.m_fillColours.Clear(); node = m_fillColours.First(); while (node) { @@ -1327,7 +1814,7 @@ void wxPseudoMetaFile::Copy(wxPseudoMetaFile& copy) * */ -bool wxPseudoMetaFile::LoadFromMetaFile(char *filename, float *rwidth, float *rheight) +bool wxPseudoMetaFile::LoadFromMetaFile(char *filename, double *rwidth, double *rheight) { if (!FileExists(filename)) return NULL; @@ -1340,8 +1827,8 @@ bool wxPseudoMetaFile::LoadFromMetaFile(char *filename, float *rwidth, float *rh return FALSE; } - float lastX = 0.0; - float lastY = 0.0; + double lastX = 0.0; + double lastY = 0.0; // Convert from metafile records to wxDrawnShape records wxNode *node = metaFile->metaRecords.First(); @@ -1353,9 +1840,9 @@ bool wxPseudoMetaFile::LoadFromMetaFile(char *filename, float *rwidth, float *rh case META_SETBKCOLOR: { wxOpSetGDI *op = new wxOpSetGDI(DRAWOP_SET_BK_COLOUR, this, 0); - op->r = (unsigned char)record->param1; - op->g = (unsigned char)record->param2; - op->b = (unsigned char)record->param3; + op->m_r = (unsigned char)record->param1; + op->m_g = (unsigned char)record->param2; + op->m_b = (unsigned char)record->param3; m_ops.Append(op); break; } @@ -1377,9 +1864,9 @@ bool wxPseudoMetaFile::LoadFromMetaFile(char *filename, float *rwidth, float *rh case META_SETTEXTCOLOR: { wxOpSetGDI *op = new wxOpSetGDI(DRAWOP_SET_TEXT_COLOUR, this, 0); - op->r = (unsigned char)record->param1; - op->g = (unsigned char)record->param2; - op->b = (unsigned char)record->param3; + op->m_r = (unsigned char)record->param1; + op->m_g = (unsigned char)record->param2; + op->m_b = (unsigned char)record->param3; m_ops.Append(op); break; } @@ -1394,22 +1881,22 @@ bool wxPseudoMetaFile::LoadFromMetaFile(char *filename, float *rwidth, float *rh // case META_SCALEVIEWPORTEXT: case META_LINETO: { - wxOpDraw *op = new wxOpDraw(DRAWOP_DRAW_LINE, (float)lastX, (float)lastY, - (float)record->param1, (float)record->param2); + wxOpDraw *op = new wxOpDraw(DRAWOP_DRAW_LINE, (double)lastX, (double)lastY, + (double)record->param1, (double)record->param2); m_ops.Append(op); break; } case META_MOVETO: { - lastX = (float)record->param1; - lastY = (float)record->param2; + lastX = (double)record->param1; + lastY = (double)record->param2; break; } case META_EXCLUDECLIPRECT: { /* wxMetaRecord *rec = new wxMetaRecord(META_EXCLUDECLIPRECT); - rec->param4 = getshort(handle); // y2 + rec->param4 = getshort(handle); // m_y2 rec->param3 = getshort(handle); // x2 rec->param2 = getshort(handle); // y1 rec->param1 = getshort(handle); // x1 @@ -1419,7 +1906,7 @@ bool wxPseudoMetaFile::LoadFromMetaFile(char *filename, float *rwidth, float *rh case META_INTERSECTCLIPRECT: { /* - rec->param4 = getshort(handle); // y2 + rec->param4 = getshort(handle); // m_y2 rec->param3 = getshort(handle); // x2 rec->param2 = getshort(handle); // y1 rec->param1 = getshort(handle); // x1 @@ -1430,9 +1917,9 @@ bool wxPseudoMetaFile::LoadFromMetaFile(char *filename, float *rwidth, float *rh case META_ELLIPSE: { wxOpDraw *op = new wxOpDraw(DRAWOP_DRAW_ELLIPSE, - (float)record->param1, (float)record->param2, - (float)(record->param3 - record->param1), - (float)(record->param4 - record->param2)); + (double)record->param1, (double)record->param2, + (double)(record->param3 - record->param1), + (double)(record->param4 - record->param2)); m_ops.Append(op); break; } @@ -1441,18 +1928,18 @@ bool wxPseudoMetaFile::LoadFromMetaFile(char *filename, float *rwidth, float *rh case META_RECTANGLE: { wxOpDraw *op = new wxOpDraw(DRAWOP_DRAW_RECT, - (float)record->param1, (float)record->param2, - (float)(record->param3 - record->param1), - (float)(record->param4 - record->param2)); + (double)record->param1, (double)record->param2, + (double)(record->param3 - record->param1), + (double)(record->param4 - record->param2)); m_ops.Append(op); break; } case META_ROUNDRECT: { wxOpDraw *op = new wxOpDraw(DRAWOP_DRAW_ROUNDED_RECT, - (float)record->param1, (float)record->param2, - (float)(record->param3 - record->param1), - (float)(record->param4 - record->param2), (float)record->param5); + (double)record->param1, (double)record->param2, + (double)(record->param3 - record->param1), + (double)(record->param4 - record->param2), (double)record->param5); m_ops.Append(op); break; } @@ -1461,7 +1948,7 @@ bool wxPseudoMetaFile::LoadFromMetaFile(char *filename, float *rwidth, float *rh case META_SETPIXEL: { wxOpDraw *op = new wxOpDraw(DRAWOP_DRAW_POINT, - (float)record->param1, (float)record->param2, + (double)record->param1, (double)record->param2, 0.0, 0.0); // SHOULD SET THE COLOUR - SET PEN? @@ -1473,7 +1960,7 @@ bool wxPseudoMetaFile::LoadFromMetaFile(char *filename, float *rwidth, float *rh case META_TEXTOUT: { wxOpDraw *op = new wxOpDraw(DRAWOP_DRAW_TEXT, - (float)record->param1, (float)record->param2, + (double)record->param1, (double)record->param2, 0.0, 0.0, 0.0, record->stringParam); m_ops.Append(op); break; @@ -1639,24 +2126,24 @@ bool wxPseudoMetaFile::LoadFromMetaFile(char *filename, float *rwidth, float *rh } node = node->Next(); } - float actualWidth = (float)fabs(metaFile->right - metaFile->left); - float actualHeight = (float)fabs(metaFile->bottom - metaFile->top); - - float initialScaleX = 1.0; - float initialScaleY = 1.0; + double actualWidth = (double)fabs(metaFile->right - metaFile->left); + double actualHeight = (double)fabs(metaFile->bottom - metaFile->top); + + double initialScaleX = 1.0; + double initialScaleY = 1.0; - float xoffset, yoffset; + double xoffset, yoffset; // Translate so origin is at centre of rectangle if (metaFile->bottom > metaFile->top) - yoffset = - (float)((metaFile->bottom - metaFile->top)/2.0); + yoffset = - (double)((metaFile->bottom - metaFile->top)/2.0); else - yoffset = - (float)((metaFile->top - metaFile->bottom)/2.0); + yoffset = - (double)((metaFile->top - metaFile->bottom)/2.0); if (metaFile->right > metaFile->left) - xoffset = - (float)((metaFile->right - metaFile->left)/2.0); + xoffset = - (double)((metaFile->right - metaFile->left)/2.0); else - xoffset = - (float)((metaFile->left - metaFile->right)/2.0); + xoffset = - (double)((metaFile->left - metaFile->right)/2.0); Translate(xoffset, yoffset); @@ -1664,7 +2151,7 @@ bool wxPseudoMetaFile::LoadFromMetaFile(char *filename, float *rwidth, float *rh // as a guide) if (actualWidth != 0.0) { - initialScaleX = (float)((*rwidth) / actualWidth); + initialScaleX = (double)((*rwidth) / actualWidth); initialScaleY = initialScaleX; (*rheight) = initialScaleY*actualHeight; } @@ -1678,70 +2165,86 @@ bool wxPseudoMetaFile::LoadFromMetaFile(char *filename, float *rwidth, float *rh } // Scale to fit size -void wxPseudoMetaFile::ScaleTo(float w, float h) +void wxPseudoMetaFile::ScaleTo(double w, double h) { - float scaleX = (float)(w/m_width); - float scaleY = (float)(h/m_height); + double scaleX = (double)(w/m_width); + double scaleY = (double)(h/m_height); // Do the scaling Scale(scaleX, scaleY); } -void wxPseudoMetaFile::GetBounds(float *boundMinX, float *boundMinY, float *boundMaxX, float *boundMaxY) +void wxPseudoMetaFile::GetBounds(double *boundMinX, double *boundMinY, double *boundMaxX, double *boundMaxY) { - float maxX = (float) -99999.9; - float maxY = (float) -99999.9; - float minX = (float) 99999.9; - float minY = (float) 99999.9; + double maxX = (double) -99999.9; + double maxY = (double) -99999.9; + double minX = (double) 99999.9; + double minY = (double) 99999.9; wxNode *node = m_ops.First(); while (node) { wxDrawOp *op = (wxDrawOp *)node->Data(); - switch (op->op) + switch (op->GetOp()) { case DRAWOP_DRAW_LINE: case DRAWOP_DRAW_RECT: case DRAWOP_DRAW_ROUNDED_RECT: case DRAWOP_DRAW_ELLIPSE: case DRAWOP_DRAW_POINT: - case DRAWOP_DRAW_ARC: case DRAWOP_DRAW_TEXT: { wxOpDraw *opDraw = (wxOpDraw *)op; - if (opDraw->x1 < minX) minX = opDraw->x1; - if (opDraw->x1 > maxX) maxX = opDraw->x1; - if (opDraw->y1 < minY) minY = opDraw->y1; - if (opDraw->y1 > maxY) maxY = opDraw->y1; - if (op->op == DRAWOP_DRAW_LINE) + if (opDraw->m_x1 < minX) minX = opDraw->m_x1; + if (opDraw->m_x1 > maxX) maxX = opDraw->m_x1; + if (opDraw->m_y1 < minY) minY = opDraw->m_y1; + if (opDraw->m_y1 > maxY) maxY = opDraw->m_y1; + if (op->GetOp() == DRAWOP_DRAW_LINE) { - if (opDraw->x2 < minX) minX = opDraw->x2; - if (opDraw->x2 > maxX) maxX = opDraw->x2; - if (opDraw->y2 < minY) minY = opDraw->y2; - if (opDraw->y2 > maxY) maxY = opDraw->y2; + if (opDraw->m_x2 < minX) minX = opDraw->m_x2; + if (opDraw->m_x2 > maxX) maxX = opDraw->m_x2; + if (opDraw->m_y2 < minY) minY = opDraw->m_y2; + if (opDraw->m_y2 > maxY) maxY = opDraw->m_y2; } - else if (op->op == DRAWOP_DRAW_RECT || - op->op == DRAWOP_DRAW_ROUNDED_RECT || - op->op == DRAWOP_DRAW_ELLIPSE) + else if (op->GetOp() == DRAWOP_DRAW_RECT || + op->GetOp() == DRAWOP_DRAW_ROUNDED_RECT || + op->GetOp() == DRAWOP_DRAW_ELLIPSE) { - if ((opDraw->x1 + opDraw->x2) < minX) minX = (opDraw->x1 + opDraw->x2); - if ((opDraw->x1 + opDraw->x2) > maxX) maxX = (opDraw->x1 + opDraw->x2); - if ((opDraw->y1 + opDraw->y2) < minY) minY = (opDraw->y1 + opDraw->y2); - if ((opDraw->y1 + opDraw->y2) > maxY) maxY = (opDraw->y1 + opDraw->y2); + if ((opDraw->m_x1 + opDraw->m_x2) < minX) minX = (opDraw->m_x1 + opDraw->m_x2); + if ((opDraw->m_x1 + opDraw->m_x2) > maxX) maxX = (opDraw->m_x1 + opDraw->m_x2); + if ((opDraw->m_y1 + opDraw->m_y2) < minY) minY = (opDraw->m_y1 + opDraw->m_y2); + if ((opDraw->m_y1 + opDraw->m_y2) > maxY) maxY = (opDraw->m_y1 + opDraw->m_y2); } break; } + case DRAWOP_DRAW_ARC: + { + // TODO: don't yet know how to calculate the bounding box + // for an arc. So pretend it's a line; to get a correct + // bounding box, draw a blank rectangle first, of the correct + // size. + wxOpDraw *opDraw = (wxOpDraw *)op; + if (opDraw->m_x1 < minX) minX = opDraw->m_x1; + if (opDraw->m_x1 > maxX) maxX = opDraw->m_x1; + if (opDraw->m_y1 < minY) minY = opDraw->m_y1; + if (opDraw->m_y1 > maxY) maxY = opDraw->m_y1; + if (opDraw->m_x2 < minX) minX = opDraw->m_x2; + if (opDraw->m_x2 > maxX) maxX = opDraw->m_x2; + if (opDraw->m_y2 < minY) minY = opDraw->m_y2; + if (opDraw->m_y2 > maxY) maxY = opDraw->m_y2; + break; + } case DRAWOP_DRAW_POLYLINE: case DRAWOP_DRAW_POLYGON: case DRAWOP_DRAW_SPLINE: { wxOpPolyDraw *poly = (wxOpPolyDraw *)op; - for (int i = 0; i < poly->noPoints; i++) + for (int i = 0; i < poly->m_noPoints; i++) { - if (poly->points[i].x < minX) minX = poly->points[i].x; - if (poly->points[i].x > maxX) maxX = poly->points[i].x; - if (poly->points[i].y < minY) minY = poly->points[i].y; - if (poly->points[i].y > maxY) maxY = poly->points[i].y; + if (poly->m_points[i].x < minX) minX = poly->m_points[i].x; + if (poly->m_points[i].x > maxX) maxX = poly->m_points[i].x; + if (poly->m_points[i].y < minY) minY = poly->m_points[i].y; + if (poly->m_points[i].y > maxY) maxY = poly->m_points[i].y; } break; } @@ -1756,9 +2259,230 @@ void wxPseudoMetaFile::GetBounds(float *boundMinX, float *boundMinY, float *boun *boundMaxX = maxX; *boundMaxY = maxY; /* - *w = (float)fabs(maxX - minX); - *h = (float)fabs(maxY - minY); + *w = (double)fabs(maxX - minX); + *h = (double)fabs(maxY - minY); */ } +// Calculate size from current operations +void wxPseudoMetaFile::CalculateSize(wxDrawnShape* shape) +{ + double boundMinX, boundMinY, boundMaxX, boundMaxY; + + GetBounds(& boundMinX, & boundMinY, & boundMaxX, & boundMaxY); + + SetSize(boundMaxX - boundMinX, boundMaxY - boundMinY); + + if (shape) + { + shape->SetWidth(m_width); + shape->SetHeight(m_height); + } +} + +// Set of functions for drawing into a pseudo metafile. +// They use integers, but doubles are used internally for accuracy +// when scaling. + +void wxPseudoMetaFile::DrawLine(const wxPoint& pt1, const wxPoint& pt2) +{ + wxOpDraw *theOp = new wxOpDraw(DRAWOP_DRAW_LINE, + (double) pt1.x, (double) pt1.y, (double) pt2.x, (double) pt2.y); + + m_ops.Append(theOp); +} + +void wxPseudoMetaFile::DrawRectangle(const wxRect& rect) +{ + wxOpDraw *theOp = new wxOpDraw(DRAWOP_DRAW_RECT, + (double) rect.x, (double) rect.y, (double) rect.width, (double) rect.height); + + m_ops.Append(theOp); +} + +void wxPseudoMetaFile::DrawRoundedRectangle(const wxRect& rect, double radius) +{ + wxOpDraw *theOp = new wxOpDraw(DRAWOP_DRAW_ROUNDED_RECT, + (double) rect.x, (double) rect.y, (double) rect.width, (double) rect.height); + + theOp->m_radius = radius; + + m_ops.Append(theOp); +} + +void wxPseudoMetaFile::DrawEllipse(const wxRect& rect) +{ + wxOpDraw *theOp = new wxOpDraw(DRAWOP_DRAW_ELLIPSE, + (double) rect.x, (double) rect.y, (double) rect.width, (double) rect.height); + + m_ops.Append(theOp); +} + +void wxPseudoMetaFile::DrawArc(const wxPoint& centrePt, const wxPoint& startPt, const wxPoint& endPt) +{ + wxOpDraw *theOp = new wxOpDraw(DRAWOP_DRAW_ARC, + (double) centrePt.x, (double) centrePt.y, (double) startPt.x, (double) startPt.y); + + theOp->m_x3 = (double) endPt.x; + theOp->m_y3 = (double) endPt.y; + + m_ops.Append(theOp); +} + +void wxPseudoMetaFile::DrawEllipticArc(const wxRect& rect, double startAngle, double endAngle) +{ + const double pi = 3.1415926535897932384626433832795 ; + + double startAngleRadians = startAngle* (pi*2.0/360.0); + double endAngleRadians = endAngle* (pi*2.0/360.0); + + wxOpDraw *theOp = new wxOpDraw(DRAWOP_DRAW_ELLIPTIC_ARC, + (double) rect.x, (double) rect.y, (double) rect.width, (double) rect.height); + + theOp->m_x3 = startAngleRadians; + theOp->m_y3 = endAngleRadians; + + m_ops.Append(theOp); +} + +void wxPseudoMetaFile::DrawPoint(const wxPoint& pt) +{ + wxOpDraw *theOp = new wxOpDraw(DRAWOP_DRAW_POINT, + (double) pt.x, (double) pt.y, 0.0, 0.0); + + m_ops.Append(theOp); +} + +void wxPseudoMetaFile::DrawText(const wxString& text, const wxPoint& pt) +{ + wxOpDraw *theOp = new wxOpDraw(DRAWOP_DRAW_TEXT, + (double) pt.x, (double) pt.y, 0.0, 0.0); + + theOp->m_textString = copystring(text); + + m_ops.Append(theOp); +} + +void wxPseudoMetaFile::DrawLines(int n, wxPoint pts[]) +{ + wxRealPoint* realPoints = new wxRealPoint[n]; + int i; + for (i = 0; i < n; i++) + { + realPoints[i].x = pts[i].x; + realPoints[i].y = pts[i].y; + } + wxOpPolyDraw* theOp = new wxOpPolyDraw(DRAWOP_DRAW_POLYLINE, n, realPoints); + m_ops.Append(theOp); +} + +void wxPseudoMetaFile::DrawPolygon(int n, wxPoint pts[], int flags) +{ + wxRealPoint* realPoints = new wxRealPoint[n]; + int i; + for (i = 0; i < n; i++) + { + realPoints[i].x = pts[i].x; + realPoints[i].y = pts[i].y; + } + wxOpPolyDraw* theOp = new wxOpPolyDraw(DRAWOP_DRAW_POLYGON, n, realPoints); + m_ops.Append(theOp); + + if (flags & oglMETAFLAGS_OUTLINE) + m_outlineOp = (m_ops.Number() - 1); +} + +void wxPseudoMetaFile::DrawSpline(int n, wxPoint pts[]) +{ + wxRealPoint* realPoints = new wxRealPoint[n]; + int i; + for (i = 0; i < n; i++) + { + realPoints[i].x = pts[i].x; + realPoints[i].y = pts[i].y; + } + wxOpPolyDraw* theOp = new wxOpPolyDraw(DRAWOP_DRAW_SPLINE, n, realPoints); + m_ops.Append(theOp); +} + +void wxPseudoMetaFile::SetClippingRect(const wxRect& rect) +{ + wxOpSetClipping* theOp = new wxOpSetClipping(DRAWOP_SET_CLIPPING_RECT, + (double) rect.x, (double) rect.y, (double) rect.width, (double) rect.height); +} + +void wxPseudoMetaFile::DestroyClippingRect() +{ + wxOpSetClipping* theOp = new wxOpSetClipping(DRAWOP_DESTROY_CLIPPING_RECT, + 0.0, 0.0, 0.0, 0.0); + + m_ops.Append(theOp); +} + +void wxPseudoMetaFile::SetPen(wxPen* pen, bool isOutline) +{ + m_gdiObjects.Append(pen); + int n = m_gdiObjects.Number(); + + wxOpSetGDI* theOp = new wxOpSetGDI(DRAWOP_SET_PEN, this, n - 1); + + m_ops.Append(theOp); + + if (isOutline) + { + m_outlineColours.Append((wxObject*) (n - 1)); + } +} + +void wxPseudoMetaFile::SetBrush(wxBrush* brush, bool isFill) +{ + m_gdiObjects.Append(brush); + int n = m_gdiObjects.Number(); + + wxOpSetGDI* theOp = new wxOpSetGDI(DRAWOP_SET_BRUSH, this, n - 1); + + m_ops.Append(theOp); + + if (isFill) + { + m_fillColours.Append((wxObject*) (n - 1)); + } +} + +void wxPseudoMetaFile::SetFont(wxFont* font) +{ + m_gdiObjects.Append(font); + int n = m_gdiObjects.Number(); + + wxOpSetGDI* theOp = new wxOpSetGDI(DRAWOP_SET_FONT, this, n - 1); + + m_ops.Append(theOp); +} + +void wxPseudoMetaFile::SetTextColour(const wxColour& colour) +{ + wxOpSetGDI* theOp = new wxOpSetGDI(DRAWOP_SET_TEXT_COLOUR, this, 0); + theOp->m_r = colour.Red(); + theOp->m_g = colour.Green(); + theOp->m_b = colour.Blue(); + + m_ops.Append(theOp); +} + +void wxPseudoMetaFile::SetBackgroundColour(const wxColour& colour) +{ + wxOpSetGDI* theOp = new wxOpSetGDI(DRAWOP_SET_BK_COLOUR, this, 0); + theOp->m_r = colour.Red(); + theOp->m_g = colour.Green(); + theOp->m_b = colour.Blue(); + + m_ops.Append(theOp); +} + +void wxPseudoMetaFile::SetBackgroundMode(int mode) +{ + wxOpSetGDI* theOp = new wxOpSetGDI(DRAWOP_SET_BK_MODE, this, 0, mode); + + m_ops.Append(theOp); +}