blob: 01ebca1464ffe8bd9c889089e611b32541c43d62 [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 */
commit-bot@chromium.orgddf94cf2013-10-12 17:25:17 +00007
commit-bot@chromium.org8f838252013-05-22 12:35:50 +00008#include "Test.h"
tfarina@chromium.orge4fafb12013-12-12 21:11:12 +00009#include "TestClassDef.h"
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000010#include "SkBitmap.h"
robertphillips@google.com1f2f3382013-08-29 11:54:56 +000011#include "SkBitmapDevice.h"
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000012#include "SkCanvas.h"
13#include "SkDraw.h"
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000014#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
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
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000038static 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.
commit-bot@chromium.org4b413c82013-11-25 19:44:07 +000046 layerInfo.fOffset.set(10.0f, 20.0f);
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000047 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));
commit-bot@chromium.org4b413c82013-11-25 19:44:07 +000059 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());
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000062 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));
commit-bot@chromium.org4b413c82013-11-25 19:44:07 +000067 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());
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000070
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 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.
commit-bot@chromium.org4b413c82013-11-25 19:44:07 +000083 layerInfo.fOffset.set(10.0f, 20.0f);
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000084 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));
commit-bot@chromium.org4b413c82013-11-25 19:44:07 +000096 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());
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000099 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));
commit-bot@chromium.org4b413c82013-11-25 19:44:07 +0000104 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());
commit-bot@chromium.org8f838252013-05-22 12:35:50 +0000107
108 // Only two layers were added, so that should be the end.
109 REPORTER_ASSERT(reporter, !looper->next(&canvas, &paint));
110}
111
112static 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.
commit-bot@chromium.org4b413c82013-11-25 19:44:07 +0000120 layerInfo.fOffset.set(10.0f, 20.0f);
commit-bot@chromium.org8f838252013-05-22 12:35:50 +0000121 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));
commit-bot@chromium.org4b413c82013-11-25 19:44:07 +0000133 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());
commit-bot@chromium.org8f838252013-05-22 12:35:50 +0000136 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));
commit-bot@chromium.org4b413c82013-11-25 19:44:07 +0000141 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());
commit-bot@chromium.org8f838252013-05-22 12:35:50 +0000144
145 // Only two layers were added, so that should be the end.
146 REPORTER_ASSERT(reporter, !looper->next(&canvas, &paint));
147}
148
tfarina@chromium.orge4fafb12013-12-12 21:11:12 +0000149DEF_TEST(LayerDrawLooper, reporter) {
commit-bot@chromium.org8f838252013-05-22 12:35:50 +0000150 test_frontToBack(reporter);
151 test_backToFront(reporter);
152 test_mixed(reporter);
153}