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 19enum 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 35const 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 52DEFINE_GET_MEMBER(SkDrawMatrix); 53 54SkDrawMatrix::SkDrawMatrix() : fChildHasID(false), fDirty(false) { 55 fConcat.reset(); 56 fMatrix.reset(); 57} 58 59SkDrawMatrix::~SkDrawMatrix() { 60 for (SkMatrixPart** part = fParts.begin(); part < fParts.end(); part++) 61 delete *part; 62} 63 64bool 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 73bool SkDrawMatrix::childrenNeedDisposing() const { 74 return false; 75} 76 77SkDisplayable* 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 86void SkDrawMatrix::dirty() { 87 fDirty = true; 88} 89 90bool SkDrawMatrix::draw(SkAnimateMaker& maker) { 91 SkMatrix& concat = getMatrix(); 92 maker.fCanvas->concat(concat); 93 return false; 94} 95 96#ifdef SK_DUMP_ENABLED 97void 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 = fMatrix.getPerspX(); 123 if (result) 124 SkDebugf("perspect-x=\"%g\" ", SkScalarToFloat(result)); 125 result = fMatrix.getPerspY(); 126 if (result) 127 SkDebugf("perspect-y=\"%g\" ", SkScalarToFloat(result)); 128 SkDebugf("/>\n"); 129} 130#endif 131 132SkMatrix& 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 144bool 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 180void SkDrawMatrix::initialize() { 181 fConcat = fMatrix; 182} 183 184void 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(vals[6]); 194 fMatrix.setPerspY(vals[7]); 195// fMatrix.setPerspW(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(); 204setConcat: 205 fConcat = fMatrix; 206 fDirty = false; 207 } 208} 209 210void SkDrawMatrix::setChildHasID() { 211 fChildHasID = true; 212} 213 214bool 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(number); 228 break; 229 case SK_PROPERTY(perspectY): 230 fMatrix.setPerspY(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