From 2a8c290e0de5e657f22a0c13817df65688b01345 Mon Sep 17 00:00:00 2001 From: jonkraber Date: Sun, 24 Dec 2017 15:37:10 +0100 Subject: [PATCH 1/3] Restore previous clipping box in wxDCClipper Remember the clipping box of the previously active clipping region in wxDCClipper ctor and restore it in its dtor. See #13834. --- include/wx/dc.h | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/include/wx/dc.h b/include/wx/dc.h index 7cfe17fb14..dadbe793a3 100644 --- a/include/wx/dc.h +++ b/include/wx/dc.h @@ -1436,16 +1436,30 @@ class WXDLLIMPEXP_CORE wxDCClipper { public: wxDCClipper(wxDC& dc, const wxRegion& r) : m_dc(dc) - { dc.SetClippingRegion(r.GetBox()); } + { + dc.GetClippingBox(m_oldClipRect); + dc.SetClippingRegion(r.GetBox()); + } wxDCClipper(wxDC& dc, const wxRect& r) : m_dc(dc) - { dc.SetClippingRegion(r.x, r.y, r.width, r.height); } + { + dc.GetClippingBox(m_oldClipRect); + dc.SetClippingRegion(r.x, r.y, r.width, r.height); + } wxDCClipper(wxDC& dc, wxCoord x, wxCoord y, wxCoord w, wxCoord h) : m_dc(dc) - { dc.SetClippingRegion(x, y, w, h); } + { + dc.GetClippingBox(m_oldClipRect); + dc.SetClippingRegion(x, y, w, h); + } - ~wxDCClipper() { m_dc.DestroyClippingRegion(); } + ~wxDCClipper() + { + m_dc.DestroyClippingRegion(); + m_dc.SetClippingRegion(m_oldClipRect); + } private: wxDC& m_dc; + wxRect m_oldClipRect; wxDECLARE_NO_COPY_CLASS(wxDCClipper); }; From ba719c576ec72d42186309131d30c111309a2ce9 Mon Sep 17 00:00:00 2001 From: John Roberts Date: Sun, 24 Dec 2017 15:39:40 +0100 Subject: [PATCH 2/3] Document the new wxDCClipper behaviour after last commit change wxDCClipper does restore the (bounding box of the) previously active clipping region now. See #13834. --- interface/wx/dc.h | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/interface/wx/dc.h b/interface/wx/dc.h index 67ce583325..79490c9c9a 100644 --- a/interface/wx/dc.h +++ b/interface/wx/dc.h @@ -1669,11 +1669,10 @@ public: } @endcode - @note Unlike other similar classes such as wxDCFontChanger, wxDCClipper - currently doesn't restore the previously active clipping region when it - is destroyed but simply resets clipping on the associated wxDC. This - may be changed in the future wxWidgets versions but has to be taken - into account explicitly in the current one. + @note Since 3.1.1 wxDCClipper restores the previously active clipping + region when it is destroyed. Previously it reset clipping on the + associated wxDC and this has to be taken into account explicitly in + previous wxWidgets versions. @library{wxcore} @category{gdi} From 7f52ff751f377ab616550fdf9dbbfeff2f808332 Mon Sep 17 00:00:00 2001 From: jonkraber Date: Sun, 24 Dec 2017 15:43:20 +0100 Subject: [PATCH 3/3] Fix clipping of cell contents in wxGrid Use wxDCClipper, now that it doesn't lose the previously set clipping region any more, in wxGridCellStringRenderer::Draw() to ensure that we don't overflow the area allocated for the cell. Closes #17872. --- src/generic/grid.cpp | 5 ++++- src/generic/gridctrl.cpp | 4 +--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/generic/grid.cpp b/src/generic/grid.cpp index 64b2113ebf..37041f5d1d 100644 --- a/src/generic/grid.cpp +++ b/src/generic/grid.cpp @@ -1871,7 +1871,10 @@ void wxGrid::Render( wxDC& dc, dc.DrawRectangle( pointOffSet, sizeCells ); // draw cells - DrawGridCellArea( dc, renderCells ); + { + wxDCClipper clipper( dc, wxRect(pointOffSet, sizeCells) ); + DrawGridCellArea( dc, renderCells ); + } // draw grid lines if ( style & wxGRID_DRAW_CELL_LINES ) diff --git a/src/generic/gridctrl.cpp b/src/generic/gridctrl.cpp index 36ff071777..ecd8ac5d13 100644 --- a/src/generic/gridctrl.cpp +++ b/src/generic/gridctrl.cpp @@ -630,8 +630,7 @@ void wxGridCellStringRenderer::Draw(wxGrid& grid, for (int i = col + cell_cols; i <= col_end; i++) { clip.width = grid.GetColSize(i) - 1; - dc.DestroyClippingRegion(); - dc.SetClippingRegion(clip); + wxDCClipper clipper(dc, clip); SetTextColoursAndFont(grid, attr, dc, grid.IsInSelection(row,i)); @@ -644,7 +643,6 @@ void wxGridCellStringRenderer::Draw(wxGrid& grid, rect = rectCell; rect.Inflate(-1); rect.width++; - dc.DestroyClippingRegion(); } }