| |
| /* |
| * 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::add(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]); |
| #ifdef SK_SCALAR_IS_FIXED |
| fMatrix.setPerspX(SkFixedToFract(vals[6])); |
| fMatrix.setPerspY(SkFixedToFract(vals[7])); |
| #else |
| fMatrix.setPerspX(vals[6]); |
| fMatrix.setPerspY(vals[7]); |
| #endif |
| // 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): |
| #ifdef SK_SCALAR_IS_FIXED |
| fMatrix.setPerspX(SkFixedToFract(number)); |
| #else |
| fMatrix.setPerspX(number); |
| #endif |
| break; |
| case SK_PROPERTY(perspectY): |
| #ifdef SK_SCALAR_IS_FIXED |
| fMatrix.setPerspY(SkFixedToFract(number)); |
| #else |
| fMatrix.setPerspY(number); |
| #endif |
| 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; |
| } |
| |