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