lottie/parser: Added support for separate position attribute in transform object. 75/186975/4
authorsubhransu mohanty <sub.mohanty@samsung.com>
Fri, 17 Aug 2018 04:06:57 +0000 (13:06 +0900)
committerSubhransu Mohanty <sub.mohanty@samsung.com>
Fri, 17 Aug 2018 06:33:43 +0000 (06:33 +0000)
Transform object can have separate x and y or a point object.

Change-Id: I0ad0073b3cb958336539ad520434c3284894c6b9

src/lottie/lottiemodel.cpp
src/lottie/lottiemodel.h
src/lottie/lottieparser.cpp

index 934b6ce..c119950 100644 (file)
@@ -76,7 +76,12 @@ void LOTTransformData::cacheMatrix()
 VMatrix LOTTransformData::computeMatrix(int frameNo) const
 {
     VMatrix m;
-    m.translate(mPosition.value(frameNo))
+    VPointF position = mPosition.value(frameNo);
+    if (mSeparate) {
+        position.setX(mX.value(frameNo));
+        position.setY(mY.value(frameNo));
+    }
+    m.translate(position)
         .rotate(mRotation.value(frameNo))
         .scale(mScale.value(frameNo) / 100.f)
         .translate(-mAnchor.value(frameNo));
index 69523b1..1321d92 100644 (file)
@@ -392,11 +392,14 @@ public:
     LOTAnimatable<float>     mRotation{0};  /* "r" */
     LOTAnimatable<VPointF>   mScale;     /* "s" */
     LOTAnimatable<VPointF>   mPosition;  /* "p" */
+    LOTAnimatable<float>     mX{0};
+    LOTAnimatable<float>     mY{0};
     LOTAnimatable<VPointF>   mAnchor;    /* "a" */
     LOTAnimatable<float>     mOpacity{100};   /* "o" */
     LOTAnimatable<float>     mSkew{0};      /* "sk" */
     LOTAnimatable<float>     mSkewAxis{0};  /* "sa" */
     bool                     mStaticMatrix{true};
+    bool                     mSeparate{false};
     VMatrix                  mCachedMatrix;
 };
 
index 39cad49..d4e6db3 100644 (file)
@@ -233,6 +233,8 @@ public:
     void parseKeyFrame(LOTAnimInfo<T> &obj);
     template <typename T>
     void parseProperty(LOTAnimatable<T> &obj);
+    template <typename T>
+    void parsePropertyHelper(LOTAnimatable<T> &obj);
 
     void parseShapeKeyFrame(LOTAnimInfo<LottieShapeData> &obj);
     void parseShapeProperty(LOTAnimatable<LottieShapeData> &obj);
@@ -1164,7 +1166,20 @@ std::shared_ptr<LOTTransformData> LottieParserImpl::parseTransformObject()
         if (0 == strcmp(key, "a")) {
             parseProperty(obj->mAnchor);
         } else if (0 == strcmp(key, "p")) {
-            parseProperty(obj->mPosition);
+            EnterObject();
+            while (const char *key = NextObjectKey()) {
+                if (0 == strcmp(key, "k")) {
+                    parsePropertyHelper(obj->mPosition);
+                } else if (0 == strcmp(key, "s")) {
+                    obj->mSeparate = GetBool();
+                } else if (obj->mSeparate && (0 == strcmp(key, "x"))) {
+                    parseProperty(obj->mX);
+                } else if (obj->mSeparate && (0 == strcmp(key, "y"))) {
+                    parseProperty(obj->mY);
+                }else {
+                    Skip(key);
+                }
+            }
         } else if (0 == strcmp(key, "r")) {
             parseProperty(obj->mRotation);
         } else if (0 == strcmp(key, "s")) {
@@ -1181,7 +1196,9 @@ std::shared_ptr<LOTTransformData> LottieParserImpl::parseTransformObject()
     }
     obj->mStaticMatrix = obj->mAnchor.isStatic() && obj->mPosition.isStatic() &&
                          obj->mRotation.isStatic() && obj->mScale.isStatic() &&
-                         obj->mSkew.isStatic() && obj->mSkewAxis.isStatic();
+                         obj->mSkew.isStatic() && obj->mSkewAxis.isStatic() &&
+                         obj->mX.isStatic() && obj->mY.isStatic();
+
     obj->setStatic(obj->mStaticMatrix && obj->mOpacity.isStatic());
 
     if (obj->mStaticMatrix) obj->cacheMatrix();
@@ -1785,6 +1802,38 @@ void LottieParserImpl::parseShapeProperty(LOTAnimatable<LottieShapeData> &obj)
     }
 }
 
+template <typename T>
+void LottieParserImpl::parsePropertyHelper(LOTAnimatable<T> &obj)
+{
+    if (PeekType() == kNumberType) {
+        /*single value property with no animation*/
+        getValue(obj.mValue);
+    } else {
+        RAPIDJSON_ASSERT(PeekType() == kArrayType);
+        EnterArray();
+        while (NextArrayValue()) {
+            /* property with keyframe info*/
+            if (PeekType() == kObjectType) {
+                if (!obj.mAnimInfo)
+                    obj.mAnimInfo = std::make_unique<LOTAnimInfo<T>>();
+                parseKeyFrame(*obj.mAnimInfo.get());
+            } else {
+                /* Read before modifying.
+                 * as there is no way of knowing if the
+                 * value of the array is either array of numbers
+                 * or array of object without entering the array
+                 * thats why this hack is there
+                 */
+                RAPIDJSON_ASSERT(PeekType() == kNumberType);
+                /*multi value property with no animation*/
+                parseArrayValue(obj.mValue);
+                /*break here as we already reached end of array*/
+                break;
+            }
+        }
+    }
+}
+
 /*
  * https://github.com/airbnb/lottie-web/tree/master/docs/json/properties
  */
@@ -1794,36 +1843,7 @@ void LottieParserImpl::parseProperty(LOTAnimatable<T> &obj)
     EnterObject();
     while (const char *key = NextObjectKey()) {
         if (0 == strcmp(key, "k")) {
-            if (PeekType() == kNumberType) {
-                /*single value property with no animation*/
-                getValue(obj.mValue);
-            } else {
-                RAPIDJSON_ASSERT(PeekType() == kArrayType);
-                EnterArray();
-                while (NextArrayValue()) {
-                    /* property with keyframe info*/
-                    if (PeekType() == kObjectType) {
-                        if (!obj.mAnimInfo)
-                            obj.mAnimInfo = std::make_unique<LOTAnimInfo<T>>();
-                        parseKeyFrame(*obj.mAnimInfo.get());
-                    } else {
-                        /* Read before modifying.
-                         * as there is no way of knowing if the
-                         * value of the array is either array of numbers
-                         * or array of object without entering the array
-                         * thats why this hack is there
-                         */
-                        RAPIDJSON_ASSERT(PeekType() == kNumberType);
-                        /*multi value property with no animation*/
-                        parseArrayValue(obj.mValue);
-                        /*break here as we already reached end of array*/
-                        break;
-                    }
-                }
-            }
-        } else if (0 == strcmp(key, "ix")) {
-            RAPIDJSON_ASSERT(PeekType() == kNumberType);
-            obj.mPropertyIndex = GetInt();
+            parsePropertyHelper(obj);
         } else {
             Skip(key);
         }