Matrix.h revision 996fe656340ede058a6f0e6b18f9ec525ddb4e27
1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
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
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 */
16
17#ifndef ANDROID_HWUI_MATRIX_H
18#define ANDROID_HWUI_MATRIX_H
19
20#include <SkMatrix.h>
21
22#include <cutils/compiler.h>
23
24#include "Rect.h"
25
26namespace android {
27namespace uirenderer {
28
29#define MATRIX_STRING "[%.2f %.2f %.2f] [%.2f %.2f %.2f] [%.2f %.2f %.2f]"
30#define 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)
34
35///////////////////////////////////////////////////////////////////////////////
36// Classes
37///////////////////////////////////////////////////////////////////////////////
38
39class ANDROID_API Matrix4 {
40public:
41    float data[16];
42
43    enum Entry {
44        kScaleX = 0,
45        kSkewY = 1,
46        kPerspective0 = 3,
47        kSkewX = 4,
48        kScaleY = 5,
49        kPerspective1 = 7,
50        kScaleZ = 10,
51        kTranslateX = 12,
52        kTranslateY = 13,
53        kTranslateZ = 14,
54        kPerspective2 = 15
55    };
56
57    // NOTE: The flags from kTypeIdentity to kTypePerspective
58    //       must be kept in sync with the type flags found
59    //       in SkMatrix
60    enum Type {
61        kTypeIdentity = 0,
62        kTypeTranslate = 0x1,
63        kTypeScale = 0x2,
64        kTypeAffine = 0x4,
65        kTypePerspective = 0x8,
66        kTypeRectToRect = 0x10,
67        kTypeUnknown = 0x20,
68    };
69
70    static const int sGeometryMask = 0xf;
71
72    Matrix4() {
73        loadIdentity();
74    }
75
76    Matrix4(const float* v) {
77        load(v);
78    }
79
80    Matrix4(const Matrix4& v) {
81        load(v);
82    }
83
84    Matrix4(const SkMatrix& v) {
85        load(v);
86    }
87
88    float operator[](int index) const {
89        return data[index];
90    }
91
92    float& operator[](int index) {
93        mType = kTypeUnknown;
94        return data[index];
95    }
96
97    Matrix4& operator=(const SkMatrix& v) {
98        load(v);
99        return *this;
100    }
101
102    friend bool operator==(const Matrix4& a, const Matrix4& b) {
103        return !memcmp(&a.data[0], &b.data[0], 16 * sizeof(float));
104    }
105
106    friend bool operator!=(const Matrix4& a, const Matrix4& b) {
107        return !(a == b);
108    }
109
110    void loadIdentity();
111
112    void load(const float* v);
113    void load(const Matrix4& v);
114    void load(const SkMatrix& v);
115
116    void loadInverse(const Matrix4& v);
117
118    void loadTranslate(float x, float y, float z);
119    void loadScale(float sx, float sy, float sz);
120    void loadSkew(float sx, float sy);
121    void loadRotate(float angle);
122    void loadRotate(float angle, float x, float y, float z);
123    void loadMultiply(const Matrix4& u, const Matrix4& v);
124
125    void loadOrtho(float left, float right, float bottom, float top, float near, float far);
126
127    uint8_t getType() const;
128
129    void multiply(const Matrix4& v) {
130        Matrix4 u;
131        u.loadMultiply(*this, v);
132        load(u);
133    }
134
135    void multiply(float v);
136
137    void translate(float x, float y) {
138        if ((getType() & sGeometryMask) <= kTypeTranslate) {
139            data[kTranslateX] += x;
140            data[kTranslateY] += y;
141        } else {
142            // Doing a translation will only affect the translate bit of the type
143            // Save the type
144            uint8_t type = mType;
145
146            Matrix4 u;
147            u.loadTranslate(x, y, 0.0f);
148            multiply(u);
149
150            // Restore the type and fix the translate bit
151            mType = type;
152            if (data[kTranslateX] != 0.0f || data[kTranslateY] != 0.0f) {
153                mType |= kTypeTranslate;
154            } else {
155                mType &= ~kTypeTranslate;
156            }
157        }
158    }
159
160    void scale(float sx, float sy, float sz) {
161        Matrix4 u;
162        u.loadScale(sx, sy, sz);
163        multiply(u);
164    }
165
166    void skew(float sx, float sy) {
167        Matrix4 u;
168        u.loadSkew(sx, sy);
169        multiply(u);
170    }
171
172    void rotate(float angle, float x, float y, float z) {
173        Matrix4 u;
174        u.loadRotate(angle, x, y, z);
175        multiply(u);
176    }
177
178    /**
179     * If the matrix is identity or translate and/or scale.
180     */
181    bool isSimple() const;
182    bool isPureTranslate() const;
183    bool isIdentity() const;
184    bool isPerspective() const;
185    bool rectToRect() const;
186    bool positiveScale() const;
187
188    bool changesBounds() const;
189
190    void copyTo(float* v) const;
191    void copyTo(SkMatrix& v) const;
192
193    void mapRect(Rect& r) const;
194    void mapPoint(float& x, float& y) const;
195
196    float getTranslateX() const;
197    float getTranslateY() const;
198
199    void decomposeScale(float& sx, float& sy) const;
200
201    void dump() const;
202
203    static const Matrix4& identity();
204
205private:
206    mutable uint8_t mType;
207
208    inline float get(int i, int j) const {
209        return data[i * 4 + j];
210    }
211
212    inline void set(int i, int j, float v) {
213        data[i * 4 + j] = v;
214    }
215
216    uint8_t getGeometryType() const;
217
218}; // class Matrix4
219
220///////////////////////////////////////////////////////////////////////////////
221// Types
222///////////////////////////////////////////////////////////////////////////////
223
224typedef Matrix4 mat4;
225
226}; // namespace uirenderer
227}; // namespace android
228
229#endif // ANDROID_HWUI_MATRIX_H
230