bool SkAnimatorScript::EvalMemberCommon(SkScriptEngine* engine, const SkMemberInfo* info,
        SkDisplayable* displayable, SkScriptValue* value) {
    SkDisplayTypes original;
    SkDisplayTypes type = original = (SkDisplayTypes) info->getType();
    if (info->fType == SkType_Array)
        type = SkType_Array;
    switch (type) {
        case SkType_ARGB:
            type = SkType_Int;
        case SkType_Boolean:
        case SkType_Int:
        case SkType_MSec:
        case SkType_Float:
            SkASSERT(info->getCount() == 1);
            if (info->fType != SkType_MemberProperty && info->fType != SkType_MemberFunction)
                value->fOperand.fS32 = *(int32_t*) info->memberData(displayable);   // OK for SkScalar too
            if (type == SkType_MSec) {
                value->fOperand.fScalar = SkScalarDiv((SkScalar) value->fOperand.fS32, 1000); // dividing two ints is the same as dividing two scalars
                type = SkType_Float;
            }
            break;
        case SkType_String: {
            SkString* displayableString;
            if (info->fType != SkType_MemberProperty && info->fType != SkType_MemberFunction) {
                info->getString(displayable, &displayableString);
                value->fOperand.fString = new SkString(*displayableString);
            }
            } break;
        case SkType_Array: {
            SkASSERT(info->fType != SkType_MemberProperty); // !!! incomplete
            SkTDOperandArray* displayableArray = (SkTDOperandArray*) info->memberData(displayable);
            if (displayable->getType() == SkType_Array) {
                SkDisplayArray* typedArray = (SkDisplayArray*) displayable;
                original = typedArray->values.getType();
            }
            SkASSERT(original != SkType_Unknown);
            SkTypedArray* array = value->fOperand.fArray = new SkTypedArray(original);
            engine->track(array);
            int count = displayableArray->count();
            if (count > 0) {
                array->setCount(count);
                memcpy(array->begin(), displayableArray->begin(), count * sizeof(SkOperand));
            }
            } break;
        default:
            SkASSERT(0); // unimplemented
    }
    value->fType = type;
    return true;
}
Ejemplo n.º 2
0
void SkApply::applyValues(int animatorIndex, SkOperand* values, int count,
     SkDisplayTypes valuesType, SkMSec time) 
{
    SkAnimateBase* animator = fActive->fAnimators[animatorIndex];
    const SkMemberInfo * info = animator->fFieldInfo;
    SkASSERT(animator);
    SkASSERT(info != NULL);
    SkDisplayTypes type = (SkDisplayTypes) info->fType;
    SkDisplayable* target = getTarget(animator);
    if (animator->hasExecute() || type == SkType_MemberFunction || type == SkType_MemberProperty) {
        SkDisplayable* executor = animator->hasExecute() ? animator : target;
        if (type != SkType_MemberProperty) {
            SkTDArray<SkScriptValue> typedValues;
            for (int index = 0; index < count; index++) {
                SkScriptValue temp;
                temp.fType = valuesType;
                temp.fOperand = values[index];
                *typedValues.append() = temp;
            }
            executor->executeFunction(target, info->functionIndex(), typedValues, info->getType(), NULL);
        } else {
            SkScriptValue scriptValue;
            scriptValue.fOperand = values[0];
            scriptValue.fType = info->getType();
            target->setProperty(info->propertyIndex(), scriptValue);
        }
    } else {
        SkTypedArray converted;
        if (type == SkType_ARGB) {
            if (count == 4) {
                // !!! assert that it is SkType_Float ?
                animator->packARGB(&values->fScalar, count, &converted);
                values = converted.begin();
                count = converted.count();
            } else {
                SkASSERT(count == 1);
            }
        }
//      SkASSERT(type == SkType_ARGB || type == SkType_String ||info->isSettable());
        if (type == SkType_String || type == SkType_DynamicString)
            info->setString(target, values->fString);
        else if (type == SkType_Drawable || type == SkType_Displayable)
            target->setReference(info, values->fDisplayable);
        else
            info->setValue(target, values, count);
    } 
}
void SkAnimate::onEndElement(SkAnimateMaker& maker) {
    bool resolved = resolveCommon(maker);
    if (resolved && fFieldInfo == NULL) {
        maker.setErrorNoun(field);
        maker.setErrorCode(SkDisplayXMLParserError::kFieldNotInTarget);
    }
    if (resolved == false || fFieldInfo == NULL)
        return;
    SkDisplayTypes outType = fFieldInfo->getType();
    if (fHasValues) {
        SkASSERT(to.size() > 0);
        fFieldInfo->setValue(maker, &fValues, 0, 0, NULL, outType, to);
        SkASSERT(0);
        // !!! this needs to set fComponents
        return;
    }
    fComponents = fFieldInfo->getCount();
    if (fFieldInfo->fType == SkType_Array) {
        SkTypedArray* array = (SkTypedArray*) fFieldInfo->memberData(fTarget);
        int count = array->count();
        if (count > 0)
            fComponents = count;
    }
    if (outType == SkType_ARGB) {
        fComponents <<= 2;  // four color components
        outType = SkType_Float;
    }
    fValues.setType(outType);
    if (formula.size() > 0){
        fComponents = 1;
        from.set("0");
        to.set("dur");
        outType = SkType_MSec;
    }
    int max = fComponents * 2;
    fValues.setCount(max);
    memset(fValues.begin(), 0, max * sizeof(fValues.begin()[0]));
    fFieldInfo->setValue(maker, &fValues, fFieldOffset, max, this, outType, from);
    fFieldInfo->setValue(maker, &fValues, fComponents + fFieldOffset, max, this, outType, to);
}
Ejemplo n.º 4
0
bool SkMemberInfo::writeValue(SkDisplayable* displayable, SkTDOperandArray* arrayStorage, 
    int storageOffset, int maxStorage, void* untypedStorage, SkDisplayTypes outType, 
    SkScriptValue& scriptValue) const
{
    SkOperand* storage = untypedStorage ? (SkOperand*) untypedStorage : arrayStorage ? 
        arrayStorage->begin() : NULL;
    if (storage)
        storage += storageOffset;
    SkDisplayTypes type = getType();
    if (fType == SkType_MemberProperty) {
        if(displayable)
            displayable->setProperty(propertyIndex(), scriptValue);
        else {
            SkASSERT(storageOffset < arrayStorage->count());
            switch (scriptValue.fType) {
                case SkType_Boolean:
                case SkType_Float:
                case SkType_Int:
                    memcpy(&storage->fScalar, &scriptValue.fOperand.fScalar, sizeof(SkScalar));
                    break;
                case SkType_Array:
                    memcpy(&storage->fScalar, scriptValue.fOperand.fArray->begin(), scriptValue.fOperand.fArray->count() * sizeof(SkScalar));
                    break;
                case SkType_String:
                    storage->fString->set(*scriptValue.fOperand.fString);
                    break;
                default:
                    SkASSERT(0);    // type isn't handled yet
            }
        }
    } else if (fType == SkType_MemberFunction) {
        SkASSERT(scriptValue.fType == SkType_Array);
        if (displayable)
            displayable->executeFunction(displayable, this, scriptValue.fOperand.fArray, NULL);
        else {
            int count = scriptValue.fOperand.fArray->count();
    //      SkASSERT(maxStorage == 0 || count == maxStorage);
            if (arrayStorage->count() == 2)
                arrayStorage->setCount(2 * count);
            else {
                storageOffset *= count;
                SkASSERT(count + storageOffset <= arrayStorage->count());
            }
            memcpy(&(*arrayStorage)[storageOffset], scriptValue.fOperand.fArray->begin(), count * sizeof(SkOperand));
        }

    } else if (fType == SkType_Array) {
        SkTypedArray* destArray = (SkTypedArray*) (untypedStorage ? untypedStorage : arrayStorage);
        SkASSERT(destArray);
    //  destArray->setCount(0);
        if (scriptValue.fType != SkType_Array) {
            SkASSERT(type == scriptValue.fType);
    //      SkASSERT(storageOffset + 1 <= maxStorage);
            destArray->setCount(storageOffset + 1);
            (*destArray)[storageOffset] = scriptValue.fOperand;
        } else {
            if (type == SkType_Unknown) {
                type = scriptValue.fOperand.fArray->getType();
                destArray->setType(type);
            }
            SkASSERT(type == scriptValue.fOperand.fArray->getType());
            int count = scriptValue.fOperand.fArray->count();
    //      SkASSERT(storageOffset + count <= maxStorage);
            destArray->setCount(storageOffset + count);
            memcpy(destArray->begin() + storageOffset, scriptValue.fOperand.fArray->begin(), sizeof(SkOperand) * count);
        }
    } else if (type == SkType_String) {
        SkString* string = untypedStorage ? (SkString*) untypedStorage : (*arrayStorage)[storageOffset].fString;
        string->set(*scriptValue.fOperand.fString);
    } else if (type == SkType_ARGB && outType == SkType_Float) {
        SkTypedArray* array = scriptValue.fOperand.fArray;
        SkASSERT(scriptValue.fType == SkType_Int || scriptValue.fType == SkType_ARGB || 
            scriptValue.fType == SkType_Array);
        SkASSERT(scriptValue.fType != SkType_Array || (array != NULL &&
            array->getType() == SkType_Int));
        int numberOfColors = scriptValue.fType == SkType_Array ? array->count() : 1;
        int numberOfComponents = numberOfColors * 4;
    //  SkASSERT(maxStorage == 0 || maxStorage == numberOfComponents);
        if (maxStorage == 0)
            arrayStorage->setCount(numberOfComponents);
        for (int index = 0; index < numberOfColors; index++) {
            SkColor color = scriptValue.fType == SkType_Array ? 
                (SkColor) array->begin()[index].fS32 : (SkColor) scriptValue.fOperand.fS32;
            storage[0].fScalar = SkIntToScalar(SkColorGetA(color));
            storage[1].fScalar = SkIntToScalar(SkColorGetR(color));
            storage[2].fScalar = SkIntToScalar(SkColorGetG(color));
            storage[3].fScalar = SkIntToScalar(SkColorGetB(color));
            storage += 4;
        }
    } else if (SkDisplayType::IsStruct(NULL /* !!! maker*/, type)) {
        if (scriptValue.fType != SkType_Array)
            return true;    // error
        SkASSERT(sizeof(SkScalar) == sizeof(SkOperand)); // !!! no 64 bit pointer support yet
        int count = scriptValue.fOperand.fArray->count();
        if (count > 0) {
            SkASSERT(fCount == count);
            memcpy(storage, scriptValue.fOperand.fArray->begin(), count * sizeof(SkOperand));
        }
    } else if (scriptValue.fType == SkType_Array) {
        SkASSERT(scriptValue.fOperand.fArray->getType() == type);
        SkASSERT(scriptValue.fOperand.fArray->count() == getCount());
        memcpy(storage, scriptValue.fOperand.fArray->begin(), getCount() * sizeof(SkOperand));
    } else {
        memcpy(storage, &scriptValue.fOperand, sizeof(SkOperand));
    }
    return false;
}
Ejemplo n.º 5
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;
}