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