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
16 #include "bridge/declarative_frontend/jsview/canvas/js_canvas_util.h"
17
18 namespace OHOS::Ace::Framework {
ExtractInfoToRadii(const JSRef<JSVal> value,std::vector<double> & radii)19 bool ExtractInfoToRadii(const JSRef<JSVal> value, std::vector<double>& radii)
20 {
21 if (value->IsNull() || value->IsUndefined()) {
22 radii.emplace_back(0.0);
23 return true;
24 }
25 if (!value->IsNumber()) {
26 return false;
27 }
28 double radiusValue = value->ToNumber<double>();
29 if (LessNotEqual(radiusValue, 0.0)) {
30 JSException::Throw(
31 ERROR_CODE_CANVAS_PARAM_INVALID, "%s", "radii parameter error: The param radii contains negative value.");
32 return false;
33 }
34 radii.emplace_back(radiusValue);
35 return true;
36 }
37
ParseRadii(const JSCallbackInfo & info,std::vector<double> & radii)38 bool ParseRadii(const JSCallbackInfo& info, std::vector<double>& radii)
39 {
40 if (info[4]->IsArray()) { // 4: The fifth param is array.
41 JSRef<JSArray> array = JSRef<JSArray>::Cast(info[4]); // 4: The fifth param of roundRect
42 if ((array->Length() <= 0) || (array->Length() > 4)) { // The size of the fifth param > 4 or <= 0
43 JSException::Throw(ERROR_CODE_CANVAS_PARAM_INVALID, "%s",
44 "radii parameter error: The param radii is a list that has zero or more than four elements.");
45 return false;
46 }
47 for (uint32_t i = 0; i < array->Length(); ++i) {
48 JSRef<JSVal> value = array->GetValueAt(i);
49 if (!ExtractInfoToRadii(value, radii)) {
50 return false;
51 }
52 }
53 return true;
54 }
55 return ExtractInfoToRadii(info[4], radii); // 4: Parse the fifth param of roundRect
56 }
57
ParseRoundRect(const JSCallbackInfo & info,Rect & rect,std::vector<double> & radii,double density,bool isJudgeSpecialValue)58 bool ParseRoundRect(
59 const JSCallbackInfo& info, Rect& rect, std::vector<double>& radii, double density, bool isJudgeSpecialValue)
60 {
61 double x = 0.0;
62 double y = 0.0;
63 double width = 0.0;
64 double height = 0.0;
65 if (!((info.GetDoubleArg(0, x, isJudgeSpecialValue) || info[0]->IsNull()) && // 0: the 1st arg.
66 (info.GetDoubleArg(1, y, isJudgeSpecialValue) || info[1]->IsNull()) && // 1: the 2nd arg.
67 (info.GetDoubleArg(2, width, isJudgeSpecialValue) || info[2]->IsNull()) && // 2: the 3rd arg.
68 (info.GetDoubleArg(3, height, isJudgeSpecialValue) || info[3]->IsNull()))) { // 3: the 4th arg.
69 return false;
70 }
71 rect.SetRect(x, y, width, height);
72 if ((info.Length() >= 5) && !ParseRadii(info, radii)) { // 5: roundRect has the fifth param.
73 return false;
74 }
75 switch (radii.size()) {
76 case 0: // 0: The fifth param is not set.
77 radii = std::vector<double>(4, 0.0); // 4: four corners are 0.0.
78 break;
79 case 1: // 1: The fifth param has 1 values.
80 radii = std::vector<double>(4, radii[0] * density); // 4: four corners are radii[0].
81 break;
82 case 2: // 2: The fifth param has 2 values.
83 radii = {
84 radii[0] * density, radii[1] * density, // 0: top-left-and-bottom-right, 1: top-right-and-bottom-left.
85 radii[0] * density, radii[1] * density // 0: top-left-and-bottom-right, 1: top-right-and-bottom-left.
86 };
87 break;
88 case 3: // 3: The fifth param has 3 values.
89 radii = {
90 radii[0] * density, radii[1] * density, // 0: top-left, 1: top-right-and-bottom-left.
91 radii[2] * density, radii[1] * density // 2: bottom-right, 1: top-right-and-bottom-left.
92 };
93 break;
94 case 4: // 4: The fifth param has 4 values.
95 radii = {
96 radii[0] * density, radii[1] * density, // 0: top-left, 1: top-right.
97 radii[2] * density, radii[3] * density // 2: bottom-right, 3: bottom-left.
98 };
99 break;
100 default:
101 return false;
102 }
103 return true;
104 }
105 } // namespace OHOS::Ace::Framework