|
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::addChild(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::addChild(SkAnimateMaker& , SkDisplayable*) { |
|
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 } |