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