Matrix.h revision 996fe656340ede058a6f0e6b18f9ec525ddb4e27
108ae317c21ec3086b5017672bba87420cc38a407Romain Guy/* 208ae317c21ec3086b5017672bba87420cc38a407Romain Guy * Copyright (C) 2010 The Android Open Source Project 308ae317c21ec3086b5017672bba87420cc38a407Romain Guy * 408ae317c21ec3086b5017672bba87420cc38a407Romain Guy * Licensed under the Apache License, Version 2.0 (the "License"); 508ae317c21ec3086b5017672bba87420cc38a407Romain Guy * you may not use this file except in compliance with the License. 608ae317c21ec3086b5017672bba87420cc38a407Romain Guy * You may obtain a copy of the License at 708ae317c21ec3086b5017672bba87420cc38a407Romain Guy * 808ae317c21ec3086b5017672bba87420cc38a407Romain Guy * http://www.apache.org/licenses/LICENSE-2.0 908ae317c21ec3086b5017672bba87420cc38a407Romain Guy * 1008ae317c21ec3086b5017672bba87420cc38a407Romain Guy * Unless required by applicable law or agreed to in writing, software 1108ae317c21ec3086b5017672bba87420cc38a407Romain Guy * distributed under the License is distributed on an "AS IS" BASIS, 1208ae317c21ec3086b5017672bba87420cc38a407Romain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1308ae317c21ec3086b5017672bba87420cc38a407Romain Guy * See the License for the specific language governing permissions and 1408ae317c21ec3086b5017672bba87420cc38a407Romain Guy * limitations under the License. 1508ae317c21ec3086b5017672bba87420cc38a407Romain Guy */ 1608ae317c21ec3086b5017672bba87420cc38a407Romain Guy 175b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy#ifndef ANDROID_HWUI_MATRIX_H 185b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy#define ANDROID_HWUI_MATRIX_H 1908ae317c21ec3086b5017672bba87420cc38a407Romain Guy 20f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy#include <SkMatrix.h> 21f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 2271e36aa7db69449e210d0791284cb810a7471c07Romain Guy#include <cutils/compiler.h> 2371e36aa7db69449e210d0791284cb810a7471c07Romain Guy 249d5316e3f56d138504565ff311145ac01621dff4Romain Guy#include "Rect.h" 259d5316e3f56d138504565ff311145ac01621dff4Romain Guy 2608ae317c21ec3086b5017672bba87420cc38a407Romain Guynamespace android { 279d5316e3f56d138504565ff311145ac01621dff4Romain Guynamespace uirenderer { 2808ae317c21ec3086b5017672bba87420cc38a407Romain Guy 2928ce94a4ffc7576f40776d212f1ada79fafaa061Chris Craik#define MATRIX_STRING "[%.2f %.2f %.2f] [%.2f %.2f %.2f] [%.2f %.2f %.2f]" 3028ce94a4ffc7576f40776d212f1ada79fafaa061Chris Craik#define MATRIX_ARGS(m) \ 3128ce94a4ffc7576f40776d212f1ada79fafaa061Chris Craik (m)->get(0), (m)->get(1), (m)->get(2), \ 3228ce94a4ffc7576f40776d212f1ada79fafaa061Chris Craik (m)->get(3), (m)->get(4), (m)->get(5), \ 3328ce94a4ffc7576f40776d212f1ada79fafaa061Chris Craik (m)->get(6), (m)->get(7), (m)->get(8) 3428ce94a4ffc7576f40776d212f1ada79fafaa061Chris Craik 3508ae317c21ec3086b5017672bba87420cc38a407Romain Guy/////////////////////////////////////////////////////////////////////////////// 3608ae317c21ec3086b5017672bba87420cc38a407Romain Guy// Classes 3708ae317c21ec3086b5017672bba87420cc38a407Romain Guy/////////////////////////////////////////////////////////////////////////////// 3808ae317c21ec3086b5017672bba87420cc38a407Romain Guy 3971e36aa7db69449e210d0791284cb810a7471c07Romain Guyclass ANDROID_API Matrix4 { 4008ae317c21ec3086b5017672bba87420cc38a407Romain Guypublic: 417ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy float data[16]; 42c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy 43af28b514964861d81b48902f942f706050936d38Romain Guy enum Entry { 44af28b514964861d81b48902f942f706050936d38Romain Guy kScaleX = 0, 45af28b514964861d81b48902f942f706050936d38Romain Guy kSkewY = 1, 46af28b514964861d81b48902f942f706050936d38Romain Guy kPerspective0 = 3, 47af28b514964861d81b48902f942f706050936d38Romain Guy kSkewX = 4, 48af28b514964861d81b48902f942f706050936d38Romain Guy kScaleY = 5, 49af28b514964861d81b48902f942f706050936d38Romain Guy kPerspective1 = 7, 50af28b514964861d81b48902f942f706050936d38Romain Guy kScaleZ = 10, 51af28b514964861d81b48902f942f706050936d38Romain Guy kTranslateX = 12, 52af28b514964861d81b48902f942f706050936d38Romain Guy kTranslateY = 13, 53af28b514964861d81b48902f942f706050936d38Romain Guy kTranslateZ = 14, 54af28b514964861d81b48902f942f706050936d38Romain Guy kPerspective2 = 15 55af28b514964861d81b48902f942f706050936d38Romain Guy }; 56af28b514964861d81b48902f942f706050936d38Romain Guy 578ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy // NOTE: The flags from kTypeIdentity to kTypePerspective 588ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy // must be kept in sync with the type flags found 598ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy // in SkMatrix 608ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy enum Type { 618ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy kTypeIdentity = 0, 628ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy kTypeTranslate = 0x1, 638ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy kTypeScale = 0x2, 648ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy kTypeAffine = 0x4, 658ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy kTypePerspective = 0x8, 668ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy kTypeRectToRect = 0x10, 67996fe656340ede058a6f0e6b18f9ec525ddb4e27Chris Craik kTypeUnknown = 0x20, 688ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy }; 698ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy 708ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy static const int sGeometryMask = 0xf; 718ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy 727ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy Matrix4() { 737ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy loadIdentity(); 747ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy } 7508ae317c21ec3086b5017672bba87420cc38a407Romain Guy 767ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy Matrix4(const float* v) { 777ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy load(v); 787ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy } 7908ae317c21ec3086b5017672bba87420cc38a407Romain Guy 807ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy Matrix4(const Matrix4& v) { 817ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy load(v); 827ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy } 8308ae317c21ec3086b5017672bba87420cc38a407Romain Guy 847ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy Matrix4(const SkMatrix& v) { 857ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy load(v); 867ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy } 87f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 883b753829ae858d424fe109f714745379a6daf455Romain Guy float operator[](int index) const { 893b753829ae858d424fe109f714745379a6daf455Romain Guy return data[index]; 903b753829ae858d424fe109f714745379a6daf455Romain Guy } 913b753829ae858d424fe109f714745379a6daf455Romain Guy 923b753829ae858d424fe109f714745379a6daf455Romain Guy float& operator[](int index) { 933b753829ae858d424fe109f714745379a6daf455Romain Guy mType = kTypeUnknown; 943b753829ae858d424fe109f714745379a6daf455Romain Guy return data[index]; 953b753829ae858d424fe109f714745379a6daf455Romain Guy } 963b753829ae858d424fe109f714745379a6daf455Romain Guy 973b753829ae858d424fe109f714745379a6daf455Romain Guy Matrix4& operator=(const SkMatrix& v) { 983b753829ae858d424fe109f714745379a6daf455Romain Guy load(v); 993b753829ae858d424fe109f714745379a6daf455Romain Guy return *this; 1003b753829ae858d424fe109f714745379a6daf455Romain Guy } 1013b753829ae858d424fe109f714745379a6daf455Romain Guy 102bd3055f95e67a55648fd84a125e939293115171bRomain Guy friend bool operator==(const Matrix4& a, const Matrix4& b) { 103bd3055f95e67a55648fd84a125e939293115171bRomain Guy return !memcmp(&a.data[0], &b.data[0], 16 * sizeof(float)); 104bd3055f95e67a55648fd84a125e939293115171bRomain Guy } 105bd3055f95e67a55648fd84a125e939293115171bRomain Guy 106bd3055f95e67a55648fd84a125e939293115171bRomain Guy friend bool operator!=(const Matrix4& a, const Matrix4& b) { 107bd3055f95e67a55648fd84a125e939293115171bRomain Guy return !(a == b); 108bd3055f95e67a55648fd84a125e939293115171bRomain Guy } 109bd3055f95e67a55648fd84a125e939293115171bRomain Guy 1107ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy void loadIdentity(); 11108ae317c21ec3086b5017672bba87420cc38a407Romain Guy 1127ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy void load(const float* v); 1137ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy void load(const Matrix4& v); 1147ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy void load(const SkMatrix& v); 11508ae317c21ec3086b5017672bba87420cc38a407Romain Guy 116079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy void loadInverse(const Matrix4& v); 117079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy 1187ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy void loadTranslate(float x, float y, float z); 1197ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy void loadScale(float sx, float sy, float sz); 120807daf7df615b60ce6fc41355aabe3aa353cebabRomain Guy void loadSkew(float sx, float sy); 1218ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy void loadRotate(float angle); 1227ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy void loadRotate(float angle, float x, float y, float z); 1237ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy void loadMultiply(const Matrix4& u, const Matrix4& v); 12408ae317c21ec3086b5017672bba87420cc38a407Romain Guy 1257ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy void loadOrtho(float left, float right, float bottom, float top, float near, float far); 12608ae317c21ec3086b5017672bba87420cc38a407Romain Guy 127f6bed4f12a2c975678fc0bdea15054ab169aafb5Romain Guy uint8_t getType() const; 1288ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy 1297ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy void multiply(const Matrix4& v) { 1307ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy Matrix4 u; 1317ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy u.loadMultiply(*this, v); 1327ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy load(u); 1337ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy } 13408ae317c21ec3086b5017672bba87420cc38a407Romain Guy 135ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy void multiply(float v); 136ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy 1374c2547fa9244e78115cde0a259291053108c3dc7Romain Guy void translate(float x, float y) { 138f6bed4f12a2c975678fc0bdea15054ab169aafb5Romain Guy if ((getType() & sGeometryMask) <= kTypeTranslate) { 1394c2547fa9244e78115cde0a259291053108c3dc7Romain Guy data[kTranslateX] += x; 1404c2547fa9244e78115cde0a259291053108c3dc7Romain Guy data[kTranslateY] += y; 1414c2547fa9244e78115cde0a259291053108c3dc7Romain Guy } else { 1424c2547fa9244e78115cde0a259291053108c3dc7Romain Guy // Doing a translation will only affect the translate bit of the type 1434c2547fa9244e78115cde0a259291053108c3dc7Romain Guy // Save the type 144f6bed4f12a2c975678fc0bdea15054ab169aafb5Romain Guy uint8_t type = mType; 1454c2547fa9244e78115cde0a259291053108c3dc7Romain Guy 1464c2547fa9244e78115cde0a259291053108c3dc7Romain Guy Matrix4 u; 1474c2547fa9244e78115cde0a259291053108c3dc7Romain Guy u.loadTranslate(x, y, 0.0f); 1484c2547fa9244e78115cde0a259291053108c3dc7Romain Guy multiply(u); 1494c2547fa9244e78115cde0a259291053108c3dc7Romain Guy 1504c2547fa9244e78115cde0a259291053108c3dc7Romain Guy // Restore the type and fix the translate bit 1514c2547fa9244e78115cde0a259291053108c3dc7Romain Guy mType = type; 1524c2547fa9244e78115cde0a259291053108c3dc7Romain Guy if (data[kTranslateX] != 0.0f || data[kTranslateY] != 0.0f) { 1534c2547fa9244e78115cde0a259291053108c3dc7Romain Guy mType |= kTypeTranslate; 1544c2547fa9244e78115cde0a259291053108c3dc7Romain Guy } else { 1554c2547fa9244e78115cde0a259291053108c3dc7Romain Guy mType &= ~kTypeTranslate; 1564c2547fa9244e78115cde0a259291053108c3dc7Romain Guy } 1574c2547fa9244e78115cde0a259291053108c3dc7Romain Guy } 1587ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy } 15908ae317c21ec3086b5017672bba87420cc38a407Romain Guy 1607ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy void scale(float sx, float sy, float sz) { 1617ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy Matrix4 u; 1627ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy u.loadScale(sx, sy, sz); 1637ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy multiply(u); 1647ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy } 16508ae317c21ec3086b5017672bba87420cc38a407Romain Guy 166807daf7df615b60ce6fc41355aabe3aa353cebabRomain Guy void skew(float sx, float sy) { 167807daf7df615b60ce6fc41355aabe3aa353cebabRomain Guy Matrix4 u; 168807daf7df615b60ce6fc41355aabe3aa353cebabRomain Guy u.loadSkew(sx, sy); 169807daf7df615b60ce6fc41355aabe3aa353cebabRomain Guy multiply(u); 170807daf7df615b60ce6fc41355aabe3aa353cebabRomain Guy } 171807daf7df615b60ce6fc41355aabe3aa353cebabRomain Guy 1727ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy void rotate(float angle, float x, float y, float z) { 1737ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy Matrix4 u; 1747ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy u.loadRotate(angle, x, y, z); 1757ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy multiply(u); 1767ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy } 17708ae317c21ec3086b5017672bba87420cc38a407Romain Guy 1788ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy /** 1798ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy * If the matrix is identity or translate and/or scale. 1808ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy */ 181710f46d9d6a5bf9ea1c1833384caf61e1934124fChris Craik bool isSimple() const; 1828ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy bool isPureTranslate() const; 183710f46d9d6a5bf9ea1c1833384caf61e1934124fChris Craik bool isIdentity() const; 184a3dc55f83ab583e0a66b893c71b849afa046770aRomain Guy bool isPerspective() const; 1858ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy bool rectToRect() const; 186d965bc5823d878a3fd056b8a95fb4eb578ed3fe4Chris Craik bool positiveScale() const; 1876620c6d413f972819fada92b574f0fa9e96d36c1Romain Guy 188710f46d9d6a5bf9ea1c1833384caf61e1934124fChris Craik bool changesBounds() const; 189e8cb9c14309b0f01c0159efdf9a7198f44a62642Romain Guy 1907ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy void copyTo(float* v) const; 1917ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy void copyTo(SkMatrix& v) const; 19208ae317c21ec3086b5017672bba87420cc38a407Romain Guy 1937ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy void mapRect(Rect& r) const; 1940ba681bce12d522c5575dfccb5a6ca12f0fba746Romain Guy void mapPoint(float& x, float& y) const; 1959d5316e3f56d138504565ff311145ac01621dff4Romain Guy 196624234f69b2a4781d24f3e4c6ae6450729e38397Romain Guy float getTranslateX() const; 197624234f69b2a4781d24f3e4c6ae6450729e38397Romain Guy float getTranslateY() const; 198bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy 1993b753829ae858d424fe109f714745379a6daf455Romain Guy void decomposeScale(float& sx, float& sy) const; 2003b753829ae858d424fe109f714745379a6daf455Romain Guy 2017ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy void dump() const; 20208ae317c21ec3086b5017672bba87420cc38a407Romain Guy 203c74f45a334f0e3725c23cdd270cbcb0efac4ea75Romain Guy static const Matrix4& identity(); 204c74f45a334f0e3725c23cdd270cbcb0efac4ea75Romain Guy 205f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guyprivate: 206f6bed4f12a2c975678fc0bdea15054ab169aafb5Romain Guy mutable uint8_t mType; 207af28b514964861d81b48902f942f706050936d38Romain Guy 20808ae317c21ec3086b5017672bba87420cc38a407Romain Guy inline float get(int i, int j) const { 209c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy return data[i * 4 + j]; 21008ae317c21ec3086b5017672bba87420cc38a407Romain Guy } 21108ae317c21ec3086b5017672bba87420cc38a407Romain Guy 21208ae317c21ec3086b5017672bba87420cc38a407Romain Guy inline void set(int i, int j, float v) { 2137ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy data[i * 4 + j] = v; 21408ae317c21ec3086b5017672bba87420cc38a407Romain Guy } 2158ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy 216f6bed4f12a2c975678fc0bdea15054ab169aafb5Romain Guy uint8_t getGeometryType() const; 2178ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy 21808ae317c21ec3086b5017672bba87420cc38a407Romain Guy}; // class Matrix4 21908ae317c21ec3086b5017672bba87420cc38a407Romain Guy 22008ae317c21ec3086b5017672bba87420cc38a407Romain Guy/////////////////////////////////////////////////////////////////////////////// 22108ae317c21ec3086b5017672bba87420cc38a407Romain Guy// Types 22208ae317c21ec3086b5017672bba87420cc38a407Romain Guy/////////////////////////////////////////////////////////////////////////////// 22308ae317c21ec3086b5017672bba87420cc38a407Romain Guy 22408ae317c21ec3086b5017672bba87420cc38a407Romain Guytypedef Matrix4 mat4; 22508ae317c21ec3086b5017672bba87420cc38a407Romain Guy 2269d5316e3f56d138504565ff311145ac01621dff4Romain Guy}; // namespace uirenderer 22708ae317c21ec3086b5017672bba87420cc38a407Romain Guy}; // namespace android 22808ae317c21ec3086b5017672bba87420cc38a407Romain Guy 2295b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy#endif // ANDROID_HWUI_MATRIX_H 230