offsetimagefilter.cpp revision 37bd7c3aca66697fff2db79c21771a0b3cbe3b4c
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 "sk_tool_utils.h"
9#include "SkImage.h"
10#include "SkImageSource.h"
11#include "SkOffsetImageFilter.h"
12#include "SkSurface.h"
13#include "gm.h"
14
15#define WIDTH 600
16#define HEIGHT 100
17#define MARGIN 12
18
19class OffsetImageFilterGM : public skiagm::GM {
20public:
21    OffsetImageFilterGM() {
22        this->setBGColor(0xFF000000);
23    }
24
25protected:
26    SkString onShortName() override {
27        return SkString("offsetimagefilter");
28    }
29
30    SkISize onISize() override {
31        return SkISize::Make(WIDTH, HEIGHT);
32    }
33
34    void onOnceBeforeDraw() override {
35        fBitmap = SkImage::MakeFromBitmap(
36            sk_tool_utils::create_string_bitmap(80, 80, 0xD000D000, 15, 65, 96, "e"));
37
38        fCheckerboard = SkImage::MakeFromBitmap(
39            sk_tool_utils::create_checkerboard_bitmap(80, 80,
40                                                      sk_tool_utils::color_to_565(0xFFA0A0A0),
41                                                      sk_tool_utils::color_to_565(0xFF404040),
42                                                      8));
43    }
44
45    void onDraw(SkCanvas* canvas) override {
46        canvas->clear(SK_ColorBLACK);
47        SkPaint paint;
48
49        for (int i = 0; i < 4; i++) {
50            SkImage* image = (i & 0x01) ? fCheckerboard.get() : fBitmap.get();
51            SkIRect cropRect = SkIRect::MakeXYWH(i * 12,
52                                                 i * 8,
53                                                 image->width() - i * 8,
54                                                 image->height() - i * 12);
55            SkImageFilter::CropRect rect(SkRect::Make(cropRect));
56            SkAutoTUnref<SkImageFilter> tileInput(SkImageSource::Create(image));
57            SkScalar dx = SkIntToScalar(i*5);
58            SkScalar dy = SkIntToScalar(i*10);
59            SkAutoTUnref<SkImageFilter> filter(SkOffsetImageFilter::Create(dx, dy, tileInput,
60                                                                           &rect));
61            paint.setImageFilter(filter);
62            DrawClippedImage(canvas, image, paint, 1, cropRect);
63            canvas->translate(SkIntToScalar(image->width() + MARGIN), 0);
64        }
65
66        SkIRect cropRect = SkIRect::MakeXYWH(0, 0, 100, 100);
67        SkImageFilter::CropRect rect(SkRect::Make(cropRect));
68        SkAutoTUnref<SkImageFilter> filter(SkOffsetImageFilter::Create(-5, -10, nullptr, &rect));
69        paint.setImageFilter(filter);
70        DrawClippedImage(canvas, fBitmap.get(), paint, 2, cropRect);
71    }
72private:
73    static void DrawClippedImage(SkCanvas* canvas, const SkImage* image, const SkPaint& paint,
74                          SkScalar scale, const SkIRect& cropRect) {
75        SkRect clipRect = SkRect::MakeIWH(image->width(), image->height());
76
77        canvas->save();
78        canvas->clipRect(clipRect);
79        canvas->scale(scale, scale);
80        canvas->drawImage(image, 0, 0, &paint);
81        canvas->restore();
82
83        // Draw a boundary rect around the intersection of the clip rect and crop rect.
84        SkRect cropRectFloat;
85        SkMatrix::MakeScale(scale, scale).mapRect(&cropRectFloat, SkRect::Make(cropRect));
86        if (clipRect.intersect(cropRectFloat)) {
87            SkPaint strokePaint;
88            strokePaint.setStyle(SkPaint::kStroke_Style);
89            strokePaint.setStrokeWidth(2);
90            strokePaint.setColor(SK_ColorRED);
91            canvas->drawRect(clipRect, strokePaint);
92        }
93    }
94
95    sk_sp<SkImage> fBitmap, fCheckerboard;
96
97    typedef skiagm::GM INHERITED;
98};
99DEF_GM( return new OffsetImageFilterGM; )
100
101//////////////////////////////////////////////////////////////////////////////
102
103class SimpleOffsetImageFilterGM : public skiagm::GM {
104public:
105    SimpleOffsetImageFilterGM() {}
106
107protected:
108    SkString onShortName() override {
109        return SkString("simple-offsetimagefilter");
110    }
111
112    SkISize onISize() override { return SkISize::Make(640, 200); }
113
114    void doDraw(SkCanvas* canvas, const SkRect& r, SkImageFilter* imgf,
115                const SkRect* clipR = nullptr) {
116        SkPaint p;
117
118        if (clipR) {
119            p.setColor(0xFF00FF00);
120            p.setStyle(SkPaint::kStroke_Style);
121            canvas->drawRect(clipR->makeInset(SK_ScalarHalf, SK_ScalarHalf), p);
122            p.setStyle(SkPaint::kFill_Style);
123        }
124
125        if (imgf && imgf->cropRectIsSet()) {
126            SkImageFilter::CropRect cr = imgf->getCropRect();
127
128            p.setColor(0x66FF00FF);
129            p.setStyle(SkPaint::kStroke_Style);
130            canvas->drawRect(cr.rect().makeInset(SK_ScalarHalf, SK_ScalarHalf), p);
131            p.setStyle(SkPaint::kFill_Style);
132        }
133
134        p.setColor(0x660000FF);
135        canvas->drawRect(r, p);
136
137        if (clipR) {
138            canvas->save();
139            canvas->clipRect(*clipR);
140        }
141        if (imgf) {
142            p.setImageFilter(imgf)->unref();
143        }
144        p.setColor(0x66FF0000);
145        canvas->drawRect(r, p);
146
147        if (clipR) {
148            canvas->restore();
149        }
150    }
151
152    void onDraw(SkCanvas* canvas) override {
153        const SkRect r = SkRect::MakeWH(40, 40);
154        SkImageFilter::CropRect cr0(r);
155        SkImageFilter::CropRect cr1(SkRect::MakeWH(20, 20));
156        const SkRect r2 = SkRect::MakeXYWH(40, 0, 40, 40);
157        SkImageFilter::CropRect cr2(r2);
158
159        canvas->translate(40, 40);
160
161        canvas->save();
162        this->doDraw(canvas, r, nullptr);
163
164        canvas->translate(100, 0);
165        this->doDraw(canvas, r, SkOffsetImageFilter::Create(20, 20));
166
167        canvas->translate(100, 0);
168        this->doDraw(canvas, r, SkOffsetImageFilter::Create(20, 20, nullptr, &cr0));
169
170        canvas->translate(100, 0);
171        this->doDraw(canvas, r, SkOffsetImageFilter::Create(20, 20), &r);
172
173        canvas->translate(100, 0);
174        this->doDraw(canvas, r, SkOffsetImageFilter::Create(20, 20, nullptr, &cr1));
175
176        SkRect clipR = SkRect::MakeXYWH(40, 40, 40, 40);
177        canvas->translate(100, 0);
178        this->doDraw(canvas, r, SkOffsetImageFilter::Create(20, 20, nullptr, nullptr), &clipR);
179        canvas->restore();
180
181        // 2nd row
182        canvas->translate(0, 80);
183
184        /*
185         *  combos of clip and crop rects that align with src and dst
186         */
187
188        // crop==clip==src
189        this->doDraw(canvas, r, SkOffsetImageFilter::Create(40, 0, nullptr, &cr0), &r);
190
191        // crop==src, clip==dst
192        canvas->translate(100, 0);
193        this->doDraw(canvas, r, SkOffsetImageFilter::Create(40, 0, nullptr, &cr0), &r2);
194
195        // crop==dst, clip==src
196        canvas->translate(100, 0);
197        this->doDraw(canvas, r, SkOffsetImageFilter::Create(40, 0, nullptr, &cr2), &r);
198
199        // crop==clip==dst
200        canvas->translate(100, 0);
201        this->doDraw(canvas, r, SkOffsetImageFilter::Create(40, 0, nullptr, &cr2), &r2);
202    }
203
204private:
205    typedef skiagm::GM INHERITED;
206};
207DEF_GM( return new SimpleOffsetImageFilterGM; )
208