1/*
2 * Copyright 2014 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 "SkBlurImageFilter.h"
11#include "SkColor.h"
12#include "SkDisplacementMapEffect.h"
13#include "SkDropShadowImageFilter.h"
14#include "SkGradientShader.h"
15#include "SkLightingImageFilter.h"
16#include "SkMorphologyImageFilter.h"
17#include "SkOffsetImageFilter.h"
18#include "SkPerlinNoiseShader.h"
19#include "SkRectShaderImageFilter.h"
20#include "SkScalar.h"
21#include "gm.h"
22
23#define RESIZE_FACTOR SkIntToScalar(4)
24
25namespace skiagm {
26
27class ImageFiltersScaledGM : public GM {
28public:
29    ImageFiltersScaledGM() : fInitialized(false) {
30        this->setBGColor(0x00000000);
31    }
32
33protected:
34
35    virtual SkString onShortName() {
36        return SkString("imagefiltersscaled");
37    }
38
39    virtual SkISize onISize() {
40        return SkISize::Make(1428, 500);
41    }
42
43    void make_gradient_circle(int width, int height) {
44        SkScalar x = SkIntToScalar(width / 2);
45        SkScalar y = SkIntToScalar(height / 2);
46        SkScalar radius = SkScalarMul(SkMinScalar(x, y), SkIntToScalar(4) / SkIntToScalar(5));
47        fGradientCircle.allocN32Pixels(width, height);
48        SkCanvas canvas(fGradientCircle);
49        canvas.clear(0x00000000);
50        SkColor colors[2];
51        colors[0] = SK_ColorWHITE;
52        colors[1] = SK_ColorBLACK;
53        SkAutoTUnref<SkShader> shader(
54            SkGradientShader::CreateRadial(SkPoint::Make(x, y), radius, colors, NULL, 2,
55                                           SkShader::kClamp_TileMode)
56        );
57        SkPaint paint;
58        paint.setShader(shader);
59        canvas.drawCircle(x, y, radius, paint);
60    }
61
62    virtual void onDraw(SkCanvas* canvas) {
63        if (!fInitialized) {
64            fCheckerboard.allocN32Pixels(64, 64);
65            SkCanvas checkerboardCanvas(fCheckerboard);
66            sk_tool_utils::draw_checkerboard(&checkerboardCanvas, 0xFFA0A0A0, 0xFF404040, 8);
67
68            this->make_gradient_circle(64, 64);
69            fInitialized = true;
70        }
71        canvas->clear(SK_ColorBLACK);
72
73        SkAutoTUnref<SkImageFilter> gradient(SkBitmapSource::Create(fGradientCircle));
74        SkAutoTUnref<SkImageFilter> checkerboard(SkBitmapSource::Create(fCheckerboard));
75        SkAutoTUnref<SkShader> noise(SkPerlinNoiseShader::CreateFractalNoise(
76            SkDoubleToScalar(0.1), SkDoubleToScalar(0.05), 1, 0));
77
78        SkPoint3 pointLocation(0, 0, SkIntToScalar(10));
79        SkPoint3 spotLocation(SkIntToScalar(-10), SkIntToScalar(-10), SkIntToScalar(20));
80        SkPoint3 spotTarget(SkIntToScalar(40), SkIntToScalar(40), 0);
81        SkScalar spotExponent = SK_Scalar1;
82        SkScalar cutoffAngle = SkIntToScalar(15);
83        SkScalar kd = SkIntToScalar(2);
84        SkScalar surfaceScale = SkIntToScalar(1);
85        SkColor white(0xFFFFFFFF);
86        SkMatrix resizeMatrix;
87        resizeMatrix.setScale(RESIZE_FACTOR, RESIZE_FACTOR);
88
89        SkImageFilter* filters[] = {
90            SkBlurImageFilter::Create(SkIntToScalar(4), SkIntToScalar(4)),
91            SkDropShadowImageFilter::Create(SkIntToScalar(5), SkIntToScalar(10),
92                SkIntToScalar(3), SkIntToScalar(3), SK_ColorYELLOW,
93                SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode),
94            SkDisplacementMapEffect::Create(SkDisplacementMapEffect::kR_ChannelSelectorType,
95                                            SkDisplacementMapEffect::kR_ChannelSelectorType,
96                                            SkIntToScalar(12),
97                                            gradient.get(),
98                                            checkerboard.get()),
99            SkDilateImageFilter::Create(1, 1, checkerboard.get()),
100            SkErodeImageFilter::Create(1, 1, checkerboard.get()),
101            SkOffsetImageFilter::Create(SkIntToScalar(32), 0),
102            SkImageFilter::CreateMatrixFilter(resizeMatrix, kNone_SkFilterQuality),
103            SkRectShaderImageFilter::Create(noise),
104            SkLightingImageFilter::CreatePointLitDiffuse(pointLocation, white, surfaceScale, kd),
105            SkLightingImageFilter::CreateSpotLitDiffuse(spotLocation, spotTarget, spotExponent,
106                                                        cutoffAngle, white, surfaceScale, kd),
107        };
108
109        SkVector scales[] = {
110            SkVector::Make(SkScalarInvert(2), SkScalarInvert(2)),
111            SkVector::Make(SkIntToScalar(1), SkIntToScalar(1)),
112            SkVector::Make(SkIntToScalar(1), SkIntToScalar(2)),
113            SkVector::Make(SkIntToScalar(2), SkIntToScalar(1)),
114            SkVector::Make(SkIntToScalar(2), SkIntToScalar(2)),
115        };
116
117        SkRect r = SkRect::MakeWH(SkIntToScalar(64), SkIntToScalar(64));
118        SkScalar margin = SkIntToScalar(16);
119        SkRect bounds = r;
120        bounds.outset(margin, margin);
121
122        for (size_t j = 0; j < SK_ARRAY_COUNT(scales); ++j) {
123            canvas->save();
124            for (size_t i = 0; i < SK_ARRAY_COUNT(filters); ++i) {
125                SkPaint paint;
126                paint.setColor(SK_ColorBLUE);
127                paint.setImageFilter(filters[i]);
128                paint.setAntiAlias(true);
129                canvas->save();
130                canvas->scale(scales[j].fX, scales[j].fY);
131                if (5 == i) {
132                    canvas->translate(SkIntToScalar(-32), 0);
133                } else if (6 == i) {
134                    canvas->scale(SkScalarInvert(RESIZE_FACTOR),
135                                  SkScalarInvert(RESIZE_FACTOR));
136                }
137                canvas->drawCircle(r.centerX(), r.centerY(), r.width()*2/5, paint);
138                canvas->restore();
139                canvas->translate(r.width() * scales[j].fX + margin, 0);
140            }
141            canvas->restore();
142            canvas->translate(0, r.height() * scales[j].fY + margin);
143        }
144
145        for (size_t i = 0; i < SK_ARRAY_COUNT(filters); ++i) {
146            filters[i]->unref();
147        }
148    }
149
150private:
151    bool fInitialized;
152    SkBitmap fCheckerboard;
153    SkBitmap fGradientCircle;
154    typedef GM INHERITED;
155};
156
157//////////////////////////////////////////////////////////////////////////////
158
159static GM* MyFactory(void*) { return new ImageFiltersScaledGM; }
160static GMRegistry reg(MyFactory);
161
162}
163