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