diff options
author | Lars Knoll <lars.knoll@nokia.com> | 2009-03-30 18:44:39 (GMT) |
---|---|---|
committer | Bjoern Erik Nilsen <bjorn.nilsen@nokia.com> | 2009-04-07 13:51:08 (GMT) |
commit | 6f93983dcce291f66d42e844f1d12bd4a59b046b (patch) | |
tree | e9d7e121bcb3142c7cc61c56ff4277083842c3f8 /src/gui/painting/qtransform.cpp | |
parent | fde7f3d03782c801901f511131458d6fcb1021a5 (diff) | |
download | Qt-6f93983dcce291f66d42e844f1d12bd4a59b046b.zip Qt-6f93983dcce291f66d42e844f1d12bd4a59b046b.tar.gz Qt-6f93983dcce291f66d42e844f1d12bd4a59b046b.tar.bz2 |
Optimise QMatrix and QTransform
Add some private inline constructors and do inlining
other places.
All test still pass.
Diffstat (limited to 'src/gui/painting/qtransform.cpp')
-rw-r--r-- | src/gui/painting/qtransform.cpp | 198 |
1 files changed, 139 insertions, 59 deletions
diff --git a/src/gui/painting/qtransform.cpp b/src/gui/painting/qtransform.cpp index b25146d..6c37ab6 100644 --- a/src/gui/painting/qtransform.cpp +++ b/src/gui/painting/qtransform.cpp @@ -238,11 +238,11 @@ QT_BEGIN_NAMESPACE \sa reset() */ QTransform::QTransform() - : m_13(0), m_23(0), m_33(1) + : affine(true) + , m_13(0), m_23(0), m_33(1) , m_type(TxNone) , m_dirty(TxNone) { - } /*! @@ -256,12 +256,11 @@ QTransform::QTransform() QTransform::QTransform(qreal h11, qreal h12, qreal h13, qreal h21, qreal h22, qreal h23, qreal h31, qreal h32, qreal h33) - : affine(h11, h12, h21, h22, h31, h32), - m_13(h13), m_23(h23), m_33(h33) + : affine(h11, h12, h21, h22, h31, h32, true) + , m_13(h13), m_23(h23), m_33(h33) , m_type(TxNone) , m_dirty(TxProject) { - } /*! @@ -273,12 +272,11 @@ QTransform::QTransform(qreal h11, qreal h12, qreal h13, */ QTransform::QTransform(qreal h11, qreal h12, qreal h21, qreal h22, qreal dx, qreal dy) - : affine(h11, h12, h21, h22, dx, dy), - m_13(0), m_23(0), m_33(1) + : affine(h11, h12, h21, h22, dx, dy, true) + , m_13(0), m_23(0), m_33(1) , m_type(TxNone) , m_dirty(TxShear) { - } /*! @@ -289,12 +287,11 @@ QTransform::QTransform(qreal h11, qreal h12, qreal h21, and 1 respectively. */ QTransform::QTransform(const QMatrix &mtx) - : affine(mtx), + : affine(mtx._m11, mtx._m12, mtx._m21, mtx._m22, mtx._dx, mtx._dy, true), m_13(0), m_23(0), m_33(1) , m_type(TxNone) , m_dirty(TxShear) { - } /*! @@ -317,7 +314,7 @@ QTransform QTransform::adjoint() const return QTransform(h11, h12, h13, h21, h22, h23, - h31, h32, h33); + h31, h32, h33, true); } /*! @@ -327,7 +324,7 @@ QTransform QTransform::transposed() const { QTransform t(affine._m11, affine._m21, affine._dx, affine._m12, affine._m22, affine._dy, - m_13, m_23, m_33); + m_13, m_23, m_33, true); t.m_type = m_type; t.m_dirty = m_dirty; return t; @@ -345,11 +342,10 @@ QTransform QTransform::transposed() const */ QTransform QTransform::inverted(bool *invertible) const { - QTransform invert; + QTransform invert(true); bool inv = true; - qreal det; - switch(type()) { + switch(inline_type()) { case TxNone: break; case TxTranslate: @@ -357,11 +353,11 @@ QTransform QTransform::inverted(bool *invertible) const invert.affine._dy = -affine._dy; break; case TxScale: - inv = !qFuzzyCompare(affine._m11 + 1, 1); - inv &= !qFuzzyCompare(affine._m22 + 1, 1); + inv = !qIsFuzzyNull(affine._m11); + inv &= !qIsFuzzyNull(affine._m22); if (inv) { - invert.affine._m11 = 1 / affine._m11; - invert.affine._m22 = 1 / affine._m22; + invert.affine._m11 = 1. / affine._m11; + invert.affine._m22 = 1. / affine._m22; invert.affine._dx = -affine._dx * invert.affine._m11; invert.affine._dy = -affine._dy * invert.affine._m22; } @@ -372,8 +368,8 @@ QTransform QTransform::inverted(bool *invertible) const break; default: // general case - det = determinant(); - inv = !qFuzzyCompare(det + 1, 1); + qreal det = determinant(); + inv = !qIsFuzzyNull(det); if (inv) invert = adjoint() / det; break; @@ -397,12 +393,12 @@ QTransform QTransform::inverted(bool *invertible) const \sa setMatrix() */ -QTransform & QTransform::translate(qreal dx, qreal dy) +QTransform &QTransform::translate(qreal dx, qreal dy) { if (dx == 0 && dy == 0) return *this; - switch(type()) { + switch(inline_type()) { case TxNone: affine._dx = dx; affine._dy = dy; @@ -437,7 +433,7 @@ QTransform & QTransform::translate(qreal dx, qreal dy) */ QTransform QTransform::fromTranslate(qreal dx, qreal dy) { - QTransform transform(1, 0, 0, 1, dx, dy); + QTransform transform(1, 0, 0, 0, 1, 0, dx, dy, 1, true); if (dx == 0 && dy == 0) transform.m_dirty = TxNone; else @@ -456,7 +452,7 @@ QTransform & QTransform::scale(qreal sx, qreal sy) if (sx == 1 && sy == 1) return *this; - switch(type()) { + switch(inline_type()) { case TxNone: case TxTranslate: affine._m11 = sx; @@ -489,8 +485,8 @@ QTransform & QTransform::scale(qreal sx, qreal sy) */ QTransform QTransform::fromScale(qreal sx, qreal sy) { - QTransform transform(sx, 0, 0, sy, 0, 0); - if (sx == 1 && sy == 1) + QTransform transform(sx, 0, 0, 0, sy, 0, 0, 0, 1, true); + if (sx == 1. && sy == 1.) transform.m_dirty = TxNone; else transform.m_dirty = TxScale; @@ -505,7 +501,7 @@ QTransform QTransform::fromScale(qreal sx, qreal sy) */ QTransform & QTransform::shear(qreal sh, qreal sv) { - switch(type()) { + switch(inline_type()) { case TxNone: case TxTranslate: affine._m12 = sv; @@ -574,7 +570,7 @@ QTransform & QTransform::rotate(qreal a, Qt::Axis axis) } if (axis == Qt::ZAxis) { - switch(type()) { + switch(inline_type()) { case TxNone: case TxTranslate: affine._m11 = cosa; @@ -646,7 +642,7 @@ QTransform & QTransform::rotateRadians(qreal a, Qt::Axis axis) qreal cosa = qCos(a); if (axis == Qt::ZAxis) { - switch(type()) { + switch(inline_type()) { case TxNone: case TxTranslate: affine._m11 = cosa; @@ -730,11 +726,11 @@ bool QTransform::operator!=(const QTransform &o) const */ QTransform & QTransform::operator*=(const QTransform &o) { - const TransformationType otherType = o.type(); + const TransformationType otherType = o.inline_type(); if (otherType == TxNone) return *this; - const TransformationType thisType = type(); + const TransformationType thisType = inline_type(); if (thisType == TxNone) return operator=(o); @@ -812,9 +808,77 @@ QTransform & QTransform::operator*=(const QTransform &o) */ QTransform QTransform::operator*(const QTransform &m) const { - QTransform result = *this; - result *= m; - return result; + const TransformationType otherType = m.inline_type(); + if (otherType == TxNone) + return *this; + + const TransformationType thisType = inline_type(); + if (thisType == TxNone) + return m; + + QTransform t(true); + TransformationType type = qMax(thisType, otherType); + switch(type) { + case TxNone: + break; + case TxTranslate: + t.affine._dx = affine._dx + m.affine._dx; + t.affine._dy += affine._dy + m.affine._dy; + break; + case TxScale: + { + qreal m11 = affine._m11*m.affine._m11; + qreal m22 = affine._m22*m.affine._m22; + + qreal m31 = affine._dx*m.affine._m11 + m.affine._dx; + qreal m32 = affine._dy*m.affine._m22 + m.affine._dy; + + t.affine._m11 = m11; + t.affine._m22 = m22; + t.affine._dx = m31; t.affine._dy = m32; + break; + } + case TxRotate: + case TxShear: + { + qreal m11 = affine._m11*m.affine._m11 + affine._m12*m.affine._m21; + qreal m12 = affine._m11*m.affine._m12 + affine._m12*m.affine._m22; + + qreal m21 = affine._m21*m.affine._m11 + affine._m22*m.affine._m21; + qreal m22 = affine._m21*m.affine._m12 + affine._m22*m.affine._m22; + + qreal m31 = affine._dx*m.affine._m11 + affine._dy*m.affine._m21 + m.affine._dx; + qreal m32 = affine._dx*m.affine._m12 + affine._dy*m.affine._m22 + m.affine._dy; + + t.affine._m11 = m11; t.affine._m12 = m12; + t.affine._m21 = m21; t.affine._m22 = m22; + t.affine._dx = m31; t.affine._dy = m32; + break; + } + case TxProject: + { + qreal m11 = affine._m11*m.affine._m11 + affine._m12*m.affine._m21 + m_13*m.affine._dx; + qreal m12 = affine._m11*m.affine._m12 + affine._m12*m.affine._m22 + m_13*m.affine._dy; + qreal m13 = affine._m11*m.m_13 + affine._m12*m.m_23 + m_13*m.m_33; + + qreal m21 = affine._m21*m.affine._m11 + affine._m22*m.affine._m21 + m_23*m.affine._dx; + qreal m22 = affine._m21*m.affine._m12 + affine._m22*m.affine._m22 + m_23*m.affine._dy; + qreal m23 = affine._m21*m.m_13 + affine._m22*m.m_23 + m_23*m.m_33; + + qreal m31 = affine._dx*m.affine._m11 + affine._dy*m.affine._m21 + m_33*m.affine._dx; + qreal m32 = affine._dx*m.affine._m12 + affine._dy*m.affine._m22 + m_33*m.affine._dy; + qreal m33 = affine._dx*m.m_13 + affine._dy*m.m_23 + m_33*m.m_33; + + t.affine._m11 = m11; t.affine._m12 = m12; t.m_13 = m13; + t.affine._m21 = m21; t.affine._m22 = m22; t.m_23 = m23; + t.affine._dx = m31; t.affine._dy = m32; t.m_33 = m33; + } + } + + t.m_dirty = type; + t.m_type = type; + + return t; } /*! @@ -976,7 +1040,7 @@ QPoint QTransform::map(const QPoint &p) const qreal x = 0, y = 0; - TransformationType t = type(); + TransformationType t = inline_type(); switch(t) { case TxNone: x = fx; @@ -1027,7 +1091,7 @@ QPointF QTransform::map(const QPointF &p) const qreal x = 0, y = 0; - TransformationType t = type(); + TransformationType t = inline_type(); switch(t) { case TxNone: x = fx; @@ -1098,7 +1162,7 @@ QLine QTransform::map(const QLine &l) const qreal x1 = 0, y1 = 0, x2 = 0, y2 = 0; - TransformationType t = type(); + TransformationType t = inline_type(); switch(t) { case TxNone: x1 = fx1; @@ -1157,7 +1221,7 @@ QLineF QTransform::map(const QLineF &l) const qreal x1 = 0, y1 = 0, x2 = 0, y2 = 0; - TransformationType t = type(); + TransformationType t = inline_type(); switch(t) { case TxNone: x1 = fx1; @@ -1245,7 +1309,7 @@ static QPolygonF mapProjective(const QTransform &transform, const QPolygonF &pol */ QPolygonF QTransform::map(const QPolygonF &a) const { - TransformationType t = type(); + TransformationType t = inline_type(); if (t <= TxTranslate) return a.translated(affine._dx, affine._dy); @@ -1275,7 +1339,7 @@ QPolygonF QTransform::map(const QPolygonF &a) const */ QPolygon QTransform::map(const QPolygon &a) const { - TransformationType t = type(); + TransformationType t = inline_type(); if (t <= TxTranslate) return a.translated(qRound(affine._dx), qRound(affine._dy)); @@ -1320,7 +1384,7 @@ extern QPainterPath qt_regionToPath(const QRegion ®ion); */ QRegion QTransform::map(const QRegion &r) const { - TransformationType t = type(); + TransformationType t = inline_type(); if (t == TxNone) return r; if (t == TxTranslate) { @@ -1343,7 +1407,7 @@ struct QHomogeneousCoordinate QHomogeneousCoordinate(qreal x_, qreal y_, qreal w_) : x(x_), y(y_), w(w_) {} const QPointF toPoint() const { - qreal iw = 1 / w; + qreal iw = 1. / w; return QPointF(x * iw, y * iw); } }; @@ -1481,7 +1545,7 @@ static QPainterPath mapProjective(const QTransform &transform, const QPainterPat */ QPainterPath QTransform::map(const QPainterPath &path) const { - TransformationType t = type(); + TransformationType t = inline_type(); if (t == TxNone || path.isEmpty()) return path; @@ -1526,7 +1590,7 @@ QPainterPath QTransform::map(const QPainterPath &path) const */ QPolygon QTransform::mapToPolygon(const QRect &rect) const { - TransformationType t = type(); + TransformationType t = inline_type(); QPolygon a(4); qreal x[4] = { 0, 0, 0, 0 }, y[4] = { 0, 0, 0, 0 }; @@ -1700,7 +1764,7 @@ void QTransform::setMatrix(qreal m11, qreal m12, qreal m13, QRect QTransform::mapRect(const QRect &rect) const { - TransformationType t = type(); + TransformationType t = inline_type(); if (t <= TxTranslate) return rect.translated(qRound(affine._dx), qRound(affine._dy)); @@ -1771,7 +1835,7 @@ QRect QTransform::mapRect(const QRect &rect) const */ QRectF QTransform::mapRect(const QRectF &rect) const { - TransformationType t = type(); + TransformationType t = inline_type(); if (t <= TxTranslate) return rect.translated(affine._dx, affine._dy); @@ -1846,7 +1910,7 @@ QRectF QTransform::mapRect(const QRectF &rect) const */ void QTransform::map(qreal x, qreal y, qreal *tx, qreal *ty) const { - TransformationType t = type(); + TransformationType t = inline_type(); MAP(x, y, *tx, *ty); } @@ -1860,7 +1924,7 @@ void QTransform::map(qreal x, qreal y, qreal *tx, qreal *ty) const */ void QTransform::map(int x, int y, int *tx, int *ty) const { - TransformationType t = type(); + TransformationType t = inline_type(); qreal fx = 0, fy = 0; MAP(x, y, fx, fy); *tx = qRound(fx); @@ -1889,25 +1953,41 @@ const QMatrix &QTransform::toAffine() const */ QTransform::TransformationType QTransform::type() const { - if (m_dirty >= m_type) { - if (m_dirty > TxShear && (!qFuzzyCompare(m_13 + 1, 1) || !qFuzzyCompare(m_23 + 1, 1))) + if(m_dirty == TxNone || m_dirty < m_type) + return static_cast<TransformationType>(m_type); + + switch (static_cast<TransformationType>(m_dirty)) { + case TxProject: + if (!qIsFuzzyNull(m_13) || !qIsFuzzyNull(m_23) || !qIsFuzzyNull(m_33 - 1)) { m_type = TxProject; - else if (m_dirty > TxScale && (!qFuzzyCompare(affine._m12 + 1, 1) || !qFuzzyCompare(affine._m21 + 1, 1))) { + break; + } + case TxShear: + case TxRotate: + if (!qIsFuzzyNull(affine._m12) || !qIsFuzzyNull(affine._m21)) { const qreal dot = affine._m11 * affine._m12 + affine._m21 * affine._m22; - if (qFuzzyCompare(dot + 1, 1)) + if (qIsFuzzyNull(dot)) m_type = TxRotate; else m_type = TxShear; - } else if (m_dirty > TxTranslate && (!qFuzzyCompare(affine._m11, 1) || !qFuzzyCompare(affine._m22, 1) || !qFuzzyCompare(m_33, 1))) + break; + } + case TxScale: + if (!qIsFuzzyNull(affine._m11 - 1) || !qIsFuzzyNull(affine._m22 - 1)) { m_type = TxScale; - else if (m_dirty > TxNone && (!qFuzzyCompare(affine._dx + 1, 1) || !qFuzzyCompare(affine._dy + 1, 1))) + break; + } + case TxTranslate: + if (!qIsFuzzyNull(affine._dx) || !qIsFuzzyNull(affine._dy)) { m_type = TxTranslate; - else - m_type = TxNone; - - m_dirty = TxNone; + break; + } + case TxNone: + m_type = TxNone; + break; } + m_dirty = TxNone; return static_cast<TransformationType>(m_type); } |