| |
| /* |
| * Copyright 2006 The Android Open Source Project |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| |
| #include "SkDrawPath.h" |
| #include "SkAnimateMaker.h" |
| #include "SkCanvas.h" |
| #include "SkMath.h" |
| #include "SkMatrixParts.h" |
| #include "SkPaint.h" |
| #include "SkPathParts.h" |
| |
| enum SkPath_Properties { |
| SK_PROPERTY(fillType), |
| SK_PROPERTY(length) |
| }; |
| |
| #if SK_USE_CONDENSED_INFO == 0 |
| |
| const SkMemberInfo SkDrawPath::fInfo[] = { |
| SK_MEMBER(d, String), |
| SK_MEMBER_PROPERTY(fillType, FillType), |
| SK_MEMBER_PROPERTY(length, Float) |
| }; |
| |
| #endif |
| |
| DEFINE_GET_MEMBER(SkDrawPath); |
| |
| SkDrawPath::SkDrawPath() |
| { |
| fParent = NULL; |
| fLength = SK_ScalarNaN; |
| fChildHasID = false; |
| fDirty = false; |
| } |
| |
| SkDrawPath::~SkDrawPath() { |
| for (SkPathPart** part = fParts.begin(); part < fParts.end(); part++) |
| delete *part; |
| } |
| |
| bool SkDrawPath::add(SkAnimateMaker& maker, SkDisplayable* child) { |
| SkASSERT(child && child->isPathPart()); |
| SkPathPart* part = (SkPathPart*) child; |
| *fParts.append() = part; |
| if (part->add()) |
| maker.setErrorCode(SkDisplayXMLParserError::kErrorAddingToPath); |
| fDirty = false; |
| return true; |
| } |
| |
| bool SkDrawPath::childrenNeedDisposing() const { |
| return false; |
| } |
| |
| void SkDrawPath::dirty() { |
| fDirty = true; |
| fLength = SK_ScalarNaN; |
| if (fParent) |
| fParent->dirty(); |
| } |
| |
| bool SkDrawPath::draw(SkAnimateMaker& maker) { |
| SkPath& path = getPath(); |
| SkBoundableAuto boundable(this, maker); |
| maker.fCanvas->drawPath(path, *maker.fPaint); |
| return false; |
| } |
| |
| SkDisplayable* SkDrawPath::getParent() const { |
| return fParent; |
| } |
| |
| #ifdef SK_DUMP_ENABLED |
| void SkDrawPath::dump(SkAnimateMaker* maker) { |
| dumpBase(maker); |
| dumpAttrs(maker); |
| bool closedYet = false; |
| SkDisplayList::fIndent += 4; |
| for(SkPathPart** part = fParts.begin(); part < fParts.end(); part++) { |
| if (closedYet == false) { |
| SkDebugf(">\n"); |
| closedYet = true; |
| } |
| (*part)->dump(maker); |
| } |
| SkDisplayList::fIndent -= 4; |
| if (closedYet) |
| dumpEnd(maker); |
| else |
| SkDebugf("/>\n"); |
| } |
| #endif |
| |
| SkPath& SkDrawPath::getPath() { |
| if (fDirty == false) |
| return fPath; |
| if (d.size() > 0) |
| { |
| parseSVG(); |
| d.reset(); |
| } |
| else |
| { |
| fPath.reset(); |
| for (SkPathPart** part = fParts.begin(); part < fParts.end(); part++) |
| (*part)->add(); |
| } |
| fDirty = false; |
| return fPath; |
| } |
| |
| void SkDrawPath::onEndElement(SkAnimateMaker& ) { |
| if (d.size() > 0) { |
| parseSVG(); |
| d.reset(); |
| fDirty = false; |
| return; |
| } |
| if (fChildHasID == false) { |
| for (SkPathPart** part = fParts.begin(); part < fParts.end(); part++) |
| delete *part; |
| fParts.reset(); |
| fDirty = false; |
| } |
| } |
| |
| bool SkDrawPath::getProperty(int index, SkScriptValue* value) const { |
| switch (index) { |
| case SK_PROPERTY(length): |
| if (SkScalarIsNaN(fLength)) { |
| const SkPath& path = ((SkDrawPath*) this)->getPath(); |
| SkPathMeasure pathMeasure(path, false); |
| fLength = pathMeasure.getLength(); |
| } |
| value->fType = SkType_Float; |
| value->fOperand.fScalar = fLength; |
| break; |
| case SK_PROPERTY(fillType): |
| value->fType = SkType_FillType; |
| value->fOperand.fS32 = (int) fPath.getFillType(); |
| break; |
| default: |
| SkASSERT(0); |
| return false; |
| } |
| return true; |
| } |
| |
| void SkDrawPath::setChildHasID() { |
| fChildHasID = true; |
| } |
| |
| bool SkDrawPath::setParent(SkDisplayable* parent) { |
| fParent = parent; |
| return false; |
| } |
| |
| bool SkDrawPath::setProperty(int index, SkScriptValue& value) |
| { |
| switch (index) { |
| case SK_PROPERTY(fillType): |
| SkASSERT(value.fType == SkType_FillType); |
| SkASSERT(value.fOperand.fS32 >= SkPath::kWinding_FillType && |
| value.fOperand.fS32 <= SkPath::kEvenOdd_FillType); |
| fPath.setFillType((SkPath::FillType) value.fOperand.fS32); |
| break; |
| default: |
| SkASSERT(0); |
| return false; |
| } |
| return true; |
| } |
| |
| #if SK_USE_CONDENSED_INFO == 0 |
| |
| const SkMemberInfo SkPolyline::fInfo[] = { |
| SK_MEMBER_ARRAY(points, Float) |
| }; |
| |
| #endif |
| |
| DEFINE_GET_MEMBER(SkPolyline); |
| |
| bool SkPolyline::add(SkAnimateMaker& , SkDisplayable*) const { |
| return false; |
| } |
| |
| void SkPolyline::onEndElement(SkAnimateMaker& maker) { |
| INHERITED::onEndElement(maker); |
| if (points.count() <= 0) |
| return; |
| fPath.reset(); |
| fPath.moveTo(points[0], points[1]); |
| int count = points.count(); |
| for (int index = 2; index < count; index += 2) |
| fPath.lineTo(points[index], points[index+1]); |
| } |
| |
| |
| #if SK_USE_CONDENSED_INFO == 0 |
| |
| const SkMemberInfo SkPolygon::fInfo[] = { |
| SK_MEMBER_INHERITED |
| }; |
| |
| #endif |
| |
| DEFINE_GET_MEMBER(SkPolygon); |
| |
| void SkPolygon::onEndElement(SkAnimateMaker& maker) { |
| INHERITED::onEndElement(maker); |
| fPath.close(); |
| } |
| |