From: subhransu mohanty Date: Fri, 13 Jul 2018 07:30:44 +0000 (+0900) Subject: lottie/parser : Fixed proper parsing of opacity stops for gradient. X-Git-Tag: submit/tizen/20180917.042405~259 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F44%2F184044%2F2;p=platform%2Fcore%2Fuifw%2Flottie-player.git lottie/parser : Fixed proper parsing of opacity stops for gradient. Change-Id: I91a2a8f99c253fa0478ec8e8ffc76d5313fafa97 --- diff --git a/src/lottie/lottiemodel.cpp b/src/lottie/lottiemodel.cpp index e843008..29156e6 100644 --- a/src/lottie/lottiemodel.cpp +++ b/src/lottie/lottiemodel.cpp @@ -230,6 +230,83 @@ int LOTGStrokeData::getDashInfo(int frameNo, float *array) const } } +/** + * Both the color stops and opacity stops are in the same array. + * There are {@link #colorPoints} colors sequentially as: + * [ + * ..., + * position, + * red, + * green, + * blue, + * ... + * ] + * + * The remainder of the array is the opacity stops sequentially as: + * [ + * ..., + * position, + * opacity, + * ... + * ] + */ +void LOTGradient::populate(VGradientStops &stops, int frameNo) +{ + LottieGradient gradData = mGradient.value(frameNo); + int size = gradData.mGradient.size(); + float *ptr = gradData.mGradient.data(); + int colorPoints = mColorPoints; + if (colorPoints == -1 ) { // for legacy bodymovin (ref: lottie-android) + colorPoints = size / 4; + } + int opacityArraySize = size - colorPoints * 4; + float *opacityPtr = ptr + (colorPoints * 4); + stops.clear(); + int j = 0; + for (int i = 0; i < colorPoints ; i++) { + float colorStop = ptr[0]; + LottieColor color = LottieColor(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; + } + } else { + stops.push_back(std::make_pair(colorStop, color.toColor())); + } + ptr += 4; + } +} + void LOTGradient::update(std::unique_ptr &grad, int frameNo) { bool init = false; @@ -243,15 +320,7 @@ void LOTGradient::update(std::unique_ptr &grad, int frameNo) } if (!mGradient.isStatic() || init) { - LottieGradient gradData = mGradient.value(frameNo); - int size = gradData.mGradient.size(); - float *ptr = gradData.mGradient.data(); - grad->mStops.clear(); - for (int i = 0; i < size ; i += 4) { - float stop = ptr[i]; - LottieColor color = LottieColor(ptr[i+1], ptr[i+2], ptr[i+3]); - grad->mStops.push_back(std::make_pair(stop, color.toColor())); - } + populate(grad->mStops, frameNo); } if (mGradientType == 1) { //linear gradient diff --git a/src/lottie/lottiemodel.h b/src/lottie/lottiemodel.h index 9265dda..80cca54 100644 --- a/src/lottie/lottiemodel.h +++ b/src/lottie/lottiemodel.h @@ -555,17 +555,21 @@ inline LottieGradient operator*(float m, const LottieGradient &g) class LOTGradient : public LOTData { public: - LOTGradient(LOTData::Type type):LOTData(type){} + LOTGradient(LOTData::Type type):LOTData(type), mColorPoints(-1){} inline float opacity(int frameNo) const {return mOpacity.value(frameNo)/100.0;} void update(std::unique_ptr &grad, int frameNo); + +private: + void populate(VGradientStops &stops, int frameNo); public: int mGradientType; /* "t" Linear=1 , Radial = 2*/ - LOTAnimatable mStartPoint; /* "s" */ - LOTAnimatable mEndPoint; /* "e" */ + LOTAnimatable mStartPoint; /* "s" */ + LOTAnimatable mEndPoint; /* "e" */ LOTAnimatable mHighlightLength; /* "h" */ LOTAnimatable mHighlightAngle; /* "a" */ LOTAnimatable mOpacity; /* "o" */ LOTAnimatable mGradient; /* "g" */ + int mColorPoints; bool mEnabled = true; /* "fillEnabled" */ }; diff --git a/src/lottie/lottieparser.cpp b/src/lottie/lottieparser.cpp index 5ff3451..8905d50 100644 --- a/src/lottie/lottieparser.cpp +++ b/src/lottie/lottieparser.cpp @@ -1274,7 +1274,9 @@ LottieParserImpl::parseGradientProperty(LOTGradient *obj, const char *key) while (const char* key = NextObjectKey()) { if (0 == strcmp(key, "k")) { parseProperty(obj->mGradient); - } else { + } else if (0 == strcmp(key, "p")) { + obj->mColorPoints = GetInt(); + } else { Skip(nullptr); } }