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