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