1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/animator/SkAnimator.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,706 @@ 1.4 + 1.5 +/* 1.6 + * Copyright 2006 The Android Open Source Project 1.7 + * 1.8 + * Use of this source code is governed by a BSD-style license that can be 1.9 + * found in the LICENSE file. 1.10 + */ 1.11 + 1.12 + 1.13 +#include "SkAnimator.h" 1.14 +#include "SkAnimateMaker.h" 1.15 +#include "SkCanvas.h" 1.16 +#include "SkDisplayApply.h" 1.17 +#include "SkDisplayMovie.h" 1.18 +#include "SkDisplayTypes.h" 1.19 +#include "SkDisplayXMLParser.h" 1.20 +#include "SkStream.h" 1.21 +#include "SkScript.h" 1.22 +#include "SkScript2.h" // compiled script experiment 1.23 +#include "SkSystemEventTypes.h" 1.24 +#include "SkTypedArray.h" 1.25 +#ifdef SK_BUILD_FOR_ANDROID 1.26 +#include "SkDrawExtraPathEffect.h" 1.27 +#endif 1.28 +#ifdef SK_DEBUG 1.29 +#include "SkTime.h" 1.30 +#endif 1.31 + 1.32 +#if defined SK_BUILD_FOR_WIN32 && defined SK_DEBUG 1.33 + #define _static 1.34 + extern const char gMathPrimerText[]; 1.35 + extern const char gMathPrimerBinary[]; 1.36 +#else 1.37 + #define _static static 1.38 +#endif 1.39 + 1.40 +_static const char gMathPrimerText[] = 1.41 +"<screenplay>" 1.42 + "<Math id=\"Math\"/>" 1.43 + "<Number id=\"Number\"/>" 1.44 +"</screenplay>"; 1.45 + 1.46 +#define gMathPrimer gMathPrimerText 1.47 + 1.48 +SkAnimator::SkAnimator() : fMaker(NULL) { 1.49 + initialize(); 1.50 +} 1.51 + 1.52 +SkAnimator::~SkAnimator() { 1.53 + SkDELETE(fMaker); 1.54 +} 1.55 + 1.56 +void SkAnimator::addExtras(SkExtras* extras) { 1.57 + *fMaker->fExtras.append() = extras; 1.58 +} 1.59 + 1.60 +bool SkAnimator::appendStream(SkStream* stream) { 1.61 + return decodeStream(stream); 1.62 +} 1.63 + 1.64 +bool SkAnimator::decodeMemory(const void* buffer, size_t size) 1.65 +{ 1.66 + fMaker->fFileName.reset(); 1.67 + SkDisplayXMLParser parser(*fMaker); 1.68 + return parser.parse((const char*)buffer, size); 1.69 +} 1.70 + 1.71 +bool SkAnimator::decodeStream(SkStream* stream) 1.72 +{ 1.73 + SkDisplayXMLParser parser(*fMaker); 1.74 + bool result = parser.parse(*stream); 1.75 + fMaker->setErrorString(); 1.76 + return result; 1.77 +} 1.78 + 1.79 +bool SkAnimator::decodeDOM(const SkDOM& dom, const SkDOMNode* node) 1.80 +{ 1.81 + fMaker->fFileName.reset(); 1.82 + SkDisplayXMLParser parser(*fMaker); 1.83 + return parser.parse(dom, node); 1.84 +} 1.85 + 1.86 +bool SkAnimator::decodeURI(const char uri[]) { 1.87 +// SkDebugf("animator decode %s\n", uri); 1.88 + 1.89 +// SkStream* stream = SkStream::GetURIStream(fMaker->fPrefix.c_str(), uri); 1.90 + SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(uri)); 1.91 + if (stream.get()) { 1.92 + this->setURIBase(uri); 1.93 + return decodeStream(stream); 1.94 + } else { 1.95 + return false; 1.96 + } 1.97 +} 1.98 + 1.99 +bool SkAnimator::doCharEvent(SkUnichar code) { 1.100 + if (code == 0) 1.101 + return false; 1.102 + struct SkEventState state; 1.103 + state.fCode = code; 1.104 + fMaker->fEnableTime = fMaker->getAppTime(); 1.105 + bool result = fMaker->fEvents.doEvent(*fMaker, SkDisplayEvent::kKeyChar, &state); 1.106 + fMaker->notifyInval(); 1.107 + return result; 1.108 +} 1.109 + 1.110 +bool SkAnimator::doClickEvent(int clickState, SkScalar x, SkScalar y) { 1.111 + SkASSERT(clickState >= 0 && clickState <= 2); 1.112 + struct SkEventState state; 1.113 + state.fX = x; 1.114 + state.fY = y; 1.115 + fMaker->fEnableTime = fMaker->getAppTime(); 1.116 + bool result = fMaker->fEvents.doEvent(*fMaker, 1.117 + clickState == 0 ? SkDisplayEvent::kMouseDown : 1.118 + clickState == 1 ? SkDisplayEvent::kMouseDrag : 1.119 + SkDisplayEvent::kMouseUp, &state); 1.120 + fMaker->notifyInval(); 1.121 + return result; 1.122 +} 1.123 + 1.124 +bool SkAnimator::doKeyEvent(SkKey code) { 1.125 + if (code == 0) 1.126 + return false; 1.127 + struct SkEventState state; 1.128 + state.fCode = code; 1.129 + fMaker->fEnableTime = fMaker->getAppTime(); 1.130 + bool result = fMaker->fEvents.doEvent(*fMaker, SkDisplayEvent::kKeyPress, &state); 1.131 + fMaker->notifyInval(); 1.132 + return result; 1.133 +} 1.134 + 1.135 +bool SkAnimator::doKeyUpEvent(SkKey code) { 1.136 + if (code == 0) 1.137 + return false; 1.138 + struct SkEventState state; 1.139 + state.fCode = code; 1.140 + fMaker->fEnableTime = fMaker->getAppTime(); 1.141 + bool result = fMaker->fEvents.doEvent(*fMaker, SkDisplayEvent::kKeyPressUp, &state); 1.142 + fMaker->notifyInval(); 1.143 + return result; 1.144 +} 1.145 + 1.146 +bool SkAnimator::doUserEvent(const SkEvent& evt) { 1.147 + fMaker->fEnableTime = fMaker->getAppTime(); 1.148 + return onEvent(evt); 1.149 +} 1.150 + 1.151 +SkAnimator::DifferenceType SkAnimator::draw(SkCanvas* canvas, SkPaint* paint, SkMSec time) { 1.152 + if (paint == NULL) 1.153 + return draw(canvas, time); 1.154 + fMaker->fScreenplay.time = time; 1.155 + fMaker->fCanvas = canvas; 1.156 + fMaker->fPaint = paint; 1.157 + fMaker->fDisplayList.fHasUnion = false; 1.158 + int result = fMaker->fDisplayList.draw(*fMaker, time); 1.159 + if (result) 1.160 + result += fMaker->fDisplayList.fHasUnion; 1.161 + return (DifferenceType) result; 1.162 +} 1.163 + 1.164 +SkAnimator::DifferenceType SkAnimator::draw(SkCanvas* canvas, SkMSec time) { 1.165 + SkPaint paint; 1.166 + return draw(canvas, &paint, time); 1.167 +} 1.168 + 1.169 +#ifdef SK_DEBUG 1.170 +void SkAnimator::eventDone(const SkEvent& ) { 1.171 +} 1.172 +#endif 1.173 + 1.174 +bool SkAnimator::findClickEvent(SkScalar x, SkScalar y) { 1.175 + struct SkEventState state; 1.176 + state.fDisable = true; 1.177 + state.fX = x; 1.178 + state.fY = y; 1.179 + fMaker->fEnableTime = fMaker->getAppTime(); 1.180 + bool result = fMaker->fEvents.doEvent(*fMaker, SkDisplayEvent::kMouseDown, &state); 1.181 + fMaker->notifyInval(); 1.182 + return result; 1.183 +} 1.184 + 1.185 +const SkAnimator* SkAnimator::getAnimator(const SkDisplayable* displayable) const { 1.186 + if (displayable->getType() != SkType_Movie) 1.187 + return NULL; 1.188 + const SkDisplayMovie* movie = (const SkDisplayMovie*) displayable; 1.189 + return movie->getAnimator(); 1.190 +} 1.191 + 1.192 +const SkDisplayable* SkAnimator::getElement(const char* id) { 1.193 + SkDisplayable* element; 1.194 + if (fMaker->find(id, &element) == false) 1.195 + return NULL; 1.196 + return (const SkDisplayable*) element; 1.197 +} 1.198 + 1.199 +SkElementType SkAnimator::getElementType(const SkDisplayable* ae) { 1.200 + SkDisplayable* element = (SkDisplayable*) ae; 1.201 + const SkMemberInfo* info = SkDisplayType::GetMembers(fMaker, element->getType(), NULL); 1.202 + return (SkElementType) SkDisplayType::Find(fMaker, info); 1.203 +} 1.204 + 1.205 +SkElementType SkAnimator::getElementType(const char* id) { 1.206 + const SkDisplayable* element = getElement(id); 1.207 + return getElementType(element); 1.208 +} 1.209 + 1.210 +const SkMemberInfo* SkAnimator::getField(const SkDisplayable* ae, const char* field) { 1.211 + SkDisplayable* element = (SkDisplayable*) ae; 1.212 + const SkMemberInfo* info = element->getMember(field); 1.213 + return (const SkMemberInfo*) info; 1.214 +} 1.215 + 1.216 +const SkMemberInfo* SkAnimator::getField(const char* elementID, const char* field) { 1.217 + const SkDisplayable* element = getElement(elementID); 1.218 + return getField(element, field); 1.219 +} 1.220 + 1.221 +SkFieldType SkAnimator::getFieldType(const SkMemberInfo* ai) { 1.222 + const SkMemberInfo* info = (const SkMemberInfo*) ai; 1.223 + return (SkFieldType) info->getType(); 1.224 +} 1.225 + 1.226 +SkFieldType SkAnimator::getFieldType(const char* id, const char* fieldID) { 1.227 + const SkMemberInfo* field = getField(id, fieldID); 1.228 + return getFieldType(field); 1.229 +} 1.230 + 1.231 +static bool getArrayCommon(const SkDisplayable* ae, const SkMemberInfo* ai, 1.232 + int index, SkOperand* operand) { 1.233 + const SkDisplayable* element = (const SkDisplayable*) ae; 1.234 + const SkMemberInfo* info = (const SkMemberInfo*) ai; 1.235 + SkASSERT(info->fType == SkType_Array); 1.236 + return info->getArrayValue(element, index, operand); 1.237 +} 1.238 + 1.239 +int32_t SkAnimator::getArrayInt(const SkDisplayable* ae, 1.240 + const SkMemberInfo* ai, int index) { 1.241 + SkOperand operand; 1.242 + bool result = getArrayCommon(ae, ai, index, &operand); 1.243 + return result ? operand.fS32 : SK_NaN32; 1.244 +} 1.245 + 1.246 +int32_t SkAnimator::getArrayInt(const char* id, const char* fieldID, int index) { 1.247 + const SkDisplayable* element = getElement(id); 1.248 + if (element == NULL) 1.249 + return SK_NaN32; 1.250 + const SkMemberInfo* field = getField(element, fieldID); 1.251 + if (field == NULL) 1.252 + return SK_NaN32; 1.253 + return getArrayInt(element, field, index); 1.254 +} 1.255 + 1.256 +SkScalar SkAnimator::getArrayScalar(const SkDisplayable* ae, 1.257 + const SkMemberInfo* ai, int index) { 1.258 + SkOperand operand; 1.259 + bool result = getArrayCommon(ae, ai, index, &operand); 1.260 + return result ? operand.fScalar : SK_ScalarNaN; 1.261 +} 1.262 + 1.263 +SkScalar SkAnimator::getArrayScalar(const char* id, const char* fieldID, int index) { 1.264 + const SkDisplayable* element = getElement(id); 1.265 + if (element == NULL) 1.266 + return SK_ScalarNaN; 1.267 + const SkMemberInfo* field = getField(element, fieldID); 1.268 + if (field == NULL) 1.269 + return SK_ScalarNaN; 1.270 + return getArrayScalar(element, field, index); 1.271 +} 1.272 + 1.273 +const char* SkAnimator::getArrayString(const SkDisplayable* ae, 1.274 + const SkMemberInfo* ai, int index) { 1.275 + SkOperand operand; 1.276 + bool result = getArrayCommon(ae, ai, index, &operand); 1.277 + return result ? operand.fString->c_str() : NULL; 1.278 +} 1.279 + 1.280 +const char* SkAnimator::getArrayString(const char* id, const char* fieldID, int index) { 1.281 + const SkDisplayable* element = getElement(id); 1.282 + if (element == NULL) 1.283 + return NULL; 1.284 + const SkMemberInfo* field = getField(element, fieldID); 1.285 + if (field == NULL) 1.286 + return NULL; 1.287 + return getArrayString(element, field, index); 1.288 +} 1.289 + 1.290 +SkMSec SkAnimator::getInterval() { 1.291 + return fMaker->fMinimumInterval == (SkMSec) -1 ? 0 : fMaker->fMinimumInterval; 1.292 +} 1.293 + 1.294 +void SkAnimator::getInvalBounds(SkRect* inval) { 1.295 + if (fMaker->fDisplayList.fHasUnion) { 1.296 + inval->fLeft = SkIntToScalar(fMaker->fDisplayList.fInvalBounds.fLeft); 1.297 + inval->fTop = SkIntToScalar(fMaker->fDisplayList.fInvalBounds.fTop); 1.298 + inval->fRight = SkIntToScalar(fMaker->fDisplayList.fInvalBounds.fRight); 1.299 + inval->fBottom = SkIntToScalar(fMaker->fDisplayList.fInvalBounds.fBottom); 1.300 + } else { 1.301 + inval->fLeft = inval->fTop = -SK_ScalarMax; 1.302 + inval->fRight = inval->fBottom = SK_ScalarMax; 1.303 + } 1.304 +} 1.305 + 1.306 +const SkXMLParserError* SkAnimator::getParserError() { 1.307 + return &fMaker->fError; 1.308 +} 1.309 + 1.310 +const char* SkAnimator::getParserErrorString() { 1.311 + if (fMaker->fErrorString.size() == 0 && fMaker->fError.hasError()) 1.312 + fMaker->setErrorString(); 1.313 + return fMaker->fErrorString.c_str(); 1.314 +} 1.315 + 1.316 +int32_t SkAnimator::getInt(const SkDisplayable* element, const SkMemberInfo* info) { 1.317 + if (info->fType != SkType_MemberProperty) { 1.318 + SkOperand operand; 1.319 + if (info->getType() == SkType_Int) { 1.320 + info->getValue(element, &operand, 1); 1.321 + return operand.fS32; 1.322 + } 1.323 + return SK_NaN32; 1.324 + } 1.325 + SkScriptValue scriptValue; 1.326 + bool success = element->getProperty(info->propertyIndex(), &scriptValue); 1.327 + if (success && scriptValue.fType == SkType_Int) 1.328 + return scriptValue.fOperand.fS32; 1.329 + return SK_NaN32; 1.330 +} 1.331 + 1.332 +int32_t SkAnimator::getInt(const char* id, const char* fieldID) { 1.333 + const SkDisplayable* element = getElement(id); 1.334 + if (element == NULL) 1.335 + return SK_NaN32; 1.336 + const SkMemberInfo* field = getField(element, fieldID); 1.337 + if (field == NULL) 1.338 + return SK_NaN32; 1.339 + return getInt(element, field); 1.340 +} 1.341 + 1.342 +SkScalar SkAnimator::getScalar(const SkDisplayable* element, const SkMemberInfo* info) { 1.343 + if (info->fType != SkType_MemberProperty) { 1.344 + SkOperand operand; 1.345 + if (info->getType() == SkType_Float) { 1.346 + info->getValue(element, &operand, 1); 1.347 + return operand.fScalar; 1.348 + } 1.349 + return SK_ScalarNaN; 1.350 + } 1.351 + SkScriptValue scriptValue; 1.352 + bool success = element->getProperty(info->propertyIndex(), &scriptValue); 1.353 + if (success && scriptValue.fType == SkType_Float) 1.354 + return scriptValue.fOperand.fScalar; 1.355 + return SK_ScalarNaN; 1.356 +} 1.357 + 1.358 +SkScalar SkAnimator::getScalar(const char* id, const char* fieldID) { 1.359 + const SkDisplayable* element = getElement(id); 1.360 + if (element == NULL) 1.361 + return SK_ScalarNaN; 1.362 + const SkMemberInfo* field = getField(element, fieldID); 1.363 + if (field == NULL) 1.364 + return SK_ScalarNaN; 1.365 + return getScalar(element, field); 1.366 +} 1.367 + 1.368 +const char* SkAnimator::getString(const SkDisplayable* ae, 1.369 + const SkMemberInfo* ai) { 1.370 + const SkDisplayable* element = (const SkDisplayable*) ae; 1.371 + const SkMemberInfo* info = (const SkMemberInfo*) ai; 1.372 + SkString* temp; 1.373 + info->getString(element, &temp); 1.374 + return temp->c_str(); 1.375 +} 1.376 + 1.377 +const char* SkAnimator::getString(const char* id, const char* fieldID) { 1.378 + const SkDisplayable* element = getElement(id); 1.379 + if (element == NULL) 1.380 + return NULL; 1.381 + const SkMemberInfo* field = getField(element, fieldID); 1.382 + if (field == NULL) 1.383 + return NULL; 1.384 + return getString(element, field); 1.385 +} 1.386 + 1.387 +const char* SkAnimator::getURIBase() { 1.388 + return fMaker->fPrefix.c_str(); 1.389 +} 1.390 + 1.391 +void SkAnimator::initialize() { 1.392 + SkDELETE(fMaker); 1.393 + fMaker = SkNEW_ARGS(SkAnimateMaker, (this, NULL, NULL)); 1.394 + decodeMemory(gMathPrimer, sizeof(gMathPrimer)-1); 1.395 +#ifdef SK_BUILD_FOR_ANDROID 1.396 + InitializeSkExtraPathEffects(this); 1.397 +#endif 1.398 +} 1.399 + 1.400 + 1.401 +#ifdef SK_DEBUG 1.402 +bool SkAnimator::isTrackingEvents() { 1.403 + return false; 1.404 +} 1.405 +#endif 1.406 + 1.407 +bool SkAnimator::onEvent(const SkEvent& evt) { 1.408 +#ifdef SK_DEBUG 1.409 + SkAnimator* root = fMaker->getRoot(); 1.410 + if (root == NULL) 1.411 + root = this; 1.412 + if (root->isTrackingEvents()) 1.413 + root->eventDone(evt); 1.414 +#endif 1.415 + if (evt.isType(SK_EventType_OnEnd)) { 1.416 + SkEventState eventState; 1.417 + SkDEBUGCODE(bool success =) evt.findPtr("anim", (void**) &eventState.fDisplayable); 1.418 + SkASSERT(success); 1.419 + SkDEBUGCODE(success =) evt.findS32("time", (int32_t*) &fMaker->fEnableTime); 1.420 + SkASSERT(success); 1.421 + fMaker->fAdjustedStart = fMaker->getAppTime() - fMaker->fEnableTime; 1.422 + fMaker->fEvents.doEvent(*fMaker, SkDisplayEvent::kOnEnd, &eventState); 1.423 + fMaker->fAdjustedStart = 0; 1.424 + goto inval; 1.425 + } 1.426 + if (evt.isType(SK_EventType_Delay)) { 1.427 + fMaker->doDelayedEvent(); 1.428 + goto inval; 1.429 + } 1.430 + { 1.431 + const char* id = evt.findString("id"); 1.432 + if (id == NULL) 1.433 + return false; 1.434 + SkDisplayable** firstMovie = fMaker->fMovies.begin(); 1.435 + SkDisplayable** endMovie = fMaker->fMovies.end(); 1.436 + for (SkDisplayable** ptr = firstMovie; ptr < endMovie; ptr++) { 1.437 + SkDisplayMovie* movie = (SkDisplayMovie*) *ptr; 1.438 + movie->doEvent(evt); 1.439 + } 1.440 + { 1.441 + SkDisplayable* event; 1.442 + if (fMaker->find(id, &event) == false) 1.443 + return false; 1.444 + #if defined SK_DEBUG && defined SK_DEBUG_ANIMATION_TIMING 1.445 + SkString debugOut; 1.446 + SkMSec realTime = fMaker->getAppTime(); 1.447 + debugOut.appendS32(realTime - fMaker->fDebugTimeBase); 1.448 + debugOut.append(" onEvent id="); 1.449 + debugOut.append(id); 1.450 + #endif 1.451 + SkMSec time = evt.getFast32(); 1.452 + if (time != 0) { 1.453 + SkMSec app = fMaker->getAppTime(); 1.454 + fMaker->setEnableTime(app, time); 1.455 + #if defined SK_DEBUG && defined SK_DEBUG_ANIMATION_TIMING 1.456 + debugOut.append(" time="); 1.457 + debugOut.appendS32(time - fMaker->fDebugTimeBase); 1.458 + debugOut.append(" adjust="); 1.459 + debugOut.appendS32(fMaker->fAdjustedStart); 1.460 + #endif 1.461 + } 1.462 + #if defined SK_DEBUG && defined SK_DEBUG_ANIMATION_TIMING 1.463 + SkDebugf("%s\n", debugOut.c_str()); 1.464 + #endif 1.465 + SkASSERT(event->isEvent()); 1.466 + SkDisplayEvent* displayEvent = (SkDisplayEvent*) event; 1.467 + displayEvent->populateInput(*fMaker, evt); 1.468 + displayEvent->enableEvent(*fMaker); 1.469 + } 1.470 + } 1.471 +inval: 1.472 + fMaker->notifyInval(); 1.473 + return true; 1.474 +} 1.475 + 1.476 +void SkAnimator::onEventPost(SkEvent* evt, SkEventSinkID sinkID) 1.477 +{ 1.478 +#ifdef SK_DEBUG 1.479 + SkAnimator* root = fMaker->getRoot(); 1.480 + if (root) { 1.481 + root->onEventPost(evt, sinkID); 1.482 + return; 1.483 + } 1.484 +#else 1.485 + SkASSERT(sinkID == this->getSinkID() || this->getHostEventSinkID() == sinkID); 1.486 +#endif 1.487 + evt->setTargetID(sinkID)->post(); 1.488 +} 1.489 + 1.490 +void SkAnimator::onEventPostTime(SkEvent* evt, SkEventSinkID sinkID, SkMSec time) 1.491 +{ 1.492 +#ifdef SK_DEBUG 1.493 + SkAnimator* root = fMaker->getRoot(); 1.494 + if (root) { 1.495 + root->onEventPostTime(evt, sinkID, time); 1.496 + return; 1.497 + } 1.498 +#else 1.499 + SkASSERT(sinkID == this->getSinkID() || this->getHostEventSinkID() == sinkID); 1.500 +#endif 1.501 + evt->setTargetID(sinkID)->postTime(time); 1.502 +} 1.503 + 1.504 +void SkAnimator::reset() { 1.505 + fMaker->fDisplayList.reset(); 1.506 +} 1.507 + 1.508 +SkEventSinkID SkAnimator::getHostEventSinkID() const { 1.509 + return fMaker->fHostEventSinkID; 1.510 +} 1.511 + 1.512 +void SkAnimator::setHostEventSinkID(SkEventSinkID target) { 1.513 + fMaker->fHostEventSinkID = target; 1.514 +} 1.515 + 1.516 +void SkAnimator::onSetHostHandler(Handler ) { 1.517 +} 1.518 + 1.519 +void SkAnimator::setJavaOwner(Handler ) { 1.520 +} 1.521 + 1.522 +bool SkAnimator::setArrayString(const char* id, const char* fieldID, const char** array, int num) 1.523 +{ 1.524 + SkTypedArray tArray(SkType_String); 1.525 + tArray.setCount(num); 1.526 + for (int i = 0; i < num; i++) { 1.527 + SkOperand op; 1.528 + op.fString = new SkString(array[i]); 1.529 + tArray[i] = op; 1.530 + } 1.531 + return setArray(id, fieldID, tArray); 1.532 +} 1.533 +bool SkAnimator::setArrayInt(const char* id, const char* fieldID, const int* array, int num) 1.534 +{ 1.535 + SkTypedArray tArray(SkType_Int); 1.536 + tArray.setCount(num); 1.537 + for (int i = 0; i < num; i++) { 1.538 + SkOperand op; 1.539 + op.fS32 = array[i]; 1.540 + tArray[i] = op; 1.541 + } 1.542 + return setArray(id, fieldID, tArray); 1.543 +} 1.544 + 1.545 +bool SkAnimator::setArray(SkDisplayable* element, const SkMemberInfo* info, SkTypedArray array) { 1.546 + if (info->fType != SkType_Array) 1.547 + return false; //the field is not an array 1.548 + //i think we can handle the case where the displayable itself is an array differently from the 1.549 + //case where it has an array - for one thing, if it is an array, i think we can change its type 1.550 + //if it's not, we cannot 1.551 + SkDisplayTypes type = element->getType(); 1.552 + if (type == SkType_Array) { 1.553 + SkDisplayArray* dispArray = (SkDisplayArray*) element; 1.554 + dispArray->values = array; 1.555 + return true; 1.556 + } 1.557 + else 1.558 + return false; //currently i don't care about this case 1.559 +} 1.560 + 1.561 +bool SkAnimator::setArray(const char* id, const char* fieldID, SkTypedArray array) { 1.562 + SkDisplayable* element = (SkDisplayable*) getElement(id); 1.563 + //should I go ahead and change all 'NULL's to 'NULL'? 1.564 + if (element == NULL) 1.565 + return false; 1.566 + const SkMemberInfo* field = getField(element, fieldID); 1.567 + if (field == NULL) 1.568 + return false; 1.569 + return setArray(element, field, array); 1.570 +} 1.571 + 1.572 +bool SkAnimator::setInt(SkDisplayable* element, const SkMemberInfo* info, int32_t s32) { 1.573 + if (info->fType != SkType_MemberProperty) { 1.574 + SkOperand operand; 1.575 + operand.fS32 = s32; 1.576 + SkASSERT(info->getType() == SkType_Int); 1.577 + info->setValue(element, &operand, 1); 1.578 + } else { 1.579 + SkScriptValue scriptValue; 1.580 + scriptValue.fType = SkType_Int; 1.581 + scriptValue.fOperand.fS32 = s32; 1.582 + element->setProperty(info->propertyIndex(), scriptValue); 1.583 + } 1.584 + return true; 1.585 +} 1.586 + 1.587 +bool SkAnimator::setInt(const char* id, const char* fieldID, int32_t s32) { 1.588 + SkDisplayable* element = (SkDisplayable*) getElement(id); 1.589 + if (element == NULL) 1.590 + return false; 1.591 + const SkMemberInfo* field = getField(element, fieldID); 1.592 + if (field == NULL) 1.593 + return false; 1.594 + return setInt(element, field, s32); 1.595 +} 1.596 + 1.597 +bool SkAnimator::setScalar(SkDisplayable* element, const SkMemberInfo* info, SkScalar scalar) { 1.598 + if (info->fType != SkType_MemberProperty) { 1.599 + SkOperand operand; 1.600 + operand.fScalar = scalar; 1.601 + SkASSERT(info->getType() == SkType_Float); 1.602 + info->setValue(element, &operand, 1); 1.603 + } else { 1.604 + SkScriptValue scriptValue; 1.605 + scriptValue.fType = SkType_Float; 1.606 + scriptValue.fOperand.fScalar = scalar; 1.607 + element->setProperty(info->propertyIndex(), scriptValue); 1.608 + } 1.609 + return true; 1.610 +} 1.611 + 1.612 +bool SkAnimator::setScalar(const char* id, const char* fieldID, SkScalar scalar) { 1.613 + SkDisplayable* element = (SkDisplayable*) getElement(id); 1.614 + if (element == NULL) 1.615 + return false; 1.616 + const SkMemberInfo* field = getField(element, fieldID); 1.617 + if (field == NULL) 1.618 + return false; 1.619 + return setScalar(element, field, scalar); 1.620 +} 1.621 + 1.622 +bool SkAnimator::setString(SkDisplayable* element, 1.623 + const SkMemberInfo* info, const char* str) { 1.624 + // !!! until this is fixed, can't call script with global references from here 1.625 + info->setValue(*fMaker, NULL, 0, info->fCount, element, info->getType(), str, strlen(str)); 1.626 + return true; 1.627 +} 1.628 + 1.629 +bool SkAnimator::setString(const char* id, const char* fieldID, const char* str) { 1.630 + SkDisplayable* element = (SkDisplayable*) getElement(id); 1.631 + if (element == NULL) 1.632 + return false; 1.633 + const SkMemberInfo* field = getField(element, fieldID); 1.634 + if (field == NULL) 1.635 + return false; 1.636 + return setString(element, field, str); 1.637 +} 1.638 + 1.639 +void SkAnimator::setTimeline(const Timeline& timeline) { 1.640 + fMaker->fTimeline = &timeline; 1.641 +} 1.642 + 1.643 +void SkAnimator::setURIBase(const char* uri) { 1.644 + if (uri) 1.645 + { 1.646 + const char* tail = strrchr(uri, '/'); 1.647 + if (tail) { 1.648 + SkString prefix(uri, tail - uri + 1); 1.649 + if (uri[0] != '.' /*SkStream::IsAbsoluteURI(uri)*/) 1.650 + fMaker->fPrefix.reset(); 1.651 + fMaker->fPrefix.append(prefix); 1.652 + fMaker->fFileName.set(tail + 1); 1.653 + } else 1.654 + fMaker->fFileName.set(uri); 1.655 + } 1.656 +} 1.657 + 1.658 +#ifdef SK_DEBUG 1.659 +bool SkAnimator::NoLeaks() { 1.660 +#ifdef SK_BUILD_FOR_MAC 1.661 + if (SkDisplayable::fAllocations.count() == 0) 1.662 + return true; 1.663 +// return SkDisplayable::fAllocationCount == 0; 1.664 + SkDebugf("!!! leaked %d displayables:\n", SkDisplayable::fAllocations.count()); 1.665 + for (SkDisplayable** leak = SkDisplayable::fAllocations.begin(); leak < SkDisplayable::fAllocations.end(); leak++) 1.666 + SkDebugf("%08x %s\n", *leak, (*leak)->id); 1.667 +#endif 1.668 + return false; 1.669 +} 1.670 +#endif 1.671 + 1.672 +#ifdef SK_SUPPORT_UNITTEST 1.673 +#include "SkAnimatorScript.h" 1.674 +#include "SkBase64.h" 1.675 +#include "SkParse.h" 1.676 +#include "SkMemberInfo.h" 1.677 + 1.678 +#define unittestline(type) { #type , type::UnitTest } 1.679 +#endif 1.680 + 1.681 + 1.682 +#ifdef SK_SUPPORT_UNITTEST 1.683 +void SkAnimator::Init(bool runUnitTests) { 1.684 + if (runUnitTests == false) 1.685 + return; 1.686 + static const struct { 1.687 + const char* fTypeName; 1.688 + void (*fUnitTest)( ); 1.689 + } gUnitTests[] = { 1.690 + unittestline(SkBase64), 1.691 + unittestline(SkDisplayType), 1.692 + unittestline(SkParse), 1.693 + unittestline(SkScriptEngine), 1.694 +// unittestline(SkScriptEngine2), // compiled script experiment 1.695 + unittestline(SkAnimatorScript) 1.696 + }; 1.697 + for (int i = 0; i < (int)SK_ARRAY_COUNT(gUnitTests); i++) 1.698 + { 1.699 + SkDebugf("SkAnimator: Running UnitTest for %s\n", gUnitTests[i].fTypeName); 1.700 + gUnitTests[i].fUnitTest(); 1.701 + SkDebugf("SkAnimator: End UnitTest for %s\n", gUnitTests[i].fTypeName); 1.702 + } 1.703 +} 1.704 +#else 1.705 +void SkAnimator::Init(bool) {} 1.706 +#endif 1.707 + 1.708 +void SkAnimator::Term() { 1.709 +}