1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2006 The Android Open Source Project 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */ 8ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkAnimatorScript.h" 118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkAnimateBase.h" 128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkAnimateMaker.h" 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDisplayTypes.h" 148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkExtras.h" 158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkMemberInfo.h" 168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkParse.h" 178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic const SkDisplayEnumMap gEnumMaps[] = { 198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { SkType_AddMode, "indirect|immediate" }, 208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { SkType_Align, "left|center|right" }, 218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { SkType_ApplyMode, "create|immediate|once" }, 228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { SkType_ApplyTransition, "normal|reverse" }, 238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { SkType_BitmapEncoding, "jpeg|png" }, 248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { SkType_BitmapFormat, "none|A1|A8|Index8|RGB16|RGB32" }, 258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { SkType_Boolean, "false|true" }, 268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { SkType_Cap, "butt|round|square" }, 278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { SkType_EventCode, "none|leftSoftKey|rightSoftKey|home|back|send|end|key0|key1|key2|key3|key4|key5|key6|key7|key8|key9|star|hash|up|down|left|right|OK|volUp|volDown|camera" }, 288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { SkType_EventKind, "none|keyChar|keyPress|keyPressUp|mouseDown|mouseDrag|mouseMove|mouseUp|onEnd|onLoad|user" }, 298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { SkType_EventMode, "deferred|immediate" }, 308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { SkType_FillType, "winding|evenOdd" }, 318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { SkType_FilterType, "none|bilinear" }, 328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { SkType_FontStyle, "normal|bold|italic|boldItalic" }, 338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { SkType_FromPathMode, "normal|angle|position" }, 348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { SkType_Join, "miter|round|blunt" }, 358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { SkType_MaskFilterBlurStyle, "normal|solid|outer|inner" }, 368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { SkType_PathDirection, "cw|ccw" }, 378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { SkType_Style, "fill|stroke|strokeAndFill" }, 388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { SkType_TextBoxAlign, "start|center|end" }, 398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { SkType_TextBoxMode, "oneLine|lineBreak" }, 408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { SkType_TileMode, "clamp|repeat|mirror" }, 418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { SkType_Xfermode, "clear|src|dst|srcOver|dstOver|srcIn|dstIn|srcOut|dstOut|" 428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com "srcATop|dstATop|xor|darken|lighten" }, 438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic int gEnumMapCount = SK_ARRAY_COUNT(gEnumMaps); 468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkAnimatorScript::SkAnimatorScript(SkAnimateMaker& maker, SkDisplayable* working, SkDisplayTypes type) 488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com : SkScriptEngine(SkScriptEngine::ToOpType(type)), fMaker(maker), fParent(NULL), fWorking(working) 498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com memberCallBack(EvalMember, (void*) this); 518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com memberFunctionCallBack(EvalMemberFunction, (void*) this); 528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com boxCallBack(Box, (void*) this); 538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unboxCallBack(Unbox, (void*) &maker); 548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com propertyCallBack(EvalID, (void*) this); // must be first (entries are prepended, will be last), since it never fails 558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com propertyCallBack(Infinity, (void*) this); 568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com propertyCallBack(NaN, (void*) this); 578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com functionCallBack(Eval, (void*) this); 588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com functionCallBack(IsFinite, (void*) this); 598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com functionCallBack(IsNaN, (void*) this); 608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (type == SkType_ARGB) { 618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com functionCallBack(EvalRGB, (void*) this); 628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com propertyCallBack(EvalNamedColor, (void*) &maker.fIDs); 638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (SkDisplayType::IsEnum(&maker, type)) { 658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // !!! for SpiderMonkey, iterate through the enum values, and map them to globals 668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkDisplayEnumMap& map = GetEnumValues(type); 67d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com propertyCallBack(EvalEnum, (void*) map.fValues); 68d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com } 698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (SkExtras** extraPtr = maker.fExtras.begin(); extraPtr < maker.fExtras.end(); extraPtr++) { 708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkExtras* extra = *extraPtr; 718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (extra->fExtraCallBack) 728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com propertyCallBack(extra->fExtraCallBack, extra->fExtraStorage); 738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkAnimatorScript::~SkAnimatorScript() { 778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (SkDisplayable** dispPtr = fTrackDisplayable.begin(); dispPtr < fTrackDisplayable.end(); dispPtr++) 788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com delete *dispPtr; 798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkAnimatorScript::evaluate(const char* original, SkScriptValue* result, SkDisplayTypes type) { 828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* script = original; 838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool success = evaluateScript(&script, result); 848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (success == false || result->fType != type) { 858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMaker.setScriptError(*this); 868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkAnimatorScript::Box(void* user, SkScriptValue* scriptValue) { 928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAnimatorScript* engine = (SkAnimatorScript*) user; 938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDisplayTypes type = scriptValue->fType; 948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDisplayable* displayable; 958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com switch (type) { 968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com case SkType_Array: { 978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDisplayArray* boxedValue = new SkDisplayArray(*scriptValue->fOperand.fArray); 988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com displayable = boxedValue; 998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } break; 1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com case SkType_Boolean: { 1018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDisplayBoolean* boxedValue = new SkDisplayBoolean; 1028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com displayable = boxedValue; 1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com boxedValue->value = !! scriptValue->fOperand.fS32; 1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } break; 1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com case SkType_Int: { 1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDisplayInt* boxedValue = new SkDisplayInt; 1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com displayable = boxedValue; 1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com boxedValue->value = scriptValue->fOperand.fS32; 1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } break; 1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com case SkType_Float: { 1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDisplayFloat* boxedValue = new SkDisplayFloat; 1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com displayable = boxedValue; 1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com boxedValue->value = scriptValue->fOperand.fScalar; 1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } break; 1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com case SkType_String: { 1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDisplayString* boxedValue = new SkDisplayString(*scriptValue->fOperand.fString); 1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com displayable = boxedValue; 1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } break; 119d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com case SkType_Displayable: 1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com scriptValue->fOperand.fObject = scriptValue->fOperand.fDisplayable; 1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com scriptValue->fType = SkType_Displayable; 1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com default: 1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(0); 1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com engine->track(displayable); 1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com scriptValue->fOperand.fObject = displayable; 1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com scriptValue->fType = SkType_Displayable; 1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 133d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.combool SkAnimatorScript::Eval(const char* function, size_t len, SkTDArray<SkScriptValue>& params, 1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void* eng, SkScriptValue* value) { 1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (SK_LITERAL_STR_EQUAL("eval", function, len) == false) 1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (params.count() != 1) 1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAnimatorScript* host = (SkAnimatorScript*) eng; 1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAnimatorScript engine(host->fMaker, host->fWorking, SkScriptEngine::ToDisplayType(host->fReturnType)); 1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScriptValue* scriptValue = params.begin(); 1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool success = true; 1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (scriptValue->fType == SkType_String) { 1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* script = scriptValue->fOperand.fString->c_str(); 1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com success = engine.evaluateScript(&script, value); 1468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else 1478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *value = *scriptValue; 1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return success; 1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkAnimatorScript::EvalEnum(const char* token, size_t len, void* callBack, SkScriptValue* value) { 1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* tokens = (const char*) callBack; 1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com value->fType = SkType_Int; 1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (MapEnums(tokens, token, len, (int*)&value->fOperand.fS32)) 155d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com return true; 1568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkAnimatorScript::EvalID(const char* token, size_t len, void* user, SkScriptValue* value) { 1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAnimatorScript* engine = (SkAnimatorScript*) user; 1618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkTDict<SkDisplayable*>* ids = &engine->fMaker.fIDs; 1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDisplayable* displayable; 163d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com bool success = ids->find(token, len, &displayable); 1648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (success == false) { 1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com displayable = engine->fWorking; 1668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (SK_LITERAL_STR_EQUAL("parent", token, len)) { 1678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDisplayable* parent = displayable->getParent(); 1686bf19415c3a3ac25a8fccb66ab5cc55d046bd042commit-bot@chromium.org if (parent == NULL) 1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com parent = engine->fParent; 1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (parent) { 1718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com value->fOperand.fDisplayable = parent; 1728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com value->fType = SkType_Displayable; 1738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 1748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (displayable && EvalMember(token, len, displayable, engine, value)) 1778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com value->fOperand.fString = NULL; 179d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com value->fType = SkType_String; 1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDisplayable* working = engine->fWorking; 1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com value->fOperand.fDisplayable = displayable; 1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com value->fType = SkType_Displayable; 1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (displayable->canContainDependents() && working && working->isAnimate()) { 1858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAnimateBase* animator = (SkAnimateBase*) working; 1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (animator->isDynamic()) { 1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDisplayDepend* depend = (SkDisplayDepend* ) displayable; 1888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com depend->addDependent(working); 1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 1938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkAnimatorScript::EvalNamedColor(const char* token, size_t len, void* callback, SkScriptValue* value) { 1968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com value->fType = SkType_Int; 1978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (SkParse::FindNamedColor(token, len, (SkColor*) &value->fOperand.fS32) != NULL) 1988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 1998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 2008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 202d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.combool SkAnimatorScript::EvalRGB(const char* function, size_t len, SkTDArray<SkScriptValue>& params, 2038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void* eng, SkScriptValue* value) { 2048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (SK_LITERAL_STR_EQUAL("rgb", function, len) == false) 2058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 2068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (params.count() != 3) 2078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 2088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScriptEngine* engine = (SkScriptEngine*) eng; 2098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned result = 0xFF000000; 2108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int shift = 16; 2118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (SkScriptValue* valuePtr = params.begin(); valuePtr < params.end(); valuePtr++) { 2128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com engine->convertTo(SkType_Int, valuePtr); 2138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com result |= SkClampMax(valuePtr->fOperand.fS32, 255) << shift; 2148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com shift -= 8; 2158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com value->fOperand.fS32 = result; 2178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com value->fType = SkType_Int; 2188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 2198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 221d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.combool SkAnimatorScript::EvalMemberCommon(SkScriptEngine* engine, const SkMemberInfo* info, 2228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDisplayable* displayable, SkScriptValue* value) { 2238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDisplayTypes original; 2248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDisplayTypes type = original = (SkDisplayTypes) info->getType(); 2258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (info->fType == SkType_Array) 2268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com type = SkType_Array; 2278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com switch (type) { 2288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com case SkType_ARGB: 2298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com type = SkType_Int; 2308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com case SkType_Boolean: 2318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com case SkType_Int: 2328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com case SkType_MSec: 2338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com case SkType_Float: 2348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(info->getCount() == 1); 235d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com if (info->fType != SkType_MemberProperty && info->fType != SkType_MemberFunction) 2368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com value->fOperand.fS32 = *(int32_t*) info->memberData(displayable); // OK for SkScalar too 2378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (type == SkType_MSec) { 238d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com value->fOperand.fScalar = SkScalarDiv((SkScalar) value->fOperand.fS32, 1000); // dividing two ints is the same as dividing two scalars 2398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com type = SkType_Float; 2408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 2428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com case SkType_String: { 2438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkString* displayableString; 2448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (info->fType != SkType_MemberProperty && info->fType != SkType_MemberFunction) { 2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com info->getString(displayable, &displayableString); 2468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com value->fOperand.fString = new SkString(*displayableString); 2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } break; 2498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com case SkType_Array: { 2508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(info->fType != SkType_MemberProperty); // !!! incomplete 2518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkTDOperandArray* displayableArray = (SkTDOperandArray*) info->memberData(displayable); 2528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (displayable->getType() == SkType_Array) { 2538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDisplayArray* typedArray = (SkDisplayArray*) displayable; 2548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com original = typedArray->values.getType(); 2558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(original != SkType_Unknown); 2578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkTypedArray* array = value->fOperand.fArray = new SkTypedArray(original); 2588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com engine->track(array); 2598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int count = displayableArray->count(); 2608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (count > 0) { 2618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com array->setCount(count); 2628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com memcpy(array->begin(), displayableArray->begin(), count * sizeof(SkOperand)); 2638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } break; 2658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com default: 2668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(0); // unimplemented 2678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com value->fType = type; 2698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 2708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 272d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.combool SkAnimatorScript::EvalMember(const char* member, size_t len, void* object, void* eng, 2738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScriptValue* value) { 2748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScriptEngine* engine = (SkScriptEngine*) eng; 2758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDisplayable* displayable = (SkDisplayable*) object; 2768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkString name(member, len); 2778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDisplayable* named = displayable->contains(name); 2788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (named) { 2798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com value->fOperand.fDisplayable = named; 2808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com value->fType = SkType_Displayable; 2818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 2828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMemberInfo* info = displayable->getMember(name.c_str()); 2848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (info == NULL) 2858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 2868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (info->fType == SkType_MemberProperty) { 2878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (displayable->getProperty(info->propertyIndex(), value) == false) { 2888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(0); 2898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 2908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return EvalMemberCommon(engine, info, displayable, value); 2938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 295d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.combool SkAnimatorScript::EvalMemberFunction(const char* member, size_t len, void* object, 2968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkTDArray<SkScriptValue>& params, void* eng, SkScriptValue* value) { 2978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScriptEngine* engine = (SkScriptEngine*) eng; 2988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDisplayable* displayable = (SkDisplayable*) object; 2998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkString name(member, len); 3008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMemberInfo* info = displayable->getMember(name.c_str()); 3018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(info != NULL); /* !!! error handling unimplemented */ 3028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (info->fType != SkType_MemberFunction) { 3038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(0); 3048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 3058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 306d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com displayable->executeFunction(displayable, info->functionIndex(), params, info->getType(), 3078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com value); 3088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return EvalMemberCommon(engine, info, displayable, value); 3098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkAnimatorScript::EvaluateDisplayable(SkAnimateMaker& maker, SkDisplayable* displayable, const char* script, SkDisplayable** result) { 3128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAnimatorScript engine(maker, displayable, SkType_Displayable); 3138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScriptValue value; 3148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool success = engine.evaluate(script, &value, SkType_Displayable); 3158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (success) 3168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *result = value.fOperand.fDisplayable; 3178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return success; 3188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkAnimatorScript::EvaluateInt(SkAnimateMaker& maker, SkDisplayable* displayable, const char* script, int32_t* result) { 3218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAnimatorScript engine(maker, displayable, SkType_Int); 3228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScriptValue value; 3238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool success = engine.evaluate(script, &value, SkType_Int); 3248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (success) 3258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *result = value.fOperand.fS32; 3268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return success; 3278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkAnimatorScript::EvaluateFloat(SkAnimateMaker& maker, SkDisplayable* displayable, const char* script, SkScalar* result) { 3308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAnimatorScript engine(maker, displayable, SkType_Float); 3318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScriptValue value; 3328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool success = engine.evaluate(script, &value, SkType_Float); 3338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (success) 3348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *result = value.fOperand.fScalar; 3358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return success; 3368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkAnimatorScript::EvaluateString(SkAnimateMaker& maker, SkDisplayable* displayable, const char* script, SkString* result) { 3398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAnimatorScript engine(maker, displayable, SkType_String); 3408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScriptValue value; 3418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool success = engine.evaluate(script, &value, SkType_String); 3428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (success) 3438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com result->set(*(value.fOperand.fString)); 3448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return success; 3458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkAnimatorScript::EvaluateString(SkAnimateMaker& maker, SkDisplayable* displayable, SkDisplayable* parent, const char* script, SkString* result) { 3488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAnimatorScript engine(maker, displayable, SkType_String); 3498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com engine.fParent = parent; 3508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScriptValue value; 3518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool success = engine.evaluate(script, &value, SkType_String); 3528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (success) 3538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com result->set(*(value.fOperand.fString)); 3548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return success; 3558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkDisplayEnumMap& SkAnimatorScript::GetEnumValues(SkDisplayTypes type) { 358d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com int index = SkTSearch<SkDisplayTypes>(&gEnumMaps[0].fType, gEnumMapCount, type, 3598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sizeof(SkDisplayEnumMap)); 3608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(index >= 0); 3618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return gEnumMaps[index]; 3628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkAnimatorScript::Infinity(const char* token, size_t len, void* user, SkScriptValue* value) { 3658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (SK_LITERAL_STR_EQUAL("Infinity", token, len) == false) 3668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 3678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com value->fType = SkType_Float; 3688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com value->fOperand.fScalar = SK_ScalarInfinity; 3698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 3708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 372d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.combool SkAnimatorScript::IsFinite(const char* function, size_t len, SkTDArray<SkScriptValue>& params, 3738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void* eng, SkScriptValue* value) { 3748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (SK_LITERAL_STR_EQUAL(function, "isFinite", len) == false) 3758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 3768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (params.count() != 1) 3778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 3788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScriptValue* scriptValue = params.begin(); 3798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDisplayTypes type = scriptValue->fType; 3808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar scalar = scriptValue->fOperand.fScalar; 3818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com value->fType = SkType_Int; 382d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com value->fOperand.fS32 = type == SkType_Float ? SkScalarIsNaN(scalar) == false && 3838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalarAbs(scalar) != SK_ScalarInfinity : type == SkType_Int; 3848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 3858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 387d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.combool SkAnimatorScript::IsNaN(const char* function, size_t len, SkTDArray<SkScriptValue>& params, 3888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void* eng, SkScriptValue* value) { 3898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (SK_LITERAL_STR_EQUAL("isNaN", function, len) == false) 3908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 3918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (params.count() != 1) 3928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 3938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScriptValue* scriptValue = params.begin(); 3948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com value->fType = SkType_Int; 3958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com value->fOperand.fS32 = scriptValue->fType == SkType_Float ? SkScalarIsNaN(scriptValue->fOperand.fScalar) : 0; 3968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 3978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkAnimatorScript::MapEnums(const char* ptr, const char* match, size_t len, int* value) { 4008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int index = 0; 4018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool more = true; 4028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { 4038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* last = strchr(ptr, '|'); 4048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (last == NULL) { 4058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com last = &ptr[strlen(ptr)]; 4068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com more = false; 4078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com size_t length = last - ptr; 4098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (len == length && strncmp(ptr, match, length) == 0) { 4108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *value = index; 4118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 4128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com index++; 4148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ptr = last + 1; 4158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } while (more); 4168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 4178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkAnimatorScript::NaN(const char* token, size_t len, void* user, SkScriptValue* value) { 4208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (SK_LITERAL_STR_EQUAL("NaN", token, len) == false) 4218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 4228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com value->fType = SkType_Float; 4238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com value->fOperand.fScalar = SK_ScalarNaN; 4248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 4258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#if 0 4288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkAnimatorScript::ObjectToString(void* object, void* user, SkScriptValue* value) { 4298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkTDict<SkDisplayable*>* ids = (SkTDict<SkDisplayable*>*) user; 4308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDisplayable* displayable = (SkDisplayable*) object; 4318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* key; 432d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com bool success = ids->findKey(displayable, &key); 4338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (success == false) 4348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 4358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com value->fOperand.fString = new SkString(key); 4368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com value->fType = SkType_String; 4378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 4388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 4408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkAnimatorScript::Unbox(void* m, SkScriptValue* scriptValue) { 4428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAnimateMaker* maker = (SkAnimateMaker*) m; 4438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT((unsigned) scriptValue->fType == (unsigned) SkType_Displayable); 4448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDisplayable* displayable = (SkDisplayable*) scriptValue->fOperand.fObject; 4458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDisplayTypes type = displayable->getType(); 4468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com switch (displayable->getType()) { 4478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com case SkType_Array: { 4488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDisplayArray* boxedValue = (SkDisplayArray*) displayable; 4498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com scriptValue->fOperand.fArray = &boxedValue->values; 4508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } break; 4518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com case SkType_Boolean: { 4528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDisplayBoolean* boxedValue = (SkDisplayBoolean*) displayable; 4538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com scriptValue->fOperand.fS32 = boxedValue->value; 4548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } break; 4558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com case SkType_Int: { 4568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDisplayInt* boxedValue = (SkDisplayInt*) displayable; 4578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com scriptValue->fOperand.fS32 = boxedValue->value; 4588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } break; 4598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com case SkType_Float: { 4608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDisplayFloat* boxedValue = (SkDisplayFloat*) displayable; 4618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com scriptValue->fOperand.fScalar = boxedValue->value; 4628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } break; 4638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com case SkType_String: { 4648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDisplayString* boxedValue = (SkDisplayString*) displayable; 4658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com scriptValue->fOperand.fString = SkNEW_ARGS(SkString, (boxedValue->value)); 4668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } break; 4678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com default: { 468a7ed3cc6371e50a5beb3750c475fe23665dafa7dtomhudson@google.com const char* id = NULL; 4690e51577a14f903ffeafa117a75954baeb173ffb9humper@google.com SkDEBUGCODE(bool success = ) maker->findKey(displayable, &id); 4708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(success); 4718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com scriptValue->fOperand.fString = SkNEW_ARGS(SkString, (id)); 4728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com type = SkType_String; 4738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com scriptValue->fType = type; 4768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 4778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#if defined SK_SUPPORT_UNITTEST 4808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkAnimator.h" 4828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 483d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.comstatic const char scriptTestSetup[] = 4848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com"<screenplay>\n" 4858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com "<text id='label' text='defg'/>\n" 4868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com "<add id='addLabel' use='label'/>\n" 4878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com "<text id='text1' text='test'/>\n" 4888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com "<apply scope='addLabel'>\n" 4898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com "<set target='label' field='text' to='#script:text1.text'/>\n" 4908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com "</apply>\n" 4918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com "<apply>\n" 4928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com "<paint id='labelPaint'>\n" 4938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com "<emboss id='emboss' direction='[1,1,1]' />\n" 4948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com "</paint>\n" 4958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com "<animate id='animation' field='direction' target='emboss' from='[1,1,1]' to='[-1,1,1]' dur='1'/>\n" 4968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com "<set lval='direction[0]' target='emboss' to='-1' />\n" 4978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com "</apply>\n" 4988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com "<color id='testColor' color='0 ? rgb(0,0,0) : rgb(255,255,255)' />\n" 4998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com "<color id='xColor' color='rgb(12,34,56)' />\n" 5008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com "<array id='emptyArray' />\n" 5018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com "<array id='intArray' values='[1, 4, 6]' />\n" 5028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com "<int id='idx' value='2' />\n" 5038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com "<int id='idy' value='2' />\n" 5048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com "<string id='alpha' value='abc' />\n" 5058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com "<rect id='testRect' left='Math.cos(0)' top='2' right='12' bottom='5' />\n" 5068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com "<event id='evt'>\n" 5078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com "<input name='x' />\n" 5088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com "<apply scope='idy'>\n" 5098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com "<set field='value' to='evt.x.int' />\n" 5108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com "</apply>\n" 5118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com "</event>\n" 5128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com"</screenplay>"; 5138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define DEFAULT_ANSWER , 0 5158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic const SkScriptNAnswer scriptTests[] = { 5178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { "label.text.length == 4", SkType_Int, 1 DEFAULT_ANSWER DEFAULT_ANSWER }, 5188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// { "labelPaint.measureText(label.text) > 0 ? labelPaint.measureText(label.text)+10 : 40", SkType_Float, 0, SkIntToScalar(0x23) }, 5198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { "Number.POSITIVE_INFINITY >= Number.MAX_VALUE ? 1 : 0", SkType_Int, 1 DEFAULT_ANSWER DEFAULT_ANSWER }, 5208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { "Infinity >= Number.MAX_VALUE ? 1 : 0", SkType_Int, 1 DEFAULT_ANSWER DEFAULT_ANSWER }, 5218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { "Number.NEGATIVE_INFINITY <= -Number.MAX_VALUE ? 1 : 0", SkType_Int, 1 DEFAULT_ANSWER DEFAULT_ANSWER }, 5228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { "Number.MIN_VALUE > 0 ? 1 : 0", SkType_Int, 1 DEFAULT_ANSWER DEFAULT_ANSWER }, 5238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { "isNaN(Number.NaN)", SkType_Int, 1 DEFAULT_ANSWER DEFAULT_ANSWER }, 5248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { "isNaN(NaN)", SkType_Int, 1 DEFAULT_ANSWER DEFAULT_ANSWER }, 5258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { "Math.sin(0)", SkType_Float, 0, SkIntToScalar(0) DEFAULT_ANSWER }, 5268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { "alpha+alpha", SkType_String, 0, 0, "abcabc" }, 5278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { "intArray[4]", SkType_Unknown DEFAULT_ANSWER DEFAULT_ANSWER DEFAULT_ANSWER }, 5288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { "emptyArray[4]", SkType_Unknown DEFAULT_ANSWER DEFAULT_ANSWER DEFAULT_ANSWER }, 5298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { "idx", SkType_Int, 2 DEFAULT_ANSWER DEFAULT_ANSWER }, 5308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { "intArray.length", SkType_Int, 3 DEFAULT_ANSWER DEFAULT_ANSWER }, 5318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { "intArray.values[0]", SkType_Int, 1 DEFAULT_ANSWER DEFAULT_ANSWER }, 5328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { "intArray[0]", SkType_Int, 1 DEFAULT_ANSWER DEFAULT_ANSWER }, 5338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { "idx.value", SkType_Int, 2 DEFAULT_ANSWER DEFAULT_ANSWER }, 5348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { "alpha.value", SkType_String, 0, 0, "abc" }, 5358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { "alpha", SkType_String, 0, 0, "abc" }, 5368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { "alpha.value+alpha.value", SkType_String, 0, 0, "abcabc" }, 5378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { "alpha+idx", SkType_String, 0, 0, "abc2" }, 5388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { "idx+alpha", SkType_String, 0, 0, "2abc" }, 5398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { "intArray[idx]", SkType_Int, 6 DEFAULT_ANSWER DEFAULT_ANSWER }, 5408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { "alpha.slice(1,2)", SkType_String, 0, 0, "b" }, 5418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { "alpha.value.slice(1,2)", SkType_String, 0, 0, "b" }, 5428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { "testRect.left+2", SkType_Float, 0, SkIntToScalar(3) DEFAULT_ANSWER }, 5438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { "0 ? Math.sin(0) : 1", SkType_Int, 1 DEFAULT_ANSWER DEFAULT_ANSWER }, 5448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { "0 ? intArray[0] : 1", SkType_Int, 1 DEFAULT_ANSWER DEFAULT_ANSWER }, 5458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { "0 ? intArray.values[0] : 1", SkType_Int, 1 DEFAULT_ANSWER DEFAULT_ANSWER }, 5468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { "0 ? idx : 1", SkType_Int, 1 DEFAULT_ANSWER DEFAULT_ANSWER }, 5478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { "0 ? idx.value : 1", SkType_Int, 1 DEFAULT_ANSWER DEFAULT_ANSWER }, 5488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { "0 ? alpha.slice(1,2) : 1", SkType_Int, 1 DEFAULT_ANSWER DEFAULT_ANSWER }, 5498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { "0 ? alpha.value.slice(1,2) : 1", SkType_Int, 1 DEFAULT_ANSWER DEFAULT_ANSWER }, 5508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { "idy", SkType_Int, 3 DEFAULT_ANSWER DEFAULT_ANSWER } 5518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 5528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkScriptNAnswer_testCount SK_ARRAY_COUNT(scriptTests) 5548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkAnimatorScript::UnitTest() { 556ec10d21eb9a17639688188b0defce6d757331eb4reed@android.com#if defined(SK_SUPPORT_UNITTEST) 5578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAnimator animator; 5588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(animator.decodeMemory(scriptTestSetup, sizeof(scriptTestSetup)-1)); 5598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkEvent evt; 5608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com evt.setString("id", "evt"); 5618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com evt.setS32("x", 3); 5628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com animator.doUserEvent(evt); 5638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // set up animator with memory script above, then run value tests 5648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (unsigned index = 0; index < SkScriptNAnswer_testCount; index++) { 5658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAnimatorScript engine(*animator.fMaker, NULL, scriptTests[index].fType); 5668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScriptValue value; 5678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* script = scriptTests[index].fScript; 5688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool success = engine.evaluateScript(&script, &value); 5698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (success == false) { 5708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDebugf("script failed: %s\n", scriptTests[index].fScript); 5718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(scriptTests[index].fType == SkType_Unknown); 5728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com continue; 5738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(value.fType == scriptTests[index].fType); 5758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar error; 5768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com switch (value.fType) { 5778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com case SkType_Int: 5788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(value.fOperand.fS32 == scriptTests[index].fIntAnswer); 5798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 5808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com case SkType_Float: 5818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com error = SkScalarAbs(value.fOperand.fScalar - scriptTests[index].fScalarAnswer); 5828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(error < SK_Scalar1 / 10000); 5838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 5848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com case SkType_String: 5858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(strcmp(value.fOperand.fString->c_str(), scriptTests[index].fStringAnswer) == 0); 5868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 5878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com default: 5888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(0); 5898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 5928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 595