diff --git a/docs/changes.txt b/docs/changes.txt index 6c2029a5cf..e02c41a436 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -124,6 +124,7 @@ wxMSW: - Restore dispatching wxThreadEvent while resizing the window broken in 3.1.0. - Fix wxGraphicsMatrix::TransformDistance for Direct2D renderer. - Fix wxDC::Clear() for rotated DC. +- Fix wxDC::GetClippingBox() for transformed wxDC. wxOSX: diff --git a/include/wx/msw/dc.h b/include/wx/msw/dc.h index b4f603023c..01eb90fbe8 100644 --- a/include/wx/msw/dc.h +++ b/include/wx/msw/dc.h @@ -121,8 +121,7 @@ public: // return it if asked -- but avoid calling ::GetClipBox() right now as // it could be unnecessary wasteful m_clipping = true; - m_clipX1 = - m_clipX2 = 0; + m_isClipBoxValid = false; } void* GetHandle() const { return (void*)GetHDC(); } @@ -164,6 +163,7 @@ protected: #if wxUSE_PALETTE m_oldPalette = NULL; #endif // wxUSE_PALETTE + m_isClipBoxValid = false; } // create an uninitialized DC: this should be only used by the derived @@ -323,6 +323,8 @@ protected: static wxObjectList sm_dcCache; #endif + bool m_isClipBoxValid; + wxDECLARE_CLASS(wxMSWDCImpl); wxDECLARE_NO_COPY_CLASS(wxMSWDCImpl); }; diff --git a/src/msw/dc.cpp b/src/msw/dc.cpp index 193067414c..5d19524668 100644 --- a/src/msw/dc.cpp +++ b/src/msw/dc.cpp @@ -579,21 +579,32 @@ void wxMSWDCImpl::UpdateClipBox() m_clipY1 = (wxCoord) YDEV2LOG(rect.top); m_clipX2 = (wxCoord) XDEV2LOG(rect.right); m_clipY2 = (wxCoord) YDEV2LOG(rect.bottom); + m_isClipBoxValid = true; } void wxMSWDCImpl::DoGetClippingBox(wxCoord *x, wxCoord *y, wxCoord *w, wxCoord *h) const { // check if we should try to retrieve the clipping region possibly not set - // by our SetClippingRegion() but preset by Windows:this can only happen - // when we're associated with an existing HDC usign SetHDC(), see there - if ( m_clipping && !m_clipX1 && !m_clipX2 ) + // by our SetClippingRegion() but preset or modified by Windows: this + // can happen when we're associated with an existing HDC using SetHDC() or + // when wxDC logical coordinates are transformed with SetDeviceOrigin(), + // SetLogicalOrigin(), SetUserScale(), SetLogicalScale(), + // SetTransformMatrix(), ResetTransformMatrix(). + if ( !m_isClipBoxValid ) { wxMSWDCImpl *self = wxConstCast(this, wxMSWDCImpl); self->UpdateClipBox(); } - wxDCImpl::DoGetClippingBox(x, y, w, h); + if ( x ) + *x = m_clipX1; + if ( y ) + *y = m_clipY1; + if ( w ) + *w = m_clipX2 - m_clipX1; + if ( h ) + *h = m_clipY2 - m_clipY1; } // common part of DoSetClippingRegion() and DoSetDeviceClippingRegion() @@ -679,6 +690,7 @@ void wxMSWDCImpl::DestroyClippingRegion() } wxDCImpl::DestroyClippingRegion(); + m_isClipBoxValid = false; } // --------------------------------------------------------------------------- @@ -1868,6 +1880,8 @@ void wxMSWDCImpl::RealizeScaleAndOrigin() ::SetViewportOrgEx(GetHdc(), m_deviceOriginX, m_deviceOriginY, NULL); ::SetWindowOrgEx(GetHdc(), m_logicalOriginX, m_logicalOriginY, NULL); + + m_isClipBoxValid = false; } void wxMSWDCImpl::SetMapMode(wxMappingMode mode) @@ -1977,6 +1991,8 @@ void wxMSWDCImpl::SetDeviceOrigin(wxCoord x, wxCoord y) wxDCImpl::SetDeviceOrigin( x, y ); ::SetViewportOrgEx(GetHdc(), (int)m_deviceOriginX, (int)m_deviceOriginY, NULL); + + m_isClipBoxValid = false; } // ---------------------------------------------------------------------------- @@ -2022,6 +2038,7 @@ bool wxMSWDCImpl::SetTransformMatrix(const wxAffineMatrix2D &matrix) return false; } + m_isClipBoxValid = false; return true; } @@ -2047,6 +2064,7 @@ void wxMSWDCImpl::ResetTransformMatrix() { ::ModifyWorldTransform(GetHdc(), NULL, MWT_IDENTITY); ::SetGraphicsMode(GetHdc(), GM_COMPATIBLE); + m_isClipBoxValid = false; } #endif // wxUSE_DC_TRANSFORM_MATRIX