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