1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/common/graphcmn.cpp 
   3 // Purpose:     graphics context methods common to all platforms 
   4 // Author:      Stefan Csomor 
   8 // Copyright:   (c) Stefan Csomor 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // For compilers that support precompilation, includes "wx.h". 
  13 #include "wx/wxprec.h" 
  15 #if defined(__BORLANDC__) 
  19 #if wxUSE_GRAPHICS_CONTEXT 
  21 #include "wx/graphics.h" 
  25     #include "wx/bitmap.h" 
  26     #include "wx/dcmemory.h" 
  27     #include "wx/region.h" 
  30 //----------------------------------------------------------------------------- 
  32 //----------------------------------------------------------------------------- 
  34 static const double RAD2DEG 
= 180.0 / M_PI
; 
  36 //----------------------------------------------------------------------------- 
  38 //----------------------------------------------------------------------------- 
  40 static inline double DegToRad(double deg
) 
  42     return (deg 
* M_PI
) / 180.0; 
  45 //----------------------------------------------------------------------------- 
  47 //----------------------------------------------------------------------------- 
  50 IMPLEMENT_DYNAMIC_CLASS(wxGCDC
, wxDCBase
) 
  52 IMPLEMENT_DYNAMIC_CLASS(wxGCDC
, wxDC
) 
  60 void wxGCDC::SetGraphicsContext( wxGraphicsContext
* ctx 
) 
  62     delete m_graphicContext
; 
  63     m_graphicContext 
= ctx
; 
  64     if ( m_graphicContext 
) 
  66         m_matrixOriginal 
= m_graphicContext
->GetTransform(); 
  68         // apply the stored transformations to the passed in context 
  69         ComputeScaleAndOrigin(); 
  70         m_graphicContext
->SetFont( m_font 
, m_textForegroundColour 
); 
  71         m_graphicContext
->SetPen( m_pen 
); 
  72         m_graphicContext
->SetBrush( m_brush
); 
  76 wxGCDC::wxGCDC(const wxWindowDC
& dc
) 
  79     SetGraphicsContext( wxGraphicsContext::Create(dc
) ); 
  83 wxGCDC::wxGCDC(const wxMemoryDC
& dc
) 
  86     SetGraphicsContext( wxGraphicsContext::Create(dc
) ); 
  94     m_mm_to_pix_x 
= mm2pt
; 
  95     m_mm_to_pix_y 
= mm2pt
; 
  98     m_font 
= *wxNORMAL_FONT
; 
  99     m_brush 
= *wxWHITE_BRUSH
; 
 101     m_graphicContext 
= NULL
; 
 102     m_logicalFunctionSupported 
= true; 
 108     delete m_graphicContext
; 
 111 void wxGCDC::DoDrawBitmap( const wxBitmap 
&bmp
, wxCoord x
, wxCoord y
, bool WXUNUSED(useMask
) ) 
 113     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawBitmap - invalid DC") ); 
 114     wxCHECK_RET( bmp
.Ok(), wxT("wxGCDC(cg)::DoDrawBitmap - invalid bitmap") ); 
 116     if ( bmp
.GetDepth() == 1 ) 
 118         m_graphicContext
->SetPen(*wxTRANSPARENT_PEN
); 
 119         m_graphicContext
->SetBrush( wxBrush( m_textBackgroundColour 
, wxSOLID 
) ); 
 120         m_graphicContext
->DrawRectangle( x 
, y 
, bmp
.GetWidth() , bmp
.GetHeight() );         
 121         m_graphicContext
->SetBrush( wxBrush( m_textForegroundColour 
, wxSOLID 
) ); 
 122         m_graphicContext
->DrawBitmap( bmp
, x 
, y 
, bmp
.GetWidth() , bmp
.GetHeight() ); 
 123         m_graphicContext
->SetBrush( m_graphicContext
->CreateBrush(m_brush
)); 
 124         m_graphicContext
