Added support for RoundedCornor objects. accepted/tizen/unified/20201124.123025 submit/tizen/20201122.211513
authorSubhransu Mohanty <sub.mohanty@samsung.com>
Mon, 16 Nov 2020 06:39:16 +0000 (15:39 +0900)
committerJongmin Lee <jm105.lee@samsung.com>
Sun, 22 Nov 2020 21:06:57 +0000 (06:06 +0900)
- Currently RoundedCorner object only affects Rect object round property.
- yet to implement for Shape object.

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

index 7cd25ccd7d39249dc77b03ea7a35aca94a8b5ca0..7a746b8ca9bce0c0e2bfde517e01142ffe878ea3 100644 (file)
@@ -1097,7 +1097,7 @@ void renderer::Rect::updatePath(VPath &path, int frameNo)
 {
     VPointF pos = mData->mPos.value(frameNo);
     VPointF size = mData->mSize.value(frameNo);
-    float   roundness = mData->mRound.value(frameNo);
+    float   roundness = mData->roundness(frameNo);
     VRectF  r(pos.x() - size.x() / 2, pos.y() - size.y() / 2, size.x(),
              size.y());
 
index 1fcb561b949527335e58f942ca5772a53541e4f0..6f60254994b698f3630f68dd3b973385c274463b 100644 (file)
@@ -449,7 +449,7 @@ protected:
     {
         return (mData->mPos.changed(prevFrame, curFrame) ||
                 mData->mSize.changed(prevFrame, curFrame) ||
-                mData->mRound.changed(prevFrame, curFrame));
+                mData->roundnessChanged(prevFrame, curFrame));
     }
 };
 
index 85134147625c3a70419571e050a786740231422a..7f95c7fc376e570db51163a9ad0c02b704015b2b 100644 (file)
@@ -440,7 +440,8 @@ public:
         Path,
         Polystar,
         Trim,
-        Repeater
+        Repeater,
+        RoundedCorner
     };
 
     explicit Object(Object::Type type) : mPtr(nullptr)
@@ -670,6 +671,7 @@ public:
         Text = 5
     };
     Layer() : Group(Object::Type::Layer) {}
+    bool    hasRoundedCorner() const noexcept { return mHasRoundedCorner; }
     bool    hasPathOperator() const noexcept { return mHasPathOperator; }
     bool    hasGradient() const noexcept { return mHasGradient; }
     bool    hasMask() const noexcept { return mHasMask; }
@@ -717,6 +719,7 @@ public:
     MatteType mMatteType{MatteType::None};
     Type      mLayerType{Layer::Type::Null};
     BlendMode mBlendMode{BlendMode::Normal};
+    bool      mHasRoundedCorner{false};
     bool      mHasPathOperator{false};
     bool      mHasMask{false};
     bool      mHasRepeater{false};
@@ -893,11 +896,30 @@ public:
     Property<PathData> mShape;
 };
 
