1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2016 Google Inc.
3*c8dee2aaSAndroid Build Coastguard Worker *
4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker */
7*c8dee2aaSAndroid Build Coastguard Worker
8*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkCanvas.h"
9*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColor.h"
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkData.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkDrawable.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkFlattenable.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkFont.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkImageFilter.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkMaskFilter.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPaint.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPictureRecorder.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRect.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRefCnt.h"
20*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypes.h"
21*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkPathEffectBase.h"
22*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkReadBuffer.h"
23*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkWriteBuffer.h"
24*c8dee2aaSAndroid Build Coastguard Worker #include "src/effects/colorfilters/SkColorFilterBase.h"
25*c8dee2aaSAndroid Build Coastguard Worker #include "src/shaders/SkShaderBase.h"
26*c8dee2aaSAndroid Build Coastguard Worker #include "tests/Test.h"
27*c8dee2aaSAndroid Build Coastguard Worker #include "tools/fonts/FontToolUtils.h"
28*c8dee2aaSAndroid Build Coastguard Worker
29*c8dee2aaSAndroid Build Coastguard Worker #include <cstdint>
30*c8dee2aaSAndroid Build Coastguard Worker #include <cstring>
31*c8dee2aaSAndroid Build Coastguard Worker
32*c8dee2aaSAndroid Build Coastguard Worker class IntDrawable : public SkDrawable {
33*c8dee2aaSAndroid Build Coastguard Worker public:
IntDrawable(uint32_t a,uint32_t b,uint32_t c,uint32_t d)34*c8dee2aaSAndroid Build Coastguard Worker IntDrawable(uint32_t a, uint32_t b, uint32_t c, uint32_t d)
35*c8dee2aaSAndroid Build Coastguard Worker : fA(a)
36*c8dee2aaSAndroid Build Coastguard Worker , fB(b)
37*c8dee2aaSAndroid Build Coastguard Worker , fC(c)
38*c8dee2aaSAndroid Build Coastguard Worker , fD(d)
39*c8dee2aaSAndroid Build Coastguard Worker {}
40*c8dee2aaSAndroid Build Coastguard Worker
flatten(SkWriteBuffer & buffer) const41*c8dee2aaSAndroid Build Coastguard Worker void flatten(SkWriteBuffer& buffer) const override {
42*c8dee2aaSAndroid Build Coastguard Worker buffer.writeUInt(fA);
43*c8dee2aaSAndroid Build Coastguard Worker buffer.writeUInt(fB);
44*c8dee2aaSAndroid Build Coastguard Worker buffer.writeUInt(fC);
45*c8dee2aaSAndroid Build Coastguard Worker buffer.writeUInt(fD);
46*c8dee2aaSAndroid Build Coastguard Worker }
47*c8dee2aaSAndroid Build Coastguard Worker
CreateProc(SkReadBuffer & buffer)48*c8dee2aaSAndroid Build Coastguard Worker static sk_sp<SkFlattenable> CreateProc(SkReadBuffer& buffer) {
49*c8dee2aaSAndroid Build Coastguard Worker uint32_t a = buffer.readUInt();
50*c8dee2aaSAndroid Build Coastguard Worker uint32_t b = buffer.readUInt();
51*c8dee2aaSAndroid Build Coastguard Worker uint32_t c = buffer.readUInt();
52*c8dee2aaSAndroid Build Coastguard Worker uint32_t d = buffer.readUInt();
53*c8dee2aaSAndroid Build Coastguard Worker return sk_sp<IntDrawable>(new IntDrawable(a, b, c, d));
54*c8dee2aaSAndroid Build Coastguard Worker }
55*c8dee2aaSAndroid Build Coastguard Worker
getFactory() const56*c8dee2aaSAndroid Build Coastguard Worker Factory getFactory() const override { return CreateProc; }
57*c8dee2aaSAndroid Build Coastguard Worker
a() const58*c8dee2aaSAndroid Build Coastguard Worker uint32_t a() const { return fA; }
b() const59*c8dee2aaSAndroid Build Coastguard Worker uint32_t b() const { return fB; }
c() const60*c8dee2aaSAndroid Build Coastguard Worker uint32_t c() const { return fC; }
d() const61*c8dee2aaSAndroid Build Coastguard Worker uint32_t d() const { return fD; }
62*c8dee2aaSAndroid Build Coastguard Worker
getTypeName() const63*c8dee2aaSAndroid Build Coastguard Worker const char* getTypeName() const override { return "IntDrawable"; }
64*c8dee2aaSAndroid Build Coastguard Worker
65*c8dee2aaSAndroid Build Coastguard Worker protected:
onGetBounds()66*c8dee2aaSAndroid Build Coastguard Worker SkRect onGetBounds() override { return SkRect::MakeEmpty(); }
onDraw(SkCanvas *)67*c8dee2aaSAndroid Build Coastguard Worker void onDraw(SkCanvas*) override {}
68*c8dee2aaSAndroid Build Coastguard Worker
69*c8dee2aaSAndroid Build Coastguard Worker private:
70*c8dee2aaSAndroid Build Coastguard Worker uint32_t fA;
71*c8dee2aaSAndroid Build Coastguard Worker uint32_t fB;
72*c8dee2aaSAndroid Build Coastguard Worker uint32_t fC;
73*c8dee2aaSAndroid Build Coastguard Worker uint32_t fD;
74*c8dee2aaSAndroid Build Coastguard Worker };
75*c8dee2aaSAndroid Build Coastguard Worker
76*c8dee2aaSAndroid Build Coastguard Worker class PaintDrawable : public SkDrawable {
77*c8dee2aaSAndroid Build Coastguard Worker public:
PaintDrawable(const SkPaint & paint)78*c8dee2aaSAndroid Build Coastguard Worker PaintDrawable(const SkPaint& paint)
79*c8dee2aaSAndroid Build Coastguard Worker : fPaint(paint)
80*c8dee2aaSAndroid Build Coastguard Worker {}
81*c8dee2aaSAndroid Build Coastguard Worker
flatten(SkWriteBuffer & buffer) const82*c8dee2aaSAndroid Build Coastguard Worker void flatten(SkWriteBuffer& buffer) const override {
83*c8dee2aaSAndroid Build Coastguard Worker buffer.writePaint(fPaint);
84*c8dee2aaSAndroid Build Coastguard Worker }
85*c8dee2aaSAndroid Build Coastguard Worker
CreateProc(SkReadBuffer & buffer)86*c8dee2aaSAndroid Build Coastguard Worker static sk_sp<SkFlattenable> CreateProc(SkReadBuffer& buffer) {
87*c8dee2aaSAndroid Build Coastguard Worker return sk_sp<PaintDrawable>(new PaintDrawable(buffer.readPaint()));
88*c8dee2aaSAndroid Build Coastguard Worker }
89*c8dee2aaSAndroid Build Coastguard Worker
getFactory() const90*c8dee2aaSAndroid Build Coastguard Worker Factory getFactory() const override { return CreateProc; }
91*c8dee2aaSAndroid Build Coastguard Worker
paint() const92*c8dee2aaSAndroid Build Coastguard Worker const SkPaint& paint() const { return fPaint; }
93*c8dee2aaSAndroid Build Coastguard Worker
getTypeName() const94*c8dee2aaSAndroid Build Coastguard Worker const char* getTypeName() const override { return "PaintDrawable"; }
95*c8dee2aaSAndroid Build Coastguard Worker
96*c8dee2aaSAndroid Build Coastguard Worker protected:
onGetBounds()97*c8dee2aaSAndroid Build Coastguard Worker SkRect onGetBounds() override { return SkRect::MakeEmpty(); }
onDraw(SkCanvas *)98*c8dee2aaSAndroid Build Coastguard Worker void onDraw(SkCanvas*) override {}
99*c8dee2aaSAndroid Build Coastguard Worker
100*c8dee2aaSAndroid Build Coastguard Worker private:
101*c8dee2aaSAndroid Build Coastguard Worker SkPaint fPaint;
102*c8dee2aaSAndroid Build Coastguard Worker };
103*c8dee2aaSAndroid Build Coastguard Worker
104*c8dee2aaSAndroid Build Coastguard Worker class CompoundDrawable : public SkDrawable {
105*c8dee2aaSAndroid Build Coastguard Worker public:
CompoundDrawable(uint32_t a,uint32_t b,uint32_t c,uint32_t d,const SkPaint & paint)106*c8dee2aaSAndroid Build Coastguard Worker CompoundDrawable(uint32_t a, uint32_t b, uint32_t c, uint32_t d, const SkPaint& paint)
107*c8dee2aaSAndroid Build Coastguard Worker : fIntDrawable(new IntDrawable(a, b, c, d))
108*c8dee2aaSAndroid Build Coastguard Worker , fPaintDrawable(new PaintDrawable(paint))
109*c8dee2aaSAndroid Build Coastguard Worker {}
110*c8dee2aaSAndroid Build Coastguard Worker
CompoundDrawable(IntDrawable * intDrawable,PaintDrawable * paintDrawable)111*c8dee2aaSAndroid Build Coastguard Worker CompoundDrawable(IntDrawable* intDrawable, PaintDrawable* paintDrawable)
112*c8dee2aaSAndroid Build Coastguard Worker : fIntDrawable(SkRef(intDrawable))
113*c8dee2aaSAndroid Build Coastguard Worker , fPaintDrawable(SkRef(paintDrawable))
114*c8dee2aaSAndroid Build Coastguard Worker {}
115*c8dee2aaSAndroid Build Coastguard Worker
flatten(SkWriteBuffer & buffer) const116*c8dee2aaSAndroid Build Coastguard Worker void flatten(SkWriteBuffer& buffer) const override {
117*c8dee2aaSAndroid Build Coastguard Worker buffer.writeFlattenable(fIntDrawable.get());
118*c8dee2aaSAndroid Build Coastguard Worker buffer.writeFlattenable(fPaintDrawable.get());
119*c8dee2aaSAndroid Build Coastguard Worker }
120*c8dee2aaSAndroid Build Coastguard Worker
CreateProc(SkReadBuffer & buffer)121*c8dee2aaSAndroid Build Coastguard Worker static sk_sp<SkFlattenable> CreateProc(SkReadBuffer& buffer) {
122*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkFlattenable> intDrawable(
123*c8dee2aaSAndroid Build Coastguard Worker buffer.readFlattenable(SkFlattenable::kSkDrawable_Type));
124*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(intDrawable);
125*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(!strcmp("IntDrawable", intDrawable->getTypeName()));
126*c8dee2aaSAndroid Build Coastguard Worker
127*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkFlattenable> paintDrawable(
128*c8dee2aaSAndroid Build Coastguard Worker buffer.readFlattenable(SkFlattenable::kSkDrawable_Type));
129*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(paintDrawable);
130*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(!strcmp("PaintDrawable", paintDrawable->getTypeName()));
131*c8dee2aaSAndroid Build Coastguard Worker
132*c8dee2aaSAndroid Build Coastguard Worker return sk_sp<CompoundDrawable>(new CompoundDrawable((IntDrawable*) intDrawable.get(),
133*c8dee2aaSAndroid Build Coastguard Worker (PaintDrawable*) paintDrawable.get()));
134*c8dee2aaSAndroid Build Coastguard Worker }
135*c8dee2aaSAndroid Build Coastguard Worker
getFactory() const136*c8dee2aaSAndroid Build Coastguard Worker Factory getFactory() const override { return CreateProc; }
137*c8dee2aaSAndroid Build Coastguard Worker
intDrawable() const138*c8dee2aaSAndroid Build Coastguard Worker IntDrawable* intDrawable() const { return fIntDrawable.get(); }
paintDrawable() const139*c8dee2aaSAndroid Build Coastguard Worker PaintDrawable* paintDrawable() const { return fPaintDrawable.get(); }
140*c8dee2aaSAndroid Build Coastguard Worker
getTypeName() const141*c8dee2aaSAndroid Build Coastguard Worker const char* getTypeName() const override { return "CompoundDrawable"; }
142*c8dee2aaSAndroid Build Coastguard Worker
143*c8dee2aaSAndroid Build Coastguard Worker protected:
onGetBounds()144*c8dee2aaSAndroid Build Coastguard Worker SkRect onGetBounds() override { return SkRect::MakeEmpty(); }
onDraw(SkCanvas *)145*c8dee2aaSAndroid Build Coastguard Worker void onDraw(SkCanvas*) override {}
146*c8dee2aaSAndroid Build Coastguard Worker
147*c8dee2aaSAndroid Build Coastguard Worker private:
148*c8dee2aaSAndroid Build Coastguard Worker sk_sp<IntDrawable> fIntDrawable;
149*c8dee2aaSAndroid Build Coastguard Worker sk_sp<PaintDrawable> fPaintDrawable;
150*c8dee2aaSAndroid Build Coastguard Worker };
151*c8dee2aaSAndroid Build Coastguard Worker
152*c8dee2aaSAndroid Build Coastguard Worker class RootDrawable : public SkDrawable {
153*c8dee2aaSAndroid Build Coastguard Worker public:
RootDrawable(uint32_t a,uint32_t b,uint32_t c,uint32_t d,const SkPaint & paint,uint32_t e,uint32_t f,uint32_t g,uint32_t h,SkDrawable * drawable)154*c8dee2aaSAndroid Build Coastguard Worker RootDrawable(uint32_t a, uint32_t b, uint32_t c, uint32_t d, const SkPaint& paint,
155*c8dee2aaSAndroid Build Coastguard Worker uint32_t e, uint32_t f, uint32_t g, uint32_t h, SkDrawable* drawable)
156*c8dee2aaSAndroid Build Coastguard Worker : fCompoundDrawable(new CompoundDrawable(a, b, c, d, paint))
157*c8dee2aaSAndroid Build Coastguard Worker , fIntDrawable(new IntDrawable(e, f, g, h))
158*c8dee2aaSAndroid Build Coastguard Worker , fDrawable(SkRef(drawable))
159*c8dee2aaSAndroid Build Coastguard Worker {}
160*c8dee2aaSAndroid Build Coastguard Worker
RootDrawable(CompoundDrawable * compoundDrawable,IntDrawable * intDrawable,SkDrawable * drawable)161*c8dee2aaSAndroid Build Coastguard Worker RootDrawable(CompoundDrawable* compoundDrawable, IntDrawable* intDrawable,
162*c8dee2aaSAndroid Build Coastguard Worker SkDrawable* drawable)
163*c8dee2aaSAndroid Build Coastguard Worker : fCompoundDrawable(SkRef(compoundDrawable))
164*c8dee2aaSAndroid Build Coastguard Worker , fIntDrawable(SkRef(intDrawable))
165*c8dee2aaSAndroid Build Coastguard Worker , fDrawable(SkRef(drawable))
166*c8dee2aaSAndroid Build Coastguard Worker {}
167*c8dee2aaSAndroid Build Coastguard Worker
flatten(SkWriteBuffer & buffer) const168*c8dee2aaSAndroid Build Coastguard Worker void flatten(SkWriteBuffer& buffer) const override {
169*c8dee2aaSAndroid Build Coastguard Worker buffer.writeFlattenable(fCompoundDrawable.get());
170*c8dee2aaSAndroid Build Coastguard Worker buffer.writeFlattenable(fIntDrawable.get());
171*c8dee2aaSAndroid Build Coastguard Worker buffer.writeFlattenable(fDrawable.get());
172*c8dee2aaSAndroid Build Coastguard Worker }
173*c8dee2aaSAndroid Build Coastguard Worker
CreateProc(SkReadBuffer & buffer)174*c8dee2aaSAndroid Build Coastguard Worker static sk_sp<SkFlattenable> CreateProc(SkReadBuffer& buffer) {
175*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkFlattenable> compoundDrawable(
176*c8dee2aaSAndroid Build Coastguard Worker buffer.readFlattenable(SkFlattenable::kSkDrawable_Type));
177*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(compoundDrawable);
178*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(!strcmp("CompoundDrawable", compoundDrawable->getTypeName()));
179*c8dee2aaSAndroid Build Coastguard Worker
180*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkFlattenable> intDrawable(
181*c8dee2aaSAndroid Build Coastguard Worker buffer.readFlattenable(SkFlattenable::kSkDrawable_Type));
182*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(intDrawable);
183*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(!strcmp("IntDrawable", intDrawable->getTypeName()));
184*c8dee2aaSAndroid Build Coastguard Worker
185*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkFlattenable> drawable(
186*c8dee2aaSAndroid Build Coastguard Worker buffer.readFlattenable(SkFlattenable::kSkDrawable_Type));
187*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(drawable);
188*c8dee2aaSAndroid Build Coastguard Worker
189*c8dee2aaSAndroid Build Coastguard Worker return sk_sp<RootDrawable>(new RootDrawable((CompoundDrawable*) compoundDrawable.get(),
190*c8dee2aaSAndroid Build Coastguard Worker (IntDrawable*) intDrawable.get(),
191*c8dee2aaSAndroid Build Coastguard Worker (SkDrawable*) drawable.get()));
192*c8dee2aaSAndroid Build Coastguard Worker }
193*c8dee2aaSAndroid Build Coastguard Worker
getFactory() const194*c8dee2aaSAndroid Build Coastguard Worker Factory getFactory() const override { return CreateProc; }
195*c8dee2aaSAndroid Build Coastguard Worker
compoundDrawable() const196*c8dee2aaSAndroid Build Coastguard Worker CompoundDrawable* compoundDrawable() const { return fCompoundDrawable.get(); }
intDrawable() const197*c8dee2aaSAndroid Build Coastguard Worker IntDrawable* intDrawable() const { return fIntDrawable.get(); }
drawable() const198*c8dee2aaSAndroid Build Coastguard Worker SkDrawable* drawable() const { return fDrawable.get(); }
199*c8dee2aaSAndroid Build Coastguard Worker
getTypeName() const200*c8dee2aaSAndroid Build Coastguard Worker const char* getTypeName() const override { return "RootDrawable"; }
201*c8dee2aaSAndroid Build Coastguard Worker
202*c8dee2aaSAndroid Build Coastguard Worker protected:
onGetBounds()203*c8dee2aaSAndroid Build Coastguard Worker SkRect onGetBounds() override { return SkRect::MakeEmpty(); }
onDraw(SkCanvas *)204*c8dee2aaSAndroid Build Coastguard Worker void onDraw(SkCanvas*) override {}
205*c8dee2aaSAndroid Build Coastguard Worker
206*c8dee2aaSAndroid Build Coastguard Worker private:
207*c8dee2aaSAndroid Build Coastguard Worker sk_sp<CompoundDrawable> fCompoundDrawable;
208*c8dee2aaSAndroid Build Coastguard Worker sk_sp<IntDrawable> fIntDrawable;
209*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkDrawable> fDrawable;
210*c8dee2aaSAndroid Build Coastguard Worker };
211*c8dee2aaSAndroid Build Coastguard Worker
212*c8dee2aaSAndroid Build Coastguard Worker // Register these drawables for deserialization some time before main().
213*c8dee2aaSAndroid Build Coastguard Worker static struct Initializer {
InitializerInitializer214*c8dee2aaSAndroid Build Coastguard Worker Initializer() {
215*c8dee2aaSAndroid Build Coastguard Worker SK_REGISTER_FLATTENABLE(IntDrawable);
216*c8dee2aaSAndroid Build Coastguard Worker SK_REGISTER_FLATTENABLE(PaintDrawable);
217*c8dee2aaSAndroid Build Coastguard Worker SK_REGISTER_FLATTENABLE(CompoundDrawable);
218*c8dee2aaSAndroid Build Coastguard Worker SK_REGISTER_FLATTENABLE(RootDrawable);
219*c8dee2aaSAndroid Build Coastguard Worker }
220*c8dee2aaSAndroid Build Coastguard Worker } initializer;
221*c8dee2aaSAndroid Build Coastguard Worker
DEF_TEST(FlattenDrawable,r)222*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(FlattenDrawable, r) {
223*c8dee2aaSAndroid Build Coastguard Worker // Create and serialize the test drawable
224*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkDrawable> drawable(new IntDrawable(1, 2, 3, 4));
225*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint;
226*c8dee2aaSAndroid Build Coastguard Worker paint.setColor(SK_ColorBLUE);
227*c8dee2aaSAndroid Build Coastguard Worker sk_sp<RootDrawable> root(new RootDrawable(5, 6, 7, 8, paint, 9, 10, 11, 12, drawable.get()));
228*c8dee2aaSAndroid Build Coastguard Worker SkBinaryWriteBuffer writeBuffer({});
229*c8dee2aaSAndroid Build Coastguard Worker writeBuffer.writeFlattenable(root.get());
230*c8dee2aaSAndroid Build Coastguard Worker
231*c8dee2aaSAndroid Build Coastguard Worker // Copy the contents of the write buffer into a read buffer
232*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkData> data = SkData::MakeUninitialized(writeBuffer.bytesWritten());
233*c8dee2aaSAndroid Build Coastguard Worker writeBuffer.writeToMemory(data->writable_data());
234*c8dee2aaSAndroid Build Coastguard Worker SkReadBuffer readBuffer(data->data(), data->size());
235*c8dee2aaSAndroid Build Coastguard Worker
236*c8dee2aaSAndroid Build Coastguard Worker // Deserialize and verify the drawable
237*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkDrawable> out((SkDrawable*)readBuffer.readFlattenable(SkFlattenable::kSkDrawable_Type));
238*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(r, out);
239*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(r, !strcmp("RootDrawable", out->getTypeName()));
240*c8dee2aaSAndroid Build Coastguard Worker
241*c8dee2aaSAndroid Build Coastguard Worker RootDrawable* rootOut = (RootDrawable*) out.get();
242*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(r, 5 == rootOut->compoundDrawable()->intDrawable()->a());
243*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(r, 6 == rootOut->compoundDrawable()->intDrawable()->b());
244*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(r, 7 == rootOut->compoundDrawable()->intDrawable()->c());
245*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(r, 8 == rootOut->compoundDrawable()->intDrawable()->d());
246*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(r, SK_ColorBLUE ==
247*c8dee2aaSAndroid Build Coastguard Worker rootOut->compoundDrawable()->paintDrawable()->paint().getColor());
248*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(r, 9 == rootOut->intDrawable()->a());
249*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(r, 10 == rootOut->intDrawable()->b());
250*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(r, 11 == rootOut->intDrawable()->c());
251*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(r, 12 == rootOut->intDrawable()->d());
252*c8dee2aaSAndroid Build Coastguard Worker
253*c8dee2aaSAndroid Build Coastguard Worker // Note that we can still recognize the generic drawable as an IntDrawable
254*c8dee2aaSAndroid Build Coastguard Worker SkDrawable* generic = rootOut->drawable();
255*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(r, !strcmp("IntDrawable", generic->getTypeName()));
256*c8dee2aaSAndroid Build Coastguard Worker IntDrawable* integer = (IntDrawable*) generic;
257*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(r, 1 == integer->a());
258*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(r, 2 == integer->b());
259*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(r, 3 == integer->c());
260*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(r, 4 == integer->d());
261*c8dee2aaSAndroid Build Coastguard Worker }
262*c8dee2aaSAndroid Build Coastguard Worker
DEF_TEST(FlattenRecordedDrawable,r)263*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(FlattenRecordedDrawable, r) {
264*c8dee2aaSAndroid Build Coastguard Worker // Record a set of canvas draw commands
265*c8dee2aaSAndroid Build Coastguard Worker SkPictureRecorder recorder;
266*c8dee2aaSAndroid Build Coastguard Worker SkCanvas* canvas = recorder.beginRecording(1000.0f, 1000.0f);
267*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint;
268*c8dee2aaSAndroid Build Coastguard Worker paint.setColor(SK_ColorGREEN);
269*c8dee2aaSAndroid Build Coastguard Worker canvas->drawPoint(42.0f, 17.0f, paint);
270*c8dee2aaSAndroid Build Coastguard Worker paint.setColor(SK_ColorRED);
271*c8dee2aaSAndroid Build Coastguard Worker canvas->drawPaint(paint);
272*c8dee2aaSAndroid Build Coastguard Worker SkPaint textPaint;
273*c8dee2aaSAndroid Build Coastguard Worker textPaint.setColor(SK_ColorBLUE);
274*c8dee2aaSAndroid Build Coastguard Worker canvas->drawString("TEXT", 467.0f, 100.0f, ToolUtils::DefaultFont(), textPaint);
275*c8dee2aaSAndroid Build Coastguard Worker
276*c8dee2aaSAndroid Build Coastguard Worker // Draw some drawables as well
277*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkDrawable> drawable(new IntDrawable(1, 2, 3, 4));
278*c8dee2aaSAndroid Build Coastguard Worker sk_sp<RootDrawable> root(new RootDrawable(5, 6, 7, 8, paint, 9, 10, 11, 12, drawable.get()));
279*c8dee2aaSAndroid Build Coastguard Worker canvas->drawDrawable(root.get(), 747.0f, 242.0f);
280*c8dee2aaSAndroid Build Coastguard Worker sk_sp<PaintDrawable> paintDrawable(new PaintDrawable(paint));
281*c8dee2aaSAndroid Build Coastguard Worker canvas->drawDrawable(paintDrawable.get(), 500.0, 500.0f);
282*c8dee2aaSAndroid Build Coastguard Worker sk_sp<CompoundDrawable> comDrawable(new CompoundDrawable(13, 14, 15, 16, textPaint));
283*c8dee2aaSAndroid Build Coastguard Worker canvas->drawDrawable(comDrawable.get(), 10.0f, 10.0f);
284*c8dee2aaSAndroid Build Coastguard Worker
285*c8dee2aaSAndroid Build Coastguard Worker // Serialize the recorded drawable
286*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkDrawable> recordedDrawable = recorder.finishRecordingAsDrawable();
287*c8dee2aaSAndroid Build Coastguard Worker SkBinaryWriteBuffer writeBuffer({});
288*c8dee2aaSAndroid Build Coastguard Worker writeBuffer.writeFlattenable(recordedDrawable.get());
289*c8dee2aaSAndroid Build Coastguard Worker
290*c8dee2aaSAndroid Build Coastguard Worker // Copy the contents of the write buffer into a read buffer
291*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkData> data = SkData::MakeUninitialized(writeBuffer.bytesWritten());
292*c8dee2aaSAndroid Build Coastguard Worker writeBuffer.writeToMemory(data->writable_data());
293*c8dee2aaSAndroid Build Coastguard Worker SkReadBuffer readBuffer(data->data(), data->size());
294*c8dee2aaSAndroid Build Coastguard Worker
295*c8dee2aaSAndroid Build Coastguard Worker // Deserialize and verify the drawable
296*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkDrawable> out((SkDrawable*)readBuffer.readFlattenable(SkFlattenable::kSkDrawable_Type));
297*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(r, out);
298*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(r, !strcmp("SkRecordedDrawable", out->getTypeName()));
299*c8dee2aaSAndroid Build Coastguard Worker }
300*c8dee2aaSAndroid Build Coastguard Worker
301*c8dee2aaSAndroid Build Coastguard Worker // be sure these constructs compile, don't assert, and return null
DEF_TEST(Flattenable_EmptyDeserialze,reporter)302*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(Flattenable_EmptyDeserialze, reporter) {
303*c8dee2aaSAndroid Build Coastguard Worker auto data = SkData::MakeEmpty();
304*c8dee2aaSAndroid Build Coastguard Worker
305*c8dee2aaSAndroid Build Coastguard Worker #define test(name) REPORTER_ASSERT(reporter, !name::Deserialize(data->data(), data->size()))
306*c8dee2aaSAndroid Build Coastguard Worker test(SkPathEffectBase);
307*c8dee2aaSAndroid Build Coastguard Worker test(SkMaskFilter);
308*c8dee2aaSAndroid Build Coastguard Worker test(SkShaderBase); // todo: make this just be shader!
309*c8dee2aaSAndroid Build Coastguard Worker test(SkColorFilterBase);
310*c8dee2aaSAndroid Build Coastguard Worker test(SkImageFilter);
311*c8dee2aaSAndroid Build Coastguard Worker #undef test
312*c8dee2aaSAndroid Build Coastguard Worker }
313*c8dee2aaSAndroid Build Coastguard Worker
314