->SetPen( m_graphicContext
->CreatePen(m_pen
)); 
 127         m_graphicContext
->DrawBitmap( bmp
, x 
, y 
, bmp
.GetWidth() , bmp
.GetHeight() ); 
 130 void wxGCDC::DoDrawIcon( const wxIcon 
&icon
, wxCoord x
, wxCoord y 
) 
 132     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawIcon - invalid DC") ); 
 133     wxCHECK_RET( icon
.Ok(), wxT("wxGCDC(cg)::DoDrawIcon - invalid icon") ); 
 135     wxCoord w 
= icon
.GetWidth(); 
 136     wxCoord h 
= icon
.GetHeight(); 
 138     m_graphicContext
->DrawIcon( icon 
, x
, y
, w
, h 
); 
 141 void wxGCDC::DoSetClippingRegion( wxCoord x
, wxCoord y
, wxCoord w
, wxCoord h 
) 
 143     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoSetClippingRegion - invalid DC") ); 
 145     m_graphicContext
->Clip( x
, y
, w
, h 
); 
 148         m_clipX1 
= wxMax( m_clipX1
, x 
); 
 149         m_clipY1 
= wxMax( m_clipY1
, y 
); 
 150         m_clipX2 
= wxMin( m_clipX2
, (x 
+ w
) ); 
 151         m_clipY2 
= wxMin( m_clipY2
, (y 
+ h
) ); 
 164 void wxGCDC::DoSetClippingRegionAsRegion( const wxRegion 
®ion 
) 
 166     // region is in device coordinates 
 167     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoSetClippingRegionAsRegion - invalid DC") ); 
 171         DestroyClippingRegion(); 
 175     wxRegion 
logRegion( region 
); 
 178     logRegion
.Offset( DeviceToLogicalX(0), DeviceToLogicalY(0) ); 
 179     logRegion
.GetBox( x
, y
, w
, h 
); 
 181     m_graphicContext
->Clip( logRegion 
); 
 184         m_clipX1 
= wxMax( m_clipX1
, x 
); 
 185         m_clipY1 
= wxMax( m_clipY1
, y 
); 
 186         m_clipX2 
= wxMin( m_clipX2
, (x 
+ w
) ); 
 187         m_clipY2 
= wxMin( m_clipY2
, (y 
+ h
) ); 
 200 void wxGCDC::DestroyClippingRegion() 
 202     m_graphicContext
->ResetClip(); 
 203     m_graphicContext
->SetPen( m_pen 
); 
 204     m_graphicContext
->SetBrush( m_brush 
); 
 209 void wxGCDC::DoGetSizeMM( int* width
, int* height 
) const 
 215         *width 
= long( double(w
) / (m_scaleX 
* m_mm_to_pix_x
) ); 
 217         *height 
= long( double(h
) / (m_scaleY 
* m_mm_to_pix_y
) ); 
 220 void wxGCDC::SetTextForeground( const wxColour 
&col 
) 
 222     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::SetTextForeground - invalid DC") ); 
 224     if ( col 
!= m_textForegroundColour 
) 
 226         m_textForegroundColour 
= col
; 
 227         m_graphicContext
->SetFont( m_font
, m_textForegroundColour 
); 
 231 void wxGCDC::SetTextBackground( const wxColour 
&col 
) 
 233     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::SetTextBackground - invalid DC") ); 
 235     m_textBackgroundColour 
