Add bool return value for wxDC::GetClippingBox()
Determining whether there is an actual clipping region or not is not that simple, as shown by the recent problems in wxDCClipper code, so return a boolean value indicating this from GetClippingBox() directly, instead of requiring the caller to find it out on their own. This simplifies wxDCClipper code, as well as any other code calling GetClippingBox(), at the price of some extra complexity in wxDCImpl itself, which seems to be worth it.
This commit is contained in:
@@ -446,21 +446,18 @@ public:
|
||||
// NB: this function works with device coordinates, not the logical ones!
|
||||
virtual void DoSetDeviceClippingRegion(const wxRegion& region) = 0;
|
||||
|
||||
virtual void DoGetClippingBox(wxCoord *x, wxCoord *y,
|
||||
wxCoord *w, wxCoord *h) const
|
||||
{
|
||||
int dcWidth, dcHeight;
|
||||
DoGetSize(&dcWidth, &dcHeight);
|
||||
// Method used to implement wxDC::GetClippingBox().
|
||||
//
|
||||
// Default implementation returns values stored in m_clip[XY][12] member
|
||||
// variables, so this method doesn't need to be overridden if they're kept
|
||||
// up to date.
|
||||
virtual bool DoGetClippingRect(wxRect& rect) const;
|
||||
|
||||
if ( x )
|
||||
*x = m_clipping ? m_clipX1 : DeviceToLogicalX(0);
|
||||
if ( y )
|
||||
*y = m_clipping ? m_clipY1 : DeviceToLogicalY(0);
|
||||
if ( w )
|
||||
*w = m_clipping ? m_clipX2 - m_clipX1 : DeviceToLogicalXRel(dcWidth);
|
||||
if ( h )
|
||||
*h = m_clipping ? m_clipY2 - m_clipY1 : DeviceToLogicalYRel(dcHeight);
|
||||
}
|
||||
// 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;
|
||||
|
||||
virtual void DestroyClippingRegion() { ResetClipping(); }
|
||||
|
||||
@@ -736,6 +733,9 @@ protected:
|
||||
#endif // wxUSE_PALETTE
|
||||
|
||||
private:
|
||||
// Return the full DC area in logical coordinates.
|
||||
wxRect GetLogicalArea() const;
|
||||
|
||||
wxDECLARE_ABSTRACT_CLASS(wxDCImpl);
|
||||
};
|
||||
|
||||
@@ -959,10 +959,22 @@ public:
|
||||
void DestroyClippingRegion()
|
||||
{ m_pimpl->DestroyClippingRegion(); }
|
||||
|
||||
void GetClippingBox(wxCoord *x, wxCoord *y, wxCoord *w, wxCoord *h) const
|
||||
{ m_pimpl->DoGetClippingBox(x, y, w, h); }
|
||||
void GetClippingBox(wxRect& rect) const
|
||||
{ m_pimpl->DoGetClippingBox(&rect.x, &rect.y, &rect.width, &rect.height); }
|
||||
bool GetClippingBox(wxCoord *x, wxCoord *y, wxCoord *w, wxCoord *h) const
|
||||
{
|
||||
wxRect r;
|
||||
const bool clipping = m_pimpl->DoGetClippingRect(r);
|
||||
if ( x )
|
||||
*x = r.x;
|
||||
if ( y )
|
||||
*y = r.y;
|
||||
if ( w )
|
||||
*w = r.width;
|
||||
if ( h )
|
||||
*h = r.height;
|
||||
return clipping;
|
||||
}
|
||||
bool GetClippingBox(wxRect& rect) const
|
||||
{ return m_pimpl->DoGetClippingRect(rect); }
|
||||
|
||||
// coordinates conversions and transforms
|
||||
|
||||
@@ -1451,7 +1463,7 @@ public:
|
||||
~wxDCClipper()
|
||||
{
|
||||
m_dc.DestroyClippingRegion();
|
||||
if ( !m_oldClipRect.IsEmpty() )
|
||||
if ( m_restoreOld )
|
||||
m_dc.SetClippingRegion(m_oldClipRect);
|
||||
}
|
||||
|
||||
@@ -1459,19 +1471,13 @@ private:
|
||||
// Common part of all ctors.
|
||||
void Init(const wxRect& r)
|
||||
{
|
||||
// GetClippingBox() is supposed to return the rectangle corresponding
|
||||
// to the full DC area and some implementations actually do it, while
|
||||
// others return an empty rectangle instead. Check for both possible
|
||||
// results here to avoid restoring the clipping region unnecessarily in
|
||||
// the dtor.
|
||||
m_dc.GetClippingBox(m_oldClipRect);
|
||||
if ( m_oldClipRect == m_dc.GetSize() )
|
||||
m_oldClipRect = wxRect();
|
||||
m_restoreOld = m_dc.GetClippingBox(m_oldClipRect);
|
||||
m_dc.SetClippingRegion(r);
|
||||
}
|
||||
|
||||
wxDC& m_dc;
|
||||
wxRect m_oldClipRect;
|
||||
bool m_restoreOld;
|
||||
|
||||
wxDECLARE_NO_COPY_CLASS(wxDCClipper);
|
||||
};
|
||||
|
Reference in New Issue
Block a user