From 4feb4019cfc144cef4cd9177d52e52dee9ebdf32 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Samuel=20R=C3=B8dal?= <sroedal@trolltech.com>
Date: Tue, 18 Aug 2009 17:00:34 +0200
Subject: Fixed bug in drawImage() when fall-back code path is used.

We need to floor instead of round to prevent rectangles that are on the
edge from being shifted one pixel down / right.

Task-number: 258776
Reviewed-by: Kim
---
 src/gui/painting/qrasterizer.cpp     | 14 +++++++-------
 tests/auto/qpainter/tst_qpainter.cpp | 26 ++++++++++++++++++++++++++
 2 files changed, 33 insertions(+), 7 deletions(-)

diff --git a/src/gui/painting/qrasterizer.cpp b/src/gui/painting/qrasterizer.cpp
index fe90221..d514e71 100644
--- a/src/gui/painting/qrasterizer.cpp
+++ b/src/gui/painting/qrasterizer.cpp
@@ -691,14 +691,14 @@ static inline bool q16Dot16Compare(qreal p1, qreal p2)
     return FloatToQ16Dot16(p2 - p1) == 0;
 }
 
-static inline qreal qRoundF(qreal v)
+static inline qreal qFloorF(qreal v)
 {
 #ifdef QT_USE_MATH_H_FLOATS
     if (sizeof(qreal) == sizeof(float))
-        return floorf(v + 0.5);
+        return floorf(v);
     else
 #endif
-        return floor(v + 0.5);
+        return floor(v);
 }
 
 void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, bool squareCap)
@@ -758,10 +758,10 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width,
         const qreal reciprocal = 1 / gridResolution;
 
         // snap to grid to prevent large slopes
-        pa.rx() = qRoundF(pa.rx() * gridResolution) * reciprocal;
-        pa.ry() = qRoundF(pa.ry() * gridResolution) * reciprocal;
-        pb.rx() = qRoundF(pb.rx() * gridResolution) * reciprocal;
-        pb.ry() = qRoundF(pb.ry() * gridResolution) * reciprocal;
+        pa.rx() = qFloorF(pa.rx() * gridResolution) * reciprocal;
+        pa.ry() = qFloorF(pa.ry() * gridResolution) * reciprocal;
+        pb.rx() = qFloorF(pb.rx() * gridResolution) * reciprocal;
+        pb.ry() = qFloorF(pb.ry() * gridResolution) * reciprocal;
 
         // old delta
         const QPointF d0 = a - b;
diff --git a/tests/auto/qpainter/tst_qpainter.cpp b/tests/auto/qpainter/tst_qpainter.cpp
index a105bc5..e77d133 100644
--- a/tests/auto/qpainter/tst_qpainter.cpp
+++ b/tests/auto/qpainter/tst_qpainter.cpp
@@ -202,6 +202,7 @@ private slots:
 
     void drawImage_task217400_data();
     void drawImage_task217400();
+    void drawImage_task258776();
     void drawRect_task215378();
     void drawRect_task247505();
 
@@ -3507,6 +3508,31 @@ void tst_QPainter::drawImage_task217400()
     }
 }
 
+void tst_QPainter::drawImage_task258776()
+{
+    QImage src(16, 16, QImage::Format_RGB888);
+    QImage dest(33, 33, QImage::Format_RGB888);
+    src.fill(0x00ff00);
+    dest.fill(0x0000ff);
+
+    QPainter painter(&dest);
+    painter.drawImage(QRectF(0.499, 0.499, 32, 32), src, QRectF(0, 0, 16, 16));
+    painter.end();
+
+    QImage expected(33, 33, QImage::Format_RGB32);
+    expected.fill(0xff0000);
+
+    painter.begin(&expected);
+    painter.drawImage(QRectF(0, 0, 32, 32), src);
+    painter.end();
+
+    dest = dest.convertToFormat(QImage::Format_RGB32);
+
+    dest.save("dest.png");
+    expected.save("expected.png");
+    QCOMPARE(dest, expected);
+}
+
 void tst_QPainter::clipRectSaveRestore()
 {
     QImage img(64, 64, QImage::Format_ARGB32_Premultiplied);
-- 
cgit v0.12