]> git.saurik.com Git - wxWidgets.git/blob - src/os2/dc.cpp
fix from Robert
[wxWidgets.git] / src / os2 / dc.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: dc.cpp
3 // Purpose: wxDC class
4 // Author: David Webster
5 // Modified by:
6 // Created: 10/14/99
7 // RCS-ID: $Id$
8 // Copyright: (c) David Webster
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
14
15 #ifndef WX_PRECOMP
16 #include "wx/window.h"
17 #include "wx/dc.h"
18 #include "wx/utils.h"
19 #include "wx/dialog.h"
20 #include "wx/app.h"
21 #include "wx/bitmap.h"
22 #include "wx/dcmemory.h"
23 #include "wx/log.h"
24 #include "wx/icon.h"
25 #endif
26
27 #include "wx/dcprint.h"
28
29 #include <string.h>
30 #include <math.h>
31
32 #include "wx/os2/private.h"
33
34 IMPLEMENT_ABSTRACT_CLASS(wxDC, wxObject)
35
36 // ---------------------------------------------------------------------------
37 // constants
38 // ---------------------------------------------------------------------------
39
40 static const int VIEWPORT_EXTENT = 1000;
41
42 static const int MM_POINTS = 9;
43 static const int MM_METRIC = 10;
44
45 // usually this is defined in math.h
46 #ifndef M_PI
47 static const double M_PI = 3.14159265358979323846;
48 #endif // M_PI
49
50 // ---------------------------------------------------------------------------
51 // private functions
52 // ---------------------------------------------------------------------------
53
54 // convert degrees to radians
55 static inline double DegToRad(double deg) { return (deg * M_PI) / 180.0; }
56
57 // ===========================================================================
58 // implementation
59 // ===========================================================================
60
61 // ---------------------------------------------------------------------------
62 // wxDC
63 // ---------------------------------------------------------------------------
64
65 wxDC::wxDC(void)
66 {
67 m_pCanvas = NULL;
68
69 m_hOldBitmap = 0;
70 m_hOldPen = 0;
71 m_hOldBrush = 0;
72 m_hOldFont = 0;
73 m_hOldPalette = 0;
74
75 m_bOwnsDC = FALSE;
76 m_hDC = 0;
77 m_nDCCount = 0;
78 };
79
80 wxDC::~wxDC(void)
81 {
82 // TODO:
83 };
84
85 // This will select current objects out of the DC,
86 // which is what you have to do before deleting the
87 // DC.
88 void wxDC::SelectOldObjects(WXHDC dc)
89 {
90 if (dc)
91 {
92 if (m_hOldBitmap)
93 {
94 // ::SelectObject((HDC) dc, (HBITMAP) m_oldBitmap);
95 if (m_vSelectedBitmap.Ok())
96 {
97 m_vSelectedBitmap.SetSelectedInto(NULL);
98 }
99 }
100 m_hOldBitmap = 0;
101 if (m_hOldPen)
102 {
103 // ::SelectObject((HDC) dc, (HPEN) m_oldPen);
104 }
105 m_hOldPen = 0;
106 if (m_hOldBrush)
107 {
108 // ::SelectObject((HDC) dc, (HBRUSH) m_oldBrush);
109 }
110 m_hOldBrush = 0;
111 if (m_hOldFont)
112 {
113 // ::SelectObject((HDC) dc, (HFONT) m_oldFont);
114 }
115 m_hOldFont = 0;
116 if (m_hOldPalette)
117 {
118 // ::SelectPalette((HDC) dc, (HPALETTE) m_oldPalette, TRUE);
119 }
120 m_hOldPalette = 0;
121 }
122
123 m_brush = wxNullBrush;
124 m_pen = wxNullPen;
125 m_palette = wxNullPalette;
126 m_font = wxNullFont;
127 m_backgroundBrush = wxNullBrush;
128 m_vSelectedBitmap = wxNullBitmap;
129 }
130
131 // ---------------------------------------------------------------------------
132 // clipping
133 // ---------------------------------------------------------------------------
134
135 #define DO_SET_CLIPPING_BOX() \
136 { \
137 RECT rect; \
138 \
139 GetClipBox(GetHdc(), &rect); \
140 \
141 m_clipX1 = (wxCoord) XDEV2LOG(rect.left); \
142 m_clipY1 = (wxCoord) YDEV2LOG(rect.top); \
143 m_clipX2 = (wxCoord) XDEV2LOG(rect.right); \
144 m_clipY2 = (wxCoord) YDEV2LOG(rect.bottom); \
145 }
146
147 void wxDC::DoSetClippingRegion( wxCoord x, wxCoord y
148 ,wxCoord width, wxCoord height
149 )
150 {
151 // TODO
152 }
153
154 void wxDC::DoSetClippingRegionAsRegion(const wxRegion& region)
155 {
156 // TODO
157 }
158
159 void wxDC::DestroyClippingRegion(void)
160 {
161 // TODO:
162 };
163
164 // ---------------------------------------------------------------------------
165 // query capabilities
166 // ---------------------------------------------------------------------------
167
168 bool wxDC::CanDrawBitmap() const
169 {
170 return TRUE;
171 }
172
173 bool wxDC::CanGetTextExtent() const
174 {
175 // What sort of display is it?
176 int technology = 0; // TODO: ::GetDeviceCaps(GetHdc(), TECHNOLOGY);
177
178 // TODO: return (technology == DT_RASDISPLAY) || (technology == DT_RASPRINTER);
179 return FALSE;
180 }
181
182 int wxDC::GetDepth() const
183 {
184 // TODO:
185 return (1);
186 }
187
188 // ---------------------------------------------------------------------------
189 // drawing
190 // ---------------------------------------------------------------------------
191
192 void wxDC::Clear()
193 {
194 // TODO
195 }
196
197 void wxDC::DoFloodFill( wxCoord x
198 ,wxCoord y
199 ,const wxColour& col
200 ,int style
201 )
202 {
203 // TODO
204 }
205
206 bool wxDC::DoGetPixel(wxCoord x, wxCoord y, wxColour *col) const
207 {
208 // TODO
209 return(TRUE);
210 }
211
212 void wxDC::DoCrossHair(wxCoord x, wxCoord y)
213 {
214 // TODO
215 }
216
217 void wxDC::DoDrawLine(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2)
218 {
219 // TODO
220 }
221
222 void wxDC::DoDrawArc( wxCoord x1, wxCoord y1
223 ,wxCoord x2, wxCoord y2
224 ,wxCoord xc, wxCoord yc
225 )
226 {
227 // TODO
228 }
229
230 void wxDC::DoDrawCheckMark(wxCoord x1, wxCoord y1,
231 wxCoord width, wxCoord height)
232 {
233 // TODO
234 }
235
236 void wxDC::DoDrawPoint(wxCoord x, wxCoord y)
237 {
238 // TODO
239 }
240
241 void wxDC::DoDrawPolygon(int n, wxPoint points[]
242 ,wxCoord xoffset, wxCoord yoffset
243 ,int fillStyle
244 )
245 {
246 // TODO
247 }
248
249 void wxDC::DoDrawLines( int n, wxPoint points[]
250 ,wxCoord xoffset, wxCoord yoffset
251 )
252 {
253 // TODO
254 }
255
256 void wxDC::DoDrawRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
257 {
258 // TODO
259 }
260
261 void wxDC::DoDrawRoundedRectangle( wxCoord x, wxCoord y
262 ,wxCoord width, wxCoord height
263 ,double radius
264 )
265 {
266 // TODO
267 }
268
269 void wxDC::DoDrawEllipse(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
270 {
271 // TODO
272 }
273
274 void wxDC::DoDrawEllipticArc( wxCoord x
275 ,wxCoord y
276 ,wxCoord w
277 ,wxCoord h
278 ,double sa
279 ,double ea
280 )
281 {
282 // TODO
283 }
284
285 void wxDC::DoDrawIcon(const wxIcon& icon, wxCoord x, wxCoord y)
286 {
287 // TODO
288 }
289
290 void wxDC::DoDrawBitmap( const wxBitmap &bmp
291 ,wxCoord x, wxCoord y
292 ,bool useMask
293 )
294 {
295 // TODO
296 }
297
298 void wxDC::DoDrawText(const wxString& text, wxCoord x, wxCoord y)
299 {
300 // TODO
301 }
302
303 void wxDC::DrawAnyText(const wxString& text, wxCoord x, wxCoord y)
304 {
305 // TODO
306 }
307
308 void wxDC::DoDrawRotatedText(const wxString& text,
309 wxCoord x, wxCoord y,
310 double angle)
311 {
312 // TODO:
313 /*
314 if ( angle == 0.0 )
315 {
316 DoDrawText(text, x, y);
317 }
318 else
319 {
320 LOGFONT lf;
321 wxFillLogFont(&lf, &m_font);
322
323 // GDI wants the angle in tenth of degree
324 long angle10 = (long)(angle * 10);
325 lf.lfEscapement = angle10;
326 lf. lfOrientation = angle10;
327
328 HFONT hfont = ::CreateFontIndirect(&lf);
329 if ( !hfont )
330 {
331 wxLogLastError("CreateFont");
332 }
333 else
334 {
335 HFONT hfontOld = ::SelectObject(GetHdc(), hfont);
336
337 DrawAnyText(text, x, y);
338
339 (void)::SelectObject(GetHdc(), hfontOld);
340 }
341
342 // call the bounding box by adding all four vertices of the rectangle
343 // containing the text to it (simpler and probably not slower than
344 // determining which of them is really topmost/leftmost/...)
345 wxCoord w, h;
346 GetTextExtent(text, &w, &h);
347
348 double rad = DegToRad(angle);
349
350 // "upper left" and "upper right"
351 CalcBoundingBox(x, y);
352 CalcBoundingBox(x + w*cos(rad), y - h*sin(rad));
353 CalcBoundingBox(x + h*sin(rad), y + h*cos(rad));
354
355 // "bottom left" and "bottom right"
356 x += (wxCoord)(h*sin(rad));
357 y += (wxCoord)(h*cos(rad));
358 CalcBoundingBox(x, y);
359 CalcBoundingBox(x + h*sin(rad), y + h*cos(rad));
360 }
361 */
362 }
363
364 // ---------------------------------------------------------------------------
365 // set GDI objects
366 // ---------------------------------------------------------------------------
367
368 void wxDC::SetPalette(const wxPalette& palette)
369 {
370 // TODO
371 }
372
373 void wxDC::SetFont(
374 const wxFont& rFont
375 )
376 {
377 //
378 // Set the old object temporarily, in case the assignment deletes an object
379 // that's not yet selected out.
380 //
381 if (m_hOldFont)
382 {
383 // ::SelectObject(GetHdc(), (HFONT) m_hOldFont);
384 m_hOldFont = 0;
385 }
386
387 m_font = rFont;
388
389 if (!rFont.Ok())
390 {
391 if (m_hOldFont)
392 // ::SelectObject(GetHdc(), (HFONT) m_hOldFont);
393 m_hOldFont = 0;
394 }
395
396 if (m_font.Ok() && m_font.GetResourceHandle())
397 {
398 HFONT hFont = (HFONT)0; //::SelectObject(GetHdc(), (HFONT) m_font.GetResourceHandle());
399 if (hFont == (HFONT) NULL)
400 {
401 wxLogDebug(wxT("::SelectObject failed in wxDC::SetFont."));
402 }
403 if (!m_hOldFont)
404 m_hOldFont = (WXHFONT) hFont;
405 }
406 }
407
408 void wxDC::SetPen(const wxPen& pen)
409 {
410 // TODO
411 }
412 void wxDC::SetBrush(const wxBrush& brush)
413 {
414 // TODO
415 }
416
417 void wxDC::SetBackground(const wxBrush& brush)
418 {
419 // TODO
420 }
421
422 void wxDC::SetBackgroundMode(int mode)
423 {
424 // TODO
425 }
426
427 void wxDC::SetLogicalFunction(int function)
428 {
429 // TODO
430 }
431
432 void wxDC::SetRop(WXHDC dc)
433 {
434 if (!dc || m_logicalFunction < 0)
435 return;
436
437 int c_rop;
438 // These may be wrong
439 switch (m_logicalFunction)
440 {
441 // TODO: Figure this stuff out
442 // case wxXOR: c_rop = R2_XORPEN; break;
443 // case wxXOR: c_rop = R2_NOTXORPEN; break;
444 // case wxINVERT: c_rop = R2_NOT; break;
445 // case wxOR_REVERSE: c_rop = R2_MERGEPENNOT; break;
446 // case wxAND_REVERSE: c_rop = R2_MASKPENNOT; break;
447 // case wxCLEAR: c_rop = R2_WHITE; break;
448 // case wxSET: c_rop = R2_BLACK; break;
449 // case wxSRC_INVERT: c_rop = R2_NOTCOPYPEN; break;
450 // case wxOR_INVERT: c_rop = R2_MERGENOTPEN; break;
451 // case wxAND: c_rop = R2_MASKPEN; break;
452 // case wxOR: c_rop = R2_MERGEPEN; break;
453 // case wxAND_INVERT: c_rop = R2_MASKNOTPEN; break;
454 // case wxEQUIV:
455 // case wxNAND:
456 // case wxCOPY:
457 default:
458 // c_rop = R2_COPYPEN;
459 break;
460 }
461 // SetROP2((HDC) dc, c_rop);
462 }
463
464 bool wxDC::StartDoc(const wxString& message)
465 {
466 // We might be previewing, so return TRUE to let it continue.
467 return TRUE;
468 }
469
470 void wxDC::EndDoc()
471 {
472 }
473
474 void wxDC::StartPage()
475 {
476 }
477
478 void wxDC::EndPage()
479 {
480 }
481
482 // ---------------------------------------------------------------------------
483 // text metrics
484 // ---------------------------------------------------------------------------
485
486 wxCoord wxDC::GetCharHeight() const
487 {
488 // TODO
489 return(1);
490 }
491
492 wxCoord wxDC::GetCharWidth() const
493 {
494 // TODO
495 return(1);
496 }
497
498 void wxDC::DoGetTextExtent( const wxString& string
499 ,wxCoord* x
500 ,wxCoord* y
501 ,wxCoord* decent
502 ,wxCoord* externalLeading
503 ,wxFont* theFont
504 ) const
505 {
506 // TODO:
507 }
508
509 void wxDC::SetMapMode( int mode )
510 {
511 // TODO:
512 };
513
514 void wxDC::SetUserScale(double x, double y)
515 {
516 m_userScaleX = x;
517 m_userScaleY = y;
518
519 SetMapMode(m_mappingMode);
520 }
521
522 void wxDC::SetAxisOrientation(bool xLeftRight, bool yBottomUp)
523 {
524 m_signX = xLeftRight ? 1 : -1;
525 m_signY = yBottomUp ? -1 : 1;
526
527 SetMapMode(m_mappingMode);
528 }
529
530 void wxDC::SetSystemScale(double x, double y)
531 {
532 m_scaleX = x;
533 m_scaleY = y;
534
535 SetMapMode(m_mappingMode);
536 }
537
538 void wxDC::SetLogicalOrigin( wxCoord x, wxCoord y )
539 {
540 // TODO:
541 };
542
543 void wxDC::SetDeviceOrigin( wxCoord x, wxCoord y )
544 {
545 // TODO:
546 };
547
548 // ---------------------------------------------------------------------------
549 // coordinates transformations
550 // ---------------------------------------------------------------------------
551
552 wxCoord wxDCBase::DeviceToLogicalX(wxCoord x) const
553 {
554 return (wxCoord) (((x) - m_deviceOriginX)/(m_logicalScaleX*m_userScaleX*m_signX*m_scaleX) - m_logicalOriginX);
555 }
556
557 wxCoord wxDCBase::DeviceToLogicalXRel(wxCoord x) const
558 {
559 return (wxCoord) ((x)/(m_logicalScaleX*m_userScaleX*m_signX*m_scaleX));
560 }
561
562 wxCoord wxDCBase::DeviceToLogicalY(wxCoord y) const
563 {
564 return (wxCoord) (((y) - m_deviceOriginY)/(m_logicalScaleY*m_userScaleY*m_signY*m_scaleY) - m_logicalOriginY);
565 }
566
567 wxCoord wxDCBase::DeviceToLogicalYRel(wxCoord y) const
568 {
569 return (wxCoord) ((y)/(m_logicalScaleY*m_userScaleY*m_signY*m_scaleY));
570 }
571
572 wxCoord wxDCBase::LogicalToDeviceX(wxCoord x) const
573 {
574 return (wxCoord) ((x - m_logicalOriginX)*m_logicalScaleX*m_userScaleX*m_signX*m_scaleX + m_deviceOriginX);
575 }
576
577 wxCoord wxDCBase::LogicalToDeviceXRel(wxCoord x) const
578 {
579 return (wxCoord) (x*m_logicalScaleX*m_userScaleX*m_signX*m_scaleX);
580 }
581
582 wxCoord wxDCBase::LogicalToDeviceY(wxCoord y) const
583 {
584 return (wxCoord) ((y - m_logicalOriginY)*m_logicalScaleY*m_userScaleY*m_signY*m_scaleY + m_deviceOriginY);
585 }
586
587 wxCoord wxDCBase::LogicalToDeviceYRel(wxCoord y) const
588 {
589 return (wxCoord) (y*m_logicalScaleY*m_userScaleY*m_signY*m_scaleY);
590 }
591
592 // ---------------------------------------------------------------------------
593 // bit blit
594 // ---------------------------------------------------------------------------
595
596 bool wxDC::DoBlit( wxCoord xdest
597 ,wxCoord ydest
598 ,wxCoord width
599 ,wxCoord height
600 ,wxDC *source
601 ,wxCoord xsrc
602 ,wxCoord ysrc
603 ,int rop
604 ,bool useMask
605 )
606 {
607 // TODO
608 return(TRUE);
609 }
610
611 void wxDC::DoGetSize( int* width, int* height ) const
612 {
613 // TODO:
614 };
615
616 void wxDC::DoGetSizeMM( int* width, int* height ) const
617 {
618 // TODO:
619 };
620
621 wxSize wxDC::GetPPI() const
622 {
623 int x = 1;
624 int y = 1;
625 // TODO:
626 return (wxSize(x,y));
627 }
628
629 void wxDC::SetLogicalScale( double x, double y )
630 {
631 // TODO:
632 };
633
634 #if WXWIN_COMPATIBILITY
635 void wxDC::DoGetTextExtent(const wxString& string, float *x, float *y,
636 float *descent, float *externalLeading,
637 wxFont *theFont, bool use16bit) const
638 {
639 wxCoord x1, y1, descent1, externalLeading1;
640 GetTextExtent(string, & x1, & y1, & descent1, & externalLeading1, theFont, use16bit);
641 *x = x1; *y = y1;
642 if (descent)
643 *descent = descent1;
644 if (externalLeading)
645 *externalLeading = externalLeading1;
646 }
647 #endif
648
649 // ---------------------------------------------------------------------------
650 // spline drawing code
651 // ---------------------------------------------------------------------------
652
653 #if wxUSE_SPLINES
654
655 class wxSpline: public wxObject
656 {
657 public:
658 int type;
659 wxList *points;
660
661 wxSpline(wxList *list);
662 void DeletePoints();
663
664 // Doesn't delete points
665 ~wxSpline();
666 };
667
668 void wx_draw_open_spline(wxDC *dc, wxSpline *spline);
669
670 void wx_quadratic_spline(double a1, double b1, double a2, double b2,
671 double a3, double b3, double a4, double b4);
672 void wx_clear_stack();
673 int wx_spline_pop(double *x1, double *y1, double *x2, double *y2, double *x3,
674 double *y3, double *x4, double *y4);
675 void wx_spline_push(double x1, double y1, double x2, double y2, double x3, double y3,
676 double x4, double y4);
677 static bool wx_spline_add_point(double x, double y);
678 static void wx_spline_draw_point_array(wxDC *dc);
679 wxSpline *wx_make_spline(int x1, int y1, int x2, int y2, int x3, int y3);
680
681 void wxDC::DoDrawSpline(wxList *list)
682 {
683 wxSpline spline(list);
684
685 wx_draw_open_spline(this, &spline);
686 }
687
688 wxList wx_spline_point_list;
689
690 void wx_draw_open_spline(wxDC *dc, wxSpline *spline)
691 {
692 wxPoint *p;
693 double cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4;
694 double x1, y1, x2, y2;
695
696 wxNode *node = spline->points->First();
697 p = (wxPoint *)node->Data();
698
699 x1 = p->x;
700 y1 = p->y;
701
702 node = node->Next();
703 p = (wxPoint *)node->Data();
704
705 x2 = p->x;
706 y2 = p->y;
707 cx1 = (double)((x1 + x2) / 2);
708 cy1 = (double)((y1 + y2) / 2);
709 cx2 = (double)((cx1 + x2) / 2);
710 cy2 = (double)((cy1 + y2) / 2);
711
712 wx_spline_add_point(x1, y1);
713
714 while ((node = node->Next()) != NULL)
715 {
716 p = (wxPoint *)node->Data();
717 x1 = x2;
718 y1 = y2;
719 x2 = p->x;
720 y2 = p->y;
721 cx4 = (double)(x1 + x2) / 2;
722 cy4 = (double)(y1 + y2) / 2;
723 cx3 = (double)(x1 + cx4) / 2;
724 cy3 = (double)(y1 + cy4) / 2;
725
726 wx_quadratic_spline(cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4);
727
728 cx1 = cx4;
729 cy1 = cy4;
730 cx2 = (double)(cx1 + x2) / 2;
731 cy2 = (double)(cy1 + y2) / 2;
732 }
733
734 wx_spline_add_point((double)wx_round(cx1), (double)wx_round(cy1));
735 wx_spline_add_point(x2, y2);
736
737 wx_spline_draw_point_array(dc);
738
739 }
740
741 /********************* CURVES FOR SPLINES *****************************
742
743 The following spline drawing routine is from
744
745 "An Algorithm for High-Speed Curve Generation"
746 by George Merrill Chaikin,
747 Computer Graphics and Image Processing, 3, Academic Press,
748 1974, 346-349.
749
750 and
751
752 "On Chaikin's Algorithm" by R. F. Riesenfeld,
753 Computer Graphics and Image Processing, 4, Academic Press,
754 1975, 304-310.
755
756 ***********************************************************************/
757
758 #define half(z1, z2) ((z1+z2)/2.0)
759 #define THRESHOLD 5
760
761 /* iterative version */
762
763 void wx_quadratic_spline(double a1, double b1, double a2, double b2, double a3, double b3, double a4,
764 double b4)
765 {
766 register double xmid, ymid;
767 double x1, y1, x2, y2, x3, y3, x4, y4;
768
769 wx_clear_stack();
770 wx_spline_push(a1, b1, a2, b2, a3, b3, a4, b4);
771
772 while (wx_spline_pop(&x1, &y1, &x2, &y2, &x3, &y3, &x4, &y4)) {
773 xmid = (double)half(x2, x3);
774 ymid = (double)half(y2, y3);
775 if (fabs(x1 - xmid) < THRESHOLD && fabs(y1 - ymid) < THRESHOLD &&
776 fabs(xmid - x4) < THRESHOLD && fabs(ymid - y4) < THRESHOLD) {
777 wx_spline_add_point((double)wx_round(x1), (double)wx_round(y1));
778 wx_spline_add_point((double)wx_round(xmid), (double)wx_round(ymid));
779 } else {
780 wx_spline_push(xmid, ymid, (double)half(xmid, x3), (double)half(ymid, y3),
781 (double)half(x3, x4), (double)half(y3, y4), x4, y4);
782 wx_spline_push(x1, y1, (double)half(x1, x2), (double)half(y1, y2),
783 (double)half(x2, xmid), (double)half(y2, ymid), xmid, ymid);
784 }
785 }
786 }
787
788
789 /* utilities used by spline drawing routines */
790
791
792 typedef struct wx_spline_stack_struct {
793 double x1, y1, x2, y2, x3, y3, x4, y4;
794 }
795 Stack;
796
797 #define SPLINE_STACK_DEPTH 20
798 static Stack wx_spline_stack[SPLINE_STACK_DEPTH];
799 static Stack *wx_stack_top;
800 static int wx_stack_count;
801
802 void wx_clear_stack()
803 {
804 wx_stack_top = wx_spline_stack;
805 wx_stack_count = 0;
806 }
807
808 void wx_spline_push(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4)
809 {
810 wx_stack_top->x1 = x1;
811 wx_stack_top->y1 = y1;
812 wx_stack_top->x2 = x2;
813 wx_stack_top->y2 = y2;
814 wx_stack_top->x3 = x3;
815 wx_stack_top->y3 = y3;
816 wx_stack_top->x4 = x4;
817 wx_stack_top->y4 = y4;
818 wx_stack_top++;
819 wx_stack_count++;
820 }
821
822 int wx_spline_pop(double *x1, double *y1, double *x2, double *y2,
823 double *x3, double *y3, double *x4, double *y4)
824 {
825 if (wx_stack_count == 0)
826 return (0);
827 wx_stack_top--;
828 wx_stack_count--;
829 *x1 = wx_stack_top->x1;
830 *y1 = wx_stack_top->y1;
831 *x2 = wx_stack_top->x2;
832 *y2 = wx_stack_top->y2;
833 *x3 = wx_stack_top->x3;
834 *y3 = wx_stack_top->y3;
835 *x4 = wx_stack_top->x4;
836 *y4 = wx_stack_top->y4;
837 return (1);
838 }
839
840 static bool wx_spline_add_point(double x, double y)
841 {
842 wxPoint *point = new wxPoint;
843 point->x = (int) x;
844 point->y = (int) y;
845 wx_spline_point_list.Append((wxObject*)point);
846 return TRUE;
847 }
848
849 static void wx_spline_draw_point_array(wxDC *dc)
850 {
851 dc->DrawLines(&wx_spline_point_list, 0, 0);
852 wxNode *node = wx_spline_point_list.First();
853 while (node)
854 {
855 wxPoint *point = (wxPoint *)node->Data();
856 delete point;
857 delete node;
858 node = wx_spline_point_list.First();
859 }
860 }
861
862 wxSpline::wxSpline(wxList *list)
863 {
864 points = list;
865 }
866
867 wxSpline::~wxSpline()
868 {
869 }
870
871 void wxSpline::DeletePoints()
872 {
873 for(wxNode *node = points->First(); node; node = points->First())
874 {
875 wxPoint *point = (wxPoint *)node->Data();
876 delete point;
877 delete node;
878 }
879 delete points;
880 }
881
882
883 #endif // wxUSE_SPLINES
884