1 2 /* 3 * Copyright 2011 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9 10 11 #ifndef SkMatrix44_DEFINED 12 #define SkMatrix44_DEFINED 13 14 #include "SkMatrix.h" 15 #include "SkScalar.h" 16 17 #ifdef SK_MSCALAR_IS_DOUBLE 18 typedef double SkMScalar; 19 static inline double SkFloatToMScalar(float x) { 20 return static_cast<double>(x); 21 } 22 static inline float SkMScalarToFloat(double x) { 23 return static_cast<float>(x); 24 } 25 static inline double SkDoubleToMScalar(double x) { 26 return x; 27 } 28 static inline double SkMScalarToDouble(double x) { 29 return x; 30 } 31 static const SkMScalar SK_MScalarPI = 3.141592653589793; 32 #else 33 typedef float SkMScalar; 34 static inline float SkFloatToMScalar(float x) { 35 return x; 36 } 37 static inline float SkMScalarToFloat(float x) { 38 return x; 39 } 40 static inline float SkDoubleToMScalar(double x) { 41 return static_cast<float>(x); 42 } 43 static inline double SkMScalarToDouble(float x) { 44 return static_cast<double>(x); 45 } 46 static const SkMScalar SK_MScalarPI = 3.14159265f; 47 #endif 48 49 #ifdef SK_SCALAR_IS_FLOAT 50 #define SkMScalarToScalar SkMScalarToFloat 51 #define SkScalarToMScalar SkFloatToMScalar 52 #else 53 #if SK_MSCALAR_IS_DOUBLE 54 // we don't have fixed <-> double macros, use double<->scalar macros 55 #define SkMScalarToScalar SkDoubleToScalar 56 #define SkScalarToMScalar SkScalarToDouble 57 #else 58 #define SkMScalarToScalar SkFloatToFixed 59 #define SkScalarToMScalar SkFixedToFloat 60 #endif 61 #endif 62 63 static const SkMScalar SK_MScalar1 = 1; 64 65 /////////////////////////////////////////////////////////////////////////////// 66 67 struct SkVector4 { 68 SkScalar fData[4]; 69 70 SkVector4() { 71 this->set(0, 0, 0, 1); 72 } 73 SkVector4(const SkVector4& src) { 74 memcpy(fData, src.fData, sizeof(fData)); 75 } 76 SkVector4(SkScalar x, SkScalar y, SkScalar z, SkScalar w = SK_Scalar1) { 77 fData[0] = x; 78 fData[1] = y; 79 fData[2] = z; 80 fData[3] = w; 81 } 82 83 SkVector4& operator=(const SkVector4& src) { 84 memcpy(fData, src.fData, sizeof(fData)); 85 return *this; 86 } 87 88 bool operator==(const SkVector4& v) { 89 return fData[0] == v.fData[0] && fData[1] == v.fData[1] && 90 fData[2] == v.fData[2] && fData[3] == v.fData[3]; 91 } 92 bool operator!=(const SkVector4& v) { 93 return !(*this == v); 94 } 95 bool equals(SkScalar x, SkScalar y, SkScalar z, SkScalar w = SK_Scalar1) { 96 return fData[0] == x && fData[1] == y && 97 fData[2] == z && fData[3] == w; 98 } 99 100 void set(SkScalar x, SkScalar y, SkScalar z, SkScalar w = SK_Scalar1) { 101 fData[0] = x; 102 fData[1] = y; 103 fData[2] = z; 104 fData[3] = w; 105 } 106 }; 107 108 class SK_API SkMatrix44 { 109 public: 110 SkMatrix44(); 111 SkMatrix44(const SkMatrix44&); 112 SkMatrix44(const SkMatrix44& a, const SkMatrix44& b); 113 114 SkMatrix44& operator=(const SkMatrix44& src) { 115 memcpy(this, &src, sizeof(*this)); 116 return *this; 117 } 118 119 bool operator==(const SkMatrix44& other) const { 120 return !memcmp(this, &other, sizeof(*this)); 121 } 122 bool operator!=(const SkMatrix44& other) const { 123 return !!memcmp(this, &other, sizeof(*this)); 124 } 125 126 SkMatrix44(const SkMatrix&); 127 SkMatrix44& operator=(const SkMatrix& src); 128 operator SkMatrix() const; 129 130 SkMScalar get(int row, int col) const; 131 void set(int row, int col, const SkMScalar& value); 132 133 void asColMajorf(float[]) const; 134 void asColMajord(double[]) const; 135 void asRowMajorf(float[]) const; 136 void asRowMajord(double[]) const; 137 138 bool isIdentity() const; 139 void setIdentity(); 140 void reset() { this->setIdentity();} 141 142 void set3x3(SkMScalar m00, SkMScalar m01, SkMScalar m02, 143 SkMScalar m10, SkMScalar m11, SkMScalar m12, 144 SkMScalar m20, SkMScalar m21, SkMScalar m22); 145 146 void setTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz); 147 void preTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz); 148 void postTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz); 149 150 void setScale(SkMScalar sx, SkMScalar sy, SkMScalar sz); 151 void preScale(SkMScalar sx, SkMScalar sy, SkMScalar sz); 152 void postScale(SkMScalar sx, SkMScalar sy, SkMScalar sz); 153 154 void setScale(SkMScalar scale) { 155 this->setScale(scale, scale, scale); 156 } 157 void preScale(SkMScalar scale) { 158 this->preScale(scale, scale, scale); 159 } 160 void postScale(SkMScalar scale) { 161 this->postScale(scale, scale, scale); 162 } 163 164 void setRotateDegreesAbout(SkMScalar x, SkMScalar y, SkMScalar z, 165 SkMScalar degrees) { 166 this->setRotateAbout(x, y, z, degrees * SK_MScalarPI / 180); 167 } 168 169 /** Rotate about the vector [x,y,z]. If that vector is not unit-length, 170 it will be automatically resized. 171 */ 172 void setRotateAbout(SkMScalar x, SkMScalar y, SkMScalar z, 173 SkMScalar radians); 174 /** Rotate about the vector [x,y,z]. Does not check the length of the 175 vector, assuming it is unit-length. 176 */ 177 void setRotateAboutUnit(SkMScalar x, SkMScalar y, SkMScalar z, 178 SkMScalar radians); 179 180 void setConcat(const SkMatrix44& a, const SkMatrix44& b); 181 void preConcat(const SkMatrix44& m) { 182 this->setConcat(*this, m); 183 } 184 void postConcat(const SkMatrix44& m) { 185 this->setConcat(m, *this); 186 } 187 188 friend SkMatrix44 operator*(const SkMatrix44& a, const SkMatrix44& b) { 189 return SkMatrix44(a, b); 190 } 191 192 /** If this is invertible, return that in inverse and return true. If it is 193 not invertible, return false and ignore the inverse parameter. 194 */ 195 bool invert(SkMatrix44* inverse) const; 196 197 /** Apply the matrix to the src vector, returning the new vector in dst. 198 It is legal for src and dst to point to the same memory. 199 */ 200 void map(const SkScalar src[4], SkScalar dst[4]) const; 201 void map(SkScalar vec[4]) const { 202 this->map(vec, vec); 203 } 204 205 friend SkVector4 operator*(const SkMatrix44& m, const SkVector4& src) { 206 SkVector4 dst; 207 m.map(src.fData, dst.fData); 208 return dst; 209 } 210 211 void dump() const; 212 213 private: 214 /* Stored in the same order as opengl: 215 [3][0] = tx 216 [3][1] = ty 217 [3][2] = tz 218 */ 219 SkMScalar fMat[4][4]; 220 221 double determinant() const; 222 }; 223 224 #endif 225