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"
30 // bool wxDCBase::sm_cacheing = false;
32 // ============================================================================
34 // ============================================================================
36 // ----------------------------------------------------------------------------
38 // ----------------------------------------------------------------------------
40 void wxDCBase::DoDrawCheckMark(wxCoord x1
, wxCoord y1
,
41 wxCoord width
, wxCoord height
)
43 wxCHECK_RET( Ok(), wxT("invalid window dc") );
45 wxCoord x2
= x1
+ width
,
48 // this is to yield width of 3 for width == height == 10
49 SetPen(wxPen(GetTextForeground(), (width
+ height
+ 1) / 7, wxSOLID
));
51 // we're drawing a scaled version of wx/generic/tick.xpm here
52 wxCoord x3
= x1
+ (4*width
) / 10, // x of the tick bottom
53 y3
= y1
+ height
/ 2; // y of the left tick branch
54 DoDrawLine(x1
, y3
, x3
, y2
);
55 DoDrawLine(x3
, y2
, x2
, y1
);
57 CalcBoundingBox(x1
, y1
);
58 CalcBoundingBox(x2
, y2
);
61 // ----------------------------------------------------------------------------
63 // ----------------------------------------------------------------------------
65 void wxDCBase::DrawLines(const wxList
*list
, wxCoord xoffset
, wxCoord yoffset
)
67 int n
= list
->GetCount();
68 wxPoint
*points
= new wxPoint
[n
];
71 for ( wxList::compatibility_iterator node
= list
->GetFirst(); node
; node
= node
->GetNext(), i
++ )
73 wxPoint
*point
= (wxPoint
*)node
->GetData();
74 points
[i
].x
= point
->x
;
75 points
[i
].y
= point
->y
;
78 DoDrawLines(n
, points
, xoffset
, yoffset
);
84 void wxDCBase::DrawPolygon(const wxList
*list
,
85 wxCoord xoffset
, wxCoord yoffset
,
88 int n
= list
->GetCount();
89 wxPoint
*points
= new wxPoint
[n
];
92 for ( wxList::compatibility_iterator node
= list
->GetFirst(); node
; node
= node
->GetNext(), i
++ )
94 wxPoint
*point
= (wxPoint
*)node
->GetData();
95 points
[i
].x
= point
->x
;
96 points
[i
].y
= point
->y
;
99 DoDrawPolygon(n
, points
, xoffset
, yoffset
, fillStyle
);
105 wxDCBase::DoDrawPolyPolygon(int n
,
108 wxCoord xoffset
, wxCoord yoffset
,
113 DoDrawPolygon(count
[0], points
, xoffset
, yoffset
, fillStyle
);
121 for (i
= j
= lastOfs
= 0; i
< n
; i
++)
126 pts
= new wxPoint
[j
+n
-1];
127 for (i
= 0; i
< j
; i
++)
129 for (i
= 2; i
<= n
; i
++)
131 lastOfs
-= count
[n
-i
];
132 pts
[j
++] = pts
[lastOfs
];
136 SetPen(wxPen(*wxBLACK
, 0, wxTRANSPARENT
));
137 DoDrawPolygon(j
, pts
, xoffset
, yoffset
, fillStyle
);
139 for (i
= j
= 0; i
< n
; i
++)
141 DoDrawLines(count
[i
], pts
+j
, xoffset
, yoffset
);
147 // ----------------------------------------------------------------------------
149 // ----------------------------------------------------------------------------
153 // TODO: this API needs fixing (wxPointList, why (!const) "wxList *"?)
154 void wxDCBase::DrawSpline(wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
, wxCoord x3
, wxCoord y3
)
158 wxPoint
*point1
= new wxPoint
;
159 point1
->x
= x1
; point1
->y
= y1
;
160 point_list
.Append((wxObject
*)point1
);
162 wxPoint
*point2
= new wxPoint
;
163 point2
->x
= x2
; point2
->y
= y2
;
164 point_list
.Append((wxObject
*)point2
);
166 wxPoint
*point3
= new wxPoint
;
167 point3
->x
= x3
; point3
->y
= y3
;
168 point_list
.Append((wxObject
*)point3
);
170 DrawSpline(&point_list
);
172 for( wxList::compatibility_iterator node
= point_list
.GetFirst(); node
; node
= node
->GetNext() )
174 wxPoint
*p
= (wxPoint
*)node
->GetData();
179 void wxDCBase::DrawSpline(int n
, wxPoint points
[])
182 for (int i
=0; i
< n
; i
++)
184 list
.Append((wxObject
*)&points
[i
]);
190 // ----------------------------------- spline code ----------------------------------------
192 void wx_quadratic_spline(double a1
, double b1
, double a2
, double b2
,
193 double a3
, double b3
, double a4
, double b4
);
194 void wx_clear_stack();
195 int wx_spline_pop(double *x1
, double *y1
, double *x2
, double *y2
, double *x3
,
196 double *y3
, double *x4
, double *y4
);
197 void wx_spline_push(double x1
, double y1
, double x2
, double y2
, double x3
, double y3
,
198 double x4
, double y4
);
199 static bool wx_spline_add_point(double x
, double y
);
200 static void wx_spline_draw_point_array(wxDCBase
*dc
);
202 wxList wx_spline_point_list
;
204 #define half(z1, z2) ((z1+z2)/2.0)
207 /* iterative version */
209 void wx_quadratic_spline(double a1
, double b1
, double a2
, double b2
, double a3
, double b3
, double a4
,
212 register double xmid
, ymid
;
213 double x1
, y1
, x2
, y2
, x3
, y3
, x4
, y4
;
216 wx_spline_push(a1
, b1
, a2
, b2
, a3
, b3
, a4
, b4
);
218 while (wx_spline_pop(&x1
, &y1
, &x2
, &y2
, &x3
, &y3
, &x4
, &y4
)) {
219 xmid
= (double)half(x2
, x3
);
220 ymid
= (double)half(y2
, y3
);
221 if (fabs(x1
- xmid
) < THRESHOLD
&& fabs(y1
- ymid
) < THRESHOLD
&&
222 fabs(xmid
- x4
) < THRESHOLD
&& fabs(ymid
- y4
) < THRESHOLD
) {
223 wx_spline_add_point( x1
, y1
);
224 wx_spline_add_point( xmid
, ymid
);
226 wx_spline_push(xmid
, ymid
, (double)half(xmid
, x3
), (double)half(ymid
, y3
),
227 (double)half(x3
, x4
), (double)half(y3
, y4
), x4
, y4
);
228 wx_spline_push(x1
, y1
, (double)half(x1
, x2
), (double)half(y1
, y2
),
229 (double)half(x2
, xmid
), (double)half(y2
, ymid
), xmid
, ymid
);
234 /* utilities used by spline drawing routines */
236 typedef struct wx_spline_stack_struct
{
237 double x1
, y1
, x2
, y2
, x3
, y3
, x4
, y4
;
240 #define SPLINE_STACK_DEPTH 20
241 static Stack wx_spline_stack
[SPLINE_STACK_DEPTH
];
242 static Stack
*wx_stack_top
;
243 static int wx_stack_count
;
245 void wx_clear_stack()
247 wx_stack_top
= wx_spline_stack
;
251 void wx_spline_push(double x1
, double y1
, double x2
, double y2
, double x3
, double y3
, double x4
, double y4
)
253 wx_stack_top
->x1
= x1
;
254 wx_stack_top
->y1
= y1
;
255 wx_stack_top
->x2
= x2
;
256 wx_stack_top
->y2
= y2
;
257 wx_stack_top
->x3
= x3
;
258 wx_stack_top
->y3
= y3
;
259 wx_stack_top
->x4
= x4
;
260 wx_stack_top
->y4
= y4
;
265 int wx_spline_pop(double *x1
, double *y1
, double *x2
, double *y2
,
266 double *x3
, double *y3
, double *x4
, double *y4
)
268 if (wx_stack_count
== 0)
272 *x1
= wx_stack_top
->x1
;
273 *y1
= wx_stack_top
->y1
;
274 *x2
= wx_stack_top
->x2
;
275 *y2
= wx_stack_top
->y2
;
276 *x3
= wx_stack_top
->x3
;
277 *y3
= wx_stack_top
->y3
;
278 *x4
= wx_stack_top
->x4
;
279 *y4
= wx_stack_top
->y4
;
283 static bool wx_spline_add_point(double x
, double y
)
285 wxPoint
*point
= new wxPoint
;
288 wx_spline_point_list
.Append((wxObject
*)point
);
292 static void wx_spline_draw_point_array(wxDCBase
*dc
)
294 dc
->DrawLines(&wx_spline_point_list
, 0, 0 );
295 wxList::compatibility_iterator node
= wx_spline_point_list
.GetFirst();
298 wxPoint
*point
= (wxPoint
*)node
->GetData();
300 wx_spline_point_list
.Erase(node
);
301 node
= wx_spline_point_list
.GetFirst();
305 void wxDCBase::DoDrawSpline( wxList
*points
)
307 wxCHECK_RET( Ok(), wxT("invalid window dc") );
310 double cx1
, cy1
, cx2
, cy2
, cx3
, cy3
, cx4
, cy4
;
311 double x1
, y1
, x2
, y2
;
313 wxList::compatibility_iterator node
= points
->GetFirst();
314 if (node
== wxList::compatibility_iterator())
318 p
= (wxPoint
*)node
->GetData();
323 node
= node
->GetNext();
324 p
= (wxPoint
*)node
->GetData();
328 cx1
= (double)((x1
+ x2
) / 2);
329 cy1
= (double)((y1
+ y2
) / 2);
330 cx2
= (double)((cx1
+ x2
) / 2);
331 cy2
= (double)((cy1
+ y2
) / 2);
333 wx_spline_add_point(x1
, y1
);
335 while ((node
= node
->GetNext())
341 p
= (wxPoint
*)node
->GetData();
346 cx4
= (double)(x1
+ x2
) / 2;
347 cy4
= (double)(y1
+ y2
) / 2;
348 cx3
= (double)(x1
+ cx4
) / 2;
349 cy3
= (double)(y1
+ cy4
) / 2;
351 wx_quadratic_spline(cx1
, cy1
, cx2
, cy2
, cx3
, cy3
, cx4
, cy4
);
355 cx2
= (double)(cx1
+ x2
) / 2;
356 cy2
= (double)(cy1
+ y2
) / 2;
359 wx_spline_add_point( cx1
, cy1
);
360 wx_spline_add_point( x2
, y2
);
362 wx_spline_draw_point_array( this );
365 #endif // wxUSE_SPLINES
367 // ----------------------------------------------------------------------------
368 // Partial Text Extents
369 // ----------------------------------------------------------------------------
372 // Each element of the widths array will be the width of the string up to and
373 // including the corresponding character in text. This is the generic
374 // implementation, the port-specific classes should do this with native APIs
375 // if available and if faster. Note: pango_layout_index_to_pos is much slower
376 // than calling GetTextExtent!!
383 FontWidthCache() : m_scaleX(1), m_widths(NULL
) { }
384 ~FontWidthCache() { delete []m_widths
; }
389 m_widths
= new int[FWC_SIZE
];
391 memset(m_widths
, 0, sizeof(int)*FWC_SIZE
);
399 static FontWidthCache s_fontWidthCache
;
401 bool wxDCBase::DoGetPartialTextExtents(const wxString
& text
, wxArrayInt
& widths
) const
405 const size_t len
= text
.Length();
409 // reset the cache if font or horizontal scale have changed
410 if ( !s_fontWidthCache
.m_widths
||
411 !wxIsSameDouble(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
422 for ( size_t i
= 0; i
< len
; i
++ )
424 const wxChar c
= text
[i
];
425 unsigned int c_int
= (unsigned int)c
;
427 if ((c_int
< FWC_SIZE
) && (s_fontWidthCache
.m_widths
[c_int
] != 0))
429 w
= s_fontWidthCache
.m_widths
[c_int
];
433 GetTextExtent(c
, &w
, &h
);
434 if (c_int
< FWC_SIZE
)
435 s_fontWidthCache
.m_widths
[c_int
] = w
;
439 widths
[i
] = totalWidth
;
446 // ----------------------------------------------------------------------------
447 // enhanced text drawing
448 // ----------------------------------------------------------------------------
450 void wxDCBase::GetMultiLineTextExtent(const wxString
& text
,
456 wxCoord widthTextMax
= 0, widthLine
,
457 heightTextTotal
= 0, heightLineDefault
= 0, heightLine
= 0;
460 for ( const wxChar
*pc
= text
; ; pc
++ )
462 if ( *pc
== _T('\n') || *pc
== _T('\0') )
464 if ( curLine
.empty() )
466 // we can't use GetTextExtent - it will return 0 for both width
467 // and height and an empty line should count in height
470 // assume that this line has the same height as the previous
472 if ( !heightLineDefault
)
473 heightLineDefault
= heightLine
;
475 if ( !heightLineDefault
)
477 // but we don't know it yet - choose something reasonable
478 GetTextExtent(_T("W"), NULL
, &heightLineDefault
,
482 heightTextTotal
+= heightLineDefault
;
486 GetTextExtent(curLine
, &widthLine
, &heightLine
,
488 if ( widthLine
> widthTextMax
)
489 widthTextMax
= widthLine
;
490 heightTextTotal
+= heightLine
;
493 if ( *pc
== _T('\n') )
512 *y
= heightTextTotal
;
517 void wxDCBase::DrawLabel(const wxString
& text
,
518 const wxBitmap
& bitmap
,
522 wxRect
*rectBounding
)
524 // find the text position
525 wxCoord widthText
, heightText
, heightLine
;
526 GetMultiLineTextExtent(text
, &widthText
, &heightText
, &heightLine
);
528 wxCoord width
, height
;
531 width
= widthText
+ bitmap
.GetWidth();
532 height
= bitmap
.GetHeight();
541 if ( alignment
& wxALIGN_RIGHT
)
543 x
= rect
.GetRight() - width
;
545 else if ( alignment
& wxALIGN_CENTRE_HORIZONTAL
)
547 x
= (rect
.GetLeft() + rect
.GetRight() + 1 - width
) / 2;
549 else // alignment & wxALIGN_LEFT
554 if ( alignment
& wxALIGN_BOTTOM
)
556 y
= rect
.GetBottom() - height
;
558 else if ( alignment
& wxALIGN_CENTRE_VERTICAL
)
560 y
= (rect
.GetTop() + rect
.GetBottom() + 1 - height
) / 2;
562 else // alignment & wxALIGN_TOP
567 // draw the bitmap first
573 DrawBitmap(bitmap
, x
, y
, true /* use mask */);
575 wxCoord offset
= bitmap
.GetWidth() + 4;
579 y
+= (height
- heightText
) / 2;
582 // we will draw the underscore under the accel char later
583 wxCoord startUnderscore
= 0,
587 // split the string into lines and draw each of them separately
589 for ( const wxChar
*pc
= text
; ; pc
++ )
591 if ( *pc
== _T('\n') || *pc
== _T('\0') )
593 int xRealStart
= x
; // init it here to avoid compielr warnings
595 if ( !curLine
.empty() )
597 // NB: can't test for !(alignment & wxALIGN_LEFT) because
599 if ( alignment
& (wxALIGN_RIGHT
| wxALIGN_CENTRE_HORIZONTAL
) )
602 GetTextExtent(curLine
, &widthLine
, NULL
);
604 if ( alignment
& wxALIGN_RIGHT
)
606 xRealStart
+= width
- widthLine
;
608 else // if ( alignment & wxALIGN_CENTRE_HORIZONTAL )
610 xRealStart
+= (width
- widthLine
) / 2;
613 //else: left aligned, nothing to do
615 DrawText(curLine
, xRealStart
, y
);
620 // do we have underscore in this line? we can check yUnderscore
621 // because it is set below to just y + heightLine if we do
622 if ( y
== yUnderscore
)
624 // adjust the horz positions to account for the shift
625 startUnderscore
+= xRealStart
;
626 endUnderscore
+= xRealStart
;
629 if ( *pc
== _T('\0') )
634 else // not end of line
636 if ( pc
- text
.c_str() == indexAccel
)
638 // remeber to draw underscore here
639 GetTextExtent(curLine
, &startUnderscore
, NULL
);
641 GetTextExtent(curLine
, &endUnderscore
, NULL
);
643 yUnderscore
= y
+ heightLine
;
652 // draw the underscore if found
653 if ( startUnderscore
!= endUnderscore
)
655 // it should be of the same colour as text
656 SetPen(wxPen(GetTextForeground(), 0, wxSOLID
));
660 DrawLine(startUnderscore
, yUnderscore
, endUnderscore
, yUnderscore
);
663 // return bounding rect if requested
666 *rectBounding
= wxRect(x
, y
- heightText
, widthText
, heightText
);
669 CalcBoundingBox(x0
, y0
);
670 CalcBoundingBox(x0
+ width0
, y0
+ height
);
674 Notes for wxWidgets DrawEllipticArcRot(...)
676 wxDCBase::DrawEllipticArcRot(...) draws a rotated elliptic arc or an ellipse.
677 It uses wxDCBase::CalculateEllipticPoints(...) and wxDCBase::Rotate(...),
680 All methods are generic, so they can be implemented in wxDCBase.
681 DoDrawEllipticArcRot(...) is virtual, so it can be called from deeper
682 methods like (WinCE) wxDC::DoDrawArc(...).
684 CalculateEllipticPoints(...) fills a given list of wxPoints with some points
685 of an elliptic arc. The algorithm is pixel-based: In every row (in flat
686 parts) or every column (in steep parts) only one pixel is calculated.
687 Trigonometric calculation (sin, cos, tan, atan) is only done if the
688 starting angle is not equal to the ending angle. The calculation of the
689 pixels is done using simple arithmetic only and should perform not too
690 bad even on devices without floating point processor. I didn't test this yet.
692 Rotate(...) rotates a list of point pixel-based, you will see rounding errors.
693 For instance: an ellipse rotated 180 degrees is drawn
694 slightly different from the original.
696 The points are then moved to an array and used to draw a polyline and/or polygon
697 (with center added, the pie).
698 The result looks quite similar to the native ellipse, only e few pixels differ.
700 The performance on a desktop system (Athlon 1800, WinXP) is about 7 times
701 slower as DrawEllipse(...), which calls the native API.
702 An rotated ellipse outside the clipping region takes nearly the same time,
703 while an native ellipse outside takes nearly no time to draw.
705 If you draw an arc with this new method, you will see the starting and ending angles
706 are calculated properly.
707 If you use DrawEllipticArc(...), you will see they are only correct for circles
708 and not properly calculated for ellipses.
711 p.lenhard@t-online.de
715 void wxDCBase::DoDrawEllipticArcRot( wxCoord x
, wxCoord y
,
716 wxCoord w
, wxCoord h
,
717 double sa
, double ea
, double angle
)
721 CalculateEllipticPoints( &list
, x
, y
, w
, h
, sa
, ea
);
722 Rotate( &list
, angle
, wxPoint( x
+w
/2, y
+h
/2 ) );
724 // Add center (for polygon/pie)
725 list
.Append( (wxObject
*) new wxPoint( x
+w
/2, y
+h
/2 ) );
727 // copy list into array and delete list elements
728 int n
= list
.Number();
729 wxPoint
*points
= new wxPoint
[n
];
732 for ( node
= list
.First(); node
; node
= node
->Next(), i
++ )
734 wxPoint
*point
= (wxPoint
*)node
->Data();
735 points
[i
].x
= point
->x
;
736 points
[i
].y
= point
->y
;
740 // first draw the pie without pen, if necessary
741 if( GetBrush() != *wxTRANSPARENT_BRUSH
)
743 wxPen
tempPen( GetPen() );
744 SetPen( *wxTRANSPARENT_PEN
);
745 DoDrawPolygon( n
, points
, 0, 0 );
749 // then draw the arc without brush, if necessary
750 if( GetPen() != *wxTRANSPARENT_PEN
)
753 DoDrawLines( n
-1, points
, 0, 0 );
758 } // DrawEllipticArcRot
760 void wxDCBase::Rotate( wxList
* points
, double angle
, wxPoint center
)
765 double dSinA
= -sin(angle
*2.0*pi
/360.0);
766 double dCosA
= cos(angle
*2.0*pi
/360.0);
767 for ( wxNode
* node
= points
->First(); node
; node
= node
->Next() )
769 wxPoint
* point
= (wxPoint
*)node
->Data();
771 // transform coordinates, if necessary
772 if( center
.x
) point
->x
-= center
.x
;
773 if( center
.y
) point
->y
-= center
.y
;
775 // calculate rotation, rounding simply by implicit cast to integer
776 int xTemp
= point
->x
* dCosA
- point
->y
* dSinA
;
777 point
->y
= point
->x
* dSinA
+ point
->y
* dCosA
;
780 // back transform coordinates, if necessary
781 if( center
.x
) point
->x
+= center
.x
;
782 if( center
.y
) point
->y
+= center
.y
;
787 void wxDCBase::CalculateEllipticPoints( wxList
* points
,
788 wxCoord xStart
, wxCoord yStart
,
789 wxCoord w
, wxCoord h
,
790 double sa
, double ea
)
801 bool bUseAngles
= false;
807 // decrement 1 pixel if ellipse is smaller than 2*a, 2*b
809 if( 2*a
== w
) decrX
= 1;
811 if( 2*b
== h
) decrY
= 1;
813 wxCoord xCenter
= xStart
+ a
;
814 wxCoord yCenter
= yStart
+ b
;
815 // calculate data for start and end, if necessary
819 // normalisation of angles
820 while( sa
<0 ) sa
+= 360;
821 while( ea
<0 ) ea
+= 360;
822 while( sa
>=360 ) sa
-= 360;
823 while( ea
>=360 ) ea
-= 360;
824 // calculate quadrant numbers
825 if( sa
> 270 ) sq
= 3;
826 else if( sa
> 180 ) sq
= 2;
827 else if( sa
> 90 ) sq
= 1;
828 if( ea
> 270 ) eq
= 3;
829 else if( ea
> 180 ) eq
= 2;
830 else if( ea
> 90 ) eq
= 1;
831 sar
= sa
* pi
/ 180.0;
832 ear
= ea
* pi
/ 180.0;
833 // correct angle circle -> ellipse
834 sar
= atan( -a
/(double)b
* tan( sar
) );
835 if ( sq
== 1 || sq
== 2 ) sar
+= pi
;
836 ear
= atan( -a
/(double)b
* tan( ear
) );
837 if ( eq
== 1 || eq
== 2 ) ear
+= pi
;
838 // coordinates of points
839 xsa
= xCenter
+ a
* cos( sar
);
840 if( sq
== 0 || sq
== 3 ) xsa
-= decrX
;
841 ysa
= yCenter
+ b
* sin( sar
);
842 if( sq
== 2 || sq
== 3 ) ysa
-= decrY
;
843 xea
= xCenter
+ a
* cos( ear
);
844 if( eq
== 0 || eq
== 3 ) xea
-= decrX
;
845 yea
= yCenter
+ b
* sin( ear
);
846 if( eq
== 2 || eq
== 3 ) yea
-= decrY
;
848 // calculate c1 = b^2, c2 = b^2/a^2 with a = w/2, b = h/2
859 // Lists for quadrant 1 to 4
860 wxList pointsarray
[4];
861 // Calculate points for first quadrant and set in all quadrants
862 for( x
= 0; x
<= a
; ++x
)
867 bool bNewPoint
= false;
868 while( y2
> c1
- c2
* x2
&& y
> 0 )
874 // old y now to big: set point with old y, old x
875 if( bNewPoint
&& x
>1)
878 // remove points on the same line
879 pointsarray
[0].Insert( (wxObject
*) new wxPoint( xCenter
+ x1
- decrX
, yCenter
- y_old
) );
880 pointsarray
[1].Append( (wxObject
*) new wxPoint( xCenter
- x1
, yCenter
- y_old
) );
881 pointsarray
[2].Insert( (wxObject
*) new wxPoint( xCenter
- x1
, yCenter
+ y_old
- decrY
) );
882 pointsarray
[3].Append( (wxObject
*) new wxPoint( xCenter
+ x1
- decrX
, yCenter
+ y_old
- decrY
) );
886 // Starting and/or ending points for the quadrants, first quadrant gets both.
887 pointsarray
[0].Insert( (wxObject
*) new wxPoint( xCenter
+ a
- decrX
, yCenter
) );
888 pointsarray
[0].Append( (wxObject
*) new wxPoint( xCenter
, yCenter
- b
) );
889 pointsarray
[1].Append( (wxObject
*) new wxPoint( xCenter
- a
, yCenter
) );
890 pointsarray
[2].Append( (wxObject
*) new wxPoint( xCenter
, yCenter
+ b
- decrY
) );
891 pointsarray
[3].Append( (wxObject
*) new wxPoint( xCenter
+ a
- decrX
, yCenter
) );
893 // copy quadrants in original list
896 // Copy the right part of the points in the lists
897 // and delete the wxPoints, because they do not leave this method.
898 points
->Append( (wxObject
*) new wxPoint( xsa
, ysa
) );
900 bool bStarted
= false;
902 bool bForceTurn
= ( sq
== eq
&& sa
> ea
);
905 for( wxNode
*node
= pointsarray
[q
].First(); node
; node
= node
->Next() )
907 // once: go to starting point in start quadrant
910 ( (wxPoint
*) node
->Data() )->x
< xsa
+1 && q
<= 1
912 ( (wxPoint
*) node
->Data() )->x
> xsa
-1 && q
>= 2
919 // copy point, if not at ending point
922 if( q
!= eq
|| bForceTurn
924 ( (wxPoint
*) node
->Data() )->x
> xea
+1 && q
<= 1
926 ( (wxPoint
*) node
->Data() )->x
< xea
-1 && q
>= 2
930 wxPoint
* pPoint
= new wxPoint( *((wxPoint
*) node
->Data() ) );
931 points
->Append( (wxObject
*) pPoint
);
933 else if( q
== eq
&& !bForceTurn
|| ( (wxPoint
*) node
->Data() )->x
== xea
)
943 } // while not bReady
944 points
->Append( (wxObject
*) new wxPoint( xea
, yea
) );
947 for( q
= 0; q
< 4; ++q
)
949 for( wxNode
*node
= pointsarray
[q
].First(); node
; node
= node
->Next() )
951 wxPoint
*p
= (wxPoint
*)node
->Data();
958 // copy whole ellipse, wxPoints will be deleted outside
959 for( wxNode
*node
= pointsarray
[0].First(); node
; node
= node
->Next() )
961 wxObject
*p
= node
->Data();
964 for( node
= pointsarray
[1].First(); node
; node
= node
->Next() )
966 wxObject
*p
= node
->Data();
969 for( node
= pointsarray
[2].First(); node
; node
= node
->Next() )
971 wxObject
*p
= node
->Data();
974 for( node
= pointsarray
[3].First(); node
; node
= node
->Next() )
976 wxObject
*p
= node
->Data();
980 } // CalculateEllipticPoints