= col
; 
 238 void wxGCDC::SetMapMode( int mode 
) 
 243         SetLogicalScale( twips2mm 
* m_mm_to_pix_x
, twips2mm 
* m_mm_to_pix_y 
); 
 247         SetLogicalScale( pt2mm 
* m_mm_to_pix_x
, pt2mm 
* m_mm_to_pix_y 
); 
 251         SetLogicalScale( m_mm_to_pix_x
, m_mm_to_pix_y 
); 
 255         SetLogicalScale( m_mm_to_pix_x 
/ 10.0, m_mm_to_pix_y 
/ 10.0 ); 
 260         SetLogicalScale( 1.0, 1.0 ); 
 264     ComputeScaleAndOrigin(); 
 267 void wxGCDC::SetUserScale( double x
, double y 
) 
 269     // allow negative ? -> no 
 273     ComputeScaleAndOrigin(); 
 276 void wxGCDC::SetLogicalScale( double x
, double y 
) 
 281     ComputeScaleAndOrigin(); 
 284 void wxGCDC::SetLogicalOrigin( wxCoord x
, wxCoord y 
) 
 286     m_logicalOriginX 
= x 
* m_signX
;   // is this still correct ? 
 287     m_logicalOriginY 
= y 
* m_signY
; 
 288     ComputeScaleAndOrigin(); 
 291 void wxGCDC::SetDeviceOrigin( wxCoord x
, wxCoord y 
) 
 295     ComputeScaleAndOrigin(); 
 298 void wxGCDC::SetAxisOrientation( bool xLeftRight
, bool yBottomUp 
) 
 300     m_signX 
= (xLeftRight 
?  1 : -1); 
 301     m_signY 
= (yBottomUp 
? -1 :  1); 
 302     ComputeScaleAndOrigin(); 
 305 wxSize 
wxGCDC::GetPPI() const 
 307     return wxSize(72, 72); 
 310 int wxGCDC::GetDepth() const 
 315 void wxGCDC::ComputeScaleAndOrigin() 
 317     m_scaleX 
= m_logicalScaleX 
* m_userScaleX
; 
 318     m_scaleY 
= m_logicalScaleY 
* m_userScaleY
; 
 320     if ( m_graphicContext 
) 
 322         m_matrixCurrent 
= m_graphicContext
->CreateMatrix(); 
 323         m_matrixCurrent
.Translate( m_deviceOriginX
, m_deviceOriginY 
); 
 324         m_matrixCurrent
.Scale( m_scaleX
, m_scaleY 
); 
 325         // the logical origin sets the origin to have new coordinates 
 326         m_matrixCurrent
.Translate( -m_logicalOriginX
, -m_logicalOriginY 
); 
 328         m_graphicContext
->SetTransform( m_matrixOriginal 
); 
 329         m_graphicContext
->ConcatTransform( m_matrixCurrent 
); 
 333 void wxGCDC::SetPalette( const wxPalette
& WXUNUSED(palette
) ) 
 338 void wxGCDC::SetBackgroundMode( int mode 
) 
 340     m_backgroundMode 
= mode
; 
 343 void wxGCDC::SetFont( const wxFont 
&font 
) 
 346     if ( m_graphicContext 
) 
 350             f
.SetPointSize( /*LogicalToDeviceYRel*/(font
.GetPointSize())); 
 351         m_graphicContext
->SetFont( f
, m_textForegroundColour 
); 
 355 void wxGCDC::SetPen( const wxPen 
&pen 
) 
 361     if ( m_graphicContext 
) 
 363         m_graphicContext
->SetPen( m_pen 
); 
 367 void wxGCDC::SetBrush( const wxBrush 
&brush 
) 
 369     if (m_brush 
== brush
) 
 373     if ( m_graphicContext 
) 
 375         m_graphicContext
->SetBrush( m_brush 
); 
 379 void wxGCDC::SetBackground( const wxBrush 
&brush 
) 
 381     if (m_backgroundBrush 
== brush
) 
 384     m_backgroundBrush 
= brush
; 
 385     if (!m_backgroundBrush
.Ok()) 
 389 void wxGCDC::SetLogicalFunction( int function 
) 
 391     if (m_logicalFunction 
== function
) 
 394     m_logicalFunction 
= function
; 
 395     if ( m_graphicContext
->SetLogicalFunction( function 
) ) 
 396         m_logicalFunctionSupported
