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