summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Rødal <samuel.rodal@nokia.com>2010-09-20 14:54:30 +0200
committerSamuli Piippo <samuli.piippo@digia.com>2011-06-09 13:06:57 +0300
commitde8ac0524e7ad9748d6a4f54d5d77bae7a6f3eb0 (patch)
tree06bc00a7bc541c001e280b0eb3fac07cc97da553
parent0a245d03022efbc1664b4f8844e4ff9a1c71b063 (diff)
downloadqt4-tools-de8ac0524e7ad9748d6a4f54d5d77bae7a6f3eb0.tar.gz
Fixed scaled point drawing with square cap in raster paint engine.
With a large pen width and a small scale, due to the hacky way we draw points (stroking a line from (x, y) to (x + tiny_amount, y)), we some times end up snapping these two points to the same in rasterizeLine(). If we instead apply the SquareCap before we do clipping / snapping we don't get this problem. Task-number: QTBUG-13429 Reviewed-by: Trond (cherry picked from commit 7c673a4cf64ba043bb27f90287517bdcdd7a21db)
-rw-r--r--src/gui/painting/qrasterizer.cpp41
-rw-r--r--tests/auto/qpainter/tst_qpainter.cpp22
2 files changed, 39 insertions, 24 deletions
diff --git a/src/gui/painting/qrasterizer.cpp b/src/gui/painting/qrasterizer.cpp
index aed9291072..fae3e94985 100644
--- a/src/gui/painting/qrasterizer.cpp
+++ b/src/gui/painting/qrasterizer.cpp
@@ -712,17 +712,21 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width,
QPointF pa = a;
QPointF pb = b;
- QPointF offs = QPointF(qAbs(b.y() - a.y()), qAbs(b.x() - a.x())) * width * 0.5;
- if (squareCap)
- offs += QPointF(offs.y(), offs.x());
+ if (squareCap) {
+ QPointF delta = pb - pa;
+ pa -= (0.5f * width) * delta;
+ pb += (0.5f * width) * delta;
+ }
+
+ QPointF offs = QPointF(qAbs(b.y() - a.y()), qAbs(b.x() - a.x())) * width * 0.5;
const QRectF clip(d->clipRect.topLeft() - offs, d->clipRect.bottomRight() + QPoint(1, 1) + offs);
- if (!clip.contains(a) || !clip.contains(b)) {
+ if (!clip.contains(pa) || !clip.contains(pb)) {
qreal t1 = 0;
qreal t2 = 1;
- const qreal o[2] = { a.x(), a.y() };
- const qreal d[2] = { b.x() - a.x(), b.y() - a.y() };
+ const qreal o[2] = { pa.x(), pa.y() };
+ const qreal d[2] = { pb.x() - pa.x(), pb.y() - pa.y() };
const qreal low[2] = { clip.left(), clip.top() };
const qreal high[2] = { clip.right(), clip.bottom() };
@@ -745,8 +749,12 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width,
if (t1 >= t2)
return;
}
- pa = a + (b - a) * t1;
- pb = a + (b - a) * t2;
+
+ QPointF npa = pa + (pb - pa) * t1;
+ QPointF npb = pa + (pb - pa) * t2;
+
+ pa = npa;
+ pb = npb;
}
if (!d->antialiased) {
@@ -793,12 +801,7 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width,
pa = QPointF(x, y - dy);
pb = QPointF(x, y + dy);
- if (squareCap)
- width = 1 / width + 1.0f;
- else
- width = 1 / width;
-
- squareCap = false;
+ width = 1 / width;
}
if (q16Dot16Compare(pa.x(), pb.x())) {
@@ -808,11 +811,6 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width,
const qreal dy = pb.y() - pa.y();
const qreal halfWidth = 0.5f * width * dy;
- if (squareCap) {
- pa.ry() -= halfWidth;
- pb.ry() += halfWidth;
- }
-
qreal left = pa.x() - halfWidth;
qreal right = pa.x() + halfWidth;
@@ -893,11 +891,6 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width,
delta *= 0.5f * width;
const QPointF perp(delta.y(), -delta.x());
- if (squareCap) {
- pa -= delta;
- pb += delta;
- }
-
QPointF top;
QPointF left;
QPointF right;
diff --git a/tests/auto/qpainter/tst_qpainter.cpp b/tests/auto/qpainter/tst_qpainter.cpp
index d453b5008c..729dd5ebb2 100644
--- a/tests/auto/qpainter/tst_qpainter.cpp
+++ b/tests/auto/qpainter/tst_qpainter.cpp
@@ -251,6 +251,8 @@ private slots:
void QTBUG5939_attachPainterPrivate();
+ void drawPointScaled();
+
private:
void fillData();
void setPenColor(QPainter& p);
@@ -4458,6 +4460,26 @@ void tst_QPainter::QTBUG5939_attachPainterPrivate()
QCOMPARE(widget->deviceTransform, proxy->deviceTransform);
}
+void tst_QPainter::drawPointScaled()
+{
+ QImage image(32, 32, QImage::Format_RGB32);
+ image.fill(0xffffffff);
+
+ QPainter p(&image);
+
+ p.scale(0.1, 0.1);
+
+ QPen pen;
+ pen.setWidth(1000);
+ pen.setColor(Qt::red);
+
+ p.setPen(pen);
+ p.drawPoint(0, 0);
+ p.end();
+
+ QCOMPARE(image.pixel(16, 16), 0xffff0000);
+}
+
QTEST_MAIN(tst_QPainter)
#include "tst_qpainter.moc"