1 /*
2 * Copyright 2024 Google LLC
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/gm.h"
9
10 #include "include/core/SkCanvas.h"
11 #include "include/core/SkPaint.h"
12 #include "include/effects/SkGradientShader.h"
13 #include "src/shaders/SkEmptyShader.h"
14
15 namespace skiagm {
16
17 namespace {
18
empty(SkRect r)19 sk_sp<SkShader> empty(SkRect r) { return sk_make_sp<SkEmptyShader>(); }
20
degen_sweep(SkRect r)21 sk_sp<SkShader> degen_sweep(SkRect r) {
22 // A too small angle between start and end falls back to an empty shader
23 const float startAngle = 0.0f;
24 const float endAngle = nextafter(startAngle, 360.0f);
25 const SkColor colors[2] = { SK_ColorRED, SK_ColorGREEN };
26
27 return SkGradientShader::MakeSweep(r.centerX(), r.centerY(),
28 colors,
29 /* pos= */ nullptr,
30 std::size(colors),
31 SkTileMode::kDecal,
32 startAngle, endAngle,
33 /* flags= */ 0,
34 /* localMatrix= */ nullptr);
35 }
36
degen_linear(SkRect r)37 sk_sp<SkShader> degen_linear(SkRect r) {
38 // Having the two positions be the same causes a fallback to an empty shader
39 const SkPoint pts[2] = { r.center(), r.center() };
40 const SkColor colors[2] = { SK_ColorRED, SK_ColorGREEN };
41
42 return SkGradientShader::MakeLinear(pts,
43 colors,
44 /* pos= */ nullptr,
45 std::size(colors),
46 SkTileMode::kDecal);
47 }
48
degen_radial(SkRect r)49 sk_sp<SkShader> degen_radial(SkRect r) {
50 const SkColor colors[2] = { SK_ColorRED, SK_ColorGREEN };
51
52 // Having a radius of 0.0 causes a fallback to an empty shader
53 return SkGradientShader::MakeRadial(r.center(),
54 /* radius= */ 0.0f,
55 colors,
56 /* pos= */ nullptr,
57 std::size(colors),
58 SkTileMode::kDecal);
59 }
60
degen_conical(SkRect r)61 sk_sp<SkShader> degen_conical(SkRect r) {
62 const SkColor colors[2] = {SK_ColorRED, SK_ColorGREEN};
63
64 // Having the start and end radii be the same causes a fallback to an empty shader
65 return SkGradientShader::MakeTwoPointConical(r.center(), /* startRadius= */ 0.0f,
66 r.center(), /* endRadius= */ 0.0f,
67 colors,
68 /* pos= */ nullptr,
69 std::size(colors),
70 SkTileMode::kDecal);
71 }
72
73 } // anonymous namespace
74
75 class EmptyShaderGM : public GM {
76 public:
EmptyShaderGM()77 EmptyShaderGM() {
78 this->setBGColor(0xFFCCCCCC);
79 }
80
81 protected:
getName() const82 SkString getName() const override { return SkString("emptyshader"); }
83
getISize()84 SkISize getISize() override { return SkISize::Make(128, 88); }
85
onDraw(SkCanvas * canvas)86 void onDraw(SkCanvas* canvas) override {
87 SkPaint stroke;
88 stroke.setStyle(SkPaint::kStroke_Style);
89
90 int left = kPad, top = kPad;
91 for (auto f : { empty, degen_sweep, degen_linear, degen_radial, degen_conical }) {
92 SkRect r = SkRect::MakeXYWH(left, top, kSize, kSize);
93
94 SkPaint p;
95 p.setColor(SK_ColorBLUE);
96 p.setShader(f(r));
97
98 canvas->drawRect(r, p);
99 canvas->drawRect(r, stroke);
100
101 left += kSize + kPad;
102 if (left >= this->getISize().width()) {
103 left = kPad;
104 top += kSize + kPad;
105 }
106 }
107 }
108
109 private:
110 static constexpr int kPad = 8;
111 static constexpr int kSize = 32;
112 };
113
114 //////////////////////////////////////////////////////////////////////////////
115
116 DEF_GM(return new EmptyShaderGM;)
117
118 } // namespace skiagm
119