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