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#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 */ 63class SK_API SkFlattenable : public SkRefCnt { 64public: 65 typedef SkFlattenable* (*Factory)(SkFlattenableReadBuffer&); 66 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: 91 Registrar(const char name[], Factory factory) { 92 SkFlattenable::Register(name, factory); 93 } 94 }; 95 96protected: 97 SkFlattenable(SkFlattenableReadBuffer&) {} 98 99private: 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 109class SkMatrix; 110extern void SkReadMatrix(SkReader32*, SkMatrix*); 111extern void SkWriteMatrix(SkWriter32*, const SkMatrix&); 112 113class SkRegion; 114extern void SkReadRegion(SkReader32*, SkRegion*); 115extern void SkWriteRegion(SkWriter32*, const SkRegion&); 116 117/////////////////////////////////////////////////////////////////////////////// 118/////////////////////////////////////////////////////////////////////////////// 119 120class SkTypeface; 121 122class SkFlattenableReadBuffer : public SkReader32 { 123public: 124 SkFlattenableReadBuffer(); 125 explicit SkFlattenableReadBuffer(const void* data); 126 SkFlattenableReadBuffer(const void* data, size_t size); 127 128 void setRefCntArray(SkRefCnt* array[], int count) { 129 fRCArray = array; 130 fRCCount = count; 131 } 132 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 */ 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 */ 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 164 void setPictureVersion(uint32_t version) { fPictureVersion = version; } 165 uint32_t getPictureVersion() { return fPictureVersion; } 166 167private: 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 */ 192class SkRefCntSet : public SkTPtrSet<SkRefCnt*> { 193public: 194 virtual ~SkRefCntSet(); 195 196protected: 197 // overrides 198 virtual void incPtr(void*); 199 virtual void decPtr(void*); 200}; 201 202class SkFactorySet : public SkTPtrSet<SkFlattenable::Factory> {}; 203 204class SkFlattenableWriteBuffer : public SkWriter32 { 205public: 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 214 SkRefCntSet* getTypefaceRecorder() const { return fTFSet; } 215 SkRefCntSet* setTypefaceRecorder(SkRefCntSet*); 216 217 SkRefCntSet* getRefCntRecorder() const { return fRCSet; } 218 SkRefCntSet* setRefCntRecorder(SkRefCntSet*); 219 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 }; 231 Flags getFlags() const { return (Flags)fFlags; } 232 void setFlags(Flags flags) { fFlags = flags; } 233 234 bool isCrossProcess() const { 235 return SkToBool(fFlags & kCrossProcess_Flag); 236 } 237 bool inlineFactoryNames() const { 238 return SkToBool(fFlags & kInlineFactoryNames_Flag); 239 } 240 241 bool persistBitmapPixels() const { 242 return (fFlags & kCrossProcess_Flag) != 0; 243 } 244 245 bool persistTypeface() const { return (fFlags & kCrossProcess_Flag) != 0; } 246 247private: 248 uint32_t fFlags; 249 SkRefCntSet* fTFSet; 250 SkRefCntSet* fRCSet; 251 SkFactorySet* fFactorySet; 252 253 typedef SkWriter32 INHERITED; 254}; 255 256#endif 257 258