Changeset 561 for trunk/src/gui/painting/qtransform.cpp
- Timestamp:
- Feb 11, 2010, 11:19:06 PM (15 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk
-
Property svn:mergeinfo
set to (toggle deleted branches)
/branches/vendor/nokia/qt/4.6.1 merged eligible /branches/vendor/nokia/qt/current merged eligible /branches/vendor/trolltech/qt/current 3-149
-
Property svn:mergeinfo
set to (toggle deleted branches)
-
trunk/src/gui/painting/qtransform.cpp
r2 r561 2 2 ** 3 3 ** 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]) 5 6 ** 6 7 ** This file is part of the QtGui module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 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. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you 37 ** @nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 49 49 #include <qmath.h> 50 50 51 52 51 53 QT_BEGIN_NAMESPACE 52 54 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 56 60 #define MAP(x, y, nx, ny) \ 57 61 do { \ … … 77 81 ny = affine._m12 * FX_ + affine._m22 * FY_ + affine._dy; \ 78 82 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; \ 80 86 nx *= w; \ 81 87 ny *= w; \ … … 88 94 \brief The QTransform class specifies 2D transformations of a coordinate system. 89 95 \since 4.3 90 \ingroup multimedia96 \ingroup 91 97 92 98 A transformation specifies how to translate, scale, shear, rotate … … 98 104 method allows casting QTransform to QMatrix. If a perspective 99 105 transformation has been specified on the matrix, then the 100 conversion to an affine QMatrixwill cause loss of data.106 conversion will cause loss of data. 101 107 102 108 QTransform is the recommended transformation class in Qt. … … 122 128 I). The inverted() function returns an inverted copy of \e this 123 129 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. 129 137 130 138 \tableofcontents … … 188 196 matrix, or by using the setMatrix() function later on. They can also 189 197 be manipulated using the translate(), rotate(), scale() and 190 shear() convenience functions ,The currently set values can be198 shear() convenience functions The currently set values can be 191 199 retrieved using the m11(), m12(), m13(), m21(), m22(), m23(), 192 200 m31(), m32(), m33(), dx() and dy() functions. … … 201 209 and \c m21. Setting these elements to values different from zero 202 210 will twist the coordinate system. Rotation is achieved by 203 carefully setting both the shearing factors and the scaling204 factors. Perspective transformation is achieved by carefully setting205 both the projection factors andthe scaling factors.211 212 213 the scaling factors. 206 214 207 215 Here's the combined transformations example using basic matrix … … 231 239 232 240 /*! 241 242 243 244 245 233 246 Constructs an identity matrix. 234 247 … … 239 252 */ 240 253 QTransform::QTransform() 241 : m_13(0), m_23(0), m_33(1) 254 : affine(true) 255 , m_13(0), m_23(0), m_33(1) 242 256 , m_type(TxNone) 243 257 , m_dirty(TxNone) 244 258 { 245 246 259 } 247 260 … … 257 270 qreal h21, qreal h22, qreal h23, 258 271 qreal h31, qreal h32, qreal h33) 259 : affine(h11, h12, h21, h22, h31, h32 ),260 272 : affine(h11, h12, h21, h22, h31, h32 273 m_13(h13), m_23(h23), m_33(h33) 261 274 , m_type(TxNone) 262 275 , m_dirty(TxProject) 263 276 { 264 265 277 } 266 278 … … 274 286 QTransform::QTransform(qreal h11, qreal h12, qreal h21, 275 287 qreal h22, qreal dx, qreal dy) 276 : affine(h11, h12, h21, h22, dx, dy ),277 288 : affine(h11, h12, h21, h22, dx, dy 289 m_13(0), m_23(0), m_33(1) 278 290 , m_type(TxNone) 279 291 , m_dirty(TxShear) 280 292 { 281 282 293 } 283 294 … … 290 301 */ 291 302 QTransform::QTransform(const QMatrix &mtx) 292 : affine(mtx ),303 : affine(mtx), 293 304 m_13(0), m_23(0), m_33(1) 294 305 , m_type(TxNone) 295 306 , m_dirty(TxShear) 296 307 { 297 298 308 } 299 309 … … 318 328 return QTransform(h11, h12, h13, 319 329 h21, h22, h23, 320 h31, h32, h33 );330 h31, h32, h33); 321 331 } 322 332 … … 328 338 QTransform t(affine._m11, affine._m21, affine._dx, 329 339 affine._m12, affine._m22, affine._dy, 330 m_13, m_23, m_33 );340 m_13, m_23, m_33); 331 341 t.m_type = m_type; 332 342 t.m_dirty = m_dirty; … … 346 356 QTransform QTransform::inverted(bool *invertible) const 347 357 { 348 QTransform invert ;358 QTransform invert; 349 359 bool inv = true; 350 qreal det; 351 352 switch(type()) { 360 361 switch(inline_type()) { 353 362 case TxNone: 354 363 break; … … 358 367 break; 359 368 case TxScale: 360 inv = !qFuzzy Compare(affine._m11 + 1,1);361 inv &= !qFuzzy Compare(affine._m22 + 1, 1);369 inv = !qFuzzy1); 370 inv &= !qFuzzy); 362 371 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; 365 374 invert.affine._dx = -affine._dx * invert.affine._m11; 366 375 invert.affine._dy = -affine._dy * invert.affine._m22; … … 373 382 default: 374 383 // general case 375 det = determinant();376 inv = !qFuzzy Compare(det + 1, 1);384 det = determinant(); 385 inv = !qFuzzy); 377 386 if (inv) 378 387 invert = adjoint() / det; … … 398 407 \sa setMatrix() 399 408 */ 400 QTransform & 409 QTransform &QTransform::translate(qreal dx, qreal dy) 401 410 { 402 411 if (dx == 0 && dy == 0) 403 412 return *this; 404 413 405 switch( type()) {414 switch(type()) { 406 415 case TxNone: 407 416 affine._dx = dx; … … 425 434 break; 426 435 } 427 m_dirty |= TxTranslate; 436 if (m_dirty < TxTranslate) 437 m_dirty = TxTranslate; 428 438 return *this; 429 439 } … … 438 448 QTransform QTransform::fromTranslate(qreal dx, qreal dy) 439 449 { 440 QTransform transform(1, 0, 0, 1, dx, dy);450 QTransform transform(1, 0, 0, ); 441 451 if (dx == 0 && dy == 0) 442 transform.m_ dirty= TxNone;452 transform.m_ = TxNone; 443 453 else 444 transform.m_dirty = TxTranslate; 454 transform.m_type = TxTranslate; 455 transform.m_dirty = TxNone; 445 456 return transform; 446 457 } … … 457 468 return *this; 458 469 459 switch( type()) {470 switch(type()) { 460 471 case TxNone: 461 472 case TxTranslate: … … 477 488 break; 478 489 } 479 m_dirty |= TxScale; 490 if (m_dirty < TxScale) 491 m_dirty = TxScale; 480 492 return *this; 481 493 } … … 490 502 QTransform QTransform::fromScale(qreal sx, qreal sy) 491 503 { 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; 495 507 else 496 transform.m_dirty = TxScale; 508 transform.m_type = TxScale; 509 transform.m_dirty = TxNone; 497 510 return transform; 498 511 } … … 506 519 QTransform & QTransform::shear(qreal sh, qreal sv) 507 520 { 508 switch(type()) { 521 if (sh == 0 && sv == 0) 522 return *this; 523 524 switch(inline_type()) { 509 525 case TxNone: 510 526 case TxTranslate: … … 534 550 } 535 551 } 536 m_dirty |= TxShear; 552 if (m_dirty < TxShear) 553 m_dirty = TxShear; 537 554 return *this; 538 555 } … … 575 592 576 593 if (axis == Qt::ZAxis) { 577 switch( type()) {594 switch(type()) { 578 595 case TxNone: 579 596 case TxTranslate: … … 610 627 } 611 628 } 612 m_dirty |= TxRotate; 629 if (m_dirty < TxRotate) 630 m_dirty = TxRotate; 613 631 } else { 614 632 QTransform result; … … 647 665 648 666 if (axis == Qt::ZAxis) { 649 switch( type()) {667 switch(type()) { 650 668 case TxNone: 651 669 case TxTranslate: … … 682 700 } 683 701 } 684 m_dirty |= TxRotate; 702 if (m_dirty < TxRotate) 703 m_dirty = TxRotate; 685 704 } else { 686 705 QTransform result; … … 705 724 bool QTransform::operator==(const QTransform &o) const 706 725 { 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; 712 735 } 713 736 … … 731 754 QTransform & QTransform::operator*=(const QTransform &o) 732 755 { 733 const TransformationType otherType = o. type();756 const TransformationType otherType = o.type(); 734 757 if (otherType == TxNone) 735 758 return *this; 736 759 737 const TransformationType thisType = type();760 const TransformationType thisType = type(); 738 761 if (thisType == TxNone) 739 762 return operator=(o); … … 813 836 QTransform QTransform::operator*(const QTransform &m) const 814 837 { 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; 818 909 } 819 910 … … 872 963 /*! 873 964 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 are875 set to 1.965 to zero, except \c m11 and \c m22 (specifying the scale) 966 set to 1. 876 967 877 968 \sa QTransform(), isIdentity(), {QTransform#Basic Matrix … … 957 1048 << " 32=" << m.m32() 958 1049 << " 33=" << m.m33() 959 << ")";1050 << ; 960 1051 return dbg.space(); 961 1052 } … … 977 1068 qreal x = 0, y = 0; 978 1069 979 TransformationType t = type();1070 TransformationType t = type(); 980 1071 switch(t) { 981 1072 case TxNone: … … 1028 1119 qreal x = 0, y = 0; 1029 1120 1030 TransformationType t = type();1121 TransformationType t = type(); 1031 1122 switch(t) { 1032 1123 case TxNone: … … 1099 1190 qreal x1 = 0, y1 = 0, x2 = 0, y2 = 0; 1100 1191 1101 TransformationType t = type();1192 TransformationType t = type(); 1102 1193 switch(t) { 1103 1194 case TxNone: … … 1158 1249 qreal x1 = 0, y1 = 0, x2 = 0, y2 = 0; 1159 1250 1160 TransformationType t = type();1251 TransformationType t = type(); 1161 1252 switch(t) { 1162 1253 case TxNone: … … 1246 1337 QPolygonF QTransform::map(const QPolygonF &a) const 1247 1338 { 1248 TransformationType t = type(); 1339 TransformationType t = inline_type(); 1340 if (t <= TxTranslate) 1341 return a.translated(affine._dx, affine._dy); 1342 1249 1343 if (t >= QTransform::TxProject) 1250 1344 return mapProjective(*this, a); … … 1273 1367 QPolygon QTransform::map(const QPolygon &a) const 1274 1368 { 1275 TransformationType t = type(); 1369 TransformationType t = inline_type(); 1370 if (t <= TxTranslate) 1371 return a.translated(qRound(affine._dx), qRound(affine._dy)); 1372 1276 1373 if (t >= QTransform::TxProject) 1277 1374 return mapProjective(*this, QPolygonF(a)).toPolygon(); … … 1315 1412 QRegion QTransform::map(const QRegion &r) const 1316 1413 { 1317 TransformationType t = type();1414 TransformationType t = type(); 1318 1415 if (t == TxNone) 1319 1416 return r; 1417 1320 1418 if (t == TxTranslate) { 1321 1419 QRegion copy(r); … … 1324 1422 } 1325 1423 1424 1425 1426 1326 1427 QPainterPath p = map(qt_regionToPath(r)); 1327 1428 return p.toFillPolygon(QTransform()).toPolygon(); … … 1338 1439 1339 1440 const QPointF toPoint() const { 1340 qreal iw = 1 / w;1441 qreal iw = 1 / w; 1341 1442 return QPointF(x * iw, y * iw); 1342 1443 } … … 1352 1453 } 1353 1454 1354 static inline bool lineTo_clipped(QPainterPath &path, const QTransform &transform, const QPointF &a, const QPointF &b, bool needsMoveTo) 1455 static inline bool lineTo_clipped(QPainterPath &path, const QTransform &transform, const QPointF &a, const QPointF &b, 1456 bool needsMoveTo, bool needsLineTo = true) 1355 1457 { 1356 1458 QHomogeneousCoordinate ha = mapHomogeneous(transform, a); … … 1385 1487 path.moveTo(ha.toPoint()); 1386 1488 1387 path.lineTo(hb.toPoint()); 1489 if (needsLineTo) 1490 path.lineTo(hb.toPoint()); 1388 1491 1389 1492 return true; … … 1392 1495 static inline bool cubicTo_clipped(QPainterPath &path, const QTransform &transform, const QPointF &a, const QPointF &b, const QPointF &c, const QPointF &d, bool needsMoveTo) 1393 1496 { 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)) 1415 1503 needsMoveTo = false; 1416 1504 … … 1452 1540 1453 1541 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()); 1456 1545 return result; 1457 1546 } … … 1476 1565 QPainterPath QTransform::map(const QPainterPath &path) const 1477 1566 { 1478 TransformationType t = type();1567 TransformationType t = type(); 1479 1568 if (t == TxNone || path.isEmpty()) 1480 1569 return path; … … 1484 1573 1485 1574 QPainterPath copy = path; 1486 copy.detach();1487 1575 1488 1576 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); 1494 1578 } else { 1579 1495 1580 // Full xform 1496 1581 for (int i=0; i<path.elementCount(); ++i) { … … 1525 1610 QPolygon QTransform::mapToPolygon(const QRect &rect) const 1526 1611 { 1527 TransformationType t = type();1612 TransformationType t = type(); 1528 1613 1529 1614 QPolygon a(4); … … 1679 1764 \a m12, \a m13 \a m21, \a m22, \a m23 \a m31, \a m32 and 1680 1765 \a m33. Note that this function replaces the previous values. 1681 Q Matrixprovides the translate(), rotate(), scale() and shear()1766 Q provides the translate(), rotate(), scale() and shear() 1682 1767 convenience functions to manipulate the various matrix elements 1683 1768 based on the currently defined coordinate system. … … 1697 1782 } 1698 1783 1784 1785 1786 1787 1788 1789 1790 1791 1699 1792 QRect QTransform::mapRect(const QRect &rect) const 1700 1793 { 1701 TransformationType t = type(); 1794 TransformationType t = inline_type(); 1795 if (t <= TxTranslate) 1796 return rect.translated(qRound(affine._dx), qRound(affine._dy)); 1797 1702 1798 if (t <= TxScale) { 1703 1799 int x = qRound(affine._m11*rect.x() + affine._dx); … … 1714 1810 } 1715 1811 return QRect(x, y, w, h); 1716 } else if (t < TxProject ) {1812 } else if (t < TxProject) { 1717 1813 // 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; 1725 1820 MAP(rect.right() + 1, rect.top(), x, y); 1726 1821 xmin = qMin(xmin, x); … … 1767 1862 QRectF QTransform::mapRect(const QRectF &rect) const 1768 1863 { 1769 TransformationType t = type(); 1864 TransformationType t = inline_type(); 1865 if (t <= TxTranslate) 1866 return rect.translated(affine._dx, affine._dy); 1867 1770 1868 if (t <= TxScale) { 1771 1869 qreal x = affine._m11*rect.x() + affine._dx; … … 1782 1880 } 1783 1881 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; 1792 1889 MAP(rect.x() + rect.width(), rect.y(), x, y); 1793 1890 xmin = qMin(xmin, x); … … 1839 1936 void QTransform::map(qreal x, qreal y, qreal *tx, qreal *ty) const 1840 1937 { 1841 TransformationType t = type();1938 TransformationType t = type(); 1842 1939 MAP(x, y, *tx, *ty); 1843 1940 } … … 1853 1950 void QTransform::map(int x, int y, int *tx, int *ty) const 1854 1951 { 1855 TransformationType t = type();1952 TransformationType t = type(); 1856 1953 qreal fx = 0, fy = 0; 1857 1954 MAP(x, y, fx, fy); … … 1861 1958 1862 1959 /*! 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 */ 1865 1965 const QMatrix &QTransform::toAffine() const 1866 1966 { … … 1882 1982 QTransform::TransformationType QTransform::type() const 1883 1983 { 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)) { 1886 1990 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)) { 1888 1996 const qreal dot = affine._m11 * affine._m12 + affine._m21 * affine._m22; 1889 if (qFuzzy Compare(dot + 1, 1))1997 if (qFuzzy)) 1890 1998 m_type = TxRotate; 1891 1999 else 1892 2000 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)) { 1894 2005 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)) { 1896 2010 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; 1903 2019 return static_cast<TransformationType>(m_type); 1904 2020 } … … 1924 2040 /*! 1925 2041 \fn qreal QTransform::det() const 1926 1927 Returns the matrix's determinant. 2042 \obsolete 2043 2044 Returns the matrix's determinant. Use determinant() instead. 1928 2045 */ 1929 2046 … … 2078 2195 \sa reset() 2079 2196 */ 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2080 2208 2081 2209 // returns true if the transform is uniformly scaling … … 2087 2215 const QTransform::TransformationType type = transform.type(); 2088 2216 if (type <= QTransform::TxTranslate) { 2089 *scale = 1; 2217 if (scale) 2218 *scale = 1; 2090 2219 return true; 2091 2220 } else if (type == QTransform::TxScale) { 2092 2221 const qreal xScale = qAbs(transform.m11()); 2093 2222 const qreal yScale = qAbs(transform.m22()); 2094 *scale = qMax(xScale, yScale); 2223 if (scale) 2224 *scale = qMax(xScale, yScale); 2095 2225 return qFuzzyCompare(xScale, yScale); 2096 2226 } … … 2100 2230 const qreal yScale = transform.m12() * transform.m12() 2101 2231 + transform.m22() * transform.m22(); 2102 *scale = qSqrt(qMax(xScale, yScale)); 2232 if (scale) 2233 *scale = qSqrt(qMax(xScale, yScale)); 2103 2234 return type == QTransform::TxRotate && qFuzzyCompare(xScale, yScale); 2104 2235 }
Note:
See TracChangeset
for help on using the changeset viewer.