From ebbab30af417dfbf3df47dec15c0e2f8d6a30fa6 Mon Sep 17 00:00:00 2001 From: Benjamin Poulain Date: Thu, 29 Jul 2010 11:09:48 +0200 Subject: Fix the rendering of lines with the X11 paint engine On the X11 paint engine, when rendering lines with float coordinates, the lines were one pixel off if the decimal was > 0.5. This fixes the WebKit bug https://bugs.webkit.org/show_bug.cgi?id=42248 Autotest by Yoann Lopes. Reviewed-by: Simon Hausmann Reviewed-by: Yoann Lopes Reviewed-by: Andreas Kling --- src/gui/painting/qpaintengine_x11.cpp | 22 ++++++------ tests/auto/qpainter/tst_qpainter.cpp | 65 +++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 12 deletions(-) diff --git a/src/gui/painting/qpaintengine_x11.cpp b/src/gui/painting/qpaintengine_x11.cpp index 910b2df..e521e01 100644 --- a/src/gui/painting/qpaintengine_x11.cpp +++ b/src/gui/painting/qpaintengine_x11.cpp @@ -696,11 +696,10 @@ void QX11PaintEngine::drawLines(const QLine *lines, int lineCount) linef = d->matrix.map(QLineF(lines[i])); } if (clipLine(&linef, d->polygonClipper.boundingRect())) { - int x1 = qRound(linef.x1() + aliasedCoordinateDelta); - int y1 = qRound(linef.y1() + aliasedCoordinateDelta); - int x2 = qRound(linef.x2() + aliasedCoordinateDelta); - int y2 = qRound(linef.y2() + aliasedCoordinateDelta); - + int x1 = qFloor(linef.x1() + aliasedCoordinateDelta); + int y1 = qFloor(linef.y1() + aliasedCoordinateDelta); + int x2 = qFloor(linef.x2() + aliasedCoordinateDelta); + int y2 = qFloor(linef.y2() + aliasedCoordinateDelta); XDrawLine(d->dpy, d->hd, d->gc, x1, y1, x2, y2); } } @@ -730,11 +729,10 @@ void QX11PaintEngine::drawLines(const QLineF *lines, int lineCount) for (int i = 0; i < lineCount; ++i) { QLineF linef = d->matrix.map(lines[i]); if (clipLine(&linef, d->polygonClipper.boundingRect())) { - int x1 = qRound(linef.x1() + aliasedCoordinateDelta); - int y1 = qRound(linef.y1() + aliasedCoordinateDelta); - int x2 = qRound(linef.x2() + aliasedCoordinateDelta); - int y2 = qRound(linef.y2() + aliasedCoordinateDelta); - + int x1 = qFloor(linef.x1() + aliasedCoordinateDelta); + int y1 = qFloor(linef.y1() + aliasedCoordinateDelta); + int x2 = qFloor(linef.x2() + aliasedCoordinateDelta); + int y2 = qFloor(linef.y2() + aliasedCoordinateDelta); XDrawLine(d->dpy, d->hd, d->gc, x1, y1, x2, y2); } } @@ -1690,8 +1688,8 @@ void QX11PaintEnginePrivate::strokePolygon_dev(const QPointF *polygonPoints, int if (clippedCount > 0) { QVarLengthArray xpoints(clippedCount); for (int i = 0; i < clippedCount; ++i) { - xpoints[i].x = qRound(clippedPoints[i].x + aliasedCoordinateDelta); - xpoints[i].y = qRound(clippedPoints[i].y + aliasedCoordinateDelta); + xpoints[i].x = qFloor(clippedPoints[i].x + aliasedCoordinateDelta); + xpoints[i].y = qFloor(clippedPoints[i].y + aliasedCoordinateDelta); } uint numberPoints = qMin(clippedCount, xlibMaxLinePoints); XPoint *pts = xpoints.data(); diff --git a/tests/auto/qpainter/tst_qpainter.cpp b/tests/auto/qpainter/tst_qpainter.cpp index f358681..2cbb9b2 100644 --- a/tests/auto/qpainter/tst_qpainter.cpp +++ b/tests/auto/qpainter/tst_qpainter.cpp @@ -118,10 +118,12 @@ private slots: void drawLine_task190634(); void drawLine_task229459(); void drawLine_task234891(); + void drawHorizontalLineF(); void drawRect_data() { fillData(); } void drawRect(); void drawRect2(); + void drawRectFHorizontalLine(); void fillRect(); void fillRect2(); @@ -251,6 +253,7 @@ private slots: void setPenColorOnPixmap(); void QTBUG5939_attachPainterPrivate(); + void drawHorizontalLine(); private: void fillData(); @@ -1218,6 +1221,26 @@ void tst_QPainter::drawLine_task234891() QCOMPARE(expected, img); } +void tst_QPainter::drawHorizontalLineF() +{ + QPixmap pixmap(100, 3); + pixmap.fill(); + + { + QPainter painter(&pixmap); + painter.drawLine(QLineF(1.5f, 1.5f, 98.5f, 1.5f)); + } + + QImage refImage(100, 3, QImage::Format_ARGB32); + refImage.fill(0xFFFFFFFF); + { + QPainter painter(&refImage); + painter.drawLine(QLineF(1.5f, 1.5f, 98.5f, 1.5f)); + } + + QCOMPARE(pixmap.toImage().convertToFormat(QImage::Format_ARGB32), refImage); +} + void tst_QPainter::drawLine_task216948() { QImage img(1, 10, QImage::Format_ARGB32_Premultiplied); @@ -1302,6 +1325,26 @@ void tst_QPainter::drawRect2() } } +void tst_QPainter::drawRectFHorizontalLine() +{ + QPixmap pixmap(100, 3); + pixmap.fill(); + + { + QPainter painter(&pixmap); + painter.drawRect(QRectF(1.5f, 1.5f, 98.5f, 1.5f)); + } + + QImage refImage(100, 3, QImage::Format_ARGB32); + refImage.fill(0xFFFFFFFF); + { + QPainter painter(&refImage); + painter.drawRect(QRectF(1.5f, 1.5f, 98.5f, 1.5f)); + } + + QCOMPARE(pixmap.toImage().convertToFormat(QImage::Format_ARGB32), refImage); +} + void tst_QPainter::fillRect() { QImage image(100, 100, QImage::Format_ARGB32_Premultiplied); @@ -4522,6 +4565,28 @@ void tst_QPainter::QTBUG5939_attachPainterPrivate() QCOMPARE(widget->deviceTransform, proxy->deviceTransform); } +void tst_QPainter::drawHorizontalLine() +{ + QPixmap pixmap(100, 3); + pixmap.fill(); + + { + QPainter painter(&pixmap); + painter.translate(0.3, 0.3); + painter.drawLine(QLine(1, 1, 99, 1)); + } + + QImage refImage(100, 3, QImage::Format_ARGB32); + refImage.fill(0xFFFFFFFF); + { + QPainter painter(&refImage); + painter.translate(0.3, 0.3); + painter.drawLine(QLine(1, 1, 99, 1)); + } + + QCOMPARE(pixmap.toImage().convertToFormat(QImage::Format_ARGB32), refImage); +} + QTEST_MAIN(tst_QPainter) #include "tst_qpainter.moc" -- cgit v0.12