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 62 SkDrawMatrix::SkDrawMatrix() : fChildHasID(false), fDirty(false) { 63 fConcat.reset(); 64 fMatrix.reset(); 65 } 66 67 SkDrawMatrix::~SkDrawMatrix() { 68 for (SkMatrixPart** part = fParts.begin(); part < fParts.end(); part++) 69 delete *part; 70 } 71 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 81 bool SkDrawMatrix::childrenNeedDisposing() const { 82 return false; 83 } 84 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 94 void SkDrawMatrix::dirty() { 95 fDirty = true; 96 } 97 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 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 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 152 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 188 void SkDrawMatrix::initialize() { 189 fConcat = fMatrix; 190 } 191 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 223 void SkDrawMatrix::setChildHasID() { 224 fChildHasID = true; 225 } 226 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