• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
SkDrawPath()43 SkDrawPath::SkDrawPath()
44 {
45     fParent = NULL;
46     fLength = SK_ScalarNaN;
47     fChildHasID = false;
48     fDirty = false;
49 }
50 
~SkDrawPath()51 SkDrawPath::~SkDrawPath() {
52     for (SkPathPart** part = fParts.begin(); part < fParts.end();  part++)
53         delete *part;
54 }
55 
add(SkAnimateMaker & maker,SkDisplayable * child)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 
childrenNeedDisposing() const66 bool SkDrawPath::childrenNeedDisposing() const {
67     return false;
68 }
69 
dirty()70 void SkDrawPath::dirty() {
71     fDirty = true;
72     fLength = SK_ScalarNaN;
73     if (fParent)
74         fParent->dirty();
75 }
76 
draw(SkAnimateMaker & maker)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 
getParent() const84 SkDisplayable* SkDrawPath::getParent() const {
85     return fParent;
86 }
87 
88 #ifdef SK_DUMP_ENABLED
dump(SkAnimateMaker * maker)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 
getPath()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 
onEndElement(SkAnimateMaker &)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 
getProperty(int index,SkScriptValue * value) const142 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 
setChildHasID()164 void SkDrawPath::setChildHasID() {
165     fChildHasID = true;
166 }
167 
setParent(SkDisplayable * parent)168 bool SkDrawPath::setParent(SkDisplayable* parent) {
169     fParent = parent;
170     return false;
171 }
172 
setProperty(int index,SkScriptValue & value)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 
add(SkAnimateMaker &,SkDisplayable *) const199 bool SkPolyline::add(SkAnimateMaker& , SkDisplayable*) const {
200     return false;
201 }
202 
onEndElement(SkAnimateMaker & maker)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 
onEndElement(SkAnimateMaker & maker)225 void SkPolygon::onEndElement(SkAnimateMaker& maker) {
226     INHERITED::onEndElement(maker);
227     fPath.close();
228 }
229 
230