lottie: support default slot overriding

issue: https://github.com/thorvg/thorvg/issues/2915
This commit is contained in:
Hermet Park 2024-11-09 15:00:28 +09:00
parent f42559e613
commit e12765ef41
8 changed files with 61 additions and 7 deletions

View file

@ -43,6 +43,10 @@ void LottieLoader::run(unsigned tid)
ScopedLock lock(key);
comp = parser.comp;
}
if (parser.slots) {
override(parser.slots, false);
parser.slots = nullptr;
}
builder->build(comp);
release();
@ -286,16 +290,16 @@ Paint* LottieLoader::paint()
}
bool LottieLoader::override(const char* slot)
bool LottieLoader::override(const char* slots, bool copy)
{
if (!ready() || comp->slots.count == 0) return false;
auto success = true;
//override slots
if (slot) {
if (slots) {
//Copy the input data because the JSON parser will encode the data immediately.
auto temp = strdup(slot);
auto temp = copy ? strdup(slots) : slots;
//parsing slot json
LottieParser parser(temp, dirName);
@ -312,7 +316,7 @@ bool LottieLoader::override(const char* slot)
}
if (idx < 1) success = false;
free(temp);
free((char*)temp);
rebuild = overridden = success;
//reset slots
} else if (overridden) {

View file

@ -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 override(const char* slot, bool copy = true);
//Frame Controls
bool frame(float no) override;

View file

@ -584,7 +584,6 @@ struct LottieGradient : LottieObject
return nullptr;
}
uint32_t populate(ColorStop& color, size_t count);
Fill* fill(float frameNo, LottieExpressions* exps);

View file

@ -1478,6 +1478,47 @@ bool LottieParser::apply(LottieSlot* slot)
}
void LottieParser::captureSlots(const char* key)
{
free(slots);
// TODO: Replace with immediate parsing, once the slot spec is confirmed by the LAC
auto begin = getPos();
auto end = getPos();
auto depth = 1;
auto invalid = true;
//get slots string
while (++end) {
if (*end == '}') {
--depth;
if (depth == 0) {
invalid = false;
break;
}
} else if (*end == '{') {
++depth;
}
}
if (invalid) {
TVGERR("LOTTIE", "Invalid Slots!");
skip(key);
return;
}
//composite '{' + slots + '}'
auto len = (end - begin + 2);
slots = (char*)malloc(sizeof(char) * len + 1);
slots[0] = '{';
memcpy(slots + 1, begin, len);
slots[len] = '\0';
skip(key);
}
bool LottieParser::parse()
{
//verify json.
@ -1506,6 +1547,7 @@ bool LottieParser::parse()
else if (KEY_AS("fonts")) parseFonts();
else if (KEY_AS("chars")) parseChars(glyphs);
else if (KEY_AS("markers")) parseMarkers();
else if (KEY_AS("slots")) captureSlots(key);
else skip(key);
}

View file

@ -38,10 +38,12 @@ public:
bool parse();
bool apply(LottieSlot* slot);
const char* sid(bool first = false);
void captureSlots(const char* key);
template<LottieProperty::Type type = LottieProperty::Type::Invalid> void registerSlot(LottieObject* obj);
LottieComposition* comp = nullptr;
const char* dirName = nullptr; //base resource directory
char* slots = nullptr;
private:
RGB24 getColor(const char *str);

View file

@ -232,4 +232,10 @@ void LookaheadParserHandler::skip(const char* key)
} else {
skipOut(0);
}
}
char* LookaheadParserHandler::getPos()
{
return iss.src_;
}

View file

@ -195,6 +195,7 @@ struct LookaheadParserHandler
void skip(const char* key);
void skipOut(int depth);
int peekType();
char* getPos();
};
#endif //_TVG_LOTTIE_PARSER_HANDLER_H_

View file

@ -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}],"markers":[]}