1 /*
2 * Copyright (c) 2021 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
16 #include "core/pipeline/layers/gradient_layer.h"
17
18 #include "flutter/lib/ui/painting/gradient.h"
19
20 namespace OHOS::Ace::Flutter {
21 namespace {
22
23 const size_t END_POINTS_COUNT = 4;
24
25 } // namespace
26
AddToScene(SceneBuilder & builder,double x,double y)27 void GradientLayer::AddToScene(SceneBuilder& builder, double x, double y)
28 {
29 bool pushSuccess = false;
30 if ((!points_.empty()) && (!colors_.empty()) && (points_.size() == colors_.size())) {
31 auto gradientShader = flutter::CanvasGradient::Create();
32
33 // Unfold first and last points position to a float list.
34 tonic::Float32List endPoints(END_POINTS_COUNT);
35 endPoints[0] = points_.front().GetX();
36 endPoints[1] = points_.front().GetY();
37 endPoints[2] = points_.back().GetX();
38 endPoints[3] = points_.back().GetY();
39
40 // Convert color list.
41 tonic::Int32List colorList(colors_.size());
42 for (size_t i = 0; i < colors_.size(); i++) {
43 colorList[i] = static_cast<int32_t>(colors_[i].GetValue());
44 }
45
46 // Calculate stop point position(from 0.0 to 1.0).
47 tonic::Float32List colorStops(points_.size());
48 auto endPositionTotal = points_.back().GetX() + points_.back().GetY();
49 for (size_t i = 0; i < points_.size(); i++) {
50 colorStops[i] = (points_[i].GetX() + points_[i].GetY()) / endPositionTotal;
51 }
52 tonic::Float64List matrix;
53 #ifdef USE_SYSTEM_SKIA
54 gradientShader->initLinear(endPoints, colorList, colorStops, SkShader::kClamp_TileMode, matrix);
55 #else
56 gradientShader->initLinear(endPoints, colorList, colorStops, SkTileMode::kClamp, matrix);
57 #endif
58 builder.PushShaderMask(gradientShader, x + x_ + rect_.Left(), x + x_ + rect_.Right(), y + y_ + rect_.Top(),
59 y + y_ + rect_.Bottom(), static_cast<int32_t>(blendMode_));
60 pushSuccess = true;
61 }
62 builder.PushOpacity(alpha_, 0, 0);
63 AddChildToScene(builder, x + x_, y + y_);
64 builder.Pop();
65 if (pushSuccess) {
66 builder.Pop();
67 }
68 }
69
70 } // namespace OHOS::Ace::Flutter
71