• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 class SK_API SkFlattenable : public SkRefCnt {
64 public:
65     typedef SkFlattenable* (*Factory)(SkFlattenableReadBuffer&);
66 
SkFlattenable()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:
Registrar(const char name[],Factory factory)91         Registrar(const char name[], Factory factory) {
92             SkFlattenable::Register(name, factory);
93         }
94     };
95 
96 protected:
SkFlattenable(SkFlattenableReadBuffer &)97     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 
setRefCntArray(SkRefCnt * array[],int count)128     void setRefCntArray(SkRefCnt* array[], int count) {
129         fRCArray = array;
130         fRCCount = count;
131     }
132 
setTypefaceArray(SkTypeface * array[],int count)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      */
setFactoryPlayback(SkFlattenable::Factory array[],int count)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      */
setFactoryArray(SkTDArray<SkFlattenable::Factory> * array)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 
setPictureVersion(uint32_t version)164     void setPictureVersion(uint32_t version) { fPictureVersion = version; }
getPictureVersion()165     uint32_t getPictureVersion() { return fPictureVersion; }
166 
167 private:
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  */
192 class SkRefCntSet : public SkTPtrSet<SkRefCnt*> {
193 public:
194     virtual ~SkRefCntSet();
195 
196 protected:
197     // overrides
198     virtual void incPtr(void*);
199     virtual void decPtr(void*);
200 };
201 
202 class SkFactorySet : public SkTPtrSet<SkFlattenable::Factory> {};
203 
204 class SkFlattenableWriteBuffer : public SkWriter32 {
205 public:
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 
getTypefaceRecorder()214     SkRefCntSet* getTypefaceRecorder() const { return fTFSet; }
215     SkRefCntSet* setTypefaceRecorder(SkRefCntSet*);
216 
getRefCntRecorder()217     SkRefCntSet* getRefCntRecorder() const { return fRCSet; }
218     SkRefCntSet* setRefCntRecorder(SkRefCntSet*);
219 
getFactoryRecorder()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     };
getFlags()231     Flags getFlags() const { return (Flags)fFlags; }
setFlags(Flags flags)232     void setFlags(Flags flags) { fFlags = flags; }
233 
isCrossProcess()234     bool isCrossProcess() const {
235         return SkToBool(fFlags & kCrossProcess_Flag);
236     }
inlineFactoryNames()237     bool inlineFactoryNames() const {
238         return SkToBool(fFlags & kInlineFactoryNames_Flag);
239     }
240 
persistBitmapPixels()241     bool persistBitmapPixels() const {
242         return (fFlags & kCrossProcess_Flag) != 0;
243     }
244 
persistTypeface()245     bool persistTypeface() const { return (fFlags & kCrossProcess_Flag) != 0; }
246 
247 private:
248     uint32_t        fFlags;
249     SkRefCntSet*    fTFSet;
250     SkRefCntSet*    fRCSet;
251     SkFactorySet*   fFactorySet;
252 
253     typedef SkWriter32 INHERITED;
254 };
255 
256 #endif
257 
258