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 "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 
     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 
    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 
    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 
    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
    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 
    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 
    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 
    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 
    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 
    702 SkDisplayTypes SkDisplayType::RegisterNewType() {
    703     gNewTypes = (SkDisplayTypes) (gNewTypes + 1);
    704     return gNewTypes;
    705 }
    706 
    707 
    708 
    709 #ifdef SK_DEBUG
    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
    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