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