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 0 : class SK_API SkFlattenable : public SkRefCnt {
64 : public:
65 : typedef SkFlattenable* (*Factory)(SkFlattenableReadBuffer&);
66 :
67 0 : 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 40992 : Registrar(const char name[], Factory factory) {
92 40992 : SkFlattenable::Register(name, factory);
93 40992 : }
94 : };
95 :
96 : protected:
97 0 : 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 :
128 0 : void setRefCntArray(SkRefCnt* array[], int count) {
129 0 : fRCArray = array;
130 0 : fRCCount = count;
131 0 : }
132 :
133 0 : void setTypefaceArray(SkTypeface* array[], int count) {
134 0 : fTFArray = array;
135 0 : fTFCount = count;
136 0 : }
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 0 : void setFactoryPlayback(SkFlattenable::Factory array[], int count) {
143 0 : fFactoryTDArray = NULL;
144 0 : fFactoryArray = array;
145 0 : fFactoryCount = count;
146 0 : }
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 : private:
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 : */
187 0 : class SkRefCntSet : public SkTPtrSet<SkRefCnt*> {
188 : public:
189 : virtual ~SkRefCntSet();
190 :
191 : protected:
192 : // overrides
193 : virtual void incPtr(void*);
194 : virtual void decPtr(void*);
195 : };
196 :
197 0 : class SkFactorySet : public SkTPtrSet<SkFlattenable::Factory> {};
198 :
199 : class SkFlattenableWriteBuffer : public SkWriter32 {
200 : public:
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 0 : void setFlags(Flags flags) { fFlags = flags; }
228 :
229 0 : bool isCrossProcess() const {
230 0 : return SkToBool(fFlags & kCrossProcess_Flag);
231 : }
232 0 : bool inlineFactoryNames() const {
233 0 : return SkToBool(fFlags & kInlineFactoryNames_Flag);
234 : }
235 :
236 0 : bool persistBitmapPixels() const {
237 0 : return (fFlags & kCrossProcess_Flag) != 0;
238 : }
239 :
240 : bool persistTypeface() const { return (fFlags & kCrossProcess_Flag) != 0; }
241 :
242 : private:
243 : uint32_t fFlags;
244 : SkRefCntSet* fTFSet;
245 : SkRefCntSet* fRCSet;
246 : SkFactorySet* fFactorySet;
247 :
248 : typedef SkWriter32 INHERITED;
249 : };
250 :
251 : #endif
252 :
|