X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/906c935a80b10d53cecf57f71ab5f3f4f1d529ec..ea160f01c60cfc879e1ba3ffec76d113a0404603:/src/common/dcgraph.cpp diff --git a/src/common/dcgraph.cpp b/src/common/dcgraph.cpp index a06cd25382..f787932c21 100644 --- a/src/common/dcgraph.cpp +++ b/src/common/dcgraph.cpp @@ -18,24 +18,12 @@ #if wxUSE_GRAPHICS_CONTEXT -#include "wx/graphics.h" #include "wx/dcgraph.h" #ifndef WX_PRECOMP #include "wx/icon.h" - #include "wx/bitmap.h" + #include "wx/dcclient.h" #include "wx/dcmemory.h" - #include "wx/region.h" -#endif - -#include "wx/dcclient.h" - -#ifdef __WXOSX_OR_COCOA__ -#ifdef __WXOSX_IPHONE__ - #include -#else - #include -#endif #endif //----------------------------------------------------------------------------- @@ -121,6 +109,12 @@ wxGCDC::wxGCDC(const wxEnhMetaFileDC& dc) } #endif +wxGCDC::wxGCDC(wxGraphicsContext* context) : + wxDC( new wxGCDCImpl( this ) ) +{ + SetGraphicsContext(context); +} + wxGCDC::wxGCDC() : wxDC( new wxGCDCImpl( this ) ) { @@ -149,7 +143,7 @@ IMPLEMENT_ABSTRACT_CLASS(wxGCDCImpl, wxDCImpl) wxGCDCImpl::wxGCDCImpl( wxDC *owner ) : wxDCImpl( owner ) { - Init(); + Init(wxGraphicsContext::Create()); } void wxGCDCImpl::SetGraphicsContext( wxGraphicsContext* ctx ) @@ -171,32 +165,21 @@ void wxGCDCImpl::SetGraphicsContext( wxGraphicsContext* ctx ) wxGCDCImpl::wxGCDCImpl( wxDC *owner, const wxWindowDC& dc ) : wxDCImpl( owner ) { - Init(); - SetGraphicsContext( wxGraphicsContext::Create(dc) ); + Init(wxGraphicsContext::Create(dc)); m_window = dc.GetWindow(); } 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 ); + Init(wxGraphicsContext::Create(dc)); } #if wxUSE_PRINTING_ARCHITECTURE wxGCDCImpl::wxGCDCImpl( wxDC *owner, const wxPrinterDC& dc ) : wxDCImpl( owner ) { - Init(); - SetGraphicsContext( wxGraphicsContext::Create(dc) ); + Init(wxGraphicsContext::Create(dc)); } #endif @@ -204,12 +187,18 @@ wxGCDCImpl::wxGCDCImpl( wxDC *owner, const wxPrinterDC& dc ) : wxGCDCImpl::wxGCDCImpl(wxDC *owner, const wxEnhMetaFileDC& dc) : wxDCImpl(owner) { - Init(); - SetGraphicsContext(wxGraphicsContext::Create(dc)); + Init(wxGraphicsContext::Create(dc)); } #endif -void wxGCDCImpl::Init() +wxGCDCImpl::wxGCDCImpl(wxDC* owner, int) + : wxDCImpl(owner) +{ + // derived class will set a context + Init(NULL); +} + +void wxGCDCImpl::Init(wxGraphicsContext* ctx) { m_ok = false; m_colour = true; @@ -220,11 +209,13 @@ void wxGCDCImpl::Init() m_font = *wxNORMAL_FONT; m_brush = *wxWHITE_BRUSH; - m_graphicContext = wxGraphicsContext::Create(); + m_graphicContext = NULL; + if (ctx) + SetGraphicsContext(ctx); + m_logicalFunctionSupported = true; } - wxGCDCImpl::~wxGCDCImpl() { delete m_graphicContext; @@ -236,8 +227,8 @@ void wxGCDCImpl::DoDrawBitmap( const wxBitmap &bmp, wxCoord x, wxCoord y, 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(); + int w = bmp.GetScaledWidth(); + int h = bmp.GetScaledHeight(); if ( bmp.GetDepth() == 1 ) { m_graphicContext->SetPen(*wxTRANSPARENT_PEN); @@ -298,22 +289,8 @@ void wxGCDCImpl::DoSetClippingRegion( wxCoord x, wxCoord y, wxCoord w, wxCoord h wxCHECK_RET( IsOk(), wxT("wxGCDC(cg)::DoSetClippingRegion - invalid DC") ); m_graphicContext->Clip( x, y, w, h ); - if ( m_clipping ) - { - m_clipX1 = wxMax( m_clipX1, x ); - m_clipY1 = wxMax( m_clipY1, y ); - m_clipX2 = wxMin( m_clipX2, (x + w) ); - m_clipY2 = wxMin( m_clipY2, (y + h) ); - } - else - { - m_clipping = true; - m_clipX1 = x; - m_clipY1 = y; - m_clipX2 = x + w; - m_clipY2 = y + h; - } + wxDCImpl::DoSetClippingRegion(x, y, w, h); } void wxGCDCImpl::DoSetDeviceClippingRegion( const wxRegion ®ion ) @@ -382,7 +359,10 @@ void wxGCDCImpl::SetTextForeground( const wxColour &col ) { wxCHECK_RET( IsOk(), wxT("wxGCDC(cg)::SetTextForeground - invalid DC") ); - if ( col != m_textForegroundColour ) + // don't set m_textForegroundColour to an invalid colour as we'd crash + // later then (we use m_textForegroundColour.GetColor() without checking + // in a few places) + if ( col.IsOk() ) { m_textForegroundColour = col; m_graphicContext->SetFont( m_font, m_textForegroundColour ); @@ -396,35 +376,6 @@ void wxGCDCImpl::SetTextBackground( const wxColour &col ) m_textBackgroundColour = col; } -void wxGCDCImpl::SetMapMode( wxMappingMode mode ) -{ - switch (mode) - { - case wxMM_TWIPS: - SetLogicalScale( twips2mm * m_mm_to_pix_x, twips2mm * m_mm_to_pix_y ); - break; - - case wxMM_POINTS: - SetLogicalScale( pt2mm * m_mm_to_pix_x, pt2mm * m_mm_to_pix_y ); - break; - - case wxMM_METRIC: - SetLogicalScale( m_mm_to_pix_x, m_mm_to_pix_y ); - break; - - case wxMM_LOMETRIC: - SetLogicalScale( m_mm_to_pix_x / 10.0, m_mm_to_pix_y / 10.0 ); - break; - - case wxMM_TEXT: - default: - SetLogicalScale( 1.0, 1.0 ); - break; - } - - ComputeScaleAndOrigin(); -} - wxSize wxGCDCImpl::GetPPI() const { return wxSize(72, 72); @@ -445,7 +396,7 @@ void wxGCDCImpl::ComputeScaleAndOrigin() // the logical origin sets the origin to have new coordinates m_matrixCurrent.Translate( m_deviceOriginX - m_logicalOriginX * m_signX * m_scaleX, - m_deviceOriginY-m_logicalOriginY * m_signY * m_scaleY); + m_deviceOriginY - m_logicalOriginY * m_signY * m_scaleY); m_matrixCurrent.Scale( m_scaleX * m_signX, m_scaleY * m_signY ); @@ -454,6 +405,16 @@ void wxGCDCImpl::ComputeScaleAndOrigin() } } +void* wxGCDCImpl::GetHandle() const +{ + void* cgctx = NULL; + wxGraphicsContext* gc = GetGraphicsContext(); + if (gc) { + cgctx = gc->GetNativeContext(); + } + return cgctx; +} + void wxGCDCImpl::SetPalette( const wxPalette& WXUNUSED(palette) ) { @@ -469,18 +430,12 @@ void wxGCDCImpl::SetFont( const wxFont &font ) m_font = font; if ( m_graphicContext ) { - wxFont f = font; - if ( f.IsOk() ) - f.SetPointSize( /*LogicalToDeviceYRel*/(font.GetPointSize())); - m_graphicContext->SetFont( f, m_textForegroundColour ); + m_graphicContext->SetFont(font, m_textForegroundColour); } } void wxGCDCImpl::SetPen( const wxPen &pen ) { - if ( m_pen == pen ) - return; - m_pen = pen; if ( m_graphicContext ) { @@ -490,9 +445,6 @@ void wxGCDCImpl::SetPen( const wxPen &pen ) void wxGCDCImpl::SetBrush( const wxBrush &brush ) { - if (m_brush == brush) - return; - m_brush = brush; if ( m_graphicContext ) { @@ -502,9 +454,6 @@ void wxGCDCImpl::SetBrush( const wxBrush &brush ) void wxGCDCImpl::SetBackground( const wxBrush &brush ) { - if (m_backgroundBrush == brush) - return; - m_backgroundBrush = brush; if (!m_backgroundBrush.IsOk()) return; @@ -512,9 +461,6 @@ void wxGCDCImpl::SetBackground( const wxBrush &brush ) void wxGCDCImpl::SetLogicalFunction( wxRasterOperationMode function ) { - if (m_logicalFunction == function) - return; - m_logicalFunction = function; wxCompositionMode mode = TranslateRasterOp( function ); @@ -662,7 +608,7 @@ void wxGCDCImpl::DoDrawPoint( wxCoord x, wxCoord y ) DoDrawLine( x , y , x + 1 , y + 1 ); } -void wxGCDCImpl::DoDrawLines(int n, wxPoint points[], +void wxGCDCImpl::DoDrawLines(int n, const wxPoint points[], wxCoord xoffset, wxCoord yoffset) { wxCHECK_RET( IsOk(), wxT("wxGCDC(cg)::DoDrawLines - invalid DC") ); @@ -696,7 +642,7 @@ void wxGCDCImpl::DoDrawSpline(const wxPointList *points) // empty list return; - wxPoint *p = node->GetData(); + const wxPoint *p = node->GetData(); wxCoord x1 = p->x; wxCoord y1 = p->y; @@ -740,7 +686,7 @@ void wxGCDCImpl::DoDrawSpline(const wxPointList *points) } #endif // wxUSE_SPLINES -void wxGCDCImpl::DoDrawPolygon( int n, wxPoint points[], +void wxGCDCImpl::DoDrawPolygon( int n, const wxPoint points[], wxCoord xoffset, wxCoord yoffset, wxPolygonFillMode fillStyle ) { @@ -769,8 +715,8 @@ void wxGCDCImpl::DoDrawPolygon( int n, wxPoint points[], } void wxGCDCImpl::DoDrawPolyPolygon(int n, - int count[], - wxPoint points[], + const int count[], + const wxPoint points[], wxCoord xoffset, wxCoord yoffset, wxPolygonFillMode fillStyle) @@ -896,6 +842,18 @@ bool wxGCDCImpl::DoStretchBlit( return false; } + wxRect subrect(source->LogicalToDeviceX(xsrc), + source->LogicalToDeviceY(ysrc), + source->LogicalToDeviceXRel(srcWidth), + source->LogicalToDeviceYRel(srcHeight)); + const wxRect subrectOrig = subrect; + // clip the subrect down to the size of the source DC + wxRect clip; + source->GetSize(&clip.width, &clip.height); + subrect.Intersect(clip); + if (subrect.width == 0) + return true; + bool retval = true; wxCompositionMode formerMode = m_graphicContext->GetCompositionMode(); @@ -913,21 +871,6 @@ bool wxGCDCImpl::DoStretchBlit( ysrcMask = ysrc; } - wxRect subrect(source->LogicalToDeviceX(xsrc), - source->LogicalToDeviceY(ysrc), - source->LogicalToDeviceXRel(srcWidth), - source->LogicalToDeviceYRel(srcHeight)); - - // 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.IsOk() ) @@ -935,8 +878,19 @@ bool wxGCDCImpl::DoStretchBlit( if ( !useMask && blit.GetMask() ) blit.SetMask(NULL); - m_graphicContext->DrawBitmap( blit, xdest, ydest, - dstWidth, dstHeight); + double x = xdest; + double y = ydest; + double w = dstWidth; + double h = dstHeight; + // adjust dest rect if source rect is clipped + if (subrect.width != subrectOrig.width || subrect.height != subrectOrig.height) + { + x += (subrect.x - subrectOrig.x) / double(subrectOrig.width) * dstWidth; + y += (subrect.y - subrectOrig.y) / double(subrectOrig.height) * dstHeight; + w *= double(subrect.width) / subrectOrig.width; + h *= double(subrect.height) / subrectOrig.height; + } + m_graphicContext->DrawBitmap(blit, x, y, w, h); } else { @@ -1078,7 +1032,10 @@ void wxGCDCImpl::Clear(void) m_graphicContext->SetPen( p ); wxCompositionMode formerMode = m_graphicContext->GetCompositionMode(); m_graphicContext->SetCompositionMode(wxCOMPOSITION_SOURCE); - DoDrawRectangle( 0, 0, 32000 , 32000 ); + // maximum positive coordinate Cairo can handle is 2^23 - 1 + DoDrawRectangle( + DeviceToLogicalX(0), DeviceToLogicalY(0), + DeviceToLogicalXRel(0x007fffff), DeviceToLogicalYRel(0x007fffff)); m_graphicContext->SetCompositionMode(formerMode); m_graphicContext->SetPen( m_pen ); m_graphicContext->SetBrush( m_brush ); @@ -1136,6 +1093,7 @@ void wxGCDCImpl::DoGradientFillLinear(const wxRect& rect, m_graphicContext->SetPen(*wxTRANSPARENT_PEN); m_graphicContext->DrawRectangle(rect.x,rect.y,rect.width,rect.height); m_graphicContext->SetPen(m_pen); + m_graphicContext->SetBrush(m_brush); } void wxGCDCImpl::DoGradientFillConcentric(const wxRect& rect, @@ -1164,6 +1122,7 @@ void wxGCDCImpl::DoGradientFillConcentric(const wxRect& rect, m_graphicContext->DrawRectangle(rect.x,rect.y,rect.width,rect.height); m_graphicContext->SetPen(m_pen); + m_graphicContext->SetBrush(m_brush); } void wxGCDCImpl::DoDrawCheckMark(wxCoord x, wxCoord y,