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