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 #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();
323 p
= (wxPoint
*)node
->GetData();
328 node
= node
->GetNext();
329 p
= (wxPoint
*)node
->GetData();
333 cx1
= (double)((x1
+ x2
) / 2);
334 cy1
= (double)((y1
+ y2
) / 2);
335 cx2
= (double)((cx1
+ x2
) / 2);
336 cy2
= (double)((cy1
+ y2
) / 2);
338 wx_spline_add_point(x1
, y1
);
340 while ((node
= node
->GetNext())
346 p
= (wxPoint
*)node
->GetData();
351 cx4
= (double)(x1
+ x2
) / 2;
352 cy4
= (double)(y1
+ y2
) / 2;
353 cx3
= (double)(x1
+ cx4
) / 2;
354 cy3
= (double)(y1
+ cy4
) / 2;
356 wx_quadratic_spline(cx1
, cy1
, cx2
, cy2
, cx3
, cy3
, cx4
, cy4
);
360 cx2
= (double)(cx1
+ x2
) / 2;
361 cy2
= (double)(cy1
+ y2
) / 2;
364 wx_spline_add_point( cx1
, cy1
);
365 wx_spline_add_point( x2
, y2
);
367 wx_spline_draw_point_array( this );
370 #endif // wxUSE_SPLINES
372 // ----------------------------------------------------------------------------
373 // Partial Text Extents
374 // ----------------------------------------------------------------------------
377 // Each element of the widths array will be the width of the string up to and
378 // including the coresponding character in text. This is the generic
379 // implementation, the port-specific classes should do this with native APIs
380 // if available and if faster. Note: pango_layout_index_to_pos is much slower
381 // than calling GetTextExtent!!
388 FontWidthCache() : m_scaleX(1), m_widths(NULL
) { }
389 ~FontWidthCache() { delete []m_widths
; }
394 m_widths
= new int[FWC_SIZE
];
396 memset(m_widths
, 0, sizeof(int)*FWC_SIZE
);
404 static FontWidthCache s_fontWidthCache
;
406 bool wxDCBase::DoGetPartialTextExtents(const wxString
& text
, wxArrayInt
& widths
) const
410 size_t i
, len
= text
.Length();
415 // reset the cache if font or horizontal scale have changed
416 if (!s_fontWidthCache
.m_widths
||
417 (s_fontWidthCache
.m_scaleX
!= m_scaleX
) ||
418 (s_fontWidthCache
.m_font
!= GetFont()))
420 s_fontWidthCache
.Reset();
421 s_fontWidthCache
.m_font
= GetFont();
422 s_fontWidthCache
.m_scaleX
= m_scaleX
;
425 // Calculate the position of each character based on the widths of
426 // the previous characters
427 for (i
=0; i
<len
; i
++)
429 const wxChar c
= text
[i
];
430 unsigned int c_int
= (unsigned int)c
;
432 if ((c_int
< FWC_SIZE
) && (s_fontWidthCache
.m_widths
[c_int
] != 0))
434 w
= s_fontWidthCache
.m_widths
[c_int
];
438 GetTextExtent(c
, &w
, &h
);
439 if (c_int
< FWC_SIZE
)
440 s_fontWidthCache
.m_widths
[c_int
] = w
;
444 widths
[i
] = totalWidth
;
451 // ----------------------------------------------------------------------------
452 // enhanced text drawing
453 // ----------------------------------------------------------------------------
455 void wxDCBase::GetMultiLineTextExtent(const wxString
& text
,
461 wxCoord widthTextMax
= 0, widthLine
,
462 heightTextTotal
= 0, heightLineDefault
= 0, heightLine
= 0;
465 for ( const wxChar
*pc
= text
; ; pc
++ )
467 if ( *pc
== _T('\n') || *pc
== _T('\0') )
469 if ( curLine
.empty() )
471 // we can't use GetTextExtent - it will return 0 for both width
472 // and height and an empty line should count in height
475 // assume that this line has the same height as the previous
477 if ( !heightLineDefault
)
478 heightLineDefault
= heightLine
;
480 if ( !heightLineDefault
)
482 // but we don't know it yet - choose something reasonable
483 GetTextExtent(_T("W"), NULL
, &heightLineDefault
,
487 heightTextTotal
+= heightLineDefault
;
491 GetTextExtent(curLine
, &widthLine
, &heightLine
,
493 if ( widthLine
> widthTextMax
)
494 widthTextMax
= widthLine
;
495 heightTextTotal
+= heightLine
;
498 if ( *pc
== _T('\n') )
517 *y
= heightTextTotal
;
522 void wxDCBase::DrawLabel(const wxString
& text
,
523 const wxBitmap
& bitmap
,
527 wxRect
*rectBounding
)
529 // find the text position
530 wxCoord widthText
, heightText
, heightLine
;
531 GetMultiLineTextExtent(text
, &widthText
, &heightText
, &heightLine
);
533 wxCoord width
, height
;
536 width
= widthText
+ bitmap
.GetWidth();
537 height
= bitmap
.GetHeight();
546 if ( alignment
& wxALIGN_RIGHT
)
548 x
= rect
.GetRight() - width
;
550 else if ( alignment
& wxALIGN_CENTRE_HORIZONTAL
)
552 x
= (rect
.GetLeft() + rect
.GetRight() + 1 - width
) / 2;
554 else // alignment & wxALIGN_LEFT
559 if ( alignment
& wxALIGN_BOTTOM
)
561 y
= rect
.GetBottom() - height
;
563 else if ( alignment
& wxALIGN_CENTRE_VERTICAL
)
565 y
= (rect
.GetTop() + rect
.GetBottom() + 1 - height
) / 2;
567 else // alignment & wxALIGN_TOP
572 // draw the bitmap first
578 DrawBitmap(bitmap
, x
, y
, true /* use mask */);
580 wxCoord offset
= bitmap
.GetWidth() + 4;
584 y
+= (height
- heightText
) / 2;
587 // we will draw the underscore under the accel char later
588 wxCoord startUnderscore
= 0,
592 // split the string into lines and draw each of them separately
594 for ( const wxChar
*pc
= text
; ; pc
++ )
596 if ( *pc
== _T('\n') || *pc
== _T('\0') )
598 int xRealStart
= x
; // init it here to avoid compielr warnings
600 if ( !curLine
.empty() )
602 // NB: can't test for !(alignment & wxALIGN_LEFT) because
604 if ( alignment
& (wxALIGN_RIGHT
| wxALIGN_CENTRE_HORIZONTAL
) )
607 GetTextExtent(curLine
, &widthLine
, NULL
);
609 if ( alignment
& wxALIGN_RIGHT
)
611 xRealStart
+= width
- widthLine
;
613 else // if ( alignment & wxALIGN_CENTRE_HORIZONTAL )
615 xRealStart
+= (width
- widthLine
) / 2;
618 //else: left aligned, nothing to do
620 DrawText(curLine
, xRealStart
, y
);
625 // do we have underscore in this line? we can check yUnderscore
626 // because it is set below to just y + heightLine if we do
627 if ( y
== yUnderscore
)
629 // adjust the horz positions to account for the shift
630 startUnderscore
+= xRealStart
;
631 endUnderscore
+= xRealStart
;
634 if ( *pc
== _T('\0') )
639 else // not end of line
641 if ( pc
- text
.c_str() == indexAccel
)
643 // remeber to draw underscore here
644 GetTextExtent(curLine
, &startUnderscore
, NULL
);
646 GetTextExtent(curLine
, &endUnderscore
, NULL
);
648 yUnderscore
= y
+ heightLine
;
657 // draw the underscore if found
658 if ( startUnderscore
!= endUnderscore
)
660 // it should be of the same colour as text
661 SetPen(wxPen(GetTextForeground(), 0, wxSOLID
));
665 DrawLine(startUnderscore
, yUnderscore
, endUnderscore
, yUnderscore
);
668 // return bounding rect if requested
671 *rectBounding
= wxRect(x
, y
- heightText
, widthText
, heightText
);
674 CalcBoundingBox(x0
, y0
);
675 CalcBoundingBox(x0
+ width0
, y0
+ height
);
679 Notes for wxWidgets DrawEllipticArcRot(...)
681 wxDCBase::DrawEllipticArcRot(...) draws a rotated elliptic arc or an ellipse.
682 It uses wxDCBase::CalculateEllipticPoints(...) and wxDCBase::Rotate(...),
685 All methods are generic, so they can be implemented in wxDCBase.
686 DoDrawEllipticArcRot(...) is virtual, so it can be called from deeper
687 methods like (WinCE) wxDC::DoDrawArc(...).
689 CalculateEllipticPoints(...) fills a given list of wxPoints with some points
690 of an elliptic arc. The algorithm is pixel-based: In every row (in flat
691 parts) or every column (in steep parts) only one pixel is calculated.
692 Trigonometric calculation (sin, cos, tan, atan) is only done if the
693 starting angle is not equal to the ending angle. The calculation of the
694 pixels is done using simple arithmetic only and should perform not too
695 bad even on devices without floating point processor. I didn't test this yet.
697 Rotate(...) rotates a list of point pixel-based, you will see rounding errors.
698 For instance: an ellipse rotated 180 degrees is drawn
699 slightly different from the original.
701 The points are then moved to an array and used to draw a polyline and/or polygon
702 (with center added, the pie).
703 The result looks quite similar to the native ellipse, only e few pixels differ.
705 The performance on a desktop system (Athlon 1800, WinXP) is about 7 times
706 slower as DrawEllipse(...), which calls the native API.
707 An rotated ellipse outside the clipping region takes nearly the same time,
708 while an native ellipse outside takes nearly no time to draw.
710 If you draw an arc with this new method, you will see the starting and ending angles
711 are calculated properly.
712 If you use DrawEllipticArc(...), you will see they are only correct for circles
713 and not properly calculated for ellipses.
716 p.lenhard@t-online.de
720 void wxDCBase::DoDrawEllipticArcRot( wxCoord x
, wxCoord y
,
721 wxCoord w
, wxCoord h
,
722 double sa
, double ea
, double angle
)
726 CalculateEllipticPoints( &list
, x
, y
, w
, h
, sa
, ea
);
727 Rotate( &list
, angle
, wxPoint( x
+w
/2, y
+h
/2 ) );
729 // Add center (for polygon/pie)
730 list
.Append( (wxObject
*) new wxPoint( x
+w
/2, y
+h
/2 ) );
732 // copy list into array and delete list elements
733 int n
= list
.Number();
734 wxPoint
*points
= new wxPoint
[n
];
737 for ( node
= list
.First(); node
; node
= node
->Next(), i
++ )
739 wxPoint
*point
= (wxPoint
*)node
->Data();
740 points
[i
].x
= point
->x
;
741 points
[i
].y
= point
->y
;
745 // first draw the pie without pen, if necessary
746 if( GetBrush() != *wxTRANSPARENT_BRUSH
)
748 wxPen
tempPen( GetPen() );
749 SetPen( *wxTRANSPARENT_PEN
);
750 DoDrawPolygon( n
, points
, 0, 0 );
754 // then draw the arc without brush, if necessary
755 if( GetPen() != *wxTRANSPARENT_PEN
)
758 DoDrawLines( n
-1, points
, 0, 0 );
763 } // DrawEllipticArcRot
765 void wxDCBase::Rotate( wxList
* points
, double angle
, wxPoint center
)
769 double pi(3.1415926536);
770 double dSinA
= -sin(angle
*2.0*pi
/360.0);
771 double dCosA
= cos(angle
*2.0*pi
/360.0);
772 for ( wxNode
* node
= points
->First(); node
; node
= node
->Next() )
774 wxPoint
* point
= (wxPoint
*)node
->Data();
776 // transform coordinates, if necessary
777 if( center
.x
) point
->x
-= center
.x
;
778 if( center
.y
) point
->y
-= center
.y
;
780 // calculate rotation, rounding simply by implicit cast to integer
781 int xTemp
= point
->x
* dCosA
- point
->y
* dSinA
;
782 point
->y
= point
->x
* dSinA
+ point
->y
* dCosA
;
785 // back transform coordinates, if necessary
786 if( center
.x
) point
->x
+= center
.x
;
787 if( center
.y
) point
->y
+= center
.y
;
792 void wxDCBase::CalculateEllipticPoints( wxList
* points
,
793 wxCoord xStart
, wxCoord yStart
,
794 wxCoord w
, wxCoord h
,
795 double sa
, double ea
)
797 double pi
= 3.1415926535;
806 bool bUseAngles
= false;
812 // decrement 1 pixel if ellipse is smaller than 2*a, 2*b
814 if( 2*a
== w
) decrX
= 1;
816 if( 2*b
== h
) decrY
= 1;
818 wxCoord xCenter
= xStart
+ a
;
819 wxCoord yCenter
= yStart
+ b
;
820 // calculate data for start and end, if necessary
824 // normalisation of angles
825 while( sa
<0 ) sa
+= 360;
826 while( ea
<0 ) ea
+= 360;
827 while( sa
>=360 ) sa
-= 360;
828 while( ea
>=360 ) ea
-= 360;
829 // calculate quadrant numbers
830 if( sa
> 270 ) sq
= 3;
831 else if( sa
> 180 ) sq
= 2;
832 else if( sa
> 90 ) sq
= 1;
833 if( ea
> 270 ) eq
= 3;
834 else if( ea
> 180 ) eq
= 2;
835 else if( ea
> 90 ) eq
= 1;
836 sar
= sa
* pi
/ 180.0;
837 ear
= ea
* pi
/ 180.0;
838 // correct angle circle -> ellipse
839 sar
= atan( -a
/(double)b
* tan( sar
) );
840 if ( sq
== 1 || sq
== 2 ) sar
+= pi
;
841 ear
= atan( -a
/(double)b
* tan( ear
) );
842 if ( eq
== 1 || eq
== 2 ) ear
+= pi
;
843 // coordinates of points
844 xsa
= xCenter
+ a
* cos( sar
);
845 if( sq
== 0 || sq
== 3 ) xsa
-= decrX
;
846 ysa
= yCenter
+ b
* sin( sar
);
847 if( sq
== 2 || sq
== 3 ) ysa
-= decrY
;
848 xea
= xCenter
+ a
* cos( ear
);
849 if( eq
== 0 || eq
== 3 ) xea
-= decrX
;
850 yea
= yCenter
+ b
* sin( ear
);
851 if( eq
== 2 || eq
== 3 ) yea
-= decrY
;
853 // calculate c1 = b^2, c2 = b^2/a^2 with a = w/2, b = h/2
864 // Lists for quadrant 1 to 4
865 wxList pointsarray
[4];
866 // Calculate points for first quadrant and set in all quadrants
867 for( x
= 0; x
<= a
; ++x
)
872 bool bNewPoint
= false;
873 while( y2
> c1
- c2
* x2
&& y
> 0 )
879 // old y now to big: set point with old y, old x
880 if( bNewPoint
&& x
>1)
883 // remove points on the same line
884 pointsarray
[0].Insert( (wxObject
*) new wxPoint( xCenter
+ x1
- decrX
, yCenter
- y_old
) );
885 pointsarray
[1].Append( (wxObject
*) new wxPoint( xCenter
- x1
, yCenter
- y_old
) );
886 pointsarray
[2].Insert( (wxObject
*) new wxPoint( xCenter
- x1
, yCenter
+ y_old
- decrY
) );
887 pointsarray
[3].Append( (wxObject
*) new wxPoint( xCenter
+ x1
- decrX
, yCenter
+ y_old
- decrY
) );
891 // Starting and/or ending points for the quadrants, first quadrant gets both.
892 pointsarray
[0].Insert( (wxObject
*) new wxPoint( xCenter
+ a
- decrX
, yCenter
) );
893 pointsarray
[0].Append( (wxObject
*) new wxPoint( xCenter
, yCenter
- b
) );
894 pointsarray
[1].Append( (wxObject
*) new wxPoint( xCenter
- a
, yCenter
) );
895 pointsarray
[2].Append( (wxObject
*) new wxPoint( xCenter
, yCenter
+ b
- decrY
) );
896 pointsarray
[3].Append( (wxObject
*) new wxPoint( xCenter
+ a
- decrX
, yCenter
) );
898 // copy quadrants in original list
901 // Copy the right part of the points in the lists
902 // and delete the wxPoints, because they do not leave this method.
903 points
->Append( (wxObject
*) new wxPoint( xsa
, ysa
) );
905 bool bStarted
= false;
907 bool bForceTurn
= ( sq
== eq
&& sa
> ea
);
910 for( wxNode
*node
= pointsarray
[q
].First(); node
; node
= node
->Next() )
912 // once: go to starting point in start quadrant
915 ( (wxPoint
*) node
->Data() )->x
< xsa
+1 && q
<= 1
917 ( (wxPoint
*) node
->Data() )->x
> xsa
-1 && q
>= 2
924 // copy point, if not at ending point
927 if( q
!= eq
|| bForceTurn
929 ( (wxPoint
*) node
->Data() )->x
> xea
+1 && q
<= 1
931 ( (wxPoint
*) node
->Data() )->x
< xea
-1 && q
>= 2
935 wxPoint
* pPoint
= new wxPoint( *((wxPoint
*) node
->Data() ) );
936 points
->Append( (wxObject
*) pPoint
);
938 else if( q
== eq
&& !bForceTurn
|| ( (wxPoint
*) node
->Data() )->x
== xea
)
948 } // while not bReady
949 points
->Append( (wxObject
*) new wxPoint( xea
, yea
) );
952 for( q
= 0; q
< 4; ++q
)
954 for( wxNode
*node
= pointsarray
[q
].First(); node
; node
= node
->Next() )
956 wxPoint
*p
= (wxPoint
*)node
->Data();
963 // copy whole ellipse, wxPoints will be deleted outside
964 for( wxNode
*node
= pointsarray
[0].First(); node
; node
= node
->Next() )
966 wxObject
*p
= node
->Data();
969 for( node
= pointsarray
[1].First(); node
; node
= node
->Next() )
971 wxObject
*p
= node
->Data();
974 for( node
= pointsarray
[2].First(); node
; node
= node
->Next() )
976 wxObject
*p
= node
->Data();
979 for( node
= pointsarray
[3].First(); node
; node
= node
->Next() )
981 wxObject
*p
= node
->Data();
985 } // CalculateEllipticPoints