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); } }
void SkAnimateMaker::loadMovies() { for (SkDisplayable** dispPtr = fMovies.begin(); dispPtr < fMovies.end(); dispPtr++) { SkDisplayable* displayable = *dispPtr; SkASSERT(displayable->getType() == SkType_Movie); SkDisplayMovie* movie = (SkDisplayMovie*) displayable; SkAnimateMaker* movieMaker = movie->fMovie.fMaker; movieMaker->fEvents.doEvent(*movieMaker, SkDisplayEvent::kOnload, NULL); movieMaker->fEvents.removeEvent(SkDisplayEvent::kOnload, NULL); movieMaker->loadMovies(); } }
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; }
bool SkDisplayXMLParser::onStartElementLen(const char name[], size_t len) { fCurrDisplayable = NULL; // init so we'll ignore attributes if we exit early if (strncasecmp(name, "screenplay", len) == 0) { fInSkia = true; if (fInInclude == false) fMaker.idsSet(name, len, &fMaker.fScreenplay); return false; } if (fInSkia == false) return false; SkDisplayable* displayable = fMaker.createInstance(name, len); if (displayable == NULL) { fError->setNoun(name, len); fError->setCode(SkXMLParserError::kUnknownElement); return true; } SkDisplayTypes type = displayable->getType(); Parent record = { displayable, type }; *fParents.append() = record; if (fParents.count() == 1) fMaker.childrenAdd(displayable); else { Parent* parent = fParents.end() - 2; if (displayable->setParent(parent->fDisplayable)) { fError->setNoun(name, len); getError()->setCode(SkDisplayXMLParserError::kParentElementCantContain); return true; } } // set these for subsequent calls to addAttribute() fCurrDisplayable = displayable; fCurrType = type; return false; }
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; }
SkElementType SkAnimator::getElementType(const SkDisplayable* ae) { SkDisplayable* element = (SkDisplayable*) ae; const SkMemberInfo* info = SkDisplayType::GetMembers(fMaker, element->getType(), nullptr); return (SkElementType) SkDisplayType::Find(fMaker, info); }
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; }
JSBool SkJSDisplayable::GetProperty(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 = (SkDisplayTypes) info->fType; SkScalar scalar = 0; S32 s32 = 0; SkString* string= NULL; JSString *str; if (infoType == SkType_MemberProperty) { infoType = info->propertyType(); switch (infoType) { case SkType_Scalar: { SkScriptValue scriptValue; bool success = displayable->getProperty(info->propertyIndex(), &scriptValue); SkASSERT(scriptValue.fType == SkType_Scalar); scalar = scriptValue.fOperand.fScalar; } break; default: SkASSERT(0); // !!! unimplemented } } else { SkASSERT(info->fCount == 1); switch (infoType) { case SkType_Boolean: case SkType_Color: case SkType_S32: s32 = *(S32*) info->memberData(displayable); break; case SkType_String: info->getString(displayable, &string); break; case SkType_Scalar: SkOperand operand; info->getValue(displayable, &operand, 1); scalar = operand.fScalar; break; default: SkASSERT(0); // !!! unimplemented } } switch (infoType) { case SkType_Boolean: *vp = BOOLEAN_TO_JSVAL(s32); break; case SkType_Color: case SkType_S32: *vp = INT_TO_JSVAL(s32); break; case SkType_Scalar: if (SkScalarFraction(scalar) == 0) *vp = INT_TO_JSVAL(SkScalarFloor(scalar)); else #ifdef SK_SCALAR_IS_FLOAT *vp = DOUBLE_TO_JSVAL(scalar); #else *vp = DOUBLE_TO_JSVAL(scalar / 65536.0f ); #endif break; case SkType_String: str = JS_NewStringCopyN(cx, string->c_str(), string->size()); *vp = STRING_TO_JSVAL(str); break; default: SkASSERT(0); // !!! unimplemented } return JS_TRUE; }