blob: 8b1aa0d9345f9cb4ad97c054248c6958f56edb29 [file] [log] [blame]
commit-bot@chromium.org8f838252013-05-22 12:35:50 +00001/*
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"
robertphillips@google.com1f2f3382013-08-29 11:54:56 +00009#include "SkBitmapDevice.h"
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000010#include "SkCanvas.h"
11#include "SkDraw.h"
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000012#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
robertphillips@google.com1f2f3382013-08-29 11:54:56 +000022class FakeDevice : public SkBitmapDevice {
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000023public:
robertphillips@google.com1f2f3382013-08-29 11:54:56 +000024 FakeDevice() : SkBitmapDevice(SkBitmap::kARGB_8888_Config, 100, 100, false) { }
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000025
skia.committer@gmail.com7f1af502013-07-24 07:01:12 +000026 virtual void drawRect(const SkDraw& draw, const SkRect& r,
commit-bot@chromium.org3e2ea252013-07-23 11:28:45 +000027 const SkPaint& paint) SK_OVERRIDE {
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000028 fLastMatrix = *draw.fMatrix;
robertphillips@google.com1f2f3382013-08-29 11:54:56 +000029 INHERITED::drawRect(draw, r, paint);
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000030 }
31
32 SkMatrix fLastMatrix;
robertphillips@google.com1f2f3382013-08-29 11:54:56 +000033
34private:
35 typedef SkBitmapDevice INHERITED;
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000036};
37
38} // namespace
39
40static void test_frontToBack(skiatest::Reporter* reporter) {
41 SkAutoTUnref<SkLayerDrawLooper> looper(SkNEW(SkLayerDrawLooper));
42 SkLayerDrawLooper::LayerInfo layerInfo;
43
44 // Add the front layer, with the defaults.
45 (void)looper->addLayer(layerInfo);
46
47 // Add the back layer, with some layer info set.
48 layerInfo.fOffset.set(SkFloatToScalar(10.0f), SkFloatToScalar(20.0f));
49 layerInfo.fPaintBits |= SkLayerDrawLooper::kXfermode_Bit;
50 SkPaint* layerPaint = looper->addLayer(layerInfo);
51 layerPaint->setXfermodeMode(SkXfermode::kSrc_Mode);
52
53 FakeDevice device;
54 SkCanvas canvas(&device);
55 SkPaint paint;
56 looper->init(&canvas);
57
58 // The back layer should come first.
59 REPORTER_ASSERT(reporter, looper->next(&canvas, &paint));
60 REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrc_Mode));
61 canvas.drawRect(SkRect::MakeWH(SkFloatToScalar(50.0f), SkFloatToScalar(50.0f)), paint);
62 REPORTER_ASSERT(reporter, SkFloatToScalar(10.0f) == device.fLastMatrix.getTranslateX());
63 REPORTER_ASSERT(reporter, SkFloatToScalar(20.0f) == device.fLastMatrix.getTranslateY());
64 paint.reset();
65
66 // Then the front layer.
67 REPORTER_ASSERT(reporter, looper->next(&canvas, &paint));
68 REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode));
69 canvas.drawRect(SkRect::MakeWH(SkFloatToScalar(50.0f), SkFloatToScalar(50.0f)), paint);
70 REPORTER_ASSERT(reporter, SkFloatToScalar(0.0f) == device.fLastMatrix.getTranslateX());
71 REPORTER_ASSERT(reporter, SkFloatToScalar(0.0f) == device.fLastMatrix.getTranslateY());
72
73 // Only two layers were added, so that should be the end.
74 REPORTER_ASSERT(reporter, !looper->next(&canvas, &paint));
75}
76
77static void test_backToFront(skiatest::Reporter* reporter) {
78 SkAutoTUnref<SkLayerDrawLooper> looper(SkNEW(SkLayerDrawLooper));
79 SkLayerDrawLooper::LayerInfo layerInfo;
80
81 // Add the back layer, with the defaults.
82 (void)looper->addLayerOnTop(layerInfo);
83
84 // Add the front layer, with some layer info set.
85 layerInfo.fOffset.set(SkFloatToScalar(10.0f), SkFloatToScalar(20.0f));
86 layerInfo.fPaintBits |= SkLayerDrawLooper::kXfermode_Bit;
87 SkPaint* layerPaint = looper->addLayerOnTop(layerInfo);
88 layerPaint->setXfermodeMode(SkXfermode::kSrc_Mode);
89
90 FakeDevice device;
91 SkCanvas canvas(&device);
92 SkPaint paint;
93 looper->init(&canvas);
94
95 // The back layer should come first.
96 REPORTER_ASSERT(reporter, looper->next(&canvas, &paint));
97 REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode));
98 canvas.drawRect(SkRect::MakeWH(SkFloatToScalar(50.0f), SkFloatToScalar(50.0f)), paint);
99 REPORTER_ASSERT(reporter, SkFloatToScalar(0.0f) == device.fLastMatrix.getTranslateX());
100 REPORTER_ASSERT(reporter, SkFloatToScalar(0.0f) == device.fLastMatrix.getTranslateY());
101 paint.reset();
102
103 // Then the front layer.
104 REPORTER_ASSERT(reporter, looper->next(&canvas, &paint));
105 REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrc_Mode));
106 canvas.drawRect(SkRect::MakeWH(SkFloatToScalar(50.0f), SkFloatToScalar(50.0f)), paint);
107 REPORTER_ASSERT(reporter, SkFloatToScalar(10.0f) == device.fLastMatrix.getTranslateX());
108 REPORTER_ASSERT(reporter, SkFloatToScalar(20.0f) == device.fLastMatrix.getTranslateY());
109
110 // Only two layers were added, so that should be the end.
111 REPORTER_ASSERT(reporter, !looper->next(&canvas, &paint));
112}
113
114static void test_mixed(skiatest::Reporter* reporter) {
115 SkAutoTUnref<SkLayerDrawLooper> looper(SkNEW(SkLayerDrawLooper));
116 SkLayerDrawLooper::LayerInfo layerInfo;
117
118 // Add the back layer, with the defaults.
119 (void)looper->addLayer(layerInfo);
120
121 // Add the front layer, with some layer info set.
122 layerInfo.fOffset.set(SkFloatToScalar(10.0f), SkFloatToScalar(20.0f));
123 layerInfo.fPaintBits |= SkLayerDrawLooper::kXfermode_Bit;
124 SkPaint* layerPaint = looper->addLayerOnTop(layerInfo);
125 layerPaint->setXfermodeMode(SkXfermode::kSrc_Mode);
126
127 FakeDevice device;
128 SkCanvas canvas(&device);
129 SkPaint paint;
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(SkFloatToScalar(50.0f), SkFloatToScalar(50.0f)), paint);
136 REPORTER_ASSERT(reporter, SkFloatToScalar(0.0f) == device.fLastMatrix.getTranslateX());
137 REPORTER_ASSERT(reporter, SkFloatToScalar(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(SkFloatToScalar(50.0f), SkFloatToScalar(50.0f)), paint);
144 REPORTER_ASSERT(reporter, SkFloatToScalar(10.0f) == device.fLastMatrix.getTranslateX());
145 REPORTER_ASSERT(reporter, SkFloatToScalar(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
151static void TestLayerDrawLooper(skiatest::Reporter* reporter) {
152 test_frontToBack(reporter);
153 test_backToFront(reporter);
154 test_mixed(reporter);
155}
156
157#include "TestClassDef.h"
158DEFINE_TESTCLASS("LayerDrawLooper", TestLayerDrawLooperClass, TestLayerDrawLooper)