Home | History | Annotate | Download | only in animator
      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 "SkDrawExtraPathEffect.h"
     11 #include "SkDrawPath.h"
     12 #include "Sk1DPathEffect.h"
     13 #include "Sk2DPathEffect.h"
     14 #include "SkMemberInfo.h"
     15 #include "SkPaintParts.h"
     16 #include "SkPathEffect.h"
     17 #include "SkCornerPathEffect.h"
     18 
     19 #include "SkDashPathEffect.h"
     20 
     21 class SkDrawShapePathEffect : public SkDrawPathEffect {
     22     DECLARE_PRIVATE_MEMBER_INFO(DrawShapePathEffect);
     23     SkDrawShapePathEffect();
     24     virtual ~SkDrawShapePathEffect();
     25     virtual bool addChild(SkAnimateMaker& , SkDisplayable* ) SK_OVERRIDE;
     26     virtual SkPathEffect* getPathEffect();
     27 protected:
     28     SkDrawable* addPath;
     29     SkDrawable* addMatrix;
     30     SkDrawPath* path;
     31     SkPathEffect* fPathEffect;
     32     friend class SkShape1DPathEffect;
     33     friend class SkShape2DPathEffect;
     34 };
     35 
     36 class SkDrawShape1DPathEffect : public SkDrawShapePathEffect {
     37     DECLARE_EXTRAS_MEMBER_INFO(SkDrawShape1DPathEffect);
     38     SkDrawShape1DPathEffect(SkDisplayTypes );
     39     virtual ~SkDrawShape1DPathEffect();
     40     virtual void onEndElement(SkAnimateMaker& );
     41 private:
     42     SkString phase;
     43     SkString spacing;
     44     friend class SkShape1DPathEffect;
     45     typedef SkDrawShapePathEffect INHERITED;
     46 };
     47 
     48 class SkDrawShape2DPathEffect : public SkDrawShapePathEffect {
     49     DECLARE_EXTRAS_MEMBER_INFO(SkDrawShape2DPathEffect);
     50     SkDrawShape2DPathEffect(SkDisplayTypes );
     51     virtual ~SkDrawShape2DPathEffect();
     52     virtual void onEndElement(SkAnimateMaker& );
     53 private:
     54     SkDrawMatrix* matrix;
     55     friend class SkShape2DPathEffect;
     56     typedef SkDrawShapePathEffect INHERITED;
     57 };
     58 
     59 class SkDrawComposePathEffect : public SkDrawPathEffect {
     60     DECLARE_EXTRAS_MEMBER_INFO(SkDrawComposePathEffect);
     61     SkDrawComposePathEffect(SkDisplayTypes );
     62     virtual ~SkDrawComposePathEffect();
     63     virtual bool addChild(SkAnimateMaker& , SkDisplayable* ) SK_OVERRIDE;
     64     virtual SkPathEffect* getPathEffect();
     65     virtual bool isPaint() const;
     66 private:
     67     SkDrawPathEffect* effect1;
     68     SkDrawPathEffect* effect2;
     69 };
     70 
     71 class SkDrawCornerPathEffect : public SkDrawPathEffect {
     72     DECLARE_EXTRAS_MEMBER_INFO(SkDrawCornerPathEffect);
     73     SkDrawCornerPathEffect(SkDisplayTypes );
     74     virtual ~SkDrawCornerPathEffect();
     75     virtual SkPathEffect* getPathEffect();
     76 private:
     77     SkScalar radius;
     78 };
     79 
     80 //////////// SkShape1DPathEffect
     81 
     82 #include "SkAnimateMaker.h"
     83 #include "SkAnimatorScript.h"
     84 #include "SkDisplayApply.h"
     85 #include "SkDrawMatrix.h"
     86 #include "SkPaint.h"
     87 
     88 class SkShape1DPathEffect : public Sk1DPathEffect {
     89 public:
     90     SkShape1DPathEffect(SkDrawShape1DPathEffect* draw, SkAnimateMaker* maker) :
     91         fDraw(draw), fMaker(maker) {
     92     }
     93 
     94     SK_DECLARE_UNFLATTENABLE_OBJECT()
     95 
     96 protected:
     97     virtual SkScalar begin(SkScalar contourLength) const {
     98         SkScriptValue value;
     99         SkAnimatorScript engine(*fMaker, NULL, SkType_Float);
    100         engine.propertyCallBack(GetContourLength, &contourLength);
    101         value.fOperand.fScalar = 0;
    102         engine.evaluate(fDraw->phase.c_str(), &value, SkType_Float);
    103         return value.fOperand.fScalar;
    104     }
    105 
    106     virtual SkScalar next(SkPath* dst, SkScalar distance, SkPathMeasure&) const {
    107         fMaker->setExtraPropertyCallBack(fDraw->fType, GetDistance, &distance);
    108         SkDrawPath* drawPath = NULL;
    109         if (fDraw->addPath->isPath()) {
    110             drawPath = (SkDrawPath*) fDraw->addPath;
    111         } else {
    112             SkApply* apply = (SkApply*) fDraw->addPath;
    113             apply->refresh(*fMaker);
    114             apply->activate(*fMaker);
    115             apply->interpolate(*fMaker, SkScalarMulRound(distance, 1000));
    116             drawPath = (SkDrawPath*) apply->getScope();
    117         }
    118         SkMatrix m;
    119         m.reset();
    120         if (fDraw->addMatrix) {
    121             SkDrawMatrix* matrix;
    122             if (fDraw->addMatrix->getType() == SkType_Matrix)
    123                 matrix = (SkDrawMatrix*) fDraw->addMatrix;
    124             else {
    125                 SkApply* apply = (SkApply*) fDraw->addMatrix;
    126                 apply->refresh(*fMaker);
    127                 apply->activate(*fMaker);
    128                 apply->interpolate(*fMaker, SkScalarMulRound(distance, 1000));
    129                 matrix = (SkDrawMatrix*) apply->getScope();
    130             }
    131             if (matrix) {
    132                 m = matrix->getMatrix();
    133             }
    134         }
    135         SkScalar result = 0;
    136         SkAnimatorScript::EvaluateFloat(*fMaker, NULL, fDraw->spacing.c_str(), &result);
    137         if (drawPath)
    138             dst->addPath(drawPath->getPath(), m);
    139         fMaker->clearExtraPropertyCallBack(fDraw->fType);
    140         return result;
    141     }
    142 
    143 private:
    144     static bool GetContourLength(const char* token, size_t len, void* clen, SkScriptValue* value) {
    145         if (SK_LITERAL_STR_EQUAL("contourLength", token, len)) {
    146             value->fOperand.fScalar = *(SkScalar*) clen;
    147             value->fType = SkType_Float;
    148             return true;
    149         }
    150         return false;
    151     }
    152 
    153     static bool GetDistance(const char* token, size_t len, void* dist, SkScriptValue* value) {
    154         if (SK_LITERAL_STR_EQUAL("distance", token, len)) {
    155             value->fOperand.fScalar = *(SkScalar*) dist;
    156             value->fType = SkType_Float;
    157             return true;
    158         }
    159         return false;
    160     }
    161 
    162     SkDrawShape1DPathEffect* fDraw;
    163     SkAnimateMaker* fMaker;
    164 };
    165 
    166 //////////// SkDrawShapePathEffect
    167 
    168 #if SK_USE_CONDENSED_INFO == 0
    169 
    170 const SkMemberInfo SkDrawShapePathEffect::fInfo[] = {
    171     SK_MEMBER(addMatrix, Drawable), // either matrix or apply
    172     SK_MEMBER(addPath, Drawable),   // either path or apply
    173     SK_MEMBER(path, Path),
    174 };
    175 
    176 #endif
    177 
    178 DEFINE_GET_MEMBER(SkDrawShapePathEffect);
    179 
    180 SkDrawShapePathEffect::SkDrawShapePathEffect() :
    181     addPath(NULL), addMatrix(NULL), path(NULL), fPathEffect(NULL) {
    182 }
    183 
    184 SkDrawShapePathEffect::~SkDrawShapePathEffect() {
    185     SkSafeUnref(fPathEffect);
    186 }
    187 
    188 bool SkDrawShapePathEffect::addChild(SkAnimateMaker& , SkDisplayable* child) {
    189     path = (SkDrawPath*) child;
    190     return true;
    191 }
    192 
    193 SkPathEffect* SkDrawShapePathEffect::getPathEffect() {
    194     fPathEffect->ref();
    195     return fPathEffect;
    196 }
    197 
    198 //////////// SkDrawShape1DPathEffect
    199 
    200 #if SK_USE_CONDENSED_INFO == 0
    201 
    202 const SkMemberInfo SkDrawShape1DPathEffect::fInfo[] = {
    203     SK_MEMBER_INHERITED,
    204     SK_MEMBER(phase, String),
    205     SK_MEMBER(spacing, String),
    206 };
    207 
    208 #endif
    209 
    210 DEFINE_GET_MEMBER(SkDrawShape1DPathEffect);
    211 
    212 SkDrawShape1DPathEffect::SkDrawShape1DPathEffect(SkDisplayTypes type) : fType(type) {
    213 }
    214 
    215 SkDrawShape1DPathEffect::~SkDrawShape1DPathEffect() {
    216 }
    217 
    218 void SkDrawShape1DPathEffect::onEndElement(SkAnimateMaker& maker) {
    219     if (addPath == NULL || (addPath->isPath() == false && addPath->isApply() == false))
    220         maker.setErrorCode(SkDisplayXMLParserError::kUnknownError); // !!! add error
    221     else
    222         fPathEffect = new SkShape1DPathEffect(this, &maker);
    223 }
    224 
    225 ////////// SkShape2DPathEffect
    226 
    227 class SkShape2DPathEffect : public Sk2DPathEffect {
    228 public:
    229     SkShape2DPathEffect(SkDrawShape2DPathEffect* draw, SkAnimateMaker* maker,
    230         const SkMatrix& matrix) : Sk2DPathEffect(matrix), fDraw(draw), fMaker(maker) {
    231     }
    232 
    233 protected:
    234     virtual void begin(const SkIRect& uvBounds, SkPath*) const SK_OVERRIDE {
    235         const_cast<SkShape2DPathEffect*>(this)->setUVBounds(uvBounds);
    236     }
    237 
    238     virtual void next(const SkPoint& loc, int u, int v, SkPath* dst) const SK_OVERRIDE {
    239         const_cast<SkShape2DPathEffect*>(this)->addPath(loc, u, v, dst);
    240     }
    241 
    242 private:
    243     void setUVBounds(const SkIRect& uvBounds) {
    244         fUVBounds.set(SkIntToScalar(uvBounds.fLeft), SkIntToScalar(uvBounds.fTop),
    245             SkIntToScalar(uvBounds.fRight), SkIntToScalar(uvBounds.fBottom));
    246     }
    247 
    248     void addPath(const SkPoint& loc, int u, int v, SkPath* dst) {
    249         fLoc = loc;
    250         fU = u;
    251         fV = v;
    252         SkDrawPath* drawPath;
    253         fMaker->setExtraPropertyCallBack(fDraw->fType, Get2D, this);
    254         if (fDraw->addPath->isPath()) {
    255             drawPath = (SkDrawPath*) fDraw->addPath;
    256         } else {
    257             SkApply* apply = (SkApply*) fDraw->addPath;
    258             apply->refresh(*fMaker);
    259             apply->activate(*fMaker);
    260             apply->interpolate(*fMaker, v);
    261             drawPath = (SkDrawPath*) apply->getScope();
    262         }
    263         if (drawPath == NULL)
    264             goto clearCallBack;
    265         if (fDraw->matrix) {
    266             SkDrawMatrix* matrix;
    267             if (fDraw->matrix->getType() == SkType_Matrix)
    268                 matrix = (SkDrawMatrix*) fDraw->matrix;
    269             else {
    270                 SkApply* apply = (SkApply*) fDraw->matrix;
    271                 apply->activate(*fMaker);
    272                 apply->interpolate(*fMaker, v);
    273                 matrix = (SkDrawMatrix*) apply->getScope();
    274             }
    275             if (matrix) {
    276                 dst->addPath(drawPath->getPath(), matrix->getMatrix());
    277                 goto clearCallBack;
    278             }
    279         }
    280         dst->addPath(drawPath->getPath());
    281 clearCallBack:
    282         fMaker->clearExtraPropertyCallBack(fDraw->fType);
    283     }
    284 
    285     static bool Get2D(const char* token, size_t len, void* s2D, SkScriptValue* value) {
    286         static const char match[] = "locX|locY|left|top|right|bottom|u|v" ;
    287         SkShape2DPathEffect* shape2D = (SkShape2DPathEffect*) s2D;
    288         int index;
    289         if (SkAnimatorScript::MapEnums(match, token, len, &index) == false)
    290             return false;
    291         SkASSERT((sizeof(SkPoint) +     sizeof(SkRect)) / sizeof(SkScalar) == 6);
    292         if (index < 6) {
    293             value->fType = SkType_Float;
    294             value->fOperand.fScalar = (&shape2D->fLoc.fX)[index];
    295         } else {
    296             value->fType = SkType_Int;
    297             value->fOperand.fS32 = (&shape2D->fU)[index - 6];
    298         }
    299         return true;
    300     }
    301 
    302     SkPoint fLoc;
    303     SkRect fUVBounds;
    304     int32_t fU;
    305     int32_t fV;
    306     SkDrawShape2DPathEffect* fDraw;
    307     SkAnimateMaker* fMaker;
    308 
    309     // illegal
    310     SkShape2DPathEffect(const SkShape2DPathEffect&);
    311     SkShape2DPathEffect& operator=(const SkShape2DPathEffect&);
    312 };
    313 
    314 ////////// SkDrawShape2DPathEffect
    315 
    316 #if SK_USE_CONDENSED_INFO == 0
    317 
    318 const SkMemberInfo SkDrawShape2DPathEffect::fInfo[] = {
    319     SK_MEMBER_INHERITED,
    320     SK_MEMBER(matrix, Matrix)
    321 };
    322 
    323 #endif
    324 
    325 DEFINE_GET_MEMBER(SkDrawShape2DPathEffect);
    326 
    327 SkDrawShape2DPathEffect::SkDrawShape2DPathEffect(SkDisplayTypes type) : fType(type) {
    328 }
    329 
    330 SkDrawShape2DPathEffect::~SkDrawShape2DPathEffect() {
    331 }
    332 
    333 void SkDrawShape2DPathEffect::onEndElement(SkAnimateMaker& maker) {
    334     if (addPath == NULL || (addPath->isPath() == false && addPath->isApply() == false) ||
    335             matrix == NULL)
    336         maker.setErrorCode(SkDisplayXMLParserError::kUnknownError); // !!! add error
    337     else
    338         fPathEffect = new SkShape2DPathEffect(this, &maker, matrix->getMatrix());
    339 }
    340 
    341 ////////// SkDrawComposePathEffect
    342 
    343 #if SK_USE_CONDENSED_INFO == 0
    344 
    345 const SkMemberInfo SkDrawComposePathEffect::fInfo[] = {
    346     SK_MEMBER(effect1, PathEffect),
    347     SK_MEMBER(effect2, PathEffect)
    348 };
    349 
    350 #endif
    351 
    352 DEFINE_GET_MEMBER(SkDrawComposePathEffect);
    353 
    354 SkDrawComposePathEffect::SkDrawComposePathEffect(SkDisplayTypes type) : fType(type),
    355     effect1(NULL), effect2(NULL) {
    356 }
    357 
    358 SkDrawComposePathEffect::~SkDrawComposePathEffect() {
    359     delete effect1;
    360     delete effect2;
    361 }
    362 
    363 bool SkDrawComposePathEffect::addChild(SkAnimateMaker& , SkDisplayable* child) {
    364     if (effect1 == NULL)
    365         effect1 = (SkDrawPathEffect*) child;
    366     else
    367         effect2 = (SkDrawPathEffect*) child;
    368     return true;
    369 }
    370 
    371 SkPathEffect* SkDrawComposePathEffect::getPathEffect() {
    372     SkPathEffect* e1 = effect1->getPathEffect();
    373     SkPathEffect* e2 = effect2->getPathEffect();
    374     SkPathEffect* composite = new SkComposePathEffect(e1, e2);
    375     e1->unref();
    376     e2->unref();
    377     return composite;
    378 }
    379 
    380 bool SkDrawComposePathEffect::isPaint() const {
    381     return true;
    382 }
    383 
    384 //////////// SkDrawCornerPathEffect
    385 
    386 #if SK_USE_CONDENSED_INFO == 0
    387 
    388 const SkMemberInfo SkDrawCornerPathEffect::fInfo[] = {
    389     SK_MEMBER(radius, Float)
    390 };
    391 
    392 #endif
    393 
    394 DEFINE_GET_MEMBER(SkDrawCornerPathEffect);
    395 
    396 SkDrawCornerPathEffect::SkDrawCornerPathEffect(SkDisplayTypes type):
    397     fType(type), radius(0) {
    398 }
    399 
    400 SkDrawCornerPathEffect::~SkDrawCornerPathEffect() {
    401 }
    402 
    403 SkPathEffect* SkDrawCornerPathEffect::getPathEffect() {
    404     return new SkCornerPathEffect(radius);
    405 }
    406 
    407 /////////
    408 
    409 #include "SkExtras.h"
    410 
    411 const char kDrawShape1DPathEffectName[] = "pathEffect:shape1D";
    412 const char kDrawShape2DPathEffectName[] = "pathEffect:shape2D";
    413 const char kDrawComposePathEffectName[] = "pathEffect:compose";
    414 const char kDrawCornerPathEffectName[]  = "pathEffect:corner";
    415 
    416 class SkExtraPathEffects : public SkExtras {
    417 public:
    418     SkExtraPathEffects() :
    419             skDrawShape1DPathEffectType(SkType_Unknown),
    420             skDrawShape2DPathEffectType(SkType_Unknown),
    421             skDrawComposePathEffectType(SkType_Unknown),
    422             skDrawCornerPathEffectType(SkType_Unknown) {
    423     }
    424 
    425     virtual SkDisplayable* createInstance(SkDisplayTypes type) {
    426         SkDisplayable* result = NULL;
    427         if (skDrawShape1DPathEffectType == type)
    428             result = new SkDrawShape1DPathEffect(type);
    429         else if (skDrawShape2DPathEffectType == type)
    430             result = new SkDrawShape2DPathEffect(type);
    431         else if (skDrawComposePathEffectType == type)
    432             result = new SkDrawComposePathEffect(type);
    433         else if (skDrawCornerPathEffectType == type)
    434             result = new SkDrawCornerPathEffect(type);
    435         return result;
    436     }
    437 
    438     virtual bool definesType(SkDisplayTypes type) {
    439         return type == skDrawShape1DPathEffectType ||
    440             type == skDrawShape2DPathEffectType ||
    441             type == skDrawComposePathEffectType ||
    442             type == skDrawCornerPathEffectType;
    443     }
    444 
    445 #if SK_USE_CONDENSED_INFO == 0
    446     virtual const SkMemberInfo* getMembers(SkDisplayTypes type, int* infoCountPtr) {
    447         const SkMemberInfo* info = NULL;
    448         int infoCount = 0;
    449         if (skDrawShape1DPathEffectType == type) {
    450             info = SkDrawShape1DPathEffect::fInfo;
    451             infoCount = SkDrawShape1DPathEffect::fInfoCount;
    452         } else if (skDrawShape2DPathEffectType == type) {
    453             info = SkDrawShape2DPathEffect::fInfo;
    454             infoCount = SkDrawShape2DPathEffect::fInfoCount;
    455         } else if (skDrawComposePathEffectType == type) {
    456             info = SkDrawComposePathEffect::fInfo;
    457             infoCount = SkDrawShape1DPathEffect::fInfoCount;
    458         } else if (skDrawCornerPathEffectType == type) {
    459             info = SkDrawCornerPathEffect::fInfo;
    460             infoCount = SkDrawCornerPathEffect::fInfoCount;
    461         }
    462         if (infoCountPtr)
    463             *infoCountPtr = infoCount;
    464         return info;
    465     }
    466 #endif
    467 
    468 #ifdef SK_DEBUG
    469     virtual const char* getName(SkDisplayTypes type) {
    470         if (skDrawShape1DPathEffectType == type)
    471             return kDrawShape1DPathEffectName;
    472         else if (skDrawShape2DPathEffectType == type)
    473             return kDrawShape2DPathEffectName;
    474         else if (skDrawComposePathEffectType == type)
    475             return kDrawComposePathEffectName;
    476         else if (skDrawCornerPathEffectType == type)
    477             return kDrawCornerPathEffectName;
    478         return NULL;
    479     }
    480 #endif
    481 
    482     virtual SkDisplayTypes getType(const char name[], size_t len ) {
    483         SkDisplayTypes* type = NULL;
    484         if (SK_LITERAL_STR_EQUAL(kDrawShape1DPathEffectName, name, len))
    485             type = &skDrawShape1DPathEffectType;
    486         else if (SK_LITERAL_STR_EQUAL(kDrawShape2DPathEffectName, name, len))
    487             type = &skDrawShape2DPathEffectType;
    488         else if (SK_LITERAL_STR_EQUAL(kDrawComposePathEffectName, name, len))
    489             type = &skDrawComposePathEffectType;
    490         else if (SK_LITERAL_STR_EQUAL(kDrawCornerPathEffectName, name, len))
    491             type = &skDrawCornerPathEffectType;
    492         if (type) {
    493             if (*type == SkType_Unknown)
    494                 *type = SkDisplayType::RegisterNewType();
    495             return *type;
    496         }
    497         return SkType_Unknown;
    498     }
    499 
    500 private:
    501     SkDisplayTypes skDrawShape1DPathEffectType;
    502     SkDisplayTypes skDrawShape2DPathEffectType;
    503     SkDisplayTypes skDrawComposePathEffectType;
    504     SkDisplayTypes skDrawCornerPathEffectType;
    505 };
    506 
    507 void InitializeSkExtraPathEffects(SkAnimator* animator) {
    508     animator->addExtras(new SkExtraPathEffects());
    509 }
    510 
    511 ////////////////
    512 
    513 
    514 SkExtras::SkExtras() : fExtraCallBack(NULL), fExtraStorage(NULL) {
    515 }
    516