Ignore:
Timestamp:
Feb 11, 2010, 11:19:06 PM (15 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.6.1 sources.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/gui/painting/qtransform.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information ([email protected])
     4** All rights reserved.
     5** Contact: Nokia Corporation ([email protected])
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you
     37** @nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    4949#include <qmath.h>
    5050
     51
     52
    5153QT_BEGIN_NAMESPACE
    5254
    53 #define Q_NEAR_CLIP 0.000001
    54 
    55 
     55#define Q_NEAR_CLIP (sizeof(qreal) == sizeof(double) ? 0.000001 : 0.0001)
     56
     57#ifdef MAP
     58#  undef MAP
     59#endif
    5660#define MAP(x, y, nx, ny) \
    5761    do { \
     
    7781            ny = affine._m12 * FX_ + affine._m22 * FY_ + affine._dy;        \
    7882            if (t == TxProject) {                                       \
    79                 qreal w = 1./(m_13 * FX_ + m_23 * FY_ + m_33);              \
     83                qreal w = (m_13 * FX_ + m_23 * FY_ + m_33);              \
     84                if (w < qreal(Q_NEAR_CLIP)) w = qreal(Q_NEAR_CLIP);     \
     85                w = 1./w;                                               \
    8086                nx *= w;                                                \
    8187                ny *= w;                                                \
     
    8894    \brief The QTransform class specifies 2D transformations of a coordinate system.
    8995    \since 4.3
    90     \ingroup multimedia
     96    \ingroup
    9197
    9298    A transformation specifies how to translate, scale, shear, rotate
     
    98104    method allows casting QTransform to QMatrix. If a perspective
    99105    transformation has been specified on the matrix, then the
    100     conversion to an affine QMatrix will cause loss of data.
     106    conversion will cause loss of data.
    101107
    102108    QTransform is the recommended transformation class in Qt.
     
    122128    I). The inverted() function returns an inverted copy of \e this
    123129    matrix if it is invertible (otherwise it returns the identity
    124     matrix). In addition, QTransform provides the det() function
    125     returning the matrix's determinant.
    126 
    127     Finally, the QTransform class supports matrix multiplication, and
    128     objects of the class can be streamed as well as compared.
     130    matrix), and adjoint() returns the matrix's classical adjoint.
     131    In addition, QTransform provides the determinant() function which
     132    returns the matrix's determinant.
     133
     134    Finally, the QTransform class supports matrix multiplication, addition
     135    and subtraction, and objects of the class can be streamed as well
     136    as compared.
    129137
    130138    \tableofcontents
     
    188196    matrix, or by using the setMatrix() function later on. They can also
    189197    be manipulated using the translate(), rotate(), scale() and
    190     shear() convenience functions, The currently set values can be
     198    shear() convenience functions The currently set values can be
    191199    retrieved using the m11(), m12(), m13(), m21(), m22(), m23(),
    192200    m31(), m32(), m33(), dx() and dy() functions.
     
    201209    and \c m21. Setting these elements to values different from zero
    202210    will twist the coordinate system. Rotation is achieved by
    203     carefully setting both the shearing factors and the scaling
    204     factors. Perspective transformation is achieved by carefully setting
    205     both the projection factors and the scaling factors.
     211   
     212   
     213    the scaling factors.
    206214
    207215    Here's the combined transformations example using basic matrix
     
    231239
    232240/*!
     241
     242
     243
     244
     245
    233246    Constructs an identity matrix.
    234247
     
    239252*/
    240253QTransform::QTransform()
    241     : m_13(0), m_23(0), m_33(1)
     254    : affine(true)
     255    , m_13(0), m_23(0), m_33(1)
    242256    , m_type(TxNone)
    243257    , m_dirty(TxNone)
    244258{
    245 
    246259}
    247260
     
    257270                       qreal h21, qreal h22, qreal h23,
    258271                       qreal h31, qreal h32, qreal h33)
    259     : affine(h11, h12, h21, h22, h31, h32),
    260       m_13(h13), m_23(h23), m_33(h33)
     272    : affine(h11, h12, h21, h22, h31, h32
     273    m_13(h13), m_23(h23), m_33(h33)
    261274    , m_type(TxNone)
    262275    , m_dirty(TxProject)
    263276{
    264 
    265277}
    266278
     
    274286QTransform::QTransform(qreal h11, qreal h12, qreal h21,
    275287                       qreal h22, qreal dx, qreal dy)
    276     : affine(h11, h12, h21, h22, dx, dy),
    277       m_13(0), m_23(0), m_33(1)
     288    : affine(h11, h12, h21, h22, dx, dy
     289    m_13(0), m_23(0), m_33(1)
    278290    , m_type(TxNone)
    279291    , m_dirty(TxShear)
    280292{
    281 
    282293}
    283294
     
    290301 */
    291302QTransform::QTransform(const QMatrix &mtx)
    292     : affine(mtx),
     303    : affine(mtx),
    293304      m_13(0), m_23(0), m_33(1)
    294305    , m_type(TxNone)
    295306    , m_dirty(TxShear)
    296307{
    297 
    298308}
    299309
     
    318328    return QTransform(h11, h12, h13,
    319329                      h21, h22, h23,
    320                       h31, h32, h33);
     330                      h31, h32, h33);
    321331}
    322332
     
    328338    QTransform t(affine._m11, affine._m21, affine._dx,
    329339                 affine._m12, affine._m22, affine._dy,
    330                  m_13, m_23, m_33);
     340                 m_13, m_23, m_33);
    331341    t.m_type = m_type;
    332342    t.m_dirty = m_dirty;
     
    346356QTransform QTransform::inverted(bool *invertible) const
    347357{
    348     QTransform invert;
     358    QTransform invert;
    349359    bool inv = true;
    350     qreal det;
    351 
    352     switch(type()) {
     360
     361    switch(inline_type()) {
    353362    case TxNone:
    354363        break;
     
    358367        break;
    359368    case TxScale:
    360         inv = !qFuzzyCompare(affine._m11 + 1, 1);
    361         inv &= !qFuzzyCompare(affine._m22 + 1, 1);
     369        inv = !qFuzzy1);
     370        inv &= !qFuzzy);
    362371        if (inv) {
    363             invert.affine._m11 = 1 / affine._m11;
    364             invert.affine._m22 = 1 / affine._m22;
     372            invert.affine._m11 = 1 / affine._m11;
     373            invert.affine._m22 = 1 / affine._m22;
    365374            invert.affine._dx = -affine._dx * invert.affine._m11;
    366375            invert.affine._dy = -affine._dy * invert.affine._m22;
     
    373382    default:
    374383        // general case
    375         det = determinant();
    376         inv = !qFuzzyCompare(det + 1, 1);
     384        det = determinant();
     385        inv = !qFuzzy);
    377386        if (inv)
    378387            invert = adjoint() / det;
     
    398407    \sa setMatrix()
    399408*/
    400 QTransform & QTransform::translate(qreal dx, qreal dy)
     409QTransform &QTransform::translate(qreal dx, qreal dy)
    401410{
    402411    if (dx == 0 && dy == 0)
    403412        return *this;
    404413
    405     switch(type()) {
     414    switch(type()) {
    406415    case TxNone:
    407416        affine._dx = dx;
     
    425434        break;
    426435    }
    427     m_dirty |= TxTranslate;
     436    if (m_dirty < TxTranslate)
     437        m_dirty = TxTranslate;
    428438    return *this;
    429439}
     
    438448QTransform QTransform::fromTranslate(qreal dx, qreal dy)
    439449{
    440     QTransform transform(1, 0, 0, 1, dx, dy);
     450    QTransform transform(1, 0, 0, );
    441451    if (dx == 0 && dy == 0)
    442         transform.m_dirty = TxNone;
     452        transform.m_ = TxNone;
    443453    else
    444         transform.m_dirty = TxTranslate;
     454        transform.m_type = TxTranslate;
     455    transform.m_dirty = TxNone;
    445456    return transform;
    446457}
     
    457468        return *this;
    458469
    459     switch(type()) {
     470    switch(type()) {
    460471    case TxNone:
    461472    case TxTranslate:
     
    477488        break;
    478489    }
    479     m_dirty |= TxScale;
     490    if (m_dirty < TxScale)
     491        m_dirty = TxScale;
    480492    return *this;
    481493}
     
    490502QTransform QTransform::fromScale(qreal sx, qreal sy)
    491503{
    492     QTransform transform(sx, 0, 0, sy, 0, 0);
    493     if (sx == 1 && sy == 1)
    494         transform.m_dirty = TxNone;
     504    QTransform transform(sx, 0, 0, );
     505    if (sx == 1)
     506        transform.m_ = TxNone;
    495507    else
    496         transform.m_dirty = TxScale;
     508        transform.m_type = TxScale;
     509    transform.m_dirty = TxNone;
    497510    return transform;
    498511}
     
    506519QTransform & QTransform::shear(qreal sh, qreal sv)
    507520{
    508     switch(type()) {
     521    if (sh == 0 && sv == 0)
     522        return *this;
     523
     524    switch(inline_type()) {
    509525    case TxNone:
    510526    case TxTranslate:
     
    534550    }
    535551    }
    536     m_dirty |= TxShear;
     552    if (m_dirty < TxShear)
     553        m_dirty = TxShear;
    537554    return *this;
    538555}
     
    575592
    576593    if (axis == Qt::ZAxis) {
    577         switch(type()) {
     594        switch(type()) {
    578595        case TxNone:
    579596        case TxTranslate:
     
    610627        }
    611628        }
    612         m_dirty |= TxRotate;
     629        if (m_dirty < TxRotate)
     630            m_dirty = TxRotate;
    613631    } else {
    614632        QTransform result;
     
    647665
    648666    if (axis == Qt::ZAxis) {
    649         switch(type()) {
     667        switch(type()) {
    650668        case TxNone:
    651669        case TxTranslate:
     
    682700        }
    683701        }
    684         m_dirty |= TxRotate;
     702        if (m_dirty < TxRotate)
     703            m_dirty = TxRotate;
    685704    } else {
    686705        QTransform result;
     
    705724bool QTransform::operator==(const QTransform &o) const
    706725{
    707 #define qFZ qFuzzyCompare
    708     return qFZ(affine._m11, o.affine._m11) &&  qFZ(affine._m12, o.affine._m12) &&  qFZ(m_13, o.m_13)
    709         && qFZ(affine._m21, o.affine._m21) &&  qFZ(affine._m22, o.affine._m22) &&  qFZ(m_23, o.m_23)
    710         && qFZ(affine._dx, o.affine._dx) &&  qFZ(affine._dy, o.affine._dy) &&  qFZ(m_33, o.m_33);
    711 #undef qFZ
     726    return affine._m11 == o.affine._m11 &&
     727           affine._m12 == o.affine._m12 &&
     728           affine._m21 == o.affine._m21 &&
     729           affine._m22 == o.affine._m22 &&
     730           affine._dx == o.affine._dx &&
     731           affine._dy == o.affine._dy &&
     732           m_13 == o.m_13 &&
     733           m_23 == o.m_23 &&
     734           m_33 == o.m_33;
    712735}
    713736
     
    731754QTransform & QTransform::operator*=(const QTransform &o)
    732755{
    733     const TransformationType otherType = o.type();
     756    const TransformationType otherType = o.type();
    734757    if (otherType == TxNone)
    735758        return *this;
    736759
    737     const TransformationType thisType = type();
     760    const TransformationType thisType = type();
    738761    if (thisType == TxNone)
    739762        return operator=(o);
     
    813836QTransform QTransform::operator*(const QTransform &m) const
    814837{
    815     QTransform result = *this;
    816     result *= m;
    817     return result;
     838    const TransformationType otherType = m.inline_type();
     839    if (otherType == TxNone)
     840        return *this;
     841
     842    const TransformationType thisType = inline_type();
     843    if (thisType == TxNone)
     844        return m;
     845
     846    QTransform t(true);
     847    TransformationType type = qMax(thisType, otherType);
     848    switch(type) {
     849    case TxNone:
     850        break;
     851    case TxTranslate:
     852        t.affine._dx = affine._dx + m.affine._dx;
     853        t.affine._dy += affine._dy + m.affine._dy;
     854        break;
     855    case TxScale:
     856    {
     857        qreal m11 = affine._m11*m.affine._m11;
     858        qreal m22 = affine._m22*m.affine._m22;
     859
     860        qreal m31 = affine._dx*m.affine._m11 + m.affine._dx;
     861        qreal m32 = affine._dy*m.affine._m22 + m.affine._dy;
     862
     863        t.affine._m11 = m11;
     864        t.affine._m22 = m22;
     865        t.affine._dx = m31; t.affine._dy = m32;
     866        break;
     867    }
     868    case TxRotate:
     869    case TxShear:
     870    {
     871        qreal m11 = affine._m11*m.affine._m11 + affine._m12*m.affine._m21;
     872        qreal m12 = affine._m11*m.affine._m12 + affine._m12*m.affine._m22;
     873
     874        qreal m21 = affine._m21*m.affine._m11 + affine._m22*m.affine._m21;
     875        qreal m22 = affine._m21*m.affine._m12 + affine._m22*m.affine._m22;
     876
     877        qreal m31 = affine._dx*m.affine._m11 + affine._dy*m.affine._m21 + m.affine._dx;
     878        qreal m32 = affine._dx*m.affine._m12 + affine._dy*m.affine._m22 + m.affine._dy;
     879
     880        t.affine._m11 = m11; t.affine._m12 = m12;
     881        t.affine._m21 = m21; t.affine._m22 = m22;
     882        t.affine._dx = m31; t.affine._dy = m32;
     883        break;
     884    }
     885    case TxProject:
     886    {
     887        qreal m11 = affine._m11*m.affine._m11 + affine._m12*m.affine._m21 + m_13*m.affine._dx;
     888        qreal m12 = affine._m11*m.affine._m12 + affine._m12*m.affine._m22 + m_13*m.affine._dy;
     889        qreal m13 = affine._m11*m.m_13 + affine._m12*m.m_23 + m_13*m.m_33;
     890
     891        qreal m21 = affine._m21*m.affine._m11 + affine._m22*m.affine._m21 + m_23*m.affine._dx;
     892        qreal m22 = affine._m21*m.affine._m12 + affine._m22*m.affine._m22 + m_23*m.affine._dy;
     893        qreal m23 = affine._m21*m.m_13 + affine._m22*m.m_23 + m_23*m.m_33;
     894
     895        qreal m31 = affine._dx*m.affine._m11 + affine._dy*m.affine._m21 + m_33*m.affine._dx;
     896        qreal m32 = affine._dx*m.affine._m12 + affine._dy*m.affine._m22 + m_33*m.affine._dy;
     897        qreal m33 = affine._dx*m.m_13 + affine._dy*m.m_23 + m_33*m.m_33;
     898
     899        t.affine._m11 = m11; t.affine._m12 = m12; t.m_13 = m13;
     900        t.affine._m21 = m21; t.affine._m22 = m22; t.m_23 = m23;
     901        t.affine._dx = m31; t.affine._dy = m32; t.m_33 = m33;
     902    }
     903    }
     904
     905    t.m_dirty = type;
     906    t.m_type = type;
     907
     908    return t;
    818909}
    819910
     
    872963/*!
    873964    Resets the matrix to an identity matrix, i.e. all elements are set
    874     to zero, except \c m11 and \c m22 (specifying the scale) which are
    875     set to 1.
     965    to zero, except \c m11 and \c m22 (specifying the scale)
     966    set to 1.
    876967
    877968    \sa QTransform(), isIdentity(), {QTransform#Basic Matrix
     
    9571048                  << " 32=" << m.m32()
    9581049                  << " 33=" << m.m33()
    959                   << ")";
     1050                  << ;
    9601051    return dbg.space();
    9611052}
     
    9771068    qreal x = 0, y = 0;
    9781069
    979     TransformationType t = type();
     1070    TransformationType t = type();
    9801071    switch(t) {
    9811072    case TxNone:
     
    10281119    qreal x = 0, y = 0;
    10291120
    1030     TransformationType t = type();
     1121    TransformationType t = type();
    10311122    switch(t) {
    10321123    case TxNone:
     
    10991190    qreal x1 = 0, y1 = 0, x2 = 0, y2 = 0;
    11001191
    1101     TransformationType t = type();
     1192    TransformationType t = type();
    11021193    switch(t) {
    11031194    case TxNone:
     
    11581249    qreal x1 = 0, y1 = 0, x2 = 0, y2 = 0;
    11591250
    1160     TransformationType t = type();
     1251    TransformationType t = type();
    11611252    switch(t) {
    11621253    case TxNone:
     
    12461337QPolygonF QTransform::map(const QPolygonF &a) const
    12471338{
    1248     TransformationType t = type();
     1339    TransformationType t = inline_type();
     1340    if (t <= TxTranslate)
     1341        return a.translated(affine._dx, affine._dy);
     1342
    12491343    if (t >= QTransform::TxProject)
    12501344        return mapProjective(*this, a);
     
    12731367QPolygon QTransform::map(const QPolygon &a) const
    12741368{
    1275     TransformationType t = type();
     1369    TransformationType t = inline_type();
     1370    if (t <= TxTranslate)
     1371        return a.translated(qRound(affine._dx), qRound(affine._dy));
     1372
    12761373    if (t >= QTransform::TxProject)
    12771374        return mapProjective(*this, QPolygonF(a)).toPolygon();
     
    13151412QRegion QTransform::map(const QRegion &r) const
    13161413{
    1317     TransformationType t = type();
     1414    TransformationType t = type();
    13181415    if (t == TxNone)
    13191416        return r;
     1417
    13201418    if (t == TxTranslate) {
    13211419        QRegion copy(r);
     
    13241422    }
    13251423
     1424
     1425
     1426
    13261427    QPainterPath p = map(qt_regionToPath(r));
    13271428    return p.toFillPolygon(QTransform()).toPolygon();
     
    13381439
    13391440    const QPointF toPoint() const {
    1340         qreal iw = 1 / w;
     1441        qreal iw = 1 / w;
    13411442        return QPointF(x * iw, y * iw);
    13421443    }
     
    13521453}
    13531454
    1354 static inline bool lineTo_clipped(QPainterPath &path, const QTransform &transform, const QPointF &a, const QPointF &b, bool needsMoveTo)
     1455static inline bool lineTo_clipped(QPainterPath &path, const QTransform &transform, const QPointF &a, const QPointF &b,
     1456                                  bool needsMoveTo, bool needsLineTo = true)
    13551457{
    13561458    QHomogeneousCoordinate ha = mapHomogeneous(transform, a);
     
    13851487        path.moveTo(ha.toPoint());
    13861488
    1387     path.lineTo(hb.toPoint());
     1489    if (needsLineTo)
     1490        path.lineTo(hb.toPoint());
    13881491
    13891492    return true;
     
    13921495static inline bool cubicTo_clipped(QPainterPath &path, const QTransform &transform, const QPointF &a, const QPointF &b, const QPointF &c, const QPointF &d, bool needsMoveTo)
    13931496{
    1394     const QHomogeneousCoordinate ha = mapHomogeneous(transform, a);
    1395     const QHomogeneousCoordinate hb = mapHomogeneous(transform, b);
    1396     const QHomogeneousCoordinate hc = mapHomogeneous(transform, c);
    1397     const QHomogeneousCoordinate hd = mapHomogeneous(transform, d);
    1398 
    1399     if (ha.w < Q_NEAR_CLIP && hb.w < Q_NEAR_CLIP && hc.w < Q_NEAR_CLIP && hd.w < Q_NEAR_CLIP)
    1400         return false;
    1401 
    1402     if (ha.w >= Q_NEAR_CLIP && hb.w >= Q_NEAR_CLIP && hc.w >= Q_NEAR_CLIP && hd.w >= Q_NEAR_CLIP) {
    1403         if (needsMoveTo)
    1404             path.moveTo(ha.toPoint());
    1405 
    1406         path.cubicTo(hb.toPoint(), hc.toPoint(), hd.toPoint());
    1407         return true;
    1408     }
    1409 
    1410     if (lineTo_clipped(path, transform, a, b, needsMoveTo))
    1411             needsMoveTo = false;
    1412     if (lineTo_clipped(path, transform, b, c, needsMoveTo))
    1413             needsMoveTo = false;
    1414     if (lineTo_clipped(path, transform, c, d, needsMoveTo))
     1497    // Convert projective xformed curves to line
     1498    // segments so they can be transformed more accurately
     1499    QPolygonF segment = QBezier::fromPoints(a, b, c, d).toPolygon();
     1500
     1501    for (int i = 0; i < segment.size() - 1; ++i)
     1502        if (lineTo_clipped(path, transform, segment.at(i), segment.at(i+1), needsMoveTo))
    14151503            needsMoveTo = false;
    14161504
     
    14521540
    14531541    if (path.elementCount() > 0 && lastMoveTo != last)
    1454         lineTo_clipped(result, transform, last, lastMoveTo, needsMoveTo);
    1455 
     1542        lineTo_clipped(result, transform, last, lastMoveTo, needsMoveTo, false);
     1543
     1544    result.setFillRule(path.fillRule());
    14561545    return result;
    14571546}
     
    14761565QPainterPath QTransform::map(const QPainterPath &path) const
    14771566{
    1478     TransformationType t = type();
     1567    TransformationType t = type();
    14791568    if (t == TxNone || path.isEmpty())
    14801569        return path;
     
    14841573
    14851574    QPainterPath copy = path;
    1486     copy.detach();
    14871575
    14881576    if (t == TxTranslate) {
    1489         for (int i=0; i<path.elementCount(); ++i) {
    1490             QPainterPath::Element &e = copy.d_ptr->elements[i];
    1491             e.x += affine._dx;
    1492             e.y += affine._dy;
    1493         }
     1577        copy.translate(affine._dx, affine._dy);
    14941578    } else {
     1579
    14951580        // Full xform
    14961581        for (int i=0; i<path.elementCount(); ++i) {
     
    15251610QPolygon QTransform::mapToPolygon(const QRect &rect) const
    15261611{
    1527     TransformationType t = type();
     1612    TransformationType t = type();
    15281613
    15291614    QPolygon a(4);
     
    16791764    \a m12, \a m13 \a m21, \a m22, \a m23 \a m31, \a m32 and
    16801765    \a m33. Note that this function replaces the previous values.
    1681     QMatrix provides the translate(), rotate(), scale() and shear()
     1766    Q provides the translate(), rotate(), scale() and shear()
    16821767    convenience functions to manipulate the various matrix elements
    16831768    based on the currently defined coordinate system.
     
    16971782}
    16981783
     1784
     1785
     1786
     1787
     1788
     1789
     1790
     1791
    16991792QRect QTransform::mapRect(const QRect &rect) const
    17001793{
    1701     TransformationType t = type();
     1794    TransformationType t = inline_type();
     1795    if (t <= TxTranslate)
     1796        return rect.translated(qRound(affine._dx), qRound(affine._dy));
     1797
    17021798    if (t <= TxScale) {
    17031799        int x = qRound(affine._m11*rect.x() + affine._dx);
     
    17141810        }
    17151811        return QRect(x, y, w, h);
    1716     } else if (t < TxProject) {
     1812    } else if (t < TxProject) {
    17171813        // see mapToPolygon for explanations of the algorithm.
    1718         qreal x0 = 0, y0 = 0;
    1719         qreal x, y;
    1720         MAP(rect.left(), rect.top(), x0, y0);
    1721         qreal xmin = x0;
    1722         qreal ymin = y0;
    1723         qreal xmax = x0;
    1724         qreal ymax = y0;
     1814        qreal x = 0, y = 0;
     1815        MAP(rect.left(), rect.top(), x, y);
     1816        qreal xmin = x;
     1817        qreal ymin = y;
     1818        qreal xmax = x;
     1819        qreal ymax = y;
    17251820        MAP(rect.right() + 1, rect.top(), x, y);
    17261821        xmin = qMin(xmin, x);
     
    17671862QRectF QTransform::mapRect(const QRectF &rect) const
    17681863{
    1769     TransformationType t = type();
     1864    TransformationType t = inline_type();
     1865    if (t <= TxTranslate)
     1866        return rect.translated(affine._dx, affine._dy);
     1867
    17701868    if (t <= TxScale) {
    17711869        qreal x = affine._m11*rect.x() + affine._dx;
     
    17821880        }
    17831881        return QRectF(x, y, w, h);
    1784     } else if (t < TxProject) {
    1785         qreal x0 = 0, y0 = 0;
    1786         qreal x, y;
    1787         MAP(rect.x(), rect.y(), x0, y0);
    1788         qreal xmin = x0;
    1789         qreal ymin = y0;
    1790         qreal xmax = x0;
    1791         qreal ymax = y0;
     1882    } else if (t < TxProject || !needsPerspectiveClipping(rect, *this)) {
     1883        qreal x = 0, y = 0;
     1884        MAP(rect.x(), rect.y(), x, y);
     1885        qreal xmin = x;
     1886        qreal ymin = y;
     1887        qreal xmax = x;
     1888        qreal ymax = y;
    17921889        MAP(rect.x() + rect.width(), rect.y(), x, y);
    17931890        xmin = qMin(xmin, x);
     
    18391936void QTransform::map(qreal x, qreal y, qreal *tx, qreal *ty) const
    18401937{
    1841     TransformationType t = type();
     1938    TransformationType t = type();
    18421939    MAP(x, y, *tx, *ty);
    18431940}
     
    18531950void QTransform::map(int x, int y, int *tx, int *ty) const
    18541951{
    1855     TransformationType t = type();
     1952    TransformationType t = type();
    18561953    qreal fx = 0, fy = 0;
    18571954    MAP(x, y, fx, fy);
     
    18611958
    18621959/*!
    1863   Returns the QTransform cast to a QMatrix.
    1864  */
     1960  Returns the QTransform as an affine matrix.
     1961
     1962  \warning If a perspective transformation has been specified,
     1963  then the conversion will cause loss of data.
     1964*/
    18651965const QMatrix &QTransform::toAffine() const
    18661966{
     
    18821982QTransform::TransformationType QTransform::type() const
    18831983{
    1884     if (m_dirty >= m_type) {
    1885         if (m_dirty > TxShear && (!qFuzzyCompare(m_13 + 1, 1) || !qFuzzyCompare(m_23 + 1, 1)))
     1984    if(m_dirty == TxNone || m_dirty < m_type)
     1985        return static_cast<TransformationType>(m_type);
     1986
     1987    switch (static_cast<TransformationType>(m_dirty)) {
     1988    case TxProject:
     1989        if (!qFuzzyIsNull(m_13) || !qFuzzyIsNull(m_23) || !qFuzzyIsNull(m_33 - 1)) {
    18861990             m_type = TxProject;
    1887         else if (m_dirty > TxScale && (!qFuzzyCompare(affine._m12 + 1, 1) || !qFuzzyCompare(affine._m21 + 1, 1))) {
     1991             break;
     1992         }
     1993    case TxShear:
     1994    case TxRotate:
     1995        if (!qFuzzyIsNull(affine._m12) || !qFuzzyIsNull(affine._m21)) {
    18881996            const qreal dot = affine._m11 * affine._m12 + affine._m21 * affine._m22;
    1889             if (qFuzzyCompare(dot + 1, 1))
     1997            if (qFuzzy))
    18901998                m_type = TxRotate;
    18911999            else
    18922000                m_type = TxShear;
    1893         } else if (m_dirty > TxTranslate && (!qFuzzyCompare(affine._m11, 1) || !qFuzzyCompare(affine._m22, 1) || !qFuzzyCompare(m_33, 1)))
     2001            break;
     2002        }
     2003    case TxScale:
     2004        if (!qFuzzyIsNull(affine._m11 - 1) || !qFuzzyIsNull(affine._m22 - 1)) {
    18942005            m_type = TxScale;
    1895         else if (m_dirty > TxNone && (!qFuzzyCompare(affine._dx + 1, 1) || !qFuzzyCompare(affine._dy + 1, 1)))
     2006            break;
     2007        }
     2008    case TxTranslate:
     2009        if (!qFuzzyIsNull(affine._dx) || !qFuzzyIsNull(affine._dy)) {
    18962010            m_type = TxTranslate;
    1897         else
    1898             m_type = TxNone;
    1899 
    1900         m_dirty = TxNone;
    1901     }
    1902 
     2011            break;
     2012        }
     2013    case TxNone:
     2014        m_type = TxNone;
     2015        break;
     2016    }
     2017
     2018    m_dirty = TxNone;
    19032019    return static_cast<TransformationType>(m_type);
    19042020}
     
    19242040/*!
    19252041    \fn qreal QTransform::det() const
    1926 
    1927     Returns the matrix's determinant.
     2042    \obsolete
     2043
     2044    Returns the matrix's determinant. Use determinant() instead.
    19282045*/
    19292046
     
    20782195    \sa reset()
    20792196*/
     2197
     2198
     2199
     2200
     2201
     2202
     2203
     2204
     2205
     2206
     2207
    20802208
    20812209// returns true if the transform is uniformly scaling
     
    20872215    const QTransform::TransformationType type = transform.type();
    20882216    if (type <= QTransform::TxTranslate) {
    2089         *scale = 1;
     2217        if (scale)
     2218            *scale = 1;
    20902219        return true;
    20912220    } else if (type == QTransform::TxScale) {
    20922221        const qreal xScale = qAbs(transform.m11());
    20932222        const qreal yScale = qAbs(transform.m22());
    2094         *scale = qMax(xScale, yScale);
     2223        if (scale)
     2224            *scale = qMax(xScale, yScale);
    20952225        return qFuzzyCompare(xScale, yScale);
    20962226    }
     
    21002230    const qreal yScale = transform.m12() * transform.m12()
    21012231                         + transform.m22() * transform.m22();
    2102     *scale = qSqrt(qMax(xScale, yScale));
     2232    if (scale)
     2233        *scale = qSqrt(qMax(xScale, yScale));
    21032234    return type == QTransform::TxRotate && qFuzzyCompare(xScale, yScale);
    21042235}
Note: See TracChangeset for help on using the changeset viewer.