• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 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 #include <ui/Region.h>
18 
19 #include <private/pixelflinger/ggl_fixed.h>
20 
21 #include "Transform.h"
22 
23 // ---------------------------------------------------------------------------
24 
25 #define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
26 #define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
27 
28 // ---------------------------------------------------------------------------
29 
30 namespace android {
31 
32 // ---------------------------------------------------------------------------
33 
Transform()34 Transform::Transform()
35     : mType(0)
36 {
37     mTransform.reset();
38 }
39 
Transform(const Transform & other)40 Transform::Transform(const Transform&  other)
41     : mTransform(other.mTransform), mType(other.mType)
42 {
43 }
44 
~Transform()45 Transform::~Transform() {
46 }
47 
operator *(const Transform & rhs) const48 Transform Transform::operator * (const Transform& rhs) const
49 {
50     if (LIKELY(mType == 0))
51         return rhs;
52 
53     Transform r(*this);
54     r.mTransform.preConcat(rhs.mTransform);
55     r.mType |= rhs.mType;
56     return r;
57 }
58 
operator [](int i) const59 float Transform::operator [] (int i) const
60 {
61     float r = 0;
62     switch(i) {
63         case 0: r = SkScalarToFloat( mTransform[SkMatrix::kMScaleX] );  break;
64         case 1: r = SkScalarToFloat( mTransform[SkMatrix::kMSkewX] );   break;
65         case 2: r = SkScalarToFloat( mTransform[SkMatrix::kMSkewY] );   break;
66         case 3: r = SkScalarToFloat( mTransform[SkMatrix::kMScaleY] );  break;
67     }
68     return r;
69 }
70 
type() const71 uint8_t Transform::type() const
72 {
73     if (UNLIKELY(mType & 0x80000000)) {
74         mType = mTransform.getType();
75     }
76     return uint8_t(mType & 0xFF);
77 }
78 
transformed() const79 bool Transform::transformed() const {
80     return type() > SkMatrix::kTranslate_Mask;
81 }
82 
tx() const83 int Transform::tx() const {
84     return SkScalarRound( mTransform[SkMatrix::kMTransX] );
85 }
86 
ty() const87 int Transform::ty() const {
88     return SkScalarRound( mTransform[SkMatrix::kMTransY] );
89 }
90 
reset()91 void Transform::reset() {
92     mTransform.reset();
93     mType = 0;
94 }
95 
set(float xx,float xy,float yx,float yy)96 void Transform::set( float xx, float xy,
97                      float yx, float yy)
98 {
99     mTransform.set(SkMatrix::kMScaleX, SkFloatToScalar(xx));
100     mTransform.set(SkMatrix::kMSkewX, SkFloatToScalar(xy));
101     mTransform.set(SkMatrix::kMSkewY, SkFloatToScalar(yx));
102     mTransform.set(SkMatrix::kMScaleY, SkFloatToScalar(yy));
103     mType |= 0x80000000;
104 }
105 
set(float radian,float x,float y)106 void Transform::set(float radian, float x, float y)
107 {
108     float r00 = cosf(radian);    float r01 = -sinf(radian);
109     float r10 = sinf(radian);    float r11 =  cosf(radian);
110     mTransform.set(SkMatrix::kMScaleX, SkFloatToScalar(r00));
111     mTransform.set(SkMatrix::kMSkewX, SkFloatToScalar(r01));
112     mTransform.set(SkMatrix::kMSkewY, SkFloatToScalar(r10));
113     mTransform.set(SkMatrix::kMScaleY, SkFloatToScalar(r11));
114     mTransform.set(SkMatrix::kMTransX, SkIntToScalar(x - r00*x - r01*y));
115     mTransform.set(SkMatrix::kMTransY, SkIntToScalar(y - r10*x - r11*y));
116     mType |= 0x80000000 | SkMatrix::kTranslate_Mask;
117 }
118 
scale(float s,float x,float y)119 void Transform::scale(float s, float x, float y)
120 {
121     mTransform.postScale(s, s, x, y);
122     mType |= 0x80000000;
123 }
124 
set(int tx,int ty)125 void Transform::set(int tx, int ty)
126 {
127     if (tx | ty) {
128         mTransform.set(SkMatrix::kMTransX, SkIntToScalar(tx));
129         mTransform.set(SkMatrix::kMTransY, SkIntToScalar(ty));
130         mType |= SkMatrix::kTranslate_Mask;
131     } else {
132         mTransform.set(SkMatrix::kMTransX, 0);
133         mTransform.set(SkMatrix::kMTransY, 0);
134         mType &= ~SkMatrix::kTranslate_Mask;
135     }
136 }
137 
transform(GLfixed * point,int x,int y) const138 void Transform::transform(GLfixed* point, int x, int y) const
139 {
140     SkPoint s;
141     mTransform.mapXY(SkIntToScalar(x), SkIntToScalar(y), &s);
142     point[0] = SkScalarToFixed(s.fX);
143     point[1] = SkScalarToFixed(s.fY);
144 }
145 
makeBounds(int w,int h) const146 Rect Transform::makeBounds(int w, int h) const
147 {
148     Rect r;
149     SkRect d, s;
150     s.set(0, 0, SkIntToScalar(w), SkIntToScalar(h));
151     mTransform.mapRect(&d, s);
152     r.left   = SkScalarRound( d.fLeft );
153     r.top    = SkScalarRound( d.fTop );
154     r.right  = SkScalarRound( d.fRight );
155     r.bottom = SkScalarRound( d.fBottom );
156     return r;
157 }
158 
transform(const Rect & bounds) const159 Rect Transform::transform(const Rect& bounds) const
160 {
161     Rect r;
162     SkRect d, s;
163     s.set(  SkIntToScalar( bounds.left ),
164             SkIntToScalar( bounds.top ),
165             SkIntToScalar( bounds.right ),
166             SkIntToScalar( bounds.bottom ));
167     mTransform.mapRect(&d, s);
168     r.left   = SkScalarRound( d.fLeft );
169     r.top    = SkScalarRound( d.fTop );
170     r.right  = SkScalarRound( d.fRight );
171     r.bottom = SkScalarRound( d.fBottom );
172     return r;
173 }
174 
transform(const Region & reg) const175 Region Transform::transform(const Region& reg) const
176 {
177     Region out;
178     if (UNLIKELY(transformed())) {
179         if (LIKELY(preserveRects())) {
180             Region::const_iterator it = reg.begin();
181             Region::const_iterator const end = reg.end();
182             while (it != end) {
183                 out.orSelf(transform(*it++));
184             }
185         } else {
186             out.set(transform(reg.bounds()));
187         }
188     } else {
189         out = reg.translate(tx(), ty());
190     }
191     return out;
192 }
193 
getOrientation() const194 int32_t Transform::getOrientation() const
195 {
196     uint32_t flags = 0;
197     if (UNLIKELY(transformed())) {
198         SkScalar a = mTransform[SkMatrix::kMScaleX];
199         SkScalar b = mTransform[SkMatrix::kMSkewX];
200         SkScalar c = mTransform[SkMatrix::kMSkewY];
201         SkScalar d = mTransform[SkMatrix::kMScaleY];
202         if (b==0 && c==0 && a && d) {
203             if (a<0)    flags |= FLIP_H;
204             if (d<0)    flags |= FLIP_V;
205         } else if (b && c && a==0 && d==0) {
206             flags |= ROT_90;
207             if (b>0)    flags |= FLIP_H;
208             if (c<0)    flags |= FLIP_V;
209         } else {
210             flags = 0x80000000;
211         }
212     }
213     return flags;
214 }
215 
preserveRects() const216 bool Transform::preserveRects() const
217 {
218     return mTransform.rectStaysRect();
219 }
220 
221 // ---------------------------------------------------------------------------
222 
223 }; // namespace android
224