]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/dcgraph.cpp
sockets work with wxDFB now
[wxWidgets.git] / src / common / dcgraph.cpp
index d5da1bb58bb9ee5f952a1b0e080ff3e5a6f5fb2f..613c6a1bcf458d8f166d3535476bbd494787963f 100644 (file)
     #include "wx/region.h"
 #endif
 
     #include "wx/region.h"
 #endif
 
-#ifndef wxMAC_USE_CORE_GRAPHICS_BLEND_MODES
-    #define wxMAC_USE_CORE_GRAPHICS_BLEND_MODES 0
-#endif
-
 //-----------------------------------------------------------------------------
 // constants
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 // constants
 //-----------------------------------------------------------------------------
@@ -83,6 +79,14 @@ wxGCDC::wxGCDC(const wxWindowDC& dc)
     SetGraphicsContext( wxGraphicsContext::Create(dc) );
 }
 
     SetGraphicsContext( wxGraphicsContext::Create(dc) );
 }
 
+#ifdef __WXMSW__
+wxGCDC::wxGCDC(const wxMemoryDC& dc)
+{
+    Init();
+    SetGraphicsContext( wxGraphicsContext::Create(dc) );
+}
+#endif    
+
 void wxGCDC::Init()
 {
     m_ok = false;
 void wxGCDC::Init()
 {
     m_ok = false;
@@ -95,6 +99,7 @@ void wxGCDC::Init()
     m_brush = *wxWHITE_BRUSH;
 
     m_graphicContext = NULL;
     m_brush = *wxWHITE_BRUSH;
 
     m_graphicContext = NULL;
+    m_logicalFunctionSupported = true;
 }
 
 
 }
 
 
@@ -158,6 +163,7 @@ void wxGCDC::DoSetClippingRegion( wxCoord x, wxCoord y, wxCoord w, wxCoord h )
 
 void wxGCDC::DoSetClippingRegionAsRegion( const wxRegion &region )
 {
 
 void wxGCDC::DoSetClippingRegionAsRegion( const wxRegion &region )
 {
+    // region is in device coordinates
     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoSetClippingRegionAsRegion - invalid DC") );
 
     if (region.Empty())
     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoSetClippingRegionAsRegion - invalid DC") );
 
     if (region.Empty())
@@ -166,10 +172,13 @@ void wxGCDC::DoSetClippingRegionAsRegion( const wxRegion &region )
         return;
     }
 
         return;
     }
 
+    wxRegion logRegion( region );
     wxCoord x, y, w, h;
     wxCoord x, y, w, h;
-    region.GetBox( x, y, w, h );
 
 
-    m_graphicContext->Clip( region );
+    logRegion.Offset( DeviceToLogicalX(0), DeviceToLogicalY(0) );
+    logRegion.GetBox( x, y, w, h );
+
+    m_graphicContext->Clip( logRegion );
     if ( m_clipping )
     {
         m_clipX1 = wxMax( m_clipX1, x );
     if ( m_clipping )
     {
         m_clipX1 = wxMax( m_clipX1, x );
@@ -366,7 +375,7 @@ void wxGCDC::SetBrush( const wxBrush &brush )
         m_graphicContext->SetBrush( m_brush );
     }
 }
         m_graphicContext->SetBrush( m_brush );
     }
 }
