/* * Copyright 2006 The Android Open Source Project * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "SkDisplayType.h" #include "SkAnimateMaker.h" #include "SkAnimateSet.h" #include "SkDisplayAdd.h" #include "SkDisplayApply.h" #include "SkDisplayBounds.h" #include "SkDisplayEvent.h" #include "SkDisplayInclude.h" #ifdef SK_DEBUG #include "SkDisplayList.h" #endif #include "SkDisplayMath.h" #include "SkDisplayMovie.h" #include "SkDisplayNumber.h" #include "SkDisplayPost.h" #include "SkDisplayRandom.h" #include "SkDisplayTypes.h" #include "SkDraw3D.h" #include "SkDrawBitmap.h" #include "SkDrawClip.h" #include "SkDrawDash.h" #include "SkDrawDiscrete.h" #include "SkDrawEmboss.h" #include "SkDrawFull.h" #include "SkDrawGradient.h" #include "SkDrawLine.h" #include "SkDrawMatrix.h" #include "SkDrawOval.h" #include "SkDrawPaint.h" #include "SkDrawPath.h" #include "SkDrawPoint.h" #include "SkDrawSaveLayer.h" #include "SkDrawText.h" #include "SkDrawTextBox.h" #include "SkDrawTo.h" #include "SkDump.h" #include "SkExtras.h" #include "SkHitClear.h" #include "SkHitTest.h" #include "SkMatrixParts.h" #include "SkPathParts.h" #include "SkPostParts.h" #include "SkSnapshot.h" #include "SkTextOnPath.h" #include "SkTextToPath.h" #include "SkTSearch.h" #define CASE_NEW(_class) \ case SkType_##_class: result = new Sk##_class(); break #define CASE_DRAW_NEW(_class) \ case SkType_##_class: result = new SkDraw##_class(); break #define CASE_DISPLAY_NEW(_class) \ case SkType_##_class: result = new SkDisplay##_class(); break #ifdef SK_DEBUG #define CASE_DEBUG_RETURN_NIL(_class) \ case SkType_##_class: return nullptr #else #define CASE_DEBUG_RETURN_NIL(_class) #endif SkDisplayTypes SkDisplayType::gNewTypes = kNumberOfTypes; SkDisplayable* SkDisplayType::CreateInstance(SkAnimateMaker* maker, SkDisplayTypes type) { SkDisplayable* result = nullptr; switch (type) { // unknown CASE_DISPLAY_NEW(Math); CASE_DISPLAY_NEW(Number); CASE_NEW(Add); CASE_NEW(AddCircle); // addgeom CASE_DEBUG_RETURN_NIL(AddMode); CASE_NEW(AddOval); CASE_NEW(AddPath); CASE_NEW(AddRect); CASE_NEW(AddRoundRect); CASE_DEBUG_RETURN_NIL(Align); CASE_NEW(Animate); // animatebase CASE_NEW(Apply); CASE_DEBUG_RETURN_NIL(ApplyMode); CASE_DEBUG_RETURN_NIL(ApplyTransition); CASE_DISPLAY_NEW(Array); // argb // base64 // basebitmap // baseclassinfo CASE_DRAW_NEW(Bitmap); // bitmapencoding // bitmapformat CASE_DRAW_NEW(BitmapShader); CASE_DRAW_NEW(Blur); CASE_DISPLAY_NEW(Boolean); // boundable CASE_DISPLAY_NEW(Bounds); CASE_DEBUG_RETURN_NIL(Cap); CASE_NEW(Clear); CASE_DRAW_NEW(Clip); CASE_NEW(Close); CASE_DRAW_NEW(Color); CASE_NEW(CubicTo); CASE_NEW(Dash); CASE_NEW(DataInput); CASE_NEW(Discrete); // displayable // drawable CASE_NEW(DrawTo); CASE_NEW(Dump); // dynamicstring CASE_DRAW_NEW(Emboss); CASE_DISPLAY_NEW(Event); CASE_DEBUG_RETURN_NIL(EventCode); CASE_DEBUG_RETURN_NIL(EventKind); CASE_DEBUG_RETURN_NIL(EventMode); // filltype // filtertype CASE_DISPLAY_NEW(Float); CASE_NEW(FromPath); CASE_DEBUG_RETURN_NIL(FromPathMode); CASE_NEW(Full); // gradient CASE_NEW(Group); CASE_NEW(HitClear); CASE_NEW(HitTest); CASE_NEW(ImageBaseBitmap); CASE_NEW(Include); CASE_NEW(Input); CASE_DISPLAY_NEW(Int); CASE_DEBUG_RETURN_NIL(Join); CASE_NEW(Line); CASE_NEW(LineTo); CASE_NEW(DrawLinearGradient); CASE_DRAW_NEW(MaskFilter); CASE_DEBUG_RETURN_NIL(MaskFilterBlurStyle); // maskfilterlight CASE_DRAW_NEW(Matrix); // memberfunction // memberproperty CASE_NEW(Move); CASE_NEW(MoveTo); CASE_DISPLAY_NEW(Movie); // msec CASE_NEW(Oval); CASE_DRAW_NEW(Paint); CASE_DRAW_NEW(Path); // pathdirection CASE_DRAW_NEW(PathEffect); // point CASE_NEW(DrawPoint); CASE_NEW(PolyToPoly); CASE_NEW(Polygon); CASE_NEW(Polyline); CASE_NEW(Post); CASE_NEW(QuadTo); CASE_NEW(RCubicTo); CASE_NEW(RLineTo); CASE_NEW(RMoveTo); CASE_NEW(RQuadTo); CASE_NEW(DrawRadialGradient); CASE_DISPLAY_NEW(Random); CASE_DRAW_NEW(Rect); CASE_NEW(RectToRect); CASE_NEW(Remove); CASE_NEW(Replace); CASE_NEW(Rotate); CASE_NEW(RoundRect); CASE_NEW(Save); CASE_NEW(SaveLayer); CASE_NEW(Scale); // screenplay CASE_NEW(Set); CASE_DRAW_NEW(Shader); CASE_NEW(Skew); CASE_NEW(3D_Camera); CASE_NEW(3D_Patch); // 3dpoint CASE_NEW(Snapshot); CASE_DISPLAY_NEW(String); // style CASE_NEW(Text); CASE_DRAW_NEW(TextBox); // textboxalign // textboxmode CASE_NEW(TextOnPath); CASE_NEW(TextToPath); CASE_DEBUG_RETURN_NIL(TileMode); CASE_NEW(Translate); CASE_DRAW_NEW(Typeface); CASE_DEBUG_RETURN_NIL(Xfermode); default: SkExtras** end = maker->fExtras.end(); for (SkExtras** extraPtr = maker->fExtras.begin(); extraPtr < end; extraPtr++) { if ((result = (*extraPtr)->createInstance(type)) != nullptr) return result; } SkASSERT(0); } return result; } #undef CASE_NEW #undef CASE_DRAW_NEW #undef CASE_DISPLAY_NEW #if SK_USE_CONDENSED_INFO == 0 #define CASE_GET_INFO(_class) case SkType_##_class: \ info = Sk##_class::fInfo; infoCount = Sk##_class::fInfoCount; break #define CASE_GET_DRAW_INFO(_class) case SkType_##_class: \ info = SkDraw##_class::fInfo; infoCount = SkDraw##_class::fInfoCount; break #define CASE_GET_DISPLAY_INFO(_class) case SkType_##_class: \ info = SkDisplay##_class::fInfo; infoCount = SkDisplay##_class::fInfoCount; \ break const SkMemberInfo* SkDisplayType::GetMembers(SkAnimateMaker* maker, SkDisplayTypes type, int* infoCountPtr) { const SkMemberInfo* info = nullptr; int infoCount = 0; switch (type) { // unknown CASE_GET_DISPLAY_INFO(Math); CASE_GET_DISPLAY_INFO(Number); CASE_GET_INFO(Add); CASE_GET_INFO(AddCircle); CASE_GET_INFO(AddGeom); // addmode CASE_GET_INFO(AddOval); CASE_GET_INFO(AddPath); CASE_GET_INFO(AddRect); CASE_GET_INFO(AddRoundRect); // align CASE_GET_INFO(Animate); CASE_GET_INFO(AnimateBase); CASE_GET_INFO(Apply); // applymode // applytransition CASE_GET_DISPLAY_INFO(Array); // argb // base64 CASE_GET_INFO(BaseBitmap); // baseclassinfo CASE_GET_DRAW_INFO(Bitmap); // bitmapencoding // bitmapformat CASE_GET_DRAW_INFO(BitmapShader); CASE_GET_DRAW_INFO(Blur); CASE_GET_DISPLAY_INFO(Boolean); // boundable CASE_GET_DISPLAY_INFO(Bounds); // cap // clear CASE_GET_DRAW_INFO(Clip); // close CASE_GET_DRAW_INFO(Color); CASE_GET_INFO(CubicTo); CASE_GET_INFO(Dash); CASE_GET_INFO(DataInput); CASE_GET_INFO(Discrete); // displayable // drawable CASE_GET_INFO(DrawTo); CASE_GET_INFO(Dump); // dynamicstring CASE_GET_DRAW_INFO(Emboss); CASE_GET_DISPLAY_INFO(Event); // eventcode // eventkind // eventmode // filltype // filtertype CASE_GET_DISPLAY_INFO(Float); CASE_GET_INFO(FromPath); // frompathmode // full CASE_GET_INFO(DrawGradient); CASE_GET_INFO(Group); CASE_GET_INFO(HitClear); CASE_GET_INFO(HitTest); CASE_GET_INFO(ImageBaseBitmap); CASE_GET_INFO(Include); CASE_GET_INFO(Input); CASE_GET_DISPLAY_INFO(Int); // join CASE_GET_INFO(Line); CASE_GET_INFO(LineTo); CASE_GET_INFO(DrawLinearGradient); // maskfilter // maskfilterblurstyle // maskfilterlight CASE_GET_DRAW_INFO(Matrix); // memberfunction // memberproperty CASE_GET_INFO(Move); CASE_GET_INFO(MoveTo); CASE_GET_DISPLAY_INFO(Movie); // msec CASE_GET_INFO(Oval); CASE_GET_DRAW_INFO(Path); CASE_GET_DRAW_INFO(Paint); // pathdirection // patheffect case SkType_Point: info = Sk_Point::fInfo; infoCount = Sk_Point::fInfoCount; break; // no virtual flavor CASE_GET_INFO(DrawPoint); // virtual flavor CASE_GET_INFO(PolyToPoly); CASE_GET_INFO(Polygon); CASE_GET_INFO(Polyline); CASE_GET_INFO(Post); CASE_GET_INFO(QuadTo); CASE_GET_INFO(RCubicTo); CASE_GET_INFO(RLineTo); CASE_GET_INFO(RMoveTo); CASE_GET_INFO(RQuadTo); CASE_GET_INFO(DrawRadialGradient); CASE_GET_DISPLAY_INFO(Random); CASE_GET_DRAW_INFO(Rect); CASE_GET_INFO(RectToRect); CASE_GET_INFO(Remove); CASE_GET_INFO(Replace); CASE_GET_INFO(Rotate); CASE_GET_INFO(RoundRect); CASE_GET_INFO(Save); CASE_GET_INFO(SaveLayer); CASE_GET_INFO(Scale); // screenplay CASE_GET_INFO(Set); CASE_GET_DRAW_INFO(Shader); CASE_GET_INFO(Skew); CASE_GET_INFO(3D_Camera); CASE_GET_INFO(3D_Patch); CASE_GET_INFO(3D_Point); CASE_GET_INFO(Snapshot); CASE_GET_DISPLAY_INFO(String); // style CASE_GET_INFO(Text); CASE_GET_DRAW_INFO(TextBox); // textboxalign // textboxmode CASE_GET_INFO(TextOnPath); CASE_GET_INFO(TextToPath); // tilemode CASE_GET_INFO(Translate); CASE_GET_DRAW_INFO(Typeface); // xfermode // knumberoftypes default: if (maker) { SkExtras** end = maker->fExtras.end(); for (SkExtras** extraPtr = maker->fExtras.begin(); extraPtr < end; extraPtr++) { if ((info = (*extraPtr)->getMembers(type, infoCountPtr)) != nullptr) return info; } } return nullptr; } if (infoCountPtr) *infoCountPtr = infoCount; return info; } const SkMemberInfo* SkDisplayType::GetMember(SkAnimateMaker* maker, SkDisplayTypes type, const char** matchPtr ) { int infoCount = 0; // Initialize to remove a warning. const SkMemberInfo* info = GetMembers(maker, type, &infoCount); info = SkMemberInfo::Find(info, infoCount, matchPtr); // SkASSERT(info); return info; } #undef CASE_GET_INFO #undef CASE_GET_DRAW_INFO #undef CASE_GET_DISPLAY_INFO #endif // SK_USE_CONDENSED_INFO == 0 #if defined SK_DEBUG || defined SK_BUILD_CONDENSED #define DRAW_NAME(_name, _type) {_name, _type, true, false } #define DISPLAY_NAME(_name, _type) {_name, _type, false, true } #define INIT_BOOL_FIELDS , false, false #else #define DRAW_NAME(_name, _type) {_name, _type } #define DISPLAY_NAME(_name, _type) {_name, _type } #define INIT_BOOL_FIELDS #endif const TypeNames gTypeNames[] = { // unknown { "Math", SkType_Math INIT_BOOL_FIELDS }, { "Number", SkType_Number INIT_BOOL_FIELDS }, { "add", SkType_Add INIT_BOOL_FIELDS }, { "addCircle", SkType_AddCircle INIT_BOOL_FIELDS }, // addgeom // addmode { "addOval", SkType_AddOval INIT_BOOL_FIELDS }, { "addPath", SkType_AddPath INIT_BOOL_FIELDS }, { "addRect", SkType_AddRect INIT_BOOL_FIELDS }, { "addRoundRect", SkType_AddRoundRect INIT_BOOL_FIELDS }, // align { "animate", SkType_Animate INIT_BOOL_FIELDS }, // animateBase { "apply", SkType_Apply INIT_BOOL_FIELDS }, // applymode // applytransition { "array", SkType_Array INIT_BOOL_FIELDS }, // argb // base64 // basebitmap // baseclassinfo DRAW_NAME("bitmap", SkType_Bitmap), // bitmapencoding // bitmapformat DRAW_NAME("bitmapShader", SkType_BitmapShader), DRAW_NAME("blur", SkType_Blur), { "boolean", SkType_Boolean INIT_BOOL_FIELDS }, // boundable DISPLAY_NAME("bounds", SkType_Bounds), // cap { "clear", SkType_Clear INIT_BOOL_FIELDS }, DRAW_NAME("clip", SkType_Clip), { "close", SkType_Close INIT_BOOL_FIELDS }, DRAW_NAME("color", SkType_Color), { "cubicTo", SkType_CubicTo INIT_BOOL_FIELDS }, { "dash", SkType_Dash INIT_BOOL_FIELDS }, { "data", SkType_DataInput INIT_BOOL_FIELDS }, { "discrete", SkType_Discrete INIT_BOOL_FIELDS }, // displayable // drawable { "drawTo", SkType_DrawTo INIT_BOOL_FIELDS }, { "dump", SkType_Dump INIT_BOOL_FIELDS }, // dynamicstring DRAW_NAME("emboss", SkType_Emboss), DISPLAY_NAME("event", SkType_Event), // eventcode // eventkind // eventmode // filltype // filtertype { "float", SkType_Float INIT_BOOL_FIELDS }, { "fromPath", SkType_FromPath INIT_BOOL_FIELDS }, // frompathmode { "full", SkType_Full INIT_BOOL_FIELDS }, // gradient { "group", SkType_Group INIT_BOOL_FIELDS }, { "hitClear", SkType_HitClear INIT_BOOL_FIELDS }, { "hitTest", SkType_HitTest INIT_BOOL_FIELDS }, { "image", SkType_ImageBaseBitmap INIT_BOOL_FIELDS }, { "include", SkType_Include INIT_BOOL_FIELDS }, { "input", SkType_Input INIT_BOOL_FIELDS }, { "int", SkType_Int INIT_BOOL_FIELDS }, // join { "line", SkType_Line INIT_BOOL_FIELDS }, { "lineTo", SkType_LineTo INIT_BOOL_FIELDS }, { "linearGradient", SkType_DrawLinearGradient INIT_BOOL_FIELDS }, { "maskFilter", SkType_MaskFilter INIT_BOOL_FIELDS }, // maskfilterblurstyle // maskfilterlight DRAW_NAME("matrix", SkType_Matrix), // memberfunction // memberproperty { "move", SkType_Move INIT_BOOL_FIELDS }, { "moveTo", SkType_MoveTo INIT_BOOL_FIELDS }, { "movie", SkType_Movie INIT_BOOL_FIELDS }, // msec { "oval", SkType_Oval INIT_BOOL_FIELDS }, DRAW_NAME("paint", SkType_Paint), DRAW_NAME("path", SkType_Path), // pathdirection { "pathEffect", SkType_PathEffect INIT_BOOL_FIELDS }, // point DRAW_NAME("point", SkType_DrawPoint), { "polyToPoly", SkType_PolyToPoly INIT_BOOL_FIELDS }, { "polygon", SkType_Polygon INIT_BOOL_FIELDS }, { "polyline", SkType_Polyline INIT_BOOL_FIELDS }, { "post", SkType_Post INIT_BOOL_FIELDS }, { "quadTo", SkType_QuadTo INIT_BOOL_FIELDS }, { "rCubicTo", SkType_RCubicTo INIT_BOOL_FIELDS }, { "rLineTo", SkType_RLineTo INIT_BOOL_FIELDS }, { "rMoveTo", SkType_RMoveTo INIT_BOOL_FIELDS }, { "rQuadTo", SkType_RQuadTo INIT_BOOL_FIELDS }, { "radialGradient", SkType_DrawRadialGradient INIT_BOOL_FIELDS }, DISPLAY_NAME("random", SkType_Random), { "rect", SkType_Rect INIT_BOOL_FIELDS }, { "rectToRect", SkType_RectToRect INIT_BOOL_FIELDS }, { "remove", SkType_Remove INIT_BOOL_FIELDS }, { "replace", SkType_Replace INIT_BOOL_FIELDS }, { "rotate", SkType_Rotate INIT_BOOL_FIELDS }, { "roundRect", SkType_RoundRect INIT_BOOL_FIELDS }, { "save", SkType_Save INIT_BOOL_FIELDS }, { "saveLayer", SkType_SaveLayer INIT_BOOL_FIELDS }, { "scale", SkType_Scale INIT_BOOL_FIELDS }, // screenplay { "set", SkType_Set INIT_BOOL_FIELDS }, { "shader", SkType_Shader INIT_BOOL_FIELDS }, { "skew", SkType_Skew INIT_BOOL_FIELDS }, { "skia3d:camera", SkType_3D_Camera INIT_BOOL_FIELDS }, { "skia3d:patch", SkType_3D_Patch INIT_BOOL_FIELDS }, // point { "snapshot", SkType_Snapshot INIT_BOOL_FIELDS }, { "string", SkType_String INIT_BOOL_FIELDS }, // style { "text", SkType_Text INIT_BOOL_FIELDS }, { "textBox", SkType_TextBox INIT_BOOL_FIELDS }, // textboxalign // textboxmode { "textOnPath", SkType_TextOnPath INIT_BOOL_FIELDS }, { "textToPath", SkType_TextToPath INIT_BOOL_FIELDS }, // tilemode { "translate", SkType_Translate INIT_BOOL_FIELDS }, { "typeface", SkType_Typeface INIT_BOOL_FIELDS } // xfermode // knumberoftypes }; const int kTypeNamesSize = SK_ARRAY_COUNT(gTypeNames); SkDisplayTypes SkDisplayType::Find(SkAnimateMaker* maker, const SkMemberInfo* match) { for (int index = 0; index < kTypeNamesSize; index++) { SkDisplayTypes type = gTypeNames[index].fType; const SkMemberInfo* info = SkDisplayType::GetMembers(maker, type, nullptr); if (info == match) return type; } return (SkDisplayTypes) -1; } // !!! optimize this by replacing function with a byte-sized lookup table SkDisplayTypes SkDisplayType::GetParent(SkAnimateMaker* maker, SkDisplayTypes base) { if (base == SkType_Group || base == SkType_Save || base == SkType_SaveLayer) //!!! cheat a little until we have a lookup table return SkType_Displayable; if (base == SkType_Set) return SkType_Animate; // another cheat until we have a lookup table const SkMemberInfo* info = GetMembers(maker, base, nullptr); // get info for this type SkASSERT(info); if (info->fType != SkType_BaseClassInfo) return SkType_Unknown; // if no base, done // !!! could change SK_MEMBER_INHERITED macro to take type, stuff in offset, so that // this (and table builder) could know type without the following steps: const SkMemberInfo* inherited = info->getInherited(); SkDisplayTypes result = (SkDisplayTypes) (SkType_Unknown + 1); for (; result <= SkType_Xfermode; result = (SkDisplayTypes) (result + 1)) { const SkMemberInfo* match = GetMembers(maker, result, nullptr); if (match == inherited) break; } SkASSERT(result <= SkType_Xfermode); return result; } SkDisplayTypes SkDisplayType::GetType(SkAnimateMaker* maker, const char match[], size_t len ) { int index = SkStrSearch(&gTypeNames[0].fName, kTypeNamesSize, match, len, sizeof(gTypeNames[0])); if (index >= 0 && index < kTypeNamesSize) return gTypeNames[index].fType; SkExtras** end = maker->fExtras.end(); for (SkExtras** extraPtr = maker->fExtras.begin(); extraPtr < end; extraPtr++) { SkDisplayTypes result = (*extraPtr)->getType(match, len); if (result != SkType_Unknown) return result; } return (SkDisplayTypes) -1; } bool SkDisplayType::IsEnum(SkAnimateMaker* , SkDisplayTypes type) { switch (type) { case SkType_AddMode: case SkType_Align: case SkType_ApplyMode: case SkType_ApplyTransition: case SkType_BitmapEncoding: case SkType_BitmapFormat: case SkType_Boolean: case SkType_Cap: case SkType_EventCode: case SkType_EventKind: case SkType_EventMode: case SkType_FillType: case SkType_FilterType: case SkType_FontStyle: case SkType_FromPathMode: case SkType_Join: case SkType_MaskFilterBlurStyle: case SkType_PathDirection: case SkType_Style: case SkType_TextBoxAlign: case SkType_TextBoxMode: case SkType_TileMode: case SkType_Xfermode: return true; default: // to avoid warnings break; } return false; } bool SkDisplayType::IsDisplayable(SkAnimateMaker* , SkDisplayTypes type) { switch (type) { case SkType_Add: case SkType_AddCircle: case SkType_AddOval: case SkType_AddPath: case SkType_AddRect: case SkType_AddRoundRect: case SkType_Animate: case SkType_AnimateBase: case SkType_Apply: case SkType_BaseBitmap: case SkType_Bitmap: case SkType_BitmapShader: case SkType_Blur: case SkType_Clear: case SkType_Clip: case SkType_Close: case SkType_Color: case SkType_CubicTo: case SkType_Dash: case SkType_DataInput: case SkType_Discrete: case SkType_Displayable: case SkType_Drawable: case SkType_DrawTo: case SkType_Emboss: case SkType_Event: case SkType_FromPath: case SkType_Full: case SkType_Group: case SkType_ImageBaseBitmap: case SkType_Input: case SkType_Line: case SkType_LineTo: case SkType_DrawLinearGradient: case SkType_Matrix: case SkType_Move: case SkType_MoveTo: case SkType_Movie: case SkType_Oval: case SkType_Paint: case SkType_Path: case SkType_PolyToPoly: case SkType_Polygon: case SkType_Polyline: case SkType_Post: case SkType_QuadTo: case SkType_RCubicTo: case SkType_RLineTo: case SkType_RMoveTo: case SkType_RQuadTo: case SkType_DrawRadialGradient: case SkType_Random: case SkType_Rect: case SkType_RectToRect: case SkType_Remove: case SkType_Replace: case SkType_Rotate: case SkType_RoundRect: case SkType_Save: case SkType_SaveLayer: case SkType_Scale: case SkType_Set: case SkType_Shader: case SkType_Skew: case SkType_3D_Camera: case SkType_3D_Patch: case SkType_Snapshot: case SkType_Text: case SkType_TextBox: case SkType_TextOnPath: case SkType_TextToPath: case SkType_Translate: return true; default: // to avoid warnings break; } return false; } bool SkDisplayType::IsStruct(SkAnimateMaker* , SkDisplayTypes type) { switch (type) { case SkType_Point: case SkType_3D_Point: return true; default: // to avoid warnings break; } return false; } SkDisplayTypes SkDisplayType::RegisterNewType() { gNewTypes = (SkDisplayTypes) (gNewTypes + 1); return gNewTypes; } #ifdef SK_DEBUG const char* SkDisplayType::GetName(SkAnimateMaker* maker, SkDisplayTypes type) { for (int index = 0; index < kTypeNamesSize - 1; index++) { if (gTypeNames[index].fType == type) return gTypeNames[index].fName; } SkExtras** end = maker->fExtras.end(); for (SkExtras** extraPtr = maker->fExtras.begin(); extraPtr < end; extraPtr++) { const char* result = (*extraPtr)->getName(type); if (result != nullptr) return result; } return nullptr; } #endif #ifdef SK_SUPPORT_UNITTEST void SkDisplayType::UnitTest() { SkAnimator animator; SkAnimateMaker* maker = animator.fMaker; int index; for (index = 0; index < kTypeNamesSize - 1; index++) { SkASSERT(strcmp(gTypeNames[index].fName, gTypeNames[index + 1].fName) < 0); SkASSERT(gTypeNames[index].fType < gTypeNames[index + 1].fType); } for (index = 0; index < kTypeNamesSize; index++) { SkDisplayable* test = CreateInstance(maker, gTypeNames[index].fType); if (test == nullptr) continue; #if defined _WIN32 && defined _INC_CRTDBG // only on windows, only if using "crtdbg.h" // we know that crtdbg puts 0xfdfdfdfd at the end of the block // look for unitialized memory, signature 0xcdcdcdcd prior to that int* start = (int*) test; while (*start != 0xfdfdfdfd) { SkASSERT(*start != 0xcdcdcdcd); start++; } #endif delete test; } for (index = 0; index < kTypeNamesSize; index++) { int infoCount; const SkMemberInfo* info = GetMembers(maker, gTypeNames[index].fType, &infoCount); if (info == nullptr) continue; #if SK_USE_CONDENSED_INFO == 0 for (int inner = 0; inner < infoCount - 1; inner++) { if (info[inner].fType == SkType_BaseClassInfo) continue; SkASSERT(strcmp(info[inner].fName, info[inner + 1].fName) < 0); } #endif } #if defined SK_DEBUG || defined SK_BUILD_CONDENSED BuildCondensedInfo(maker); #endif } #endif