1 /* 2 * Copyright (c) 2021-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 #ifndef RENDER_SERVICE_CLIENT_CORE_ANIMATION_RS_CUBIC_BEZIER_INTERPOLATOR_H 17 #define RENDER_SERVICE_CLIENT_CORE_ANIMATION_RS_CUBIC_BEZIER_INTERPOLATOR_H 18 19 #include "animation/rs_interpolator.h" 20 #include "platform/common/rs_log.h" 21 22 namespace OHOS { 23 namespace Rosen { 24 class RSCubicBezierInterpolator : public RSInterpolator { 25 public: RSCubicBezierInterpolator(float ctrx1,float ctry1,float ctrx2,float ctry2)26 explicit RSCubicBezierInterpolator(float ctrx1, float ctry1, float ctrx2, float ctry2) 27 : controllx1_(ctrx1), controlly1_(ctry1), controllx2_(ctrx2), controlly2_(ctry2) 28 {} 29 ~RSCubicBezierInterpolator() = default; 30 Interpolate(float input)31 float Interpolate(float input) const override 32 { 33 return GetCubicBezierValue(SEARCH_STEP * BinarySearch(input), controlly1_, controlly2_); 34 } Marshalling(Parcel & parcel)35 bool Marshalling(Parcel& parcel) const override 36 { 37 if (!parcel.WriteUint16(InterpolatorType::CUBIC_BEZIER)) { 38 ROSEN_LOGE("CubicBezierInterpolator::Marshalling, write type failed"); 39 return false; 40 } 41 if (!(parcel.WriteFloat(controllx1_) && parcel.WriteFloat(controlly1_) && parcel.WriteFloat(controllx2_) && 42 parcel.WriteFloat(controlly2_))) { 43 ROSEN_LOGE("CubicBezierInterpolator::Marshalling, write value failed"); 44 return false; 45 } 46 return true; 47 } Unmarshalling(Parcel & parcel)48 [[nodiscard]] static RSCubicBezierInterpolator* Unmarshalling(Parcel& parcel) 49 { 50 float x1 = 0; 51 float y1 = 0; 52 float x2 = 0; 53 float y2 = 0; 54 if (!(parcel.ReadFloat(x1) && parcel.ReadFloat(y1) && parcel.ReadFloat(x2) && parcel.ReadFloat(y2))) { 55 ROSEN_LOGE("CubicBezierInterpolator::Unmarshalling, read failed"); 56 return nullptr; 57 } 58 return new RSCubicBezierInterpolator(x1, y1, x2, y2); 59 } 60 61 private: GetCubicBezierValue(const float time,const float ctr1,const float ctr2)62 float GetCubicBezierValue(const float time, const float ctr1, const float ctr2) const 63 { 64 return THIRD_RDER * (1.0f - time) * (1.0f - time) * time * ctr1 + 65 THIRD_RDER * (1.0f - time) * time * time * ctr2 + time * time * time; 66 } 67 BinarySearch(float key)68 int BinarySearch(float key) const 69 { 70 int low = 0; 71 int high = MAX_RESOLUTION; 72 int middle; 73 float approximation; 74 while (low <= high) { 75 middle = (low + high) / 2; 76 approximation = GetCubicBezierValue(SEARCH_STEP * middle, controllx1_, controllx2_); 77 if (approximation < key) { 78 low = middle + 1; 79 } else { 80 high = middle - 1; 81 } 82 if (fabs(approximation - key) <= 1e-6) { 83 return middle; 84 } 85 } 86 return low; 87 } 88 89 constexpr static int MAX_RESOLUTION = 4000; 90 constexpr static float SEARCH_STEP = 1.0f / MAX_RESOLUTION; 91 constexpr static int THIRD_RDER = 3.0; 92 93 float controllx1_; 94 float controlly1_; 95 float controllx2_; 96 float controlly2_; 97 }; 98 } // namespace Rosen 99 } // namespace OHOS 100 101 #endif // RENDER_SERVICE_CLIENT_CORE_ANIMATION_RS_CUBIC_BEZIER_INTERPOLATOR_H 102