void SkDisplayEvent::onEndElement(SkAnimateMaker& maker)
{
    if (kind == kUser)
        return;
    maker.fEvents.addEvent(this);
    if (kind == kOnEnd) {
        bool found = maker.find(target.c_str(), &fTarget);
        SkASSERT(found);
        SkASSERT(fTarget && fTarget->isAnimate());
        SkAnimateBase* animate = (SkAnimateBase*) fTarget;
        animate->setHasEndEvent();
    }
}
Esempio n. 2
0
void SkAnimateBase::setTarget(SkAnimateMaker& maker) {
    if (target.size()) {
        SkAnimatorScript engine(maker, this, SkType_Displayable);
        const char* script = target.c_str();
        SkScriptValue scriptValue;
        bool success = engine.evaluateScript(&script, &scriptValue);
        if (success && scriptValue.fType == SkType_Displayable)
            fTarget = scriptValue.fOperand.fDrawable;
        else if (maker.find(target.c_str(), (SkDisplayable**) &fTarget) == false) {
            if (fApply->getMode() == SkApply::kMode_create)
                return; // may not be an error
            if (engine.getError() != SkScriptEngine::kNoError)
                maker.setScriptError(engine);
            else {
                maker.setErrorNoun(target);
                maker.setErrorCode(SkDisplayXMLParserError::kTargetIDNotFound);
            }
            return;
        }
        if (fApply && fApply->getMode() != SkApply::kMode_create)
            target.reset();
    }
}
bool SkAnimatorScript::Unbox(void* m, SkScriptValue* scriptValue) {
    SkAnimateMaker* maker = (SkAnimateMaker*) m;
    SkASSERT((unsigned) scriptValue->fType == (unsigned) SkType_Displayable);
    SkDisplayable* displayable = (SkDisplayable*) scriptValue->fOperand.fObject;
    SkDisplayTypes type = displayable->getType();
    switch (displayable->getType()) {
        case SkType_Array: {
            SkDisplayArray* boxedValue = (SkDisplayArray*) displayable;
            scriptValue->fOperand.fArray = &boxedValue->values;
            } break;
        case SkType_Boolean: {
            SkDisplayBoolean* boxedValue = (SkDisplayBoolean*) displayable;
            scriptValue->fOperand.fS32 = boxedValue->value;
            } break;
        case SkType_Int: {
            SkDisplayInt* boxedValue = (SkDisplayInt*) displayable;
            scriptValue->fOperand.fS32 = boxedValue->value;
            } break;
        case SkType_Float: {
            SkDisplayFloat* boxedValue = (SkDisplayFloat*) displayable;
            scriptValue->fOperand.fScalar = boxedValue->value;
            } break;
        case SkType_String: {
            SkDisplayString* boxedValue = (SkDisplayString*) displayable;
            scriptValue->fOperand.fString = SkNEW_ARGS(SkString, (boxedValue->value));
            } break;
        default: {
            const char* id = NULL;
            bool success = maker->findKey(displayable, &id);
            SkASSERT(success);
            scriptValue->fOperand.fString = SkNEW_ARGS(SkString, (id));
            type = SkType_String;
        }
    }
    scriptValue->fType = type;
    return true;
}
Esempio n. 4
0
void SkInclude::onEndElement(SkAnimateMaker& maker) {
    maker.fInInclude = true;
    if (src.size() == 0 || maker.decodeURI(src.c_str()) == false) {
        if (maker.getErrorCode() != SkXMLParserError::kNoError || maker.getNativeCode() != -1) {
            maker.setInnerError(&maker, src);
            maker.setErrorCode(SkDisplayXMLParserError::kInInclude);
        } else {
            maker.setErrorNoun(src);
            maker.setErrorCode(SkDisplayXMLParserError::kIncludeNameUnknownOrMissing);
        }
    }
    maker.fInInclude = false;
}
Esempio n. 5
0
void SkDisplayEvent::populateInput(SkAnimateMaker& maker, const SkEvent& fEvent) {
    const SkMetaData& meta = fEvent.getMetaData();
    SkMetaData::Iter iter(meta);
    SkMetaData::Type    type;
    int number;
    const char* name;
    while ((name = iter.next(&type, &number)) != NULL) {
        if (name[0] == '\0')
            continue;
        SkDisplayable* displayable;
        SkInput* input;
        for (int index = 0; index < fChildren.count(); index++) {
            displayable = fChildren[index];
            if (displayable->getType() != SkType_Input)
                continue;
            input = (SkInput*) displayable;
            if (input->name.equals(name))
                goto found;
        }
        if (!maker.find(name, &displayable) || displayable->getType() != SkType_Input)
            continue;
        input = (SkInput*) displayable;
    found:
        switch (type) {
            case SkMetaData::kS32_Type:
                meta.findS32(name, &input->fInt);
                break;
            case SkMetaData::kScalar_Type:
                meta.findScalar(name, &input->fFloat);
                break;
            case SkMetaData::kPtr_Type:
                SkASSERT(0);
                break; // !!! not handled for now
            case SkMetaData::kString_Type:
                input->string.set(meta.findString(name));
                break;
            default:
                SkASSERT(0);
        }
    }
    // re-evaluate all animators that may have built their values from input strings
    for (SkDisplayable** childPtr = fChildren.begin(); childPtr < fChildren.end(); childPtr++) {
        SkDisplayable* displayable = *childPtr;
        if (displayable->isApply() == false)
            continue;
        SkApply* apply = (SkApply*) displayable;
        apply->refresh(maker);
    }
}
Esempio n. 6
0
bool SkGroup::resolveIDs(SkAnimateMaker& maker, SkDisplayable* orig, SkApply* apply) {
    SkGroup* original = (SkGroup*) orig;
    SkTDDrawableArray& originalChildren = original->fChildren;
    SkDrawable** originalPtr = originalChildren.begin();
    SkDrawable** ptr = fChildren.begin();
    SkDrawable** end = fChildren.end();
    SkDrawable** origChild = ((SkGroup*) orig)->fChildren.begin();
    while (ptr < end) {
        SkDrawable* drawable = *ptr++;
        maker.resolveID(drawable, *origChild++);
        if (drawable->resolveIDs(maker, *originalPtr++, apply) == true)
            return true; // failed
    }
    return false;
}
bool SkDump::enable(SkAnimateMaker& maker ) {
    if (script.size() > 0)
        return evaluate(maker);
    bool hasAttr = false;
    if (events > 0)
        hasAttr |= maker.fDumpEvents = true;
    if (posts > 0)
        hasAttr |= maker.fDumpPosts = true;
    if (groups > 0)
        hasAttr |= maker.fDumpGConditions = true;
    if ((hasAttr |= (eventList > 0)) == true)
        maker.fEvents.dump(maker);
    if ((hasAttr |= (name.size() > 0)) == true)
        maker.dump(name.c_str());
    if (displayList > 0 || displayList != 0 && hasAttr == false)
        maker.fDisplayList.dump(&maker);
    return true;
}
Esempio n. 8
0
void SkDisplayMovie::buildMovie() {
    if (fMovieBuilt)
        return;
    SkAnimateMaker* movieMaker = fMovie.fMaker;
    SkAnimateMaker* parentMaker = movieMaker->fParentMaker;
    if (src.size() == 0 || parentMaker == NULL)
        return;
    movieMaker->fPrefix.set(parentMaker->fPrefix);
    fDecodedSuccessfully = fMovie.fMaker->decodeURI(src.c_str());
    if (fDecodedSuccessfully == false) {

        if (movieMaker->getErrorCode() != SkXMLParserError::kNoError || movieMaker->getNativeCode() != -1) {
            movieMaker->setInnerError(parentMaker, src);
            parentMaker->setErrorCode(SkDisplayXMLParserError::kInMovie);
        } else {
            parentMaker->setErrorNoun(src);
            parentMaker->setErrorCode(SkDisplayXMLParserError::kMovieNameUnknownOrMissing);
        }
    }
    fMovieBuilt = true;
}
Esempio n. 9
0
void SkApply::activate(SkAnimateMaker& maker) {
    if (fActive != NULL) {
        if (fActive->fDrawIndex == 0 && fActive->fDrawMax == 0)
            return; // if only one use, nothing more to do
        if (restore == false)
            return; // all share same state, regardless of instance number
        bool save = fActive->initializeSave();
        fActive->fixInterpolator(save);
    } else {
        fActive = new SkActive(*this, maker);
        fActive->init();
        maker.appendActive(fActive);
        if (restore) {
            fActive->initializeSave();
            int animators = fAnimators.count();
            for (int index = 0; index < animators; index++)
                fActive->saveInterpolatorValues(index);
        }
    }
}
Esempio n. 10
0
bool SkApply::resolveIDs(SkAnimateMaker& maker, SkDisplayable* original, SkApply* apply) { //   replace to/formula strings in animators of the form xxx.step with the step value, if xxx.step is in scope
    if (resolveField(maker, apply, &dynamicScope) == false)
        return true;    // failed
    SkAnimateBase** endPtr = fAnimators.end();
    SkAnimateBase** origPtr = ((SkApply*) original)->fAnimators.begin();
    for (SkAnimateBase** animPtr = fAnimators.begin(); animPtr < endPtr; ) {
        SkAnimateBase* animator = *animPtr++;
        maker.resolveID(animator, *origPtr++);
        if (resolveField(maker, this, &animator->target) == false)
            return true;
        if (resolveField(maker, this, &animator->from) == false)
            return true;
        if (resolveField(maker, this, &animator->to) == false)
            return true;
        if (resolveField(maker, this, &animator->formula) == false)
            return true;
    }
//  setEmbedded();
    onEndElement(maker);
    return false; // succeeded
}
Esempio n. 11
0
bool SkApply::draw(SkAnimateMaker& maker) {
    if (scope ==NULL)
        return false;
    if (scope->isApply() || scope->isDrawable() == false)
        return false;
    if (fEnabled == false)
        enable(maker);
    SkASSERT(scope);
    activate(maker);
    if (mode == kMode_immediate)
        return fActive->draw();
    bool result = interpolate(maker, maker.getInTime());
    if (dontDraw == false) {
//      if (scope->isDrawable())
            result |= scope->draw(maker);
    }
    if (restore) {
        for (int index = 0; index < fActive->fAnimators.count(); index++)
            endSave(index);
        fActive->advance();
    }
    return result;
}
Esempio n. 12
0
bool SkMemberInfo::setValue(SkAnimateMaker& maker, SkTDOperandArray* arrayStorage, 
    int storageOffset, int maxStorage, SkDisplayable* displayable, SkDisplayTypes outType,
    const char rawValue[], size_t rawValueLen) const 
{
    SkString valueStr(rawValue, rawValueLen);
    SkScriptValue scriptValue;
    scriptValue.fType = SkType_Unknown;
    scriptValue.fOperand.fS32 = 0;
    SkDisplayTypes type = getType();
    SkAnimatorScript engine(maker, displayable, type);
    if (arrayStorage)
        displayable = NULL;
    bool success = true;
    void* untypedStorage = NULL;
    if (displayable && fType != SkType_MemberProperty && fType != SkType_MemberFunction)
        untypedStorage = (SkTDOperandArray*) memberData(displayable);

    if (type == SkType_ARGB) {
        // for both SpiderMonkey and SkiaScript, substitute any #xyz or #xxyyzz first
            // it's enough to expand the colors into 0xFFxxyyzz
        const char* poundPos;
        while ((poundPos = strchr(valueStr.c_str(), '#')) != NULL) {
            size_t offset = poundPos - valueStr.c_str();
            if (valueStr.size() - offset < 4)
                break;
            char r = poundPos[1];
            char g = poundPos[2];
            char b = poundPos[3];
            if (is_hex(r) == false || is_hex(g) == false || is_hex(b) == false)
                break;
            char hex = poundPos[4];
            if (is_hex(hex) == false) {
                valueStr.insertUnichar(offset + 1, r);
                valueStr.insertUnichar(offset + 3, g);
                valueStr.insertUnichar(offset + 5, b);
            }
            *(char*) poundPos = '0'; // overwrite '#'
            valueStr.insert(offset + 1, "xFF");
        } 
    }
    if (SkDisplayType::IsDisplayable(&maker, type) || SkDisplayType::IsEnum(&maker, type) || type == SkType_ARGB)
        goto scriptCommon;
    switch (type) {
        case SkType_String:
#if 0
            if (displayable && displayable->isAnimate()) {
                
                goto noScriptString;
            } 
            if (strncmp(rawValue, "#string:", sizeof("#string:") - 1) == 0) {
                SkASSERT(sizeof("string") == sizeof("script"));
                char* stringHeader = valueStr.writable_str();
                memcpy(&stringHeader[1], "script", sizeof("script") - 1);
                rawValue = valueStr.c_str();
                goto noScriptString;
            } else 
#endif
            if (strncmp(rawValue, "#script:", sizeof("#script:") - 1) != 0)
                goto noScriptString;
            valueStr.remove(0, 8);
        case SkType_Unknown:
        case SkType_Int: 
        case SkType_MSec:  // for the purposes of script, MSec is treated as a Scalar
        case SkType_Point:
        case SkType_3D_Point:
        case SkType_Float:
        case SkType_Array:
scriptCommon: {
                const char* script = valueStr.c_str();
                success = engine.evaluateScript(&script, &scriptValue);
                if (success == false) {
                    maker.setScriptError(engine);
                    return false;
                }
            }
            SkASSERT(success);
            if (scriptValue.fType == SkType_Displayable) {
                if (type == SkType_String) {
                    const char* charPtr;
                    maker.findKey(scriptValue.fOperand.fDisplayable, &charPtr);
                    scriptValue.fOperand.fString = new SkString(charPtr);
                    scriptValue.fType = SkType_String;
                    engine.SkScriptEngine::track(scriptValue.fOperand.fString);
                    break;
                }
                SkASSERT(SkDisplayType::IsDisplayable(&maker, type));
                if (displayable)
                    displayable->setReference(this, scriptValue.fOperand.fDisplayable);
                else
                    arrayStorage->begin()[0].fDisplayable = scriptValue.fOperand.fDisplayable;
                return true;
            }
            if (type != scriptValue.fType) {
                if (scriptValue.fType == SkType_Array) {
                    engine.forget(scriptValue.getArray());
                    goto writeStruct; // real structs have already been written by script
                }
                switch (type) {
                    case SkType_String:
                        success = engine.convertTo(SkType_String, &scriptValue);
                        break;
                    case SkType_MSec:
                    case SkType_Float:
                        success = engine.convertTo(SkType_Float, &scriptValue);
                        break;
                    case SkType_Int:
                        success = engine.convertTo(SkType_Int, &scriptValue);
                        break;
                    case SkType_Array:
                        success = engine.convertTo(arrayType(), &scriptValue);
                        // !!! incomplete; create array of appropriate type and add scriptValue to it
                        SkASSERT(0);
                        break;
                    case SkType_Displayable:
                    case SkType_Drawable:
                        return false;   // no way to convert other types to this
                    default:    // to avoid warnings
                        break;
                }
                if (success == false)
                    return false;
            }
            if (type == SkType_MSec)
                scriptValue.fOperand.fMSec = SkScalarMulRound(scriptValue.fOperand.fScalar, 1000);
            scriptValue.fType = type;
        break;
        noScriptString:
        case SkType_DynamicString:
            if (fType == SkType_MemberProperty && displayable) {
                SkString string(rawValue, rawValueLen);
                SkScriptValue scriptValue;
                scriptValue.fOperand.fString = &string;
                scriptValue.fType = SkType_String;
                displayable->setProperty(propertyIndex(), scriptValue);
            } else if (displayable) {
                SkString* string = (SkString*) memberData(displayable);
                string->set(rawValue, rawValueLen);
            } else {
                SkASSERT(arrayStorage->count() == 1);
                arrayStorage->begin()->fString->set(rawValue, rawValueLen);
            }
            goto dirty;
        case SkType_Base64: {
            SkBase64 base64;
            base64.decode(rawValue, rawValueLen);
            *(SkBase64* ) untypedStorage = base64;
            } goto dirty;
        default:
            SkASSERT(0);
            break;
    }
//  if (SkDisplayType::IsStruct(type) == false) 
    {
writeStruct:
        if (writeValue(displayable, arrayStorage, storageOffset, maxStorage, 
                untypedStorage, outType, scriptValue)) {
                    maker.setErrorCode(SkDisplayXMLParserError::kUnexpectedType);
            return false;
        }
    }
dirty:
    if (displayable)
        displayable->dirty();
    return true;
}
void SkDrawShape1DPathEffect::onEndElement(SkAnimateMaker& maker) {
    if (addPath == nullptr || (addPath->isPath() == false && addPath->isApply() == false))
        maker.setErrorCode(SkDisplayXMLParserError::kUnknownError); // !!! add error
    else
        fPathEffect = new SkShape1DPathEffect(this, &maker);
}
Esempio n. 14
0
bool SkApply::interpolate(SkAnimateMaker& maker, SkMSec rawTime) {
    if (fActive == NULL)
        return false;
    bool result = false;
#if defined SK_DEBUG && defined SK_DEBUG_ANIMATION_TIMING
    SkMSec time = maker.getAppTime();
    if (lastTime == (SkMSec) -1)
        lastTime = rawTime - 1;
    if (fActive != NULL && 
        strcmp(id, "a3") == 0 && rawTime > lastTime) {
        lastTime += 1000;
        SkString debugOut;
        debugOut.appendS32(time - maker.fDebugTimeBase);
        debugOut.append(" apply id=");
        debugOut.append(_id);
        debugOut.append("; ");
        debugOut.append(fActive->fAnimators[0]->_id);
        debugOut.append("=");
        debugOut.appendS32(rawTime - fActive->fState[0].fStartTime);
        debugOut.append(")");
        SkDebugf("%s\n", debugOut.c_str());
    }
#endif
    fActive->start();
    if (restore)
        fActive->initializeSave();
    int animators = fActive->fAnimators.count();
    for (int inner = 0; inner < animators; inner++) {
        SkAnimateBase* animate = fActive->fAnimators[inner];
        if (animate->fChanged) {
            animate->fChanged = false;
            animate->fStart = rawTime;
    //      SkTypedArray values;
    //      int count = animate->fValues.count();
    //      values.setCount(count);
    //      memcpy(values.begin(), animate->fValues.begin(), sizeof(SkOperand) * count);
            animate->onEndElement(maker);
    //      if (memcmp(values.begin(), animate->fValues.begin(), sizeof(SkOperand) * count) != 0) {
                fActive->append(this);
                fActive->start();
    //      }
        }
        SkMSec time = fActive->getTime(rawTime, inner);
        SkActive::SkState& state = fActive->fState[inner];
        if (SkMSec_LT(rawTime, state.fStartTime)) {
            if (fEnabling) {
                animate->fDelayed = true;
                maker.delayEnable(this, state.fStartTime);
            }
            continue;
        } else
            animate->fDelayed = false;
        SkMSec innerTime = fLastTime = state.getRelativeTime(time);
        if (restore) 
            fActive->restoreInterpolatorValues(inner);
        if (animate->fReset) {
            if (transition != SkApply::kTransition_reverse) {
                if (SkMSec_LT(state.fBegin + state.fDuration, innerTime)) {
                    if (animate->fResetPending) {
                        innerTime = 0;
                        animate->fResetPending = false;
                    } else
                        continue;
                }
            } else if (innerTime == 0) {
                    if (animate->fResetPending) {
                        innerTime = state.fBegin + state.fDuration;
                        animate->fResetPending = false;
                    } else
                        continue;
            }
        }
        int count = animate->components();
        SkAutoSTMalloc<16, SkOperand> values(count);
        SkInterpolatorBase::Result interpResult = fActive->fInterpolators[inner]->timeToValues(
            innerTime, values.get());
        result |= (interpResult != SkInterpolatorBase::kFreezeEnd_Result);
        if ((transition != SkApply::kTransition_reverse && interpResult == SkInterpolatorBase::kFreezeEnd_Result ||
                transition == SkApply::kTransition_reverse && fLastTime == 0) && state.fUnpostedEndEvent) {
//          SkDEBUGF(("interpolate: post on end\n"));
            state.fUnpostedEndEvent = false;
            maker.postOnEnd(animate, state.fBegin + state.fDuration);
            maker.fAdjustedStart = 0;    // !!! left over from synchronizing animation days, undoubtably out of date (and broken)
        }
        if (animate->formula.size() > 0) {
            if (fLastTime > animate->dur)
                fLastTime = animate->dur;
            SkTypedArray formulaValues;
            formulaValues.setCount(count);
            bool success = animate->fFieldInfo->setValue(maker, &formulaValues, 0, 0, NULL, 
                animate->getValuesType(), animate->formula);
            SkASSERT(success);
            if (restore)
                save(inner); // save existing value
            applyValues(inner, formulaValues.begin(), count, animate->getValuesType(), innerTime);
        } else {
            if (restore)
                save(inner); // save existing value
            applyValues(inner, values.get(), count, animate->getValuesType(), innerTime);
        }
    }
    return result;
}
Esempio n. 15
0
bool SkApply::enable(SkAnimateMaker& maker) {
    fEnabled = true;
    bool initialized = fActive != NULL;
    if (dynamicScope.size() > 0)
        enableDynamic(maker);
    if (maker.fError.hasError()) 
        return false;
    int animators = fAnimators.count();
    int index;
    for (index = 0; index < animators; index++) {
        SkAnimateBase* animator = fAnimators[index];
        animator->fStart = maker.fEnableTime;
        animator->fResetPending = animator->fReset;
    }
    if (scope && scope->isApply())
        ((SkApply*) scope)->setEmbedded();
/*  if (mode == kMode_once) {
        if (scope) {
            activate(maker);
            interpolate(maker, maker.fEnableTime);
            inactivate(maker);
        }
        return true;
    }*/
    if ((mode == kMode_immediate || mode == kMode_create) && scope == NULL)
        return false;   // !!! error?
    bool enableMe = scope && (scope->hasEnable() || scope->isApply() || scope->isDrawable() == false);
    if (mode == kMode_immediate && enableMe || mode == kMode_create)
        activate(maker);    // for non-drawables like post, prime them here
    if (mode == kMode_immediate && enableMe)
        fActive->enable();
    if (mode == kMode_create && scope != NULL) {
        enableCreate(maker);
        return true;
    }
    if (mode == kMode_immediate) {
        return scope->isApply() || scope->isDrawable() == false;
    }
    refresh(maker);
    SkDisplayList& displayList = maker.fDisplayList;
    SkDrawable* drawable;
#if defined SK_DEBUG && defined SK_DEBUG_ANIMATION_TIMING
    SkString debugOut;
    SkMSec time = maker.getAppTime();
    debugOut.appendS32(time - maker.fDebugTimeBase);
    debugOut.append(" apply enable id=");
    debugOut.append(_id);
    debugOut.append("; start=");
    debugOut.appendS32(maker.fEnableTime - maker.fDebugTimeBase);
    SkDebugf("%s\n", debugOut.c_str());
#endif
    if (scope == NULL || scope->isApply() || scope->getType() == SkType_Movie || scope->isDrawable() == false) {
        activate(maker);    // for non-drawables like post, prime them here
        if (initialized) {
            append(this);
        }
        fEnabling = true;
        interpolate(maker, maker.fEnableTime);
        fEnabling = false;
        if (scope != NULL && dontDraw == false)
            scope->enable(maker);
        return true;
    } else if (initialized && restore == false)
        append(this);
#if 0
    bool wasActive = inactivate(maker); // start fresh
    if (wasActive) {
        activate(maker);
        interpolate(maker, maker.fEnableTime);
        return true;
    }
#endif
//  start here;
    // now that one apply might embed another, only the parent apply should replace the scope 
    // or get appended to the display list
    // similarly, an apply added by an add immediate has already been located in the display list
    // and should not get moved or added again here
    if (fEmbedded) {
        return false;   // already added to display list by embedder
    }
    drawable = (SkDrawable*) scope;
    SkTDDrawableArray* parentList;
    SkTDDrawableArray* grandList;
    SkGroup* parentGroup;
    SkGroup* thisGroup;
    int old = displayList.findGroup(drawable, &parentList, &parentGroup, &thisGroup, &grandList);
    if (old < 0)
        goto append;
    else if (fContainsScope) {
        if ((*parentList)[old] != this || restore == true) {
append:
            if (parentGroup)
                parentGroup->markCopySize(old);
            if (parentList->count() < 10000) {
                fAppended = true;
                *parentList->append() = this;
            } else
                maker.setErrorCode(SkDisplayXMLParserError::kDisplayTreeTooDeep);
            old = -1;
        } else
            reset();
    } else {
        SkASSERT(old < parentList->count());
        if ((*parentList)[old]->isApply()) {
            SkApply* apply = (SkApply*) (*parentList)[old];
            if (apply != this && apply->fActive == NULL)
                apply->activate(maker);
            apply->append(this);
            parentGroup = NULL;
        } else {
            if (parentGroup)
                parentGroup->markCopySize(old);
            SkDrawable** newApplyLocation = &(*parentList)[old];
            SkGroup* pGroup;
            int oldApply = displayList.findGroup(this, &parentList, &pGroup, &thisGroup, &grandList);
            if (oldApply >= 0) {
                (*parentList)[oldApply] = (SkDrawable*) SkDisplayType::CreateInstance(&maker, SkType_Apply);
                parentGroup = NULL;
                fDeleteScope = true;
            }
            *newApplyLocation = this;
        }
    }
    if (parentGroup) {
        parentGroup->markCopySet(old);
        fDeleteScope = dynamicScope.size() == 0;
    }
    return true;
}
Esempio n. 16
0
void SkSaveLayer::onEndElement(SkAnimateMaker& maker)
{
    if (!bounds)
        maker.setErrorCode(SkDisplayXMLParserError::kSaveLayerNeedsBounds);
    INHERITED::onEndElement(maker);
}
bool SkAnimate::resolveCommon(SkAnimateMaker& maker) {
    if (fTarget == NULL) // if NULL, recall onEndElement after apply closes and sets target to scope
        return false;
    INHERITED::onEndElement(maker);
    return maker.hasError() == false;
}
Esempio n. 18
0
bool SkAdd::enable(SkAnimateMaker& maker ) {
    SkDisplayTypes type = getType();
    SkDisplayList& displayList = maker.fDisplayList;
    SkTDDrawableArray* parentList = displayList.getDrawList();
    if (type == SkType_Add) {
        if (use == NULL) // not set in apply yet
            return true;
    }
    bool skipAddToParent = true;
    SkASSERT(type != SkType_Replace || where);
    SkTDDrawableArray* grandList SK_INIT_TO_AVOID_WARNING;
    SkGroup* parentGroup = NULL;
    SkGroup* thisGroup = NULL;
    int index = where ? displayList.findGroup(where, &parentList, &parentGroup,
        &thisGroup, &grandList) : 0;
    if (index < 0)
        return true;
    int max = parentList->count();
    if (where == NULL && type == SkType_Move)
        index = max;
    if (offset != SK_MaxS32) {
        index += offset;
        if (index > max) {
            maker.setErrorCode(SkDisplayXMLParserError::kIndexOutOfRange);
            return true;    // caller should not add
        }
    }
    if (offset < 0 && where == NULL)
        index += max + 1;
    switch (type) {
        case SkType_Add:
            if (offset == SK_MaxS32 && where == NULL) {
                if (use->isDrawable()) {
                    skipAddToParent = mode == kMode_immediate;
                    if (skipAddToParent) {
                        if (where == NULL) {
                            SkTDDrawableArray* useParentList;
                            index = displayList.findGroup(this, &useParentList, &parentGroup,
                                &thisGroup, &grandList);
                            if (index >= 0) {
                                parentGroup->markCopySize(index);
                                parentGroup->markCopySet(index);
                                useParentList->begin()[index] = use;
                                break;
                            }
                        }
                        *parentList->append() = use;
                    }
                }
                break;
            } else {
                if (thisGroup)
                    thisGroup->markCopySize(index);
                *parentList->insert(index) = use;
                if (thisGroup)
                    thisGroup->markCopySet(index);
                if (use->isApply())
                    ((SkApply*) use)->setEmbedded();
            }
            break;
        case SkType_Move: {
            int priorLocation = parentList->find(use);
            if (priorLocation < 0)
                break;
            *parentList->insert(index) = use;
            if (index < priorLocation)
                priorLocation++;
            parentList->remove(priorLocation);
            } break;
        case SkType_Remove: {
            SkDisplayable* old = (*parentList)[index];
            if (((SkRemove*)(this))->fDelete) {
                delete old;
                goto noHelperNeeded;
            }
            for (int inner = 0; inner < maker.fChildren.count(); inner++) {
                SkDisplayable* child = maker.fChildren[inner];
                if (child == old || child->contains(old))
                    goto noHelperNeeded;
            }
            if (maker.fHelpers.find(old) < 0)
                maker.helperAdd(old);
noHelperNeeded:
            parentList->remove(index);
            } break;
        case SkType_Replace:
            if (thisGroup) {
                thisGroup->markCopySize(index);
                if (thisGroup->markedForDelete(index)) {
                    SkDisplayable* old = (*parentList)[index];
                    if (maker.fHelpers.find(old) < 0)
                        maker.helperAdd(old);
                }
            }
            (*parentList)[index] = use;
            if (thisGroup)
                thisGroup->markCopySet(index);
            break;
        default:
            SkASSERT(0);
    }
    if (type == SkType_Remove)
        return true;
    if (use->hasEnable())
        use->enable(maker);
    return skipAddToParent; // append if indirect: *parentList->append() = this;
}