aboutsummaryrefslogtreecommitdiffhomepage
path: root/gm/blurignorexform.cpp
blob: 1e89dec68133f84af2b5ea5c54632e4e2a7e87ac (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/*
 * Copyright 2017 Google Inc.
 *
 * Use of this source code is governed by a BD-style license that can be
 * found in the LICENSE file.
 */

#include "gm.h"
#include "sk_tool_utils.h"

#include "SkBlurMask.h"
#include "SkCanvas.h"
#include "SkMaskFilter.h"
#include "SkPaint.h"

// This GM tests out the SkBlurMaskFilter's kIgnoreTransform flag. That flag causes the blur mask
// filter to not apply the CTM to the blur's radius.
class BlurIgnoreXformGM : public skiagm::GM {
public:
    enum class DrawType {
        kCircle,
        kRect,
        kRRect,
    };

    BlurIgnoreXformGM(DrawType drawType) : fDrawType(drawType) { }

protected:
    bool runAsBench() const override { return true; }

    SkString onShortName() override {
        SkString name;
        name.printf("blur_ignore_xform_%s",
                    DrawType::kCircle == fDrawType ? "circle"
                        : DrawType::kRect == fDrawType ? "rect" : "rrect");
        return name;
    }

    SkISize onISize() override {
        return SkISize::Make(375, 475);
    }

    void onOnceBeforeDraw() override {
        for (int i = 0; i < kNumBlurs; ++i) {
            fBlurFilters[i] = SkMaskFilter::MakeBlur(
                                    kNormal_SkBlurStyle,
                                    SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(20)),
                                    kBlurFlags[i].fRespectCTM);
        }
    }

    void onDraw(SkCanvas* canvas) override {
        SkPaint paint;
        paint.setColor(SK_ColorBLACK);
        paint.setAntiAlias(true);

        canvas->translate(10, 25);
        canvas->save();
        canvas->translate(80, 0);
        for (size_t i = 0; i < kNumBlurs; ++i) {
            SkAutoCanvasRestore autoRestore(canvas, true);
            canvas->translate(SkIntToScalar(i * 150), 0);
            for (auto scale : kMatrixScales) {
                canvas->save();
                canvas->scale(scale.fScale, scale.fScale);
                static const SkScalar kRadius = 20.0f;
                SkScalar coord = 50.0f * 1.0f / scale.fScale;
                SkRect rect = SkRect::MakeXYWH(coord - kRadius , coord - kRadius,
                                               2 * kRadius, 2 * kRadius);
                SkRRect rrect = SkRRect::MakeRectXY(rect, kRadius/2.0f, kRadius/2.0f);

                paint.setMaskFilter(fBlurFilters[i]);
                for (int j = 0; j < 2; ++j) {
                    canvas->save();
                    canvas->translate(10 * (1 - j), 10 * (1 - j));
                    if (DrawType::kCircle == fDrawType) {
                        canvas->drawCircle(coord, coord, kRadius, paint);
                    } else if (DrawType::kRect == fDrawType) {
                        canvas->drawRect(rect, paint);
                    } else {
                        canvas->drawRRect(rrect, paint);
                    }
                    paint.setMaskFilter(nullptr);
                    canvas->restore();
                }
                canvas->restore();
                canvas->translate(0, SkIntToScalar(150));
            }
        }
        canvas->restore();
        if (kBench_Mode != this->getMode()) {
            this->drawOverlay(canvas);
        }
    }

    void drawOverlay(SkCanvas* canvas) {
        canvas->translate(10, 0);
        SkPaint textPaint;
        sk_tool_utils::set_portable_typeface(&textPaint);
        textPaint.setAntiAlias(true);
        canvas->save();
        for (int i = 0; i < kNumBlurs; ++i) {
            canvas->drawString(kBlurFlags[i].fName, 100, 0, textPaint);
            canvas->translate(SkIntToScalar(130), 0);
        }
        canvas->restore();
        for (auto scale : kMatrixScales) {
            canvas->drawString(scale.fName, 0, 50, textPaint);
            canvas->translate(0, SkIntToScalar(150));
        }
    }

private:
    static constexpr int kNumBlurs = 2;

    static const struct BlurFlags {
        bool fRespectCTM;
        const char* fName;
    } kBlurFlags[kNumBlurs];

    static const struct MatrixScale {
        float fScale;
        const char* fName;
    } kMatrixScales[3];

    DrawType fDrawType;
    sk_sp<SkMaskFilter> fBlurFilters[kNumBlurs];

    typedef         skiagm::GM INHERITED;
};

const BlurIgnoreXformGM::BlurFlags BlurIgnoreXformGM::kBlurFlags[] = {
    {true, "none"},
    {false, "IgnoreTransform"}
};

const BlurIgnoreXformGM::MatrixScale BlurIgnoreXformGM::kMatrixScales[] = {
    {1.0f, "Identity"},
    {0.5f, "Scale = 0.5"},
    {2.0f, "Scale = 2.0"}
};

DEF_GM(return new BlurIgnoreXformGM(BlurIgnoreXformGM::DrawType::kCircle);)
DEF_GM(return new BlurIgnoreXformGM(BlurIgnoreXformGM::DrawType::kRect);)
DEF_GM(return new BlurIgnoreXformGM(BlurIgnoreXformGM::DrawType::kRRect);)