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

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     2 /*
     3  * Copyright 2006 The Android Open Source Project
     4  *
     5  * Use of this source code is governed by a BSD-style license that can be
     6  * found in the LICENSE file.
     7  */
    10 #include "SkAnimator.h"
    11 #include "SkAnimateMaker.h"
    12 #include "SkCanvas.h"
    13 #include "SkDisplayApply.h"
    14 #include "SkDisplayMovie.h"
    15 #include "SkDisplayTypes.h"
    16 #include "SkDisplayXMLParser.h"
    17 #include "SkStream.h"
    18 #include "SkScript.h"
    19 #include "SkScript2.h" //   compiled script experiment
    20 #include "SkSystemEventTypes.h"
    21 #include "SkTypedArray.h"
    22 #ifdef SK_BUILD_FOR_ANDROID
    23 #include "SkDrawExtraPathEffect.h"
    24 #endif
    25 #ifdef SK_DEBUG
    26 #include "SkTime.h"
    27 #endif
    29 #if defined SK_BUILD_FOR_WIN32 && defined SK_DEBUG
    30     #define _static
    31     extern const char gMathPrimerText[];
    32     extern const char gMathPrimerBinary[];
    33 #else
    34     #define _static static
    35 #endif
    37 _static const char gMathPrimerText[] =
    38 "<screenplay>"
    39     "<Math id=\"Math\"/>"
    40     "<Number id=\"Number\"/>"
    41 "</screenplay>";
    43 #define gMathPrimer gMathPrimerText
    45 SkAnimator::SkAnimator() : fMaker(NULL) {
    46     initialize();
    47 }
    49 SkAnimator::~SkAnimator() {
    50     SkDELETE(fMaker);
    51 }
    53 void SkAnimator::addExtras(SkExtras* extras) {
    54     *fMaker->fExtras.append() = extras;
    55 }
    57 bool SkAnimator::appendStream(SkStream* stream) {
    58     return decodeStream(stream);
    59 }
    61 bool SkAnimator::decodeMemory(const void* buffer, size_t size)
    62 {
    63     fMaker->fFileName.reset();
    64     SkDisplayXMLParser parser(*fMaker);
    65     return parser.parse((const char*)buffer, size);
    66 }
    68 bool SkAnimator::decodeStream(SkStream* stream)
    69 {
    70     SkDisplayXMLParser parser(*fMaker);
    71     bool result = parser.parse(*stream);
    72     fMaker->setErrorString();
    73     return result;
    74 }
    76 bool SkAnimator::decodeDOM(const SkDOM& dom, const SkDOMNode* node)
    77 {
    78     fMaker->fFileName.reset();
    79     SkDisplayXMLParser parser(*fMaker);
    80     return parser.parse(dom, node);
    81 }
    83 bool SkAnimator::decodeURI(const char uri[]) {
    84 //  SkDebugf("animator decode %s\n", uri);
    86 //    SkStream* stream = SkStream::GetURIStream(fMaker->fPrefix.c_str(), uri);
    87     SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(uri));
    88     if (stream.get()) {
    89         this->setURIBase(uri);
    90         return decodeStream(stream);
    91     } else {
    92         return false;
    93     }
    94 }
    96 bool SkAnimator::doCharEvent(SkUnichar code) {
    97     if (code == 0)
    98         return false;
    99     struct SkEventState state;
   100     state.fCode = code;
   101     fMaker->fEnableTime = fMaker->getAppTime();
   102     bool result = fMaker->fEvents.doEvent(*fMaker, SkDisplayEvent::kKeyChar, &state);
   103     fMaker->notifyInval();
   104     return result;
   105 }
   107 bool SkAnimator::doClickEvent(int clickState, SkScalar x, SkScalar y) {
   108     SkASSERT(clickState >= 0 && clickState <= 2);
   109     struct SkEventState state;
   110     state.fX = x;
   111     state.fY = y;
   112     fMaker->fEnableTime = fMaker->getAppTime();
   113     bool result = fMaker->fEvents.doEvent(*fMaker,
   114         clickState == 0 ? SkDisplayEvent::kMouseDown :
   115         clickState == 1 ? SkDisplayEvent::kMouseDrag :
   116         SkDisplayEvent::kMouseUp, &state);
   117     fMaker->notifyInval();
   118     return result;
   119 }
   121 bool SkAnimator::doKeyEvent(SkKey code) {
   122     if (code == 0)
   123         return false;
   124     struct SkEventState state;
   125     state.fCode = code;
   126     fMaker->fEnableTime = fMaker->getAppTime();
   127     bool result = fMaker->fEvents.doEvent(*fMaker, SkDisplayEvent::kKeyPress, &state);
   128     fMaker->notifyInval();
   129     return result;
   130 }
   132 bool SkAnimator::doKeyUpEvent(SkKey code) {
   133     if (code == 0)
   134         return false;
   135     struct SkEventState state;
   136     state.fCode = code;
   137     fMaker->fEnableTime = fMaker->getAppTime();
   138     bool result = fMaker->fEvents.doEvent(*fMaker, SkDisplayEvent::kKeyPressUp, &state);
   139     fMaker->notifyInval();
   140     return result;
   141 }
   143 bool SkAnimator::doUserEvent(const SkEvent& evt) {
   144     fMaker->fEnableTime = fMaker->getAppTime();
   145     return onEvent(evt);
   146 }
   148 SkAnimator::DifferenceType SkAnimator::draw(SkCanvas* canvas, SkPaint* paint, SkMSec time) {
   149     if (paint == NULL)
   150         return draw(canvas, time);
   151     fMaker->fScreenplay.time = time;
   152     fMaker->fCanvas = canvas;
   153     fMaker->fPaint = paint;
   154     fMaker->fDisplayList.fHasUnion = false;
   155     int result = fMaker->fDisplayList.draw(*fMaker, time);
   156     if (result)
   157         result += fMaker->fDisplayList.fHasUnion;
   158     return (DifferenceType) result;
   159 }
   161 SkAnimator::DifferenceType SkAnimator::draw(SkCanvas* canvas, SkMSec time) {
   162     SkPaint paint;
   163     return draw(canvas, &paint, time);
   164 }
   166 #ifdef SK_DEBUG
   167 void SkAnimator::eventDone(const SkEvent& ) {
   168 }
   169 #endif
   171 bool SkAnimator::findClickEvent(SkScalar x, SkScalar y) {
   172     struct SkEventState state;
   173     state.fDisable = true;
   174     state.fX = x;
   175     state.fY = y;
   176     fMaker->fEnableTime = fMaker->getAppTime();
   177     bool result = fMaker->fEvents.doEvent(*fMaker, SkDisplayEvent::kMouseDown, &state);
   178     fMaker->notifyInval();
   179     return result;
   180 }
   182 const SkAnimator* SkAnimator::getAnimator(const SkDisplayable* displayable) const {
   183     if (displayable->getType() != SkType_Movie)
   184         return NULL;
   185     const SkDisplayMovie* movie = (const SkDisplayMovie*) displayable;
   186     return movie->getAnimator();
   187 }
   189 const SkDisplayable* SkAnimator::getElement(const char* id) {
   190     SkDisplayable* element;
   191     if (fMaker->find(id, &element) == false)
   192         return NULL;
   193     return (const SkDisplayable*) element;
   194 }
   196 SkElementType SkAnimator::getElementType(const SkDisplayable* ae) {
   197     SkDisplayable* element = (SkDisplayable*) ae;
   198     const SkMemberInfo* info = SkDisplayType::GetMembers(fMaker, element->getType(), NULL);
   199     return (SkElementType) SkDisplayType::Find(fMaker, info);
   200 }
   202 SkElementType SkAnimator::getElementType(const char* id) {
   203     const SkDisplayable* element = getElement(id);
   204     return getElementType(element);
   205 }
   207 const SkMemberInfo* SkAnimator::getField(const SkDisplayable* ae, const char* field) {
   208     SkDisplayable* element = (SkDisplayable*) ae;
   209     const SkMemberInfo* info = element->getMember(field);
   210     return (const SkMemberInfo*) info;
   211 }
   213 const SkMemberInfo* SkAnimator::getField(const char* elementID, const char* field) {
   214     const SkDisplayable* element = getElement(elementID);
   215     return getField(element, field);
   216 }
   218 SkFieldType SkAnimator::getFieldType(const SkMemberInfo* ai) {
   219     const SkMemberInfo* info = (const SkMemberInfo*) ai;
   220     return (SkFieldType) info->getType();
   221 }
   223 SkFieldType SkAnimator::getFieldType(const char* id, const char* fieldID) {
   224     const SkMemberInfo* field = getField(id, fieldID);
   225     return getFieldType(field);
   226 }
   228 static bool getArrayCommon(const SkDisplayable* ae, const SkMemberInfo* ai,
   229                            int index, SkOperand* operand) {
   230     const SkDisplayable* element = (const SkDisplayable*) ae;
   231     const SkMemberInfo* info = (const SkMemberInfo*) ai;
   232     SkASSERT(info->fType == SkType_Array);
   233     return info->getArrayValue(element, index, operand);
   234 }
   236 int32_t SkAnimator::getArrayInt(const SkDisplayable* ae,
   237         const SkMemberInfo* ai, int index) {
   238     SkOperand operand;
   239     bool result = getArrayCommon(ae, ai, index, &operand);
   240     return result ? operand.fS32 : SK_NaN32;
   241 }
   243 int32_t SkAnimator::getArrayInt(const char* id, const char* fieldID, int index) {
   244     const SkDisplayable* element = getElement(id);
   245     if (element == NULL)
   246         return SK_NaN32;
   247     const SkMemberInfo* field = getField(element, fieldID);
   248     if (field == NULL)
   249         return SK_NaN32;
   250     return getArrayInt(element, field, index);
   251 }
   253 SkScalar SkAnimator::getArrayScalar(const SkDisplayable* ae,
   254         const SkMemberInfo* ai, int index) {
   255     SkOperand operand;
   256     bool result = getArrayCommon(ae, ai, index, &operand);
   257     return result ? operand.fScalar : SK_ScalarNaN;
   258 }
   260 SkScalar SkAnimator::getArrayScalar(const char* id, const char* fieldID, int index) {
   261     const SkDisplayable* element = getElement(id);
   262     if (element == NULL)
   263         return SK_ScalarNaN;
   264     const SkMemberInfo* field = getField(element, fieldID);
   265     if (field == NULL)
   266         return SK_ScalarNaN;
   267     return getArrayScalar(element, field, index);
   268 }
   270 const char* SkAnimator::getArrayString(const SkDisplayable* ae,
   271         const SkMemberInfo* ai, int index) {
   272     SkOperand operand;
   273     bool result = getArrayCommon(ae, ai, index, &operand);
   274     return result ? operand.fString->c_str() : NULL;
   275 }
   277 const char* SkAnimator::getArrayString(const char* id, const char* fieldID, int index) {
   278     const SkDisplayable* element = getElement(id);
   279     if (element == NULL)
   280         return NULL;
   281     const SkMemberInfo* field = getField(element, fieldID);
   282     if (field == NULL)
   283         return NULL;
   284     return getArrayString(element, field, index);
   285 }
   287 SkMSec SkAnimator::getInterval() {
   288     return fMaker->fMinimumInterval == (SkMSec) -1 ? 0 : fMaker->fMinimumInterval;
   289 }
   291 void SkAnimator::getInvalBounds(SkRect* inval) {
   292     if (fMaker->fDisplayList.fHasUnion) {
   293         inval->fLeft = SkIntToScalar(fMaker->fDisplayList.fInvalBounds.fLeft);
   294         inval->fTop = SkIntToScalar(fMaker->fDisplayList.fInvalBounds.fTop);
   295         inval->fRight = SkIntToScalar(fMaker->fDisplayList.fInvalBounds.fRight);
   296         inval->fBottom = SkIntToScalar(fMaker->fDisplayList.fInvalBounds.fBottom);
   297     } else {
   298         inval->fLeft = inval->fTop = -SK_ScalarMax;
   299         inval->fRight = inval->fBottom = SK_ScalarMax;
   300     }
   301 }
   303 const SkXMLParserError* SkAnimator::getParserError() {
   304     return &fMaker->fError;
   305 }
   307 const char* SkAnimator::getParserErrorString() {
   308     if (fMaker->fErrorString.size() == 0 && fMaker->fError.hasError())
   309         fMaker->setErrorString();
   310     return fMaker->fErrorString.c_str();
   311 }
   313 int32_t SkAnimator::getInt(const SkDisplayable* element, const SkMemberInfo* info) {
   314     if (info->fType != SkType_MemberProperty) {
   315         SkOperand operand;
   316         if (info->getType() == SkType_Int) {
   317             info->getValue(element, &operand, 1);
   318             return operand.fS32;
   319         }
   320         return SK_NaN32;
   321     }
   322     SkScriptValue scriptValue;
   323     bool success = element->getProperty(info->propertyIndex(), &scriptValue);
   324     if (success && scriptValue.fType == SkType_Int)
   325         return scriptValue.fOperand.fS32;
   326     return SK_NaN32;
   327 }
   329 int32_t SkAnimator::getInt(const char* id, const char* fieldID) {
   330     const SkDisplayable* element = getElement(id);
   331     if (element == NULL)
   332         return SK_NaN32;
   333     const SkMemberInfo* field = getField(element, fieldID);
   334     if (field == NULL)
   335         return SK_NaN32;
   336     return getInt(element, field);
   337 }
   339 SkScalar SkAnimator::getScalar(const SkDisplayable* element, const SkMemberInfo* info) {
   340     if (info->fType != SkType_MemberProperty) {
   341         SkOperand operand;
   342         if (info->getType() == SkType_Float) {
   343             info->getValue(element, &operand, 1);
   344             return operand.fScalar;
   345         }
   346         return SK_ScalarNaN;
   347     }
   348     SkScriptValue scriptValue;
   349     bool success = element->getProperty(info->propertyIndex(), &scriptValue);
   350     if (success && scriptValue.fType == SkType_Float)
   351         return scriptValue.fOperand.fScalar;
   352     return SK_ScalarNaN;
   353 }
   355 SkScalar SkAnimator::getScalar(const char* id, const char* fieldID) {
   356     const SkDisplayable* element = getElement(id);
   357     if (element == NULL)
   358         return SK_ScalarNaN;
   359     const SkMemberInfo* field = getField(element, fieldID);
   360     if (field == NULL)
   361         return SK_ScalarNaN;
   362     return getScalar(element, field);
   363 }
   365 const char* SkAnimator::getString(const SkDisplayable* ae,
   366         const SkMemberInfo* ai) {
   367     const SkDisplayable* element = (const SkDisplayable*) ae;
   368     const SkMemberInfo* info = (const SkMemberInfo*) ai;
   369     SkString* temp;
   370     info->getString(element, &temp);
   371     return temp->c_str();
   372 }
   374 const char* SkAnimator::getString(const char* id, const char* fieldID) {
   375     const SkDisplayable* element = getElement(id);
   376     if (element == NULL)
   377         return NULL;
   378     const SkMemberInfo* field = getField(element, fieldID);
   379     if (field == NULL)
   380         return NULL;
   381     return getString(element, field);
   382 }
   384 const char* SkAnimator::getURIBase() {
   385     return fMaker->fPrefix.c_str();
   386 }
   388 void SkAnimator::initialize() {
   389     SkDELETE(fMaker);
   390     fMaker = SkNEW_ARGS(SkAnimateMaker, (this, NULL, NULL));
   391     decodeMemory(gMathPrimer, sizeof(gMathPrimer)-1);
   392 #ifdef SK_BUILD_FOR_ANDROID
   393     InitializeSkExtraPathEffects(this);
   394 #endif
   395 }
   398 #ifdef SK_DEBUG
   399 bool SkAnimator::isTrackingEvents() {
   400     return false;
   401 }
   402 #endif
   404 bool SkAnimator::onEvent(const SkEvent& evt) {
   405 #ifdef SK_DEBUG
   406     SkAnimator* root = fMaker->getRoot();
   407     if (root == NULL)
   408         root = this;
   409     if (root->isTrackingEvents())
   410         root->eventDone(evt);
   411 #endif
   412     if (evt.isType(SK_EventType_OnEnd)) {
   413         SkEventState eventState;
   414         SkDEBUGCODE(bool success =) evt.findPtr("anim", (void**) &eventState.fDisplayable);
   415         SkASSERT(success);
   416         SkDEBUGCODE(success =) evt.findS32("time", (int32_t*) &fMaker->fEnableTime);
   417         SkASSERT(success);
   418         fMaker->fAdjustedStart = fMaker->getAppTime() - fMaker->fEnableTime;
   419         fMaker->fEvents.doEvent(*fMaker, SkDisplayEvent::kOnEnd, &eventState);
   420         fMaker->fAdjustedStart = 0;
   421         goto inval;
   422     }
   423     if (evt.isType(SK_EventType_Delay)) {
   424         fMaker->doDelayedEvent();
   425         goto inval;
   426     }
   427     {
   428         const char* id = evt.findString("id");
   429         if (id == NULL)
   430             return false;
   431         SkDisplayable** firstMovie = fMaker->fMovies.begin();
   432         SkDisplayable** endMovie = fMaker->fMovies.end();
   433         for (SkDisplayable** ptr = firstMovie; ptr < endMovie; ptr++) {
   434             SkDisplayMovie* movie = (SkDisplayMovie*) *ptr;
   435             movie->doEvent(evt);
   436         }
   437         {
   438             SkDisplayable* event;
   439             if (fMaker->find(id, &event) == false)
   440                 return false;
   441     #if defined SK_DEBUG && defined SK_DEBUG_ANIMATION_TIMING
   442             SkString debugOut;
   443             SkMSec realTime = fMaker->getAppTime();
   444             debugOut.appendS32(realTime - fMaker->fDebugTimeBase);
   445             debugOut.append(" onEvent id=");
   446             debugOut.append(id);
   447     #endif
   448             SkMSec time = evt.getFast32();
   449             if (time != 0) {
   450                 SkMSec app  = fMaker->getAppTime();
   451                 fMaker->setEnableTime(app, time);
   452     #if defined SK_DEBUG && defined SK_DEBUG_ANIMATION_TIMING
   453                 debugOut.append(" time=");
   454                 debugOut.appendS32(time - fMaker->fDebugTimeBase);
   455                 debugOut.append(" adjust=");
   456                 debugOut.appendS32(fMaker->fAdjustedStart);
   457     #endif
   458             }
   459     #if defined SK_DEBUG && defined SK_DEBUG_ANIMATION_TIMING
   460             SkDebugf("%s\n", debugOut.c_str());
   461     #endif
   462             SkASSERT(event->isEvent());
   463             SkDisplayEvent* displayEvent = (SkDisplayEvent*) event;
   464             displayEvent->populateInput(*fMaker, evt);
   465             displayEvent->enableEvent(*fMaker);
   466         }
   467     }
   468 inval:
   469     fMaker->notifyInval();
   470     return true;
   471 }
   473 void SkAnimator::onEventPost(SkEvent* evt, SkEventSinkID sinkID)
   474 {
   475 #ifdef SK_DEBUG
   476     SkAnimator* root = fMaker->getRoot();
   477     if (root) {
   478         root->onEventPost(evt, sinkID);
   479         return;
   480     }
   481 #else
   482     SkASSERT(sinkID == this->getSinkID() || this->getHostEventSinkID() == sinkID);
   483 #endif
   484     evt->setTargetID(sinkID)->post();
   485 }
   487 void SkAnimator::onEventPostTime(SkEvent* evt, SkEventSinkID sinkID, SkMSec time)
   488 {
   489 #ifdef SK_DEBUG
   490     SkAnimator* root = fMaker->getRoot();
   491     if (root) {
   492         root->onEventPostTime(evt, sinkID, time);
   493         return;
   494     }
   495 #else
   496     SkASSERT(sinkID == this->getSinkID() || this->getHostEventSinkID() == sinkID);
   497 #endif
   498     evt->setTargetID(sinkID)->postTime(time);
   499 }
   501 void SkAnimator::reset() {
   502     fMaker->fDisplayList.reset();
   503 }
   505 SkEventSinkID SkAnimator::getHostEventSinkID() const {
   506     return fMaker->fHostEventSinkID;
   507 }
   509 void SkAnimator::setHostEventSinkID(SkEventSinkID target) {
   510     fMaker->fHostEventSinkID = target;
   511 }
   513 void SkAnimator::onSetHostHandler(Handler ) {
   514 }
   516 void SkAnimator::setJavaOwner(Handler ) {
   517 }
   519 bool SkAnimator::setArrayString(const char* id, const char* fieldID, const char** array, int num)
   520 {
   521     SkTypedArray tArray(SkType_String);
   522     tArray.setCount(num);
   523     for (int i = 0; i < num; i++) {
   524         SkOperand op;
   525         op.fString = new SkString(array[i]);
   526         tArray[i] = op;
   527     }
   528     return setArray(id, fieldID, tArray);
   529 }
   530 bool SkAnimator::setArrayInt(const char* id, const char* fieldID, const int* array, int num)
   531 {
   532     SkTypedArray tArray(SkType_Int);
   533     tArray.setCount(num);
   534     for (int i = 0; i < num; i++) {
   535         SkOperand op;
   536         op.fS32 = array[i];
   537         tArray[i] = op;
   538     }
   539     return setArray(id, fieldID, tArray);
   540 }
   542 bool SkAnimator::setArray(SkDisplayable* element, const SkMemberInfo* info, SkTypedArray array) {
   543     if (info->fType != SkType_Array)
   544         return false;   //the field is not an array
   545     //i think we can handle the case where the displayable itself is an array differently from the
   546     //case where it has an array - for one thing, if it is an array, i think we can change its type
   547     //if it's not, we cannot
   548     SkDisplayTypes type = element->getType();
   549     if (type == SkType_Array) {
   550         SkDisplayArray* dispArray = (SkDisplayArray*) element;
   551         dispArray->values = array;
   552         return true;
   553     }
   554     else
   555         return false;   //currently i don't care about this case
   556 }
   558 bool SkAnimator::setArray(const char* id, const char* fieldID, SkTypedArray array) {
   559     SkDisplayable* element = (SkDisplayable*) getElement(id);
   560     //should I go ahead and change all 'NULL's to 'NULL'?
   561     if (element == NULL)
   562         return false;
   563     const SkMemberInfo* field = getField(element, fieldID);
   564     if (field == NULL)
   565         return false;
   566     return setArray(element, field, array);
   567 }
   569 bool SkAnimator::setInt(SkDisplayable* element, const SkMemberInfo* info, int32_t s32) {
   570     if (info->fType != SkType_MemberProperty) {
   571         SkOperand operand;
   572         operand.fS32 = s32;
   573         SkASSERT(info->getType() == SkType_Int);
   574         info->setValue(element, &operand, 1);
   575     } else {
   576         SkScriptValue scriptValue;
   577         scriptValue.fType = SkType_Int;
   578         scriptValue.fOperand.fS32 = s32;
   579         element->setProperty(info->propertyIndex(), scriptValue);
   580     }
   581     return true;
   582 }
   584 bool SkAnimator::setInt(const char* id, const char* fieldID, int32_t s32) {
   585     SkDisplayable* element = (SkDisplayable*) getElement(id);
   586     if (element == NULL)
   587         return false;
   588     const SkMemberInfo* field = getField(element, fieldID);
   589     if (field == NULL)
   590         return false;
   591     return setInt(element, field, s32);
   592 }
   594 bool SkAnimator::setScalar(SkDisplayable* element, const SkMemberInfo* info, SkScalar scalar) {
   595     if (info->fType != SkType_MemberProperty) {
   596         SkOperand operand;
   597         operand.fScalar = scalar;
   598         SkASSERT(info->getType() == SkType_Float);
   599         info->setValue(element, &operand, 1);
   600     } else {
   601         SkScriptValue scriptValue;
   602         scriptValue.fType = SkType_Float;
   603         scriptValue.fOperand.fScalar = scalar;
   604         element->setProperty(info->propertyIndex(), scriptValue);
   605     }
   606     return true;
   607 }
   609 bool SkAnimator::setScalar(const char* id, const char* fieldID, SkScalar scalar) {
   610     SkDisplayable* element = (SkDisplayable*) getElement(id);
   611     if (element == NULL)
   612         return false;
   613     const SkMemberInfo* field = getField(element, fieldID);
   614     if (field == NULL)
   615         return false;
   616     return setScalar(element, field, scalar);
   617 }
   619 bool SkAnimator::setString(SkDisplayable* element,
   620         const SkMemberInfo* info, const char* str) {
   621     // !!! until this is fixed, can't call script with global references from here
   622     info->setValue(*fMaker, NULL, 0, info->fCount, element, info->getType(), str, strlen(str));
   623     return true;
   624 }
   626 bool SkAnimator::setString(const char* id, const char* fieldID, const char* str) {
   627     SkDisplayable* element = (SkDisplayable*) getElement(id);
   628     if (element == NULL)
   629         return false;
   630     const SkMemberInfo* field = getField(element, fieldID);
   631     if (field == NULL)
   632         return false;
   633     return setString(element, field, str);
   634 }
   636 void SkAnimator::setTimeline(const Timeline& timeline) {
   637     fMaker->fTimeline = &timeline;
   638 }
   640 void SkAnimator::setURIBase(const char* uri) {
   641     if (uri)
   642     {
   643         const char* tail = strrchr(uri, '/');
   644         if (tail) {
   645             SkString prefix(uri, tail - uri + 1);
   646             if (uri[0] != '.' /*SkStream::IsAbsoluteURI(uri)*/)
   647                 fMaker->fPrefix.reset();
   648             fMaker->fPrefix.append(prefix);
   649             fMaker->fFileName.set(tail + 1);
   650         } else
   651             fMaker->fFileName.set(uri);
   652     }
   653 }
   655 #ifdef SK_DEBUG
   656 bool SkAnimator::NoLeaks() {
   657 #ifdef SK_BUILD_FOR_MAC
   658     if (SkDisplayable::fAllocations.count() == 0)
   659         return true;
   660 //  return SkDisplayable::fAllocationCount == 0;
   661     SkDebugf("!!! leaked %d displayables:\n", SkDisplayable::fAllocations.count());
   662     for (SkDisplayable** leak = SkDisplayable::fAllocations.begin(); leak < SkDisplayable::fAllocations.end(); leak++)
   663         SkDebugf("%08x %s\n", *leak, (*leak)->id);
   664 #endif
   665     return false;
   666 }
   667 #endif
   669 #ifdef SK_SUPPORT_UNITTEST
   670 #include "SkAnimatorScript.h"
   671 #include "SkBase64.h"
   672 #include "SkParse.h"
   673 #include "SkMemberInfo.h"
   675 #define unittestline(type)  { #type , type::UnitTest }
   676 #endif
   679 #ifdef SK_SUPPORT_UNITTEST
   680 void SkAnimator::Init(bool runUnitTests) {
   681     if (runUnitTests == false)
   682         return;
   683     static const struct {
   684         const char* fTypeName;
   685         void (*fUnitTest)( );
   686     } gUnitTests[] = {
   687         unittestline(SkBase64),
   688         unittestline(SkDisplayType),
   689         unittestline(SkParse),
   690         unittestline(SkScriptEngine),
   691 //      unittestline(SkScriptEngine2),  // compiled script experiment
   692         unittestline(SkAnimatorScript)
   693     };
   694     for (int i = 0; i < (int)SK_ARRAY_COUNT(gUnitTests); i++)
   695     {
   696         SkDebugf("SkAnimator: Running UnitTest for %s\n", gUnitTests[i].fTypeName);
   697         gUnitTests[i].fUnitTest();
   698         SkDebugf("SkAnimator: End UnitTest for %s\n", gUnitTests[i].fTypeName);
   699     }
   700 }
   701 #else
   702 void SkAnimator::Init(bool) {}
   703 #endif
   705 void SkAnimator::Term() {
   706 }

mercurial