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 "SkDisplacementMapEffect.h"
9#include "SkImage.h"
10#include "SkImageSource.h"
11#include "gm.h"
12#include "sk_tool_utils.h"
13
14namespace skiagm {
15
16class DisplacementMapGM : public GM {
17public:
18    DisplacementMapGM() {
19        this->setBGColor(0xFF000000);
20    }
21
22protected:
23    SkString onShortName() override {
24        return SkString("displacement");
25    }
26
27    void onOnceBeforeDraw() override {
28        fBitmap = sk_tool_utils::create_string_bitmap(80, 80, 0xFF884422, 15, 55, 96, "g");
29
30        SkColor c1 = sk_tool_utils::color_to_565(0xFF244484);
31        SkColor c2 = sk_tool_utils::color_to_565(0xFF804020);
32
33        fCheckerboard = SkImage::MakeFromBitmap(
34            sk_tool_utils::create_checkerboard_bitmap(80, 80, c1, c2, 8));
35        fSmall = SkImage::MakeFromBitmap(
36            sk_tool_utils::create_checkerboard_bitmap(64, 64, c1, c2, 8));
37        fLarge = SkImage::MakeFromBitmap(
38            sk_tool_utils::create_checkerboard_bitmap(96, 96, c1, c2, 8));
39        fLargeW =
40            SkImage::MakeFromBitmap(sk_tool_utils::create_checkerboard_bitmap(96, 64, c1, c2, 8));
41        fLargeH = SkImage::MakeFromBitmap(
42            sk_tool_utils::create_checkerboard_bitmap(64, 96, c1, c2, 8));
43    }
44
45    SkISize onISize() override {
46        return SkISize::Make(600, 500);
47    }
48
49    void drawClippedBitmap(SkCanvas* canvas, int x, int y, const SkPaint& paint) const {
50        canvas->save();
51        canvas->translate(SkIntToScalar(x), SkIntToScalar(y));
52        canvas->clipRect(SkRect::MakeWH(SkIntToScalar(fBitmap.width()), SkIntToScalar(fBitmap.height())));
53        canvas->drawBitmap(fBitmap, 0, 0, &paint);
54        canvas->restore();
55    }
56
57    void onDraw(SkCanvas* canvas) override {
58        canvas->clear(SK_ColorBLACK);
59        SkPaint paint;
60        sk_sp<SkImageFilter> displ(SkImageSource::Make(fCheckerboard));
61        paint.setImageFilter(SkDisplacementMapEffect::Make(
62            SkDisplacementMapEffect::kR_ChannelSelectorType,
63            SkDisplacementMapEffect::kG_ChannelSelectorType, 0.0f, displ, nullptr));
64        this->drawClippedBitmap(canvas, 0, 0, paint);
65        paint.setImageFilter(SkDisplacementMapEffect::Make(
66            SkDisplacementMapEffect::kB_ChannelSelectorType,
67            SkDisplacementMapEffect::kA_ChannelSelectorType, 16.0f, displ, nullptr));
68        this->drawClippedBitmap(canvas, 100, 0, paint);
69        paint.setImageFilter(SkDisplacementMapEffect::Make(
70            SkDisplacementMapEffect::kR_ChannelSelectorType,
71            SkDisplacementMapEffect::kB_ChannelSelectorType, 32.0f, displ, nullptr));
72        this->drawClippedBitmap(canvas, 200, 0, paint);
73        paint.setImageFilter(SkDisplacementMapEffect::Make(
74            SkDisplacementMapEffect::kG_ChannelSelectorType,
75            SkDisplacementMapEffect::kA_ChannelSelectorType, 48.0f, displ, nullptr));
76        this->drawClippedBitmap(canvas, 300, 0, paint);
77        paint.setImageFilter(SkDisplacementMapEffect::Make(
78            SkDisplacementMapEffect::kR_ChannelSelectorType,
79            SkDisplacementMapEffect::kA_ChannelSelectorType, 64.0f, displ, nullptr));
80        this->drawClippedBitmap(canvas, 400, 0, paint);
81
82        paint.setImageFilter(SkDisplacementMapEffect::Make(
83            SkDisplacementMapEffect::kR_ChannelSelectorType,
84            SkDisplacementMapEffect::kG_ChannelSelectorType, 40.0f, displ, nullptr));
85        this->drawClippedBitmap(canvas, 0, 100, paint);
86        paint.setImageFilter(SkDisplacementMapEffect::Make(
87            SkDisplacementMapEffect::kB_ChannelSelectorType,
88            SkDisplacementMapEffect::kA_ChannelSelectorType, 40.0f, displ, nullptr));
89        this->drawClippedBitmap(canvas, 100, 100, paint);
90        paint.setImageFilter(SkDisplacementMapEffect::Make(
91            SkDisplacementMapEffect::kR_ChannelSelectorType,
92            SkDisplacementMapEffect::kB_ChannelSelectorType, 40.0f, displ, nullptr));
93        this->drawClippedBitmap(canvas, 200, 100, paint);
94        paint.setImageFilter(SkDisplacementMapEffect::Make(
95            SkDisplacementMapEffect::kG_ChannelSelectorType,
96            SkDisplacementMapEffect::kA_ChannelSelectorType, 40.0f, displ, nullptr));
97        this->drawClippedBitmap(canvas, 300, 100, paint);
98        paint.setImageFilter(SkDisplacementMapEffect::Make(
99            SkDisplacementMapEffect::kR_ChannelSelectorType,
100            SkDisplacementMapEffect::kA_ChannelSelectorType, 40.0f, displ, nullptr));
101        this->drawClippedBitmap(canvas, 400, 100, paint);
102
103        SkImageFilter::CropRect cropRect(SkRect::MakeXYWH(30, 30, 40, 40));
104        paint.setImageFilter(SkDisplacementMapEffect::Make(
105            SkDisplacementMapEffect::kR_ChannelSelectorType,
106            SkDisplacementMapEffect::kG_ChannelSelectorType,
107            0.0f, displ, nullptr, &cropRect));
108        this->drawClippedBitmap(canvas, 0, 200, paint);
109        paint.setImageFilter(SkDisplacementMapEffect::Make(
110            SkDisplacementMapEffect::kB_ChannelSelectorType,
111            SkDisplacementMapEffect::kA_ChannelSelectorType,
112            16.0f, displ, nullptr, &cropRect));
113        this->drawClippedBitmap(canvas, 100, 200, paint);
114        paint.setImageFilter(SkDisplacementMapEffect::Make(
115            SkDisplacementMapEffect::kR_ChannelSelectorType,
116            SkDisplacementMapEffect::kB_ChannelSelectorType,
117            32.0f, displ, nullptr, &cropRect));
118        this->drawClippedBitmap(canvas, 200, 200, paint);
119        paint.setImageFilter(SkDisplacementMapEffect::Make(
120            SkDisplacementMapEffect::kG_ChannelSelectorType,
121            SkDisplacementMapEffect::kA_ChannelSelectorType,
122            48.0f, displ, nullptr, &cropRect));
123        this->drawClippedBitmap(canvas, 300, 200, paint);
124        paint.setImageFilter(SkDisplacementMapEffect::Make(
125            SkDisplacementMapEffect::kR_ChannelSelectorType,
126            SkDisplacementMapEffect::kA_ChannelSelectorType,
127            64.0f, displ, nullptr, &cropRect));
128        this->drawClippedBitmap(canvas, 400, 200, paint);
129
130        paint.setImageFilter(SkDisplacementMapEffect::Make(
131            SkDisplacementMapEffect::kR_ChannelSelectorType,
132            SkDisplacementMapEffect::kG_ChannelSelectorType,
133            40.0f, displ, nullptr, &cropRect));
134        this->drawClippedBitmap(canvas, 0, 300, paint);
135        paint.setImageFilter(SkDisplacementMapEffect::Make(
136            SkDisplacementMapEffect::kB_ChannelSelectorType,
137            SkDisplacementMapEffect::kA_ChannelSelectorType,
138            40.0f, displ, nullptr, &cropRect));
139        this->drawClippedBitmap(canvas, 100, 300, paint);
140        paint.setImageFilter(SkDisplacementMapEffect::Make(
141            SkDisplacementMapEffect::kR_ChannelSelectorType,
142            SkDisplacementMapEffect::kB_ChannelSelectorType,
143            40.0f, displ, nullptr, &cropRect));
144        this->drawClippedBitmap(canvas, 200, 300, paint);
145        paint.setImageFilter(SkDisplacementMapEffect::Make(
146            SkDisplacementMapEffect::kG_ChannelSelectorType,
147            SkDisplacementMapEffect::kA_ChannelSelectorType,
148            40.0f, displ, nullptr, &cropRect));
149        this->drawClippedBitmap(canvas, 300, 300, paint);
150        paint.setImageFilter(SkDisplacementMapEffect::Make(
151            SkDisplacementMapEffect::kR_ChannelSelectorType,
152            SkDisplacementMapEffect::kA_ChannelSelectorType,
153            40.0f, displ, nullptr, &cropRect));
154        this->drawClippedBitmap(canvas, 400, 300, paint);
155
156        // Test for negative scale.
157        paint.setImageFilter(SkDisplacementMapEffect::Make(
158            SkDisplacementMapEffect::kG_ChannelSelectorType,
159            SkDisplacementMapEffect::kA_ChannelSelectorType,
160            -40.0f, displ, nullptr));
161        this->drawClippedBitmap(canvas, 500, 0, paint);
162
163        // Tests for images of different sizes
164        displ = SkImageSource::Make(fSmall);
165        paint.setImageFilter(SkDisplacementMapEffect::Make(
166            SkDisplacementMapEffect::kR_ChannelSelectorType,
167            SkDisplacementMapEffect::kG_ChannelSelectorType,
168            40.0f, std::move(displ), nullptr));
169        this->drawClippedBitmap(canvas, 0, 400, paint);
170        displ = SkImageSource::Make(fLarge);
171        paint.setImageFilter(SkDisplacementMapEffect::Make(
172            SkDisplacementMapEffect::kB_ChannelSelectorType,
173            SkDisplacementMapEffect::kA_ChannelSelectorType,
174            40.0f, std::move(displ), nullptr));
175        this->drawClippedBitmap(canvas, 100, 400, paint);
176        displ = SkImageSource::Make(fLargeW);
177        paint.setImageFilter(SkDisplacementMapEffect::Make(
178            SkDisplacementMapEffect::kR_ChannelSelectorType,
179            SkDisplacementMapEffect::kB_ChannelSelectorType,
180            40.0f, std::move(displ), nullptr));
181        this->drawClippedBitmap(canvas, 200, 400, paint);
182        displ = SkImageSource::Make(fLargeH);
183        paint.setImageFilter(SkDisplacementMapEffect::Make(
184            SkDisplacementMapEffect::kG_ChannelSelectorType,
185            SkDisplacementMapEffect::kA_ChannelSelectorType,
186            40.0f, std::move(displ), nullptr));
187        this->drawClippedBitmap(canvas, 300, 400, paint);
188
189        // Test for no given displacement input. In this case, both displacement
190        // and color should use the same bitmap, given to SkCanvas::drawBitmap()
191        // as an input argument.
192        paint.setImageFilter(SkDisplacementMapEffect::Make(
193            SkDisplacementMapEffect::kG_ChannelSelectorType,
194            SkDisplacementMapEffect::kA_ChannelSelectorType,
195            40.0f, nullptr, nullptr));
196        this->drawClippedBitmap(canvas, 400, 400, paint);
197    }
198
199private:
200    SkBitmap fBitmap;
201    sk_sp<SkImage> fCheckerboard, fSmall, fLarge, fLargeW, fLargeH;
202
203    typedef GM INHERITED;
204};
205
206//////////////////////////////////////////////////////////////////////////////
207
208DEF_GM(return new DisplacementMapGM;)
209}
210