From c5530b1abf36c652c29611c2ccb5a9d01305a3c1 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 18 Jun 2018 23:57:05 +0200 Subject: [PATCH] Switch to using DoGetClippingRect() instead of DoGetClippingBox() The new method returns a boolean flag which indicates whether there is any clipping region or not and so is preferable to using the old one and checking its return value to determine this, which can't be done reliably. --- include/wx/dc.h | 8 ++++++-- include/wx/dcgraph.h | 3 +-- include/wx/gtk/dcclient.h | 2 +- include/wx/msw/dc.h | 3 +-- src/common/dcbase.cpp | 16 ++++++++++------ src/common/dcgraph.cpp | 24 ++++++++++++++---------- src/gtk/dcclient.cpp | 13 +++---------- src/msw/dc.cpp | 27 +++++++++++++++++---------- src/msw/dcclient.cpp | 2 +- 9 files changed, 54 insertions(+), 44 deletions(-) diff --git a/include/wx/dc.h b/include/wx/dc.h index 55b1129218..a34a73b698 100644 --- a/include/wx/dc.h +++ b/include/wx/dc.h @@ -453,11 +453,15 @@ public: // up to date. virtual bool DoGetClippingRect(wxRect& rect) const; +#if WXWIN_COMPATIBILITY_3_0 // This method is kept for backwards compatibility but shouldn't be used // nor overridden in the new code, implement DoGetClippingRect() above // instead. - virtual void DoGetClippingBox(wxCoord *x, wxCoord *y, - wxCoord *w, wxCoord *h) const; + wxDEPRECATED_BUT_USED_INTERNALLY( + virtual void DoGetClippingBox(wxCoord *x, wxCoord *y, + wxCoord *w, wxCoord *h) const + ); +#endif // WXWIN_COMPATIBILITY_3_0 virtual void DestroyClippingRegion() { ResetClipping(); } diff --git a/include/wx/dcgraph.h b/include/wx/dcgraph.h index f9ac7461dd..9a11a19ce4 100644 --- a/include/wx/dcgraph.h +++ b/include/wx/dcgraph.h @@ -195,8 +195,7 @@ public: virtual void DoSetDeviceClippingRegion(const wxRegion& region) wxOVERRIDE; virtual void DoSetClippingRegion(wxCoord x, wxCoord y, wxCoord width, wxCoord height) wxOVERRIDE; - virtual void DoGetClippingBox(wxCoord *x, wxCoord *y, - wxCoord *w, wxCoord *h) const wxOVERRIDE; + virtual bool DoGetClippingRect(wxRect& rect) const wxOVERRIDE; virtual void DoGetTextExtent(const wxString& string, wxCoord *x, wxCoord *y, diff --git a/include/wx/gtk/dcclient.h b/include/wx/gtk/dcclient.h index 7911b74274..a633faccda 100644 --- a/include/wx/gtk/dcclient.h +++ b/include/wx/gtk/dcclient.h @@ -71,7 +71,7 @@ public: virtual bool DoGetPartialTextExtents(const wxString& text, wxArrayInt& widths) const wxOVERRIDE; virtual void DoSetClippingRegion( wxCoord x, wxCoord y, wxCoord width, wxCoord height ) wxOVERRIDE; virtual void DoSetDeviceClippingRegion( const wxRegion ®ion ) wxOVERRIDE; - virtual void DoGetClippingBox(wxCoord *x, wxCoord *y, wxCoord *w, wxCoord *h) const wxOVERRIDE; + virtual bool DoGetClippingRect(wxRect& rect) const wxOVERRIDE; virtual wxCoord GetCharWidth() const wxOVERRIDE; virtual wxCoord GetCharHeight() const wxOVERRIDE; diff --git a/include/wx/msw/dc.h b/include/wx/msw/dc.h index 269b81cff2..7e16a138b2 100644 --- a/include/wx/msw/dc.h +++ b/include/wx/msw/dc.h @@ -243,8 +243,7 @@ public: virtual void DoSetClippingRegion(wxCoord x, wxCoord y, wxCoord width, wxCoord height) wxOVERRIDE; virtual void DoSetDeviceClippingRegion(const wxRegion& region) wxOVERRIDE; - virtual void DoGetClippingBox(wxCoord *x, wxCoord *y, - wxCoord *w, wxCoord *h) const wxOVERRIDE; + virtual bool DoGetClippingRect(wxRect& rect) const wxOVERRIDE; virtual void DoGetSizeMM(int* width, int* height) const wxOVERRIDE; diff --git a/src/common/dcbase.cpp b/src/common/dcbase.cpp index 0a0e2d2f1d..1363984b7e 100644 --- a/src/common/dcbase.cpp +++ b/src/common/dcbase.cpp @@ -414,6 +414,7 @@ wxRect wxDCImpl::GetLogicalArea() const bool wxDCImpl::DoGetClippingRect(wxRect& rect) const { +#if WXWIN_COMPATIBILITY_3_0 // Call the old function for compatibility. DoGetClippingBox(&rect.x, &rect.y, &rect.width, &rect.height); if ( rect != wxRect(-1, -1, 0, 0) ) @@ -425,6 +426,7 @@ bool wxDCImpl::DoGetClippingRect(wxRect& rect) const // is not empty because some implementations seem to do this instead. return !rect.IsEmpty() && rect != GetLogicalArea(); } +#endif // WXWIN_COMPATIBILITY_3_0 if ( m_clipping ) { @@ -443,6 +445,7 @@ bool wxDCImpl::DoGetClippingRect(wxRect& rect) const } } +#if WXWIN_COMPATIBILITY_3_0 void wxDCImpl::DoGetClippingBox(wxCoord *x, wxCoord *y, wxCoord *w, wxCoord *h) const { @@ -457,6 +460,7 @@ void wxDCImpl::DoGetClippingBox(wxCoord *x, wxCoord *y, if ( h ) *h = 0; } +#endif // WXWIN_COMPATIBILITY_3_0 // ---------------------------------------------------------------------------- // coordinate conversions and transforms @@ -1370,12 +1374,12 @@ void wxDC::GetDeviceOrigin(long *x, long *y) const void wxDC::GetClippingBox(long *x, long *y, long *w, long *h) const { - wxCoord xx,yy,ww,hh; - m_pimpl->DoGetClippingBox(&xx, &yy, &ww, &hh); - if (x) *x = xx; - if (y) *y = yy; - if (w) *w = ww; - if (h) *h = hh; + wxRect r; + m_pimpl->DoGetClippingRect(r); + if (x) *x = r.x; + if (y) *y = r.y; + if (w) *w = r.width; + if (h) *h = r.height; } void wxDC::DrawObject(wxDrawObject* drawobject) diff --git a/src/common/dcgraph.cpp b/src/common/dcgraph.cpp index 8a1441697d..d70113dfcc 100644 --- a/src/common/dcgraph.cpp +++ b/src/common/dcgraph.cpp @@ -282,6 +282,17 @@ void wxGCDCImpl::UpdateClipBox() double x, y, w, h; m_graphicContext->GetClipBox(&x, &y, &w, &h); + // We shouldn't reset m_clipping if the clipping region that we set happens + // to be empty (e.g. because its intersection with the previous clipping + // region was empty), but we should set it to true if we do have a valid + // clipping region and it was false which may happen if the clipping region + // set from the outside of wxWidgets code. + if ( !m_clipping ) + { + if ( w != 0. && h != 0. ) + m_clipping = true; + } + m_clipX1 = wxRound(x); m_clipY1 = wxRound(y); m_clipX2 = wxRound(x+w); @@ -289,9 +300,9 @@ void wxGCDCImpl::UpdateClipBox() m_isClipBoxValid = true; } -void wxGCDCImpl::DoGetClippingBox(wxCoord *x, wxCoord *y, wxCoord *w, wxCoord *h) const +bool wxGCDCImpl::DoGetClippingRect(wxRect& rect) const { - wxCHECK_RET( IsOk(), wxS("wxGCDC::DoGetClippingRegion - invalid GC") ); + wxCHECK_MSG( IsOk(), false, wxS("wxGCDC::DoGetClippingRegion - invalid GC") ); // Check if we should retrieve the clipping region possibly not set // by SetClippingRegion() but modified by application: this can // happen when we're associated with an existing graphics context using @@ -303,14 +314,7 @@ void wxGCDCImpl::DoGetClippingBox(wxCoord *x, wxCoord *y, wxCoord *w, wxCoord *h self->UpdateClipBox(); } - if ( x ) - *x = m_clipX1; - if ( y ) - *y = m_clipY1; - if ( w ) - *w = m_clipX2 - m_clipX1; - if ( h ) - *h = m_clipY2 - m_clipY1; + return wxDCImpl::DoGetClippingRect(rect); } void wxGCDCImpl::DoSetClippingRegion( wxCoord x, wxCoord y, wxCoord w, wxCoord h ) diff --git a/src/gtk/dcclient.cpp b/src/gtk/dcclient.cpp index 0f29c219f5..9e98f62b4d 100644 --- a/src/gtk/dcclient.cpp +++ b/src/gtk/dcclient.cpp @@ -1914,9 +1914,9 @@ void wxWindowDCImpl::UpdateClipBox() m_isClipBoxValid = true; } -void wxWindowDCImpl::DoGetClippingBox(wxCoord *x, wxCoord *y, wxCoord *w, wxCoord *h) const +bool wxWindowDCImpl::DoGetClippingRect(wxRect& rect) const { - wxCHECK_RET( IsOk(), wxS("invalid window dc") ); + wxCHECK_MSG( IsOk(), false, wxS("invalid window dc") ); // Check if we should try to retrieve the clipping region possibly not set // by our SetClippingRegion() but preset or modified by application: this @@ -1928,14 +1928,7 @@ void wxWindowDCImpl::DoGetClippingBox(wxCoord *x, wxCoord *y, wxCoord *w, wxCoor self->UpdateClipBox(); } - if ( x ) - *x = m_clipX1; - if ( y ) - *y = m_clipY1; - if ( w ) - *w = m_clipX2 - m_clipX1; - if ( h ) - *h = m_clipY2 - m_clipY1; + return wxGTKDCImpl::DoGetClippingRect(rect); } void wxWindowDCImpl::DoSetClippingRegion( wxCoord x, wxCoord y, wxCoord width, wxCoord height ) diff --git a/src/msw/dc.cpp b/src/msw/dc.cpp index 404c86735b..41ada622d9 100644 --- a/src/msw/dc.cpp +++ b/src/msw/dc.cpp @@ -574,8 +574,7 @@ void wxMSWDCImpl::UpdateClipBox() m_isClipBoxValid = true; } -void -wxMSWDCImpl::DoGetClippingBox(wxCoord *x, wxCoord *y, wxCoord *w, wxCoord *h) const +bool wxMSWDCImpl::DoGetClippingRect(wxRect& rect) const { // check if we should try to retrieve the clipping region possibly not set // by our SetClippingRegion() but preset or modified by Windows: this @@ -589,14 +588,22 @@ wxMSWDCImpl::DoGetClippingBox(wxCoord *x, wxCoord *y, wxCoord *w, wxCoord *h) co self->UpdateClipBox(); } - if ( x ) - *x = m_clipX1; - if ( y ) - *y = m_clipY1; - if ( w ) - *w = m_clipX2 - m_clipX1; - if ( h ) - *h = m_clipY2 - m_clipY1; + // Unfortunately we can't just call wxDCImpl::DoGetClippingRect() here + // because it wouldn't return the correct result if there is no clipping + // region and this DC has a world transform applied to it, as the base + // class version doesn't know anything about world transforms and wouldn't + // apply it to GetLogicalArea() that it returns in this case. + // + // We could solve this by overriding GetLogicalArea() in wxMSW and using + // DPtoLP() to perform the conversion correctly ourselves, but it's even + // simpler to just use the value returned by our UpdateClipBox() which is + // already correct in any case, so just do this instead. + rect = wxRect(m_clipX1, + m_clipY1, + m_clipX2 - m_clipX1, + m_clipY2 - m_clipY1); + + return m_clipping; } // common part of DoSetClippingRegion() and DoSetDeviceClippingRegion() diff --git a/src/msw/dcclient.cpp b/src/msw/dcclient.cpp index 511256f4a5..ae8cbeaec0 100644 --- a/src/msw/dcclient.cpp +++ b/src/msw/dcclient.cpp @@ -302,7 +302,7 @@ wxPaintDCImpl::wxPaintDCImpl( wxDC *owner, wxWindow *window ) : InitDC(); // the HDC can have a clipping box (which we didn't set), make sure our - // DoGetClippingBox() checks for it + // DoGetClippingRect() checks for it m_clipping = true; }