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 201a32f1758b7ebd889eecfdc67c935e7edcedc5be3tomhudson inline bool hasPerspective() const { 202a32f1758b7ebd889eecfdc67c935e7edcedc5be3tomhudson return SkToBool(this->getType() & kPerspective_Mask); 203a32f1758b7ebd889eecfdc67c935e7edcedc5be3tomhudson } 204a32f1758b7ebd889eecfdc67c935e7edcedc5be3tomhudson 2057d68335eb427547606497eb4edea81acce7891f9reed@google.com void setIdentity(); 2067d68335eb427547606497eb4edea81acce7891f9reed@google.com inline void reset() { this->setIdentity();} 2077d68335eb427547606497eb4edea81acce7891f9reed@google.com 2087d68335eb427547606497eb4edea81acce7891f9reed@google.com /** 2097d68335eb427547606497eb4edea81acce7891f9reed@google.com * get a value from the matrix. The row,col parameters work as follows: 2107d68335eb427547606497eb4edea81acce7891f9reed@google.com * (0, 0) scale-x 2117d68335eb427547606497eb4edea81acce7891f9reed@google.com * (0, 3) translate-x 2127d68335eb427547606497eb4edea81acce7891f9reed@google.com * (3, 0) perspective-x 2137d68335eb427547606497eb4edea81acce7891f9reed@google.com */ 2147d68335eb427547606497eb4edea81acce7891f9reed@google.com inline SkMScalar get(int row, int col) const { 215631940c8c44e92939fc95d305b87be64eb9b886ereed@google.com SkASSERT((unsigned)row <= 3); 216631940c8c44e92939fc95d305b87be64eb9b886ereed@google.com SkASSERT((unsigned)col <= 3); 217631940c8c44e92939fc95d305b87be64eb9b886ereed@google.com return fMat[col][row]; 218631940c8c44e92939fc95d305b87be64eb9b886ereed@google.com } 2198260a895869beaa4cab9f8b915e457728f41e561reed@google.com 2207d68335eb427547606497eb4edea81acce7891f9reed@google.com /** 2217d68335eb427547606497eb4edea81acce7891f9reed@google.com * set a value in the matrix. The row,col parameters work as follows: 2227d68335eb427547606497eb4edea81acce7891f9reed@google.com * (0, 0) scale-x 2237d68335eb427547606497eb4edea81acce7891f9reed@google.com * (0, 3) translate-x 2247d68335eb427547606497eb4edea81acce7891f9reed@google.com * (3, 0) perspective-x 2257d68335eb427547606497eb4edea81acce7891f9reed@google.com */ 2267d68335eb427547606497eb4edea81acce7891f9reed@google.com inline void set(int row, int col, SkMScalar value) { 227631940c8c44e92939fc95d305b87be64eb9b886ereed@google.com SkASSERT((unsigned)row <= 3); 228631940c8c44e92939fc95d305b87be64eb9b886ereed@google.com SkASSERT((unsigned)col <= 3); 229631940c8c44e92939fc95d305b87be64eb9b886ereed@google.com fMat[col][row] = value; 2307d68335eb427547606497eb4edea81acce7891f9reed@google.com this->dirtyTypeMask(); 231631940c8c44e92939fc95d305b87be64eb9b886ereed@google.com } 232ab38f7acb336c4330af015312e854e990babd3f5skia.committer@gmail.com 2337d68335eb427547606497eb4edea81acce7891f9reed@google.com inline double getDouble(int row, int col) const { 2349b21c25e742d6a8b69bee8b049e79877f93b5936vollick@chromium.org return SkMScalarToDouble(this->get(row, col)); 2359b21c25e742d6a8b69bee8b049e79877f93b5936vollick@chromium.org } 2367d68335eb427547606497eb4edea81acce7891f9reed@google.com inline void setDouble(int row, int col, double value) { 2379b21c25e742d6a8b69bee8b049e79877f93b5936vollick@chromium.org this->set(row, col, SkDoubleToMScalar(value)); 2389b21c25e742d6a8b69bee8b049e79877f93b5936vollick@chromium.org } 239e2419cc5edbe1a6a7dae81a90ca44673a1fa030fcommit-bot@chromium.org inline float getFloat(int row, int col) const { 240e2419cc5edbe1a6a7dae81a90ca44673a1fa030fcommit-bot@chromium.org return SkMScalarToFloat(this->get(row, col)); 241e2419cc5edbe1a6a7dae81a90ca44673a1fa030fcommit-bot@chromium.org } 242e2419cc5edbe1a6a7dae81a90ca44673a1fa030fcommit-bot@chromium.org inline void setFloat(int row, int col, float value) { 243e2419cc5edbe1a6a7dae81a90ca44673a1fa030fcommit-bot@chromium.org this->set(row, col, SkFloatToMScalar(value)); 244e2419cc5edbe1a6a7dae81a90ca44673a1fa030fcommit-bot@chromium.org } 2459b21c25e742d6a8b69bee8b049e79877f93b5936vollick@chromium.org 246f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org /** These methods allow one to efficiently read matrix entries into an 247f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org * array. The given array must have room for exactly 16 entries. Whenever 248f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org * possible, they will try to use memcpy rather than an entry-by-entry 249f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org * copy. 250f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org */ 251da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com void asColMajorf(float[]) const; 252da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com void asColMajord(double[]) const; 253da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com void asRowMajorf(float[]) const; 254da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com void asRowMajord(double[]) const; 255da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com 256f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org /** These methods allow one to efficiently set all matrix entries from an 257f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org * array. The given array must have room for exactly 16 entries. Whenever 258f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org * possible, they will try to use memcpy rather than an entry-by-entry 259f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org * copy. 260f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org */ 261f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org void setColMajorf(const float[]); 262f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org void setColMajord(const double[]); 263f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org void setRowMajorf(const float[]); 264f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org void setRowMajord(const double[]); 265f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org 2667d68335eb427547606497eb4edea81acce7891f9reed@google.com#ifdef SK_MSCALAR_IS_FLOAT 2677d68335eb427547606497eb4edea81acce7891f9reed@google.com void setColMajor(const SkMScalar data[]) { this->setColMajorf(data); } 2687d68335eb427547606497eb4edea81acce7891f9reed@google.com void setRowMajor(const SkMScalar data[]) { this->setRowMajorf(data); } 2697d68335eb427547606497eb4edea81acce7891f9reed@google.com#else 2707d68335eb427547606497eb4edea81acce7891f9reed@google.com void setColMajor(const SkMScalar data[]) { this->setColMajord(data); } 2717d68335eb427547606497eb4edea81acce7891f9reed@google.com void setRowMajor(const SkMScalar data[]) { this->setRowMajord(data); } 2727d68335eb427547606497eb4edea81acce7891f9reed@google.com#endif 2738260a895869beaa4cab9f8b915e457728f41e561reed@google.com 274722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org /* This sets the top-left of the matrix and clears the translation and 275722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org * perspective components (with [3][3] set to 1). */ 2768260a895869beaa4cab9f8b915e457728f41e561reed@google.com void set3x3(SkMScalar m00, SkMScalar m01, SkMScalar m02, 2778260a895869beaa4cab9f8b915e457728f41e561reed@google.com SkMScalar m10, SkMScalar m11, SkMScalar m12, 2788260a895869beaa4cab9f8b915e457728f41e561reed@google.com SkMScalar m20, SkMScalar m21, SkMScalar m22); 2798260a895869beaa4cab9f8b915e457728f41e561reed@google.com 2808260a895869beaa4cab9f8b915e457728f41e561reed@google.com void setTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz); 2818260a895869beaa4cab9f8b915e457728f41e561reed@google.com void preTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz); 2828260a895869beaa4cab9f8b915e457728f41e561reed@google.com void postTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz); 2838260a895869beaa4cab9f8b915e457728f41e561reed@google.com 2848260a895869beaa4cab9f8b915e457728f41e561reed@google.com void setScale(SkMScalar sx, SkMScalar sy, SkMScalar sz); 2858260a895869beaa4cab9f8b915e457728f41e561reed@google.com void preScale(SkMScalar sx, SkMScalar sy, SkMScalar sz); 2868260a895869beaa4cab9f8b915e457728f41e561reed@google.com void postScale(SkMScalar sx, SkMScalar sy, SkMScalar sz); 2878260a895869beaa4cab9f8b915e457728f41e561reed@google.com 2887d68335eb427547606497eb4edea81acce7891f9reed@google.com inline void setScale(SkMScalar scale) { 2898260a895869beaa4cab9f8b915e457728f41e561reed@google.com this->setScale(scale, scale, scale); 2908260a895869beaa4cab9f8b915e457728f41e561reed@google.com } 2917d68335eb427547606497eb4edea81acce7891f9reed@google.com inline void preScale(SkMScalar scale) { 2928260a895869beaa4cab9f8b915e457728f41e561reed@google.com this->preScale(scale, scale, scale); 2938260a895869beaa4cab9f8b915e457728f41e561reed@google.com } 2947d68335eb427547606497eb4edea81acce7891f9reed@google.com inline void postScale(SkMScalar scale) { 2958260a895869beaa4cab9f8b915e457728f41e561reed@google.com this->postScale(scale, scale, scale); 2968260a895869beaa4cab9f8b915e457728f41e561reed@google.com } 2978260a895869beaa4cab9f8b915e457728f41e561reed@google.com 2988260a895869beaa4cab9f8b915e457728f41e561reed@google.com void setRotateDegreesAbout(SkMScalar x, SkMScalar y, SkMScalar z, 2998260a895869beaa4cab9f8b915e457728f41e561reed@google.com SkMScalar degrees) { 3008260a895869beaa4cab9f8b915e457728f41e561reed@google.com this->setRotateAbout(x, y, z, degrees * SK_MScalarPI / 180); 3018260a895869beaa4cab9f8b915e457728f41e561reed@google.com } 3028260a895869beaa4cab9f8b915e457728f41e561reed@google.com 3038260a895869beaa4cab9f8b915e457728f41e561reed@google.com /** Rotate about the vector [x,y,z]. If that vector is not unit-length, 3048260a895869beaa4cab9f8b915e457728f41e561reed@google.com it will be automatically resized. 3058260a895869beaa4cab9f8b915e457728f41e561reed@google.com */ 3068260a895869beaa4cab9f8b915e457728f41e561reed@google.com void setRotateAbout(SkMScalar x, SkMScalar y, SkMScalar z, 3078260a895869beaa4cab9f8b915e457728f41e561reed@google.com SkMScalar radians); 3088260a895869beaa4cab9f8b915e457728f41e561reed@google.com /** Rotate about the vector [x,y,z]. Does not check the length of the 3098260a895869beaa4cab9f8b915e457728f41e561reed@google.com vector, assuming it is unit-length. 3108260a895869beaa4cab9f8b915e457728f41e561reed@google.com */ 3118260a895869beaa4cab9f8b915e457728f41e561reed@google.com void setRotateAboutUnit(SkMScalar x, SkMScalar y, SkMScalar z, 3128260a895869beaa4cab9f8b915e457728f41e561reed@google.com SkMScalar radians); 3138260a895869beaa4cab9f8b915e457728f41e561reed@google.com 3148260a895869beaa4cab9f8b915e457728f41e561reed@google.com void setConcat(const SkMatrix44& a, const SkMatrix44& b); 3157d68335eb427547606497eb4edea81acce7891f9reed@google.com inline void preConcat(const SkMatrix44& m) { 3168260a895869beaa4cab9f8b915e457728f41e561reed@google.com this->setConcat(*this, m); 3178260a895869beaa4cab9f8b915e457728f41e561reed@google.com } 3187d68335eb427547606497eb4edea81acce7891f9reed@google.com inline void postConcat(const SkMatrix44& m) { 3198260a895869beaa4cab9f8b915e457728f41e561reed@google.com this->setConcat(m, *this); 3208260a895869beaa4cab9f8b915e457728f41e561reed@google.com } 3218260a895869beaa4cab9f8b915e457728f41e561reed@google.com 3228260a895869beaa4cab9f8b915e457728f41e561reed@google.com friend SkMatrix44 operator*(const SkMatrix44& a, const SkMatrix44& b) { 3238260a895869beaa4cab9f8b915e457728f41e561reed@google.com return SkMatrix44(a, b); 3248260a895869beaa4cab9f8b915e457728f41e561reed@google.com } 3258260a895869beaa4cab9f8b915e457728f41e561reed@google.com 3268260a895869beaa4cab9f8b915e457728f41e561reed@google.com /** If this is invertible, return that in inverse and return true. If it is 3278260a895869beaa4cab9f8b915e457728f41e561reed@google.com not invertible, return false and ignore the inverse parameter. 3288260a895869beaa4cab9f8b915e457728f41e561reed@google.com */ 3298260a895869beaa4cab9f8b915e457728f41e561reed@google.com bool invert(SkMatrix44* inverse) const; 3308260a895869beaa4cab9f8b915e457728f41e561reed@google.com 3319b21c25e742d6a8b69bee8b049e79877f93b5936vollick@chromium.org /** Transpose this matrix in place. */ 3329b21c25e742d6a8b69bee8b049e79877f93b5936vollick@chromium.org void transpose(); 3339b21c25e742d6a8b69bee8b049e79877f93b5936vollick@chromium.org 3348260a895869beaa4cab9f8b915e457728f41e561reed@google.com /** Apply the matrix to the src vector, returning the new vector in dst. 3358260a895869beaa4cab9f8b915e457728f41e561reed@google.com It is legal for src and dst to point to the same memory. 3368260a895869beaa4cab9f8b915e457728f41e561reed@google.com */ 3371ea95be560b38a71e3f24749c4e5e3d3564e4c6creed@google.com void mapScalars(const SkScalar src[4], SkScalar dst[4]) const; 3387d68335eb427547606497eb4edea81acce7891f9reed@google.com inline void mapScalars(SkScalar vec[4]) const { 3391ea95be560b38a71e3f24749c4e5e3d3564e4c6creed@google.com this->mapScalars(vec, vec); 3401ea95be560b38a71e3f24749c4e5e3d3564e4c6creed@google.com } 3411ea95be560b38a71e3f24749c4e5e3d3564e4c6creed@google.com 3424469938e92d779dff05e745559e67907bbf21e78reed@google.com SK_ATTR_DEPRECATED("use mapScalars") 3431ea95be560b38a71e3f24749c4e5e3d3564e4c6creed@google.com void map(const SkScalar src[4], SkScalar dst[4]) const { 3441ea95be560b38a71e3f24749c4e5e3d3564e4c6creed@google.com this->mapScalars(src, dst); 3451ea95be560b38a71e3f24749c4e5e3d3564e4c6creed@google.com } 3464469938e92d779dff05e745559e67907bbf21e78reed@google.com 3474469938e92d779dff05e745559e67907bbf21e78reed@google.com SK_ATTR_DEPRECATED("use mapScalars") 3488260a895869beaa4cab9f8b915e457728f41e561reed@google.com void map(SkScalar vec[4]) const { 3491ea95be560b38a71e3f24749c4e5e3d3564e4c6creed@google.com this->mapScalars(vec, vec); 3501ea95be560b38a71e3f24749c4e5e3d3564e4c6creed@google.com } 3511ea95be560b38a71e3f24749c4e5e3d3564e4c6creed@google.com 3521ea95be560b38a71e3f24749c4e5e3d3564e4c6creed@google.com#ifdef SK_MSCALAR_IS_DOUBLE 353dd31131021e2b5ef16b4f3cdec3cf328adcfd6ccreed@google.com void mapMScalars(const SkMScalar src[4], SkMScalar dst[4]) const; 3545596a69e9f7884e3042bceba071c468dee52aa7fvollick@chromium.org#elif defined SK_MSCALAR_IS_FLOAT 3557d68335eb427547606497eb4edea81acce7891f9reed@google.com inline void mapMScalars(const SkMScalar src[4], SkMScalar dst[4]) const { 3561ea95be560b38a71e3f24749c4e5e3d3564e4c6creed@google.com this->mapScalars(src, dst); 3571ea95be560b38a71e3f24749c4e5e3d3564e4c6creed@google.com } 3581ea95be560b38a71e3f24749c4e5e3d3564e4c6creed@google.com#endif 3597d68335eb427547606497eb4edea81acce7891f9reed@google.com inline void mapMScalars(SkMScalar vec[4]) const { 3601ea95be560b38a71e3f24749c4e5e3d3564e4c6creed@google.com this->mapMScalars(vec, vec); 3618260a895869beaa4cab9f8b915e457728f41e561reed@google.com } 3628260a895869beaa4cab9f8b915e457728f41e561reed@google.com 3638260a895869beaa4cab9f8b915e457728f41e561reed@google.com friend SkVector4 operator*(const SkMatrix44& m, const SkVector4& src) { 3648260a895869beaa4cab9f8b915e457728f41e561reed@google.com SkVector4 dst; 3654469938e92d779dff05e745559e67907bbf21e78reed@google.com m.mapScalars(src.fData, dst.fData); 3668260a895869beaa4cab9f8b915e457728f41e561reed@google.com return dst; 3678260a895869beaa4cab9f8b915e457728f41e561reed@google.com } 3688260a895869beaa4cab9f8b915e457728f41e561reed@google.com 36999b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com /** 37099b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com * map an array of [x, y, 0, 1] through the matrix, returning an array 37199b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com * of [x', y', z', w']. 37299b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com * 37399b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com * @param src2 array of [x, y] pairs, with implied z=0 and w=1 37499b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com * @param count number of [x, y] pairs in src2 37599b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com * @param dst4 array of [x', y', z', w'] quads as the output. 37699b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com */ 37799b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com void map2(const float src2[], int count, float dst4[]) const; 37899b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com void map2(const double src2[], int count, double dst4[]) const; 37999b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com 3808260a895869beaa4cab9f8b915e457728f41e561reed@google.com void dump() const; 3818260a895869beaa4cab9f8b915e457728f41e561reed@google.com 3823959a76ab086a4adbdb9d48977fa276ce0213cb1vollick@chromium.org double determinant() const; 3833959a76ab086a4adbdb9d48977fa276ce0213cb1vollick@chromium.org 3848260a895869beaa4cab9f8b915e457728f41e561reed@google.comprivate: 385d53025364a8062b5c72f3f9ed54a613a1ae17958reed@google.com SkMScalar fMat[4][4]; 386d53025364a8062b5c72f3f9ed54a613a1ae17958reed@google.com mutable unsigned fTypeMask; 3870264fb4543b0d8cebe00f1ee32433784f4ceb074skia.committer@gmail.com 3887d68335eb427547606497eb4edea81acce7891f9reed@google.com enum { 3897d68335eb427547606497eb4edea81acce7891f9reed@google.com kUnknown_Mask = 0x80, 3907d68335eb427547606497eb4edea81acce7891f9reed@google.com 3917d68335eb427547606497eb4edea81acce7891f9reed@google.com kAllPublic_Masks = 0xF 3927d68335eb427547606497eb4edea81acce7891f9reed@google.com }; 3937d68335eb427547606497eb4edea81acce7891f9reed@google.com 3947d68335eb427547606497eb4edea81acce7891f9reed@google.com SkMScalar transX() const { return fMat[3][0]; } 3957d68335eb427547606497eb4edea81acce7891f9reed@google.com SkMScalar transY() const { return fMat[3][1]; } 3967d68335eb427547606497eb4edea81acce7891f9reed@google.com SkMScalar transZ() const { return fMat[3][2]; } 3977d68335eb427547606497eb4edea81acce7891f9reed@google.com 3987d68335eb427547606497eb4edea81acce7891f9reed@google.com SkMScalar scaleX() const { return fMat[0][0]; } 3997d68335eb427547606497eb4edea81acce7891f9reed@google.com SkMScalar scaleY() const { return fMat[1][1]; } 4007d68335eb427547606497eb4edea81acce7891f9reed@google.com SkMScalar scaleZ() const { return fMat[2][2]; } 4010264fb4543b0d8cebe00f1ee32433784f4ceb074skia.committer@gmail.com 4027d68335eb427547606497eb4edea81acce7891f9reed@google.com SkMScalar perspX() const { return fMat[0][3]; } 4037d68335eb427547606497eb4edea81acce7891f9reed@google.com SkMScalar perspY() const { return fMat[1][3]; } 4047d68335eb427547606497eb4edea81acce7891f9reed@google.com SkMScalar perspZ() const { return fMat[2][3]; } 405deb4c169690c777acb27ee8ce67d70d3f6eb2a2cjamesr@chromium.org 4067d68335eb427547606497eb4edea81acce7891f9reed@google.com int computeTypeMask() const; 4077d68335eb427547606497eb4edea81acce7891f9reed@google.com 4087d68335eb427547606497eb4edea81acce7891f9reed@google.com inline void dirtyTypeMask() { 4097d68335eb427547606497eb4edea81acce7891f9reed@google.com fTypeMask = kUnknown_Mask; 4107d68335eb427547606497eb4edea81acce7891f9reed@google.com } 4117d68335eb427547606497eb4edea81acce7891f9reed@google.com 4127d68335eb427547606497eb4edea81acce7891f9reed@google.com inline void setTypeMask(int mask) { 4137d68335eb427547606497eb4edea81acce7891f9reed@google.com SkASSERT(0 == (~(kAllPublic_Masks | kUnknown_Mask) & mask)); 4147d68335eb427547606497eb4edea81acce7891f9reed@google.com fTypeMask = mask; 4157d68335eb427547606497eb4edea81acce7891f9reed@google.com } 4167d68335eb427547606497eb4edea81acce7891f9reed@google.com 4177d68335eb427547606497eb4edea81acce7891f9reed@google.com /** 4187d68335eb427547606497eb4edea81acce7891f9reed@google.com * Does not take the time to 'compute' the typemask. Only returns true if 4197d68335eb427547606497eb4edea81acce7891f9reed@google.com * we already know that this matrix is identity. 4207d68335eb427547606497eb4edea81acce7891f9reed@google.com */ 4217d68335eb427547606497eb4edea81acce7891f9reed@google.com inline bool isTriviallyIdentity() const { 4227d68335eb427547606497eb4edea81acce7891f9reed@google.com return 0 == fTypeMask; 4237d68335eb427547606497eb4edea81acce7891f9reed@google.com } 4247cfb9c7b6186bf1e42b7d13466eab94470587e7etomhudson@google.com}; 4258260a895869beaa4cab9f8b915e457728f41e561reed@google.com 4268260a895869beaa4cab9f8b915e457728f41e561reed@google.com#endif 427