1 /* libs/graphics/animator/SkDrawMatrix.cpp
2 **
3 ** Copyright 2006, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 ** http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17
18 #include "SkDrawMatrix.h"
19 #include "SkAnimateMaker.h"
20 #include "SkCanvas.h"
21 #include "SkPaint.h"
22 #include "SkParse.h"
23 #include "SkMatrixParts.h"
24 #include "SkScript.h"
25 #include "SkTypedArray.h"
26
27 enum SkDrawMatrix_Properties {
28 SK_PROPERTY(perspectX),
29 SK_PROPERTY(perspectY),
30 SK_PROPERTY(rotate),
31 SK_PROPERTY(scale),
32 SK_PROPERTY(scaleX),
33 SK_PROPERTY(scaleY),
34 SK_PROPERTY(skewX),
35 SK_PROPERTY(skewY),
36 SK_PROPERTY(translate),
37 SK_PROPERTY(translateX),
38 SK_PROPERTY(translateY)
39 };
40
41 #if SK_USE_CONDENSED_INFO == 0
42
43 const SkMemberInfo SkDrawMatrix::fInfo[] = {
44 SK_MEMBER_ARRAY(matrix, Float),
45 SK_MEMBER_PROPERTY(perspectX, Float),
46 SK_MEMBER_PROPERTY(perspectY, Float),
47 SK_MEMBER_PROPERTY(rotate, Float),
48 SK_MEMBER_PROPERTY(scale, Float),
49 SK_MEMBER_PROPERTY(scaleX, Float),
50 SK_MEMBER_PROPERTY(scaleY, Float),
51 SK_MEMBER_PROPERTY(skewX, Float),
52 SK_MEMBER_PROPERTY(skewY, Float),
53 SK_MEMBER_PROPERTY(translate, Point),
54 SK_MEMBER_PROPERTY(translateX, Float),
55 SK_MEMBER_PROPERTY(translateY, Float)
56 };
57
58 #endif
59
60 DEFINE_GET_MEMBER(SkDrawMatrix);
61
SkDrawMatrix()62 SkDrawMatrix::SkDrawMatrix() : fChildHasID(false), fDirty(false) {
63 fConcat.reset();
64 fMatrix.reset();
65 }
66
~SkDrawMatrix()67 SkDrawMatrix::~SkDrawMatrix() {
68 for (SkMatrixPart** part = fParts.begin(); part < fParts.end(); part++)
69 delete *part;
70 }
71
add(SkAnimateMaker & maker,SkDisplayable * child)72 bool SkDrawMatrix::add(SkAnimateMaker& maker, SkDisplayable* child) {
73 SkASSERT(child && child->isMatrixPart());
74 SkMatrixPart* part = (SkMatrixPart*) child;
75 *fParts.append() = part;
76 if (part->add())
77 maker.setErrorCode(SkDisplayXMLParserError::kErrorAddingToMatrix);
78 return true;
79 }
80
childrenNeedDisposing() const81 bool SkDrawMatrix::childrenNeedDisposing() const {
82 return false;
83 }
84
deepCopy(SkAnimateMaker * maker)85 SkDisplayable* SkDrawMatrix::deepCopy(SkAnimateMaker* maker) {
86 SkDrawMatrix* copy = (SkDrawMatrix*)
87 SkDisplayType::CreateInstance(maker, SkType_Matrix);
88 SkASSERT(fParts.count() == 0);
89 copy->fMatrix = fMatrix;
90 copy->fConcat = fConcat;
91 return copy;
92 }
93
dirty()94 void SkDrawMatrix::dirty() {
95 fDirty = true;
96 }
97
draw(SkAnimateMaker & maker)98 bool SkDrawMatrix::draw(SkAnimateMaker& maker) {
99 SkMatrix& concat = getMatrix();
100 maker.fCanvas->concat(concat);
101 return false;
102 }
103
104 #ifdef SK_DUMP_ENABLED
dump(SkAnimateMaker * maker)105 void SkDrawMatrix::dump(SkAnimateMaker* maker) {
106 dumpBase(maker);
107 if (fMatrix.isIdentity()) {
108 SkDebugf("matrix=\"identity\"/>\n");
109 return;
110 }
111 SkScalar result;
112 result = fMatrix[SkMatrix::kMScaleX];
113 if (result != SK_Scalar1)
114 SkDebugf("sx=\"%g\" ", SkScalarToFloat(result));
115 result = fMatrix.getScaleY();
116 if (result != SK_Scalar1)
117 SkDebugf("sy=\"%g\" ", SkScalarToFloat(result));
118 result = fMatrix.getSkewX();
119 if (result)
120 SkDebugf("skew-x=\"%g\" ", SkScalarToFloat(result));
121 result = fMatrix.getSkewY();
122 if (result)
123 SkDebugf("skew-y=\"%g\" ", SkScalarToFloat(result));
124 result = fMatrix.getTranslateX();
125 if (result)
126 SkDebugf("tx=\"%g\" ", SkScalarToFloat(result));
127 result = fMatrix.getTranslateY();
128 if (result)
129 SkDebugf("ty=\"%g\" ", SkScalarToFloat(result));
130 result = fMatrix.getPerspX();
131 if (result)
132 SkDebugf("perspect-x=\"%g\" ", SkScalarToFloat(result));
133 result = fMatrix.getPerspY();
134 if (result)
135 SkDebugf("perspect-y=\"%g\" ", SkScalarToFloat(result));
136 SkDebugf("/>\n");
137 }
138 #endif
139
getMatrix()140 SkMatrix& SkDrawMatrix::getMatrix() {
141 if (fDirty == false)
142 return fConcat;
143 fMatrix.reset();
144 for (SkMatrixPart** part = fParts.begin(); part < fParts.end(); part++) {
145 (*part)->add();
146 fConcat = fMatrix;
147 }
148 fDirty = false;
149 return fConcat;
150 }
151
getProperty(int index,SkScriptValue * value) const152 bool SkDrawMatrix::getProperty(int index, SkScriptValue* value) const {
153 value->fType = SkType_Float;
154 SkScalar result;
155 switch (index) {
156 case SK_PROPERTY(perspectX):
157 result = fMatrix.getPerspX();
158 break;
159 case SK_PROPERTY(perspectY):
160 result = fMatrix.getPerspY();
161 break;
162 case SK_PROPERTY(scaleX):
163 result = fMatrix.getScaleX();
164 break;
165 case SK_PROPERTY(scaleY):
166 result = fMatrix.getScaleY();
167 break;
168 case SK_PROPERTY(skewX):
169 result = fMatrix.getSkewX();
170 break;
171 case SK_PROPERTY(skewY):
172 result = fMatrix.getSkewY();
173 break;
174 case SK_PROPERTY(translateX):
175 result = fMatrix.getTranslateX();
176 break;
177 case SK_PROPERTY(translateY):
178 result = fMatrix.getTranslateY();
179 break;
180 default:
181 // SkASSERT(0);
182 return false;
183 }
184 value->fOperand.fScalar = result;
185 return true;
186 }
187
initialize()188 void SkDrawMatrix::initialize() {
189 fConcat = fMatrix;
190 }
191
onEndElement(SkAnimateMaker &)192 void SkDrawMatrix::onEndElement(SkAnimateMaker& ) {
193 if (matrix.count() > 0) {
194 SkScalar* vals = matrix.begin();
195 fMatrix.setScaleX(vals[0]);
196 fMatrix.setSkewX(vals[1]);
197 fMatrix.setTranslateX(vals[2]);
198 fMatrix.setSkewY(vals[3]);
199 fMatrix.setScaleY(vals[4]);
200 fMatrix.setTranslateY(vals[5]);
201 #ifdef SK_SCALAR_IS_FIXED
202 fMatrix.setPerspX(SkFixedToFract(vals[6]));
203 fMatrix.setPerspY(SkFixedToFract(vals[7]));
204 #else
205 fMatrix.setPerspX(vals[6]);
206 fMatrix.setPerspY(vals[7]);
207 #endif
208 // fMatrix.setPerspW(vals[8]);
209 goto setConcat;
210 }
211 if (fChildHasID == false) {
212 {
213 for (SkMatrixPart** part = fParts.begin(); part < fParts.end(); part++)
214 delete *part;
215 }
216 fParts.reset();
217 setConcat:
218 fConcat = fMatrix;
219 fDirty = false;
220 }
221 }
222
setChildHasID()223 void SkDrawMatrix::setChildHasID() {
224 fChildHasID = true;
225 }
226
setProperty(int index,SkScriptValue & scriptValue)227 bool SkDrawMatrix::setProperty(int index, SkScriptValue& scriptValue) {
228 SkScalar number = scriptValue.fOperand.fScalar;
229 switch (index) {
230 case SK_PROPERTY(translate):
231 // SkScalar xy[2];
232 SkASSERT(scriptValue.fType == SkType_Array);
233 SkASSERT(scriptValue.fOperand.fArray->getType() == SkType_Float);
234 SkASSERT(scriptValue.fOperand.fArray->count() == 2);
235 // SkParse::FindScalars(scriptValue.fOperand.fString->c_str(), xy, 2);
236 fMatrix.setTranslateX((*scriptValue.fOperand.fArray)[0].fScalar);
237 fMatrix.setTranslateY((*scriptValue.fOperand.fArray)[1].fScalar);
238 return true;
239 case SK_PROPERTY(perspectX):
240 #ifdef SK_SCALAR_IS_FIXED
241 fMatrix.setPerspX(SkFixedToFract(number));
242 #else
243 fMatrix.setPerspX(number);
244 #endif
245 break;
246 case SK_PROPERTY(perspectY):
247 #ifdef SK_SCALAR_IS_FIXED
248 fMatrix.setPerspY(SkFixedToFract(number));
249 #else
250 fMatrix.setPerspY(number);
251 #endif
252 break;
253 case SK_PROPERTY(rotate): {
254 SkMatrix temp;
255 temp.setRotate(number, 0, 0);
256 fMatrix.setScaleX(temp.getScaleX());
257 fMatrix.setScaleY(temp.getScaleY());
258 fMatrix.setSkewX(temp.getSkewX());
259 fMatrix.setSkewY(temp.getSkewY());
260 } break;
261 case SK_PROPERTY(scale):
262 fMatrix.setScaleX(number);
263 fMatrix.setScaleY(number);
264 break;
265 case SK_PROPERTY(scaleX):
266 fMatrix.setScaleX(number);
267 break;
268 case SK_PROPERTY(scaleY):
269 fMatrix.setScaleY(number);
270 break;
271 case SK_PROPERTY(skewX):
272 fMatrix.setSkewX(number);
273 break;
274 case SK_PROPERTY(skewY):
275 fMatrix.setSkewY(number);
276 break;
277 case SK_PROPERTY(translateX):
278 fMatrix.setTranslateX(number);
279 break;
280 case SK_PROPERTY(translateY):
281 fMatrix.setTranslateY(number);
282 break;
283 default:
284 SkASSERT(0);
285 return false;
286 }
287 fConcat = fMatrix;
288 return true;
289 }
290
291