summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gui/painting/qcosmeticstroker.cpp11
-rw-r--r--src/gui/painting/qcosmeticstroker_p.h4
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp26
-rw-r--r--src/gui/painting/qpaintengine_raster_p.h1
-rw-r--r--tests/auto/gui/painting/qpainter/tst_qpainter.cpp38
5 files changed, 62 insertions, 18 deletions
diff --git a/src/gui/painting/qcosmeticstroker.cpp b/src/gui/painting/qcosmeticstroker.cpp
index 1ba55aa7f1..1de955bc13 100644
--- a/src/gui/painting/qcosmeticstroker.cpp
+++ b/src/gui/painting/qcosmeticstroker.cpp
@@ -290,11 +290,14 @@ void QCosmeticStroker::setup()
ppl = buffer->bytesPerLine()>>2;
}
+ // dashes are sensitive to clips, so we need to clip consistently when painting to the same device
+ QRect clipRect = strokeSelection & Dashed ? deviceRect : clip;
+
// setup FP clip bounds
- xmin = clip.left() - 1;
- xmax = clip.right() + 2;
- ymin = clip.top() - 1;
- ymax = clip.bottom() + 2;
+ xmin = clipRect.left() - 1;
+ xmax = clipRect.right() + 2;
+ ymin = clipRect.top() - 1;
+ ymax = clipRect.bottom() + 2;
lastPixel.x = -1;
}
diff --git a/src/gui/painting/qcosmeticstroker_p.h b/src/gui/painting/qcosmeticstroker_p.h
index 136b014424..f4fb5fab30 100644
--- a/src/gui/painting/qcosmeticstroker_p.h
+++ b/src/gui/painting/qcosmeticstroker_p.h
@@ -85,8 +85,9 @@ public:
HorizontalMask = 0xc
};
- QCosmeticStroker(QRasterPaintEngineState *s, const QRect &dr)
+ QCosmeticStroker(QRasterPaintEngineState *s, const QRect &dr, const QRect &dr_unclipped)
: state(s),
+ deviceRect(dr_unclipped),
clip(dr),
pattern(0),
reversePattern(0),
@@ -110,6 +111,7 @@ public:
QRasterPaintEngineState *state;
+ QRect deviceRect;
QRect clip;
// clip bounds in real
qreal xmin, xmax;
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index aaa0a4b87e..941e3ea71a 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -1054,20 +1054,20 @@ void QRasterPaintEnginePrivate::drawImage(const QPointF &pt,
void QRasterPaintEnginePrivate::systemStateChanged()
{
- QRect clipRect(0, 0,
+ deviceRectUnclipped = QRect(0, 0,
qMin(QT_RASTER_COORD_LIMIT, device->width()),
qMin(QT_RASTER_COORD_LIMIT, device->height()));
if (!systemClip.isEmpty()) {
- QRegion clippedDeviceRgn = systemClip & clipRect;
+ QRegion clippedDeviceRgn = systemClip & deviceRectUnclipped;
deviceRect = clippedDeviceRgn.boundingRect();
baseClip->setClipRegion(clippedDeviceRgn);
} else {
- deviceRect = clipRect;
+ deviceRect = deviceRectUnclipped;
baseClip->setClipRect(deviceRect);
}
#ifdef QT_DEBUG_DRAW
- qDebug() << "systemStateChanged" << this << "deviceRect" << deviceRect << clipRect << systemClip;
+ qDebug() << "systemStateChanged" << this << "deviceRect" << deviceRect << deviceRectUnclipped << systemClip;
#endif
exDeviceRect = deviceRect;
@@ -1529,7 +1529,7 @@ void QRasterPaintEngine::drawRects(const QRect *rects, int rectCount)
if (s->penData.blend) {
QRectVectorPath path;
if (s->flags.fast_pen) {
- QCosmeticStroker stroker(s, d->deviceRect);
+ QCosmeticStroker stroker(s, d->deviceRect, d->deviceRectUnclipped);
stroker.setLegacyRoundingEnabled(s->flags.legacy_rounding);
for (int i = 0; i < rectCount; ++i) {
path.set(rects[i]);
@@ -1576,7 +1576,7 @@ void QRasterPaintEngine::drawRects(const QRectF *rects, int rectCount)
if (s->penData.blend) {
QRectVectorPath path;
if (s->flags.fast_pen) {
- QCosmeticStroker stroker(s, d->deviceRect);
+ QCosmeticStroker stroker(s, d->deviceRect, d->deviceRectUnclipped);
stroker.setLegacyRoundingEnabled(s->flags.legacy_rounding);
for (int i = 0; i < rectCount; ++i) {
path.set(rects[i]);
@@ -1610,7 +1610,7 @@ void QRasterPaintEngine::stroke(const QVectorPath &path, const QPen &pen)
return;
if (s->flags.fast_pen) {
- QCosmeticStroker stroker(s, d->deviceRect);
+ QCosmeticStroker stroker(s, d->deviceRect, d->deviceRectUnclipped);
stroker.setLegacyRoundingEnabled(s->flags.legacy_rounding);
stroker.drawPath(path);
} else if (s->flags.non_complex_pen && path.shape() == QVectorPath::LinesHint) {
@@ -1953,7 +1953,7 @@ void QRasterPaintEngine::drawPolygon(const QPointF *points, int pointCount, Poly
if (s->penData.blend) {
QVectorPath vp((qreal *) points, pointCount, 0, QVectorPath::polygonFlags(mode));
if (s->flags.fast_pen) {
- QCosmeticStroker stroker(s, d->deviceRect);
+ QCosmeticStroker stroker(s, d->deviceRect, d->deviceRectUnclipped);
stroker.setLegacyRoundingEnabled(s->flags.legacy_rounding);
stroker.drawPath(vp);
} else {
@@ -2018,7 +2018,7 @@ void QRasterPaintEngine::drawPolygon(const QPoint *points, int pointCount, Polyg
QVectorPath vp((qreal *) fpoints.data(), pointCount, 0, QVectorPath::polygonFlags(mode));
if (s->flags.fast_pen) {
- QCosmeticStroker stroker(s, d->deviceRect);
+ QCosmeticStroker stroker(s, d->deviceRect, d->deviceRectUnclipped);
stroker.setLegacyRoundingEnabled(s->flags.legacy_rounding);
stroker.drawPath(vp);
} else {
@@ -3112,7 +3112,7 @@ void QRasterPaintEngine::drawPoints(const QPointF *points, int pointCount)
return;
}
- QCosmeticStroker stroker(s, d->deviceRect);
+ QCosmeticStroker stroker(s, d->deviceRect, d->deviceRectUnclipped);
stroker.setLegacyRoundingEnabled(s->flags.legacy_rounding);
stroker.drawPoints(points, pointCount);
}
@@ -3132,7 +3132,7 @@ void QRasterPaintEngine::drawPoints(const QPoint *points, int pointCount)
return;
}
- QCosmeticStroker stroker(s, d->deviceRect);
+ QCosmeticStroker stroker(s, d->deviceRect, d->deviceRectUnclipped);
stroker.setLegacyRoundingEnabled(s->flags.legacy_rounding);
stroker.drawPoints(points, pointCount);
}
@@ -3153,7 +3153,7 @@ void QRasterPaintEngine::drawLines(const QLine *lines, int lineCount)
return;
if (s->flags.fast_pen) {
- QCosmeticStroker stroker(s, d->deviceRect);
+ QCosmeticStroker stroker(s, d->deviceRect, d->deviceRectUnclipped);
stroker.setLegacyRoundingEnabled(s->flags.legacy_rounding);
for (int i=0; i<lineCount; ++i) {
const QLine &l = lines[i];
@@ -3225,7 +3225,7 @@ void QRasterPaintEngine::drawLines(const QLineF *lines, int lineCount)
if (!s->penData.blend)
return;
if (s->flags.fast_pen) {
- QCosmeticStroker stroker(s, d->deviceRect);
+ QCosmeticStroker stroker(s, d->deviceRect, d->deviceRectUnclipped);
stroker.setLegacyRoundingEnabled(s->flags.legacy_rounding);
for (int i=0; i<lineCount; ++i) {
QLineF line = lines[i];
diff --git a/src/gui/painting/qpaintengine_raster_p.h b/src/gui/painting/qpaintengine_raster_p.h
index e90cad6d8a..d9e4a4b505 100644
--- a/src/gui/painting/qpaintengine_raster_p.h
+++ b/src/gui/painting/qpaintengine_raster_p.h
@@ -323,6 +323,7 @@ public:
#endif
QRect deviceRect;
+ QRect deviceRectUnclipped;
QStroker basicStroker;
QScopedPointer<QDashStroker> dashStroker;
diff --git a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp
index cf520c06a9..774ade5fb0 100644
--- a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp
+++ b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp
@@ -280,6 +280,7 @@ private slots:
void drawTextWithComplexBrush();
void QTBUG26013_squareCapStroke();
void QTBUG25153_drawLine();
+ void dashing_systemClip();
private:
void fillData();
@@ -4461,6 +4462,43 @@ void tst_QPainter::QTBUG25153_drawLine()
}
}
+static void dashing_systemClip_paint(QPainter *p)
+{
+ p->setPen(QPen(Qt::black, 1, Qt::DashLine, Qt::RoundCap, Qt::MiterJoin));
+ p->drawLine(8, 8, 42, 8);
+ p->drawLine(42, 8, 42, 42);
+ p->drawLine(42, 42, 8, 42);
+ p->drawLine(8, 42, 8, 8);
+}
+
+void tst_QPainter::dashing_systemClip()
+{
+ QImage image(50, 50, QImage::Format_RGB32);
+ image.fill(Qt::white);
+
+ QPainter p(&image);
+ dashing_systemClip_paint(&p);
+ p.end();
+
+ QImage old = image.copy();
+
+ image.paintEngine()->setSystemClip(QRect(10, 0, image.width() - 10, image.height()));
+
+ p.begin(&image);
+ dashing_systemClip_paint(&p);
+
+ // doing same paint operation again with different system clip should not change the image
+ QCOMPARE(old, image);
+
+ old = image;
+
+ p.setClipRect(QRect(20, 20, 30, 30));
+ dashing_systemClip_paint(&p);
+
+ // ditto for regular clips
+ QCOMPARE(old, image);
+}
+
QTEST_MAIN(tst_QPainter)
#include "tst_qpainter.moc"