From: JunsuChoi Date: Thu, 9 Dec 2021 00:50:46 +0000 (+0900) Subject: lottiemodel: Improve opacity calculation for gradient stop X-Git-Tag: submit/tizen_6.5/20211215.043506^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c22c860428f3ff9d48e5e6c6538f59cb7ce98e07;p=platform%2Fcore%2Fuifw%2Flottie-player.git lottiemodel: Improve opacity calculation for gradient stop Basically, Graeidnt stop's color and opacity are provided as separate arrays. Stop position and opacity position do not match each other. Existing code is a sequential approach. It caused problems in various cases of positions. The improved logic repeats the loop, but no exceptions are raised. It's not complicated, it's simple. This code referenced the lottie-android library. https://github.com/airbnb/lottie-android/blob/master/lottie/src/main/java/com/airbnb/lottie/parser/GradientColorParser.java Change-Id: Ie4e45b04dd8ef4d951d8177cb204b612760e6bda --- diff --git a/src/lottie/lottiemodel.cpp b/src/lottie/lottiemodel.cpp index 9da82f7..1bca99d 100644 --- a/src/lottie/lottiemodel.cpp +++ b/src/lottie/lottiemodel.cpp @@ -256,52 +256,12 @@ void model::Gradient::populate(VGradientStops &stops, int frameNo) auto opacityArraySize = size - colorPoints * 4; float *opacityPtr = ptr + (colorPoints * 4); stops.clear(); - size_t j = 0; for (int i = 0; i < colorPoints; i++) { float colorStop = ptr[0]; model::Color color = model::Color(ptr[1], ptr[2], ptr[3]); if (opacityArraySize) { - if (j == opacityArraySize) { - // already reached the end - float stop1 = opacityPtr[j - 4]; - float op1 = opacityPtr[j - 3]; - float stop2 = opacityPtr[j - 2]; - float op2 = opacityPtr[j - 1]; - if (colorStop > stop2) { - stops.push_back( - std::make_pair(colorStop, color.toColor(op2))); - } else { - float progress = (colorStop - stop1) / (stop2 - stop1); - float opacity = op1 + progress * (op2 - op1); - stops.push_back( - std::make_pair(colorStop, color.toColor(opacity))); - } - continue; - } - for (; j < opacityArraySize; j += 2) { - float opacityStop = opacityPtr[j]; - if (opacityStop < colorStop) { - // add a color using opacity stop - stops.push_back(std::make_pair( - opacityStop, color.toColor(opacityPtr[j + 1]))); - continue; - } - // add a color using color stop - if (j == 0) { - stops.push_back(std::make_pair( - colorStop, color.toColor(opacityPtr[j + 1]))); - } else { - float progress = (colorStop - opacityPtr[j - 2]) / - (opacityPtr[j] - opacityPtr[j - 2]); - float opacity = - opacityPtr[j - 1] + - progress * (opacityPtr[j + 1] - opacityPtr[j - 1]); - stops.push_back( - std::make_pair(colorStop, color.toColor(opacity))); - } - j += 2; - break; - } + float opacity = getOpacityAtPosition(opacityPtr, opacityArraySize, colorStop); + stops.push_back(std::make_pair(colorStop, color.toColor(opacity))); } else { stops.push_back(std::make_pair(colorStop, color.toColor())); } @@ -309,6 +269,21 @@ void model::Gradient::populate(VGradientStops &stops, int frameNo) } } +float model::Gradient::getOpacityAtPosition(float *opacities, size_t opacityArraySize, float position) +{ + for (size_t i = 2; i < opacityArraySize; i += 2) + { + float lastPosition = opacities[i - 2]; + float thisPosition = opacities[i]; + if (opacities[i] >= position) { + float progress = (position - lastPosition) / (thisPosition - lastPosition); + progress = progress < 0.0f ? 0.0f : 1.0f < progress ? 1.0f : progress; //clamp(progress, 0, 1) + return opacities[i - 1] + progress * (opacities[i + 1] - opacities[i - 1]); + } + } + return 0.0f; +} + void model::Gradient::update(std::unique_ptr &grad, int frameNo) { bool init = false; diff --git a/src/lottie/lottiemodel.h b/src/lottie/lottiemodel.h index c6b8cf6..cf87adb 100644 --- a/src/lottie/lottiemodel.h +++ b/src/lottie/lottiemodel.h @@ -821,6 +821,7 @@ public: private: void populate(VGradientStops &stops, int frameNo); + float getOpacityAtPosition(float *opacities, size_t opacityArraySize, float position); public: int mGradientType{1}; /* "t" Linear=1 , Radial = 2*/