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