1 2 /* 3 * Copyright 2011 Google Inc. 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 #include "SkPathHeap.h" 9 #include "SkPath.h" 10 #include "SkStream.h" 11 #include "SkReadBuffer.h" 12 #include "SkTSearch.h" 13 #include "SkWriteBuffer.h" 14 #include <new> 15 16 #define kPathCount 64 17 SkPathHeap()18SkPathHeap::SkPathHeap() : fHeap(kPathCount * sizeof(SkPath)) { 19 } 20 SkPathHeap(SkReadBuffer & buffer)21SkPathHeap::SkPathHeap(SkReadBuffer& buffer) 22 : fHeap(kPathCount * sizeof(SkPath)) { 23 const int count = buffer.readInt(); 24 25 fPaths.setCount(count); 26 SkPath** ptr = fPaths.begin(); 27 SkPath* p = (SkPath*)fHeap.allocThrow(count * sizeof(SkPath)); 28 29 for (int i = 0; i < count; i++) { 30 new (p) SkPath; 31 buffer.readPath(p); 32 *ptr++ = p; // record the pointer 33 p++; // move to the next storage location 34 } 35 } 36 ~SkPathHeap()37SkPathHeap::~SkPathHeap() { 38 SkPath** iter = fPaths.begin(); 39 SkPath** stop = fPaths.end(); 40 while (iter < stop) { 41 (*iter)->~SkPath(); 42 iter++; 43 } 44 } 45 append(const SkPath & path)46int SkPathHeap::append(const SkPath& path) { 47 SkPath* p = (SkPath*)fHeap.allocThrow(sizeof(SkPath)); 48 new (p) SkPath(path); 49 *fPaths.append() = p; 50 return fPaths.count(); 51 } 52 LookupEntry(const SkPath & path)53SkPathHeap::LookupEntry::LookupEntry(const SkPath& path) 54 : fGenerationID(path.getGenerationID()), fStorageSlot(0) { 55 } 56 addIfNotPresent(const SkPath & path)57SkPathHeap::LookupEntry* SkPathHeap::addIfNotPresent(const SkPath& path) { 58 LookupEntry searchKey(path); 59 int index = SkTSearch<const LookupEntry, LookupEntry::Less>( 60 fLookupTable.begin(), 61 fLookupTable.count(), 62 searchKey, 63 sizeof(LookupEntry)); 64 if (index < 0) { 65 index = ~index; 66 *fLookupTable.insert(index) = LookupEntry(path); 67 } 68 69 return &fLookupTable[index];; 70 } 71 insert(const SkPath & path)72int SkPathHeap::insert(const SkPath& path) { 73 SkPathHeap::LookupEntry* entry = this->addIfNotPresent(path); 74 75 if (entry->storageSlot() > 0) { 76 return entry->storageSlot(); 77 } 78 79 int newSlot = this->append(path); 80 SkASSERT(newSlot > 0); 81 entry->setStorageSlot(newSlot); 82 return newSlot; 83 } 84 flatten(SkWriteBuffer & buffer) const85void SkPathHeap::flatten(SkWriteBuffer& buffer) const { 86 int count = fPaths.count(); 87 88 buffer.writeInt(count); 89 SkPath* const* iter = fPaths.begin(); 90 SkPath* const* stop = fPaths.end(); 91 while (iter < stop) { 92 buffer.writePath(**iter); 93 iter++; 94 } 95 } 96