1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/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" 
  28 #include "wx/dcclient.h" 
  29 #include "wx/dcmemory.h" 
  30 #include "wx/dcscreen.h" 
  31 #include "wx/dcprint.h" 
  32 #include "wx/dcbuffer.h" // for IMPLEMENT_DYNAMIC_CLASS 
  33 #include "wx/prntbase.h" 
  43 //---------------------------------------------------------------------------- 
  45 //---------------------------------------------------------------------------- 
  47 wxDCFactory 
*wxDCFactory::m_factory 
= NULL
; 
  49 void wxDCFactory::SetDCFactory( wxDCFactory 
*factory 
) 
  51     if (wxDCFactory::m_factory
) 
  52         delete wxDCFactory::m_factory
; 
  54     wxDCFactory::m_factory 
= factory
; 
  57 wxDCFactory 
*wxDCFactory::GetFactory() 
  59     if (!wxDCFactory::m_factory
) 
  60         wxDCFactory::m_factory 
= new wxNativeDCFactory
; 
  62     return wxDCFactory::m_factory
; 
  65 //----------------------------------------------------------------------------- 
  67 //----------------------------------------------------------------------------- 
  69 wxImplDC
* wxNativeDCFactory::CreateWindowDC( wxWindowDC 
*owner 
) 
  71 #if defined(__WXMSW__) 
  72     return new wxWindowsWindowImplDC( owner 
); 
  73 #elif defined(__WXGTK20__) 
  74     return new wxGTKWindowImplDC( owner 
); 
  75 #elif defined(__WXGTK__) 
  76     return new wxGTKWindowImplDC( owner 
); 
  77 #elif defined(__WXMAC__) 
  78     return new wxMacWindowImplDC( owner 
); 
  79 #elif defined(__WXCOCOA__) 
  80     return new wxCocoaWindowImplDC( owner 
); 
  81 #elif defined(__WXMOTIF__) 
  82     return new wxMotifWindowImplDC( owner 
); 
  83 #elif defined(__WXX11__) 
  84     return new wxX11WindowImplDC( owner 
); 
  85 #elif defined(__WXMGL__) 
  86     return new wxMGLWindowImplDC( owner 
); 
  87 #elif defined(__WXDFB__) 
  88     return new wxDFBWindowImplDC( owner 
); 
  89 #elif defined(__WXPM__) 
  90     return new wxPMWindowImplDC( owner 
); 
  91 #elif defined(__PALMOS__) 
  92     return new wxPalmWindowImplDC( owner 
); 
  96 wxImplDC
* wxNativeDCFactory::CreateWindowDC( wxWindowDC 
*owner
, wxWindow 
*window 
) 
  98 #if defined(__WXMSW__) 
  99     return new wxWindowsWindowImplDC( owner
, window 
); 
 100 #elif defined(__WXGTK20__) 
 101     return new wxGTKWindowImplDC( owner
, window 
); 
 102 #elif defined(__WXGTK__) 
 103     return new wxGTKWindowImplDC( owner
, window 
); 
 104 #elif defined(__WXMAC__) 
 105     return new wxMacWindowImplDC( owner
, window 
); 
 106 #elif defined(__WXCOCOA__) 
 107     return new wxCocoaWindowImplDC( owner
, window 
); 
 108 #elif defined(__WXMOTIF__) 
 109     return new wxMotifWindowImplDC( owner
, window 
); 
 110 #elif defined(__WXX11__) 
 111     return new wxX11WindowImplDC( owner
, window 
); 
 112 #elif defined(__WXMGL__) 
 113     return new wxMGLWindowImplDC( owner
, window 
); 
 114 #elif defined(__WXDFB__) 
 115     return new wxDFBWindowImplDC( owner
, window 
); 
 116 #elif defined(__WXPM__) 
 117     return new wxPMWindowImplDC( owner
, window 
); 
 118 #elif defined(__PALMOS__) 
 119     return new wxPalmWindowImplDC( owner
, window 
); 
 123 wxImplDC
* wxNativeDCFactory::CreateClientDC( wxClientDC 
*owner 
) 
 125 #if defined(__WXMSW__) 
 126     return new wxWindowsClientImplDC( owner 
); 
 127 #elif defined(__WXGTK20__) 
 128     return new wxGTKClientImplDC( owner 
); 
 129 #elif defined(__WXGTK__) 
 130     return new wxGTKClientImplDC( owner 
); 
 131 #elif defined(__WXMAC__) 
 132     return new wxMacClientImplDC( owner 
); 
 133 #elif defined(__WXCOCOA__) 
 134     return new wxCocoaClientImplDC( owner 
); 
 135 #elif defined(__WXMOTIF__) 
 136     return new wxMotifClientImplDC( owner 
); 
 137 #elif defined(__WXX11__) 
 138     return new wxX11ClientImplDC( owner 
); 
 139 #elif defined(__WXMGL__) 
 140     return new wxMGLClientImplDC( owner 
); 
 141 #elif defined(__WXDFB__) 
 142     return new wxDFBClientImplDC( owner 
); 
 143 #elif defined(__WXPM__) 
 144     return new wxPMClientImplDC( owner 
); 
 145 #elif defined(__PALMOS__) 
 146     return new wxPalmClientImplDC( owner 
); 
 150 wxImplDC
* wxNativeDCFactory::CreateClientDC( wxClientDC 
*owner
, wxWindow 
*window 
) 
 152 #if defined(__WXMSW__) 
 153     return new wxWindowsClientImplDC( owner
, window 
); 
 154 #elif defined(__WXGTK20__) 
 155     return new wxGTKClientImplDC( owner
, window 
); 
 156 #elif defined(__WXGTK__) 
 157     return new wxGTKClientImplDC( owner
, window 
); 
 158 #elif defined(__WXMAC__) 
 159     return new wxMacClientImplDC( owner
, window 
); 
 160 #elif defined(__WXCOCOA__) 
 161     return new wxCocoaClientImplDC( owner
, window 
); 
 162 #elif defined(__WXMOTIF__) 
 163     return new wxMotifClientImplDC( owner
, window 
); 
 164 #elif defined(__WXX11__) 
 165     return new wxX11ClientImplDC( owner
, window 
); 
 166 #elif defined(__WXMGL__) 
 167     return new wxMGLClientImplDC( owner
, window 
); 
 168 #elif defined(__WXDFB__) 
 169     return new wxDFBClientImplDC( owner
, window 
); 
 170 #elif defined(__WXPM__) 
 171     return new wxPMClientImplDC( owner
, window 
); 
 172 #elif defined(__PALMOS__) 
 173     return new wxPalmClientImplDC( owner
, window 
); 
 177 wxImplDC
* wxNativeDCFactory::CreatePaintDC( wxPaintDC 
*owner 
) 
 179 #if defined(__WXMSW__) 
 180     return new wxWindowsPaintImplDC( owner 
); 
 181 #elif defined(__WXGTK20__) 
 182     return new wxGTKPaintImplDC( owner 
); 
 183 #elif defined(__WXGTK__) 
 184     return new wxGTKPaintImplDC( owner 
); 
 185 #elif defined(__WXMAC__) 
 186     return new wxMacPaintImplDC( owner 
); 
 187 #elif defined(__WXCOCOA__) 
 188     return new wxCocoaPaintImplDC( owner 
); 
 189 #elif defined(__WXMOTIF__) 
 190     return new wxMotifPaintImplDC( owner 
); 
 191 #elif defined(__WXX11__) 
 192     return new wxX11PaintImplDC( owner 
); 
 193 #elif defined(__WXMGL__) 
 194     return new wxMGLPaintImplDC( owner 
); 
 195 #elif defined(__WXDFB__) 
 196     return new wxDFBPaintImplDC( owner 
); 
 197 #elif defined(__WXPM__) 
 198     return new wxPMPaintImplDC( owner 
); 
 199 #elif defined(__PALMOS__) 
 200     return new wxPalmPaintImplDC( owner 
); 
 204 wxImplDC
* wxNativeDCFactory::CreatePaintDC( wxPaintDC 
*owner
, wxWindow 
*window 
) 
 206 #if defined(__WXMSW__) 
 207     return new wxWindowsPaintImplDC( owner
, window 
); 
 208 #elif defined(__WXGTK20__) 
 209     return new wxGTKPaintImplDC( owner
, window 
); 
 210 #elif defined(__WXGTK__) 
 211     return new wxGTKPaintImplDC( owner
, window 
); 
 212 #elif defined(__WXMAC__) 
 213     return new wxMacPaintImplDC( owner
, window 
); 
 214 #elif defined(__WXCOCOA__) 
 215     return new wxCocoaPaintImplDC( owner
, window 
); 
 216 #elif defined(__WXMOTIF__) 
 217     return new wxMotifPaintImplDC( owner
, window 
); 
 218 #elif defined(__WXX11__) 
 219     return new wxX11PaintImplDC( owner
, window 
); 
 220 #elif defined(__WXMGL__) 
 221     return new wxMGLPaintImplDC( owner
, window 
); 
 222 #elif defined(__WXDFB__) 
 223     return new wxDFBPaintImplDC( owner
, window 
); 
 224 #elif defined(__WXPM__) 
 225     return new wxPMPaintImplDC( owner
, window 
); 
 226 #elif defined(__PALMOS__) 
 227     return new wxPalmPaintImplDC( owner
, window 
); 
 231 wxImplDC
* wxNativeDCFactory::CreateMemoryDC( wxMemoryDC 
*owner 
) 
 233 #if defined(__WXMSW__) 
 234     return new wxWindowsMemoryImplDC( owner 
); 
 235 #elif defined(__WXGTK20__) 
 236     return new wxGTKMemoryImplDC( owner 
); 
 237 #elif defined(__WXGTK__) 
 238     return new wxGTKMemoryImplDC( owner 
); 
 239 #elif defined(__WXMAC__) 
 240     return new wxMacMemoryImplDC( owner 
); 
 241 #elif defined(__WXCOCOA__) 
 242     return new wxCocoaMemoryImplDC( owner 
); 
 243 #elif defined(__WXMOTIF__) 
 244     return new wxMotifMemoryImplDC( owner 
); 
 245 #elif defined(__WXX11__) 
 246     return new wxX11MemoryImplDC( owner 
); 
 247 #elif defined(__WXMGL__) 
 248     return new wxMGLMemoryImplDC( owner 
); 
 249 #elif defined(__WXDFB__) 
 250     return new wxDFBMemoryImplDC( owner 
); 
 251 #elif defined(__WXPM__) 
 252     return new wxPMMemoryImplDC( owner 
); 
 253 #elif defined(__PALMOS__) 
 254     return new wxPalmMemoryImplDC( owner 
); 
 258 wxImplDC
* wxNativeDCFactory::CreateMemoryDC( wxMemoryDC 
*owner
, wxBitmap 
&bitmap 
) 
 260 #if defined(__WXMSW__) 
 261     return new wxWindowsMemoryImplDC( owner
, bitmap 
); 
 262 #elif defined(__WXGTK20__) 
 263     return new wxGTKMemoryImplDC( owner
, bitmap 
); 
 264 #elif defined(__WXGTK__) 
 265     return new wxGTKMemoryImplDC( owner
, bitmap 
); 
 266 #elif defined(__WXMAC__) 
 267     return new wxMacMemoryImplDC( owner
, bitmap 
); 
 268 #elif defined(__WXCOCOA__) 
 269     return new wxCocoaMemoryImplDC( owner
, bitmap 
); 
 270 #elif defined(__WXMOTIF__) 
 271     return new wxMotifMemoryImplDC( owner
, bitmap 
); 
 272 #elif defined(__WXX11__) 
 273     return new wxX11MemoryImplDC( owner
, bitmap 
); 
 274 #elif defined(__WXMGL__) 
 275     return new wxMGLMemoryImplDC( owner
, bitmap 
); 
 276 #elif defined(__WXDFB__) 
 277     return new wxDFBMemoryImplDC( owner
, bitmap 
); 
 278 #elif defined(__WXPM__) 
 279     return new wxPMMemoryImplDC( owner
, bitmap 
); 
 280 #elif defined(__PALMOS__) 
 281     return new wxPalmMemoryImplDC( owner
, bitmap 
); 
 285 wxImplDC
