From df792f3f790e677552ea950b039d8f8e491180bf Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Thu, 28 May 2009 16:47:29 +0200 Subject: greatly speed up QTransform::mapRect() for projective transforms The code so far was converting the rect to a painterpath, mapping that one and then taking the bounding rect. It is actually sufficient to simply map the four corners of the rectangle and take the bounding rect of these four points even in the projective case. Fix the MAP macro to be more correct for degenerated projective transformations. Reviewed-By: Samuel --- src/gui/painting/qtransform.cpp | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/gui/painting/qtransform.cpp b/src/gui/painting/qtransform.cpp index 385fde1..7ca3b79 100644 --- a/src/gui/painting/qtransform.cpp +++ b/src/gui/painting/qtransform.cpp @@ -76,7 +76,9 @@ QT_BEGIN_NAMESPACE nx = affine._m11 * FX_ + affine._m21 * FY_ + affine._dx; \ ny = affine._m12 * FX_ + affine._m22 * FY_ + affine._dy; \ if (t == TxProject) { \ - qreal w = 1./(m_13 * FX_ + m_23 * FY_ + m_33); \ + qreal w = (m_13 * FX_ + m_23 * FY_ + m_33); \ + if (w < Q_NEAR_CLIP) w = Q_NEAR_CLIP; \ + w = 1./w; \ nx *= w; \ ny *= w; \ } \ @@ -1800,7 +1802,7 @@ QRect QTransform::mapRect(const QRect &rect) const y -= h; } return QRect(x, y, w, h); - } else if (t < TxProject) { + } else { // see mapToPolygon for explanations of the algorithm. qreal x = 0, y = 0; MAP(rect.left(), rect.top(), x, y); @@ -1824,10 +1826,6 @@ QRect QTransform::mapRect(const QRect &rect) const xmax = qMax(xmax, x); ymax = qMax(ymax, y); return QRect(qRound(xmin), qRound(ymin), qRound(xmax)-qRound(xmin), qRound(ymax)-qRound(ymin)); - } else { - QPainterPath path; - path.addRect(rect); - return map(path).boundingRect().toRect(); } } @@ -1870,7 +1868,7 @@ QRectF QTransform::mapRect(const QRectF &rect) const y -= h; } return QRectF(x, y, w, h); - } else if (t < TxProject) { + } else { qreal x = 0, y = 0; MAP(rect.x(), rect.y(), x, y); qreal xmin = x; @@ -1893,10 +1891,6 @@ QRectF QTransform::mapRect(const QRectF &rect) const xmax = qMax(xmax, x); ymax = qMax(ymax, y); return QRectF(xmin, ymin, xmax-xmin, ymax - ymin); - } else { - QPainterPath path; - path.addRect(rect); - return map(path).boundingRect(); } } -- cgit v0.12