From 902b9a5c5654e6ba10eac970ca1128ad9eee0f64 Mon Sep 17 00:00:00 2001 From: Artur Wieczorek Date: Sun, 17 Jul 2016 00:09:33 +0200 Subject: [PATCH] Fix calculating the extent of clipping box (wxDC, GTK). While setting a clipping region there is necessary to intersect it either with current clipping region location if such region exists or with wxDC surface extents if no clipping region is set. This way effective clipping box will be always inside the wxDC surface. Effective clipping box can be an empty region. Clipping box parameters are calculated and stored in logical coordinates. --- docs/changes.txt | 3 ++- src/gtk/dc.cpp | 42 +++++++++++++++++++++++++++++++++++++----- src/gtk/dcclient.cpp | 3 ++- 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index 1b8ee90d70..dc1d948b26 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -74,7 +74,6 @@ All: - Add support for loading dynamic lexer in wxStyledTextCtrl (New Pagodi). - Handle strings with embedded NULs in wxDataStream (Nitch). - Don't crash in wxTextFile::GetLastLine() if the file is empty (crohr). -- Many fixes and improvements in Direct2D, Cairo, and GDI+ graphics renderers. All (GUI): @@ -92,6 +91,8 @@ All (GUI): - Implement auto complete in generic wxSearchCtrl (Eric Jensen). - Fix preserving selection when changing selection mode in wxGrid (jonkraber). - Fix wxTextEntry::SetHint() with wxTE_PASSWORD in generic implementation. +- Many fixes and improvements in Direct2D, Cairo, and GDI+ graphics renderers. +- Fix and unify clipping region support for MSW and GTK+. wxGTK: diff --git a/src/gtk/dc.cpp b/src/gtk/dc.cpp index e87585b6d5..bef12a5081 100644 --- a/src/gtk/dc.cpp +++ b/src/gtk/dc.cpp @@ -398,11 +398,43 @@ wxGTKDCImpl::~wxGTKDCImpl() void wxGTKDCImpl::DoSetClippingRegion( wxCoord x, wxCoord y, wxCoord width, wxCoord height ) { - m_clipping = TRUE; - m_clipX1 = x; - m_clipY1 = y; - m_clipX2 = x + width; - m_clipY2 = y + height; + wxASSERT_MSG( width >= 0 && height >= 0, + "Clipping box size values cannot be negative" ); + + wxRect newRegion(x, y, width, height); + + wxRect clipRegion; + 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); + clipRegion = curRegion.Intersect(newRegion); + } + else + { + // Effective clipping box is an intersection + // of required clipping box and DC surface. + int dcWidth, dcHeight; + DoGetSize(&dcWidth, &dcHeight); + wxRect dcRect(DeviceToLogicalX(0), DeviceToLogicalY(0), + DeviceToLogicalXRel(dcWidth), DeviceToLogicalYRel(dcHeight)); + clipRegion = dcRect.Intersect(newRegion); + + m_clipping = true; + } + + if ( clipRegion.IsEmpty() ) + { + m_clipX1 = m_clipY1 = m_clipX2 = m_clipY2 = 0; + } + else + { + m_clipX1 = clipRegion.GetLeftTop().x; + m_clipY1 = clipRegion.GetLeftTop().y; + m_clipX2 = clipRegion.GetBottomRight().x + 1; + m_clipY2 = clipRegion.GetBottomRight().y + 1; + } } // --------------------------------------------------------------------------- diff --git a/src/gtk/dcclient.cpp b/src/gtk/dcclient.cpp index f0cd8151ce..05ccdea82b 100644 --- a/src/gtk/dcclient.cpp +++ b/src/gtk/dcclient.cpp @@ -1918,7 +1918,8 @@ void wxWindowDCImpl::DoSetDeviceClippingRegion( const wxRegion ®ion ) wxCoord xx, yy, ww, hh; m_currentClippingRegion.GetBox( xx, yy, ww, hh ); - wxGTKDCImpl::DoSetClippingRegion( xx, yy, ww, hh ); + wxGTKDCImpl::DoSetClippingRegion(DeviceToLogicalX(xx), DeviceToLogicalY(yy), + DeviceToLogicalXRel(ww), DeviceToLogicalYRel(hh)); GdkRegion* gdkRegion = m_currentClippingRegion.GetRegion(); gdk_gc_set_clip_region(m_penGC, gdkRegion);