=true; 
 398         m_logicalFunctionSupported
=false; 
 401 bool wxGCDC::DoFloodFill(wxCoord 
WXUNUSED(x
), wxCoord 
WXUNUSED(y
), 
 402                          const wxColour
& WXUNUSED(col
), int WXUNUSED(style
)) 
 407 bool wxGCDC::DoGetPixel( wxCoord 
WXUNUSED(x
), wxCoord 
WXUNUSED(y
), wxColour 
*WXUNUSED(col
) ) const 
 409     //  wxCHECK_MSG( 0 , false, wxT("wxGCDC(cg)::DoGetPixel - not implemented") ); 
 413 void wxGCDC::DoDrawLine( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2 
) 
 415     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawLine - invalid DC") ); 
 417     if ( !m_logicalFunctionSupported 
) 
 420     m_graphicContext
->StrokeLine(x1
,y1
,x2
,y2
); 
 422     CalcBoundingBox(x1
, y1
); 
 423     CalcBoundingBox(x2
, y2
); 
 426 void wxGCDC::DoCrossHair( wxCoord x
, wxCoord y 
) 
 428     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoCrossHair - invalid DC") ); 
 430     if ( !m_logicalFunctionSupported 
) 
 437     m_graphicContext
->StrokeLine(0,y
,w
,y
); 
 438     m_graphicContext
->StrokeLine(x
,0,x
,h
); 
 440     CalcBoundingBox(0, 0); 
 441     CalcBoundingBox(0+w
, 0+h
); 
 444 void wxGCDC::DoDrawArc( wxCoord x1
, wxCoord y1
, 
 445                         wxCoord x2
, wxCoord y2
, 
 446                         wxCoord xc
, wxCoord yc 
) 
 448     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawArc - invalid DC") ); 
 450     if ( !m_logicalFunctionSupported 
) 
 455     double radius 
= sqrt((double)(dx 
* dx 
+ dy 
* dy
)); 
 456     wxCoord rad 
= (wxCoord
)radius
; 
 458     if (x1 
== x2 
&& y1 
== y2
) 
 463     else if (radius 
== 0.0) 
 469         sa 
= (x1 
- xc 
== 0) ? 
 470      (y1 
- yc 
< 0) ? 90.0 : -90.0 : 
 471              -atan2(double(y1 
- yc
), double(x1 
- xc
)) * RAD2DEG
; 
 472         ea 
= (x2 
- xc 
== 0) ? 
 473      (y2 
- yc 
< 0) ? 90.0 : -90.0 : 
 474              -atan2(double(y2 
- yc
), double(x2 
- xc
)) * RAD2DEG
; 
 477     bool fill 
= m_brush
.GetStyle() != wxTRANSPARENT
; 
 479     wxGraphicsPath path 
= m_graphicContext
->CreatePath(); 
 480     if ( fill 
&& ((x1
!=x2
)||(y1
!=y2
)) ) 
 481         path
.MoveToPoint( xc
, yc 
); 
 482     // since these angles (ea,sa) are measured counter-clockwise, we invert them to 
 483     // get clockwise angles 
 484     path
.AddArc( xc
, yc 
, rad 
, DegToRad(-sa
) , DegToRad(-ea
), false ); 
 485     if ( fill 
&& ((x1
!=x2
)||(y1
!=y2
)) ) 
 486         path
.AddLineToPoint( xc
, yc 
); 
 487     m_graphicContext
->DrawPath(path
); 
 490 void wxGCDC::DoDrawEllipticArc( wxCoord x
, wxCoord y
, wxCoord w
, wxCoord h
, 
 491                                 double sa
, double ea 
) 
 493     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawEllipticArc - invalid DC") ); 
 495     if ( !m_logicalFunctionSupported 
) 
 498     bool fill 
= m_brush
.GetStyle() != wxTRANSPARENT
; 
 500     wxGraphicsPath path 
