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 "gm.h"
9#include "SkOffsetImageFilter.h"
10#include "SkBitmapSource.h"
11
12#define WIDTH 600
13#define HEIGHT 100
14#define MARGIN 12
15
16namespace skiagm {
17
18class OffsetImageFilterGM : public GM {
19public:
20    OffsetImageFilterGM() : fInitialized(false) {
21        this->setBGColor(0xFF000000);
22    }
23
24protected:
25    virtual SkString onShortName() {
26        return SkString("offsetimagefilter");
27    }
28
29    void make_bitmap() {
30        fBitmap.allocN32Pixels(80, 80);
31        SkCanvas canvas(fBitmap);
32        canvas.clear(0x00000000);
33        SkPaint paint;
34        paint.setAntiAlias(true);
35        sk_tool_utils::set_portable_typeface(&paint);
36        paint.setColor(0xD000D000);
37        paint.setTextSize(SkIntToScalar(96));
38        const char* str = "e";
39        canvas.drawText(str, strlen(str), SkIntToScalar(15), SkIntToScalar(65), paint);
40    }
41
42    void make_checkerboard() {
43        fCheckerboard.allocN32Pixels(80, 80);
44        SkCanvas canvas(fCheckerboard);
45        canvas.clear(0x00000000);
46        SkPaint darkPaint;
47        darkPaint.setColor(0xFF404040);
48        SkPaint lightPaint;
49        lightPaint.setColor(0xFFA0A0A0);
50        for (int y = 0; y < 80; y += 16) {
51          for (int x = 0; x < 80; x += 16) {
52            canvas.save();
53            canvas.translate(SkIntToScalar(x), SkIntToScalar(y));
54            canvas.drawRect(SkRect::MakeXYWH(0, 0, 8, 8), darkPaint);
55            canvas.drawRect(SkRect::MakeXYWH(8, 0, 8, 8), lightPaint);
56            canvas.drawRect(SkRect::MakeXYWH(0, 8, 8, 8), lightPaint);
57            canvas.drawRect(SkRect::MakeXYWH(8, 8, 8, 8), darkPaint);
58            canvas.restore();
59          }
60        }
61    }
62
63    virtual SkISize onISize() {
64        return SkISize::Make(WIDTH, HEIGHT);
65    }
66
67    void drawClippedBitmap(SkCanvas* canvas, const SkBitmap& bitmap, const SkPaint& paint, SkScalar scale, const SkIRect& cropRect) {
68        canvas->save();
69        SkRect clipRect = SkRect::MakeWH(
70            SkIntToScalar(bitmap.width()), SkIntToScalar(bitmap.height()));
71        canvas->clipRect(clipRect);
72        canvas->scale(scale, scale);
73        canvas->drawBitmap(bitmap, 0, 0, &paint);
74        canvas->restore();
75        SkPaint strokePaint;
76        strokePaint.setStyle(SkPaint::kStroke_Style);
77        strokePaint.setColor(SK_ColorRED);
78
79        // Draw a boundary rect around the intersection of the clip rect
80        // and crop rect.
81        SkMatrix scaleMatrix;
82        scaleMatrix.setScale(scale, scale);
83        SkRect cropRectFloat;
84        scaleMatrix.mapRect(&cropRectFloat, SkRect::Make(cropRect));
85        clipRect.intersect(cropRectFloat);
86        canvas->drawRect(clipRect, strokePaint);
87    }
88
89    virtual void onDraw(SkCanvas* canvas) {
90        if (!fInitialized) {
91            make_bitmap();
92            make_checkerboard();
93            fInitialized = true;
94        }
95        canvas->clear(0x00000000);
96        SkPaint paint;
97
98        for (int i = 0; i < 4; i++) {
99            SkBitmap* bitmap = (i & 0x01) ? &fCheckerboard : &fBitmap;
100            SkIRect cropRect = SkIRect::MakeXYWH(i * 12,
101                                                 i * 8,
102                                                 bitmap->width() - i * 8,
103                                                 bitmap->height() - i * 12);
104            SkImageFilter::CropRect rect(SkRect::Make(cropRect));
105            SkAutoTUnref<SkImageFilter> tileInput(SkBitmapSource::Create(*bitmap));
106            SkScalar dx = SkIntToScalar(i*5);
107            SkScalar dy = SkIntToScalar(i*10);
108            SkAutoTUnref<SkImageFilter> filter(
109                SkOffsetImageFilter::Create(dx, dy, tileInput, &rect));
110            paint.setImageFilter(filter);
111            drawClippedBitmap(canvas, *bitmap, paint, SK_Scalar1, cropRect);
112            canvas->translate(SkIntToScalar(bitmap->width() + MARGIN), 0);
113        }
114
115        SkIRect cropRect = SkIRect::MakeXYWH(0, 0, 100, 100);
116        SkImageFilter::CropRect rect(SkRect::Make(cropRect));
117        SkAutoTUnref<SkImageFilter> filter(
118            SkOffsetImageFilter::Create(SkIntToScalar(-5), SkIntToScalar(-10), NULL, &rect));
119        paint.setImageFilter(filter);
120        drawClippedBitmap(canvas, fBitmap, paint, SkIntToScalar(2), cropRect);
121    }
122private:
123    typedef GM INHERITED;
124    SkBitmap fBitmap, fCheckerboard;
125    bool fInitialized;
126};
127
128//////////////////////////////////////////////////////////////////////////////
129
130static GM* MyFactory(void*) { return new OffsetImageFilterGM; }
131static GMRegistry reg(MyFactory);
132
133}
134