SkFlattenable.h revision ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976e
1 2/* 3 * Copyright 2006 The Android Open Source Project 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 9 10#ifndef SkFlattenable_DEFINED 11#define SkFlattenable_DEFINED 12 13#include "SkRefCnt.h" 14#include "SkBitmap.h" 15#include "SkReader32.h" 16#include "SkTDArray.h" 17#include "SkWriter32.h" 18 19class SkFlattenableReadBuffer; 20class SkFlattenableWriteBuffer; 21class SkString; 22 23/** \class SkFlattenable 24 25 SkFlattenable is the base class for objects that need to be flattened 26 into a data stream for either transport or as part of the key to the 27 font cache. 28 */ 29class SK_API SkFlattenable : public SkRefCnt { 30public: 31 typedef SkFlattenable* (*Factory)(SkFlattenableReadBuffer&); 32 33 SkFlattenable() {} 34 35 /** Implement this to return a factory function pointer that can be called 36 to recreate your class given a buffer (previously written to by your 37 override of flatten(). 38 */ 39 virtual Factory getFactory() = 0; 40 /** Override this to write data specific to your subclass into the buffer, 41 being sure to call your super-class' version first. This data will later 42 be passed to your Factory function, returned by getFactory(). 43 */ 44 virtual void flatten(SkFlattenableWriteBuffer&); 45 46 /** Set the string to describe the sublass and return true. If this is not 47 overridden, ignore the string param and return false. 48 */ 49 virtual bool toDumpString(SkString*) const; 50 51 static Factory NameToFactory(const char name[]); 52 static const char* FactoryToName(Factory); 53 static void Register(const char name[], Factory); 54 55 class Registrar { 56 public: 57 Registrar(const char name[], Factory factory) { 58 SkFlattenable::Register(name, factory); 59 } 60 }; 61 62protected: 63 SkFlattenable(SkFlattenableReadBuffer&) {} 64}; 65 66// helpers for matrix and region 67 68class SkMatrix; 69extern void SkReadMatrix(SkReader32*, SkMatrix*); 70extern void SkWriteMatrix(SkWriter32*, const SkMatrix&); 71 72class SkRegion; 73extern void SkReadRegion(SkReader32*, SkRegion*); 74extern void SkWriteRegion(SkWriter32*, const SkRegion&); 75 76/////////////////////////////////////////////////////////////////////////////// 77/////////////////////////////////////////////////////////////////////////////// 78 79class SkTypeface; 80 81class SkFlattenableReadBuffer : public SkReader32 { 82public: 83 SkFlattenableReadBuffer(); 84 explicit SkFlattenableReadBuffer(const void* data); 85 SkFlattenableReadBuffer(const void* data, size_t size); 86 87 void setRefCntArray(SkRefCnt* array[], int count) { 88 fRCArray = array; 89 fRCCount = count; 90 } 91 92 void setTypefaceArray(SkTypeface* array[], int count) { 93 fTFArray = array; 94 fTFCount = count; 95 } 96 97 /** 98 * Call this with a pre-loaded array of Factories, in the same order as 99 * were created/written by the writer. SkPicture uses this. 100 */ 101 void setFactoryPlayback(SkFlattenable::Factory array[], int count) { 102 fFactoryTDArray = NULL; 103 fFactoryArray = array; 104 fFactoryCount = count; 105 } 106 107 /** 108 * Call this with an initially empty array, so the reader can cache each 109 * factory it sees by name. Used by the pipe code in conjunction with 110 * the writer's kInlineFactoryNames_Flag. 111 */ 112 void setFactoryArray(SkTDArray<SkFlattenable::Factory>* array) { 113 fFactoryTDArray = array; 114 fFactoryArray = NULL; 115 fFactoryCount = 0; 116 } 117 118 SkTypeface* readTypeface(); 119 SkRefCnt* readRefCnt(); 120 void* readFunctionPtr(); 121 SkFlattenable* readFlattenable(); 122 123private: 124 SkRefCnt** fRCArray; 125 int fRCCount; 126 127 SkTypeface** fTFArray; 128 int fTFCount; 129 130 SkTDArray<SkFlattenable::Factory>* fFactoryTDArray; 131 SkFlattenable::Factory* fFactoryArray; 132 int fFactoryCount; 133 134 typedef SkReader32 INHERITED; 135}; 136 137/////////////////////////////////////////////////////////////////////////////// 138 139#include "SkPtrRecorder.h" 140 141/** 142 * Subclass of SkTPtrSet specialed to call ref() and unref() when the 143 * base class's incPtr() and decPtr() are called. This makes it a valid owner 144 * of each ptr, which is released when the set is reset or destroyed. 145 */ 146class SkRefCntSet : public SkTPtrSet<SkRefCnt*> { 147public: 148 virtual ~SkRefCntSet(); 149 150protected: 151 // overrides 152 virtual void incPtr(void*); 153 virtual void decPtr(void*); 154}; 155 156class SkFactorySet : public SkTPtrSet<SkFlattenable::Factory> {}; 157 158class SkFlattenableWriteBuffer : public SkWriter32 { 159public: 160 SkFlattenableWriteBuffer(size_t minSize); 161 virtual ~SkFlattenableWriteBuffer(); 162 163 void writeTypeface(SkTypeface*); 164 void writeRefCnt(SkRefCnt*); 165 void writeFunctionPtr(void*); 166 void writeFlattenable(SkFlattenable* flattenable); 167 168 SkRefCntSet* getTypefaceRecorder() const { return fTFSet; } 169 SkRefCntSet* setTypefaceRecorder(SkRefCntSet*); 170 171 SkRefCntSet* getRefCntRecorder() const { return fRCSet; } 172 SkRefCntSet* setRefCntRecorder(SkRefCntSet*); 173 174 SkFactorySet* getFactoryRecorder() const { return fFactorySet; } 175 SkFactorySet* setFactoryRecorder(SkFactorySet*); 176 177 enum Flags { 178 kCrossProcess_Flag = 0x01, 179 /** 180 * Instructs the writer to inline Factory names as there are seen the 181 * first time (after that we store an index). The pipe code uses this. 182 */ 183 kInlineFactoryNames_Flag = 0x02, 184 }; 185 Flags getFlags() const { return (Flags)fFlags; } 186 void setFlags(Flags flags) { fFlags = flags; } 187 188 bool isCrossProcess() const { 189 return SkToBool(fFlags & kCrossProcess_Flag); 190 } 191 bool inlineFactoryNames() const { 192 return SkToBool(fFlags & kInlineFactoryNames_Flag); 193 } 194 195 bool persistBitmapPixels() const { 196 return (fFlags & kCrossProcess_Flag) != 0; 197 } 198 199 bool persistTypeface() const { return (fFlags & kCrossProcess_Flag) != 0; } 200 201private: 202 uint32_t fFlags; 203 SkRefCntSet* fTFSet; 204 SkRefCntSet* fRCSet; 205 SkFactorySet* fFactorySet; 206 207 typedef SkWriter32 INHERITED; 208}; 209 210#endif 211 212