diff options
author | initial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-07-27 00:09:42 +0000 |
---|---|---|
committer | initial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-07-27 00:09:42 +0000 |
commit | ae2c20f398933a9e86c387dcc465ec0f71065ffc (patch) | |
tree | de668b1411e2ee0b4e49b6d8f8b68183134ac990 /skia/animator/SkMemberInfo.cpp | |
parent | 09911bf300f1a419907a9412154760efd0b7abc3 (diff) | |
download | chromium_src-ae2c20f398933a9e86c387dcc465ec0f71065ffc.zip chromium_src-ae2c20f398933a9e86c387dcc465ec0f71065ffc.tar.gz chromium_src-ae2c20f398933a9e86c387dcc465ec0f71065ffc.tar.bz2 |
Add skia to the repository.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@16 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'skia/animator/SkMemberInfo.cpp')
-rw-r--r-- | skia/animator/SkMemberInfo.cpp | 568 |
1 files changed, 568 insertions, 0 deletions
diff --git a/skia/animator/SkMemberInfo.cpp b/skia/animator/SkMemberInfo.cpp new file mode 100644 index 0000000..d4f4e51 --- /dev/null +++ b/skia/animator/SkMemberInfo.cpp @@ -0,0 +1,568 @@ +/* libs/graphics/animator/SkMemberInfo.cpp +** +** Copyright 2006, Google Inc. +** +** 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 "SkMemberInfo.h" +#include "SkAnimateMaker.h" +#include "SkAnimatorScript.h" +#include "SkBase64.h" +#include "SkCamera.h" +#include "SkDisplayable.h" +#include "SkDisplayTypes.h" +#include "SkDraw3D.h" +#include "SkDrawColor.h" +#include "SkParse.h" +#include "SkScript.h" +#include "SkTSearch.h" +#include "SkTypedArray.h" + +size_t SkMemberInfo::GetSize(SkDisplayTypes type) { // size of simple types only + size_t byteSize; + switch (type) { + case SkType_ARGB: + byteSize = sizeof(SkColor); + break; + case SkType_AddMode: + case SkType_Align: + case SkType_ApplyMode: + case SkType_ApplyTransition: + case SkType_BitmapEncoding: + case SkType_Boolean: + case SkType_Cap: + case SkType_EventCode: + case SkType_EventKind: + case SkType_EventMode: + case SkType_FilterType: + case SkType_FontStyle: + case SkType_FromPathMode: + case SkType_Join: + case SkType_MaskFilterBlurStyle: + case SkType_PathDirection: + case SkType_Style: + case SkType_TileMode: + case SkType_Xfermode: + byteSize = sizeof(int); + break; + case SkType_Base64: // assume base64 data is always const, copied by ref + case SkType_Displayable: + case SkType_Drawable: + case SkType_Matrix: + byteSize = sizeof(void*); + break; + case SkType_MSec: + byteSize = sizeof(SkMSec); + break; + case SkType_Point: + byteSize = sizeof(SkPoint); + break; + case SkType_3D_Point: + byteSize = sizeof(Sk3D_Point); + break; + case SkType_Int: + byteSize = sizeof(int32_t); + break; + case SkType_Float: + byteSize = sizeof(SkScalar); + break; + case SkType_DynamicString: + case SkType_String: + byteSize = sizeof(SkString); // assume we'll copy by reference, not value + break; + default: +// SkASSERT(0); + byteSize = 0; + } + return byteSize; +} + +bool SkMemberInfo::getArrayValue(const SkDisplayable* displayable, int index, SkOperand* value) const { + SkASSERT(fType != SkType_String && fType != SkType_MemberProperty); + char* valuePtr = (char*) *(SkOperand**) memberData(displayable); + SkDisplayTypes type = (SkDisplayTypes) 0; + if (displayable->getType() == SkType_Array) { + SkDisplayArray* dispArray = (SkDisplayArray*) displayable; + if (dispArray->values.count() <= index) + return false; + type = dispArray->values.getType(); + } else + SkASSERT(0); // incomplete + size_t byteSize = GetSize(type); + memcpy(value, valuePtr + index * byteSize, byteSize); + 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; +} + +void SkMemberInfo::getString(const SkDisplayable* displayable, SkString** string) const { + if (fType == SkType_MemberProperty) { + SkScriptValue value; + displayable->getProperty(propertyIndex(), &value); + SkASSERT(value.fType == SkType_String); + *string = value.fOperand.fString; + return; + } + SkASSERT(fCount == sizeof(SkString) / sizeof(SkScalar)); + SkASSERT(fType == SkType_String || fType == SkType_DynamicString); + void* valuePtr = memberData(displayable); + *string = (SkString*) valuePtr; +} + +void SkMemberInfo::getValue(const SkDisplayable* displayable, SkOperand value[], int count) const { + SkASSERT(fType != SkType_String && fType != SkType_MemberProperty); + SkASSERT(count == fCount); + void* valuePtr = memberData(displayable); + size_t byteSize = getSize(displayable); + SkASSERT(sizeof(value[0].fScalar) == sizeof(value[0])); // no support for 64 bit pointers, yet + memcpy(value, valuePtr, byteSize); +} + +void SkMemberInfo::setString(SkDisplayable* displayable, SkString* value) const { + SkString* string = (SkString*) memberData(displayable); + string->set(*value); + displayable->dirty(); +} + +void SkMemberInfo::setValue(SkDisplayable* displayable, const SkOperand values[], + int count) const { + SkASSERT(sizeof(values[0].fScalar) == sizeof(values[0])); // no support for 64 bit pointers, yet + char* dst = (char*) memberData(displayable); + if (fType == SkType_Array) { + SkTDScalarArray* array = (SkTDScalarArray* ) dst; + array->setCount(count); + dst = (char*) array->begin(); + } + memcpy(dst, values, count * sizeof(SkOperand)); + displayable->dirty(); +} + + +static inline bool is_between(int c, int min, int max) +{ + return (unsigned)(c - min) <= (unsigned)(max - min); +} + +static inline bool is_hex(int c) +{ + if (is_between(c, '0', '9')) + return true; + c |= 0x20; // make us lower-case + if (is_between(c, 'a', 'f')) + return true; + return false; +} + + +bool SkMemberInfo::setValue(SkAnimateMaker& maker, SkTDOperandArray* arrayStorage, + int storageOffset, int maxStorage, SkDisplayable* displayable, SkDisplayTypes outType, + const char rawValue[], size_t rawValueLen) const +{ + SkString valueStr(rawValue, rawValueLen); + SkScriptValue scriptValue; + scriptValue.fType = SkType_Unknown; + scriptValue.fOperand.fS32 = 0; + SkDisplayTypes type = getType(); + SkAnimatorScript engine(maker, displayable, type); + if (arrayStorage) + displayable = NULL; + bool success = true; + void* untypedStorage = NULL; + if (displayable && fType != SkType_MemberProperty && fType != SkType_MemberFunction) + untypedStorage = (SkTDOperandArray*) memberData(displayable); + + if (type == SkType_ARGB) { + // for both SpiderMonkey and SkiaScript, substitute any #xyz or #xxyyzz first + // it's enough to expand the colors into 0xFFxxyyzz + const char* poundPos; + while ((poundPos = strchr(valueStr.c_str(), '#')) != NULL) { + size_t offset = poundPos - valueStr.c_str(); + if (valueStr.size() - offset < 4) + break; + char r = poundPos[1]; + char g = poundPos[2]; + char b = poundPos[3]; + if (is_hex(r) == false || is_hex(g) == false || is_hex(b) == false) + break; + char hex = poundPos[4]; + if (is_hex(hex) == false) { + valueStr.insertUnichar(offset + 1, r); + valueStr.insertUnichar(offset + 3, g); + valueStr.insertUnichar(offset + 5, b); + } + *(char*) poundPos = '0'; // overwrite '#' + valueStr.insert(offset + 1, "xFF"); + } + } + if (SkDisplayType::IsDisplayable(&maker, type) || SkDisplayType::IsEnum(&maker, type) || type == SkType_ARGB) + goto scriptCommon; + switch (type) { + case SkType_String: +#if 0 + if (displayable && displayable->isAnimate()) { + + goto noScriptString; + } + if (strncmp(rawValue, "#string:", sizeof("#string:") - 1) == 0) { + SkASSERT(sizeof("string") == sizeof("script")); + char* stringHeader = valueStr.writable_str(); + memcpy(&stringHeader[1], "script", sizeof("script") - 1); + rawValue = valueStr.c_str(); + goto noScriptString; + } else +#endif + if (strncmp(rawValue, "#script:", sizeof("#script:") - 1) != 0) + goto noScriptString; + valueStr.remove(0, 8); + case SkType_Unknown: + case SkType_Int: + case SkType_MSec: // for the purposes of script, MSec is treated as a Scalar + case SkType_Point: + case SkType_3D_Point: + case SkType_Float: + case SkType_Array: +scriptCommon: { + const char* script = valueStr.c_str(); + success = engine.evaluateScript(&script, &scriptValue); + if (success == false) { + maker.setScriptError(engine); + return false; + } + } + SkASSERT(success); + if (scriptValue.fType == SkType_Displayable) { + if (type == SkType_String) { + const char* charPtr; + maker.findKey(scriptValue.fOperand.fDisplayable, &charPtr); + scriptValue.fOperand.fString = new SkString(charPtr); + scriptValue.fType = SkType_String; + engine.SkScriptEngine::track(scriptValue.fOperand.fString); + break; + } + SkASSERT(SkDisplayType::IsDisplayable(&maker, type)); + if (displayable) + displayable->setReference(this, scriptValue.fOperand.fDisplayable); + else + arrayStorage->begin()[0].fDisplayable = scriptValue.fOperand.fDisplayable; + return true; + } + if (type != scriptValue.fType) { + if (scriptValue.fType == SkType_Array) { + engine.forget(scriptValue.getArray()); + goto writeStruct; // real structs have already been written by script + } + switch (type) { + case SkType_String: + success = engine.convertTo(SkType_String, &scriptValue); + break; + case SkType_MSec: + case SkType_Float: + success = engine.convertTo(SkType_Float, &scriptValue); + break; + case SkType_Int: + success = engine.convertTo(SkType_Int, &scriptValue); + break; + case SkType_Array: + success = engine.convertTo(arrayType(), &scriptValue); + // !!! incomplete; create array of appropriate type and add scriptValue to it + SkASSERT(0); + break; + case SkType_Displayable: + case SkType_Drawable: + return false; // no way to convert other types to this + default: // to avoid warnings + break; + } + if (success == false) + return false; + } + if (type == SkType_MSec) + scriptValue.fOperand.fMSec = SkScalarMulRound(scriptValue.fOperand.fScalar, 1000); + scriptValue.fType = type; + break; + noScriptString: + case SkType_DynamicString: + if (fType == SkType_MemberProperty && displayable) { + SkString string(rawValue, rawValueLen); + SkScriptValue scriptValue; + scriptValue.fOperand.fString = &string; + scriptValue.fType = SkType_String; + displayable->setProperty(propertyIndex(), scriptValue); + } else if (displayable) { + SkString* string = (SkString*) memberData(displayable); + string->set(rawValue, rawValueLen); + } else { + SkASSERT(arrayStorage->count() == 1); + arrayStorage->begin()->fString->set(rawValue, rawValueLen); + } + goto dirty; + case SkType_Base64: { + SkBase64 base64; + base64.decode(rawValue, rawValueLen); + *(SkBase64* ) untypedStorage = base64; + } goto dirty; + default: + SkASSERT(0); + break; + } +// if (SkDisplayType::IsStruct(type) == false) + { +writeStruct: + if (writeValue(displayable, arrayStorage, storageOffset, maxStorage, + untypedStorage, outType, scriptValue)) { + maker.setErrorCode(SkDisplayXMLParserError::kUnexpectedType); + return false; + } + } +dirty: + if (displayable) + displayable->dirty(); + return true; +} + +bool SkMemberInfo::setValue(SkAnimateMaker& maker, SkTDOperandArray* arrayStorage, + int storageOffset, int maxStorage, SkDisplayable* displayable, SkDisplayTypes outType, + SkString& raw) const { + return setValue(maker, arrayStorage, storageOffset, maxStorage, displayable, outType, raw.c_str(), + raw.size()); +} + +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; +} + + +//void SkMemberInfo::setValue(SkDisplayable* displayable, const char value[], const char name[]) const { +// void* valuePtr = (void*) ((char*) displayable + fOffset); +// switch (fType) { +// case SkType_Point3D: { +// static const char xyz[] = "x|y|z"; +// int index = find_one(xyz, name); +// SkASSERT(index >= 0); +// valuePtr = (void*) ((char*) valuePtr + index * sizeof(SkScalar)); +// } break; +// default: +// SkASSERT(0); +// } +// SkParse::FindScalar(value, (SkScalar*) valuePtr); +// displayable->dirty(); +//} + +#if SK_USE_CONDENSED_INFO == 0 + +// Find Nth memberInfo +const SkMemberInfo* SkMemberInfo::Find(const SkMemberInfo info[], int count, int* index) { + SkASSERT(*index >= 0); + if (info->fType == SkType_BaseClassInfo) { + const SkMemberInfo* inherited = (SkMemberInfo*) info->fName; + const SkMemberInfo* result = SkMemberInfo::Find(inherited, info->fCount, index); + if (result != NULL) + return result; + if (--count == 0) + return NULL; + info++; + } + SkASSERT(info->fName); + SkASSERT(info->fType != SkType_BaseClassInfo); + if (*index >= count) { + *index -= count; + return NULL; + } + return &info[*index]; +} + +// Find named memberinfo +const SkMemberInfo* SkMemberInfo::Find(const SkMemberInfo info[], int count, const char** matchPtr) { + const char* match = *matchPtr; + if (info->fType == SkType_BaseClassInfo) { + const SkMemberInfo* inherited = (SkMemberInfo*) info->fName; + const SkMemberInfo* result = SkMemberInfo::Find(inherited, info->fCount, matchPtr); + if (result != NULL) + return result; + if (--count == 0) + return NULL; + info++; + } + SkASSERT(info->fName); + SkASSERT(info->fType != SkType_BaseClassInfo); + int index = SkStrSearch(&info->fName, count, match, sizeof(*info)); + if (index < 0 || index >= count) + return NULL; + return &info[index]; +} + +const SkMemberInfo* SkMemberInfo::getInherited() const { + return (SkMemberInfo*) fName; +} + +#endif // SK_USE_CONDENSED_INFO == 0 + +#if 0 +bool SkMemberInfo::SetValue(void* valuePtr, const char value[], SkDisplayTypes type, + int count) { + switch (type) { + case SkType_Animate: + case SkType_BaseBitmap: + case SkType_Bitmap: + case SkType_Dash: + case SkType_Displayable: + case SkType_Drawable: + case SkType_Matrix: + case SkType_Path: + case SkType_Text: + case SkType_3D_Patch: + return false; // ref to object; caller must resolve + case SkType_MSec: { + SkParse::FindMSec(value, (SkMSec*) valuePtr); + } break; + case SkType_3D_Point: + case SkType_Point: + // case SkType_PointArray: + case SkType_ScalarArray: + SkParse::FindScalars(value, (SkScalar*) valuePtr, count); + break; + default: + SkASSERT(0); + } + return true; +} +#endif + + |