1 /*
2 * Copyright (c) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "ge_linear_gradient_shader_mask.h"
16
17 #include "ge_log.h"
18 #include "ge_system_properties.h"
19
20 namespace OHOS {
21 namespace Rosen {
22 namespace Drawing {
23
GELinearGradientShaderMask(const GELinearGradientShaderMaskParams & params)24 GELinearGradientShaderMask::GELinearGradientShaderMask(const GELinearGradientShaderMaskParams& params)
25 : fractionStops_(params.fractionStops), startPos_(params.startPosition), endPos_(params.endPosition)
26 {
27 }
28
GenerateDrawingShader(float width,float height) const29 std::shared_ptr<ShaderEffect> GELinearGradientShaderMask::GenerateDrawingShader(float width, float height) const
30 {
31 std::vector<Drawing::ColorQuad> c;
32 std::vector<Drawing::scalar> p;
33 if (fractionStops_.empty()) {
34 LOGE("GELinearGradientShaderMask::GenerateDrawingShader invalid fractionStops size");
35 return nullptr;
36 }
37
38 uint8_t ColorMax = 255;
39 uint8_t ColorMin = 0;
40 LOGD("GELinearGradientShaderMask::GenerateDrawingShader %{public}f, %{public}f, %{public}f, %{public}f, "
41 "%{public}f, %{public}f, %{public}d",
42 width,
43 height,
44 static_cast<float>(startPos_.GetX()),
45 static_cast<float>(startPos_.GetY()),
46 static_cast<float>(endPos_.GetX()),
47 static_cast<float>(endPos_.GetY()),
48 static_cast<int>(fractionStops_.size()));
49 constexpr double bias = 0.01; // 0.01 represents the fraction bias
50 if (fractionStops_.front().second > bias) {
51 c.emplace_back(Drawing::Color::ColorQuadSetARGB(ColorMin, ColorMin, ColorMin, ColorMin));
52 p.emplace_back(fractionStops_[0].second - bias);
53 }
54
55 for (const auto& [color, stop] : fractionStops_) {
56 uint8_t alpha = static_cast<uint8_t>(color * ColorMax);
57 c.emplace_back(Drawing::Color::ColorQuadSetARGB(alpha, ColorMax, ColorMax, ColorMax));
58 p.emplace_back(stop);
59 }
60 if (fractionStops_.back().second < (1 - bias)) {
61 c.emplace_back(Drawing::Color::ColorQuadSetARGB(ColorMin, ColorMax, ColorMax, ColorMax));
62 p.emplace_back(fractionStops_.back().second + bias);
63 }
64 return Drawing::ShaderEffect::CreateLinearGradient(startPos_, endPos_, c, p, Drawing::TileMode::CLAMP);
65 }
66
GenerateDrawingShaderHasNormal(float width,float height) const67 std::shared_ptr<ShaderEffect> GELinearGradientShaderMask::GenerateDrawingShaderHasNormal(float width,
68 float height) const
69 {
70 std::vector<Drawing::ColorQuad> c;
71 std::vector<Drawing::scalar> p;
72 if (fractionStops_.empty()) {
73 LOGE("GELinearGradientShaderMask::GenerateDrawingShaderHasNormal invalid fractionStops size");
74 return nullptr;
75 }
76
77 uint8_t ColorMax = 255;
78 uint8_t ColorMin = 0;
79 LOGD("GELinearGradientShaderMask::GenerateDrawingShaderHasNormal %{public}f, %{public}f, %{public}f, "
80 "%{public}f, %{public}f, %{public}f, %{public}d",
81 width,
82 height,
83 static_cast<float>(startPos_.GetX()),
84 static_cast<float>(startPos_.GetY()),
85 static_cast<float>(endPos_.GetX()),
86 static_cast<float>(endPos_.GetY()),
87 static_cast<int>(fractionStops_.size()));
88 constexpr double bias = 0.01; // 0.01 represents the fraction bias
89 if (fractionStops_.front().second > bias) {
90 c.emplace_back(Drawing::Color::ColorQuadSetARGB(ColorMin, ColorMin, ColorMin, ColorMin));
91 p.emplace_back(fractionStops_[0].second - bias);
92 }
93
94 for (const auto& [color, stop] : fractionStops_) {
95 uint8_t alpha = static_cast<uint8_t>(color * ColorMax);
96 c.emplace_back(Drawing::Color::ColorQuadSetARGB(alpha, alpha, alpha, alpha));
97 p.emplace_back(stop);
98 }
99 if (fractionStops_.back().second < (1 - bias)) {
100 c.emplace_back(Drawing::Color::ColorQuadSetARGB(ColorMin, ColorMin, ColorMin, ColorMin));
101 p.emplace_back(fractionStops_.back().second + bias);
102 }
103 return Drawing::ShaderEffect::CreateLinearGradient(startPos_, endPos_, c, p, Drawing::TileMode::CLAMP);
104 }
105 }
106 }
107 }
108