OLD | NEW |
| (Empty) |
1 #include "SkFlattenable.h" | |
2 #include "SkTypeface.h" | |
3 | |
4 void SkFlattenable::flatten(SkFlattenableWriteBuffer&) | |
5 { | |
6 /* we don't write anything at the moment, but this allows our subclasses | |
7 to not know that, since we want them to always call INHERITED::flatten() | |
8 in their code. | |
9 */ | |
10 } | |
11 | |
12 /////////////////////////////////////////////////////////////////////////////// | |
13 /////////////////////////////////////////////////////////////////////////////// | |
14 | |
15 SkFlattenableReadBuffer::SkFlattenableReadBuffer() { | |
16 fRCArray = NULL; | |
17 fRCCount = 0; | |
18 | |
19 fTFArray = NULL; | |
20 fTFCount = 0; | |
21 | |
22 fFactoryArray = NULL; | |
23 fFactoryCount = 0; | |
24 } | |
25 | |
26 SkFlattenableReadBuffer::SkFlattenableReadBuffer(const void* data) : | |
27 INHERITED(data, 1024 * 1024) { | |
28 fRCArray = NULL; | |
29 fRCCount = 0; | |
30 | |
31 fTFArray = NULL; | |
32 fTFCount = 0; | |
33 | |
34 fFactoryArray = NULL; | |
35 fFactoryCount = 0; | |
36 } | |
37 | |
38 SkFlattenableReadBuffer::SkFlattenableReadBuffer(const void* data, size_t size) | |
39 : INHERITED(data, size) { | |
40 fRCArray = NULL; | |
41 fRCCount = 0; | |
42 | |
43 fTFArray = NULL; | |
44 fTFCount = 0; | |
45 | |
46 fFactoryArray = NULL; | |
47 fFactoryCount = 0; | |
48 } | |
49 | |
50 SkTypeface* SkFlattenableReadBuffer::readTypeface() { | |
51 uint32_t index = this->readU32(); | |
52 if (0 == index || index > (unsigned)fTFCount) { | |
53 if (index) { | |
54 SkDebugf("====== typeface index %d\n", index); | |
55 } | |
56 return NULL; | |
57 } else { | |
58 SkASSERT(fTFArray); | |
59 return fTFArray[index - 1]; | |
60 } | |
61 } | |
62 | |
63 SkRefCnt* SkFlattenableReadBuffer::readRefCnt() { | |
64 uint32_t index = this->readU32(); | |
65 if (0 == index || index > (unsigned)fRCCount) { | |
66 return NULL; | |
67 } else { | |
68 SkASSERT(fRCArray); | |
69 return fRCArray[index - 1]; | |
70 } | |
71 } | |
72 | |
73 SkFlattenable* SkFlattenableReadBuffer::readFlattenable() { | |
74 SkFlattenable::Factory factory = NULL; | |
75 | |
76 if (fFactoryCount > 0) { | |
77 uint32_t index = this->readU32(); | |
78 if (index > 0) { | |
79 index -= 1; | |
80 SkASSERT(index < (unsigned)fFactoryCount); | |
81 factory = fFactoryArray[index]; | |
82 // if we recorded an index, but failed to get a factory, we need | |
83 // to skip the flattened data in the buffer | |
84 if (NULL == factory) { | |
85 uint32_t size = this->readU32(); | |
86 this->skip(size); | |
87 // fall through and return NULL for the object | |
88 } | |
89 } | |
90 } else { | |
91 factory = (SkFlattenable::Factory)readFunctionPtr(); | |
92 } | |
93 | |
94 SkFlattenable* obj = NULL; | |
95 if (factory) { | |
96 uint32_t sizeRecorded = this->readU32(); | |
97 uint32_t offset = this->offset(); | |
98 obj = (*factory)(*this); | |
99 // check that we read the amount we expected | |
100 uint32_t sizeRead = this->offset() - offset; | |
101 if (sizeRecorded != sizeRead) { | |
102 // we could try to fix up the offset... | |
103 sk_throw(); | |
104 } | |
105 } | |
106 return obj; | |
107 } | |
108 | |
109 void* SkFlattenableReadBuffer::readFunctionPtr() { | |
110 void* proc; | |
111 this->read(&proc, sizeof(proc)); | |
112 return proc; | |
113 } | |
114 | |
115 /////////////////////////////////////////////////////////////////////////////// | |
116 | |
117 SkFlattenableWriteBuffer::SkFlattenableWriteBuffer(size_t minSize) : | |
118 INHERITED(minSize) { | |
119 fFlags = (Flags)0; | |
120 fRCRecorder = NULL; | |
121 fTFRecorder = NULL; | |
122 fFactoryRecorder = NULL; | |
123 } | |
124 | |
125 SkFlattenableWriteBuffer::~SkFlattenableWriteBuffer() { | |
126 fRCRecorder->safeUnref(); | |
127 fTFRecorder->safeUnref(); | |
128 fFactoryRecorder->safeUnref(); | |
129 } | |
130 | |
131 SkRefCntRecorder* SkFlattenableWriteBuffer::setRefCntRecorder( | |
132 SkRefCntRecorder* rec) { | |
133 SkRefCnt_SafeAssign(fRCRecorder, rec); | |
134 return rec; | |
135 } | |
136 | |
137 SkRefCntRecorder* SkFlattenableWriteBuffer::setTypefaceRecorder( | |
138 SkRefCntRecorder* rec) { | |
139 SkRefCnt_SafeAssign(fTFRecorder, rec); | |
140 return rec; | |
141 } | |
142 | |
143 SkFactoryRecorder* SkFlattenableWriteBuffer::setFactoryRecorder( | |
144 SkFactoryRecorder* rec) { | |
145 SkRefCnt_SafeAssign(fFactoryRecorder, rec); | |
146 return rec; | |
147 } | |
148 | |
149 void SkFlattenableWriteBuffer::writeTypeface(SkTypeface* obj) { | |
150 if (NULL == obj || NULL == fTFRecorder) { | |
151 this->write32(0); | |
152 } else { | |
153 this->write32(fTFRecorder->record(obj)); | |
154 } | |
155 } | |
156 | |
157 void SkFlattenableWriteBuffer::writeRefCnt(SkRefCnt* obj) { | |
158 if (NULL == obj || NULL == fRCRecorder) { | |
159 this->write32(0); | |
160 } else { | |
161 this->write32(fRCRecorder->record(obj)); | |
162 } | |
163 } | |
164 | |
165 void SkFlattenableWriteBuffer::writeFlattenable(SkFlattenable* flattenable) { | |
166 SkFlattenable::Factory factory = NULL; | |
167 if (flattenable) { | |
168 factory = flattenable->getFactory(); | |
169 } | |
170 | |
171 if (fFactoryRecorder) { | |
172 this->write32(fFactoryRecorder->record(factory)); | |
173 } else { | |
174 this->writeFunctionPtr((void*)factory); | |
175 } | |
176 | |
177 if (factory) { | |
178 // make room for the size of the flatttened object | |
179 (void)this->reserve(sizeof(uint32_t)); | |
180 // record the current size, so we can subtract after the object writes. | |
181 uint32_t offset = this->size(); | |
182 // now flatten the object | |
183 flattenable->flatten(*this); | |
184 uint32_t objSize = this->size() - offset; | |
185 // record the obj's size | |
186 *this->peek32(offset - sizeof(uint32_t)) = objSize; | |
187 } | |
188 } | |
189 | |
190 void SkFlattenableWriteBuffer::writeFunctionPtr(void* proc) { | |
191 *(void**)this->reserve(sizeof(void*)) = proc; | |
192 } | |
193 | |
194 /////////////////////////////////////////////////////////////////////////////// | |
195 | |
196 SkRefCntRecorder::~SkRefCntRecorder() { | |
197 // call this now, while our decPtr() is sill in scope | |
198 this->reset(); | |
199 } | |
200 | |
201 void SkRefCntRecorder::incPtr(void* ptr) { | |
202 ((SkRefCnt*)ptr)->ref(); | |
203 } | |
204 | |
205 void SkRefCntRecorder::decPtr(void* ptr) { | |
206 ((SkRefCnt*)ptr)->unref(); | |
207 } | |
208 | |
209 /////////////////////////////////////////////////////////////////////////////// | |
210 /////////////////////////////////////////////////////////////////////////////// | |
211 /////////////////////////////////////////////////////////////////////////////// | |
212 | |
213 #define MAX_PAIR_COUNT 64 | |
214 | |
215 struct Pair { | |
216 const char* fName; | |
217 SkFlattenable::Factory fFactory; | |
218 }; | |
219 | |
220 static int gCount; | |
221 static Pair gPairs[MAX_PAIR_COUNT]; | |
222 | |
223 void SkFlattenable::Register(const char name[], Factory factory) { | |
224 SkASSERT(name); | |
225 SkASSERT(factory); | |
226 | |
227 static bool gOnce; | |
228 if (!gOnce) { | |
229 gCount = 0; | |
230 gOnce = true; | |
231 } | |
232 | |
233 SkASSERT(gCount < MAX_PAIR_COUNT); | |
234 | |
235 gPairs[gCount].fName = name; | |
236 gPairs[gCount].fFactory = factory; | |
237 gCount += 1; | |
238 } | |
239 | |
240 SkFlattenable::Factory SkFlattenable::NameToFactory(const char name[]) { | |
241 const Pair* pairs = gPairs; | |
242 for (int i = gCount - 1; i >= 0; --i) { | |
243 if (strcmp(pairs[i].fName, name) == 0) { | |
244 return pairs[i].fFactory; | |
245 } | |
246 } | |
247 return NULL; | |
248 } | |
249 | |
250 const char* SkFlattenable::FactoryToName(Factory fact) { | |
251 const Pair* pairs = gPairs; | |
252 for (int i = gCount - 1; i >= 0; --i) { | |
253 if (pairs[i].fFactory == fact) { | |
254 return pairs[i].fName; | |
255 } | |
256 } | |
257 return NULL; | |
258 } | |
259 | |
OLD | NEW |