| /* |
| * Copyright 2024 Google LLC |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #include "gm/gm.h" |
| |
| #include "include/core/SkCanvas.h" |
| #include "include/core/SkPaint.h" |
| #include "include/effects/SkGradientShader.h" |
| #include "src/shaders/SkEmptyShader.h" |
| |
| namespace skiagm { |
| |
| namespace { |
| |
| sk_sp<SkShader> empty(SkRect r) { return sk_make_sp<SkEmptyShader>(); } |
| |
| sk_sp<SkShader> degen_sweep(SkRect r) { |
| // A too small angle between start and end falls back to an empty shader |
| const float startAngle = 0.0f; |
| const float endAngle = nextafter(startAngle, 360.0f); |
| const SkColor colors[2] = { SK_ColorRED, SK_ColorGREEN }; |
| |
| return SkGradientShader::MakeSweep(r.centerX(), r.centerY(), |
| colors, |
| /* pos= */ nullptr, |
| std::size(colors), |
| SkTileMode::kDecal, |
| startAngle, endAngle, |
| /* flags= */ 0, |
| /* localMatrix= */ nullptr); |
| } |
| |
| sk_sp<SkShader> degen_linear(SkRect r) { |
| // Having the two positions be the same causes a fallback to an empty shader |
| const SkPoint pts[2] = { r.center(), r.center() }; |
| const SkColor colors[2] = { SK_ColorRED, SK_ColorGREEN }; |
| |
| return SkGradientShader::MakeLinear(pts, |
| colors, |
| /* pos= */ nullptr, |
| std::size(colors), |
| SkTileMode::kDecal); |
| } |
| |
| sk_sp<SkShader> degen_radial(SkRect r) { |
| const SkColor colors[2] = { SK_ColorRED, SK_ColorGREEN }; |
| |
| // Having a radius of 0.0 causes a fallback to an empty shader |
| return SkGradientShader::MakeRadial(r.center(), |
| /* radius= */ 0.0f, |
| colors, |
| /* pos= */ nullptr, |
| std::size(colors), |
| SkTileMode::kDecal); |
| } |
| |
| sk_sp<SkShader> degen_conical(SkRect r) { |
| const SkColor colors[2] = {SK_ColorRED, SK_ColorGREEN}; |
| |
| // Having the start and end radii be the same causes a fallback to an empty shader |
| return SkGradientShader::MakeTwoPointConical(r.center(), /* startRadius= */ 0.0f, |
| r.center(), /* endRadius= */ 0.0f, |
| colors, |
| /* pos= */ nullptr, |
| std::size(colors), |
| SkTileMode::kDecal); |
| } |
| |
| } // anonymous namespace |
| |
| class EmptyShaderGM : public GM { |
| public: |
| EmptyShaderGM() { |
| this->setBGColor(0xFFCCCCCC); |
| } |
| |
| protected: |
| SkString getName() const override { return SkString("emptyshader"); } |
| |
| SkISize getISize() override { return SkISize::Make(128, 88); } |
| |
| void onDraw(SkCanvas* canvas) override { |
| SkPaint stroke; |
| stroke.setStyle(SkPaint::kStroke_Style); |
| |
| int left = kPad, top = kPad; |
| for (auto f : { empty, degen_sweep, degen_linear, degen_radial, degen_conical }) { |
| SkRect r = SkRect::MakeXYWH(left, top, kSize, kSize); |
| |
| SkPaint p; |
| p.setColor(SK_ColorBLUE); |
| p.setShader(f(r)); |
| |
| canvas->drawRect(r, p); |
| canvas->drawRect(r, stroke); |
| |
| left += kSize + kPad; |
| if (left >= this->getISize().width()) { |
| left = kPad; |
| top += kSize + kPad; |
| } |
| } |
| } |
| |
| private: |
| static constexpr int kPad = 8; |
| static constexpr int kSize = 32; |
| }; |
| |
| ////////////////////////////////////////////////////////////////////////////// |
| |
| DEF_GM(return new EmptyShaderGM;) |
| |
| } // namespace skiagm |