return (deg * M_PI) / 180.0;
}
-static bool TranslateRasterOp(wxRasterOperationMode function, wxCompositionMode *op)
+static wxCompositionMode TranslateRasterOp(wxRasterOperationMode function)
{
switch ( function )
{
case wxCOPY: // src
// since we are supporting alpha, _OVER is closer to the intention than _SOURCE
// since the latter would overwrite even when alpha is not set to opaque
- *op = wxCOMPOSITION_OVER;
- break;
+ return wxCOMPOSITION_OVER;
+
case wxOR: // src OR dst
- *op = wxCOMPOSITION_ADD;
- break;
+ return wxCOMPOSITION_ADD;
+
case wxNO_OP: // dst
- *op = wxCOMPOSITION_DEST; // ignore the source
- break;
+ return wxCOMPOSITION_DEST; // ignore the source
+
case wxCLEAR: // 0
- *op = wxCOMPOSITION_CLEAR;// clear dst
- break;
+ return wxCOMPOSITION_CLEAR;// clear dst
+
case wxXOR: // src XOR dst
- *op = wxCOMPOSITION_XOR;
- break;
+ return wxCOMPOSITION_XOR;
case wxAND: // src AND dst
case wxAND_INVERT: // (NOT src) AND dst
case wxOR_REVERSE: // src OR (NOT dst)
case wxSET: // 1
case wxSRC_INVERT: // NOT src
- default:
- return false;
+ break;
}
- return true;
+
+ return wxCOMPOSITION_INVALID;
}
//-----------------------------------------------------------------------------
}
#endif
+#if defined(__WXMSW__) && wxUSE_ENH_METAFILE
+wxGCDC::wxGCDC(const wxEnhMetaFileDC& dc)
+ : wxDC(new wxGCDCImpl(this, dc))
+{
+}
+#endif
+
+wxGCDC::wxGCDC(wxGraphicsContext* context) :
+ wxDC( new wxGCDCImpl( this ) )
+{
+ SetGraphicsContext(context);
+}
+
wxGCDC::wxGCDC() :
wxDC( new wxGCDCImpl( this ) )
{
{
}
-wxGraphicsContext* wxGCDC::GetGraphicsContext()
+wxGraphicsContext* wxGCDC::GetGraphicsContext() const
{
if (!m_pimpl) return NULL;
wxGCDCImpl *gc_impl = (wxGCDCImpl*) m_pimpl;
{
Init();
wxGraphicsContext* context;
-#if wxUSE_CAIRO
- wxGraphicsRenderer* renderer = wxGraphicsRenderer::GetCairoRenderer();
- context = renderer->CreateContext(dc);
-#else
context = wxGraphicsContext::Create(dc);
-#endif
-
SetGraphicsContext( context );
}
}
#endif
+#if defined(__WXMSW__) && wxUSE_ENH_METAFILE
+wxGCDCImpl::wxGCDCImpl(wxDC *owner, const wxEnhMetaFileDC& dc)
+ : wxDCImpl(owner)
+{
+ Init();
+ SetGraphicsContext(wxGraphicsContext::Create(dc));
+}
+#endif
+
void wxGCDCImpl::Init()
{
m_ok = false;
{
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 );
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);
void wxGCDCImpl::SetPen( const wxPen &pen )
{
- if ( m_pen == pen )
- return;
-
m_pen = pen;
if ( m_graphicContext )
{
void wxGCDCImpl::SetBrush( const wxBrush &brush )
{
- if (m_brush == brush)
- return;
-
m_brush = brush;
if ( m_graphicContext )
{
void wxGCDCImpl::SetBackground( const wxBrush &brush )
{
- if (m_backgroundBrush == brush)
- return;
-
m_backgroundBrush = brush;
if (!m_backgroundBrush.IsOk())
return;
void wxGCDCImpl::SetLogicalFunction( wxRasterOperationMode function )
{
- if (m_logicalFunction == function)
- return;
-
m_logicalFunction = function;
- wxCompositionMode mode;
- m_logicalFunctionSupported = TranslateRasterOp( function, &mode);
+ wxCompositionMode mode = TranslateRasterOp( function );
+ m_logicalFunctionSupported = mode != wxCOMPOSITION_INVALID;
if (m_logicalFunctionSupported)
m_logicalFunctionSupported = m_graphicContext->SetCompositionMode(mode);
if ( logical_func == wxNO_OP )
return true;
- wxCompositionMode mode;
- if ( !TranslateRasterOp(logical_func, &mode) )
+ wxCompositionMode mode = TranslateRasterOp(logical_func);
+ if ( mode == wxCOMPOSITION_INVALID )
{
wxFAIL_MSG( wxT("Blitting is not supported with this logical operation.") );
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();
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() )
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
{
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,
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,
wxDCImpl::DoDrawCheckMark(x,y,width,height);
}
+#ifdef __WXMSW__
+wxRect wxGCDCImpl::MSWApplyGDIPlusTransform(const wxRect& r) const
+{
+ wxGraphicsContext* const gc = GetGraphicsContext();
+ wxCHECK_MSG( gc, r, wxT("Invalid wxGCDC") );
+
+ double x = 0,
+ y = 0;
+ gc->GetTransform().TransformPoint(&x, &y);
+
+ wxRect rect(r);
+ rect.Offset(x, y);
+
+ return rect;
+}
+#endif // __WXMSW__
+
#endif // wxUSE_GRAPHICS_CONTEXT