Home | History | Annotate | Download | only in animator
      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 
     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 
    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 
    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 
    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
    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 
    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 
    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 
    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 
    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 
    697 SkDisplayTypes SkDisplayType::RegisterNewType() {
    698     gNewTypes = (SkDisplayTypes) (gNewTypes + 1);
    699     return gNewTypes;
    700 }
    701 
    702 
    703 
    704 #ifdef SK_DEBUG
    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
    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