qtransform.h

Go to the documentation of this file.
00001 /****************************************************************************
00002 **
00003 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
00004 ** All rights reserved.
00005 ** Contact: Nokia Corporation (qt-info@nokia.com)
00006 **
00007 ** This file is part of the QtGui module of the Qt Toolkit.
00008 **
00009 ** $QT_BEGIN_LICENSE:LGPL$
00010 ** Commercial Usage
00011 ** Licensees holding valid Qt Commercial licenses may use this file in
00012 ** accordance with the Qt Commercial License Agreement provided with the
00013 ** Software or, alternatively, in accordance with the terms contained in
00014 ** a written agreement between you and Nokia.
00015 **
00016 ** GNU Lesser General Public License Usage
00017 ** Alternatively, this file may be used under the terms of the GNU Lesser
00018 ** General Public License version 2.1 as published by the Free Software
00019 ** Foundation and appearing in the file LICENSE.LGPL included in the
00020 ** packaging of this file.  Please review the following information to
00021 ** ensure the GNU Lesser General Public License version 2.1 requirements
00022 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
00023 **
00024 ** In addition, as a special exception, Nokia gives you certain additional
00025 ** rights.  These rights are described in the Nokia Qt LGPL Exception
00026 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this module.
00027 **
00028 ** GNU General Public License Usage
00029 ** Alternatively, this file may be used under the terms of the GNU
00030 ** General Public License version 3.0 as published by the Free Software
00031 ** Foundation and appearing in the file LICENSE.GPL included in the
00032 ** packaging of this file.  Please review the following information to
00033 ** ensure the GNU General Public License version 3.0 requirements will be
00034 ** met: http://www.gnu.org/copyleft/gpl.html.
00035 **
00036 ** If you have questions regarding the use of this file, please contact
00037 ** Nokia at qt-info@nokia.com.
00038 ** $QT_END_LICENSE$
00039 **
00040 ****************************************************************************/
00041 #ifndef QTRANSFORM_H
00042 #define QTRANSFORM_H
00043 
00044 #include <QtGui/qmatrix.h>
00045 #include <QtGui/qpainterpath.h>
00046 #include <QtGui/qpolygon.h>
00047 #include <QtGui/qregion.h>
00048 #include <QtGui/qwindowdefs.h>
00049 #include <QtCore/qline.h>
00050 #include <QtCore/qpoint.h>
00051 #include <QtCore/qrect.h>
00052 
00053 #if defined(Q_OS_VXWORKS) && defined(m_type)
00054 #  undef m_type
00055 #endif
00056 
00057 QT_BEGIN_HEADER
00058 
00059 QT_BEGIN_NAMESPACE
00060 
00061 QT_MODULE(Gui)
00062 
00063 class QVariant;
00064 
00065 class Q_GUI_EXPORT QTransform
00066 {
00067 public:
00068     enum TransformationType {
00069         TxNone      = 0x00,
00070         TxTranslate = 0x01,
00071         TxScale     = 0x02,
00072         TxRotate    = 0x04,
00073         TxShear     = 0x08,
00074         TxProject   = 0x10
00075     };
00076 
00077     inline explicit QTransform(Qt::Initialization) : affine(Qt::Uninitialized) {}
00078     QTransform();
00079     QTransform(qreal h11, qreal h12, qreal h13,
00080                qreal h21, qreal h22, qreal h23,
00081                qreal h31, qreal h32, qreal h33 = 1.0);
00082     QTransform(qreal h11, qreal h12, qreal h21,
00083                qreal h22, qreal dx, qreal dy);
00084     explicit QTransform(const QMatrix &mtx);
00085 
00086     bool isAffine() const;
00087     bool isIdentity() const;
00088     bool isInvertible() const;
00089     bool isScaling() const;
00090     bool isRotating() const;
00091     bool isTranslating() const;
00092 
00093     TransformationType type() const;
00094 
00095     inline qreal determinant() const;
00096     qreal det() const;
00097 
00098     qreal m11() const;
00099     qreal m12() const;
00100     qreal m13() const;
00101     qreal m21() const;
00102     qreal m22() const;
00103     qreal m23() const;
00104     qreal m31() const;
00105     qreal m32() const;
00106     qreal m33() const;
00107     qreal dx() const;
00108     qreal dy() const;
00109 
00110     void setMatrix(qreal m11, qreal m12, qreal m13,
00111                    qreal m21, qreal m22, qreal m23,
00112                    qreal m31, qreal m32, qreal m33);
00113 
00114     QTransform inverted(bool *invertible = 0) const;
00115     QTransform adjoint() const;
00116     QTransform transposed() const;
00117 
00118     QTransform &translate(qreal dx, qreal dy);
00119     QTransform &scale(qreal sx, qreal sy);
00120     QTransform &shear(qreal sh, qreal sv);
00121     QTransform &rotate(qreal a, Qt::Axis axis = Qt::ZAxis);
00122     QTransform &rotateRadians(qreal a, Qt::Axis axis = Qt::ZAxis);
00123 
00124     static bool squareToQuad(const QPolygonF &square, QTransform &result);
00125     static bool quadToSquare(const QPolygonF &quad, QTransform &result);
00126     static bool quadToQuad(const QPolygonF &one,
00127                            const QPolygonF &two,
00128                            QTransform &result);
00129 
00130     bool operator==(const QTransform &) const;
00131     bool operator!=(const QTransform &) const;
00132 
00133     QTransform &operator*=(const QTransform &);
00134     QTransform operator*(const QTransform &o) const;
00135 
00136     QTransform &operator=(const QTransform &);
00137 
00138     operator QVariant() const;
00139 
00140     void reset();
00141     QPoint       map(const QPoint &p) const;
00142     QPointF      map(const QPointF &p) const;
00143     QLine        map(const QLine &l) const;
00144     QLineF       map(const QLineF &l) const;
00145     QPolygonF    map(const QPolygonF &a) const;
00146     QPolygon     map(const QPolygon &a) const;
00147     QRegion      map(const QRegion &r) const;
00148     QPainterPath map(const QPainterPath &p) const;
00149     QPolygon     mapToPolygon(const QRect &r) const;
00150     QRect mapRect(const QRect &) const;
00151     QRectF mapRect(const QRectF &) const;
00152     void map(int x, int y, int *tx, int *ty) const;
00153     void map(qreal x, qreal y, qreal *tx, qreal *ty) const;
00154 
00155     const QMatrix &toAffine() const;
00156 
00157     QTransform &operator*=(qreal div);
00158     QTransform &operator/=(qreal div);
00159     QTransform &operator+=(qreal div);
00160     QTransform &operator-=(qreal div);
00161 
00162     static QTransform fromTranslate(qreal dx, qreal dy);
00163     static QTransform fromScale(qreal dx, qreal dy);
00164 
00165 private:
00166     inline QTransform(qreal h11, qreal h12, qreal h13,
00167                       qreal h21, qreal h22, qreal h23,
00168                       qreal h31, qreal h32, qreal h33, bool)
00169         : affine(h11, h12, h21, h22, h31, h32, true)
00170         , m_13(h13), m_23(h23), m_33(h33)
00171         , m_type(TxNone)
00172         , m_dirty(TxProject) {}
00173     inline QTransform(bool)
00174         : affine(true)
00175         , m_13(0), m_23(0), m_33(1)
00176         , m_type(TxNone)
00177         , m_dirty(TxNone) {}
00178     inline TransformationType inline_type() const;
00179     QMatrix affine;
00180     qreal   m_13;
00181     qreal   m_23;
00182     qreal   m_33;
00183 
00184     mutable uint m_type : 5;
00185     mutable uint m_dirty : 5;
00186 
00187     class Private;
00188     Private *d;
00189 };
00190 Q_DECLARE_TYPEINFO(QTransform, Q_MOVABLE_TYPE);
00191 
00192 /******* inlines *****/
00193 inline QTransform::TransformationType QTransform::inline_type() const
00194 {
00195     if (m_dirty == TxNone)
00196         return static_cast<TransformationType>(m_type);
00197     return type();
00198 }
00199 
00200 inline bool QTransform::isAffine() const
00201 {
00202     return inline_type() < TxProject;
00203 }
00204 inline bool QTransform::isIdentity() const
00205 {
00206     return inline_type() == TxNone;
00207 }
00208 
00209 inline bool QTransform::isInvertible() const
00210 {
00211     return !qFuzzyIsNull(determinant());
00212 }
00213 
00214 inline bool QTransform::isScaling() const
00215 {
00216     return type() >= TxScale;
00217 }
00218 inline bool QTransform::isRotating() const
00219 {
00220     return inline_type() >= TxRotate;
00221 }
00222 
00223 inline bool QTransform::isTranslating() const
00224 {
00225     return inline_type() >= TxTranslate;
00226 }
00227 
00228 inline qreal QTransform::determinant() const
00229 {
00230     return affine._m11*(m_33*affine._m22-affine._dy*m_23) -
00231         affine._m21*(m_33*affine._m12-affine._dy*m_13)+affine._dx*(m_23*affine._m12-affine._m22*m_13);
00232 }
00233 inline qreal QTransform::det() const
00234 {
00235     return determinant();
00236 }
00237 inline qreal QTransform::m11() const
00238 {
00239     return affine._m11;
00240 }
00241 inline qreal QTransform::m12() const
00242 {
00243     return affine._m12;
00244 }
00245 inline qreal QTransform::m13() const
00246 {
00247     return m_13;
00248 }
00249 inline qreal QTransform::m21() const
00250 {
00251     return affine._m21;
00252 }
00253 inline qreal QTransform::m22() const
00254 {
00255     return affine._m22;
00256 }
00257 inline qreal QTransform::m23() const
00258 {
00259     return m_23;
00260 }
00261 inline qreal QTransform::m31() const
00262 {
00263     return affine._dx;
00264 }
00265 inline qreal QTransform::m32() const
00266 {
00267     return affine._dy;
00268 }
00269 inline qreal QTransform::m33() const
00270 {
00271     return m_33;
00272 }
00273 inline qreal QTransform::dx() const
00274 {
00275     return affine._dx;
00276 }
00277 inline qreal QTransform::dy() const
00278 {
00279     return affine._dy;
00280 }
00281 
00282 inline QTransform &QTransform::operator*=(qreal num)
00283 {
00284     if (num == 1.)
00285         return *this;
00286     affine._m11 *= num;
00287     affine._m12 *= num;
00288     m_13        *= num;
00289     affine._m21 *= num;
00290     affine._m22 *= num;
00291     m_23        *= num;
00292     affine._dx  *= num;
00293     affine._dy  *= num;
00294     m_33        *= num;
00295     if (m_dirty < TxScale)
00296         m_dirty = TxScale;
00297     return *this;
00298 }
00299 inline QTransform &QTransform::operator/=(qreal div)
00300 {
00301     if (div == 0)
00302         return *this;
00303     div = 1/div;
00304     return operator*=(div);
00305 }
00306 inline QTransform &QTransform::operator+=(qreal num)
00307 {
00308     if (num == 0)
00309         return *this;
00310     affine._m11 += num;
00311     affine._m12 += num;
00312     m_13        += num;
00313     affine._m21 += num;
00314     affine._m22 += num;
00315     m_23        += num;
00316     affine._dx  += num;
00317     affine._dy  += num;
00318     m_33        += num;
00319     m_dirty     = TxProject;
00320     return *this;
00321 }
00322 inline QTransform &QTransform::operator-=(qreal num)
00323 {
00324     if (num == 0)
00325         return *this;
00326     affine._m11 -= num;
00327     affine._m12 -= num;
00328     m_13        -= num;
00329     affine._m21 -= num;
00330     affine._m22 -= num;
00331     m_23        -= num;
00332     affine._dx  -= num;
00333     affine._dy  -= num;
00334     m_33        -= num;
00335     m_dirty     = TxProject;
00336     return *this;
00337 }
00338 
00339 inline bool qFuzzyCompare(const QTransform& t1, const QTransform& t2)
00340 {
00341     return qFuzzyCompare(t1.m11(), t2.m11())
00342         && qFuzzyCompare(t1.m12(), t2.m12())
00343         && qFuzzyCompare(t1.m13(), t2.m13())
00344         && qFuzzyCompare(t1.m21(), t2.m21())
00345         && qFuzzyCompare(t1.m22(), t2.m22())
00346         && qFuzzyCompare(t1.m23(), t2.m23())
00347         && qFuzzyCompare(t1.m31(), t2.m31())
00348         && qFuzzyCompare(t1.m32(), t2.m32())
00349         && qFuzzyCompare(t1.m33(), t2.m33());
00350 }
00351 
00352 
00353 /****** stream functions *******************/
00354 #ifndef QT_NO_DATASTREAM
00355 Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QTransform &);
00356 Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QTransform &);
00357 #endif
00358 
00359 #ifndef QT_NO_DEBUG_STREAM
00360 Q_GUI_EXPORT QDebug operator<<(QDebug, const QTransform &);
00361 #endif
00362 /****** end stream functions *******************/
00363 
00364 // mathematical semantics
00365 Q_GUI_EXPORT_INLINE QPoint operator*(const QPoint &p, const QTransform &m)
00366 { return m.map(p); }
00367 Q_GUI_EXPORT_INLINE QPointF operator*(const QPointF &p, const QTransform &m)
00368 { return m.map(p); }
00369 Q_GUI_EXPORT_INLINE QLineF operator*(const QLineF &l, const QTransform &m)
00370 { return m.map(l); }
00371 Q_GUI_EXPORT_INLINE QLine operator*(const QLine &l, const QTransform &m)
00372 { return m.map(l); }
00373 Q_GUI_EXPORT_INLINE QPolygon operator *(const QPolygon &a, const QTransform &m)
00374 { return m.map(a); }
00375 Q_GUI_EXPORT_INLINE QPolygonF operator *(const QPolygonF &a, const QTransform &m)
00376 { return m.map(a); }
00377 Q_GUI_EXPORT_INLINE QRegion operator *(const QRegion &r, const QTransform &m)
00378 { return m.map(r); }
00379 Q_GUI_EXPORT_INLINE QPainterPath operator *(const QPainterPath &p, const QTransform &m)
00380 { return m.map(p); }
00381 
00382 Q_GUI_EXPORT_INLINE QTransform operator *(const QTransform &a, qreal n)
00383 { QTransform t(a); t *= n; return t; }
00384 Q_GUI_EXPORT_INLINE QTransform operator /(const QTransform &a, qreal n)
00385 { QTransform t(a); t /= n; return t; }
00386 Q_GUI_EXPORT_INLINE QTransform operator +(const QTransform &a, qreal n)
00387 { QTransform t(a); t += n; return t; }
00388 Q_GUI_EXPORT_INLINE QTransform operator -(const QTransform &a, qreal n)
00389 { QTransform t(a); t -= n; return t; }
00390 
00391 QT_END_NAMESPACE
00392 
00393 QT_END_HEADER
00394 
00395 #endif