diff --git a/src/loaders/lottie/tvgLottieLoader.cpp b/src/loaders/lottie/tvgLottieLoader.cpp index 061cdc49..1099a047 100644 --- a/src/loaders/lottie/tvgLottieLoader.cpp +++ b/src/loaders/lottie/tvgLottieLoader.cpp @@ -44,7 +44,7 @@ void LottieLoader::run(unsigned tid) comp = parser.comp; } if (parser.slots) { - override(parser.slots, false); + override(parser.slots, true); parser.slots = nullptr; } builder->build(comp); @@ -291,7 +291,7 @@ Paint* LottieLoader::paint() } -bool LottieLoader::override(const char* slots, bool copy) +bool LottieLoader::override(const char* slots, bool byDefault) { if (!ready() || comp->slots.count == 0) return false; @@ -300,7 +300,7 @@ bool LottieLoader::override(const char* slots, bool copy) //override slots if (slots) { //Copy the input data because the JSON parser will encode the data immediately. - auto temp = copy ? strdup(slots) : slots; + auto temp = byDefault ? slots : strdup(slots); //parsing slot json LottieParser parser(temp, dirName); @@ -310,7 +310,7 @@ bool LottieLoader::override(const char* slots, bool copy) while (auto sid = parser.sid(idx == 0)) { for (auto s = comp->slots.begin(); s < comp->slots.end(); ++s) { if (strcmp((*s)->sid, sid)) continue; - if (!parser.apply(*s)) success = false; + if (!parser.apply(*s, byDefault)) success = false; break; } ++idx; diff --git a/src/loaders/lottie/tvgLottieLoader.h b/src/loaders/lottie/tvgLottieLoader.h index 7e7ef843..1726bc46 100644 --- a/src/loaders/lottie/tvgLottieLoader.h +++ b/src/loaders/lottie/tvgLottieLoader.h @@ -57,7 +57,7 @@ public: bool resize(Paint* paint, float w, float h) override; bool read() override; Paint* paint() override; - bool override(const char* slot, bool copy = true); + bool override(const char* slot, bool byDefault = false); //Frame Controls bool frame(float no) override; diff --git a/src/loaders/lottie/tvgLottieModel.cpp b/src/loaders/lottie/tvgLottieModel.cpp index e269f5d9..333c8fb4 100644 --- a/src/loaders/lottie/tvgLottieModel.cpp +++ b/src/loaders/lottie/tvgLottieModel.cpp @@ -78,56 +78,43 @@ void LottieSlot::reset() } -void LottieSlot::assign(LottieObject* target) +void LottieSlot::assign(LottieObject* target, bool byDefault) { + auto copy = !overridden && !byDefault; + //apply slot object to all targets for (auto pair = pairs.begin(); pair < pairs.end(); ++pair) { //backup the original properties before overwriting switch (type) { case LottieProperty::Type::Opacity: { - if (!overridden) { - pair->prop = new LottieOpacity; - *static_cast(pair->prop) = static_cast(pair->obj)->opacity; - } - pair->obj->override(&static_cast(target)->opacity); + if (copy) pair->prop = new LottieOpacity(static_cast(pair->obj)->opacity); + pair->obj->override(&static_cast(target)->opacity, byDefault); break; } case LottieProperty::Type::Color: { - if (!overridden) { - pair->prop = new LottieColor; - *static_cast(pair->prop) = static_cast(pair->obj)->color; - } - pair->obj->override(&static_cast(target)->color); + if (copy) pair->prop = new LottieColor(static_cast(pair->obj)->color); + pair->obj->override(&static_cast(target)->color, byDefault); break; } case LottieProperty::Type::ColorStop: { - if (!overridden) { - pair->prop = new LottieColorStop; - *static_cast(pair->prop) = static_cast(pair->obj)->colorStops; - } - pair->obj->override(&static_cast(target)->colorStops); + if (copy) pair->prop = new LottieColorStop(static_cast(pair->obj)->colorStops); + pair->obj->override(&static_cast(target)->colorStops, byDefault); break; } case LottieProperty::Type::TextDoc: { - if (!overridden) { - pair->prop = new LottieTextDoc; - *static_cast(pair->prop) = static_cast(pair->obj)->doc; - } - pair->obj->override(&static_cast(target)->doc); + if (copy) pair->prop = new LottieTextDoc(static_cast(pair->obj)->doc); + pair->obj->override(&static_cast(target)->doc, byDefault); break; } case LottieProperty::Type::Image: { - if (!overridden) { - pair->prop = new LottieBitmap; - *static_cast(pair->prop) = static_cast(pair->obj)->data; - } - pair->obj->override(&static_cast(target)->data); + if (copy) pair->prop = new LottieBitmap(static_cast(pair->obj)->data); + pair->obj->override(&static_cast(target)->data, byDefault); break; } default: break; } } - overridden = true; + if (!byDefault) overridden = true; } diff --git a/src/loaders/lottie/tvgLottieModel.h b/src/loaders/lottie/tvgLottieModel.h index a8e6e141..bb32019e 100644 --- a/src/loaders/lottie/tvgLottieModel.h +++ b/src/loaders/lottie/tvgLottieModel.h @@ -158,7 +158,7 @@ struct LottieObject { } - virtual void override(LottieProperty* prop) + virtual void override(LottieProperty* prop, bool byDefault = false) { TVGERR("LOTTIE", "Unsupported slot type"); } @@ -278,10 +278,11 @@ struct LottieText : LottieObject, LottieRenderPooler LottieObject::type = LottieObject::Text; } - void override(LottieProperty* prop) override + void override(LottieProperty* prop, bool byDefault = false) override { - this->doc = *static_cast(prop); - this->prepare(); + if (byDefault) doc.release(); + doc = *static_cast(prop); + prepare(); } LottieProperty* property(uint16_t ix) override @@ -549,10 +550,11 @@ struct LottieSolidStroke : LottieSolid, LottieStroke return LottieSolid::property(ix); } - void override(LottieProperty* prop) override + void override(LottieProperty* prop, bool byDefault) override { - this->color = *static_cast(prop); - this->prepare(); + if (byDefault) color.release(); + color = *static_cast(prop); + prepare(); } }; @@ -564,11 +566,16 @@ struct LottieSolidFill : LottieSolid LottieObject::type = LottieObject::SolidFill; } - void override(LottieProperty* prop) override + void override(LottieProperty* prop, bool byDefault) override { - if (prop->type == LottieProperty::Type::Opacity) this->opacity = *static_cast(prop); - else if (prop->type == LottieProperty::Type::Color) this->color = *static_cast(prop); - this->prepare(); + if (prop->type == LottieProperty::Type::Opacity) { + if (byDefault) opacity.release(); + opacity = *static_cast(prop); + } else if (prop->type == LottieProperty::Type::Color) { + if (byDefault) color.release(); + color = *static_cast(prop); + } + prepare(); } FillRule rule = FillRule::Winding; @@ -626,10 +633,11 @@ struct LottieGradientFill : LottieGradient LottieGradient::prepare(); } - void override(LottieProperty* prop) override + void override(LottieProperty* prop, bool byDefault) override { - this->colorStops = *static_cast(prop); - this->prepare(); + if (byDefault) colorStops.release(); + colorStops = *static_cast(prop); + prepare(); } FillRule rule = FillRule::Winding; @@ -655,10 +663,11 @@ struct LottieGradientStroke : LottieGradient, LottieStroke return LottieGradient::property(ix); } - void override(LottieProperty* prop) override + void override(LottieProperty* prop, bool byDefault = false) override { - this->colorStops = *static_cast(prop); - this->prepare(); + if (byDefault) colorStops.release(); + colorStops = *static_cast(prop); + prepare(); } }; @@ -667,10 +676,11 @@ struct LottieImage : LottieObject, LottieRenderPooler { LottieBitmap data; - void override(LottieProperty* prop) override + void override(LottieProperty* prop, bool byDefault = false) override { - this->data = *static_cast(prop); - this->prepare(); + if (byDefault) data.release(); + data = *static_cast(prop); + prepare(); } void prepare(); @@ -841,7 +851,7 @@ struct LottieSlot LottieProperty* prop; }; - void assign(LottieObject* target); + void assign(LottieObject* target, bool byDefault); void reset(); LottieSlot(char* sid, LottieObject* obj, LottieProperty::Type type) : sid(sid), type(type) diff --git a/src/loaders/lottie/tvgLottieParser.cpp b/src/loaders/lottie/tvgLottieParser.cpp index 1377f1c1..b7880924 100644 --- a/src/loaders/lottie/tvgLottieParser.cpp +++ b/src/loaders/lottie/tvgLottieParser.cpp @@ -1472,7 +1472,7 @@ const char* LottieParser::sid(bool first) } -bool LottieParser::apply(LottieSlot* slot) +bool LottieParser::apply(LottieSlot* slot, bool byDefault) { enterObject(); @@ -1517,7 +1517,7 @@ bool LottieParser::apply(LottieSlot* slot) if (!obj || Invalid()) return false; - slot->assign(obj); + slot->assign(obj, byDefault); delete(obj); diff --git a/src/loaders/lottie/tvgLottieParser.h b/src/loaders/lottie/tvgLottieParser.h index c74d5e12..d246ce3c 100644 --- a/src/loaders/lottie/tvgLottieParser.h +++ b/src/loaders/lottie/tvgLottieParser.h @@ -36,7 +36,7 @@ public: } bool parse(); - bool apply(LottieSlot* slot); + bool apply(LottieSlot* slot, bool byDefault); const char* sid(bool first = false); void captureSlots(const char* key); template void registerSlot(LottieObject* obj, char* sid); diff --git a/src/loaders/lottie/tvgLottieProperty.h b/src/loaders/lottie/tvgLottieProperty.h index 23e9a145..a04b6ea9 100644 --- a/src/loaders/lottie/tvgLottieProperty.h +++ b/src/loaders/lottie/tvgLottieProperty.h @@ -261,6 +261,11 @@ struct LottieGenericProperty : LottieProperty LottieGenericProperty(T v) : value(v) {} LottieGenericProperty() {} + LottieGenericProperty(const LottieGenericProperty& rhs) + { + *this = rhs; + } + ~LottieGenericProperty() { release(); @@ -329,13 +334,13 @@ struct LottieGenericProperty : LottieProperty return operator()(frameNo); } - LottieGenericProperty& operator=(const LottieGenericProperty& other) + LottieGenericProperty& operator=(const LottieGenericProperty& rhs) { //shallow copy, used for slot overriding - if (other.frames) { - frames = other.frames; - const_cast&>(other).frames = nullptr; - } else value = other.value; + if (rhs.frames) { + frames = rhs.frames; + const_cast&>(rhs).frames = nullptr; + } else value = rhs.value; return *this; } @@ -504,6 +509,13 @@ struct LottieColorStop : LottieProperty uint16_t count = 0; //colorstop count bool populated = false; + LottieColorStop() {} + + LottieColorStop(const LottieColorStop& rhs) + { + *this = rhs; + } + ~LottieColorStop() { release(); @@ -608,18 +620,18 @@ struct LottieColorStop : LottieProperty return fill->colorStops(result.data, count); } - LottieColorStop& operator=(const LottieColorStop& other) + LottieColorStop& operator=(const LottieColorStop& rhs) { //shallow copy, used for slot overriding - if (other.frames) { - frames = other.frames; - const_cast(other).frames = nullptr; + if (rhs.frames) { + frames = rhs.frames; + const_cast(rhs).frames = nullptr; } else { - value = other.value; - const_cast(other).value = {nullptr, nullptr}; + value = rhs.value; + const_cast(rhs).value = {nullptr, nullptr}; } - populated = other.populated; - count = other.count; + populated = rhs.populated; + count = rhs.count; return *this; } @@ -735,6 +747,13 @@ struct LottieTextDoc : LottieProperty Array>* frames = nullptr; TextDocument value; + LottieTextDoc() {} + + LottieTextDoc(const LottieTextDoc& rhs) + { + *this = rhs; + } + ~LottieTextDoc() { release(); @@ -808,16 +827,16 @@ struct LottieTextDoc : LottieProperty return frame->value; } - LottieTextDoc& operator=(const LottieTextDoc& other) + LottieTextDoc& operator=(const LottieTextDoc& rhs) { //shallow copy, used for slot overriding - if (other.frames) { - frames = other.frames; - const_cast(other).frames = nullptr; + if (rhs.frames) { + frames = rhs.frames; + const_cast(rhs).frames = nullptr; } else { - value = other.value; - const_cast(other).value.text = nullptr; - const_cast(other).value.name = nullptr; + value = rhs.value; + const_cast(rhs).value.text = nullptr; + const_cast(rhs).value.name = nullptr; } return *this; } @@ -837,6 +856,13 @@ struct LottieBitmap : LottieProperty float width = 0.0f; float height = 0.0f; + LottieBitmap() {} + + LottieBitmap(const LottieBitmap& rhs) + { + *this = rhs; + } + ~LottieBitmap() { release(); @@ -855,18 +881,18 @@ struct LottieBitmap : LottieProperty uint32_t nearest(float time) override { return 0; } float frameNo(int32_t key) override { return 0; } - LottieBitmap& operator=(const LottieBitmap& other) + LottieBitmap& operator=(const LottieBitmap& rhs) { //shallow copy, used for slot overriding - if (other.mimeType) b64Data = other.b64Data; - else path = other.path; - mimeType = other.mimeType; - size = other.size; - width = other.width; - height = other.height; + if (rhs.mimeType) b64Data = rhs.b64Data; + else path = rhs.path; + mimeType = rhs.mimeType; + size = rhs.size; + width = rhs.width; + height = rhs.height; - const_cast(other).b64Data = nullptr; - const_cast(other).mimeType = nullptr; + const_cast(rhs).b64Data = nullptr; + const_cast(rhs).mimeType = nullptr; return *this; } };