blob: 5f13cb9a8d4db0ebbfa7c1948dae973135fc72ec [file] [log] [blame]
croachrose48ede9b2006-11-08 19:24:48 +00001/* libs/graphics/animator/SkDrawPath.cpp
2**
3** Copyright 2006, Google Inc.
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
croachrose0f87cd82006-09-20 15:47:42 +000018#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
26enum SkPath_Properties {
croachrose48ede9b2006-11-08 19:24:48 +000027 SK_PROPERTY(fillType),
28 SK_PROPERTY(length)
croachrose0f87cd82006-09-20 15:47:42 +000029};
30
31#if SK_USE_CONDENSED_INFO == 0
32
33const SkMemberInfo SkDrawPath::fInfo[] = {
croachrose48ede9b2006-11-08 19:24:48 +000034 SK_MEMBER(d, String),
35 SK_MEMBER_PROPERTY(fillType, FillType),
36 SK_MEMBER_PROPERTY(length, Float)
croachrose0f87cd82006-09-20 15:47:42 +000037};
38
39#endif
40
41DEFINE_GET_MEMBER(SkDrawPath);
42
43SkDrawPath::SkDrawPath()
44{
croachrose48ede9b2006-11-08 19:24:48 +000045 fParent = nil;
46 fLength = SK_ScalarNaN;
47 fChildHasID = false;
48 fDirty = false;
croachrose0f87cd82006-09-20 15:47:42 +000049}
50
51SkDrawPath::~SkDrawPath() {
croachrose48ede9b2006-11-08 19:24:48 +000052 for (SkPathPart** part = fParts.begin(); part < fParts.end(); part++)
53 delete *part;
croachrose0f87cd82006-09-20 15:47:42 +000054}
55
56bool SkDrawPath::add(SkAnimateMaker& maker, SkDisplayable* child) {
croachrose48ede9b2006-11-08 19:24:48 +000057 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;
croachrose0f87cd82006-09-20 15:47:42 +000064}
65
66bool SkDrawPath::childrenNeedDisposing() const {
croachrose48ede9b2006-11-08 19:24:48 +000067 return false;
croachrose0f87cd82006-09-20 15:47:42 +000068}
69
70void SkDrawPath::dirty() {
croachrose48ede9b2006-11-08 19:24:48 +000071 fDirty = true;
72 fLength = SK_ScalarNaN;
73 if (fParent)
74 fParent->dirty();
croachrose0f87cd82006-09-20 15:47:42 +000075}
76
77bool SkDrawPath::draw(SkAnimateMaker& maker) {
croachrose48ede9b2006-11-08 19:24:48 +000078 SkPath& path = getPath();
79 SkBoundableAuto boundable(this, maker);
80 maker.fCanvas->drawPath(path, *maker.fPaint);
81 return false;
croachrose0f87cd82006-09-20 15:47:42 +000082}
83
84SkDisplayable* SkDrawPath::getParent() const {
croachrose48ede9b2006-11-08 19:24:48 +000085 return fParent;
croachrose0f87cd82006-09-20 15:47:42 +000086}
87
88#ifdef SK_DUMP_ENABLED
89void 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
109SkPath& SkDrawPath::getPath() {
croachrose48ede9b2006-11-08 19:24:48 +0000110 if (fDirty == false)
111 return fPath;
croachrose0f87cd82006-09-20 15:47:42 +0000112 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 }
croachrose48ede9b2006-11-08 19:24:48 +0000123 fDirty = false;
124 return fPath;
croachrose0f87cd82006-09-20 15:47:42 +0000125}
croachrose48ede9b2006-11-08 19:24:48 +0000126
croachrose0f87cd82006-09-20 15:47:42 +0000127void SkDrawPath::onEndElement(SkAnimateMaker& ) {
croachrose48ede9b2006-11-08 19:24:48 +0000128 if (d.size() > 0) {
129 parseSVG();
130 d.reset();
croachrose0f87cd82006-09-20 15:47:42 +0000131 fDirty = false;
132 return;
croachrose48ede9b2006-11-08 19:24:48 +0000133 }
134 if (fChildHasID == false) {
135 for (SkPathPart** part = fParts.begin(); part < fParts.end(); part++)
136 delete *part;
137 fParts.reset();
138 fDirty = false;
139 }
croachrose0f87cd82006-09-20 15:47:42 +0000140}
141
142bool SkDrawPath::getProperty(int index, SkScriptValue* value) const {
croachrose48ede9b2006-11-08 19:24:48 +0000143 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;
croachrose0f87cd82006-09-20 15:47:42 +0000153 case SK_PROPERTY(fillType):
154 value->fType = SkType_FillType;
155 value->fOperand.fS32 = (int) fPath.getFillType();
156 break;
croachrose48ede9b2006-11-08 19:24:48 +0000157 default:
158 SkASSERT(0);
159 return false;
160 }
161 return true;
croachrose0f87cd82006-09-20 15:47:42 +0000162}
163
164void SkDrawPath::setChildHasID() {
croachrose48ede9b2006-11-08 19:24:48 +0000165 fChildHasID = true;
croachrose0f87cd82006-09-20 15:47:42 +0000166}
167
168bool SkDrawPath::setParent(SkDisplayable* parent) {
croachrose48ede9b2006-11-08 19:24:48 +0000169 fParent = parent;
170 return false;
croachrose0f87cd82006-09-20 15:47:42 +0000171}
172
173bool SkDrawPath::setProperty(int index, SkScriptValue& value)
174{
croachrose48ede9b2006-11-08 19:24:48 +0000175 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;
croachrose0f87cd82006-09-20 15:47:42 +0000187}
188
189#if SK_USE_CONDENSED_INFO == 0
190
191const SkMemberInfo SkPolyline::fInfo[] = {
croachrose48ede9b2006-11-08 19:24:48 +0000192 SK_MEMBER_ARRAY(points, Float)
croachrose0f87cd82006-09-20 15:47:42 +0000193};
194
195#endif
196
197DEFINE_GET_MEMBER(SkPolyline);
198
199bool SkPolyline::add(SkAnimateMaker& , SkDisplayable*) const {
croachrose48ede9b2006-11-08 19:24:48 +0000200 return false;
croachrose0f87cd82006-09-20 15:47:42 +0000201}
202
203void SkPolyline::onEndElement(SkAnimateMaker& maker) {
croachrose48ede9b2006-11-08 19:24:48 +0000204 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]);
croachrose0f87cd82006-09-20 15:47:42 +0000212}
213
214
215#if SK_USE_CONDENSED_INFO == 0
216
217const SkMemberInfo SkPolygon::fInfo[] = {
croachrose48ede9b2006-11-08 19:24:48 +0000218 SK_MEMBER_INHERITED
croachrose0f87cd82006-09-20 15:47:42 +0000219};
220
221#endif
222
223DEFINE_GET_MEMBER(SkPolygon);
224
225void SkPolygon::onEndElement(SkAnimateMaker& maker) {
croachrose48ede9b2006-11-08 19:24:48 +0000226 INHERITED::onEndElement(maker);
227 fPath.close();
croachrose0f87cd82006-09-20 15:47:42 +0000228}
229