summaryrefslogtreecommitdiffstats
path: root/src/gui/painting/qpaintengine_raster.cpp
diff options
context:
space:
mode:
authorGunnar Sletta <gunnar@sletta.org>2016-02-23 08:56:22 +0100
committerGunnar Sletta <gunnar@sletta.org>2016-10-06 14:22:05 +0000
commit2a43eba41433d45743fcc324c614c904bde0571e (patch)
tree15e5318f11303306e474e1dcbf18111ff10ce9f6 /src/gui/painting/qpaintengine_raster.cpp
parent978cb5d3ce05748f5707f0c2c58e698f11e6ef89 (diff)
Normalize QRects the way QPainter expects them
[ChangeLog][QtGui][QPainter] Fix fills of negatively sized QRects. Task-number: QTBUG-28851 Change-Id: I59abad28266eea6118da3ec37473ff101000bb7a Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
Diffstat (limited to 'src/gui/painting/qpaintengine_raster.cpp')
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp41
1 files changed, 36 insertions, 5 deletions
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index 0edd9125a3..dd6bcdebec 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -272,6 +272,35 @@ static void qt_debug_path(const QPainterPath &path)
}
#endif
+// QRect::normalized() will change the width/height of the rectangle due to
+// its incusive-integer definition of left/right vs width. This is not
+// something we want to change in QRect as that would potentially introduce
+// regressions all over the place, so we implement a straightforward
+// normalized here. QRectF already does this, so QRectF::normalized() is ok to
+// use.
+static QRect qrect_normalized(const QRect &rect)
+{
+ int x, y, w, h;
+ if (Q_UNLIKELY(rect.width() < 0)) {
+ x = rect.x() + rect.width();
+ w = -rect.width();
+ } else {
+ x = rect.x();
+ w = rect.width();
+ }
+
+ if (Q_UNLIKELY(rect.height() < 0)) {
+ y = rect.y() + rect.height();
+ h = -rect.height();
+ } else {
+ y = rect.y();
+ h = rect.height();
+ }
+
+ return QRect(x, y, w, h);
+}
+
+
QRasterPaintEnginePrivate::QRasterPaintEnginePrivate() :
QPaintEngineExPrivate(),
cachedLines(0)
@@ -1236,7 +1265,9 @@ void QRasterPaintEngine::clip(const QRect &rect, Qt::ClipOperation op)
bool QRasterPaintEngine::setClipRectInDeviceCoords(const QRect &r, Qt::ClipOperation op)
{
Q_D(QRasterPaintEngine);
- QRect clipRect = r & d->deviceRect;
+ // normalize before using the & operator which uses QRect::normalize()
+ // internally which will give us the wrong values.
+ QRect clipRect = qrect_normalized(r) & d->deviceRect;
QRasterPaintEngineState *s = state();
if (op == Qt::ReplaceClip || s->clip == 0) {
@@ -1471,7 +1502,7 @@ void QRasterPaintEngine::drawRects(const QRect *rects, int rectCount)
int offset_x = int(s->matrix.dx());
int offset_y = int(s->matrix.dy());
while (r < lastRect) {
- QRect rect = r->normalized();
+ QRect rect = qrect_normalized(*r);
QRect rr = rect.translated(offset_x, offset_y);
fillRect_normalized(rr, &s->brushData, d);
++r;
@@ -2498,7 +2529,7 @@ void QRasterPaintEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap,
QRectF rr = r;
rr.translate(s->matrix.dx(), s->matrix.dy());
- fillRect_normalized(rr.toRect().normalized(), &d->image_filler, d);
+ fillRect_normalized(rr.normalized().toRect(), &d->image_filler, d);
}
}
@@ -2878,7 +2909,7 @@ bool QRasterPaintEnginePrivate::isUnclipped(const QRect &rect,
const QRasterPaintEngineState *s = q->state();
const QClipData *cl = clip();
if (!cl) {
- QRect r = rect.normalized();
+ QRect r = qrect_normalized(rect);
// inline contains() for performance (we know the rects are normalized)
const QRect &r1 = deviceRect;
return (r.left() >= r1.left() && r.right() <= r1.right()
@@ -2893,7 +2924,7 @@ bool QRasterPaintEnginePrivate::isUnclipped(const QRect &rect,
if (s->flags.antialiased)
++penWidth;
- QRect r = rect.normalized();
+ QRect r = qrect_normalized(rect);
if (penWidth > 0) {
r.setX(r.x() - penWidth);
r.setY(r.y() - penWidth);