mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-15 04:24:28 +00:00
lottie: corrected an omission in overriding the default slot
issue: https://github.com/thorvg/thorvg/issues/2953
This commit is contained in:
parent
fcf080cc4e
commit
88098f547f
7 changed files with 108 additions and 85 deletions
|
@ -44,7 +44,7 @@ void LottieLoader::run(unsigned tid)
|
||||||
comp = parser.comp;
|
comp = parser.comp;
|
||||||
}
|
}
|
||||||
if (parser.slots) {
|
if (parser.slots) {
|
||||||
override(parser.slots, false);
|
override(parser.slots, true);
|
||||||
parser.slots = nullptr;
|
parser.slots = nullptr;
|
||||||
}
|
}
|
||||||
builder->build(comp);
|
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;
|
if (!ready() || comp->slots.count == 0) return false;
|
||||||
|
|
||||||
|
@ -299,7 +299,7 @@ bool LottieLoader::override(const char* slots, bool copy)
|
||||||
//override slots
|
//override slots
|
||||||
if (slots) {
|
if (slots) {
|
||||||
//Copy the input data because the JSON parser will encode the data immediately.
|
//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
|
//parsing slot json
|
||||||
LottieParser parser(temp, dirName);
|
LottieParser parser(temp, dirName);
|
||||||
|
@ -309,7 +309,7 @@ bool LottieLoader::override(const char* slots, bool copy)
|
||||||
while (auto sid = parser.sid(idx == 0)) {
|
while (auto sid = parser.sid(idx == 0)) {
|
||||||
for (auto s = comp->slots.begin(); s < comp->slots.end(); ++s) {
|
for (auto s = comp->slots.begin(); s < comp->slots.end(); ++s) {
|
||||||
if (strcmp((*s)->sid, sid)) continue;
|
if (strcmp((*s)->sid, sid)) continue;
|
||||||
if (!parser.apply(*s)) success = false;
|
if (!parser.apply(*s, byDefault)) success = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
++idx;
|
++idx;
|
||||||
|
|
|
@ -57,7 +57,7 @@ public:
|
||||||
bool resize(Paint* paint, float w, float h) override;
|
bool resize(Paint* paint, float w, float h) override;
|
||||||
bool read() override;
|
bool read() override;
|
||||||
Paint* paint() override;
|
Paint* paint() override;
|
||||||
bool override(const char* slot, bool copy = true);
|
bool override(const char* slot, bool byDefault = false);
|
||||||
|
|
||||||
//Frame Controls
|
//Frame Controls
|
||||||
bool frame(float no) override;
|
bool frame(float no) override;
|
||||||
|
|
|
@ -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
|
//apply slot object to all targets
|
||||||
for (auto pair = pairs.begin(); pair < pairs.end(); ++pair) {
|
for (auto pair = pairs.begin(); pair < pairs.end(); ++pair) {
|
||||||
//backup the original properties before overwriting
|
//backup the original properties before overwriting
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case LottieProperty::Type::Opacity: {
|
case LottieProperty::Type::Opacity: {
|
||||||
if (!overridden) {
|
if (copy) pair->prop = new LottieOpacity(static_cast<LottieSolid*>(pair->obj)->opacity);
|
||||||
pair->prop = new LottieOpacity;
|
pair->obj->override(&static_cast<LottieSolid*>(target)->opacity, byDefault);
|
||||||
*static_cast<LottieOpacity*>(pair->prop) = static_cast<LottieSolid*>(pair->obj)->opacity;
|
|
||||||
}
|
|
||||||
pair->obj->override(&static_cast<LottieSolid*>(target)->opacity);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LottieProperty::Type::Color: {
|
case LottieProperty::Type::Color: {
|
||||||
if (!overridden) {
|
if (copy) pair->prop = new LottieColor(static_cast<LottieSolid*>(pair->obj)->color);
|
||||||
pair->prop = new LottieColor;
|
pair->obj->override(&static_cast<LottieSolid*>(target)->color, byDefault);
|
||||||
*static_cast<LottieColor*>(pair->prop) = static_cast<LottieSolid*>(pair->obj)->color;
|
|
||||||
}
|
|
||||||
pair->obj->override(&static_cast<LottieSolid*>(target)->color);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LottieProperty::Type::ColorStop: {
|
case LottieProperty::Type::ColorStop: {
|
||||||
if (!overridden) {
|
if (copy) pair->prop = new LottieColorStop(static_cast<LottieGradient*>(pair->obj)->colorStops);
|
||||||
pair->prop = new LottieColorStop;
|
pair->obj->override(&static_cast<LottieGradient*>(target)->colorStops, byDefault);
|
||||||
*static_cast<LottieColorStop*>(pair->prop) = static_cast<LottieGradient*>(pair->obj)->colorStops;
|
|
||||||
}
|
|
||||||
pair->obj->override(&static_cast<LottieGradient*>(target)->colorStops);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LottieProperty::Type::TextDoc: {
|
case LottieProperty::Type::TextDoc: {
|
||||||
if (!overridden) {
|
if (copy) pair->prop = new LottieTextDoc(static_cast<LottieText*>(pair->obj)->doc);
|
||||||
pair->prop = new LottieTextDoc;
|
pair->obj->override(&static_cast<LottieText*>(target)->doc, byDefault);
|
||||||
*static_cast<LottieTextDoc*>(pair->prop) = static_cast<LottieText*>(pair->obj)->doc;
|
|
||||||
}
|
|
||||||
pair->obj->override(&static_cast<LottieText*>(target)->doc);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LottieProperty::Type::Image: {
|
case LottieProperty::Type::Image: {
|
||||||
if (!overridden) {
|
if (copy) pair->prop = new LottieBitmap(static_cast<LottieImage*>(pair->obj)->data);
|
||||||
pair->prop = new LottieBitmap;
|
pair->obj->override(&static_cast<LottieImage*>(target)->data, byDefault);
|
||||||
*static_cast<LottieBitmap*>(pair->prop) = static_cast<LottieImage*>(pair->obj)->data;
|
|
||||||
}
|
|
||||||
pair->obj->override(&static_cast<LottieImage*>(target)->data);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
overridden = true;
|
if (!byDefault) overridden = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -142,7 +142,7 @@ struct LottieObject
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void override(LottieProperty* prop)
|
virtual void override(LottieProperty* prop, bool byDefault = false)
|
||||||
{
|
{
|
||||||
TVGERR("LOTTIE", "Unsupported slot type");
|
TVGERR("LOTTIE", "Unsupported slot type");
|
||||||
}
|
}
|
||||||
|
@ -262,10 +262,11 @@ struct LottieText : LottieObject, LottieRenderPooler<tvg::Shape>
|
||||||
LottieObject::type = LottieObject::Text;
|
LottieObject::type = LottieObject::Text;
|
||||||
}
|
}
|
||||||
|
|
||||||
void override(LottieProperty* prop) override
|
void override(LottieProperty* prop, bool byDefault = false) override
|
||||||
{
|
{
|
||||||
this->doc = *static_cast<LottieTextDoc*>(prop);
|
if (byDefault) doc.release();
|
||||||
this->prepare();
|
doc = *static_cast<LottieTextDoc*>(prop);
|
||||||
|
prepare();
|
||||||
}
|
}
|
||||||
|
|
||||||
LottieProperty* property(uint16_t ix) override
|
LottieProperty* property(uint16_t ix) override
|
||||||
|
@ -533,10 +534,11 @@ struct LottieSolidStroke : LottieSolid, LottieStroke
|
||||||
return LottieSolid::property(ix);
|
return LottieSolid::property(ix);
|
||||||
}
|
}
|
||||||
|
|
||||||
void override(LottieProperty* prop) override
|
void override(LottieProperty* prop, bool byDefault) override
|
||||||
{
|
{
|
||||||
this->color = *static_cast<LottieColor*>(prop);
|
if (byDefault) color.release();
|
||||||
this->prepare();
|
color = *static_cast<LottieColor*>(prop);
|
||||||
|
prepare();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -548,11 +550,16 @@ struct LottieSolidFill : LottieSolid
|
||||||
LottieObject::type = LottieObject::SolidFill;
|
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<LottieOpacity*>(prop);
|
if (prop->type == LottieProperty::Type::Opacity) {
|
||||||
else if (prop->type == LottieProperty::Type::Color) this->color = *static_cast<LottieColor*>(prop);
|
if (byDefault) opacity.release();
|
||||||
this->prepare();
|
opacity = *static_cast<LottieOpacity*>(prop);
|
||||||
|
} else if (prop->type == LottieProperty::Type::Color) {
|
||||||
|
if (byDefault) color.release();
|
||||||
|
color = *static_cast<LottieColor*>(prop);
|
||||||
|
}
|
||||||
|
prepare();
|
||||||
}
|
}
|
||||||
|
|
||||||
FillRule rule = FillRule::Winding;
|
FillRule rule = FillRule::Winding;
|
||||||
|
@ -610,10 +617,11 @@ struct LottieGradientFill : LottieGradient
|
||||||
LottieGradient::prepare();
|
LottieGradient::prepare();
|
||||||
}
|
}
|
||||||
|
|
||||||
void override(LottieProperty* prop) override
|
void override(LottieProperty* prop, bool byDefault) override
|
||||||
{
|
{
|
||||||
this->colorStops = *static_cast<LottieColorStop*>(prop);
|
if (byDefault) colorStops.release();
|
||||||
this->prepare();
|
colorStops = *static_cast<LottieColorStop*>(prop);
|
||||||
|
prepare();
|
||||||
}
|
}
|
||||||
|
|
||||||
FillRule rule = FillRule::Winding;
|
FillRule rule = FillRule::Winding;
|
||||||
|
@ -639,10 +647,11 @@ struct LottieGradientStroke : LottieGradient, LottieStroke
|
||||||
return LottieGradient::property(ix);
|
return LottieGradient::property(ix);
|
||||||
}
|
}
|
||||||
|
|
||||||
void override(LottieProperty* prop) override
|
void override(LottieProperty* prop, bool byDefault = false) override
|
||||||
{
|
{
|
||||||
this->colorStops = *static_cast<LottieColorStop*>(prop);
|
if (byDefault) colorStops.release();
|
||||||
this->prepare();
|
colorStops = *static_cast<LottieColorStop*>(prop);
|
||||||
|
prepare();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -651,10 +660,11 @@ struct LottieImage : LottieObject, LottieRenderPooler<tvg::Picture>
|
||||||
{
|
{
|
||||||
LottieBitmap data;
|
LottieBitmap data;
|
||||||
|
|
||||||
void override(LottieProperty* prop) override
|
void override(LottieProperty* prop, bool byDefault = false) override
|
||||||
{
|
{
|
||||||
this->data = *static_cast<LottieBitmap*>(prop);
|
if (byDefault) data.release();
|
||||||
this->prepare();
|
data = *static_cast<LottieBitmap*>(prop);
|
||||||
|
prepare();
|
||||||
}
|
}
|
||||||
|
|
||||||
void prepare();
|
void prepare();
|
||||||
|
@ -825,7 +835,7 @@ struct LottieSlot
|
||||||
LottieProperty* prop;
|
LottieProperty* prop;
|
||||||
};
|
};
|
||||||
|
|
||||||
void assign(LottieObject* target);
|
void assign(LottieObject* target, bool byDefault);
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
LottieSlot(char* sid, LottieObject* obj, LottieProperty::Type type) : sid(sid), type(type)
|
LottieSlot(char* sid, LottieObject* obj, LottieProperty::Type type) : sid(sid), type(type)
|
||||||
|
|
|
@ -1441,7 +1441,7 @@ const char* LottieParser::sid(bool first)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool LottieParser::apply(LottieSlot* slot)
|
bool LottieParser::apply(LottieSlot* slot, bool byDefault)
|
||||||
{
|
{
|
||||||
enterObject();
|
enterObject();
|
||||||
|
|
||||||
|
@ -1486,7 +1486,7 @@ bool LottieParser::apply(LottieSlot* slot)
|
||||||
|
|
||||||
if (!obj || Invalid()) return false;
|
if (!obj || Invalid()) return false;
|
||||||
|
|
||||||
slot->assign(obj);
|
slot->assign(obj, byDefault);
|
||||||
|
|
||||||
delete(obj);
|
delete(obj);
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
bool parse();
|
bool parse();
|
||||||
bool apply(LottieSlot* slot);
|
bool apply(LottieSlot* slot, bool byDefault);
|
||||||
const char* sid(bool first = false);
|
const char* sid(bool first = false);
|
||||||
void captureSlots(const char* key);
|
void captureSlots(const char* key);
|
||||||
template<LottieProperty::Type type = LottieProperty::Type::Invalid> void registerSlot(LottieObject* obj, char* sid);
|
template<LottieProperty::Type type = LottieProperty::Type::Invalid> void registerSlot(LottieObject* obj, char* sid);
|
||||||
|
|
|
@ -261,6 +261,11 @@ struct LottieGenericProperty : LottieProperty
|
||||||
LottieGenericProperty(T v) : value(v) {}
|
LottieGenericProperty(T v) : value(v) {}
|
||||||
LottieGenericProperty() {}
|
LottieGenericProperty() {}
|
||||||
|
|
||||||
|
LottieGenericProperty(const LottieGenericProperty<T>& rhs)
|
||||||
|
{
|
||||||
|
*this = rhs;
|
||||||
|
}
|
||||||
|
|
||||||
~LottieGenericProperty()
|
~LottieGenericProperty()
|
||||||
{
|
{
|
||||||
release();
|
release();
|
||||||
|
@ -329,13 +334,13 @@ struct LottieGenericProperty : LottieProperty
|
||||||
return operator()(frameNo);
|
return operator()(frameNo);
|
||||||
}
|
}
|
||||||
|
|
||||||
LottieGenericProperty<T>& operator=(const LottieGenericProperty<T>& other)
|
LottieGenericProperty<T>& operator=(const LottieGenericProperty<T>& rhs)
|
||||||
{
|
{
|
||||||
//shallow copy, used for slot overriding
|
//shallow copy, used for slot overriding
|
||||||
if (other.frames) {
|
if (rhs.frames) {
|
||||||
frames = other.frames;
|
frames = rhs.frames;
|
||||||
const_cast<LottieGenericProperty<T>&>(other).frames = nullptr;
|
const_cast<LottieGenericProperty<T>&>(rhs).frames = nullptr;
|
||||||
} else value = other.value;
|
} else value = rhs.value;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -504,6 +509,13 @@ struct LottieColorStop : LottieProperty
|
||||||
uint16_t count = 0; //colorstop count
|
uint16_t count = 0; //colorstop count
|
||||||
bool populated = false;
|
bool populated = false;
|
||||||
|
|
||||||
|
LottieColorStop() {}
|
||||||
|
|
||||||
|
LottieColorStop(const LottieColorStop& rhs)
|
||||||
|
{
|
||||||
|
*this = rhs;
|
||||||
|
}
|
||||||
|
|
||||||
~LottieColorStop()
|
~LottieColorStop()
|
||||||
{
|
{
|
||||||
release();
|
release();
|
||||||
|
@ -610,18 +622,18 @@ struct LottieColorStop : LottieProperty
|
||||||
return fill->colorStops(result.data, count);
|
return fill->colorStops(result.data, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
LottieColorStop& operator=(const LottieColorStop& other)
|
LottieColorStop& operator=(const LottieColorStop& rhs)
|
||||||
{
|
{
|
||||||
//shallow copy, used for slot overriding
|
//shallow copy, used for slot overriding
|
||||||
if (other.frames) {
|
if (rhs.frames) {
|
||||||
frames = other.frames;
|
frames = rhs.frames;
|
||||||
const_cast<LottieColorStop&>(other).frames = nullptr;
|
const_cast<LottieColorStop&>(rhs).frames = nullptr;
|
||||||
} else {
|
} else {
|
||||||
value = other.value;
|
value = rhs.value;
|
||||||
const_cast<LottieColorStop&>(other).value = {nullptr, nullptr};
|
const_cast<LottieColorStop&>(rhs).value = {nullptr, nullptr};
|
||||||
}
|
}
|
||||||
populated = other.populated;
|
populated = rhs.populated;
|
||||||
count = other.count;
|
count = rhs.count;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -737,6 +749,13 @@ struct LottieTextDoc : LottieProperty
|
||||||
Array<LottieScalarFrame<TextDocument>>* frames = nullptr;
|
Array<LottieScalarFrame<TextDocument>>* frames = nullptr;
|
||||||
TextDocument value;
|
TextDocument value;
|
||||||
|
|
||||||
|
LottieTextDoc() {}
|
||||||
|
|
||||||
|
LottieTextDoc(const LottieTextDoc& rhs)
|
||||||
|
{
|
||||||
|
*this = rhs;
|
||||||
|
}
|
||||||
|
|
||||||
~LottieTextDoc()
|
~LottieTextDoc()
|
||||||
{
|
{
|
||||||
release();
|
release();
|
||||||
|
@ -810,16 +829,16 @@ struct LottieTextDoc : LottieProperty
|
||||||
return frame->value;
|
return frame->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
LottieTextDoc& operator=(const LottieTextDoc& other)
|
LottieTextDoc& operator=(const LottieTextDoc& rhs)
|
||||||
{
|
{
|
||||||
//shallow copy, used for slot overriding
|
//shallow copy, used for slot overriding
|
||||||
if (other.frames) {
|
if (rhs.frames) {
|
||||||
frames = other.frames;
|
frames = rhs.frames;
|
||||||
const_cast<LottieTextDoc&>(other).frames = nullptr;
|
const_cast<LottieTextDoc&>(rhs).frames = nullptr;
|
||||||
} else {
|
} else {
|
||||||
value = other.value;
|
value = rhs.value;
|
||||||
const_cast<LottieTextDoc&>(other).value.text = nullptr;
|
const_cast<LottieTextDoc&>(rhs).value.text = nullptr;
|
||||||
const_cast<LottieTextDoc&>(other).value.name = nullptr;
|
const_cast<LottieTextDoc&>(rhs).value.name = nullptr;
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -839,6 +858,13 @@ struct LottieBitmap : LottieProperty
|
||||||
float width = 0.0f;
|
float width = 0.0f;
|
||||||
float height = 0.0f;
|
float height = 0.0f;
|
||||||
|
|
||||||
|
LottieBitmap() {}
|
||||||
|
|
||||||
|
LottieBitmap(const LottieBitmap& rhs)
|
||||||
|
{
|
||||||
|
*this = rhs;
|
||||||
|
}
|
||||||
|
|
||||||
~LottieBitmap()
|
~LottieBitmap()
|
||||||
{
|
{
|
||||||
release();
|
release();
|
||||||
|
@ -857,18 +883,18 @@ struct LottieBitmap : LottieProperty
|
||||||
uint32_t nearest(float time) override { return 0; }
|
uint32_t nearest(float time) override { return 0; }
|
||||||
float frameNo(int32_t key) 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
|
//shallow copy, used for slot overriding
|
||||||
if (other.mimeType) b64Data = other.b64Data;
|
if (rhs.mimeType) b64Data = rhs.b64Data;
|
||||||
else path = other.path;
|
else path = rhs.path;
|
||||||
mimeType = other.mimeType;
|
mimeType = rhs.mimeType;
|
||||||
size = other.size;
|
size = rhs.size;
|
||||||
width = other.width;
|
width = rhs.width;
|
||||||
height = other.height;
|
height = rhs.height;
|
||||||
|
|
||||||
const_cast<LottieBitmap&>(other).b64Data = nullptr;
|
const_cast<LottieBitmap&>(rhs).b64Data = nullptr;
|
||||||
const_cast<LottieBitmap&>(other).mimeType = nullptr;
|
const_cast<LottieBitmap&>(rhs).mimeType = nullptr;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue