]> git.saurik.com Git - wxWidgets.git/blame - utils/ogl/src/drawn.cpp
spurious error messages from wxRegKey::HasValue() suppressed
[wxWidgets.git] / utils / ogl / src / drawn.cpp
CommitLineData
0fc1a713
JS
1/////////////////////////////////////////////////////////////////////////////
2// Name: drawn.cpp
3// Purpose: wxDrawnShape
4// Author: Julian Smart
5// Modified by:
6// Created: 12/07/98
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13#pragma implementation "drawn.h"
14#endif
15
16// For compilers that support precompilation, includes "wx.h".
17#include <wx/wxprec.h>
18
19#ifdef __BORLANDC__
20#pragma hdrstop
21#endif
22
23#ifndef WX_PRECOMP
24#include <wx/wx.h>
25#endif
26
27#ifdef PROLOGIO
28#include <wx/wxexpr.h>
29#endif
30
31#include "basic.h"
32#include "basicp.h"
33#include "canvas.h"
34#include "mfutils.h"
35#include "drawn.h"
36#include "drawnp.h"
37#include "misc.h"
38
39static void IntToHex(unsigned int dec, char *buf);
40static unsigned long HexToInt(char *buf);
41extern char *GraphicsBuffer;
42
43#define gyTYPE_PEN 40
44#define gyTYPE_BRUSH 41
45#define gyTYPE_FONT 42
46
47/*
48 * Drawn object
49 *
50 */
51
34138703 52IMPLEMENT_DYNAMIC_CLASS(wxDrawnShape, wxRectangleShape)
0fc1a713
JS
53
54wxDrawnShape::wxDrawnShape():wxRectangleShape(100.0, 50.0)
55{
56 m_saveToFile = TRUE;
57}
58
59wxDrawnShape::~wxDrawnShape()
60{
61}
62
63void wxDrawnShape::OnDraw(wxDC& dc)
64{
65 // Pass pen and brush in case we have force outline
66 // and fill colours
67 if (m_shadowMode != SHADOW_NONE)
68 {
69 if (m_shadowBrush)
70 m_metafile.m_fillBrush = m_shadowBrush;
71 m_metafile.m_outlinePen = transparent_pen;
72 m_metafile.Draw(dc, m_xpos + m_shadowOffsetX, m_ypos + m_shadowOffsetY);
73 }
74
75 m_metafile.m_outlinePen = m_pen;
76 m_metafile.m_fillBrush = m_brush;
77 m_metafile.Draw(dc, m_xpos, m_ypos);
78}
79
80void wxDrawnShape::SetSize(float w, float h, bool recursive)
81{
82 SetAttachmentSize(w, h);
83
84 float scaleX;
85 float scaleY;
86 if (GetWidth() == 0.0)
87 scaleX = 1.0;
88 else scaleX = w/GetWidth();
89 if (GetHeight() == 0.0)
90 scaleY = 1.0;
91 else scaleY = h/GetHeight();
92
93 m_metafile.Scale(scaleX, scaleY);
94 m_width = w;
95 m_height = h;
96 SetDefaultRegionSize();
97}
98
99void wxDrawnShape::Scale(float sx, float sy)
100{
101 m_metafile.Scale(sx, sy);
34138703 102 m_metafile.CalculateSize(this);
0fc1a713
JS
103}
104
105void wxDrawnShape::Translate(float x, float y)
106{
107 m_metafile.Translate(x, y);
34138703 108 m_metafile.CalculateSize(this);
0fc1a713
JS
109}
110
111void wxDrawnShape::Rotate(float x, float y, float theta)
112{
113 if (!m_metafile.GetRotateable())
114 return;
115
116 float actualTheta = theta-m_metafile.m_currentRotation;
117
118 // Rotate metafile
119 m_metafile.Rotate(x, y, theta);
120
121 // Rotate attachment points
122 float sinTheta = (float)sin(actualTheta);
123 float cosTheta = (float)cos(actualTheta);
124 wxNode *node = m_attachmentPoints.First();
125 while (node)
126 {
127 wxAttachmentPoint *point = (wxAttachmentPoint *)node->Data();
128 float x1 = point->m_x;
129 float y1 = point->m_y;
130 point->m_x = x1*cosTheta - y1*sinTheta + x*(1 - cosTheta) + y*sinTheta;
131 point->m_y = x1*sinTheta + y1*cosTheta + y*(1 - cosTheta) + x*sinTheta;
132 node = node->Next();
133 }
134 m_rotation = theta;
34138703
JS
135
136 m_metafile.CalculateSize(this);
0fc1a713
JS
137}
138
139#ifdef PROLOGIO
140// Prolog database stuff
141char *wxDrawnShape::GetFunctor()
142{
143 return "node_image";
144}
145
146void wxDrawnShape::WritePrologAttributes(wxExpr *clause)
147{
148 wxRectangleShape::WritePrologAttributes(clause);
149
150 clause->AddAttributeValue("save_metafile", (long)m_saveToFile);
151 if (m_saveToFile)
152 m_metafile.WritePrologAttributes(clause);
153}
154
155void wxDrawnShape::ReadPrologAttributes(wxExpr *clause)
156{
157 wxRectangleShape::ReadPrologAttributes(clause);
158
159 int iVal = (int) m_saveToFile;
160 clause->AssignAttributeValue("save_metafile", &iVal);
161 m_saveToFile = (iVal != 0);
162
163 if (m_saveToFile)
164 m_metafile.ReadPrologAttributes(clause);
165}
166#endif
167
168// Does the copying for this object
2bb0cd28 169void wxDrawnShape::Copy(wxShape& copy)
0fc1a713
JS
170{
171 wxRectangleShape::Copy(copy);
0fc1a713 172
2bb0cd28
JS
173 wxASSERT( copy.IsKindOf(CLASSINFO(wxDrawnShape)) ) ;
174
175 wxDrawnShape& drawnCopy = (wxDrawnShape&) copy;
176
177 m_metafile.Copy(drawnCopy.m_metafile);
178 drawnCopy.m_saveToFile = m_saveToFile;
0fc1a713
JS
179}
180
181bool wxDrawnShape::LoadFromMetaFile(char *filename)
182{
183 return m_metafile.LoadFromMetaFile(filename, &m_width, &m_height);
184}
185
34138703
JS
186// Set of functions for drawing into a pseudo metafile.
187// They use integers, but doubles are used internally for accuracy
188// when scaling.
189
190void wxDrawnShape::DrawLine(const wxPoint& pt1, const wxPoint& pt2)
191{
192 m_metafile.DrawLine(pt1, pt2);
193}
194
195void wxDrawnShape::DrawRectangle(const wxRect& rect)
196{
197 m_metafile.DrawRectangle(rect);
198}
199
200void wxDrawnShape::DrawRoundedRectangle(const wxRect& rect, double radius)
201{
202 m_metafile.DrawRoundedRectangle(rect, radius);
203}
204
205void wxDrawnShape::DrawEllipse(const wxRect& rect)
206{
207 m_metafile.DrawEllipse(rect);
208}
209
210void wxDrawnShape::DrawPoint(const wxPoint& pt)
211{
212 m_metafile.DrawPoint(pt);
213}
214
215void wxDrawnShape::DrawText(const wxString& text, const wxPoint& pt)
216{
217 m_metafile.DrawText(text, pt);
218}
219
220void wxDrawnShape::DrawLines(int n, wxPoint pts[])
221{
222 m_metafile.DrawLines(n, pts);
223}
224
225void wxDrawnShape::DrawPolygon(int n, wxPoint pts[])
226{
227 m_metafile.DrawPolygon(n, pts);
228}
229
230void wxDrawnShape::DrawSpline(int n, wxPoint pts[])
231{
232 m_metafile.DrawSpline(n, pts);
233}
234
235void wxDrawnShape::SetClippingRect(const wxRect& rect)
236{
237 m_metafile.SetClippingRect(rect);
238}
239
240void wxDrawnShape::DestroyClippingRect()
241{
242 m_metafile.DestroyClippingRect();
243}
244
245void wxDrawnShape::SetPen(wxPen* pen, bool isOutline)
246{
247 m_metafile.SetPen(pen, isOutline);
248}
249
250void wxDrawnShape::SetBrush(wxBrush* brush, bool isFill)
251{
252 m_metafile.SetBrush(brush, isFill);
253}
254
255void wxDrawnShape::SetFont(wxFont* font)
256{
257 m_metafile.SetFont(font);
258}
259
260void wxDrawnShape::SetTextColour(const wxColour& colour)
261{
262 m_metafile.SetTextColour(colour);
263}
264
265void wxDrawnShape::SetBackgroundColour(const wxColour& colour)
266{
267 m_metafile.SetBackgroundColour(colour);
268}
269
270void wxDrawnShape::SetBackgroundMode(int mode)
271{
272 m_metafile.SetBackgroundMode(mode);
273}
274
275
0fc1a713
JS
276/*
277 * Individual operations
278 *
279 */
280
281/*
282 * Set font, brush, text colour
283 *
284 */
285
286wxOpSetGDI::wxOpSetGDI(int theOp, wxPseudoMetaFile *theImage, int theGdiIndex, int theMode):
287 wxDrawOp(theOp)
288{
34138703
JS
289 m_gdiIndex = theGdiIndex;
290 m_image = theImage;
291 m_mode = theMode;
0fc1a713
JS
292}
293
294void wxOpSetGDI::Do(wxDC& dc, float xoffset, float yoffset)
295{
34138703 296 switch (m_op)
0fc1a713
JS
297 {
298 case DRAWOP_SET_PEN:
299 {
300 // Check for overriding this operation for outline
301 // colour
34138703 302 if (m_image->m_outlineColours.Member((wxObject *)m_gdiIndex))
0fc1a713 303 {
34138703
JS
304 if (m_image->m_outlinePen)
305 dc.SetPen(m_image->m_outlinePen);
0fc1a713
JS
306 }
307 else
308 {
34138703 309 wxNode *node = m_image->m_gdiObjects.Nth(m_gdiIndex);
0fc1a713
JS
310 if (node)
311 {
312 wxPen *pen = (wxPen *)node->Data();
313 if (pen)
314 dc.SetPen(pen);
315 }
316 }
317 break;
318 }
319 case DRAWOP_SET_BRUSH:
320 {
321 // Check for overriding this operation for outline or fill
322 // colour
34138703 323 if (m_image->m_outlineColours.Member((wxObject *)m_gdiIndex))
0fc1a713
JS
324 {
325 // Need to construct a brush to match the outline pen's colour
34138703 326 if (m_image->m_outlinePen)
0fc1a713 327 {
34138703 328 wxBrush *br = wxTheBrushList->FindOrCreateBrush(m_image->m_outlinePen->GetColour(), wxSOLID);
0fc1a713
JS
329 if (br)
330 dc.SetBrush(br);
331 }
332 }
34138703 333 else if (m_image->m_fillColours.Member((wxObject *)m_gdiIndex))
0fc1a713 334 {
34138703 335 if (m_image->m_fillBrush)
0fc1a713 336 {
34138703 337 dc.SetBrush(m_image->m_fillBrush);
0fc1a713
JS
338 }
339 }
340 else
341 {
34138703 342 wxNode *node = m_image->m_gdiObjects.Nth(m_gdiIndex);
0fc1a713
JS
343 if (node)
344 {
345 wxBrush *brush = (wxBrush *)node->Data();
346 if (brush)
347 dc.SetBrush(brush);
348 }
349 }
350 break;
351 }
352 case DRAWOP_SET_FONT:
353 {
34138703 354 wxNode *node = m_image->m_gdiObjects.Nth(m_gdiIndex);
0fc1a713
JS
355 if (node)
356 {
357 wxFont *font = (wxFont *)node->Data();
358 if (font)
359 dc.SetFont(font);
360 }
361 break;
362 }
363 case DRAWOP_SET_TEXT_COLOUR:
364 {
34138703 365 wxColour col(m_r,m_g,m_b);
0fc1a713
JS
366 dc.SetTextForeground(col);
367 break;
368 }
369 case DRAWOP_SET_BK_COLOUR:
370 {
34138703 371 wxColour col(m_r,m_g,m_b);
0fc1a713
JS
372 dc.SetTextBackground(col);
373 break;
374 }
375 case DRAWOP_SET_BK_MODE:
376 {
34138703 377 dc.SetBackgroundMode(m_mode);
0fc1a713
JS
378 break;
379 }
380 default:
381 break;
382 }
383}
384
385wxDrawOp *wxOpSetGDI::Copy(wxPseudoMetaFile *newImage)
386{
34138703
JS
387 wxOpSetGDI *newOp = new wxOpSetGDI(m_op, newImage, m_gdiIndex, m_mode);
388 newOp->m_r = m_r;
389 newOp->m_g = m_g;
390 newOp->m_b = m_b;
0fc1a713
JS
391 return newOp;
392}
393
34138703 394wxExpr *wxOpSetGDI::WriteExpr(wxPseudoMetaFile *image)
0fc1a713
JS
395{
396 wxExpr *expr = new wxExpr(PrologList);
34138703
JS
397 expr->Append(new wxExpr((long)m_op));
398 switch (m_op)
0fc1a713
JS
399 {
400 case DRAWOP_SET_PEN:
401 case DRAWOP_SET_BRUSH:
402 case DRAWOP_SET_FONT:
403 {
34138703 404 expr->Append(new wxExpr((long)m_gdiIndex));
0fc1a713
JS
405 break;
406 }
407 case DRAWOP_SET_TEXT_COLOUR:
408 case DRAWOP_SET_BK_COLOUR:
409 {
34138703
JS
410 expr->Append(new wxExpr((long)m_r));
411 expr->Append(new wxExpr((long)m_g));
412 expr->Append(new wxExpr((long)m_b));
0fc1a713
JS
413 break;
414 }
415 case DRAWOP_SET_BK_MODE:
416 {
34138703 417 expr->Append(new wxExpr((long)m_mode));
0fc1a713
JS
418 break;
419 }
420 default:
421 break;
422 }
423 return expr;
424}
425
34138703 426void wxOpSetGDI::ReadExpr(wxPseudoMetaFile *image, wxExpr *expr)
0fc1a713 427{
34138703 428 switch (m_op)
0fc1a713
JS
429 {
430 case DRAWOP_SET_PEN:
431 case DRAWOP_SET_BRUSH:
432 case DRAWOP_SET_FONT:
433 {
34138703 434 m_gdiIndex = (int)expr->Nth(1)->IntegerValue();
0fc1a713
JS
435 break;
436 }
437 case DRAWOP_SET_TEXT_COLOUR:
438 case DRAWOP_SET_BK_COLOUR:
439 {
34138703
JS
440 m_r = (unsigned char)expr->Nth(1)->IntegerValue();
441 m_g = (unsigned char)expr->Nth(2)->IntegerValue();
442 m_b = (unsigned char)expr->Nth(3)->IntegerValue();
0fc1a713
JS
443 break;
444 }
445 case DRAWOP_SET_BK_MODE:
446 {
34138703 447 m_mode = (int)expr->Nth(1)->IntegerValue();
0fc1a713
JS
448 break;
449 }
450 default:
451 break;
452 }
453}
454
455/*
456 * Set/destroy clipping
457 *
458 */
459
460wxOpSetClipping::wxOpSetClipping(int theOp, float theX1, float theY1,
461 float theX2, float theY2):wxDrawOp(theOp)
462{
34138703
JS
463 m_x1 = theX1;
464 m_y1 = theY1;
465 m_x2 = theX2;
466 m_y2 = theY2;
0fc1a713
JS
467}
468
469wxDrawOp *wxOpSetClipping::Copy(wxPseudoMetaFile *newImage)
470{
34138703 471 wxOpSetClipping *newOp = new wxOpSetClipping(m_op, m_x1, m_y1, m_x2, m_y2);
0fc1a713
JS
472 return newOp;
473}
474
475void wxOpSetClipping::Do(wxDC& dc, float xoffset, float yoffset)
476{
34138703 477 switch (m_op)
0fc1a713
JS
478 {
479 case DRAWOP_SET_CLIPPING_RECT:
480 {
34138703 481 dc.SetClippingRegion(m_x1 + xoffset, m_y1 + yoffset, m_x2 + xoffset, m_y2 + yoffset);
0fc1a713
JS
482 break;
483 }
484 case DRAWOP_DESTROY_CLIPPING_RECT:
485 {
486 dc.DestroyClippingRegion();
487 break;
488 }
489 default:
490 break;
491 }
492}
493
494void wxOpSetClipping::Scale(float xScale, float yScale)
495{
34138703
JS
496 m_x1 *= xScale;
497 m_y1 *= yScale;
498 m_x2 *= xScale;
499 m_y2 *= yScale;
0fc1a713
JS
500}
501
502void wxOpSetClipping::Translate(float x, float y)
503{
34138703
JS
504 m_x1 += x;
505 m_y1 += y;
0fc1a713
JS
506}
507
34138703 508wxExpr *wxOpSetClipping::WriteExpr(wxPseudoMetaFile *image)
0fc1a713
JS
509{
510 wxExpr *expr = new wxExpr(PrologList);
34138703
JS
511 expr->Append(new wxExpr((long)m_op));
512 switch (m_op)
0fc1a713
JS
513 {
514 case DRAWOP_SET_CLIPPING_RECT:
515 {
34138703
JS
516 expr->Append(new wxExpr(m_x1));
517 expr->Append(new wxExpr(m_y1));
518 expr->Append(new wxExpr(m_x2));
519 expr->Append(new wxExpr(m_y2));
0fc1a713
JS
520 break;
521 }
522 default:
523 break;
524 }
525 return expr;
526}
527
34138703 528void wxOpSetClipping::ReadExpr(wxPseudoMetaFile *image, wxExpr *expr)
0fc1a713 529{
34138703 530 switch (m_op)
0fc1a713
JS
531 {
532 case DRAWOP_SET_CLIPPING_RECT:
533 {
34138703
JS
534 m_x1 = expr->Nth(1)->RealValue();
535 m_y1 = expr->Nth(2)->RealValue();
536 m_x2 = expr->Nth(3)->RealValue();
537 m_y2 = expr->Nth(4)->RealValue();
0fc1a713
JS
538 break;
539 }
540 default:
541 break;
542 }
543}
544
545/*
546 * Draw line, rectangle, rounded rectangle, ellipse, point, arc, text
547 *
548 */
549
550wxOpDraw::wxOpDraw(int theOp, float theX1, float theY1, float theX2, float theY2,
551 float theRadius, char *s):wxDrawOp(theOp)
552{
34138703
JS
553 m_x1 = theX1;
554 m_y1 = theY1;
555 m_x2 = theX2;
556 m_y2 = theY2;
557 m_radius = theRadius;
558 if (s) m_textString = copystring(s);
559 else m_textString = NULL;
0fc1a713
JS
560}
561
562wxOpDraw::~wxOpDraw()
563{
34138703 564 if (m_textString) delete[] m_textString;
0fc1a713
JS
565}
566
567wxDrawOp *wxOpDraw::Copy(wxPseudoMetaFile *newImage)
568{
34138703 569 wxOpDraw *newOp = new wxOpDraw(m_op, m_x1, m_y1, m_x2, m_y2, m_radius, m_textString);
0fc1a713
JS
570 return newOp;
571}
572
573void wxOpDraw::Do(wxDC& dc, float xoffset, float yoffset)
574{
34138703 575 switch (m_op)
0fc1a713
JS
576 {
577 case DRAWOP_DRAW_LINE:
578 {
34138703 579 dc.DrawLine(m_x1+xoffset, m_y1+yoffset, m_x2+xoffset, m_y2+yoffset);
0fc1a713
JS
580 break;
581 }
582 case DRAWOP_DRAW_RECT:
583 {
34138703 584 dc.DrawRectangle(m_x1+xoffset, m_y1+yoffset, m_x2, m_y2);
0fc1a713
JS
585 break;
586 }
587 case DRAWOP_DRAW_ROUNDED_RECT:
588 {
34138703 589 dc.DrawRoundedRectangle(m_x1+xoffset, m_y1+yoffset, m_x2, m_y2, m_radius);
0fc1a713
JS
590 break;
591 }
592 case DRAWOP_DRAW_ELLIPSE:
593 {
34138703 594 dc.DrawEllipse(m_x1+xoffset, m_y1+yoffset, m_x2, m_y2);
0fc1a713
JS
595 break;
596 }
597 case DRAWOP_DRAW_POINT:
598 {
34138703 599 dc.DrawPoint(m_x1+xoffset, m_y1+yoffset);
0fc1a713
JS
600 break;
601 }
602 case DRAWOP_DRAW_TEXT:
603 {
34138703 604 dc.DrawText(m_textString, m_x1+xoffset, m_y1+yoffset);
0fc1a713
JS
605 break;
606 }
607 default:
608 break;
609 }
610}
611
612void wxOpDraw::Scale(float scaleX, float scaleY)
613{
34138703
JS
614 m_x1 *= scaleX;
615 m_y1 *= scaleY;
616 m_x2 *= scaleX;
617 m_y2 *= scaleY;
618 m_radius *= scaleX;
0fc1a713
JS
619}
620
621void wxOpDraw::Translate(float x, float y)
622{
34138703
JS
623 m_x1 += x;
624 m_y1 += y;
0fc1a713
JS
625}
626
627void wxOpDraw::Rotate(float x, float y, float sinTheta, float cosTheta)
628{
34138703
JS
629 m_x1 = m_x1*cosTheta - m_y1*sinTheta + x*(1 - cosTheta) + y*sinTheta;
630 m_y1 = m_x1*sinTheta + m_y1*cosTheta + y*(1 - cosTheta) + x*sinTheta;
631
632 switch (m_op)
0fc1a713
JS
633 {
634 case DRAWOP_DRAW_LINE:
635 {
34138703
JS
636 m_x2 = m_x2*cosTheta - m_y2*sinTheta + x*(1 - cosTheta) + y*sinTheta;
637 m_y2 = m_x2*sinTheta + m_y2*cosTheta + y*(1 - cosTheta) + x*sinTheta;
0fc1a713
JS
638 break;
639 }
640 default:
641 break;
642 }
643}
644
34138703 645wxExpr *wxOpDraw::WriteExpr(wxPseudoMetaFile *image)
0fc1a713
JS
646{
647 wxExpr *expr = new wxExpr(PrologList);
34138703
JS
648 expr->Append(new wxExpr((long)m_op));
649 switch (m_op)
0fc1a713
JS
650 {
651 case DRAWOP_DRAW_LINE:
652 case DRAWOP_DRAW_RECT:
653 case DRAWOP_DRAW_ELLIPSE:
654 {
34138703
JS
655 expr->Append(new wxExpr(m_x1));
656 expr->Append(new wxExpr(m_y1));
657 expr->Append(new wxExpr(m_x2));
658 expr->Append(new wxExpr(m_y2));
0fc1a713
JS
659 break;
660 }
661 case DRAWOP_DRAW_ROUNDED_RECT:
662 {
34138703
JS
663 expr->Append(new wxExpr(m_x1));
664 expr->Append(new wxExpr(m_y1));
665 expr->Append(new wxExpr(m_x2));
666 expr->Append(new wxExpr(m_y2));
667 expr->Append(new wxExpr(m_radius));
0fc1a713
JS
668 break;
669 }
670 case DRAWOP_DRAW_POINT:
671 {
34138703
JS
672 expr->Append(new wxExpr(m_x1));
673 expr->Append(new wxExpr(m_y1));
0fc1a713
JS
674 break;
675 }
676 case DRAWOP_DRAW_TEXT:
677 {
34138703
JS
678 expr->Append(new wxExpr(m_x1));
679 expr->Append(new wxExpr(m_y1));
680 expr->Append(new wxExpr(PrologString, m_textString));
0fc1a713
JS
681 break;
682 }
683 case DRAWOP_DRAW_ARC:
684 default:
685 {
686 break;
687 }
688 }
689 return expr;
690}
691
34138703 692void wxOpDraw::ReadExpr(wxPseudoMetaFile *image, wxExpr *expr)
0fc1a713 693{
34138703 694 switch (m_op)
0fc1a713
JS
695 {
696 case DRAWOP_DRAW_LINE:
697 case DRAWOP_DRAW_RECT:
698 case DRAWOP_DRAW_ELLIPSE:
699 {
34138703
JS
700 m_x1 = expr->Nth(1)->RealValue();
701 m_y1 = expr->Nth(2)->RealValue();
702 m_x2 = expr->Nth(3)->RealValue();
703 m_y2 = expr->Nth(4)->RealValue();
0fc1a713
JS
704 break;
705 }
706 case DRAWOP_DRAW_ROUNDED_RECT:
707 {
34138703
JS
708 m_x1 = expr->Nth(1)->RealValue();
709 m_y1 = expr->Nth(2)->RealValue();
710 m_x2 = expr->Nth(3)->RealValue();
711 m_y2 = expr->Nth(4)->RealValue();
712 m_radius = expr->Nth(5)->RealValue();
0fc1a713
JS
713 break;
714 }
715 case DRAWOP_DRAW_POINT:
716 {
34138703
JS
717 m_x1 = expr->Nth(1)->RealValue();
718 m_y1 = expr->Nth(2)->RealValue();
0fc1a713
JS
719 break;
720 }
721 case DRAWOP_DRAW_TEXT:
722 {
34138703
JS
723 m_x1 = expr->Nth(1)->RealValue();
724 m_y1 = expr->Nth(2)->RealValue();
725 m_textString = copystring(expr->Nth(3)->StringValue());
0fc1a713
JS
726 break;
727 }
728 case DRAWOP_DRAW_ARC:
729 default:
730 {
731 break;
732 }
733 }
734}
735
736/*
737 * Draw polygon, polyline, spline
738 *
739 */
740
741wxOpPolyDraw::wxOpPolyDraw(int theOp, int n, wxRealPoint *thePoints):wxDrawOp(theOp)
742{
34138703
JS
743 m_noPoints = n;
744 m_points = thePoints;
0fc1a713
JS
745}
746
747wxOpPolyDraw::~wxOpPolyDraw()
748{
34138703 749 delete[] m_points;
0fc1a713
JS
750}
751
752wxDrawOp *wxOpPolyDraw::Copy(wxPseudoMetaFile *newImage)
753{
34138703
JS
754 wxRealPoint *newPoints = new wxRealPoint[m_noPoints];
755 for (int i = 0; i < m_noPoints; i++)
0fc1a713 756 {
34138703
JS
757 newPoints[i].x = m_points[i].x;
758 newPoints[i].y = m_points[i].y;
0fc1a713 759 }
34138703 760 wxOpPolyDraw *newOp = new wxOpPolyDraw(m_op, m_noPoints, newPoints);
0fc1a713
JS
761 return newOp;
762}
763
764void wxOpPolyDraw::Do(wxDC& dc, float xoffset, float yoffset)
765{
34138703 766 switch (m_op)
0fc1a713
JS
767 {
768 case DRAWOP_DRAW_POLYLINE:
769 {
34138703 770 wxPoint *actualPoints = new wxPoint[m_noPoints];
0fc1a713 771 int i;
34138703 772 for (i = 0; i < m_noPoints; i++)
0fc1a713 773 {
34138703
JS
774 actualPoints[i].x = (long) m_points[i].x;
775 actualPoints[i].y = (long) m_points[i].y;
0fc1a713
JS
776 }
777
34138703 778 dc.DrawLines(m_noPoints, actualPoints, xoffset, yoffset);
0fc1a713
JS
779
780 delete[] actualPoints;
781 break;
782 }
783 case DRAWOP_DRAW_POLYGON:
784 {
34138703 785 wxPoint *actualPoints = new wxPoint[m_noPoints];
0fc1a713 786 int i;
34138703 787 for (i = 0; i < m_noPoints; i++)
0fc1a713 788 {
34138703
JS
789 actualPoints[i].x = (long) m_points[i].x;
790 actualPoints[i].y = (long) m_points[i].y;
0fc1a713
JS
791 }
792
34138703 793 dc.DrawPolygon(m_noPoints, actualPoints, xoffset, yoffset);
0fc1a713
JS
794
795 delete[] actualPoints;
796 break;
797 }
798 case DRAWOP_DRAW_SPLINE:
799 {
34138703
JS
800 wxPoint *actualPoints = new wxPoint[m_noPoints];
801 int i;
802 for (i = 0; i < m_noPoints; i++)
803 {
804 actualPoints[i].x = (long) m_points[i].x;
805 actualPoints[i].y = (long) m_points[i].y;
806 }
807
808 dc.DrawSpline(m_noPoints, actualPoints); // no offsets in DrawSpline // , xoffset, yoffset);
809
810 delete[] actualPoints;
811 break;
0fc1a713
JS
812 break;
813 }
814 default:
815 break;
816 }
817}
818
819void wxOpPolyDraw::Scale(float scaleX, float scaleY)
820{
34138703 821 for (int i = 0; i < m_noPoints; i++)
0fc1a713 822 {
34138703
JS
823 m_points[i].x *= scaleX;
824 m_points[i].y *= scaleY;
0fc1a713
JS
825 }
826}
827
828void wxOpPolyDraw::Translate(float x, float y)
829{
34138703 830 for (int i = 0; i < m_noPoints; i++)
0fc1a713 831 {
34138703
JS
832 m_points[i].x += x;
833 m_points[i].y += y;
0fc1a713
JS
834 }
835}
836
837void wxOpPolyDraw::Rotate(float x, float y, float sinTheta, float cosTheta)
838{
34138703 839 for (int i = 0; i < m_noPoints; i++)
0fc1a713 840 {
34138703
JS
841 float x1 = m_points[i].x;
842 float y1 = m_points[i].y;
843 m_points[i].x = x1*cosTheta - y1*sinTheta + x*(1 - cosTheta) + y*sinTheta;
844 m_points[i].y = x1*sinTheta + y1*cosTheta + y*(1 - cosTheta) + x*sinTheta;
0fc1a713
JS
845 }
846}
847
34138703 848wxExpr *wxOpPolyDraw::WriteExpr(wxPseudoMetaFile *image)
0fc1a713
JS
849{
850 wxExpr *expr = new wxExpr(PrologList);
34138703
JS
851 expr->Append(new wxExpr((long)m_op));
852 expr->Append(new wxExpr((long)m_noPoints));
0fc1a713
JS
853
854// char buf1[9];
855 char buf2[5];
856 char buf3[5];
857
858 GraphicsBuffer[0] = 0;
859
860 /*
861 * Store each coordinate pair in a hex string to save space.
862 * E.g. "1B9080CD". 4 hex digits per coordinate pair.
863 *
864 */
865
34138703 866 for (int i = 0; i < m_noPoints; i++)
0fc1a713 867 {
34138703
JS
868 long signedX = (long)(m_points[i].x*100.0);
869 long signedY = (long)(m_points[i].y*100.0);
0fc1a713
JS
870
871 // Scale to 0 -> 64K
872 long unSignedX = (long)(signedX + 32767.0);
873 long unSignedY = (long)(signedY + 32767.0);
874
875// IntToHex((unsigned int)signedX, buf2);
876// IntToHex((unsigned int)signedY, buf3);
877 IntToHex((int)unSignedX, buf2);
878 IntToHex((int)unSignedY, buf3);
879
880 // Don't overrun the buffer
881 if ((i*8) < 3000)
882 {
883 strcat(GraphicsBuffer, buf2);
884 strcat(GraphicsBuffer, buf3);
885 }
886 }
887 expr->Append(new wxExpr(PrologString, GraphicsBuffer));
888 return expr;
889}
890
34138703 891void wxOpPolyDraw::ReadExpr(wxPseudoMetaFile *image, wxExpr *expr)
0fc1a713 892{
34138703 893 m_noPoints = (int)expr->Nth(1)->IntegerValue();
0fc1a713
JS
894
895 char buf1[5];
896 char buf2[5];
897
34138703 898 m_points = new wxRealPoint[m_noPoints];
0fc1a713
JS
899 int i = 0;
900 int bufPtr = 0;
901 wxString hexString = expr->Nth(2)->StringValue();
34138703 902 while (i < m_noPoints)
0fc1a713
JS
903 {
904 buf1[0] = hexString[bufPtr];
905 buf1[1] = hexString[bufPtr + 1];
906 buf1[2] = hexString[bufPtr + 2];
907 buf1[3] = hexString[bufPtr + 3];
908 buf1[4] = 0;
909
910 buf2[0] = hexString[bufPtr + 4];
911 buf2[1] = hexString[bufPtr + 5];
912 buf2[2] = hexString[bufPtr + 6];
913 buf2[3] = hexString[bufPtr + 7];
914 buf2[4] = 0;
915
916 bufPtr += 8;
917
918// int signedX = (signed int)HexToInt(buf1);
919// int signedY = (signed int)HexToInt(buf2);
920 long unSignedX = HexToInt(buf1);
921 long unSignedY = HexToInt(buf2);
922 // Scale -32K -> +32K
923 long signedX = unSignedX - 32767;
924 long signedY = unSignedY - 32767;
925#ifdef __WXMSW__
926 int testX = (signed int)unSignedX;
927 int testY = (signed int)unSignedY;
928#endif
929
34138703
JS
930 m_points[i].x = (float)(signedX / 100.0);
931 m_points[i].y = (float)(signedY / 100.0);
0fc1a713
JS
932
933 i ++;
934 }
935}
936
937
938/*
939 * Utilities
940 *
941 */
942
943static char hexArray[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B',
944 'C', 'D', 'E', 'F' };
945
946// Convert unsigned 16-bit integer to 4-character hex string
947static void IntToHex(unsigned int dec, char *buf)
948{
949 int digit1 = (int)(dec/4096);
950 int digit2 = (int)((dec - (digit1*4096))/256);
951 int digit3 = (int)((dec - (digit1*4096) - (digit2*256))/16);
952 int digit4 = dec - (digit1*4096 + digit2*256 + digit3*16);
953
954 buf[0] = hexArray[digit1];
955 buf[1] = hexArray[digit2];
956 buf[2] = hexArray[digit3];
957 buf[3] = hexArray[digit4];
958 buf[4] = 0;
959}
960
961// One hex digit to decimal number
962static int HexToInt1(char hex)
963{
964 switch (hex)
965 {
966 case '0':
967 return 0;
968 case '1':
969 return 1;
970 case '2':
971 return 2;
972 case '3':
973 return 3;
974 case '4':
975 return 4;
976 case '5':
977 return 5;
978 case '6':
979 return 6;
980 case '7':
981 return 7;
982 case '8':
983 return 8;
984 case '9':
985 return 9;
986 case 'A':
987 return 10;
988 case 'B':
989 return 11;
990 case 'C':
991 return 12;
992 case 'D':
993 return 13;
994 case 'E':
995 return 14;
996 case 'F':
997 return 15;
998 default:
999 return 0;
1000 }
1001 return 0;
1002}
1003
1004// 4-digit hex string to unsigned integer
1005static unsigned long HexToInt(char *buf)
1006{
1007 long d1 = (long)(HexToInt1(buf[0])*4096.0) ;
1008 long d2 = (long)(HexToInt1(buf[1])*256.0) ;
1009 long d3 = (long)(HexToInt1(buf[2])*16.0) ;
1010 long d4 = (long)(HexToInt1(buf[3])) ;
1011 unsigned long n = (long)(d1 + d2 + d3 + d4) ;
1012 return n;
1013}
1014
1015/*
1016 * wxPseudo meta-file
1017 *
1018 */
1019
1020IMPLEMENT_DYNAMIC_CLASS(wxPseudoMetaFile, wxObject)
1021
1022wxPseudoMetaFile::wxPseudoMetaFile()
1023{
1024 m_currentRotation = 0;
1025 m_rotateable = TRUE;
1026 m_width = 0.0;
1027 m_height = 0.0;
34138703
JS
1028 m_outlinePen = NULL;
1029 m_fillBrush = NULL;
0fc1a713
JS
1030}
1031
1032wxPseudoMetaFile::wxPseudoMetaFile(wxPseudoMetaFile& mf)
1033{
1034 mf.Copy(*this);
1035}
1036
1037wxPseudoMetaFile::~wxPseudoMetaFile()
1038{
1039 Clear();
1040}
1041
1042void wxPseudoMetaFile::Clear()
1043{
1044 wxNode *node = m_ops.First();
1045 while (node)
1046 {
1047 wxDrawOp *op = (wxDrawOp *)node->Data();
1048 delete op;
1049 node = node->Next();
1050 }
1051 m_ops.Clear();
1052 m_gdiObjects.Clear();
34138703
JS
1053 m_outlineColours.Clear();
1054 m_fillColours.Clear();
0fc1a713
JS
1055}
1056
1057void wxPseudoMetaFile::Draw(wxDC& dc, float xoffset, float yoffset)
1058{
1059 wxNode *node = m_ops.First();
1060 while (node)
1061 {
1062 wxDrawOp *op = (wxDrawOp *)node->Data();
1063 op->Do(dc, xoffset, yoffset);
1064 node = node->Next();
1065 }
1066}
1067
1068void wxPseudoMetaFile::Scale(float sx, float sy)
1069{
1070 wxNode *node = m_ops.First();
1071 while (node)
1072 {
1073 wxDrawOp *op = (wxDrawOp *)node->Data();
1074 op->Scale(sx, sy);
1075 node = node->Next();
1076 }
1077 m_width *= sx;
1078 m_height *= sy;
1079}
1080
1081void wxPseudoMetaFile::Translate(float x, float y)
1082{
1083 wxNode *node = m_ops.First();
1084 while (node)
1085 {
1086 wxDrawOp *op = (wxDrawOp *)node->Data();
1087 op->Translate(x, y);
1088 node = node->Next();
1089 }
1090}
1091
1092void wxPseudoMetaFile::Rotate(float x, float y, float theta)
1093{
1094 float theta1 = theta-m_currentRotation;
1095 if (theta1 == 0.0) return;
1096 float cosTheta = (float)cos(theta1);
1097 float sinTheta = (float)sin(theta1);
1098
1099 wxNode *node = m_ops.First();
1100 while (node)
1101 {
1102 wxDrawOp *op = (wxDrawOp *)node->Data();
1103 op->Rotate(x, y, sinTheta, cosTheta);
1104 node = node->Next();
1105 }
1106 m_currentRotation = theta;
1107}
1108
1109#ifdef PROLOGIO
1110void wxPseudoMetaFile::WritePrologAttributes(wxExpr *clause)
1111{
1112 // Write width and height
1113 clause->AddAttributeValue("meta_width", m_width);
1114 clause->AddAttributeValue("meta_height", m_height);
1115 clause->AddAttributeValue("meta_rotateable", (long)m_rotateable);
1116
1117 // Write GDI objects
1118 char buf[50];
1119 int i = 1;
1120 wxNode *node = m_gdiObjects.First();
1121 while (node)
1122 {
1123 sprintf(buf, "gdi%d", i);
1124 wxObject *obj = (wxObject *)node->Data();
1125 wxExpr *expr = NULL;
1126 if (obj)
1127 {
1128 if (obj->IsKindOf(CLASSINFO(wxPen)))
1129 {
1130 wxPen *thePen = (wxPen *)obj;
1131 expr = new wxExpr(PrologList);
1132 expr->Append(new wxExpr((long)gyTYPE_PEN));
1133 expr->Append(new wxExpr((long)thePen->GetWidth()));
1134 expr->Append(new wxExpr((long)thePen->GetStyle()));
1135 expr->Append(new wxExpr((long)thePen->GetColour().Red()));
1136 expr->Append(new wxExpr((long)thePen->GetColour().Green()));
1137 expr->Append(new wxExpr((long)thePen->GetColour().Blue()));
1138 }
1139 else if (obj->IsKindOf(CLASSINFO(wxBrush)))
1140 {
1141 wxBrush *theBrush = (wxBrush *)obj;
1142 expr = new wxExpr(PrologList);
1143 expr->Append(new wxExpr((long)gyTYPE_BRUSH));
1144 expr->Append(new wxExpr((long)theBrush->GetStyle()));
1145 expr->Append(new wxExpr((long)theBrush->GetColour().Red()));
1146 expr->Append(new wxExpr((long)theBrush->GetColour().Green()));
1147 expr->Append(new wxExpr((long)theBrush->GetColour().Blue()));
1148 }
1149 else if (obj->IsKindOf(CLASSINFO(wxFont)))
1150 {
1151 wxFont *theFont = (wxFont *)obj;
1152 expr = new wxExpr(PrologList);
1153 expr->Append(new wxExpr((long)gyTYPE_FONT));
1154 expr->Append(new wxExpr((long)theFont->GetPointSize()));
1155 expr->Append(new wxExpr((long)theFont->GetFamily()));
1156 expr->Append(new wxExpr((long)theFont->GetStyle()));
1157 expr->Append(new wxExpr((long)theFont->GetWeight()));
1158 expr->Append(new wxExpr((long)theFont->GetUnderlined()));
1159 }
1160 }
1161 else
1162 {
1163 // If no recognised GDI object, append a place holder anyway.
1164 expr = new wxExpr(PrologList);
1165 expr->Append(new wxExpr((long)0));
1166 }
1167
1168 if (expr)
1169 {
1170 clause->AddAttributeValue(buf, expr);
1171 i ++;
1172 }
1173 node = node->Next();
1174 }
1175
1176 // Write drawing operations
1177 i = 1;
1178 node = m_ops.First();
1179 while (node)
1180 {
1181 sprintf(buf, "op%d", i);
1182 wxDrawOp *op = (wxDrawOp *)node->Data();
34138703 1183 wxExpr *expr = op->WriteExpr(this);
0fc1a713
JS
1184 if (expr)
1185 {
1186 clause->AddAttributeValue(buf, expr);
1187 i ++;
1188 }
1189 node = node->Next();
1190 }
1191
1192 // Write outline and fill GDI op lists (if any)
1193 if (m_outlineColours.Number() > 0)
1194 {
1195 wxExpr *outlineExpr = new wxExpr(PrologList);
1196 node = m_outlineColours.First();
1197 while (node)
1198 {
1199 outlineExpr->Append(new wxExpr((long)node->Data()));
1200 node = node->Next();
1201 }
1202 clause->AddAttributeValue("outline_objects", outlineExpr);
1203 }
1204 if (m_fillColours.Number() > 0)
1205 {
1206 wxExpr *fillExpr = new wxExpr(PrologList);
1207 node = m_fillColours.First();
1208 while (node)
1209 {
1210 fillExpr->Append(new wxExpr((long)node->Data()));
1211 node = node->Next();
1212 }
1213 clause->AddAttributeValue("fill_objects", fillExpr);
1214 }
1215
1216}
1217
1218void wxPseudoMetaFile::ReadPrologAttributes(wxExpr *clause)
1219{
1220 clause->AssignAttributeValue("meta_width", &m_width);
1221 clause->AssignAttributeValue("meta_height", &m_height);
1222
1223 int iVal = (int) m_rotateable;
1224 clause->AssignAttributeValue("meta_rotateable", &iVal);
1225 m_rotateable = (iVal != 0);
1226
1227 // Read GDI objects
1228 char buf[50];
1229 int i = 1;
1230 bool keepGoing = TRUE;
1231 while (keepGoing)
1232 {
1233 sprintf(buf, "gdi%d", i);
1234 wxExpr *expr = NULL;
1235 clause->AssignAttributeValue(buf, &expr);
1236 if (!expr)
1237 {
1238 keepGoing = FALSE;
1239 }
1240 else
1241 {
1242 wxExpr *idExpr = expr->Nth(0);
1243 switch (idExpr->IntegerValue())
1244 {
1245 case gyTYPE_PEN:
1246 {
1247 int penWidth = (int)expr->Nth(1)->IntegerValue();
1248 int penStyle = (int)expr->Nth(2)->IntegerValue();
1249 int penRed = (int)expr->Nth(3)->IntegerValue();
1250 int penGreen = (int)expr->Nth(4)->IntegerValue();
1251 int penBlue = (int)expr->Nth(5)->IntegerValue();
1252 wxColour col(penRed, penGreen, penBlue);
1253 wxPen *p = wxThePenList->FindOrCreatePen(col, penWidth, penStyle);
1254 if (!p)
1255 p = wxBLACK_PEN;
1256 m_gdiObjects.Append(p);
1257 break;
1258 }
1259 case gyTYPE_BRUSH:
1260 {
1261 int brushStyle = (int)expr->Nth(1)->IntegerValue();
1262 int brushRed = (int)expr->Nth(2)->IntegerValue();
1263 int brushGreen = (int)expr->Nth(3)->IntegerValue();
1264 int brushBlue = (int)expr->Nth(4)->IntegerValue();
1265 wxColour col(brushRed, brushGreen, brushBlue);
1266 wxBrush *b = wxTheBrushList->FindOrCreateBrush(col, brushStyle);
1267 if (!b)
1268 b = wxWHITE_BRUSH;
1269 m_gdiObjects.Append(b);
1270 break;
1271 }
1272 case gyTYPE_FONT:
1273 {
1274 int fontPointSize = (int)expr->Nth(1)->IntegerValue();
1275 int fontFamily = (int)expr->Nth(2)->IntegerValue();
1276 int fontStyle = (int)expr->Nth(3)->IntegerValue();
1277 int fontWeight = (int)expr->Nth(4)->IntegerValue();
1278 int fontUnderlined = (int)expr->Nth(5)->IntegerValue();
1279 m_gdiObjects.Append(wxTheFontList->FindOrCreateFont(fontPointSize,
1280 fontFamily, fontStyle, fontWeight, (fontUnderlined != 0)));
1281 break;
1282 }
1283 default:
1284 {
1285 // Place holder
1286 m_gdiObjects.Append(NULL);
1287 break;
1288 }
1289 }
1290 i ++;
1291 }
1292 }
1293
1294 // Now read in the operations
1295 keepGoing = TRUE;
1296 i = 1;
1297 while (keepGoing)
1298 {
1299 sprintf(buf, "op%d", i);
1300 wxExpr *expr = NULL;
1301 clause->AssignAttributeValue(buf, &expr);
1302 if (!expr)
1303 {
1304 keepGoing = FALSE;
1305 }
1306 else
1307 {
1308 wxExpr *idExpr = expr->Nth(0);
1309 int opId = (int)idExpr->IntegerValue();
1310 switch (opId)
1311 {
1312 case DRAWOP_SET_PEN:
1313 case DRAWOP_SET_BRUSH:
1314 case DRAWOP_SET_FONT:
1315 case DRAWOP_SET_TEXT_COLOUR:
1316 case DRAWOP_SET_BK_COLOUR:
1317 case DRAWOP_SET_BK_MODE:
1318 {
1319 wxOpSetGDI *theOp = new wxOpSetGDI(opId, this, 0);
34138703 1320 theOp->ReadExpr(this, expr);
0fc1a713
JS
1321 m_ops.Append(theOp);
1322 break;
1323 }
1324
1325 case DRAWOP_SET_CLIPPING_RECT:
1326 case DRAWOP_DESTROY_CLIPPING_RECT:
1327 {
1328 wxOpSetClipping *theOp = new wxOpSetClipping(opId, 0.0, 0.0, 0.0, 0.0);
34138703 1329 theOp->ReadExpr(this, expr);
0fc1a713
JS
1330 m_ops.Append(theOp);
1331 break;
1332 }
1333
1334 case DRAWOP_DRAW_LINE:
1335 case DRAWOP_DRAW_RECT:
1336 case DRAWOP_DRAW_ROUNDED_RECT:
1337 case DRAWOP_DRAW_ELLIPSE:
1338 case DRAWOP_DRAW_POINT:
1339 case DRAWOP_DRAW_ARC:
1340 case DRAWOP_DRAW_TEXT:
1341 {
1342 wxOpDraw *theOp = new wxOpDraw(opId, 0.0, 0.0, 0.0, 0.0);
34138703 1343 theOp->ReadExpr(this, expr);
0fc1a713
JS
1344 m_ops.Append(theOp);
1345 break;
1346 }
1347 case DRAWOP_DRAW_SPLINE:
1348 case DRAWOP_DRAW_POLYLINE:
1349 case DRAWOP_DRAW_POLYGON:
1350 {
1351 wxOpPolyDraw *theOp = new wxOpPolyDraw(opId, 0, NULL);
34138703 1352 theOp->ReadExpr(this, expr);
0fc1a713
JS
1353 m_ops.Append(theOp);
1354 break;
1355 }
1356 default:
1357 break;
1358 }
1359 }
1360 i ++;
1361 }
1362
1363 // Now read in the list of outline and fill operations, if any
1364 wxExpr *expr1 = clause->AttributeValue("outline_objects");
1365 if (expr1)
1366 {
1367 wxExpr *eachExpr = expr1->GetFirst();
1368 while (eachExpr)
1369 {
1370 m_outlineColours.Append((wxObject *)eachExpr->IntegerValue());
1371 eachExpr = eachExpr->GetNext();
1372 }
1373 }
1374 expr1 = clause->AttributeValue("fill_objects");
1375 if (expr1)
1376 {
1377 wxExpr *eachExpr = expr1->GetFirst();
1378 while (eachExpr)
1379 {
1380 m_fillColours.Append((wxObject *)eachExpr->IntegerValue());
1381 eachExpr = eachExpr->GetNext();
1382 }
1383 }
1384}
1385#endif
1386
1387// Does the copying for this object
1388void wxPseudoMetaFile::Copy(wxPseudoMetaFile& copy)
1389{
1390 copy.m_currentRotation = m_currentRotation;
1391 copy.m_width = m_width;
1392 copy.m_height = m_height;
1393 copy.m_rotateable = m_rotateable;
34138703
JS
1394 copy.m_fillBrush = m_fillBrush;
1395 copy.m_outlinePen = m_outlinePen;
1396
1397 copy.Clear();
0fc1a713
JS
1398
1399 // Copy the GDI objects
1400 wxNode *node = m_gdiObjects.First();
1401 while (node)
1402 {
1403 wxObject *obj = (wxObject *)node->Data();
1404 copy.m_gdiObjects.Append(obj);
1405 node = node->Next();
1406 }
1407
1408 // Copy the operations
1409 node = m_ops.First();
1410 while (node)
1411 {
1412 wxDrawOp *op = (wxDrawOp *)node->Data();
1413 copy.m_ops.Append(op->Copy(&copy));
1414 node = node->Next();
1415 }
1416
1417 // Copy the outline/fill operations
0fc1a713
JS
1418 node = m_outlineColours.First();
1419 while (node)
1420 {
1421 copy.m_outlineColours.Append((wxObject *)node->Data());
1422 node = node->Next();
1423 }
0fc1a713
JS
1424 node = m_fillColours.First();
1425 while (node)
1426 {
1427 copy.m_fillColours.Append((wxObject *)node->Data());
1428 node = node->Next();
1429 }
1430}
1431
1432/*
1433 * Pass size of existing image; scale height to
1434 * fit width and return new width and height.
1435 *
1436 */
1437
1438bool wxPseudoMetaFile::LoadFromMetaFile(char *filename, float *rwidth, float *rheight)
1439{
1440 if (!FileExists(filename))
1441 return NULL;
1442
1443 wxXMetaFile *metaFile = new wxXMetaFile;
1444
1445 if (!metaFile->ReadFile(filename))
1446 {
1447 delete metaFile;
1448 return FALSE;
1449 }
1450
1451 float lastX = 0.0;
1452 float lastY = 0.0;
1453
1454 // Convert from metafile records to wxDrawnShape records
1455 wxNode *node = metaFile->metaRecords.First();
1456 while (node)
1457 {
1458 wxMetaRecord *record = (wxMetaRecord *)node->Data();
1459 switch (record->metaFunction)
1460 {
1461 case META_SETBKCOLOR:
1462 {
1463 wxOpSetGDI *op = new wxOpSetGDI(DRAWOP_SET_BK_COLOUR, this, 0);
34138703
JS
1464 op->m_r = (unsigned char)record->param1;
1465 op->m_g = (unsigned char)record->param2;
1466 op->m_b = (unsigned char)record->param3;
0fc1a713
JS
1467 m_ops.Append(op);
1468 break;
1469 }
1470 case META_SETBKMODE:
1471 {
1472 wxOpSetGDI *op = new wxOpSetGDI(DRAWOP_SET_BK_MODE, this, 0, (int)record->param1);
1473 m_ops.Append(op);
1474 break;
1475 }
1476 case META_SETMAPMODE:
1477 {
1478 break;
1479 }
1480// case META_SETROP2:
1481// case META_SETRELABS:
1482// case META_SETPOLYFILLMODE:
1483// case META_SETSTRETCHBLTMODE:
1484// case META_SETTEXTCHAREXTRA:
1485 case META_SETTEXTCOLOR:
1486 {
1487 wxOpSetGDI *op = new wxOpSetGDI(DRAWOP_SET_TEXT_COLOUR, this, 0);
34138703
JS
1488 op->m_r = (unsigned char)record->param1;
1489 op->m_g = (unsigned char)record->param2;
1490 op->m_b = (unsigned char)record->param3;
0fc1a713
JS
1491 m_ops.Append(op);
1492 break;
1493 }
1494// case META_SETTEXTJUSTIFICATION:
1495// case META_SETWINDOWORG:
1496// case META_SETWINDOWEXT:
1497// case META_SETVIEWPORTORG:
1498// case META_SETVIEWPORTEXT:
1499// case META_OFFSETWINDOWORG:
1500// case META_SCALEWINDOWEXT:
1501// case META_OFFSETVIEWPORTORG:
1502// case META_SCALEVIEWPORTEXT:
1503 case META_LINETO:
1504 {
1505 wxOpDraw *op = new wxOpDraw(DRAWOP_DRAW_LINE, (float)lastX, (float)lastY,
1506 (float)record->param1, (float)record->param2);
1507 m_ops.Append(op);
1508 break;
1509 }
1510 case META_MOVETO:
1511 {
1512 lastX = (float)record->param1;
1513 lastY = (float)record->param2;
1514 break;
1515 }
1516 case META_EXCLUDECLIPRECT:
1517 {
1518/*
1519 wxMetaRecord *rec = new wxMetaRecord(META_EXCLUDECLIPRECT);
34138703 1520 rec->param4 = getshort(handle); // m_y2
0fc1a713
JS
1521 rec->param3 = getshort(handle); // x2
1522 rec->param2 = getshort(handle); // y1
1523 rec->param1 = getshort(handle); // x1
1524*/
1525 break;
1526 }
1527 case META_INTERSECTCLIPRECT:
1528 {
1529/*
34138703 1530 rec->param4 = getshort(handle); // m_y2
0fc1a713
JS
1531 rec->param3 = getshort(handle); // x2
1532 rec->param2 = getshort(handle); // y1
1533 rec->param1 = getshort(handle); // x1
1534*/
1535 break;
1536 }
1537// case META_ARC: // DO!!!
1538 case META_ELLIPSE:
1539 {
1540 wxOpDraw *op = new wxOpDraw(DRAWOP_DRAW_ELLIPSE,
1541 (float)record->param1, (float)record->param2,
1542 (float)(record->param3 - record->param1),
1543 (float)(record->param4 - record->param2));
1544 m_ops.Append(op);
1545 break;
1546 }
1547// case META_FLOODFILL:
1548// case META_PIE: // DO!!!
1549 case META_RECTANGLE:
1550 {
1551 wxOpDraw *op = new wxOpDraw(DRAWOP_DRAW_RECT,
1552 (float)record->param1, (float)record->param2,
1553 (float)(record->param3 - record->param1),
1554 (float)(record->param4 - record->param2));
1555 m_ops.Append(op);
1556 break;
1557 }
1558 case META_ROUNDRECT:
1559 {
1560 wxOpDraw *op = new wxOpDraw(DRAWOP_DRAW_ROUNDED_RECT,
1561 (float)record->param1, (float)record->param2,
1562 (float)(record->param3 - record->param1),
1563 (float)(record->param4 - record->param2), (float)record->param5);
1564 m_ops.Append(op);
1565 break;
1566 }
1567// case META_PATBLT:
1568// case META_SAVEDC:
1569 case META_SETPIXEL:
1570 {
1571 wxOpDraw *op = new wxOpDraw(DRAWOP_DRAW_POINT,
1572 (float)record->param1, (float)record->param2,
1573 0.0, 0.0);
1574
1575// SHOULD SET THE COLOUR - SET PEN?
1576// rec->param3 = getint(handle); // COLORREF
1577 m_ops.Append(op);
1578 break;
1579 }
1580// case META_OFFSETCLIPRGN:
1581 case META_TEXTOUT:
1582 {
1583 wxOpDraw *op = new wxOpDraw(DRAWOP_DRAW_TEXT,
1584 (float)record->param1, (float)record->param2,
1585 0.0, 0.0, 0.0, record->stringParam);
1586 m_ops.Append(op);
1587 break;
1588 }
1589// case META_BITBLT:
1590// case META_STRETCHBLT:
1591 case META_POLYGON:
1592 {
1593 int n = (int)record->param1;
1594 wxRealPoint *newPoints = new wxRealPoint[n];
1595 for (int i = 0; i < n; i++)
1596 {
1597 newPoints[i].x = record->points[i].x;
1598 newPoints[i].y = record->points[i].y;
1599 }
1600
1601 wxOpPolyDraw *op = new wxOpPolyDraw(DRAWOP_DRAW_POLYGON, n, newPoints);
1602 m_ops.Append(op);
1603 break;
1604 }
1605 case META_POLYLINE:
1606 {
1607 int n = (int)record->param1;
1608 wxRealPoint *newPoints = new wxRealPoint[n];
1609 for (int i = 0; i < n; i++)
1610 {
1611 newPoints[i].x = record->points[i].x;
1612 newPoints[i].y = record->points[i].y;
1613 }
1614
1615 wxOpPolyDraw *op = new wxOpPolyDraw(DRAWOP_DRAW_POLYLINE, n, newPoints);
1616 m_ops.Append(op);
1617 break;
1618 }
1619// case META_ESCAPE:
1620// case META_RESTOREDC:
1621// case META_FILLREGION:
1622// case META_FRAMEREGION:
1623// case META_INVERTREGION:
1624// case META_PAINTREGION:
1625// case META_SELECTCLIPREGION: // DO THIS!
1626 case META_SELECTOBJECT:
1627 {
1628 // The pen, brush etc. has already been created when the metafile
1629 // was read in, so we don't create it - we set it.
1630 wxNode *recNode = metaFile->gdiObjects.Nth((int)record->param2);
1631 if (recNode)
1632 {
1633 wxMetaRecord *gdiRec = (wxMetaRecord *)recNode->Data();
1634 if (gdiRec && (gdiRec->param1 != 0))
1635 {
1636 wxObject *obj = (wxObject *)gdiRec->param1;
1637 if (obj->IsKindOf(CLASSINFO(wxPen)))
1638 {
1639 wxOpSetGDI *op = new wxOpSetGDI(DRAWOP_SET_PEN, this, (int)record->param2);
1640 m_ops.Append(op);
1641 }
1642 else if (obj->IsKindOf(CLASSINFO(wxBrush)))
1643 {
1644 wxOpSetGDI *op = new wxOpSetGDI(DRAWOP_SET_BRUSH, this, (int)record->param2);
1645 m_ops.Append(op);
1646 }
1647 else if (obj->IsKindOf(CLASSINFO(wxFont)))
1648 {
1649 wxOpSetGDI *op = new wxOpSetGDI(DRAWOP_SET_FONT, this, (int)record->param2);
1650 m_ops.Append(op);
1651 }
1652 }
1653 }
1654 break;
1655 }
1656// case META_SETTEXTALIGN:
1657// case META_DRAWTEXT:
1658// case META_CHORD:
1659// case META_SETMAPPERFLAGS:
1660// case META_EXTTEXTOUT:
1661// case META_SETDIBTODEV:
1662// case META_SELECTPALETTE:
1663// case META_REALIZEPALETTE:
1664// case META_ANIMATEPALETTE:
1665// case META_SETPALENTRIES:
1666// case META_POLYPOLYGON:
1667// case META_RESIZEPALETTE:
1668// case META_DIBBITBLT:
1669// case META_DIBSTRETCHBLT:
1670 case META_DIBCREATEPATTERNBRUSH:
1671 {
1672 // Place holder
1673 m_gdiObjects.Append(NULL);
1674 break;
1675 }
1676// case META_STRETCHDIB:
1677// case META_EXTFLOODFILL:
1678// case META_RESETDC:
1679// case META_STARTDOC:
1680// case META_STARTPAGE:
1681// case META_ENDPAGE:
1682// case META_ABORTDOC:
1683// case META_ENDDOC:
1684// case META_DELETEOBJECT: // DO!!
1685 case META_CREATEPALETTE:
1686 {
1687 // Place holder
1688 m_gdiObjects.Append(NULL);
1689 break;
1690 }
1691 case META_CREATEBRUSH:
1692 {
1693 // Place holder
1694 m_gdiObjects.Append(NULL);
1695 break;
1696 }
1697 case META_CREATEPATTERNBRUSH:
1698 {
1699 // Place holder
1700 m_gdiObjects.Append(NULL);
1701 break;
1702 }
1703 case META_CREATEPENINDIRECT:
1704 {
1705 // The pen is created when the metafile is read in.
1706 // We keep track of all the GDI objects needed for this
1707 // image so when reading the wxDrawnShape from file,
1708 // we can read in all the GDI objects, then refer
1709 // to them by an index starting from zero thereafter.
1710 m_gdiObjects.Append((wxObject *)record->param1);
1711 break;
1712 }
1713 case META_CREATEFONTINDIRECT:
1714 {
1715 m_gdiObjects.Append((wxObject *)record->param1);
1716 break;
1717 }
1718 case META_CREATEBRUSHINDIRECT:
1719 {
1720 // Don't have to do anything here: the pen is created
1721 // when the metafile is read in.
1722 m_gdiObjects.Append((wxObject *)record->param1);
1723 break;
1724 }
1725 case META_CREATEBITMAPINDIRECT:
1726 {
1727 // Place holder
1728 m_gdiObjects.Append(NULL);
1729 break;
1730 }
1731 case META_CREATEBITMAP:
1732 {
1733 // Place holder
1734 m_gdiObjects.Append(NULL);
1735 break;
1736 }
1737 case META_CREATEREGION:
1738 {
1739 // Place holder
1740 m_gdiObjects.Append(NULL);
1741 break;
1742 }
1743 default:
1744 {
1745 break;
1746 }
1747 }
1748 node = node->Next();
1749 }
1750 float actualWidth = (float)fabs(metaFile->right - metaFile->left);
1751 float actualHeight = (float)fabs(metaFile->bottom - metaFile->top);
1752
1753 float initialScaleX = 1.0;
1754 float initialScaleY = 1.0;
1755
1756 float xoffset, yoffset;
1757
1758 // Translate so origin is at centre of rectangle
1759 if (metaFile->bottom > metaFile->top)
1760 yoffset = - (float)((metaFile->bottom - metaFile->top)/2.0);
1761 else
1762 yoffset = - (float)((metaFile->top - metaFile->bottom)/2.0);
1763
1764 if (metaFile->right > metaFile->left)
1765 xoffset = - (float)((metaFile->right - metaFile->left)/2.0);
1766 else
1767 xoffset = - (float)((metaFile->left - metaFile->right)/2.0);
1768
1769 Translate(xoffset, yoffset);
1770
1771 // Scale to a reasonable size (take the width of this wxDrawnShape
1772 // as a guide)
1773 if (actualWidth != 0.0)
1774 {
1775 initialScaleX = (float)((*rwidth) / actualWidth);
1776 initialScaleY = initialScaleX;
1777 (*rheight) = initialScaleY*actualHeight;
1778 }
1779 Scale(initialScaleX, initialScaleY);
1780
1781 m_width = (actualWidth*initialScaleX);
1782 m_height = *rheight;
1783
1784 delete metaFile;
1785 return TRUE;
1786}
1787
1788// Scale to fit size
1789void wxPseudoMetaFile::ScaleTo(float w, float h)
1790{
1791 float scaleX = (float)(w/m_width);
1792 float scaleY = (float)(h/m_height);
1793
1794 // Do the scaling
1795 Scale(scaleX, scaleY);
1796}
1797
1798void wxPseudoMetaFile::GetBounds(float *boundMinX, float *boundMinY, float *boundMaxX, float *boundMaxY)
1799{
1800 float maxX = (float) -99999.9;
1801 float maxY = (float) -99999.9;
1802 float minX = (float) 99999.9;
1803 float minY = (float) 99999.9;
1804
1805 wxNode *node = m_ops.First();
1806 while (node)
1807 {
1808 wxDrawOp *op = (wxDrawOp *)node->Data();
34138703 1809 switch (op->GetOp())
0fc1a713
JS
1810 {
1811 case DRAWOP_DRAW_LINE:
1812 case DRAWOP_DRAW_RECT:
1813 case DRAWOP_DRAW_ROUNDED_RECT:
1814 case DRAWOP_DRAW_ELLIPSE:
1815 case DRAWOP_DRAW_POINT:
1816 case DRAWOP_DRAW_ARC:
1817 case DRAWOP_DRAW_TEXT:
1818 {
1819 wxOpDraw *opDraw = (wxOpDraw *)op;
34138703
JS
1820 if (opDraw->m_x1 < minX) minX = opDraw->m_x1;
1821 if (opDraw->m_x1 > maxX) maxX = opDraw->m_x1;
1822 if (opDraw->m_y1 < minY) minY = opDraw->m_y1;
1823 if (opDraw->m_y1 > maxY) maxY = opDraw->m_y1;
1824 if (op->GetOp() == DRAWOP_DRAW_LINE)
0fc1a713 1825 {
34138703
JS
1826 if (opDraw->m_x2 < minX) minX = opDraw->m_x2;
1827 if (opDraw->m_x2 > maxX) maxX = opDraw->m_x2;
1828 if (opDraw->m_y2 < minY) minY = opDraw->m_y2;
1829 if (opDraw->m_y2 > maxY) maxY = opDraw->m_y2;
0fc1a713 1830 }
34138703
JS
1831 else if (op->GetOp() == DRAWOP_DRAW_RECT ||
1832 op->GetOp() == DRAWOP_DRAW_ROUNDED_RECT ||
1833 op->GetOp() == DRAWOP_DRAW_ELLIPSE)
0fc1a713 1834 {
34138703
JS
1835 if ((opDraw->m_x1 + opDraw->m_x2) < minX) minX = (opDraw->m_x1 + opDraw->m_x2);
1836 if ((opDraw->m_x1 + opDraw->m_x2) > maxX) maxX = (opDraw->m_x1 + opDraw->m_x2);
1837 if ((opDraw->m_y1 + opDraw->m_y2) < minY) minY = (opDraw->m_y1 + opDraw->m_y2);
1838 if ((opDraw->m_y1 + opDraw->m_y2) > maxY) maxY = (opDraw->m_y1 + opDraw->m_y2);
0fc1a713
JS
1839 }
1840 break;
1841 }
1842 case DRAWOP_DRAW_POLYLINE:
1843 case DRAWOP_DRAW_POLYGON:
1844 case DRAWOP_DRAW_SPLINE:
1845 {
1846 wxOpPolyDraw *poly = (wxOpPolyDraw *)op;
34138703 1847 for (int i = 0; i < poly->m_noPoints; i++)
0fc1a713 1848 {
34138703
JS
1849 if (poly->m_points[i].x < minX) minX = poly->m_points[i].x;
1850 if (poly->m_points[i].x > maxX) maxX = poly->m_points[i].x;
1851 if (poly->m_points[i].y < minY) minY = poly->m_points[i].y;
1852 if (poly->m_points[i].y > maxY) maxY = poly->m_points[i].y;
0fc1a713
JS
1853 }
1854 break;
1855 }
1856 default:
1857 break;
1858 }
1859 node = node->Next();
1860 }
1861
1862 *boundMinX = minX;
1863 *boundMinY = minY;
1864 *boundMaxX = maxX;
1865 *boundMaxY = maxY;
1866/*
1867 *w = (float)fabs(maxX - minX);
1868 *h = (float)fabs(maxY - minY);
1869*/
1870}
1871
34138703
JS
1872// Calculate size from current operations
1873void wxPseudoMetaFile::CalculateSize(wxDrawnShape* shape)
1874{
1875 float boundMinX, boundMinY, boundMaxX, boundMaxY;
1876
1877 GetBounds(& boundMinX, & boundMinY, & boundMaxX, & boundMaxY);
1878
1879 SetSize(boundMaxX - boundMinX, boundMaxY - boundMinY);
1880
1881 if (shape)
1882 {
1883 shape->SetWidth(m_width);
1884 shape->SetHeight(m_height);
1885 }
1886}
1887
1888// Set of functions for drawing into a pseudo metafile.
1889// They use integers, but doubles are used internally for accuracy
1890// when scaling.
1891
1892void wxPseudoMetaFile::DrawLine(const wxPoint& pt1, const wxPoint& pt2)
1893{
1894 wxOpDraw *theOp = new wxOpDraw(DRAWOP_DRAW_LINE,
1895 (double) pt1.x, (double) pt1.y, (double) pt2.x, (double) pt2.y);
1896
1897 m_ops.Append(theOp);
1898}
1899
1900void wxPseudoMetaFile::DrawRectangle(const wxRect& rect)
1901{
1902 wxOpDraw *theOp = new wxOpDraw(DRAWOP_DRAW_RECT,
1903 (double) rect.x, (double) rect.y, (double) rect.width, (double) rect.height);
1904
1905 m_ops.Append(theOp);
1906}
1907
1908void wxPseudoMetaFile::DrawRoundedRectangle(const wxRect& rect, double radius)
1909{
1910 wxOpDraw *theOp = new wxOpDraw(DRAWOP_DRAW_ROUNDED_RECT,
1911 (double) rect.x, (double) rect.y, (double) rect.width, (double) rect.height);
1912
1913 theOp->m_radius = radius;
1914
1915 m_ops.Append(theOp);
1916}
1917
1918void wxPseudoMetaFile::DrawEllipse(const wxRect& rect)
1919{
1920 wxOpDraw *theOp = new wxOpDraw(DRAWOP_DRAW_ELLIPSE,
1921 (double) rect.x, (double) rect.y, (double) rect.width, (double) rect.height);
1922
1923 m_ops.Append(theOp);
1924}
1925
1926void wxPseudoMetaFile::DrawPoint(const wxPoint& pt)
1927{
1928 wxOpDraw *theOp = new wxOpDraw(DRAWOP_DRAW_POINT,
1929 (double) pt.x, (double) pt.y, 0.0, 0.0);
1930
1931 m_ops.Append(theOp);
1932}
1933
1934void wxPseudoMetaFile::DrawText(const wxString& text, const wxPoint& pt)
1935{
1936 wxOpDraw *theOp = new wxOpDraw(DRAWOP_DRAW_TEXT,
1937 (double) pt.x, (double) pt.y, 0.0, 0.0);
1938
1939 theOp->m_textString = copystring(text);
1940
1941 m_ops.Append(theOp);
1942}
1943
1944void wxPseudoMetaFile::DrawLines(int n, wxPoint pts[])
1945{
1946 wxRealPoint* realPoints = new wxRealPoint[n];
1947 int i;
1948 for (i = 0; i < n; i++)
1949 {
1950 realPoints[i].x = pts[i].x;
1951 realPoints[i].y = pts[i].y;
1952 }
1953 wxOpPolyDraw* theOp = new wxOpPolyDraw(DRAWOP_DRAW_POLYLINE, n, realPoints);
1954 m_ops.Append(theOp);
1955}
1956
1957void wxPseudoMetaFile::DrawPolygon(int n, wxPoint pts[])
1958{
1959 wxRealPoint* realPoints = new wxRealPoint[n];
1960 int i;
1961 for (i = 0; i < n; i++)
1962 {
1963 realPoints[i].x = pts[i].x;
1964 realPoints[i].y = pts[i].y;
1965 }
1966 wxOpPolyDraw* theOp = new wxOpPolyDraw(DRAWOP_DRAW_POLYGON, n, realPoints);
1967 m_ops.Append(theOp);
1968}
1969
1970void wxPseudoMetaFile::DrawSpline(int n, wxPoint pts[])
1971{
1972 wxRealPoint* realPoints = new wxRealPoint[n];
1973 int i;
1974 for (i = 0; i < n; i++)
1975 {
1976 realPoints[i].x = pts[i].x;
1977 realPoints[i].y = pts[i].y;
1978 }
1979 wxOpPolyDraw* theOp = new wxOpPolyDraw(DRAWOP_DRAW_SPLINE, n, realPoints);
1980 m_ops.Append(theOp);
1981}
1982
1983void wxPseudoMetaFile::SetClippingRect(const wxRect& rect)
1984{
1985 wxOpSetClipping* theOp = new wxOpSetClipping(DRAWOP_SET_CLIPPING_RECT,
1986 (double) rect.x, (double) rect.y, (double) rect.width, (double) rect.height);
1987}
1988
1989void wxPseudoMetaFile::DestroyClippingRect()
1990{
1991 wxOpSetClipping* theOp = new wxOpSetClipping(DRAWOP_DESTROY_CLIPPING_RECT,
1992 0.0, 0.0, 0.0, 0.0);
1993
1994 m_ops.Append(theOp);
1995}
1996
1997void wxPseudoMetaFile::SetPen(wxPen* pen, bool isOutline)
1998{
1999 m_gdiObjects.Append(pen);
2000 int n = m_gdiObjects.Number();
2001
2002 wxOpSetGDI* theOp = new wxOpSetGDI(DRAWOP_SET_PEN, this, n - 1);
2003
2004 m_ops.Append(theOp);
2005
2006 if (isOutline)
2007 {
2008 m_outlineColours.Append((wxObject*) (n - 1));
2009 }
2010}
2011
2012void wxPseudoMetaFile::SetBrush(wxBrush* brush, bool isFill)
2013{
2014 m_gdiObjects.Append(brush);
2015 int n = m_gdiObjects.Number();
2016
2017 wxOpSetGDI* theOp = new wxOpSetGDI(DRAWOP_SET_BRUSH, this, n - 1);
2018
2019 m_ops.Append(theOp);
2020
2021 if (isFill)
2022 {
2023 m_fillColours.Append((wxObject*) (n - 1));
2024 }
2025}
2026
2027void wxPseudoMetaFile::SetFont(wxFont* font)
2028{
2029 m_gdiObjects.Append(font);
2030 int n = m_gdiObjects.Number();
2031
2032 wxOpSetGDI* theOp = new wxOpSetGDI(DRAWOP_SET_FONT, this, n - 1);
2033
2034 m_ops.Append(theOp);
2035}
2036
2037void wxPseudoMetaFile::SetTextColour(const wxColour& colour)
2038{
2039 wxOpSetGDI* theOp = new wxOpSetGDI(DRAWOP_SET_TEXT_COLOUR, this, 0);
2040 theOp->m_r = colour.Red();
2041 theOp->m_g = colour.Green();
2042 theOp->m_b = colour.Blue();
2043
2044 m_ops.Append(theOp);
2045}
2046
2047void wxPseudoMetaFile::SetBackgroundColour(const wxColour& colour)
2048{
2049 wxOpSetGDI* theOp = new wxOpSetGDI(DRAWOP_SET_BK_COLOUR, this, 0);
2050 theOp->m_r = colour.Red();
2051 theOp->m_g = colour.Green();
2052 theOp->m_b = colour.Blue();
2053
2054 m_ops.Append(theOp);
2055}
2056
2057void wxPseudoMetaFile::SetBackgroundMode(int mode)
2058{
2059 wxOpSetGDI* theOp = new wxOpSetGDI(DRAWOP_SET_BK_MODE, this, 0, mode);
2060
2061 m_ops.Append(theOp);
2062}
0fc1a713 2063