SkFlattenable.h revision 9d0c6ecb8440e8e546881a4ff850eb6333f24541
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 164private: 165 SkRefCnt** fRCArray; 166 int fRCCount; 167 168 SkTypeface** fTFArray; 169 int fTFCount; 170 171 SkTDArray<SkFlattenable::Factory>* fFactoryTDArray; 172 SkFlattenable::Factory* fFactoryArray; 173 int fFactoryCount; 174 175 typedef SkReader32 INHERITED; 176}; 177 178/////////////////////////////////////////////////////////////////////////////// 179 180#include "SkPtrRecorder.h" 181 182/** 183 * Subclass of SkTPtrSet specialed to call ref() and unref() when the 184 * base class's incPtr() and decPtr() are called. This makes it a valid owner 185 * of each ptr, which is released when the set is reset or destroyed. 186 */ 187class SkRefCntSet : public SkTPtrSet<SkRefCnt*> { 188public: 189 virtual ~SkRefCntSet(); 190 191protected: 192 // overrides 193 virtual void incPtr(void*); 194 virtual void decPtr(void*); 195}; 196 197class SkFactorySet : public SkTPtrSet<SkFlattenable::Factory> {}; 198 199class SkFlattenableWriteBuffer : public SkWriter32 { 200public: 201 SkFlattenableWriteBuffer(size_t minSize); 202 virtual ~SkFlattenableWriteBuffer(); 203 204 void writeTypeface(SkTypeface*); 205 void writeRefCnt(SkRefCnt*); 206 void writeFunctionPtr(void*); 207 void writeFlattenable(SkFlattenable* flattenable); 208 209 SkRefCntSet* getTypefaceRecorder() const { return fTFSet; } 210 SkRefCntSet* setTypefaceRecorder(SkRefCntSet*); 211 212 SkRefCntSet* getRefCntRecorder() const { return fRCSet; } 213 SkRefCntSet* setRefCntRecorder(SkRefCntSet*); 214 215 SkFactorySet* getFactoryRecorder() const { return fFactorySet; } 216 SkFactorySet* setFactoryRecorder(SkFactorySet*); 217 218 enum Flags { 219 kCrossProcess_Flag = 0x01, 220 /** 221 * Instructs the writer to inline Factory names as there are seen the 222 * first time (after that we store an index). The pipe code uses this. 223 */ 224 kInlineFactoryNames_Flag = 0x02, 225 }; 226 Flags getFlags() const { return (Flags)fFlags; } 227 void setFlags(Flags flags) { fFlags = flags; } 228 229 bool isCrossProcess() const { 230 return SkToBool(fFlags & kCrossProcess_Flag); 231 } 232 bool inlineFactoryNames() const { 233 return SkToBool(fFlags & kInlineFactoryNames_Flag); 234 } 235 236 bool persistBitmapPixels() const { 237 return (fFlags & kCrossProcess_Flag) != 0; 238 } 239 240 bool persistTypeface() const { return (fFlags & kCrossProcess_Flag) != 0; } 241 242private: 243 uint32_t fFlags; 244 SkRefCntSet* fTFSet; 245 SkRefCntSet* fRCSet; 246 SkFactorySet* fFactorySet; 247 248 typedef SkWriter32 INHERITED; 249}; 250 251#endif 252 253