Home | History | Annotate | Download | only in hwui
      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 
     26 namespace android {
     27 namespace 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 
     39 class ANDROID_API Matrix4 {
     40 public:
     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 
    205 private:
    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 
    224 typedef Matrix4 mat4;
    225 
    226 }; // namespace uirenderer
    227 }; // namespace android
    228 
    229 #endif // ANDROID_HWUI_MATRIX_H
    230