1 /////////////////////////////////////////////////////////////////////////////
2 // Name: common/dcbase.cpp
3 // Purpose: generic methods of the wxDC Class
4 // Author: Vadim Zeitlin
8 // Copyright: (c) wxWidgets team
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
29 // bool wxDCBase::sm_cacheing = false;
31 // ============================================================================
33 // ============================================================================
35 // ----------------------------------------------------------------------------
37 // ----------------------------------------------------------------------------
39 void wxDCBase::DoDrawCheckMark(wxCoord x1
, wxCoord y1
,
40 wxCoord width
, wxCoord height
)
42 wxCHECK_RET( Ok(), wxT("invalid window dc") );
44 wxCoord x2
= x1
+ width
,
47 // this is to yield width of 3 for width == height == 10
48 SetPen(wxPen(GetTextForeground(), (width
+ height
+ 1) / 7, wxSOLID
));
50 // we're drawing a scaled version of wx/generic/tick.xpm here
51 wxCoord x3
= x1
+ (4*width
) / 10, // x of the tick bottom
52 y3
= y1
+ height
/ 2; // y of the left tick branch
53 DoDrawLine(x1
, y3
, x3
, y2
);
54 DoDrawLine(x3
, y2
, x2
, y1
);
56 CalcBoundingBox(x1
, y1
);
57 CalcBoundingBox(x2
, y2
);
60 // ----------------------------------------------------------------------------
62 // ----------------------------------------------------------------------------
64 void wxDCBase::DrawLines(const wxList
*list
, wxCoord xoffset
, wxCoord yoffset
)
66 int n
= list
->GetCount();
67 wxPoint
*points
= new wxPoint
[n
];
70 for ( wxList::compatibility_iterator node
= list
->GetFirst(); node
; node
= node
->GetNext(), i
++ )
72 wxPoint
*point
= (wxPoint
*)node
->GetData();
73 points
[i
].x
= point
->x
;
74 points
[i
].y
= point
->y
;
77 DoDrawLines(n
, points
, xoffset
, yoffset
);
83 void wxDCBase::DrawPolygon(const wxList
*list
,
84 wxCoord xoffset
, wxCoord yoffset
,
87 int n
= list
->GetCount();
88 wxPoint
*points
= new wxPoint
[n
];
91 for ( wxList::compatibility_iterator node
= list
->GetFirst(); node
; node
= node
->GetNext(), i
++ )
93 wxPoint
*point
= (wxPoint
*)node
->GetData();
94 points
[i
].x
= point
->x
;
95 points
[i
].y
= point
->y
;
98 DoDrawPolygon(n
, points
, xoffset
, yoffset
, fillStyle
);
104 wxDCBase::DoDrawPolyPolygon(int n
,
107 wxCoord xoffset
, wxCoord yoffset
,
112 DoDrawPolygon(count
[0], points
, xoffset
, yoffset
, fillStyle
);
120 for (i
= j
= lastOfs
= 0; i
< n
; i
++)
125 pts
= new wxPoint
[j
+n
-1];
126 for (i
= 0; i
< j
; i
++)
128 for (i
= 2; i
<= n
; i
++)
130 lastOfs
-= count
[n
-i
];
131 pts
[j
++] = pts
[lastOfs
];
135 SetPen(wxPen(*wxBLACK
, 0, wxTRANSPARENT
));
136 DoDrawPolygon(j
, pts
, xoffset
, yoffset
, fillStyle
);
138 for (i
= j
= 0; i
< n
; i
++)
140 DoDrawLines(count
[i
], pts
+j
, xoffset
, yoffset
);
146 // ----------------------------------------------------------------------------
148 // ----------------------------------------------------------------------------
152 // TODO: this API needs fixing (wxPointList, why (!const) "wxList *"?)
153 void wxDCBase::DrawSpline(wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
, wxCoord x3
, wxCoord y3
)
157 wxPoint
*point1
= new wxPoint
;
158 point1
->x
= x1
; point1
->y
= y1
;
159 point_list
.Append((wxObject
*)point1
);
161 wxPoint
*point2
= new wxPoint
;
162 point2
->x
= x2
; point2
->y
= y2
;
163 point_list
.Append((wxObject
*)point2
);
165 wxPoint
*point3
= new wxPoint
;
166 point3
->x
= x3
; point3
->y
= y3
;
167 point_list
.Append((wxObject
*)point3
);
169 DrawSpline(&point_list
);
171 for( wxList::compatibility_iterator node
= point_list
.GetFirst(); node
; node
= node
->GetNext() )
173 wxPoint
*p
= (wxPoint
*)node
->GetData();
178 void wxDCBase::DrawSpline(int n
, wxPoint points
[])
181 for (int i
=0; i
< n
; i
++)
183 list
.Append((wxObject
*)&points
[i
]);
189 // ----------------------------------- spline code ----------------------------------------
191 void wx_quadratic_spline(double a1
, double b1
, double a2
, double b2
,
192 double a3
, double b3
, double a4
, double b4
);
193 void wx_clear_stack();
194 int wx_spline_pop(double *x1
, double *y1
, double *x2
, double *y2
, double *x3
,
195 double *y3
, double *x4
, double *y4
);
196 void wx_spline_push(double x1
, double y1
, double x2
, double y2
, double x3
, double y3
,
197 double x4
, double y4
);
198 static bool wx_spline_add_point(double x
, double y
);
199 static void wx_spline_draw_point_array(wxDCBase
*dc
);
201 wxList wx_spline_point_list
;
203 #define half(z1, z2) ((z1+z2)/2.0)
206 /* iterative version */
208 void wx_quadratic_spline(double a1
, double b1
, double a2
, double b2
, double a3
, double b3
, double a4
,
211 register double xmid
, ymid
;
212 double x1
, y1
, x2
, y2
, x3
, y3
, x4
, y4
;
215 wx_spline_push(a1
, b1
, a2
, b2
, a3
, b3
, a4
, b4
);
217 while (wx_spline_pop(&x1
, &y1
, &x2
, &y2
, &x3
, &y3
, &x4
, &y4
)) {
218 xmid
= (double)half(x2
, x3
);
219 ymid
= (double)half(y2
, y3
);
220 if (fabs(x1
- xmid
) < THRESHOLD
&& fabs(y1
- ymid
) < THRESHOLD
&&
221 fabs(xmid
- x4
) < THRESHOLD
&& fabs(ymid
- y4
) < THRESHOLD
) {
222 wx_spline_add_point( x1
, y1
);
223 wx_spline_add_point( xmid
, ymid
);
225 wx_spline_push(xmid
, ymid
, (double)half(xmid
, x3
), (double)half(ymid
, y3
),
226 (double)half(x3
, x4
), (double)half(y3
, y4
), x4
, y4
);
227 wx_spline_push(x1
, y1
, (double)half(x1
, x2
), (double)half(y1
, y2
),
228 (double)half(x2
, xmid
), (double)half(y2
, ymid
), xmid
, ymid
);
233 /* utilities used by spline drawing routines */
235 typedef struct wx_spline_stack_struct
{
236 double x1
, y1
, x2
, y2
, x3
, y3
, x4
, y4
;
239 #define SPLINE_STACK_DEPTH 20
240 static Stack wx_spline_stack
[SPLINE_STACK_DEPTH
];
241 static Stack
*wx_stack_top
;
242 static int wx_stack_count
;
244 void wx_clear_stack()
246 wx_stack_top
= wx_spline_stack
;
250 void wx_spline_push(double x1
, double y1
, double x2
, double y2
, double x3
, double y3
, double x4
, double y4
)
252 wx_stack_top
->x1
= x1
;
253 wx_stack_top
->y1
= y1
;
254 wx_stack_top
->x2
= x2
;
255 wx_stack_top
->y2
= y2
;
256 wx_stack_top
->x3
= x3
;
257 wx_stack_top
->y3
= y3
;
258 wx_stack_top
->x4
= x4
;
259 wx_stack_top
->y4
= y4
;
264 int wx_spline_pop(double *x1
, double *y1
, double *x2
, double *y2
,
265 double *x3
, double *y3
, double *x4
, double *y4
)
267 if (wx_stack_count
== 0)
271 *x1
= wx_stack_top
->x1
;
272 *y1
= wx_stack_top
->y1
;
273 *x2
= wx_stack_top
->x2
;
274 *y2
= wx_stack_top
->y2
;
275 *x3
= wx_stack_top
->x3
;
276 *y3
= wx_stack_top
->y3
;
277 *x4
= wx_stack_top
->x4
;
278 *y4
= wx_stack_top
->y4
;
282 static bool wx_spline_add_point(double x
, double y
)
284 wxPoint
*point
= new wxPoint
;
287 wx_spline_point_list
.Append((wxObject
*)point
);
291 static void wx_spline_draw_point_array(wxDCBase
*dc
)
293 dc
->DrawLines(&wx_spline_point_list
, 0, 0 );
294 wxList::compatibility_iterator node
= wx_spline_point_list
.GetFirst();
297 wxPoint
*point
= (wxPoint
*)node
->GetData();
299 wx_spline_point_list
.Erase(node
);
300 node
= wx_spline_point_list
.GetFirst();
304 void wxDCBase::DoDrawSpline( wxList
*points
)
306 wxCHECK_RET( Ok(), wxT("invalid window dc") );
309 double cx1
, cy1
, cx2
, cy2
, cx3
, cy3
, cx4
, cy4
;
310 double x1
, y1
, x2
, y2
;
312 wxList::compatibility_iterator node
= points
->GetFirst();
313 if (node
== wxList::compatibility_iterator())
317 p
= (wxPoint
*)node
->GetData();
322 node
= node
->GetNext();
323 p
= (wxPoint
*)node
->GetData();
327 cx1
= (double)((x1
+ x2
) / 2);
328 cy1
= (double)((y1
+ y2
) / 2);
329 cx2
= (double)((cx1
+ x2
) / 2);
330 cy2
= (double)((cy1
+ y2
) / 2);
332 wx_spline_add_point(x1
, y1
);
334 while ((node
= node
->GetNext())
340 p
= (wxPoint
*)node
->GetData();
345 cx4
= (double)(x1
+ x2
) / 2;
346 cy4
= (double)(y1
+ y2
) / 2;
347 cx3
= (double)(x1
+ cx4
) / 2;
348 cy3
= (double)(y1
+ cy4
) / 2;
350 wx_quadratic_spline(cx1
, cy1
, cx2
, cy2
, cx3
, cy3
, cx4
, cy4
);
354 cx2
= (double)(cx1
+ x2
) / 2;
355 cy2
= (double)(cy1
+ y2
) / 2;
358 wx_spline_add_point( cx1
, cy1
);
359 wx_spline_add_point( x2
, y2
);
361 wx_spline_draw_point_array( this );
364 #endif // wxUSE_SPLINES
366 // ----------------------------------------------------------------------------
367 // Partial Text Extents
368 // ----------------------------------------------------------------------------
371 // Each element of the widths array will be the width of the string up to and
372 // including the corresponding character in text. This is the generic
373 // implementation, the port-specific classes should do this with native APIs
374 // if available and if faster. Note: pango_layout_index_to_pos is much slower
375 // than calling GetTextExtent!!
382 FontWidthCache() : m_scaleX(1), m_widths(NULL
) { }
383 ~FontWidthCache() { delete []m_widths
; }
388 m_widths
= new int[FWC_SIZE
];
390 memset(m_widths
, 0, sizeof(int)*FWC_SIZE
);
398 static FontWidthCache s_fontWidthCache
;
400 bool wxDCBase::DoGetPartialTextExtents(const wxString
& text
, wxArrayInt
& widths
) const
404 size_t i
, len
= text
.Length();
409 // reset the cache if font or horizontal scale have changed
410 if (!s_fontWidthCache
.m_widths
||
411 (s_fontWidthCache
.m_scaleX
!= m_scaleX
) ||
412 (s_fontWidthCache
.m_font
!= GetFont()))
414 s_fontWidthCache
.Reset();
415 s_fontWidthCache
.m_font
= GetFont();
416 s_fontWidthCache
.m_scaleX
= m_scaleX
;
419 // Calculate the position of each character based on the widths of
420 // the previous characters
421 for (i
=0; i
<len
; i
++)
423 const wxChar c
= text
[i
];
424 unsigned int c_int
= (unsigned int)c
;
426 if ((c_int
< FWC_SIZE
) && (s_fontWidthCache
.m_widths
[c_int
] != 0))
428 w
= s_fontWidthCache
.m_widths
[c_int
];
432 GetTextExtent(c
, &w
, &h
);
433 if (c_int
< FWC_SIZE
)
434 s_fontWidthCache
.m_widths
[c_int
] = w
;
438 widths
[i
] = totalWidth
;
445 // ----------------------------------------------------------------------------
446 // enhanced text drawing
447 // ----------------------------------------------------------------------------
449 void wxDCBase::GetMultiLineTextExtent(const wxString
& text
,
455 wxCoord widthTextMax
= 0, widthLine
,
456 heightTextTotal
= 0, heightLineDefault
= 0, heightLine
= 0;
459 for ( const wxChar
*pc
= text
; ; pc
++ )
461 if ( *pc
== _T('\n') || *pc
== _T('\0') )
463 if ( curLine
.empty() )
465 // we can't use GetTextExtent - it will return 0 for both width
466 // and height and an empty line should count in height
469 // assume that this line has the same height as the previous
471 if ( !heightLineDefault
)
472 heightLineDefault
= heightLine
;
474 if ( !heightLineDefault
)
476 // but we don't know it yet - choose something reasonable
477 GetTextExtent(_T("W"), NULL
, &heightLineDefault
,
481 heightTextTotal
+= heightLineDefault
;
485 GetTextExtent(curLine
, &widthLine
, &heightLine
,
487 if ( widthLine
> widthTextMax
)
488 widthTextMax
= widthLine
;
489 heightTextTotal
+= heightLine
;
492 if ( *pc
== _T('\n') )
511 *y
= heightTextTotal
;
516 void wxDCBase::DrawLabel(const wxString
& text
,
517 const wxBitmap
& bitmap
,
521 wxRect
*rectBounding
)
523 // find the text position
524 wxCoord widthText
, heightText
, heightLine
;
525 GetMultiLineTextExtent(text
, &widthText
, &heightText
, &heightLine
);
527 wxCoord width
, height
;
530 width
= widthText
+ bitmap
.GetWidth();
531 height
= bitmap
.GetHeight();
540 if ( alignment
& wxALIGN_RIGHT
)
542 x
= rect
.GetRight() - width
;
544 else if ( alignment
& wxALIGN_CENTRE_HORIZONTAL
)
546 x
= (rect
.GetLeft() + rect
.GetRight() + 1 - width
) / 2;
548 else // alignment & wxALIGN_LEFT
553 if ( alignment
& wxALIGN_BOTTOM
)
555 y
= rect
.GetBottom() - height
;
557 else if ( alignment
& wxALIGN_CENTRE_VERTICAL
)
559 y
= (rect
.GetTop() + rect
.GetBottom() + 1 - height
) / 2;
561 else // alignment & wxALIGN_TOP
566 // draw the bitmap first
572 DrawBitmap(bitmap
, x
, y
, true /* use mask */);
574 wxCoord offset
= bitmap
.GetWidth() + 4;
578 y
+= (height
- heightText
) / 2;
581 // we will draw the underscore under the accel char later
582 wxCoord startUnderscore
= 0,
586 // split the string into lines and draw each of them separately
588 for ( const wxChar
*pc
= text
; ; pc
++ )
590 if ( *pc
== _T('\n') || *pc
== _T('\0') )
592 int xRealStart
= x
; // init it here to avoid compielr warnings
594 if ( !curLine
.empty() )
596 // NB: can't test for !(alignment & wxALIGN_LEFT) because
598 if ( alignment
& (wxALIGN_RIGHT
| wxALIGN_CENTRE_HORIZONTAL
) )
601 GetTextExtent(curLine
, &widthLine
, NULL
);
603 if ( alignment
& wxALIGN_RIGHT
)
605 xRealStart
+= width
- widthLine
;
607 else // if ( alignment & wxALIGN_CENTRE_HORIZONTAL )
609 xRealStart
+= (width
- widthLine
) / 2;
612 //else: left aligned, nothing to do
614 DrawText(curLine
, xRealStart
, y
);
619 // do we have underscore in this line? we can check yUnderscore
620 // because it is set below to just y + heightLine if we do
621 if ( y
== yUnderscore
)
623 // adjust the horz positions to account for the shift
624 startUnderscore
+= xRealStart
;
625 endUnderscore
+= xRealStart
;
628 if ( *pc
== _T('\0') )
633 else // not end of line
635 if ( pc
- text
.c_str() == indexAccel
)
637 // remeber to draw underscore here
638 GetTextExtent(curLine
, &startUnderscore
, NULL
);
640 GetTextExtent(curLine
, &endUnderscore
, NULL
);
642 yUnderscore
= y
+ heightLine
;
651 // draw the underscore if found
652 if ( startUnderscore
!= endUnderscore
)
654 // it should be of the same colour as text
655 SetPen(wxPen(GetTextForeground(), 0, wxSOLID
));
659 DrawLine(startUnderscore
, yUnderscore
, endUnderscore
, yUnderscore
);
662 // return bounding rect if requested
665 *rectBounding
= wxRect(x
, y
- heightText
, widthText
, heightText
);
668 CalcBoundingBox(x0
, y0
);
669 CalcBoundingBox(x0
+ width0
, y0
+ height
);
673 Notes for wxWidgets DrawEllipticArcRot(...)
675 wxDCBase::DrawEllipticArcRot(...) draws a rotated elliptic arc or an ellipse.
676 It uses wxDCBase::CalculateEllipticPoints(...) and wxDCBase::Rotate(...),
679 All methods are generic, so they can be implemented in wxDCBase.
680 DoDrawEllipticArcRot(...) is virtual, so it can be called from deeper
681 methods like (WinCE) wxDC::DoDrawArc(...).
683 CalculateEllipticPoints(...) fills a given list of wxPoints with some points
684 of an elliptic arc. The algorithm is pixel-based: In every row (in flat
685 parts) or every column (in steep parts) only one pixel is calculated.
686 Trigonometric calculation (sin, cos, tan, atan) is only done if the
687 starting angle is not equal to the ending angle. The calculation of the
688 pixels is done using simple arithmetic only and should perform not too
689 bad even on devices without floating point processor. I didn't test this yet.
691 Rotate(...) rotates a list of point pixel-based, you will see rounding errors.
692 For instance: an ellipse rotated 180 degrees is drawn
693 slightly different from the original.
695 The points are then moved to an array and used to draw a polyline and/or polygon
696 (with center added, the pie).
697 The result looks quite similar to the native ellipse, only e few pixels differ.
699 The performance on a desktop system (Athlon 1800, WinXP) is about 7 times
700 slower as DrawEllipse(...), which calls the native API.
701 An rotated ellipse outside the clipping region takes nearly the same time,
702 while an native ellipse outside takes nearly no time to draw.
704 If you draw an arc with this new method, you will see the starting and ending angles
705 are calculated properly.
706 If you use DrawEllipticArc(...), you will see they are only correct for circles
707 and not properly calculated for ellipses.
710 p.lenhard@t-online.de
714 void wxDCBase::DoDrawEllipticArcRot( wxCoord x
, wxCoord y
,
715 wxCoord w
, wxCoord h
,
716 double sa
, double ea
, double angle
)
720 CalculateEllipticPoints( &list
, x
, y
, w
, h
, sa
, ea
);
721 Rotate( &list
, angle
, wxPoint( x
+w
/2, y
+h
/2 ) );
723 // Add center (for polygon/pie)
724 list
.Append( (wxObject
*) new wxPoint( x
+w
/2, y
+h
/2 ) );
726 // copy list into array and delete list elements
727 int n
= list
.Number();
728 wxPoint
*points
= new wxPoint
[n
];
731 for ( node
= list
.First(); node
; node
= node
->Next(), i
++ )
733 wxPoint
*point
= (wxPoint
*)node
->Data();
734 points
[i
].x
= point
->x
;
735 points
[i
].y
= point
->y
;
739 // first draw the pie without pen, if necessary
740 if( GetBrush() != *wxTRANSPARENT_BRUSH
)
742 wxPen
tempPen( GetPen() );
743 SetPen( *wxTRANSPARENT_PEN
);
744 DoDrawPolygon( n
, points
, 0, 0 );
748 // then draw the arc without brush, if necessary
749 if( GetPen() != *wxTRANSPARENT_PEN
)
752 DoDrawLines( n
-1, points
, 0, 0 );
757 } // DrawEllipticArcRot
759 void wxDCBase::Rotate( wxList
* points
, double angle
, wxPoint center
)
764 double dSinA
= -sin(angle
*2.0*pi
/360.0);
765 double dCosA
= cos(angle
*2.0*pi
/360.0);
766 for ( wxNode
* node
= points
->First(); node
; node
= node
->Next() )
768 wxPoint
* point
= (wxPoint
*)node
->Data();
770 // transform coordinates, if necessary
771 if( center
.x
) point
->x
-= center
.x
;
772 if( center
.y
) point
->y
-= center
.y
;
774 // calculate rotation, rounding simply by implicit cast to integer
775 int xTemp
= point
->x
* dCosA
- point
->y
* dSinA
;
776 point
->y
= point
->x
* dSinA
+ point
->y
* dCosA
;
779 // back transform coordinates, if necessary
780 if( center
.x
) point
->x
+= center
.x
;
781 if( center
.y
) point
->y
+= center
.y
;
786 void wxDCBase::CalculateEllipticPoints( wxList
* points
,
787 wxCoord xStart
, wxCoord yStart
,
788 wxCoord w
, wxCoord h
,
789 double sa
, double ea
)
800 bool bUseAngles
= false;
806 // decrement 1 pixel if ellipse is smaller than 2*a, 2*b
808 if( 2*a
== w
) decrX
= 1;
810 if( 2*b
== h
) decrY
= 1;
812 wxCoord xCenter
= xStart
+ a
;
813 wxCoord yCenter
= yStart
+ b
;
814 // calculate data for start and end, if necessary
818 // normalisation of angles
819 while( sa
<0 ) sa
+= 360;
820 while( ea
<0 ) ea
+= 360;
821 while( sa
>=360 ) sa
-= 360;
822 while( ea
>=360 ) ea
-= 360;
823 // calculate quadrant numbers
824 if( sa
> 270 ) sq
= 3;
825 else if( sa
> 180 ) sq
= 2;
826 else if( sa
> 90 ) sq
= 1;
827 if( ea
> 270 ) eq
= 3;
828 else if( ea
> 180 ) eq
= 2;
829 else if( ea
> 90 ) eq
= 1;
830 sar
= sa
* pi
/ 180.0;
831 ear
= ea
* pi
/ 180.0;
832 // correct angle circle -> ellipse
833 sar
= atan( -a
/(double)b
* tan( sar
) );
834 if ( sq
== 1 || sq
== 2 ) sar
+= pi
;
835 ear
= atan( -a
/(double)b
* tan( ear
) );
836 if ( eq
== 1 || eq
== 2 ) ear
+= pi
;
837 // coordinates of points
838 xsa
= xCenter
+ a
* cos( sar
);
839 if( sq
== 0 || sq
== 3 ) xsa
-= decrX
;
840 ysa
= yCenter
+ b
* sin( sar
);
841 if( sq
== 2 || sq
== 3 ) ysa
-= decrY
;
842 xea
= xCenter
+ a
* cos( ear
);
843 if( eq
== 0 || eq
== 3 ) xea
-= decrX
;
844 yea
= yCenter
+ b
* sin( ear
);
845 if( eq
== 2 || eq
== 3 ) yea
-= decrY
;
847 // calculate c1 = b^2, c2 = b^2/a^2 with a = w/2, b = h/2
858 // Lists for quadrant 1 to 4
859 wxList pointsarray
[4];
860 // Calculate points for first quadrant and set in all quadrants
861 for( x
= 0; x
<= a
; ++x
)
866 bool bNewPoint
= false;
867 while( y2
> c1
- c2
* x2
&& y
> 0 )
873 // old y now to big: set point with old y, old x
874 if( bNewPoint
&& x
>1)
877 // remove points on the same line
878 pointsarray
[0].Insert( (wxObject
*) new wxPoint( xCenter
+ x1
- decrX
, yCenter
- y_old
) );
879 pointsarray
[1].Append( (wxObject
*) new wxPoint( xCenter
- x1
, yCenter
- y_old
) );
880 pointsarray
[2].Insert( (wxObject
*) new wxPoint( xCenter
- x1
, yCenter
+ y_old
- decrY
) );
881 pointsarray
[3].Append( (wxObject
*) new wxPoint( xCenter
+ x1
- decrX
, yCenter
+ y_old
- decrY
) );
885 // Starting and/or ending points for the quadrants, first quadrant gets both.
886 pointsarray
[0].Insert( (wxObject
*) new wxPoint( xCenter
+ a
- decrX
, yCenter
) );
887 pointsarray
[0].Append( (wxObject
*) new wxPoint( xCenter
, yCenter
- b
) );
888 pointsarray
[1].Append( (wxObject
*) new wxPoint( xCenter
- a
, yCenter
) );
889 pointsarray
[2].Append( (wxObject
*) new wxPoint( xCenter
, yCenter
+ b
- decrY
) );
890 pointsarray
[3].Append( (wxObject
*) new wxPoint( xCenter
+ a
- decrX
, yCenter
) );
892 // copy quadrants in original list
895 // Copy the right part of the points in the lists
896 // and delete the wxPoints, because they do not leave this method.
897 points
->Append( (wxObject
*) new wxPoint( xsa
, ysa
) );
899 bool bStarted
= false;
901 bool bForceTurn
= ( sq
== eq
&& sa
> ea
);
904 for( wxNode
*node
= pointsarray
[q
].First(); node
; node
= node
->Next() )
906 // once: go to starting point in start quadrant
909 ( (wxPoint
*) node
->Data() )->x
< xsa
+1 && q
<= 1
911 ( (wxPoint
*) node
->Data() )->x
> xsa
-1 && q
>= 2
918 // copy point, if not at ending point
921 if( q
!= eq
|| bForceTurn
923 ( (wxPoint
*) node
->Data() )->x
> xea
+1 && q
<= 1
925 ( (wxPoint
*) node
->Data() )->x
< xea
-1 && q
>= 2
929 wxPoint
* pPoint
= new wxPoint( *((wxPoint
*) node
->Data() ) );
930 points
->Append( (wxObject
*) pPoint
);
932 else if( q
== eq
&& !bForceTurn
|| ( (wxPoint
*) node
->Data() )->x
== xea
)
942 } // while not bReady
943 points
->Append( (wxObject
*) new wxPoint( xea
, yea
) );
946 for( q
= 0; q
< 4; ++q
)
948 for( wxNode
*node
= pointsarray
[q
].First(); node
; node
= node
->Next() )
950 wxPoint
*p
= (wxPoint
*)node
->Data();
957 // copy whole ellipse, wxPoints will be deleted outside
958 for( wxNode
*node
= pointsarray
[0].First(); node
; node
= node
->Next() )
960 wxObject
*p
= node
->Data();
963 for( node
= pointsarray
[1].First(); node
; node
= node
->Next() )
965 wxObject
*p
= node
->Data();
968 for( node
= pointsarray
[2].First(); node
; node
= node
->Next() )
970 wxObject
*p
= node
->Data();
973 for( node
= pointsarray
[3].First(); node
; node
= node
->Next() )
975 wxObject
*p
= node
->Data();
979 } // CalculateEllipticPoints