Home | History | Annotate | Download | only in core
      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 
     18 SkPathHeap::SkPathHeap() : fHeap(kPathCount * sizeof(SkPath)) {
     19 }
     20 
     21 SkPathHeap::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 
     37 SkPathHeap::~SkPathHeap() {
     38     SkPath** iter = fPaths.begin();
     39     SkPath** stop = fPaths.end();
     40     while (iter < stop) {
     41         (*iter)->~SkPath();
     42         iter++;
     43     }
     44 }
     45 
     46 int 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 
     53 SkPathHeap::LookupEntry::LookupEntry(const SkPath& path)
     54     : fGenerationID(path.getGenerationID()), fStorageSlot(0) {
     55 }
     56 
     57 SkPathHeap::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 
     72 int 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 
     85 void 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