diff options
author | Joni Poikelin <joni.poikelin@qt.io> | 2019-01-03 11:52:15 +0200 |
---|---|---|
committer | Joni Poikelin <joni.poikelin@qt.io> | 2019-02-13 05:12:05 +0000 |
commit | 64fab8f7e2d225e37aa731db7501b5d5b82eab64 (patch) | |
tree | 0f2df9953b79d60c202fb6bead0efa12cbb43129 | |
parent | 960af0d64de576321db91ccbe426891465b24540 (diff) |
Add faster path for scaling QRegion with multiple regions
Fixes: QTBUG-72821
Change-Id: Ic4fa349087239337a77b0e280be551b46c75af71
Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
-rw-r--r-- | src/gui/painting/qtransform.cpp | 19 | ||||
-rw-r--r-- | tests/auto/gui/painting/qregion/tst_qregion.cpp | 55 |
2 files changed, 72 insertions, 2 deletions
diff --git a/src/gui/painting/qtransform.cpp b/src/gui/painting/qtransform.cpp index 5f9e037ff0..816514a695 100644 --- a/src/gui/painting/qtransform.cpp +++ b/src/gui/painting/qtransform.cpp @@ -1517,8 +1517,23 @@ QRegion QTransform::map(const QRegion &r) const return copy; } - if (t == TxScale && r.rectCount() == 1) - return QRegion(mapRect(r.boundingRect())); + if (t == TxScale) { + QRegion res; + if (m11() < 0 || m22() < 0) { + for (const QRect &rect : r) + res += mapRect(rect); + } else { + QVarLengthArray<QRect, 32> rects; + rects.reserve(r.rectCount()); + for (const QRect &rect : r) { + QRect nr = mapRect(rect); + if (!nr.isEmpty()) + rects.append(nr); + } + res.setRects(rects.constData(), rects.count()); + } + return res; + } QPainterPath p = map(qt_regionToPath(r)); return p.toFillPolygon(QTransform()).toPolygon(); diff --git a/tests/auto/gui/painting/qregion/tst_qregion.cpp b/tests/auto/gui/painting/qregion/tst_qregion.cpp index 5256fbd1dc..24c4583819 100644 --- a/tests/auto/gui/painting/qregion/tst_qregion.cpp +++ b/tests/auto/gui/painting/qregion/tst_qregion.cpp @@ -84,6 +84,8 @@ private slots: #endif void regionFromPath(); + void scaleRegions_data(); + void scaleRegions(); #ifdef QT_BUILD_INTERNAL void regionToPath_data(); @@ -973,6 +975,59 @@ void tst_QRegion::regionFromPath() } } +void tst_QRegion::scaleRegions_data() +{ + QTest::addColumn<qreal>("scale"); + QTest::addColumn<QVector<QRect>>("inputRects"); + QTest::addColumn<QVector<QRect>>("expectedRects"); + + QTest::newRow("1.0 single") << 1.0 + << QVector<QRect>{ QRect(10, 10, 20, 20) } + << QVector<QRect>{ QRect(10, 10, 20, 20) }; + QTest::newRow("1.0 multi") << 1.0 + << QVector<QRect>{ QRect(10, 10, 20, 20), QRect(40, 10, 20, 20) } + << QVector<QRect>{ QRect(10, 10, 20, 20), QRect(40, 10, 20, 20) }; + QTest::newRow("2.0 single") << 2.0 + << QVector<QRect>{ QRect(10, 10, 20, 20) } + << QVector<QRect>{ QRect(20, 20, 40, 40) }; + QTest::newRow("2.0 multi") << 2.0 + << QVector<QRect>{ QRect(10, 10, 20, 20), QRect(40, 10, 20, 20) } + << QVector<QRect>{ QRect(20, 20, 40, 40), QRect(80, 20, 40, 40) }; + QTest::newRow("-1.0 single") << -1.0 + << QVector<QRect>{ QRect(10, 10, 20, 20) } + << QVector<QRect>{ QRect(-30, -30, 20, 20) }; + QTest::newRow("-1.0 multi") << -1.0 + << QVector<QRect>{ QRect(10, 10, 20, 20), QRect(40, 10, 20, 20) } + << QVector<QRect>{ QRect(-60, -30, 20, 20), QRect(-30, -30, 20, 20) }; + QTest::newRow("-2.0 single") << -2.0 + << QVector<QRect>{ QRect(10, 10, 20, 20) } + << QVector<QRect>{ QRect(-60, -60, 40, 40) }; + QTest::newRow("-2.0 multi") << -2.0 + << QVector<QRect>{ QRect(10, 10, 20, 20), QRect(40, 10, 20, 20) } + << QVector<QRect>{ QRect(-120, -60, 40, 40), QRect(-60, -60, 40, 40) }; +} + +void tst_QRegion::scaleRegions() +{ + QFETCH(qreal, scale); + QFETCH(QVector<QRect>, inputRects); + QFETCH(QVector<QRect>, expectedRects); + + QRegion region; + region.setRects(inputRects.constData(), inputRects.size()); + + QRegion expected(expectedRects.first()); + expected.setRects(expectedRects.constData(), expectedRects.size()); + + QTransform t; + t.scale(scale, scale); + + auto result = t.map(region); + + QCOMPARE(result.rectCount(), expectedRects.size()); + QCOMPARE(result, expected); +} + Q_DECLARE_METATYPE(QPainterPath) #ifdef QT_BUILD_INTERNAL |