blob: a1319a50def8377428edf35713ea88b5c965c2e0 [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 "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"
tfarina@chromium.org8f6884a2014-01-24 20:56:26 +000019#include "Test.h"
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000020
robertphillips@google.com1f2f3382013-08-29 11:54:56 +000021class FakeDevice : public SkBitmapDevice {
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000022public:
robertphillips@google.com1f2f3382013-08-29 11:54:56 +000023 FakeDevice() : SkBitmapDevice(SkBitmap::kARGB_8888_Config, 100, 100, false) { }
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000024
skia.committer@gmail.com7f1af502013-07-24 07:01:12 +000025 virtual void drawRect(const SkDraw& draw, const SkRect& r,
commit-bot@chromium.org3e2ea252013-07-23 11:28:45 +000026 const SkPaint& paint) SK_OVERRIDE {
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000027 fLastMatrix = *draw.fMatrix;
robertphillips@google.com1f2f3382013-08-29 11:54:56 +000028 INHERITED::drawRect(draw, r, paint);
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000029 }
30
31 SkMatrix fLastMatrix;
robertphillips@google.com1f2f3382013-08-29 11:54:56 +000032
33private:
34 typedef SkBitmapDevice INHERITED;
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000035};
36
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000037static void test_frontToBack(skiatest::Reporter* reporter) {
38 SkAutoTUnref<SkLayerDrawLooper> looper(SkNEW(SkLayerDrawLooper));
39 SkLayerDrawLooper::LayerInfo layerInfo;
40
41 // Add the front layer, with the defaults.
42 (void)looper->addLayer(layerInfo);
43
44 // Add the back layer, with some layer info set.
commit-bot@chromium.org4b413c82013-11-25 19:44:07 +000045 layerInfo.fOffset.set(10.0f, 20.0f);
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000046 layerInfo.fPaintBits |= SkLayerDrawLooper::kXfermode_Bit;
47 SkPaint* layerPaint = looper->addLayer(layerInfo);
48 layerPaint->setXfermodeMode(SkXfermode::kSrc_Mode);
49
50 FakeDevice device;
51 SkCanvas canvas(&device);
52 SkPaint paint;
53 looper->init(&canvas);
54
55 // The back layer should come first.
56 REPORTER_ASSERT(reporter, looper->next(&canvas, &paint));
57 REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrc_Mode));
commit-bot@chromium.org4b413c82013-11-25 19:44:07 +000058 canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint);
59 REPORTER_ASSERT(reporter, 10.0f == device.fLastMatrix.getTranslateX());
60 REPORTER_ASSERT(reporter, 20.0f == device.fLastMatrix.getTranslateY());
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000061 paint.reset();
62
63 // Then the front layer.
64 REPORTER_ASSERT(reporter, looper->next(&canvas, &paint));
65 REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode));
commit-bot@chromium.org4b413c82013-11-25 19:44:07 +000066 canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint);
67 REPORTER_ASSERT(reporter, 0.0f == device.fLastMatrix.getTranslateX());
68 REPORTER_ASSERT(reporter, 0.0f == device.fLastMatrix.getTranslateY());
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000069
70 // Only two layers were added, so that should be the end.
71 REPORTER_ASSERT(reporter, !looper->next(&canvas, &paint));
72}
73
74static void test_backToFront(skiatest::Reporter* reporter) {
75 SkAutoTUnref<SkLayerDrawLooper> looper(SkNEW(SkLayerDrawLooper));
76 SkLayerDrawLooper::LayerInfo layerInfo;
77
78 // Add the back layer, with the defaults.
79 (void)looper->addLayerOnTop(layerInfo);
80
81 // Add the front layer, with some layer info set.
commit-bot@chromium.org4b413c82013-11-25 19:44:07 +000082 layerInfo.fOffset.set(10.0f, 20.0f);
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000083 layerInfo.fPaintBits |= SkLayerDrawLooper::kXfermode_Bit;
84 SkPaint* layerPaint = looper->addLayerOnTop(layerInfo);
85 layerPaint->setXfermodeMode(SkXfermode::kSrc_Mode);
86
87 FakeDevice device;
88 SkCanvas canvas(&device);
89 SkPaint paint;
90 looper->init(&canvas);
91
92 // The back layer should come first.
93 REPORTER_ASSERT(reporter, looper->next(&canvas, &paint));
94 REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode));
commit-bot@chromium.org4b413c82013-11-25 19:44:07 +000095 canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint);
96 REPORTER_ASSERT(reporter, 0.0f == device.fLastMatrix.getTranslateX());
97 REPORTER_ASSERT(reporter, 0.0f == device.fLastMatrix.getTranslateY());
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000098 paint.reset();
99
100 // Then the front layer.
101 REPORTER_ASSERT(reporter, looper->next(&canvas, &paint));
102 REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrc_Mode));
commit-bot@chromium.org4b413c82013-11-25 19:44:07 +0000103 canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint);
104 REPORTER_ASSERT(reporter, 10.0f == device.fLastMatrix.getTranslateX());
105 REPORTER_ASSERT(reporter, 20.0f == device.fLastMatrix.getTranslateY());
commit-bot@chromium.org8f838252013-05-22 12:35:50 +0000106
107 // Only two layers were added, so that should be the end.
108 REPORTER_ASSERT(reporter, !looper->next(&canvas, &paint));
109}
110
111static void test_mixed(skiatest::Reporter* reporter) {
112 SkAutoTUnref<SkLayerDrawLooper> looper(SkNEW(SkLayerDrawLooper));
113 SkLayerDrawLooper::LayerInfo layerInfo;
114
115 // Add the back layer, with the defaults.
116 (void)looper->addLayer(layerInfo);
117
118 // Add the front layer, with some layer info set.
commit-bot@chromium.org4b413c82013-11-25 19:44:07 +0000119 layerInfo.fOffset.set(10.0f, 20.0f);
commit-bot@chromium.org8f838252013-05-22 12:35:50 +0000120 layerInfo.fPaintBits |= SkLayerDrawLooper::kXfermode_Bit;
121 SkPaint* layerPaint = looper->addLayerOnTop(layerInfo);
122 layerPaint->setXfermodeMode(SkXfermode::kSrc_Mode);
123
124 FakeDevice device;
125 SkCanvas canvas(&device);
126 SkPaint paint;
127 looper->init(&canvas);
128
129 // The back layer should come first.
130 REPORTER_ASSERT(reporter, looper->next(&canvas, &paint));
131 REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode));
commit-bot@chromium.org4b413c82013-11-25 19:44:07 +0000132 canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint);
133 REPORTER_ASSERT(reporter, 0.0f == device.fLastMatrix.getTranslateX());
134 REPORTER_ASSERT(reporter, 0.0f == device.fLastMatrix.getTranslateY());
commit-bot@chromium.org8f838252013-05-22 12:35:50 +0000135 paint.reset();
136
137 // Then the front layer.
138 REPORTER_ASSERT(reporter, looper->next(&canvas, &paint));
139 REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrc_Mode));
commit-bot@chromium.org4b413c82013-11-25 19:44:07 +0000140 canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint);
141 REPORTER_ASSERT(reporter, 10.0f == device.fLastMatrix.getTranslateX());
142 REPORTER_ASSERT(reporter, 20.0f == device.fLastMatrix.getTranslateY());
commit-bot@chromium.org8f838252013-05-22 12:35:50 +0000143
144 // Only two layers were added, so that should be the end.
145 REPORTER_ASSERT(reporter, !looper->next(&canvas, &paint));
146}
147
tfarina@chromium.orge4fafb12013-12-12 21:11:12 +0000148DEF_TEST(LayerDrawLooper, reporter) {
commit-bot@chromium.org8f838252013-05-22 12:35:50 +0000149 test_frontToBack(reporter);
150 test_backToFront(reporter);
151 test_mixed(reporter);
152}