OLD | NEW |
| (Empty) |
1 /* libs/graphics/animator/SkDrawExtraPathEffect.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 "SkDrawExtraPathEffect.h" | |
19 #include "SkDrawPath.h" | |
20 #include "Sk1DPathEffect.h" | |
21 #include "Sk2DPathEffect.h" | |
22 #include "SkMemberInfo.h" | |
23 #include "SkPaintParts.h" | |
24 #include "SkPathEffect.h" | |
25 #include "SkCornerPathEffect.h" | |
26 | |
27 #include "SkDashPathEffect.h" | |
28 | |
29 class SkDrawShapePathEffect : public SkDrawPathEffect { | |
30 DECLARE_PRIVATE_MEMBER_INFO(DrawShapePathEffect); | |
31 SkDrawShapePathEffect(); | |
32 virtual ~SkDrawShapePathEffect(); | |
33 virtual bool add(SkAnimateMaker& , SkDisplayable* ); | |
34 virtual SkPathEffect* getPathEffect(); | |
35 protected: | |
36 SkDrawable* addPath; | |
37 SkDrawable* addMatrix; | |
38 SkDrawPath* path; | |
39 SkPathEffect* fPathEffect; | |
40 friend class SkShape1DPathEffect; | |
41 friend class SkShape2DPathEffect; | |
42 }; | |
43 | |
44 class SkDrawShape1DPathEffect : public SkDrawShapePathEffect { | |
45 DECLARE_EXTRAS_MEMBER_INFO(SkDrawShape1DPathEffect); | |
46 SkDrawShape1DPathEffect(SkDisplayTypes ); | |
47 virtual ~SkDrawShape1DPathEffect(); | |
48 virtual void onEndElement(SkAnimateMaker& ); | |
49 private: | |
50 SkString phase; | |
51 SkString spacing; | |
52 friend class SkShape1DPathEffect; | |
53 typedef SkDrawShapePathEffect INHERITED; | |
54 }; | |
55 | |
56 class SkDrawShape2DPathEffect : public SkDrawShapePathEffect { | |
57 DECLARE_EXTRAS_MEMBER_INFO(SkDrawShape2DPathEffect); | |
58 SkDrawShape2DPathEffect(SkDisplayTypes ); | |
59 virtual ~SkDrawShape2DPathEffect(); | |
60 virtual void onEndElement(SkAnimateMaker& ); | |
61 private: | |
62 SkDrawMatrix* matrix; | |
63 friend class SkShape2DPathEffect; | |
64 typedef SkDrawShapePathEffect INHERITED; | |
65 }; | |
66 | |
67 class SkDrawComposePathEffect : public SkDrawPathEffect { | |
68 DECLARE_EXTRAS_MEMBER_INFO(SkDrawComposePathEffect); | |
69 SkDrawComposePathEffect(SkDisplayTypes ); | |
70 virtual ~SkDrawComposePathEffect(); | |
71 virtual bool add(SkAnimateMaker& , SkDisplayable* ); | |
72 virtual SkPathEffect* getPathEffect(); | |
73 virtual bool isPaint() const; | |
74 private: | |
75 SkDrawPathEffect* effect1; | |
76 SkDrawPathEffect* effect2; | |
77 }; | |
78 | |
79 class SkDrawCornerPathEffect : public SkDrawPathEffect { | |
80 DECLARE_EXTRAS_MEMBER_INFO(SkDrawCornerPathEffect); | |
81 SkDrawCornerPathEffect(SkDisplayTypes ); | |
82 virtual ~SkDrawCornerPathEffect(); | |
83 virtual SkPathEffect* getPathEffect(); | |
84 private: | |
85 SkScalar radius; | |
86 }; | |
87 | |
88 //////////// SkShape1DPathEffect | |
89 | |
90 #include "SkAnimateMaker.h" | |
91 #include "SkAnimatorScript.h" | |
92 #include "SkDisplayApply.h" | |
93 #include "SkDrawMatrix.h" | |
94 #include "SkPaint.h" | |
95 | |
96 class SkShape1DPathEffect : public Sk1DPathEffect { | |
97 public: | |
98 SkShape1DPathEffect(SkDrawShape1DPathEffect* draw, SkAnimateMaker* maker) : | |
99 fDraw(draw), fMaker(maker) { | |
100 } | |
101 | |
102 protected: | |
103 virtual SkScalar begin(SkScalar contourLength) | |
104 { | |
105 SkScriptValue value; | |
106 SkAnimatorScript engine(*fMaker, NULL, SkType_Float); | |
107 engine.propertyCallBack(GetContourLength, &contourLength); | |
108 value.fOperand.fScalar = 0; | |
109 engine.evaluate(fDraw->phase.c_str(), &value, SkType_Float); | |
110 return value.fOperand.fScalar; | |
111 } | |
112 | |
113 virtual SkScalar next(SkPath* dst, SkScalar distance, SkPathMeasure& ) | |
114 { | |
115 fMaker->setExtraPropertyCallBack(fDraw->fType, GetDistance, &distance); | |
116 SkDrawPath* drawPath = NULL; | |
117 if (fDraw->addPath->isPath()) { | |
118 drawPath = (SkDrawPath*) fDraw->addPath; | |
119 } else { | |
120 SkApply* apply = (SkApply*) fDraw->addPath; | |
121 apply->refresh(*fMaker); | |
122 apply->activate(*fMaker); | |
123 apply->interpolate(*fMaker, SkScalarMulRound(distance, 1000)); | |
124 drawPath = (SkDrawPath*) apply->getScope(); | |
125 } | |
126 SkMatrix m; | |
127 m.reset(); | |
128 if (fDraw->addMatrix) { | |
129 SkDrawMatrix* matrix; | |
130 if (fDraw->addMatrix->getType() == SkType_Matrix) | |
131 matrix = (SkDrawMatrix*) fDraw->addMatrix; | |
132 else { | |
133 SkApply* apply = (SkApply*) fDraw->addMatrix; | |
134 apply->refresh(*fMaker); | |
135 apply->activate(*fMaker); | |
136 apply->interpolate(*fMaker, SkScalarMulRound(distance, 1000)); | |
137 matrix = (SkDrawMatrix*) apply->getScope(); | |
138 } | |
139 } | |
140 SkScalar result = 0; | |
141 SkAnimatorScript::EvaluateFloat(*fMaker, NULL, fDraw->spacing.c_str(), &
result); | |
142 if (drawPath) | |
143 dst->addPath(drawPath->getPath(), m); | |
144 fMaker->clearExtraPropertyCallBack(fDraw->fType); | |
145 return result; | |
146 } | |
147 | |
148 private: | |
149 virtual void flatten(SkFlattenableWriteBuffer& ) {} | |
150 virtual Factory getFactory() { return NULL; } | |
151 | |
152 static bool GetContourLength(const char* token, size_t len, void* clen, SkSc
riptValue* value) { | |
153 if (SK_LITERAL_STR_EQUAL("contourLength", token, len)) { | |
154 value->fOperand.fScalar = *(SkScalar*) clen; | |
155 value->fType = SkType_Float; | |
156 return true; | |
157 } | |
158 return false; | |
159 } | |
160 | |
161 static bool GetDistance(const char* token, size_t len, void* dist, SkScriptV
alue* value) { | |
162 if (SK_LITERAL_STR_EQUAL("distance", token, len)) { | |
163 value->fOperand.fScalar = *(SkScalar*) dist; | |
164 value->fType = SkType_Float; | |
165 return true; | |
166 } | |
167 return false; | |
168 } | |
169 | |
170 SkDrawShape1DPathEffect* fDraw; | |
171 SkAnimateMaker* fMaker; | |
172 }; | |
173 | |
174 //////////// SkDrawShapePathEffect | |
175 | |
176 #if SK_USE_CONDENSED_INFO == 0 | |
177 | |
178 const SkMemberInfo SkDrawShapePathEffect::fInfo[] = { | |
179 SK_MEMBER(addMatrix, Drawable), // either matrix or apply | |
180 SK_MEMBER(addPath, Drawable), // either path or apply | |
181 SK_MEMBER(path, Path), | |
182 }; | |
183 | |
184 #endif | |
185 | |
186 DEFINE_GET_MEMBER(SkDrawShapePathEffect); | |
187 | |
188 SkDrawShapePathEffect::SkDrawShapePathEffect() : | |
189 addPath(NULL), addMatrix(NULL), path(NULL), fPathEffect(NULL) { | |
190 } | |
191 | |
192 SkDrawShapePathEffect::~SkDrawShapePathEffect() { | |
193 fPathEffect->safeUnref(); | |
194 } | |
195 | |
196 bool SkDrawShapePathEffect::add(SkAnimateMaker& , SkDisplayable* child) { | |
197 path = (SkDrawPath*) child; | |
198 return true; | |
199 } | |
200 | |
201 SkPathEffect* SkDrawShapePathEffect::getPathEffect() { | |
202 fPathEffect->ref(); | |
203 return fPathEffect; | |
204 } | |
205 | |
206 //////////// SkDrawShape1DPathEffect | |
207 | |
208 #if SK_USE_CONDENSED_INFO == 0 | |
209 | |
210 const SkMemberInfo SkDrawShape1DPathEffect::fInfo[] = { | |
211 SK_MEMBER_INHERITED, | |
212 SK_MEMBER(phase, String), | |
213 SK_MEMBER(spacing, String), | |
214 }; | |
215 | |
216 #endif | |
217 | |
218 DEFINE_GET_MEMBER(SkDrawShape1DPathEffect); | |
219 | |
220 SkDrawShape1DPathEffect::SkDrawShape1DPathEffect(SkDisplayTypes type) : fType(ty
pe) { | |
221 } | |
222 | |
223 SkDrawShape1DPathEffect::~SkDrawShape1DPathEffect() { | |
224 } | |
225 | |
226 void SkDrawShape1DPathEffect::onEndElement(SkAnimateMaker& maker) { | |
227 if (addPath == NULL || (addPath->isPath() == false && addPath->isApply() ==
false)) | |
228 maker.setErrorCode(SkDisplayXMLParserError::kUnknownError); // !!! add e
rror | |
229 else | |
230 fPathEffect = new SkShape1DPathEffect(this, &maker); | |
231 } | |
232 | |
233 ////////// SkShape2DPathEffect | |
234 | |
235 class SkShape2DPathEffect : public Sk2DPathEffect { | |
236 public: | |
237 SkShape2DPathEffect(SkDrawShape2DPathEffect* draw, SkAnimateMaker* maker, | |
238 const SkMatrix& matrix) : Sk2DPathEffect(matrix), fDraw(draw), fMaker(ma
ker) { | |
239 } | |
240 | |
241 protected: | |
242 virtual void begin(const SkIRect& uvBounds, SkPath* ) | |
243 { | |
244 fUVBounds.set(SkIntToScalar(uvBounds.fLeft), SkIntToScalar(uvBounds.fTop
), | |
245 SkIntToScalar(uvBounds.fRight), SkIntToScalar(uvBounds.fBottom)); | |
246 } | |
247 | |
248 virtual void next(const SkPoint& loc, int u, int v, SkPath* dst) | |
249 { | |
250 fLoc = loc; | |
251 fU = u; | |
252 fV = v; | |
253 SkDrawPath* drawPath; | |
254 fMaker->setExtraPropertyCallBack(fDraw->fType, Get2D, this); | |
255 if (fDraw->addPath->isPath()) { | |
256 drawPath = (SkDrawPath*) fDraw->addPath; | |
257 } else { | |
258 SkApply* apply = (SkApply*) fDraw->addPath; | |
259 apply->refresh(*fMaker); | |
260 apply->activate(*fMaker); | |
261 apply->interpolate(*fMaker, v); | |
262 drawPath = (SkDrawPath*) apply->getScope(); | |
263 } | |
264 if (drawPath == NULL) | |
265 goto clearCallBack; | |
266 if (fDraw->matrix) { | |
267 SkDrawMatrix* matrix; | |
268 if (fDraw->matrix->getType() == SkType_Matrix) | |
269 matrix = (SkDrawMatrix*) fDraw->matrix; | |
270 else { | |
271 SkApply* apply = (SkApply*) fDraw->matrix; | |
272 apply->activate(*fMaker); | |
273 apply->interpolate(*fMaker, v); | |
274 matrix = (SkDrawMatrix*) apply->getScope(); | |
275 } | |
276 if (matrix) { | |
277 dst->addPath(drawPath->getPath(), matrix->getMatrix()); | |
278 goto clearCallBack; | |
279 } | |
280 } | |
281 dst->addPath(drawPath->getPath()); | |
282 clearCallBack: | |
283 fMaker->clearExtraPropertyCallBack(fDraw->fType); | |
284 } | |
285 | |
286 private: | |
287 | |
288 static bool Get2D(const char* token, size_t len, void* s2D, SkScriptValue* v
alue) { | |
289 static const char match[] = "locX|locY|left|top|right|bottom|u|v" ; | |
290 SkShape2DPathEffect* shape2D = (SkShape2DPathEffect*) s2D; | |
291 int index; | |
292 if (SkAnimatorScript::MapEnums(match, token, len, &index) == false) | |
293 return false; | |
294 SkASSERT((sizeof(SkPoint) + sizeof(SkRect)) / sizeof(SkScalar) == 6)
; | |
295 if (index < 6) { | |
296 value->fType = SkType_Float; | |
297 value->fOperand.fScalar = (&shape2D->fLoc.fX)[index]; | |
298 } else { | |
299 value->fType = SkType_Int; | |
300 value->fOperand.fS32 = (&shape2D->fU)[index - 6]; | |
301 } | |
302 return true; | |
303 } | |
304 | |
305 SkPoint fLoc; | |
306 SkRect fUVBounds; | |
307 int32_t fU; | |
308 int32_t fV; | |
309 SkDrawShape2DPathEffect* fDraw; | |
310 SkAnimateMaker* fMaker; | |
311 | |
312 // illegal | |
313 SkShape2DPathEffect(const SkShape2DPathEffect&); | |
314 SkShape2DPathEffect& operator=(const SkShape2DPathEffect&); | |
315 }; | |
316 | |
317 ////////// SkDrawShape2DPathEffect | |
318 | |
319 #if SK_USE_CONDENSED_INFO == 0 | |
320 | |
321 const SkMemberInfo SkDrawShape2DPathEffect::fInfo[] = { | |
322 SK_MEMBER_INHERITED, | |
323 SK_MEMBER(matrix, Matrix) | |
324 }; | |
325 | |
326 #endif | |
327 | |
328 DEFINE_GET_MEMBER(SkDrawShape2DPathEffect); | |
329 | |
330 SkDrawShape2DPathEffect::SkDrawShape2DPathEffect(SkDisplayTypes type) : fType(ty
pe) { | |
331 } | |
332 | |
333 SkDrawShape2DPathEffect::~SkDrawShape2DPathEffect() { | |
334 } | |
335 | |
336 void SkDrawShape2DPathEffect::onEndElement(SkAnimateMaker& maker) { | |
337 if (addPath == NULL || (addPath->isPath() == false && addPath->isApply() ==
false) || | |
338 matrix == NULL) | |
339 maker.setErrorCode(SkDisplayXMLParserError::kUnknownError); // !!! add e
rror | |
340 else | |
341 fPathEffect = new SkShape2DPathEffect(this, &maker, matrix->getMatrix())
; | |
342 } | |
343 | |
344 ////////// SkDrawComposePathEffect | |
345 | |
346 #if SK_USE_CONDENSED_INFO == 0 | |
347 | |
348 const SkMemberInfo SkDrawComposePathEffect::fInfo[] = { | |
349 SK_MEMBER(effect1, PathEffect), | |
350 SK_MEMBER(effect2, PathEffect) | |
351 }; | |
352 | |
353 #endif | |
354 | |
355 DEFINE_GET_MEMBER(SkDrawComposePathEffect); | |
356 | |
357 SkDrawComposePathEffect::SkDrawComposePathEffect(SkDisplayTypes type) : fType(ty
pe), | |
358 effect1(NULL), effect2(NULL) { | |
359 } | |
360 | |
361 SkDrawComposePathEffect::~SkDrawComposePathEffect() { | |
362 delete effect1; | |
363 delete effect2; | |
364 } | |
365 | |
366 bool SkDrawComposePathEffect::add(SkAnimateMaker& , SkDisplayable* child) { | |
367 if (effect1 == NULL) | |
368 effect1 = (SkDrawPathEffect*) child; | |
369 else | |
370 effect2 = (SkDrawPathEffect*) child; | |
371 return true; | |
372 } | |
373 | |
374 SkPathEffect* SkDrawComposePathEffect::getPathEffect() { | |
375 SkPathEffect* e1 = effect1->getPathEffect(); | |
376 SkPathEffect* e2 = effect2->getPathEffect(); | |
377 SkPathEffect* composite = new SkComposePathEffect(e1, e2); | |
378 e1->unref(); | |
379 e2->unref(); | |
380 return composite; | |
381 } | |
382 | |
383 bool SkDrawComposePathEffect::isPaint() const { | |
384 return true; | |
385 } | |
386 | |
387 //////////// SkDrawCornerPathEffect | |
388 | |
389 #if SK_USE_CONDENSED_INFO == 0 | |
390 | |
391 const SkMemberInfo SkDrawCornerPathEffect::fInfo[] = { | |
392 SK_MEMBER(radius, Float) | |
393 }; | |
394 | |
395 #endif | |
396 | |
397 DEFINE_GET_MEMBER(SkDrawCornerPathEffect); | |
398 | |
399 SkDrawCornerPathEffect::SkDrawCornerPathEffect(SkDisplayTypes type): | |
400 fType(type), radius(0) { | |
401 } | |
402 | |
403 SkDrawCornerPathEffect::~SkDrawCornerPathEffect() { | |
404 } | |
405 | |
406 SkPathEffect* SkDrawCornerPathEffect::getPathEffect() { | |
407 return new SkCornerPathEffect(radius); | |
408 } | |
409 | |
410 ///////// | |
411 | |
412 #include "SkExtras.h" | |
413 | |
414 const char kDrawShape1DPathEffectName[] = "pathEffect:shape1D"; | |
415 const char kDrawShape2DPathEffectName[] = "pathEffect:shape2D"; | |
416 const char kDrawComposePathEffectName[] = "pathEffect:compose"; | |
417 const char kDrawCornerPathEffectName[] = "pathEffect:corner"; | |
418 | |
419 class SkExtraPathEffects : public SkExtras { | |
420 public: | |
421 SkExtraPathEffects(SkAnimator* animator) : | |
422 skDrawShape1DPathEffectType(SkType_Unknown), | |
423 skDrawShape2DPathEffectType(SkType_Unknown), | |
424 skDrawComposePathEffectType(SkType_Unknown), | |
425 skDrawCornerPathEffectType(SkType_Unknown) { | |
426 } | |
427 | |
428 virtual SkDisplayable* createInstance(SkDisplayTypes type) { | |
429 SkDisplayable* result = NULL; | |
430 if (skDrawShape1DPathEffectType == type) | |
431 result = new SkDrawShape1DPathEffect(type); | |
432 else if (skDrawShape2DPathEffectType == type) | |
433 result = new SkDrawShape2DPathEffect(type); | |
434 else if (skDrawComposePathEffectType == type) | |
435 result = new SkDrawComposePathEffect(type); | |
436 else if (skDrawCornerPathEffectType == type) | |
437 result = new SkDrawCornerPathEffect(type); | |
438 return result; | |
439 } | |
440 | |
441 virtual bool definesType(SkDisplayTypes type) { | |
442 return type == skDrawShape1DPathEffectType || | |
443 type == skDrawShape2DPathEffectType || | |
444 type == skDrawComposePathEffectType || | |
445 type == skDrawCornerPathEffectType; | |
446 } | |
447 | |
448 #if SK_USE_CONDENSED_INFO == 0 | |
449 virtual const SkMemberInfo* getMembers(SkDisplayTypes type, int* infoCountPt
r) { | |
450 const SkMemberInfo* info = NULL; | |
451 int infoCount = 0; | |
452 if (skDrawShape1DPathEffectType == type) { | |
453 info = SkDrawShape1DPathEffect::fInfo; | |
454 infoCount = SkDrawShape1DPathEffect::fInfoCount; | |
455 } else if (skDrawShape2DPathEffectType == type) { | |
456 info = SkDrawShape2DPathEffect::fInfo; | |
457 infoCount = SkDrawShape2DPathEffect::fInfoCount; | |
458 } else if (skDrawComposePathEffectType == type) { | |
459 info = SkDrawComposePathEffect::fInfo; | |
460 infoCount = SkDrawShape1DPathEffect::fInfoCount; | |
461 } else if (skDrawCornerPathEffectType == type) { | |
462 info = SkDrawCornerPathEffect::fInfo; | |
463 infoCount = SkDrawCornerPathEffect::fInfoCount; | |
464 } | |
465 if (infoCountPtr) | |
466 *infoCountPtr = infoCount; | |
467 return info; | |
468 } | |
469 #endif | |
470 | |
471 #ifdef SK_DEBUG | |
472 virtual const char* getName(SkDisplayTypes type) { | |
473 if (skDrawShape1DPathEffectType == type) | |
474 return kDrawShape1DPathEffectName; | |
475 else if (skDrawShape2DPathEffectType == type) | |
476 return kDrawShape2DPathEffectName; | |
477 else if (skDrawComposePathEffectType == type) | |
478 return kDrawComposePathEffectName; | |
479 else if (skDrawCornerPathEffectType == type) | |
480 return kDrawCornerPathEffectName; | |
481 return NULL; | |
482 } | |
483 #endif | |
484 | |
485 virtual SkDisplayTypes getType(const char name[], size_t len ) { | |
486 SkDisplayTypes* type = NULL; | |
487 if (SK_LITERAL_STR_EQUAL(kDrawShape1DPathEffectName, name, len)) | |
488 type = &skDrawShape1DPathEffectType; | |
489 else if (SK_LITERAL_STR_EQUAL(kDrawShape2DPathEffectName, name, len)) | |
490 type = &skDrawShape2DPathEffectType; | |
491 else if (SK_LITERAL_STR_EQUAL(kDrawComposePathEffectName, name, len)) | |
492 type = &skDrawComposePathEffectType; | |
493 else if (SK_LITERAL_STR_EQUAL(kDrawCornerPathEffectName, name, len)) | |
494 type = &skDrawCornerPathEffectType; | |
495 if (type) { | |
496 if (*type == SkType_Unknown) | |
497 *type = SkDisplayType::RegisterNewType(); | |
498 return *type; | |
499 } | |
500 return SkType_Unknown; | |
501 } | |
502 | |
503 private: | |
504 SkDisplayTypes skDrawShape1DPathEffectType; | |
505 SkDisplayTypes skDrawShape2DPathEffectType; | |
506 SkDisplayTypes skDrawComposePathEffectType; | |
507 SkDisplayTypes skDrawCornerPathEffectType; | |
508 }; | |
509 | |
510 | |
511 void InitializeSkExtraPathEffects(SkAnimator* animator) { | |
512 animator->addExtras(new SkExtraPathEffects(animator)); | |
513 } | |
514 | |
515 //////////////// | |
516 | |
517 | |
518 SkExtras::SkExtras() : fExtraCallBack(NULL), fExtraStorage(NULL) { | |
519 } | |
OLD | NEW |