Improve rounding in QCosmeticStroker

Fixes the drawn position of end points in drawLine.

Based on a patch by Jørgen Lind, and modified so that
it caused no test regressions.

Task-number: QTBUG-38144
Change-Id: I24aa28480cc6ae09abf91d80378970565a29b254
Reviewed-by: Gunnar Sletta <gunnar@sletta.org>
This commit is contained in:
Allan Sandfeld Jensen 2015-03-11 17:14:50 +01:00
parent 7d43fb0c10
commit fd6a2d1c8f
2 changed files with 53 additions and 4 deletions

View File

@ -437,8 +437,9 @@ void QCosmeticStroker::calculateLastPoint(qreal rx1, qreal ry1, qreal rx2, qreal
int y = (y1 + 32) >> 6;
int ys = (y2 + 32) >> 6;
int round = (xinc > 0) ? 32 : 0;
if (y != ys) {
x += ( ((((y << 6) + 32 - y1))) * xinc ) >> 6;
x += ( ((((y << 6) + round - y1))) * xinc ) >> 6;
if (swapped) {
lastPixel.x = x >> 16;
@ -468,8 +469,9 @@ void QCosmeticStroker::calculateLastPoint(qreal rx1, qreal ry1, qreal rx2, qreal
int x = (x1 + 32) >> 6;
int xs = (x2 + 32) >> 6;
int round = (yinc > 0) ? 32 : 0;
if (x != xs) {
y += ( ((((x << 6) + 32 - x1))) * yinc ) >> 6;
y += ( ((((x << 6) + round - x1))) * yinc ) >> 6;
if (swapped) {
lastPixel.x = x;
@ -762,9 +764,10 @@ static bool drawLine(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2,
int y = (y1 + 32) >> 6;
int ys = (y2 + 32) >> 6;
int round = (xinc > 0) ? 32 : 0;
if (y != ys) {
x += ( ((((y << 6) + 32 - y1))) * xinc ) >> 6;
x += ( ((((y << 6) + round - y1))) * xinc ) >> 6;
// calculate first and last pixel and perform dropout control
QCosmeticStroker::Point first;
@ -837,9 +840,10 @@ static bool drawLine(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2,
int x = (x1 + 32) >> 6;
int xs = (x2 + 32) >> 6;
int round = (yinc > 0) ? 32 : 0;
if (x != xs) {
y += ( ((((x << 6) + 32 - x1))) * yinc ) >> 6;
y += ( ((((x << 6) + round - x1))) * yinc ) >> 6;
// calculate first and last pixel to perform dropout control
QCosmeticStroker::Point first;

View File

@ -111,6 +111,7 @@ private slots:
void drawLine_task190634();
void drawLine_task229459();
void drawLine_task234891();
void drawLineEndPoints();
void drawRect_data() { fillData(); }
void drawRect();
@ -1036,6 +1037,50 @@ void tst_QPainter::drawLine_task216948()
QCOMPARE(img.pixel(0, i), QColor(Qt::black).rgba());
}
void tst_QPainter::drawLineEndPoints()
{
QImage img(256, 256, QImage::Format_ARGB32_Premultiplied);
img.fill(0x0);
QPainter p;
for (int x = 0; x < img.width(); ++x) {
QRgb color = qRgb(x, 0, 0);
p.begin(&img);
p.setPen(QPen(color));
p.drawLine(x, 0, 255 - x, 255);
p.end();
QCOMPARE(img.pixel(x, 0), color);
QCOMPARE(img.pixel(255 - x, 255), color);
}
for (int y = 0; y < img.height(); ++y) {
QRgb color = qRgb(0, y, 0);
p.begin(&img);
p.setPen(QPen(color));
p.drawLine(0, y, 255, 255 - y);
p.end();
QCOMPARE(img.pixel(0, y), color);
QCOMPARE(img.pixel(255, 255 - y), color);
}
for (int x = 0; x < img.width(); ++x) {
QRgb color = qRgb(x, 0, x);
p.begin(&img);
p.setPen(QPen(color));
p.drawLine(x, 255, 255 - x, 0);
p.end();
QCOMPARE(img.pixel(x, 255), color);
QCOMPARE(img.pixel(255 - x, 0), color);
}
for (int y = 0; y < img.height(); ++y) {
QRgb color = qRgb(0, y, y);
p.begin(&img);
p.setPen(QPen(color));
p.drawLine(255, y, 0, 255 - y);
p.end();
QCOMPARE(img.pixel(255, y), color);
QCOMPARE(img.pixel(0, 255 - y), color);
}
}
void tst_QPainter::drawRect()
{
QFETCH(QRect, rect);