= m_graphicContext
->CreatePath(); 
 501     m_graphicContext
->PushState(); 
 502     m_graphicContext
->Translate(x
+w
/2,y
+h
/2); 
 503     wxDouble factor 
= ((wxDouble
) w
) / h
; 
 504     m_graphicContext
->Scale( factor 
, 1.0); 
 505     if ( fill 
&& (sa
!=ea
) ) 
 506         path
.MoveToPoint(0,0); 
 507     // since these angles (ea,sa) are measured counter-clockwise, we invert them to 
 508     // get clockwise angles 
 509     path
.AddArc( 0, 0, h
/2 , DegToRad(-sa
) , DegToRad(-ea
), sa 
> ea 
); 
 510     if ( fill 
&& (sa
!=ea
) ) 
 511         path
.AddLineToPoint(0,0); 
 512     m_graphicContext
->DrawPath( path 
); 
 513     m_graphicContext
->PopState(); 
 516 void wxGCDC::DoDrawPoint( wxCoord x
, wxCoord y 
) 
 518     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawPoint - invalid DC") ); 
 520     DoDrawLine( x 
, y 
, x 
+ 1 , y 
+ 1 ); 
 523 void wxGCDC::DoDrawLines(int n
, wxPoint points
[], 
 524                          wxCoord xoffset
, wxCoord yoffset
) 
 526     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawLines - invalid DC") ); 
 528     if ( !m_logicalFunctionSupported 
) 
 531     wxPoint2DDouble
* pointsD 
= new wxPoint2DDouble
[n
]; 
 532     for( int i 
= 0; i 
< n
; ++i
) 
 534         pointsD
[i
].m_x 
= points
[i
].x 
+ xoffset
; 
 535         pointsD
[i
].m_y 
= points
[i
].y 
+ yoffset
; 
 538     m_graphicContext
->StrokeLines( n 
, pointsD
); 
 543 void wxGCDC::DoDrawSpline(wxList 
*points
) 
 545     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawSpline - invalid DC") ); 
 547     if ( !m_logicalFunctionSupported 
) 
 550     wxGraphicsPath path 
= m_graphicContext
->CreatePath(); 
 552     wxList::compatibility_iterator node 
= points
->GetFirst(); 
 553     if (node 
== wxList::compatibility_iterator()) 
 557     wxPoint 
*p 
= (wxPoint 
*)node
->GetData(); 
 562     node 
= node
->GetNext(); 
 563     p 
= (wxPoint 
*)node
->GetData(); 
 567     wxCoord cx1 
= ( x1 
+ x2 
) / 2; 
 568     wxCoord cy1 
= ( y1 
+ y2 
) / 2; 
 570     path
.MoveToPoint( x1 
, y1 
); 
 571     path
.AddLineToPoint( cx1 
, cy1 
); 
 574     while ((node 
= node
->GetNext()) != NULL
) 
 577     while ((node 
= node
->GetNext())) 
 581         p 
= (wxPoint 
*)node
->GetData(); 
 586         wxCoord cx4 
= (x1 
+ x2
) / 2; 
 587         wxCoord cy4 
= (y1 
+ y2
) / 2; 
 589         path
.AddQuadCurveToPoint(x1 
, y1 
,cx4 
, cy4 
); 
 595     path
.AddLineToPoint( x2 
, y2 
); 
 597     m_graphicContext
