X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/fcaea2fab983efc4dcfe7d9f23dd046c5eb3b932..cdaed652d7d2b20bc9f508d45f77a280f88279d9:/src/common/dcgraph.cpp?ds=sidebyside diff --git a/src/common/dcgraph.cpp b/src/common/dcgraph.cpp index 54ecf302cb..66a531bb47 100644 --- a/src/common/dcgraph.cpp +++ b/src/common/dcgraph.cpp @@ -19,6 +19,7 @@ #if wxUSE_GRAPHICS_CONTEXT #include "wx/graphics.h" +#include "wx/dcgraph.h" #ifndef WX_PRECOMP #include "wx/icon.h" @@ -27,9 +28,16 @@ #include "wx/region.h" #endif -#ifdef __WXMAC__ -#include "wx/mac/private.h" +#include "wx/dcclient.h" + +#ifdef __WXOSX_OR_COCOA__ +#ifdef __WXOSX_IPHONE__ + #include +#else + #include #endif +#endif + //----------------------------------------------------------------------------- // constants //----------------------------------------------------------------------------- @@ -45,22 +53,98 @@ static inline double DegToRad(double deg) return (deg * M_PI) / 180.0; } +static bool TranslateRasterOp(wxRasterOperationMode function, wxCompositionMode *op) +{ + switch ( function ) + { + case wxCOPY: // (default) src + *op = wxCOMPOSITION_SOURCE; // + break; + case wxOR: // src OR dst + *op = wxCOMPOSITION_ADD; + break; + case wxNO_OP: // dst + *op = wxCOMPOSITION_DEST; // ignore the source + break; + case wxCLEAR: // 0 + *op = wxCOMPOSITION_CLEAR;// clear dst + break; + case wxXOR: // src XOR dst + *op = wxCOMPOSITION_XOR; + break; + + case wxAND: // src AND dst + case wxAND_INVERT: // (NOT src) AND dst + case wxAND_REVERSE:// src AND (NOT dst) + case wxEQUIV: // (NOT src) XOR dst + case wxINVERT: // NOT dst + case wxNAND: // (NOT src) OR (NOT dst) + case wxNOR: // (NOT src) AND (NOT dst) + case wxOR_INVERT: // (NOT src) OR dst + case wxOR_REVERSE: // src OR (NOT dst) + case wxSET: // 1 + case wxSRC_INVERT: // NOT src + default: + return false; + } + return true; +} + //----------------------------------------------------------------------------- // wxDC bridge class //----------------------------------------------------------------------------- -#ifdef __WXMAC__ -IMPLEMENT_DYNAMIC_CLASS(wxGCDC, wxDCBase) -#else IMPLEMENT_DYNAMIC_CLASS(wxGCDC, wxDC) + +wxGCDC::wxGCDC(const wxWindowDC& dc) : + wxDC( new wxGCDCImpl( this, dc ) ) +{ +} + +wxGCDC::wxGCDC( const wxMemoryDC& dc) : + wxDC( new wxGCDCImpl( this, dc ) ) +{ +} + +#if wxUSE_PRINTING_ARCHITECTURE +wxGCDC::wxGCDC( const wxPrinterDC& dc) : + wxDC( new wxGCDCImpl( this, dc ) ) +{ +} #endif -wxGCDC::wxGCDC() +wxGCDC::wxGCDC() : + wxDC( new wxGCDCImpl( this ) ) { - Init(); +} + +wxGCDC::~wxGCDC() +{ +} + +wxGraphicsContext* wxGCDC::GetGraphicsContext() +{ + if (!m_pimpl) return NULL; + wxGCDCImpl *gc_impl = (wxGCDCImpl*) m_pimpl; + return gc_impl->GetGraphicsContext(); } void wxGCDC::SetGraphicsContext( wxGraphicsContext* ctx ) +{ + if (!m_pimpl) return; + wxGCDCImpl *gc_impl = (wxGCDCImpl*) m_pimpl; + gc_impl->SetGraphicsContext( ctx ); +} + +IMPLEMENT_ABSTRACT_CLASS(wxGCDCImpl, wxDCImpl) + +wxGCDCImpl::wxGCDCImpl( wxDC *owner ) : + wxDCImpl( owner ) +{ + Init(); +} + +void wxGCDCImpl::SetGraphicsContext( wxGraphicsContext* ctx ) { delete m_graphicContext; m_graphicContext = ctx; @@ -76,21 +160,39 @@ void wxGCDC::SetGraphicsContext( wxGraphicsContext* ctx ) } } -wxGCDC::wxGCDC(const wxWindowDC& dc) +wxGCDCImpl::wxGCDCImpl( wxDC *owner, const wxWindowDC& dc ) : + wxDCImpl( owner ) { Init(); SetGraphicsContext( wxGraphicsContext::Create(dc) ); + m_window = dc.GetWindow(); } -#ifdef __WXMSW__ -wxGCDC::wxGCDC(const wxMemoryDC& dc) +wxGCDCImpl::wxGCDCImpl( wxDC *owner, const wxMemoryDC& dc ) : + wxDCImpl( owner ) +{ + Init(); + wxGraphicsContext* context; +#if wxUSE_CAIRO + wxGraphicsRenderer* renderer = wxGraphicsRenderer::GetCairoRenderer(); + context = renderer->CreateContext(dc); +#else + context = wxGraphicsContext::Create(dc); +#endif + + SetGraphicsContext( context ); +} + +#if wxUSE_PRINTING_ARCHITECTURE +wxGCDCImpl::wxGCDCImpl( wxDC *owner, const wxPrinterDC& dc ) : + wxDCImpl( owner ) { Init(); SetGraphicsContext( wxGraphicsContext::Create(dc) ); } -#endif +#endif -void wxGCDC::Init() +void wxGCDCImpl::Init() { m_ok = false; m_colour = true; @@ -101,39 +203,50 @@ void wxGCDC::Init() m_font = *wxNORMAL_FONT; m_brush = *wxWHITE_BRUSH; - m_graphicContext = NULL; + m_graphicContext = wxGraphicsContext::Create(); m_logicalFunctionSupported = true; } -wxGCDC::~wxGCDC() +wxGCDCImpl::~wxGCDCImpl() { delete m_graphicContext; } -void wxGCDC::DoDrawBitmap( const wxBitmap &bmp, wxCoord x, wxCoord y, bool WXUNUSED(useMask) ) +void wxGCDCImpl::DoDrawBitmap( const wxBitmap &bmp, wxCoord x, wxCoord y, + bool useMask ) { - wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawBitmap - invalid DC") ); - wxCHECK_RET( bmp.Ok(), wxT("wxGCDC(cg)::DoDrawBitmap - invalid bitmap") ); + wxCHECK_RET( IsOk(), wxT("wxGCDC(cg)::DoDrawBitmap - invalid DC") ); + wxCHECK_RET( bmp.IsOk(), wxT("wxGCDC(cg)::DoDrawBitmap - invalid bitmap") ); + int w = bmp.GetWidth(); + int h = bmp.GetHeight(); if ( bmp.GetDepth() == 1 ) { m_graphicContext->SetPen(*wxTRANSPARENT_PEN); m_graphicContext->SetBrush( wxBrush( m_textBackgroundColour , wxSOLID ) ); - m_graphicContext->DrawRectangle( x , y , bmp.GetWidth() , bmp.GetHeight() ); + m_graphicContext->DrawRectangle( x, y, w, h ); m_graphicContext->SetBrush( wxBrush( m_textForegroundColour , wxSOLID ) ); - m_graphicContext->DrawBitmap( bmp, x , y , bmp.GetWidth() , bmp.GetHeight() ); + m_graphicContext->DrawBitmap( bmp, x, y, w, h ); m_graphicContext->SetBrush( m_graphicContext->CreateBrush(m_brush)); m_graphicContext->SetPen( m_graphicContext->CreatePen(m_pen)); } - else - m_graphicContext->DrawBitmap( bmp, x , y , bmp.GetWidth() , bmp.GetHeight() ); + else // not a monochrome bitmap, handle it normally + { + // make a copy in case we need to remove its mask, if we don't modify + // it the copy is cheap as bitmaps are reference-counted + wxBitmap bmpCopy(bmp); + if ( !useMask && bmp.GetMask() ) + bmpCopy.SetMask(NULL); + + m_graphicContext->DrawBitmap( bmpCopy, x, y, w, h ); + } } -void wxGCDC::DoDrawIcon( const wxIcon &icon, wxCoord x, wxCoord y ) +void wxGCDCImpl::DoDrawIcon( const wxIcon &icon, wxCoord x, wxCoord y ) { - wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawIcon - invalid DC") ); - wxCHECK_RET( icon.Ok(), wxT("wxGCDC(cg)::DoDrawIcon - invalid icon") ); + wxCHECK_RET( IsOk(), wxT("wxGCDC(cg)::DoDrawIcon - invalid DC") ); + wxCHECK_RET( icon.IsOk(), wxT("wxGCDC(cg)::DoDrawIcon - invalid icon") ); wxCoord w = icon.GetWidth(); wxCoord h = icon.GetHeight(); @@ -141,33 +254,31 @@ void wxGCDC::DoDrawIcon( const wxIcon &icon, wxCoord x, wxCoord y ) m_graphicContext->DrawIcon( icon , x, y, w, h ); } -bool wxGCDC::StartDoc( const wxString& WXUNUSED(message) ) +bool wxGCDCImpl::StartDoc( const wxString& WXUNUSED(message) ) { - return false; + return true; } -void wxGCDC::EndDoc() +void wxGCDCImpl::EndDoc() { } -void wxGCDC::StartPage() +void wxGCDCImpl::StartPage() { } -void wxGCDC::EndPage() +void wxGCDCImpl::EndPage() { } - -void wxGCDC::Flush() + +void wxGCDCImpl::Flush() { -#ifdef __WXMAC__ - CGContextFlush( (CGContextRef) m_graphicContext->GetNativeContext() ); -#endif + m_graphicContext->Flush(); } -void wxGCDC::DoSetClippingRegion( wxCoord x, wxCoord y, wxCoord w, wxCoord h ) +void wxGCDCImpl::DoSetClippingRegion( wxCoord x, wxCoord y, wxCoord w, wxCoord h ) { - wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoSetClippingRegion - invalid DC") ); + wxCHECK_RET( IsOk(), wxT("wxGCDC(cg)::DoSetClippingRegion - invalid DC") ); m_graphicContext->Clip( x, y, w, h ); if ( m_clipping ) @@ -188,10 +299,10 @@ void wxGCDC::DoSetClippingRegion( wxCoord x, wxCoord y, wxCoord w, wxCoord h ) } } -void wxGCDC::DoSetClippingRegionAsRegion( const wxRegion ®ion ) +void wxGCDCImpl::DoSetDeviceClippingRegion( const wxRegion ®ion ) { // region is in device coordinates - wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoSetClippingRegionAsRegion - invalid DC") ); + wxCHECK_RET( IsOk(), wxT("wxGCDC(cg)::DoSetDeviceClippingRegion - invalid DC") ); if (region.Empty()) { @@ -224,35 +335,35 @@ void wxGCDC::DoSetClippingRegionAsRegion( const wxRegion ®ion ) } } -void wxGCDC::DestroyClippingRegion() +void wxGCDCImpl::DestroyClippingRegion() { m_graphicContext->ResetClip(); // currently the clip eg of a window extends to the area between the scrollbars // so we must explicitely make sure it only covers the area we want it to draw int width, height ; - GetSize( &width , &height ) ; + GetOwner()->GetSize( &width , &height ) ; m_graphicContext->Clip( DeviceToLogicalX(0) , DeviceToLogicalY(0) , DeviceToLogicalXRel(width), DeviceToLogicalYRel(height) ); - + m_graphicContext->SetPen( m_pen ); m_graphicContext->SetBrush( m_brush ); m_clipping = false; } -void wxGCDC::DoGetSizeMM( int* width, int* height ) const +void wxGCDCImpl::DoGetSizeMM( int* width, int* height ) const { int w = 0, h = 0; - GetSize( &w, &h ); + GetOwner()->GetSize( &w, &h ); if (width) *width = long( double(w) / (m_scaleX * m_mm_to_pix_x) ); if (height) *height = long( double(h) / (m_scaleY * m_mm_to_pix_y) ); } -void wxGCDC::SetTextForeground( const wxColour &col ) +void wxGCDCImpl::SetTextForeground( const wxColour &col ) { - wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::SetTextForeground - invalid DC") ); + wxCHECK_RET( IsOk(), wxT("wxGCDC(cg)::SetTextForeground - invalid DC") ); if ( col != m_textForegroundColour ) { @@ -261,14 +372,14 @@ void wxGCDC::SetTextForeground( const wxColour &col ) } } -void wxGCDC::SetTextBackground( const wxColour &col ) +void wxGCDCImpl::SetTextBackground( const wxColour &col ) { - wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::SetTextBackground - invalid DC") ); + wxCHECK_RET( IsOk(), wxT("wxGCDC(cg)::SetTextBackground - invalid DC") ); m_textBackgroundColour = col; } -void wxGCDC::SetMapMode( int mode ) +void wxGCDCImpl::SetMapMode( wxMappingMode mode ) { switch (mode) { @@ -297,95 +408,58 @@ void wxGCDC::SetMapMode( int mode ) ComputeScaleAndOrigin(); } -void wxGCDC::SetUserScale( double x, double y ) -{ - // allow negative ? -> no - - m_userScaleX = x; - m_userScaleY = y; - ComputeScaleAndOrigin(); -} - -void wxGCDC::SetLogicalScale( double x, double y ) -{ - // allow negative ? - m_logicalScaleX = x; - m_logicalScaleY = y; - ComputeScaleAndOrigin(); -} - -void wxGCDC::SetLogicalOrigin( wxCoord x, wxCoord y ) -{ - m_logicalOriginX = x * m_signX; // is this still correct ? - m_logicalOriginY = y * m_signY; - ComputeScaleAndOrigin(); -} - -void wxGCDC::SetDeviceOrigin( wxCoord x, wxCoord y ) -{ - m_deviceOriginX = x; - m_deviceOriginY = y; - ComputeScaleAndOrigin(); -} - -void wxGCDC::SetAxisOrientation( bool xLeftRight, bool yBottomUp ) -{ - m_signX = (xLeftRight ? 1 : -1); - m_signY = (yBottomUp ? -1 : 1); - ComputeScaleAndOrigin(); -} - -wxSize wxGCDC::GetPPI() const +wxSize wxGCDCImpl::GetPPI() const { return wxSize(72, 72); } -int wxGCDC::GetDepth() const +int wxGCDCImpl::GetDepth() const { return 32; } -void wxGCDC::ComputeScaleAndOrigin() +void wxGCDCImpl::ComputeScaleAndOrigin() { - m_scaleX = m_logicalScaleX * m_userScaleX; - m_scaleY = m_logicalScaleY * m_userScaleY; + wxDCImpl::ComputeScaleAndOrigin(); if ( m_graphicContext ) { m_matrixCurrent = m_graphicContext->CreateMatrix(); - m_matrixCurrent.Translate( m_deviceOriginX, m_deviceOriginY ); - m_matrixCurrent.Scale( m_scaleX, m_scaleY ); + // the logical origin sets the origin to have new coordinates - m_matrixCurrent.Translate( -m_logicalOriginX, -m_logicalOriginY ); + m_matrixCurrent.Translate( m_deviceOriginX - m_logicalOriginX * m_signX * m_scaleX, + m_deviceOriginY-m_logicalOriginY * m_signY * m_scaleY); + + m_matrixCurrent.Scale( m_scaleX * m_signX, m_scaleY * m_signY ); m_graphicContext->SetTransform( m_matrixOriginal ); m_graphicContext->ConcatTransform( m_matrixCurrent ); } } -void wxGCDC::SetPalette( const wxPalette& WXUNUSED(palette) ) +void wxGCDCImpl::SetPalette( const wxPalette& WXUNUSED(palette) ) { } -void wxGCDC::SetBackgroundMode( int mode ) +void wxGCDCImpl::SetBackgroundMode( int mode ) { m_backgroundMode = mode; } -void wxGCDC::SetFont( const wxFont &font ) +void wxGCDCImpl::SetFont( const wxFont &font ) { m_font = font; if ( m_graphicContext ) { wxFont f = font; - if ( f.Ok() ) + if ( f.IsOk() ) f.SetPointSize( /*LogicalToDeviceYRel*/(font.GetPointSize())); m_graphicContext->SetFont( f, m_textForegroundColour ); } } -void wxGCDC::SetPen( const wxPen &pen ) +void wxGCDCImpl::SetPen( const wxPen &pen ) { if ( m_pen == pen ) return; @@ -397,7 +471,7 @@ void wxGCDC::SetPen( const wxPen &pen ) } } -void wxGCDC::SetBrush( const wxBrush &brush ) +void wxGCDCImpl::SetBrush( const wxBrush &brush ) { if (m_brush == brush) return; @@ -408,44 +482,51 @@ void wxGCDC::SetBrush( const wxBrush &brush ) m_graphicContext->SetBrush( m_brush ); } } - -void wxGCDC::SetBackground( const wxBrush &brush ) + +void wxGCDCImpl::SetBackground( const wxBrush &brush ) { if (m_backgroundBrush == brush) return; m_backgroundBrush = brush; - if (!m_backgroundBrush.Ok()) + if (!m_backgroundBrush.IsOk()) return; } -void wxGCDC::SetLogicalFunction( int function ) +void wxGCDCImpl::SetLogicalFunction( wxRasterOperationMode function ) { if (m_logicalFunction == function) return; m_logicalFunction = function; - if ( m_graphicContext->SetLogicalFunction( function ) ) - m_logicalFunctionSupported=true; + + wxCompositionMode mode; + m_logicalFunctionSupported = TranslateRasterOp( function, &mode); + if (m_logicalFunctionSupported) + m_logicalFunctionSupported = m_graphicContext->SetCompositionMode(mode); + + if ( function == wxXOR ) + m_graphicContext->SetAntialiasMode(wxANTIALIAS_NONE); else - m_logicalFunctionSupported=false; + m_graphicContext->SetAntialiasMode(wxANTIALIAS_DEFAULT); } -bool wxGCDC::DoFloodFill(wxCoord WXUNUSED(x), wxCoord WXUNUSED(y), - const wxColour& WXUNUSED(col), int WXUNUSED(style)) +bool wxGCDCImpl::DoFloodFill(wxCoord WXUNUSED(x), wxCoord WXUNUSED(y), + const wxColour& WXUNUSED(col), + wxFloodFillStyle WXUNUSED(style)) { return false; } -bool wxGCDC::DoGetPixel( wxCoord WXUNUSED(x), wxCoord WXUNUSED(y), wxColour *WXUNUSED(col) ) const +bool wxGCDCImpl::DoGetPixel( wxCoord WXUNUSED(x), wxCoord WXUNUSED(y), wxColour *WXUNUSED(col) ) const { // wxCHECK_MSG( 0 , false, wxT("wxGCDC(cg)::DoGetPixel - not implemented") ); return false; } -void wxGCDC::DoDrawLine( wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2 ) +void wxGCDCImpl::DoDrawLine( wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2 ) { - wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawLine - invalid DC") ); + wxCHECK_RET( IsOk(), wxT("wxGCDC(cg)::DoDrawLine - invalid DC") ); if ( !m_logicalFunctionSupported ) return; @@ -456,16 +537,16 @@ void wxGCDC::DoDrawLine( wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2 ) CalcBoundingBox(x2, y2); } -void wxGCDC::DoCrossHair( wxCoord x, wxCoord y ) +void wxGCDCImpl::DoCrossHair( wxCoord x, wxCoord y ) { - wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoCrossHair - invalid DC") ); + wxCHECK_RET( IsOk(), wxT("wxGCDC(cg)::DoCrossHair - invalid DC") ); if ( !m_logicalFunctionSupported ) return; int w = 0, h = 0; - GetSize( &w, &h ); + GetOwner()->GetSize( &w, &h ); m_graphicContext->StrokeLine(0,y,w,y); m_graphicContext->StrokeLine(x,0,x,h); @@ -474,11 +555,11 @@ void wxGCDC::DoCrossHair( wxCoord x, wxCoord y ) CalcBoundingBox(0+w, 0+h); } -void wxGCDC::DoDrawArc( wxCoord x1, wxCoord y1, +void wxGCDCImpl::DoDrawArc( wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2, wxCoord xc, wxCoord yc ) { - wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawArc - invalid DC") ); + wxCHECK_RET( IsOk(), wxT("wxGCDC(cg)::DoDrawArc - invalid DC") ); if ( !m_logicalFunctionSupported ) return; @@ -520,10 +601,10 @@ void wxGCDC::DoDrawArc( wxCoord x1, wxCoord y1, m_graphicContext->DrawPath(path); } -void wxGCDC::DoDrawEllipticArc( wxCoord x, wxCoord y, wxCoord w, wxCoord h, +void wxGCDCImpl::DoDrawEllipticArc( wxCoord x, wxCoord y, wxCoord w, wxCoord h, double sa, double ea ) { - wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawEllipticArc - invalid DC") ); + wxCHECK_RET( IsOk(), wxT("wxGCDC(cg)::DoDrawEllipticArc - invalid DC") ); if ( !m_logicalFunctionSupported ) return; @@ -539,37 +620,35 @@ void wxGCDC::DoDrawEllipticArc( wxCoord x, wxCoord y, wxCoord w, wxCoord h, { wxGraphicsPath path = m_graphicContext->CreatePath(); path.MoveToPoint( 0, 0 ); - path.AddLineToPoint( h / 2.0 * cos(DegToRad(sa)) , h / 2.0 * sin(DegToRad(-sa)) ); - path.AddLineToPoint( h / 2.0 * cos(DegToRad(ea)) , h / 2.0 * sin(DegToRad(-ea)) ); + path.AddArc( 0, 0, h/2.0 , DegToRad(-sa) , DegToRad(-ea), sa > ea ); path.AddLineToPoint( 0, 0 ); m_graphicContext->FillPath( path ); path = m_graphicContext->CreatePath(); path.AddArc( 0, 0, h/2.0 , DegToRad(-sa) , DegToRad(-ea), sa > ea ); - m_graphicContext->FillPath( path ); m_graphicContext->StrokePath( path ); } else { wxGraphicsPath path = m_graphicContext->CreatePath(); - path.AddArc( 0, 0, h/2.0 , DegToRad(-sa) , DegToRad(-ea), sa > ea ); - m_graphicContext->DrawPath( path ); + path.AddArc( 0, 0, h/2.0 , DegToRad(-sa) , DegToRad(-ea), sa > ea ); + m_graphicContext->DrawPath( path ); } m_graphicContext->PopState(); } -void wxGCDC::DoDrawPoint( wxCoord x, wxCoord y ) +void wxGCDCImpl::DoDrawPoint( wxCoord x, wxCoord y ) { - wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawPoint - invalid DC") ); + wxCHECK_RET( IsOk(), wxT("wxGCDC(cg)::DoDrawPoint - invalid DC") ); DoDrawLine( x , y , x + 1 , y + 1 ); } -void wxGCDC::DoDrawLines(int n, wxPoint points[], +void wxGCDCImpl::DoDrawLines(int n, wxPoint points[], wxCoord xoffset, wxCoord yoffset) { - wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawLines - invalid DC") ); + wxCHECK_RET( IsOk(), wxT("wxGCDC(cg)::DoDrawLines - invalid DC") ); if ( !m_logicalFunctionSupported ) return; @@ -586,9 +665,9 @@ void wxGCDC::DoDrawLines(int n, wxPoint points[], } #if wxUSE_SPLINES -void wxGCDC::DoDrawSpline(const wxPointList *points) +void wxGCDCImpl::DoDrawSpline(const wxPointList *points) { - wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawSpline - invalid DC") ); + wxCHECK_RET( IsOk(), wxT("wxGCDC(cg)::DoDrawSpline - invalid DC") ); if ( !m_logicalFunctionSupported ) return; @@ -644,11 +723,11 @@ void wxGCDC::DoDrawSpline(const wxPointList *points) } #endif // wxUSE_SPLINES -void wxGCDC::DoDrawPolygon( int n, wxPoint points[], - wxCoord xoffset, wxCoord yoffset, - int fillStyle ) +void wxGCDCImpl::DoDrawPolygon( int n, wxPoint points[], + wxCoord xoffset, wxCoord yoffset, + wxPolygonFillMode fillStyle ) { - wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawPolygon - invalid DC") ); + wxCHECK_RET( IsOk(), wxT("wxGCDC(cg)::DoDrawPolygon - invalid DC") ); if ( n <= 0 || (m_brush.GetStyle() == wxTRANSPARENT && m_pen.GetStyle() == wxTRANSPARENT ) ) return; @@ -672,12 +751,12 @@ void wxGCDC::DoDrawPolygon( int n, wxPoint points[], delete[] pointsD; } -void wxGCDC::DoDrawPolyPolygon(int n, +void wxGCDCImpl::DoDrawPolyPolygon(int n, int count[], wxPoint points[], wxCoord xoffset, wxCoord yoffset, - int fillStyle) + wxPolygonFillMode fillStyle) { wxASSERT(n > 1); wxGraphicsPath path = m_graphicContext->CreatePath(); @@ -701,9 +780,9 @@ void wxGCDC::DoDrawPolyPolygon(int n, m_graphicContext->DrawPath( path , fillStyle); } -void wxGCDC::DoDrawRectangle(wxCoord x, wxCoord y, wxCoord w, wxCoord h) +void wxGCDCImpl::DoDrawRectangle(wxCoord x, wxCoord y, wxCoord w, wxCoord h) { - wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawRectangle - invalid DC") ); + wxCHECK_RET( IsOk(), wxT("wxGCDC(cg)::DoDrawRectangle - invalid DC") ); if ( !m_logicalFunctionSupported ) return; @@ -722,11 +801,11 @@ void wxGCDC::DoDrawRectangle(wxCoord x, wxCoord y, wxCoord w, wxCoord h) m_graphicContext->DrawRectangle(x,y,w,h); } -void wxGCDC::DoDrawRoundedRectangle(wxCoord x, wxCoord y, +void wxGCDCImpl::DoDrawRoundedRectangle(wxCoord x, wxCoord y, wxCoord w, wxCoord h, double radius) { - wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawRoundedRectangle - invalid DC") ); + wxCHECK_RET( IsOk(), wxT("wxGCDC(cg)::DoDrawRoundedRectangle - invalid DC") ); if ( !m_logicalFunctionSupported ) return; @@ -748,9 +827,9 @@ void wxGCDC::DoDrawRoundedRectangle(wxCoord x, wxCoord y, m_graphicContext->DrawRoundedRectangle( x,y,w,h,radius); } -void wxGCDC::DoDrawEllipse(wxCoord x, wxCoord y, wxCoord w, wxCoord h) +void wxGCDCImpl::DoDrawEllipse(wxCoord x, wxCoord y, wxCoord w, wxCoord h) { - wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawEllipse - invalid DC") ); + wxCHECK_RET( IsOk(), wxT("wxGCDC(cg)::DoDrawEllipse - invalid DC") ); if ( !m_logicalFunctionSupported ) return; @@ -765,14 +844,15 @@ void wxGCDC::DoDrawEllipse(wxCoord x, wxCoord y, wxCoord w, wxCoord h) m_graphicContext->DrawEllipse(x,y,w,h); } -bool wxGCDC::CanDrawBitmap() const +bool wxGCDCImpl::CanDrawBitmap() const { return true; } -bool wxGCDC::DoBlit( +bool wxGCDCImpl::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height, - wxDC *source, wxCoord xsrc, wxCoord ysrc, int logical_func , bool useMask, + wxDC *source, wxCoord xsrc, wxCoord ysrc, + wxRasterOperationMode logical_func , bool useMask, wxCoord xsrcMask, wxCoord ysrcMask ) { return DoStretchBlit( xdest, ydest, width, height, @@ -780,68 +860,88 @@ bool wxGCDC::DoBlit( xsrcMask,ysrcMask ); } -bool wxGCDC::DoStretchBlit( +bool wxGCDCImpl::DoStretchBlit( wxCoord xdest, wxCoord ydest, wxCoord dstWidth, wxCoord dstHeight, wxDC *source, wxCoord xsrc, wxCoord ysrc, wxCoord srcWidth, wxCoord srcHeight, - int logical_func , bool WXUNUSED(useMask), + wxRasterOperationMode logical_func , bool useMask, wxCoord xsrcMask, wxCoord ysrcMask ) { - wxCHECK_MSG( Ok(), false, wxT("wxGCDC(cg)::DoStretchBlit - invalid DC") ); - wxCHECK_MSG( source->Ok(), false, wxT("wxGCDC(cg)::DoStretchBlit - invalid source DC") ); + wxCHECK_MSG( IsOk(), false, wxT("wxGCDC(cg)::DoStretchBlit - invalid DC") ); + wxCHECK_MSG( source->IsOk(), false, wxT("wxGCDC(cg)::DoStretchBlit - invalid source DC") ); if ( logical_func == wxNO_OP ) return true; - else if ( !m_graphicContext->SetLogicalFunction( logical_func ) ) - + + wxCompositionMode mode; + if ( !TranslateRasterOp(logical_func, &mode) ) { - wxFAIL_MSG( wxT("Blitting is only supported with wxCOPY logical operation.") ); + wxFAIL_MSG( wxT("Blitting is not supported with this logical operation.") ); return false; } - if (xsrcMask == -1 && ysrcMask == -1) + bool retval = true; + + wxCompositionMode formerMode = m_graphicContext->GetCompositionMode(); + if (m_graphicContext->SetCompositionMode(mode)) { - xsrcMask = xsrc; - ysrcMask = ysrc; - } + wxAntialiasMode formerAa = m_graphicContext->GetAntialiasMode(); + if (mode == wxCOMPOSITION_XOR) + { + m_graphicContext->SetAntialiasMode(wxANTIALIAS_NONE); + } - wxRect subrect(source->LogicalToDeviceX(xsrc), - source->LogicalToDeviceY(ysrc), - source->LogicalToDeviceXRel(srcWidth), - source->LogicalToDeviceYRel(srcHeight)); + if (xsrcMask == -1 && ysrcMask == -1) + { + xsrcMask = xsrc; + ysrcMask = ysrc; + } - // 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; + wxRect subrect(source->LogicalToDeviceX(xsrc), + source->LogicalToDeviceY(ysrc), + source->LogicalToDeviceXRel(srcWidth), + source->LogicalToDeviceYRel(srcHeight)); - wxBitmap blit = source->GetAsBitmap( &subrect ); + // 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; - if ( blit.Ok() ) - { - m_graphicContext->DrawBitmap( blit, xdest, ydest, - dstWidth, dstHeight); - } - else - { - wxFAIL_MSG( wxT("Cannot Blit. Unable to get contents of DC as bitmap.") ); - return false; - } + wxBitmap blit = source->GetAsBitmap( &subrect ); - // reset logical function - m_graphicContext->SetLogicalFunction( m_logicalFunction ); + if ( blit.IsOk() ) + { + if ( !useMask && blit.GetMask() ) + blit.SetMask(NULL); - return true; + m_graphicContext->DrawBitmap( blit, xdest, ydest, + dstWidth, dstHeight); + } + else + { + wxFAIL_MSG( wxT("Cannot Blit. Unable to get contents of DC as bitmap.") ); + retval = false; + } + + if (mode == wxCOMPOSITION_XOR) + { + m_graphicContext->SetAntialiasMode(formerAa); + } + } + // reset composition + m_graphicContext->SetCompositionMode(formerMode); + + return retval; } -void wxGCDC::DoDrawRotatedText(const wxString& str, wxCoord x, wxCoord y, +void wxGCDCImpl::DoDrawRotatedText(const wxString& str, wxCoord x, wxCoord y, double angle) { - wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawRotatedText - invalid DC") ); + wxCHECK_RET( IsOk(), wxT("wxGCDC(cg)::DoDrawRotatedText - invalid DC") ); if ( str.length() == 0 ) return; @@ -854,9 +954,9 @@ void wxGCDC::DoDrawRotatedText(const wxString& str, wxCoord x, wxCoord y, 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 wxGCDCImpl::DoDrawText(const wxString& str, wxCoord x, wxCoord y) { - wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawRotatedText - invalid DC") ); + wxCHECK_RET( IsOk(), wxT("wxGCDC(cg)::DoDrawText - invalid DC") ); if ( str.length() == 0 ) return; @@ -870,18 +970,18 @@ void wxGCDC::DoDrawText(const wxString& str, wxCoord x, wxCoord y) m_graphicContext->DrawText( str, x ,y , m_graphicContext->CreateBrush( wxBrush(m_textBackgroundColour,wxSOLID) ) ); } -bool wxGCDC::CanGetTextExtent() const +bool wxGCDCImpl::CanGetTextExtent() const { - wxCHECK_MSG( Ok(), false, wxT("wxGCDC(cg)::CanGetTextExtent - invalid DC") ); + wxCHECK_MSG( IsOk(), false, wxT("wxGCDC(cg)::CanGetTextExtent - invalid DC") ); return true; } -void wxGCDC::DoGetTextExtent( const wxString &str, wxCoord *width, wxCoord *height, +void wxGCDCImpl::DoGetTextExtent( const wxString &str, wxCoord *width, wxCoord *height, wxCoord *descent, wxCoord *externalLeading , const wxFont *theFont ) const { - wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoGetTextExtent - invalid DC") ); + wxCHECK_RET( m_graphicContext, wxT("wxGCDC(cg)::DoGetTextExtent - invalid DC") ); if ( theFont ) { @@ -907,9 +1007,9 @@ void wxGCDC::DoGetTextExtent( const wxString &str, wxCoord *width, wxCoord *heig } } -bool wxGCDC::DoGetPartialTextExtents(const wxString& text, wxArrayInt& widths) const +bool wxGCDCImpl::DoGetPartialTextExtents(const wxString& text, wxArrayInt& widths) const { - wxCHECK_MSG( Ok(), false, wxT("wxGCDC(cg)::DoGetPartialTextExtents - invalid DC") ); + wxCHECK_MSG( m_graphicContext, false, wxT("wxGCDC(cg)::DoGetPartialTextExtents - invalid DC") ); widths.Clear(); widths.Add(0,text.Length()); if ( text.IsEmpty() ) @@ -924,7 +1024,7 @@ bool wxGCDC::DoGetPartialTextExtents(const wxString& text, wxArrayInt& widths) c return true; } -wxCoord wxGCDC::GetCharWidth(void) const +wxCoord wxGCDCImpl::GetCharWidth(void) const { wxCoord width; DoGetTextExtent( wxT("g") , &width , NULL , NULL , NULL , NULL ); @@ -932,7 +1032,7 @@ wxCoord wxGCDC::GetCharWidth(void) const return width; } -wxCoord wxGCDC::GetCharHeight(void) const +wxCoord wxGCDCImpl::GetCharHeight(void) const { wxCoord height; DoGetTextExtent( wxT("g") , NULL , &height , NULL , NULL , NULL ); @@ -940,9 +1040,9 @@ wxCoord wxGCDC::GetCharHeight(void) const return height; } -void wxGCDC::Clear(void) +void wxGCDCImpl::Clear(void) { - wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::Clear - invalid DC") ); + wxCHECK_RET( IsOk(), wxT("wxGCDC(cg)::Clear - invalid DC") ); // TODO better implementation / incorporate size info into wxGCDC or context m_graphicContext->SetBrush( m_backgroundBrush ); wxPen p = *wxTRANSPARENT_PEN; @@ -952,13 +1052,18 @@ void wxGCDC::Clear(void) m_graphicContext->SetBrush( m_brush ); } -void wxGCDC::DoGetSize(int *width, int *height) const +void wxGCDCImpl::DoGetSize(int *width, int *height) const { - *width = 10000; - *height = 10000; + wxCHECK_RET( IsOk(), wxT("wxGCDC(cg)::DoGetSize - invalid DC") ); + wxDouble w,h; + m_graphicContext->GetSize( &w, &h ); + if ( height ) + *height = (int) (h+0.5); + if ( width ) + *width = (int) (w+0.5); } -void wxGCDC::DoGradientFillLinear(const wxRect& rect, +void wxGCDCImpl::DoGradientFillLinear(const wxRect& rect, const wxColour& initialColour, const wxColour& destColour, wxDirection nDirection ) @@ -1001,7 +1106,7 @@ void wxGCDC::DoGradientFillLinear(const wxRect& rect, m_graphicContext->SetPen(m_pen); } -void wxGCDC::DoGradientFillConcentric(const wxRect& rect, +void wxGCDCImpl::DoGradientFillConcentric(const wxRect& rect, const wxColour& initialColour, const wxColour& destColour, const wxPoint& circleCenter) @@ -1029,10 +1134,10 @@ void wxGCDC::DoGradientFillConcentric(const wxRect& rect, m_graphicContext->SetPen(m_pen); } -void wxGCDC::DoDrawCheckMark(wxCoord x, wxCoord y, +void wxGCDCImpl::DoDrawCheckMark(wxCoord x, wxCoord y, wxCoord width, wxCoord height) { - wxDCBase::DoDrawCheckMark(x,y,width,height); + wxDCImpl::DoDrawCheckMark(x,y,width,height); } #endif // wxUSE_GRAPHICS_CONTEXT