1 /*
2 * Copyright (c) 2023 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 <cmath>
17 #include <utility>
18
19 #include "utils/round_rect.h"
20 #include "utils/scalar.h"
21
22 namespace OHOS {
23 namespace Rosen {
24 namespace Drawing {
ComputeMinScale(double rad1,double rad2,double limit,double curMin)25 static double ComputeMinScale(double rad1, double rad2, double limit, double curMin)
26 {
27 if ((rad1 + rad2) > limit) {
28 return std::min(curMin, limit / (rad1 + rad2));
29 }
30 return curMin;
31 }
32
ComputeRadii(double limit,double scale,float & radiiA,float & radiiB)33 static void ComputeRadii(double limit, double scale, float& radiiA, float& radiiB)
34 {
35 radiiA = static_cast<float>(static_cast<double>(radiiA * scale));
36 radiiB = static_cast<float>(static_cast<double>(radiiB * scale));
37
38 if (radiiA + radiiB > limit) {
39 float* minRadius = &radiiA;
40 float* maxRadius = &radiiB;
41
42 if (*minRadius > *maxRadius) {
43 using std::swap;
44 swap(minRadius, maxRadius);
45 }
46
47 float newMinRadius = *minRadius;
48
49 float newMaxRadius = static_cast<float>(limit - newMinRadius);
50
51 while (newMaxRadius + newMinRadius > limit) {
52 newMaxRadius = nextafterf(newMaxRadius, 0.0f);
53 }
54 *maxRadius = newMaxRadius;
55 }
56 }
57
AdjustRadiiX(double limit,double scale,CornerPos cornerPosA,CornerPos cornerPosB)58 void RoundRect::AdjustRadiiX(double limit, double scale, CornerPos cornerPosA, CornerPos cornerPosB)
59 {
60 float radiiA = radiusXY_[cornerPosA].GetX();
61 float radiiB = radiusXY_[cornerPosB].GetX();
62
63 ComputeRadii(limit, scale, radiiA, radiiB);
64
65 radiusXY_[cornerPosA].SetX(radiiA);
66 radiusXY_[cornerPosB].SetX(radiiB);
67 }
68
AdjustRadiiY(double limit,double scale,CornerPos cornerPosA,CornerPos cornerPosB)69 void RoundRect::AdjustRadiiY(double limit, double scale, CornerPos cornerPosA, CornerPos cornerPosB)
70 {
71 float radiiA = radiusXY_[cornerPosA].GetY();
72 float radiiB = radiusXY_[cornerPosB].GetY();
73
74 ComputeRadii(limit, scale, radiiA, radiiB);
75
76 radiusXY_[cornerPosA].SetY(radiiA);
77 radiusXY_[cornerPosB].SetY(radiiB);
78 }
79
ClampToZero()80 bool RoundRect::ClampToZero()
81 {
82 bool allCornersSquare = true;
83
84 for (int i = 0; i < CORNER_NUMBER; ++i) {
85 if (radiusXY_[i].GetX() <= 0 || radiusXY_[i].GetY() <= 0) {
86 radiusXY_[i].SetX(0);
87 radiusXY_[i].SetY(0);
88 } else {
89 allCornersSquare = false;
90 }
91 }
92
93 return allCornersSquare;
94 }
95
ScaleRadii()96 bool RoundRect::ScaleRadii()
97 {
98 double scale = 1.0;
99 double width = static_cast<double>(rect_.GetWidth());
100 double height = static_cast<double>(rect_.GetHeight());
101 if (width <= 0 || height <= 0) {
102 return false;
103 }
104
105 scale = ComputeMinScale(radiusXY_[TOP_LEFT_POS].GetX(), radiusXY_[TOP_RIGHT_POS].GetX(), width, scale);
106 scale = ComputeMinScale(radiusXY_[TOP_RIGHT_POS].GetY(), radiusXY_[BOTTOM_RIGHT_POS].GetY(), height, scale);
107 scale = ComputeMinScale(radiusXY_[BOTTOM_RIGHT_POS].GetX(), radiusXY_[BOTTOM_LEFT_POS].GetX(), width, scale);
108 scale = ComputeMinScale(radiusXY_[BOTTOM_LEFT_POS].GetY(), radiusXY_[TOP_LEFT_POS].GetY(), height, scale);
109 if (scale < 1.0) {
110 AdjustRadiiX(width, scale, TOP_LEFT_POS, TOP_RIGHT_POS);
111 AdjustRadiiY(height, scale, TOP_RIGHT_POS, BOTTOM_RIGHT_POS);
112 AdjustRadiiX(width, scale, BOTTOM_RIGHT_POS, BOTTOM_LEFT_POS);
113 AdjustRadiiY(height, scale, BOTTOM_LEFT_POS, TOP_LEFT_POS);
114 }
115
116 ClampToZero();
117
118 return scale < 1.0;
119 }
120 } // namespace Drawing
121 } // namespace Rosen
122 } // namespace OHOS