180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/* 280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2011 Google Inc. 380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be 580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file. 680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkMatrix44.h" 980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 10363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerstatic inline bool eq4(const SkMScalar* SK_RESTRICT a, 11363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const SkMScalar* SK_RESTRICT b) { 12363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return (a[0] == b[0]) & (a[1] == b[1]) & (a[2] == b[2]) & (a[3] == b[3]); 13363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger} 14363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 15363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerbool SkMatrix44::operator==(const SkMatrix44& other) const { 16363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (this == &other) { 17363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return true; 18363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 19363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 20363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (this->isTriviallyIdentity() && other.isTriviallyIdentity()) { 21363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return true; 22363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 23363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 24363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const SkMScalar* SK_RESTRICT a = &fMat[0][0]; 25363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const SkMScalar* SK_RESTRICT b = &other.fMat[0][0]; 26363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 27363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#if 0 28363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger for (int i = 0; i < 16; ++i) { 29363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (a[i] != b[i]) { 30363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return false; 31363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 32363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 33363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return true; 34363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#else 35363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // to reduce branch instructions, we compare 4 at a time. 36363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // see bench/Matrix44Bench.cpp for test. 37363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (!eq4(&a[0], &b[0])) { 38363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return false; 39363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 40363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (!eq4(&a[4], &b[4])) { 41363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return false; 42363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 43363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (!eq4(&a[8], &b[8])) { 44363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return false; 45363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 46363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return eq4(&a[12], &b[12]); 47363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#endif 4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 50363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger/////////////////////////////////////////////////////////////////////////////// 51363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 52363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerint SkMatrix44::computeTypeMask() const { 53363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger unsigned mask = 0; 54363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 55363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (0 != perspX() || 0 != perspY() || 0 != perspZ() || 1 != fMat[3][3]) { 56363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return kTranslate_Mask | kScale_Mask | kAffine_Mask | kPerspective_Mask; 57363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 58363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 59363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (0 != transX() || 0 != transY() || 0 != transZ()) { 60363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger mask |= kTranslate_Mask; 61363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 62363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 63363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (1 != scaleX() || 1 != scaleY() || 1 != scaleZ()) { 64363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger mask |= kScale_Mask; 65363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 66363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 67363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (0 != fMat[1][0] || 0 != fMat[0][1] || 0 != fMat[0][2] || 68363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 0 != fMat[2][0] || 0 != fMat[1][2] || 0 != fMat[2][1]) { 69363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger mask |= kAffine_Mask; 70363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 71363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 72363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return mask; 7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix44::asColMajorf(float dst[]) const { 7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkMScalar* src = &fMat[0][0]; 7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_MSCALAR_IS_DOUBLE 8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = 0; i < 16; ++i) { 8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst[i] = SkMScalarToFloat(src[i]); 8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 83363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#elif defined SK_MSCALAR_IS_FLOAT 8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru memcpy(dst, src, 16 * sizeof(float)); 8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix44::asColMajord(double dst[]) const { 8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkMScalar* src = &fMat[0][0]; 9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_MSCALAR_IS_DOUBLE 9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru memcpy(dst, src, 16 * sizeof(double)); 92363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#elif defined SK_MSCALAR_IS_FLOAT 9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = 0; i < 16; ++i) { 9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst[i] = SkMScalarToDouble(src[i]); 9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix44::asRowMajorf(float dst[]) const { 10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkMScalar* src = &fMat[0][0]; 10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = 0; i < 4; ++i) { 10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst[0] = SkMScalarToFloat(src[0]); 10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst[4] = SkMScalarToFloat(src[1]); 10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst[8] = SkMScalarToFloat(src[2]); 10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst[12] = SkMScalarToFloat(src[3]); 10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru src += 4; 10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst += 1; 10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix44::asRowMajord(double dst[]) const { 11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkMScalar* src = &fMat[0][0]; 11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = 0; i < 4; ++i) { 11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst[0] = SkMScalarToDouble(src[0]); 11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst[4] = SkMScalarToDouble(src[1]); 11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst[8] = SkMScalarToDouble(src[2]); 11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst[12] = SkMScalarToDouble(src[3]); 11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru src += 4; 11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst += 1; 12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 123363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergervoid SkMatrix44::setColMajorf(const float src[]) { 124363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkMScalar* dst = &fMat[0][0]; 125363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#ifdef SK_MSCALAR_IS_DOUBLE 126363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger for (int i = 0; i < 16; ++i) { 127363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst[i] = SkMScalarToFloat(src[i]); 128363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 129363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#elif defined SK_MSCALAR_IS_FLOAT 130363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger memcpy(dst, src, 16 * sizeof(float)); 131363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#endif 13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 133363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger this->dirtyTypeMask(); 134363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger} 135363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 136363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergervoid SkMatrix44::setColMajord(const double src[]) { 137363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkMScalar* dst = &fMat[0][0]; 138363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#ifdef SK_MSCALAR_IS_DOUBLE 139363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger memcpy(dst, src, 16 * sizeof(double)); 140363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#elif defined SK_MSCALAR_IS_FLOAT 141363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger for (int i = 0; i < 16; ++i) { 142363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst[i] = SkDoubleToMScalar(src[i]); 143363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 144363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#endif 145363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 146363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger this->dirtyTypeMask(); 147363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger} 148363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 149363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergervoid SkMatrix44::setRowMajorf(const float src[]) { 150363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkMScalar* dst = &fMat[0][0]; 151363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger for (int i = 0; i < 4; ++i) { 152363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst[0] = SkMScalarToFloat(src[0]); 153363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst[4] = SkMScalarToFloat(src[1]); 154363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst[8] = SkMScalarToFloat(src[2]); 155363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst[12] = SkMScalarToFloat(src[3]); 156363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger src += 4; 157363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst += 1; 158363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 159363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger this->dirtyTypeMask(); 160363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger} 161363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 162363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergervoid SkMatrix44::setRowMajord(const double src[]) { 163363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkMScalar* dst = &fMat[0][0]; 164363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger for (int i = 0; i < 4; ++i) { 165363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst[0] = SkDoubleToMScalar(src[0]); 166363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst[4] = SkDoubleToMScalar(src[1]); 167363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst[8] = SkDoubleToMScalar(src[2]); 168363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst[12] = SkDoubleToMScalar(src[3]); 169363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger src += 4; 170363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst += 1; 171363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 172363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger this->dirtyTypeMask(); 17380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 17480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 17580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 17680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 177363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerconst SkMatrix44& SkMatrix44::I() { 178363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger static const SkMatrix44 gIdentity44(kIdentity_Constructor); 179363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return gIdentity44; 180363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger} 181363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 18280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix44::setIdentity() { 1830a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger fMat[0][0] = 1; 1840a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger fMat[0][1] = 0; 1850a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger fMat[0][2] = 0; 1860a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger fMat[0][3] = 0; 1870a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger fMat[1][0] = 0; 1880a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger fMat[1][1] = 1; 1890a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger fMat[1][2] = 0; 1900a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger fMat[1][3] = 0; 1910a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger fMat[2][0] = 0; 1920a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger fMat[2][1] = 0; 1930a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger fMat[2][2] = 1; 1940a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger fMat[2][3] = 0; 1950a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger fMat[3][0] = 0; 1960a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger fMat[3][1] = 0; 1970a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger fMat[3][2] = 0; 1980a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger fMat[3][3] = 1; 199363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger this->setTypeMask(kIdentity_Mask); 20080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 20180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 20280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix44::set3x3(SkMScalar m00, SkMScalar m01, SkMScalar m02, 20380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMScalar m10, SkMScalar m11, SkMScalar m12, 20480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMScalar m20, SkMScalar m21, SkMScalar m22) { 20580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[0][0] = m00; fMat[0][1] = m01; fMat[0][2] = m02; fMat[0][3] = 0; 20680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[1][0] = m10; fMat[1][1] = m11; fMat[1][2] = m12; fMat[1][3] = 0; 20780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[2][0] = m20; fMat[2][1] = m21; fMat[2][2] = m22; fMat[2][3] = 0; 20880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[3][0] = 0; fMat[3][1] = 0; fMat[3][2] = 0; fMat[3][3] = 1; 209363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger this->dirtyTypeMask(); 21080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 21180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 21280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 21380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 214363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergervoid SkMatrix44::setTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz) { 21580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->setIdentity(); 216363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 217363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (!dx && !dy && !dz) { 218363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return; 219363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 220363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 221363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fMat[3][0] = dx; 222363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fMat[3][1] = dy; 223363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fMat[3][2] = dz; 224363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger this->setTypeMask(kTranslate_Mask); 22580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 22680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 22780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix44::preTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz) { 228363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (!dx && !dy && !dz) { 229363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return; 230363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 231363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 232363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger for (int i = 0; i < 4; ++i) { 2330a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger fMat[3][i] = fMat[0][i] * dx + fMat[1][i] * dy + fMat[2][i] * dz + fMat[3][i]; 234363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 235363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger this->dirtyTypeMask(); 23680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 23780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 23880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix44::postTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz) { 239363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (!dx && !dy && !dz) { 240363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return; 241363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 242363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 243363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (this->getType() & kPerspective_Mask) { 244363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger for (int i = 0; i < 4; ++i) { 245363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fMat[i][0] += fMat[i][3] * dx; 246363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fMat[i][1] += fMat[i][3] * dy; 247363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fMat[i][2] += fMat[i][3] * dz; 248363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 249363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } else { 250363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fMat[3][0] += dx; 251363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fMat[3][1] += dy; 252363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fMat[3][2] += dz; 253363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger this->dirtyTypeMask(); 254363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 25580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 25680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 25780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 25880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 25980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix44::setScale(SkMScalar sx, SkMScalar sy, SkMScalar sz) { 260363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger this->setIdentity(); 261363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 262363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (1 == sx && 1 == sy && 1 == sz) { 263363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return; 264363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 265363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 26680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[0][0] = sx; 26780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[1][1] = sy; 26880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[2][2] = sz; 269363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger this->setTypeMask(kScale_Mask); 27080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 27180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 27280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix44::preScale(SkMScalar sx, SkMScalar sy, SkMScalar sz) { 273363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (1 == sx && 1 == sy && 1 == sz) { 274363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return; 275363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 276363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 277363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // The implementation matrix * pureScale can be shortcut 278363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // by knowing that pureScale components effectively scale 279363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // the columns of the original matrix. 280363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger for (int i = 0; i < 4; i++) { 281363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fMat[0][i] *= sx; 282363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fMat[1][i] *= sy; 283363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fMat[2][i] *= sz; 284363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 285363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger this->dirtyTypeMask(); 28680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 28780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 28880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix44::postScale(SkMScalar sx, SkMScalar sy, SkMScalar sz) { 289363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (1 == sx && 1 == sy && 1 == sz) { 290363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return; 291363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 292363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 29380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = 0; i < 4; i++) { 29480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[i][0] *= sx; 29580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[i][1] *= sy; 29680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[i][2] *= sz; 29780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 298363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger this->dirtyTypeMask(); 29980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 30080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 30180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 30280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 30380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix44::setRotateAbout(SkMScalar x, SkMScalar y, SkMScalar z, 30480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMScalar radians) { 305363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double len2 = (double)x * x + (double)y * y + (double)z * z; 306363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (1 != len2) { 307363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (0 == len2) { 30880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->setIdentity(); 30980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 31080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 31180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru double scale = 1 / sqrt(len2); 31280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru x = SkDoubleToMScalar(x * scale); 31380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru y = SkDoubleToMScalar(y * scale); 31480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru z = SkDoubleToMScalar(z * scale); 31580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 31680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->setRotateAboutUnit(x, y, z, radians); 31780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 31880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 31980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix44::setRotateAboutUnit(SkMScalar x, SkMScalar y, SkMScalar z, 32080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMScalar radians) { 32180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru double c = cos(radians); 32280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru double s = sin(radians); 32380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru double C = 1 - c; 32480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru double xs = x * s; 32580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru double ys = y * s; 32680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru double zs = z * s; 32780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru double xC = x * C; 32880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru double yC = y * C; 32980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru double zC = z * C; 33080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru double xyC = x * yC; 33180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru double yzC = y * zC; 33280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru double zxC = z * xC; 33380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 33480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // if you're looking at wikipedia, remember that we're column major. 33580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->set3x3(SkDoubleToMScalar(x * xC + c), // scale x 33680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDoubleToMScalar(xyC + zs), // skew x 33780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDoubleToMScalar(zxC - ys), // trans x 33880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 33980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDoubleToMScalar(xyC - zs), // skew y 34080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDoubleToMScalar(y * yC + c), // scale y 34180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDoubleToMScalar(yzC + xs), // trans y 34280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 34380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDoubleToMScalar(zxC + ys), // persp x 34480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDoubleToMScalar(yzC - xs), // persp y 34580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDoubleToMScalar(z * zC + c)); // persp 2 34680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 34780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 34880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 34980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 350363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerstatic bool bits_isonly(int value, int mask) { 351363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return 0 == (value & ~mask); 352363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger} 353363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 35480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix44::setConcat(const SkMatrix44& a, const SkMatrix44& b) { 355363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const SkMatrix44::TypeMask a_mask = a.getType(); 356363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const SkMatrix44::TypeMask b_mask = b.getType(); 357363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 358363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (kIdentity_Mask == a_mask) { 359363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger *this = b; 360363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return; 361363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 362363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (kIdentity_Mask == b_mask) { 363363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger *this = a; 364363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return; 365363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 366363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 367363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger bool useStorage = (this == &a || this == &b); 368363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkMScalar storage[16]; 369363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkMScalar* result = useStorage ? storage : &fMat[0][0]; 370363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 371d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger // Both matrices are at most scale+translate 372363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (bits_isonly(a_mask | b_mask, kScale_Mask | kTranslate_Mask)) { 373363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger result[0] = a.fMat[0][0] * b.fMat[0][0]; 374d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger result[1] = result[2] = result[3] = result[4] = 0; 375363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger result[5] = a.fMat[1][1] * b.fMat[1][1]; 376d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger result[6] = result[7] = result[8] = result[9] = 0; 377363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger result[10] = a.fMat[2][2] * b.fMat[2][2]; 378d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger result[11] = 0; 379363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger result[12] = a.fMat[0][0] * b.fMat[3][0] + a.fMat[3][0]; 380363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger result[13] = a.fMat[1][1] * b.fMat[3][1] + a.fMat[3][1]; 381363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger result[14] = a.fMat[2][2] * b.fMat[3][2] + a.fMat[3][2]; 382363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger result[15] = 1; 383363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } else { 38480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int j = 0; j < 4; j++) { 385363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger for (int i = 0; i < 4; i++) { 386363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double value = 0; 387363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger for (int k = 0; k < 4; k++) { 388363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger value += SkMScalarToDouble(a.fMat[k][i]) * b.fMat[j][k]; 389363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 390363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger *result++ = SkDoubleToMScalar(value); 39180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 39280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 39380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 394363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 395363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (useStorage) { 396363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger memcpy(fMat, storage, sizeof(storage)); 397363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 398363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger this->dirtyTypeMask(); 39980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 40080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 40180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 40280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 40380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/** We always perform the calculation in doubles, to avoid prematurely losing 40480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru precision along the way. This relies on the compiler automatically 40580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru promoting our SkMScalar values to double (if needed). 40680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 40780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querudouble SkMatrix44::determinant() const { 408363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (this->isIdentity()) { 409363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return 1; 410363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 411363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (this->isScaleTranslate()) { 412363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return fMat[0][0] * fMat[1][1] * fMat[2][2] * fMat[3][3]; 413363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 414363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 415363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double a00 = fMat[0][0]; 416363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double a01 = fMat[0][1]; 417363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double a02 = fMat[0][2]; 418363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double a03 = fMat[0][3]; 419363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double a10 = fMat[1][0]; 420363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double a11 = fMat[1][1]; 421363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double a12 = fMat[1][2]; 422363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double a13 = fMat[1][3]; 423363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double a20 = fMat[2][0]; 424363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double a21 = fMat[2][1]; 425363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double a22 = fMat[2][2]; 426363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double a23 = fMat[2][3]; 427363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double a30 = fMat[3][0]; 428363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double a31 = fMat[3][1]; 429363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double a32 = fMat[3][2]; 430363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double a33 = fMat[3][3]; 431363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 432363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double b00 = a00 * a11 - a01 * a10; 433363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double b01 = a00 * a12 - a02 * a10; 434363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double b02 = a00 * a13 - a03 * a10; 435363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double b03 = a01 * a12 - a02 * a11; 436363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double b04 = a01 * a13 - a03 * a11; 437363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double b05 = a02 * a13 - a03 * a12; 438363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double b06 = a20 * a31 - a21 * a30; 439363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double b07 = a20 * a32 - a22 * a30; 440363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double b08 = a20 * a33 - a23 * a30; 441363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double b09 = a21 * a32 - a22 * a31; 442363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double b10 = a21 * a33 - a23 * a31; 443363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double b11 = a22 * a33 - a23 * a32; 444363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 445363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // Calculate the determinant 446363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06; 44780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 44880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 44980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 45080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 45180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkMatrix44::invert(SkMatrix44* inverse) const { 452363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (this->isIdentity()) { 453363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (inverse) { 4540a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger inverse->setIdentity(); 455363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 456910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger return true; 457363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 458910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger 459363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (this->isTranslate()) { 460363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (inverse) { 461363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger inverse->setTranslate(-fMat[3][0], -fMat[3][1], -fMat[3][2]); 462363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 463363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return true; 464363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 465910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger 466363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (this->isScaleTranslate()) { 467363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (0 == fMat[0][0] * fMat[1][1] * fMat[2][2]) { 468363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return false; 469363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 470363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 471910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger if (inverse) { 472910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger double invXScale = 1 / fMat[0][0]; 473910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger double invYScale = 1 / fMat[1][1]; 474910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger double invZScale = 1 / fMat[2][2]; 4750a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 4760a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger inverse->fMat[0][0] = invXScale; 477910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger inverse->fMat[0][1] = 0; 478910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger inverse->fMat[0][2] = 0; 479910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger inverse->fMat[0][3] = 0; 4800a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 481910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger inverse->fMat[1][0] = 0; 482910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger inverse->fMat[1][1] = invYScale; 483910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger inverse->fMat[1][2] = 0; 484910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger inverse->fMat[1][3] = 0; 4850a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 486910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger inverse->fMat[2][0] = 0; 4870a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger inverse->fMat[2][1] = 0; 488910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger inverse->fMat[2][2] = invZScale; 489910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger inverse->fMat[2][3] = 0; 4900a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 4910a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger inverse->fMat[3][0] = -fMat[3][0] * invXScale; 4920a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger inverse->fMat[3][1] = -fMat[3][1] * invYScale; 4930a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger inverse->fMat[3][2] = -fMat[3][2] * invZScale; 494363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger inverse->fMat[3][3] = 1; 495363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 496363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger inverse->setTypeMask(this->getType()); 497363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 4980a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 499363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return true; 500363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 501363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 502363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double a00 = fMat[0][0]; 503363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double a01 = fMat[0][1]; 504363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double a02 = fMat[0][2]; 505363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double a03 = fMat[0][3]; 506363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double a10 = fMat[1][0]; 507363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double a11 = fMat[1][1]; 508363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double a12 = fMat[1][2]; 509363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double a13 = fMat[1][3]; 510363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double a20 = fMat[2][0]; 511363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double a21 = fMat[2][1]; 512363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double a22 = fMat[2][2]; 513363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double a23 = fMat[2][3]; 514363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double a30 = fMat[3][0]; 515363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double a31 = fMat[3][1]; 516363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double a32 = fMat[3][2]; 517363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double a33 = fMat[3][3]; 518363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 5190a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger if (!(this->getType() & kPerspective_Mask)) { 5200a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger // If we know the matrix has no perspective, then the perspective 5210a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger // component is (0, 0, 0, 1). We can use this information to save a lot 5220a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger // of arithmetic that would otherwise be spent to compute the inverse 5230a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger // of a general matrix. 5240a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 5250a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkASSERT(a03 == 0); 5260a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkASSERT(a13 == 0); 5270a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkASSERT(a23 == 0); 5280a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkASSERT(a33 == 1); 5290a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 5300a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger double b00 = a00 * a11 - a01 * a10; 5310a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger double b01 = a00 * a12 - a02 * a10; 5320a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger double b03 = a01 * a12 - a02 * a11; 5330a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger double b06 = a20 * a31 - a21 * a30; 5340a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger double b07 = a20 * a32 - a22 * a30; 5350a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger double b08 = a20; 5360a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger double b09 = a21 * a32 - a22 * a31; 5370a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger double b10 = a21; 5380a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger double b11 = a22; 5390a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 5400a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger // Calculate the determinant 5410a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger double det = b00 * b11 - b01 * b10 + b03 * b08; 5420a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 5430a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger double invdet = 1.0 / det; 5440a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger // If det is zero, we want to return false. However, we also want to return false 5450a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger // if 1/det overflows to infinity (i.e. det is denormalized). Both of these are 5460a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger // handled by checking that 1/det is finite. 5470a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger if (!sk_float_isfinite(invdet)) { 5480a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger return false; 5490a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger } 5500a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger if (NULL == inverse) { 5510a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger return true; 5520a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger } 5530a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 5540a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger b00 *= invdet; 5550a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger b01 *= invdet; 5560a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger b03 *= invdet; 5570a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger b06 *= invdet; 5580a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger b07 *= invdet; 5590a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger b08 *= invdet; 5600a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger b09 *= invdet; 5610a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger b10 *= invdet; 5620a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger b11 *= invdet; 5630a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 5640a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger inverse->fMat[0][0] = SkDoubleToMScalar(a11 * b11 - a12 * b10); 5650a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger inverse->fMat[0][1] = SkDoubleToMScalar(a02 * b10 - a01 * b11); 5660a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger inverse->fMat[0][2] = SkDoubleToMScalar(b03); 5670a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger inverse->fMat[0][3] = 0; 5680a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger inverse->fMat[1][0] = SkDoubleToMScalar(a12 * b08 - a10 * b11); 5690a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger inverse->fMat[1][1] = SkDoubleToMScalar(a00 * b11 - a02 * b08); 5700a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger inverse->fMat[1][2] = SkDoubleToMScalar(-b01); 5710a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger inverse->fMat[1][3] = 0; 5720a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger inverse->fMat[2][0] = SkDoubleToMScalar(a10 * b10 - a11 * b08); 5730a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger inverse->fMat[2][1] = SkDoubleToMScalar(a01 * b08 - a00 * b10); 5740a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger inverse->fMat[2][2] = SkDoubleToMScalar(b00); 5750a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger inverse->fMat[2][3] = 0; 5760a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger inverse->fMat[3][0] = SkDoubleToMScalar(a11 * b07 - a10 * b09 - a12 * b06); 5770a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger inverse->fMat[3][1] = SkDoubleToMScalar(a00 * b09 - a01 * b07 + a02 * b06); 5780a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger inverse->fMat[3][2] = SkDoubleToMScalar(a31 * b01 - a30 * b03 - a32 * b00); 5790a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger inverse->fMat[3][3] = 1; 5800a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 5810a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger inverse->setTypeMask(this->getType()); 5820a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger return true; 5830a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger } 5840a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 585363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double b00 = a00 * a11 - a01 * a10; 586363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double b01 = a00 * a12 - a02 * a10; 587363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double b02 = a00 * a13 - a03 * a10; 588363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double b03 = a01 * a12 - a02 * a11; 589363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double b04 = a01 * a13 - a03 * a11; 590363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double b05 = a02 * a13 - a03 * a12; 591363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double b06 = a20 * a31 - a21 * a30; 592363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double b07 = a20 * a32 - a22 * a30; 593363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double b08 = a20 * a33 - a23 * a30; 594363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double b09 = a21 * a32 - a22 * a31; 595363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double b10 = a21 * a33 - a23 * a31; 596363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double b11 = a22 * a33 - a23 * a32; 597363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 598363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // Calculate the determinant 599363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06; 600363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 6010a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger double invdet = 1.0 / det; 6020a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger // If det is zero, we want to return false. However, we also want to return false 6030a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger // if 1/det overflows to infinity (i.e. det is denormalized). Both of these are 6040a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger // handled by checking that 1/det is finite. 6050a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger if (!sk_float_isfinite(invdet)) { 60680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 60780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 60880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == inverse) { 60980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 61080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 611363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 612363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger b00 *= invdet; 613363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger b01 *= invdet; 614363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger b02 *= invdet; 615363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger b03 *= invdet; 616363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger b04 *= invdet; 617363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger b05 *= invdet; 618363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger b06 *= invdet; 619363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger b07 *= invdet; 620363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger b08 *= invdet; 621363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger b09 *= invdet; 622363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger b10 *= invdet; 623363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger b11 *= invdet; 624363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 625363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger inverse->fMat[0][0] = SkDoubleToMScalar(a11 * b11 - a12 * b10 + a13 * b09); 626363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger inverse->fMat[0][1] = SkDoubleToMScalar(a02 * b10 - a01 * b11 - a03 * b09); 627363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger inverse->fMat[0][2] = SkDoubleToMScalar(a31 * b05 - a32 * b04 + a33 * b03); 628363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger inverse->fMat[0][3] = SkDoubleToMScalar(a22 * b04 - a21 * b05 - a23 * b03); 629363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger inverse->fMat[1][0] = SkDoubleToMScalar(a12 * b08 - a10 * b11 - a13 * b07); 630363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger inverse->fMat[1][1] = SkDoubleToMScalar(a00 * b11 - a02 * b08 + a03 * b07); 631363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger inverse->fMat[1][2] = SkDoubleToMScalar(a32 * b02 - a30 * b05 - a33 * b01); 632363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger inverse->fMat[1][3] = SkDoubleToMScalar(a20 * b05 - a22 * b02 + a23 * b01); 633363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger inverse->fMat[2][0] = SkDoubleToMScalar(a10 * b10 - a11 * b08 + a13 * b06); 634363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger inverse->fMat[2][1] = SkDoubleToMScalar(a01 * b08 - a00 * b10 - a03 * b06); 635363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger inverse->fMat[2][2] = SkDoubleToMScalar(a30 * b04 - a31 * b02 + a33 * b00); 636363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger inverse->fMat[2][3] = SkDoubleToMScalar(a21 * b02 - a20 * b04 - a23 * b00); 637363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger inverse->fMat[3][0] = SkDoubleToMScalar(a11 * b07 - a10 * b09 - a12 * b06); 638363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger inverse->fMat[3][1] = SkDoubleToMScalar(a00 * b09 - a01 * b07 + a02 * b06); 639363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger inverse->fMat[3][2] = SkDoubleToMScalar(a31 * b01 - a30 * b03 - a32 * b00); 640363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger inverse->fMat[3][3] = SkDoubleToMScalar(a20 * b03 - a21 * b01 + a22 * b00); 641363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger inverse->dirtyTypeMask(); 642363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 643363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return true; 644363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger} 645363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 646363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger/////////////////////////////////////////////////////////////////////////////// 647363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 648363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergervoid SkMatrix44::transpose() { 649363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkTSwap(fMat[0][1], fMat[1][0]); 650363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkTSwap(fMat[0][2], fMat[2][0]); 651363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkTSwap(fMat[0][3], fMat[3][0]); 652363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkTSwap(fMat[1][2], fMat[2][1]); 653363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkTSwap(fMat[1][3], fMat[3][1]); 654363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkTSwap(fMat[2][3], fMat[3][2]); 655363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 656363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (!this->isTriviallyIdentity()) { 657363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger this->dirtyTypeMask(); 658363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 659363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger} 660363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 661363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger/////////////////////////////////////////////////////////////////////////////// 662363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 663363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergervoid SkMatrix44::mapScalars(const SkScalar src[4], SkScalar dst[4]) const { 664363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkScalar storage[4]; 665363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkScalar* result = (src == dst) ? storage : dst; 66680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 66780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = 0; i < 4; i++) { 668363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkMScalar value = 0; 66980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int j = 0; j < 4; j++) { 670363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger value += fMat[j][i] * src[j]; 67180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 672363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger result[i] = SkMScalarToScalar(value); 673363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 674363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 675363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (storage == result) { 676363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger memcpy(dst, storage, sizeof(storage)); 67780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 67880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 67980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 680363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#ifdef SK_MSCALAR_IS_DOUBLE 681363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 682363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergervoid SkMatrix44::mapMScalars(const SkMScalar src[4], SkMScalar dst[4]) const { 683363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkMScalar storage[4]; 684363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkMScalar* result = (src == dst) ? storage : dst; 68580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 68680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = 0; i < 4; i++) { 68780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMScalar value = 0; 68880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int j = 0; j < 4; j++) { 68980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru value += fMat[j][i] * src[j]; 69080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 691363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger result[i] = value; 692363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 693363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 694363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (storage == result) { 695363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger memcpy(dst, storage, sizeof(storage)); 696363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 697363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger} 698363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 699363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#endif 700363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 701363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergertypedef void (*Map2Procf)(const SkMScalar mat[][4], const float src2[], int count, float dst4[]); 702363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergertypedef void (*Map2Procd)(const SkMScalar mat[][4], const double src2[], int count, double dst4[]); 703363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 704363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerstatic void map2_if(const SkMScalar mat[][4], const float* SK_RESTRICT src2, 705363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger int count, float* SK_RESTRICT dst4) { 706363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger for (int i = 0; i < count; ++i) { 707363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst4[0] = src2[0]; 708363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst4[1] = src2[1]; 709363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst4[2] = 0; 710363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst4[3] = 1; 711363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger src2 += 2; 712363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst4 += 4; 713363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 714363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger} 715363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 716363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerstatic void map2_id(const SkMScalar mat[][4], const double* SK_RESTRICT src2, 717363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger int count, double* SK_RESTRICT dst4) { 718363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger for (int i = 0; i < count; ++i) { 719363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst4[0] = src2[0]; 720363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst4[1] = src2[1]; 721363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst4[2] = 0; 722363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst4[3] = 1; 723363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger src2 += 2; 724363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst4 += 4; 725363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 726363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger} 727363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 728363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerstatic void map2_tf(const SkMScalar mat[][4], const float* SK_RESTRICT src2, 729363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger int count, float* SK_RESTRICT dst4) { 730363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const float mat30 = SkMScalarToFloat(mat[3][0]); 731363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const float mat31 = SkMScalarToFloat(mat[3][1]); 732363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const float mat32 = SkMScalarToFloat(mat[3][2]); 733363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger for (int n = 0; n < count; ++n) { 734363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst4[0] = src2[0] + mat30; 735363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst4[1] = src2[1] + mat31; 736363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst4[2] = mat32; 737363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst4[3] = 1; 738363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger src2 += 2; 739363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst4 += 4; 740363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 741363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger} 742363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 743363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerstatic void map2_td(const SkMScalar mat[][4], const double* SK_RESTRICT src2, 744363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger int count, double* SK_RESTRICT dst4) { 745363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger for (int n = 0; n < count; ++n) { 746363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst4[0] = src2[0] + mat[3][0]; 747363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst4[1] = src2[1] + mat[3][1]; 748363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst4[2] = mat[3][2]; 749363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst4[3] = 1; 750363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger src2 += 2; 751363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst4 += 4; 752363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 753363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger} 754363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 755363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerstatic void map2_sf(const SkMScalar mat[][4], const float* SK_RESTRICT src2, 756363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger int count, float* SK_RESTRICT dst4) { 757363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const float mat32 = SkMScalarToFloat(mat[3][2]); 758363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger for (int n = 0; n < count; ++n) { 759363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst4[0] = SkMScalarToFloat(mat[0][0] * src2[0] + mat[3][0]); 760363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst4[1] = SkMScalarToFloat(mat[1][1] * src2[1] + mat[3][1]); 761363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst4[2] = mat32; 762363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst4[3] = 1; 763363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger src2 += 2; 764363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst4 += 4; 765363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 766363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger} 767363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 768363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerstatic void map2_sd(const SkMScalar mat[][4], const double* SK_RESTRICT src2, 769363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger int count, double* SK_RESTRICT dst4) { 770363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger for (int n = 0; n < count; ++n) { 771363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst4[0] = mat[0][0] * src2[0] + mat[3][0]; 772363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst4[1] = mat[1][1] * src2[1] + mat[3][1]; 773363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst4[2] = mat[3][2]; 774363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst4[3] = 1; 775363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger src2 += 2; 776363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst4 += 4; 77780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 778363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger} 779363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 780363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerstatic void map2_af(const SkMScalar mat[][4], const float* SK_RESTRICT src2, 781363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger int count, float* SK_RESTRICT dst4) { 7820a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkMScalar r; 783363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger for (int n = 0; n < count; ++n) { 7840a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkMScalar sx = SkFloatToMScalar(src2[0]); 7850a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkMScalar sy = SkFloatToMScalar(src2[1]); 786363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger r = mat[0][0] * sx + mat[1][0] * sy + mat[3][0]; 787363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst4[0] = SkMScalarToFloat(r); 788363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger r = mat[0][1] * sx + mat[1][1] * sy + mat[3][1]; 789363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst4[1] = SkMScalarToFloat(r); 790363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger r = mat[0][2] * sx + mat[1][2] * sy + mat[3][2]; 791363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst4[2] = SkMScalarToFloat(r); 792363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst4[3] = 1; 793363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger src2 += 2; 794363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst4 += 4; 795363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 796363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger} 797363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 798363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerstatic void map2_ad(const SkMScalar mat[][4], const double* SK_RESTRICT src2, 799363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger int count, double* SK_RESTRICT dst4) { 800363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger for (int n = 0; n < count; ++n) { 801363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double sx = src2[0]; 802363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double sy = src2[1]; 803363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst4[0] = mat[0][0] * sx + mat[1][0] * sy + mat[3][0]; 804363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst4[1] = mat[0][1] * sx + mat[1][1] * sy + mat[3][1]; 805363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst4[2] = mat[0][2] * sx + mat[1][2] * sy + mat[3][2]; 806363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst4[3] = 1; 807363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger src2 += 2; 808363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst4 += 4; 809363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 810363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger} 811363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 812363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerstatic void map2_pf(const SkMScalar mat[][4], const float* SK_RESTRICT src2, 813363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger int count, float* SK_RESTRICT dst4) { 8140a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkMScalar r; 815363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger for (int n = 0; n < count; ++n) { 8160a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkMScalar sx = SkFloatToMScalar(src2[0]); 8170a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkMScalar sy = SkFloatToMScalar(src2[1]); 818363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger for (int i = 0; i < 4; i++) { 819363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger r = mat[0][i] * sx + mat[1][i] * sy + mat[3][i]; 820363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst4[i] = SkMScalarToFloat(r); 821363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 822363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger src2 += 2; 823363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst4 += 4; 824363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 825363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger} 826363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 827363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerstatic void map2_pd(const SkMScalar mat[][4], const double* SK_RESTRICT src2, 828363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger int count, double* SK_RESTRICT dst4) { 829363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger for (int n = 0; n < count; ++n) { 830363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double sx = src2[0]; 831363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger double sy = src2[1]; 832363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger for (int i = 0; i < 4; i++) { 833363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst4[i] = mat[0][i] * sx + mat[1][i] * sy + mat[3][i]; 834363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 835363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger src2 += 2; 836363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger dst4 += 4; 837363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 838363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger} 839363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 840363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergervoid SkMatrix44::map2(const float src2[], int count, float dst4[]) const { 841363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger static const Map2Procf gProc[] = { 842363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger map2_if, map2_tf, map2_sf, map2_sf, map2_af, map2_af, map2_af, map2_af 843363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger }; 844363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 845363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger TypeMask mask = this->getType(); 846363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger Map2Procf proc = (mask & kPerspective_Mask) ? map2_pf : gProc[mask]; 847363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger proc(fMat, src2, count, dst4); 848363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger} 849363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 850363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergervoid SkMatrix44::map2(const double src2[], int count, double dst4[]) const { 851363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger static const Map2Procd gProc[] = { 852363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger map2_id, map2_td, map2_sd, map2_sd, map2_ad, map2_ad, map2_ad, map2_ad 853363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger }; 854363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 855363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger TypeMask mask = this->getType(); 856363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger Map2Procd proc = (mask & kPerspective_Mask) ? map2_pd : gProc[mask]; 857363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger proc(fMat, src2, count, dst4); 85880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 85980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 86080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 86180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 86280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix44::dump() const { 86380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static const char* format = 86480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru "[%g %g %g %g][%g %g %g %g][%g %g %g %g][%g %g %g %g]\n"; 86580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if 0 86680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf(format, 86780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[0][0], fMat[1][0], fMat[2][0], fMat[3][0], 86880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[0][1], fMat[1][1], fMat[2][1], fMat[3][1], 86980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[0][2], fMat[1][2], fMat[2][2], fMat[3][2], 87080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[0][3], fMat[1][3], fMat[2][3], fMat[3][3]); 87180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#else 87280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf(format, 87380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[0][0], fMat[0][1], fMat[0][2], fMat[0][3], 87480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[1][0], fMat[1][1], fMat[1][2], fMat[1][3], 87580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[2][0], fMat[2][1], fMat[2][2], fMat[2][3], 87680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[3][0], fMat[3][1], fMat[3][2], fMat[3][3]); 87780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 87880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 87980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 88080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 88180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 88280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void initFromMatrix(SkMScalar dst[4][4], const SkMatrix& src) { 88380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst[0][0] = SkScalarToMScalar(src[SkMatrix::kMScaleX]); 88480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst[1][0] = SkScalarToMScalar(src[SkMatrix::kMSkewX]); 8850a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger dst[2][0] = 0; 88680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst[3][0] = SkScalarToMScalar(src[SkMatrix::kMTransX]); 88780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst[0][1] = SkScalarToMScalar(src[SkMatrix::kMSkewY]); 88880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst[1][1] = SkScalarToMScalar(src[SkMatrix::kMScaleY]); 8890a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger dst[2][1] = 0; 89080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst[3][1] = SkScalarToMScalar(src[SkMatrix::kMTransY]); 8910a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger dst[0][2] = 0; 8920a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger dst[1][2] = 0; 8930a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger dst[2][2] = 1; 8940a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger dst[3][2] = 0; 8950a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger dst[0][3] = SkScalarToMScalar(src[SkMatrix::kMPersp0]); 8960a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger dst[1][3] = SkScalarToMScalar(src[SkMatrix::kMPersp1]); 8970a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger dst[2][3] = 0; 8980a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger dst[3][3] = SkScalarToMScalar(src[SkMatrix::kMPersp2]); 89980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 90080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 90180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkMatrix44::SkMatrix44(const SkMatrix& src) { 90280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru initFromMatrix(fMat, src); 90380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 90480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 90580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkMatrix44& SkMatrix44::operator=(const SkMatrix& src) { 90680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru initFromMatrix(fMat, src); 907363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 908363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (src.isIdentity()) { 909363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger this->setTypeMask(kIdentity_Mask); 910363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } else { 911363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger this->dirtyTypeMask(); 912363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 91380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return *this; 91480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 91580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 91680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkMatrix44::operator SkMatrix() const { 91780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMatrix dst; 91880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 91980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst[SkMatrix::kMScaleX] = SkMScalarToScalar(fMat[0][0]); 92080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst[SkMatrix::kMSkewX] = SkMScalarToScalar(fMat[1][0]); 92180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst[SkMatrix::kMTransX] = SkMScalarToScalar(fMat[3][0]); 92280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 92380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst[SkMatrix::kMSkewY] = SkMScalarToScalar(fMat[0][1]); 92480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst[SkMatrix::kMScaleY] = SkMScalarToScalar(fMat[1][1]); 92580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst[SkMatrix::kMTransY] = SkMScalarToScalar(fMat[3][1]); 92680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 9270a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger dst[SkMatrix::kMPersp0] = SkMScalarToScalar(fMat[0][3]); 9280a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger dst[SkMatrix::kMPersp1] = SkMScalarToScalar(fMat[1][3]); 9290a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger dst[SkMatrix::kMPersp2] = SkMScalarToScalar(fMat[3][3]); 9300a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 93180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return dst; 93280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 933