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.

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

mercurial