summaryrefslogtreecommitdiffstats
path: root/src/gui/painting
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/painting')
-rw-r--r--src/gui/painting/qmath_p.h15
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp6
-rw-r--r--src/gui/painting/qtransform.cpp6
3 files changed, 21 insertions, 6 deletions
diff --git a/src/gui/painting/qmath_p.h b/src/gui/painting/qmath_p.h
index 0191f8381f..6691665f41 100644
--- a/src/gui/painting/qmath_p.h
+++ b/src/gui/painting/qmath_p.h
@@ -53,12 +53,27 @@
#include <qmath.h>
#include <private/qglobal_p.h>
+#include <qtransform.h>
QT_BEGIN_NAMESPACE
static const qreal Q_PI = qreal(M_PI); // pi
static const qreal Q_MM_PER_INCH = 25.4;
+inline QRect qt_mapFillRect(const QRectF &rect, const QTransform &xf)
+{
+ // Only for xf <= scaling or 90 degree rotations
+ Q_ASSERT(xf.type() <= QTransform::TxScale
+ || (xf.type() == QTransform::TxRotate && qFuzzyIsNull(xf.m11()) && qFuzzyIsNull(xf.m22())));
+ // Transform the corners instead of the rect to avoid hitting numerical accuracy limit
+ // when transforming topleft and size separately and adding afterwards,
+ // as that can sometimes be slightly off around the .5 point, leading to wrong rounding
+ QPoint pt1 = xf.map(rect.topLeft()).toPoint();
+ QPoint pt2 = xf.map(rect.bottomRight()).toPoint();
+ // Normalize and adjust for the QRect vs. QRectF bottomright
+ return QRect::span(pt1, pt2).adjusted(0, 0, -1, -1);
+}
+
QT_END_NAMESPACE
#endif // QMATH_P_H
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index b044b485df..6fbedabdbd 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -49,7 +49,7 @@
#include <qpainterpath.h>
#include <qdebug.h>
#include <qbitmap.h>
-#include <qmath.h>
+#include "qmath_p.h"
#include <qrandom.h>
// #include <private/qdatabuffer_p.h>
@@ -1195,7 +1195,7 @@ void QRasterPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op)
#endif
const qreal *points = path.points();
QRectF r(points[0], points[1], points[4]-points[0], points[5]-points[1]);
- if (setClipRectInDeviceCoords(s->matrix.mapRect(r).toAlignedRect(), op))
+ if (setClipRectInDeviceCoords(qt_mapFillRect(r, s->matrix), op))
return;
}
}
@@ -1255,7 +1255,7 @@ void QRasterPaintEngine::clip(const QRect &rect, Qt::ClipOperation op)
QPaintEngineEx::clip(rect, op);
return;
- } else if (!setClipRectInDeviceCoords(s->matrix.mapRect(QRectF(rect)).toRect(), op)) {
+ } else if (!setClipRectInDeviceCoords(qt_mapFillRect(rect, s->matrix), op)) {
QPaintEngineEx::clip(rect, op);
return;
}
diff --git a/src/gui/painting/qtransform.cpp b/src/gui/painting/qtransform.cpp
index 9d4f28c895..c318958207 100644
--- a/src/gui/painting/qtransform.cpp
+++ b/src/gui/painting/qtransform.cpp
@@ -45,7 +45,7 @@
#include "qpainterpath.h"
#include "qpainterpath_p.h"
#include "qvariant.h"
-#include <qmath.h>
+#include "qmath_p.h"
#include <qnumeric.h>
#include <private/qbezier_p.h>
@@ -1486,12 +1486,12 @@ QRegion QTransform::map(const QRegion &r) const
QRegion res;
if (m11() < 0 || m22() < 0) {
for (const QRect &rect : r)
- res += mapRect(QRectF(rect)).toRect();
+ res += qt_mapFillRect(QRectF(rect), *this);
} else {
QVarLengthArray<QRect, 32> rects;
rects.reserve(r.rectCount());
for (const QRect &rect : r) {
- QRect nr = mapRect(QRectF(rect)).toRect();
+ QRect nr = qt_mapFillRect(QRectF(rect), *this);
if (!nr.isEmpty())
rects.append(nr);
}