| Index: src/core/SkReadBuffer.cpp
|
| diff --git a/src/core/SkReadBuffer.cpp b/src/core/SkReadBuffer.cpp
|
| index abd46312f747e80e744f636d15cadb7672fa925d..ac17da8f3c0f4231ab54fd4cb59988bfe4100bc2 100644
|
| --- a/src/core/SkReadBuffer.cpp
|
| +++ b/src/core/SkReadBuffer.cpp
|
| @@ -106,6 +106,11 @@ int32_t SkReadBuffer::read32() {
|
| return fReader.readInt();
|
| }
|
|
|
| +uint8_t SkReadBuffer::peekByte() {
|
| + SkASSERT(fReader.available() > 0);
|
| + return *((uint8_t*) fReader.peek());
|
| +}
|
| +
|
| void SkReadBuffer::readString(SkString* string) {
|
| size_t len;
|
| const char* strContents = fReader.readString(&len);
|
| @@ -344,9 +349,32 @@ SkFlattenable* SkReadBuffer::readFlattenable(SkFlattenable::Type ft) {
|
| }
|
| factory = fFactoryArray[index];
|
| } else {
|
| - factory = (SkFlattenable::Factory)readFunctionPtr();
|
| - if (nullptr == factory) {
|
| - return nullptr; // writer failed to give us the flattenable
|
| + SkString name;
|
| + if (this->peekByte()) {
|
| + // If the first byte is non-zero, the flattenable is specified by a string.
|
| + this->readString(&name);
|
| +
|
| + // Add the string to the dictionary.
|
| + fFlattenableDict.set(fFlattenableDict.count() + 1, name);
|
| + } else {
|
| + // Read the index. We are guaranteed that the first byte
|
| + // is zeroed, so we must shift down a byte.
|
| + uint32_t index = fReader.readU32() >> 8;
|
| + if (0 == index) {
|
| + return nullptr; // writer failed to give us the flattenable
|
| + }
|
| +
|
| + SkString* namePtr = fFlattenableDict.find(index);
|
| + SkASSERT(namePtr);
|
| + name = *namePtr;
|
| + }
|
| +
|
| + // Check if a custom Factory has been specified for this flattenable.
|
| + if (!(factory = this->getCustomFactory(name))) {
|
| + // If there is no custom Factory, check for a default.
|
| + if (!(factory = SkFlattenable::NameToFactory(name.c_str()))) {
|
| + return nullptr; // writer failed to give us the flattenable
|
| + }
|
| }
|
| }
|
|
|
|
|