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 "SkDrawPath.h"
     11 #include "SkAnimateMaker.h"
     12 #include "SkCanvas.h"
     13 #include "SkMath.h"
     14 #include "SkMatrixParts.h"
     15 #include "SkPaint.h"
     16 #include "SkPathParts.h"
     17 
     18 enum SkPath_Properties {
     19     SK_PROPERTY(fillType),
     20     SK_PROPERTY(length)
     21 };
     22 
     23 #if SK_USE_CONDENSED_INFO == 0
     24 
     25 const SkMemberInfo SkDrawPath::fInfo[] = {
     26     SK_MEMBER(d, String),
     27     SK_MEMBER_PROPERTY(fillType, FillType),
     28     SK_MEMBER_PROPERTY(length, Float)
     29 };
     30 
     31 #endif
     32 
     33 DEFINE_GET_MEMBER(SkDrawPath);
     34 
     35 SkDrawPath::SkDrawPath()
     36 {
     37     fParent = NULL;
     38     fLength = SK_ScalarNaN;
     39     fChildHasID = false;
     40     fDirty = false;
     41 }
     42 
     43 SkDrawPath::~SkDrawPath() {
     44     for (SkPathPart** part = fParts.begin(); part < fParts.end();  part++)
     45         delete *part;
     46 }
     47 
     48 bool SkDrawPath::add(SkAnimateMaker& maker, SkDisplayable* child) {
     49     SkASSERT(child && child->isPathPart());
     50     SkPathPart* part = (SkPathPart*) child;
     51     *fParts.append() = part;
     52     if (part->add())
     53         maker.setErrorCode(SkDisplayXMLParserError::kErrorAddingToPath);
     54     fDirty = false;
     55     return true;
     56 }
     57 
     58 bool SkDrawPath::childrenNeedDisposing() const {
     59     return false;
     60 }
     61 
     62 void SkDrawPath::dirty() {
     63     fDirty = true;
     64     fLength = SK_ScalarNaN;
     65     if (fParent)
     66         fParent->dirty();
     67 }
     68 
     69 bool SkDrawPath::draw(SkAnimateMaker& maker) {
     70     SkPath& path = getPath();
     71     SkBoundableAuto boundable(this, maker);
     72     maker.fCanvas->drawPath(path, *maker.fPaint);
     73     return false;
     74 }
     75 
     76 SkDisplayable* SkDrawPath::getParent() const {
     77     return fParent;
     78 }
     79 
     80 #ifdef SK_DUMP_ENABLED
     81 void SkDrawPath::dump(SkAnimateMaker* maker) {
     82     dumpBase(maker);
     83     dumpAttrs(maker);
     84     bool closedYet = false;
     85     SkDisplayList::fIndent += 4;
     86     for(SkPathPart** part = fParts.begin(); part < fParts.end(); part++) {
     87         if (closedYet == false) {
     88             SkDebugf(">\n");
     89             closedYet = true;
     90         }
     91         (*part)->dump(maker);
     92     }
     93     SkDisplayList::fIndent -= 4;
     94     if (closedYet)
     95         dumpEnd(maker);
     96     else
     97         SkDebugf("/>\n");
     98 }
     99 #endif
    100 
    101 SkPath& SkDrawPath::getPath() {
    102     if (fDirty == false)
    103         return fPath;
    104     if (d.size() > 0)
    105     {
    106         parseSVG();
    107         d.reset();
    108     }
    109     else
    110     {
    111         fPath.reset();
    112         for (SkPathPart** part = fParts.begin(); part < fParts.end();  part++)
    113             (*part)->add();
    114     }
    115     fDirty = false;
    116     return fPath;
    117 }
    118 
    119 void SkDrawPath::onEndElement(SkAnimateMaker& ) {
    120     if (d.size() > 0) {
    121         parseSVG();
    122         d.reset();
    123         fDirty = false;
    124         return;
    125     }
    126     if (fChildHasID == false) {
    127         for (SkPathPart** part = fParts.begin(); part < fParts.end();  part++)
    128             delete *part;
    129         fParts.reset();
    130         fDirty = false;
    131     }
    132 }
    133 
    134 bool SkDrawPath::getProperty(int index, SkScriptValue* value) const {
    135     switch (index) {
    136         case SK_PROPERTY(length):
    137             if (SkScalarIsNaN(fLength)) {
    138                 const SkPath& path = ((SkDrawPath*) this)->getPath();
    139                 SkPathMeasure pathMeasure(path, false);
    140                 fLength = pathMeasure.getLength();
    141             }
    142             value->fType = SkType_Float;
    143             value->fOperand.fScalar = fLength;
    144             break;
    145         case SK_PROPERTY(fillType):
    146             value->fType = SkType_FillType;
    147             value->fOperand.fS32 = (int) fPath.getFillType();
    148             break;
    149         default:
    150             SkASSERT(0);
    151             return false;
    152     }
    153     return true;
    154 }
    155 
    156 void SkDrawPath::setChildHasID() {
    157     fChildHasID = true;
    158 }
    159 
    160 bool SkDrawPath::setParent(SkDisplayable* parent) {
    161     fParent = parent;
    162     return false;
    163 }
    164 
    165 bool SkDrawPath::setProperty(int index, SkScriptValue& value)
    166 {
    167     switch (index) {
    168         case SK_PROPERTY(fillType):
    169             SkASSERT(value.fType == SkType_FillType);
    170             SkASSERT(value.fOperand.fS32 >= SkPath::kWinding_FillType &&
    171                 value.fOperand.fS32 <= SkPath::kEvenOdd_FillType);
    172             fPath.setFillType((SkPath::FillType) value.fOperand.fS32);
    173             break;
    174         default:
    175             SkASSERT(0);
    176             return false;
    177     }
    178     return true;
    179 }
    180 
    181 #if SK_USE_CONDENSED_INFO == 0
    182 
    183 const SkMemberInfo SkPolyline::fInfo[] = {
    184     SK_MEMBER_ARRAY(points, Float)
    185 };
    186 
    187 #endif
    188 
    189 DEFINE_GET_MEMBER(SkPolyline);
    190 
    191 bool SkPolyline::add(SkAnimateMaker& , SkDisplayable*) const {
    192     return false;
    193 }
    194 
    195 void SkPolyline::onEndElement(SkAnimateMaker& maker) {
    196     INHERITED::onEndElement(maker);
    197     if (points.count() <= 0)
    198         return;
    199     fPath.reset();
    200     fPath.moveTo(points[0], points[1]);
    201     int count = points.count();
    202     for (int index = 2; index < count; index += 2)
    203         fPath.lineTo(points[index], points[index+1]);
    204 }
    205 
    206 
    207 #if SK_USE_CONDENSED_INFO == 0
    208 
    209 const SkMemberInfo SkPolygon::fInfo[] = {
    210     SK_MEMBER_INHERITED
    211 };
    212 
    213 #endif
    214 
    215 DEFINE_GET_MEMBER(SkPolygon);
    216 
    217 void SkPolygon::onEndElement(SkAnimateMaker& maker) {
    218     INHERITED::onEndElement(maker);
    219     fPath.close();
    220 }
    221 
    222