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