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