michael@0: michael@0: /* michael@0: * Copyright 2006 The Android Open Source Project michael@0: * michael@0: * Use of this source code is governed by a BSD-style license that can be michael@0: * found in the LICENSE file. michael@0: */ michael@0: michael@0: michael@0: #include "SkMemberInfo.h" michael@0: #include "SkAnimateMaker.h" michael@0: #include "SkAnimatorScript.h" michael@0: #include "SkBase64.h" michael@0: #include "SkCamera.h" michael@0: #include "SkDisplayable.h" michael@0: #include "SkDisplayTypes.h" michael@0: #include "SkDraw3D.h" michael@0: #include "SkDrawColor.h" michael@0: #include "SkParse.h" michael@0: #include "SkScript.h" michael@0: #include "SkTSearch.h" michael@0: #include "SkTypedArray.h" michael@0: michael@0: size_t SkMemberInfo::GetSize(SkDisplayTypes type) { // size of simple types only michael@0: size_t byteSize; michael@0: switch (type) { michael@0: case SkType_ARGB: michael@0: byteSize = sizeof(SkColor); michael@0: break; michael@0: case SkType_AddMode: michael@0: case SkType_Align: michael@0: case SkType_ApplyMode: michael@0: case SkType_ApplyTransition: michael@0: case SkType_BitmapEncoding: michael@0: case SkType_Boolean: michael@0: case SkType_Cap: michael@0: case SkType_EventCode: michael@0: case SkType_EventKind: michael@0: case SkType_EventMode: michael@0: case SkType_FilterType: michael@0: case SkType_FontStyle: michael@0: case SkType_FromPathMode: michael@0: case SkType_Join: michael@0: case SkType_MaskFilterBlurStyle: michael@0: case SkType_PathDirection: michael@0: case SkType_Style: michael@0: case SkType_TileMode: michael@0: case SkType_Xfermode: michael@0: byteSize = sizeof(int); michael@0: break; michael@0: case SkType_Base64: // assume base64 data is always const, copied by ref michael@0: case SkType_Displayable: michael@0: case SkType_Drawable: michael@0: case SkType_Matrix: michael@0: byteSize = sizeof(void*); michael@0: break; michael@0: case SkType_MSec: michael@0: byteSize = sizeof(SkMSec); michael@0: break; michael@0: case SkType_Point: michael@0: byteSize = sizeof(SkPoint); michael@0: break; michael@0: case SkType_3D_Point: michael@0: byteSize = sizeof(Sk3D_Point); michael@0: break; michael@0: case SkType_Int: michael@0: byteSize = sizeof(int32_t); michael@0: break; michael@0: case SkType_Float: michael@0: byteSize = sizeof(SkScalar); michael@0: break; michael@0: case SkType_DynamicString: michael@0: case SkType_String: michael@0: byteSize = sizeof(SkString); // assume we'll copy by reference, not value michael@0: break; michael@0: default: michael@0: // SkASSERT(0); michael@0: byteSize = 0; michael@0: } michael@0: return byteSize; michael@0: } michael@0: michael@0: bool SkMemberInfo::getArrayValue(const SkDisplayable* displayable, int index, SkOperand* value) const { michael@0: SkASSERT(fType != SkType_String && fType != SkType_MemberProperty); michael@0: char* valuePtr = (char*) *(SkOperand**) memberData(displayable); michael@0: SkDisplayTypes type = (SkDisplayTypes) 0; michael@0: if (displayable->getType() == SkType_Array) { michael@0: SkDisplayArray* dispArray = (SkDisplayArray*) displayable; michael@0: if (dispArray->values.count() <= index) michael@0: return false; michael@0: type = dispArray->values.getType(); michael@0: } else { michael@0: SkASSERT(0); // incomplete michael@0: } michael@0: size_t byteSize = GetSize(type); michael@0: memcpy(value, valuePtr + index * byteSize, byteSize); michael@0: return true; michael@0: } michael@0: michael@0: size_t SkMemberInfo::getSize(const SkDisplayable* displayable) const { michael@0: size_t byteSize; michael@0: switch (fType) { michael@0: case SkType_MemberProperty: michael@0: byteSize = GetSize(propertyType()); michael@0: break; michael@0: case SkType_Array: { michael@0: SkDisplayTypes type; michael@0: if (displayable == NULL) michael@0: return sizeof(int); michael@0: if (displayable->getType() == SkType_Array) { michael@0: SkDisplayArray* dispArray = (SkDisplayArray*) displayable; michael@0: type = dispArray->values.getType(); michael@0: } else michael@0: type = propertyType(); michael@0: SkTDOperandArray* array = (SkTDOperandArray*) memberData(displayable); michael@0: byteSize = GetSize(type) * array->count(); michael@0: } break; michael@0: default: michael@0: byteSize = GetSize((SkDisplayTypes) fType); michael@0: } michael@0: return byteSize; michael@0: } michael@0: michael@0: void SkMemberInfo::getString(const SkDisplayable* displayable, SkString** string) const { michael@0: if (fType == SkType_MemberProperty) { michael@0: SkScriptValue value; michael@0: displayable->getProperty(propertyIndex(), &value); michael@0: SkASSERT(value.fType == SkType_String); michael@0: *string = value.fOperand.fString; michael@0: return; michael@0: } michael@0: SkASSERT(fCount == sizeof(SkString) / sizeof(SkScalar)); michael@0: SkASSERT(fType == SkType_String || fType == SkType_DynamicString); michael@0: void* valuePtr = memberData(displayable); michael@0: *string = (SkString*) valuePtr; michael@0: } michael@0: michael@0: void SkMemberInfo::getValue(const SkDisplayable* displayable, SkOperand value[], int count) const { michael@0: SkASSERT(fType != SkType_String && fType != SkType_MemberProperty); michael@0: SkASSERT(count == fCount); michael@0: void* valuePtr = memberData(displayable); michael@0: size_t byteSize = getSize(displayable); michael@0: SkASSERT(sizeof(value[0].fScalar) == sizeof(value[0])); // no support for 64 bit pointers, yet michael@0: memcpy(value, valuePtr, byteSize); michael@0: } michael@0: michael@0: void SkMemberInfo::setString(SkDisplayable* displayable, SkString* value) const { michael@0: SkString* string = (SkString*) memberData(displayable); michael@0: string->set(*value); michael@0: displayable->dirty(); michael@0: } michael@0: michael@0: void SkMemberInfo::setValue(SkDisplayable* displayable, const SkOperand values[], michael@0: int count) const { michael@0: SkASSERT(sizeof(values[0].fScalar) == sizeof(values[0])); // no support for 64 bit pointers, yet michael@0: char* dst = (char*) memberData(displayable); michael@0: if (fType == SkType_Array) { michael@0: SkTDScalarArray* array = (SkTDScalarArray* ) dst; michael@0: array->setCount(count); michael@0: dst = (char*) array->begin(); michael@0: } michael@0: memcpy(dst, values, count * sizeof(SkOperand)); michael@0: displayable->dirty(); michael@0: } michael@0: michael@0: michael@0: static inline bool is_between(int c, int min, int max) michael@0: { michael@0: return (unsigned)(c - min) <= (unsigned)(max - min); michael@0: } michael@0: michael@0: static inline bool is_hex(int c) michael@0: { michael@0: if (is_between(c, '0', '9')) michael@0: return true; michael@0: c |= 0x20; // make us lower-case michael@0: if (is_between(c, 'a', 'f')) michael@0: return true; michael@0: return false; michael@0: } michael@0: michael@0: michael@0: bool SkMemberInfo::setValue(SkAnimateMaker& maker, SkTDOperandArray* arrayStorage, michael@0: int storageOffset, int maxStorage, SkDisplayable* displayable, SkDisplayTypes outType, michael@0: const char rawValue[], size_t rawValueLen) const michael@0: { michael@0: SkString valueStr(rawValue, rawValueLen); michael@0: SkScriptValue scriptValue; michael@0: scriptValue.fType = SkType_Unknown; michael@0: scriptValue.fOperand.fS32 = 0; michael@0: SkDisplayTypes type = getType(); michael@0: SkAnimatorScript engine(maker, displayable, type); michael@0: if (arrayStorage) michael@0: displayable = NULL; michael@0: bool success = true; michael@0: void* untypedStorage = NULL; michael@0: if (displayable && fType != SkType_MemberProperty && fType != SkType_MemberFunction) michael@0: untypedStorage = (SkTDOperandArray*) memberData(displayable); michael@0: michael@0: if (type == SkType_ARGB) { michael@0: // for both SpiderMonkey and SkiaScript, substitute any #xyz or #xxyyzz first michael@0: // it's enough to expand the colors into 0xFFxxyyzz michael@0: const char* poundPos; michael@0: while ((poundPos = strchr(valueStr.c_str(), '#')) != NULL) { michael@0: size_t offset = poundPos - valueStr.c_str(); michael@0: if (valueStr.size() - offset < 4) michael@0: break; michael@0: char r = poundPos[1]; michael@0: char g = poundPos[2]; michael@0: char b = poundPos[3]; michael@0: if (is_hex(r) == false || is_hex(g) == false || is_hex(b) == false) michael@0: break; michael@0: char hex = poundPos[4]; michael@0: if (is_hex(hex) == false) { michael@0: valueStr.insertUnichar(offset + 1, r); michael@0: valueStr.insertUnichar(offset + 3, g); michael@0: valueStr.insertUnichar(offset + 5, b); michael@0: } michael@0: *(char*) poundPos = '0'; // overwrite '#' michael@0: valueStr.insert(offset + 1, "xFF"); michael@0: } michael@0: } michael@0: if (SkDisplayType::IsDisplayable(&maker, type) || SkDisplayType::IsEnum(&maker, type) || type == SkType_ARGB) michael@0: goto scriptCommon; michael@0: switch (type) { michael@0: case SkType_String: michael@0: #if 0 michael@0: if (displayable && displayable->isAnimate()) { michael@0: michael@0: goto noScriptString; michael@0: } michael@0: if (strncmp(rawValue, "#string:", sizeof("#string:") - 1) == 0) { michael@0: SkASSERT(sizeof("string") == sizeof("script")); michael@0: char* stringHeader = valueStr.writable_str(); michael@0: memcpy(&stringHeader[1], "script", sizeof("script") - 1); michael@0: rawValue = valueStr.c_str(); michael@0: goto noScriptString; michael@0: } else michael@0: #endif michael@0: if (strncmp(rawValue, "#script:", sizeof("#script:") - 1) != 0) michael@0: goto noScriptString; michael@0: valueStr.remove(0, 8); michael@0: case SkType_Unknown: michael@0: case SkType_Int: michael@0: case SkType_MSec: // for the purposes of script, MSec is treated as a Scalar michael@0: case SkType_Point: michael@0: case SkType_3D_Point: michael@0: case SkType_Float: michael@0: case SkType_Array: michael@0: scriptCommon: { michael@0: const char* script = valueStr.c_str(); michael@0: success = engine.evaluateScript(&script, &scriptValue); michael@0: if (success == false) { michael@0: maker.setScriptError(engine); michael@0: return false; michael@0: } michael@0: } michael@0: SkASSERT(success); michael@0: if (scriptValue.fType == SkType_Displayable) { michael@0: if (type == SkType_String) { michael@0: const char* charPtr = NULL; michael@0: maker.findKey(scriptValue.fOperand.fDisplayable, &charPtr); michael@0: scriptValue.fOperand.fString = new SkString(charPtr); michael@0: scriptValue.fType = SkType_String; michael@0: engine.SkScriptEngine::track(scriptValue.fOperand.fString); michael@0: break; michael@0: } michael@0: SkASSERT(SkDisplayType::IsDisplayable(&maker, type)); michael@0: if (displayable) michael@0: displayable->setReference(this, scriptValue.fOperand.fDisplayable); michael@0: else michael@0: arrayStorage->begin()[0].fDisplayable = scriptValue.fOperand.fDisplayable; michael@0: return true; michael@0: } michael@0: if (type != scriptValue.fType) { michael@0: if (scriptValue.fType == SkType_Array) { michael@0: engine.forget(scriptValue.getArray()); michael@0: goto writeStruct; // real structs have already been written by script michael@0: } michael@0: switch (type) { michael@0: case SkType_String: michael@0: success = engine.convertTo(SkType_String, &scriptValue); michael@0: break; michael@0: case SkType_MSec: michael@0: case SkType_Float: michael@0: success = engine.convertTo(SkType_Float, &scriptValue); michael@0: break; michael@0: case SkType_Int: michael@0: success = engine.convertTo(SkType_Int, &scriptValue); michael@0: break; michael@0: case SkType_Array: michael@0: success = engine.convertTo(arrayType(), &scriptValue); michael@0: // !!! incomplete; create array of appropriate type and add scriptValue to it michael@0: SkASSERT(0); michael@0: break; michael@0: case SkType_Displayable: michael@0: case SkType_Drawable: michael@0: return false; // no way to convert other types to this michael@0: default: // to avoid warnings michael@0: break; michael@0: } michael@0: if (success == false) michael@0: return false; michael@0: } michael@0: if (type == SkType_MSec) michael@0: scriptValue.fOperand.fMSec = SkScalarRoundToInt(scriptValue.fOperand.fScalar * 1000); michael@0: scriptValue.fType = type; michael@0: break; michael@0: noScriptString: michael@0: case SkType_DynamicString: michael@0: if (fType == SkType_MemberProperty && displayable) { michael@0: SkString string(rawValue, rawValueLen); michael@0: SkScriptValue scriptValue; michael@0: scriptValue.fOperand.fString = &string; michael@0: scriptValue.fType = SkType_String; michael@0: displayable->setProperty(propertyIndex(), scriptValue); michael@0: } else if (displayable) { michael@0: SkString* string = (SkString*) memberData(displayable); michael@0: string->set(rawValue, rawValueLen); michael@0: } else { michael@0: SkASSERT(arrayStorage->count() == 1); michael@0: arrayStorage->begin()->fString->set(rawValue, rawValueLen); michael@0: } michael@0: goto dirty; michael@0: case SkType_Base64: { michael@0: SkBase64 base64; michael@0: base64.decode(rawValue, rawValueLen); michael@0: *(SkBase64* ) untypedStorage = base64; michael@0: } goto dirty; michael@0: default: michael@0: SkASSERT(0); michael@0: break; michael@0: } michael@0: // if (SkDisplayType::IsStruct(type) == false) michael@0: { michael@0: writeStruct: michael@0: if (writeValue(displayable, arrayStorage, storageOffset, maxStorage, michael@0: untypedStorage, outType, scriptValue)) { michael@0: maker.setErrorCode(SkDisplayXMLParserError::kUnexpectedType); michael@0: return false; michael@0: } michael@0: } michael@0: dirty: michael@0: if (displayable) michael@0: displayable->dirty(); michael@0: return true; michael@0: } michael@0: michael@0: bool SkMemberInfo::setValue(SkAnimateMaker& maker, SkTDOperandArray* arrayStorage, michael@0: int storageOffset, int maxStorage, SkDisplayable* displayable, SkDisplayTypes outType, michael@0: SkString& raw) const { michael@0: return setValue(maker, arrayStorage, storageOffset, maxStorage, displayable, outType, raw.c_str(), michael@0: raw.size()); michael@0: } michael@0: michael@0: bool SkMemberInfo::writeValue(SkDisplayable* displayable, SkTDOperandArray* arrayStorage, michael@0: int storageOffset, int maxStorage, void* untypedStorage, SkDisplayTypes outType, michael@0: SkScriptValue& scriptValue) const michael@0: { michael@0: SkOperand* storage = untypedStorage ? (SkOperand*) untypedStorage : arrayStorage ? michael@0: arrayStorage->begin() : NULL; michael@0: if (storage) michael@0: storage += storageOffset; michael@0: SkDisplayTypes type = getType(); michael@0: if (fType == SkType_MemberProperty) { michael@0: if(displayable) michael@0: displayable->setProperty(propertyIndex(), scriptValue); michael@0: else { michael@0: SkASSERT(storageOffset < arrayStorage->count()); michael@0: switch (scriptValue.fType) { michael@0: case SkType_Boolean: michael@0: case SkType_Float: michael@0: case SkType_Int: michael@0: memcpy(&storage->fScalar, &scriptValue.fOperand.fScalar, sizeof(SkScalar)); michael@0: break; michael@0: case SkType_Array: michael@0: memcpy(&storage->fScalar, scriptValue.fOperand.fArray->begin(), scriptValue.fOperand.fArray->count() * sizeof(SkScalar)); michael@0: break; michael@0: case SkType_String: michael@0: storage->fString->set(*scriptValue.fOperand.fString); michael@0: break; michael@0: default: michael@0: SkASSERT(0); // type isn't handled yet michael@0: } michael@0: } michael@0: } else if (fType == SkType_MemberFunction) { michael@0: SkASSERT(scriptValue.fType == SkType_Array); michael@0: if (displayable) michael@0: displayable->executeFunction(displayable, this, scriptValue.fOperand.fArray, NULL); michael@0: else { michael@0: int count = scriptValue.fOperand.fArray->count(); michael@0: // SkASSERT(maxStorage == 0 || count == maxStorage); michael@0: if (arrayStorage->count() == 2) michael@0: arrayStorage->setCount(2 * count); michael@0: else { michael@0: storageOffset *= count; michael@0: SkASSERT(count + storageOffset <= arrayStorage->count()); michael@0: } michael@0: memcpy(&(*arrayStorage)[storageOffset], scriptValue.fOperand.fArray->begin(), count * sizeof(SkOperand)); michael@0: } michael@0: michael@0: } else if (fType == SkType_Array) { michael@0: SkTypedArray* destArray = (SkTypedArray*) (untypedStorage ? untypedStorage : arrayStorage); michael@0: SkASSERT(destArray); michael@0: // destArray->setCount(0); michael@0: if (scriptValue.fType != SkType_Array) { michael@0: SkASSERT(type == scriptValue.fType); michael@0: // SkASSERT(storageOffset + 1 <= maxStorage); michael@0: destArray->setCount(storageOffset + 1); michael@0: (*destArray)[storageOffset] = scriptValue.fOperand; michael@0: } else { michael@0: if (type == SkType_Unknown) { michael@0: type = scriptValue.fOperand.fArray->getType(); michael@0: destArray->setType(type); michael@0: } michael@0: SkASSERT(type == scriptValue.fOperand.fArray->getType()); michael@0: int count = scriptValue.fOperand.fArray->count(); michael@0: // SkASSERT(storageOffset + count <= maxStorage); michael@0: destArray->setCount(storageOffset + count); michael@0: memcpy(destArray->begin() + storageOffset, scriptValue.fOperand.fArray->begin(), sizeof(SkOperand) * count); michael@0: } michael@0: } else if (type == SkType_String) { michael@0: SkString* string = untypedStorage ? (SkString*) untypedStorage : (*arrayStorage)[storageOffset].fString; michael@0: string->set(*scriptValue.fOperand.fString); michael@0: } else if (type == SkType_ARGB && outType == SkType_Float) { michael@0: SkTypedArray* array = scriptValue.fOperand.fArray; michael@0: SkASSERT(scriptValue.fType == SkType_Int || scriptValue.fType == SkType_ARGB || michael@0: scriptValue.fType == SkType_Array); michael@0: SkASSERT(scriptValue.fType != SkType_Array || (array != NULL && michael@0: array->getType() == SkType_Int)); michael@0: int numberOfColors = scriptValue.fType == SkType_Array ? array->count() : 1; michael@0: int numberOfComponents = numberOfColors * 4; michael@0: // SkASSERT(maxStorage == 0 || maxStorage == numberOfComponents); michael@0: if (maxStorage == 0) michael@0: arrayStorage->setCount(numberOfComponents); michael@0: for (int index = 0; index < numberOfColors; index++) { michael@0: SkColor color = scriptValue.fType == SkType_Array ? michael@0: (SkColor) array->begin()[index].fS32 : (SkColor) scriptValue.fOperand.fS32; michael@0: storage[0].fScalar = SkIntToScalar(SkColorGetA(color)); michael@0: storage[1].fScalar = SkIntToScalar(SkColorGetR(color)); michael@0: storage[2].fScalar = SkIntToScalar(SkColorGetG(color)); michael@0: storage[3].fScalar = SkIntToScalar(SkColorGetB(color)); michael@0: storage += 4; michael@0: } michael@0: } else if (SkDisplayType::IsStruct(NULL /* !!! maker*/, type)) { michael@0: if (scriptValue.fType != SkType_Array) michael@0: return true; // error michael@0: SkASSERT(sizeof(SkScalar) == sizeof(SkOperand)); // !!! no 64 bit pointer support yet michael@0: int count = scriptValue.fOperand.fArray->count(); michael@0: if (count > 0) { michael@0: SkASSERT(fCount == count); michael@0: memcpy(storage, scriptValue.fOperand.fArray->begin(), count * sizeof(SkOperand)); michael@0: } michael@0: } else if (scriptValue.fType == SkType_Array) { michael@0: SkASSERT(scriptValue.fOperand.fArray->getType() == type); michael@0: SkASSERT(scriptValue.fOperand.fArray->count() == getCount()); michael@0: memcpy(storage, scriptValue.fOperand.fArray->begin(), getCount() * sizeof(SkOperand)); michael@0: } else { michael@0: memcpy(storage, &scriptValue.fOperand, sizeof(SkOperand)); michael@0: } michael@0: return false; michael@0: } michael@0: michael@0: michael@0: //void SkMemberInfo::setValue(SkDisplayable* displayable, const char value[], const char name[]) const { michael@0: // void* valuePtr = (void*) ((char*) displayable + fOffset); michael@0: // switch (fType) { michael@0: // case SkType_Point3D: { michael@0: // static const char xyz[] = "x|y|z"; michael@0: // int index = find_one(xyz, name); michael@0: // SkASSERT(index >= 0); michael@0: // valuePtr = (void*) ((char*) valuePtr + index * sizeof(SkScalar)); michael@0: // } break; michael@0: // default: michael@0: // SkASSERT(0); michael@0: // } michael@0: // SkParse::FindScalar(value, (SkScalar*) valuePtr); michael@0: // displayable->dirty(); michael@0: //} michael@0: michael@0: #if SK_USE_CONDENSED_INFO == 0 michael@0: michael@0: // Find Nth memberInfo michael@0: const SkMemberInfo* SkMemberInfo::Find(const SkMemberInfo info[], int count, int* index) { michael@0: SkASSERT(*index >= 0); michael@0: if (info->fType == SkType_BaseClassInfo) { michael@0: const SkMemberInfo* inherited = (SkMemberInfo*) info->fName; michael@0: const SkMemberInfo* result = SkMemberInfo::Find(inherited, info->fCount, index); michael@0: if (result != NULL) michael@0: return result; michael@0: if (--count == 0) michael@0: return NULL; michael@0: info++; michael@0: } michael@0: SkASSERT(info->fName); michael@0: SkASSERT(info->fType != SkType_BaseClassInfo); michael@0: if (*index >= count) { michael@0: *index -= count; michael@0: return NULL; michael@0: } michael@0: return &info[*index]; michael@0: } michael@0: michael@0: // Find named memberinfo michael@0: const SkMemberInfo* SkMemberInfo::Find(const SkMemberInfo info[], int count, const char** matchPtr) { michael@0: const char* match = *matchPtr; michael@0: if (info->fType == SkType_BaseClassInfo) { michael@0: const SkMemberInfo* inherited = (SkMemberInfo*) info->fName; michael@0: const SkMemberInfo* result = SkMemberInfo::Find(inherited, info->fCount, matchPtr); michael@0: if (result != NULL) michael@0: return result; michael@0: if (--count == 0) michael@0: return NULL; michael@0: info++; michael@0: } michael@0: SkASSERT(info->fName); michael@0: SkASSERT(info->fType != SkType_BaseClassInfo); michael@0: int index = SkStrSearch(&info->fName, count, match, sizeof(*info)); michael@0: if (index < 0 || index >= count) michael@0: return NULL; michael@0: return &info[index]; michael@0: } michael@0: michael@0: const SkMemberInfo* SkMemberInfo::getInherited() const { michael@0: return (SkMemberInfo*) fName; michael@0: } michael@0: michael@0: #endif // SK_USE_CONDENSED_INFO == 0 michael@0: michael@0: #if 0 michael@0: bool SkMemberInfo::SetValue(void* valuePtr, const char value[], SkDisplayTypes type, michael@0: int count) { michael@0: switch (type) { michael@0: case SkType_Animate: michael@0: case SkType_BaseBitmap: michael@0: case SkType_Bitmap: michael@0: case SkType_Dash: michael@0: case SkType_Displayable: michael@0: case SkType_Drawable: michael@0: case SkType_Matrix: michael@0: case SkType_Path: michael@0: case SkType_Text: michael@0: case SkType_3D_Patch: michael@0: return false; // ref to object; caller must resolve michael@0: case SkType_MSec: { michael@0: SkParse::FindMSec(value, (SkMSec*) valuePtr); michael@0: } break; michael@0: case SkType_3D_Point: michael@0: case SkType_Point: michael@0: // case SkType_PointArray: michael@0: case SkType_ScalarArray: michael@0: SkParse::FindScalars(value, (SkScalar*) valuePtr, count); michael@0: break; michael@0: default: michael@0: SkASSERT(0); michael@0: } michael@0: return true; michael@0: } michael@0: #endif