From a5174c7483560eed60fe000c74a984c561568ac6 Mon Sep 17 00:00:00 2001 From: Jay Nabonne Date: Mon, 21 Jan 2019 13:49:02 +0000 Subject: [PATCH 1/5] Don't use desktop in wxQtMeasuringContext This doesn't work, so create a new QPainter instead. --- src/qt/graphics.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/qt/graphics.cpp b/src/qt/graphics.cpp index 97feabff96..4d2c351071 100644 --- a/src/qt/graphics.cpp +++ b/src/qt/graphics.cpp @@ -654,6 +654,13 @@ public: #endif + wxQtGraphicsContext(wxGraphicsRenderer* renderer, QPainter* painter, bool ownsPainter = true) + : wxGraphicsContext(renderer), + m_qtPainter(painter), + m_ownsPainter(ownsPainter) + { + } + wxQtGraphicsContext(wxGraphicsRenderer* renderer, wxWindow *window) : wxGraphicsContext(renderer) { @@ -1020,12 +1027,9 @@ class wxQtMeasuringContext : public wxQtGraphicsContext { public: wxQtMeasuringContext(wxGraphicsRenderer* renderer) - : wxQtGraphicsContext(renderer, QApplication::desktop()) + : wxQtGraphicsContext(renderer, new QPainter()) { } - -private: - QPainter painter; }; class wxQtImageContext : public wxQtGraphicsContext From b991dc9d5a9c357ffdadafc993d92762b6902a63 Mon Sep 17 00:00:00 2001 From: Jay Nabonne Date: Mon, 21 Jan 2019 13:49:02 +0000 Subject: [PATCH 2/5] Fix using inactive painter when getting text extent Ensure that the painter is active before using it. --- src/qt/graphics.cpp | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/qt/graphics.cpp b/src/qt/graphics.cpp index 4d2c351071..5b2d32122e 100644 --- a/src/qt/graphics.cpp +++ b/src/qt/graphics.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #ifndef WX_PRECOMP #include "wx/bitmap.h" @@ -34,6 +35,38 @@ #include "wx/private/graphics.h" +namespace +{ + +// Ensure that the given painter is active by calling begin() if it isn't. If +// it already is, don't do anything. +class EnsurePainterIsActive +{ +public: + explicit EnsurePainterIsActive(QPainter* painter) + : m_painter(painter), + m_wasActive(painter->isActive()) + { + if ( !m_wasActive ) + m_painter->begin(&m_picture); + } + + ~EnsurePainterIsActive() + { + if ( !m_wasActive ) + m_painter->end(); + } + +private: + QPainter* m_painter; + QPicture m_picture; + bool m_wasActive; + + wxDECLARE_NO_COPY_CLASS(EnsurePainterIsActive); +}; + +} // anonymous namespace + class WXDLLIMPEXP_CORE wxQtBrushData : public wxGraphicsObjectRefData { public: @@ -935,6 +968,8 @@ public: wxCHECK_RET( !m_font.IsNull(), "wxQtContext::GetTextExtent - no valid font set" ); + EnsurePainterIsActive active(m_qtPainter); + const wxQtFontData* fontData = static_cast(m_font.GetRefData()); m_qtPainter->setFont(fontData->GetFont()); @@ -959,6 +994,8 @@ public: wxCHECK_RET( !m_font.IsNull(), "wxQtContext::GetPartialTextExtents - no valid font set" ); + EnsurePainterIsActive active(m_qtPainter); + const wxQtFontData* fontData = static_cast(m_font.GetRefData()); m_qtPainter->setFont(fontData->GetFont()); From 6d91374dffe0a9fda941231cefbd77e297aa6c97 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 21 Jan 2019 19:37:24 +0100 Subject: [PATCH 3/5] Simplify QPainter ownership in wxQtGraphicsContext No real changes, just refactor the code to use more explicit AttachPainter() when giving ownership of a new QPainter object to wxQtGraphicsContext. This method also allows to simplify wxQtImageContext as it doesn't need to handle ownership on its own and can just leave it to the base class. And m_ownsPainter can now be made private. --- src/qt/graphics.cpp | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/qt/graphics.cpp b/src/qt/graphics.cpp index 5b2d32122e..7e0aaccac0 100644 --- a/src/qt/graphics.cpp +++ b/src/qt/graphics.cpp @@ -648,6 +648,14 @@ class WXDLLIMPEXP_CORE wxQtGraphicsContext : public wxGraphicsContext } protected: + // Use the specified painter and take ownership of it, i.e. it will be + // destroyed in this class dtor. + void AttachPainter(QPainter* painter) + { + m_qtPainter = painter; + m_ownsPainter = true; + } + wxQtGraphicsContext(wxGraphicsRenderer* renderer) : wxGraphicsContext(renderer), m_qtPainter(NULL), @@ -687,13 +695,6 @@ public: #endif - wxQtGraphicsContext(wxGraphicsRenderer* renderer, QPainter* painter, bool ownsPainter = true) - : wxGraphicsContext(renderer), - m_qtPainter(painter), - m_ownsPainter(ownsPainter) - { - } - wxQtGraphicsContext(wxGraphicsRenderer* renderer, wxWindow *window) : wxGraphicsContext(renderer) { @@ -1054,9 +1055,10 @@ protected: } QPainter* m_qtPainter; - bool m_ownsPainter; private: + bool m_ownsPainter; + wxDECLARE_NO_COPY_CLASS(wxQtGraphicsContext); }; @@ -1064,8 +1066,9 @@ class wxQtMeasuringContext : public wxQtGraphicsContext { public: wxQtMeasuringContext(wxGraphicsRenderer* renderer) - : wxQtGraphicsContext(renderer, new QPainter()) + : wxQtGraphicsContext(renderer) { + AttachPainter(new QPainter()); } }; @@ -1078,15 +1081,13 @@ public: { const wxBitmap wxbitmap(image); m_pixmap = *wxbitmap.GetHandle(); - m_qtPainter = new QPainter(&m_pixmap); - m_ownsPainter = false; + AttachPainter(new QPainter(&m_pixmap)); } ~wxQtImageContext() { wxQtBitmapData bitmap(GetRenderer(), &m_pixmap); m_image = bitmap.DoConvertToImage(); - delete m_qtPainter; } private: From 8434adb00ec1ef9fd8594842194536b10ec9f307 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 21 Jan 2019 19:40:22 +0100 Subject: [PATCH 4/5] Use AttachPainter() instead of setting m_ownsPainter directly No real changes, just another tiny simplification. --- src/qt/graphics.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/qt/graphics.cpp b/src/qt/graphics.cpp index 7e0aaccac0..f4df9b0af7 100644 --- a/src/qt/graphics.cpp +++ b/src/qt/graphics.cpp @@ -667,8 +667,7 @@ public: wxQtGraphicsContext(wxGraphicsRenderer* renderer, QPaintDevice* device) : wxGraphicsContext(renderer) { - m_qtPainter = new QPainter(device); - m_ownsPainter = true; + AttachPainter(new QPainter(device)); m_width = device->width(); m_height = device->height(); From 21e989751fd6e3e5c8ff5b61a76d6e87c059f76f Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 21 Jan 2019 19:42:56 +0100 Subject: [PATCH 5/5] Get rid of m_ownsPainter flag in wxQtGraphicsContext Use wxScopedPtr to ensure that the pointer is destroyed automatically instead of doing it manually. --- src/qt/graphics.cpp | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/src/qt/graphics.cpp b/src/qt/graphics.cpp index f4df9b0af7..be97b85cfe 100644 --- a/src/qt/graphics.cpp +++ b/src/qt/graphics.cpp @@ -31,6 +31,7 @@ #endif #include "wx/graphics.h" +#include "wx/scopedptr.h" #include "wx/tokenzr.h" #include "wx/private/graphics.h" @@ -640,7 +641,6 @@ class WXDLLIMPEXP_CORE wxQtGraphicsContext : public wxGraphicsContext void InitFromDC(const wxDC& dc) { m_qtPainter = static_cast(dc.GetHandle()); - m_ownsPainter = false; const wxSize sz = dc.GetSize(); m_width = sz.x; @@ -653,13 +653,14 @@ protected: void AttachPainter(QPainter* painter) { m_qtPainter = painter; - m_ownsPainter = true; + + // Ensure that it will be destroyed when this object is. + m_ownedPainter.reset(m_qtPainter); } wxQtGraphicsContext(wxGraphicsRenderer* renderer) : wxGraphicsContext(renderer), - m_qtPainter(NULL), - m_ownsPainter(false) + m_qtPainter(NULL) { } @@ -698,19 +699,12 @@ public: : wxGraphicsContext(renderer) { m_qtPainter = static_cast(window->QtGetPainter()); - m_ownsPainter = false; const wxSize sz = window->GetClientSize(); m_width = sz.x; m_height = sz.y; } - virtual ~wxQtGraphicsContext() - { - if ( m_ownsPainter ) - delete m_qtPainter; - } - virtual bool ShouldOffset() const wxOVERRIDE { return false; @@ -1056,7 +1050,8 @@ protected: QPainter* m_qtPainter; private: - bool m_ownsPainter; + // This pointer may be empty if we don't own m_qtPainter. + wxScopedPtr m_ownedPainter; wxDECLARE_NO_COPY_CLASS(wxQtGraphicsContext); };