| Index: skia/animator/SkDisplayXMLParser.cpp
|
| ===================================================================
|
| --- skia/animator/SkDisplayXMLParser.cpp (revision 16859)
|
| +++ skia/animator/SkDisplayXMLParser.cpp (working copy)
|
| @@ -1,318 +0,0 @@
|
| -/* libs/graphics/animator/SkDisplayXMLParser.cpp
|
| -**
|
| -** Copyright 2006, The Android Open Source Project
|
| -**
|
| -** Licensed under the Apache License, Version 2.0 (the "License");
|
| -** you may not use this file except in compliance with the License.
|
| -** You may obtain a copy of the License at
|
| -**
|
| -** http://www.apache.org/licenses/LICENSE-2.0
|
| -**
|
| -** Unless required by applicable law or agreed to in writing, software
|
| -** distributed under the License is distributed on an "AS IS" BASIS,
|
| -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| -** See the License for the specific language governing permissions and
|
| -** limitations under the License.
|
| -*/
|
| -
|
| -#include "SkDisplayXMLParser.h"
|
| -#include "SkAnimateMaker.h"
|
| -#include "SkDisplayApply.h"
|
| -#include "SkUtils.h"
|
| -#ifdef SK_DEBUG
|
| -#include "SkTime.h"
|
| -#endif
|
| -
|
| -static char const* const gErrorStrings[] = {
|
| - "unknown error ",
|
| - "apply scopes itself",
|
| - "display tree too deep (circular reference?) ",
|
| - "element missing parent ",
|
| - "element type not allowed in parent ",
|
| - "error adding <data> to <post> ",
|
| - "error adding to <matrix> ",
|
| - "error adding to <paint> ",
|
| - "error adding to <path> ",
|
| - "error in attribute value ",
|
| - "error in script ",
|
| - "expected movie in sink attribute ",
|
| - "field not in target ",
|
| - "number of offsets in gradient must match number of colors",
|
| - "no offset in gradient may be greater than one",
|
| - "last offset in gradient must be one",
|
| - "offsets in gradient must be increasing",
|
| - "first offset in gradient must be zero",
|
| - "gradient attribute \"points\" must have length of four",
|
| - "in include ",
|
| - "in movie ",
|
| - "include name unknown or missing ",
|
| - "index out of range ",
|
| - "movie name unknown or missing ",
|
| - "no parent available to resolve sink attribute ",
|
| - "parent element can't contain ",
|
| - "saveLayer must specify a bounds",
|
| - "target id not found ",
|
| - "unexpected type "
|
| -};
|
| -
|
| -SkDisplayXMLParserError::~SkDisplayXMLParserError() {
|
| -}
|
| -
|
| -void SkDisplayXMLParserError::getErrorString(SkString* str) const {
|
| - if (fCode > kUnknownError)
|
| - str->set(gErrorStrings[fCode - kUnknownError]);
|
| - else
|
| - str->reset();
|
| - INHERITED::getErrorString(str);
|
| -}
|
| -
|
| -void SkDisplayXMLParserError::setInnerError(SkAnimateMaker* parent, const SkString& src) {
|
| - SkString inner;
|
| - getErrorString(&inner);
|
| - inner.prepend(": ");
|
| - inner.prependS32(getLineNumber());
|
| - inner.prepend(", line ");
|
| - inner.prepend(src);
|
| - parent->setErrorNoun(inner);
|
| -}
|
| -
|
| -
|
| -SkDisplayXMLParser::SkDisplayXMLParser(SkAnimateMaker& maker)
|
| - : INHERITED(&maker.fError), fMaker(maker), fInInclude(maker.fInInclude),
|
| - fInSkia(maker.fInInclude), fCurrDisplayable(NULL)
|
| -{
|
| -}
|
| -
|
| -SkDisplayXMLParser::~SkDisplayXMLParser() {
|
| - if (fCurrDisplayable && fMaker.fChildren.find(fCurrDisplayable) < 0)
|
| - delete fCurrDisplayable;
|
| - for (Parent* parPtr = fParents.begin() + 1; parPtr < fParents.end(); parPtr++) {
|
| - SkDisplayable* displayable = parPtr->fDisplayable;
|
| - if (displayable == fCurrDisplayable)
|
| - continue;
|
| - SkASSERT(fMaker.fChildren.find(displayable) < 0);
|
| - if (fMaker.fHelpers.find(displayable) < 0)
|
| - delete displayable;
|
| - }
|
| -}
|
| -
|
| -
|
| -
|
| -bool SkDisplayXMLParser::onAddAttribute(const char name[], const char value[]) {
|
| - return onAddAttributeLen(name, value, strlen(value));
|
| -}
|
| -
|
| -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;
|
| -}
|
| -
|
| -bool SkDisplayXMLParser::onEndElement(const char elem[])
|
| -{
|
| - int parentIndex = fParents.count() - 1;
|
| - if (parentIndex >= 0) {
|
| - Parent& container = fParents[parentIndex];
|
| - SkDisplayable* displayable = container.fDisplayable;
|
| - fMaker.fEndDepth = parentIndex;
|
| - displayable->onEndElement(fMaker);
|
| - if (fMaker.fError.hasError())
|
| - return true;
|
| - if (parentIndex > 0) {
|
| - SkDisplayable* parent = fParents[parentIndex - 1].fDisplayable;
|
| - bool result = parent->add(fMaker, displayable);
|
| - if (fMaker.hasError())
|
| - return true;
|
| - if (result == false) {
|
| - int infoCount;
|
| - const SkMemberInfo* info =
|
| - SkDisplayType::GetMembers(&fMaker, fParents[parentIndex - 1].fType, &infoCount);
|
| - const SkMemberInfo* foundInfo;
|
| - if ((foundInfo = searchContainer(info, infoCount)) != NULL) {
|
| - parent->setReference(foundInfo, displayable);
|
| - // if (displayable->isHelper() == false)
|
| - fMaker.helperAdd(displayable);
|
| - } else {
|
| - fMaker.setErrorCode(SkDisplayXMLParserError::kElementTypeNotAllowedInParent);
|
| - return true;
|
| - }
|
| - }
|
| - if (parent->childrenNeedDisposing())
|
| - delete displayable;
|
| - }
|
| - fParents.remove(parentIndex);
|
| - }
|
| - fCurrDisplayable = NULL;
|
| - if (fInInclude == false && strcasecmp(elem, "screenplay") == 0) {
|
| - if (fMaker.fInMovie == false) {
|
| - fMaker.fEnableTime = fMaker.getAppTime();
|
| -#if defined SK_DEBUG && defined SK_DEBUG_ANIMATION_TIMING
|
| - if (fMaker.fDebugTimeBase == (SkMSec) -1)
|
| - fMaker.fDebugTimeBase = fMaker.fEnableTime;
|
| - SkString debugOut;
|
| - SkMSec time = fMaker.getAppTime();
|
| - debugOut.appendS32(time - fMaker.fDebugTimeBase);
|
| - debugOut.append(" onLoad enable=");
|
| - debugOut.appendS32(fMaker.fEnableTime - fMaker.fDebugTimeBase);
|
| - SkDebugf("%s\n", debugOut.c_str());
|
| -#endif
|
| - fMaker.fEvents.doEvent(fMaker, SkDisplayEvent::kOnload, NULL);
|
| - if (fMaker.fError.hasError())
|
| - return true;
|
| - fMaker.fEvents.removeEvent(SkDisplayEvent::kOnload, NULL);
|
| -
|
| - }
|
| - fInSkia = false;
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -bool SkDisplayXMLParser::onStartElement(const char name[])
|
| -{
|
| - return onStartElementLen(name, strlen(name));
|
| -}
|
| -
|
| -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;
|
| -}
|
| -
|
| -const SkMemberInfo* SkDisplayXMLParser::searchContainer(const SkMemberInfo* infoBase,
|
| - int infoCount) {
|
| - const SkMemberInfo* bestDisplayable = NULL;
|
| - const SkMemberInfo* lastResort = NULL;
|
| - for (int index = 0; index < infoCount; index++) {
|
| - const SkMemberInfo* info = &infoBase[index];
|
| - if (info->fType == SkType_BaseClassInfo) {
|
| - const SkMemberInfo* inherited = info->getInherited();
|
| - const SkMemberInfo* result = searchContainer(inherited, info->fCount);
|
| - if (result != NULL)
|
| - return result;
|
| - continue;
|
| - }
|
| - Parent* container = fParents.end() - 1;
|
| - SkDisplayTypes type = (SkDisplayTypes) info->fType;
|
| - if (type == SkType_MemberProperty)
|
| - type = info->propertyType();
|
| - SkDisplayTypes containerType = container->fType;
|
| - if (type == containerType && (type == SkType_Rect || type == SkType_Polygon ||
|
| - type == SkType_Array || type == SkType_Int || type == SkType_Bitmap))
|
| - goto rectNext;
|
| - while (type != containerType) {
|
| - if (containerType == SkType_Displayable)
|
| - goto next;
|
| - containerType = SkDisplayType::GetParent(&fMaker, containerType);
|
| - if (containerType == SkType_Unknown)
|
| - goto next;
|
| - }
|
| - return info;
|
| -next:
|
| - if (type == SkType_Drawable || type == SkType_Displayable &&
|
| - container->fDisplayable->isDrawable()) {
|
| -rectNext:
|
| - if (fParents.count() > 1) {
|
| - Parent* parent = fParents.end() - 2;
|
| - if (info == parent->fDisplayable->preferredChild(type))
|
| - bestDisplayable = info;
|
| - else
|
| - lastResort = info;
|
| - }
|
| - }
|
| - }
|
| - if (bestDisplayable)
|
| - return bestDisplayable;
|
| - if (lastResort)
|
| - return lastResort;
|
| - return NULL;
|
| -}
|
| -
|
| -
|
|
|