1 /* 2 * Copyright 2013 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 "Test.h" 9 #include "TestClassDef.h" 10 #include "SkBitmap.h" 11 #include "SkBitmapDevice.h" 12 #include "SkCanvas.h" 13 #include "SkDraw.h" 14 #include "SkLayerDrawLooper.h" 15 #include "SkMatrix.h" 16 #include "SkPaint.h" 17 #include "SkRect.h" 18 #include "SkRefCnt.h" 19 #include "SkScalar.h" 20 #include "SkXfermode.h" 21 22 class FakeDevice : public SkBitmapDevice { 23 public: 24 FakeDevice() : SkBitmapDevice(SkBitmap::kARGB_8888_Config, 100, 100, false) { } 25 26 virtual void drawRect(const SkDraw& draw, const SkRect& r, 27 const SkPaint& paint) SK_OVERRIDE { 28 fLastMatrix = *draw.fMatrix; 29 INHERITED::drawRect(draw, r, paint); 30 } 31 32 SkMatrix fLastMatrix; 33 34 private: 35 typedef SkBitmapDevice INHERITED; 36 }; 37 38 static void test_frontToBack(skiatest::Reporter* reporter) { 39 SkAutoTUnref<SkLayerDrawLooper> looper(SkNEW(SkLayerDrawLooper)); 40 SkLayerDrawLooper::LayerInfo layerInfo; 41 42 // Add the front layer, with the defaults. 43 (void)looper->addLayer(layerInfo); 44 45 // Add the back layer, with some layer info set. 46 layerInfo.fOffset.set(10.0f, 20.0f); 47 layerInfo.fPaintBits |= SkLayerDrawLooper::kXfermode_Bit; 48 SkPaint* layerPaint = looper->addLayer(layerInfo); 49 layerPaint->setXfermodeMode(SkXfermode::kSrc_Mode); 50 51 FakeDevice device; 52 SkCanvas canvas(&device); 53 SkPaint paint; 54 looper->init(&canvas); 55 56 // The back layer should come first. 57 REPORTER_ASSERT(reporter, looper->next(&canvas, &paint)); 58 REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrc_Mode)); 59 canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint); 60 REPORTER_ASSERT(reporter, 10.0f == device.fLastMatrix.getTranslateX()); 61 REPORTER_ASSERT(reporter, 20.0f == device.fLastMatrix.getTranslateY()); 62 paint.reset(); 63 64 // Then the front layer. 65 REPORTER_ASSERT(reporter, looper->next(&canvas, &paint)); 66 REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode)); 67 canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint); 68 REPORTER_ASSERT(reporter, 0.0f == device.fLastMatrix.getTranslateX()); 69 REPORTER_ASSERT(reporter, 0.0f == device.fLastMatrix.getTranslateY()); 70 71 // Only two layers were added, so that should be the end. 72 REPORTER_ASSERT(reporter, !looper->next(&canvas, &paint)); 73 } 74 75 static void test_backToFront(skiatest::Reporter* reporter) { 76 SkAutoTUnref<SkLayerDrawLooper> looper(SkNEW(SkLayerDrawLooper)); 77 SkLayerDrawLooper::LayerInfo layerInfo; 78 79 // Add the back layer, with the defaults. 80 (void)looper->addLayerOnTop(layerInfo); 81 82 // Add the front layer, with some layer info set. 83 layerInfo.fOffset.set(10.0f, 20.0f); 84 layerInfo.fPaintBits |= SkLayerDrawLooper::kXfermode_Bit; 85 SkPaint* layerPaint = looper->addLayerOnTop(layerInfo); 86 layerPaint->setXfermodeMode(SkXfermode::kSrc_Mode); 87 88 FakeDevice device; 89 SkCanvas canvas(&device); 90 SkPaint paint; 91 looper->init(&canvas); 92 93 // The back layer should come first. 94 REPORTER_ASSERT(reporter, looper->next(&canvas, &paint)); 95 REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode)); 96 canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint); 97 REPORTER_ASSERT(reporter, 0.0f == device.fLastMatrix.getTranslateX()); 98 REPORTER_ASSERT(reporter, 0.0f == device.fLastMatrix.getTranslateY()); 99 paint.reset(); 100 101 // Then the front layer. 102 REPORTER_ASSERT(reporter, looper->next(&canvas, &paint)); 103 REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrc_Mode)); 104 canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint); 105 REPORTER_ASSERT(reporter, 10.0f == device.fLastMatrix.getTranslateX()); 106 REPORTER_ASSERT(reporter, 20.0f == device.fLastMatrix.getTranslateY()); 107 108 // Only two layers were added, so that should be the end. 109 REPORTER_ASSERT(reporter, !looper->next(&canvas, &paint)); 110 } 111 112 static void test_mixed(skiatest::Reporter* reporter) { 113 SkAutoTUnref<SkLayerDrawLooper> looper(SkNEW(SkLayerDrawLooper)); 114 SkLayerDrawLooper::LayerInfo layerInfo; 115 116 // Add the back layer, with the defaults. 117 (void)looper->addLayer(layerInfo); 118 119 // Add the front layer, with some layer info set. 120 layerInfo.fOffset.set(10.0f, 20.0f); 121 layerInfo.fPaintBits |= SkLayerDrawLooper::kXfermode_Bit; 122 SkPaint* layerPaint = looper->addLayerOnTop(layerInfo); 123 layerPaint->setXfermodeMode(SkXfermode::kSrc_Mode); 124 125 FakeDevice device; 126 SkCanvas canvas(&device); 127 SkPaint paint; 128 looper->init(&canvas); 129 130 // The back layer should come first. 131 REPORTER_ASSERT(reporter, looper->next(&canvas, &paint)); 132 REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode)); 133 canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint); 134 REPORTER_ASSERT(reporter, 0.0f == device.fLastMatrix.getTranslateX()); 135 REPORTER_ASSERT(reporter, 0.0f == device.fLastMatrix.getTranslateY()); 136 paint.reset(); 137 138 // Then the front layer. 139 REPORTER_ASSERT(reporter, looper->next(&canvas, &paint)); 140 REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrc_Mode)); 141 canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint); 142 REPORTER_ASSERT(reporter, 10.0f == device.fLastMatrix.getTranslateX()); 143 REPORTER_ASSERT(reporter, 20.0f == device.fLastMatrix.getTranslateY()); 144 145 // Only two layers were added, so that should be the end. 146 REPORTER_ASSERT(reporter, !looper->next(&canvas, &paint)); 147 } 148 149 DEF_TEST(LayerDrawLooper, reporter) { 150 test_frontToBack(reporter); 151 test_backToFront(reporter); 152 test_mixed(reporter); 153 } 154