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/qpainter/tst_qpainter.cpp39
5 files changed, 63 insertions, 18 deletions
diff --git a/src/gui/painting/qcosmeticstroker.cpp b/src/gui/painting/qcosmeticstroker.cpp
index d940490..192b021 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 77c0039..870738b 100644
--- a/src/gui/painting/qcosmeticstroker_p.h
+++ b/src/gui/painting/qcosmeticstroker_p.h
@@ -86,8 +86,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),
@@ -106,6 +107,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 acc48d3..fe17ace 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -1056,20 +1056,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;
@@ -1536,7 +1536,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);
for (int i = 0; i < rectCount; ++i) {
path.set(rects[i]);
stroker.drawPath(path);
@@ -1582,7 +1582,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);
for (int i = 0; i < rectCount; ++i) {
path.set(rects[i]);
stroker.drawPath(path);
@@ -1615,7 +1615,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.drawPath(path);
} else if (s->flags.non_complex_pen && path.shape() == QVectorPath::LinesHint) {
qreal width = s->lastPen.isCosmetic()
@@ -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.drawPath(vp);
} else {
QPaintEngineEx::stroke(vp, s->lastPen);
@@ -2024,7 +2024,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.drawPath(vp);
} else {
QPaintEngineEx::stroke(vp, s->lastPen);
@@ -3216,7 +3216,7 @@ void QRasterPaintEngine::drawPoints(const QPointF *points, int pointCount)
return;
}
- QCosmeticStroker stroker(s, d->deviceRect);
+ QCosmeticStroker stroker(s, d->deviceRect, d->deviceRectUnclipped);
stroker.drawPoints(points, pointCount);
}
@@ -3235,7 +3235,7 @@ void QRasterPaintEngine::drawPoints(const QPoint *points, int pointCount)
return;
}
- QCosmeticStroker stroker(s, d->deviceRect);
+ QCosmeticStroker stroker(s, d->deviceRect, d->deviceRectUnclipped);
stroker.drawPoints(points, pointCount);
}
@@ -3255,7 +3255,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);
for (int i=0; i<lineCount; ++i) {
const QLine &l = lines[i];
stroker.drawLine(l.p1(), l.p2());
@@ -3326,7 +3326,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);
for (int i=0; i<lineCount; ++i) {
QLineF line = lines[i];
stroker.drawLine(line.p1(), line.p2());
diff --git a/src/gui/painting/qpaintengine_raster_p.h b/src/gui/painting/qpaintengine_raster_p.h
index 4ea7806..675dd44 100644
--- a/src/gui/painting/qpaintengine_raster_p.h
+++ b/src/gui/painting/qpaintengine_raster_p.h
@@ -353,6 +353,7 @@ public:
#endif
QRect deviceRect;
+ QRect deviceRectUnclipped;
QStroker basicStroker;
QScopedPointer<QDashStroker> dashStroker;
diff --git a/tests/auto/qpainter/tst_qpainter.cpp b/tests/auto/qpainter/tst_qpainter.cpp
index 3e8bf1c..c6bf2ec 100644
--- a/tests/auto/qpainter/tst_qpainter.cpp
+++ b/tests/auto/qpainter/tst_qpainter.cpp
@@ -272,6 +272,7 @@ private slots:
void QTBUG26013_squareCapStroke();
void QTBUG25153_drawLine();
+ void dashing_systemClip();
private:
void fillData();
@@ -4866,6 +4867,44 @@ 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"