From 88e56d0932a3615231adf40d5ae033e742d72c33 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Wed, 21 Jun 2017 10:05:07 +0200 Subject: [PATCH] Improve rounding of QRect::toRect Avoid the dimensions of the rounded QRect being off by more than one pixel. This ensures the aligned containing rect also contains the rounded rect. Task-number: QTBUG-56420 Change-Id: Ib79110e51ab80de2dc83d01ea83fc5fbf3852e75 Reviewed-by: Thiago Macieira --- src/corelib/tools/qrect.h | 2 +- tests/auto/corelib/tools/qrect/tst_qrect.cpp | 32 ++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/corelib/tools/qrect.h b/src/corelib/tools/qrect.h index 19ff87b420..3b40055b5a 100644 --- a/src/corelib/tools/qrect.h +++ b/src/corelib/tools/qrect.h @@ -870,7 +870,7 @@ Q_DECL_CONSTEXPR inline bool operator!=(const QRectF &r1, const QRectF &r2) Q_DE Q_DECL_CONSTEXPR inline QRect QRectF::toRect() const Q_DECL_NOTHROW { - return QRect(qRound(xp), qRound(yp), qRound(w), qRound(h)); + return QRect(QPoint(qRound(xp), qRound(yp)), QPoint(qRound(xp + w) - 1, qRound(yp + h) - 1)); } Q_DECL_CONSTEXPR inline QRectF operator+(const QRectF &lhs, const QMarginsF &rhs) Q_DECL_NOTHROW diff --git a/tests/auto/corelib/tools/qrect/tst_qrect.cpp b/tests/auto/corelib/tools/qrect/tst_qrect.cpp index d3c6412b0d..1c2221ec29 100644 --- a/tests/auto/corelib/tools/qrect/tst_qrect.cpp +++ b/tests/auto/corelib/tools/qrect/tst_qrect.cpp @@ -171,6 +171,7 @@ private slots: void containsPointF_data(); void containsPointF(); void smallRects() const; + void toRect(); }; // Used to work around some floating point precision problems. @@ -4331,5 +4332,36 @@ void tst_QRect::smallRects() const QVERIFY(r1 != r2); } +void tst_QRect::toRect() +{ + for (qreal x = 1.0; x < 2.0; x += 0.25) { + for (qreal y = 1.0; y < 2.0; y += 0.25) { + for (qreal w = 1.0; w < 2.0; w += 0.25) { + for (qreal h = 1.0; h < 2.0; h += 0.25) { + const QRectF rectf(x, y, w, h); + const QRectF rect = rectf.toRect(); + QVERIFY(qAbs(rect.x() - rectf.x()) < 1.0); + QVERIFY(qAbs(rect.y() - rectf.y()) < 1.0); + QVERIFY(qAbs(rect.width() - rectf.width()) < 1.0); + QVERIFY(qAbs(rect.height() - rectf.height()) < 1.0); + QVERIFY(qAbs(rect.right() - rectf.right()) < 1.0); + QVERIFY(qAbs(rect.bottom() - rectf.bottom()) < 1.0); + + const QRectF arect = rectf.toAlignedRect(); + QVERIFY(qAbs(arect.x() - rectf.x()) < 1.0); + QVERIFY(qAbs(arect.y() - rectf.y()) < 1.0); + QVERIFY(qAbs(arect.width() - rectf.width()) < 2.0); + QVERIFY(qAbs(arect.height() - rectf.height()) < 2.0); + QVERIFY(qAbs(arect.right() - rectf.right()) < 1.0); + QVERIFY(qAbs(arect.bottom() - rectf.bottom()) < 1.0); + + QVERIFY(arect.contains(rectf)); + QVERIFY(arect.contains(rect)); + } + } + } + } +} + QTEST_MAIN(tst_QRect) #include "tst_qrect.moc"