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;
}
size_t SkMemberInfo::getSize(const SkDisplayable* displayable) const {
    size_t byteSize;
    switch (fType) {
        case SkType_MemberProperty:
            byteSize = GetSize(propertyType());
            break;
        case SkType_Array: {
            SkDisplayTypes type;
            if (displayable == NULL)
                return sizeof(int);
            if (displayable->getType() == SkType_Array) {
                SkDisplayArray* dispArray = (SkDisplayArray*) displayable;
                type = dispArray->values.getType();
            } else
                type = propertyType();
            SkTDOperandArray* array = (SkTDOperandArray*) memberData(displayable);
            byteSize = GetSize(type) * array->count();
            } break;
        default:
            byteSize = GetSize((SkDisplayTypes) fType);
    }
    return byteSize;
}
Beispiel #3
0
SkDisplayable* SkDisplayable::deepCopy(SkAnimateMaker* maker) {
    SkDisplayTypes type = getType();
    if (type == SkType_Unknown) {
        SkASSERT(0);
        return NULL;
    }
    SkDisplayable* copy = SkDisplayType::CreateInstance(maker, type);
    int index = -1;
    int propIndex = 0;
    const SkMemberInfo* info;
    do {
        info = copy->getMember(++index);
        if (info == NULL)
            break;
        if (info->fType == SkType_MemberProperty) {
            SkScriptValue value;
            if (getProperty(propIndex, &value))
                copy->setProperty(propIndex, value);
            propIndex++;
            continue;
        }
        if (info->fType == SkType_MemberFunction)
            continue;
        if (info->fType == SkType_Array) {
            SkTDOperandArray* array = (SkTDOperandArray*) info->memberData(this);
            int arrayCount;
            if (array == NULL || (arrayCount = array->count()) == 0)
                continue;
            SkTDOperandArray* copyArray = (SkTDOperandArray*) info->memberData(copy);
            copyArray->setCount(arrayCount);
            SkDisplayTypes elementType;
            if (type == SkType_Array) {
                SkDisplayArray* dispArray = (SkDisplayArray*) this;
                elementType = dispArray->values.getType();
            } else
                elementType = info->arrayType();
            size_t elementSize = SkMemberInfo::GetSize(elementType);
            size_t byteSize = elementSize * arrayCount;
            memcpy(copyArray->begin(), array->begin(), byteSize);
            continue;
        }
        if (SkDisplayType::IsDisplayable(maker, info->fType)) {
            SkDisplayable** displayable = (SkDisplayable**) info->memberData(this);
            if (*displayable == NULL || *displayable == (SkDisplayable*) -1)
                continue;
            SkDisplayable* deeper = (*displayable)->deepCopy(maker);
            info->setMemberData(copy, deeper, sizeof(deeper));
            continue;
        }
        if (info->fType == SkType_String || info->fType == SkType_DynamicString) {
            SkString* string;
            info->getString(this, &string);
            info->setString(copy, string);
            continue;
        }
        void* data = info->memberData(this);
        size_t size = SkMemberInfo::GetSize(info->fType);
        info->setMemberData(copy, data, size);
    } while (true);
    copy->dirty();
    return copy;
}
Beispiel #4
0
void SkDisplayable::dumpAttrs(SkAnimateMaker* maker) {
    SkDisplayTypes type = getType();
    if (type == SkType_Unknown) {
        //SkDebugf("/>\n");
        return;
    }
    SkDisplayable* blankCopy = SkDisplayType::CreateInstance(maker, type);

    int index = -1;
    int propIndex = 0;
    const SkMemberInfo* info;
    const SkMemberInfo* blankInfo;
    SkScriptValue value;
    SkScriptValue blankValue;
    SkOperand values[2];
    SkOperand blankValues[2];
    do {
        info = this->getMember(++index);
        if (NULL == info) {
            //SkDebugf("\n");
            break;
        }
        if (SkType_MemberProperty == info->fType) {
            if (getProperty(propIndex, &value)) {
                blankCopy->getProperty(propIndex, &blankValue);
                //last two are dummies
                dumpValues(info, value.fType, value.fOperand, blankValue.fOperand, value.fOperand, blankValue.fOperand);
                }
            
            propIndex++;
            continue;
        }
        if (SkDisplayType::IsDisplayable(maker, info->fType)) {
            continue;
        }
        
        if (info->fType == SkType_MemberFunction)
            continue;
            
            
        if (info->fType == SkType_Array) {
            SkTDOperandArray* array = (SkTDOperandArray*) info->memberData(this);
            int arrayCount;
            if (array == NULL || (arrayCount = array->count()) == 0)
                continue;
            SkDisplayTypes elementType;
            if (type == SkType_Array) {
                SkDisplayArray* dispArray = (SkDisplayArray*) this;
                elementType = dispArray->values.getType();
            } else
                elementType = info->arrayType();
            bool firstElem = true;
            SkDebugf("%s=\"[", info->fName);
            for (SkOperand* op = array->begin(); op < array->end(); op++) {
                if (!firstElem) SkDebugf(",");
                switch (elementType) {
                        case SkType_Displayable:
                            SkDebugf("%s", op->fDisplayable->id);
                            break;
                        case SkType_Int:                            
                            SkDebugf("%d", op->fS32);
                            break;
                        case SkType_Float:
#ifdef SK_CAN_USE_FLOAT
                            SkDebugf("%g", SkScalarToFloat(op->fScalar));
#else
                            SkDebugf("%x", op->fScalar);
#endif
                            break;
                        case SkType_String:
                        case SkType_DynamicString:    
                            SkDebugf("%s", op->fString->c_str());
                            break;
                        default:
                            break;
                }
                firstElem = false;
            }
            SkDebugf("]\" ");
            continue;
        }
        
        if (info->fType == SkType_String || info->fType == SkType_DynamicString) {
            SkString* string;
            info->getString(this, &string);
            if (string->isEmpty() == false)
                SkDebugf("%s=\"%s\"\t", info->fName, string->c_str()); 
            continue;
        }
        
        
        blankInfo = blankCopy->getMember(index);
        int i = info->fCount;
        info->getValue(this, values, i);
        blankInfo->getValue(blankCopy, blankValues, i);
        dumpValues(info, info->fType, values[0], blankValues[0], values[1], blankValues[1]);
    } while (true);
    delete blankCopy;
}