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