Path,
Polystar,
Trim,
- Repeater
+ Repeater,
+ RoundedCorner
};
explicit Object(Object::Type type) : mPtr(nullptr)
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; }
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};
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};
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();
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();
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>();
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
*/
<< " , 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() << " }";