From 88098f547f1a4227b2b6e0e67735f4f6aa7ecc20 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Mon, 18 Nov 2024 16:23:23 +0900 Subject: [PATCH] lottie: corrected an omission in overriding the default slot issue: https://github.com/thorvg/thorvg/issues/2953 --- src/loaders/lottie/tvgLottieLoader.cpp | 8 +-- src/loaders/lottie/tvgLottieLoader.h | 2 +- src/loaders/lottie/tvgLottieModel.cpp | 41 +++++-------- src/loaders/lottie/tvgLottieModel.h | 52 +++++++++------- src/loaders/lottie/tvgLottieParser.cpp | 4 +- src/loaders/lottie/tvgLottieParser.h | 2 +- src/loaders/lottie/tvgLottieProperty.h | 84 +++++++++++++++++--------- 7 files changed, 108 insertions(+), 85 deletions(-) diff --git a/src/loaders/lottie/tvgLottieLoader.cpp b/src/loaders/lottie/tvgLottieLoader.cpp index b8919f92..fb6772bb 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); @@ -290,7 +290,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; @@ -299,7 +299,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); @@ -309,7 +309,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 865c9236..c89676a0 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 31fdfd60..4c828b9d 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 e148ca93..8c165595 100644 --- a/src/loaders/lottie/tvgLottieModel.h +++ b/src/loaders/lottie/tvgLottieModel.h @@ -142,7 +142,7 @@ struct LottieObject { } - virtual void override(LottieProperty* prop) + virtual void override(LottieProperty* prop, bool byDefault = false) { TVGERR("LOTTIE", "Unsupported slot type"); } @@ -262,10 +262,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 @@ -533,10 +534,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(); } }; @@ -548,11 +550,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; @@ -610,10 +617,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; @@ -639,10 +647,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(); } }; @@ -651,10 +660,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(); @@ -825,7 +835,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 73466a16..e390ee88 100644 --- a/src/loaders/lottie/tvgLottieParser.cpp +++ b/src/loaders/lottie/tvgLottieParser.cpp @@ -1441,7 +1441,7 @@ const char* LottieParser::sid(bool first) } -bool LottieParser::apply(LottieSlot* slot) +bool LottieParser::apply(LottieSlot* slot, bool byDefault) { enterObject(); @@ -1486,7 +1486,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 484d795e..9bdbae51 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 84c52ef7..1ba62ac4 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(); @@ -610,18 +622,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; } @@ -737,6 +749,13 @@ struct LottieTextDoc : LottieProperty Array>* frames = nullptr; TextDocument value; + LottieTextDoc() {} + + LottieTextDoc(const LottieTextDoc& rhs) + { + *this = rhs; + } + ~LottieTextDoc() { release(); @@ -810,16 +829,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; } @@ -839,6 +858,13 @@ struct LottieBitmap : LottieProperty float width = 0.0f; float height = 0.0f; + LottieBitmap() {} + + LottieBitmap(const LottieBitmap& rhs) + { + *this = rhs; + } + ~LottieBitmap() { release(); @@ -857,18 +883,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; } };