1c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org/*
2c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org * Copyright 2014 Google Inc.
3c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org *
4c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org * Use of this source code is governed by a BSD-style license that can be
5c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org * found in the LICENSE file.
6c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org */
7c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org
8c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org#include "SkBlurImageFilter.h"
9878fa0204bc246ec5fbaca4aa3c81aaefccc30a1halcanary#include "SkColor.h"
10c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org#include "SkDisplacementMapEffect.h"
11c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org#include "SkDropShadowImageFilter.h"
12c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org#include "SkGradientShader.h"
135598b63cd2443a608a74a222d0206bb2455383b7fmalita#include "SkImage.h"
145598b63cd2443a608a74a222d0206bb2455383b7fmalita#include "SkImageSource.h"
157b7ecfc046f7ec810482266db3430d1358b7a5bfsenorblanco#include "SkLightingImageFilter.h"
16c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org#include "SkMorphologyImageFilter.h"
17c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org#include "SkOffsetImageFilter.h"
1877b6ba3b6e23b84a3a4f3a62812e4a9eb6de4c23ajuma#include "SkPaintImageFilter.h"
1947d98c8e85924effc651b09df72027e6801c92a1senorblanco@chromium.org#include "SkPerlinNoiseShader.h"
207b7ecfc046f7ec810482266db3430d1358b7a5bfsenorblanco#include "SkPoint3.h"
21c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org#include "SkScalar.h"
225598b63cd2443a608a74a222d0206bb2455383b7fmalita#include "SkSurface.h"
23878fa0204bc246ec5fbaca4aa3c81aaefccc30a1halcanary#include "gm.h"
2433d2055e594177b27360f84e0631b26d74a55a9bMike Klein#include "sk_tool_utils.h"
25c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org
26897b73f62c012758bd8fef77c24d3573c847dbc3senorblanco@chromium.org#define RESIZE_FACTOR_X SkIntToScalar(2)
27897b73f62c012758bd8fef77c24d3573c847dbc3senorblanco@chromium.org#define RESIZE_FACTOR_Y SkIntToScalar(5)
28897b73f62c012758bd8fef77c24d3573c847dbc3senorblanco@chromium.org
29549c8991959333e5c0f53faebcbbd5d6bc8f6a56robertphillipsstatic sk_sp<SkImage> make_gradient_circle(int width, int height) {
30549c8991959333e5c0f53faebcbbd5d6bc8f6a56robertphillips    SkScalar x = SkIntToScalar(width / 2);
31549c8991959333e5c0f53faebcbbd5d6bc8f6a56robertphillips    SkScalar y = SkIntToScalar(height / 2);
32549c8991959333e5c0f53faebcbbd5d6bc8f6a56robertphillips    SkScalar radius = SkMinScalar(x, y) * 0.8f;
33549c8991959333e5c0f53faebcbbd5d6bc8f6a56robertphillips    auto surface(SkSurface::MakeRasterN32Premul(width, height));
34549c8991959333e5c0f53faebcbbd5d6bc8f6a56robertphillips    SkCanvas* canvas = surface->getCanvas();
35549c8991959333e5c0f53faebcbbd5d6bc8f6a56robertphillips    canvas->clear(0x00000000);
36549c8991959333e5c0f53faebcbbd5d6bc8f6a56robertphillips    SkColor colors[2];
37549c8991959333e5c0f53faebcbbd5d6bc8f6a56robertphillips    colors[0] = SK_ColorWHITE;
38549c8991959333e5c0f53faebcbbd5d6bc8f6a56robertphillips    colors[1] = SK_ColorBLACK;
39549c8991959333e5c0f53faebcbbd5d6bc8f6a56robertphillips    SkPaint paint;
40549c8991959333e5c0f53faebcbbd5d6bc8f6a56robertphillips    paint.setShader(SkGradientShader::MakeRadial(SkPoint::Make(x, y), radius, colors, nullptr,
41549c8991959333e5c0f53faebcbbd5d6bc8f6a56robertphillips        2, SkShader::kClamp_TileMode));
42549c8991959333e5c0f53faebcbbd5d6bc8f6a56robertphillips    canvas->drawCircle(x, y, radius, paint);
43549c8991959333e5c0f53faebcbbd5d6bc8f6a56robertphillips    return surface->makeImageSnapshot();
44549c8991959333e5c0f53faebcbbd5d6bc8f6a56robertphillips}
45549c8991959333e5c0f53faebcbbd5d6bc8f6a56robertphillips
4612fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillipsstatic void draw_clipped_filter(SkCanvas* canvas, sk_sp<SkImageFilter> filter, size_t i,
47549c8991959333e5c0f53faebcbbd5d6bc8f6a56robertphillips                                const SkRect& primBounds, const SkRect& clipBounds) {
48549c8991959333e5c0f53faebcbbd5d6bc8f6a56robertphillips    SkPaint paint;
49549c8991959333e5c0f53faebcbbd5d6bc8f6a56robertphillips    paint.setColor(SK_ColorWHITE);
5012fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips    paint.setImageFilter(std::move(filter));
51549c8991959333e5c0f53faebcbbd5d6bc8f6a56robertphillips    paint.setAntiAlias(true);
52549c8991959333e5c0f53faebcbbd5d6bc8f6a56robertphillips    canvas->save();
53549c8991959333e5c0f53faebcbbd5d6bc8f6a56robertphillips    canvas->clipRect(clipBounds);
54549c8991959333e5c0f53faebcbbd5d6bc8f6a56robertphillips    if (5 == i) {
55549c8991959333e5c0f53faebcbbd5d6bc8f6a56robertphillips        canvas->translate(SkIntToScalar(16), SkIntToScalar(-32));
56549c8991959333e5c0f53faebcbbd5d6bc8f6a56robertphillips    } else if (6 == i) {
57549c8991959333e5c0f53faebcbbd5d6bc8f6a56robertphillips        canvas->scale(SkScalarInvert(RESIZE_FACTOR_X), SkScalarInvert(RESIZE_FACTOR_Y));
58549c8991959333e5c0f53faebcbbd5d6bc8f6a56robertphillips    }
59549c8991959333e5c0f53faebcbbd5d6bc8f6a56robertphillips    canvas->drawCircle(primBounds.centerX(), primBounds.centerY(),
60549c8991959333e5c0f53faebcbbd5d6bc8f6a56robertphillips                       primBounds.width() * 2 / 5, paint);
61549c8991959333e5c0f53faebcbbd5d6bc8f6a56robertphillips    canvas->restore();
62549c8991959333e5c0f53faebcbbd5d6bc8f6a56robertphillips}
63549c8991959333e5c0f53faebcbbd5d6bc8f6a56robertphillips
64c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.orgnamespace skiagm {
65c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org
66c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.orgclass ImageFiltersClippedGM : public GM {
67c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.orgpublic:
68943a462fef57832e2683894bb9f2f36ac25d98f7robertphillips    ImageFiltersClippedGM() {
69c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org        this->setBGColor(0x00000000);
70c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org    }
71c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org
72c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.orgprotected:
7336352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    SkString onShortName() override {
74c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org        return SkString("imagefiltersclipped");
75c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org    }
76c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org
7736352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    SkISize onISize() override {
78f539318f0d3dba743ec1886d5d9df0fb1be628a1tfarina        return SkISize::Make(860, 500);
79c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org    }
80c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org
81943a462fef57832e2683894bb9f2f36ac25d98f7robertphillips    void onOnceBeforeDraw() override {
829ce9d6772df650ceb0511f275e1a83dffa78ff72reed        fCheckerboard = SkImage::MakeFromBitmap
839ce9d6772df650ceb0511f275e1a83dffa78ff72reed            (sk_tool_utils::create_checkerboard_bitmap(64, 64, 0xFFA0A0A0, 0xFF404040, 8));
84549c8991959333e5c0f53faebcbbd5d6bc8f6a56robertphillips        fGradientCircle = make_gradient_circle(64, 64);
85943a462fef57832e2683894bb9f2f36ac25d98f7robertphillips    }
86878fa0204bc246ec5fbaca4aa3c81aaefccc30a1halcanary
87943a462fef57832e2683894bb9f2f36ac25d98f7robertphillips    void onDraw(SkCanvas* canvas) override {
8816b254a200f63e85041cac9a283ff0ff14d94ba1senorblanco        canvas->clear(SK_ColorBLACK);
89c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org
90549c8991959333e5c0f53faebcbbd5d6bc8f6a56robertphillips        sk_sp<SkImageFilter> gradient(SkImageSource::Make(fGradientCircle));
91549c8991959333e5c0f53faebcbbd5d6bc8f6a56robertphillips        sk_sp<SkImageFilter> checkerboard(SkImageSource::Make(fCheckerboard));
92fd0ec2c76a27ce26a62da23eb75017839959e7cbsenorblanco@chromium.org        SkMatrix resizeMatrix;
93fd0ec2c76a27ce26a62da23eb75017839959e7cbsenorblanco@chromium.org        resizeMatrix.setScale(RESIZE_FACTOR_X, RESIZE_FACTOR_Y);
947b7ecfc046f7ec810482266db3430d1358b7a5bfsenorblanco        SkPoint3 pointLocation = SkPoint3::Make(32, 32, SkIntToScalar(10));
95c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org
9612fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips        sk_sp<SkImageFilter> filters[] = {
9712fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips            SkBlurImageFilter::Make(SkIntToScalar(12), SkIntToScalar(12), nullptr),
9812fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips            SkDropShadowImageFilter::Make(
9912fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips                                    SkIntToScalar(10), SkIntToScalar(10),
10012fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips                                    SkIntToScalar(3), SkIntToScalar(3), SK_ColorGREEN,
10112fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips                                    SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode,
10212fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips                                    nullptr),
103bfe11fc9a6e660f83a454b6a5f5945089a4800f3robertphillips            SkDisplacementMapEffect::Make(SkDisplacementMapEffect::kR_ChannelSelectorType,
104bfe11fc9a6e660f83a454b6a5f5945089a4800f3robertphillips                                          SkDisplacementMapEffect::kR_ChannelSelectorType,
105bfe11fc9a6e660f83a454b6a5f5945089a4800f3robertphillips                                          SkIntToScalar(12),
106bfe11fc9a6e660f83a454b6a5f5945089a4800f3robertphillips                                          std::move(gradient),
107bfe11fc9a6e660f83a454b6a5f5945089a4800f3robertphillips                                          checkerboard),
10812fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips            SkDilateImageFilter::Make(2, 2, checkerboard),
10912fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips            SkErodeImageFilter::Make(2, 2, checkerboard),
11012fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips            SkOffsetImageFilter::Make(SkIntToScalar(-16), SkIntToScalar(32), nullptr),
11112fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips            SkImageFilter::MakeMatrixFilter(resizeMatrix, kNone_SkFilterQuality, nullptr),
11212fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips            SkLightingImageFilter::MakePointLitDiffuse(pointLocation, SK_ColorWHITE, SK_Scalar1,
11312fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips                                                       SkIntToScalar(2), checkerboard),
1147b7ecfc046f7ec810482266db3430d1358b7a5bfsenorblanco
115c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org        };
116c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org
117c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org        SkRect r = SkRect::MakeWH(SkIntToScalar(64), SkIntToScalar(64));
118c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org        SkScalar margin = SkIntToScalar(16);
119c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org        SkRect bounds = r;
120c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org        bounds.outset(margin, margin);
121c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org
12202781977e00d88a7b0a3bbd6de158a9f3fecfd46jvanverth        canvas->save();
123c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org        for (int xOffset = 0; xOffset < 80; xOffset += 16) {
124c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org            canvas->save();
125c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org            bounds.fLeft = SkIntToScalar(xOffset);
126c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org            for (size_t i = 0; i < SK_ARRAY_COUNT(filters); ++i) {
12702781977e00d88a7b0a3bbd6de158a9f3fecfd46jvanverth                draw_clipped_filter(canvas, filters[i], i, r, bounds);
128c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org                canvas->translate(r.width() + margin, 0);
129c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org            }
130c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org            canvas->restore();
131c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org            canvas->translate(0, r.height() + margin);
132c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org        }
13302781977e00d88a7b0a3bbd6de158a9f3fecfd46jvanverth        canvas->restore();
13467117808ee73bee5454442af75e7d8ebdbfd00e3senorblanco@chromium.org
13577b6ba3b6e23b84a3a4f3a62812e4a9eb6de4c23ajuma        SkPaint noisePaint;
136549c8991959333e5c0f53faebcbbd5d6bc8f6a56robertphillips        noisePaint.setShader(SkPerlinNoiseShader::MakeFractalNoise(0.1f, 0.05f, 1, 0));
137549c8991959333e5c0f53faebcbbd5d6bc8f6a56robertphillips
138372177ee115d46dfb5bfb881a408e6c37ae83678robertphillips        sk_sp<SkImageFilter> rectFilter(SkPaintImageFilter::Make(noisePaint));
13902781977e00d88a7b0a3bbd6de158a9f3fecfd46jvanverth        canvas->translate(SK_ARRAY_COUNT(filters)*(r.width() + margin), 0);
14002781977e00d88a7b0a3bbd6de158a9f3fecfd46jvanverth        for (int xOffset = 0; xOffset < 80; xOffset += 16) {
14102781977e00d88a7b0a3bbd6de158a9f3fecfd46jvanverth            bounds.fLeft = SkIntToScalar(xOffset);
14212fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips            draw_clipped_filter(canvas, rectFilter, 0, r, bounds);
14302781977e00d88a7b0a3bbd6de158a9f3fecfd46jvanverth            canvas->translate(0, r.height() + margin);
14402781977e00d88a7b0a3bbd6de158a9f3fecfd46jvanverth        }
145c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org    }
146c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org
147c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.orgprivate:
1489ce9d6772df650ceb0511f275e1a83dffa78ff72reed    sk_sp<SkImage> fCheckerboard, fGradientCircle;
149943a462fef57832e2683894bb9f2f36ac25d98f7robertphillips
150c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org    typedef GM INHERITED;
151c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org};
152c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org
153c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org//////////////////////////////////////////////////////////////////////////////
154c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org
155943a462fef57832e2683894bb9f2f36ac25d98f7robertphillipsDEF_GM(return new ImageFiltersClippedGM;)
156c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org}
157