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