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