blob: dbdbf19ae13248a8b91c0e157da8449265fc43d0 [file] [log] [blame]
reed@android.com8a1c16f2008-12-17 15:59:43 +00001/* 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
27enum 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
43const 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
60DEFINE_GET_MEMBER(SkDrawMatrix);
61
62SkDrawMatrix::SkDrawMatrix() : fChildHasID(false), fDirty(false) {
63 fConcat.reset();
64 fMatrix.reset();
65}
66
67SkDrawMatrix::~SkDrawMatrix() {
68 for (SkMatrixPart** part = fParts.begin(); part < fParts.end(); part++)
69 delete *part;
70}
71
72bool 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
81bool SkDrawMatrix::childrenNeedDisposing() const {
82 return false;
83}
84
85SkDisplayable* 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
94void SkDrawMatrix::dirty() {
95 fDirty = true;
96}
97
98bool SkDrawMatrix::draw(SkAnimateMaker& maker) {
99 SkMatrix& concat = getMatrix();
100 maker.fCanvas->concat(concat);
101 return false;
102}
103
104#ifdef SK_DUMP_ENABLED
105void 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
140SkMatrix& 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
152bool 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
188void SkDrawMatrix::initialize() {
189 fConcat = fMatrix;
190}
191
192void 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();
217setConcat:
218 fConcat = fMatrix;
219 fDirty = false;
220 }
221}
222
223void SkDrawMatrix::setChildHasID() {
224 fChildHasID = true;
225}
226
227bool 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