1fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/*
2fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copyright 2011 Google Inc.
3fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *
4fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Use of this source code is governed by a BSD-style license that can be
5fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * found in the LICENSE file.
6fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */
7fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
8fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "gm.h"
9fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "sk_tool_utils.h"
10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkCanvas.h"
11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkColorFilter.h"
12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkColorPriv.h"
13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkImageFilterPriv.h"
14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkShader.h"
15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkBlurImageFilter.h"
17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkColorFilterImageFilter.h"
18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkDropShadowImageFilter.h"
19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkSpecialImage.h"
20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass FailImageFilter : public SkImageFilter {
22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    class Registrar {
24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    public:
25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        Registrar() {
26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkFlattenable::Register("FailImageFilter",
27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                    FailImageFilter::CreateProc,
28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                    FailImageFilter::GetFlattenableType());
29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static sk_sp<SkImageFilter> Make() {
32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return sk_sp<SkImageFilter>(new FailImageFilter);
33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SK_TO_STRING_OVERRIDE()
36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(FailImageFilter)
37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprotected:
39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    FailImageFilter() : INHERITED(nullptr, 0, nullptr) {}
40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    sk_sp<SkSpecialImage> onFilterImage(SkSpecialImage* source, const Context&,
42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                        SkIPoint* offset) const override {
43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return nullptr;
44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    sk_sp<SkImageFilter> onMakeColorSpace(SkColorSpaceXformer*) const override {
46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return nullptr;
47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate:
50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    typedef SkImageFilter INHERITED;
51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic FailImageFilter::Registrar gReg0;
54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotsk_sp<SkFlattenable> FailImageFilter::CreateProc(SkReadBuffer& buffer) {
56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 0);
57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return FailImageFilter::Make();
58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifndef SK_IGNORE_TO_STRING
61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid FailImageFilter::toString(SkString* str) const {
62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    str->appendf("FailImageFilter: (");
63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    str->append(")");
64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif
66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass IdentityImageFilter : public SkImageFilter {
68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    class Registrar {
70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    public:
71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        Registrar() {
72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkFlattenable::Register("IdentityImageFilter",
73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                    IdentityImageFilter::CreateProc,
74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                    IdentityImageFilter::GetFlattenableType());
75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static sk_sp<SkImageFilter> Make(sk_sp<SkImageFilter> input) {
78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return sk_sp<SkImageFilter>(new IdentityImageFilter(std::move(input)));
79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SK_TO_STRING_OVERRIDE()
82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(IdentityImageFilter)
83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
84fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprotected:
85fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    sk_sp<SkSpecialImage> onFilterImage(SkSpecialImage* source, const Context&,
86fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                        SkIPoint* offset) const override {
87fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        offset->set(0, 0);
88fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return sk_ref_sp<SkSpecialImage>(source);
89fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
90fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    sk_sp<SkImageFilter> onMakeColorSpace(SkColorSpaceXformer*) const override {
91fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return sk_ref_sp(const_cast<IdentityImageFilter*>(this));
92fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
93fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
94fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate:
95fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    IdentityImageFilter(sk_sp<SkImageFilter> input) : INHERITED(&input, 1, nullptr) {}
96fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
97fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    typedef SkImageFilter INHERITED;
98fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
99fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic IdentityImageFilter::Registrar gReg1;
101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotsk_sp<SkFlattenable> IdentityImageFilter::CreateProc(SkReadBuffer& buffer) {
103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return IdentityImageFilter::Make(common.getInput(0));
105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifndef SK_IGNORE_TO_STRING
108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid IdentityImageFilter::toString(SkString* str) const {
109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    str->appendf("IdentityImageFilter: (");
110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    str->append(")");
111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif
113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot///////////////////////////////////////////////////////////////////////////////
115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void draw_paint(SkCanvas* canvas, const SkRect& r, sk_sp<SkImageFilter> imf) {
117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPaint paint;
118fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    paint.setImageFilter(std::move(imf));
119fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    paint.setColor(SK_ColorGREEN);
120fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    canvas->save();
121fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    canvas->clipRect(r);
122fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    canvas->drawPaint(paint);
123fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    canvas->restore();
124fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
125fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
126fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void draw_line(SkCanvas* canvas, const SkRect& r, sk_sp<SkImageFilter> imf) {
127fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPaint paint;
128fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    paint.setColor(SK_ColorBLUE);
129fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    paint.setImageFilter(imf);
130fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    paint.setStrokeWidth(r.width()/10);
131fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    canvas->drawLine(r.fLeft, r.fTop, r.fRight, r.fBottom, paint);
132fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
133fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
134fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void draw_rect(SkCanvas* canvas, const SkRect& r, sk_sp<SkImageFilter> imf) {
135fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPaint paint;
136fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    paint.setColor(SK_ColorYELLOW);
137fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    paint.setImageFilter(imf);
138fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkRect rr(r);
139fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    rr.inset(r.width()/10, r.height()/10);
140fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    canvas->drawRect(rr, paint);
141fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
142fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
143fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void draw_path(SkCanvas* canvas, const SkRect& r, sk_sp<SkImageFilter> imf) {
144fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPaint paint;
145fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    paint.setColor(SK_ColorMAGENTA);
146fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    paint.setImageFilter(imf);
147fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    paint.setAntiAlias(true);
148fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    canvas->drawCircle(r.centerX(), r.centerY(), r.width()*2/5, paint);
149fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
150fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
151fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void draw_text(SkCanvas* canvas, const SkRect& r, sk_sp<SkImageFilter> imf) {
152fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPaint paint;
153fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    paint.setImageFilter(imf);
154fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    paint.setColor(SK_ColorCYAN);
155fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    paint.setAntiAlias(true);
156fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    sk_tool_utils::set_portable_typeface(&paint);
157fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    paint.setTextSize(r.height()/2);
158fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    paint.setTextAlign(SkPaint::kCenter_Align);
159fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    canvas->drawString("Text", r.centerX(), r.centerY(), paint);
160fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
161fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
162fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void draw_bitmap(SkCanvas* canvas, const SkRect& r, sk_sp<SkImageFilter> imf) {
163fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPaint paint;
164fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    paint.setImageFilter(std::move(imf));
165fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
166fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkIRect bounds;
167fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    r.roundOut(&bounds);
168fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
169fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkBitmap bm;
170fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bm.allocN32Pixels(bounds.width(), bounds.height());
171fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bm.eraseColor(SK_ColorTRANSPARENT);
172fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkCanvas c(bm);
173fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    draw_path(&c, r, nullptr);
174fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
175fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    canvas->drawBitmap(bm, 0, 0, &paint);
176fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
177fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
178fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot///////////////////////////////////////////////////////////////////////////////
179fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
180fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass ImageFiltersBaseGM : public skiagm::GM {
181fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
182fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    ImageFiltersBaseGM () {}
183fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
184fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprotected:
185fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkString onShortName() override {
186fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return SkString("imagefiltersbase");
187fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
188fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
189fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkISize onISize() override { return SkISize::Make(700, 500); }
190fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
191fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void draw_frame(SkCanvas* canvas, const SkRect& r) {
192fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPaint paint;
193fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        paint.setStyle(SkPaint::kStroke_Style);
194fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        paint.setColor(SK_ColorRED);
195fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        canvas->drawRect(r, paint);
196fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
197fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
198fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void onDraw(SkCanvas* canvas) override {
199fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        void (*drawProc[])(SkCanvas*, const SkRect&, sk_sp<SkImageFilter>) = {
200fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            draw_paint,
201fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            draw_line, draw_rect, draw_path, draw_text,
202fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            draw_bitmap,
203fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        };
204fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
205fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        auto cf = SkColorFilter::MakeModeFilter(SK_ColorRED, SkBlendMode::kSrcIn);
206fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        sk_sp<SkImageFilter> filters[] = {
207fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            nullptr,
208fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            IdentityImageFilter::Make(nullptr),
209fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            FailImageFilter::Make(),
210fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkColorFilterImageFilter::Make(std::move(cf), nullptr),
211fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            // The strage 0.29 value tickles an edge case where crop rect calculates
212fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            // a small border, but the blur really needs no border. This tickels
213fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            // an msan uninitialized value bug.
214fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkBlurImageFilter::Make(12.0f, 0.29f, nullptr),
215fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkDropShadowImageFilter::Make(
216fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                    10.0f, 5.0f, 3.0f, 3.0f, SK_ColorBLUE,
217fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                    SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode,
218fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                    nullptr),
219fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        };
220fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
221fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkRect r = SkRect::MakeWH(SkIntToScalar(64), SkIntToScalar(64));
222fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkScalar MARGIN = SkIntToScalar(16);
223fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkScalar DX = r.width() + MARGIN;
224fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkScalar DY = r.height() + MARGIN;
225fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
226fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        canvas->translate(MARGIN, MARGIN);
227fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for (size_t i = 0; i < SK_ARRAY_COUNT(drawProc); ++i) {
228fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            canvas->save();
229fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            for (size_t j = 0; j < SK_ARRAY_COUNT(filters); ++j) {
230fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                drawProc[i](canvas, r, filters[j]);
231fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
232fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                draw_frame(canvas, r);
233fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                canvas->translate(0, DY);
234fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
235fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            canvas->restore();
236fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            canvas->translate(DX, 0);
237fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
238fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
239fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
240fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate:
241fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    typedef GM INHERITED;
242fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
243fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_GM( return new ImageFiltersBaseGM; )
244fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
245fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot///////////////////////////////////////////////////////////////////////////////
246fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
247fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/*
248fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *  Want to test combos of filter and LCD text, to be sure we disable LCD in the presence of
249fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *  a filter.
250fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */
251fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass ImageFiltersTextBaseGM : public skiagm::GM {
252fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkString fSuffix;
253fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
254fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    ImageFiltersTextBaseGM(const char suffix[]) : fSuffix(suffix) {}
255fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
256fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprotected:
257fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkString onShortName() override {
258fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkString name;
259fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        name.printf("%s_%s", "textfilter", fSuffix.c_str());
260fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return name;
261fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
262fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
263fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkISize onISize() override { return SkISize::Make(512, 342); }
264fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
265fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void drawWaterfall(SkCanvas* canvas, const SkPaint& origPaint) {
266fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const uint32_t flags[] = {
267fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            0,
268fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkPaint::kAntiAlias_Flag,
269fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkPaint::kAntiAlias_Flag | SkPaint::kLCDRenderText_Flag,
270fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        };
271fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPaint paint(origPaint);
272fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        sk_tool_utils::set_portable_typeface(&paint);
273fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        paint.setTextSize(30);
274fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
275fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkAutoCanvasRestore acr(canvas, true);
276fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for (size_t i = 0; i < SK_ARRAY_COUNT(flags); ++i) {
277fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            paint.setFlags(flags[i]);
278fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            canvas->drawString("Hamburgefon", 0, 0, paint);
279fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            canvas->translate(0, 40);
280fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
281fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
282fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
283fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    virtual void installFilter(SkPaint* paint) = 0;
284fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
285fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void onDraw(SkCanvas* canvas) override {
286fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPaint paint;
287fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
288fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        canvas->translate(20, 40);
289fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
290fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for (int doSaveLayer = 0; doSaveLayer <= 1; ++doSaveLayer) {
291fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkAutoCanvasRestore acr(canvas, true);
292fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            for (int useFilter = 0; useFilter <= 1; ++useFilter) {
293fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                SkAutoCanvasRestore acr2(canvas, true);
294fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
295fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                SkPaint paint;
296fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (useFilter) {
297fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    this->installFilter(&paint);
298fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
299fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (doSaveLayer) {
300fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    canvas->saveLayer(nullptr, &paint);
301fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    paint.setImageFilter(nullptr);
302fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
303fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                this->drawWaterfall(canvas, paint);
304fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
305fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                acr2.restore();
306fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                canvas->translate(250, 0);
307fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
308fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            acr.restore();
309fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            canvas->translate(0, 200);
310fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
311fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
312fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
313fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate:
314fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    typedef GM INHERITED;
315fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
316fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
317fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass ImageFiltersText_IF : public ImageFiltersTextBaseGM {
318fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
319fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    ImageFiltersText_IF() : ImageFiltersTextBaseGM("image") {}
320fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
321fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void installFilter(SkPaint* paint) override {
322fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        paint->setImageFilter(SkBlurImageFilter::Make(1.5f, 1.5f, nullptr));
323fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
324fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
325fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_GM( return new ImageFiltersText_IF; )
326fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
327fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass ImageFiltersText_CF : public ImageFiltersTextBaseGM {
328fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
329fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    ImageFiltersText_CF() : ImageFiltersTextBaseGM("color") {}
330fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
331fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void installFilter(SkPaint* paint) override {
332fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        paint->setColorFilter(SkColorFilter::MakeModeFilter(SK_ColorBLUE, SkBlendMode::kSrcIn));
333fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
334fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
335fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_GM( return new ImageFiltersText_CF; )
336