1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxDrawnShape
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "drawn.h"
14 #pragma implementation "drawnp.h"
17 // For compilers that support precompilation, includes "wx.h".
18 #include "wx/wxprec.h"
29 #include <wx/deprecated/wxexpr.h>
32 #include "wx/ogl/ogl.h"
34 static void IntToHex(unsigned int dec
, wxChar
*buf
);
35 static unsigned long HexToInt(wxChar
*buf
);
36 extern wxChar
*oglBuffer
;
39 #define gyTYPE_BRUSH 41
40 #define gyTYPE_FONT 42
47 IMPLEMENT_DYNAMIC_CLASS(wxDrawnShape
, wxRectangleShape
)
49 wxDrawnShape::wxDrawnShape():wxRectangleShape(100.0, 50.0)
52 m_currentAngle
= oglDRAWN_ANGLE_0
;
55 wxDrawnShape::~wxDrawnShape()
59 void wxDrawnShape::OnDraw(wxDC
& dc
)
61 // Pass pen and brush in case we have force outline
63 if (m_shadowMode
!= SHADOW_NONE
)
66 m_metafiles
[m_currentAngle
].m_fillBrush
= m_shadowBrush
;
67 m_metafiles
[m_currentAngle
].m_outlinePen
= g_oglTransparentPen
;
68 m_metafiles
[m_currentAngle
].Draw(dc
, m_xpos
+ m_shadowOffsetX
, m_ypos
+ m_shadowOffsetY
);
71 m_metafiles
[m_currentAngle
].m_outlinePen
= m_pen
;
72 m_metafiles
[m_currentAngle
].m_fillBrush
= m_brush
;
73 m_metafiles
[m_currentAngle
].Draw(dc
, m_xpos
, m_ypos
);
76 void wxDrawnShape::SetSize(double w
, double h
, bool WXUNUSED(recursive
))
78 SetAttachmentSize(w
, h
);
82 if (GetWidth() == 0.0)
84 else scaleX
= w
/GetWidth();
85 if (GetHeight() == 0.0)
87 else scaleY
= h
/GetHeight();
89 for (int i
= 0; i
< 4; i
++)
91 if (m_metafiles
[i
].IsValid())
92 m_metafiles
[i
].Scale(scaleX
, scaleY
);
96 SetDefaultRegionSize();
99 void wxDrawnShape::Scale(double sx
, double sy
)
102 for (i
= 0; i
< 4; i
++)
104 if (m_metafiles
[i
].IsValid())
106 m_metafiles
[i
].Scale(sx
, sy
);
107 m_metafiles
[i
].CalculateSize(this);
112 void wxDrawnShape::Translate(double x
, double y
)
115 for (i
= 0; i
< 4; i
++)
117 if (m_metafiles
[i
].IsValid())
119 m_metafiles
[i
].Translate(x
, y
);
120 m_metafiles
[i
].CalculateSize(this);
125 // theta is absolute rotation from the zero position
126 void wxDrawnShape::Rotate(double x
, double y
, double theta
)
128 m_currentAngle
= DetermineMetaFile(theta
);
130 if (m_currentAngle
== 0)
133 if (!m_metafiles
[0].GetRotateable())
136 m_metafiles
[0].Rotate(x
, y
, theta
);
139 double actualTheta
= theta
-m_rotation
;
141 // Rotate attachment points
142 double sinTheta
= (double)sin(actualTheta
);
143 double cosTheta
= (double)cos(actualTheta
);
144 wxNode
*node
= m_attachmentPoints
.GetFirst();
147 wxAttachmentPoint
*point
= (wxAttachmentPoint
*)node
->GetData();
148 double x1
= point
->m_x
;
149 double y1
= point
->m_y
;
150 point
->m_x
= x1
*cosTheta
- y1
*sinTheta
+ x
*(1.0 - cosTheta
) + y
*sinTheta
;
151 point
->m_y
= x1
*sinTheta
+ y1
*cosTheta
+ y
*(1.0 - cosTheta
) + x
*sinTheta
;
152 node
= node
->GetNext();
156 m_metafiles
[m_currentAngle
].CalculateSize(this);
159 // Which metafile do we use now? Based on current rotation and validity
162 int wxDrawnShape::DetermineMetaFile(double rotation
)
164 double tolerance
= 0.0001;
165 const double pi
= M_PI
;
167 double angle2
= pi
/2.0;
169 double angle4
= 3.0*pi
/2.0;
171 int whichMetafile
= 0;
173 if (oglRoughlyEqual(rotation
, angle1
, tolerance
))
177 else if (oglRoughlyEqual(rotation
, angle2
, tolerance
))
181 else if (oglRoughlyEqual(rotation
, angle3
, tolerance
))
185 else if (oglRoughlyEqual(rotation
, angle4
, tolerance
))
190 if ((whichMetafile
> 0) && !m_metafiles
[whichMetafile
].IsValid())
193 return whichMetafile
;
196 void wxDrawnShape::OnDrawOutline(wxDC
& dc
, double x
, double y
, double w
, double h
)
198 if (m_metafiles
[m_currentAngle
].GetOutlineOp() != -1)
200 wxNode
* node
= m_metafiles
[m_currentAngle
].GetOps().Item(m_metafiles
[m_currentAngle
].GetOutlineOp());
201 wxASSERT (node
!= NULL
);
202 wxDrawOp
* op
= (wxDrawOp
*) node
->GetData();
204 if (op
->OnDrawOutline(dc
, x
, y
, w
, h
, m_width
, m_height
))
208 // Default... just use a rectangle
209 wxRectangleShape::OnDrawOutline(dc
, x
, y
, w
, h
);
212 // Get the perimeter point using the special outline op, if there is one,
213 // otherwise use default wxRectangleShape scheme
214 bool wxDrawnShape::GetPerimeterPoint(double x1
, double y1
,
215 double x2
, double y2
,
216 double *x3
, double *y3
)
218 if (m_metafiles
[m_currentAngle
].GetOutlineOp() != -1)
220 wxNode
* node
= m_metafiles
[m_currentAngle
].GetOps().Item(m_metafiles
[m_currentAngle
].GetOutlineOp());
221 wxASSERT (node
!= NULL
);
222 wxDrawOp
* op
= (wxDrawOp
*) node
->GetData();
224 if (op
->GetPerimeterPoint(x1
, y1
, x2
, y2
, x3
, y3
, GetX(), GetY(), GetAttachmentMode()))
228 // Default... just use a rectangle
229 return wxRectangleShape::GetPerimeterPoint(x1
, y1
, x2
, y2
, x3
, y3
);
233 void wxDrawnShape::WriteAttributes(wxExpr
*clause
)
235 wxRectangleShape::WriteAttributes(clause
);
237 clause
->AddAttributeValue(_T("current_angle"), (long)m_currentAngle
);
238 clause
->AddAttributeValue(_T("save_metafile"), (long)m_saveToFile
);
241 for (int i
= 0; i
< 4; i
++)
243 if (m_metafiles
[i
].IsValid())
244 m_metafiles
[i
].WriteAttributes(clause
, i
);
249 void wxDrawnShape::ReadAttributes(wxExpr
*clause
)
251 wxRectangleShape::ReadAttributes(clause
);
253 int iVal
= (int) m_saveToFile
;
254 clause
->GetAttributeValue(_T("save_metafile"), iVal
);
255 clause
->GetAttributeValue(_T("current_angle"), m_currentAngle
);
256 m_saveToFile
= (iVal
!= 0);
260 for (int i
= 0; i
< 4; i
++)
262 m_metafiles
[i
].ReadAttributes(clause
, i
);
268 // Does the copying for this object
269 void wxDrawnShape::Copy(wxShape
& copy
)
271 wxRectangleShape::Copy(copy
);
273 wxASSERT( copy
.IsKindOf(CLASSINFO(wxDrawnShape
)) ) ;
275 wxDrawnShape
& drawnCopy
= (wxDrawnShape
&) copy
;
277 for (int i
= 0; i
< 4; i
++)
279 m_metafiles
[i
].Copy(drawnCopy
.m_metafiles
[i
]);
281 drawnCopy
.m_saveToFile
= m_saveToFile
;
282 drawnCopy
.m_currentAngle
= m_currentAngle
;
285 bool wxDrawnShape::LoadFromMetaFile(const wxString
& filename
)
287 return m_metafiles
[0].LoadFromMetaFile(filename
, &m_width
, &m_height
);
290 // Set of functions for drawing into a pseudo metafile.
291 // They use integers, but doubles are used internally for accuracy
294 void wxDrawnShape::DrawLine(const wxPoint
& pt1
, const wxPoint
& pt2
)
296 m_metafiles
[m_currentAngle
].DrawLine(pt1
, pt2
);
299 void wxDrawnShape::DrawRectangle(const wxRect
& rect
)
301 m_metafiles
[m_currentAngle
].DrawRectangle(rect
);
304 void wxDrawnShape::DrawRoundedRectangle(const wxRect
& rect
, double radius
)
306 m_metafiles
[m_currentAngle
].DrawRoundedRectangle(rect
, radius
);
309 void wxDrawnShape::DrawEllipse(const wxRect
& rect
)
311 m_metafiles
[m_currentAngle
].DrawEllipse(rect
);
314 void wxDrawnShape::DrawArc(const wxPoint
& centrePt
, const wxPoint
& startPt
, const wxPoint
& endPt
)
316 m_metafiles
[m_currentAngle
].DrawArc(centrePt
, startPt
, endPt
);
319 void wxDrawnShape::DrawEllipticArc(const wxRect
& rect
, double startAngle
, double endAngle
)
321 m_metafiles
[m_currentAngle
].DrawEllipticArc(rect
, startAngle
, endAngle
);
324 void wxDrawnShape::DrawPoint(const wxPoint
& pt
)
326 m_metafiles
[m_currentAngle
].DrawPoint(pt
);
329 void wxDrawnShape::DrawText(const wxString
& text
, const wxPoint
& pt
)
331 m_metafiles
[m_currentAngle
].DrawText(text
, pt
);
334 void wxDrawnShape::DrawLines(int n
, wxPoint pts
[])
336 m_metafiles
[m_currentAngle
].DrawLines(n
, pts
);
339 void wxDrawnShape::DrawPolygon(int n
, wxPoint pts
[], int flags
)
341 if (flags
& oglMETAFLAGS_ATTACHMENTS
)
345 for (i
= 0; i
< n
; i
++)
346 m_attachmentPoints
.Append(new wxAttachmentPoint(i
, pts
[i
].x
, pts
[i
].y
));
348 m_metafiles
[m_currentAngle
].DrawPolygon(n
, pts
, flags
);
351 void wxDrawnShape::DrawSpline(int n
, wxPoint pts
[])
353 m_metafiles
[m_currentAngle
].DrawSpline(n
, pts
);
356 void wxDrawnShape::SetClippingRect(const wxRect
& rect
)
358 m_metafiles
[m_currentAngle
].SetClippingRect(rect
);
361 void wxDrawnShape::DestroyClippingRect()
363 m_metafiles
[m_currentAngle
].DestroyClippingRect();
366 void wxDrawnShape::SetDrawnPen(wxPen
* pen
, bool isOutline
)
368 m_metafiles
[m_currentAngle
].SetPen(pen
, isOutline
);
371 void wxDrawnShape::SetDrawnBrush(wxBrush
* brush
, bool isFill
)
373 m_metafiles
[m_currentAngle
].SetBrush(brush
, isFill
);
376 void wxDrawnShape::SetDrawnFont(wxFont
* font
)
378 m_metafiles
[m_currentAngle
].SetFont(font
);
381 void wxDrawnShape::SetDrawnTextColour(const wxColour
& colour
)
383 m_metafiles
[m_currentAngle
].SetTextColour(colour
);
386 void wxDrawnShape::SetDrawnBackgroundColour(const wxColour
& colour
)
388 m_metafiles
[m_currentAngle
].SetBackgroundColour(colour
);
391 void wxDrawnShape::SetDrawnBackgroundMode(int mode
)
393 m_metafiles
[m_currentAngle
].SetBackgroundMode(mode
);
398 * Individual operations
403 * Set font, brush, text colour
407 wxOpSetGDI::wxOpSetGDI(int theOp
, wxPseudoMetaFile
*theImage
, int theGdiIndex
, int theMode
):
410 m_gdiIndex
= theGdiIndex
;
415 void wxOpSetGDI::Do(wxDC
& dc
, double WXUNUSED(xoffset
), double WXUNUSED(yoffset
))
421 // Check for overriding this operation for outline
423 if (m_image
->m_outlineColours
.Member((wxObject
*)m_gdiIndex
))
425 if (m_image
->m_outlinePen
)
426 dc
.SetPen(* m_image
->m_outlinePen
);
430 wxNode
*node
= m_image
->m_gdiObjects
.Item(m_gdiIndex
);
433 wxPen
*pen
= (wxPen
*)node
->GetData();
440 case DRAWOP_SET_BRUSH
:
442 // Check for overriding this operation for outline or fill
444 if (m_image
->m_outlineColours
.Member((wxObject
*)m_gdiIndex
))
446 // Need to construct a brush to match the outline pen's colour
447 if (m_image
->m_outlinePen
)
449 wxBrush
*br
= wxTheBrushList
->FindOrCreateBrush(m_image
->m_outlinePen
->GetColour(), wxSOLID
);
454 else if (m_image
->m_fillColours
.Member((wxObject
*)m_gdiIndex
))
456 if (m_image
->m_fillBrush
)
458 dc
.SetBrush(* m_image
->m_fillBrush
);
463 wxNode
*node
= m_image
->m_gdiObjects
.Item(m_gdiIndex
);
466 wxBrush
*brush
= (wxBrush
*)node
->GetData();
468 dc
.SetBrush(* brush
);
473 case DRAWOP_SET_FONT
:
475 wxNode
*node
= m_image
->m_gdiObjects
.Item(m_gdiIndex
);
478 wxFont
*font
= (wxFont
*)node
->GetData();
484 case DRAWOP_SET_TEXT_COLOUR
:
486 wxColour
col(m_r
,m_g
,m_b
);
487 dc
.SetTextForeground(col
);
490 case DRAWOP_SET_BK_COLOUR
:
492 wxColour
col(m_r
,m_g
,m_b
);
493 dc
.SetTextBackground(col
);
496 case DRAWOP_SET_BK_MODE
:
498 dc
.SetBackgroundMode(m_mode
);
506 wxDrawOp
*wxOpSetGDI::Copy(wxPseudoMetaFile
*newImage
)
508 wxOpSetGDI
*newOp
= new wxOpSetGDI(m_op
, newImage
, m_gdiIndex
, m_mode
);
516 wxExpr
*wxOpSetGDI::WriteExpr(wxPseudoMetaFile
*WXUNUSED(image
))
518 wxExpr
*expr
= new wxExpr(wxExprList
);
519 expr
->Append(new wxExpr((long)m_op
));
523 case DRAWOP_SET_BRUSH
:
524 case DRAWOP_SET_FONT
:
526 expr
->Append(new wxExpr((long)m_gdiIndex
));
529 case DRAWOP_SET_TEXT_COLOUR
:
530 case DRAWOP_SET_BK_COLOUR
:
532 expr
->Append(new wxExpr((long)m_r
));
533 expr
->Append(new wxExpr((long)m_g
));
534 expr
->Append(new wxExpr((long)m_b
));
537 case DRAWOP_SET_BK_MODE
:
539 expr
->Append(new wxExpr((long)m_mode
));
548 void wxOpSetGDI::ReadExpr(wxPseudoMetaFile
*WXUNUSED(image
), wxExpr
*expr
)
553 case DRAWOP_SET_BRUSH
:
554 case DRAWOP_SET_FONT
:
556 m_gdiIndex
= (int)expr
->Nth(1)->IntegerValue();
559 case DRAWOP_SET_TEXT_COLOUR
:
560 case DRAWOP_SET_BK_COLOUR
:
562 m_r
= (unsigned char)expr
->Nth(1)->IntegerValue();
563 m_g
= (unsigned char)expr
->Nth(2)->IntegerValue();
564 m_b
= (unsigned char)expr
->Nth(3)->IntegerValue();
567 case DRAWOP_SET_BK_MODE
:
569 m_mode
= (int)expr
->Nth(1)->IntegerValue();
579 * Set/destroy clipping
583 wxOpSetClipping::wxOpSetClipping(int theOp
, double theX1
, double theY1
,
584 double theX2
, double theY2
):wxDrawOp(theOp
)
592 wxDrawOp
*wxOpSetClipping::Copy(wxPseudoMetaFile
*WXUNUSED(newImage
))
594 wxOpSetClipping
*newOp
= new wxOpSetClipping(m_op
, m_x1
, m_y1
, m_x2
, m_y2
);
598 void wxOpSetClipping::Do(wxDC
& dc
, double xoffset
, double yoffset
)
602 case DRAWOP_SET_CLIPPING_RECT
:
604 dc
.SetClippingRegion((long)(m_x1
+ xoffset
), (long)(m_y1
+ yoffset
), (long)(m_x2
+ xoffset
), (long)(m_y2
+ yoffset
));
607 case DRAWOP_DESTROY_CLIPPING_RECT
:
609 dc
.DestroyClippingRegion();
617 void wxOpSetClipping::Scale(double xScale
, double yScale
)
625 void wxOpSetClipping::Translate(double x
, double y
)
632 wxExpr
*wxOpSetClipping::WriteExpr(wxPseudoMetaFile
*WXUNUSED(image
))
634 wxExpr
*expr
= new wxExpr(wxExprList
);
635 expr
->Append(new wxExpr((long)m_op
));
638 case DRAWOP_SET_CLIPPING_RECT
:
640 expr
->Append(new wxExpr(m_x1
));
641 expr
->Append(new wxExpr(m_y1
));
642 expr
->Append(new wxExpr(m_x2
));
643 expr
->Append(new wxExpr(m_y2
));
652 void wxOpSetClipping::ReadExpr(wxPseudoMetaFile
*WXUNUSED(image
), wxExpr
*expr
)
656 case DRAWOP_SET_CLIPPING_RECT
:
658 m_x1
= expr
->Nth(1)->RealValue();
659 m_y1
= expr
->Nth(2)->RealValue();
660 m_x2
= expr
->Nth(3)->RealValue();
661 m_y2
= expr
->Nth(4)->RealValue();
671 * Draw line, rectangle, rounded rectangle, ellipse, point, arc, text
675 wxOpDraw::wxOpDraw(int theOp
, double theX1
, double theY1
, double theX2
, double theY2
,
676 double theRadius
, const wxString
& s
) : wxDrawOp(theOp
)
684 m_radius
= theRadius
;
688 wxOpDraw::~wxOpDraw()
692 wxDrawOp
*wxOpDraw::Copy(wxPseudoMetaFile
*WXUNUSED(newImage
))
694 wxOpDraw
*newOp
= new wxOpDraw(m_op
, m_x1
, m_y1
, m_x2
, m_y2
, m_radius
, m_textString
);
700 void wxOpDraw::Do(wxDC
& dc
, double xoffset
, double yoffset
)
704 case DRAWOP_DRAW_LINE
:
706 dc
.DrawLine(WXROUND(m_x1
+xoffset
), WXROUND(m_y1
+yoffset
), WXROUND(m_x2
+xoffset
), WXROUND(m_y2
+yoffset
));
709 case DRAWOP_DRAW_RECT
:
711 dc
.DrawRectangle(WXROUND(m_x1
+xoffset
), WXROUND(m_y1
+yoffset
), WXROUND(m_x2
), WXROUND(m_y2
));
714 case DRAWOP_DRAW_ROUNDED_RECT
:
716 dc
.DrawRoundedRectangle(WXROUND(m_x1
+xoffset
), WXROUND(m_y1
+yoffset
), WXROUND(m_x2
), WXROUND(m_y2
), m_radius
);
719 case DRAWOP_DRAW_ELLIPSE
:
721 dc
.DrawEllipse(WXROUND(m_x1
+xoffset
), WXROUND(m_y1
+yoffset
), WXROUND(m_x2
), WXROUND(m_y2
));
724 case DRAWOP_DRAW_ARC
:
726 dc
.DrawArc(WXROUND(m_x2
+xoffset
), WXROUND(m_y2
+yoffset
),
727 WXROUND(m_x3
+xoffset
), WXROUND(m_y3
+yoffset
),
728 WXROUND(m_x1
+xoffset
), WXROUND(m_y1
+yoffset
));
731 case DRAWOP_DRAW_ELLIPTIC_ARC
:
733 const double pi
= M_PI
;
735 // Convert back to degrees
737 WXROUND(m_x1
+xoffset
), WXROUND(m_y1
+yoffset
),
738 WXROUND(m_x2
), WXROUND(m_y2
),
739 WXROUND(m_x3
*(360.0/(2.0*pi
))), WXROUND(m_y3
*(360.0/(2.0*pi
))));
742 case DRAWOP_DRAW_POINT
:
744 dc
.DrawPoint(WXROUND(m_x1
+xoffset
), WXROUND(m_y1
+yoffset
));
747 case DRAWOP_DRAW_TEXT
:
749 dc
.DrawText(m_textString
, WXROUND(m_x1
+xoffset
), WXROUND(m_y1
+yoffset
));
757 void wxOpDraw::Scale(double scaleX
, double scaleY
)
764 if (m_op
!= DRAWOP_DRAW_ELLIPTIC_ARC
)
773 void wxOpDraw::Translate(double x
, double y
)
780 case DRAWOP_DRAW_LINE
:
786 case DRAWOP_DRAW_ARC
:
794 case DRAWOP_DRAW_ELLIPTIC_ARC
:
803 void wxOpDraw::Rotate(double x
, double y
, double theta
, double sinTheta
, double cosTheta
)
805 double newX1
= m_x1
*cosTheta
- m_y1
*sinTheta
+ x
*(1.0 - cosTheta
) + y
*sinTheta
;
806 double newY1
= m_x1
*sinTheta
+ m_y1
*cosTheta
+ y
*(1.0 - cosTheta
) + x
*sinTheta
;
810 case DRAWOP_DRAW_LINE
:
812 double newX2
= m_x2
*cosTheta
- m_y2
*sinTheta
+ x
*(1.0 - cosTheta
) + y
*sinTheta
;
813 double newY2
= m_x2
*sinTheta
+ m_y2
*cosTheta
+ y
*(1.0 - cosTheta
) + x
*sinTheta
;
821 case DRAWOP_DRAW_RECT
:
822 case DRAWOP_DRAW_ROUNDED_RECT
:
823 case DRAWOP_DRAW_ELLIPTIC_ARC
:
825 // Assume only 0, 90, 180, 270 degree rotations.
826 // oldX1, oldY1 represents the top left corner. Find the
827 // bottom right, and rotate that. Then the width/height is the difference
828 // between x/y values.
829 double oldBottomRightX
= m_x1
+ m_x2
;
830 double oldBottomRightY
= m_y1
+ m_y2
;
831 double newBottomRightX
= oldBottomRightX
*cosTheta
- oldBottomRightY
*sinTheta
+ x
*(1.0 - cosTheta
) + y
*sinTheta
;
832 double newBottomRightY
= oldBottomRightX
*sinTheta
+ oldBottomRightY
*cosTheta
+ y
*(1.0 - cosTheta
) + x
*sinTheta
;
834 // Now find the new top-left, bottom-right coordinates.
835 double minX
= wxMin(newX1
, newBottomRightX
);
836 double minY
= wxMin(newY1
, newBottomRightY
);
837 double maxX
= wxMax(newX1
, newBottomRightX
);
838 double maxY
= wxMax(newY1
, newBottomRightY
);
842 m_x2
= maxX
- minX
; // width
843 m_y2
= maxY
- minY
; // height
845 if (m_op
== DRAWOP_DRAW_ELLIPTIC_ARC
)
847 // Add rotation to angles
854 case DRAWOP_DRAW_ARC
:
856 double newX2
= m_x2
*cosTheta
- m_y2
*sinTheta
+ x
*(1.0 - cosTheta
) + y
*sinTheta
;
857 double newY2
= m_x2
*sinTheta
+ m_y2
*cosTheta
+ y
*(1.0 - cosTheta
) + x
*sinTheta
;
858 double newX3
= m_x3
*cosTheta
- m_y3
*sinTheta
+ x
*(1.0 - cosTheta
) + y
*sinTheta
;
859 double newY3
= m_x3
*sinTheta
+ m_y3
*cosTheta
+ y
*(1.0 - cosTheta
) + x
*sinTheta
;
876 wxExpr
*wxOpDraw::WriteExpr(wxPseudoMetaFile
*WXUNUSED(image
))
878 wxExpr
*expr
= new wxExpr(wxExprList
);
879 expr
->Append(new wxExpr((long)m_op
));
882 case DRAWOP_DRAW_LINE
:
883 case DRAWOP_DRAW_RECT
:
884 case DRAWOP_DRAW_ELLIPSE
:
886 expr
->Append(new wxExpr(m_x1
));
887 expr
->Append(new wxExpr(m_y1
));
888 expr
->Append(new wxExpr(m_x2
));
889 expr
->Append(new wxExpr(m_y2
));
892 case DRAWOP_DRAW_ROUNDED_RECT
:
894 expr
->Append(new wxExpr(m_x1
));
895 expr
->Append(new wxExpr(m_y1
));
896 expr
->Append(new wxExpr(m_x2
));
897 expr
->Append(new wxExpr(m_y2
));
898 expr
->Append(new wxExpr(m_radius
));
901 case DRAWOP_DRAW_POINT
:
903 expr
->Append(new wxExpr(m_x1
));
904 expr
->Append(new wxExpr(m_y1
));
907 case DRAWOP_DRAW_TEXT
:
909 expr
->Append(new wxExpr(m_x1
));
910 expr
->Append(new wxExpr(m_y1
));
911 expr
->Append(new wxExpr(wxExprString
, m_textString
));
914 case DRAWOP_DRAW_ARC
:
915 case DRAWOP_DRAW_ELLIPTIC_ARC
:
917 expr
->Append(new wxExpr(m_x1
));
918 expr
->Append(new wxExpr(m_y1
));
919 expr
->Append(new wxExpr(m_x2
));
920 expr
->Append(new wxExpr(m_y2
));
921 expr
->Append(new wxExpr(m_x3
));
922 expr
->Append(new wxExpr(m_y3
));
933 void wxOpDraw::ReadExpr(wxPseudoMetaFile
*WXUNUSED(image
), wxExpr
*expr
)
937 case DRAWOP_DRAW_LINE
:
938 case DRAWOP_DRAW_RECT
:
939 case DRAWOP_DRAW_ELLIPSE
:
941 m_x1
= expr
->Nth(1)->RealValue();
942 m_y1
= expr
->Nth(2)->RealValue();
943 m_x2
= expr
->Nth(3)->RealValue();
944 m_y2
= expr
->Nth(4)->RealValue();
947 case DRAWOP_DRAW_ROUNDED_RECT
:
949 m_x1
= expr
->Nth(1)->RealValue();
950 m_y1
= expr
->Nth(2)->RealValue();
951 m_x2
= expr
->Nth(3)->RealValue();
952 m_y2
= expr
->Nth(4)->RealValue();
953 m_radius
= expr
->Nth(5)->RealValue();
956 case DRAWOP_DRAW_POINT
:
958 m_x1
= expr
->Nth(1)->RealValue();
959 m_y1
= expr
->Nth(2)->RealValue();
962 case DRAWOP_DRAW_TEXT
:
964 m_x1
= expr
->Nth(1)->RealValue();
965 m_y1
= expr
->Nth(2)->RealValue();
966 m_textString
= wxString(expr
->Nth(3)->StringValue());
969 case DRAWOP_DRAW_ARC
:
970 case DRAWOP_DRAW_ELLIPTIC_ARC
:
972 m_x1
= expr
->Nth(1)->RealValue();
973 m_y1
= expr
->Nth(2)->RealValue();
974 m_x2
= expr
->Nth(3)->RealValue();
975 m_y2
= expr
->Nth(4)->RealValue();
976 m_x3
= expr
->Nth(5)->RealValue();
977 m_y3
= expr
->Nth(6)->RealValue();
989 * Draw polygon, polyline, spline
993 wxOpPolyDraw::wxOpPolyDraw(int theOp
, int n
, wxRealPoint
*thePoints
):wxDrawOp(theOp
)
996 m_points
= thePoints
;
999 wxOpPolyDraw::~wxOpPolyDraw()
1004 wxDrawOp
*wxOpPolyDraw::Copy(wxPseudoMetaFile
*WXUNUSED(newImage
))
1006 wxRealPoint
*newPoints
= new wxRealPoint
[m_noPoints
];
1007 for (int i
= 0; i
< m_noPoints
; i
++)
1009 newPoints
[i
].x
= m_points
[i
].x
;
1010 newPoints
[i
].y
= m_points
[i
].y
;
1012 wxOpPolyDraw
*newOp
= new wxOpPolyDraw(m_op
, m_noPoints
, newPoints
);
1016 void wxOpPolyDraw::Do(wxDC
& dc
, double xoffset
, double yoffset
)
1020 case DRAWOP_DRAW_POLYLINE
:
1022 wxPoint
*actualPoints
= new wxPoint
[m_noPoints
];
1024 for (i
= 0; i
< m_noPoints
; i
++)
1026 actualPoints
[i
].x
= WXROUND(m_points
[i
].x
);
1027 actualPoints
[i
].y
= WXROUND(m_points
[i
].y
);
1030 dc
.DrawLines(m_noPoints
, actualPoints
, WXROUND(xoffset
), WXROUND(yoffset
));
1032 delete[] actualPoints
;
1035 case DRAWOP_DRAW_POLYGON
:
1037 wxPoint
*actualPoints
= new wxPoint
[m_noPoints
];
1039 for (i
= 0; i
< m_noPoints
; i
++)
1041 actualPoints
[i
].x
= WXROUND(m_points
[i
].x
);
1042 actualPoints
[i
].y
= WXROUND(m_points
[i
].y
);
1045 dc
.DrawPolygon(m_noPoints
, actualPoints
, WXROUND(xoffset
), WXROUND(yoffset
));
1047 delete[] actualPoints
;
1050 case DRAWOP_DRAW_SPLINE
:
1052 wxPoint
*actualPoints
= new wxPoint
[m_noPoints
];
1054 for (i
= 0; i
< m_noPoints
; i
++)
1056 actualPoints
[i
].x
= WXROUND(m_points
[i
].x
);
1057 actualPoints
[i
].y
= WXROUND(m_points
[i
].y
);
1060 dc
.DrawSpline(m_noPoints
, actualPoints
); // no offsets in DrawSpline // , xoffset, yoffset);
1062 delete[] actualPoints
;
1070 void wxOpPolyDraw::Scale(double scaleX
, double scaleY
)
1072 for (int i
= 0; i
< m_noPoints
; i
++)
1074 m_points
[i
].x
*= scaleX
;
1075 m_points
[i
].y
*= scaleY
;
1079 void wxOpPolyDraw::Translate(double x
, double y
)
1081 for (int i
= 0; i
< m_noPoints
; i
++)
1088 void wxOpPolyDraw::Rotate(double x
, double y
, double WXUNUSED(theta
), double sinTheta
, double cosTheta
)
1090 for (int i
= 0; i
< m_noPoints
; i
++)
1092 double x1
= m_points
[i
].x
;
1093 double y1
= m_points
[i
].y
;
1094 m_points
[i
].x
= x1
*cosTheta
- y1
*sinTheta
+ x
*(1.0 - cosTheta
) + y
*sinTheta
;
1095 m_points
[i
].y
= x1
*sinTheta
+ y1
*cosTheta
+ y
*(1.0 - cosTheta
) + x
*sinTheta
;
1100 wxExpr
*wxOpPolyDraw::WriteExpr(wxPseudoMetaFile
*WXUNUSED(image
))
1102 wxExpr
*expr
= new wxExpr(wxExprList
);
1103 expr
->Append(new wxExpr((long)m_op
));
1104 expr
->Append(new wxExpr((long)m_noPoints
));
1113 * Store each coordinate pair in a hex string to save space.
1114 * E.g. "1B9080CD". 4 hex digits per coordinate pair.
1118 for (int i
= 0; i
< m_noPoints
; i
++)
1120 long signedX
= (long)(m_points
[i
].x
*100.0);
1121 long signedY
= (long)(m_points
[i
].y
*100.0);
1123 // Scale to 0 -> 64K
1124 long unSignedX
= (long)(signedX
+ 32767.0);
1125 long unSignedY
= (long)(signedY
+ 32767.0);
1127 // IntToHex((unsigned int)signedX, buf2);
1128 // IntToHex((unsigned int)signedY, buf3);
1129 IntToHex((int)unSignedX
, buf2
);
1130 IntToHex((int)unSignedY
, buf3
);
1132 // Don't overrun the buffer
1135 wxStrcat(oglBuffer
, buf2
);
1136 wxStrcat(oglBuffer
, buf3
);
1139 expr
->Append(new wxExpr(wxExprString
, oglBuffer
));
1143 void wxOpPolyDraw::ReadExpr(wxPseudoMetaFile
*WXUNUSED(image
), wxExpr
*expr
)
1145 m_noPoints
= (int)expr
->Nth(1)->IntegerValue();
1150 m_points
= new wxRealPoint
[m_noPoints
];
1153 wxString hexString
= expr
->Nth(2)->StringValue();
1154 while (i
< m_noPoints
)
1156 buf1
[0] = hexString
[(size_t)bufPtr
];
1157 buf1
[1] = hexString
[(size_t)(bufPtr
+ 1)];
1158 buf1
[2] = hexString
[(size_t)(bufPtr
+ 2)];
1159 buf1
[3] = hexString
[(size_t)(bufPtr
+ 3)];
1162 buf2
[0] = hexString
[(size_t)(bufPtr
+ 4)];
1163 buf2
[1] = hexString
[(size_t)(bufPtr
+ 5)];
1164 buf2
[2] = hexString
[(size_t)(bufPtr
+ 6)];
1165 buf2
[3] = hexString
[(size_t)(bufPtr
+ 7)];
1170 // int signedX = (signed int)HexToInt(buf1);
1171 // int signedY = (signed int)HexToInt(buf2);
1172 long unSignedX
= HexToInt(buf1
);
1173 long unSignedY
= HexToInt(buf2
);
1174 // Scale -32K -> +32K
1175 long signedX
= unSignedX
- 32767;
1176 long signedY
= unSignedY
- 32767;
1177 #if defined(__WXMSW__) && 0
1178 int testX
= (signed int)unSignedX
;
1179 int testY
= (signed int)unSignedY
;
1182 m_points
[i
].x
= (double)(signedX
/ 100.0);
1183 m_points
[i
].y
= (double)(signedY
/ 100.0);
1190 // Draw an outline using the current operation.
1191 bool wxOpPolyDraw::OnDrawOutline(wxDC
& dc
, double x
, double y
, double w
, double h
, double oldW
, double oldH
)
1193 dc
.SetBrush(* wxTRANSPARENT_BRUSH
);
1195 // Multiply all points by proportion of new size to old size
1196 double x_proportion
= (double)(fabs(w
/oldW
));
1197 double y_proportion
= (double)(fabs(h
/oldH
));
1200 wxPoint
*intPoints
= new wxPoint
[n
];
1202 for (i
= 0; i
< n
; i
++)
1204 intPoints
[i
].x
= WXROUND (x_proportion
* m_points
[i
].x
);
1205 intPoints
[i
].y
= WXROUND (y_proportion
* m_points
[i
].y
);
1207 dc
.DrawPolygon(n
, intPoints
, (long) x
, (long) y
);
1212 // Assume (x1, y1) is centre of box (most generally, line end at box)
1213 bool wxOpPolyDraw::GetPerimeterPoint(double x1
, double y1
,
1214 double x2
, double y2
,
1215 double *x3
, double *y3
,
1216 double xOffset
, double yOffset
,
1221 // First check for situation where the line is vertical,
1222 // and we would want to connect to a point on that vertical --
1223 // oglFindEndForPolyline can't cope with this (the arrow
1224 // gets drawn to the wrong place).
1225 if ((attachmentMode
== ATTACHMENT_MODE_NONE
) && (x1
== x2
))
1227 // Look for the point we'd be connecting to. This is
1230 for (i
= 0; i
< n
; i
++)
1232 wxRealPoint
*point
= & (m_points
[i
]);
1233 if (point
->x
== 0.0)
1235 if ((y2
> y1
) && (point
->y
> 0.0))
1237 *x3
= point
->x
+ xOffset
;
1238 *y3
= point
->y
+ yOffset
;
1241 else if ((y2
< y1
) && (point
->y
< 0.0))
1243 *x3
= point
->x
+ xOffset
;
1244 *y3
= point
->y
+ yOffset
;
1251 double *xpoints
= new double[n
];
1252 double *ypoints
= new double[n
];
1254 for (int i
= 0; i
< n
; i
++)
1256 wxRealPoint
*point
= & (m_points
[i
]);
1257 xpoints
[i
] = point
->x
+ xOffset
;
1258 ypoints
[i
] = point
->y
+ yOffset
;
1261 oglFindEndForPolyline(n
, xpoints
, ypoints
,
1262 x1
, y1
, x2
, y2
, x3
, y3
);
1276 static char hexArray
[] = {
1277 _T('0'), _T('1'), _T('2'), _T('3'), _T('4'), _T('5'), _T('6'), _T('7'),
1278 _T('8'), _T('9'), _T('A'), _T('B'), _T('C'), _T('D'), _T('E'), _T('F') };
1280 // Convert unsigned 16-bit integer to 4-character hex string
1281 static void IntToHex(unsigned int dec
, wxChar
*buf
)
1283 int digit1
= (int)(dec
/4096);
1284 int digit2
= (int)((dec
- (digit1
*4096))/256);
1285 int digit3
= (int)((dec
- (digit1
*4096) - (digit2
*256))/16);
1286 int digit4
= dec
- (digit1
*4096 + digit2
*256 + digit3
*16);
1288 buf
[0] = hexArray
[digit1
];
1289 buf
[1] = hexArray
[digit2
];
1290 buf
[2] = hexArray
[digit3
];
1291 buf
[3] = hexArray
[digit4
];
1295 // One hex digit to decimal number
1296 static int HexToInt1(wxChar hex
)
1337 // 4-digit hex string to unsigned integer
1338 static unsigned long HexToInt(wxChar
*buf
)
1340 long d1
= (long)(HexToInt1(buf
[0])*4096.0) ;
1341 long d2
= (long)(HexToInt1(buf
[1])*256.0) ;
1342 long d3
= (long)(HexToInt1(buf
[2])*16.0) ;
1343 long d4
= (long)(HexToInt1(buf
[3])) ;
1344 unsigned long n
= (long)(d1
+ d2
+ d3
+ d4
) ;
1349 * wxPseudo meta-file
1353 IMPLEMENT_DYNAMIC_CLASS(wxPseudoMetaFile
, wxObject
)
1355 wxPseudoMetaFile::wxPseudoMetaFile()
1357 m_currentRotation
= 0;
1358 m_rotateable
= true;
1361 m_outlinePen
= NULL
;
1366 wxPseudoMetaFile::wxPseudoMetaFile(wxPseudoMetaFile
& mf
):wxObject()
1371 wxPseudoMetaFile::~wxPseudoMetaFile()
1376 void wxPseudoMetaFile::Clear()
1378 wxNode
*node
= m_ops
.GetFirst();
1381 wxDrawOp
*op
= (wxDrawOp
*)node
->GetData();
1383 node
= node
->GetNext();
1386 m_gdiObjects
.Clear();
1387 m_outlineColours
.Clear();
1388 m_fillColours
.Clear();
1392 void wxPseudoMetaFile::Draw(wxDC
& dc
, double xoffset
, double yoffset
)
1394 wxNode
*node
= m_ops
.GetFirst();
1397 wxDrawOp
*op
= (wxDrawOp
*)node
->GetData();
1398 op
->Do(dc
, xoffset
, yoffset
);
1399 node
= node
->GetNext();
1403 void wxPseudoMetaFile::Scale(double sx
, double sy
)
1405 wxNode
*node
= m_ops
.GetFirst();
1408 wxDrawOp
*op
= (wxDrawOp
*)node
->GetData();
1410 node
= node
->GetNext();
1416 void wxPseudoMetaFile::Translate(double x
, double y
)
1418 wxNode
*node
= m_ops
.GetFirst();
1421 wxDrawOp
*op
= (wxDrawOp
*)node
->GetData();
1422 op
->Translate(x
, y
);
1423 node
= node
->GetNext();
1427 void wxPseudoMetaFile::Rotate(double x
, double y
, double theta
)
1429 double theta1
= theta
-m_currentRotation
;
1430 if (theta1
== 0.0) return;
1431 double cosTheta
= (double)cos(theta1
);
1432 double sinTheta
= (double)sin(theta1
);
1434 wxNode
*node
= m_ops
.GetFirst();
1437 wxDrawOp
*op
= (wxDrawOp
*)node
->GetData();
1438 op
->Rotate(x
, y
, theta
, sinTheta
, cosTheta
);
1439 node
= node
->GetNext();
1441 m_currentRotation
= theta
;
1445 void wxPseudoMetaFile::WriteAttributes(wxExpr
*clause
, int whichAngle
)
1448 widthStr
.Printf(wxT("meta_width%d"), whichAngle
);
1451 heightStr
.Printf(wxT("meta_height%d"), whichAngle
);
1453 wxString outlineStr
;
1454 outlineStr
.Printf(wxT("outline_op%d"), whichAngle
);
1456 wxString rotateableStr
;
1457 rotateableStr
.Printf(wxT("meta_rotateable%d"), whichAngle
);
1459 // Write width and height
1460 clause
->AddAttributeValue(widthStr
, m_width
);
1461 clause
->AddAttributeValue(heightStr
, m_height
);
1462 clause
->AddAttributeValue(rotateableStr
, (long)m_rotateable
);
1463 clause
->AddAttributeValue(outlineStr
, (long)m_outlineOp
);
1465 // Write GDI objects
1468 wxNode
*node
= m_gdiObjects
.GetFirst();
1471 wxSprintf(buf
, _T("gdi%d_%d"), whichAngle
, i
);
1472 wxObject
*obj
= (wxObject
*)node
->GetData();
1473 wxExpr
*expr
= NULL
;
1476 if (obj
->IsKindOf(CLASSINFO(wxPen
)))
1478 wxPen
*thePen
= (wxPen
*)obj
;
1479 expr
= new wxExpr(wxExprList
);
1480 expr
->Append(new wxExpr((long)gyTYPE_PEN
));
1481 expr
->Append(new wxExpr((long)thePen
->GetWidth()));
1482 expr
->Append(new wxExpr((long)thePen
->GetStyle()));
1483 expr
->Append(new wxExpr((long)thePen
->GetColour().Red()));
1484 expr
->Append(new wxExpr((long)thePen
->GetColour().Green()));
1485 expr
->Append(new wxExpr((long)thePen
->GetColour().Blue()));
1487 else if (obj
->IsKindOf(CLASSINFO(wxBrush
)))
1489 wxBrush
*theBrush
= (wxBrush
*)obj
;
1490 expr
= new wxExpr(wxExprList
);
1491 expr
->Append(new wxExpr((long)gyTYPE_BRUSH
));
1492 expr
->Append(new wxExpr((long)theBrush
->GetStyle()));
1493 expr
->Append(new wxExpr((long)theBrush
->GetColour().Red()));
1494 expr
->Append(new wxExpr((long)theBrush
->GetColour().Green()));
1495 expr
->Append(new wxExpr((long)theBrush
->GetColour().Blue()));
1497 else if (obj
->IsKindOf(CLASSINFO(wxFont
)))
1499 wxFont
*theFont
= (wxFont
*)obj
;
1500 expr
= new wxExpr(wxExprList
);
1501 expr
->Append(new wxExpr((long)gyTYPE_FONT
));
1502 expr
->Append(new wxExpr((long)theFont
->GetPointSize()));
1503 expr
->Append(new wxExpr((long)theFont
->GetFamily()));
1504 expr
->Append(new wxExpr((long)theFont
->GetStyle()));
1505 expr
->Append(new wxExpr((long)theFont
->GetWeight()));
1506 expr
->Append(new wxExpr((long)theFont
->GetUnderlined()));
1511 // If no recognised GDI object, append a place holder anyway.
1512 expr
= new wxExpr(wxExprList
);
1513 expr
->Append(new wxExpr((long)0));
1518 clause
->AddAttributeValue(buf
, expr
);
1521 node
= node
->GetNext();
1524 // Write drawing operations
1526 node
= m_ops
.GetFirst();
1529 wxSprintf(buf
, _T("op%d_%d"), whichAngle
, i
);
1530 wxDrawOp
*op
= (wxDrawOp
*)node
->GetData();
1531 wxExpr
*expr
= op
->WriteExpr(this);
1534 clause
->AddAttributeValue(buf
, expr
);
1537 node
= node
->GetNext();
1540 // Write outline and fill GDI op lists (if any)
1541 if (m_outlineColours
.GetCount() > 0)
1543 wxExpr
*outlineExpr
= new wxExpr(wxExprList
);
1544 node
= m_outlineColours
.GetFirst();
1547 outlineExpr
->Append(new wxExpr((long)node
->GetData()));
1548 node
= node
->GetNext();
1550 wxString outlineObjectsStr
;
1551 outlineObjectsStr
.Printf(wxT("outline_objects%d"), whichAngle
);
1553 clause
->AddAttributeValue(outlineObjectsStr
, outlineExpr
);
1555 if (m_fillColours
.GetCount() > 0)
1557 wxExpr
*fillExpr
= new wxExpr(wxExprList
);
1558 node
= m_fillColours
.GetFirst();
1561 fillExpr
->Append(new wxExpr((long)node
->GetData()));
1562 node
= node
->GetNext();
1564 wxString fillObjectsStr
;
1565 fillObjectsStr
.Printf(wxT("fill_objects%d"), whichAngle
);
1567 clause
->AddAttributeValue(fillObjectsStr
, fillExpr
);
1572 void wxPseudoMetaFile::ReadAttributes(wxExpr
*clause
, int whichAngle
)
1575 widthStr
.Printf(wxT("meta_width%d"), whichAngle
);
1578 heightStr
.Printf(wxT("meta_height%d"), whichAngle
);
1580 wxString outlineStr
;
1581 outlineStr
.Printf(wxT("outline_op%d"), whichAngle
);
1583 wxString rotateableStr
;
1584 rotateableStr
.Printf(wxT("meta_rotateable%d"), whichAngle
);
1586 clause
->GetAttributeValue(widthStr
, m_width
);
1587 clause
->GetAttributeValue(heightStr
, m_height
);
1588 clause
->GetAttributeValue(outlineStr
, m_outlineOp
);
1590 int iVal
= (int) m_rotateable
;
1591 clause
->GetAttributeValue(rotateableStr
, iVal
);
1592 m_rotateable
= (iVal
!= 0);
1597 bool keepGoing
= true;
1600 wxSprintf(buf
, _T("gdi%d_%d"), whichAngle
, i
);
1601 wxExpr
*expr
= NULL
;
1602 clause
->GetAttributeValue(buf
, &expr
);
1609 wxExpr
*idExpr
= expr
->Nth(0);
1610 switch (idExpr
->IntegerValue())
1614 int penWidth
= (int)expr
->Nth(1)->IntegerValue();
1615 int penStyle
= (int)expr
->Nth(2)->IntegerValue();
1616 unsigned char penRed
= (unsigned char)expr
->Nth(3)->IntegerValue();
1617 unsigned char penGreen
= (unsigned char)expr
->Nth(4)->IntegerValue();
1618 unsigned char penBlue
= (unsigned char)expr
->Nth(5)->IntegerValue();
1619 wxColour
col(penRed
, penGreen
, penBlue
);
1620 wxPen
*p
= wxThePenList
->FindOrCreatePen(col
, penWidth
, penStyle
);
1623 m_gdiObjects
.Append(p
);
1628 int brushStyle
= (int)expr
->Nth(1)->IntegerValue();
1629 unsigned char brushRed
= (unsigned char)expr
->Nth(2)->IntegerValue();
1630 unsigned char brushGreen
= (unsigned char)expr
->Nth(3)->IntegerValue();
1631 unsigned char brushBlue
= (unsigned char)expr
->Nth(4)->IntegerValue();
1632 wxColour
col(brushRed
, brushGreen
, brushBlue
);
1633 wxBrush
*b
= wxTheBrushList
->FindOrCreateBrush(col
, brushStyle
);
1636 m_gdiObjects
.Append(b
);
1641 int fontPointSize
= (int)expr
->Nth(1)->IntegerValue();
1642 int fontFamily
= (int)expr
->Nth(2)->IntegerValue();
1643 int fontStyle
= (int)expr
->Nth(3)->IntegerValue();
1644 int fontWeight
= (int)expr
->Nth(4)->IntegerValue();
1645 int fontUnderlined
= (int)expr
->Nth(5)->IntegerValue();
1646 m_gdiObjects
.Append(wxTheFontList
->FindOrCreateFont(fontPointSize
,
1647 fontFamily
, fontStyle
, fontWeight
, (fontUnderlined
!= 0)));
1653 m_gdiObjects
.Append(NULL
);
1661 // Now read in the operations
1666 wxSprintf(buf
, _T("op%d_%d"), whichAngle
, i
);
1667 wxExpr
*expr
= NULL
;
1668 clause
->GetAttributeValue(buf
, &expr
);
1675 wxExpr
*idExpr
= expr
->Nth(0);
1676 int opId
= (int)idExpr
->IntegerValue();
1679 case DRAWOP_SET_PEN
:
1680 case DRAWOP_SET_BRUSH
:
1681 case DRAWOP_SET_FONT
:
1682 case DRAWOP_SET_TEXT_COLOUR
:
1683 case DRAWOP_SET_BK_COLOUR
:
1684 case DRAWOP_SET_BK_MODE
:
1686 wxOpSetGDI
*theOp
= new wxOpSetGDI(opId
, this, 0);
1687 theOp
->ReadExpr(this, expr
);
1688 m_ops
.Append(theOp
);
1692 case DRAWOP_SET_CLIPPING_RECT
:
1693 case DRAWOP_DESTROY_CLIPPING_RECT
:
1695 wxOpSetClipping
*theOp
= new wxOpSetClipping(opId
, 0.0, 0.0, 0.0, 0.0);
1696 theOp
->ReadExpr(this, expr
);
1697 m_ops
.Append(theOp
);
1701 case DRAWOP_DRAW_LINE
:
1702 case DRAWOP_DRAW_RECT
:
1703 case DRAWOP_DRAW_ROUNDED_RECT
:
1704 case DRAWOP_DRAW_ELLIPSE
:
1705 case DRAWOP_DRAW_POINT
:
1706 case DRAWOP_DRAW_ARC
:
1707 case DRAWOP_DRAW_TEXT
:
1709 wxOpDraw
*theOp
= new wxOpDraw(opId
, 0.0, 0.0, 0.0, 0.0);
1710 theOp
->ReadExpr(this, expr
);
1711 m_ops
.Append(theOp
);
1714 case DRAWOP_DRAW_SPLINE
:
1715 case DRAWOP_DRAW_POLYLINE
:
1716 case DRAWOP_DRAW_POLYGON
:
1718 wxOpPolyDraw
*theOp
= new wxOpPolyDraw(opId
, 0, NULL
);
1719 theOp
->ReadExpr(this, expr
);
1720 m_ops
.Append(theOp
);
1730 wxString outlineObjectsStr
;
1731 outlineObjectsStr
.Printf(wxT("outline_objects%d"), whichAngle
);
1733 // Now read in the list of outline and fill operations, if any
1734 wxExpr
*expr1
= clause
->AttributeValue(outlineObjectsStr
);
1737 wxExpr
*eachExpr
= expr1
->GetFirst();
1740 m_outlineColours
.Append((wxObject
*)eachExpr
->IntegerValue());
1741 eachExpr
= eachExpr
->GetNext();
1745 wxString fillObjectsStr
;
1746 fillObjectsStr
.Printf(wxT("fill_objects%d"), whichAngle
);
1748 expr1
= clause
->AttributeValue(fillObjectsStr
);
1751 wxExpr
*eachExpr
= expr1
->GetFirst();
1754 m_fillColours
.Append((wxObject
*)eachExpr
->IntegerValue());
1755 eachExpr
= eachExpr
->GetNext();
1761 // Does the copying for this object
1762 void wxPseudoMetaFile::Copy(wxPseudoMetaFile
& copy
)
1766 copy
.m_currentRotation
= m_currentRotation
;
1767 copy
.m_width
= m_width
;
1768 copy
.m_height
= m_height
;
1769 copy
.m_rotateable
= m_rotateable
;
1770 copy
.m_fillBrush
= m_fillBrush
;
1771 copy
.m_outlinePen
= m_outlinePen
;
1772 copy
.m_outlineOp
= m_outlineOp
;
1774 // Copy the GDI objects
1775 wxNode
*node
= m_gdiObjects
.GetFirst();
1778 wxObject
*obj
= (wxObject
*)node
->GetData();
1779 copy
.m_gdiObjects
.Append(obj
);
1780 node
= node
->GetNext();
1783 // Copy the operations
1784 node
= m_ops
.GetFirst();
1787 wxDrawOp
*op
= (wxDrawOp
*)node
->GetData();
1788 copy
.m_ops
.Append(op
->Copy(©
));
1789 node
= node
->GetNext();
1792 // Copy the outline/fill operations
1793 node
= m_outlineColours
.GetFirst();
1796 copy
.m_outlineColours
.Append((wxObject
*)node
->GetData());
1797 node
= node
->GetNext();
1799 node
= m_fillColours
.GetFirst();
1802 copy
.m_fillColours
.Append((wxObject
*)node
->GetData());
1803 node
= node
->GetNext();
1808 * Pass size of existing image; scale height to
1809 * fit width and return new width and height.
1813 bool wxPseudoMetaFile::LoadFromMetaFile(const wxString
& filename
, double *rwidth
, double *rheight
)
1815 if (!wxFileExists(filename
))
1818 wxXMetaFile
*metaFile
= new wxXMetaFile
;
1820 if (!metaFile
->ReadFile(filename
))
1829 // Convert from metafile records to wxDrawnShape records
1830 wxNode
*node
= metaFile
->metaRecords
.GetFirst();
1833 wxMetaRecord
*record
= (wxMetaRecord
*)node
->GetData();
1834 switch (record
->metaFunction
)
1836 case META_SETBKCOLOR
:
1838 wxOpSetGDI
*op
= new wxOpSetGDI(DRAWOP_SET_BK_COLOUR
, this, 0);
1839 op
->m_r
= (unsigned char)record
->param1
;
1840 op
->m_g
= (unsigned char)record
->param2
;
1841 op
->m_b
= (unsigned char)record
->param3
;
1845 case META_SETBKMODE
:
1847 wxOpSetGDI
*op
= new wxOpSetGDI(DRAWOP_SET_BK_MODE
, this, 0, (int)record
->param1
);
1851 case META_SETMAPMODE
:
1855 // case META_SETROP2:
1856 // case META_SETRELABS:
1857 // case META_SETPOLYFILLMODE:
1858 // case META_SETSTRETCHBLTMODE:
1859 // case META_SETTEXTCHAREXTRA:
1860 case META_SETTEXTCOLOR
:
1862 wxOpSetGDI
*op
= new wxOpSetGDI(DRAWOP_SET_TEXT_COLOUR
, this, 0);
1863 op
->m_r
= (unsigned char)record
->param1
;
1864 op
->m_g
= (unsigned char)record
->param2
;
1865 op
->m_b
= (unsigned char)record
->param3
;
1869 // case META_SETTEXTJUSTIFICATION:
1870 // case META_SETWINDOWORG:
1871 // case META_SETWINDOWEXT:
1872 // case META_SETVIEWPORTORG:
1873 // case META_SETVIEWPORTEXT:
1874 // case META_OFFSETWINDOWORG:
1875 // case META_SCALEWINDOWEXT:
1876 // case META_OFFSETVIEWPORTORG:
1877 // case META_SCALEVIEWPORTEXT:
1880 wxOpDraw
*op
= new wxOpDraw(DRAWOP_DRAW_LINE
, (double)lastX
, (double)lastY
,
1881 (double)record
->param1
, (double)record
->param2
);
1887 lastX
= (double)record
->param1
;
1888 lastY
= (double)record
->param2
;
1891 case META_EXCLUDECLIPRECT
:
1894 wxMetaRecord *rec = new wxMetaRecord(META_EXCLUDECLIPRECT);
1895 rec->param4 = getshort(handle); // m_y2
1896 rec->param3 = getshort(handle); // x2
1897 rec->param2 = getshort(handle); // y1
1898 rec->param1 = getshort(handle); // x1
1902 case META_INTERSECTCLIPRECT
:
1905 rec->param4 = getshort(handle); // m_y2
1906 rec->param3 = getshort(handle); // x2
1907 rec->param2 = getshort(handle); // y1
1908 rec->param1 = getshort(handle); // x1
1912 // case META_ARC: // DO!!!
1915 wxOpDraw
*op
= new wxOpDraw(DRAWOP_DRAW_ELLIPSE
,
1916 (double)record
->param1
, (double)record
->param2
,
1917 (double)(record
->param3
- record
->param1
),
1918 (double)(record
->param4
- record
->param2
));
1922 // case META_FLOODFILL:
1923 // case META_PIE: // DO!!!
1924 case META_RECTANGLE
:
1926 wxOpDraw
*op
= new wxOpDraw(DRAWOP_DRAW_RECT
,
1927 (double)record
->param1
, (double)record
->param2
,
1928 (double)(record
->param3
- record
->param1
),
1929 (double)(record
->param4
- record
->param2
));
1933 case META_ROUNDRECT
:
1935 wxOpDraw
*op
= new wxOpDraw(DRAWOP_DRAW_ROUNDED_RECT
,
1936 (double)record
->param1
, (double)record
->param2
,
1937 (double)(record
->param3
- record
->param1
),
1938 (double)(record
->param4
- record
->param2
), (double)record
->param5
);
1942 // case META_PATBLT:
1943 // case META_SAVEDC:
1946 wxOpDraw
*op
= new wxOpDraw(DRAWOP_DRAW_POINT
,
1947 (double)record
->param1
, (double)record
->param2
,
1950 // SHOULD SET THE COLOUR - SET PEN?
1951 // rec->param3 = getint(handle); // COLORREF
1955 // case META_OFFSETCLIPRGN:
1958 wxOpDraw
*op
= new wxOpDraw(DRAWOP_DRAW_TEXT
,
1959 (double)record
->param1
, (double)record
->param2
,
1960 0.0, 0.0, 0.0, record
->stringParam
);
1964 // case META_BITBLT:
1965 // case META_STRETCHBLT:
1968 int n
= (int)record
->param1
;
1969 wxRealPoint
*newPoints
= new wxRealPoint
[n
];
1970 for (int i
= 0; i
< n
; i
++)
1972 newPoints
[i
].x
= record
->points
[i
].x
;
1973 newPoints
[i
].y
= record
->points
[i
].y
;
1976 wxOpPolyDraw
*op
= new wxOpPolyDraw(DRAWOP_DRAW_POLYGON
, n
, newPoints
);
1982 int n
= (int)record
->param1
;
1983 wxRealPoint
*newPoints
= new wxRealPoint
[n
];
1984 for (int i
= 0; i
< n
; i
++)
1986 newPoints
[i
].x
= record
->points
[i
].x
;
1987 newPoints
[i
].y
= record
->points
[i
].y
;
1990 wxOpPolyDraw
*op
= new wxOpPolyDraw(DRAWOP_DRAW_POLYLINE
, n
, newPoints
);
1994 // case META_ESCAPE:
1995 // case META_RESTOREDC:
1996 // case META_FILLREGION:
1997 // case META_FRAMEREGION:
1998 // case META_INVERTREGION:
1999 // case META_PAINTREGION:
2000 // case META_SELECTCLIPREGION: // DO THIS!
2001 case META_SELECTOBJECT
:
2003 // The pen, brush etc. has already been created when the metafile
2004 // was read in, so we don't create it - we set it.
2005 wxNode
*recNode
= metaFile
->gdiObjects
.Item((int)record
->param2
);
2008 wxMetaRecord
*gdiRec
= (wxMetaRecord
*)recNode
->GetData();
2009 if (gdiRec
&& (gdiRec
->param1
!= 0))
2011 wxObject
*obj
= (wxObject
*)gdiRec
->param1
;
2012 if (obj
->IsKindOf(CLASSINFO(wxPen
)))
2014 wxOpSetGDI
*op
= new wxOpSetGDI(DRAWOP_SET_PEN
, this, (int)record
->param2
);
2017 else if (obj
->IsKindOf(CLASSINFO(wxBrush
)))
2019 wxOpSetGDI
*op
= new wxOpSetGDI(DRAWOP_SET_BRUSH
, this, (int)record
->param2
);
2022 else if (obj
->IsKindOf(CLASSINFO(wxFont
)))
2024 wxOpSetGDI
*op
= new wxOpSetGDI(DRAWOP_SET_FONT
, this, (int)record
->param2
);
2031 // case META_SETTEXTALIGN:
2032 // case META_DRAWTEXT:
2034 // case META_SETMAPPERFLAGS:
2035 // case META_EXTTEXTOUT:
2036 // case META_SETDIBTODEV:
2037 // case META_SELECTPALETTE:
2038 // case META_REALIZEPALETTE:
2039 // case META_ANIMATEPALETTE:
2040 // case META_SETPALENTRIES:
2041 // case META_POLYPOLYGON:
2042 // case META_RESIZEPALETTE:
2043 // case META_DIBBITBLT:
2044 // case META_DIBSTRETCHBLT:
2045 case META_DIBCREATEPATTERNBRUSH
:
2048 m_gdiObjects
.Append(NULL
);
2051 // case META_STRETCHDIB:
2052 // case META_EXTFLOODFILL:
2053 // case META_RESETDC:
2054 // case META_STARTDOC:
2055 // case META_STARTPAGE:
2056 // case META_ENDPAGE:
2057 // case META_ABORTDOC:
2058 // case META_ENDDOC:
2059 // case META_DELETEOBJECT: // DO!!
2060 case META_CREATEPALETTE
:
2063 m_gdiObjects
.Append(NULL
);
2066 case META_CREATEBRUSH
:
2069 m_gdiObjects
.Append(NULL
);
2072 case META_CREATEPATTERNBRUSH
:
2075 m_gdiObjects
.Append(NULL
);
2078 case META_CREATEPENINDIRECT
:
2080 // The pen is created when the metafile is read in.
2081 // We keep track of all the GDI objects needed for this
2082 // image so when reading the wxDrawnShape from file,
2083 // we can read in all the GDI objects, then refer
2084 // to them by an index starting from zero thereafter.
2085 m_gdiObjects
.Append((wxObject
*)record
->param1
);
2088 case META_CREATEFONTINDIRECT
:
2090 m_gdiObjects
.Append((wxObject
*)record
->param1
);
2093 case META_CREATEBRUSHINDIRECT
:
2095 // Don't have to do anything here: the pen is created
2096 // when the metafile is read in.
2097 m_gdiObjects
.Append((wxObject
*)record
->param1
);
2100 case META_CREATEBITMAPINDIRECT
:
2103 m_gdiObjects
.Append(NULL
);
2106 case META_CREATEBITMAP
:
2109 m_gdiObjects
.Append(NULL
);
2112 case META_CREATEREGION
:
2115 m_gdiObjects
.Append(NULL
);
2123 node
= node
->GetNext();
2125 double actualWidth
= (double)fabs(metaFile
->right
- metaFile
->left
);
2126 double actualHeight
= (double)fabs(metaFile
->bottom
- metaFile
->top
);
2128 double initialScaleX
= 1.0;
2129 double initialScaleY
= 1.0;
2131 double xoffset
, yoffset
;
2133 // Translate so origin is at centre of rectangle
2134 if (metaFile
->bottom
> metaFile
->top
)
2135 yoffset
= - (double)((metaFile
->bottom
- metaFile
->top
)/2.0);
2137 yoffset
= - (double)((metaFile
->top
- metaFile
->bottom
)/2.0);
2139 if (metaFile
->right
> metaFile
->left
)
2140 xoffset
= - (double)((metaFile
->right
- metaFile
->left
)/2.0);
2142 xoffset
= - (double)((metaFile
->left
- metaFile
->right
)/2.0);
2144 Translate(xoffset
, yoffset
);
2146 // Scale to a reasonable size (take the width of this wxDrawnShape
2148 if (actualWidth
!= 0.0)
2150 initialScaleX
= (double)((*rwidth
) / actualWidth
);
2151 initialScaleY
= initialScaleX
;
2152 (*rheight
) = initialScaleY
*actualHeight
;
2154 Scale(initialScaleX
, initialScaleY
);
2156 m_width
= (actualWidth
*initialScaleX
);
2157 m_height
= *rheight
;
2163 // Scale to fit size
2164 void wxPseudoMetaFile::ScaleTo(double w
, double h
)
2166 double scaleX
= (double)(w
/m_width
);
2167 double scaleY
= (double)(h
/m_height
);
2170 Scale(scaleX
, scaleY
);
2173 void wxPseudoMetaFile::GetBounds(double *boundMinX
, double *boundMinY
, double *boundMaxX
, double *boundMaxY
)
2175 double maxX
= (double) -99999.9;
2176 double maxY
= (double) -99999.9;
2177 double minX
= (double) 99999.9;
2178 double minY
= (double) 99999.9;
2180 wxNode
*node
= m_ops
.GetFirst();
2183 wxDrawOp
*op
= (wxDrawOp
*)node
->GetData();
2184 switch (op
->GetOp())
2186 case DRAWOP_DRAW_LINE
:
2187 case DRAWOP_DRAW_RECT
:
2188 case DRAWOP_DRAW_ROUNDED_RECT
:
2189 case DRAWOP_DRAW_ELLIPSE
:
2190 case DRAWOP_DRAW_ELLIPTIC_ARC
:
2191 case DRAWOP_DRAW_POINT
:
2192 case DRAWOP_DRAW_TEXT
:
2194 wxOpDraw
*opDraw
= (wxOpDraw
*)op
;
2195 if (opDraw
->m_x1
< minX
) minX
= opDraw
->m_x1
;
2196 if (opDraw
->m_x1
> maxX
) maxX
= opDraw
->m_x1
;
2197 if (opDraw
->m_y1
< minY
) minY
= opDraw
->m_y1
;
2198 if (opDraw
->m_y1
> maxY
) maxY
= opDraw
->m_y1
;
2199 if (op
->GetOp() == DRAWOP_DRAW_LINE
)
2201 if (opDraw
->m_x2
< minX
) minX
= opDraw
->m_x2
;
2202 if (opDraw
->m_x2
> maxX
) maxX
= opDraw
->m_x2
;
2203 if (opDraw
->m_y2
< minY
) minY
= opDraw
->m_y2
;
2204 if (opDraw
->m_y2
> maxY
) maxY
= opDraw
->m_y2
;
2206 else if (op
->GetOp() == DRAWOP_DRAW_RECT
||
2207 op
->GetOp() == DRAWOP_DRAW_ROUNDED_RECT
||
2208 op
->GetOp() == DRAWOP_DRAW_ELLIPSE
||
2209 op
->GetOp() == DRAWOP_DRAW_ELLIPTIC_ARC
)
2211 if ((opDraw
->m_x1
+ opDraw
->m_x2
) < minX
) minX
= (opDraw
->m_x1
+ opDraw
->m_x2
);
2212 if ((opDraw
->m_x1
+ opDraw
->m_x2
) > maxX
) maxX
= (opDraw
->m_x1
+ opDraw
->m_x2
);
2213 if ((opDraw
->m_y1
+ opDraw
->m_y2
) < minY
) minY
= (opDraw
->m_y1
+ opDraw
->m_y2
);
2214 if ((opDraw
->m_y1
+ opDraw
->m_y2
) > maxY
) maxY
= (opDraw
->m_y1
+ opDraw
->m_y2
);
2218 case DRAWOP_DRAW_ARC
:
2220 // TODO: don't yet know how to calculate the bounding box
2221 // for an arc. So pretend it's a line; to get a correct
2222 // bounding box, draw a blank rectangle first, of the correct
2224 wxOpDraw
*opDraw
= (wxOpDraw
*)op
;
2225 if (opDraw
->m_x1
< minX
) minX
= opDraw
->m_x1
;
2226 if (opDraw
->m_x1
> maxX
) maxX
= opDraw
->m_x1
;
2227 if (opDraw
->m_y1
< minY
) minY
= opDraw
->m_y1
;
2228 if (opDraw
->m_y1
> maxY
) maxY
= opDraw
->m_y1
;
2229 if (opDraw
->m_x2
< minX
) minX
= opDraw
->m_x2
;
2230 if (opDraw
->m_x2
> maxX
) maxX
= opDraw
->m_x2
;
2231 if (opDraw
->m_y2
< minY
) minY
= opDraw
->m_y2
;
2232 if (opDraw
->m_y2
> maxY
) maxY
= opDraw
->m_y2
;
2235 case DRAWOP_DRAW_POLYLINE
:
2236 case DRAWOP_DRAW_POLYGON
:
2237 case DRAWOP_DRAW_SPLINE
:
2239 wxOpPolyDraw
*poly
= (wxOpPolyDraw
*)op
;
2240 for (int i
= 0; i
< poly
->m_noPoints
; i
++)
2242 if (poly
->m_points
[i
].x
< minX
) minX
= poly
->m_points
[i
].x
;
2243 if (poly
->m_points
[i
].x
> maxX
) maxX
= poly
->m_points
[i
].x
;
2244 if (poly
->m_points
[i
].y
< minY
) minY
= poly
->m_points
[i
].y
;
2245 if (poly
->m_points
[i
].y
> maxY
) maxY
= poly
->m_points
[i
].y
;
2252 node
= node
->GetNext();
2260 *w = (double)fabs(maxX - minX);
2261 *h = (double)fabs(maxY - minY);
2265 // Calculate size from current operations
2266 void wxPseudoMetaFile::CalculateSize(wxDrawnShape
* shape
)
2268 double boundMinX
, boundMinY
, boundMaxX
, boundMaxY
;
2270 GetBounds(& boundMinX
, & boundMinY
, & boundMaxX
, & boundMaxY
);
2272 SetSize(boundMaxX
- boundMinX
, boundMaxY
- boundMinY
);
2276 shape
->SetWidth(m_width
);
2277 shape
->SetHeight(m_height
);
2281 // Set of functions for drawing into a pseudo metafile.
2282 // They use integers, but doubles are used internally for accuracy
2285 void wxPseudoMetaFile::DrawLine(const wxPoint
& pt1
, const wxPoint
& pt2
)
2287 wxOpDraw
*theOp
= new wxOpDraw(DRAWOP_DRAW_LINE
,
2288 (double) pt1
.x
, (double) pt1
.y
, (double) pt2
.x
, (double) pt2
.y
);
2290 m_ops
.Append(theOp
);
2293 void wxPseudoMetaFile::DrawRectangle(const wxRect
& rect
)
2295 wxOpDraw
*theOp
= new wxOpDraw(DRAWOP_DRAW_RECT
,
2296 (double) rect
.x
, (double) rect
.y
, (double) rect
.width
, (double) rect
.height
);
2298 m_ops
.Append(theOp
);
2301 void wxPseudoMetaFile::DrawRoundedRectangle(const wxRect
& rect
, double radius
)
2303 wxOpDraw
*theOp
= new wxOpDraw(DRAWOP_DRAW_ROUNDED_RECT
,
2304 (double) rect
.x
, (double) rect
.y
, (double) rect
.width
, (double) rect
.height
);
2306 theOp
->m_radius
= radius
;
2308 m_ops
.Append(theOp
);
2311 void wxPseudoMetaFile::DrawEllipse(const wxRect
& rect
)
2313 wxOpDraw
*theOp
= new wxOpDraw(DRAWOP_DRAW_ELLIPSE
,
2314 (double) rect
.x
, (double) rect
.y
, (double) rect
.width
, (double) rect
.height
);
2316 m_ops
.Append(theOp
);
2319 void wxPseudoMetaFile::DrawArc(const wxPoint
& centrePt
, const wxPoint
& startPt
, const wxPoint
& endPt
)
2321 wxOpDraw
*theOp
= new wxOpDraw(DRAWOP_DRAW_ARC
,
2322 (double) centrePt
.x
, (double) centrePt
.y
, (double) startPt
.x
, (double) startPt
.y
);
2324 theOp
->m_x3
= (double) endPt
.x
;
2325 theOp
->m_y3
= (double) endPt
.y
;
2327 m_ops
.Append(theOp
);
2330 void wxPseudoMetaFile::DrawEllipticArc(const wxRect
& rect
, double startAngle
, double endAngle
)
2332 const double pi
= M_PI
;
2334 double startAngleRadians
= startAngle
* (pi
*2.0/360.0);
2335 double endAngleRadians
= endAngle
* (pi
*2.0/360.0);
2337 wxOpDraw
*theOp
= new wxOpDraw(DRAWOP_DRAW_ELLIPTIC_ARC
,
2338 (double) rect
.x
, (double) rect
.y
, (double) rect
.width
, (double) rect
.height
);
2340 theOp
->m_x3
= startAngleRadians
;
2341 theOp
->m_y3
= endAngleRadians
;
2343 m_ops
.Append(theOp
);
2346 void wxPseudoMetaFile::DrawPoint(const wxPoint
& pt
)
2348 wxOpDraw
*theOp
= new wxOpDraw(DRAWOP_DRAW_POINT
,
2349 (double) pt
.x
, (double) pt
.y
, 0.0, 0.0);
2351 m_ops
.Append(theOp
);
2354 void wxPseudoMetaFile::DrawText(const wxString
& text
, const wxPoint
& pt
)
2356 wxOpDraw
*theOp
= new wxOpDraw(DRAWOP_DRAW_TEXT
,
2357 (double) pt
.x
, (double) pt
.y
, 0.0, 0.0);
2359 theOp
->m_textString
= text
;
2361 m_ops
.Append(theOp
);
2364 void wxPseudoMetaFile::DrawLines(int n
, wxPoint pts
[])
2366 wxRealPoint
* realPoints
= new wxRealPoint
[n
];
2368 for (i
= 0; i
< n
; i
++)
2370 realPoints
[i
].x
= pts
[i
].x
;
2371 realPoints
[i
].y
= pts
[i
].y
;
2373 wxOpPolyDraw
* theOp
= new wxOpPolyDraw(DRAWOP_DRAW_POLYLINE
, n
, realPoints
);
2374 m_ops
.Append(theOp
);
2377 void wxPseudoMetaFile::DrawPolygon(int n
, wxPoint pts
[], int flags
)
2379 wxRealPoint
* realPoints
= new wxRealPoint
[n
];
2381 for (i
= 0; i
< n
; i
++)
2383 realPoints
[i
].x
= pts
[i
].x
;
2384 realPoints
[i
].y
= pts
[i
].y
;
2386 wxOpPolyDraw
* theOp
= new wxOpPolyDraw(DRAWOP_DRAW_POLYGON
, n
, realPoints
);
2387 m_ops
.Append(theOp
);
2389 if (flags
& oglMETAFLAGS_OUTLINE
)
2390 m_outlineOp
= (m_ops
.GetCount() - 1);
2393 void wxPseudoMetaFile::DrawSpline(int n
, wxPoint pts
[])
2395 wxRealPoint
* realPoints
= new wxRealPoint
[n
];
2397 for (i
= 0; i
< n
; i
++)
2399 realPoints
[i
].x
= pts
[i
].x
;
2400 realPoints
[i
].y
= pts
[i
].y
;
2402 wxOpPolyDraw
* theOp
= new wxOpPolyDraw(DRAWOP_DRAW_SPLINE
, n
, realPoints
);
2403 m_ops
.Append(theOp
);
2406 void wxPseudoMetaFile::SetClippingRect(const wxRect
& rect
)
2408 /* wxOpSetClipping* theOp = */ new wxOpSetClipping(DRAWOP_SET_CLIPPING_RECT
,
2409 (double) rect
.x
, (double) rect
.y
, (double) rect
.width
, (double) rect
.height
);
2412 void wxPseudoMetaFile::DestroyClippingRect()
2414 wxOpSetClipping
* theOp
= new wxOpSetClipping(DRAWOP_DESTROY_CLIPPING_RECT
,
2415 0.0, 0.0, 0.0, 0.0);
2417 m_ops
.Append(theOp
);
2420 void wxPseudoMetaFile::SetPen(wxPen
* pen
, bool isOutline
)
2422 m_gdiObjects
.Append(pen
);
2423 int n
= m_gdiObjects
.GetCount();
2425 wxOpSetGDI
* theOp
= new wxOpSetGDI(DRAWOP_SET_PEN
, this, n
- 1);
2427 m_ops
.Append(theOp
);
2431 m_outlineColours
.Append((wxObject
*) (n
- 1));
2435 void wxPseudoMetaFile::SetBrush(wxBrush
* brush
, bool isFill
)
2437 m_gdiObjects
.Append(brush
);
2438 int n
= m_gdiObjects
.GetCount();
2440 wxOpSetGDI
* theOp
= new wxOpSetGDI(DRAWOP_SET_BRUSH
, this, n
- 1);
2442 m_ops
.Append(theOp
);
2446 m_fillColours
.Append((wxObject
*) (n
- 1));
2450 void wxPseudoMetaFile::SetFont(wxFont
* font
)
2452 m_gdiObjects
.Append(font
);
2453 int n
= m_gdiObjects
.GetCount();
2455 wxOpSetGDI
* theOp
= new wxOpSetGDI(DRAWOP_SET_FONT
, this, n
- 1);
2457 m_ops
.Append(theOp
);
2460 void wxPseudoMetaFile::SetTextColour(const wxColour
& colour
)
2462 wxOpSetGDI
* theOp
= new wxOpSetGDI(DRAWOP_SET_TEXT_COLOUR
, this, 0);
2463 theOp
->m_r
= colour
.Red();
2464 theOp
->m_g
= colour
.Green();
2465 theOp
->m_b
= colour
.Blue();
2467 m_ops
.Append(theOp
);
2470 void wxPseudoMetaFile::SetBackgroundColour(const wxColour
& colour
)
2472 wxOpSetGDI
* theOp
= new wxOpSetGDI(DRAWOP_SET_BK_COLOUR
, this, 0);
2473 theOp
->m_r
= colour
.Red();
2474 theOp
->m_g
= colour
.Green();
2475 theOp
->m_b
= colour
.Blue();
2477 m_ops
.Append(theOp
);
2480 void wxPseudoMetaFile::SetBackgroundMode(int mode
)
2482 wxOpSetGDI
* theOp
= new wxOpSetGDI(DRAWOP_SET_BK_MODE
, this, 0, mode
);
2484 m_ops
.Append(theOp
);