1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc. 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 68260a895869beaa4cab9f8b915e457728f41e561reed@google.com */ 78260a895869beaa4cab9f8b915e457728f41e561reed@google.com 88260a895869beaa4cab9f8b915e457728f41e561reed@google.com#ifndef SkMatrix44_DEFINED 98260a895869beaa4cab9f8b915e457728f41e561reed@google.com#define SkMatrix44_DEFINED 108260a895869beaa4cab9f8b915e457728f41e561reed@google.com 118260a895869beaa4cab9f8b915e457728f41e561reed@google.com#include "SkMatrix.h" 128260a895869beaa4cab9f8b915e457728f41e561reed@google.com#include "SkScalar.h" 138260a895869beaa4cab9f8b915e457728f41e561reed@google.com 148260a895869beaa4cab9f8b915e457728f41e561reed@google.com#ifdef SK_MSCALAR_IS_DOUBLE 157d68335eb427547606497eb4edea81acce7891f9reed@google.com#ifdef SK_MSCALAR_IS_FLOAT 167d68335eb427547606497eb4edea81acce7891f9reed@google.com #error "can't define MSCALAR both as DOUBLE and FLOAT" 177d68335eb427547606497eb4edea81acce7891f9reed@google.com#endif 188260a895869beaa4cab9f8b915e457728f41e561reed@google.com typedef double SkMScalar; 197d68335eb427547606497eb4edea81acce7891f9reed@google.com 208260a895869beaa4cab9f8b915e457728f41e561reed@google.com static inline double SkFloatToMScalar(float x) { 218260a895869beaa4cab9f8b915e457728f41e561reed@google.com return static_cast<double>(x); 228260a895869beaa4cab9f8b915e457728f41e561reed@google.com } 238260a895869beaa4cab9f8b915e457728f41e561reed@google.com static inline float SkMScalarToFloat(double x) { 248260a895869beaa4cab9f8b915e457728f41e561reed@google.com return static_cast<float>(x); 258260a895869beaa4cab9f8b915e457728f41e561reed@google.com } 268260a895869beaa4cab9f8b915e457728f41e561reed@google.com static inline double SkDoubleToMScalar(double x) { 278260a895869beaa4cab9f8b915e457728f41e561reed@google.com return x; 288260a895869beaa4cab9f8b915e457728f41e561reed@google.com } 298260a895869beaa4cab9f8b915e457728f41e561reed@google.com static inline double SkMScalarToDouble(double x) { 308260a895869beaa4cab9f8b915e457728f41e561reed@google.com return x; 318260a895869beaa4cab9f8b915e457728f41e561reed@google.com } 328260a895869beaa4cab9f8b915e457728f41e561reed@google.com static const SkMScalar SK_MScalarPI = 3.141592653589793; 335596a69e9f7884e3042bceba071c468dee52aa7fvollick@chromium.org#elif defined SK_MSCALAR_IS_FLOAT 347d68335eb427547606497eb4edea81acce7891f9reed@google.com#ifdef SK_MSCALAR_IS_DOUBLE 357d68335eb427547606497eb4edea81acce7891f9reed@google.com #error "can't define MSCALAR both as DOUBLE and FLOAT" 367d68335eb427547606497eb4edea81acce7891f9reed@google.com#endif 378260a895869beaa4cab9f8b915e457728f41e561reed@google.com typedef float SkMScalar; 380264fb4543b0d8cebe00f1ee32433784f4ceb074skia.committer@gmail.com 398260a895869beaa4cab9f8b915e457728f41e561reed@google.com static inline float SkFloatToMScalar(float x) { 408260a895869beaa4cab9f8b915e457728f41e561reed@google.com return x; 418260a895869beaa4cab9f8b915e457728f41e561reed@google.com } 428260a895869beaa4cab9f8b915e457728f41e561reed@google.com static inline float SkMScalarToFloat(float x) { 438260a895869beaa4cab9f8b915e457728f41e561reed@google.com return x; 448260a895869beaa4cab9f8b915e457728f41e561reed@google.com } 458260a895869beaa4cab9f8b915e457728f41e561reed@google.com static inline float SkDoubleToMScalar(double x) { 468260a895869beaa4cab9f8b915e457728f41e561reed@google.com return static_cast<float>(x); 478260a895869beaa4cab9f8b915e457728f41e561reed@google.com } 488260a895869beaa4cab9f8b915e457728f41e561reed@google.com static inline double SkMScalarToDouble(float x) { 498260a895869beaa4cab9f8b915e457728f41e561reed@google.com return static_cast<double>(x); 508260a895869beaa4cab9f8b915e457728f41e561reed@google.com } 518260a895869beaa4cab9f8b915e457728f41e561reed@google.com static const SkMScalar SK_MScalarPI = 3.14159265f; 528260a895869beaa4cab9f8b915e457728f41e561reed@google.com#endif 538260a895869beaa4cab9f8b915e457728f41e561reed@google.com 5420d44677a1940c17ae9c64420b013d76bf895dd5reed@google.com#define SkMScalarToScalar SkMScalarToFloat 5520d44677a1940c17ae9c64420b013d76bf895dd5reed@google.com#define SkScalarToMScalar SkFloatToMScalar 5672e49b8982586a5d8b0425f16d909c05a36ea8c3bsalomon@google.com 578260a895869beaa4cab9f8b915e457728f41e561reed@google.comstatic const SkMScalar SK_MScalar1 = 1; 588260a895869beaa4cab9f8b915e457728f41e561reed@google.com 598260a895869beaa4cab9f8b915e457728f41e561reed@google.com/////////////////////////////////////////////////////////////////////////////// 608260a895869beaa4cab9f8b915e457728f41e561reed@google.com 618260a895869beaa4cab9f8b915e457728f41e561reed@google.comstruct SkVector4 { 628260a895869beaa4cab9f8b915e457728f41e561reed@google.com SkScalar fData[4]; 638260a895869beaa4cab9f8b915e457728f41e561reed@google.com 648260a895869beaa4cab9f8b915e457728f41e561reed@google.com SkVector4() { 658260a895869beaa4cab9f8b915e457728f41e561reed@google.com this->set(0, 0, 0, 1); 668260a895869beaa4cab9f8b915e457728f41e561reed@google.com } 678260a895869beaa4cab9f8b915e457728f41e561reed@google.com SkVector4(const SkVector4& src) { 688260a895869beaa4cab9f8b915e457728f41e561reed@google.com memcpy(fData, src.fData, sizeof(fData)); 698260a895869beaa4cab9f8b915e457728f41e561reed@google.com } 708260a895869beaa4cab9f8b915e457728f41e561reed@google.com SkVector4(SkScalar x, SkScalar y, SkScalar z, SkScalar w = SK_Scalar1) { 718260a895869beaa4cab9f8b915e457728f41e561reed@google.com fData[0] = x; 728260a895869beaa4cab9f8b915e457728f41e561reed@google.com fData[1] = y; 738260a895869beaa4cab9f8b915e457728f41e561reed@google.com fData[2] = z; 748260a895869beaa4cab9f8b915e457728f41e561reed@google.com fData[3] = w; 758260a895869beaa4cab9f8b915e457728f41e561reed@google.com } 768260a895869beaa4cab9f8b915e457728f41e561reed@google.com 778260a895869beaa4cab9f8b915e457728f41e561reed@google.com SkVector4& operator=(const SkVector4& src) { 788260a895869beaa4cab9f8b915e457728f41e561reed@google.com memcpy(fData, src.fData, sizeof(fData)); 798260a895869beaa4cab9f8b915e457728f41e561reed@google.com return *this; 808260a895869beaa4cab9f8b915e457728f41e561reed@google.com } 818260a895869beaa4cab9f8b915e457728f41e561reed@google.com 828260a895869beaa4cab9f8b915e457728f41e561reed@google.com bool operator==(const SkVector4& v) { 838260a895869beaa4cab9f8b915e457728f41e561reed@google.com return fData[0] == v.fData[0] && fData[1] == v.fData[1] && 848260a895869beaa4cab9f8b915e457728f41e561reed@google.com fData[2] == v.fData[2] && fData[3] == v.fData[3]; 858260a895869beaa4cab9f8b915e457728f41e561reed@google.com } 868260a895869beaa4cab9f8b915e457728f41e561reed@google.com bool operator!=(const SkVector4& v) { 878260a895869beaa4cab9f8b915e457728f41e561reed@google.com return !(*this == v); 888260a895869beaa4cab9f8b915e457728f41e561reed@google.com } 898260a895869beaa4cab9f8b915e457728f41e561reed@google.com bool equals(SkScalar x, SkScalar y, SkScalar z, SkScalar w = SK_Scalar1) { 908260a895869beaa4cab9f8b915e457728f41e561reed@google.com return fData[0] == x && fData[1] == y && 918260a895869beaa4cab9f8b915e457728f41e561reed@google.com fData[2] == z && fData[3] == w; 928260a895869beaa4cab9f8b915e457728f41e561reed@google.com } 938260a895869beaa4cab9f8b915e457728f41e561reed@google.com 948260a895869beaa4cab9f8b915e457728f41e561reed@google.com void set(SkScalar x, SkScalar y, SkScalar z, SkScalar w = SK_Scalar1) { 958260a895869beaa4cab9f8b915e457728f41e561reed@google.com fData[0] = x; 968260a895869beaa4cab9f8b915e457728f41e561reed@google.com fData[1] = y; 978260a895869beaa4cab9f8b915e457728f41e561reed@google.com fData[2] = z; 988260a895869beaa4cab9f8b915e457728f41e561reed@google.com fData[3] = w; 998260a895869beaa4cab9f8b915e457728f41e561reed@google.com } 1008260a895869beaa4cab9f8b915e457728f41e561reed@google.com}; 1018260a895869beaa4cab9f8b915e457728f41e561reed@google.com 1027cfb9c7b6186bf1e42b7d13466eab94470587e7etomhudson@google.comclass SK_API SkMatrix44 { 1038260a895869beaa4cab9f8b915e457728f41e561reed@google.compublic: 10457a54e33cfe771c792b1086ba67484cb95938d5dvollick@chromium.org 10557a54e33cfe771c792b1086ba67484cb95938d5dvollick@chromium.org enum Uninitialized_Constructor { 10657a54e33cfe771c792b1086ba67484cb95938d5dvollick@chromium.org kUninitialized_Constructor 10757a54e33cfe771c792b1086ba67484cb95938d5dvollick@chromium.org }; 10857a54e33cfe771c792b1086ba67484cb95938d5dvollick@chromium.org enum Identity_Constructor { 10957a54e33cfe771c792b1086ba67484cb95938d5dvollick@chromium.org kIdentity_Constructor 11057a54e33cfe771c792b1086ba67484cb95938d5dvollick@chromium.org }; 11157a54e33cfe771c792b1086ba67484cb95938d5dvollick@chromium.org 11257a54e33cfe771c792b1086ba67484cb95938d5dvollick@chromium.org SkMatrix44(Uninitialized_Constructor) { } 11357a54e33cfe771c792b1086ba67484cb95938d5dvollick@chromium.org SkMatrix44(Identity_Constructor) { this->setIdentity(); } 11457a54e33cfe771c792b1086ba67484cb95938d5dvollick@chromium.org 1154469938e92d779dff05e745559e67907bbf21e78reed@google.com SK_ATTR_DEPRECATED("use the constructors that take an enum") 1167d68335eb427547606497eb4edea81acce7891f9reed@google.com SkMatrix44() { this->setIdentity(); } 117d53025364a8062b5c72f3f9ed54a613a1ae17958reed@google.com 118d53025364a8062b5c72f3f9ed54a613a1ae17958reed@google.com SkMatrix44(const SkMatrix44& src) { 119d53025364a8062b5c72f3f9ed54a613a1ae17958reed@google.com memcpy(fMat, src.fMat, sizeof(fMat)); 120d53025364a8062b5c72f3f9ed54a613a1ae17958reed@google.com fTypeMask = src.fTypeMask; 121d53025364a8062b5c72f3f9ed54a613a1ae17958reed@google.com } 122d53025364a8062b5c72f3f9ed54a613a1ae17958reed@google.com 123d53025364a8062b5c72f3f9ed54a613a1ae17958reed@google.com SkMatrix44(const SkMatrix44& a, const SkMatrix44& b) { 124d53025364a8062b5c72f3f9ed54a613a1ae17958reed@google.com this->setConcat(a, b); 125d53025364a8062b5c72f3f9ed54a613a1ae17958reed@google.com } 1268260a895869beaa4cab9f8b915e457728f41e561reed@google.com 1278260a895869beaa4cab9f8b915e457728f41e561reed@google.com SkMatrix44& operator=(const SkMatrix44& src) { 1283fda0eadac18dc3071e2bb2979512bd580b39eadreed@google.com if (&src != this) { 1293fda0eadac18dc3071e2bb2979512bd580b39eadreed@google.com memcpy(fMat, src.fMat, sizeof(fMat)); 1303fda0eadac18dc3071e2bb2979512bd580b39eadreed@google.com fTypeMask = src.fTypeMask; 1313fda0eadac18dc3071e2bb2979512bd580b39eadreed@google.com } 1328260a895869beaa4cab9f8b915e457728f41e561reed@google.com return *this; 1338260a895869beaa4cab9f8b915e457728f41e561reed@google.com } 1348260a895869beaa4cab9f8b915e457728f41e561reed@google.com 135631940c8c44e92939fc95d305b87be64eb9b886ereed@google.com bool operator==(const SkMatrix44& other) const; 1368260a895869beaa4cab9f8b915e457728f41e561reed@google.com bool operator!=(const SkMatrix44& other) const { 137631940c8c44e92939fc95d305b87be64eb9b886ereed@google.com return !(other == *this); 1388260a895869beaa4cab9f8b915e457728f41e561reed@google.com } 1398260a895869beaa4cab9f8b915e457728f41e561reed@google.com 140722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org /* When converting from SkMatrix44 to SkMatrix, the third row and 141722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org * column is dropped. When converting from SkMatrix to SkMatrix44 142722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org * the third row and column remain as identity: 143722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org * [ a b c ] [ a b 0 c ] 144722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org * [ d e f ] -> [ d e 0 f ] 145722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org * [ g h i ] [ 0 0 1 0 ] 146722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org * [ g h 0 i ] 147722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org */ 1488260a895869beaa4cab9f8b915e457728f41e561reed@google.com SkMatrix44(const SkMatrix&); 1498260a895869beaa4cab9f8b915e457728f41e561reed@google.com SkMatrix44& operator=(const SkMatrix& src); 1508260a895869beaa4cab9f8b915e457728f41e561reed@google.com operator SkMatrix() const; 1518260a895869beaa4cab9f8b915e457728f41e561reed@google.com 1527d68335eb427547606497eb4edea81acce7891f9reed@google.com /** 1537d68335eb427547606497eb4edea81acce7891f9reed@google.com * Return a reference to a const identity matrix 1547d68335eb427547606497eb4edea81acce7891f9reed@google.com */ 1557d68335eb427547606497eb4edea81acce7891f9reed@google.com static const SkMatrix44& I(); 1567d68335eb427547606497eb4edea81acce7891f9reed@google.com 1577d68335eb427547606497eb4edea81acce7891f9reed@google.com enum TypeMask { 1587d68335eb427547606497eb4edea81acce7891f9reed@google.com kIdentity_Mask = 0, 1597d68335eb427547606497eb4edea81acce7891f9reed@google.com kTranslate_Mask = 0x01, //!< set if the matrix has translation 1607d68335eb427547606497eb4edea81acce7891f9reed@google.com kScale_Mask = 0x02, //!< set if the matrix has any scale != 1 1617d68335eb427547606497eb4edea81acce7891f9reed@google.com kAffine_Mask = 0x04, //!< set if the matrix skews or rotates 1627d68335eb427547606497eb4edea81acce7891f9reed@google.com kPerspective_Mask = 0x08 //!< set if the matrix is in perspective 1637d68335eb427547606497eb4edea81acce7891f9reed@google.com }; 1640264fb4543b0d8cebe00f1ee32433784f4ceb074skia.committer@gmail.com 1657d68335eb427547606497eb4edea81acce7891f9reed@google.com /** 1667d68335eb427547606497eb4edea81acce7891f9reed@google.com * Returns a bitfield describing the transformations the matrix may 1677d68335eb427547606497eb4edea81acce7891f9reed@google.com * perform. The bitfield is computed conservatively, so it may include 1687d68335eb427547606497eb4edea81acce7891f9reed@google.com * false positives. For example, when kPerspective_Mask is true, all 1697d68335eb427547606497eb4edea81acce7891f9reed@google.com * other bits may be set to true even in the case of a pure perspective 1707d68335eb427547606497eb4edea81acce7891f9reed@google.com * transform. 1717d68335eb427547606497eb4edea81acce7891f9reed@google.com */ 1727d68335eb427547606497eb4edea81acce7891f9reed@google.com inline TypeMask getType() const { 1737d68335eb427547606497eb4edea81acce7891f9reed@google.com if (fTypeMask & kUnknown_Mask) { 1747d68335eb427547606497eb4edea81acce7891f9reed@google.com fTypeMask = this->computeTypeMask(); 1757d68335eb427547606497eb4edea81acce7891f9reed@google.com } 1767d68335eb427547606497eb4edea81acce7891f9reed@google.com SkASSERT(!(fTypeMask & kUnknown_Mask)); 1777d68335eb427547606497eb4edea81acce7891f9reed@google.com return (TypeMask)fTypeMask; 1787d68335eb427547606497eb4edea81acce7891f9reed@google.com } 1797d68335eb427547606497eb4edea81acce7891f9reed@google.com 180f8b1ebc35b6872c2805a22481b7c23b85486fb46mike@reedtribe.org /** 181f8b1ebc35b6872c2805a22481b7c23b85486fb46mike@reedtribe.org * Return true if the matrix is identity. 182f8b1ebc35b6872c2805a22481b7c23b85486fb46mike@reedtribe.org */ 1837d68335eb427547606497eb4edea81acce7891f9reed@google.com inline bool isIdentity() const { 184f8b1ebc35b6872c2805a22481b7c23b85486fb46mike@reedtribe.org return kIdentity_Mask == this->getType(); 185f8b1ebc35b6872c2805a22481b7c23b85486fb46mike@reedtribe.org } 186f8b1ebc35b6872c2805a22481b7c23b85486fb46mike@reedtribe.org 187f8b1ebc35b6872c2805a22481b7c23b85486fb46mike@reedtribe.org /** 188f8b1ebc35b6872c2805a22481b7c23b85486fb46mike@reedtribe.org * Return true if the matrix contains translate or is identity. 189f8b1ebc35b6872c2805a22481b7c23b85486fb46mike@reedtribe.org */ 190f8b1ebc35b6872c2805a22481b7c23b85486fb46mike@reedtribe.org inline bool isTranslate() const { 191f8b1ebc35b6872c2805a22481b7c23b85486fb46mike@reedtribe.org return !(this->getType() & ~kTranslate_Mask); 192f8b1ebc35b6872c2805a22481b7c23b85486fb46mike@reedtribe.org } 193f8b1ebc35b6872c2805a22481b7c23b85486fb46mike@reedtribe.org 194f8b1ebc35b6872c2805a22481b7c23b85486fb46mike@reedtribe.org /** 195f8b1ebc35b6872c2805a22481b7c23b85486fb46mike@reedtribe.org * Return true if the matrix only contains scale or translate or is identity. 196f8b1ebc35b6872c2805a22481b7c23b85486fb46mike@reedtribe.org */ 197f8b1ebc35b6872c2805a22481b7c23b85486fb46mike@reedtribe.org inline bool isScaleTranslate() const { 198f8b1ebc35b6872c2805a22481b7c23b85486fb46mike@reedtribe.org return !(this->getType() & ~(kScale_Mask | kTranslate_Mask)); 1997d68335eb427547606497eb4edea81acce7891f9reed@google.com } 2000264fb4543b0d8cebe00f1ee32433784f4ceb074skia.committer@gmail.com 2017d68335eb427547606497eb4edea81acce7891f9reed@google.com void setIdentity(); 2027d68335eb427547606497eb4edea81acce7891f9reed@google.com inline void reset() { this->setIdentity();} 2037d68335eb427547606497eb4edea81acce7891f9reed@google.com 2047d68335eb427547606497eb4edea81acce7891f9reed@google.com /** 2057d68335eb427547606497eb4edea81acce7891f9reed@google.com * get a value from the matrix. The row,col parameters work as follows: 2067d68335eb427547606497eb4edea81acce7891f9reed@google.com * (0, 0) scale-x 2077d68335eb427547606497eb4edea81acce7891f9reed@google.com * (0, 3) translate-x 2087d68335eb427547606497eb4edea81acce7891f9reed@google.com * (3, 0) perspective-x 2097d68335eb427547606497eb4edea81acce7891f9reed@google.com */ 2107d68335eb427547606497eb4edea81acce7891f9reed@google.com inline SkMScalar get(int row, int col) const { 211631940c8c44e92939fc95d305b87be64eb9b886ereed@google.com SkASSERT((unsigned)row <= 3); 212631940c8c44e92939fc95d305b87be64eb9b886ereed@google.com SkASSERT((unsigned)col <= 3); 213631940c8c44e92939fc95d305b87be64eb9b886ereed@google.com return fMat[col][row]; 214631940c8c44e92939fc95d305b87be64eb9b886ereed@google.com } 2158260a895869beaa4cab9f8b915e457728f41e561reed@google.com 2167d68335eb427547606497eb4edea81acce7891f9reed@google.com /** 2177d68335eb427547606497eb4edea81acce7891f9reed@google.com * set a value in the matrix. The row,col parameters work as follows: 2187d68335eb427547606497eb4edea81acce7891f9reed@google.com * (0, 0) scale-x 2197d68335eb427547606497eb4edea81acce7891f9reed@google.com * (0, 3) translate-x 2207d68335eb427547606497eb4edea81acce7891f9reed@google.com * (3, 0) perspective-x 2217d68335eb427547606497eb4edea81acce7891f9reed@google.com */ 2227d68335eb427547606497eb4edea81acce7891f9reed@google.com inline void set(int row, int col, SkMScalar value) { 223631940c8c44e92939fc95d305b87be64eb9b886ereed@google.com SkASSERT((unsigned)row <= 3); 224631940c8c44e92939fc95d305b87be64eb9b886ereed@google.com SkASSERT((unsigned)col <= 3); 225631940c8c44e92939fc95d305b87be64eb9b886ereed@google.com fMat[col][row] = value; 2267d68335eb427547606497eb4edea81acce7891f9reed@google.com this->dirtyTypeMask(); 227631940c8c44e92939fc95d305b87be64eb9b886ereed@google.com } 228ab38f7acb336c4330af015312e854e990babd3f5skia.committer@gmail.com 2297d68335eb427547606497eb4edea81acce7891f9reed@google.com inline double getDouble(int row, int col) const { 2309b21c25e742d6a8b69bee8b049e79877f93b5936vollick@chromium.org return SkMScalarToDouble(this->get(row, col)); 2319b21c25e742d6a8b69bee8b049e79877f93b5936vollick@chromium.org } 2327d68335eb427547606497eb4edea81acce7891f9reed@google.com inline void setDouble(int row, int col, double value) { 2339b21c25e742d6a8b69bee8b049e79877f93b5936vollick@chromium.org this->set(row, col, SkDoubleToMScalar(value)); 2349b21c25e742d6a8b69bee8b049e79877f93b5936vollick@chromium.org } 235e2419cc5edbe1a6a7dae81a90ca44673a1fa030fcommit-bot@chromium.org inline float getFloat(int row, int col) const { 236e2419cc5edbe1a6a7dae81a90ca44673a1fa030fcommit-bot@chromium.org return SkMScalarToFloat(this->get(row, col)); 237e2419cc5edbe1a6a7dae81a90ca44673a1fa030fcommit-bot@chromium.org } 238e2419cc5edbe1a6a7dae81a90ca44673a1fa030fcommit-bot@chromium.org inline void setFloat(int row, int col, float value) { 239e2419cc5edbe1a6a7dae81a90ca44673a1fa030fcommit-bot@chromium.org this->set(row, col, SkFloatToMScalar(value)); 240e2419cc5edbe1a6a7dae81a90ca44673a1fa030fcommit-bot@chromium.org } 2419b21c25e742d6a8b69bee8b049e79877f93b5936vollick@chromium.org 242f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org /** These methods allow one to efficiently read matrix entries into an 243f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org * array. The given array must have room for exactly 16 entries. Whenever 244f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org * possible, they will try to use memcpy rather than an entry-by-entry 245f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org * copy. 246f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org */ 247da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com void asColMajorf(float[]) const; 248da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com void asColMajord(double[]) const; 249da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com void asRowMajorf(float[]) const; 250da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com void asRowMajord(double[]) const; 251da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com 252f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org /** These methods allow one to efficiently set all matrix entries from an 253f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org * array. The given array must have room for exactly 16 entries. Whenever 254f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org * possible, they will try to use memcpy rather than an entry-by-entry 255f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org * copy. 256f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org */ 257f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org void setColMajorf(const float[]); 258f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org void setColMajord(const double[]); 259f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org void setRowMajorf(const float[]); 260f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org void setRowMajord(const double[]); 261f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org 2627d68335eb427547606497eb4edea81acce7891f9reed@google.com#ifdef SK_MSCALAR_IS_FLOAT 2637d68335eb427547606497eb4edea81acce7891f9reed@google.com void setColMajor(const SkMScalar data[]) { this->setColMajorf(data); } 2647d68335eb427547606497eb4edea81acce7891f9reed@google.com void setRowMajor(const SkMScalar data[]) { this->setRowMajorf(data); } 2657d68335eb427547606497eb4edea81acce7891f9reed@google.com#else 2667d68335eb427547606497eb4edea81acce7891f9reed@google.com void setColMajor(const SkMScalar data[]) { this->setColMajord(data); } 2677d68335eb427547606497eb4edea81acce7891f9reed@google.com void setRowMajor(const SkMScalar data[]) { this->setRowMajord(data); } 2687d68335eb427547606497eb4edea81acce7891f9reed@google.com#endif 2698260a895869beaa4cab9f8b915e457728f41e561reed@google.com 270722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org /* This sets the top-left of the matrix and clears the translation and 271722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org * perspective components (with [3][3] set to 1). */ 2728260a895869beaa4cab9f8b915e457728f41e561reed@google.com void set3x3(SkMScalar m00, SkMScalar m01, SkMScalar m02, 2738260a895869beaa4cab9f8b915e457728f41e561reed@google.com SkMScalar m10, SkMScalar m11, SkMScalar m12, 2748260a895869beaa4cab9f8b915e457728f41e561reed@google.com SkMScalar m20, SkMScalar m21, SkMScalar m22); 2758260a895869beaa4cab9f8b915e457728f41e561reed@google.com 2768260a895869beaa4cab9f8b915e457728f41e561reed@google.com void setTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz); 2778260a895869beaa4cab9f8b915e457728f41e561reed@google.com void preTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz); 2788260a895869beaa4cab9f8b915e457728f41e561reed@google.com void postTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz); 2798260a895869beaa4cab9f8b915e457728f41e561reed@google.com 2808260a895869beaa4cab9f8b915e457728f41e561reed@google.com void setScale(SkMScalar sx, SkMScalar sy, SkMScalar sz); 2818260a895869beaa4cab9f8b915e457728f41e561reed@google.com void preScale(SkMScalar sx, SkMScalar sy, SkMScalar sz); 2828260a895869beaa4cab9f8b915e457728f41e561reed@google.com void postScale(SkMScalar sx, SkMScalar sy, SkMScalar sz); 2838260a895869beaa4cab9f8b915e457728f41e561reed@google.com 2847d68335eb427547606497eb4edea81acce7891f9reed@google.com inline void setScale(SkMScalar scale) { 2858260a895869beaa4cab9f8b915e457728f41e561reed@google.com this->setScale(scale, scale, scale); 2868260a895869beaa4cab9f8b915e457728f41e561reed@google.com } 2877d68335eb427547606497eb4edea81acce7891f9reed@google.com inline void preScale(SkMScalar scale) { 2888260a895869beaa4cab9f8b915e457728f41e561reed@google.com this->preScale(scale, scale, scale); 2898260a895869beaa4cab9f8b915e457728f41e561reed@google.com } 2907d68335eb427547606497eb4edea81acce7891f9reed@google.com inline void postScale(SkMScalar scale) { 2918260a895869beaa4cab9f8b915e457728f41e561reed@google.com this->postScale(scale, scale, scale); 2928260a895869beaa4cab9f8b915e457728f41e561reed@google.com } 2938260a895869beaa4cab9f8b915e457728f41e561reed@google.com 2948260a895869beaa4cab9f8b915e457728f41e561reed@google.com void setRotateDegreesAbout(SkMScalar x, SkMScalar y, SkMScalar z, 2958260a895869beaa4cab9f8b915e457728f41e561reed@google.com SkMScalar degrees) { 2968260a895869beaa4cab9f8b915e457728f41e561reed@google.com this->setRotateAbout(x, y, z, degrees * SK_MScalarPI / 180); 2978260a895869beaa4cab9f8b915e457728f41e561reed@google.com } 2988260a895869beaa4cab9f8b915e457728f41e561reed@google.com 2998260a895869beaa4cab9f8b915e457728f41e561reed@google.com /** Rotate about the vector [x,y,z]. If that vector is not unit-length, 3008260a895869beaa4cab9f8b915e457728f41e561reed@google.com it will be automatically resized. 3018260a895869beaa4cab9f8b915e457728f41e561reed@google.com */ 3028260a895869beaa4cab9f8b915e457728f41e561reed@google.com void setRotateAbout(SkMScalar x, SkMScalar y, SkMScalar z, 3038260a895869beaa4cab9f8b915e457728f41e561reed@google.com SkMScalar radians); 3048260a895869beaa4cab9f8b915e457728f41e561reed@google.com /** Rotate about the vector [x,y,z]. Does not check the length of the 3058260a895869beaa4cab9f8b915e457728f41e561reed@google.com vector, assuming it is unit-length. 3068260a895869beaa4cab9f8b915e457728f41e561reed@google.com */ 3078260a895869beaa4cab9f8b915e457728f41e561reed@google.com void setRotateAboutUnit(SkMScalar x, SkMScalar y, SkMScalar z, 3088260a895869beaa4cab9f8b915e457728f41e561reed@google.com SkMScalar radians); 3098260a895869beaa4cab9f8b915e457728f41e561reed@google.com 3108260a895869beaa4cab9f8b915e457728f41e561reed@google.com void setConcat(const SkMatrix44& a, const SkMatrix44& b); 3117d68335eb427547606497eb4edea81acce7891f9reed@google.com inline void preConcat(const SkMatrix44& m) { 3128260a895869beaa4cab9f8b915e457728f41e561reed@google.com this->setConcat(*this, m); 3138260a895869beaa4cab9f8b915e457728f41e561reed@google.com } 3147d68335eb427547606497eb4edea81acce7891f9reed@google.com inline void postConcat(const SkMatrix44& m) { 3158260a895869beaa4cab9f8b915e457728f41e561reed@google.com this->setConcat(m, *this); 3168260a895869beaa4cab9f8b915e457728f41e561reed@google.com } 3178260a895869beaa4cab9f8b915e457728f41e561reed@google.com 3188260a895869beaa4cab9f8b915e457728f41e561reed@google.com friend SkMatrix44 operator*(const SkMatrix44& a, const SkMatrix44& b) { 3198260a895869beaa4cab9f8b915e457728f41e561reed@google.com return SkMatrix44(a, b); 3208260a895869beaa4cab9f8b915e457728f41e561reed@google.com } 3218260a895869beaa4cab9f8b915e457728f41e561reed@google.com 3228260a895869beaa4cab9f8b915e457728f41e561reed@google.com /** If this is invertible, return that in inverse and return true. If it is 3238260a895869beaa4cab9f8b915e457728f41e561reed@google.com not invertible, return false and ignore the inverse parameter. 3248260a895869beaa4cab9f8b915e457728f41e561reed@google.com */ 3258260a895869beaa4cab9f8b915e457728f41e561reed@google.com bool invert(SkMatrix44* inverse) const; 3268260a895869beaa4cab9f8b915e457728f41e561reed@google.com 3279b21c25e742d6a8b69bee8b049e79877f93b5936vollick@chromium.org /** Transpose this matrix in place. */ 3289b21c25e742d6a8b69bee8b049e79877f93b5936vollick@chromium.org void transpose(); 3299b21c25e742d6a8b69bee8b049e79877f93b5936vollick@chromium.org 3308260a895869beaa4cab9f8b915e457728f41e561reed@google.com /** Apply the matrix to the src vector, returning the new vector in dst. 3318260a895869beaa4cab9f8b915e457728f41e561reed@google.com It is legal for src and dst to point to the same memory. 3328260a895869beaa4cab9f8b915e457728f41e561reed@google.com */ 3331ea95be560b38a71e3f24749c4e5e3d3564e4c6creed@google.com void mapScalars(const SkScalar src[4], SkScalar dst[4]) const; 3347d68335eb427547606497eb4edea81acce7891f9reed@google.com inline void mapScalars(SkScalar vec[4]) const { 3351ea95be560b38a71e3f24749c4e5e3d3564e4c6creed@google.com this->mapScalars(vec, vec); 3361ea95be560b38a71e3f24749c4e5e3d3564e4c6creed@google.com } 3371ea95be560b38a71e3f24749c4e5e3d3564e4c6creed@google.com 3384469938e92d779dff05e745559e67907bbf21e78reed@google.com SK_ATTR_DEPRECATED("use mapScalars") 3391ea95be560b38a71e3f24749c4e5e3d3564e4c6creed@google.com void map(const SkScalar src[4], SkScalar dst[4]) const { 3401ea95be560b38a71e3f24749c4e5e3d3564e4c6creed@google.com this->mapScalars(src, dst); 3411ea95be560b38a71e3f24749c4e5e3d3564e4c6creed@google.com } 3424469938e92d779dff05e745559e67907bbf21e78reed@google.com 3434469938e92d779dff05e745559e67907bbf21e78reed@google.com SK_ATTR_DEPRECATED("use mapScalars") 3448260a895869beaa4cab9f8b915e457728f41e561reed@google.com void map(SkScalar vec[4]) const { 3451ea95be560b38a71e3f24749c4e5e3d3564e4c6creed@google.com this->mapScalars(vec, vec); 3461ea95be560b38a71e3f24749c4e5e3d3564e4c6creed@google.com } 3471ea95be560b38a71e3f24749c4e5e3d3564e4c6creed@google.com 3481ea95be560b38a71e3f24749c4e5e3d3564e4c6creed@google.com#ifdef SK_MSCALAR_IS_DOUBLE 349dd31131021e2b5ef16b4f3cdec3cf328adcfd6ccreed@google.com void mapMScalars(const SkMScalar src[4], SkMScalar dst[4]) const; 3505596a69e9f7884e3042bceba071c468dee52aa7fvollick@chromium.org#elif defined SK_MSCALAR_IS_FLOAT 3517d68335eb427547606497eb4edea81acce7891f9reed@google.com inline void mapMScalars(const SkMScalar src[4], SkMScalar dst[4]) const { 3521ea95be560b38a71e3f24749c4e5e3d3564e4c6creed@google.com this->mapScalars(src, dst); 3531ea95be560b38a71e3f24749c4e5e3d3564e4c6creed@google.com } 3541ea95be560b38a71e3f24749c4e5e3d3564e4c6creed@google.com#endif 3557d68335eb427547606497eb4edea81acce7891f9reed@google.com inline void mapMScalars(SkMScalar vec[4]) const { 3561ea95be560b38a71e3f24749c4e5e3d3564e4c6creed@google.com this->mapMScalars(vec, vec); 3578260a895869beaa4cab9f8b915e457728f41e561reed@google.com } 3588260a895869beaa4cab9f8b915e457728f41e561reed@google.com 3598260a895869beaa4cab9f8b915e457728f41e561reed@google.com friend SkVector4 operator*(const SkMatrix44& m, const SkVector4& src) { 3608260a895869beaa4cab9f8b915e457728f41e561reed@google.com SkVector4 dst; 3614469938e92d779dff05e745559e67907bbf21e78reed@google.com m.mapScalars(src.fData, dst.fData); 3628260a895869beaa4cab9f8b915e457728f41e561reed@google.com return dst; 3638260a895869beaa4cab9f8b915e457728f41e561reed@google.com } 3648260a895869beaa4cab9f8b915e457728f41e561reed@google.com 36599b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com /** 36699b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com * map an array of [x, y, 0, 1] through the matrix, returning an array 36799b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com * of [x', y', z', w']. 36899b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com * 36999b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com * @param src2 array of [x, y] pairs, with implied z=0 and w=1 37099b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com * @param count number of [x, y] pairs in src2 37199b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com * @param dst4 array of [x', y', z', w'] quads as the output. 37299b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com */ 37399b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com void map2(const float src2[], int count, float dst4[]) const; 37499b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com void map2(const double src2[], int count, double dst4[]) const; 37599b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com 3768260a895869beaa4cab9f8b915e457728f41e561reed@google.com void dump() const; 3778260a895869beaa4cab9f8b915e457728f41e561reed@google.com 3783959a76ab086a4adbdb9d48977fa276ce0213cb1vollick@chromium.org double determinant() const; 3793959a76ab086a4adbdb9d48977fa276ce0213cb1vollick@chromium.org 3808260a895869beaa4cab9f8b915e457728f41e561reed@google.comprivate: 381d53025364a8062b5c72f3f9ed54a613a1ae17958reed@google.com SkMScalar fMat[4][4]; 382d53025364a8062b5c72f3f9ed54a613a1ae17958reed@google.com mutable unsigned fTypeMask; 3830264fb4543b0d8cebe00f1ee32433784f4ceb074skia.committer@gmail.com 3847d68335eb427547606497eb4edea81acce7891f9reed@google.com enum { 3857d68335eb427547606497eb4edea81acce7891f9reed@google.com kUnknown_Mask = 0x80, 3867d68335eb427547606497eb4edea81acce7891f9reed@google.com 3877d68335eb427547606497eb4edea81acce7891f9reed@google.com kAllPublic_Masks = 0xF 3887d68335eb427547606497eb4edea81acce7891f9reed@google.com }; 3897d68335eb427547606497eb4edea81acce7891f9reed@google.com 3907d68335eb427547606497eb4edea81acce7891f9reed@google.com SkMScalar transX() const { return fMat[3][0]; } 3917d68335eb427547606497eb4edea81acce7891f9reed@google.com SkMScalar transY() const { return fMat[3][1]; } 3927d68335eb427547606497eb4edea81acce7891f9reed@google.com SkMScalar transZ() const { return fMat[3][2]; } 3937d68335eb427547606497eb4edea81acce7891f9reed@google.com 3947d68335eb427547606497eb4edea81acce7891f9reed@google.com SkMScalar scaleX() const { return fMat[0][0]; } 3957d68335eb427547606497eb4edea81acce7891f9reed@google.com SkMScalar scaleY() const { return fMat[1][1]; } 3967d68335eb427547606497eb4edea81acce7891f9reed@google.com SkMScalar scaleZ() const { return fMat[2][2]; } 3970264fb4543b0d8cebe00f1ee32433784f4ceb074skia.committer@gmail.com 3987d68335eb427547606497eb4edea81acce7891f9reed@google.com SkMScalar perspX() const { return fMat[0][3]; } 3997d68335eb427547606497eb4edea81acce7891f9reed@google.com SkMScalar perspY() const { return fMat[1][3]; } 4007d68335eb427547606497eb4edea81acce7891f9reed@google.com SkMScalar perspZ() const { return fMat[2][3]; } 401deb4c169690c777acb27ee8ce67d70d3f6eb2a2cjamesr@chromium.org 4027d68335eb427547606497eb4edea81acce7891f9reed@google.com int computeTypeMask() const; 4037d68335eb427547606497eb4edea81acce7891f9reed@google.com 4047d68335eb427547606497eb4edea81acce7891f9reed@google.com inline void dirtyTypeMask() { 4057d68335eb427547606497eb4edea81acce7891f9reed@google.com fTypeMask = kUnknown_Mask; 4067d68335eb427547606497eb4edea81acce7891f9reed@google.com } 4077d68335eb427547606497eb4edea81acce7891f9reed@google.com 4087d68335eb427547606497eb4edea81acce7891f9reed@google.com inline void setTypeMask(int mask) { 4097d68335eb427547606497eb4edea81acce7891f9reed@google.com SkASSERT(0 == (~(kAllPublic_Masks | kUnknown_Mask) & mask)); 4107d68335eb427547606497eb4edea81acce7891f9reed@google.com fTypeMask = mask; 4117d68335eb427547606497eb4edea81acce7891f9reed@google.com } 4127d68335eb427547606497eb4edea81acce7891f9reed@google.com 4137d68335eb427547606497eb4edea81acce7891f9reed@google.com /** 4147d68335eb427547606497eb4edea81acce7891f9reed@google.com * Does not take the time to 'compute' the typemask. Only returns true if 4157d68335eb427547606497eb4edea81acce7891f9reed@google.com * we already know that this matrix is identity. 4167d68335eb427547606497eb4edea81acce7891f9reed@google.com */ 4177d68335eb427547606497eb4edea81acce7891f9reed@google.com inline bool isTriviallyIdentity() const { 4187d68335eb427547606497eb4edea81acce7891f9reed@google.com return 0 == fTypeMask; 4197d68335eb427547606497eb4edea81acce7891f9reed@google.com } 4207cfb9c7b6186bf1e42b7d13466eab94470587e7etomhudson@google.com}; 4218260a895869beaa4cab9f8b915e457728f41e561reed@google.com 4228260a895869beaa4cab9f8b915e457728f41e561reed@google.com#endif 423