* wxNativeDCFactory::CreateMemoryDC( wxMemoryDC 
*owner
, wxDC 
*dc 
) 
 287 #if defined(__WXMSW__) 
 288     return new wxWindowsMemoryImplDC( owner
, dc 
); 
 289 #elif defined(__WXGTK20__) 
 290     return new wxGTKMemoryImplDC( owner
, dc 
); 
 291 #elif defined(__WXGTK__) 
 292     return new wxGTKMemoryImplDC( owner
, dc 
); 
 293 #elif defined(__WXMAC__) 
 294     return new wxMacMemoryImplDC( owner
, dc 
); 
 295 #elif defined(__WXCOCOA__) 
 296     return new wxCocoaMemoryImplDC( owner
, dc 
); 
 297 #elif defined(__WXMOTIF__) 
 298     return new wxMotifMemoryImplDC( owner
, dc 
); 
 299 #elif defined(__WXX11__) 
 300     return new wxX11MemoryImplDC( owner
, dc 
); 
 301 #elif defined(__WXMGL__) 
 302     return new wxMGLMemoryImplDC( owner
, dc 
); 
 303 #elif defined(__WXDFB__) 
 304     return new wxDFBMemoryImplDC( owner
, dc 
); 
 305 #elif defined(__WXPM__) 
 306     return new wxPMMemoryImplDC( owner
, dc 
); 
 307 #elif defined(__PALMOS__) 
 308     return new wxPalmMemoryImplDC( owner
, dc 
); 
 312 wxImplDC
* wxNativeDCFactory::CreateScreenDC( wxScreenDC 
*owner 
) 
 314 #if defined(__WXMSW__) 
 315     return new wxWindowsScreenImplDC( owner 
); 
 316 #elif defined(__WXGTK20__) 
 317     return new wxGTKScreenImplDC( owner 
); 
 318 #elif defined(__WXGTK__) 
 319     return new wxGTKScreenImplDC( owner 
); 
 320 #elif defined(__WXMAC__) 
 321     return new wxMacScreenImplDC( owner 
); 
 322 #elif defined(__WXCOCOA__) 
 323     return new wxCocoaScreenImplDC( owner 
); 
 324 #elif defined(__WXMOTIF__) 
 325     return new wxMotifScreenImplDC( owner 
); 
 326 #elif defined(__WXX11__) 
 327     return new wxX11ScreenImplDC( owner 
); 
 328 #elif defined(__WXMGL__) 
 329     return new wxMGLScreenImplDC( owner 
); 
 330 #elif defined(__WXDFB__) 
 331     return new wxDFBScreenImplDC( owner 
); 
 332 #elif defined(__WXPM__) 
 333     return new wxPMScreenImplDC( owner 
); 
 334 #elif defined(__PALMOS__) 
 335     return new wxPalmScreenImplDC( owner 
); 
 339 wxImplDC 
*wxNativeDCFactory::CreatePrinterDC( wxPrinterDC 
*owner
, const wxPrintData 
&data 
) 
 341     wxPrintFactory 
*factory 
= wxPrintFactory::GetFactory(); 
 342     return factory
->CreatePrinterImplDC( owner
, data 
); 
 345 //----------------------------------------------------------------------------- 
 347 //----------------------------------------------------------------------------- 
 349 IMPLEMENT_DYNAMIC_CLASS(wxWindowDC
, wxDC
) 
 351 wxWindowDC::wxWindowDC() 
 353     wxDCFactory 
*factory 
= wxDCFactory::GetFactory(); 
 354     m_pimpl 
= factory
->CreateWindowDC( this ); 
 357 wxWindowDC::wxWindowDC( wxWindow 
*win 
) 
 359     wxDCFactory 
*factory 
= wxDCFactory::GetFactory(); 
 360     m_pimpl 
= factory
->CreateWindowDC( this, win 
); 
 363 //----------------------------------------------------------------------------- 
 365 //----------------------------------------------------------------------------- 
 367 IMPLEMENT_DYNAMIC_CLASS(wxClientDC
, wxDC
) 
 369 wxClientDC::wxClientDC() 
 371     wxDCFactory 
*factory 
= wxDCFactory::GetFactory(); 
 372     m_pimpl 
= factory
->CreateClientDC( this ); 
 375 wxClientDC::wxClientDC( wxWindow 
*win 
) 
 377     wxDCFactory 
*factory 
= wxDCFactory::GetFactory(); 
 378     m_pimpl 
= factory
->CreateClientDC( this, win 
); 
 381 //----------------------------------------------------------------------------- 
 383 //----------------------------------------------------------------------------- 
 385 IMPLEMENT_DYNAMIC_CLASS(wxMemoryDC
, wxDC
) 
 387 wxMemoryDC::wxMemoryDC() 
 389     wxDCFactory 
*factory 
= wxDCFactory::GetFactory(); 
 390     m_pimpl 
= factory
->CreateMemoryDC( this ); 
 393 wxMemoryDC::wxMemoryDC( wxBitmap
& bitmap 
) 
 395     wxDCFactory 
*factory 
= wxDCFactory::GetFactory(); 
 396     m_pimpl 
= factory
->CreateMemoryDC( this, bitmap 
); 
 399 wxMemoryDC::wxMemoryDC( wxDC 
*dc 
) 
 401     wxDCFactory 
*factory 
= wxDCFactory::GetFactory(); 
 402     m_pimpl 
= factory
->CreateMemoryDC( this, dc 
); 
 405 void wxMemoryDC::SelectObject(wxBitmap
& bmp
) 
 407     // make sure that the given wxBitmap is not sharing its data with other 
 408     // wxBitmap instances as its contents will be modified by any drawing 
 409     // operation done on this DC 
 413     GetImpl()->DoSelect(bmp
); 
 416 void wxMemoryDC::SelectObjectAsSource(const wxBitmap
& bmp
) 
 418     GetImpl()->DoSelect(bmp
); 
 421 const wxBitmap
& wxMemoryDC::GetSelectedBitmap() const 
 423     return GetImpl()->GetSelectedBitmap(); 
 426 wxBitmap
& wxMemoryDC::GetSelectedBitmap() 
 428     return GetImpl()->GetSelectedBitmap(); 
 432 //----------------------------------------------------------------------------- 
 434 //----------------------------------------------------------------------------- 
 436 IMPLEMENT_DYNAMIC_CLASS(wxPaintDC
, wxDC
) 
 438 wxPaintDC::wxPaintDC() 
 440     wxDCFactory 
*factory 
= wxDCFactory::GetFactory(); 
 441     m_pimpl 
= factory
->CreatePaintDC( this ); 
 444 wxPaintDC::wxPaintDC( wxWindow 
*win 
) 
 446     wxDCFactory 
*factory 
= wxDCFactory::GetFactory(); 
 447     m_pimpl 
= factory
->CreatePaintDC( this, win 
); 
 450 //----------------------------------------------------------------------------- 
 452 //----------------------------------------------------------------------------- 
 454 IMPLEMENT_DYNAMIC_CLASS(wxScreenDC
, wxWindowDC
) 
 456 wxScreenDC::wxScreenDC() 
 458     wxDCFactory 
*factory 
= wxDCFactory::GetFactory(); 
 459     m_pimpl 
= factory
->CreateScreenDC( this ); 
 462 //----------------------------------------------------------------------------- 
 464 //----------------------------------------------------------------------------- 
 466 IMPLEMENT_DYNAMIC_CLASS(wxPrinterDC
, wxDC
) 
 468 wxPrinterDC::wxPrinterDC() 
 470     wxDCFactory 
*factory 
= wxDCFactory::GetFactory(); 
 471     // m_pimpl = factory->CreatePrinterDC( this, data ); 
 474 wxPrinterDC::wxPrinterDC( const wxPrintData 
&data 
) 
 476     wxDCFactory 
*factory 
= wxDCFactory::GetFactory(); 
 477     m_pimpl 
= factory
->CreatePrinterDC( this, data 
); 
 480 //----------------------------------------------------------------------------- 
 482 //----------------------------------------------------------------------------- 
 484 IMPLEMENT_ABSTRACT_CLASS(wxImplDC
, wxObject
) 
 486 wxImplDC::wxImplDC( wxDC 
*owner 
) 
 487         : m_colour(wxColourDisplay()) 
 491         , m_isBBoxValid(false) 
 492         , m_logicalOriginX(0), m_logicalOriginY(0) 
 493         , m_deviceOriginX(0), m_deviceOriginY(0) 
 494         , m_deviceLocalOriginX(0), m_deviceLocalOriginY(0) 
 495         , m_logicalScaleX(1.0), m_logicalScaleY(1.0) 
 496         , m_userScaleX(1.0), m_userScaleY(1.0) 
 497         , m_scaleX(1.0), m_scaleY(1.0) 
 498         , m_signX(1), m_signY(1) 
 499         , m_minX(0), m_minY(0), m_maxX(0), m_maxY(0) 
 500         , m_clipX1(0), m_clipY1(0), m_clipX2(0), m_clipY2(0) 
 501         , m_logicalFunction(wxCOPY
) 
 502         , m_backgroundMode(wxTRANSPARENT
) 
 503         , m_mappingMode(wxMM_TEXT
) 
 506         , m_backgroundBrush(*wxTRANSPARENT_BRUSH
) 
 507         , m_textForegroundColour(*wxBLACK
) 
 508         , m_textBackgroundColour(*wxWHITE
) 
 512         , m_hasCustomPalette(false) 
 513 #endif // wxUSE_PALETTE 
 517     m_mm_to_pix_x 
= (double)wxGetDisplaySize().GetWidth() / 
 518                     (double)wxGetDisplaySizeMM().GetWidth(); 
 519     m_mm_to_pix_y 
= (double)wxGetDisplaySize().GetHeight() / 
 520                     (double)wxGetDisplaySizeMM().GetHeight(); 
 526 wxImplDC::~wxImplDC() 
 530 // ---------------------------------------------------------------------------- 
 531 // coordinate conversions and transforms 
 532 // ---------------------------------------------------------------------------- 
 534 wxCoord 
wxImplDC::DeviceToLogicalX(wxCoord x
) const 
 536     return wxRound((double)(x 
- m_deviceOriginX 
- m_deviceLocalOriginX
) / m_scaleX
) * m_signX 
+ m_logicalOriginX
; 
 539 wxCoord 
wxImplDC::DeviceToLogicalY(wxCoord y
) const 
 541     return wxRound((double)(y 
- m_deviceOriginY 
- m_deviceLocalOriginY
) / m_scaleY
) * m_signY 
+ m_logicalOriginY
; 
 544 wxCoord 
wxImplDC::DeviceToLogicalXRel(wxCoord x
) const 
 546     return wxRound((double)(x
) / m_scaleX
); 
 549 wxCoord 
wxImplDC::DeviceToLogicalYRel(wxCoord y
) const 
 551     return wxRound((double)(y
) / m_scaleY
); 
 554 wxCoord 
wxImplDC::LogicalToDeviceX(wxCoord x
) const 
 556     return wxRound((double)(x 
- m_logicalOriginX
) * m_scaleX
) * m_signX 
+ m_deviceOriginX 
* m_signY 
+ m_deviceLocalOriginX
; 
 559 wxCoord 
wxImplDC::LogicalToDeviceY(wxCoord y
) const 
 561     return wxRound((double)(y 
- m_logicalOriginY
) * m_scaleY
) * m_signY 
+ m_deviceOriginY 
* m_signY 
+ m_deviceLocalOriginY
; 
 564 wxCoord 
wxImplDC::LogicalToDeviceXRel(wxCoord x
) const 
 566     return wxRound((double)(x
) * m_scaleX
); 
 569 wxCoord 
wxImplDC::LogicalToDeviceYRel(wxCoord y
) const 
 571     return wxRound((double)(y
) * m_scaleY
); 
 574 void wxImplDC::ComputeScaleAndOrigin() 
 576     m_scaleX 
= m_logicalScaleX 
* m_userScaleX
; 
 577     m_scaleY 
= m_logicalScaleY 
* m_userScaleY
; 
 580 void wxImplDC::SetMapMode( int mode 
) 
 585           SetLogicalScale( twips2mm
*m_mm_to_pix_x
, twips2mm
*m_mm_to_pix_y 
); 
 588           SetLogicalScale( pt2mm
*m_mm_to_pix_x
, pt2mm
*m_mm_to_pix_y 
); 
 591           SetLogicalScale( m_mm_to_pix_x
, m_mm_to_pix_y 
); 
 594           SetLogicalScale( m_mm_to_pix_x
/10.0, m_mm_to_pix_y
/10.0 ); 
 598           SetLogicalScale( 1.0, 1.0 ); 
 601     m_mappingMode 
= mode
; 
 604 void wxImplDC::SetUserScale( double x
, double y 
) 
 606     // allow negative ? -> no 
 609     ComputeScaleAndOrigin(); 
 612 void wxImplDC::SetLogicalScale( double x
, double y 
) 
 617     ComputeScaleAndOrigin(); 
 620 void wxImplDC::SetLogicalOrigin( wxCoord x
, wxCoord y 
) 
 622     m_logicalOriginX 
= x 
* m_signX
; 
 623     m_logicalOriginY 
= y 
* m_signY
; 
 624     ComputeScaleAndOrigin(); 
 627 void wxImplDC::SetDeviceOrigin( wxCoord x
, wxCoord y 
) 
 631     ComputeScaleAndOrigin(); 
 634 void wxImplDC::SetDeviceLocalOrigin( wxCoord x
, wxCoord y 
) 
 636     m_deviceLocalOriginX 
= x
; 
 637     m_deviceLocalOriginY 
