Matrix.h revision b79a3e301a8d89b9e1b1f6f3d7fd6aa56610a6f0
1227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks/* 2227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Copyright (C) 2010 The Android Open Source Project 3227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 4227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Licensed under the Apache License, Version 2.0 (the "License"); 5227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * you may not use this file except in compliance with the License. 6227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * You may obtain a copy of the License at 7227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 8227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * http://www.apache.org/licenses/LICENSE-2.0 9227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 10227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Unless required by applicable law or agreed to in writing, software 11227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * distributed under the License is distributed on an "AS IS" BASIS, 12227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * See the License for the specific language governing permissions and 14227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * limitations under the License. 15227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 16227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 17227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks#ifndef ANDROID_HWUI_MATRIX_H 18227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks#define ANDROID_HWUI_MATRIX_H 19227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 20227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks#include <SkMatrix.h> 21227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 22227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks#include <cutils/compiler.h> 23227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 24227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks#include "Rect.h" 25227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 26227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksnamespace android { 27227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksnamespace uirenderer { 28227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 29227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks#define SK_MATRIX_STRING "[%.2f %.2f %.2f] [%.2f %.2f %.2f] [%.2f %.2f %.2f]" 30227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks#define SK_MATRIX_ARGS(m) \ 31227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks (m)->get(0), (m)->get(1), (m)->get(2), \ 32 (m)->get(3), (m)->get(4), (m)->get(5), \ 33 (m)->get(6), (m)->get(7), (m)->get(8) 34 35#define MATRIX_4_STRING "[%.2f %.2f %.2f %.2f] [%.2f %.2f %.2f %.2f]" \ 36 " [%.2f %.2f %.2f %.2f] [%.2f %.2f %.2f %.2f]" 37#define MATRIX_4_ARGS(m) \ 38 (m)->data[0], (m)->data[4], (m)->data[8], (m)->data[12], \ 39 (m)->data[1], (m)->data[5], (m)->data[9], (m)->data[13], \ 40 (m)->data[2], (m)->data[6], (m)->data[10], (m)->data[14], \ 41 (m)->data[3], (m)->data[7], (m)->data[11], (m)->data[15] \ 42 43/////////////////////////////////////////////////////////////////////////////// 44// Classes 45/////////////////////////////////////////////////////////////////////////////// 46 47class ANDROID_API Matrix4 { 48public: 49 float data[16]; 50 51 enum Entry { 52 kScaleX = 0, 53 kSkewY = 1, 54 kPerspective0 = 3, 55 kSkewX = 4, 56 kScaleY = 5, 57 kPerspective1 = 7, 58 kScaleZ = 10, 59 kTranslateX = 12, 60 kTranslateY = 13, 61 kTranslateZ = 14, 62 kPerspective2 = 15 63 }; 64 65 // NOTE: The flags from kTypeIdentity to kTypePerspective 66 // must be kept in sync with the type flags found 67 // in SkMatrix 68 enum Type { 69 kTypeIdentity = 0, 70 kTypeTranslate = 0x1, 71 kTypeScale = 0x2, 72 kTypeAffine = 0x4, 73 kTypePerspective = 0x8, 74 kTypeRectToRect = 0x10, 75 kTypeUnknown = 0x20, 76 }; 77 78 static const int sGeometryMask = 0xf; 79 80 Matrix4() { 81 loadIdentity(); 82 } 83 84 Matrix4(const float* v) { 85 load(v); 86 } 87 88 Matrix4(const Matrix4& v) { 89 load(v); 90 } 91 92 Matrix4(const SkMatrix& v) { 93 load(v); 94 } 95 96 float operator[](int index) const { 97 return data[index]; 98 } 99 100 float& operator[](int index) { 101 mType = kTypeUnknown; 102 return data[index]; 103 } 104 105 Matrix4& operator=(const SkMatrix& v) { 106 load(v); 107 return *this; 108 } 109 110 friend bool operator==(const Matrix4& a, const Matrix4& b) { 111 return !memcmp(&a.data[0], &b.data[0], 16 * sizeof(float)); 112 } 113 114 friend bool operator!=(const Matrix4& a, const Matrix4& b) { 115 return !(a == b); 116 } 117 118 void loadIdentity(); 119 120 void load(const float* v); 121 void load(const Matrix4& v); 122 void load(const SkMatrix& v); 123 124 void loadInverse(const Matrix4& v); 125 126 void loadTranslate(float x, float y, float z); 127 void loadScale(float sx, float sy, float sz); 128 void loadSkew(float sx, float sy); 129 void loadRotate(float angle); 130 void loadRotate(float angle, float x, float y, float z); 131 void loadMultiply(const Matrix4& u, const Matrix4& v); 132 133 void loadOrtho(float left, float right, float bottom, float top, float near, float far); 134 135 uint8_t getType() const; 136 137 void multiply(const Matrix4& v) { 138 Matrix4 u; 139 u.loadMultiply(*this, v); 140 load(u); 141 } 142 143 void multiply(float v); 144 145 void translate(float x, float y, float z = 0) { 146 if ((getType() & sGeometryMask) <= kTypeTranslate) { 147 data[kTranslateX] += x; 148 data[kTranslateY] += y; 149 data[kTranslateZ] += z; 150 } else { 151 // Doing a translation will only affect the translate bit of the type 152 // Save the type 153 uint8_t type = mType; 154 155 Matrix4 u; 156 u.loadTranslate(x, y, z); 157 multiply(u); 158 159 // Restore the type and fix the translate bit 160 mType = type; 161 if (data[kTranslateX] != 0.0f || data[kTranslateY] != 0.0f) { 162 mType |= kTypeTranslate; 163 } else { 164 mType &= ~kTypeTranslate; 165 } 166 } 167 } 168 169 void scale(float sx, float sy, float sz) { 170 Matrix4 u; 171 u.loadScale(sx, sy, sz); 172 multiply(u); 173 } 174 175 void skew(float sx, float sy) { 176 Matrix4 u; 177 u.loadSkew(sx, sy); 178 multiply(u); 179 } 180 181 void rotate(float angle, float x, float y, float z) { 182 Matrix4 u; 183 u.loadRotate(angle, x, y, z); 184 multiply(u); 185 } 186 187 /** 188 * If the matrix is identity or translate and/or scale. 189 */ 190 bool isSimple() const; 191 bool isPureTranslate() const; 192 bool isIdentity() const; 193 bool isPerspective() const; 194 bool rectToRect() const; 195 bool positiveScale() const; 196 197 bool changesBounds() const; 198 199 void copyTo(float* v) const; 200 void copyTo(SkMatrix& v) const; 201 202 float mapZ(const Vector3& orig) const; 203 void mapPoint3d(Vector3& vec) const; 204 void mapPoint(float& x, float& y) const; // 2d only 205 void mapRect(Rect& r) const; // 2d only 206 207 float getTranslateX() const; 208 float getTranslateY() const; 209 210 void decomposeScale(float& sx, float& sy) const; 211 212 void dump() const; 213 214 static const Matrix4& identity(); 215 216private: 217 mutable uint8_t mType; 218 219 inline float get(int i, int j) const { 220 return data[i * 4 + j]; 221 } 222 223 inline void set(int i, int j, float v) { 224 data[i * 4 + j] = v; 225 } 226 227 uint8_t getGeometryType() const; 228 229}; // class Matrix4 230 231/////////////////////////////////////////////////////////////////////////////// 232// Types 233/////////////////////////////////////////////////////////////////////////////// 234 235typedef Matrix4 mat4; 236 237}; // namespace uirenderer 238}; // namespace android 239 240#endif // ANDROID_HWUI_MATRIX_H 241