gfx/skia/trunk/src/animator/SkMemberInfo.cpp

Thu, 15 Jan 2015 15:55:04 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 15:55:04 +0100
branch
TOR_BUG_9701
changeset 9
a63d609f5ebe
permissions
-rw-r--r--

Back out 97036ab72558 which inappropriately compared turds to third parties.

     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  */
    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"
    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 }
    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 }
   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 }
   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 }
   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 }
   147 void SkMemberInfo::setString(SkDisplayable* displayable, SkString* value) const {
   148     SkString* string = (SkString*) memberData(displayable);
   149     string->set(*value);
   150     displayable->dirty();
   151 }
   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 }
   167 static inline bool is_between(int c, int min, int max)
   168 {
   169     return (unsigned)(c - min) <= (unsigned)(max - min);
   170 }
   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 }
   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);
   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()) {
   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 }
   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 }
   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         }
   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 }
   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 //}
   481 #if SK_USE_CONDENSED_INFO == 0
   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 }
   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 }
   524 const SkMemberInfo* SkMemberInfo::getInherited() const {
   525     return (SkMemberInfo*) fName;
   526 }
   528 #endif // SK_USE_CONDENSED_INFO == 0
   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

mercurial