xref: /aosp_15_r20/external/skia/gm/emptyshader.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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