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 "SkDisplayType.h"
11 #include "SkAnimateMaker.h"
12 #include "SkAnimateSet.h"
13 #include "SkDisplayAdd.h"
14 #include "SkDisplayApply.h"
15 #include "SkDisplayBounds.h"
16 #include "SkDisplayEvent.h"
17 #include "SkDisplayInclude.h"
18 #ifdef SK_DEBUG
19 #include "SkDisplayList.h"
20 #endif
21 #include "SkDisplayMath.h"
22 #include "SkDisplayMovie.h"
23 #include "SkDisplayNumber.h"
24 #include "SkDisplayPost.h"
25 #include "SkDisplayRandom.h"
26 #include "SkDisplayTypes.h"
27 #include "SkDraw3D.h"
28 #include "SkDrawBitmap.h"
29 #include "SkDrawClip.h"
30 #include "SkDrawDash.h"
31 #include "SkDrawDiscrete.h"
32 #include "SkDrawEmboss.h"
33 #include "SkDrawFull.h"
34 #include "SkDrawGradient.h"
35 #include "SkDrawLine.h"
36 #include "SkDrawMatrix.h"
37 #include "SkDrawOval.h"
38 #include "SkDrawPaint.h"
39 #include "SkDrawPath.h"
40 #include "SkDrawPoint.h"
41 #include "SkDrawSaveLayer.h"
42 #include "SkDrawText.h"
43 #include "SkDrawTextBox.h"
44 #include "SkDrawTo.h"
45 #include "SkDrawTransparentShader.h"
46 #include "SkDump.h"
47 #include "SkExtras.h"
48 #include "SkHitClear.h"
49 #include "SkHitTest.h"
50 #include "SkMatrixParts.h"
51 #include "SkPathParts.h"
52 #include "SkPostParts.h"
53 #include "SkSnapshot.h"
54 #include "SkTextOnPath.h"
55 #include "SkTextToPath.h"
56 #include "SkTSearch.h"
57 
58 #define CASE_NEW(_class) \
59     case SkType_##_class: result = new Sk##_class(); break
60 #define CASE_DRAW_NEW(_class) \
61     case SkType_##_class: result = new SkDraw##_class(); break
62 #define CASE_DISPLAY_NEW(_class) \
63     case SkType_##_class: result = new SkDisplay##_class(); break
64 #ifdef SK_DEBUG
65     #define CASE_DEBUG_RETURN_NIL(_class) \
66         case SkType_##_class: return NULL
67 #else
68     #define CASE_DEBUG_RETURN_NIL(_class)
69 #endif
70 
71 
72 SkDisplayTypes SkDisplayType::gNewTypes = kNumberOfTypes;
73 
CreateInstance(SkAnimateMaker * maker,SkDisplayTypes type)74 SkDisplayable* SkDisplayType::CreateInstance(SkAnimateMaker* maker, SkDisplayTypes type) {
75     SkDisplayable* result = NULL;
76     switch (type) {
77         // unknown
78         CASE_DISPLAY_NEW(Math);
79         CASE_DISPLAY_NEW(Number);
80         CASE_NEW(Add);
81         CASE_NEW(AddCircle);
82         // addgeom
83         CASE_DEBUG_RETURN_NIL(AddMode);
84         CASE_NEW(AddOval);
85         CASE_NEW(AddPath);
86         CASE_NEW(AddRect);
87         CASE_NEW(AddRoundRect);
88         CASE_DEBUG_RETURN_NIL(Align);
89         CASE_NEW(Animate);
90         // animatebase
91         CASE_NEW(Apply);
92         CASE_DEBUG_RETURN_NIL(ApplyMode);
93         CASE_DEBUG_RETURN_NIL(ApplyTransition);
94         CASE_DISPLAY_NEW(Array);
95         // argb
96         // base64
97         // basebitmap
98         // baseclassinfo
99         CASE_DRAW_NEW(Bitmap);
100         // bitmapencoding
101         // bitmapformat
102         CASE_DRAW_NEW(BitmapShader);
103         CASE_DRAW_NEW(Blur);
104         CASE_DISPLAY_NEW(Boolean);
105         // boundable
106         CASE_DISPLAY_NEW(Bounds);
107         CASE_DEBUG_RETURN_NIL(Cap);
108         CASE_NEW(Clear);
109         CASE_DRAW_NEW(Clip);
110         CASE_NEW(Close);
111         CASE_DRAW_NEW(Color);
112         CASE_NEW(CubicTo);
113         CASE_NEW(Dash);
114         CASE_NEW(DataInput);
115         CASE_NEW(Discrete);
116         // displayable
117         // drawable
118         CASE_NEW(DrawTo);
119         CASE_NEW(Dump);
120         // dynamicstring
121         CASE_DRAW_NEW(Emboss);
122         CASE_DISPLAY_NEW(Event);
123         CASE_DEBUG_RETURN_NIL(EventCode);
124         CASE_DEBUG_RETURN_NIL(EventKind);
125         CASE_DEBUG_RETURN_NIL(EventMode);
126         // filltype
127         // filtertype
128         CASE_DISPLAY_NEW(Float);
129         CASE_NEW(FromPath);
130         CASE_DEBUG_RETURN_NIL(FromPathMode);
131         CASE_NEW(Full);
132         // gradient
133         CASE_NEW(Group);
134         CASE_NEW(HitClear);
135         CASE_NEW(HitTest);
136         CASE_NEW(ImageBaseBitmap);
137         CASE_NEW(Include);
138         CASE_NEW(Input);
139         CASE_DISPLAY_NEW(Int);
140         CASE_DEBUG_RETURN_NIL(Join);
141         CASE_NEW(Line);
142         CASE_NEW(LineTo);
143         CASE_NEW(DrawLinearGradient);
144         CASE_DRAW_NEW(MaskFilter);
145         CASE_DEBUG_RETURN_NIL(MaskFilterBlurStyle);
146         // maskfilterlight
147         CASE_DRAW_NEW(Matrix);
148         // memberfunction
149         // memberproperty
150         CASE_NEW(Move);
151         CASE_NEW(MoveTo);
152         CASE_DISPLAY_NEW(Movie);
153         // msec
154         CASE_NEW(Oval);
155         CASE_DRAW_NEW(Paint);
156         CASE_DRAW_NEW(Path);
157         // pathdirection
158         CASE_DRAW_NEW(PathEffect);
159         // point
160         CASE_NEW(DrawPoint);
161         CASE_NEW(PolyToPoly);
162         CASE_NEW(Polygon);
163         CASE_NEW(Polyline);
164         CASE_NEW(Post);
165         CASE_NEW(QuadTo);
166         CASE_NEW(RCubicTo);
167         CASE_NEW(RLineTo);
168         CASE_NEW(RMoveTo);
169         CASE_NEW(RQuadTo);
170         CASE_NEW(DrawRadialGradient);
171         CASE_DISPLAY_NEW(Random);
172         CASE_DRAW_NEW(Rect);
173         CASE_NEW(RectToRect);
174         CASE_NEW(Remove);
175         CASE_NEW(Replace);
176         CASE_NEW(Rotate);
177         CASE_NEW(RoundRect);
178         CASE_NEW(Save);
179         CASE_NEW(SaveLayer);
180         CASE_NEW(Scale);
181         // screenplay
182         CASE_NEW(Set);
183         CASE_DRAW_NEW(Shader);
184         CASE_NEW(Skew);
185         CASE_NEW(3D_Camera);
186         CASE_NEW(3D_Patch);
187         // 3dpoint
188         CASE_NEW(Snapshot);
189         CASE_DISPLAY_NEW(String);
190         // style
191         CASE_NEW(Text);
192         CASE_DRAW_NEW(TextBox);
193         // textboxalign
194         // textboxmode
195         CASE_NEW(TextOnPath);
196         CASE_NEW(TextToPath);
197         CASE_DEBUG_RETURN_NIL(TileMode);
198         CASE_NEW(Translate);
199         CASE_DRAW_NEW(TransparentShader);
200         CASE_DRAW_NEW(Typeface);
201         CASE_DEBUG_RETURN_NIL(Xfermode);
202         default:
203             SkExtras** end = maker->fExtras.end();
204             for (SkExtras** extraPtr = maker->fExtras.begin(); extraPtr < end; extraPtr++) {
205                 if ((result = (*extraPtr)->createInstance(type)) != NULL)
206                     return result;
207             }
208             SkASSERT(0);
209     }
210     return result;
211 }
212 
213 #undef CASE_NEW
214 #undef CASE_DRAW_NEW
215 #undef CASE_DISPLAY_NEW
216 
217 #if SK_USE_CONDENSED_INFO == 0
218 
219 #define CASE_GET_INFO(_class) case SkType_##_class: \
220     info = Sk##_class::fInfo; infoCount = Sk##_class::fInfoCount; break
221 #define CASE_GET_DRAW_INFO(_class) case SkType_##_class: \
222     info = SkDraw##_class::fInfo; infoCount = SkDraw##_class::fInfoCount; break
223 #define CASE_GET_DISPLAY_INFO(_class) case SkType_##_class: \
224     info = SkDisplay##_class::fInfo; infoCount = SkDisplay##_class::fInfoCount; \
225     break
226 
GetMembers(SkAnimateMaker * maker,SkDisplayTypes type,int * infoCountPtr)227 const SkMemberInfo* SkDisplayType::GetMembers(SkAnimateMaker* maker,
228         SkDisplayTypes type, int* infoCountPtr) {
229     const SkMemberInfo* info = NULL;
230     int infoCount = 0;
231     switch (type) {
232         // unknown
233         CASE_GET_DISPLAY_INFO(Math);
234         CASE_GET_DISPLAY_INFO(Number);
235         CASE_GET_INFO(Add);
236         CASE_GET_INFO(AddCircle);
237         CASE_GET_INFO(AddGeom);
238         // addmode
239         CASE_GET_INFO(AddOval);
240         CASE_GET_INFO(AddPath);
241         CASE_GET_INFO(AddRect);
242         CASE_GET_INFO(AddRoundRect);
243         // align
244         CASE_GET_INFO(Animate);
245         CASE_GET_INFO(AnimateBase);
246         CASE_GET_INFO(Apply);
247         // applymode
248         // applytransition
249         CASE_GET_DISPLAY_INFO(Array);
250         // argb
251         // base64
252         CASE_GET_INFO(BaseBitmap);
253         // baseclassinfo
254         CASE_GET_DRAW_INFO(Bitmap);
255         // bitmapencoding
256         // bitmapformat
257         CASE_GET_DRAW_INFO(BitmapShader);
258         CASE_GET_DRAW_INFO(Blur);
259         CASE_GET_DISPLAY_INFO(Boolean);
260         // boundable
261         CASE_GET_DISPLAY_INFO(Bounds);
262         // cap
263         // clear
264         CASE_GET_DRAW_INFO(Clip);
265         // close
266         CASE_GET_DRAW_INFO(Color);
267         CASE_GET_INFO(CubicTo);
268         CASE_GET_INFO(Dash);
269         CASE_GET_INFO(DataInput);
270         CASE_GET_INFO(Discrete);
271         // displayable
272         // drawable
273         CASE_GET_INFO(DrawTo);
274         CASE_GET_INFO(Dump);
275         // dynamicstring
276         CASE_GET_DRAW_INFO(Emboss);
277         CASE_GET_DISPLAY_INFO(Event);
278         // eventcode
279         // eventkind
280         // eventmode
281         // filltype
282         // filtertype
283         CASE_GET_DISPLAY_INFO(Float);
284         CASE_GET_INFO(FromPath);
285         // frompathmode
286         // full
287         CASE_GET_INFO(DrawGradient);
288         CASE_GET_INFO(Group);
289         CASE_GET_INFO(HitClear);
290         CASE_GET_INFO(HitTest);
291         CASE_GET_INFO(ImageBaseBitmap);
292         CASE_GET_INFO(Include);
293         CASE_GET_INFO(Input);
294         CASE_GET_DISPLAY_INFO(Int);
295         // join
296         CASE_GET_INFO(Line);
297         CASE_GET_INFO(LineTo);
298         CASE_GET_INFO(DrawLinearGradient);
299         // maskfilter
300         // maskfilterblurstyle
301         // maskfilterlight
302         CASE_GET_DRAW_INFO(Matrix);
303         // memberfunction
304         // memberproperty
305         CASE_GET_INFO(Move);
306         CASE_GET_INFO(MoveTo);
307         CASE_GET_DISPLAY_INFO(Movie);
308         // msec
309         CASE_GET_INFO(Oval);
310         CASE_GET_DRAW_INFO(Path);
311         CASE_GET_DRAW_INFO(Paint);
312         // pathdirection
313         // patheffect
314         case SkType_Point: info = Sk_Point::fInfo; infoCount = Sk_Point::fInfoCount; break; // no virtual flavor
315         CASE_GET_INFO(DrawPoint); // virtual flavor
316         CASE_GET_INFO(PolyToPoly);
317         CASE_GET_INFO(Polygon);
318         CASE_GET_INFO(Polyline);
319         CASE_GET_INFO(Post);
320         CASE_GET_INFO(QuadTo);
321         CASE_GET_INFO(RCubicTo);
322         CASE_GET_INFO(RLineTo);
323         CASE_GET_INFO(RMoveTo);
324         CASE_GET_INFO(RQuadTo);
325         CASE_GET_INFO(DrawRadialGradient);
326         CASE_GET_DISPLAY_INFO(Random);
327         CASE_GET_DRAW_INFO(Rect);
328         CASE_GET_INFO(RectToRect);
329         CASE_GET_INFO(Remove);
330         CASE_GET_INFO(Replace);
331         CASE_GET_INFO(Rotate);
332         CASE_GET_INFO(RoundRect);
333         CASE_GET_INFO(Save);
334         CASE_GET_INFO(SaveLayer);
335         CASE_GET_INFO(Scale);
336         // screenplay
337         CASE_GET_INFO(Set);
338         CASE_GET_DRAW_INFO(Shader);
339         CASE_GET_INFO(Skew);
340         CASE_GET_INFO(3D_Camera);
341         CASE_GET_INFO(3D_Patch);
342         CASE_GET_INFO(3D_Point);
343         CASE_GET_INFO(Snapshot);
344         CASE_GET_DISPLAY_INFO(String);
345         // style
346         CASE_GET_INFO(Text);
347         CASE_GET_DRAW_INFO(TextBox);
348         // textboxalign
349         // textboxmode
350         CASE_GET_INFO(TextOnPath);
351         CASE_GET_INFO(TextToPath);
352         // tilemode
353         CASE_GET_INFO(Translate);
354         // transparentshader
355         CASE_GET_DRAW_INFO(Typeface);
356         // xfermode
357         // knumberoftypes
358         default:
359             if (maker) {
360                 SkExtras** end = maker->fExtras.end();
361                 for (SkExtras** extraPtr = maker->fExtras.begin(); extraPtr < end; extraPtr++) {
362                     if ((info = (*extraPtr)->getMembers(type, infoCountPtr)) != NULL)
363                         return info;
364                 }
365             }
366             return NULL;
367     }
368     if (infoCountPtr)
369         *infoCountPtr = infoCount;
370     return info;
371 }
372 
GetMember(SkAnimateMaker * maker,SkDisplayTypes type,const char ** matchPtr)373 const SkMemberInfo* SkDisplayType::GetMember(SkAnimateMaker* maker,
374         SkDisplayTypes type, const char** matchPtr ) {
375     int infoCount = 0;  // Initialize to remove a warning.
376     const SkMemberInfo* info = GetMembers(maker, type, &infoCount);
377     info = SkMemberInfo::Find(info, infoCount, matchPtr);
378 //  SkASSERT(info);
379     return info;
380 }
381 
382 #undef CASE_GET_INFO
383 #undef CASE_GET_DRAW_INFO
384 #undef CASE_GET_DISPLAY_INFO
385 
386 #endif // SK_USE_CONDENSED_INFO == 0
387 
388 #if defined SK_DEBUG || defined SK_BUILD_CONDENSED
389     #define DRAW_NAME(_name, _type) {_name, _type, true, false }
390     #define DISPLAY_NAME(_name, _type) {_name, _type, false, true }
391     #define INIT_BOOL_FIELDS    , false, false
392 #else
393     #define DRAW_NAME(_name, _type) {_name, _type }
394     #define DISPLAY_NAME(_name, _type) {_name, _type }
395     #define INIT_BOOL_FIELDS
396 #endif
397 
398 const TypeNames gTypeNames[] = {
399     // unknown
400     { "Math", SkType_Math                       INIT_BOOL_FIELDS },
401     { "Number", SkType_Number                   INIT_BOOL_FIELDS },
402     { "add", SkType_Add                         INIT_BOOL_FIELDS },
403     { "addCircle", SkType_AddCircle             INIT_BOOL_FIELDS },
404     // addgeom
405     // addmode
406     { "addOval", SkType_AddOval                 INIT_BOOL_FIELDS },
407     { "addPath", SkType_AddPath                 INIT_BOOL_FIELDS },
408     { "addRect", SkType_AddRect                 INIT_BOOL_FIELDS },
409     { "addRoundRect", SkType_AddRoundRect       INIT_BOOL_FIELDS },
410     // align
411     { "animate", SkType_Animate                 INIT_BOOL_FIELDS },
412     // animateBase
413     { "apply", SkType_Apply                     INIT_BOOL_FIELDS },
414     // applymode
415     // applytransition
416     { "array", SkType_Array                     INIT_BOOL_FIELDS },
417     // argb
418     // base64
419     // basebitmap
420     // baseclassinfo
421     DRAW_NAME("bitmap", SkType_Bitmap),
422     // bitmapencoding
423     // bitmapformat
424     DRAW_NAME("bitmapShader", SkType_BitmapShader),
425     DRAW_NAME("blur", SkType_Blur),
426     { "boolean", SkType_Boolean                 INIT_BOOL_FIELDS },
427     // boundable
428     DISPLAY_NAME("bounds", SkType_Bounds),
429     // cap
430     { "clear", SkType_Clear                     INIT_BOOL_FIELDS },
431     DRAW_NAME("clip", SkType_Clip),
432     { "close", SkType_Close                     INIT_BOOL_FIELDS },
433     DRAW_NAME("color", SkType_Color),
434     { "cubicTo", SkType_CubicTo                 INIT_BOOL_FIELDS },
435     { "dash", SkType_Dash                       INIT_BOOL_FIELDS },
436     { "data", SkType_DataInput                  INIT_BOOL_FIELDS },
437     { "discrete", SkType_Discrete               INIT_BOOL_FIELDS },
438     // displayable
439     // drawable
440     { "drawTo", SkType_DrawTo                   INIT_BOOL_FIELDS },
441     { "dump", SkType_Dump                       INIT_BOOL_FIELDS },
442     // dynamicstring
443     DRAW_NAME("emboss", SkType_Emboss),
444     DISPLAY_NAME("event", SkType_Event),
445     // eventcode
446     // eventkind
447     // eventmode
448     // filltype
449     // filtertype
450     { "float", SkType_Float                     INIT_BOOL_FIELDS },
451     { "fromPath", SkType_FromPath               INIT_BOOL_FIELDS },
452     // frompathmode
453     { "full", SkType_Full                       INIT_BOOL_FIELDS },
454     // gradient
455     { "group", SkType_Group                     INIT_BOOL_FIELDS },
456     { "hitClear", SkType_HitClear               INIT_BOOL_FIELDS },
457     { "hitTest", SkType_HitTest                 INIT_BOOL_FIELDS },
458     { "image", SkType_ImageBaseBitmap           INIT_BOOL_FIELDS },
459     { "include", SkType_Include                 INIT_BOOL_FIELDS },
460     { "input", SkType_Input                     INIT_BOOL_FIELDS },
461     { "int", SkType_Int                         INIT_BOOL_FIELDS },
462     // join
463     { "line", SkType_Line                       INIT_BOOL_FIELDS },
464     { "lineTo", SkType_LineTo                   INIT_BOOL_FIELDS },
465     { "linearGradient", SkType_DrawLinearGradient   INIT_BOOL_FIELDS },
466     { "maskFilter", SkType_MaskFilter           INIT_BOOL_FIELDS },
467     // maskfilterblurstyle
468     // maskfilterlight
469     DRAW_NAME("matrix", SkType_Matrix),
470     // memberfunction
471     // memberproperty
472     { "move", SkType_Move                       INIT_BOOL_FIELDS },
473     { "moveTo", SkType_MoveTo                   INIT_BOOL_FIELDS },
474     { "movie", SkType_Movie                     INIT_BOOL_FIELDS },
475     // msec
476     { "oval", SkType_Oval                       INIT_BOOL_FIELDS },
477     DRAW_NAME("paint", SkType_Paint),
478     DRAW_NAME("path", SkType_Path),
479     // pathdirection
480     { "pathEffect", SkType_PathEffect           INIT_BOOL_FIELDS },
481     // point
482     DRAW_NAME("point", SkType_DrawPoint),
483     { "polyToPoly", SkType_PolyToPoly           INIT_BOOL_FIELDS },
484     { "polygon", SkType_Polygon                 INIT_BOOL_FIELDS },
485     { "polyline", SkType_Polyline               INIT_BOOL_FIELDS },
486     { "post", SkType_Post                       INIT_BOOL_FIELDS },
487     { "quadTo", SkType_QuadTo                   INIT_BOOL_FIELDS },
488     { "rCubicTo", SkType_RCubicTo               INIT_BOOL_FIELDS },
489     { "rLineTo", SkType_RLineTo                 INIT_BOOL_FIELDS },
490     { "rMoveTo", SkType_RMoveTo                 INIT_BOOL_FIELDS },
491     { "rQuadTo", SkType_RQuadTo                 INIT_BOOL_FIELDS },
492     { "radialGradient", SkType_DrawRadialGradient   INIT_BOOL_FIELDS },
493     DISPLAY_NAME("random", SkType_Random),
494     { "rect", SkType_Rect                       INIT_BOOL_FIELDS },
495     { "rectToRect", SkType_RectToRect           INIT_BOOL_FIELDS },
496     { "remove", SkType_Remove                   INIT_BOOL_FIELDS },
497     { "replace", SkType_Replace                 INIT_BOOL_FIELDS },
498     { "rotate", SkType_Rotate                   INIT_BOOL_FIELDS },
499     { "roundRect", SkType_RoundRect             INIT_BOOL_FIELDS },
500     { "save", SkType_Save                       INIT_BOOL_FIELDS },
501     { "saveLayer", SkType_SaveLayer             INIT_BOOL_FIELDS },
502     { "scale", SkType_Scale                     INIT_BOOL_FIELDS },
503     // screenplay
504     { "set", SkType_Set                         INIT_BOOL_FIELDS },
505     { "shader", SkType_Shader                   INIT_BOOL_FIELDS },
506     { "skew", SkType_Skew                       INIT_BOOL_FIELDS },
507     { "skia3d:camera", SkType_3D_Camera         INIT_BOOL_FIELDS },
508     { "skia3d:patch", SkType_3D_Patch           INIT_BOOL_FIELDS },
509     // point
510     { "snapshot", SkType_Snapshot               INIT_BOOL_FIELDS },
511     { "string", SkType_String                   INIT_BOOL_FIELDS },
512     // style
513     { "text", SkType_Text                       INIT_BOOL_FIELDS },
514     { "textBox", SkType_TextBox                 INIT_BOOL_FIELDS },
515     // textboxalign
516     // textboxmode
517     { "textOnPath", SkType_TextOnPath           INIT_BOOL_FIELDS },
518     { "textToPath", SkType_TextToPath           INIT_BOOL_FIELDS },
519     // tilemode
520     { "translate", SkType_Translate             INIT_BOOL_FIELDS },
521     DRAW_NAME("transparentShader", SkType_TransparentShader),
522     { "typeface", SkType_Typeface               INIT_BOOL_FIELDS }
523     // xfermode
524     // knumberoftypes
525 };
526 
527 const int kTypeNamesSize = SK_ARRAY_COUNT(gTypeNames);
528 
Find(SkAnimateMaker * maker,const SkMemberInfo * match)529 SkDisplayTypes SkDisplayType::Find(SkAnimateMaker* maker, const SkMemberInfo* match) {
530     for (int index = 0; index < kTypeNamesSize; index++) {
531         SkDisplayTypes type = gTypeNames[index].fType;
532         const SkMemberInfo* info = SkDisplayType::GetMembers(maker, type, NULL);
533         if (info == match)
534             return type;
535     }
536     return (SkDisplayTypes) -1;
537 }
538 
539 // !!! optimize this by replacing function with a byte-sized lookup table
GetParent(SkAnimateMaker * maker,SkDisplayTypes base)540 SkDisplayTypes SkDisplayType::GetParent(SkAnimateMaker* maker, SkDisplayTypes base) {
541     if (base == SkType_Group || base == SkType_Save || base == SkType_SaveLayer)        //!!! cheat a little until we have a lookup table
542         return SkType_Displayable;
543     if (base == SkType_Set)
544         return SkType_Animate;  // another cheat until we have a lookup table
545     const SkMemberInfo* info = GetMembers(maker, base, NULL); // get info for this type
546     SkASSERT(info);
547     if (info->fType != SkType_BaseClassInfo)
548         return SkType_Unknown; // if no base, done
549     // !!! could change SK_MEMBER_INHERITED macro to take type, stuff in offset, so that
550     // this (and table builder) could know type without the following steps:
551     const SkMemberInfo* inherited = info->getInherited();
552     SkDisplayTypes result = (SkDisplayTypes) (SkType_Unknown + 1);
553     for (; result <= SkType_Xfermode; result = (SkDisplayTypes) (result + 1)) {
554         const SkMemberInfo* match = GetMembers(maker, result, NULL);
555         if (match == inherited)
556             break;
557     }
558     SkASSERT(result <= SkType_Xfermode);
559     return result;
560 }
561 
GetType(SkAnimateMaker * maker,const char match[],size_t len)562 SkDisplayTypes SkDisplayType::GetType(SkAnimateMaker* maker, const char match[], size_t len ) {
563     int index = SkStrSearch(&gTypeNames[0].fName, kTypeNamesSize, match,
564         len, sizeof(gTypeNames[0]));
565     if (index >= 0 && index < kTypeNamesSize)
566         return gTypeNames[index].fType;
567     SkExtras** end = maker->fExtras.end();
568     for (SkExtras** extraPtr = maker->fExtras.begin(); extraPtr < end; extraPtr++) {
569         SkDisplayTypes result = (*extraPtr)->getType(match, len);
570         if (result != SkType_Unknown)
571             return result;
572     }
573     return (SkDisplayTypes) -1;
574 }
575 
IsEnum(SkAnimateMaker *,SkDisplayTypes type)576 bool SkDisplayType::IsEnum(SkAnimateMaker* , SkDisplayTypes type) {
577     switch (type) {
578         case SkType_AddMode:
579         case SkType_Align:
580         case SkType_ApplyMode:
581         case SkType_ApplyTransition:
582         case SkType_BitmapEncoding:
583         case SkType_BitmapFormat:
584         case SkType_Boolean:
585         case SkType_Cap:
586         case SkType_EventCode:
587         case SkType_EventKind:
588         case SkType_EventMode:
589         case SkType_FillType:
590         case SkType_FilterType:
591         case SkType_FontStyle:
592         case SkType_FromPathMode:
593         case SkType_Join:
594         case SkType_MaskFilterBlurStyle:
595         case SkType_PathDirection:
596         case SkType_Style:
597         case SkType_TextBoxAlign:
598         case SkType_TextBoxMode:
599         case SkType_TileMode:
600         case SkType_Xfermode:
601             return true;
602         default:    // to avoid warnings
603             break;
604     }
605     return false;
606 }
607 
IsDisplayable(SkAnimateMaker *,SkDisplayTypes type)608 bool SkDisplayType::IsDisplayable(SkAnimateMaker* , SkDisplayTypes type) {
609     switch (type) {
610         case SkType_Add:
611         case SkType_AddCircle:
612         case SkType_AddOval:
613         case SkType_AddPath:
614         case SkType_AddRect:
615         case SkType_AddRoundRect:
616         case SkType_Animate:
617         case SkType_AnimateBase:
618         case SkType_Apply:
619         case SkType_BaseBitmap:
620         case SkType_Bitmap:
621         case SkType_BitmapShader:
622         case SkType_Blur:
623         case SkType_Clear:
624         case SkType_Clip:
625         case SkType_Close:
626         case SkType_Color:
627         case SkType_CubicTo:
628         case SkType_Dash:
629         case SkType_DataInput:
630         case SkType_Discrete:
631         case SkType_Displayable:
632         case SkType_Drawable:
633         case SkType_DrawTo:
634         case SkType_Emboss:
635         case SkType_Event:
636         case SkType_FromPath:
637         case SkType_Full:
638         case SkType_Group:
639         case SkType_ImageBaseBitmap:
640         case SkType_Input:
641         case SkType_Line:
642         case SkType_LineTo:
643         case SkType_DrawLinearGradient:
644         case SkType_Matrix:
645         case SkType_Move:
646         case SkType_MoveTo:
647         case SkType_Movie:
648         case SkType_Oval:
649         case SkType_Paint:
650         case SkType_Path:
651         case SkType_PolyToPoly:
652         case SkType_Polygon:
653         case SkType_Polyline:
654         case SkType_Post:
655         case SkType_QuadTo:
656         case SkType_RCubicTo:
657         case SkType_RLineTo:
658         case SkType_RMoveTo:
659         case SkType_RQuadTo:
660         case SkType_DrawRadialGradient:
661         case SkType_Random:
662         case SkType_Rect:
663         case SkType_RectToRect:
664         case SkType_Remove:
665         case SkType_Replace:
666         case SkType_Rotate:
667         case SkType_RoundRect:
668         case SkType_Save:
669         case SkType_SaveLayer:
670         case SkType_Scale:
671         case SkType_Set:
672         case SkType_Shader:
673         case SkType_Skew:
674         case SkType_3D_Camera:
675         case SkType_3D_Patch:
676         case SkType_Snapshot:
677         case SkType_Text:
678         case SkType_TextBox:
679         case SkType_TextOnPath:
680         case SkType_TextToPath:
681         case SkType_Translate:
682         case SkType_TransparentShader:
683             return true;
684         default:    // to avoid warnings
685             break;
686     }
687     return false;
688 }
689 
IsStruct(SkAnimateMaker *,SkDisplayTypes type)690 bool SkDisplayType::IsStruct(SkAnimateMaker* , SkDisplayTypes type) {
691     switch (type) {
692         case SkType_Point:
693         case SkType_3D_Point:
694             return true;
695         default:    // to avoid warnings
696             break;
697     }
698     return false;
699 }
700 
701 
RegisterNewType()702 SkDisplayTypes SkDisplayType::RegisterNewType() {
703     gNewTypes = (SkDisplayTypes) (gNewTypes + 1);
704     return gNewTypes;
705 }
706 
707 
708 
709 #ifdef SK_DEBUG
GetName(SkAnimateMaker * maker,SkDisplayTypes type)710 const char* SkDisplayType::GetName(SkAnimateMaker* maker, SkDisplayTypes type) {
711     for (int index = 0; index < kTypeNamesSize - 1; index++) {
712         if (gTypeNames[index].fType == type)
713             return gTypeNames[index].fName;
714     }
715     SkExtras** end = maker->fExtras.end();
716     for (SkExtras** extraPtr = maker->fExtras.begin(); extraPtr < end; extraPtr++) {
717         const char* result = (*extraPtr)->getName(type);
718         if (result != NULL)
719             return result;
720     }
721     return NULL;
722 }
723 #endif
724 
725 #ifdef SK_SUPPORT_UNITTEST
UnitTest()726 void SkDisplayType::UnitTest() {
727     SkAnimator animator;
728     SkAnimateMaker* maker = animator.fMaker;
729     int index;
730     for (index = 0; index < kTypeNamesSize - 1; index++) {
731         SkASSERT(strcmp(gTypeNames[index].fName, gTypeNames[index + 1].fName) < 0);
732         SkASSERT(gTypeNames[index].fType < gTypeNames[index + 1].fType);
733     }
734     for (index = 0; index < kTypeNamesSize; index++) {
735         SkDisplayable* test = CreateInstance(maker, gTypeNames[index].fType);
736         if (test == NULL)
737             continue;
738 #if defined _WIN32 && _MSC_VER >= 1300  && defined _INC_CRTDBG // only on windows, only if using "crtdbg.h"
739     // we know that crtdbg puts 0xfdfdfdfd at the end of the block
740     // look for unitialized memory, signature 0xcdcdcdcd prior to that
741         int* start = (int*) test;
742         while (*start != 0xfdfdfdfd) {
743             SkASSERT(*start != 0xcdcdcdcd);
744             start++;
745         }
746 #endif
747         delete test;
748     }
749     for (index = 0; index < kTypeNamesSize; index++) {
750         int infoCount;
751         const SkMemberInfo* info = GetMembers(maker, gTypeNames[index].fType, &infoCount);
752         if (info == NULL)
753             continue;
754 #if SK_USE_CONDENSED_INFO == 0
755         for (int inner = 0; inner < infoCount - 1; inner++) {
756             if (info[inner].fType == SkType_BaseClassInfo)
757                 continue;
758             SkASSERT(strcmp(info[inner].fName, info[inner + 1].fName) < 0);
759         }
760 #endif
761     }
762 #if defined SK_DEBUG || defined SK_BUILD_CONDENSED
763     BuildCondensedInfo(maker);
764 #endif
765 }
766 #endif
767