From 651d22e4887c7f22fdd80b225965d982cca699c5 Mon Sep 17 00:00:00 2001 From: Roman Telezhynskyi Date: Tue, 1 Aug 2017 12:57:19 +0300 Subject: [PATCH] Fix regression. Heavy method boundingRect() slows down the Details mode. --HG-- branch : develop --- .../drawTools/toolcurve/vabstractspline.cpp | 26 +---------------- src/libs/vtools/tools/vtoolseamallowance.cpp | 23 ++++++++------- src/libs/vtools/tools/vtoolseamallowance.h | 15 ++++++---- src/libs/vwidgets/global.cpp | 28 +++++++++++++++++++ src/libs/vwidgets/global.h | 4 +++ src/libs/vwidgets/vcurvepathitem.cpp | 26 +---------------- 6 files changed, 56 insertions(+), 66 deletions(-) diff --git a/src/libs/vtools/tools/drawTools/toolcurve/vabstractspline.cpp b/src/libs/vtools/tools/drawTools/toolcurve/vabstractspline.cpp index 9a8dbbc28..bfa347530 100644 --- a/src/libs/vtools/tools/drawTools/toolcurve/vabstractspline.cpp +++ b/src/libs/vtools/tools/drawTools/toolcurve/vabstractspline.cpp @@ -86,31 +86,7 @@ QPainterPath VAbstractSpline::shape() const SceneScale(scene())))); } path.setFillRule(Qt::WindingFill); - - // We unfortunately need this hack as QPainterPathStroker will set a width of 1.0 - // if we pass a value of 0.0 to QPainterPathStroker::setWidth() - const qreal penWidthZero = qreal(0.00000001); - - if (path == QPainterPath() || pen() == Qt::NoPen) - { - return path; - } - - QPainterPathStroker ps; - ps.setCapStyle(pen().capStyle()); - if (pen().widthF() <= 0.0) - { - ps.setWidth(penWidthZero); - } - else - { - ps.setWidth(pen().widthF()); - } - ps.setJoinStyle(pen().joinStyle()); - ps.setMiterLimit(pen().miterLimit()); - QPainterPath p = ps.createStroke(path); - p.addPath(path); - return p; + return ItemShapeFromPath(path, pen()); } //--------------------------------------------------------------------------------------------------------------------- diff --git a/src/libs/vtools/tools/vtoolseamallowance.cpp b/src/libs/vtools/tools/vtoolseamallowance.cpp index da69d5022..abed9fe76 100644 --- a/src/libs/vtools/tools/vtoolseamallowance.cpp +++ b/src/libs/vtools/tools/vtoolseamallowance.cpp @@ -807,18 +807,14 @@ void VToolSeamAllowance::paint(QPainter *painter, const QStyleOptionGraphicsItem //--------------------------------------------------------------------------------------------------------------------- QRectF VToolSeamAllowance::boundingRect() const { - VPiece detail; - - try + if (m_mainPathRect.isNull()) { - detail = VAbstractTool::data.GetPiece(id); + return QGraphicsPathItem::boundingRect(); } - catch(const VExceptionBadId &) + else { - return QRectF(); + return m_mainPathRect; } - - return detail.MainPathPath(this->getData()).boundingRect(); } //--------------------------------------------------------------------------------------------------------------------- @@ -1114,6 +1110,8 @@ VToolSeamAllowance::VToolSeamAllowance(VAbstractPattern *doc, VContainer *data, const QString &drawName, QGraphicsItem *parent) : VInteractiveTool(doc, data, id), QGraphicsPathItem(parent), + m_mainPath(), + m_mainPathRect(), m_sceneDetails(scene), m_drawName(drawName), m_seamAllowance(new VNoBrushScalePathItem(this)), @@ -1191,16 +1189,21 @@ void VToolSeamAllowance::RefreshGeometry() this->setFlag(QGraphicsItem::ItemSendsGeometryChanges, false); const VPiece detail = VAbstractTool::data.GetPiece(id); - QPainterPath path; + QPainterPath path = detail.MainPathPath(this->getData()); if (not detail.IsHideMainPath() || not detail.IsSeamAllowance() || detail.IsSeamAllowanceBuiltIn()) { + m_mainPath = QPainterPath(); + m_mainPathRect = QRectF(); m_seamAllowance->setBrush(QBrush(Qt::Dense7Pattern)); - path = detail.MainPathPath(this->getData()); } else { m_seamAllowance->setBrush(QBrush(Qt::NoBrush)); // Disable if the main path was hidden + // need for returning a bounding rect when main path is not visible + m_mainPath = path; + m_mainPathRect = m_mainPath.controlPointRect(); + path = QPainterPath(); } this->setPath(path); diff --git a/src/libs/vtools/tools/vtoolseamallowance.h b/src/libs/vtools/tools/vtoolseamallowance.h index 995c9d78a..ed1320fc0 100644 --- a/src/libs/vtools/tools/vtoolseamallowance.h +++ b/src/libs/vtools/tools/vtoolseamallowance.h @@ -91,12 +91,12 @@ public: virtual int type() const Q_DECL_OVERRIDE {return Type;} enum { Type = UserType + static_cast(Tool::Piece)}; - virtual QString getTagName() const Q_DECL_OVERRIDE; - virtual void ShowVisualization(bool show) Q_DECL_OVERRIDE; - virtual void GroupVisibility(quint32 object, bool visible) Q_DECL_OVERRIDE; - virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, - QWidget *widget) Q_DECL_OVERRIDE; - virtual QRectF boundingRect() const Q_DECL_OVERRIDE; + virtual QString getTagName() const Q_DECL_OVERRIDE; + virtual void ShowVisualization(bool show) Q_DECL_OVERRIDE; + virtual void GroupVisibility(quint32 object, bool visible) Q_DECL_OVERRIDE; + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, + QWidget *widget) Q_DECL_OVERRIDE; + virtual QRectF boundingRect() const Q_DECL_OVERRIDE; public slots: virtual void FullUpdateFromFile () Q_DECL_OVERRIDE; void EnableToolMove(bool move); @@ -139,6 +139,9 @@ protected: private: Q_DISABLE_COPY(VToolSeamAllowance) + QPainterPath m_mainPath; // Must be first to prevent crash + QRectF m_mainPathRect; + /** @brief sceneDetails pointer to the scene. */ VMainGraphicsScene *m_sceneDetails; QString m_drawName; diff --git a/src/libs/vwidgets/global.cpp b/src/libs/vwidgets/global.cpp index 0620c4e4b..d756ef74c 100644 --- a/src/libs/vwidgets/global.cpp +++ b/src/libs/vwidgets/global.cpp @@ -104,3 +104,31 @@ qreal ScaleWidth(qreal width, qreal scale) } return width; } + +//--------------------------------------------------------------------------------------------------------------------- +QPainterPath ItemShapeFromPath(const QPainterPath &path, const QPen &pen) +{ + // We unfortunately need this hack as QPainterPathStroker will set a width of 1.0 + // if we pass a value of 0.0 to QPainterPathStroker::setWidth() + const qreal penWidthZero = qreal(0.00000001); + + if (path == QPainterPath() || pen == Qt::NoPen) + { + return path; + } + QPainterPathStroker ps; + ps.setCapStyle(pen.capStyle()); + if (pen.widthF() <= 0.0) + { + ps.setWidth(penWidthZero); + } + else + { + ps.setWidth(pen.widthF()); + } + ps.setJoinStyle(pen.joinStyle()); + ps.setMiterLimit(pen.miterLimit()); + QPainterPath p = ps.createStroke(path); + p.addPath(path); + return p; +} diff --git a/src/libs/vwidgets/global.h b/src/libs/vwidgets/global.h index 13e761a07..5593f44b8 100644 --- a/src/libs/vwidgets/global.h +++ b/src/libs/vwidgets/global.h @@ -41,6 +41,8 @@ class QGraphicsEllipseItem; class QGraphicsLineItem; class QColor; class QRectF; +class QPainterPath; +class QPen; qreal SceneScale(QGraphicsScene *scene); @@ -51,4 +53,6 @@ qreal ScaledRadius(qreal scale); void ScaleCircleSize(QGraphicsEllipseItem *item, qreal scale); qreal ScaleWidth(qreal width, qreal scale); +QPainterPath ItemShapeFromPath(const QPainterPath &path, const QPen &pen); + #endif // GLOBAL_H diff --git a/src/libs/vwidgets/vcurvepathitem.cpp b/src/libs/vwidgets/vcurvepathitem.cpp index f007e0466..848a9fe56 100644 --- a/src/libs/vwidgets/vcurvepathitem.cpp +++ b/src/libs/vwidgets/vcurvepathitem.cpp @@ -66,31 +66,7 @@ QPainterPath VCurvePathItem::shape() const itemPath.addPath(arrowsPath); } itemPath.setFillRule(Qt::WindingFill); - - // We unfortunately need this hack as QPainterPathStroker will set a width of 1.0 - // if we pass a value of 0.0 to QPainterPathStroker::setWidth() - const qreal penWidthZero = qreal(0.00000001); - - if (itemPath == QPainterPath() || pen() == Qt::NoPen) - { - return itemPath; - } - - QPainterPathStroker ps; - ps.setCapStyle(pen().capStyle()); - if (pen().widthF() <= 0.0) - { - ps.setWidth(penWidthZero); - } - else - { - ps.setWidth(pen().widthF()); - } - ps.setJoinStyle(pen().joinStyle()); - ps.setMiterLimit(pen().miterLimit()); - QPainterPath p = ps.createStroke(itemPath); - p.addPath(itemPath); - return p; + return ItemShapeFromPath(itemPath, pen()); } //---------------------------------------------------------------------------------------------------------------------