grab from latest android



git-svn-id: http://skia.googlecode.com/svn/trunk@27 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/animator/SkDrawMatrix.cpp b/src/animator/SkDrawMatrix.cpp
new file mode 100644
index 0000000..dbdbf19
--- /dev/null
+++ b/src/animator/SkDrawMatrix.cpp
@@ -0,0 +1,290 @@
+/* libs/graphics/animator/SkDrawMatrix.cpp
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+** See the License for the specific language governing permissions and 
+** limitations under the License.
+*/
+
+#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;
+}
+