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