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