diff --git a/include/wx/dc.h b/include/wx/dc.h index 85c55342f9..8a3e796114 100644 --- a/include/wx/dc.h +++ b/include/wx/dc.h @@ -742,8 +742,7 @@ protected: // bounding and clipping boxes wxCoord m_minX, m_minY, m_maxX, m_maxY; // Bounding box is stored in device units. - wxCoord m_clipX1, m_clipY1, m_clipX2, m_clipY2; // Clipping box is stored in device units. - // Derived classes may store it in logical units. + wxCoord m_clipX1, m_clipY1, m_clipX2, m_clipY2; // Some derived classes operate directly on clipping box given in logical units. wxRasterOperationMode m_logicalFunction; int m_backgroundMode; @@ -765,6 +764,9 @@ private: // Return the full DC area in logical coordinates. wxRect GetLogicalArea() const; + wxCoord m_devClipX1, m_devClipY1, m_devClipX2, m_devClipY2; // For proper calculations of clipping box we need to store it in device units. + bool m_useDevClipCoords; + wxDECLARE_ABSTRACT_CLASS(wxDCImpl); }; diff --git a/src/common/dcbase.cpp b/src/common/dcbase.cpp index 0784915fbc..c669a028b9 100644 --- a/src/common/dcbase.cpp +++ b/src/common/dcbase.cpp @@ -345,6 +345,8 @@ wxDCImpl::wxDCImpl( wxDC *owner ) , m_palette() , m_hasCustomPalette(false) #endif // wxUSE_PALETTE + , m_devClipX1(0), m_devClipY1(0), m_devClipX2(0), m_devClipY2(0) + , m_useDevClipCoords(false) { m_owner = owner; } @@ -362,13 +364,16 @@ void wxDCImpl::DoSetClippingRegion(wxCoord x, wxCoord y, wxCoord w, wxCoord h) wxASSERT_MSG( w >= 0 && h >= 0, wxS("Clipping box size values cannot be negative") ); + // If we set clipping box with this method we can operate on device coordinates + // and calculate clipping box properly also when transfromations were applied to DC. + m_useDevClipCoords = true; wxRect clipRegion(LogicalToDevice(x, y), LogicalToDeviceRel(w, h)); if ( m_clipping ) { // New clipping box is an intersection // of required clipping box and the current one. - wxRect curRegion(m_clipX1, m_clipY1, m_clipX2 - m_clipX1, m_clipY2 - m_clipY1); + wxRect curRegion(m_devClipX1, m_devClipY1, m_devClipX2 - m_devClipX1, m_devClipY2 - m_devClipY1); clipRegion.Intersect(curRegion); } else @@ -385,14 +390,14 @@ void wxDCImpl::DoSetClippingRegion(wxCoord x, wxCoord y, wxCoord w, wxCoord h) if ( clipRegion.IsEmpty() ) { - m_clipX1 = m_clipY1 = m_clipX2 = m_clipY2 = 0; + m_devClipX1 = m_devClipY1 = m_devClipX2 = m_devClipY2 = 0; } else { - m_clipX1 = clipRegion.GetLeft(); - m_clipY1 = clipRegion.GetTop(); - m_clipX2 = clipRegion.GetRight() + 1; - m_clipY2 = clipRegion.GetBottom() + 1; + m_devClipX1 = clipRegion.GetLeft(); + m_devClipY1 = clipRegion.GetTop(); + m_devClipX2 = clipRegion.GetRight() + 1; + m_devClipY2 = clipRegion.GetBottom() + 1; } } @@ -420,11 +425,18 @@ bool wxDCImpl::DoGetClippingRect(wxRect& rect) const if ( m_clipping ) { - if ( m_clipX1 == m_clipX2 || m_clipY1 == m_clipY2 ) - rect = wxRect(); // empty clip region + if ( m_useDevClipCoords ) + { + if ( m_devClipX1 == m_devClipX2 || m_devClipY1 == m_devClipY2 ) + rect = wxRect(); // empty clip region + else + rect = wxRect(DeviceToLogical(m_devClipX1, m_devClipY1), DeviceToLogicalRel(m_devClipX2 - m_devClipX1, m_devClipY2 - m_devClipY1)); + } else - rect = wxRect(DeviceToLogical(m_clipX1, m_clipY1), DeviceToLogicalRel(m_clipX2 - m_clipX1, m_clipY2 - m_clipY1)); - + { + // When derived class set coordinates in logical units directly... + rect = wxRect(m_clipX1, m_clipY1, m_clipX2 - m_clipX1, m_clipY2 - m_clipY1); + } return true; } else // No active clipping region.