SkFlattenable.cpp revision 82065d667f64e232bcde2ad849756a6096fcbe6f
18a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkFlattenable.h"
28a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkTypeface.h"
38a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
48a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkFlattenable::flatten(SkFlattenableWriteBuffer&)
58a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
68a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /*  we don't write anything at the moment, but this allows our subclasses
78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        to not know that, since we want them to always call INHERITED::flatten()
88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        in their code.
98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkFlattenableReadBuffer::SkFlattenableReadBuffer() {
168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fRCArray = NULL;
178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fRCCount = 0;
1882065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fTFArray = NULL;
208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fTFCount = 0;
2182065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fFactoryArray = NULL;
238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fFactoryCount = 0;
248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkFlattenableReadBuffer::SkFlattenableReadBuffer(const void* data) :
278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        INHERITED(data, 1024 * 1024) {
288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fRCArray = NULL;
298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fRCCount = 0;
3082065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fTFArray = NULL;
328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fTFCount = 0;
3382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fFactoryArray = NULL;
358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fFactoryCount = 0;
368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkFlattenableReadBuffer::SkFlattenableReadBuffer(const void* data, size_t size)
398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        : INHERITED(data, size) {
408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fRCArray = NULL;
418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fRCCount = 0;
4282065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fTFArray = NULL;
448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fTFCount = 0;
4582065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fFactoryArray = NULL;
478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fFactoryCount = 0;
488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkTypeface* SkFlattenableReadBuffer::readTypeface() {
518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    uint32_t index = this->readU32();
528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (0 == index || index > (unsigned)fTFCount) {
538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (index) {
548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            SkDebugf("====== typeface index %d\n", index);
558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return NULL;
578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    } else {
588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkASSERT(fTFArray);
598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return fTFArray[index - 1];
608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkRefCnt* SkFlattenableReadBuffer::readRefCnt() {
648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    uint32_t index = this->readU32();
658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (0 == index || index > (unsigned)fRCCount) {
668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return NULL;
678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    } else {
688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkASSERT(fRCArray);
698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return fRCArray[index - 1];
708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkFlattenable* SkFlattenableReadBuffer::readFlattenable() {
748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkFlattenable::Factory factory = NULL;
7582065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (fFactoryCount > 0) {
778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        uint32_t index = this->readU32();
788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (index > 0) {
798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            index -= 1;
808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            SkASSERT(index < (unsigned)fFactoryCount);
818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            factory = fFactoryArray[index];
828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            // if we recorded an index, but failed to get a factory, we need
838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            // to skip the flattened data in the buffer
848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            if (NULL == factory) {
858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                uint32_t size = this->readU32();
868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                this->skip(size);
878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                // fall through and return NULL for the object
888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            }
898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    } else {
918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        factory = (SkFlattenable::Factory)readFunctionPtr();
928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkFlattenable* obj = NULL;
958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (factory) {
968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        uint32_t sizeRecorded = this->readU32();
978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        uint32_t offset = this->offset();
988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        obj = (*factory)(*this);
998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        // check that we read the amount we expected
1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        uint32_t sizeRead = this->offset() - offset;
1018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (sizeRecorded != sizeRead) {
1028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            // we could try to fix up the offset...
1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            sk_throw();
1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return obj;
1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid* SkFlattenableReadBuffer::readFunctionPtr() {
1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void* proc;
1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    this->read(&proc, sizeof(proc));
1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return proc;
1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkFlattenableWriteBuffer::SkFlattenableWriteBuffer(size_t minSize) :
1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        INHERITED(minSize) {
1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fFlags = (Flags)0;
1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fRCRecorder = NULL;
1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fTFRecorder = NULL;
1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fFactoryRecorder = NULL;
1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkFlattenableWriteBuffer::~SkFlattenableWriteBuffer() {
12682065d667f64e232bcde2ad849756a6096fcbe6freed@google.com    SkSafeUnref(fRCRecorder);
12782065d667f64e232bcde2ad849756a6096fcbe6freed@google.com    SkSafeUnref(fTFRecorder);
12882065d667f64e232bcde2ad849756a6096fcbe6freed@google.com    SkSafeUnref(fFactoryRecorder);
1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkRefCntRecorder* SkFlattenableWriteBuffer::setRefCntRecorder(
1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                                    SkRefCntRecorder* rec) {
1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkRefCnt_SafeAssign(fRCRecorder, rec);
1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return rec;
1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkRefCntRecorder* SkFlattenableWriteBuffer::setTypefaceRecorder(
1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                                    SkRefCntRecorder* rec) {
1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkRefCnt_SafeAssign(fTFRecorder, rec);
1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return rec;
1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkFactoryRecorder* SkFlattenableWriteBuffer::setFactoryRecorder(
1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                                    SkFactoryRecorder* rec) {
1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkRefCnt_SafeAssign(fFactoryRecorder, rec);
1468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return rec;
1478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkFlattenableWriteBuffer::writeTypeface(SkTypeface* obj) {
1508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (NULL == obj || NULL == fTFRecorder) {
1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        this->write32(0);
1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    } else {
1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        this->write32(fTFRecorder->record(obj));
1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkFlattenableWriteBuffer::writeRefCnt(SkRefCnt* obj) {
1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (NULL == obj || NULL == fRCRecorder) {
1598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        this->write32(0);
1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    } else {
1618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        this->write32(fRCRecorder->record(obj));
1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkFlattenableWriteBuffer::writeFlattenable(SkFlattenable* flattenable) {
1668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkFlattenable::Factory factory = NULL;
1678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (flattenable) {
1688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        factory = flattenable->getFactory();
1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (fFactoryRecorder) {
1728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        this->write32(fFactoryRecorder->record(factory));
1738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    } else {
1748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        this->writeFunctionPtr((void*)factory);
1758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
17682065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
1778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (factory) {
1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        // make room for the size of the flatttened object
1798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        (void)this->reserve(sizeof(uint32_t));
1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        // record the current size, so we can subtract after the object writes.
1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        uint32_t offset = this->size();
1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        // now flatten the object
1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        flattenable->flatten(*this);
1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        uint32_t objSize = this->size() - offset;
1858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        // record the obj's size
1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        *this->peek32(offset - sizeof(uint32_t)) = objSize;
1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkFlattenableWriteBuffer::writeFunctionPtr(void* proc) {
1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    *(void**)this->reserve(sizeof(void*)) = proc;
1928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
1958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkRefCntRecorder::~SkRefCntRecorder() {
1978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // call this now, while our decPtr() is sill in scope
1988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    this->reset();
1998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkRefCntRecorder::incPtr(void* ptr) {
2028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    ((SkRefCnt*)ptr)->ref();
2038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkRefCntRecorder::decPtr(void* ptr) {
2068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    ((SkRefCnt*)ptr)->unref();
2078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
2108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
2118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
2128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define MAX_PAIR_COUNT  64
2148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstruct Pair {
2168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    const char*             fName;
2178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkFlattenable::Factory  fFactory;
2188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
2198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic int gCount;
2218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic Pair gPairs[MAX_PAIR_COUNT];
2228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkFlattenable::Register(const char name[], Factory factory) {
2248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(name);
2258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(factory);
22682065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
2278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    static bool gOnce;
2288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (!gOnce) {
2298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        gCount = 0;
2308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        gOnce = true;
2318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
23282065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
2338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(gCount < MAX_PAIR_COUNT);
23482065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
2358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    gPairs[gCount].fName = name;
2368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    gPairs[gCount].fFactory = factory;
2378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    gCount += 1;
2388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkFlattenable::Factory SkFlattenable::NameToFactory(const char name[]) {
2418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    const Pair* pairs = gPairs;
2428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (int i = gCount - 1; i >= 0; --i) {
2438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (strcmp(pairs[i].fName, name) == 0) {
2448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            return pairs[i].fFactory;
2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
2468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return NULL;
2488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst char* SkFlattenable::FactoryToName(Factory fact) {
2518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    const Pair* pairs = gPairs;
2528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (int i = gCount - 1; i >= 0; --i) {
2538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (pairs[i].fFactory == fact) {
2548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            return pairs[i].fName;
2558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return NULL;
2588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkFlattenable::toDumpString(SkString* str) const {
2618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return false;
2628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
264