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