= y
; 
 638     ComputeScaleAndOrigin(); 
 641 void wxImplDC::SetAxisOrientation( bool xLeftRight
, bool yBottomUp 
) 
 643     // only wxPostScripDC has m_signX = -1, we override SetAxisOrientation there 
 644     // wxWidgets 2.9: no longer override it 
 645     m_signX 
= (xLeftRight 
?  1 : -1); 
 646     m_signY 
= (yBottomUp  
? -1 :  1); 
 647     ComputeScaleAndOrigin(); 
 651 // Each element of the widths array will be the width of the string up to and 
 652 // including the corresponding character in text.  This is the generic 
 653 // implementation, the port-specific classes should do this with native APIs 
 654 // if available and if faster.  Note: pango_layout_index_to_pos is much slower 
 655 // than calling GetTextExtent!! 
 662     FontWidthCache() : m_scaleX(1), m_widths(NULL
) { } 
 663     ~FontWidthCache() { delete []m_widths
; } 
 668             m_widths 
= new int[FWC_SIZE
]; 
 670         memset(m_widths
, 0, sizeof(int)*FWC_SIZE
); 
 678 static FontWidthCache s_fontWidthCache
; 
 680 bool wxImplDC::DoGetPartialTextExtents(const wxString
& text
, wxArrayInt
& widths
) const 
 684     const size_t len 
= text
.length(); 
 688     // reset the cache if font or horizontal scale have changed 
 689     if ( !s_fontWidthCache
.m_widths 
|| 
 690          !wxIsSameDouble(s_fontWidthCache
.m_scaleX
, m_scaleX
) || 
 691          (s_fontWidthCache
.m_font 
!= GetFont()) ) 
 693         s_fontWidthCache
.Reset(); 
 694         s_fontWidthCache
.m_font 
= GetFont(); 
 695         s_fontWidthCache
.m_scaleX 
= m_scaleX
; 
 698     // Calculate the position of each character based on the widths of 
 699     // the previous characters 
 701     for ( size_t i 
= 0; i 
< len
; i
++ ) 
 703         const wxChar c 
= text
[i
]; 
 704         unsigned int c_int 
= (unsigned int)c
; 
 706         if ((c_int 
< FWC_SIZE
) && (s_fontWidthCache
.m_widths
[c_int
] != 0)) 
 708             w 
= s_fontWidthCache
.m_widths
[c_int
]; 
 712             DoGetTextExtent(c
, &w
, &h
); 
 713             if (c_int 
< FWC_SIZE
) 
 714                 s_fontWidthCache
.m_widths
[c_int
] = w
; 
 718         widths
[i
] = totalWidth
; 
 724 void wxImplDC::GetMultiLineTextExtent(const wxString
& text
, 
 728                                       const wxFont 
*font
) const 
 730     wxCoord widthTextMax 
= 0, widthLine
, 
 731             heightTextTotal 
= 0, heightLineDefault 
= 0, heightLine 
= 0; 
 734     for ( wxString::const_iterator pc 
= text
.begin(); ; ++pc 
) 
 736         if ( pc 
== text
.end() || *pc 
== _T('\n') ) 
 738             if ( curLine
.empty() ) 
 740                 // we can't use GetTextExtent - it will return 0 for both width 
 741                 // and height and an empty line should count in height 
 744                 // assume that this line has the same height as the previous 
 746                 if ( !heightLineDefault 
) 
 747                     heightLineDefault 
