1 /////////////////////////////////////////////////////////////////////////////
2 // Name: common/dcbase.cpp
3 // Purpose: generic methods of the wxDC Class
4 // Author: Vadim Zeitlin
8 // Copyright: (c) wxWindows 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"
35 // bool wxDCBase::sm_cacheing = FALSE;
37 // ============================================================================
39 // ============================================================================
41 // ----------------------------------------------------------------------------
43 // ----------------------------------------------------------------------------
45 void wxDCBase::DoDrawCheckMark(wxCoord x1
, wxCoord y1
,
46 wxCoord width
, wxCoord height
)
48 wxCHECK_RET( Ok(), wxT("invalid window dc") );
50 wxCoord x2
= x1
+ width
,
53 // this is to yield width of 3 for width == height == 10
54 SetPen(wxPen(GetTextForeground(), (width
+ height
+ 1) / 7, wxSOLID
));
56 // we're drawing a scaled version of wx/generic/tick.xpm here
57 wxCoord x3
= x1
+ (4*width
) / 10, // x of the tick bottom
58 y3
= y1
+ height
/ 2; // y of the left tick branch
59 DoDrawLine(x1
, y3
, x3
, y2
);
60 DoDrawLine(x3
, y2
, x2
, y1
);
62 CalcBoundingBox(x1
, y1
);
63 CalcBoundingBox(x2
, y2
);
66 // ----------------------------------------------------------------------------
68 // ----------------------------------------------------------------------------
70 void wxDCBase::DrawLines(const wxList
*list
, wxCoord xoffset
, wxCoord yoffset
)
72 int n
= list
->GetCount();
73 wxPoint
*points
= new wxPoint
[n
];
76 for ( wxList::compatibility_iterator node
= list
->GetFirst(); node
; node
= node
->GetNext(), i
++ )
78 wxPoint
*point
= (wxPoint
*)node
->GetData();
79 points
[i
].x
= point
->x
;
80 points
[i
].y
= point
->y
;
83 DoDrawLines(n
, points
, xoffset
, yoffset
);
89 void wxDCBase::DrawPolygon(const wxList
*list
,
90 wxCoord xoffset
, wxCoord yoffset
,
93 int n
= list
->GetCount();
94 wxPoint
*points
= new wxPoint
[n
];
97 for ( wxList::compatibility_iterator node
= list
->GetFirst(); node
; node
= node
->GetNext(), i
++ )
99 wxPoint
*point
= (wxPoint
*)node
->GetData();
100 points
[i
].x
= point
->x
;
101 points
[i
].y
= point
->y
;
104 DoDrawPolygon(n
, points
, xoffset
, yoffset
, fillStyle
);
110 wxDCBase::DoDrawPolyPolygon(int n
,
113 wxCoord xoffset
, wxCoord yoffset
,
118 DoDrawPolygon(count
[0], points
, xoffset
, yoffset
, fillStyle
);
126 for (i
= j
= lastOfs
= 0; i
< n
; i
++)
131 pts
= new wxPoint
[j
+n
-1];
132 for (i
= 0; i
< j
; i
++)
134 for (i
= 2; i
<= n
; i
++)
136 lastOfs
-= count
[n
-i
];
137 pts
[j
++] = pts
[lastOfs
];
141 SetPen(wxPen(*wxBLACK
, 0, wxTRANSPARENT
));
142 DoDrawPolygon(j
, pts
, xoffset
, yoffset
, fillStyle
);
144 for (i
= j
= 0; i
< n
; i
++)
146 DoDrawLines(count
[i
], pts
+j
, xoffset
, yoffset
);
152 // ----------------------------------------------------------------------------
154 // ----------------------------------------------------------------------------
158 // TODO: this API needs fixing (wxPointList, why (!const) "wxList *"?)
159 void wxDCBase::DrawSpline(wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
, wxCoord x3
, wxCoord y3
)
163 wxPoint
*point1
= new wxPoint
;
164 point1
->x
= x1
; point1
->y
= y1
;
165 point_list
.Append((wxObject
*)point1
);
167 wxPoint
*point2
= new wxPoint
;
168 point2
->x
= x2
; point2
->y
= y2
;
169 point_list
.Append((wxObject
*)point2
);
171 wxPoint
*point3
= new wxPoint
;
172 point3
->x
= x3
; point3
->y
= y3
;
173 point_list
.Append((wxObject
*)point3
);
175 DrawSpline(&point_list
);
177 for( wxList::compatibility_iterator node
= point_list
.GetFirst(); node
; node
= node
->GetNext() )
179 wxPoint
*p
= (wxPoint
*)node
->GetData();
184 void wxDCBase::DrawSpline(int n
, wxPoint points
[])
187 for (int i
=0; i
< n
; i
++)
189 list
.Append((wxObject
*)&points
[i
]);
195 // ----------------------------------- spline code ----------------------------------------
197 void wx_quadratic_spline(double a1
, double b1
, double a2
, double b2
,
198 double a3
, double b3
, double a4
, double b4
);
199 void wx_clear_stack();
200 int wx_spline_pop(double *x1
, double *y1
, double *x2
, double *y2
, double *x3
,
201 double *y3
, double *x4
, double *y4
);
202 void wx_spline_push(double x1
, double y1
, double x2
, double y2
, double x3
, double y3
,
203 double x4
, double y4
);
204 static bool wx_spline_add_point(double x
, double y
);
205 static void wx_spline_draw_point_array(wxDCBase
*dc
);
207 wxList wx_spline_point_list
;
209 #define half(z1, z2) ((z1+z2)/2.0)
212 /* iterative version */
214 void wx_quadratic_spline(double a1
, double b1
, double a2
, double b2
, double a3
, double b3
, double a4
,
217 register double xmid
, ymid
;
218 double x1
, y1
, x2
, y2
, x3
, y3
, x4
, y4
;
221 wx_spline_push(a1
, b1
, a2
, b2
, a3
, b3
, a4
, b4
);
223 while (wx_spline_pop(&x1
, &y1
, &x2
, &y2
, &x3
, &y3
, &x4
, &y4
)) {
224 xmid
= (double)half(x2
, x3
);
225 ymid
= (double)half(y2
, y3
);
226 if (fabs(x1
- xmid
) < THRESHOLD
&& fabs(y1
- ymid
) < THRESHOLD
&&
227 fabs(xmid
- x4
) < THRESHOLD
&& fabs(ymid
- y4
) < THRESHOLD
) {
228 wx_spline_add_point( x1
, y1
);
229 wx_spline_add_point( xmid
, ymid
);
231 wx_spline_push(xmid
, ymid
, (double)half(xmid
, x3
), (double)half(ymid
, y3
),
232 (double)half(x3
, x4
), (double)half(y3
, y4
), x4
, y4
);
233 wx_spline_push(x1
, y1
, (double)half(x1
, x2
), (double)half(y1
, y2
),
234 (double)half(x2
, xmid
), (double)half(y2
, ymid
), xmid
, ymid
);
239 /* utilities used by spline drawing routines */
241 typedef struct wx_spline_stack_struct
{
242 double x1
, y1
, x2
, y2
, x3
, y3
, x4
, y4
;
245 #define SPLINE_STACK_DEPTH 20
246 static Stack wx_spline_stack
[SPLINE_STACK_DEPTH
];
247 static Stack
*wx_stack_top
;
248 static int wx_stack_count
;
250 void wx_clear_stack()
252 wx_stack_top
= wx_spline_stack
;
256 void wx_spline_push(double x1
, double y1
, double x2
, double y2
, double x3
, double y3
, double x4
, double y4
)
258 wx_stack_top
->x1
= x1
;
259 wx_stack_top
->y1
= y1
;
260 wx_stack_top
->x2
= x2
;
261 wx_stack_top
->y2
= y2
;
262 wx_stack_top
->x3
= x3
;
263 wx_stack_top
->y3
= y3
;
264 wx_stack_top
->x4
= x4
;
265 wx_stack_top
->y4
= y4
;
270 int wx_spline_pop(double *x1
, double *y1
, double *x2
, double *y2
,
271 double *x3
, double *y3
, double *x4
, double *y4
)
273 if (wx_stack_count
== 0)
277 *x1
= wx_stack_top
->x1
;
278 *y1
= wx_stack_top
->y1
;
279 *x2
= wx_stack_top
->x2
;
280 *y2
= wx_stack_top
->y2
;
281 *x3
= wx_stack_top
->x3
;
282 *y3
= wx_stack_top
->y3
;
283 *x4
= wx_stack_top
->x4
;
284 *y4
= wx_stack_top
->y4
;
288 static bool wx_spline_add_point(double x
, double y
)
290 wxPoint
*point
= new wxPoint
;
293 wx_spline_point_list
.Append((wxObject
*)point
);
297 static void wx_spline_draw_point_array(wxDCBase
*dc
)
299 dc
->DrawLines(&wx_spline_point_list
, 0, 0 );
300 wxList::compatibility_iterator node
= wx_spline_point_list
.GetFirst();
303 wxPoint
*point
= (wxPoint
*)node
->GetData();
305 wx_spline_point_list
.Erase(node
);
306 node
= wx_spline_point_list
.GetFirst();
310 void wxDCBase::DoDrawSpline( wxList
*points
)
312 wxCHECK_RET( Ok(), wxT("invalid window dc") );
315 double cx1
, cy1
, cx2
, cy2
, cx3
, cy3
, cx4
, cy4
;
316 double x1
, y1
, x2
, y2
;
318 wxList::compatibility_iterator node
= points
->GetFirst();
319 p
= (wxPoint
*)node
->GetData();
324 node
= node
->GetNext();
325 p
= (wxPoint
*)node
->GetData();
329 cx1
= (double)((x1
+ x2
) / 2);
330 cy1
= (double)((y1
+ y2
) / 2);
331 cx2
= (double)((cx1
+ x2
) / 2);
332 cy2
= (double)((cy1
+ y2
) / 2);
334 wx_spline_add_point(x1
, y1
);
336 while ((node
= node
->GetNext())
342 p
= (wxPoint
*)node
->GetData();
347 cx4
= (double)(x1
+ x2
) / 2;
348 cy4
= (double)(y1
+ y2
) / 2;
349 cx3
= (double)(x1
+ cx4
) / 2;
350 cy3
= (double)(y1
+ cy4
) / 2;
352 wx_quadratic_spline(cx1
, cy1
, cx2
, cy2
, cx3
, cy3
, cx4
, cy4
);
356 cx2
= (double)(cx1
+ x2
) / 2;
357 cy2
= (double)(cy1
+ y2
) / 2;
360 wx_spline_add_point( cx1
, cy1
);
361 wx_spline_add_point( x2
, y2
);
363 wx_spline_draw_point_array( this );
366 #endif // wxUSE_SPLINES
368 // ----------------------------------------------------------------------------
369 // Partial Text Extents
370 // ----------------------------------------------------------------------------
373 // Each element of the array will be the width of the string up to and
374 // including the coresoponding character in text. This is the generic
375 // implementation, the port-specific classes should do this with native APIs
378 bool wxDCBase::DoGetPartialTextExtents(const wxString
& text
, wxArrayInt
& widths
) const
384 widths
.Add(0, text
.Length());
386 // Calculate the position of each character based on the widths of
387 // the previous characters
388 for (i
=0; i
<text
.Length(); i
++) {
390 GetTextExtent(text
[i
], &w
, &h
);
392 widths
[i
] = totalWidth
;
398 // ----------------------------------------------------------------------------
399 // enhanced text drawing
400 // ----------------------------------------------------------------------------
402 void wxDCBase::GetMultiLineTextExtent(const wxString
& text
,
408 wxCoord widthTextMax
= 0, widthLine
,
409 heightTextTotal
= 0, heightLineDefault
= 0, heightLine
= 0;
412 for ( const wxChar
*pc
= text
; ; pc
++ )
414 if ( *pc
== _T('\n') || *pc
== _T('\0') )
416 if ( curLine
.empty() )
418 // we can't use GetTextExtent - it will return 0 for both width
419 // and height and an empty line should count in height
422 // assume that this line has the same height as the previous
424 if ( !heightLineDefault
)
425 heightLineDefault
= heightLine
;
427 if ( !heightLineDefault
)
429 // but we don't know it yet - choose something reasonable
430 GetTextExtent(_T("W"), NULL
, &heightLineDefault
,
434 heightTextTotal
+= heightLineDefault
;
438 GetTextExtent(curLine
, &widthLine
, &heightLine
,
440 if ( widthLine
> widthTextMax
)
441 widthTextMax
= widthLine
;
442 heightTextTotal
+= heightLine
;
445 if ( *pc
== _T('\n') )
464 *y
= heightTextTotal
;
469 void wxDCBase::DrawLabel(const wxString
& text
,
470 const wxBitmap
& bitmap
,
474 wxRect
*rectBounding
)
476 // find the text position
477 wxCoord widthText
, heightText
, heightLine
;
478 GetMultiLineTextExtent(text
, &widthText
, &heightText
, &heightLine
);
480 wxCoord width
, height
;
483 width
= widthText
+ bitmap
.GetWidth();
484 height
= bitmap
.GetHeight();
493 if ( alignment
& wxALIGN_RIGHT
)
495 x
= rect
.GetRight() - width
;
497 else if ( alignment
& wxALIGN_CENTRE_HORIZONTAL
)
499 x
= (rect
.GetLeft() + rect
.GetRight() + 1 - width
) / 2;
501 else // alignment & wxALIGN_LEFT
506 if ( alignment
& wxALIGN_BOTTOM
)
508 y
= rect
.GetBottom() - height
;
510 else if ( alignment
& wxALIGN_CENTRE_VERTICAL
)
512 y
= (rect
.GetTop() + rect
.GetBottom() + 1 - height
) / 2;
514 else // alignment & wxALIGN_TOP
519 // draw the bitmap first
525 DrawBitmap(bitmap
, x
, y
, TRUE
/* use mask */);
527 wxCoord offset
= bitmap
.GetWidth() + 4;
531 y
+= (height
- heightText
) / 2;
534 // we will draw the underscore under the accel char later
535 wxCoord startUnderscore
= 0,
539 // split the string into lines and draw each of them separately
541 for ( const wxChar
*pc
= text
; ; pc
++ )
543 if ( *pc
== _T('\n') || *pc
== _T('\0') )
545 int xRealStart
= x
; // init it here to avoid compielr warnings
547 if ( !curLine
.empty() )
549 // NB: can't test for !(alignment & wxALIGN_LEFT) because
551 if ( alignment
& (wxALIGN_RIGHT
| wxALIGN_CENTRE_HORIZONTAL
) )
554 GetTextExtent(curLine
, &widthLine
, NULL
);
556 if ( alignment
& wxALIGN_RIGHT
)
558 xRealStart
+= width
- widthLine
;
560 else // if ( alignment & wxALIGN_CENTRE_HORIZONTAL )
562 xRealStart
+= (width
- widthLine
) / 2;
565 //else: left aligned, nothing to do
567 DrawText(curLine
, xRealStart
, y
);
572 // do we have underscore in this line? we can check yUnderscore
573 // because it is set below to just y + heightLine if we do
574 if ( y
== yUnderscore
)
576 // adjust the horz positions to account for the shift
577 startUnderscore
+= xRealStart
;
578 endUnderscore
+= xRealStart
;
581 if ( *pc
== _T('\0') )
586 else // not end of line
588 if ( pc
- text
.c_str() == indexAccel
)
590 // remeber to draw underscore here
591 GetTextExtent(curLine
, &startUnderscore
, NULL
);
593 GetTextExtent(curLine
, &endUnderscore
, NULL
);
595 yUnderscore
= y
+ heightLine
;
604 // draw the underscore if found
605 if ( startUnderscore
!= endUnderscore
)
607 // it should be of the same colour as text
608 SetPen(wxPen(GetTextForeground(), 0, wxSOLID
));
612 DrawLine(startUnderscore
, yUnderscore
, endUnderscore
, yUnderscore
);
615 // return bounding rect if requested
618 *rectBounding
= wxRect(x
, y
- heightText
, widthText
, heightText
);
621 CalcBoundingBox(x0
, y0
);
622 CalcBoundingBox(x0
+ width0
, y0
+ height
);
626 Notes for wxWindows DrawEllipticArcRot(...)
628 wxDCBase::DrawEllipticArcRot(...) draws a rotated elliptic arc or an ellipse.
629 It uses wxDCBase::CalculateEllipticPoints(...) and wxDCBase::Rotate(...),
632 All methods are generic, so they can be implemented in wxDCBase.
633 DoDrawEllipticArcRot(...) is virtual, so it can be called from deeper
634 methods like (WinCE) wxDC::DoDrawArc(...).
636 CalculateEllipticPoints(...) fills a given list of wxPoints with some points
637 of an elliptic arc. The algorithm is pixel-based: In every row (in flat
638 parts) or every column (in steep parts) only one pixel is calculated.
639 Trigonometric calculation (sin, cos, tan, atan) is only done if the
640 starting angle is not equal to the ending angle. The calculation of the
641 pixels is done using simple arithmetic only and should perform not too
642 bad even on devices without floating point processor. I didn't test this yet.
644 Rotate(...) rotates a list of point pixel-based, you will see rounding errors.
645 For instance: an ellipse rotated 180 degrees is drawn
646 slightly different from the original.
648 The points are then moved to an array and used to draw a polyline and/or polygon
649 (with center added, the pie).
650 The result looks quite similar to the native ellipse, only e few pixels differ.
652 The performance on a desktop system (Athlon 1800, WinXP) is about 7 times
653 slower as DrawEllipse(...), which calls the native API.
654 An rotated ellipse outside the clipping region takes nearly the same time,
655 while an native ellipse outside takes nearly no time to draw.
657 If you draw an arc with this new method, you will see the starting and ending angles
658 are calculated properly.
659 If you use DrawEllipticArc(...), you will see they are only correct for circles
660 and not properly calculated for ellipses.
663 p.lenhard@t-online.de
667 void wxDCBase::DoDrawEllipticArcRot( wxCoord x
, wxCoord y
,
668 wxCoord w
, wxCoord h
,
669 double sa
, double ea
, double angle
)
673 CalculateEllipticPoints( &list
, x
, y
, w
, h
, sa
, ea
);
674 Rotate( &list
, angle
, wxPoint( x
+w
/2, y
+h
/2 ) );
676 // Add center (for polygon/pie)
677 list
.Append( (wxObject
*) new wxPoint( x
+w
/2, y
+h
/2 ) );
679 // copy list into array and delete list elements
680 int n
= list
.Number();
681 wxPoint
*points
= new wxPoint
[n
];
684 for ( node
= list
.First(); node
; node
= node
->Next(), i
++ )
686 wxPoint
*point
= (wxPoint
*)node
->Data();
687 points
[i
].x
= point
->x
;
688 points
[i
].y
= point
->y
;
692 // first draw the pie without pen, if necessary
693 if( GetBrush() != *wxTRANSPARENT_BRUSH
)
695 wxPen
tempPen( GetPen() );
696 SetPen( *wxTRANSPARENT_PEN
);
697 DoDrawPolygon( n
, points
, 0, 0 );
701 // then draw the arc without brush, if necessary
702 if( GetPen() != *wxTRANSPARENT_PEN
)
705 DoDrawLines( n
-1, points
, 0, 0 );
710 } // DrawEllipticArcRot
712 void wxDCBase::Rotate( wxList
* points
, double angle
, wxPoint center
)
716 double pi(3.1415926536);
717 double dSinA
= -sin(angle
*2.0*pi
/360.0);
718 double dCosA
= cos(angle
*2.0*pi
/360.0);
719 for ( wxNode
* node
= points
->First(); node
; node
= node
->Next() )
721 wxPoint
* point
= (wxPoint
*)node
->Data();
723 // transform coordinates, if necessary
724 if( center
.x
) point
->x
-= center
.x
;
725 if( center
.y
) point
->y
-= center
.y
;
727 // calculate rotation, rounding simply by implicit cast to integer
728 int xTemp
= point
->x
* dCosA
- point
->y
* dSinA
;
729 point
->y
= point
->x
* dSinA
+ point
->y
* dCosA
;
732 // back transform coordinates, if necessary
733 if( center
.x
) point
->x
+= center
.x
;
734 if( center
.y
) point
->y
+= center
.y
;
739 void wxDCBase::CalculateEllipticPoints( wxList
* points
,
740 wxCoord xStart
, wxCoord yStart
,
741 wxCoord w
, wxCoord h
,
742 double sa
, double ea
)
744 double pi
= 3.1415926535;
753 bool bUseAngles
= false;
759 // decrement 1 pixel if ellipse is smaller than 2*a, 2*b
761 if( 2*a
== w
) decrX
= 1;
763 if( 2*b
== h
) decrY
= 1;
765 wxCoord xCenter
= xStart
+ a
;
766 wxCoord yCenter
= yStart
+ b
;
767 // calculate data for start and end, if necessary
771 // normalisation of angles
772 while( sa
<0 ) sa
+= 360;
773 while( ea
<0 ) ea
+= 360;
774 while( sa
>=360 ) sa
-= 360;
775 while( ea
>=360 ) ea
-= 360;
776 // calculate quadrant numbers
777 if( sa
> 270 ) sq
= 3;
778 else if( sa
> 180 ) sq
= 2;
779 else if( sa
> 90 ) sq
= 1;
780 if( ea
> 270 ) eq
= 3;
781 else if( ea
> 180 ) eq
= 2;
782 else if( ea
> 90 ) eq
= 1;
783 sar
= sa
* pi
/ 180.0;
784 ear
= ea
* pi
/ 180.0;
785 // correct angle circle -> ellipse
786 sar
= atan( -a
/(double)b
* tan( sar
) );
787 if ( sq
== 1 || sq
== 2 ) sar
+= pi
;
788 ear
= atan( -a
/(double)b
* tan( ear
) );
789 if ( eq
== 1 || eq
== 2 ) ear
+= pi
;
790 // coordinates of points
791 xsa
= xCenter
+ a
* cos( sar
);
792 if( sq
== 0 || sq
== 3 ) xsa
-= decrX
;
793 ysa
= yCenter
+ b
* sin( sar
);
794 if( sq
== 2 || sq
== 3 ) ysa
-= decrY
;
795 xea
= xCenter
+ a
* cos( ear
);
796 if( eq
== 0 || eq
== 3 ) xea
-= decrX
;
797 yea
= yCenter
+ b
* sin( ear
);
798 if( eq
== 2 || eq
== 3 ) yea
-= decrY
;
800 // calculate c1 = b^2, c2 = b^2/a^2 with a = w/2, b = h/2
811 // Lists for quadrant 1 to 4
812 wxList pointsarray
[4];
813 // Calculate points for first quadrant and set in all quadrants
814 for( x
= 0; x
<= a
; ++x
)
819 bool bNewPoint
= false;
820 while( y2
> c1
- c2
* x2
&& y
> 0 )
826 // old y now to big: set point with old y, old x
827 if( bNewPoint
&& x
>1)
830 // remove points on the same line
831 pointsarray
[0].Insert( (wxObject
*) new wxPoint( xCenter
+ x1
- decrX
, yCenter
- y_old
) );
832 pointsarray
[1].Append( (wxObject
*) new wxPoint( xCenter
- x1
, yCenter
- y_old
) );
833 pointsarray
[2].Insert( (wxObject
*) new wxPoint( xCenter
- x1
, yCenter
+ y_old
- decrY
) );
834 pointsarray
[3].Append( (wxObject
*) new wxPoint( xCenter
+ x1
- decrX
, yCenter
+ y_old
- decrY
) );
838 // Starting and/or ending points for the quadrants, first quadrant gets both.
839 pointsarray
[0].Insert( (wxObject
*) new wxPoint( xCenter
+ a
- decrX
, yCenter
) );
840 pointsarray
[0].Append( (wxObject
*) new wxPoint( xCenter
, yCenter
- b
) );
841 pointsarray
[1].Append( (wxObject
*) new wxPoint( xCenter
- a
, yCenter
) );
842 pointsarray
[2].Append( (wxObject
*) new wxPoint( xCenter
, yCenter
+ b
- decrY
) );
843 pointsarray
[3].Append( (wxObject
*) new wxPoint( xCenter
+ a
- decrX
, yCenter
) );
845 // copy quadrants in original list
848 // Copy the right part of the points in the lists
849 // and delete the wxPoints, because they do not leave this method.
850 points
->Append( (wxObject
*) new wxPoint( xsa
, ysa
) );
852 bool bStarted
= false;
854 bool bForceTurn
= ( sq
== eq
&& sa
> ea
);
857 for( wxNode
*node
= pointsarray
[q
].First(); node
; node
= node
->Next() )
859 // once: go to starting point in start quadrant
862 ( (wxPoint
*) node
->Data() )->x
< xsa
+1 && q
<= 1
864 ( (wxPoint
*) node
->Data() )->x
> xsa
-1 && q
>= 2
871 // copy point, if not at ending point
874 if( q
!= eq
|| bForceTurn
876 ( (wxPoint
*) node
->Data() )->x
> xea
+1 && q
<= 1
878 ( (wxPoint
*) node
->Data() )->x
< xea
-1 && q
>= 2
882 wxPoint
* pPoint
= new wxPoint( *((wxPoint
*) node
->Data() ) );
883 points
->Append( (wxObject
*) pPoint
);
885 else if( q
== eq
&& !bForceTurn
|| ( (wxPoint
*) node
->Data() )->x
== xea
)
895 } // while not bReady
896 points
->Append( (wxObject
*) new wxPoint( xea
, yea
) );
899 for( q
= 0; q
< 4; ++q
)
901 for( wxNode
*node
= pointsarray
[q
].First(); node
; node
= node
->Next() )
903 wxPoint
*p
= (wxPoint
*)node
->Data();
911 // copy whole ellipse, wxPoints will be deleted outside
912 for( wxNode
*node
= pointsarray
[0].First(); node
; node
= node
->Next() )
914 wxObject
*p
= node
->Data();
917 for( node
= pointsarray
[1].First(); node
; node
= node
->Next() )
919 wxObject
*p
= node
->Data();
922 for( node
= pointsarray
[2].First(); node
; node
= node
->Next() )
924 wxObject
*p
= node
->Data();
927 for( node
= pointsarray
[3].First(); node
; node
= node
->Next() )
929 wxObject
*p
= node
->Data();
933 } // CalculateEllipticPoints