mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-08 05:33:36 +00:00
lottie/slot: revise gradient fill support
Revise gradient fill data parsing by adding support for the color stop count (p) parameter in slot data. issue: https://github.com/thorvg/thorvg/issues/2795
This commit is contained in:
parent
2207c8ce5e
commit
f42559e613
7 changed files with 43 additions and 29 deletions
|
@ -96,7 +96,7 @@ struct UserExample : tvgexam::Example
|
|||
auto picture = slotAnimation->picture();
|
||||
if (!tvgexam::verify(picture->load(EXAMPLE_DIR"/lottie/extensions/slotsample.json"))) return false;
|
||||
|
||||
const char* slotJson = R"({"gradient_fill":{"p":{"a":0,"k":[0,0.1,0.1,0.2,1,1,0.1,0.2,0.1,1]}}})";
|
||||
const char* slotJson = R"({"gradient_fill":{"p":{"p":2,"k":{"k":[0,0.1,0.1,0.2,1,1,0.1,0.2,0,0,1,1]}}}})";
|
||||
if (!tvgexam::verify(slotAnimation->override(slotJson))) return false;
|
||||
|
||||
sizing(picture, 0);
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"v":"4.8.0","meta":{"g":"LottieFiles AE 3.0.2","a":"","k":"","d":"","tc":""},"fr":60,"ip":0,"op":121,"w":550,"h":550,"nm":"C","assets":[],"layers":[{"ind":1,"ty":4,"nm":"S","sr":1,"ks":{"o":{"a":0,"k":100},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":120,"s":[360]}]},"p":{"a":0,"k":[275,275,0]},"a":{"a":0,"k":[-7.886,88.719,0]},"s":{"a":0,"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[282.019,134.888]},"p":{"a":0,"k":[0,0]},"r":{"a":0,"k":0},"nm":"R"},{"ty":"st","c":{"a":0,"k":[0.991,0,1,1]},"o":{"a":0,"k":100},"w":{"a":0,"k":3},"lc":1,"lj":1,"ml":4,"nm":"S"},{"ty":"gf","o":{"a":0,"k":100},"r":1,"g":{"p":9,"k":{"a":0,"k":[0,0.514,0.373,0.984,0.141,0.478,0.412,0.984,0.283,0.443,0.451,0.984,0.379,0.408,0.49,0.984,0.475,0.373,0.529,0.984,0.606,0.278,0.647,0.925,0.737,0.184,0.765,0.867,0.868,0.092,0.882,0.808,1,0,1,0.749],"sid":"gradient_fill"}},"s":{"a":0,"k":[-159.51,23.531]},"e":{"a":0,"k":[183.084,8.059]},"t":1,"nm":"G"},{"ty":"tr","p":{"a":0,"k":[-7.886,88.719]},"a":{"a":0,"k":[0,0]},"s":{"a":0,"k":[100,100]},"r":{"a":0,"k":0},"o":{"a":0,"k":100},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0},"nm":"T"}],"nm":"R"}],"ip":0,"op":300,"st":0}],"slots":{"gradient_fill":{"p":{"a":0,"k":[0,0.1,0.1,0.2,1,1,0.1,0.2,0.1,1]}}},"markers":[]}
|
||||
{"v":"4.8.0","meta":{"g":"LottieFiles AE 3.0.2","a":"","k":"","d":"","tc":""},"fr":60,"ip":0,"op":121,"w":550,"h":550,"nm":"C","assets":[],"layers":[{"ind":1,"ty":4,"nm":"S","sr":1,"ks":{"o":{"a":0,"k":100},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":120,"s":[360]}]},"p":{"a":0,"k":[275,275,0]},"a":{"a":0,"k":[-7.886,88.719,0]},"s":{"a":0,"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[282.019,134.888]},"p":{"a":0,"k":[0,0]},"r":{"a":0,"k":0},"nm":"R"},{"ty":"st","c":{"a":0,"k":[0.991,0,1,1]},"o":{"a":0,"k":100},"w":{"a":0,"k":3},"lc":1,"lj":1,"ml":4,"nm":"S"},{"ty":"gf","o":{"a":0,"k":100},"r":1,"g":{"p":9,"k":{"a":0,"k":[0,0.514,0.373,0.984,0.141,0.478,0.412,0.984,0.283,0.443,0.451,0.984,0.379,0.408,0.49,0.984,0.475,0.373,0.529,0.984,0.606,0.278,0.647,0.925,0.737,0.184,0.765,0.867,0.868,0.092,0.882,0.808,1,0,1,0.749]},"sid":"gradient_fill"},"s":{"a":0,"k":[-159.51,23.531]},"e":{"a":0,"k":[183.084,8.059]},"t":1,"nm":"G"},{"ty":"tr","p":{"a":0,"k":[-7.886,88.719]},"a":{"a":0,"k":[0,0]},"s":{"a":0,"k":[100,100]},"r":{"a":0,"k":0},"o":{"a":0,"k":100},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0},"nm":"T"}],"nm":"R"}],"ip":0,"op":300,"st":0}],"slots":{"gradient_fill":{"p":{"a":0,"k":[0,0.1,0.1,0.2,1,1,0.1,0.2,0.1,1]}}},"markers":[]}
|
|
@ -485,26 +485,31 @@ void LottieParser::parsePropertyInternal(T& prop)
|
|||
}
|
||||
|
||||
|
||||
template<LottieProperty::Type type>
|
||||
void LottieParser::registerSlot(LottieObject* obj)
|
||||
{
|
||||
auto sid = getStringCopy();
|
||||
|
||||
//append object if the slot already exists.
|
||||
for (auto slot = comp->slots.begin(); slot < comp->slots.end(); ++slot) {
|
||||
if (strcmp((*slot)->sid, sid)) continue;
|
||||
(*slot)->pairs.push({obj});
|
||||
return;
|
||||
}
|
||||
comp->slots.push(new LottieSlot(sid, obj, type));
|
||||
}
|
||||
|
||||
|
||||
template<LottieProperty::Type type, typename T>
|
||||
void LottieParser::parseProperty(T& prop, LottieObject* obj)
|
||||
{
|
||||
enterObject();
|
||||
while (auto key = nextObjectKey()) {
|
||||
if (KEY_AS("k")) parsePropertyInternal(prop);
|
||||
else if (obj && KEY_AS("sid")) {
|
||||
auto sid = getStringCopy();
|
||||
//append object if the slot already exists.
|
||||
for (auto slot = comp->slots.begin(); slot < comp->slots.end(); ++slot) {
|
||||
if (strcmp((*slot)->sid, sid)) continue;
|
||||
(*slot)->pairs.push({obj});
|
||||
break;
|
||||
}
|
||||
comp->slots.push(new LottieSlot(sid, obj, type));
|
||||
} else if (KEY_AS("x")) {
|
||||
prop.exp = _expression(getStringCopy(), comp, context.layer, context.parent, &prop);
|
||||
} else if (KEY_AS("ix")) {
|
||||
prop.ix = getInt();
|
||||
} else skip(key);
|
||||
else if (obj && KEY_AS("sid")) registerSlot<type>(obj);
|
||||
else if (KEY_AS("x")) prop.exp = _expression(getStringCopy(), comp, context.layer, context.parent, &prop);
|
||||
else if (KEY_AS("ix")) prop.ix = getInt();
|
||||
else skip(key);
|
||||
}
|
||||
prop.type = type;
|
||||
}
|
||||
|
@ -750,19 +755,23 @@ LottieRoundedCorner* LottieParser::parseRoundedCorner()
|
|||
}
|
||||
|
||||
|
||||
void LottieParser::parseGradient(LottieGradient* gradient, const char* key)
|
||||
void LottieParser::parseColorStop(LottieGradient* gradient)
|
||||
{
|
||||
if (KEY_AS("t")) gradient->id = getInt();
|
||||
else if (KEY_AS("o")) parseProperty<LottieProperty::Type::Opacity>(gradient->opacity, gradient);
|
||||
else if (KEY_AS("g"))
|
||||
{
|
||||
enterObject();
|
||||
while (auto key = nextObjectKey()) {
|
||||
if (KEY_AS("p")) gradient->colorStops.count = getInt();
|
||||
else if (KEY_AS("k")) parseProperty<LottieProperty::Type::ColorStop>(gradient->colorStops, gradient);
|
||||
else if (KEY_AS("sid")) registerSlot<LottieProperty::Type::ColorStop>(gradient);
|
||||
else skip(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LottieParser::parseGradient(LottieGradient* gradient, const char* key)
|
||||
{
|
||||
if (KEY_AS("t")) gradient->id = getInt();
|
||||
else if (KEY_AS("o")) parseProperty<LottieProperty::Type::Opacity>(gradient->opacity, gradient);
|
||||
else if (KEY_AS("g")) parseColorStop(gradient);
|
||||
else if (KEY_AS("s")) parseProperty<LottieProperty::Type::Point>(gradient->start, gradient);
|
||||
else if (KEY_AS("e")) parseProperty<LottieProperty::Type::Point>(gradient->end, gradient);
|
||||
else if (KEY_AS("h")) parseProperty<LottieProperty::Type::Float>(gradient->height, gradient);
|
||||
|
@ -1438,7 +1447,10 @@ bool LottieParser::apply(LottieSlot* slot)
|
|||
case LottieProperty::Type::ColorStop: {
|
||||
obj = new LottieGradient;
|
||||
context.parent = obj;
|
||||
parseSlotProperty<LottieProperty::Type::ColorStop>(static_cast<LottieGradient*>(obj)->colorStops);
|
||||
while (auto key = nextObjectKey()) {
|
||||
if (KEY_AS("p")) parseColorStop(static_cast<LottieGradient*>(obj));
|
||||
else skip(key);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case LottieProperty::Type::Color: {
|
||||
|
|
|
@ -38,6 +38,7 @@ public:
|
|||
bool parse();
|
||||
bool apply(LottieSlot* slot);
|
||||
const char* sid(bool first = false);
|
||||
template<LottieProperty::Type type = LottieProperty::Type::Invalid> void registerSlot(LottieObject* obj);
|
||||
|
||||
LottieComposition* comp = nullptr;
|
||||
const char* dirName = nullptr; //base resource directory
|
||||
|
@ -107,6 +108,7 @@ private:
|
|||
void parseTimeRemap(LottieLayer* layer);
|
||||
void parseStrokeDash(LottieStroke* stroke);
|
||||
void parseGradient(LottieGradient* gradient, const char* key);
|
||||
void parseColorStop(LottieGradient* gradient);
|
||||
void parseTextRange(LottieText* text);
|
||||
void parseAssets();
|
||||
void parseFonts();
|
||||
|
|
|
@ -41,7 +41,7 @@ TEST_CASE("Lottie Slot", "[capiLottie]")
|
|||
REQUIRE(tvg_paint_get_type(picture, &type) == TVG_RESULT_SUCCESS);
|
||||
REQUIRE(type == TVG_TYPE_PICTURE);
|
||||
|
||||
const char* slotJson = R"({"gradient_fill":{"p":{"a":0,"k":[0,0.1,0.1,0.2,1,1,0.1,0.2,0.1,1]}}})";
|
||||
const char* slotJson = R"({"gradient_fill":{"p":{"p":2,"k":{"a":0,"k":[0,0.1,0.1,0.2,1,1,0.1,0.2,0.1,1]}}}})";
|
||||
|
||||
//Slot override before loaded
|
||||
REQUIRE(tvg_lottie_animation_override(animation, slotJson) == TVG_RESULT_INSUFFICIENT_CONDITION);
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"v":"4.8.0","meta":{"g":"LottieFiles AE 3.0.2","a":"","k":"","d":"","tc":""},"fr":60,"ip":0,"op":121,"w":550,"h":550,"nm":"C","assets":[],"layers":[{"ind":1,"ty":4,"nm":"S","sr":1,"ks":{"o":{"a":0,"k":100},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":120,"s":[360]}]},"p":{"a":0,"k":[275,275,0]},"a":{"a":0,"k":[-7.886,88.719,0]},"s":{"a":0,"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[282.019,134.888]},"p":{"a":0,"k":[0,0]},"r":{"a":0,"k":0},"nm":"R"},{"ty":"st","c":{"a":0,"k":[0.991,0,1,1]},"o":{"a":0,"k":100},"w":{"a":0,"k":3},"lc":1,"lj":1,"ml":4,"nm":"S"},{"ty":"gf","o":{"a":0,"k":100},"r":1,"g":{"p":9,"k":{"a":0,"k":[0,0.514,0.373,0.984,0.141,0.478,0.412,0.984,0.283,0.443,0.451,0.984,0.379,0.408,0.49,0.984,0.475,0.373,0.529,0.984,0.606,0.278,0.647,0.925,0.737,0.184,0.765,0.867,0.868,0.092,0.882,0.808,1,0,1,0.749],"sid":"gradient_fill"}},"s":{"a":0,"k":[-159.51,23.531]},"e":{"a":0,"k":[183.084,8.059]},"t":1,"nm":"G"},{"ty":"tr","p":{"a":0,"k":[-7.886,88.719]},"a":{"a":0,"k":[0,0]},"s":{"a":0,"k":[100,100]},"r":{"a":0,"k":0},"o":{"a":0,"k":100},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0},"nm":"T"}],"nm":"R"}],"ip":0,"op":300,"st":0}],"slots":{"gradient_fill":{"p":{"a":0,"k":[0,0.1,0.1,0.2,1,1,0.1,0.2,0.1,1]}}},"markers":[]}
|
||||
{"v":"4.8.0","meta":{"g":"LottieFiles AE 3.0.2","a":"","k":"","d":"","tc":""},"fr":60,"ip":0,"op":121,"w":550,"h":550,"nm":"C","assets":[],"layers":[{"ind":1,"ty":4,"nm":"S","sr":1,"ks":{"o":{"a":0,"k":100},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":120,"s":[360]}]},"p":{"a":0,"k":[275,275,0]},"a":{"a":0,"k":[-7.886,88.719,0]},"s":{"a":0,"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[282.019,134.888]},"p":{"a":0,"k":[0,0]},"r":{"a":0,"k":0},"nm":"R"},{"ty":"st","c":{"a":0,"k":[0.991,0,1,1]},"o":{"a":0,"k":100},"w":{"a":0,"k":3},"lc":1,"lj":1,"ml":4,"nm":"S"},{"ty":"gf","o":{"a":0,"k":100},"r":1,"g":{"p":9,"k":{"a":0,"k":[0,0.514,0.373,0.984,0.141,0.478,0.412,0.984,0.283,0.443,0.451,0.984,0.379,0.408,0.49,0.984,0.475,0.373,0.529,0.984,0.606,0.278,0.647,0.925,0.737,0.184,0.765,0.867,0.868,0.092,0.882,0.808,1,0,1,0.749]},"sid":"gradient_fill"},"s":{"a":0,"k":[-159.51,23.531]},"e":{"a":0,"k":[183.084,8.059]},"t":1,"nm":"G"},{"ty":"tr","p":{"a":0,"k":[-7.886,88.719]},"a":{"a":0,"k":[0,0]},"s":{"a":0,"k":[100,100]},"r":{"a":0,"k":0},"o":{"a":0,"k":100},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0},"nm":"T"}],"nm":"R"}],"ip":0,"op":300,"st":0}],"slots":{"gradient_fill":{"p":{"a":0,"k":[0,0.1,0.1,0.2,1,1,0.1,0.2,0.1,1]}}},"markers":[]}
|
|
@ -44,7 +44,7 @@ TEST_CASE("Lottie Slot", "[tvgLottie]")
|
|||
auto picture = animation->picture();
|
||||
REQUIRE(picture->type() == Type::Picture);
|
||||
|
||||
const char* slotJson = R"({"gradient_fill":{"p":{"a":0,"k":[0,0.1,0.1,0.2,1,1,0.1,0.2,0.1,1]}}})";
|
||||
const char* slotJson = R"({"gradient_fill":{"p":{"p":2,"k":{"a":0,"k":[0,0.1,0.1,0.2,1,1,0.1,0.2,0.1,1]}}}})";
|
||||
|
||||
//Slot override before loaded
|
||||
REQUIRE(animation->override(slotJson) == Result::InsufficientCondition);
|
||||
|
|
Loading…
Add table
Reference in a new issue