SkMemberInfo.cpp revision 0910916c0f7b951ee55c4b7c6358295b9bca0565
10910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/* libs/graphics/animator/SkMemberInfo.cpp
20910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project**
30910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** Copyright 2006, The Android Open Source Project
40910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project**
50910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License");
60910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** you may not use this file except in compliance with the License.
70910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** You may obtain a copy of the License at
80910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project**
90910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project**     http://www.apache.org/licenses/LICENSE-2.0
100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project**
110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** Unless required by applicable law or agreed to in writing, software
120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS,
130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** See the License for the specific language governing permissions and
150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** limitations under the License.
160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project*/
170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkMemberInfo.h"
190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkAnimateMaker.h"
200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkAnimatorScript.h"
210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkBase64.h"
220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkCamera.h"
230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkDisplayable.h"
240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkDisplayTypes.h"
250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkDraw3D.h"
260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkDrawColor.h"
270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkParse.h"
280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkScript.h"
290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkTSearch.h"
300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkTypedArray.h"
310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectsize_t SkMemberInfo::GetSize(SkDisplayTypes type) { // size of simple types only
330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    size_t byteSize;
340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    switch (type) {
350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_ARGB:
360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            byteSize = sizeof(SkColor);
370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_AddMode:
390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_Align:
400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_ApplyMode:
410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_ApplyTransition:
420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_BitmapEncoding:
430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_Boolean:
440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_Cap:
450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_EventCode:
460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_EventKind:
470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_EventMode:
480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_FilterType:
490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_FontStyle:
500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_FromPathMode:
510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_Join:
520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_MaskFilterBlurStyle:
530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_PathDirection:
540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_Style:
550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_TileMode:
560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_Xfermode:
570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            byteSize = sizeof(int);
580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_Base64: // assume base64 data is always const, copied by ref
600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_Displayable:
610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_Drawable:
620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_Matrix:
630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            byteSize = sizeof(void*);
640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_MSec:
660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            byteSize = sizeof(SkMSec);
670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_Point:
690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            byteSize = sizeof(SkPoint);
700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_3D_Point:
720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            byteSize = sizeof(Sk3D_Point);
730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_Int:
750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            byteSize = sizeof(int32_t);
760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_Float:
780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            byteSize = sizeof(SkScalar);
790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_DynamicString:
810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_String:
820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            byteSize = sizeof(SkString);    // assume we'll copy by reference, not value
830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        default:
850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project//          SkASSERT(0);
860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            byteSize = 0;
870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return byteSize;
890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkMemberInfo::getArrayValue(const SkDisplayable* displayable, int index, SkOperand* value) const {
920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(fType != SkType_String && fType != SkType_MemberProperty);
930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    char* valuePtr = (char*) *(SkOperand**) memberData(displayable);
940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkDisplayTypes type = (SkDisplayTypes) 0;
950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (displayable->getType() == SkType_Array) {
960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkDisplayArray* dispArray = (SkDisplayArray*) displayable;
970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (dispArray->values.count() <= index)
980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return false;
990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        type = dispArray->values.getType();
1000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    } else
1010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(0); // incomplete
1020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    size_t byteSize = GetSize(type);
1030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    memcpy(value, valuePtr + index * byteSize, byteSize);
1040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return true;
1050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectsize_t SkMemberInfo::getSize(const SkDisplayable* displayable) const {
1080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    size_t byteSize;
1090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    switch (fType) {
1100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_MemberProperty:
1110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            byteSize = GetSize(propertyType());
1120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
1130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_Array: {
1140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkDisplayTypes type;
1150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (displayable == NULL)
1160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                return sizeof(int);
1170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (displayable->getType() == SkType_Array) {
1180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkDisplayArray* dispArray = (SkDisplayArray*) displayable;
1190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                type = dispArray->values.getType();
1200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            } else
1210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                type = propertyType();
1220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkTDOperandArray* array = (SkTDOperandArray*) memberData(displayable);
1230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            byteSize = GetSize(type) * array->count();
1240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            } break;
1250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        default:
1260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            byteSize = GetSize((SkDisplayTypes) fType);
1270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
1280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return byteSize;
1290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkMemberInfo::getString(const SkDisplayable* displayable, SkString** string) const {
1320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (fType == SkType_MemberProperty) {
1330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkScriptValue value;
1340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        displayable->getProperty(propertyIndex(), &value);
1350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(value.fType == SkType_String);
1360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        *string = value.fOperand.fString;
1370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return;
1380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
1390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(fCount == sizeof(SkString) / sizeof(SkScalar));
1400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(fType == SkType_String || fType == SkType_DynamicString);
1410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    void* valuePtr = memberData(displayable);
1420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *string = (SkString*) valuePtr;
1430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkMemberInfo::getValue(const SkDisplayable* displayable, SkOperand value[], int count) const {
1460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(fType != SkType_String && fType != SkType_MemberProperty);
1470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(count == fCount);
1480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    void* valuePtr = memberData(displayable);
1490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    size_t byteSize = getSize(displayable);
1500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(sizeof(value[0].fScalar) == sizeof(value[0])); // no support for 64 bit pointers, yet
1510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    memcpy(value, valuePtr, byteSize);
1520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkMemberInfo::setString(SkDisplayable* displayable, SkString* value) const {
1550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkString* string = (SkString*) memberData(displayable);
1560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    string->set(*value);
1570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    displayable->dirty();
1580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkMemberInfo::setValue(SkDisplayable* displayable, const SkOperand values[],
1610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                            int count) const {
1620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(sizeof(values[0].fScalar) == sizeof(values[0]));   // no support for 64 bit pointers, yet
1630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    char* dst = (char*) memberData(displayable);
1640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (fType == SkType_Array) {
1650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkTDScalarArray* array = (SkTDScalarArray* ) dst;
1660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        array->setCount(count);
1670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        dst = (char*) array->begin();
1680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
1690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    memcpy(dst, values, count * sizeof(SkOperand));
1700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    displayable->dirty();
1710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic inline bool is_between(int c, int min, int max)
1750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return (unsigned)(c - min) <= (unsigned)(max - min);
1770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic inline bool is_hex(int c)
1800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (is_between(c, '0', '9'))
1820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return true;
1830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    c |= 0x20;  // make us lower-case
1840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (is_between(c, 'a', 'f'))
1850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return true;
1860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return false;
1870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkMemberInfo::setValue(SkAnimateMaker& maker, SkTDOperandArray* arrayStorage,
1910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int storageOffset, int maxStorage, SkDisplayable* displayable, SkDisplayTypes outType,
1920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const char rawValue[], size_t rawValueLen) const
1930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkString valueStr(rawValue, rawValueLen);
1950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScriptValue scriptValue;
1960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    scriptValue.fType = SkType_Unknown;
1970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    scriptValue.fOperand.fS32 = 0;
1980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkDisplayTypes type = getType();
1990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAnimatorScript engine(maker, displayable, type);
2000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (arrayStorage)
2010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        displayable = NULL;
2020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool success = true;
2030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    void* untypedStorage = NULL;
2040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (displayable && fType != SkType_MemberProperty && fType != SkType_MemberFunction)
2050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        untypedStorage = (SkTDOperandArray*) memberData(displayable);
2060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (type == SkType_ARGB) {
2080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // for both SpiderMonkey and SkiaScript, substitute any #xyz or #xxyyzz first
2090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            // it's enough to expand the colors into 0xFFxxyyzz
2100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const char* poundPos;
2110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        while ((poundPos = strchr(valueStr.c_str(), '#')) != NULL) {
2120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            size_t offset = poundPos - valueStr.c_str();
2130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (valueStr.size() - offset < 4)
2140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                break;
2150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            char r = poundPos[1];
2160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            char g = poundPos[2];
2170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            char b = poundPos[3];
2180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (is_hex(r) == false || is_hex(g) == false || is_hex(b) == false)
2190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                break;
2200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            char hex = poundPos[4];
2210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (is_hex(hex) == false) {
2220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                valueStr.insertUnichar(offset + 1, r);
2230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                valueStr.insertUnichar(offset + 3, g);
2240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                valueStr.insertUnichar(offset + 5, b);
2250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
2260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            *(char*) poundPos = '0'; // overwrite '#'
2270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            valueStr.insert(offset + 1, "xFF");
2280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
2290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
2300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (SkDisplayType::IsDisplayable(&maker, type) || SkDisplayType::IsEnum(&maker, type) || type == SkType_ARGB)
2310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        goto scriptCommon;
2320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    switch (type) {
2330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_String:
2340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#if 0
2350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (displayable && displayable->isAnimate()) {
2360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                goto noScriptString;
2380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
2390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (strncmp(rawValue, "#string:", sizeof("#string:") - 1) == 0) {
2400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkASSERT(sizeof("string") == sizeof("script"));
2410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                char* stringHeader = valueStr.writable_str();
2420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                memcpy(&stringHeader[1], "script", sizeof("script") - 1);
2430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                rawValue = valueStr.c_str();
2440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                goto noScriptString;
2450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            } else
2460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
2470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (strncmp(rawValue, "#script:", sizeof("#script:") - 1) != 0)
2480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                goto noScriptString;
2490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            valueStr.remove(0, 8);
2500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_Unknown:
2510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_Int:
2520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_MSec:  // for the purposes of script, MSec is treated as a Scalar
2530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_Point:
2540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_3D_Point:
2550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_Float:
2560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_Array:
2570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectscriptCommon: {
2580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                const char* script = valueStr.c_str();
2590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                success = engine.evaluateScript(&script, &scriptValue);
2600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (success == false) {
2610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    maker.setScriptError(engine);
2620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    return false;
2630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
2640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
2650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkASSERT(success);
2660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (scriptValue.fType == SkType_Displayable) {
2670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (type == SkType_String) {
2680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    const char* charPtr;
2690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    maker.findKey(scriptValue.fOperand.fDisplayable, &charPtr);
2700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    scriptValue.fOperand.fString = new SkString(charPtr);
2710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    scriptValue.fType = SkType_String;
2720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    engine.SkScriptEngine::track(scriptValue.fOperand.fString);
2730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    break;
2740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
2750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkASSERT(SkDisplayType::IsDisplayable(&maker, type));
2760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (displayable)
2770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    displayable->setReference(this, scriptValue.fOperand.fDisplayable);
2780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                else
2790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    arrayStorage->begin()[0].fDisplayable = scriptValue.fOperand.fDisplayable;
2800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                return true;
2810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
2820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (type != scriptValue.fType) {
2830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (scriptValue.fType == SkType_Array) {
2840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    engine.forget(scriptValue.getArray());
2850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    goto writeStruct; // real structs have already been written by script
2860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
2870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                switch (type) {
2880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    case SkType_String:
2890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        success = engine.convertTo(SkType_String, &scriptValue);
2900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        break;
2910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    case SkType_MSec:
2920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    case SkType_Float:
2930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        success = engine.convertTo(SkType_Float, &scriptValue);
2940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        break;
2950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    case SkType_Int:
2960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        success = engine.convertTo(SkType_Int, &scriptValue);
2970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        break;
2980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    case SkType_Array:
2990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        success = engine.convertTo(arrayType(), &scriptValue);
3000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        // !!! incomplete; create array of appropriate type and add scriptValue to it
3010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        SkASSERT(0);
3020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        break;
3030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    case SkType_Displayable:
3040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    case SkType_Drawable:
3050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        return false;   // no way to convert other types to this
3060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    default:    // to avoid warnings
3070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        break;
3080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
3090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (success == false)
3100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    return false;
3110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
3120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (type == SkType_MSec)
3130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                scriptValue.fOperand.fMSec = SkScalarMulRound(scriptValue.fOperand.fScalar, 1000);
3140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            scriptValue.fType = type;
3150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        break;
3160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        noScriptString:
3170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_DynamicString:
3180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (fType == SkType_MemberProperty && displayable) {
3190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkString string(rawValue, rawValueLen);
3200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkScriptValue scriptValue;
3210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                scriptValue.fOperand.fString = &string;
3220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                scriptValue.fType = SkType_String;
3230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                displayable->setProperty(propertyIndex(), scriptValue);
3240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            } else if (displayable) {
3250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkString* string = (SkString*) memberData(displayable);
3260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                string->set(rawValue, rawValueLen);
3270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            } else {
3280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkASSERT(arrayStorage->count() == 1);
3290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                arrayStorage->begin()->fString->set(rawValue, rawValueLen);
3300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
3310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            goto dirty;
3320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_Base64: {
3330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkBase64 base64;
3340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            base64.decode(rawValue, rawValueLen);
3350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            *(SkBase64* ) untypedStorage = base64;
3360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            } goto dirty;
3370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        default:
3380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkASSERT(0);
3390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
3400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
3410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project//  if (SkDisplayType::IsStruct(type) == false)
3420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
3430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectwriteStruct:
3440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (writeValue(displayable, arrayStorage, storageOffset, maxStorage,
3450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                untypedStorage, outType, scriptValue)) {
3460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    maker.setErrorCode(SkDisplayXMLParserError::kUnexpectedType);
3470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return false;
3480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
3490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
3500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectdirty:
3510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (displayable)
3520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        displayable->dirty();
3530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return true;
3540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkMemberInfo::setValue(SkAnimateMaker& maker, SkTDOperandArray* arrayStorage,
3570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int storageOffset, int maxStorage, SkDisplayable* displayable, SkDisplayTypes outType,
3580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkString& raw) const {
3590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return setValue(maker, arrayStorage, storageOffset, maxStorage, displayable, outType, raw.c_str(),
3600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        raw.size());
3610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkMemberInfo::writeValue(SkDisplayable* displayable, SkTDOperandArray* arrayStorage,
3640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int storageOffset, int maxStorage, void* untypedStorage, SkDisplayTypes outType,
3650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScriptValue& scriptValue) const
3660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
3670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkOperand* storage = untypedStorage ? (SkOperand*) untypedStorage : arrayStorage ?
3680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        arrayStorage->begin() : NULL;
3690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (storage)
3700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        storage += storageOffset;
3710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkDisplayTypes type = getType();
3720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (fType == SkType_MemberProperty) {
3730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if(displayable)
3740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            displayable->setProperty(propertyIndex(), scriptValue);
3750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        else {
3760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkASSERT(storageOffset < arrayStorage->count());
3770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            switch (scriptValue.fType) {
3780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                case SkType_Boolean:
3790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                case SkType_Float:
3800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                case SkType_Int:
3810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    memcpy(&storage->fScalar, &scriptValue.fOperand.fScalar, sizeof(SkScalar));
3820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    break;
3830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                case SkType_Array:
3840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    memcpy(&storage->fScalar, scriptValue.fOperand.fArray->begin(), scriptValue.fOperand.fArray->count() * sizeof(SkScalar));
3850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    break;
3860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                case SkType_String:
3870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    storage->fString->set(*scriptValue.fOperand.fString);
3880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    break;
3890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                default:
3900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    SkASSERT(0);    // type isn't handled yet
3910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
3920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
3930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    } else if (fType == SkType_MemberFunction) {
3940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(scriptValue.fType == SkType_Array);
3950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (displayable)
3960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            displayable->executeFunction(displayable, this, scriptValue.fOperand.fArray, NULL);
3970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        else {
3980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            int count = scriptValue.fOperand.fArray->count();
3990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    //      SkASSERT(maxStorage == 0 || count == maxStorage);
4000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (arrayStorage->count() == 2)
4010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                arrayStorage->setCount(2 * count);
4020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            else {
4030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                storageOffset *= count;
4040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkASSERT(count + storageOffset <= arrayStorage->count());
4050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
4060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            memcpy(&(*arrayStorage)[storageOffset], scriptValue.fOperand.fArray->begin(), count * sizeof(SkOperand));
4070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
4080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    } else if (fType == SkType_Array) {
4100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkTypedArray* destArray = (SkTypedArray*) (untypedStorage ? untypedStorage : arrayStorage);
4110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(destArray);
4120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    //  destArray->setCount(0);
4130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (scriptValue.fType != SkType_Array) {
4140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkASSERT(type == scriptValue.fType);
4150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    //      SkASSERT(storageOffset + 1 <= maxStorage);
4160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            destArray->setCount(storageOffset + 1);
4170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            (*destArray)[storageOffset] = scriptValue.fOperand;
4180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        } else {
4190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (type == SkType_Unknown) {
4200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                type = scriptValue.fOperand.fArray->getType();
4210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                destArray->setType(type);
4220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
4230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkASSERT(type == scriptValue.fOperand.fArray->getType());
4240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            int count = scriptValue.fOperand.fArray->count();
4250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    //      SkASSERT(storageOffset + count <= maxStorage);
4260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            destArray->setCount(storageOffset + count);
4270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            memcpy(destArray->begin() + storageOffset, scriptValue.fOperand.fArray->begin(), sizeof(SkOperand) * count);
4280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
4290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    } else if (type == SkType_String) {
4300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkString* string = untypedStorage ? (SkString*) untypedStorage : (*arrayStorage)[storageOffset].fString;
4310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        string->set(*scriptValue.fOperand.fString);
4320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    } else if (type == SkType_ARGB && outType == SkType_Float) {
4330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkTypedArray* array = scriptValue.fOperand.fArray;
4340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(scriptValue.fType == SkType_Int || scriptValue.fType == SkType_ARGB ||
4350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            scriptValue.fType == SkType_Array);
4360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(scriptValue.fType != SkType_Array || (array != NULL &&
4370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            array->getType() == SkType_Int));
4380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int numberOfColors = scriptValue.fType == SkType_Array ? array->count() : 1;
4390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int numberOfComponents = numberOfColors * 4;
4400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    //  SkASSERT(maxStorage == 0 || maxStorage == numberOfComponents);
4410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (maxStorage == 0)
4420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            arrayStorage->setCount(numberOfComponents);
4430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        for (int index = 0; index < numberOfColors; index++) {
4440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkColor color = scriptValue.fType == SkType_Array ?
4450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                (SkColor) array->begin()[index].fS32 : (SkColor) scriptValue.fOperand.fS32;
4460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            storage[0].fScalar = SkIntToScalar(SkColorGetA(color));
4470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            storage[1].fScalar = SkIntToScalar(SkColorGetR(color));
4480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            storage[2].fScalar = SkIntToScalar(SkColorGetG(color));
4490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            storage[3].fScalar = SkIntToScalar(SkColorGetB(color));
4500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            storage += 4;
4510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
4520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    } else if (SkDisplayType::IsStruct(NULL /* !!! maker*/, type)) {
4530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (scriptValue.fType != SkType_Array)
4540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return true;    // error
4550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(sizeof(SkScalar) == sizeof(SkOperand)); // !!! no 64 bit pointer support yet
4560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int count = scriptValue.fOperand.fArray->count();
4570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (count > 0) {
4580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkASSERT(fCount == count);
4590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            memcpy(storage, scriptValue.fOperand.fArray->begin(), count * sizeof(SkOperand));
4600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
4610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    } else if (scriptValue.fType == SkType_Array) {
4620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(scriptValue.fOperand.fArray->getType() == type);
4630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(scriptValue.fOperand.fArray->count() == getCount());
4640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        memcpy(storage, scriptValue.fOperand.fArray->begin(), getCount() * sizeof(SkOperand));
4650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    } else {
4660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        memcpy(storage, &scriptValue.fOperand, sizeof(SkOperand));
4670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
4680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return false;
4690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
4700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project//void SkMemberInfo::setValue(SkDisplayable* displayable, const char value[], const char name[]) const {
4730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project//  void* valuePtr = (void*) ((char*) displayable + fOffset);
4740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project//  switch (fType) {
4750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project//      case SkType_Point3D: {
4760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project//          static const char xyz[] = "x|y|z";
4770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project//          int index = find_one(xyz, name);
4780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project//          SkASSERT(index >= 0);
4790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project//          valuePtr = (void*) ((char*) valuePtr + index * sizeof(SkScalar));
4800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project//          } break;
4810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project//      default:
4820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project//          SkASSERT(0);
4830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project//  }
4840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project//  SkParse::FindScalar(value, (SkScalar*) valuePtr);
4850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project//  displayable->dirty();
4860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project//}
4870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#if SK_USE_CONDENSED_INFO == 0
4890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project// Find Nth memberInfo
4910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectconst SkMemberInfo* SkMemberInfo::Find(const SkMemberInfo info[], int count, int* index) {
4920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(*index >= 0);
4930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (info->fType == SkType_BaseClassInfo) {
4940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const SkMemberInfo* inherited = (SkMemberInfo*) info->fName;
4950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const SkMemberInfo* result = SkMemberInfo::Find(inherited, info->fCount, index);
4960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (result != NULL)
4970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return result;
4980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (--count == 0)
4990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return NULL;
5000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        info++;
5010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
5020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(info->fName);
5030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(info->fType != SkType_BaseClassInfo);
5040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (*index >= count) {
5050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        *index -= count;
5060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return NULL;
5070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
5080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return &info[*index];
5090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
5100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project// Find named memberinfo
5120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectconst SkMemberInfo* SkMemberInfo::Find(const SkMemberInfo info[], int count, const char** matchPtr) {
5130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const char* match = *matchPtr;
5140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (info->fType == SkType_BaseClassInfo) {
5150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const SkMemberInfo* inherited = (SkMemberInfo*) info->fName;
5160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const SkMemberInfo* result = SkMemberInfo::Find(inherited, info->fCount, matchPtr);
5170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (result != NULL)
5180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return result;
5190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (--count == 0)
5200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return NULL;
5210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        info++;
5220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
5230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(info->fName);
5240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(info->fType != SkType_BaseClassInfo);
5250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int index = SkStrSearch(&info->fName, count, match, sizeof(*info));
5260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (index < 0 || index >= count)
5270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return NULL;
5280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return &info[index];
5290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
5300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectconst SkMemberInfo* SkMemberInfo::getInherited() const {
5320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return (SkMemberInfo*) fName;
5330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
5340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif // SK_USE_CONDENSED_INFO == 0
5360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#if 0
5380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkMemberInfo::SetValue(void* valuePtr, const char value[], SkDisplayTypes type,
5390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                            int count) {
5400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    switch (type) {
5410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_Animate:
5420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_BaseBitmap:
5430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_Bitmap:
5440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_Dash:
5450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_Displayable:
5460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_Drawable:
5470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_Matrix:
5480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_Path:
5490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_Text:
5500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_3D_Patch:
5510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return false; // ref to object; caller must resolve
5520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_MSec: {
5530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkParse::FindMSec(value, (SkMSec*) valuePtr);
5540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            } break;
5550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_3D_Point:
5560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_Point:
5570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    //  case SkType_PointArray:
5580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkType_ScalarArray:
5590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkParse::FindScalars(value, (SkScalar*) valuePtr, count);
5600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
5610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        default:
5620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkASSERT(0);
5630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
5640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return true;
5650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
5660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
5670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
569