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