| /* | |
| * Copyright 2006 The Android Open Source Project | |
| * | |
| * Use of this source code is governed by a BSD-style license that can be | |
| * found in the LICENSE file. | |
| */ | |
| #include "SkDrawMatrix.h" | |
| #include "SkAnimateMaker.h" | |
| #include "SkCanvas.h" | |
| #include "SkPaint.h" | |
| #include "SkParse.h" | |
| #include "SkMatrixParts.h" | |
| #include "SkScript.h" | |
| #include "SkTypedArray.h" | |
| enum SkDrawMatrix_Properties { | |
| SK_PROPERTY(perspectX), | |
| SK_PROPERTY(perspectY), | |
| SK_PROPERTY(rotate), | |
| SK_PROPERTY(scale), | |
| SK_PROPERTY(scaleX), | |
| SK_PROPERTY(scaleY), | |
| SK_PROPERTY(skewX), | |
| SK_PROPERTY(skewY), | |
| SK_PROPERTY(translate), | |
| SK_PROPERTY(translateX), | |
| SK_PROPERTY(translateY) | |
| }; | |
| #if SK_USE_CONDENSED_INFO == 0 | |
| const SkMemberInfo SkDrawMatrix::fInfo[] = { | |
| SK_MEMBER_ARRAY(matrix, Float), | |
| SK_MEMBER_PROPERTY(perspectX, Float), | |
| SK_MEMBER_PROPERTY(perspectY, Float), | |
| SK_MEMBER_PROPERTY(rotate, Float), | |
| SK_MEMBER_PROPERTY(scale, Float), | |
| SK_MEMBER_PROPERTY(scaleX, Float), | |
| SK_MEMBER_PROPERTY(scaleY, Float), | |
| SK_MEMBER_PROPERTY(skewX, Float), | |
| SK_MEMBER_PROPERTY(skewY, Float), | |
| SK_MEMBER_PROPERTY(translate, Point), | |
| SK_MEMBER_PROPERTY(translateX, Float), | |
| SK_MEMBER_PROPERTY(translateY, Float) | |
| }; | |
| #endif | |
| DEFINE_GET_MEMBER(SkDrawMatrix); | |
| SkDrawMatrix::SkDrawMatrix() : fChildHasID(false), fDirty(false) { | |
| fConcat.reset(); | |
| fMatrix.reset(); | |
| } | |
| SkDrawMatrix::~SkDrawMatrix() { | |
| for (SkMatrixPart** part = fParts.begin(); part < fParts.end(); part++) | |
| delete *part; | |
| } | |
| bool SkDrawMatrix::addChild(SkAnimateMaker& maker, SkDisplayable* child) { | |
| SkASSERT(child && child->isMatrixPart()); | |
| SkMatrixPart* part = (SkMatrixPart*) child; | |
| *fParts.append() = part; | |
| if (part->add()) | |
| maker.setErrorCode(SkDisplayXMLParserError::kErrorAddingToMatrix); | |
| return true; | |
| } | |
| bool SkDrawMatrix::childrenNeedDisposing() const { | |
| return false; | |
| } | |
| SkDisplayable* SkDrawMatrix::deepCopy(SkAnimateMaker* maker) { | |
| SkDrawMatrix* copy = (SkDrawMatrix*) | |
| SkDisplayType::CreateInstance(maker, SkType_Matrix); | |
| SkASSERT(fParts.count() == 0); | |
| copy->fMatrix = fMatrix; | |
| copy->fConcat = fConcat; | |
| return copy; | |
| } | |
| void SkDrawMatrix::dirty() { | |
| fDirty = true; | |
| } | |
| bool SkDrawMatrix::draw(SkAnimateMaker& maker) { | |
| SkMatrix& concat = getMatrix(); | |
| maker.fCanvas->concat(concat); | |
| return false; | |
| } | |
| #ifdef SK_DUMP_ENABLED | |
| void SkDrawMatrix::dump(SkAnimateMaker* maker) { | |
| dumpBase(maker); | |
| if (fMatrix.isIdentity()) { | |
| SkDebugf("matrix=\"identity\"/>\n"); | |
| return; | |
| } | |
| SkScalar result; | |
| result = fMatrix[SkMatrix::kMScaleX]; | |
| if (result != SK_Scalar1) | |
| SkDebugf("sx=\"%g\" ", SkScalarToFloat(result)); | |
| result = fMatrix.getScaleY(); | |
| if (result != SK_Scalar1) | |
| SkDebugf("sy=\"%g\" ", SkScalarToFloat(result)); | |
| result = fMatrix.getSkewX(); | |
| if (result) | |
| SkDebugf("skew-x=\"%g\" ", SkScalarToFloat(result)); | |
| result = fMatrix.getSkewY(); | |
| if (result) | |
| SkDebugf("skew-y=\"%g\" ", SkScalarToFloat(result)); | |
| result = fMatrix.getTranslateX(); | |
| if (result) | |
| SkDebugf("tx=\"%g\" ", SkScalarToFloat(result)); | |
| result = fMatrix.getTranslateY(); | |
| if (result) | |
| SkDebugf("ty=\"%g\" ", SkScalarToFloat(result)); | |
| result = fMatrix.getPerspX(); | |
| if (result) | |
| SkDebugf("perspect-x=\"%g\" ", SkScalarToFloat(result)); | |
| result = fMatrix.getPerspY(); | |
| if (result) | |
| SkDebugf("perspect-y=\"%g\" ", SkScalarToFloat(result)); | |
| SkDebugf("/>\n"); | |
| } | |
| #endif | |
| SkMatrix& SkDrawMatrix::getMatrix() { | |
| if (fDirty == false) | |
| return fConcat; | |
| fMatrix.reset(); | |
| for (SkMatrixPart** part = fParts.begin(); part < fParts.end(); part++) { | |
| (*part)->add(); | |
| fConcat = fMatrix; | |
| } | |
| fDirty = false; | |
| return fConcat; | |
| } | |
| bool SkDrawMatrix::getProperty(int index, SkScriptValue* value) const { | |
| value->fType = SkType_Float; | |
| SkScalar result; | |
| switch (index) { | |
| case SK_PROPERTY(perspectX): | |
| result = fMatrix.getPerspX(); | |
| break; | |
| case SK_PROPERTY(perspectY): | |
| result = fMatrix.getPerspY(); | |
| break; | |
| case SK_PROPERTY(scaleX): | |
| result = fMatrix.getScaleX(); | |
| break; | |
| case SK_PROPERTY(scaleY): | |
| result = fMatrix.getScaleY(); | |
| break; | |
| case SK_PROPERTY(skewX): | |
| result = fMatrix.getSkewX(); | |
| break; | |
| case SK_PROPERTY(skewY): | |
| result = fMatrix.getSkewY(); | |
| break; | |
| case SK_PROPERTY(translateX): | |
| result = fMatrix.getTranslateX(); | |
| break; | |
| case SK_PROPERTY(translateY): | |
| result = fMatrix.getTranslateY(); | |
| break; | |
| default: | |
| // SkASSERT(0); | |
| return false; | |
| } | |
| value->fOperand.fScalar = result; | |
| return true; | |
| } | |
| void SkDrawMatrix::initialize() { | |
| fConcat = fMatrix; | |
| } | |
| void SkDrawMatrix::onEndElement(SkAnimateMaker& ) { | |
| if (matrix.count() > 0) { | |
| SkScalar* vals = matrix.begin(); | |
| fMatrix.setScaleX(vals[0]); | |
| fMatrix.setSkewX(vals[1]); | |
| fMatrix.setTranslateX(vals[2]); | |
| fMatrix.setSkewY(vals[3]); | |
| fMatrix.setScaleY(vals[4]); | |
| fMatrix.setTranslateY(vals[5]); | |
| fMatrix.setPerspX(vals[6]); | |
| fMatrix.setPerspY(vals[7]); | |
| // fMatrix.setPerspW(vals[8]); | |
| goto setConcat; | |
| } | |
| if (fChildHasID == false) { | |
| { | |
| for (SkMatrixPart** part = fParts.begin(); part < fParts.end(); part++) | |
| delete *part; | |
| } | |
| fParts.reset(); | |
| setConcat: | |
| fConcat = fMatrix; | |
| fDirty = false; | |
| } | |
| } | |
| void SkDrawMatrix::setChildHasID() { | |
| fChildHasID = true; | |
| } | |
| bool SkDrawMatrix::setProperty(int index, SkScriptValue& scriptValue) { | |
| SkScalar number = scriptValue.fOperand.fScalar; | |
| switch (index) { | |
| case SK_PROPERTY(translate): | |
| // SkScalar xy[2]; | |
| SkASSERT(scriptValue.fType == SkType_Array); | |
| SkASSERT(scriptValue.fOperand.fArray->getType() == SkType_Float); | |
| SkASSERT(scriptValue.fOperand.fArray->count() == 2); | |
| // SkParse::FindScalars(scriptValue.fOperand.fString->c_str(), xy, 2); | |
| fMatrix.setTranslateX((*scriptValue.fOperand.fArray)[0].fScalar); | |
| fMatrix.setTranslateY((*scriptValue.fOperand.fArray)[1].fScalar); | |
| return true; | |
| case SK_PROPERTY(perspectX): | |
| fMatrix.setPerspX(number); | |
| break; | |
| case SK_PROPERTY(perspectY): | |
| fMatrix.setPerspY(number); | |
| break; | |
| case SK_PROPERTY(rotate): { | |
| SkMatrix temp; | |
| temp.setRotate(number, 0, 0); | |
| fMatrix.setScaleX(temp.getScaleX()); | |
| fMatrix.setScaleY(temp.getScaleY()); | |
| fMatrix.setSkewX(temp.getSkewX()); | |
| fMatrix.setSkewY(temp.getSkewY()); | |
| } break; | |
| case SK_PROPERTY(scale): | |
| fMatrix.setScaleX(number); | |
| fMatrix.setScaleY(number); | |
| break; | |
| case SK_PROPERTY(scaleX): | |
| fMatrix.setScaleX(number); | |
| break; | |
| case SK_PROPERTY(scaleY): | |
| fMatrix.setScaleY(number); | |
| break; | |
| case SK_PROPERTY(skewX): | |
| fMatrix.setSkewX(number); | |
| break; | |
| case SK_PROPERTY(skewY): | |
| fMatrix.setSkewY(number); | |
| break; | |
| case SK_PROPERTY(translateX): | |
| fMatrix.setTranslateX(number); | |
| break; | |
| case SK_PROPERTY(translateY): | |
| fMatrix.setTranslateY(number); | |
| break; | |
| default: | |
| SkASSERT(0); | |
| return false; | |
| } | |
| fConcat = fMatrix; | |
| return true; | |
| } |