1/*
2 * Copyright 2012 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 "SkColor.h"
10#include "SkMatrixConvolutionImageFilter.h"
11#include "SkGradientShader.h"
12
13namespace skiagm {
14
15class MatrixConvolutionGM : public GM {
16public:
17    MatrixConvolutionGM() : fInitialized(false) {
18        this->setBGColor(0x00000000);
19    }
20
21protected:
22    virtual SkString onShortName() {
23        return SkString("matrixconvolution");
24    }
25
26    void make_bitmap() {
27        fBitmap.setConfig(SkBitmap::kARGB_8888_Config, 80, 80);
28        fBitmap.allocPixels();
29        SkDevice device(fBitmap);
30        SkCanvas canvas(&device);
31        canvas.clear(0x00000000);
32        SkPaint paint;
33        paint.setAntiAlias(true);
34        paint.setColor(0xFFFFFFFF);
35        paint.setTextSize(SkIntToScalar(180));
36        SkPoint pts[2] = { SkPoint::Make(0, 0),
37                           SkPoint::Make(0, SkIntToScalar(80)) };
38        SkColor colors[2] = { 0xFFFFFFFF, 0x40404040 };
39        SkScalar pos[2] = { 0, SkIntToScalar(80) };
40        paint.setShader(SkGradientShader::CreateLinear(
41            pts, colors, pos, 2, SkShader::kClamp_TileMode))->unref();
42        const char* str = "e";
43        canvas.drawText(str, strlen(str), SkIntToScalar(-10), SkIntToScalar(80), paint);
44    }
45
46    virtual SkISize onISize() {
47        return make_isize(400, 300);
48    }
49
50    void draw(SkCanvas* canvas, int x, int y, const SkIPoint& target, SkMatrixConvolutionImageFilter::TileMode tileMode, bool convolveAlpha) {
51        SkScalar kernel[9] = {
52            SkIntToScalar( 1), SkIntToScalar( 1), SkIntToScalar( 1),
53            SkIntToScalar( 1), SkIntToScalar(-7), SkIntToScalar( 1),
54            SkIntToScalar( 1), SkIntToScalar( 1), SkIntToScalar( 1),
55        };
56        SkISize kernelSize = SkISize::Make(3, 3);
57        SkScalar gain = SkFloatToScalar(0.3f), bias = SkIntToScalar(100);
58        SkPaint paint;
59        SkAutoTUnref<SkImageFilter> filter(SkNEW_ARGS(SkMatrixConvolutionImageFilter, (kernelSize, kernel, gain, bias, target, tileMode, convolveAlpha)));
60        paint.setImageFilter(filter);
61        canvas->save();
62        canvas->clipRect(SkRect::MakeXYWH(SkIntToScalar(x), SkIntToScalar(y),
63            SkIntToScalar(fBitmap.width()), SkIntToScalar(fBitmap.height())));
64        canvas->drawBitmap(fBitmap, SkIntToScalar(x), SkIntToScalar(y), &paint);
65        canvas->restore();
66    }
67
68    virtual void onDraw(SkCanvas* canvas) {
69        if (!fInitialized) {
70            make_bitmap();
71            fInitialized = true;
72        }
73        canvas->clear(0x00000000);
74        SkIPoint target = SkIPoint::Make(1, 0);
75        for (int x = 10; x < 310; x += 100) {
76            draw(canvas, x, 10, target, SkMatrixConvolutionImageFilter::kClamp_TileMode, true);
77            draw(canvas, x, 110, target, SkMatrixConvolutionImageFilter::kClampToBlack_TileMode, true);
78            draw(canvas, x, 210, target, SkMatrixConvolutionImageFilter::kRepeat_TileMode, true);
79            target.fY++;
80        }
81        target.fY = 1;
82        draw(canvas, 310, 10, target, SkMatrixConvolutionImageFilter::kClamp_TileMode, false);
83        draw(canvas, 310, 110, target, SkMatrixConvolutionImageFilter::kClampToBlack_TileMode, false);
84        draw(canvas, 310, 210, target, SkMatrixConvolutionImageFilter::kRepeat_TileMode, false);
85    }
86
87private:
88    typedef GM INHERITED;
89    SkBitmap fBitmap;
90    bool fInitialized;
91};
92
93//////////////////////////////////////////////////////////////////////////////
94
95static GM* MyFactory(void*) { return new MatrixConvolutionGM; }
96static GMRegistry reg(MyFactory);
97
98}
99