xref: /aosp_15_r20/external/skia/modules/sksg/src/SkSGGradient.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2018 Google Inc.
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 "modules/sksg/include/SkSGGradient.h"
9 
10 #include "include/core/SkColorSpace.h"
11 #include "include/core/SkShader.h"
12 #include "include/effects/SkGradientShader.h"
13 #include "include/private/base/SkAssert.h"
14 #include "include/private/base/SkTPin.h"
15 #include "include/private/base/SkTo.h"
16 
17 namespace sksg {
18 
onRevalidateShader()19 sk_sp<SkShader> Gradient::onRevalidateShader() {
20     if (fColorStops.empty()) {
21         return nullptr;
22     }
23 
24     std::vector<SkColor4f> colors;
25     std::vector<SkScalar>  positions;
26     colors.reserve(fColorStops.size());
27     positions.reserve(fColorStops.size());
28 
29     SkScalar position = 0;
30     for (const auto& stop : fColorStops) {
31         colors.push_back(stop.fColor);
32         position = SkTPin(stop.fPosition, position, 1.0f);
33         positions.push_back(position);
34     }
35 
36     // TODO: detect even stop distributions, pass null for positions.
37     return this->onMakeShader(colors, positions);
38 }
39 
onMakeShader(const std::vector<SkColor4f> & colors,const std::vector<SkScalar> & positions) const40 sk_sp<SkShader> LinearGradient::onMakeShader(const std::vector<SkColor4f>& colors,
41                                              const std::vector<SkScalar >& positions) const {
42     SkASSERT(colors.size() == positions.size());
43 
44     const SkPoint pts[] = { fStartPoint, fEndPoint };
45     return SkGradientShader::MakeLinear(pts, colors.data(), nullptr, positions.data(),
46                                         SkToInt(colors.size()), this->getTileMode());
47 }
48 
onMakeShader(const std::vector<SkColor4f> & colors,const std::vector<SkScalar> & positions) const49 sk_sp<SkShader> RadialGradient::onMakeShader(const std::vector<SkColor4f>& colors,
50                                              const std::vector<SkScalar >& positions) const {
51     SkASSERT(colors.size() == positions.size());
52 
53     return (fStartRadius <= 0 && fStartCenter == fEndCenter)
54         ? SkGradientShader::MakeRadial(fEndCenter, fEndRadius,
55                                        colors.data(), nullptr, positions.data(),
56                                        SkToInt(colors.size()), this->getTileMode())
57         : SkGradientShader::MakeTwoPointConical(fStartCenter, fStartRadius,
58                                                 fEndCenter, fEndRadius,
59                                                 colors.data(), nullptr, positions.data(),
60                                                 SkToInt(colors.size()), this->getTileMode());
61 }
62 
63 } //namespace sksg
64