gfx/skia/trunk/src/animator/SkAnimatorScript2.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     2 /*
     3  * Copyright 2011 Google Inc.
     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 #include "SkAnimatorScript2.h"
     9 #include "SkAnimateBase.h"
    10 #include "SkAnimateMaker.h"
    11 #include "SkDisplayTypes.h"
    12 #include "SkExtras.h"
    13 #include "SkMemberInfo.h"
    14 #include "SkOpArray.h"
    15 #include "SkParse.h"
    16 #include "SkScript2.h"
    17 #include "SkScriptCallBack.h"
    19 static const SkDisplayEnumMap gEnumMaps[] = {
    20     { SkType_AddMode, "indirect|immediate" },
    21     { SkType_Align, "left|center|right" },
    22     { SkType_ApplyMode, "immediate|once" },
    23     { SkType_ApplyTransition, "reverse" },
    24     { SkType_BitmapEncoding, "jpeg|png" },
    25     { SkType_BitmapFormat, "none|A1|A8|Index8|RGB16|RGB32" },
    26     { SkType_Boolean, "false|true" },
    27     { SkType_Cap, "butt|round|square" },
    28     { SkType_EventCode, "none|up|down|left|right|back|end|OK|send|leftSoftKey|rightSoftKey|key0|key1|key2|key3|key4|key5|key6|key7|key8|key9|star|hash" },
    29     { SkType_EventKind, "none|keyChar|keyPress|mouseDown|mouseDrag|mouseMove|mouseUp|onEnd|onLoad|user" },
    30     { SkType_EventMode, "deferred|immediate" },
    31     { SkType_FillType, "winding|evenOdd" },
    32     { SkType_FilterType, "none|bilinear" },
    33     { SkType_FromPathMode, "normal|angle|position" },
    34     { SkType_Join, "miter|round|blunt" },
    35     { SkType_MaskFilterBlurStyle, "normal|solid|outer|inner" },
    36     { SkType_PathDirection, "cw|ccw" },
    37     { SkType_Style, "fill|stroke|strokeAndFill" },
    38     { SkType_TextBoxAlign, "start|center|end" },
    39     { SkType_TextBoxMode, "oneLine|lineBreak" },
    40     { SkType_TileMode, "clamp|repeat|mirror" },
    41     { SkType_Xfermode, "clear|src|dst|srcOver|dstOver|srcIn|dstIn|srcOut|dstOut|"
    42         "srcATop|dstATop|xor|darken|lighten" },
    43 };
    45 static int gEnumMapCount = SK_ARRAY_COUNT(gEnumMaps);
    48 class SkAnimatorScript_Box : public SkScriptCallBackConvert {
    49 public:
    50     SkAnimatorScript_Box() {}
    52     ~SkAnimatorScript_Box() {
    53         for (SkDisplayable** dispPtr = fTrackDisplayable.begin(); dispPtr < fTrackDisplayable.end(); dispPtr++)
    54             delete *dispPtr;
    55     }
    57     virtual bool convert(SkOperand2::OpType type, SkOperand2* operand) {
    58         SkDisplayable* displayable;
    59         switch (type) {
    60             case SkOperand2::kArray: {
    61                 SkDisplayArray* boxedValue = new SkDisplayArray(*operand->fArray);
    62                 displayable = boxedValue;
    63                 } break;
    64             case SkOperand2::kS32: {
    65                 SkDisplayInt* boxedValue = new SkDisplayInt;
    66                 displayable = boxedValue;
    67                 boxedValue->value = operand->fS32;
    68                 } break;
    69             case SkOperand2::kScalar: {
    70                 SkDisplayFloat* boxedValue = new SkDisplayFloat;
    71                 displayable = boxedValue;
    72                 boxedValue->value = operand->fScalar;
    73                 } break;
    74             case SkOperand2::kString: {
    75                 SkDisplayString* boxedValue = new SkDisplayString(*operand->fString);
    76                 displayable = boxedValue;
    77                 } break;
    78             case SkOperand2::kObject:
    79                 return true;
    80             default:
    81                 SkASSERT(0);
    82                 return false;
    83         }
    84         track(displayable);
    85         operand->fObject = (void*) displayable;
    86         return true;
    87     }
    89     virtual SkOperand2::OpType getReturnType(int index) {
    90         return SkOperand2::kObject;
    91     }
    93     virtual Type getType() const {
    94         return kBox;
    95     }
    97     void track(SkDisplayable* displayable) {
    98         SkASSERT(fTrackDisplayable.find(displayable) < 0);
    99         *fTrackDisplayable.append() = displayable;
   100     }
   102     SkTDDisplayableArray fTrackDisplayable;
   103 };
   106 class SkAnimatorScript_Enum : public SkScriptCallBackProperty {
   107 public:
   108     SkAnimatorScript_Enum(const char* tokens) : fTokens(tokens) {}
   110     virtual bool getConstValue(const char* name, int len, SkOperand2* value) {
   111         return SkAnimatorScript2::MapEnums(fTokens, name, len, &value->fS32);
   112     }
   114 private:
   115     const char* fTokens;
   116 };
   118     // !!! if type is string, call invoke
   119     // if any other type, return original value
   120         // distinction is undone: could do this by returning index == 0 only if param is string
   121         // still, caller of getParamTypes will attempt to convert param to string (I guess)
   122 class SkAnimatorScript_Eval : public SkScriptCallBackFunction {
   123 public:
   124     SkAnimatorScript_Eval(SkAnimatorScript2* engine) : fEngine(engine) {}
   126     virtual bool getIndex(const char* name, int len, size_t* result) {
   127         if (SK_LITERAL_STR_EQUAL("eval", name, len) != 0)
   128             return false;
   129         *result = 0;
   130         return true;
   131     }
   133     virtual void getParamTypes(SkIntArray(SkOperand2::OpType)* types) {
   134         types->setCount(1);
   135         SkOperand2::OpType* type = types->begin();
   136         type[0] = SkOperand2::kString;
   137     }
   139     virtual bool invoke(size_t index, SkOpArray* params, SkOperand2* answer) {
   140         SkAnimatorScript2 engine(fEngine->getMaker(), fEngine->getWorking(),
   141             SkAnimatorScript2::ToDisplayType(fEngine->getReturnType()));
   142         SkOperand2* op = params->begin();
   143         const char* script = op->fString->c_str();
   144         SkScriptValue2 value;
   145         return engine.evaluateScript(&script, &value);
   146         SkASSERT(value.fType == fEngine->getReturnType());
   147         *answer = value.fOperand;
   148         // !!! incomplete ?
   149         return true;
   150     }
   152 private:
   153     SkAnimatorScript2* fEngine;
   154 };
   156 class SkAnimatorScript_ID : public SkScriptCallBackProperty {
   157 public:
   158     SkAnimatorScript_ID(SkAnimatorScript2* engine) : fEngine(engine) {}
   160     virtual bool getIndex(const char* token, int len, size_t* result) {
   161         SkDisplayable* displayable;
   162         bool success = fEngine->getMaker().find(token, len, &displayable);
   163         if (success == false) {
   164             *result = 0;
   165         } else {
   166             *result = (size_t) displayable;
   167             SkDisplayable* working = fEngine->getWorking();
   168             if (displayable->canContainDependents() && working && working->isAnimate()) {
   169                 SkAnimateBase* animator = (SkAnimateBase*) working;
   170                 if (animator->isDynamic()) {
   171                     SkDisplayDepend* depend = (SkDisplayDepend* ) displayable;
   172                     depend->addDependent(working);
   173                 }
   174             }
   175         }
   176         return true;
   177     }
   179     virtual bool getResult(size_t ref, SkOperand2* answer) {
   180         answer->fObject = (void*) ref;
   181         return true;
   182     }
   184     virtual SkOperand2::OpType getReturnType(size_t index) {
   185         return index == 0 ? SkOperand2::kString : SkOperand2::kObject;
   186     }
   188 private:
   189     SkAnimatorScript2* fEngine;
   190 };
   193 class SkAnimatorScript_Member : public SkScriptCallBackMember {
   194 public:
   196     SkAnimatorScript_Member(SkAnimatorScript2* engine) : fEngine(engine) {}
   198     bool getMemberReference(const char* member, size_t len, void* object, SkScriptValue2* ref) {
   199         SkDisplayable* displayable = (SkDisplayable*) object;
   200         SkString name(member, len);
   201         SkDisplayable* named = displayable->contains(name);
   202         if (named) {
   203             ref->fType = SkOperand2::kObject;
   204             ref->fOperand.fObject = named;
   205             return true;
   206         }
   207         const SkMemberInfo* info = displayable->getMember(name.c_str());
   208         if (info == NULL)
   209             return false;    // !!! add additional error info?
   210         ref->fType = SkAnimatorScript2::ToOpType(info->getType());
   211         ref->fOperand.fObject = (void*) info;
   212         return true;
   213     }
   215     bool invoke(size_t ref, void* object, SkOperand2* value) {
   216         const SkMemberInfo* info = (const SkMemberInfo* ) ref;
   217         SkDisplayable* displayable = (SkDisplayable*) object;
   218         if (info->fType == SkType_MemberProperty) {
   219             if (displayable->getProperty2(info->propertyIndex(), value) == false) {
   220                 return false;
   221             }
   222         }
   223         return fEngine->evalMemberCommon(info, displayable, value);
   224     }
   226     SkAnimatorScript2* fEngine;
   227 };
   230 class SkAnimatorScript_MemberFunction : public SkScriptCallBackMemberFunction {
   231 public:
   232     SkAnimatorScript_MemberFunction(SkAnimatorScript2* engine) : fEngine(engine) {}
   234     bool getMemberReference(const char* member, size_t len, void* object, SkScriptValue2* ref) {
   235         SkDisplayable* displayable = (SkDisplayable*) object;
   236         SkString name(member, len);
   237         const SkMemberInfo* info = displayable->getMember(name.c_str());
   238         if (info == NULL || info->fType != SkType_MemberFunction)
   239             return false;    // !!! add additional error info?
   240         ref->fType = SkAnimatorScript2::ToOpType(info->getType());
   241         ref->fOperand.fObject = (void*) info;
   242         return true;
   243     }
   245     virtual void getParamTypes(SkIntArray(SkOperand2::OpType)* types) {
   246         types->setCount(3);
   247         SkOperand2::OpType* type = types->begin();
   248         type[0] = type[1] = type[2] = SkOperand2::kS32;
   249     }
   251     bool invoke(size_t ref, void* object, SkOpArray* params, SkOperand2* value)
   252     {
   253         const SkMemberInfo* info = (const SkMemberInfo* ) ref;
   254         SkDisplayable* displayable = (SkDisplayable*) object;
   255         displayable->executeFunction2(displayable, info->functionIndex(), params, info->getType(),
   256             value);
   257         return fEngine->evalMemberCommon(info, displayable, value);
   258     }
   260     SkAnimatorScript2* fEngine;
   261 };
   264 class SkAnimatorScript_NamedColor : public SkScriptCallBackProperty {
   265 public:
   266     virtual bool getConstValue(const char* name, int len, SkOperand2* value) {
   267         return SkParse::FindNamedColor(name, len, (SkColor*) &value->fS32) != NULL;
   268     }
   269 };
   272 class SkAnimatorScript_RGB : public SkScriptCallBackFunction {
   273 public:
   274     virtual bool getIndex(const char* name, int len, size_t* result) {
   275         if (SK_LITERAL_STR_EQUAL("rgb", name, len) != 0)
   276             return false;
   277         *result = 0;
   278         return true;
   279     }
   281     virtual void getParamTypes(SkIntArray(SkOperand2::OpType)* types) {
   282         types->setCount(3);
   283         SkOperand2::OpType* type = types->begin();
   284         type[0] = type[1] = type[2] = SkOperand2::kS32;
   285     }
   287     virtual bool invoke(size_t index, SkOpArray* params, SkOperand2* answer) {
   288         SkASSERT(index == 0);
   289         unsigned result = 0xFF000000;
   290         int shift = 16;
   291         for (int index = 0; index < 3; index++) {
   292             result |= SkClampMax(params->begin()[index].fS32, 255) << shift;
   293             shift -= 8;
   294         }
   295         answer->fS32 = result;
   296         return true;
   297     }
   299 };
   302 class SkAnimatorScript_Unbox : public SkScriptCallBackConvert {
   303 public:
   304     SkAnimatorScript_Unbox(SkAnimatorScript2* engine) : fEngine(engine) {}
   306     virtual bool convert(SkOperand2::OpType type, SkOperand2* operand) {
   307         SkASSERT(type == SkOperand2::kObject);
   308         SkDisplayable* displayable = (SkDisplayable*) operand->fObject;
   309         switch (displayable->getType()) {
   310             case SkType_Array: {
   311                 SkDisplayArray* boxedValue = (SkDisplayArray*) displayable;
   312                 operand->fArray = new SkOpArray(SkAnimatorScript2::ToOpType(boxedValue->values.getType()));
   313                 int count = boxedValue->values.count();
   314                 operand->fArray->setCount(count);
   315                 memcpy(operand->fArray->begin(), boxedValue->values.begin(), count * sizeof(SkOperand2));
   316                 fEngine->track(operand->fArray);
   317                 } break;
   318             case SkType_Boolean: {
   319                 SkDisplayBoolean* boxedValue = (SkDisplayBoolean*) displayable;
   320                 operand->fS32 = boxedValue->value;
   321                 } break;
   322             case SkType_Int: {
   323                 SkDisplayInt* boxedValue = (SkDisplayInt*) displayable;
   324                 operand->fS32 = boxedValue->value;
   325                 } break;
   326             case SkType_Float: {
   327                 SkDisplayFloat* boxedValue = (SkDisplayFloat*) displayable;
   328                 operand->fScalar = boxedValue->value;
   329                 } break;
   330             case SkType_String: {
   331                 SkDisplayString* boxedValue = (SkDisplayString*) displayable;
   332                 operand->fString = SkNEW_ARGS(SkString, (boxedValue->value));
   333                 } break;
   334             default: {
   335                 const char* id;
   336                 bool success = fEngine->getMaker().findKey(displayable, &id);
   337                 SkASSERT(success);
   338                 operand->fString = SkNEW_ARGS(SkString, (id));
   339             }
   340         }
   341         return true;
   342     }
   344     virtual SkOperand2::OpType getReturnType(int /*index*/, SkOperand2* operand) {
   345         SkDisplayable* displayable = (SkDisplayable*) operand->fObject;
   346         switch (displayable->getType()) {
   347             case SkType_Array:
   348                 return SkOperand2::kArray;
   349             case SkType_Int:
   350                 return SkOperand2::kS32;
   351             case SkType_Float:
   352                 return SkOperand2::kScalar;
   353             case SkType_String:
   354             default:
   355                 return SkOperand2::kString;
   356         }
   357     }
   359     virtual Type getType() const {
   360         return kUnbox;
   361     }
   363     SkAnimatorScript2* fEngine;
   364 };
   366 SkAnimatorScript2::SkAnimatorScript2(SkAnimateMaker& maker, SkDisplayable* working, SkDisplayTypes type) :
   367         SkScriptEngine2(ToOpType(type)), fMaker(maker), fWorking(working) {
   368     *fCallBackArray.append() = new SkAnimatorScript_Member(this);
   369     *fCallBackArray.append() = new SkAnimatorScript_MemberFunction(this);
   370     *fCallBackArray.append() = new SkAnimatorScript_Box();
   371     *fCallBackArray.append() = new SkAnimatorScript_Unbox(this);
   372     *fCallBackArray.append() = new SkAnimatorScript_ID(this);
   373     if (type == SkType_ARGB) {
   374         *fCallBackArray.append() = new SkAnimatorScript_RGB();
   375         *fCallBackArray.append() = new SkAnimatorScript_NamedColor();
   376     }
   377     if (SkDisplayType::IsEnum(&maker, type)) {
   378         // !!! for SpiderMonkey, iterate through the enum values, and map them to globals
   379         const SkDisplayEnumMap& map = GetEnumValues(type);
   380         *fCallBackArray.append() = new SkAnimatorScript_Enum(map.fValues);
   381     }
   382     *fCallBackArray.append() = new SkAnimatorScript_Eval(this);
   383 #if 0        // !!! no extra support for now
   384     for (SkExtras** extraPtr = maker.fExtras.begin(); extraPtr < maker.fExtras.end(); extraPtr++) {
   385         SkExtras* extra = *extraPtr;
   386         if (extra->fExtraCallBack)
   387             *fCallBackArray.append() = new propertyCallBack(extra->fExtraCallBack, extra->fExtraStorage);
   388     }
   389 #endif
   390 }
   392 SkAnimatorScript2::~SkAnimatorScript2() {
   393     SkScriptCallBack** end = fCallBackArray.end();
   394     for (SkScriptCallBack** ptr = fCallBackArray.begin(); ptr < end; ptr++)
   395         delete *ptr;
   396 }
   398 bool SkAnimatorScript2::evalMemberCommon(const SkMemberInfo* info,
   399         SkDisplayable* displayable, SkOperand2* value) {
   400     SkDisplayTypes original;
   401     SkDisplayTypes type = original = (SkDisplayTypes) info->getType();
   402     if (info->fType == SkType_Array)
   403         type = SkType_Array;
   404     switch (type) {
   405         case SkType_ARGB:
   406             type = SkType_Int;
   407         case SkType_Boolean:
   408         case SkType_Int:
   409         case SkType_MSec:
   410         case SkType_Float:
   411             SkASSERT(info->getCount() == 1);
   412             if (info->fType != SkType_MemberProperty && info->fType != SkType_MemberFunction)
   413                 value->fS32 = *(int32_t*) info->memberData(displayable);    // OK for SkScalar too
   414             if (type == SkType_MSec) {
   415                 value->fScalar = SkScalarDiv((SkScalar) value->fS32, 1000); // dividing two ints is the same as dividing two scalars
   416                 type = SkType_Float;
   417             }
   418             break;
   419         case SkType_String: {
   420             SkString* displayableString;
   421             if (info->fType != SkType_MemberProperty && info->fType != SkType_MemberFunction) {
   422                 info->getString(displayable, &displayableString);
   423                 value->fString = new SkString(*displayableString);
   424             }
   425             } break;
   426         case SkType_Array: {
   427             SkASSERT(info->fType != SkType_MemberProperty); // !!! incomplete
   428             SkTDOperandArray* displayableArray = (SkTDOperandArray*) info->memberData(displayable);
   429             if (displayable->getType() == SkType_Array) {
   430                 SkDisplayArray* typedArray = (SkDisplayArray*) displayable;
   431                 original = typedArray->values.getType();
   432             }
   433             SkASSERT(original != SkType_Unknown);
   434             SkOpArray* array = value->fArray = new SkOpArray(ToOpType(original));
   435             track(array);
   436             int count = displayableArray->count();
   437             if (count > 0) {
   438                 array->setCount(count);
   439                 memcpy(array->begin(), displayableArray->begin(), count * sizeof(SkOperand2));
   440             }
   441             } break;
   442         default:
   443             SkASSERT(0); // unimplemented
   444     }
   445     return true;
   446 }
   448 const SkDisplayEnumMap& SkAnimatorScript2::GetEnumValues(SkDisplayTypes type) {
   449     int index = SkTSearch<SkDisplayTypes>(&gEnumMaps[0].fType, gEnumMapCount, type,
   450         sizeof(SkDisplayEnumMap));
   451     SkASSERT(index >= 0);
   452     return gEnumMaps[index];
   453 }
   455 SkDisplayTypes SkAnimatorScript2::ToDisplayType(SkOperand2::OpType type) {
   456     int val = type;
   457     switch (val) {
   458         case SkOperand2::kNoType:
   459             return SkType_Unknown;
   460         case SkOperand2::kS32:
   461             return SkType_Int;
   462         case SkOperand2::kScalar:
   463             return SkType_Float;
   464         case SkOperand2::kString:
   465             return SkType_String;
   466         case SkOperand2::kArray:
   467             return SkType_Array;
   468         case SkOperand2::kObject:
   469             return SkType_Displayable;
   470         default:
   471             SkASSERT(0);
   472             return SkType_Unknown;
   473     }
   474 }
   476 SkOperand2::OpType SkAnimatorScript2::ToOpType(SkDisplayTypes type) {
   477     if (SkDisplayType::IsDisplayable(NULL /* fMaker */, type))
   478         return SkOperand2::kObject;
   479     if (SkDisplayType::IsEnum(NULL /* fMaker */, type))
   480         return SkOperand2::kS32;
   481     switch (type) {
   482         case SkType_ARGB:
   483         case SkType_MSec:
   484         case SkType_Int:
   485             return SkOperand2::kS32;
   486         case SkType_Float:
   487         case SkType_Point:
   488         case SkType_3D_Point:
   489             return SkOperand2::kScalar;
   490         case SkType_Base64:
   491         case SkType_DynamicString:
   492         case SkType_String:
   493             return SkOperand2::kString;
   494         case SkType_Array:
   495             return SkOperand2::kArray;
   496         case SkType_Unknown:
   497             return SkOperand2::kNoType;
   498         default:
   499             SkASSERT(0);
   500             return SkOperand2::kNoType;
   501     }
   502 }
   504 bool SkAnimatorScript2::MapEnums(const char* ptr, const char* match, size_t len, int* value) {
   505     int index = 0;
   506     bool more = true;
   507     do {
   508         const char* last = strchr(ptr, '|');
   509         if (last == NULL) {
   510             last = &ptr[strlen(ptr)];
   511             more = false;
   512         }
   513         size_t length = last - ptr;
   514         if (len == length && strncmp(ptr, match, length) == 0) {
   515             *value = index;
   516             return true;
   517         }
   518         index++;
   519         ptr = last + 1;
   520     } while (more);
   521     return false;
   522 }
   524 #if defined SK_DEBUG
   526 #include "SkAnimator.h"
   528 static const char scriptTestSetup[]  =
   529 "<screenplay>"
   530     "<apply>"
   531         "<paint>"
   532             "<emboss id='emboss' direction='[1,1,1]'  />"
   533         "</paint>"
   534         "<animateField id='animation' field='direction' target='emboss' from='[1,1,1]' to='[-1,1,1]' dur='1'/>"
   535         "<set lval='direction[0]' target='emboss' to='-1' />"
   536     "</apply>"
   537     "<color id='testColor' color='0 ? rgb(0,0,0) : rgb(255,255,255)' />"
   538     "<color id='xColor' color='rgb(12,34,56)' />"
   539     "<typedArray id='emptyArray' />"
   540     "<typedArray id='intArray' values='[1, 4, 6]' />"
   541     "<s32 id='idx' value='2' />"
   542     "<s32 id='idy' value='2' />"
   543     "<string id='alpha' value='abc' />"
   544     "<rectangle id='testRect' left='Math.cos(0)' top='2' right='12' bottom='5' />"
   545     "<event id='evt'>"
   546         "<input name='x' />"
   547         "<apply scope='idy'>"
   548             "<set field='value' to='evt.x.s32' />"
   549         "</apply>"
   550     "</event>"
   551 "</screenplay>";
   553 static const SkScriptNAnswer scriptTests[]  = {
   554     {    "alpha+alpha", SkType_String, 0, 0, "abcabc" },
   555     {    "0 ? Math.sin(0) : 1", SkType_Int, 1 },
   556     {    "intArray[4]", SkType_Unknown },
   557     {    "emptyArray[4]", SkType_Unknown },
   558     {    "idx", SkType_Int, 2 },
   559     {    "intArray.length", SkType_Int, 3 },
   560     {    "intArray.values[0]", SkType_Int, 1 },
   561     {    "intArray[0]", SkType_Int, 1 },
   562     {    "idx.value", SkType_Int, 2 },
   563     {    "alpha.value", SkType_String, 0, 0, "abc" },
   564     {    "alpha", SkType_String, 0, 0, "abc" },
   565     {    "alpha.value+alpha.value", SkType_String, 0, 0, "abcabc" },
   566     {    "alpha+idx", SkType_String, 0, 0, "abc2" },
   567     {    "idx+alpha", SkType_String, 0, 0, "2abc" },
   568     {    "intArray[idx]", SkType_Int, 6 },
   569     {    "alpha.slice(1,2)", SkType_String, 0, 0, "b" },
   570     {    "alpha.value.slice(1,2)", SkType_String, 0, 0, "b" },
   571     {    "Math.sin(0)", SkType_Float, 0, SkIntToScalar(0) },
   572     {    "testRect.left+2", SkType_Float, 0, SkIntToScalar(3) },
   573     {    "0 ? intArray[0] : 1", SkType_Int, 1 },
   574     {    "0 ? intArray.values[0] : 1", SkType_Int, 1 },
   575     {    "0 ? idx : 1", SkType_Int, 1 },
   576     {    "0 ? idx.value : 1", SkType_Int, 1 },
   577     {    "0 ? alpha.slice(1,2) : 1", SkType_Int, 1 },
   578     {    "0 ? alpha.value.slice(1,2) : 1", SkType_Int, 1 },
   579     { "idy", SkType_Int, 3 }
   580 };
   582 #define SkScriptNAnswer_testCount    SK_ARRAY_COUNT(scriptTests)
   584 void SkAnimatorScript2::UnitTest() {
   585 #if defined(SK_SUPPORT_UNITTEST)
   586     SkAnimator animator;
   587     SkASSERT(animator.decodeMemory(scriptTestSetup, sizeof(scriptTestSetup)-1));
   588     SkEvent evt;
   589     evt.setString("id", "evt");
   590     evt.setS32("x", 3);
   591     animator.doUserEvent(evt);
   592     // set up animator with memory script above, then run value tests
   593     for (int index = 0; index < SkScriptNAnswer_testCount; index++) {
   594         SkAnimatorScript2 engine(*animator.fMaker, NULL, scriptTests[index].fType);
   595         SkScriptValue2 value;
   596         const char* script = scriptTests[index].fScript;
   597         bool success = engine.evaluateScript(&script, &value);
   598         if (success == false) {
   599             SkASSERT(scriptTests[index].fType == SkType_Unknown);
   600             continue;
   601         }
   602         SkASSERT(value.fType == ToOpType(scriptTests[index].fType));
   603         SkScalar error;
   604         switch (value.fType) {
   605             case SkOperand2::kS32:
   606                 SkASSERT(value.fOperand.fS32 == scriptTests[index].fIntAnswer);
   607                 break;
   608             case SkOperand2::kScalar:
   609                 error = SkScalarAbs(value.fOperand.fScalar - scriptTests[index].fScalarAnswer);
   610                 SkASSERT(error < SK_Scalar1 / 10000);
   611                 break;
   612             case SkOperand2::kString:
   613                 SkASSERT(value.fOperand.fString->equals(scriptTests[index].fStringAnswer));
   614                 break;
   615             default:
   616                 SkASSERT(0);
   617         }
   618     }
   619 #endif
   620 }
   622 #endif

mercurial