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