= heightLine
; 
 749                 if ( !heightLineDefault 
) 
 751                     // but we don't know it yet - choose something reasonable 
 752                     DoGetTextExtent(_T("W"), NULL
, &heightLineDefault
, 
 756                 heightTextTotal 
+= heightLineDefault
; 
 760                 DoGetTextExtent(curLine
, &widthLine
, &heightLine
, 
 762                 if ( widthLine 
> widthTextMax 
) 
 763                     widthTextMax 
= widthLine
; 
 764                 heightTextTotal 
+= heightLine
; 
 767             if ( pc 
== text
.end() ) 
 785         *y 
= heightTextTotal
; 
 790 void wxImplDC::DoDrawCheckMark(wxCoord x1
, wxCoord y1
, 
 791                                wxCoord width
, wxCoord height
) 
 793     wxCHECK_RET( IsOk(), wxT("invalid window dc") ); 
 795     wxCoord x2 
= x1 
+ width
, 
 798     // the pen width is calibrated to give 3 for width == height == 10 
 799     wxDCPenChanger 
pen( *m_owner
, wxPen(GetTextForeground(), (width 
+ height 
+ 1)/7)); 
 801     // we're drawing a scaled version of wx/generic/tick.xpm here 
 802     wxCoord x3 
= x1 
+ (4*width
) / 10,   // x of the tick bottom 
 803             y3 
= y1 
+ height 
/ 2;       // y of the left tick branch 
 804     DoDrawLine(x1
, y3
, x3
, y2
); 
 805     DoDrawLine(x3
, y2
, x2
, y1
); 
 807     CalcBoundingBox(x1
, y1
); 
 808     CalcBoundingBox(x2
, y2
); 
 812 wxImplDC::DoStretchBlit(wxCoord xdest
, wxCoord ydest
, 
 813                         wxCoord dstWidth
, wxCoord dstHeight
, 
 815                         wxCoord xsrc
, wxCoord ysrc
, 
 816                         wxCoord srcWidth
, wxCoord srcHeight
, 
 822     wxCHECK_MSG( srcWidth 
&& srcHeight 
&& dstWidth 
&& dstHeight
, false, 
 823                  _T("invalid blit size") ); 
 825     // emulate the stretching by modifying the DC scale 
 826     double xscale 
= (double)srcWidth
/dstWidth
, 
 827            yscale 
= (double)srcHeight
/dstHeight
; 
 829     double xscaleOld
, yscaleOld
; 
 830     GetUserScale(&xscaleOld
, &yscaleOld
); 
 831     SetUserScale(xscaleOld
/xscale
, yscaleOld
/yscale
); 
 833     bool rc 
= DoBlit(wxCoord(xdest
*xscale
), wxCoord(ydest
*yscale
), 
 834                      wxCoord(dstWidth
*xscale
), wxCoord(dstHeight
*yscale
), 
 836                      xsrc
, ysrc
, rop
, useMask
, xsrcMask
, ysrcMask
); 
 838     SetUserScale(xscaleOld
, yscaleOld
); 
 843 void wxImplDC::DrawLines(const wxPointList 
*list
, wxCoord xoffset
, wxCoord yoffset
) 
 845     int n 
= list
->GetCount(); 
 846     wxPoint 
*points 
= new wxPoint
[n
]; 
 849     for ( wxPointList::compatibility_iterator node 
= list
->GetFirst(); node
; node 
= node
->GetNext(), i
++ ) 
 851         wxPoint 
*point 
= node
->GetData(); 
 852         points
[i
].x 
= point
->x
; 
 853         points
[i
].y 
= point
->y
; 
 856     DoDrawLines(n
, points
, xoffset
, yoffset
); 
 861 void wxImplDC::DrawPolygon(const wxPointList 
*list
, 
 862                            wxCoord xoffset
, wxCoord yoffset
, 
 865     int n 
= list
->GetCount(); 
 866     wxPoint 
*points 
= new wxPoint
[n
]; 
 869     for ( wxPointList::compatibility_iterator node 
= list
->GetFirst(); node
; node 
= node
->GetNext(), i
++ ) 
 871         wxPoint 
*point 
= node
->GetData(); 
 872         points
[i
].x 
= point
->x
; 
 873         points
[i
].y 
= point
->y
; 
 876     DoDrawPolygon(n
, points
, xoffset
, yoffset
, fillStyle
); 
 882 wxImplDC::DoDrawPolyPolygon(int n
, 
 885                             wxCoord xoffset
, wxCoord yoffset
, 
 890         DoDrawPolygon(count
[0], points
, xoffset
, yoffset
, fillStyle
); 
 898     for (i 
= j 
= lastOfs 
= 0; i 
< n
; i
++) 
 903     pts 
= new wxPoint
[j
+n
-1]; 
 904     for (i 
= 0; i 
< j
; i
++) 
 906     for (i 
= 2; i 
<= n
; i
++) 
 908         lastOfs 
-= count
[n
-i
]; 
 909         pts
[j
++] = pts
[lastOfs
]; 
 913     SetPen(wxPen(*wxBLACK
, 0, wxTRANSPARENT
)); 
 914     DoDrawPolygon(j
, pts
, xoffset
, yoffset
, fillStyle
); 
 916     for (i 
= j 
= 0; i 
< n
; i
++) 
 918         DoDrawLines(count
[i
], pts
+j
, xoffset
, yoffset
); 
 926 void wxImplDC::DoDrawSpline(wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
, wxCoord x3
, wxCoord y3
) 
 928     wxPointList point_list
; 
 930     wxPoint 
*point1 
= new wxPoint
; 
 931     point1
->x 
= x1
; point1
->y 
= y1
; 
 932     point_list
.Append( point1 
); 
 934     wxPoint 
*point2 
= new wxPoint
; 
 935     point2
->x 
= x2
; point2
->y 
= y2
; 
 936     point_list
.Append( point2 
); 
 938     wxPoint 
*point3 
= new wxPoint
; 
 939     point3
->x 
= x3
; point3
->y 
= y3
; 
 940     point_list
.Append( point3 
); 
 942     DoDrawSpline(&point_list
); 
 944     for( wxPointList::compatibility_iterator node 
= point_list
.GetFirst(); node
; node 
= node
->GetNext() ) 
 946         wxPoint 
*p 
= node
->GetData(); 
 951 void wxImplDC::DoDrawSpline(int n
, wxPoint points
[]) 
 954     for (int i 
=0; i 
< n
; i
++) 
 955         list
.Append( &points
[i
] ); 
 960 // ----------------------------------- spline code ---------------------------------------- 
 962 void wx_quadratic_spline(double a1
, double b1
, double a2
, double b2
, 
 963                          double a3
, double b3
, double a4
, double b4
); 
 964 void wx_clear_stack(); 
 965 int wx_spline_pop(double *x1
, double *y1
, double *x2
, double *y2
, double *x3
, 
 966         double *y3
, double *x4
, double *y4
); 
 967 void wx_spline_push(double x1
, double y1
, double x2
, double y2
, double x3
, double y3
, 
 968           double x4
, double y4
); 
 969 static bool wx_spline_add_point(double x
, double y
); 
 970 static void wx_spline_draw_point_array(wxDC 
*dc
); 
 972 wxPointList wx_spline_point_list
; 
 974 #define                half(z1, z2)        ((z1+z2)/2.0) 
 977 /* iterative version */ 
 979 void wx_quadratic_spline(double a1
, double b1
, double a2
, double b2
, double a3
, double b3
, double a4
, 
 982     register double  xmid
, ymid
; 
 983     double           x1
, y1
, x2
, y2
, x3
, y3
, x4
, y4
; 
 986     wx_spline_push(a1
, b1
, a2
, b2
, a3
, b3
, a4
, b4
); 
 988     while (wx_spline_pop(&x1
, &y1
, &x2
, &y2
, &x3
, &y3
, &x4
, &y4
)) { 
 989         xmid 
= (double)half(x2
, x3
); 
 990         ymid 
= (double)half(y2
, y3
); 
 991         if (fabs(x1 
- xmid
) < THRESHOLD 
&& fabs(y1 
- ymid
) < THRESHOLD 
&& 
 992             fabs(xmid 
- x4
) < THRESHOLD 
&& fabs(ymid 
- y4
) < THRESHOLD
) { 
 993             wx_spline_add_point( x1
, y1 
); 
 994             wx_spline_add_point( xmid
, ymid 
); 
 996             wx_spline_push(xmid
, ymid
, (double)half(xmid
, x3
), (double)half(ymid
, y3
), 
 997                  (double)half(x3
, x4
), (double)half(y3
, y4
), x4
, y4
); 
 998             wx_spline_push(x1
, y1
, (double)half(x1
, x2
), (double)half(y1
, y2
), 
 999                  (double)half(x2
, xmid
), (double)half(y2
, ymid
), xmid
, ymid
); 
1004 /* utilities used by spline drawing routines */ 
1006 typedef struct wx_spline_stack_struct 
{ 
1007     double           x1
, y1
, x2
, y2
, x3
, y3
, x4
, y4
; 
1010 #define         SPLINE_STACK_DEPTH             20 
1011 static Stack    wx_spline_stack
[SPLINE_STACK_DEPTH
]; 
1012 static Stack   
*wx_stack_top
; 
1013 static int      wx_stack_count
; 
1015 void wx_clear_stack() 
1017     wx_stack_top 
= wx_spline_stack
; 
1021 void wx_spline_push(double x1
, double y1
, double x2
, double y2
, double x3
, double y3
, double x4
, double y4
) 
1023     wx_stack_top
->x1 
= x1
; 
1024     wx_stack_top
->y1 
= y1
; 
1025     wx_stack_top
->x2 
= x2
; 
1026     wx_stack_top
->y2 
= y2
; 
1027     wx_stack_top
->x3 
= x3
; 
1028     wx_stack_top
->y3 
= y3
; 
1029     wx_stack_top
->x4 
= x4
; 
1030     wx_stack_top
->y4 
= y4
; 
1035 int wx_spline_pop(double *x1
, double *y1
, double *x2
, double *y2
, 
1036                   double *x3
, double *y3
, double *x4
, double *y4
) 
1038     if (wx_stack_count 
== 0) 
1042     *x1 
= wx_stack_top
->x1
; 
1043     *y1 
= wx_stack_top
->y1
; 
1044     *x2 
= wx_stack_top
->x2
; 
1045     *y2 
= wx_stack_top
->y2
; 
1046     *x3 
= wx_stack_top
->x3
; 
1047     *y3 
= wx_stack_top
->y3
; 
1048     *x4 
= wx_stack_top
->x4
; 
1049     *y4 
= wx_stack_top
->y4
; 
1053 static bool wx_spline_add_point(double x
, double y
) 
1055     wxPoint 
*point 
= new wxPoint( wxRound(x
), wxRound(y
) ); 
1056     wx_spline_point_list
.Append(point 
); 
1060 static void wx_spline_draw_point_array(wxDC 
*dc
) 
1062     dc
->DrawLines(&wx_spline_point_list
, 0, 0 ); 
1063     wxPointList::compatibility_iterator node 
= wx_spline_point_list
.GetFirst(); 
1066         wxPoint 
*point 
= node
->GetData(); 
1068         wx_spline_point_list
.Erase(node
); 
1069         node 
= wx_spline_point_list
.GetFirst(); 
1073 void wxImplDC::DoDrawSpline( const wxPointList 
*points 
) 
1075     wxCHECK_RET( IsOk(), wxT("invalid window dc") ); 
1078     double           cx1
, cy1
, cx2
, cy2
, cx3
, cy3
, cx4
, cy4
; 
1079     double           x1
, y1
, x2
, y2
; 
1081     wxPointList::compatibility_iterator node 
= points
->GetFirst(); 
1086     p 
= (wxPoint 
*)node
->GetData(); 
1091     node 
= node
->GetNext(); 
1092     p 
= node
->GetData(); 
1096     cx1 
= (double)((x1 
+ x2
) / 2); 
1097     cy1 
= (double)((y1 
+ y2
) / 2); 
1098     cx2 
= (double)((cx1 
+ x2
) / 2); 
1099     cy2 
= (double)((cy1 
+ y2
) / 2); 
1101     wx_spline_add_point(x1
, y1
); 
1103     while ((node 
= node
->GetNext()) 
1106 #endif // !wxUSE_STL 
1109         p 
= node
->GetData(); 
1114         cx4 
= (double)(x1 
+ x2
) / 2; 
1115         cy4 
= (double)(y1 
+ y2
) / 2; 
1116         cx3 
= (double)(x1 
+ cx4
) / 2; 
1117         cy3 
= (double)(y1 
+ cy4
) / 2; 
1119         wx_quadratic_spline(cx1
, cy1
, cx2
, cy2
, cx3
, cy3
, cx4
, cy4
); 
1123         cx2 
= (double)(cx1 
+ x2
) / 2; 
1124         cy2 
= (double)(cy1 
+ y2
) / 2; 
1127     wx_spline_add_point( cx1
, cy1 
); 
1128     wx_spline_add_point( x2
, y2 
); 
1130     wx_spline_draw_point_array( m_owner 
); 
1133 #endif // wxUSE_SPLINES 
1137 void wxImplDC::DoGradientFillLinear(const wxRect
& rect
, 
1138                                     const wxColour
& initialColour
, 
1139                                     const wxColour
& destColour
, 
1140                                     wxDirection nDirection
) 
1143     wxPen oldPen 
= m_pen
; 
1144     wxBrush oldBrush 
= m_brush
; 
1146     wxUint8 nR1 
= initialColour
.Red(); 
1147     wxUint8 nG1 
= initialColour
.Green(); 
1148     wxUint8 nB1 
= initialColour
.Blue(); 
1149     wxUint8 nR2 
= destColour
.Red(); 
1150     wxUint8 nG2 
= destColour
.Green(); 
1151     wxUint8 nB2 
= destColour
.Blue(); 
1154     if ( nDirection 
== wxEAST 
|| nDirection 
== wxWEST 
) 
1156         wxInt32 x 
= rect
.GetWidth(); 
1157         wxInt32 w 
= x
;              // width of area to shade 
1158         wxInt32 xDelta 
= w
/256;     // height of one shade bend 
1166                 nR 
= nR1 
- (nR1
-nR2
)*(w
-x
)/w
; 
1168                 nR 
= nR1 
+ (nR2
-nR1
)*(w
-x
)/w
; 
1171                 nG 
= nG1 
- (nG1
-nG2
)*(w
-x
)/w
; 
1173                 nG 
= nG1 
+ (nG2
-nG1
)*(w
-x
)/w
; 
1176                 nB 
= nB1 
- (nB1
-nB2
)*(w
-x
)/w
; 
1178                 nB 
= nB1 
+ (nB2
-nB1
)*(w
-x
)/w
; 
1180             wxColour 
colour(nR
,nG
,nB
); 
1181             SetPen(wxPen(colour
, 1, wxSOLID
)); 
1182             SetBrush(wxBrush(colour
)); 
1183             if(nDirection 
== wxEAST
) 
1184                 DoDrawRectangle(rect
.GetRight()-x
-xDelta
+1, rect
.GetTop(), 
1185                         xDelta
, rect
.GetHeight()); 
1186             else //nDirection == wxWEST 
1187                 DoDrawRectangle(rect
.GetLeft()+x
, rect
.GetTop(), 
1188                         xDelta
, rect
.GetHeight()); 
1191     else  // nDirection == wxNORTH || nDirection == wxSOUTH 
1193         wxInt32 y 
= rect
.GetHeight(); 
1194         wxInt32 w 
= y
;              // height of area to shade 
1195         wxInt32 yDelta 
= w
/255;     // height of one shade bend 
1203                 nR 
= nR1 
- (nR1
-nR2
)*(w
-y
)/w
; 
1205                 nR 
= nR1 
+ (nR2
-nR1
)*(w
-y
)/w
; 
1208                 nG 
= nG1 
- (nG1
-nG2
)*(w
-y
)/w
; 
1210                 nG 
= nG1 
+ (nG2
-nG1
)*(w
-y
)/w
; 
1213                 nB 
= nB1 
- (nB1
-nB2
)*(w
-y
)/w
; 
1215                 nB 
= nB1 
+ (nB2
-nB1
)*(w
-y
)/w
; 
1217             wxColour 
colour(nR
,nG
,nB
); 
1218             SetPen(wxPen(colour
, 1, wxSOLID
)); 
1219             SetBrush(wxBrush(colour
)); 
1220             if(nDirection 
== wxNORTH
) 
1221                 DoDrawRectangle(rect
.GetLeft(), rect
.GetTop()+y
, 
1222                         rect
.GetWidth(), yDelta
); 
1223             else //nDirection == wxSOUTH 
1224                 DoDrawRectangle(rect
.GetLeft(), rect
.GetBottom()-y
-yDelta
+1, 
1225                         rect
.GetWidth(), yDelta
); 
1233 void wxImplDC::DoGradientFillConcentric(const wxRect
& rect
, 
1234                                       const wxColour
& initialColour
, 
1235                                       const wxColour
& destColour
, 
1236                                       const wxPoint
& circleCenter
) 
1238     //save the old pen color 
1239     wxColour oldPenColour 
= m_pen
.GetColour(); 
1241     wxUint8 nR1 
= destColour
.Red(); 
1242     wxUint8 nG1 
= destColour
.Green(); 
1243     wxUint8 nB1 
= destColour
.Blue(); 
1244     wxUint8 nR2 
= initialColour
.Red(); 
1245     wxUint8 nG2 
= initialColour
.Green(); 
1246     wxUint8 nB2 
= initialColour
.Blue(); 
1251     wxInt32 cx 
= rect
.GetWidth() / 2; 
1252     wxInt32 cy 
= rect
.GetHeight() / 2; 
1260     wxInt32 nCircleOffX 
= circleCenter
.x 
- (rect
.GetWidth() / 2); 
1261     wxInt32 nCircleOffY 
= circleCenter
.y 
- (rect
.GetHeight() / 2); 
1263     for ( wxInt32 x 
= 0; x 
< rect
.GetWidth(); x
++ ) 
1265         for ( wxInt32 y 
= 0; y 
< rect
.GetHeight(); y
++ ) 
1267             //get color difference 
1268             wxInt32 nGradient 
= ((nRadius 
- 
1270                                     pow((double)(x 
- cx 
- nCircleOffX
), 2) + 
1271                                     pow((double)(y 
- cy 
- nCircleOffY
), 2) 
1272                                   )) * 100) / nRadius
; 
1274             //normalize Gradient 
1279             nR 
= (wxUint8
)(nR1 
+ ((nR2 
- nR1
) * nGradient 
/ 100)); 
1280             nG 
= (wxUint8
)(nG1 
+ ((nG2 
- nG1
) * nGradient 
/ 100)); 
1281             nB 
= (wxUint8
)(nB1 
+ ((nB2 
- nB1
) * nGradient 
/ 100)); 
1284             m_pen
.SetColour(wxColour(nR
,nG
,nB
)); 
1285             DoDrawPoint(x 
+ rect
.GetLeft(), y 
+ rect
.GetTop()); 
1288     //return old pen color 
1289     m_pen
.SetColour(oldPenColour
); 
1292 //----------------------------------------------------------------------------- 
1294 //----------------------------------------------------------------------------- 
1296 IMPLEMENT_ABSTRACT_CLASS(wxDC
, wxObject
) 
1298 void wxDC::DrawLabel(const wxString
& text
, 
1299                          const wxBitmap
& bitmap
, 
1303                          wxRect 
*rectBounding
) 
1305     // find the text position 
1306     wxCoord widthText
, heightText
, heightLine
; 
1307     GetMultiLineTextExtent(text
, &widthText
, &heightText
, &heightLine
); 
1309     wxCoord width
, height
; 
1312         width 
= widthText 
+ bitmap
.GetWidth(); 
1313         height 
= bitmap
.GetHeight(); 
1318         height 
= heightText
; 
1322     if ( alignment 
& wxALIGN_RIGHT 
) 
1324         x 
= rect
.GetRight() - width
; 
1326     else if ( alignment 
& wxALIGN_CENTRE_HORIZONTAL 
) 
1328         x 
= (rect
.GetLeft() + rect
.GetRight() + 1 - width
) / 2; 
1330     else // alignment & wxALIGN_LEFT 
1335     if ( alignment 
& wxALIGN_BOTTOM 
) 
1337         y 
= rect
.GetBottom() - height
; 
1339     else if ( alignment 
& wxALIGN_CENTRE_VERTICAL 
) 
1341         y 
= (rect
.GetTop() + rect
.GetBottom() + 1 - height
) / 2; 
1343     else // alignment & wxALIGN_TOP 
1348     // draw the bitmap first 
1354         DrawBitmap(bitmap
, x
, y
, true /* use mask */); 
1356         wxCoord offset 
= bitmap
.GetWidth() + 4; 
1360         y 
+= (height 
- heightText
) / 2; 
1363     // we will draw the underscore under the accel char later 
1364     wxCoord startUnderscore 
= 0, 
1368     // split the string into lines and draw each of them separately 
1370     for ( wxString::const_iterator pc 
= text
.begin(); ; ++pc 
) 
1372         if ( *pc 
== _T('\n') || pc 
== text
.end() ) 
1374             int xRealStart 
= x
; // init it here to avoid compielr warnings 
1376             if ( !curLine
.empty() ) 
1378                 // NB: can't test for !(alignment & wxALIGN_LEFT) because 
1379                 //     wxALIGN_LEFT is 0 
1380                 if ( alignment 
& (wxALIGN_RIGHT 
| wxALIGN_CENTRE_HORIZONTAL
) ) 
1383                     GetTextExtent(curLine
, &widthLine
, NULL
); 
1385                     if ( alignment 
& wxALIGN_RIGHT 
) 
1387                         xRealStart 
+= width 
- widthLine
; 
1389                     else // if ( alignment & wxALIGN_CENTRE_HORIZONTAL ) 
1391                         xRealStart 
+= (width 
- widthLine
) / 2; 
1394                 //else: left aligned, nothing to do 
1396                 DrawText(curLine
, xRealStart
, y
); 
1401             // do we have underscore in this line? we can check yUnderscore 
1402             // because it is set below to just y + heightLine if we do 
1403             if ( y 
== yUnderscore 
) 
1405                 // adjust the horz positions to account for the shift 
1406                 startUnderscore 
+= xRealStart
; 
1407                 endUnderscore 
+= xRealStart
; 
1410             if ( pc 
== text
.end() ) 
1415         else // not end of line 
1417             if ( pc 
- text
.begin() == indexAccel 
) 
1419                 // remeber to draw underscore here 
1420                 GetTextExtent(curLine
, &startUnderscore
, NULL
); 
1422                 GetTextExtent(curLine
, &endUnderscore
, NULL
); 
1424                 yUnderscore 
= y 
+ heightLine
; 
1433     // draw the underscore if found 
1434     if ( startUnderscore 
!= endUnderscore 
) 
1436         // it should be of the same colour as text 
1437         SetPen(wxPen(GetTextForeground(), 0, wxSOLID
)); 
1441         DrawLine(startUnderscore
, yUnderscore
, endUnderscore
, yUnderscore
); 
1444     // return bounding rect if requested 
1447         *rectBounding 
= wxRect(x
, y 
- heightText
, widthText
, heightText
); 
1450     CalcBoundingBox(x0
, y0
); 
1451     CalcBoundingBox(x0 
+ width0
, y0 
+ height
); 
1454 #if WXWIN_COMPATIBILITY_2_8 
1455     // for compatibility with the old code when wxCoord was long everywhere 
1456 void wxDC::GetTextExtent(const wxString
& string
, 
1459                        long *externalLeading
, 
1460                        const wxFont 
*theFont
) const 
1462         wxCoord x2
, y2
, descent2
, externalLeading2
; 
1463         m_pimpl
->DoGetTextExtent(string
, &x2
, &y2
, 
1464                         &descent2
, &externalLeading2
, 
1471             *descent 
= descent2
; 
1472         if ( externalLeading 
) 
1473             *externalLeading 
= externalLeading2
; 
1476 void wxDC::GetLogicalOrigin(long *x
, long *y
) const  
1479         m_pimpl
->DoGetLogicalOrigin(&x2
, &y2
); 
1486 void wxDC::GetDeviceOrigin(long *x
, long *y
) const  
1489         m_pimpl
->DoGetDeviceOrigin(&x2
, &y2
); 
1496 void wxDC::GetClippingBox(long *x
, long *y
, long *w
, long *h
) const  
1498         wxCoord xx
,yy
,ww
,hh
; 
1499         m_pimpl
->DoGetClippingBox(&xx
, &yy
, &ww
, &hh
); 
1506 #endif  // WXWIN_COMPATIBILITY_2_8 
1509 #else  // wxUSE_NEW_DC 
1512 // bool wxDCBase::sm_cacheing = false; 
1514 IMPLEMENT_ABSTRACT_CLASS(wxDCBase
, wxObject
) 
1516 // ============================================================================ 
1518 // ============================================================================ 
1520 IMPLEMENT_DYNAMIC_CLASS(wxBufferedDC
, wxMemoryDC
) 
1521 IMPLEMENT_ABSTRACT_CLASS(wxBufferedPaintDC
, wxBufferedDC
) 
1523 wxDCBase::wxDCBase() 
1524         : m_colour(wxColourDisplay()) 
1527         , m_isInteractive(0) 
1528         , m_isBBoxValid(false) 
1529         , m_logicalOriginX(0), m_logicalOriginY(0) 
1530         , m_deviceOriginX(0), m_deviceOriginY(0) 
1531         , m_deviceLocalOriginX(0), m_deviceLocalOriginY(0) 
1532         , m_logicalScaleX(1.0), m_logicalScaleY(1.0) 
1533         , m_userScaleX(1.0), m_userScaleY(1.0) 
1534         , m_scaleX(1.0), m_scaleY(1.0) 
1535         , m_signX(1), m_signY(1) 
1536         , m_minX(0), m_minY(0), m_maxX(0), m_maxY(0) 
1537         , m_clipX1(0), m_clipY1(0), m_clipX2(0), m_clipY2(0) 
1538         , m_logicalFunction(wxCOPY
) 
1539         , m_backgroundMode(wxTRANSPARENT
) 
1540         , m_mappingMode(wxMM_TEXT
) 
1543         , m_backgroundBrush(*wxTRANSPARENT_BRUSH
) 
1544         , m_textForegroundColour(*wxBLACK
) 
1545         , m_textBackgroundColour(*wxWHITE
) 
1549         , m_hasCustomPalette(false) 
1550 #endif // wxUSE_PALETTE 
1552     m_mm_to_pix_x 
= (double)wxGetDisplaySize().GetWidth() / 
1553                     (double)wxGetDisplaySizeMM().GetWidth(); 
1554     m_mm_to_pix_y 
= (double)wxGetDisplaySize().GetHeight() / 
1555                     (double)wxGetDisplaySizeMM().GetHeight(); 
1561 wxDCBase::~wxDCBase() 
1565 #if WXWIN_COMPATIBILITY_2_6 
1566 void wxDCBase::BeginDrawing() 
1570 void wxDCBase::EndDrawing() 
1573 #endif // WXWIN_COMPATIBILITY_2_6 
1575 #if WXWIN_COMPATIBILITY_2_8 
1576     // for compatibility with the old code when wxCoord was long everywhere 
1577 void wxDCBase::GetTextExtent(const wxString
& string
, 
1580                        long *externalLeading
, 
1581                        const wxFont 
*theFont
) const 
1583         wxCoord x2
, y2
, descent2
, externalLeading2
; 
1584         DoGetTextExtent(string
, &x2
, &y2
, 
1585                         &descent2
, &externalLeading2
, 
1592             *descent 
= descent2
; 
1593         if ( externalLeading 
) 
1594             *externalLeading 
= externalLeading2
; 
1597 void wxDCBase::GetLogicalOrigin(long *x
, long *y
) const  
1600         DoGetLogicalOrigin(&x2
, &y2
); 
1607 void wxDCBase::GetDeviceOrigin(long *x
, long *y
) const  
1610         DoGetDeviceOrigin(&x2
, &y2
); 
1617 void wxDCBase::GetClippingBox(long *x
, long *y
, long *w
, long *h
) const  
1619         wxCoord xx
,yy
,ww
,hh
; 
1620         DoGetClippingBox(&xx
, &yy
, &ww
, &hh
); 
1626 #endif  // WXWIN_COMPATIBILITY_2_8 
1630 // ---------------------------------------------------------------------------- 
1631 // coordinate conversions and transforms 
1632 // ---------------------------------------------------------------------------- 
1634 wxCoord 
wxDCBase::DeviceToLogicalX(wxCoord x
) const 
1636     return wxRound((double)(x 
- m_deviceOriginX 
- m_deviceLocalOriginX
) / m_scaleX
) * m_signX 
+ m_logicalOriginX
; 
1639 wxCoord 
wxDCBase::DeviceToLogicalY(wxCoord y
) const 
1641     return wxRound((double)(y 
- m_deviceOriginY 
- m_deviceLocalOriginY
) / m_scaleY
) * m_signY 
+ m_logicalOriginY
; 
1644 wxCoord 
wxDCBase::DeviceToLogicalXRel(wxCoord x
) const 
1646     return wxRound((double)(x
) / m_scaleX
); 
1649 wxCoord 
wxDCBase::DeviceToLogicalYRel(wxCoord y
) const 
1651     return wxRound((double)(y
) / m_scaleY
); 
1654 wxCoord 
wxDCBase::LogicalToDeviceX(wxCoord x
) const 
1656     return wxRound((double)(x 
- m_logicalOriginX
) * m_scaleX
) * m_signX 
+ m_deviceOriginX 
+ m_deviceLocalOriginX
; 
1659 wxCoord 
wxDCBase::LogicalToDeviceY(wxCoord y
) const 
1661     return wxRound((double)(y 
- m_logicalOriginY
) * m_scaleY
) * m_signY 
+ m_deviceOriginY 
+ m_deviceLocalOriginY
; 
1664 wxCoord 
wxDCBase::LogicalToDeviceXRel(wxCoord x
) const 
1666     return wxRound((double)(x
) * m_scaleX
); 
1669 wxCoord 
wxDCBase::LogicalToDeviceYRel(wxCoord y
) const 
1671     return wxRound((double)(y
) * m_scaleY
); 
1674 void wxDCBase::ComputeScaleAndOrigin() 
1676     m_scaleX 
= m_logicalScaleX 
* m_userScaleX
; 
1677     m_scaleY 
= m_logicalScaleY 
* m_userScaleY
; 
1680 void wxDCBase::SetMapMode( int mode 
) 
1685           SetLogicalScale( twips2mm
*m_mm_to_pix_x
, twips2mm
*m_mm_to_pix_y 
); 
1688           SetLogicalScale( pt2mm
*m_mm_to_pix_x
, pt2mm
*m_mm_to_pix_y 
); 
1691           SetLogicalScale( m_mm_to_pix_x
, m_mm_to_pix_y 
); 
1694           SetLogicalScale( m_mm_to_pix_x
/10.0, m_mm_to_pix_y
/10.0 ); 
1698           SetLogicalScale( 1.0, 1.0 ); 
1701     m_mappingMode 
= mode
; 
1704 void wxDCBase::SetUserScale( double x
, double y 
) 
1706     // allow negative ? -> no 
1709     ComputeScaleAndOrigin(); 
1712 void wxDCBase::SetLogicalScale( double x
, double y 
) 
1715     m_logicalScaleX 
= x
; 
1716     m_logicalScaleY 
= y
; 
1717     ComputeScaleAndOrigin(); 
1720 void wxDCBase::SetLogicalOrigin( wxCoord x
, wxCoord y 
) 
1722     m_logicalOriginX 
= x 
* m_signX
; 
1723     m_logicalOriginY 
= y 
* m_signY
; 
1724     ComputeScaleAndOrigin(); 
1727 void wxDCBase::SetDeviceOrigin( wxCoord x
, wxCoord y 
) 
1729     m_deviceOriginX 
= x
; 
1730     m_deviceOriginY 
= y
; 
1731     ComputeScaleAndOrigin(); 
1734 void wxDCBase::SetDeviceLocalOrigin( wxCoord x
, wxCoord y 
) 
1736     m_deviceLocalOriginX 
= x
; 
1737     m_deviceLocalOriginY 
= y
; 
1738     ComputeScaleAndOrigin(); 
1741 void wxDCBase::SetAxisOrientation( bool xLeftRight
, bool yBottomUp 
) 
1743     // only wxPostScripDC has m_signX = -1, we override SetAxisOrientation there 
1744     // wxWidgets 2.9: no longer override it 
1745     m_signX 
= (xLeftRight 
?  1 : -1); 
1746     m_signY 
= (yBottomUp  
? -1 :  1); 
1747     ComputeScaleAndOrigin(); 
1750 // ---------------------------------------------------------------------------- 
1752 // ---------------------------------------------------------------------------- 
1754 void wxDCBase::DoDrawCheckMark(wxCoord x1
, wxCoord y1
, 
1755                                wxCoord width
, wxCoord height
) 
1757     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
1759     wxCoord x2 
= x1 
+ width
, 
1762     // the pen width is calibrated to give 3 for width == height == 10 
1763     wxDCPenChanger 
pen((wxDC
&)*this, 
1764                         wxPen(GetTextForeground(), (width 
+ height 
+ 1)/7)); 
1766     // we're drawing a scaled version of wx/generic/tick.xpm here 
1767     wxCoord x3 
= x1 
+ (4*width
) / 10,   // x of the tick bottom 
1768             y3 
= y1 
+ height 
/ 2;       // y of the left tick branch 
1769     DoDrawLine(x1
, y3
, x3
, y2
); 
1770     DoDrawLine(x3
, y2
, x2
, y1
); 
1772     CalcBoundingBox(x1
, y1
); 
1773     CalcBoundingBox(x2
, y2
); 
1776 // ---------------------------------------------------------------------------- 
1777 // stubs for functions not implemented in all ports 
1778 // ---------------------------------------------------------------------------- 
1781 wxDCBase::DoStretchBlit(wxCoord xdest
, wxCoord ydest
, 
1782                         wxCoord dstWidth
, wxCoord dstHeight
, 
1784                         wxCoord xsrc
, wxCoord ysrc
, 
1785                         wxCoord srcWidth
, wxCoord srcHeight
, 
1791     wxCHECK_MSG( srcWidth 
&& srcHeight 
&& dstWidth 
&& dstHeight
, false, 
1792                  _T("invalid blit size") ); 
1794     // emulate the stretching by modifying the DC scale 
1795     double xscale 
= (double)srcWidth
/dstWidth
, 
1796            yscale 
= (double)srcHeight
/dstHeight
; 
1798     double xscaleOld
, yscaleOld
; 
1799     GetUserScale(&xscaleOld
, &yscaleOld
); 
1800     SetUserScale(xscaleOld
/xscale
, yscaleOld
/yscale
); 
1802     bool rc 
= DoBlit(wxCoord(xdest
*xscale
), wxCoord(ydest
*yscale
), 
1803                      wxCoord(dstWidth
*xscale
), wxCoord(dstHeight
*yscale
), 
1805                      xsrc
, ysrc
, rop
, useMask
, xsrcMask
, ysrcMask
); 
1807     SetUserScale(xscaleOld
, yscaleOld
); 
1812 // ---------------------------------------------------------------------------- 
1814 // ---------------------------------------------------------------------------- 
1816 void wxDCBase::DrawLines(const wxPointList 
*list
, wxCoord xoffset
, wxCoord yoffset
) 
1818     unsigned int n 
= list
->GetCount(); 
1819     wxPoint 
*points 
= new wxPoint
[n
]; 
1822     wxPointList::compatibility_iterator node
; 
1823     for ( node 
= list
->GetFirst(); node
; node 
= node
->GetNext(), i
++ ) 
1825         wxPoint 
*point 
= node
->GetData(); 
1826         points
[i
].x 
= point
->x
; 
1827         points
[i
].y 
= point
->y
; 
1830     DoDrawLines(n
, points
, xoffset
, yoffset
); 
1835 #if WXWIN_COMPATIBILITY_2_8 
1836 void wxDCBase::DrawLines(const wxList 
*list
, wxCoord xoffset
, wxCoord yoffset 
) 
1838     unsigned int n 
= list
->GetCount(); 
1839     wxPoint 
*points 
= new wxPoint
[n
]; 
1842     wxObjectList::compatibility_iterator node
; 
1843     for ( node 
= list
->GetFirst(); node
; node 
= node
->GetNext(), i
++ ) 
1845         wxPoint 
*point 
= (wxPoint
*) node
->GetData(); 
1846         points
[i
].x 
= point
->x
; 
1847         points
[i
].y 
= point
->y
; 
1850     DoDrawLines(n
, points
, xoffset
, yoffset
); 
1854 #endif  // WXWIN_COMPATIBILITY_2_8 
1857 void wxDCBase::DrawPolygon(const wxPointList 
*list
, 
1858                            wxCoord xoffset
, wxCoord yoffset
, 
1861     unsigned int n 
= list
->GetCount(); 
1862     wxPoint 
*points 
= new wxPoint
[n
]; 
1865     wxPointList::compatibility_iterator node
; 
1866     for ( node 
= list
->GetFirst(); node
; node 
= node
->GetNext(), i
++ ) 
1868         wxPoint 
*point 
= node
->GetData(); 
1869         points
[i
].x 
= point
->x
; 
1870         points
[i
].y 
= point
->y
; 
1873     DoDrawPolygon(n
, points
, xoffset
, yoffset
, fillStyle
); 
1879 #if WXWIN_COMPATIBILITY_2_8 
1880 void wxDCBase::DrawPolygon(const wxList 
*list
, 
1881                      wxCoord xoffset
, wxCoord yoffset
, 
1884     unsigned int n 
= list
->GetCount(); 
1885     wxPoint 
*points 
= new wxPoint
[n
]; 
1888     wxObjectList::compatibility_iterator node
; 
1889     for ( node 
= list
->GetFirst(); node
; node 
= node
->GetNext(), i
++ ) 
1891         wxPoint 
*point 
= (wxPoint
*) node
->GetData(); 
1892         points
[i
].x 
= point
->x
; 
1893         points
[i
].y 
= point
->y
; 
1896     DoDrawPolygon(n
, points
, xoffset
, yoffset
, fillStyle
); 
1900 #endif  // WXWIN_COMPATIBILITY_2_8 
1903 wxDCBase::DoDrawPolyPolygon(int n
, 
1906                             wxCoord xoffset
, wxCoord yoffset
, 
1911         DoDrawPolygon(count
[0], points
, xoffset
, yoffset
, fillStyle
); 
1919     for (i 
= j 
= lastOfs 
= 0; i 
< n
; i
++) 
1924     pts 
= new wxPoint
[j
+n
-1]; 
1925     for (i 
= 0; i 
< j
; i
++) 
1927     for (i 
= 2; i 
<= n
; i
++) 
1929         lastOfs 
-= count
[n
-i
]; 
1930         pts
[j
++] = pts
[lastOfs
]; 
1934     SetPen(wxPen(*wxBLACK
, 0, wxTRANSPARENT
)); 
1935     DoDrawPolygon(j
, pts
, xoffset
, yoffset
, fillStyle
); 
1937     for (i 
= j 
= 0; i 
< n
; i
++) 
1939         DoDrawLines(count
[i
], pts
+j
, xoffset
, yoffset
); 
1945 // ---------------------------------------------------------------------------- 
1947 // ---------------------------------------------------------------------------- 
1951 void wxDCBase::DrawSpline(wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
, wxCoord x3
, wxCoord y3
) 
1953     wxPointList point_list
; 
1955     wxPoint 
*point1 
= new wxPoint
; 
1956     point1
->x 
= x1
; point1
->y 
= y1
; 
1957     point_list
.Append( point1 
); 
1959     wxPoint 
*point2 
= new wxPoint
; 
1960     point2
->x 
= x2
; point2
->y 
= y2
; 
1961     point_list
.Append( point2 
); 
1963     wxPoint 
*point3 
= new wxPoint
; 
1964     point3
->x 
= x3
; point3
->y 
= y3
; 
1965     point_list
.Append( point3 
); 
1967     DrawSpline(&point_list
); 
1969     for( wxPointList::compatibility_iterator node 
= point_list
.GetFirst(); node
; node 
= node
->GetNext() ) 
1971         wxPoint 
*p 
= node
->GetData(); 
1976 void wxDCBase::DrawSpline(int n
, wxPoint points
[]) 
1979     for (int i 
=0; i 
< n
; i
++) 
1980         list
.Append( &points
[i
] ); 
1985 // ----------------------------------- spline code ---------------------------------------- 
1987 void wx_quadratic_spline(double a1
, double b1
, double a2
, double b2
, 
1988                          double a3
, double b3
, double a4
, double b4
); 
1989 void wx_clear_stack(); 
1990 int wx_spline_pop(double *x1
, double *y1
, double *x2
, double *y2
, double *x3
, 
1991         double *y3
, double *x4
, double *y4
); 
1992 void wx_spline_push(double x1
, double y1
, double x2
, double y2
, double x3
, double y3
, 
1993           double x4
, double y4
); 
1994 static bool wx_spline_add_point(double x
, double y
); 
1995 static void wx_spline_draw_point_array(wxDCBase 
*dc
); 
1997 wxPointList wx_spline_point_list
; 
1999 #define                half(z1, z2)        ((z1+z2)/2.0) 
2002 /* iterative version */ 
2004 void wx_quadratic_spline(double a1
, double b1
, double a2
, double b2
, double a3
, double b3
, double a4
, 
2007     register double  xmid
, ymid
; 
2008     double           x1
, y1
, x2
, y2
, x3
, y3
, x4
, y4
; 
2011     wx_spline_push(a1
, b1
, a2
, b2
, a3
, b3
, a4
, b4
); 
2013     while (wx_spline_pop(&x1
, &y1
, &x2
, &y2
, &x3
, &y3
, &x4
, &y4
)) { 
2014         xmid 
= (double)half(x2
, x3
); 
2015         ymid 
= (double)half(y2
, y3
); 
2016         if (fabs(x1 
- xmid
) < THRESHOLD 
&& fabs(y1 
- ymid
) < THRESHOLD 
&& 
2017             fabs(xmid 
- x4
) < THRESHOLD 
&& fabs(ymid 
- y4
) < THRESHOLD
) { 
2018             wx_spline_add_point( x1
, y1 
); 
2019             wx_spline_add_point( xmid
, ymid 
); 
2021             wx_spline_push(xmid
, ymid
, (double)half(xmid
, x3
), (double)half(ymid
, y3
), 
2022                  (double)half(x3
, x4
), (double)half(y3
, y4
), x4
, y4
); 
2023             wx_spline_push(x1
, y1
, (double)half(x1
, x2
), (double)half(y1
, y2
), 
2024                  (double)half(x2
, xmid
), (double)half(y2
, ymid
), xmid
, ymid
); 
2029 /* utilities used by spline drawing routines */ 
2031 typedef struct wx_spline_stack_struct 
{ 
2032     double           x1
, y1
, x2
, y2
, x3
, y3
, x4
, y4
; 
2035 #define         SPLINE_STACK_DEPTH             20 
2036 static Stack    wx_spline_stack
[SPLINE_STACK_DEPTH
]; 
2037 static Stack   
*wx_stack_top
; 
2038 static int      wx_stack_count
; 
2040 void wx_clear_stack() 
2042     wx_stack_top 
= wx_spline_stack
; 
2046 void wx_spline_push(double x1
, double y1
, double x2
, double y2
, double x3
, double y3
, double x4
, double y4
) 
2048     wx_stack_top
->x1 
= x1
; 
2049     wx_stack_top
->y1 
= y1
; 
2050     wx_stack_top
->x2 
= x2
; 
2051     wx_stack_top
->y2 
= y2
; 
2052     wx_stack_top
->x3 
= x3
; 
2053     wx_stack_top
->y3 
= y3
; 
2054     wx_stack_top
->x4 
= x4
; 
2055     wx_stack_top
->y4 
= y4
; 
2060 int wx_spline_pop(double *x1
, double *y1
, double *x2
, double *y2
, 
2061                   double *x3
, double *y3
, double *x4
, double *y4
) 
2063     if (wx_stack_count 
== 0) 
2067     *x1 
= wx_stack_top
->x1
; 
2068     *y1 
= wx_stack_top
->y1
; 
2069     *x2 
= wx_stack_top
->x2
; 
2070     *y2 
= wx_stack_top
->y2
; 
2071     *x3 
= wx_stack_top
->x3
; 
2072     *y3 
= wx_stack_top
->y3
; 
2073     *x4 
= wx_stack_top
->x4
; 
2074     *y4 
= wx_stack_top
->y4
; 
2078 static bool wx_spline_add_point(double x
, double y
) 
2080     wxPoint 
*point 
= new wxPoint( wxRound(x
), wxRound(y
) ); 
2081     wx_spline_point_list
.Append( point 
); 
2085 static void wx_spline_draw_point_array(wxDCBase 
*dc
) 
2087     dc
->DrawLines(&wx_spline_point_list
, 0, 0 ); 
2088     wxPointList::compatibility_iterator node 
= wx_spline_point_list
.GetFirst(); 
2091         wxPoint 
*point 
= node
->GetData(); 
2093         wx_spline_point_list
.Erase(node
); 
2094         node 
= wx_spline_point_list
.GetFirst(); 
2098 #if WXWIN_COMPATIBILITY_2_8 
2099 void wxDCBase::DrawSpline(const wxList 
*points
) 
2102     wxObjectList::compatibility_iterator node 
= points
->GetFirst(); 
2105         list
.Append( (wxPoint
*) node
->GetData() ); 
2106         node 
= node
->GetNext(); 
2108     DoDrawSpline( &list 
); 
2110 #endif  // WXWIN_COMPATIBILITY_2_8 
2112 void wxDCBase::DoDrawSpline( const wxPointList 
*points 
) 
2114     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
2117     double           cx1
, cy1
, cx2
, cy2
, cx3
, cy3
, cx4
, cy4
; 
2118     double           x1
, y1
, x2
, y2
; 
2120     wxPointList::compatibility_iterator node 
= points
->GetFirst(); 
2125     p 
= node
->GetData(); 
2130     node 
= node
->GetNext(); 
2131     p 
= node
->GetData(); 
2135     cx1 
= (double)((x1 
+ x2
) / 2); 
2136     cy1 
= (double)((y1 
+ y2
) / 2); 
2137     cx2 
= (double)((cx1 
+ x2
) / 2); 
2138     cy2 
= (double)((cy1 
+ y2
) / 2); 
2140     wx_spline_add_point(x1
, y1
); 
2142     while ((node 
= node
->GetNext()) 
2145 #endif // !wxUSE_STL 
2148         p 
= node
->GetData(); 
2153         cx4 
= (double)(x1 
+ x2
) / 2; 
2154         cy4 
= (double)(y1 
+ y2
) / 2; 
2155         cx3 
= (double)(x1 
+ cx4
) / 2; 
2156         cy3 
= (double)(y1 
+ cy4
) / 2; 
2158         wx_quadratic_spline(cx1
, cy1
, cx2
, cy2
, cx3
, cy3
, cx4
, cy4
); 
2162         cx2 
= (double)(cx1 
+ x2
) / 2; 
2163         cy2 
= (double)(cy1 
+ y2
) / 2; 
2166     wx_spline_add_point( cx1
, cy1 
); 
2167     wx_spline_add_point( x2
, y2 
); 
2169     wx_spline_draw_point_array( this ); 
2172 #endif // wxUSE_SPLINES 
2174 // ---------------------------------------------------------------------------- 
2175 // Partial Text Extents 
2176 // ---------------------------------------------------------------------------- 
2179 // Each element of the widths array will be the width of the string up to and 
2180 // including the corresponding character in text.  This is the generic 
2181 // implementation, the port-specific classes should do this with native APIs 
2182 // if available and if faster.  Note: pango_layout_index_to_pos is much slower 
2183 // than calling GetTextExtent!! 
2185 #define FWC_SIZE 256 
2187 class FontWidthCache
 
2190     FontWidthCache() : m_scaleX(1), m_widths(NULL
) { } 
2191     ~FontWidthCache() { delete []m_widths
; } 
2196             m_widths 
= new int[FWC_SIZE
]; 
2198         memset(m_widths
, 0, sizeof(int)*FWC_SIZE
); 
2206 static FontWidthCache s_fontWidthCache
; 
2208 bool wxDCBase::DoGetPartialTextExtents(const wxString
& text
, wxArrayInt
& widths
) const 
2212     const size_t len 
= text
.length(); 
2216     // reset the cache if font or horizontal scale have changed 
2217     if ( !s_fontWidthCache
.m_widths 
|| 
2218          !wxIsSameDouble(s_fontWidthCache
.m_scaleX
, m_scaleX
) || 
2219          (s_fontWidthCache
.m_font 
!= GetFont()) ) 
2221         s_fontWidthCache
.Reset(); 
2222         s_fontWidthCache
.m_font 
= GetFont(); 
2223         s_fontWidthCache
.m_scaleX 
= m_scaleX
; 
2226     // Calculate the position of each character based on the widths of 
2227     // the previous characters 
2229     for ( size_t i 
= 0; i 
< len
; i
++ ) 
2231         const wxChar c 
= text
[i
]; 
2232         unsigned int c_int 
= (unsigned int)c
; 
2234         if ((c_int 
< FWC_SIZE
) && (s_fontWidthCache
.m_widths
[c_int
] != 0)) 
2236             w 
= s_fontWidthCache
.m_widths
[c_int
]; 
2240             GetTextExtent(c
, &w
, &h
); 
2241             if (c_int 
< FWC_SIZE
) 
2242                 s_fontWidthCache
.m_widths
[c_int
] = w
; 
2246         widths
[i
] = totalWidth
; 
2253 // ---------------------------------------------------------------------------- 
2254 // enhanced text drawing 
2255 // ---------------------------------------------------------------------------- 
2257 void wxDCBase::GetMultiLineTextExtent(const wxString
& text
, 
2261                                       const wxFont 
*font
) const 
2263     wxCoord widthTextMax 
= 0, widthLine
, 
2264             heightTextTotal 
= 0, heightLineDefault 
= 0, heightLine 
= 0; 
2267     for ( wxString::const_iterator pc 
= text
.begin(); ; ++pc 
) 
2269         if ( pc 
== text
.end() || *pc 
== _T('\n') ) 
2271             if ( curLine
.empty() ) 
2273                 // we can't use GetTextExtent - it will return 0 for both width 
2274                 // and height and an empty line should count in height 
2277                 // assume that this line has the same height as the previous 
2279                 if ( !heightLineDefault 
) 
2280                     heightLineDefault 
= heightLine
; 
2282                 if ( !heightLineDefault 
) 
2284                     // but we don't know it yet - choose something reasonable 
2285                     GetTextExtent(_T("W"), NULL
, &heightLineDefault
, 
2289                 heightTextTotal 
+= heightLineDefault
; 
2293                 GetTextExtent(curLine
, &widthLine
, &heightLine
, 
2295                 if ( widthLine 
> widthTextMax 
) 
2296                     widthTextMax 
= widthLine
; 
2297                 heightTextTotal 
+= heightLine
; 
2300             if ( pc 
== text
.end() ) 
2318         *y 
= heightTextTotal
; 
2323 void wxDCBase::DrawLabel(const wxString
& text
, 
2324                          const wxBitmap
& bitmap
, 
2328                          wxRect 
*rectBounding
) 
2330     // find the text position 
2331     wxCoord widthText
, heightText
, heightLine
; 
2332     GetMultiLineTextExtent(text
, &widthText
, &heightText
, &heightLine
); 
2334     wxCoord width
, height
; 
2337         width 
= widthText 
+ bitmap
.GetWidth(); 
2338         height 
= bitmap
.GetHeight(); 
2343         height 
= heightText
; 
2347     if ( alignment 
& wxALIGN_RIGHT 
) 
2349         x 
= rect
.GetRight() - width
; 
2351     else if ( alignment 
& wxALIGN_CENTRE_HORIZONTAL 
) 
2353         x 
= (rect
.GetLeft() + rect
.GetRight() + 1 - width
) / 2; 
2355     else // alignment & wxALIGN_LEFT 
2360     if ( alignment 
& wxALIGN_BOTTOM 
) 
2362         y 
= rect
.GetBottom() - height
; 
2364     else if ( alignment 
& wxALIGN_CENTRE_VERTICAL 
) 
2366         y 
= (rect
.GetTop() + rect
.GetBottom() + 1 - height
) / 2; 
2368     else // alignment & wxALIGN_TOP 
2373     // draw the bitmap first 
2379         DrawBitmap(bitmap
, x
, y
, true /* use mask */); 
2381         wxCoord offset 
= bitmap
.GetWidth() + 4; 
2385         y 
+= (height 
- heightText
) / 2; 
2388     // we will draw the underscore under the accel char later 
2389     wxCoord startUnderscore 
= 0, 
2393     // split the string into lines and draw each of them separately 
2395     for ( wxString::const_iterator pc 
= text
.begin(); ; ++pc 
) 
2397         if ( pc 
== text
.end() || *pc 
== _T('\n') ) 
2399             int xRealStart 
= x
; // init it here to avoid compielr warnings 
2401             if ( !curLine
.empty() ) 
2403                 // NB: can't test for !(alignment & wxALIGN_LEFT) because 
2404                 //     wxALIGN_LEFT is 0 
2405                 if ( alignment 
& (wxALIGN_RIGHT 
| wxALIGN_CENTRE_HORIZONTAL
) ) 
2408                     GetTextExtent(curLine
, &widthLine
, NULL
); 
2410                     if ( alignment 
& wxALIGN_RIGHT 
) 
2412                         xRealStart 
+= width 
- widthLine
; 
2414                     else // if ( alignment & wxALIGN_CENTRE_HORIZONTAL ) 
2416                         xRealStart 
+= (width 
- widthLine
) / 2; 
2419                 //else: left aligned, nothing to do 
2421                 DrawText(curLine
, xRealStart
, y
); 
2426             // do we have underscore in this line? we can check yUnderscore 
2427             // because it is set below to just y + heightLine if we do 
2428             if ( y 
== yUnderscore 
) 
2430                 // adjust the horz positions to account for the shift 
2431                 startUnderscore 
+= xRealStart
; 
2432                 endUnderscore 
+= xRealStart
; 
2435             if ( pc 
== text
.end() ) 
2440         else // not end of line 
2442             if ( pc 
- text
.begin() == indexAccel 
) 
2444                 // remeber to draw underscore here 
2445                 GetTextExtent(curLine
, &startUnderscore
, NULL
); 
2447                 GetTextExtent(curLine
, &endUnderscore
, NULL
); 
2449                 yUnderscore 
= y 
+ heightLine
; 
2458     // draw the underscore if found 
2459     if ( startUnderscore 
!= endUnderscore 
) 
2461         // it should be of the same colour as text 
2462         SetPen(wxPen(GetTextForeground(), 0, wxSOLID
)); 
2466         DrawLine(startUnderscore
, yUnderscore
, endUnderscore
, yUnderscore
); 
2469     // return bounding rect if requested 
2472         *rectBounding 
= wxRect(x
, y 
- heightText
, widthText
, heightText
); 
2475     CalcBoundingBox(x0
, y0
); 
2476     CalcBoundingBox(x0 
+ width0
, y0 
+ height
); 
2480 void wxDCBase::DoGradientFillLinear(const wxRect
& rect
, 
2481                                     const wxColour
& initialColour
, 
2482                                     const wxColour
& destColour
, 
2483                                     wxDirection nDirection
) 
2486     wxPen oldPen 
= m_pen
; 
2487     wxBrush oldBrush 
= m_brush
; 
2489     wxUint8 nR1 
= initialColour
.Red(); 
2490     wxUint8 nG1 
= initialColour
.Green(); 
2491     wxUint8 nB1 
= initialColour
.Blue(); 
2492     wxUint8 nR2 
= destColour
.Red(); 
2493     wxUint8 nG2 
= destColour
.Green(); 
2494     wxUint8 nB2 
= destColour
.Blue(); 
2497     if ( nDirection 
== wxEAST 
|| nDirection 
== wxWEST 
) 
2499         wxInt32 x 
= rect
.GetWidth(); 
2500         wxInt32 w 
= x
;              // width of area to shade 
2501         wxInt32 xDelta 
= w
/256;     // height of one shade bend 
2509                 nR 
= nR1 
- (nR1
-nR2
)*(w
-x
)/w
; 
2511                 nR 
= nR1 
+ (nR2
-nR1
)*(w
-x
)/w
; 
2514                 nG 
= nG1 
- (nG1
-nG2
)*(w
-x
)/w
; 
2516                 nG 
= nG1 
+ (nG2
-nG1
)*(w
-x
)/w
; 
2519                 nB 
= nB1 
- (nB1
-nB2
)*(w
-x
)/w
; 
2521                 nB 
= nB1 
+ (nB2
-nB1
)*(w
-x
)/w
; 
2523             wxColour 
colour(nR
,nG
,nB
); 
2524             SetPen(wxPen(colour
, 1, wxSOLID
)); 
2525             SetBrush(wxBrush(colour
)); 
2526             if(nDirection 
== wxEAST
) 
2527                 DrawRectangle(rect
.GetRight()-x
-xDelta
+1, rect
.GetTop(), 
2528                         xDelta
, rect
.GetHeight()); 
2529             else //nDirection == wxWEST 
2530                 DrawRectangle(rect
.GetLeft()+x
, rect
.GetTop(), 
2531                         xDelta
, rect
.GetHeight()); 
2534     else  // nDirection == wxNORTH || nDirection == wxSOUTH 
2536         wxInt32 y 
= rect
.GetHeight(); 
2537         wxInt32 w 
= y
;              // height of area to shade 
2538         wxInt32 yDelta 
= w
/255;     // height of one shade bend 
2546                 nR 
= nR1 
- (nR1
-nR2
)*(w
-y
)/w
; 
2548                 nR 
= nR1 
+ (nR2
-nR1
)*(w
-y
)/w
; 
2551                 nG 
= nG1 
- (nG1
-nG2
)*(w
-y
)/w
; 
2553                 nG 
= nG1 
+ (nG2
-nG1
)*(w
-y
)/w
; 
2556                 nB 
= nB1 
- (nB1
-nB2
)*(w
-y
)/w
; 
2558                 nB 
= nB1 
+ (nB2
-nB1
)*(w
-y
)/w
; 
2560             wxColour 
colour(nR
,nG
,nB
); 
2561             SetPen(wxPen(colour
, 1, wxSOLID
)); 
2562             SetBrush(wxBrush(colour
)); 
2563             if(nDirection 
== wxNORTH
) 
2564                 DrawRectangle(rect
.GetLeft(), rect
.GetTop()+y
, 
2565                         rect
.GetWidth(), yDelta
); 
2566             else //nDirection == wxSOUTH 
2567                 DrawRectangle(rect
.GetLeft(), rect
.GetBottom()-y
-yDelta
+1, 
2568                         rect
.GetWidth(), yDelta
); 
2576 void wxDCBase::DoGradientFillConcentric(const wxRect
& rect
, 
2577                                       const wxColour
& initialColour
, 
2578                                       const wxColour
& destColour
, 
2579                                       const wxPoint
& circleCenter
) 
2581     //save the old pen color 
2582     wxColour oldPenColour 
= m_pen
.GetColour(); 
2584     wxUint8 nR1 
= destColour
.Red(); 
2585     wxUint8 nG1 
= destColour
.Green(); 
2586     wxUint8 nB1 
= destColour
.Blue(); 
2587     wxUint8 nR2 
= initialColour
.Red(); 
2588     wxUint8 nG2 
= initialColour
.Green(); 
2589     wxUint8 nB2 
= initialColour
.Blue(); 
2594     wxInt32 cx 
= rect
.GetWidth() / 2; 
2595     wxInt32 cy 
= rect
.GetHeight() / 2; 
2603     wxInt32 nCircleOffX 
= circleCenter
.x 
- (rect
.GetWidth() / 2); 
2604     wxInt32 nCircleOffY 
= circleCenter
.y 
- (rect
.GetHeight() / 2); 
2606     for ( wxInt32 x 
= 0; x 
< rect
.GetWidth(); x
++ ) 
2608         for ( wxInt32 y 
= 0; y 
< rect
.GetHeight(); y
++ ) 
2610             //get color difference 
2611             wxInt32 nGradient 
= ((nRadius 
- 
2613                                     pow((double)(x 
- cx 
- nCircleOffX
), 2) + 
2614                                     pow((double)(y 
- cy 
- nCircleOffY
), 2) 
2615                                   )) * 100) / nRadius
; 
2617             //normalize Gradient 
2622             nR 
= (wxUint8
)(nR1 
+ ((nR2 
- nR1
) * nGradient 
/ 100)); 
2623             nG 
= (wxUint8
)(nG1 
+ ((nG2 
- nG1
) * nGradient 
/ 100)); 
2624             nB 
= (wxUint8
)(nB1 
+ ((nB2 
- nB1
) * nGradient 
/ 100)); 
2627             m_pen
.SetColour(wxColour(nR
,nG
,nB
)); 
2628             DrawPoint(wxPoint(x 
+ rect
.GetLeft(), y 
+ rect
.GetTop())); 
2631     //return old pen color 
2632     m_pen
.SetColour(oldPenColour
); 
2636 Notes for wxWidgets DrawEllipticArcRot(...) 
2638 wxDCBase::DrawEllipticArcRot(...) draws a rotated elliptic arc or an ellipse. 
2639 It uses wxDCBase::CalculateEllipticPoints(...) and wxDCBase::Rotate(...), 
2642 All methods are generic, so they can be implemented in wxDCBase. 
2643 DoDrawEllipticArcRot(...) is virtual, so it can be called from deeper 
2644 methods like (WinCE) wxDC::DoDrawArc(...). 
2646 CalculateEllipticPoints(...) fills a given list of wxPoints with some points 
2647 of an elliptic arc. The algorithm is pixel-based: In every row (in flat 
2648 parts) or every column (in steep parts) only one pixel is calculated. 
2649 Trigonometric calculation (sin, cos, tan, atan) is only done if the 
2650 starting angle is not equal to the ending angle. The calculation of the 
2651 pixels is done using simple arithmetic only and should perform not too 
2652 bad even on devices without floating point processor. I didn't test this yet. 
2654 Rotate(...) rotates a list of point pixel-based, you will see rounding errors. 
2655 For instance: an ellipse rotated 180 degrees is drawn 
2656 slightly different from the original. 
2658 The points are then moved to an array and used to draw a polyline and/or polygon 
2659 (with center added, the pie). 
2660 The result looks quite similar to the native ellipse, only e few pixels differ. 
2662 The performance on a desktop system (Athlon 1800, WinXP) is about 7 times 
2663 slower as DrawEllipse(...), which calls the native API. 
2664 An rotated ellipse outside the clipping region takes nearly the same time, 
2665 while an native ellipse outside takes nearly no time to draw. 
2667 If you draw an arc with this new method, you will see the starting and ending angles 
2668 are calculated properly. 
2669 If you use DrawEllipticArc(...), you will see they are only correct for circles 
2670 and not properly calculated for ellipses. 
2673 p.lenhard@t-online.de 
2677 void wxDCBase::DoDrawEllipticArcRot( wxCoord x
, wxCoord y
, 
2678                                      wxCoord w
, wxCoord h
, 
2679                                      double sa
, double ea
, double angle 
) 
2683     CalculateEllipticPoints( &list
, x
, y
, w
, h
, sa
, ea 
); 
2684     Rotate( &list
, angle
, wxPoint( x
+w
/2, y
+h
/2 ) ); 
2686     // Add center (for polygon/pie) 
2687     list
.Append( new wxPoint( x
+w
/2, y
+h
/2 ) ); 
2689     // copy list into array and delete list elements 
2690     int n 
= list
.GetCount(); 
2691     wxPoint 
*points 
= new wxPoint
[n
]; 
2693     wxPointList::compatibility_iterator node
; 
2694     for ( node 
= list
.GetFirst(); node
; node 
= node
->GetNext(), i
++ ) 
2696         wxPoint 
*point 
= node
->GetData(); 
2697         points
[i
].x 
= point
->x
; 
2698         points
[i
].y 
= point
->y
; 
2702     // first draw the pie without pen, if necessary 
2703     if( GetBrush() != *wxTRANSPARENT_BRUSH 
) 
2705         wxPen 
tempPen( GetPen() ); 
2706         SetPen( *wxTRANSPARENT_PEN 
); 
2707         DoDrawPolygon( n
, points
, 0, 0 ); 
2711     // then draw the arc without brush, if necessary 
2712     if( GetPen() != *wxTRANSPARENT_PEN 
) 
2715         DoDrawLines( n
-1, points
, 0, 0 ); 
2720 } // DrawEllipticArcRot 
2722 void wxDCBase::Rotate( wxPointList
* points
, double angle
, wxPoint center 
) 
2727         double dSinA 
= -sin(angle
*2.0*pi
/360.0); 
2728         double dCosA 
= cos(angle
*2.0*pi
/360.0); 
2729         wxPointList::compatibility_iterator node
; 
2730         for ( node 
= points
->GetFirst(); node
; node 
= node
->GetNext() ) 
2732             wxPoint
* point 
= node
->GetData(); 
2734             // transform coordinates, if necessary 
2735             if( center
.x 
) point
->x 
-= center
.x
; 
2736             if( center
.y 
) point
->y 
-= center
.y
; 
2738             // calculate rotation, rounding simply by implicit cast to integer 
2739             int xTemp 
= point
->x 
* dCosA 
- point
->y 
* dSinA
; 
2740             point
->y 
= point
->x 
* dSinA 
+ point
->y 
* dCosA
; 
2743             // back transform coordinates, if necessary 
2744             if( center
.x 
) point
->x 
+= center
.x
; 
2745             if( center
.y 
) point
->y 
+= center
.y
; 
2750 void wxDCBase::CalculateEllipticPoints( wxPointList
* points
, 
2751                                         wxCoord xStart
, wxCoord yStart
, 
2752                                         wxCoord w
, wxCoord h
, 
2753                                         double sa
, double ea 
) 
2764     bool bUseAngles 
= false; 
2770     // decrement 1 pixel if ellipse is smaller than 2*a, 2*b 
2772     if( 2*a 
== w 
) decrX 
= 1; 
2774     if( 2*b 
== h 
) decrY 
= 1; 
2776     wxCoord xCenter 
= xStart 
+ a
; 
2777     wxCoord yCenter 
= yStart 
+ b
; 
2778     // calculate data for start and end, if necessary 
2782         // normalisation of angles 
2783         while( sa
<0 ) sa 
+= 360; 
2784         while( ea
<0 ) ea 
+= 360; 
2785         while( sa
>=360 ) sa 
-= 360; 
2786         while( ea
>=360 ) ea 
-= 360; 
2787         // calculate quadrant numbers 
2788         if( sa 
> 270 ) sq 
= 3; 
2789         else if( sa 
> 180 ) sq 
= 2; 
2790         else if( sa 
> 90 ) sq 
= 1; 
2791         if( ea 
> 270 ) eq 
= 3; 
2792         else if( ea 
> 180 ) eq 
= 2; 
2793         else if( ea 
> 90 ) eq 
= 1; 
2794         sar 
= sa 
* pi 
/ 180.0; 
2795         ear 
= ea 
* pi 
/ 180.0; 
2796         // correct angle circle -> ellipse 
2797         sar 
= atan( -a
/(double)b 
* tan( sar 
) ); 
2798         if ( sq 
== 1 || sq 
== 2 ) sar 
+= pi
; 
2799         ear 
= atan( -a
/(double)b 
* tan( ear 
) ); 
2800         if ( eq 
== 1 || eq 
== 2 ) ear 
+= pi
; 
2801         // coordinates of points 
2802         xsa 
= xCenter 
+ a 
* cos( sar 
); 
2803         if( sq 
== 0 || sq 
== 3 ) xsa 
-= decrX
; 
2804         ysa 
= yCenter 
+ b 
* sin( sar 
); 
2805         if( sq 
== 2 || sq 
== 3 ) ysa 
-= decrY
; 
2806         xea 
= xCenter 
+ a 
* cos( ear 
); 
2807         if( eq 
== 0 || eq 
== 3 ) xea 
-= decrX
; 
2808         yea 
= yCenter 
+ b 
* sin( ear 
); 
2809         if( eq 
== 2 || eq 
== 3 ) yea 
-= decrY
; 
2811     // calculate c1 = b^2, c2 = b^2/a^2 with a = w/2, b = h/2 
2813     double c2 
= 2.0 / w
; 
2822     // Lists for quadrant 1 to 4 
2823     wxPointList pointsarray
[4]; 
2824     // Calculate points for first quadrant and set in all quadrants 
2825     for( x 
= 0; x 
<= a
; ++x 
) 
2830         bool bNewPoint 
= false; 
2831         while( y2 
> c1 
- c2 
* x2 
&& y 
> 0 ) 
2837         // old y now to big: set point with old y, old x 
2838         if( bNewPoint 
&& x
>1) 
2841             // remove points on the same line 
2842             pointsarray
[0].Insert( new wxPoint( xCenter 
+ x1 
- decrX
, yCenter 
- y_old 
) ); 
2843             pointsarray
[1].Append( new wxPoint( xCenter 
- x1
, yCenter 
- y_old 
) ); 
2844             pointsarray
[2].Insert( new wxPoint( xCenter 
- x1
, yCenter 
+ y_old 
- decrY 
) ); 
2845             pointsarray
[3].Append( new wxPoint( xCenter 
+ x1 
- decrX
, yCenter 
+ y_old 
- decrY 
) ); 
2847     } // calculate point 
2849     // Starting and/or ending points for the quadrants, first quadrant gets both. 
2850     pointsarray
[0].Insert( new wxPoint( xCenter 
+ a 
- decrX
, yCenter 
) ); 
2851     pointsarray
[0].Append( new wxPoint( xCenter
, yCenter 
- b 
) ); 
2852     pointsarray
[1].Append( new wxPoint( xCenter 
- a
, yCenter 
) ); 
2853     pointsarray
[2].Append( new wxPoint( xCenter
, yCenter 
+ b 
- decrY 
) ); 
2854     pointsarray
[3].Append( new wxPoint( xCenter 
+ a 
- decrX
, yCenter 
) ); 
2856     // copy quadrants in original list 
2859         // Copy the right part of the points in the lists 
2860         // and delete the wxPoints, because they do not leave this method. 
2861         points
->Append( new wxPoint( xsa
, ysa 
) ); 
2863         bool bStarted 
= false; 
2864         bool bReady 
= false; 
2865         bool bForceTurn 
= ( sq 
== eq 
&& sa 
> ea 
); 
2868             wxPointList::compatibility_iterator node
; 
2869             for( node 
= pointsarray
[q
].GetFirst(); node
; node 
= node
->GetNext() ) 
2871                 // once: go to starting point in start quadrant 
2874                       node
->GetData()->x 
< xsa
+1 && q 
<= 1 
2876                       node
->GetData()->x 
> xsa
-1 && q 
>= 2 
2883                 // copy point, if not at ending point 
2886                     if( q 
!= eq 
|| bForceTurn
 
2888                         ( (wxPoint
*) node
->GetData() )->x 
> xea
+1 && q 
<= 1 
2890                         ( (wxPoint
*) node
->GetData() )->x 
< xea
-1 && q 
>= 2 
2894                         wxPoint
* pPoint 
= new wxPoint( *(node
->GetData()) ); 
2895                         points
->Append( pPoint 
); 
2897                     else if( q 
== eq 
&& !bForceTurn 
|| node
->GetData()->x 
== xea
) 
2907         } // while not bReady 
2908         points
->Append( new wxPoint( xea
, yea 
) ); 
2911         for( q 
= 0; q 
< 4; ++q 
) 
2913             wxPointList::compatibility_iterator node
; 
2914             for( node 
= pointsarray
[q
].GetFirst(); node
; node 
= node
->GetNext() ) 
2916                 wxPoint 
*p 
= node
->GetData(); 
2923         wxPointList::compatibility_iterator node
; 
2924         // copy whole ellipse, wxPoints will be deleted outside 
2925         for( node 
= pointsarray
[0].GetFirst(); node
; node 
= node
->GetNext() ) 
2927             wxPoint 
*p 
= node
->GetData(); 
2928             points
->Append( p 
); 
2930         for( node 
= pointsarray
[1].GetFirst(); node
; node 
= node
->GetNext() ) 
2932             wxPoint 
*p 
= node
->GetData(); 
2933             points
->Append( p 
); 
2935         for( node 
= pointsarray
[2].GetFirst(); node
; node 
= node
->GetNext() ) 
2937             wxPoint 
*p 
= node
->GetData(); 
2938             points
->Append( p 
); 
2940         for( node 
= pointsarray
[3].GetFirst(); node
; node 
= node
->GetNext() ) 
2942             wxPoint 
*p 
= node
->GetData(); 
2943             points
->Append( p 
); 
2946 } // CalculateEllipticPoints 
2948 #endif // __WXWINCE__ 
2950 #endif  // wxUSE_NEW_DC