1
/////////////////////////////////////////////////////////////////////////////
2
// Name: common/dcbase.cpp
3
// Purpose: generic methods of the wxDC Class
4
// Author: Vadim Zeitlin
7
// RCS-ID: $Id: dcbase.cpp,v 1.39.2.2 2006/03/15 08:50:46 JS Exp $
8
// Copyright: (c) wxWidgets team
9
// Licence: wxWindows licence
10
/////////////////////////////////////////////////////////////////////////////
12
// ============================================================================
14
// ============================================================================
16
#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
17
#pragma implementation "dcbase.h"
20
// ----------------------------------------------------------------------------
22
// ----------------------------------------------------------------------------
24
// For compilers that support precompilation, includes "wx.h".
25
#include "wx/wxprec.h"
33
// bool wxDCBase::sm_cacheing = false;
35
// ============================================================================
37
// ============================================================================
39
// ----------------------------------------------------------------------------
41
// ----------------------------------------------------------------------------
43
void wxDCBase::DoDrawCheckMark(wxCoord x1, wxCoord y1,
44
wxCoord width, wxCoord height)
46
wxCHECK_RET( Ok(), wxT("invalid window dc") );
48
wxCoord x2 = x1 + width,
51
// this is to yield width of 3 for width == height == 10
52
SetPen(wxPen(GetTextForeground(), (width + height + 1) / 7, wxSOLID));
54
// we're drawing a scaled version of wx/generic/tick.xpm here
55
wxCoord x3 = x1 + (4*width) / 10, // x of the tick bottom
56
y3 = y1 + height / 2; // y of the left tick branch
57
DoDrawLine(x1, y3, x3, y2);
58
DoDrawLine(x3, y2, x2, y1);
60
CalcBoundingBox(x1, y1);
61
CalcBoundingBox(x2, y2);
64
// ----------------------------------------------------------------------------
66
// ----------------------------------------------------------------------------
68
void wxDCBase::DrawLines(const wxList *list, wxCoord xoffset, wxCoord yoffset)
70
int n = list->GetCount();
71
wxPoint *points = new wxPoint[n];
74
for ( wxList::compatibility_iterator node = list->GetFirst(); node; node = node->GetNext(), i++ )
76
wxPoint *point = (wxPoint *)node->GetData();
77
points[i].x = point->x;
78
points[i].y = point->y;
81
DoDrawLines(n, points, xoffset, yoffset);
87
void wxDCBase::DrawPolygon(const wxList *list,
88
wxCoord xoffset, wxCoord yoffset,
91
int n = list->GetCount();
92
wxPoint *points = new wxPoint[n];
95
for ( wxList::compatibility_iterator node = list->GetFirst(); node; node = node->GetNext(), i++ )
97
wxPoint *point = (wxPoint *)node->GetData();
98
points[i].x = point->x;
99
points[i].y = point->y;
102
DoDrawPolygon(n, points, xoffset, yoffset, fillStyle);
108
wxDCBase::DoDrawPolyPolygon(int n,
111
wxCoord xoffset, wxCoord yoffset,
116
DoDrawPolygon(count[0], points, xoffset, yoffset, fillStyle);
124
for (i = j = lastOfs = 0; i < n; i++)
129
pts = new wxPoint[j+n-1];
130
for (i = 0; i < j; i++)
132
for (i = 2; i <= n; i++)
134
lastOfs -= count[n-i];
135
pts[j++] = pts[lastOfs];
139
SetPen(wxPen(*wxBLACK, 0, wxTRANSPARENT));
140
DoDrawPolygon(j, pts, xoffset, yoffset, fillStyle);
142
for (i = j = 0; i < n; i++)
144
DoDrawLines(count[i], pts+j, xoffset, yoffset);
150
// ----------------------------------------------------------------------------
152
// ----------------------------------------------------------------------------
156
// TODO: this API needs fixing (wxPointList, why (!const) "wxList *"?)
157
void wxDCBase::DrawSpline(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2, wxCoord x3, wxCoord y3)
161
wxPoint *point1 = new wxPoint;
162
point1->x = x1; point1->y = y1;
163
point_list.Append((wxObject*)point1);
165
wxPoint *point2 = new wxPoint;
166
point2->x = x2; point2->y = y2;
167
point_list.Append((wxObject*)point2);
169
wxPoint *point3 = new wxPoint;
170
point3->x = x3; point3->y = y3;
171
point_list.Append((wxObject*)point3);
173
DrawSpline(&point_list);
175
for( wxList::compatibility_iterator node = point_list.GetFirst(); node; node = node->GetNext() )
177
wxPoint *p = (wxPoint *)node->GetData();
182
void wxDCBase::DrawSpline(int n, wxPoint points[])
185
for (int i =0; i < n; i++)
187
list.Append((wxObject*)&points[i]);
193
// ----------------------------------- spline code ----------------------------------------
195
void wx_quadratic_spline(double a1, double b1, double a2, double b2,
196
double a3, double b3, double a4, double b4);
197
void wx_clear_stack();
198
int wx_spline_pop(double *x1, double *y1, double *x2, double *y2, double *x3,
199
double *y3, double *x4, double *y4);
200
void wx_spline_push(double x1, double y1, double x2, double y2, double x3, double y3,
201
double x4, double y4);
202
static bool wx_spline_add_point(double x, double y);
203
static void wx_spline_draw_point_array(wxDCBase *dc);
205
wxList wx_spline_point_list;
207
#define half(z1, z2) ((z1+z2)/2.0)
210
/* iterative version */
212
void wx_quadratic_spline(double a1, double b1, double a2, double b2, double a3, double b3, double a4,
215
register double xmid, ymid;
216
double x1, y1, x2, y2, x3, y3, x4, y4;
219
wx_spline_push(a1, b1, a2, b2, a3, b3, a4, b4);
221
while (wx_spline_pop(&x1, &y1, &x2, &y2, &x3, &y3, &x4, &y4)) {
222
xmid = (double)half(x2, x3);
223
ymid = (double)half(y2, y3);
224
if (fabs(x1 - xmid) < THRESHOLD && fabs(y1 - ymid) < THRESHOLD &&
225
fabs(xmid - x4) < THRESHOLD && fabs(ymid - y4) < THRESHOLD) {
226
wx_spline_add_point( x1, y1 );
227
wx_spline_add_point( xmid, ymid );
229
wx_spline_push(xmid, ymid, (double)half(xmid, x3), (double)half(ymid, y3),
230
(double)half(x3, x4), (double)half(y3, y4), x4, y4);
231
wx_spline_push(x1, y1, (double)half(x1, x2), (double)half(y1, y2),
232
(double)half(x2, xmid), (double)half(y2, ymid), xmid, ymid);
237
/* utilities used by spline drawing routines */
239
typedef struct wx_spline_stack_struct {
240
double x1, y1, x2, y2, x3, y3, x4, y4;
243
#define SPLINE_STACK_DEPTH 20
244
static Stack wx_spline_stack[SPLINE_STACK_DEPTH];
245
static Stack *wx_stack_top;
246
static int wx_stack_count;
248
void wx_clear_stack()
250
wx_stack_top = wx_spline_stack;
254
void wx_spline_push(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4)
256
wx_stack_top->x1 = x1;
257
wx_stack_top->y1 = y1;
258
wx_stack_top->x2 = x2;
259
wx_stack_top->y2 = y2;
260
wx_stack_top->x3 = x3;
261
wx_stack_top->y3 = y3;
262
wx_stack_top->x4 = x4;
263
wx_stack_top->y4 = y4;
268
int wx_spline_pop(double *x1, double *y1, double *x2, double *y2,
269
double *x3, double *y3, double *x4, double *y4)
271
if (wx_stack_count == 0)
275
*x1 = wx_stack_top->x1;
276
*y1 = wx_stack_top->y1;
277
*x2 = wx_stack_top->x2;
278
*y2 = wx_stack_top->y2;
279
*x3 = wx_stack_top->x3;
280
*y3 = wx_stack_top->y3;
281
*x4 = wx_stack_top->x4;
282
*y4 = wx_stack_top->y4;
286
static bool wx_spline_add_point(double x, double y)
288
wxPoint *point = new wxPoint ;
291
wx_spline_point_list.Append((wxObject*)point);
295
static void wx_spline_draw_point_array(wxDCBase *dc)
297
dc->DrawLines(&wx_spline_point_list, 0, 0 );
298
wxList::compatibility_iterator node = wx_spline_point_list.GetFirst();
301
wxPoint *point = (wxPoint *)node->GetData();
303
wx_spline_point_list.Erase(node);
304
node = wx_spline_point_list.GetFirst();
308
void wxDCBase::DoDrawSpline( wxList *points )
310
wxCHECK_RET( Ok(), wxT("invalid window dc") );
313
double cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4;
314
double x1, y1, x2, y2;
316
wxList::compatibility_iterator node = points->GetFirst();
317
if (node == wxList::compatibility_iterator())
321
p = (wxPoint *)node->GetData();
326
node = node->GetNext();
327
p = (wxPoint *)node->GetData();
331
cx1 = (double)((x1 + x2) / 2);
332
cy1 = (double)((y1 + y2) / 2);
333
cx2 = (double)((cx1 + x2) / 2);
334
cy2 = (double)((cy1 + y2) / 2);
336
wx_spline_add_point(x1, y1);
338
while ((node = node->GetNext())
344
p = (wxPoint *)node->GetData();
349
cx4 = (double)(x1 + x2) / 2;
350
cy4 = (double)(y1 + y2) / 2;
351
cx3 = (double)(x1 + cx4) / 2;
352
cy3 = (double)(y1 + cy4) / 2;
354
wx_quadratic_spline(cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4);
358
cx2 = (double)(cx1 + x2) / 2;
359
cy2 = (double)(cy1 + y2) / 2;
362
wx_spline_add_point( cx1, cy1 );
363
wx_spline_add_point( x2, y2 );
365
wx_spline_draw_point_array( this );
368
#endif // wxUSE_SPLINES
370
// ----------------------------------------------------------------------------
371
// Partial Text Extents
372
// ----------------------------------------------------------------------------
375
// Each element of the widths array will be the width of the string up to and
376
// including the corresponding character in text. This is the generic
377
// implementation, the port-specific classes should do this with native APIs
378
// if available and if faster. Note: pango_layout_index_to_pos is much slower
379
// than calling GetTextExtent!!
386
FontWidthCache() : m_scaleX(1), m_widths(NULL) { }
387
~FontWidthCache() { delete []m_widths; }
392
m_widths = new int[FWC_SIZE];
394
memset(m_widths, 0, sizeof(int)*FWC_SIZE);
402
static FontWidthCache s_fontWidthCache;
404
bool wxDCBase::DoGetPartialTextExtents(const wxString& text, wxArrayInt& widths) const
408
size_t i, len = text.Length();
413
// reset the cache if font or horizontal scale have changed
414
if (!s_fontWidthCache.m_widths ||
415
(s_fontWidthCache.m_scaleX != m_scaleX) ||
416
(s_fontWidthCache.m_font != GetFont()))
418
s_fontWidthCache.Reset();
419
s_fontWidthCache.m_font = GetFont();
420
s_fontWidthCache.m_scaleX = m_scaleX;
423
// Calculate the position of each character based on the widths of
424
// the previous characters
425
for (i=0; i<len; i++)
427
const wxChar c = text[i];
428
unsigned int c_int = (unsigned int)c;
430
if ((c_int < FWC_SIZE) && (s_fontWidthCache.m_widths[c_int] != 0))
432
w = s_fontWidthCache.m_widths[c_int];
436
GetTextExtent(c, &w, &h);
437
if (c_int < FWC_SIZE)
438
s_fontWidthCache.m_widths[c_int] = w;
442
widths[i] = totalWidth;
449
// ----------------------------------------------------------------------------
450
// enhanced text drawing
451
// ----------------------------------------------------------------------------
453
void wxDCBase::GetMultiLineTextExtent(const wxString& text,
459
wxCoord widthTextMax = 0, widthLine,
460
heightTextTotal = 0, heightLineDefault = 0, heightLine = 0;
463
for ( const wxChar *pc = text; ; pc++ )
465
if ( *pc == _T('\n') || *pc == _T('\0') )
467
if ( curLine.empty() )
469
// we can't use GetTextExtent - it will return 0 for both width
470
// and height and an empty line should count in height
473
// assume that this line has the same height as the previous
475
if ( !heightLineDefault )
476
heightLineDefault = heightLine;
478
if ( !heightLineDefault )
480
// but we don't know it yet - choose something reasonable
481
GetTextExtent(_T("W"), NULL, &heightLineDefault,
485
heightTextTotal += heightLineDefault;
489
GetTextExtent(curLine, &widthLine, &heightLine,
491
if ( widthLine > widthTextMax )
492
widthTextMax = widthLine;
493
heightTextTotal += heightLine;
496
if ( *pc == _T('\n') )
515
*y = heightTextTotal;
520
void wxDCBase::DrawLabel(const wxString& text,
521
const wxBitmap& bitmap,
525
wxRect *rectBounding)
527
// find the text position
528
wxCoord widthText, heightText, heightLine;
529
GetMultiLineTextExtent(text, &widthText, &heightText, &heightLine);
531
wxCoord width, height;
534
width = widthText + bitmap.GetWidth();
535
height = bitmap.GetHeight();
544
if ( alignment & wxALIGN_RIGHT )
546
x = rect.GetRight() - width;
548
else if ( alignment & wxALIGN_CENTRE_HORIZONTAL )
550
x = (rect.GetLeft() + rect.GetRight() + 1 - width) / 2;
552
else // alignment & wxALIGN_LEFT
557
if ( alignment & wxALIGN_BOTTOM )
559
y = rect.GetBottom() - height;
561
else if ( alignment & wxALIGN_CENTRE_VERTICAL )
563
y = (rect.GetTop() + rect.GetBottom() + 1 - height) / 2;
565
else // alignment & wxALIGN_TOP
570
// draw the bitmap first
576
DrawBitmap(bitmap, x, y, true /* use mask */);
578
wxCoord offset = bitmap.GetWidth() + 4;
582
y += (height - heightText) / 2;
585
// we will draw the underscore under the accel char later
586
wxCoord startUnderscore = 0,
590
// split the string into lines and draw each of them separately
592
for ( const wxChar *pc = text; ; pc++ )
594
if ( *pc == _T('\n') || *pc == _T('\0') )
596
int xRealStart = x; // init it here to avoid compielr warnings
598
if ( !curLine.empty() )
600
// NB: can't test for !(alignment & wxALIGN_LEFT) because
602
if ( alignment & (wxALIGN_RIGHT | wxALIGN_CENTRE_HORIZONTAL) )
605
GetTextExtent(curLine, &widthLine, NULL);
607
if ( alignment & wxALIGN_RIGHT )
609
xRealStart += width - widthLine;
611
else // if ( alignment & wxALIGN_CENTRE_HORIZONTAL )
613
xRealStart += (width - widthLine) / 2;
616
//else: left aligned, nothing to do
618
DrawText(curLine, xRealStart, y);
623
// do we have underscore in this line? we can check yUnderscore
624
// because it is set below to just y + heightLine if we do
625
if ( y == yUnderscore )
627
// adjust the horz positions to account for the shift
628
startUnderscore += xRealStart;
629
endUnderscore += xRealStart;
632
if ( *pc == _T('\0') )
637
else // not end of line
639
if ( pc - text.c_str() == indexAccel )
641
// remeber to draw underscore here
642
GetTextExtent(curLine, &startUnderscore, NULL);
644
GetTextExtent(curLine, &endUnderscore, NULL);
646
yUnderscore = y + heightLine;
655
// draw the underscore if found
656
if ( startUnderscore != endUnderscore )
658
// it should be of the same colour as text
659
SetPen(wxPen(GetTextForeground(), 0, wxSOLID));
663
DrawLine(startUnderscore, yUnderscore, endUnderscore, yUnderscore);
666
// return bounding rect if requested
669
*rectBounding = wxRect(x, y - heightText, widthText, heightText);
672
CalcBoundingBox(x0, y0);
673
CalcBoundingBox(x0 + width0, y0 + height);
677
Notes for wxWidgets DrawEllipticArcRot(...)
679
wxDCBase::DrawEllipticArcRot(...) draws a rotated elliptic arc or an ellipse.
680
It uses wxDCBase::CalculateEllipticPoints(...) and wxDCBase::Rotate(...),
683
All methods are generic, so they can be implemented in wxDCBase.
684
DoDrawEllipticArcRot(...) is virtual, so it can be called from deeper
685
methods like (WinCE) wxDC::DoDrawArc(...).
687
CalculateEllipticPoints(...) fills a given list of wxPoints with some points
688
of an elliptic arc. The algorithm is pixel-based: In every row (in flat
689
parts) or every column (in steep parts) only one pixel is calculated.
690
Trigonometric calculation (sin, cos, tan, atan) is only done if the
691
starting angle is not equal to the ending angle. The calculation of the
692
pixels is done using simple arithmetic only and should perform not too
693
bad even on devices without floating point processor. I didn't test this yet.
695
Rotate(...) rotates a list of point pixel-based, you will see rounding errors.
696
For instance: an ellipse rotated 180 degrees is drawn
697
slightly different from the original.
699
The points are then moved to an array and used to draw a polyline and/or polygon
700
(with center added, the pie).
701
The result looks quite similar to the native ellipse, only e few pixels differ.
703
The performance on a desktop system (Athlon 1800, WinXP) is about 7 times
704
slower as DrawEllipse(...), which calls the native API.
705
An rotated ellipse outside the clipping region takes nearly the same time,
706
while an native ellipse outside takes nearly no time to draw.
708
If you draw an arc with this new method, you will see the starting and ending angles
709
are calculated properly.
710
If you use DrawEllipticArc(...), you will see they are only correct for circles
711
and not properly calculated for ellipses.
714
p.lenhard@t-online.de
718
void wxDCBase::DoDrawEllipticArcRot( wxCoord x, wxCoord y,
719
wxCoord w, wxCoord h,
720
double sa, double ea, double angle )
724
CalculateEllipticPoints( &list, x, y, w, h, sa, ea );
725
Rotate( &list, angle, wxPoint( x+w/2, y+h/2 ) );
727
// Add center (for polygon/pie)
728
list.Append( (wxObject*) new wxPoint( x+w/2, y+h/2 ) );
730
// copy list into array and delete list elements
731
int n = list.GetCount();
732
wxPoint *points = new wxPoint[n];
735
for ( node = list.GetFirst(); node; node = node->GetNext(), i++ )
737
wxPoint *point = (wxPoint *)node->GetData();
738
points[i].x = point->x;
739
points[i].y = point->y;
743
// first draw the pie without pen, if necessary
744
if( GetBrush() != *wxTRANSPARENT_BRUSH )
746
wxPen tempPen( GetPen() );
747
SetPen( *wxTRANSPARENT_PEN );
748
DoDrawPolygon( n, points, 0, 0 );
752
// then draw the arc without brush, if necessary
753
if( GetPen() != *wxTRANSPARENT_PEN )
756
DoDrawLines( n-1, points, 0, 0 );
761
} // DrawEllipticArcRot
763
void wxDCBase::Rotate( wxList* points, double angle, wxPoint center )
768
double dSinA = -sin(angle*2.0*pi/360.0);
769
double dCosA = cos(angle*2.0*pi/360.0);
770
for ( wxNode* node = points->GetFirst(); node; node = node->GetNext() )
772
wxPoint* point = (wxPoint*)node->GetData();
774
// transform coordinates, if necessary
775
if( center.x ) point->x -= center.x;
776
if( center.y ) point->y -= center.y;
778
// calculate rotation, rounding simply by implicit cast to integer
779
int xTemp = point->x * dCosA - point->y * dSinA;
780
point->y = point->x * dSinA + point->y * dCosA;
783
// back transform coordinates, if necessary
784
if( center.x ) point->x += center.x;
785
if( center.y ) point->y += center.y;
790
void wxDCBase::CalculateEllipticPoints( wxList* points,
791
wxCoord xStart, wxCoord yStart,
792
wxCoord w, wxCoord h,
793
double sa, double ea )
804
bool bUseAngles = false;
810
// decrement 1 pixel if ellipse is smaller than 2*a, 2*b
812
if( 2*a == w ) decrX = 1;
814
if( 2*b == h ) decrY = 1;
816
wxCoord xCenter = xStart + a;
817
wxCoord yCenter = yStart + b;
818
// calculate data for start and end, if necessary
822
// normalisation of angles
823
while( sa<0 ) sa += 360;
824
while( ea<0 ) ea += 360;
825
while( sa>=360 ) sa -= 360;
826
while( ea>=360 ) ea -= 360;
827
// calculate quadrant numbers
828
if( sa > 270 ) sq = 3;
829
else if( sa > 180 ) sq = 2;
830
else if( sa > 90 ) sq = 1;
831
if( ea > 270 ) eq = 3;
832
else if( ea > 180 ) eq = 2;
833
else if( ea > 90 ) eq = 1;
834
sar = sa * pi / 180.0;
835
ear = ea * pi / 180.0;
836
// correct angle circle -> ellipse
837
sar = atan( -a/(double)b * tan( sar ) );
838
if ( sq == 1 || sq == 2 ) sar += pi;
839
ear = atan( -a/(double)b * tan( ear ) );
840
if ( eq == 1 || eq == 2 ) ear += pi;
841
// coordinates of points
842
xsa = xCenter + a * cos( sar );
843
if( sq == 0 || sq == 3 ) xsa -= decrX;
844
ysa = yCenter + b * sin( sar );
845
if( sq == 2 || sq == 3 ) ysa -= decrY;
846
xea = xCenter + a * cos( ear );
847
if( eq == 0 || eq == 3 ) xea -= decrX;
848
yea = yCenter + b * sin( ear );
849
if( eq == 2 || eq == 3 ) yea -= decrY;
851
// calculate c1 = b^2, c2 = b^2/a^2 with a = w/2, b = h/2
862
// Lists for quadrant 1 to 4
863
wxList pointsarray[4];
864
// Calculate points for first quadrant and set in all quadrants
865
for( x = 0; x <= a; ++x )
870
bool bNewPoint = false;
871
while( y2 > c1 - c2 * x2 && y > 0 )
877
// old y now to big: set point with old y, old x
878
if( bNewPoint && x>1)
881
// remove points on the same line
882
pointsarray[0].Insert( (wxObject*) new wxPoint( xCenter + x1 - decrX, yCenter - y_old ) );
883
pointsarray[1].Append( (wxObject*) new wxPoint( xCenter - x1, yCenter - y_old ) );
884
pointsarray[2].Insert( (wxObject*) new wxPoint( xCenter - x1, yCenter + y_old - decrY ) );
885
pointsarray[3].Append( (wxObject*) new wxPoint( xCenter + x1 - decrX, yCenter + y_old - decrY ) );
889
// Starting and/or ending points for the quadrants, first quadrant gets both.
890
pointsarray[0].Insert( (wxObject*) new wxPoint( xCenter + a - decrX, yCenter ) );
891
pointsarray[0].Append( (wxObject*) new wxPoint( xCenter, yCenter - b ) );
892
pointsarray[1].Append( (wxObject*) new wxPoint( xCenter - a, yCenter ) );
893
pointsarray[2].Append( (wxObject*) new wxPoint( xCenter, yCenter + b - decrY ) );
894
pointsarray[3].Append( (wxObject*) new wxPoint( xCenter + a - decrX, yCenter ) );
896
// copy quadrants in original list
899
// Copy the right part of the points in the lists
900
// and delete the wxPoints, because they do not leave this method.
901
points->Append( (wxObject*) new wxPoint( xsa, ysa ) );
903
bool bStarted = false;
905
bool bForceTurn = ( sq == eq && sa > ea );
908
for( wxNode *node = pointsarray[q].GetFirst(); node; node = node->GetNext() )
910
// once: go to starting point in start quadrant
913
( (wxPoint*) node->GetData() )->x < xsa+1 && q <= 1
915
( (wxPoint*) node->GetData() )->x > xsa-1 && q >= 2
922
// copy point, if not at ending point
925
if( q != eq || bForceTurn
927
( (wxPoint*) node->GetData() )->x > xea+1 && q <= 1
929
( (wxPoint*) node->GetData() )->x < xea-1 && q >= 2
933
wxPoint* pPoint = new wxPoint( *((wxPoint*) node->GetData() ) );
934
points->Append( (wxObject*) pPoint );
936
else if( q == eq && !bForceTurn || ( (wxPoint*) node->GetData() )->x == xea)
946
} // while not bReady
947
points->Append( (wxObject*) new wxPoint( xea, yea ) );
950
for( q = 0; q < 4; ++q )
952
for( wxNode *node = pointsarray[q].GetFirst(); node; node = node->GetNext() )
954
wxPoint *p = (wxPoint *)node->GetData();
962
// copy whole ellipse, wxPoints will be deleted outside
963
for( node = pointsarray[0].GetFirst(); node; node = node->GetNext() )
965
wxObject *p = node->GetData();
968
for( node = pointsarray[1].GetFirst(); node; node = node->GetNext() )
970
wxObject *p = node->GetData();
973
for( node = pointsarray[2].GetFirst(); node; node = node->GetNext() )
975
wxObject *p = node->GetData();
978
for( node = pointsarray[3].GetFirst(); node; node = node->GetNext() )
980
wxObject *p = node->GetData();
984
} // CalculateEllipticPoints