| |
| /* |
| * Copyright 2011 Google Inc. |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| #include "SkPictureFlat.h" |
| |
| #include "SkChecksum.h" |
| #include "SkColorFilter.h" |
| #include "SkDrawLooper.h" |
| #include "SkMaskFilter.h" |
| #include "SkRasterizer.h" |
| #include "SkShader.h" |
| #include "SkTypeface.h" |
| #include "SkXfermode.h" |
| |
| SK_DEFINE_INST_COUNT(SkFlatController) |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| SkTypefacePlayback::SkTypefacePlayback() : fCount(0), fArray(NULL) {} |
| |
| SkTypefacePlayback::~SkTypefacePlayback() { |
| this->reset(NULL); |
| } |
| |
| void SkTypefacePlayback::reset(const SkRefCntSet* rec) { |
| for (int i = 0; i < fCount; i++) { |
| SkASSERT(fArray[i]); |
| fArray[i]->unref(); |
| } |
| SkDELETE_ARRAY(fArray); |
| |
| if (rec!= NULL && rec->count() > 0) { |
| fCount = rec->count(); |
| fArray = SkNEW_ARRAY(SkRefCnt*, fCount); |
| rec->copyToArray(fArray); |
| for (int i = 0; i < fCount; i++) { |
| fArray[i]->ref(); |
| } |
| } else { |
| fCount = 0; |
| fArray = NULL; |
| } |
| } |
| |
| void SkTypefacePlayback::setCount(int count) { |
| this->reset(NULL); |
| |
| fCount = count; |
| fArray = SkNEW_ARRAY(SkRefCnt*, count); |
| sk_bzero(fArray, count * sizeof(SkRefCnt*)); |
| } |
| |
| SkRefCnt* SkTypefacePlayback::set(int index, SkRefCnt* obj) { |
| SkASSERT((unsigned)index < (unsigned)fCount); |
| SkRefCnt_SafeAssign(fArray[index], obj); |
| return obj; |
| } |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| SkFlatController::SkFlatController() |
| : fBitmapHeap(NULL) |
| , fTypefaceSet(NULL) |
| , fTypefacePlayback(NULL) |
| , fFactorySet(NULL) |
| , fWriteBufferFlags(0) {} |
| |
| SkFlatController::~SkFlatController() { |
| SkSafeUnref(fBitmapHeap); |
| SkSafeUnref(fTypefaceSet); |
| SkSafeUnref(fFactorySet); |
| } |
| |
| void SkFlatController::setBitmapHeap(SkBitmapHeap* heap) { |
| SkRefCnt_SafeAssign(fBitmapHeap, heap); |
| } |
| |
| void SkFlatController::setTypefaceSet(SkRefCntSet *set) { |
| SkRefCnt_SafeAssign(fTypefaceSet, set); |
| } |
| |
| void SkFlatController::setTypefacePlayback(SkTypefacePlayback* playback) { |
| fTypefacePlayback = playback; |
| } |
| |
| SkNamedFactorySet* SkFlatController::setNamedFactorySet(SkNamedFactorySet* set) { |
| SkRefCnt_SafeAssign(fFactorySet, set); |
| return set; |
| } |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| SkFlatData* SkFlatData::Create(SkFlatController* controller, |
| const void* obj, |
| int index, |
| void (*flattenProc)(SkOrderedWriteBuffer&, const void*)) { |
| // a buffer of 256 bytes should be sufficient for most paints, regions, |
| // and matrices. |
| intptr_t storage[256]; |
| SkOrderedWriteBuffer buffer(256, storage, sizeof(storage)); |
| |
| buffer.setBitmapHeap(controller->getBitmapHeap()); |
| buffer.setTypefaceRecorder(controller->getTypefaceSet()); |
| buffer.setNamedFactoryRecorder(controller->getNamedFactorySet()); |
| buffer.setFlags(controller->getWriteBufferFlags()); |
| |
| flattenProc(buffer, obj); |
| uint32_t size = buffer.size(); |
| SkASSERT(SkIsAlign4(size)); |
| |
| // Allocate enough memory to hold SkFlatData struct and the flat data itself. |
| size_t allocSize = sizeof(SkFlatData) + size; |
| SkFlatData* result = (SkFlatData*) controller->allocThrow(allocSize); |
| |
| // Put the serialized contents into the data section of the new allocation. |
| buffer.writeToMemory(result->data()); |
| // Stamp the index, size and checksum in the header. |
| result->stampHeader(index, size); |
| return result; |
| } |
| |
| void SkFlatData::unflatten(void* result, |
| void (*unflattenProc)(SkOrderedReadBuffer&, void*), |
| SkBitmapHeap* bitmapHeap, |
| SkTypefacePlayback* facePlayback) const { |
| |
| SkOrderedReadBuffer buffer(this->data(), fFlatSize); |
| |
| if (bitmapHeap) { |
| buffer.setBitmapStorage(bitmapHeap); |
| } |
| if (facePlayback) { |
| facePlayback->setupBuffer(buffer); |
| } |
| |
| unflattenProc(buffer, result); |
| SkASSERT(fFlatSize == (int32_t)buffer.offset()); |
| } |