OLD | NEW |
---|---|
(Empty) | |
1 /* | |
2 * Copyright 2016 Google Inc. | |
3 * | |
4 * Use of this source code is governed by a BSD-style license that can be | |
5 * found in the LICENSE file. | |
6 */ | |
7 | |
8 #include "SkCanvas.h" | |
9 #include "SkDrawable.h" | |
10 #include "SkOnce.h" | |
11 #include "SkPictureRecorder.h" | |
12 #include "SkReadBuffer.h" | |
13 #include "SkRect.h" | |
14 #include "SkStream.h" | |
15 #include "SkWriteBuffer.h" | |
16 #include "Test.h" | |
17 | |
18 class IntDrawable : public SkDrawable { | |
19 public: | |
20 IntDrawable(uint32_t a, uint32_t b, uint32_t c, uint32_t d) | |
21 : fA(a) | |
22 , fB(b) | |
23 , fC(c) | |
24 , fD(d) | |
25 {} | |
26 | |
27 void flatten(SkWriteBuffer& buffer) const override { | |
28 buffer.writeUInt(fA); | |
29 buffer.writeUInt(fB); | |
30 buffer.writeUInt(fC); | |
31 buffer.writeUInt(fD); | |
32 } | |
33 | |
34 static SkFlattenable* CreateProc(SkReadBuffer& buffer) { | |
35 uint32_t a = buffer.readUInt(); | |
36 uint32_t b = buffer.readUInt(); | |
37 uint32_t c = buffer.readUInt(); | |
38 uint32_t d = buffer.readUInt(); | |
39 return new IntDrawable(a, b, c, d); | |
40 } | |
41 | |
42 Factory getFactory() const override { return CreateProc; } | |
43 | |
44 uint32_t a() const { return fA; } | |
45 uint32_t b() const { return fB; } | |
46 uint32_t c() const { return fC; } | |
47 uint32_t d() const { return fD; } | |
48 | |
49 protected: | |
50 SkRect onGetBounds() override { return SkRect::MakeEmpty(); } | |
51 void onDraw(SkCanvas*) override {} | |
52 | |
53 private: | |
54 uint32_t fA; | |
55 uint32_t fB; | |
56 uint32_t fC; | |
57 uint32_t fD; | |
58 }; | |
59 | |
60 class PaintDrawable : public SkDrawable { | |
61 public: | |
62 PaintDrawable(const SkPaint& paint) | |
63 : fPaint(paint) | |
64 {} | |
65 | |
66 void flatten(SkWriteBuffer& buffer) const override { | |
67 buffer.writePaint(fPaint); | |
68 } | |
69 | |
70 static SkFlattenable* CreateProc(SkReadBuffer& buffer) { | |
71 SkPaint paint; | |
72 buffer.readPaint(&paint); | |
73 return new PaintDrawable(paint); | |
74 } | |
75 | |
76 Factory getFactory() const override { return CreateProc; } | |
77 | |
78 const SkPaint& paint() const { return fPaint; } | |
79 | |
80 protected: | |
81 SkRect onGetBounds() override { return SkRect::MakeEmpty(); } | |
82 void onDraw(SkCanvas*) override {} | |
83 | |
84 private: | |
85 SkPaint fPaint; | |
86 }; | |
87 | |
88 class CompoundDrawable : public SkDrawable { | |
89 public: | |
90 CompoundDrawable(uint32_t a, uint32_t b, uint32_t c, uint32_t d, const SkPai nt& paint) | |
91 : fIntDrawable(new IntDrawable(a, b, c, d)) | |
92 , fPaintDrawable(new PaintDrawable(paint)) | |
93 {} | |
94 | |
95 CompoundDrawable(IntDrawable* intDrawable, PaintDrawable* paintDrawable) | |
96 : fIntDrawable(SkRef(intDrawable)) | |
97 , fPaintDrawable(SkRef(paintDrawable)) | |
98 {} | |
99 | |
100 void flatten(SkWriteBuffer& buffer) const override { | |
101 buffer.writeFlattenable(fIntDrawable); | |
102 buffer.writeFlattenable(fPaintDrawable); | |
103 } | |
104 | |
105 static SkFlattenable* CreateProc(SkReadBuffer& buffer) { | |
106 SkAutoTUnref<SkFlattenable> intDrawable( | |
107 buffer.readFlattenable(SkFlattenable::kSkDrawable_Type)); | |
108 SkASSERT(intDrawable); | |
109 SkASSERT(!strcmp("IntDrawable", intDrawable->getTypeName())); | |
110 | |
111 SkAutoTUnref<SkFlattenable> paintDrawable( | |
112 buffer.readFlattenable(SkFlattenable::kSkDrawable_Type)); | |
113 SkASSERT(paintDrawable); | |
114 SkASSERT(!strcmp("PaintDrawable", paintDrawable->getTypeName())); | |
115 | |
116 return new CompoundDrawable((IntDrawable*) intDrawable.get(), | |
117 (PaintDrawable*) paintDrawable.get()); | |
118 } | |
119 | |
120 Factory getFactory() const override { return CreateProc; } | |
121 | |
122 IntDrawable* intDrawable() const { return fIntDrawable; } | |
123 PaintDrawable* paintDrawable() const { return fPaintDrawable; } | |
124 | |
125 protected: | |
126 SkRect onGetBounds() override { return SkRect::MakeEmpty(); } | |
127 void onDraw(SkCanvas*) override {} | |
128 | |
129 private: | |
130 SkAutoTUnref<IntDrawable> fIntDrawable; | |
131 SkAutoTUnref<PaintDrawable> fPaintDrawable; | |
132 }; | |
133 | |
134 class RootDrawable : public SkDrawable { | |
135 public: | |
136 RootDrawable(uint32_t a, uint32_t b, uint32_t c, uint32_t d, const SkPaint& paint, | |
137 uint32_t e, uint32_t f, uint32_t g, uint32_t h, SkDrawable* d rawable) | |
138 : fCompoundDrawable(new CompoundDrawable(a, b, c, d, paint)) | |
139 , fIntDrawable(new IntDrawable(e, f, g, h)) | |
140 , fDrawable(SkRef(drawable)) | |
141 {} | |
142 | |
143 RootDrawable(CompoundDrawable* compoundDrawable, IntDrawable* intDrawable, | |
144 SkDrawable* drawable) | |
145 : fCompoundDrawable(SkRef(compoundDrawable)) | |
146 , fIntDrawable(SkRef(intDrawable)) | |
147 , fDrawable(SkRef(drawable)) | |
148 {} | |
149 | |
150 void flatten(SkWriteBuffer& buffer) const override { | |
151 buffer.writeFlattenable(fCompoundDrawable); | |
152 buffer.writeFlattenable(fIntDrawable); | |
153 buffer.writeFlattenable(fDrawable); | |
154 } | |
155 | |
156 static SkFlattenable* CreateProc(SkReadBuffer& buffer) { | |
157 SkAutoTUnref<SkFlattenable> compoundDrawable( | |
158 buffer.readFlattenable(SkFlattenable::kSkDrawable_Type)); | |
159 SkASSERT(compoundDrawable); | |
160 SkASSERT(!strcmp("CompoundDrawable", compoundDrawable->getTypeName())); | |
161 | |
162 SkAutoTUnref<SkFlattenable> intDrawable( | |
163 buffer.readFlattenable(SkFlattenable::kSkDrawable_Type)); | |
164 SkASSERT(intDrawable); | |
165 SkASSERT(!strcmp("IntDrawable", intDrawable->getTypeName())); | |
166 | |
167 SkAutoTUnref<SkFlattenable> drawable( | |
168 buffer.readFlattenable(SkFlattenable::kSkDrawable_Type)); | |
169 SkASSERT(drawable); | |
170 | |
171 return new RootDrawable((CompoundDrawable*) compoundDrawable.get(), | |
172 (IntDrawable*) intDrawable.get(), | |
173 (SkDrawable*) drawable.get()); | |
174 } | |
175 | |
176 Factory getFactory() const override { return CreateProc; } | |
177 | |
178 CompoundDrawable* compoundDrawable() const { return fCompoundDrawable; } | |
179 IntDrawable* intDrawable() const { return fIntDrawable; } | |
180 SkDrawable* drawable() const { return fDrawable; } | |
181 | |
182 protected: | |
183 SkRect onGetBounds() override { return SkRect::MakeEmpty(); } | |
184 void onDraw(SkCanvas*) override {} | |
185 | |
186 private: | |
187 SkAutoTUnref<CompoundDrawable> fCompoundDrawable; | |
188 SkAutoTUnref<IntDrawable> fIntDrawable; | |
189 SkAutoTUnref<SkDrawable> fDrawable; | |
190 }; | |
191 | |
192 static void register_test_drawables() { | |
193 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(IntDrawable) | |
194 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(PaintDrawable) | |
195 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(CompoundDrawable) | |
196 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(RootDrawable) | |
197 } | |
198 | |
199 SK_DECLARE_STATIC_ONCE(gOnce); | |
200 static void register_test_drawables_once() { | |
201 SkOnce(&gOnce, register_test_drawables); | |
202 } | |
203 | |
204 DEF_TEST(SerializeDrawable, r) { | |
205 register_test_drawables_once(); | |
206 | |
207 // Create and serialize the test drawable | |
208 SkAutoTUnref<SkDrawable> drawable(new IntDrawable(1, 2, 3, 4)); | |
209 SkPaint paint; | |
210 paint.setColor(SK_ColorBLUE); | |
211 SkAutoTUnref<RootDrawable> root(new RootDrawable(5, 6, 7, 8, paint, 9, 10, 1 1, 12, drawable)); | |
212 SkWriteBuffer writeBuffer; | |
213 writeBuffer.writeFlattenable(root); | |
214 | |
215 // Copy the contents of the write buffer into a read buffer | |
216 sk_sp<SkData> data = SkData::MakeUninitialized(writeBuffer.bytesWritten()); | |
217 writeBuffer.writeToMemory(data->writable_data()); | |
218 SkReadBuffer readBuffer(data->data(), data->size()); | |
219 | |
220 // Deserialize and verify the drawable | |
221 SkAutoTUnref<SkDrawable> out((SkDrawable*) | |
222 readBuffer.readFlattenable(SkFlattenable::kSkDrawable_Type)); | |
223 REPORTER_ASSERT(r, out); | |
224 REPORTER_ASSERT(r, !strcmp("RootDrawable", out->getTypeName())); | |
225 | |
226 RootDrawable* rootOut = (RootDrawable*) out.get(); | |
227 REPORTER_ASSERT(r, 5 == rootOut->compoundDrawable()->intDrawable()->a()); | |
228 REPORTER_ASSERT(r, 6 == rootOut->compoundDrawable()->intDrawable()->b()); | |
229 REPORTER_ASSERT(r, 7 == rootOut->compoundDrawable()->intDrawable()->c()); | |
230 REPORTER_ASSERT(r, 8 == rootOut->compoundDrawable()->intDrawable()->d()); | |
231 REPORTER_ASSERT(r, SK_ColorBLUE == | |
232 rootOut->compoundDrawable()->paintDrawable()->paint().getColor()); | |
233 REPORTER_ASSERT(r, 9 == rootOut->intDrawable()->a()); | |
234 REPORTER_ASSERT(r, 10 == rootOut->intDrawable()->b()); | |
235 REPORTER_ASSERT(r, 11 == rootOut->intDrawable()->c()); | |
236 REPORTER_ASSERT(r, 12 == rootOut->intDrawable()->d()); | |
237 | |
238 // Note that we can still recognize the generic drawable as an IntDrawable | |
239 SkDrawable* generic = rootOut->drawable(); | |
240 REPORTER_ASSERT(r, !strcmp("IntDrawable", generic->getTypeName())); | |
241 IntDrawable* integer = (IntDrawable*) generic; | |
242 REPORTER_ASSERT(r, 1 == integer->a()); | |
243 REPORTER_ASSERT(r, 2 == integer->b()); | |
244 REPORTER_ASSERT(r, 3 == integer->c()); | |
245 REPORTER_ASSERT(r, 4 == integer->d()); | |
246 } | |
247 | |
248 DEF_TEST(SerializeRecordedDrawable, r) { | |
249 register_test_drawables_once(); | |
250 | |
251 // Record a set of canvas draw commands | |
252 SkPictureRecorder recorder; | |
253 SkCanvas* canvas = recorder.beginRecording(1000.0f, 1000.0f); | |
254 canvas->drawPoint(42.0f, 17.0f, SK_ColorGREEN); | |
255 SkPaint paint; | |
256 paint.setColor(SK_ColorRED); | |
257 canvas->drawPaint(paint); | |
258 SkPaint textPaint; | |
259 textPaint.setColor(SK_ColorBLUE); | |
260 canvas->drawText("TEXT", 354.0f, 467.0f, 100.0f, textPaint); | |
261 | |
262 // Draw some drawables as well | |
263 SkAutoTUnref<SkDrawable> drawable(new IntDrawable(1, 2, 3, 4)); | |
264 SkAutoTUnref<RootDrawable> root(new RootDrawable(5, 6, 7, 8, paint, 9, 10, 1 1, 12, drawable)); | |
265 canvas->drawDrawable(root, 747.0f, 242.0f); | |
266 SkAutoTUnref<PaintDrawable> paintDrawable(new PaintDrawable(paint)); | |
267 canvas->drawDrawable(paintDrawable, 500.0, 500.0f); | |
268 SkAutoTUnref<CompoundDrawable> comDrawable(new CompoundDrawable(13, 14, 15, 16, textPaint)); | |
269 canvas->drawDrawable(comDrawable, 10.0f, 10.0f); | |
270 | |
271 // Serialize the recorded drawable | |
272 sk_sp<SkDrawable> recordedDrawable = recorder.finishRecordingAsDrawable(); | |
273 SkWriteBuffer writeBuffer; | |
274 writeBuffer.writeFlattenable(recordedDrawable.get()); | |
275 | |
276 // Copy the contents of the write buffer into a read buffer | |
277 sk_sp<SkData> data = SkData::MakeUninitialized(writeBuffer.bytesWritten()); | |
278 writeBuffer.writeToMemory(data->writable_data()); | |
279 SkReadBuffer readBuffer(data->data(), data->size()); | |
280 | |
281 // Deserialize and verify the drawable | |
282 SkAutoTUnref<SkDrawable> out((SkDrawable*) | |
283 readBuffer.readFlattenable(SkFlattenable::kSkDrawable_Type)); | |
284 REPORTER_ASSERT(r, out); | |
285 REPORTER_ASSERT(r, !strcmp("SkRecordedDrawable", out->getTypeName())); | |
286 | |
287 /* | |
288 * If we include SkRecordedDrawable.h and make all of the fields on | |
msarett
2016/03/30 20:34:11
I'll remove this code block before submitting.
I
| |
289 * SkRecordedDrawable public, the following tests should also pass. | |
290 */ | |
291 /* | |
292 SkRecordedDrawable* outRD = (SkRecordedDrawable*) out.get(); | |
293 SkRecordedDrawable* inRD = (SkRecordedDrawable*) recordedDrawable.get(); | |
294 REPORTER_ASSERT(r, outRD->fBounds == inRD->fBounds); | |
295 | |
296 REPORTER_ASSERT(r, outRD->fDrawableList->count() == 3); | |
297 REPORTER_ASSERT(r, outRD->fDrawableList->count() == inRD->fDrawableList->cou nt()); | |
298 SkDrawable* const* outArray = outRD->fDrawableList->begin(); | |
299 | |
300 // First the RootDrawable | |
301 REPORTER_ASSERT(r, !strcmp("RootDrawable", outArray[0]->getTypeName())); | |
302 RootDrawable* outRoot = (RootDrawable*) outArray[0]; | |
303 REPORTER_ASSERT(r, 5 == outRoot->compoundDrawable()->intDrawable()->a()); | |
304 REPORTER_ASSERT(r, 6 == outRoot->compoundDrawable()->intDrawable()->b()); | |
305 REPORTER_ASSERT(r, 7 == outRoot->compoundDrawable()->intDrawable()->c()); | |
306 REPORTER_ASSERT(r, 8 == outRoot->compoundDrawable()->intDrawable()->d()); | |
307 REPORTER_ASSERT(r, SK_ColorRED == | |
308 outRoot->compoundDrawable()->paintDrawable()->paint().getColor()); | |
309 REPORTER_ASSERT(r, 9 == outRoot->intDrawable()->a()); | |
310 REPORTER_ASSERT(r, 10 == outRoot->intDrawable()->b()); | |
311 REPORTER_ASSERT(r, 11 == outRoot->intDrawable()->c()); | |
312 REPORTER_ASSERT(r, 12 == outRoot->intDrawable()->d()); | |
313 SkDrawable* generic = outRoot->drawable(); | |
314 REPORTER_ASSERT(r, !strcmp("IntDrawable", generic->getTypeName())); | |
315 IntDrawable* integer = (IntDrawable*) generic; | |
316 REPORTER_ASSERT(r, 1 == integer->a()); | |
317 REPORTER_ASSERT(r, 2 == integer->b()); | |
318 REPORTER_ASSERT(r, 3 == integer->c()); | |
319 REPORTER_ASSERT(r, 4 == integer->d()); | |
320 | |
321 // Next the PaintDrawable | |
322 REPORTER_ASSERT(r, !strcmp("PaintDrawable", outArray[1]->getTypeName())); | |
323 PaintDrawable* outPaint = (PaintDrawable*) outArray[1]; | |
324 REPORTER_ASSERT(r, SK_ColorRED == outPaint->paint().getColor()); | |
325 | |
326 // Finally the CompoundDrawable | |
327 REPORTER_ASSERT(r, !strcmp("CompoundDrawable", outArray[2]->getTypeName())); | |
328 CompoundDrawable* outCompound = (CompoundDrawable*) outArray[2]; | |
329 REPORTER_ASSERT(r, 13 == outCompound->intDrawable()->a()); | |
330 REPORTER_ASSERT(r, 14 == outCompound->intDrawable()->b()); | |
331 REPORTER_ASSERT(r, 15 == outCompound->intDrawable()->c()); | |
332 REPORTER_ASSERT(r, 16 == outCompound->intDrawable()->d()); | |
333 REPORTER_ASSERT(r, SK_ColorBLUE == outCompound->paintDrawable()->paint().get Color()); | |
334 */ | |
335 } | |
OLD | NEW |