2 * Copyright (C) 2010 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
21 #include <cutils/compiler.h>
27 namespace uirenderer {
29 #define SK_MATRIX_STRING "[%.2f %.2f %.2f] [%.2f %.2f %.2f] [%.2f %.2f %.2f]"
30 #define SK_MATRIX_ARGS(m) \
31 (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)
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] \
43 ///////////////////////////////////////////////////////////////////////////////
45 ///////////////////////////////////////////////////////////////////////////////
47 class ANDROID_API Matrix4 {
65 // NOTE: The flags from kTypeIdentity to kTypePerspective
66 // must be kept in sync with the type flags found
73 kTypePerspective = 0x8,
74 kTypeRectToRect = 0x10,
78 static const int sGeometryMask = 0xf;
84 explicit Matrix4(const float* v) {
88 Matrix4(const SkMatrix& v) { // NOLINT, implicit
92 float operator[](int index) const {
96 float& operator[](int index) {
101 Matrix4& operator=(const SkMatrix& v) {
106 friend bool operator==(const Matrix4& a, const Matrix4& b) {
107 return !memcmp(&a.data[0], &b.data[0], 16 * sizeof(float));
110 friend bool operator!=(const Matrix4& a, const Matrix4& b) {
116 void load(const float* v);
117 void load(const SkMatrix& v);
119 void loadInverse(const Matrix4& v);
121 void loadTranslate(float x, float y, float z);
122 void loadScale(float sx, float sy, float sz);
123 void loadSkew(float sx, float sy);
124 void loadRotate(float angle);
125 void loadRotate(float angle, float x, float y, float z);
126 void loadMultiply(const Matrix4& u, const Matrix4& v);
128 void loadOrtho(float left, float right, float bottom, float top, float near, float far);
129 void loadOrtho(int width, int height) {
130 loadOrtho(0, width, height, 0, -1, 1);
133 uint8_t getType() const;
135 void multiplyInverse(const Matrix4& v) {
141 void multiply(const Matrix4& v) {
142 if (!v.isIdentity()) {
144 u.loadMultiply(*this, v);
149 void multiply(float v);
151 void translate(float x, float y, float z = 0) {
152 if ((getType() & sGeometryMask) <= kTypeTranslate) {
153 data[kTranslateX] += x;
154 data[kTranslateY] += y;
155 data[kTranslateZ] += z;
156 mType |= kTypeUnknown;
158 // Doing a translation will only affect the translate bit of the type
160 uint8_t type = mType;
163 u.loadTranslate(x, y, z);
166 // Restore the type and fix the translate bit
168 if (data[kTranslateX] != 0.0f || data[kTranslateY] != 0.0f) {
169 mType |= kTypeTranslate;
171 mType &= ~kTypeTranslate;
176 void scale(float sx, float sy, float sz) {
178 u.loadScale(sx, sy, sz);
182 void skew(float sx, float sy) {
188 void rotate(float angle, float x, float y, float z) {
190 u.loadRotate(angle, x, y, z);
195 * If the matrix is identity or translate and/or scale.
197 bool isSimple() const;
198 bool isPureTranslate() const;
199 bool isIdentity() const;
200 bool isPerspective() const;
201 bool rectToRect() const;
202 bool positiveScale() const;
204 bool changesBounds() const;
206 void copyTo(float* v) const;
207 void copyTo(SkMatrix& v) const;
209 float mapZ(const Vector3& orig) const;
210 void mapPoint3d(Vector3& vec) const;
211 void mapPoint(float& x, float& y) const; // 2d only
212 void mapRect(Rect& r) const; // 2d only
214 float getTranslateX() const;
215 float getTranslateY() const;
217 void decomposeScale(float& sx, float& sy) const;
219 void dump(const char* label = nullptr) const;
221 friend std::ostream& operator<<(std::ostream& os, const Matrix4& matrix) {
222 if (matrix.isSimple()) {
223 os << "offset " << matrix.getTranslateX() << "x" << matrix.getTranslateY();
224 if (!matrix.isPureTranslate()) {
225 os << ", scale " << matrix[kScaleX] << "x" << matrix[kScaleY];
228 os << "[" << matrix[0];
229 for (int i = 1; i < 16; i++) {
230 os << ", " << matrix[i];
237 static const Matrix4& identity();
239 void invalidateType() { mType = kTypeUnknown; }
242 mutable uint8_t mType;
244 inline float get(int i, int j) const {
245 return data[i * 4 + j];
248 inline void set(int i, int j, float v) {
252 uint8_t getGeometryType() const;
256 ///////////////////////////////////////////////////////////////////////////////
258 ///////////////////////////////////////////////////////////////////////////////
260 typedef Matrix4 mat4;
262 }; // namespace uirenderer
263 }; // namespace android