From 3ea10ecbc98fb76dda26ea085b633c2b55d0d74b Mon Sep 17 00:00:00 2001 From: subhransu mohanty Date: Mon, 20 May 2019 14:28:20 +0900 Subject: [PATCH] lottie/parser: Fixed regression of interpolator string handling. With older bodymovin pluggins the interpolator cache string sometimes dosen't match with the in and out tangent results into wrong animation. So parse the interpolator string whenever available. --- src/lottie/lottieparser.cpp | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/src/lottie/lottieparser.cpp b/src/lottie/lottieparser.cpp index c9249b0169..bd38fbd0c1 100644 --- a/src/lottie/lottieparser.cpp +++ b/src/lottie/lottieparser.cpp @@ -260,7 +260,7 @@ public: void parseShapeProperty(LOTAnimatable &obj); void parseDashProperty(LOTDashProperty &dash); - std::shared_ptr interpolator(VPointF inTangent, VPointF outTangent); + std::shared_ptr interpolator(VPointF, VPointF, std::string); LottieColor toColor(const char *str); @@ -1840,20 +1840,21 @@ bool LottieParserImpl::parseKeyFrameValue(const char * key, } std::shared_ptr -LottieParserImpl::interpolator(VPointF inTangent, VPointF outTangent) +LottieParserImpl::interpolator(VPointF inTangent, VPointF outTangent, std::string key) { - std::array temp; - snprintf(temp.data(), temp.size(), "%.2f_%.2f_%.2f_%.2f", - inTangent.x(), inTangent.y(), outTangent.x(), outTangent.y()); - - std::string key(temp.data()); + if (key.empty()) { + std::array temp; + snprintf(temp.data(), temp.size(), "%.2f_%.2f_%.2f_%.2f", + inTangent.x(), inTangent.y(), outTangent.x(), outTangent.y()); + key = temp.data(); + } auto search = mInterpolatorCache.find(key); if (search != mInterpolatorCache.end()) { return search->second; } else { auto obj = std::make_shared(VInterpolator(outTangent, inTangent)); - mInterpolatorCache[key] = obj; + mInterpolatorCache[std::move(key)] = obj; return obj; } } @@ -1865,6 +1866,7 @@ template void LottieParserImpl::parseKeyFrame(LOTAnimInfo &obj) { struct ParsedField { + std::string interpolatorKey; bool interpolator{false}; bool value{false}; bool hold{false}; @@ -1893,6 +1895,23 @@ void LottieParserImpl::parseKeyFrame(LOTAnimInfo &obj) parsed.noEndValue = false; getValue(keyframe.mValue.mEndValue); continue; + } else if (0 == strcmp(key, "n")) { + if (PeekType() == kStringType) { + parsed.interpolatorKey = GetString(); + } else { + RAPIDJSON_ASSERT(PeekType() == kArrayType); + EnterArray(); + while (NextArrayValue()) { + RAPIDJSON_ASSERT(PeekType() == kStringType); + if (parsed.interpolatorKey.empty()) { + parsed.interpolatorKey = GetString(); + } else { + //skip rest of the string + GetString(); + } + } + } + continue; } else if (parseKeyFrameValue(key, keyframe.mValue)) { continue; } else if (0 == strcmp(key, "h")) { @@ -1921,7 +1940,7 @@ void LottieParserImpl::parseKeyFrame(LOTAnimInfo &obj) keyframe.mEndFrame = keyframe.mStartFrame; obj.mKeyFrames.push_back(keyframe); } else if (parsed.interpolator) { - keyframe.mInterpolator = interpolator(inTangent, outTangent); + keyframe.mInterpolator = interpolator(inTangent, outTangent, std::move(parsed.interpolatorKey)); obj.mKeyFrames.push_back(keyframe); } else { //its the last frame discard.