->StrokePath( path 
); 
 599 #endif // wxUSE_SPLINES 
 601 void wxGCDC::DoDrawPolygon( int n
, wxPoint points
[], 
 602                             wxCoord xoffset
, wxCoord yoffset
, 
 605     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawPolygon - invalid DC") ); 
 607     if ( n 
<= 0 || (m_brush
.GetStyle() == wxTRANSPARENT 
&& m_pen
.GetStyle() == wxTRANSPARENT 
) ) 
 609     if ( !m_logicalFunctionSupported 
) 
 612     bool closeIt 
= false; 
 613     if (points
[n
-1] != points
[0]) 
 616     wxPoint2DDouble
* pointsD 
= new wxPoint2DDouble
[n
+(closeIt
?1:0)]; 
 617     for( int i 
= 0; i 
< n
; ++i
) 
 619         pointsD
[i
].m_x 
= points
[i
].x 
+ xoffset
; 
 620         pointsD
[i
].m_y 
= points
[i
].y 
+ yoffset
; 
 623         pointsD
[n
] = pointsD
[0]; 
 625     m_graphicContext
->DrawLines( n
+(closeIt
?1:0) , pointsD
, fillStyle
); 
 629 void wxGCDC::DoDrawPolyPolygon(int n
, 
 637     wxGraphicsPath path 
= m_graphicContext
->CreatePath(); 
 640     for ( int j 
= 0; j 
< n
; ++j
) 
 642         wxPoint start 
= points
[i
]; 
 643         path
.MoveToPoint( start
.x
+ xoffset
, start
.y
+ yoffset
); 
 646         for ( int k 
= 1; k 
< l
; ++k
) 
 648             path
.AddLineToPoint( points
[i
].x
+ xoffset
, points
[i
].y
+ yoffset
); 
 652         if ( start 
!= points
[i
-1]) 
 653             path
.AddLineToPoint( start
.x
+ xoffset
, start
.y
+ yoffset
); 
 655     m_graphicContext
->DrawPath( path 
, fillStyle
); 
 658 void wxGCDC::DoDrawRectangle(wxCoord x
, wxCoord y
, wxCoord w
, wxCoord h
) 
 660     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawRectangle - invalid DC") ); 
 662     if ( !m_logicalFunctionSupported 
) 
 665     // CMB: draw nothing if transformed w or h is 0 
 666     if (w 
== 0 || h 
== 0) 
 669     if ( m_graphicContext
->ShouldOffset() ) 
 671         // if we are offsetting the entire rectangle is moved 0.5, so the 
 672         // border line gets off by 1 
 676     m_graphicContext
->DrawRectangle(x
,y
,w
,h
); 
 679 void wxGCDC::DoDrawRoundedRectangle(wxCoord x
, wxCoord y
, 
 680                                     wxCoord w
, wxCoord h
, 
 683     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawRoundedRectangle - invalid DC") ); 
 685     if ( !m_logicalFunctionSupported 
) 
 689         radius 
= - radius 
* ((w 
< h
) ? w 
: h
); 
 691     // CMB: draw nothing if transformed w or h is 0 
 692     if (w 
== 0 || h 
== 0) 
 695     m_graphicContext
->DrawRoundedRectangle( x
,y
,w
,h
,radius
); 
 698 void wxGCDC::DoDrawEllipse(wxCoord x
, wxCoord y
, wxCoord w
, wxCoord h
) 
 700     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawEllipse - invalid DC") ); 
 702     if ( !m_logicalFunctionSupported 
) 
 705     m_graphicContext
->DrawEllipse(x
,y
,w
,h
); 
 708 bool wxGCDC::CanDrawBitmap() const 
 714     wxCoord xdest
, wxCoord ydest
, wxCoord width
, wxCoord height
, 
 715     wxDC 
*source
, wxCoord xsrc
, wxCoord ysrc
, int logical_func 
, bool WXUNUSED(useMask
), 
 716     wxCoord xsrcMask
, wxCoord ysrcMask 
) 
 718     wxCHECK_MSG( Ok(), false, wxT("wxGCDC(cg)::DoBlit - invalid DC") ); 
 719     wxCHECK_MSG( source
->Ok(), false, wxT("wxGCDC(cg)::DoBlit - invalid source DC") ); 
 721     if ( logical_func 
== wxNO_OP 
) 
 723     else if ( logical_func 
!= wxCOPY 
) 
 725         wxFAIL_MSG( wxT("Blitting is only supported with wxCOPY logical operation.") ); 
 729     if (xsrcMask 
== -1 && ysrcMask 
== -1) 
 735     wxRect 
subrect(source
-> LogicalToDeviceX(xsrc
),source
-> LogicalToDeviceY(ysrc
), 
 736         source
-> LogicalToDeviceXRel(width
),source
-> LogicalToDeviceYRel(height
)); 
 738     wxBitmap blit 
= source
->GetAsBitmap( &subrect 
); 
 742         m_graphicContext
->DrawBitmap( blit
, xdest 
, ydest 
, width 
, height 
); 
 746         wxFAIL_MSG( wxT("Cannot Blit. Unable to get contents of DC as bitmap.") ); 
 753 void wxGCDC::DoDrawRotatedText(const wxString
& str
, wxCoord x
, wxCoord y
, 
 756     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawRotatedText - invalid DC") ); 
 758     if ( str
.length() == 0 ) 
 760     if ( !m_logicalFunctionSupported 
) 
 763     if ( m_backgroundMode 
== wxTRANSPARENT 
) 
 764         m_graphicContext
->DrawText( str
, x 
,y 
, DegToRad(angle 
)); 
 766         m_graphicContext
->DrawText( str
, x 
,y 
, DegToRad(angle 
), m_graphicContext
->CreateBrush( wxBrush(m_textBackgroundColour
,wxSOLID
) ) ); 
 769 void wxGCDC::DoDrawText(const wxString
& str
, wxCoord x
, wxCoord y
) 
 771     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawRotatedText - invalid DC") ); 
 773     if ( str
.length() == 0 ) 
 776     if ( !m_logicalFunctionSupported 
) 
 779     if ( m_backgroundMode 
== wxTRANSPARENT 
) 
 780         m_graphicContext
->DrawText( str
, x 
,y
); 
 782         m_graphicContext
->DrawText( str
, x 
,y 
, m_graphicContext
->CreateBrush( wxBrush(m_textBackgroundColour
,wxSOLID
) ) ); 
 785 bool wxGCDC::CanGetTextExtent() const 
 787     wxCHECK_MSG( Ok(), false, wxT("wxGCDC(cg)::CanGetTextExtent - invalid DC") ); 
 792 void wxGCDC::DoGetTextExtent( const wxString 
&str
, wxCoord 
*width
, wxCoord 
*height
, 
 793                               wxCoord 
*descent
, wxCoord 
*externalLeading 
, 
 794                               wxFont 
*theFont 
) const 
 796     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoGetTextExtent - invalid DC") ); 
 800         m_graphicContext
->SetFont( *theFont
, m_textForegroundColour 
); 
 803     wxDouble h 
, d 
, e 
, w
; 
 805     m_graphicContext
->GetTextExtent( str
, &w
, &h
, &d
, &e 
); 
 808         *height 
= (wxCoord
)h
; 
 810         *descent 
= (wxCoord
)d
; 
 811     if ( externalLeading 
) 
 812         *externalLeading 
= (wxCoord
)e
; 
 818         m_graphicContext
->SetFont( m_font
, m_textForegroundColour 
); 
 822 bool wxGCDC::DoGetPartialTextExtents(const wxString
& text
, wxArrayInt
& widths
) const 
 824     wxCHECK_MSG( Ok(), false, wxT("wxGCDC(cg)::DoGetPartialTextExtents - invalid DC") ); 
 826     widths
.Add(0,text
.Length()); 
 827     if ( text
.IsEmpty() ) 
 830     wxArrayDouble widthsD
; 
 832     m_graphicContext
->GetPartialTextExtents( text
, widthsD 
); 
 833     for ( size_t i 
= 0; i 
< widths
.GetCount(); ++i 
) 
 834         widths
[i
] = (wxCoord
)(widthsD
[i
] + 0.5); 
 839 wxCoord 
wxGCDC::GetCharWidth(void) const 
 842     DoGetTextExtent( wxT("g") , &width 
, NULL 
, NULL 
, NULL 
, NULL 
); 
 847 wxCoord 
wxGCDC::GetCharHeight(void) const 
 850     DoGetTextExtent( wxT("g") , NULL 
, &height 
, NULL 
, NULL 
, NULL 
); 
 855 void wxGCDC::Clear(void) 
 857     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::Clear - invalid DC") ); 
 858     // TODO better implementation / incorporate size info into wxGCDC or context 
 859     m_graphicContext
->SetBrush( m_backgroundBrush 
); 
 860     wxPen p 
= *wxTRANSPARENT_PEN
; 
 861     m_graphicContext
->SetPen( p 
); 
 862     DoDrawRectangle( 0, 0, 32000 , 32000 ); 
 863     m_graphicContext
->SetPen( m_pen 
); 
 864     m_graphicContext
->SetBrush( m_brush 
); 
 867 void wxGCDC::DoGetSize(int *width
, int *height
) const 
 873 void wxGCDC::DoGradientFillLinear(const wxRect
& rect
, 
 874                                   const wxColour
& initialColour
, 
 875                                   const wxColour
& destColour
, 
 876                                   wxDirection nDirection 
) 
 883         start 
= rect
.GetRightBottom(); 
 885         end 
= rect
.GetLeftBottom(); 
 888         start 
= rect
.GetLeftBottom(); 
 889         end 
= rect
.GetRightBottom(); 
 893         start 
= rect
.GetLeftBottom(); 
 895         end 
= rect
.GetLeftTop(); 
 898         start 
= rect
.GetLeftTop(); 
 899         end 
= rect
.GetLeftBottom(); 
 906     if (rect
.width 
== 0 || rect
.height 
== 0) 
 909     m_graphicContext
->SetBrush( m_graphicContext
->CreateLinearGradientBrush( 
 910         start
.x
,start
.y
,end
.x
,end
.y
, initialColour
, destColour
)); 
 911     m_graphicContext
->SetPen(*wxTRANSPARENT_PEN
); 
 912     m_graphicContext
->DrawRectangle(rect
.x
,rect
.y
,rect
.width
,rect
.height
); 
 913     m_graphicContext
->SetPen(m_pen
); 
 916 void wxGCDC::DoGradientFillConcentric(const wxRect
& rect
, 
 917                                       const wxColour
& initialColour
, 
 918                                       const wxColour
& destColour
, 
 919                                       const wxPoint
& circleCenter
) 
 922     wxInt32 cx 
= rect
.GetWidth() / 2; 
 923     wxInt32 cy 
= rect
.GetHeight() / 2; 
 930     // make sure the background is filled (todo move into specific platform implementation ?) 
 931     m_graphicContext
->SetPen(*wxTRANSPARENT_PEN
); 
 932     m_graphicContext
->SetBrush( wxBrush( destColour
) ); 
 933     m_graphicContext
->DrawRectangle(rect
.x
,rect
.y
,rect
.width
,rect
.height
); 
 935     m_graphicContext
->SetBrush( m_graphicContext
->CreateRadialGradientBrush( 
 936         rect
.x
+circleCenter
.x
,rect
.y
+circleCenter
.y
, 
 937         rect
.x
+circleCenter
.x
,rect
.y
+circleCenter
.y
, 
 938         nRadius
,initialColour
,destColour
)); 
 940     m_graphicContext
->DrawRectangle(rect
.x
,rect
.y
,rect
.width
,rect
.height
); 
 941     m_graphicContext
->SetPen(m_pen
); 
 944 void wxGCDC::DoDrawCheckMark(wxCoord x
, wxCoord y
, 
 945                              wxCoord width
, wxCoord height
) 
 947     wxDCBase::DoDrawCheckMark(x
,y
,width
,height
); 
 950 #endif // wxUSE_GRAPHICS_CONTEXT