1685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com 2685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com/* 3685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com * Copyright 2006 The Android Open Source Project 4685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com * 5685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com * Use of this source code is governed by a BSD-style license that can be 6685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com * found in the LICENSE file. 7685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com */ 8685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com 9bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 10bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#include "SkMemberInfo.h" 11bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#include "SkAnimateMaker.h" 12bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#include "SkAnimatorScript.h" 13bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#include "SkBase64.h" 14bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#include "SkCamera.h" 15bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#include "SkDisplayable.h" 16bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#include "SkDisplayTypes.h" 17bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#include "SkDraw3D.h" 18bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#include "SkDrawColor.h" 19bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#include "SkParse.h" 20bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#include "SkScript.h" 21bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#include "SkTSearch.h" 22bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#include "SkTypedArray.h" 23bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 24bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comsize_t SkMemberInfo::GetSize(SkDisplayTypes type) { // size of simple types only 25bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com size_t byteSize; 26bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com switch (type) { 27bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_ARGB: 28bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com byteSize = sizeof(SkColor); 29bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com break; 30bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_AddMode: 31bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_Align: 32bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_ApplyMode: 33bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_ApplyTransition: 34bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_BitmapEncoding: 35bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_Boolean: 36bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_Cap: 37bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_EventCode: 38bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_EventKind: 39bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_EventMode: 40bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_FilterType: 41bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_FontStyle: 42bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_FromPathMode: 43bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_Join: 44bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_MaskFilterBlurStyle: 45bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_PathDirection: 46bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_Style: 47bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_TileMode: 48bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_Xfermode: 49bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com byteSize = sizeof(int); 50bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com break; 51bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_Base64: // assume base64 data is always const, copied by ref 52bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_Displayable: 53bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_Drawable: 54bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_Matrix: 55dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com byteSize = sizeof(void*); 56bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com break; 57bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_MSec: 58bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com byteSize = sizeof(SkMSec); 59bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com break; 60bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_Point: 61bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com byteSize = sizeof(SkPoint); 62bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com break; 63bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_3D_Point: 64bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com byteSize = sizeof(Sk3D_Point); 65bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com break; 66bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_Int: 67bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com byteSize = sizeof(int32_t); 68bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com break; 69bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_Float: 70bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com byteSize = sizeof(SkScalar); 71bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com break; 72bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_DynamicString: 73bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_String: 74bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com byteSize = sizeof(SkString); // assume we'll copy by reference, not value 75bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com break; 76bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com default: 77bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com// SkASSERT(0); 78bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com byteSize = 0; 79bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 80bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return byteSize; 81bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 82bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 83bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.combool SkMemberInfo::getArrayValue(const SkDisplayable* displayable, int index, SkOperand* value) const { 84bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(fType != SkType_String && fType != SkType_MemberProperty); 85bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com char* valuePtr = (char*) *(SkOperand**) memberData(displayable); 86bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkDisplayTypes type = (SkDisplayTypes) 0; 87bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (displayable->getType() == SkType_Array) { 88bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkDisplayArray* dispArray = (SkDisplayArray*) displayable; 89bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (dispArray->values.count() <= index) 90bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return false; 91bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com type = dispArray->values.getType(); 9262169b6b2af23ef3e62b218033a3b2d471522975tomhudson@google.com } else { 93bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(0); // incomplete 9462169b6b2af23ef3e62b218033a3b2d471522975tomhudson@google.com } 95bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com size_t byteSize = GetSize(type); 96bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com memcpy(value, valuePtr + index * byteSize, byteSize); 97bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return true; 98bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 99bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 100bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comsize_t SkMemberInfo::getSize(const SkDisplayable* displayable) const { 101bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com size_t byteSize; 102bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com switch (fType) { 103bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_MemberProperty: 104bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com byteSize = GetSize(propertyType()); 105bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com break; 106bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_Array: { 107bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkDisplayTypes type; 108bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (displayable == NULL) 109bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return sizeof(int); 110bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (displayable->getType() == SkType_Array) { 111bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkDisplayArray* dispArray = (SkDisplayArray*) displayable; 112bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com type = dispArray->values.getType(); 113bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } else 114bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com type = propertyType(); 115bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkTDOperandArray* array = (SkTDOperandArray*) memberData(displayable); 116bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com byteSize = GetSize(type) * array->count(); 117bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } break; 118bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com default: 119bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com byteSize = GetSize((SkDisplayTypes) fType); 120bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 121bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return byteSize; 122bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 123bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 124bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkMemberInfo::getString(const SkDisplayable* displayable, SkString** string) const { 125bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (fType == SkType_MemberProperty) { 126bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkScriptValue value; 127bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com displayable->getProperty(propertyIndex(), &value); 128bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(value.fType == SkType_String); 129bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com *string = value.fOperand.fString; 130bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return; 131bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 132bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(fCount == sizeof(SkString) / sizeof(SkScalar)); 133bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(fType == SkType_String || fType == SkType_DynamicString); 134bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com void* valuePtr = memberData(displayable); 135bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com *string = (SkString*) valuePtr; 136bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 137bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 138bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkMemberInfo::getValue(const SkDisplayable* displayable, SkOperand value[], int count) const { 139bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(fType != SkType_String && fType != SkType_MemberProperty); 140dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com SkASSERT(count == fCount); 141bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com void* valuePtr = memberData(displayable); 142bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com size_t byteSize = getSize(displayable); 143bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(sizeof(value[0].fScalar) == sizeof(value[0])); // no support for 64 bit pointers, yet 144bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com memcpy(value, valuePtr, byteSize); 145bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 146bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 147bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkMemberInfo::setString(SkDisplayable* displayable, SkString* value) const { 148bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkString* string = (SkString*) memberData(displayable); 149bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com string->set(*value); 150bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com displayable->dirty(); 151bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 152bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 153dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.comvoid SkMemberInfo::setValue(SkDisplayable* displayable, const SkOperand values[], 154bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com int count) const { 155bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(sizeof(values[0].fScalar) == sizeof(values[0])); // no support for 64 bit pointers, yet 156bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com char* dst = (char*) memberData(displayable); 157bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (fType == SkType_Array) { 158bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkTDScalarArray* array = (SkTDScalarArray* ) dst; 159bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com array->setCount(count); 160bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com dst = (char*) array->begin(); 161bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 162bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com memcpy(dst, values, count * sizeof(SkOperand)); 163bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com displayable->dirty(); 164bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 165bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 166dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com 167bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comstatic inline bool is_between(int c, int min, int max) 168bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{ 169bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return (unsigned)(c - min) <= (unsigned)(max - min); 170bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 171bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 172bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comstatic inline bool is_hex(int c) 173bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{ 174bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (is_between(c, '0', '9')) 175bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return true; 176bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com c |= 0x20; // make us lower-case 177bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (is_between(c, 'a', 'f')) 178bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return true; 179bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return false; 180bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 181bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 182bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 183dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.combool SkMemberInfo::setValue(SkAnimateMaker& maker, SkTDOperandArray* arrayStorage, 184bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com int storageOffset, int maxStorage, SkDisplayable* displayable, SkDisplayTypes outType, 185dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com const char rawValue[], size_t rawValueLen) const 186bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{ 187bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkString valueStr(rawValue, rawValueLen); 188bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkScriptValue scriptValue; 189bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com scriptValue.fType = SkType_Unknown; 190bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com scriptValue.fOperand.fS32 = 0; 191bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkDisplayTypes type = getType(); 192bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkAnimatorScript engine(maker, displayable, type); 193bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (arrayStorage) 194bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com displayable = NULL; 195bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com bool success = true; 196bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com void* untypedStorage = NULL; 197bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (displayable && fType != SkType_MemberProperty && fType != SkType_MemberFunction) 198bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com untypedStorage = (SkTDOperandArray*) memberData(displayable); 199bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 200bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (type == SkType_ARGB) { 201bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com // for both SpiderMonkey and SkiaScript, substitute any #xyz or #xxyyzz first 202bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com // it's enough to expand the colors into 0xFFxxyyzz 203bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com const char* poundPos; 204bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com while ((poundPos = strchr(valueStr.c_str(), '#')) != NULL) { 205bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com size_t offset = poundPos - valueStr.c_str(); 206bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (valueStr.size() - offset < 4) 207bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com break; 208bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com char r = poundPos[1]; 209bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com char g = poundPos[2]; 210bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com char b = poundPos[3]; 211bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (is_hex(r) == false || is_hex(g) == false || is_hex(b) == false) 212bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com break; 213bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com char hex = poundPos[4]; 214bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (is_hex(hex) == false) { 215bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com valueStr.insertUnichar(offset + 1, r); 216bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com valueStr.insertUnichar(offset + 3, g); 217bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com valueStr.insertUnichar(offset + 5, b); 218bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 219bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com *(char*) poundPos = '0'; // overwrite '#' 220bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com valueStr.insert(offset + 1, "xFF"); 221dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com } 222bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 223bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (SkDisplayType::IsDisplayable(&maker, type) || SkDisplayType::IsEnum(&maker, type) || type == SkType_ARGB) 224bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com goto scriptCommon; 225bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com switch (type) { 226bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_String: 227bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#if 0 228bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (displayable && displayable->isAnimate()) { 229dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com 230bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com goto noScriptString; 231dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com } 232bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (strncmp(rawValue, "#string:", sizeof("#string:") - 1) == 0) { 233bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(sizeof("string") == sizeof("script")); 234bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com char* stringHeader = valueStr.writable_str(); 235bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com memcpy(&stringHeader[1], "script", sizeof("script") - 1); 236bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com rawValue = valueStr.c_str(); 237bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com goto noScriptString; 238dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com } else 239bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#endif 240bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (strncmp(rawValue, "#script:", sizeof("#script:") - 1) != 0) 241bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com goto noScriptString; 242bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com valueStr.remove(0, 8); 243bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_Unknown: 244dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com case SkType_Int: 245bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_MSec: // for the purposes of script, MSec is treated as a Scalar 246bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_Point: 247bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_3D_Point: 248bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_Float: 249bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_Array: 250bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comscriptCommon: { 251bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com const char* script = valueStr.c_str(); 252bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com success = engine.evaluateScript(&script, &scriptValue); 253bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (success == false) { 254bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com maker.setScriptError(engine); 255bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return false; 256bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 257bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 258bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(success); 259bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (scriptValue.fType == SkType_Displayable) { 260bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (type == SkType_String) { 26162169b6b2af23ef3e62b218033a3b2d471522975tomhudson@google.com const char* charPtr = NULL; 262bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com maker.findKey(scriptValue.fOperand.fDisplayable, &charPtr); 263bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com scriptValue.fOperand.fString = new SkString(charPtr); 264bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com scriptValue.fType = SkType_String; 265bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com engine.SkScriptEngine::track(scriptValue.fOperand.fString); 266bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com break; 267bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 268bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(SkDisplayType::IsDisplayable(&maker, type)); 269bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (displayable) 270bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com displayable->setReference(this, scriptValue.fOperand.fDisplayable); 271bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com else 272bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com arrayStorage->begin()[0].fDisplayable = scriptValue.fOperand.fDisplayable; 273bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return true; 274bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 275bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (type != scriptValue.fType) { 276bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (scriptValue.fType == SkType_Array) { 277bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com engine.forget(scriptValue.getArray()); 278bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com goto writeStruct; // real structs have already been written by script 279bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 280bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com switch (type) { 281bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_String: 282bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com success = engine.convertTo(SkType_String, &scriptValue); 283bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com break; 284bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_MSec: 285bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_Float: 286bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com success = engine.convertTo(SkType_Float, &scriptValue); 287bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com break; 288bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_Int: 289bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com success = engine.convertTo(SkType_Int, &scriptValue); 290bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com break; 291bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_Array: 292bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com success = engine.convertTo(arrayType(), &scriptValue); 293bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com // !!! incomplete; create array of appropriate type and add scriptValue to it 294bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(0); 295bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com break; 296bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_Displayable: 297bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_Drawable: 298bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return false; // no way to convert other types to this 299bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com default: // to avoid warnings 300bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com break; 301bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 302bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (success == false) 303bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return false; 304bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 305bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (type == SkType_MSec) 306bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com scriptValue.fOperand.fMSec = SkScalarMulRound(scriptValue.fOperand.fScalar, 1000); 307bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com scriptValue.fType = type; 308bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com break; 309bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com noScriptString: 310bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_DynamicString: 311bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (fType == SkType_MemberProperty && displayable) { 312bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkString string(rawValue, rawValueLen); 313bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkScriptValue scriptValue; 314bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com scriptValue.fOperand.fString = &string; 315bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com scriptValue.fType = SkType_String; 316bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com displayable->setProperty(propertyIndex(), scriptValue); 317bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } else if (displayable) { 318bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkString* string = (SkString*) memberData(displayable); 319bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com string->set(rawValue, rawValueLen); 320bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } else { 321bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(arrayStorage->count() == 1); 322bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com arrayStorage->begin()->fString->set(rawValue, rawValueLen); 323bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 324bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com goto dirty; 325bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_Base64: { 326bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkBase64 base64; 327bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com base64.decode(rawValue, rawValueLen); 328bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com *(SkBase64* ) untypedStorage = base64; 329bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } goto dirty; 330bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com default: 331bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(0); 332bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com break; 333bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 334dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com// if (SkDisplayType::IsStruct(type) == false) 335bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com { 336bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comwriteStruct: 337dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com if (writeValue(displayable, arrayStorage, storageOffset, maxStorage, 338bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com untypedStorage, outType, scriptValue)) { 339bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com maker.setErrorCode(SkDisplayXMLParserError::kUnexpectedType); 340bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return false; 341bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 342bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 343bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comdirty: 344bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (displayable) 345bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com displayable->dirty(); 346bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return true; 347bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 348bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 349dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.combool SkMemberInfo::setValue(SkAnimateMaker& maker, SkTDOperandArray* arrayStorage, 350bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com int storageOffset, int maxStorage, SkDisplayable* displayable, SkDisplayTypes outType, 351bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkString& raw) const { 352bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return setValue(maker, arrayStorage, storageOffset, maxStorage, displayable, outType, raw.c_str(), 353bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com raw.size()); 354bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 355bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 356dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.combool SkMemberInfo::writeValue(SkDisplayable* displayable, SkTDOperandArray* arrayStorage, 357dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com int storageOffset, int maxStorage, void* untypedStorage, SkDisplayTypes outType, 358bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkScriptValue& scriptValue) const 359bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{ 360dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com SkOperand* storage = untypedStorage ? (SkOperand*) untypedStorage : arrayStorage ? 361bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com arrayStorage->begin() : NULL; 362bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (storage) 363bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com storage += storageOffset; 364bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkDisplayTypes type = getType(); 365bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (fType == SkType_MemberProperty) { 366bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if(displayable) 367bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com displayable->setProperty(propertyIndex(), scriptValue); 368bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com else { 369bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(storageOffset < arrayStorage->count()); 370bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com switch (scriptValue.fType) { 371bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_Boolean: 372bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_Float: 373bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_Int: 374bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com memcpy(&storage->fScalar, &scriptValue.fOperand.fScalar, sizeof(SkScalar)); 375bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com break; 376bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_Array: 377bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com memcpy(&storage->fScalar, scriptValue.fOperand.fArray->begin(), scriptValue.fOperand.fArray->count() * sizeof(SkScalar)); 378bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com break; 379bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_String: 380bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com storage->fString->set(*scriptValue.fOperand.fString); 381bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com break; 382bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com default: 383bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(0); // type isn't handled yet 384bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 385bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 386bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } else if (fType == SkType_MemberFunction) { 387bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(scriptValue.fType == SkType_Array); 388bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (displayable) 389bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com displayable->executeFunction(displayable, this, scriptValue.fOperand.fArray, NULL); 390bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com else { 391bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com int count = scriptValue.fOperand.fArray->count(); 392bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com // SkASSERT(maxStorage == 0 || count == maxStorage); 393bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (arrayStorage->count() == 2) 394bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com arrayStorage->setCount(2 * count); 395bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com else { 396bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com storageOffset *= count; 397bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(count + storageOffset <= arrayStorage->count()); 398bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 399bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com memcpy(&(*arrayStorage)[storageOffset], scriptValue.fOperand.fArray->begin(), count * sizeof(SkOperand)); 400bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 401bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 402bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } else if (fType == SkType_Array) { 403bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkTypedArray* destArray = (SkTypedArray*) (untypedStorage ? untypedStorage : arrayStorage); 404bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(destArray); 405bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com // destArray->setCount(0); 406bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (scriptValue.fType != SkType_Array) { 407bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(type == scriptValue.fType); 408bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com // SkASSERT(storageOffset + 1 <= maxStorage); 409bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com destArray->setCount(storageOffset + 1); 410bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com (*destArray)[storageOffset] = scriptValue.fOperand; 411bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } else { 412bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (type == SkType_Unknown) { 413bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com type = scriptValue.fOperand.fArray->getType(); 414bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com destArray->setType(type); 415bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 416bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(type == scriptValue.fOperand.fArray->getType()); 417bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com int count = scriptValue.fOperand.fArray->count(); 418bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com // SkASSERT(storageOffset + count <= maxStorage); 419bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com destArray->setCount(storageOffset + count); 420bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com memcpy(destArray->begin() + storageOffset, scriptValue.fOperand.fArray->begin(), sizeof(SkOperand) * count); 421bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 422bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } else if (type == SkType_String) { 423bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkString* string = untypedStorage ? (SkString*) untypedStorage : (*arrayStorage)[storageOffset].fString; 424bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com string->set(*scriptValue.fOperand.fString); 425bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } else if (type == SkType_ARGB && outType == SkType_Float) { 426bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkTypedArray* array = scriptValue.fOperand.fArray; 427dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com SkASSERT(scriptValue.fType == SkType_Int || scriptValue.fType == SkType_ARGB || 428bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com scriptValue.fType == SkType_Array); 429bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(scriptValue.fType != SkType_Array || (array != NULL && 430bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com array->getType() == SkType_Int)); 431bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com int numberOfColors = scriptValue.fType == SkType_Array ? array->count() : 1; 432bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com int numberOfComponents = numberOfColors * 4; 433bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com // SkASSERT(maxStorage == 0 || maxStorage == numberOfComponents); 434bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (maxStorage == 0) 435bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com arrayStorage->setCount(numberOfComponents); 436bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com for (int index = 0; index < numberOfColors; index++) { 437dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com SkColor color = scriptValue.fType == SkType_Array ? 438bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com (SkColor) array->begin()[index].fS32 : (SkColor) scriptValue.fOperand.fS32; 439bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com storage[0].fScalar = SkIntToScalar(SkColorGetA(color)); 440bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com storage[1].fScalar = SkIntToScalar(SkColorGetR(color)); 441bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com storage[2].fScalar = SkIntToScalar(SkColorGetG(color)); 442bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com storage[3].fScalar = SkIntToScalar(SkColorGetB(color)); 443bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com storage += 4; 444bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 445bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } else if (SkDisplayType::IsStruct(NULL /* !!! maker*/, type)) { 446bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (scriptValue.fType != SkType_Array) 447bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return true; // error 448bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(sizeof(SkScalar) == sizeof(SkOperand)); // !!! no 64 bit pointer support yet 449bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com int count = scriptValue.fOperand.fArray->count(); 450bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (count > 0) { 451bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(fCount == count); 452bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com memcpy(storage, scriptValue.fOperand.fArray->begin(), count * sizeof(SkOperand)); 453bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 454bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } else if (scriptValue.fType == SkType_Array) { 455bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(scriptValue.fOperand.fArray->getType() == type); 456bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(scriptValue.fOperand.fArray->count() == getCount()); 457bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com memcpy(storage, scriptValue.fOperand.fArray->begin(), getCount() * sizeof(SkOperand)); 458bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } else { 459bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com memcpy(storage, &scriptValue.fOperand, sizeof(SkOperand)); 460bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 461bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return false; 462bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 463bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 464bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 465bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com//void SkMemberInfo::setValue(SkDisplayable* displayable, const char value[], const char name[]) const { 466bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com// void* valuePtr = (void*) ((char*) displayable + fOffset); 467bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com// switch (fType) { 468bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com// case SkType_Point3D: { 469bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com// static const char xyz[] = "x|y|z"; 470bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com// int index = find_one(xyz, name); 471bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com// SkASSERT(index >= 0); 472bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com// valuePtr = (void*) ((char*) valuePtr + index * sizeof(SkScalar)); 473bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com// } break; 474bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com// default: 475bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com// SkASSERT(0); 476bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com// } 477bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com// SkParse::FindScalar(value, (SkScalar*) valuePtr); 478bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com// displayable->dirty(); 479bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com//} 480bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 481bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#if SK_USE_CONDENSED_INFO == 0 482bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 483bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com// Find Nth memberInfo 484bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comconst SkMemberInfo* SkMemberInfo::Find(const SkMemberInfo info[], int count, int* index) { 485bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(*index >= 0); 486bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (info->fType == SkType_BaseClassInfo) { 487bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com const SkMemberInfo* inherited = (SkMemberInfo*) info->fName; 488bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com const SkMemberInfo* result = SkMemberInfo::Find(inherited, info->fCount, index); 489bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (result != NULL) 490bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return result; 491bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (--count == 0) 492bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return NULL; 493bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com info++; 494bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 495bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(info->fName); 496bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(info->fType != SkType_BaseClassInfo); 497bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (*index >= count) { 498bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com *index -= count; 499bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return NULL; 500bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 501bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return &info[*index]; 502bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 503bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 504bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com// Find named memberinfo 505bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comconst SkMemberInfo* SkMemberInfo::Find(const SkMemberInfo info[], int count, const char** matchPtr) { 506bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com const char* match = *matchPtr; 507bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (info->fType == SkType_BaseClassInfo) { 508bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com const SkMemberInfo* inherited = (SkMemberInfo*) info->fName; 509bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com const SkMemberInfo* result = SkMemberInfo::Find(inherited, info->fCount, matchPtr); 510bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (result != NULL) 511bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return result; 512bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (--count == 0) 513bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return NULL; 514bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com info++; 515bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 516bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(info->fName); 517bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(info->fType != SkType_BaseClassInfo); 518bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com int index = SkStrSearch(&info->fName, count, match, sizeof(*info)); 519bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (index < 0 || index >= count) 520bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return NULL; 521bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return &info[index]; 522bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 523bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 524bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comconst SkMemberInfo* SkMemberInfo::getInherited() const { 525bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return (SkMemberInfo*) fName; 526bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 527bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 528bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#endif // SK_USE_CONDENSED_INFO == 0 529bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 530bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#if 0 531dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.combool SkMemberInfo::SetValue(void* valuePtr, const char value[], SkDisplayTypes type, 532bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com int count) { 533bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com switch (type) { 534bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_Animate: 535dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com case SkType_BaseBitmap: 536bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_Bitmap: 537bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_Dash: 538bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_Displayable: 539bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_Drawable: 540bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_Matrix: 541bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_Path: 542bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_Text: 543bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_3D_Patch: 544bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return false; // ref to object; caller must resolve 545bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_MSec: { 546bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkParse::FindMSec(value, (SkMSec*) valuePtr); 547bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } break; 548bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_3D_Point: 549bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com case SkType_Point: 550bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com // case SkType_PointArray: 551dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com case SkType_ScalarArray: 552bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkParse::FindScalars(value, (SkScalar*) valuePtr, count); 553bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com break; 554bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com default: 555bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(0); 556bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 557bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return true; 558bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 559bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#endif 560