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 sk_sp<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 sk_sp<IntDrawable>(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 const char* getTypeName() const override { return "IntDrawable"; } |
| 50 |
| 51 protected: |
| 52 SkRect onGetBounds() override { return SkRect::MakeEmpty(); } |
| 53 void onDraw(SkCanvas*) override {} |
| 54 |
| 55 private: |
| 56 uint32_t fA; |
| 57 uint32_t fB; |
| 58 uint32_t fC; |
| 59 uint32_t fD; |
| 60 }; |
| 61 |
| 62 class PaintDrawable : public SkDrawable { |
| 63 public: |
| 64 PaintDrawable(const SkPaint& paint) |
| 65 : fPaint(paint) |
| 66 {} |
| 67 |
| 68 void flatten(SkWriteBuffer& buffer) const override { |
| 69 buffer.writePaint(fPaint); |
| 70 } |
| 71 |
| 72 static sk_sp<SkFlattenable> CreateProc(SkReadBuffer& buffer) { |
| 73 SkPaint paint; |
| 74 buffer.readPaint(&paint); |
| 75 return sk_sp<PaintDrawable>(new PaintDrawable(paint)); |
| 76 } |
| 77 |
| 78 Factory getFactory() const override { return CreateProc; } |
| 79 |
| 80 const SkPaint& paint() const { return fPaint; } |
| 81 |
| 82 protected: |
| 83 SkRect onGetBounds() override { return SkRect::MakeEmpty(); } |
| 84 void onDraw(SkCanvas*) override {} |
| 85 |
| 86 private: |
| 87 SkPaint fPaint; |
| 88 }; |
| 89 |
| 90 class CompoundDrawable : public SkDrawable { |
| 91 public: |
| 92 CompoundDrawable(uint32_t a, uint32_t b, uint32_t c, uint32_t d, const SkPai
nt& paint) |
| 93 : fIntDrawable(new IntDrawable(a, b, c, d)) |
| 94 , fPaintDrawable(new PaintDrawable(paint)) |
| 95 {} |
| 96 |
| 97 CompoundDrawable(IntDrawable* intDrawable, PaintDrawable* paintDrawable) |
| 98 : fIntDrawable(SkRef(intDrawable)) |
| 99 , fPaintDrawable(SkRef(paintDrawable)) |
| 100 {} |
| 101 |
| 102 void flatten(SkWriteBuffer& buffer) const override { |
| 103 buffer.writeFlattenable(fIntDrawable); |
| 104 buffer.writeFlattenable(fPaintDrawable); |
| 105 } |
| 106 |
| 107 static sk_sp<SkFlattenable> CreateProc(SkReadBuffer& buffer) { |
| 108 SkAutoTUnref<SkFlattenable> intDrawable( |
| 109 buffer.readFlattenable(SkFlattenable::kSkDrawable_Type)); |
| 110 SkASSERT(intDrawable); |
| 111 SkASSERT(!strcmp("IntDrawable", intDrawable->getTypeName())); |
| 112 |
| 113 SkAutoTUnref<SkFlattenable> paintDrawable( |
| 114 buffer.readFlattenable(SkFlattenable::kSkDrawable_Type)); |
| 115 SkASSERT(paintDrawable); |
| 116 SkASSERT(!strcmp("PaintDrawable", paintDrawable->getTypeName())); |
| 117 |
| 118 return sk_sp<CompoundDrawable>(new CompoundDrawable((IntDrawable*) intDr
awable.get(), |
| 119 (PaintDrawable*) pai
ntDrawable.get())); |
| 120 } |
| 121 |
| 122 Factory getFactory() const override { return CreateProc; } |
| 123 |
| 124 IntDrawable* intDrawable() const { return fIntDrawable; } |
| 125 PaintDrawable* paintDrawable() const { return fPaintDrawable; } |
| 126 |
| 127 protected: |
| 128 SkRect onGetBounds() override { return SkRect::MakeEmpty(); } |
| 129 void onDraw(SkCanvas*) override {} |
| 130 |
| 131 private: |
| 132 SkAutoTUnref<IntDrawable> fIntDrawable; |
| 133 SkAutoTUnref<PaintDrawable> fPaintDrawable; |
| 134 }; |
| 135 |
| 136 class RootDrawable : public SkDrawable { |
| 137 public: |
| 138 RootDrawable(uint32_t a, uint32_t b, uint32_t c, uint32_t d, const SkPaint&
paint, |
| 139 uint32_t e, uint32_t f, uint32_t g, uint32_t h, SkDrawable* d
rawable) |
| 140 : fCompoundDrawable(new CompoundDrawable(a, b, c, d, paint)) |
| 141 , fIntDrawable(new IntDrawable(e, f, g, h)) |
| 142 , fDrawable(SkRef(drawable)) |
| 143 {} |
| 144 |
| 145 RootDrawable(CompoundDrawable* compoundDrawable, IntDrawable* intDrawable, |
| 146 SkDrawable* drawable) |
| 147 : fCompoundDrawable(SkRef(compoundDrawable)) |
| 148 , fIntDrawable(SkRef(intDrawable)) |
| 149 , fDrawable(SkRef(drawable)) |
| 150 {} |
| 151 |
| 152 void flatten(SkWriteBuffer& buffer) const override { |
| 153 buffer.writeFlattenable(fCompoundDrawable); |
| 154 buffer.writeFlattenable(fIntDrawable); |
| 155 buffer.writeFlattenable(fDrawable); |
| 156 } |
| 157 |
| 158 static sk_sp<SkFlattenable> CreateProc(SkReadBuffer& buffer) { |
| 159 SkAutoTUnref<SkFlattenable> compoundDrawable( |
| 160 buffer.readFlattenable(SkFlattenable::kSkDrawable_Type)); |
| 161 SkASSERT(compoundDrawable); |
| 162 SkASSERT(!strcmp("CompoundDrawable", compoundDrawable->getTypeName())); |
| 163 |
| 164 SkAutoTUnref<SkFlattenable> intDrawable( |
| 165 buffer.readFlattenable(SkFlattenable::kSkDrawable_Type)); |
| 166 SkASSERT(intDrawable); |
| 167 SkASSERT(!strcmp("IntDrawable", intDrawable->getTypeName())); |
| 168 |
| 169 SkAutoTUnref<SkFlattenable> drawable( |
| 170 buffer.readFlattenable(SkFlattenable::kSkDrawable_Type)); |
| 171 SkASSERT(drawable); |
| 172 |
| 173 return sk_sp<RootDrawable>(new RootDrawable((CompoundDrawable*) compound
Drawable.get(), |
| 174 (IntDrawable*) intDrawable.g
et(), |
| 175 (SkDrawable*) drawable.get()
)); |
| 176 } |
| 177 |
| 178 Factory getFactory() const override { return CreateProc; } |
| 179 |
| 180 CompoundDrawable* compoundDrawable() const { return fCompoundDrawable; } |
| 181 IntDrawable* intDrawable() const { return fIntDrawable; } |
| 182 SkDrawable* drawable() const { return fDrawable; } |
| 183 |
| 184 protected: |
| 185 SkRect onGetBounds() override { return SkRect::MakeEmpty(); } |
| 186 void onDraw(SkCanvas*) override {} |
| 187 |
| 188 private: |
| 189 SkAutoTUnref<CompoundDrawable> fCompoundDrawable; |
| 190 SkAutoTUnref<IntDrawable> fIntDrawable; |
| 191 SkAutoTUnref<SkDrawable> fDrawable; |
| 192 }; |
| 193 |
| 194 static void register_test_drawables() { |
| 195 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(IntDrawable) |
| 196 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(PaintDrawable) |
| 197 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(CompoundDrawable) |
| 198 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(RootDrawable) |
| 199 } |
| 200 |
| 201 static void register_test_drawables_once() { |
| 202 static SkOnce once; |
| 203 once(register_test_drawables); |
| 204 } |
| 205 |
| 206 DEF_TEST(FlattenDrawable, r) { |
| 207 register_test_drawables_once(); |
| 208 |
| 209 // Create and serialize the test drawable |
| 210 SkAutoTUnref<SkDrawable> drawable(new IntDrawable(1, 2, 3, 4)); |
| 211 SkPaint paint; |
| 212 paint.setColor(SK_ColorBLUE); |
| 213 SkAutoTUnref<RootDrawable> root(new RootDrawable(5, 6, 7, 8, paint, 9, 10, 1
1, 12, drawable)); |
| 214 SkWriteBuffer writeBuffer; |
| 215 writeBuffer.writeFlattenable(root); |
| 216 |
| 217 // Copy the contents of the write buffer into a read buffer |
| 218 sk_sp<SkData> data = SkData::MakeUninitialized(writeBuffer.bytesWritten()); |
| 219 writeBuffer.writeToMemory(data->writable_data()); |
| 220 SkReadBuffer readBuffer(data->data(), data->size()); |
| 221 |
| 222 // Deserialize and verify the drawable |
| 223 SkAutoTUnref<SkDrawable> out((SkDrawable*) |
| 224 readBuffer.readFlattenable(SkFlattenable::kSkDrawable_Type)); |
| 225 REPORTER_ASSERT(r, out); |
| 226 REPORTER_ASSERT(r, !strcmp("RootDrawable", out->getTypeName())); |
| 227 |
| 228 RootDrawable* rootOut = (RootDrawable*) out.get(); |
| 229 REPORTER_ASSERT(r, 5 == rootOut->compoundDrawable()->intDrawable()->a()); |
| 230 REPORTER_ASSERT(r, 6 == rootOut->compoundDrawable()->intDrawable()->b()); |
| 231 REPORTER_ASSERT(r, 7 == rootOut->compoundDrawable()->intDrawable()->c()); |
| 232 REPORTER_ASSERT(r, 8 == rootOut->compoundDrawable()->intDrawable()->d()); |
| 233 REPORTER_ASSERT(r, SK_ColorBLUE == |
| 234 rootOut->compoundDrawable()->paintDrawable()->paint().getColor()); |
| 235 REPORTER_ASSERT(r, 9 == rootOut->intDrawable()->a()); |
| 236 REPORTER_ASSERT(r, 10 == rootOut->intDrawable()->b()); |
| 237 REPORTER_ASSERT(r, 11 == rootOut->intDrawable()->c()); |
| 238 REPORTER_ASSERT(r, 12 == rootOut->intDrawable()->d()); |
| 239 |
| 240 // Note that we can still recognize the generic drawable as an IntDrawable |
| 241 SkDrawable* generic = rootOut->drawable(); |
| 242 REPORTER_ASSERT(r, !strcmp("IntDrawable", generic->getTypeName())); |
| 243 IntDrawable* integer = (IntDrawable*) generic; |
| 244 REPORTER_ASSERT(r, 1 == integer->a()); |
| 245 REPORTER_ASSERT(r, 2 == integer->b()); |
| 246 REPORTER_ASSERT(r, 3 == integer->c()); |
| 247 REPORTER_ASSERT(r, 4 == integer->d()); |
| 248 } |
| 249 |
| 250 DEF_TEST(FlattenRecordedDrawable, r) { |
| 251 register_test_drawables_once(); |
| 252 |
| 253 // Record a set of canvas draw commands |
| 254 SkPictureRecorder recorder; |
| 255 SkCanvas* canvas = recorder.beginRecording(1000.0f, 1000.0f); |
| 256 canvas->drawPoint(42.0f, 17.0f, SK_ColorGREEN); |
| 257 SkPaint paint; |
| 258 paint.setColor(SK_ColorRED); |
| 259 canvas->drawPaint(paint); |
| 260 SkPaint textPaint; |
| 261 textPaint.setColor(SK_ColorBLUE); |
| 262 canvas->drawText("TEXT", 354.0f, 467.0f, 100.0f, textPaint); |
| 263 |
| 264 // Draw some drawables as well |
| 265 SkAutoTUnref<SkDrawable> drawable(new IntDrawable(1, 2, 3, 4)); |
| 266 SkAutoTUnref<RootDrawable> root(new RootDrawable(5, 6, 7, 8, paint, 9, 10, 1
1, 12, drawable)); |
| 267 canvas->drawDrawable(root, 747.0f, 242.0f); |
| 268 SkAutoTUnref<PaintDrawable> paintDrawable(new PaintDrawable(paint)); |
| 269 canvas->drawDrawable(paintDrawable, 500.0, 500.0f); |
| 270 SkAutoTUnref<CompoundDrawable> comDrawable(new CompoundDrawable(13, 14, 15,
16, textPaint)); |
| 271 canvas->drawDrawable(comDrawable, 10.0f, 10.0f); |
| 272 |
| 273 // Serialize the recorded drawable |
| 274 sk_sp<SkDrawable> recordedDrawable = recorder.finishRecordingAsDrawable(); |
| 275 SkWriteBuffer writeBuffer; |
| 276 writeBuffer.writeFlattenable(recordedDrawable.get()); |
| 277 |
| 278 // Copy the contents of the write buffer into a read buffer |
| 279 sk_sp<SkData> data = SkData::MakeUninitialized(writeBuffer.bytesWritten()); |
| 280 writeBuffer.writeToMemory(data->writable_data()); |
| 281 SkReadBuffer readBuffer(data->data(), data->size()); |
| 282 |
| 283 // Deserialize and verify the drawable |
| 284 SkAutoTUnref<SkDrawable> out((SkDrawable*) |
| 285 readBuffer.readFlattenable(SkFlattenable::kSkDrawable_Type)); |
| 286 REPORTER_ASSERT(r, out); |
| 287 REPORTER_ASSERT(r, !strcmp("SkRecordedDrawable", out->getTypeName())); |
| 288 } |
| 289 |
| 290 static sk_sp<SkFlattenable> custom_create_proc(SkReadBuffer& buffer) { |
| 291 sk_sp<SkFlattenable> drawable = IntDrawable::CreateProc(buffer); |
| 292 IntDrawable* intDrawable = (IntDrawable*) drawable.get(); |
| 293 return sk_sp<IntDrawable>(new IntDrawable(intDrawable->a() + 1, intDrawable-
>b() + 1, |
| 294 intDrawable->c() + 1, intDrawable-
>d() + 1)); |
| 295 } |
| 296 |
| 297 DEF_TEST(FlattenCustomDrawable, r) { |
| 298 // No need to register the drawables since we will be using a custom proc. |
| 299 |
| 300 // Create and serialize the test drawable |
| 301 SkAutoTUnref<SkDrawable> drawable(new IntDrawable(1, 2, 3, 4)); |
| 302 SkWriteBuffer writeBuffer; |
| 303 writeBuffer.writeFlattenable(drawable); |
| 304 |
| 305 // Copy the contents of the write buffer into a read buffer |
| 306 sk_sp<SkData> data = SkData::MakeUninitialized(writeBuffer.bytesWritten()); |
| 307 writeBuffer.writeToMemory(data->writable_data()); |
| 308 SkReadBuffer readBuffer(data->data(), data->size()); |
| 309 |
| 310 // Register a custom factory with the read buffer |
| 311 readBuffer.setCustomFactory(SkString("IntDrawable"), &custom_create_proc); |
| 312 |
| 313 // Deserialize and verify the drawable |
| 314 SkAutoTUnref<IntDrawable> out((IntDrawable*) |
| 315 readBuffer.readFlattenable(SkFlattenable::kSkDrawable_Type)); |
| 316 REPORTER_ASSERT(r, out); |
| 317 REPORTER_ASSERT(r, 2 == out->a()); |
| 318 REPORTER_ASSERT(r, 3 == out->b()); |
| 319 REPORTER_ASSERT(r, 4 == out->c()); |
| 320 REPORTER_ASSERT(r, 5 == out->d()); |
| 321 } |
OLD | NEW |