void SkApply::endSave(int index) { SkAnimateBase* animate = fActive->fAnimators[index]; const SkMemberInfo* info = animate->fFieldInfo; SkDisplayTypes type = (SkDisplayTypes) info->fType; if (type == SkType_MemberFunction) return; SkDisplayable* target = getTarget(animate); size_t size = info->getSize(target); int count = (int) (size / sizeof(SkScalar)); int activeIndex = fActive->fDrawIndex + index; SkOperand* last = new SkOperand[count]; SkAutoTDelete<SkOperand> autoLast(last); if (type != SkType_MemberProperty) { info->getValue(target, last, count); SkOperand* saveOperand = fActive->fSaveRestore[activeIndex]; if (saveOperand) info->setValue(target, fActive->fSaveRestore[activeIndex], count); } else { SkScriptValue scriptValue; bool success = target->getProperty(info->propertyIndex(), &scriptValue); SkASSERT(success = true); last[0] = scriptValue.fOperand; scriptValue.fOperand = fActive->fSaveRestore[activeIndex][0]; target->setProperty(info->propertyIndex(), scriptValue); } SkOperand* save = fActive->fSaveRestore[activeIndex]; if (save) memcpy(save, last, count * sizeof(SkOperand)); }
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 SkApply::save(int index) { SkAnimateBase* animate = fActive->fAnimators[index]; const SkMemberInfo * info = animate->fFieldInfo; SkDisplayable* target = getTarget(animate); // if (animate->hasExecute()) // info = animate->getResolvedInfo(); SkDisplayTypes type = (SkDisplayTypes) info->fType; if (type == SkType_MemberFunction) return; // nothing to save size_t size = info->getSize(target); int count = (int) (size / sizeof(SkScalar)); bool useLast = true; // !!! this all may be unneeded, at least in the dynamic case ?? int activeIndex = fActive->fDrawIndex + index; SkTDOperandArray last; if (fActive->fSaveRestore[activeIndex] == NULL) { fActive->fSaveRestore[activeIndex] = new SkOperand[count]; useLast = false; } else { last.setCount(count); memcpy(last.begin(), fActive->fSaveRestore[activeIndex], count * sizeof(SkOperand)); } if (type != SkType_MemberProperty) { info->getValue(target, fActive->fSaveRestore[activeIndex], count); if (useLast) info->setValue(target, last.begin(), count); } else { SkScriptValue scriptValue; bool success = target->getProperty(info->propertyIndex(), &scriptValue); SkASSERT(success == true); SkASSERT(scriptValue.fType == SkType_Float); fActive->fSaveRestore[activeIndex][0] = scriptValue.fOperand; if (useLast) { SkScriptValue scriptValue; scriptValue.fType = type; scriptValue.fOperand = last[0]; target->setProperty(info->propertyIndex(), scriptValue); } } // !!! end of unneeded }
bool SkDisplayXMLParser::onAddAttributeLen(const char attrName[], const char attrValue[], size_t attrValueLen) { if (fCurrDisplayable == NULL) // this signals we should ignore attributes for this element return strncmp(attrName, "xmlns", sizeof("xmlns") - 1) != 0; SkDisplayable* displayable = fCurrDisplayable; SkDisplayTypes type = fCurrType; if (strcmp(attrName, "id") == 0) { if (fMaker.find(attrValue, attrValueLen, NULL)) { fError->setNoun(attrValue, attrValueLen); fError->setCode(SkXMLParserError::kDuplicateIDs); return true; } #ifdef SK_DEBUG displayable->_id.set(attrValue, attrValueLen); displayable->id = displayable->_id.c_str(); #endif fMaker.idsSet(attrValue, attrValueLen, displayable); int parentIndex = fParents.count() - 1; if (parentIndex > 0) { SkDisplayable* parent = fParents[parentIndex - 1].fDisplayable; parent->setChildHasID(); } return false; } const char* name = attrName; const SkMemberInfo* info = SkDisplayType::GetMember(&fMaker, type, &name); if (info == NULL) { fError->setNoun(name); fError->setCode(SkXMLParserError::kUnknownAttributeName); return true; } if (info->setValue(fMaker, NULL, 0, info->getCount(), displayable, info->getType(), attrValue, attrValueLen)) return false; if (fMaker.fError.hasError()) { fError->setNoun(attrValue, attrValueLen); return true; } SkDisplayable* ref = NULL; if (fMaker.find(attrValue, attrValueLen, &ref) == false) { ref = fMaker.createInstance(attrValue, attrValueLen); if (ref == NULL) { fError->setNoun(attrValue, attrValueLen); fError->setCode(SkXMLParserError::kErrorInAttributeValue); return true; } else fMaker.helperAdd(ref); } if (info->fType != SkType_MemberProperty) { fError->setNoun(name); fError->setCode(SkXMLParserError::kUnknownAttributeName); return true; } SkScriptValue scriptValue; scriptValue.fOperand.fDisplayable = ref; scriptValue.fType = ref->getType(); displayable->setProperty(info->propertyIndex(), scriptValue); return false; }
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; }
JSBool SkJSDisplayable::SetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) { if (JSVAL_IS_INT(id) == 0) return JS_TRUE; SkJSDisplayable *p = (SkJSDisplayable *) JS_GetPrivate(cx, obj); SkDisplayable* displayable = p->fDisplayable; SkDisplayTypes displayableType = displayable->getType(); int members; const SkMemberInfo* info = SkDisplayType::GetMembers(NULL /* fMaker */, displayableType, &members); int idIndex = JSVAL_TO_INT(id); SkASSERT(idIndex >= 0 && idIndex < members); info = &info[idIndex]; SkDisplayTypes infoType = info->getType(); SkScalar scalar = 0; S32 s32 = 0; SkString string; JSString* str; jsval value = *vp; switch (infoType) { case SkType_Boolean: s32 = JSVAL_TO_BOOLEAN(value); break; case SkType_Color: case SkType_S32: s32 = JSVAL_TO_INT(value); break; case SkType_Scalar: if (JSVAL_IS_INT(value)) scalar = SkIntToScalar(JSVAL_TO_INT(value)); else { SkASSERT(JSVAL_IS_DOUBLE(value)); #ifdef SK_SCALAR_IS_FLOAT scalar = (float) *(double*) JSVAL_TO_DOUBLE(value); #else scalar = (SkFixed) (*(double*)JSVAL_TO_DOUBLE(value) * 65536.0); #endif } break; case SkType_String: str = JS_ValueToString(cx, value); string.set(JS_GetStringBytes(str)); break; default: SkASSERT(0); // !!! unimplemented } if (info->fType == SkType_MemberProperty) { switch (infoType) { case SkType_Scalar: { SkScriptValue scriptValue; scriptValue.fType = SkType_Scalar; scriptValue.fOperand.fScalar = scalar; displayable->setProperty(-1 - (int) info->fOffset, scriptValue); } break; default: SkASSERT(0); // !!! unimplemented } } else { SkASSERT(info->fCount == 1); switch (infoType) { case SkType_Boolean: case SkType_Color: case SkType_S32: s32 = *(S32*) ((const char*) displayable + info->fOffset); break; case SkType_String: info->setString(displayable, &string); break; case SkType_Scalar: SkOperand operand; operand.fScalar = scalar; info->setValue(displayable, &operand, 1); break; default: SkASSERT(0); // !!! unimplemented } } return JS_TRUE; }