-
 void wxGCDC::SetBackground( const wxBrush &brush )
 {
     if (m_backgroundBrush == brush)
 void wxGCDC::SetBackground( const wxBrush &brush )
 {
     if (m_backgroundBrush == brush)
@@ -383,17 +392,10 @@ void wxGCDC::SetLogicalFunction( int function )
         return;
 
     m_logicalFunction = function;
         return;
 
     m_logicalFunction = function;
-#if wxMAC_USE_CORE_GRAPHICS_BLEND_MODES
-
-    CGContextRef cgContext = ((wxCairoContext*)(m_graphicContext))->GetNativeContext();
-    if ( m_logicalFunction == wxCOPY )
-        CGContextSetBlendMode( cgContext, kCGBlendModeNormal );
-    else if ( m_logicalFunction == wxINVERT )
-        CGContextSetBlendMode( cgContext, kCGBlendModeExclusion );
+    if ( m_graphicContext->SetLogicalFunction( function ) )
+        m_logicalFunctionSupported=true;
     else
     else
-        CGContextSetBlendMode( cgContext, kCGBlendModeNormal );
-#endif
-
+        m_logicalFunctionSupported=false;
 }
 
 bool wxGCDC::DoFloodFill(wxCoord WXUNUSED(x), wxCoord WXUNUSED(y),
 }
 
 bool wxGCDC::DoFloodFill(wxCoord WXUNUSED(x), wxCoord WXUNUSED(y),
@@ -412,11 +414,8 @@ void wxGCDC::DoDrawLine( wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2 )
 {
     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawLine - invalid DC") );
 
 {
     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawLine - invalid DC") );
 
-#if !wxMAC_USE_CORE_GRAPHICS_BLEND_MODES
-
-    if ( m_logicalFunction != wxCOPY )
+    if ( !m_logicalFunctionSupported )
         return;
         return;
-#endif
 
     m_graphicContext->StrokeLine(x1,y1,x2,y2);
 
 
     m_graphicContext->StrokeLine(x1,y1,x2,y2);
 
@@ -428,7 +427,7 @@ void wxGCDC::DoCrossHair( wxCoord x, wxCoord y )
 {
     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoCrossHair - invalid DC") );
 
 {
     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoCrossHair - invalid DC") );
 
-    if ( m_logicalFunction != wxCOPY )
+    if ( !m_logicalFunctionSupported )
         return;
 
     int w = 0, h = 0;
         return;
 
     int w = 0, h = 0;
@@ -448,7 +447,7 @@ void wxGCDC::DoDrawArc( wxCoord x1, wxCoord y1,
 {
     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawArc - invalid DC") );
 
 {
     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawArc - invalid DC") );
 
-    if ( m_logicalFunction != wxCOPY )
+    if ( !m_logicalFunctionSupported )
         return;
 
     double dx = x1 - xc;
         return;
 
     double dx = x1 - xc;
@@ -480,7 +479,9 @@ void wxGCDC::DoDrawArc( wxCoord x1, wxCoord y1,
     wxGraphicsPath path = m_graphicContext->CreatePath();
     if ( fill && ((x1!=x2)||(y1!=y2)) )
         path.MoveToPoint( xc, yc );
     wxGraphicsPath path = m_graphicContext->CreatePath();
     if ( fill && ((x1!=x2)||(y1!=y2)) )
         path.MoveToPoint( xc, yc );
-    path.AddArc( xc, yc , rad , DegToRad(sa) , DegToRad(ea), false );
+    // since these angles (ea,sa) are measured counter-clockwise, we invert them to
+    // get clockwise angles
+    path.AddArc( xc, yc , rad , DegToRad(-sa) , DegToRad(-ea), false );
     if ( fill && ((x1!=x2)||(y1!=y2)) )
         path.AddLineToPoint( xc, yc );
     m_graphicContext->DrawPath(path);
     if ( fill && ((x1!=x2)||(y1!=y2)) )
         path.AddLineToPoint( xc, yc );
     m_graphicContext->DrawPath(path);
@@ -491,7 +492,7 @@ void wxGCDC::DoDrawEllipticArc( wxCoord x, wxCoord y, wxCoord w, wxCoord h,
 {
     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawEllipticArc - invalid DC") );
 
 {
     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawEllipticArc - invalid DC") );
 
-    if ( m_logicalFunction != wxCOPY )
+    if ( !m_logicalFunctionSupported )
         return;
 
     bool fill = m_brush.GetStyle() != wxTRANSPARENT;
         return;
 
     bool fill = m_brush.GetStyle() != wxTRANSPARENT;
@@ -524,11 +525,8 @@ void wxGCDC::DoDrawLines(int n, wxPoint points[],
 {
     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawLines - invalid DC") );
 
 {
     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawLines - invalid DC") );
 
-#if !wxMAC_USE_CORE_GRAPHICS_BLEND_MODES
-
-    if ( m_logicalFunction != wxCOPY )
+    if ( !m_logicalFunctionSupported )
         return;
         return;
-#endif
 
     wxPoint2DDouble* pointsD = new wxPoint2DDouble[n];
     for( int i = 0; i < n; ++i)
 
     wxPoint2DDouble* pointsD = new wxPoint2DDouble[n];
     for( int i = 0; i < n; ++i)
@@ -546,7 +544,7 @@ void wxGCDC::DoDrawSpline(wxList *points)
 {
     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawSpline - invalid DC") );
 
 {
     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawSpline - invalid DC") );
 
-    if ( m_logicalFunction != wxCOPY )
+    if ( !m_logicalFunctionSupported )
         return;
 
     wxGraphicsPath path = m_graphicContext->CreatePath();
         return;
 
     wxGraphicsPath path = m_graphicContext->CreatePath();
@@ -608,7 +606,7 @@ void wxGCDC::DoDrawPolygon( int n, wxPoint points[],
 
     if ( n <= 0 || (m_brush.GetStyle() == wxTRANSPARENT && m_pen.GetStyle() == wxTRANSPARENT ) )
         return;
 
     if ( n <= 0 || (m_brush.GetStyle() == wxTRANSPARENT && m_pen.GetStyle() == wxTRANSPARENT ) )
         return;
-    if ( m_logicalFunction != wxCOPY )
+    if ( !m_logicalFunctionSupported )
         return;
 
     bool closeIt = false;
         return;
 
     bool closeIt = false;
@@ -661,7 +659,7 @@ void wxGCDC::DoDrawRectangle(wxCoord x, wxCoord y, wxCoord w, wxCoord h)
 {
     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawRectangle - invalid DC") );
 
 {
     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawRectangle - invalid DC") );
 
-    if ( m_logicalFunction != wxCOPY )
+    if ( !m_logicalFunctionSupported )
         return;
 
     // CMB: draw nothing if transformed w or h is 0
         return;
 
     // CMB: draw nothing if transformed w or h is 0
@@ -684,7 +682,7 @@ void wxGCDC::DoDrawRoundedRectangle(wxCoord x, wxCoord y,
 {
     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawRoundedRectangle - invalid DC") );
 
 {
     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawRoundedRectangle - invalid DC") );
 
-    if ( m_logicalFunction != wxCOPY )
+    if ( !m_logicalFunctionSupported )
         return;
 
     if (radius < 0.0)
         return;
 
     if (radius < 0.0)
@@ -701,7 +699,7 @@ void wxGCDC::DoDrawEllipse(wxCoord x, wxCoord y, wxCoord w, wxCoord h)
 {
     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawEllipse - invalid DC") );
 
 {
     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawEllipse - invalid DC") );
 
-    if ( m_logicalFunction != wxCOPY )
+    if ( !m_logicalFunctionSupported )
         return;
 
     m_graphicContext->DrawEllipse(x,y,w,h);
         return;
 
     m_graphicContext->DrawEllipse(x,y,w,h);
@@ -734,14 +732,28 @@ bool wxGCDC::DoBlit(
         ysrcMask = ysrc;
     }
 
         ysrcMask = ysrc;
     }
 
-    wxRect subrect(source-> LogicalToDeviceX(xsrc),source-> LogicalToDeviceY(ysrc),
-        source-> LogicalToDeviceXRel(width),source-> LogicalToDeviceYRel(height));
+    wxRect subrect(source->LogicalToDeviceX(xsrc),
+                   source->LogicalToDeviceY(ysrc),
+                   source->LogicalToDeviceXRel(width),
+                   source->LogicalToDeviceYRel(height));
+
+    // if needed clip the subrect down to the size of the source DC
+    wxCoord sw, sh;
+    source->GetSize(&sw, &sh);
+    sw = source->LogicalToDeviceXRel(sw);
+    sh = source->LogicalToDeviceYRel(sh);
+    if (subrect.x + subrect.width > sw)
+        subrect.width = sw - subrect.x;
+    if (subrect.y + subrect.height > sh)
+        subrect.height = sh - subrect.y;
 
     wxBitmap blit = source->GetAsBitmap( &subrect );
 
     if ( blit.Ok() )
     {
 
     wxBitmap blit = source->GetAsBitmap( &subrect );
 
     if ( blit.Ok() )
     {
-        m_graphicContext->DrawBitmap( blit, xdest , ydest , width , height );
+        m_graphicContext->DrawBitmap( blit, xdest, ydest,
+                                      wxMin(width, blit.GetWidth()),
+                                      wxMin(height, blit.GetHeight()));
     }
     else
     {
     }
     else
     {
@@ -759,10 +771,13 @@ void wxGCDC::DoDrawRotatedText(const wxString& str, wxCoord x, wxCoord y,
 
     if ( str.length() == 0 )
         return;
 
     if ( str.length() == 0 )
         return;
-    if ( m_logicalFunction != wxCOPY )
+    if ( !m_logicalFunctionSupported )
         return;
 
         return;
 
-     m_graphicContext->DrawText( str, x ,y , DegToRad(angle ));
+    if ( m_backgroundMode == wxTRANSPARENT )
+        m_graphicContext->DrawText( str, x ,y , DegToRad(angle ));
+    else
+        m_graphicContext->DrawText( str, x ,y , DegToRad(angle ), m_graphicContext->CreateBrush( wxBrush(m_textBackgroundColour,wxSOLID) ) );
 }
 
 void wxGCDC::DoDrawText(const wxString& str, wxCoord x, wxCoord y)
 }
 
 void wxGCDC::DoDrawText(const wxString& str, wxCoord x, wxCoord y)
@@ -771,10 +786,14 @@ void wxGCDC::DoDrawText(const wxString& str, wxCoord x, wxCoord y)
 
     if ( str.length() == 0 )
         return;
 
     if ( str.length() == 0 )
         return;
-    if ( m_logicalFunction != wxCOPY )
+
+    if ( !m_logicalFunctionSupported )
         return;
 
         return;
 
-    m_graphicContext->DrawText( str, x ,y);
+    if ( m_backgroundMode == wxTRANSPARENT )
+        m_graphicContext->DrawText( str, x ,y);
+    else
+        m_graphicContext->DrawText( str, x ,y , m_graphicContext->CreateBrush( wxBrush(m_textBackgroundColour,wxSOLID) ) );
 }
 
 bool wxGCDC::CanGetTextExtent() const
 }
 
 bool wxGCDC::CanGetTextExtent() const