• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 "injector_utils.h"
17 
18 #include <iostream>
19 #include <map>
20 
21 namespace OHOS {
22 namespace Ace {
23 namespace {
24 constexpr int32_t TIME_TRANSITION = 1000;
25 } // namespace
26 
27 bool InjectorUtils::debugEnabled_ = false;
28 
GetSysClockTime()29 int64_t InjectorUtils::GetSysClockTime()
30 {
31     struct timespec ts = { 0, 0 };
32     if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) {
33         return 0;
34     }
35     return (ts.tv_sec * TIME_TRANSITION * TIME_TRANSITION) + (ts.tv_nsec / TIME_TRANSITION);
36 }
37 
CalculateNextPosValueWithLinear(int32_t startPoint,int32_t targetPoint,int32_t currentIndex,int32_t totalCount)38 int32_t InjectorUtils::CalculateNextPosValueWithLinear(
39     int32_t startPoint, int32_t targetPoint, int32_t currentIndex, int32_t totalCount)
40 {
41     if (totalCount < 1) {
42         std::cout << "too few total count" << std::endl;
43         return -1;
44     }
45 
46     if (targetPoint == startPoint) {
47         // no moving
48         return targetPoint;
49     }
50 
51     auto distance = targetPoint - startPoint;
52     auto possitive = (distance > 0) ? 1 : -1; // possitive means increasing
53     // distance step
54     float absStep = static_cast<float>(std::abs(distance)) / totalCount;
55     // one px at least
56     absStep = (absStep == 0) ? 1 : absStep;
57     int32_t result = startPoint + static_cast<float>((absStep * (currentIndex + 1)) * possitive);
58     if (possitive > 0) {
59         result = (result > targetPoint) ? targetPoint : result;
60     } else {
61         result = (result < targetPoint) ? targetPoint : result;
62     }
63     return result;
64 }
65 
Combination(int n,int k)66 int InjectorUtils::Combination(int n, int k)
67 {
68     double result = 1.0;
69     for (int i = 1; i <= k; ++i) {
70         result *= static_cast<double>(n - i + 1) / i;
71     }
72     return result;
73 }
74 
BezierCurve(const std::vector<Point> & controlPoints,double t)75 Point InjectorUtils::BezierCurve(const std::vector<Point>& controlPoints, double t)
76 {
77     Point result = { 0.0, 0.0 };
78     size_t count = controlPoints.size();
79     if (count <= 1) {
80         std::cout << "too few control points" << std::endl;
81         return result;
82     }
83 
84     size_t n = count - 1;
85 
86     for (size_t i = 0; i <= n; ++i) {
87         double coeff = static_cast<double>(Combination(n, i)) * pow(t, i) * pow(1 - t, n - i);
88         result.x += coeff * controlPoints[i].x;
89         result.y += coeff * controlPoints[i].y;
90     }
91 
92     return result;
93 }
94 
95 // cubic: x < 0.5 ? 4 * x * x * x : 1 - pow(-2 * x + 2, 3) / 2
EaseInOutCubic(double t)96 static double EaseInOutCubic(double t)
97 {
98     const double c1 = 0.5;
99     const int c2 = 4;
100     const int c3 = -2;
101     const int c4 = 2;
102     const int c5 = 3;
103     const int c6 = 2;
104     return (t < c1) ? (c2 * t * t * t) : (1 - pow(c3 * t + c4, c5) / c6);
105 }
106 
107 // quart: x < 0.5 ? 8 * x * x * x * x : 1 - pow(-2 * x + 2, 4) / 2
EaseInOutQuart(double t)108 static double EaseInOutQuart(double t)
109 {
110     const double c1 = 0.5;
111     const int c2 = 8;
112     const int c3 = -2;
113     const int c4 = 2;
114     const int c5 = 4;
115     const int c6 = 2;
116     return (t < c1) ? (c2 * t * t * t * t) : (1 - pow(c3 * t + c4, c5) / c6);
117 }
118 
EaseInOut(double t,EaseAlgorithm algorithm)119 double InjectorUtils::EaseInOut(double t, EaseAlgorithm algorithm)
120 {
121     static const std::map<EaseAlgorithm, double (*)(double)> easeAlgorithmMap = {
122         { EaseAlgorithm::CUBIC, EaseInOutCubic }, { EaseAlgorithm::QUART, EaseInOutQuart }
123     };
124     return easeAlgorithmMap.at(algorithm)(t);
125 }
126 
CalculateNextPosValueWithBezier(std::vector<Point> & controlPoints,int32_t currentIndex,int32_t totalCount,CoordinateCurve curve)127 Point InjectorUtils::CalculateNextPosValueWithBezier(
128     std::vector<Point>& controlPoints, int32_t currentIndex, int32_t totalCount, CoordinateCurve curve)
129 {
130     Point result;
131     if (currentIndex < 0 || currentIndex > totalCount || totalCount < 1) {
132         std::cout << "wrong count given: currentIndex " << currentIndex << ", totalCount " << totalCount << std::endl;
133         return result;
134     }
135 
136     if (controlPoints.empty()) {
137         std::cout << "start and target point need be given at least" << std::endl;
138         return result;
139     }
140 
141     double t = static_cast<double>(currentIndex) / totalCount;
142     if (curve == CoordinateCurve::EASE_IN_OUT) {
143         t = EaseInOut(t, EaseAlgorithm::QUART);
144     }
145     return BezierCurve(controlPoints, t);
146 }
147 } // namespace Ace
148 } // namespace OHOS
149