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