From 7706c2a28ea5995f828144e39b8d1662aa263aa2 Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Thu, 23 Nov 2023 12:10:24 +0100 Subject: [PATCH] Raster painting: Correct the coordinate rounding in drawPoints() When using the cosmetic stroker (i.e. plain pens with effective line width of 1), drawing points with fractional coordinates >= 0.5 would fill the wrong pixel. This is a long-standing bug where the drawPoints() code in the cosmetic stroker code was missed during the painting coordinate system shift for Qt 5.0. Prior to that, coordinates were interpreted as the upper left corner of a pixel, so rounding fractional coordinates to the closest integer would be the correct way to determine the pixel to be filled. From Qt 5 onwards however, coordinates instead designate the center point of the primitive to be stroked. In order to determine which pixel is most covered by the unit square centered in the given coordinates, fractional coordinates must be rounded downwards (floored). This fix makes the behavior consistent between the cosmetic and non-cosmetic stroker, so that drawPoints() with e.g. penwidths 1 and 1.01 in practice fills the same pixels. Pick-to: 6.6 Fixes: QTBUG-119306 Change-Id: I39cb7ad55229553dda098e6fbc9ee449b1fd9664 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/painting/qcosmeticstroker.cpp | 4 ++-- tests/baseline/painting/scripts/aliasing.qps | 13 ++++++++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/gui/painting/qcosmeticstroker.cpp b/src/gui/painting/qcosmeticstroker.cpp index f555b56adb7..a0eddf65d91 100644 --- a/src/gui/painting/qcosmeticstroker.cpp +++ b/src/gui/painting/qcosmeticstroker.cpp @@ -364,7 +364,7 @@ void QCosmeticStroker::drawPoints(const QPoint *points, int num) const QPoint *end = points + num; while (points < end) { QPointF p = QPointF(*points) * state->matrix; - drawPixel(this, qRound(p.x()), qRound(p.y()), 255); + drawPixel(this, std::floor(p.x()), std::floor(p.y()), 255); ++points; } @@ -377,7 +377,7 @@ void QCosmeticStroker::drawPoints(const QPointF *points, int num) const QPointF *end = points + num; while (points < end) { QPointF p = (*points) * state->matrix; - drawPixel(this, qRound(p.x()), qRound(p.y()), 255); + drawPixel(this, std::floor(p.x()), std::floor(p.y()), 255); ++points; } diff --git a/tests/baseline/painting/scripts/aliasing.qps b/tests/baseline/painting/scripts/aliasing.qps index 59878f9c4d3..1fb0113396e 100644 --- a/tests/baseline/painting/scripts/aliasing.qps +++ b/tests/baseline/painting/scripts/aliasing.qps @@ -19,6 +19,17 @@ begin_block drawing setPen black drawText 0 68 "QwErTy@" + setPen green 1 SolidLine + drawLine 0 75 10 75 + setPen 800000ff 1 + drawPoint 0 75 + drawPoint 10 75 + + setPen green 2 SolidLine + drawLine 20 75 30 75 + setPen 800000ff 2 + drawPoint 20 75 + drawPoint 30 75 setPen black 1 setBrush 7f7fff @@ -153,4 +164,4 @@ drawText 15 185 "1.0" resetMatrix drawText 430 95 "Aliased" -drawText 430 275 "Anti-Aliased" \ No newline at end of file +drawText 430 275 "Anti-Aliased"