+class RoundedCorner : public Object {
+public:
+    RoundedCorner() : Object(Object::Type::RoundedCorner) {}
+    float radius(int frameNo) const { return mRadius.value(frameNo);}
+public:
+    Property<float>   mRadius{0};
+};
+
 class Rect : public Shape {
 public:
     Rect() : Shape(Object::Type::Rect) {}
+    float roundness(int frameNo)
+    {
+        return mRoundedCorner ? mRoundedCorner->radius(frameNo) :
+                                mRound.value(frameNo);
+    }
 
+    bool roundnessChanged(int prevFrame, int curFrame)
+    {
+        return mRoundedCorner ? mRoundedCorner->mRadius.changed(prevFrame, curFrame) :
+                        mRound.changed(prevFrame, curFrame);
+    }
 public:
+    RoundedCorner*    mRoundedCorner{nullptr};
     Property<VPointF> mPos;
     Property<VPointF> mSize;
     Property<float>   mRound{0};
index e5ef037742855d2eb340957deb345636f7369c4a..914507d12e025af4c4a61414b9dc40267b843c1b 100644 (file)
@@ -228,6 +228,9 @@ public:
     model::Object *  parseObjectTypeAttr();
     model::Object *  parseGroupObject();
     model::Rect *    parseRectObject();
+    model::RoundedCorner *    parseRoundedCorner();
+    void updateRoundedCorner(model::Group *parent, model::RoundedCorner *rc);
+
     model::Ellipse * parseEllipseObject();
     model::Path *    parseShapeObject();
     model::Polystar *parsePolystarObject();
@@ -1168,7 +1171,10 @@ model::Object *LottieParserImpl::parseObjectTypeAttr()
         return parseGroupObject();
     } else if (0 == strcmp(type, "rc")) {
         return parseRectObject();
-    } else if (0 == strcmp(type, "el")) {
+    } else if (0 == strcmp(type, "rd")) {
+        curLayerRef->mHasRoundedCorner = true;
+        return parseRoundedCorner();
+    }  else if (0 == strcmp(type, "el")) {
         return parseEllipseObject();
     } else if (0 == strcmp(type, "tr")) {
         return parseTransformObject();
@@ -1210,13 +1216,35 @@ void LottieParserImpl::parseObject(model::Group *parent)
     while (const char *key = NextObjectKey()) {
         if (0 == strcmp(key, "ty")) {
             auto child = parseObjectTypeAttr();
-            if (child && !child->hidden()) parent->mChildren.push_back(child);
+            if (child && !child->hidden()) {
+                if (child->type() == model::Object::Type::RoundedCorner) {
+                    updateRoundedCorner(parent, static_cast<model::RoundedCorner *>(child));
+                }
+                parent->mChildren.push_back(child);
+            }
         } else {
             Skip(key);
         }
     }
 }
 
+void LottieParserImpl::updateRoundedCorner(model::Group *group, model::RoundedCorner *rc)
+{
+    for(auto &e : group->mChildren)
+    {
+        if (e->type() == model::Object::Type::Rect) {
+            static_cast<model::Rect *>(e)->mRoundedCorner = rc;
+            if (!rc->isStatic()) {
+                e->setStatic(false);
+                group->setStatic(false);
+                //@TODO need to propagate.
+            }
+        } else if ( e->type() == model::Object::Type::Group) {
+            updateRoundedCorner(static_cast<model::Group *>(e), rc);
+        }
+    }
+}
+
 model::Object *LottieParserImpl::parseGroupObject()
 {
     auto group = allocator().make<model::Group>();
@@ -1282,6 +1310,28 @@ model::Rect *LottieParserImpl::parseRectObject()
     return obj;
 }
 
+/*
+ * https://github.com/airbnb/lottie-web/blob/master/docs/json/shapes/rect.json
+ */
+model::RoundedCorner *LottieParserImpl::parseRoundedCorner()
+{
+    auto obj = allocator().make<model::RoundedCorner>();
+
+    while (const char *key = NextObjectKey()) {
+        if (0 == strcmp(key, "nm")) {
+            obj->setName(GetString());
+        } else if (0 == strcmp(key, "r")) {
+            parseProperty(obj->mRadius);
+        } else if (0 == strcmp(key, "hd")) {
+            obj->setHidden(GetBool());
+        } else {
+            Skip(key);
+        }
+    }
+    obj->setStatic(obj->mRadius.isStatic());
+    return obj;
+}
+
 /*
  * https://github.com/airbnb/lottie-web/blob/master/docs/json/shapes/ellipse.json
  */
@@ -2252,6 +2302,11 @@ public:
                    << " , a:" << !obj->isStatic() << " }";
             break;
         }
+        case model::Object::Type::RoundedCorner: {
+            vDebug << level << "{ RoundedCorner: name: " << obj->name()
+                   << " , a:" << !obj->isStatic() << " }";
+            break;
+        }
         case model::Object::Type::Ellipse: {
             vDebug << level << "{ Ellipse: name: " << obj->name()
                    << " , a:" << !obj->isStatic() << " }";