lottie/slot: Support transform slot overriding

issue: https://github.com/thorvg/thorvg/issues/2591
This commit is contained in:
Jinny You 2024-12-28 13:27:28 +07:00 committed by Mira Grudzinska
parent bd8c2fca76
commit 1ae817b634
4 changed files with 81 additions and 4 deletions

View file

@ -61,8 +61,26 @@ void LottieSlot::assign(LottieObject* target, bool byDefault)
for (auto pair = pairs.begin(); pair < pairs.end(); ++pair) {
//backup the original properties before overwriting
switch (type) {
case LottieProperty::Type::Position: {
if (copy) pair->prop = new LottiePosition(static_cast<LottieTransform*>(pair->obj)->position);
pair->obj->override(&static_cast<LottieTransform*>(target)->position, shallow, byDefault);
break;
}
case LottieProperty::Type::Point: {
if (copy) pair->prop = new LottiePoint(static_cast<LottieTransform*>(pair->obj)->scale);
pair->obj->override(&static_cast<LottieTransform*>(target)->scale, shallow, byDefault);
break;
}
case LottieProperty::Type::Float: {
if (copy) pair->prop = new LottieFloat(static_cast<LottieTransform*>(pair->obj)->rotation);
pair->obj->override(&static_cast<LottieTransform*>(target)->rotation, shallow, byDefault);
break;
}
case LottieProperty::Type::Opacity: {
if (copy) pair->prop = new LottieOpacity(static_cast<LottieSolid*>(pair->obj)->opacity);
if (copy) {
if (pair->obj->type == LottieObject::Type::Transform) pair->prop = new LottieOpacity(static_cast<LottieTransform*>(pair->obj)->opacity);
else pair->prop = new LottieOpacity(static_cast<LottieSolid*>(pair->obj)->opacity);
}
pair->obj->override(&static_cast<LottieSolid*>(target)->opacity, shallow, byDefault);
break;
}

View file

@ -550,6 +550,33 @@ struct LottieTransform : LottieObject
return nullptr;
}
void override(LottieProperty* prop, bool shallow, bool byDefault) override
{
switch (prop->type) {
case LottieProperty::Type::Position: {
if (byDefault) position.release();
position.copy(*static_cast<LottiePosition*>(prop), shallow);
break;
}
case LottieProperty::Type::Float: {
if (byDefault) rotation.release();
rotation.copy(*static_cast<LottieFloat*>(prop), shallow);
break;
}
case LottieProperty::Type::Point: {
if (byDefault) scale.release();
scale.copy(*static_cast<LottiePoint*>(prop), shallow);
break;
}
case LottieProperty::Type::Opacity: {
if (byDefault) opacity.release();
opacity.copy(*static_cast<LottieOpacity*>(prop), shallow);
break;
}
default: break;
}
}
LottiePosition position = Point{0.0f, 0.0f};
LottieFloat rotation = 0.0f; //z rotation
LottiePoint scale = Point{100.0f, 100.0f};

View file

@ -608,14 +608,15 @@ LottieTransform* LottieParser::parseTransform(bool ddd)
else if (transform->coords && KEY_AS("x")) parseProperty<LottieProperty::Type::Float>(transform->coords->x);
else if (transform->coords && KEY_AS("y")) parseProperty<LottieProperty::Type::Float>(transform->coords->y);
else if (KEY_AS("x")) transform->position.exp = _expression(getStringCopy(), comp, context.layer, context.parent, &transform->position);
else if (KEY_AS("sid")) registerSlot<LottieProperty::Type::Position>(transform, getString());
else skip(key);
}
transform->position.type = LottieProperty::Type::Position;
}
else if (KEY_AS("a")) parseProperty<LottieProperty::Type::Point>(transform->anchor);
else if (KEY_AS("s")) parseProperty<LottieProperty::Type::Point>(transform->scale);
else if (KEY_AS("r")) parseProperty<LottieProperty::Type::Float>(transform->rotation);
else if (KEY_AS("o")) parseProperty<LottieProperty::Type::Opacity>(transform->opacity);
else if (KEY_AS("s")) parseProperty<LottieProperty::Type::Point>(transform->scale, transform);
else if (KEY_AS("r")) parseProperty<LottieProperty::Type::Float>(transform->rotation, transform);
else if (KEY_AS("o")) parseProperty<LottieProperty::Type::Opacity>(transform->opacity, transform);
else if (transform->rotationEx && KEY_AS("rx")) parseProperty<LottieProperty::Type::Float>(transform->rotationEx->x);
else if (transform->rotationEx && KEY_AS("ry")) parseProperty<LottieProperty::Type::Float>(transform->rotationEx->y);
else if (transform->rotationEx && KEY_AS("rz")) parseProperty<LottieProperty::Type::Float>(transform->rotation);
@ -1582,6 +1583,24 @@ bool LottieParser::apply(LottieSlot* slot, bool byDefault)
LottieObject* obj = nullptr; //slot object
switch (slot->type) {
case LottieProperty::Type::Position: {
obj = new LottieTransform;
context.parent = obj;
parseSlotProperty<LottieProperty::Type::Position>(static_cast<LottieTransform*>(obj)->position);
break;
}
case LottieProperty::Type::Point: {
obj = new LottieTransform;
context.parent = obj;
parseSlotProperty<LottieProperty::Type::Point>(static_cast<LottieTransform*>(obj)->scale);
break;
}
case LottieProperty::Type::Float: {
obj = new LottieTransform;
context.parent = obj;
parseSlotProperty<LottieProperty::Type::Float>(static_cast<LottieTransform*>(obj)->rotation);
break;
}
case LottieProperty::Type::Opacity: {
obj = new LottieSolid;
context.parent = obj;

View file

@ -741,6 +741,19 @@ struct LottiePosition : LottieProperty
return frame->angle(frame + 1, frameNo);
}
void copy(const LottiePosition& rhs, bool shallow = true)
{
if (rhs.frames) {
if (shallow) {
frames = rhs.frames;
const_cast<LottiePosition&>(rhs).frames = nullptr;
} else {
frames = new Array<LottieVectorFrame<Point>>;
*frames = *rhs.frames;
}
} else value = rhs.value;
}
void prepare()
{
if (!frames || frames->count < 2) return;