summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEirik Aavitsland <eirik.aavitsland@qt.io>2024-02-20 08:07:38 +0100
committerEirik Aavitsland <eirik.aavitsland@qt.io>2024-02-20 16:27:20 +0100
commita43d86fe1c0bc9d352f67c134a9ee5f754aea5e6 (patch)
treea66ebd2dde0bc7bd7f15d65aab9f2a017e65d58d
parent9362e4f3fa7c42b9d76fd5b4dd504e749b3bcaab (diff)
QPainter: fix assert when drawing bitmaps at very near to .5 coord
The code assumed that the rounding of a floating point value, and the rounding of the sum of that value and an integer, would always snap in the same direction. But because of accuracy limits (independently of the rounding function employed), that is not always the case for fractions very near to .5. Fixes: QTBUG-122451 Pick-to: 6.7 6.6 6.5 6.2 5.15 Change-Id: I0825d42e6be7f6e3397760a5e9be5dddca42dcdc Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp14
-rw-r--r--tests/auto/gui/painting/qpainter/tst_qpainter.cpp11
2 files changed, 19 insertions, 6 deletions
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index 0ff52a8730..582ad500f8 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -3397,16 +3397,18 @@ void QRasterPaintEngine::drawBitmap(const QPointF &pos, const QImage &image, QSp
// Boundaries
int w = image.width();
int h = image.height();
- int ymax = qMin(qRound(pos.y() + h), d->rasterBuffer->height());
- int ymin = qMax(qRound(pos.y()), 0);
- int xmax = qMin(qRound(pos.x() + w), d->rasterBuffer->width());
- int xmin = qMax(qRound(pos.x()), 0);
+ int px = qRound(pos.x());
+ int py = qRound(pos.y());
+ int ymax = qMin(py + h, d->rasterBuffer->height());
+ int ymin = qMax(py, 0);
+ int xmax = qMin(px + w, d->rasterBuffer->width());
+ int xmin = qMax(px, 0);
- int x_offset = xmin - qRound(pos.x());
+ int x_offset = xmin - px;
QImage::Format format = image.format();
for (int y = ymin; y < ymax; ++y) {
- const uchar *src = image.scanLine(y - qRound(pos.y()));
+ const uchar *src = image.scanLine(y - py);
if (format == QImage::Format_MonoLSB) {
for (int x = 0; x < xmax - xmin; ++x) {
int src_x = x + x_offset;
diff --git a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp
index 7c361fd994..15735aecf7 100644
--- a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp
+++ b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp
@@ -61,6 +61,7 @@ private slots:
#endif
void drawPixmapFragments();
void drawPixmapNegativeScale();
+ void drawPixmapRounding();
void drawLine_data();
void drawLine();
@@ -747,6 +748,16 @@ void tst_QPainter::drawPixmapNegativeScale()
QVERIFY(resultImage.pixel(12, 8) == qRgba(0, 0, 0, 255)); // and right strip is now black
}
+void tst_QPainter::drawPixmapRounding()
+{
+ // Just test that we don't assert
+ QBitmap bm(8, 8);
+ QImage out(64, 64, QImage::Format_RGB32);
+ QPainter p(&out);
+ qreal y = 26.499999999999996;
+ p.drawPixmap(QPointF(0, y), bm);
+}
+
void tst_QPainter::drawLine_data()
{
QTest::addColumn<QLine>("line");