From 09ebf10432962e3824294349982514a967ec0522 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Sat, 25 Jan 2025 02:33:20 +0900 Subject: [PATCH] lottie: revise the effect parsing logic Unify the common parts of the parsing logic by applying a strategy pattern, allowing the behavior to vary based on the effect type. This helps to reduce the size and improved the parsing safety. --- src/loaders/lottie/tvgLottieParser.cpp | 188 +++++++------------- src/loaders/lottie/tvgLottieParser.h | 13 +- src/loaders/lottie/tvgLottieParserHandler.h | 2 +- 3 files changed, 74 insertions(+), 129 deletions(-) diff --git a/src/loaders/lottie/tvgLottieParser.cpp b/src/loaders/lottie/tvgLottieParser.cpp index c9b4597f..e05d58f6 100644 --- a/src/loaders/lottie/tvgLottieParser.cpp +++ b/src/loaders/lottie/tvgLottieParser.cpp @@ -1261,7 +1261,7 @@ void LottieParser::parseMasks(LottieLayer* layer) } -void LottieParser::parseTint(LottieFxTint* effect) +void LottieParser::parseEffect(LottieEffect* effect, void(LottieParser::*func)(LottieEffect*, int)) { int idx = 0; enterArray(); @@ -1269,144 +1269,88 @@ void LottieParser::parseTint(LottieFxTint* effect) enterObject(); while (auto key = nextObjectKey()) { if (KEY_AS("v")) { - enterObject(); - while (auto key = nextObjectKey()) { - if (KEY_AS("k")) { - if (idx == 0) parsePropertyInternal(effect->black); - else if (idx == 1) parsePropertyInternal(effect->white); - else if (idx == 2) parsePropertyInternal(effect->intensity); + if (peekType() == kObjectType) { + enterObject(); + while (auto key = nextObjectKey()) { + if (KEY_AS("k")) (this->*func)(effect, idx); else skip(key); - } else skip(key); - } - ++idx; - } else skip(key); + } + ++idx; + } else skip(); + } else skip(); } } } -void LottieParser::parseTritone(LottieFxTritone* effect) +void LottieParser::parseTint(LottieEffect* effect, int idx) { - int idx = 0; - enterArray(); - while (nextArrayValue()) { - enterObject(); - while (auto key = nextObjectKey()) { - if (KEY_AS("v")) { - enterObject(); - while (auto key = nextObjectKey()) { - if (KEY_AS("k")) { - if (idx == 0) parsePropertyInternal(effect->bright); - else if (idx == 1) parsePropertyInternal(effect->midtone); - else if (idx == 2) parsePropertyInternal(effect->dark); - else skip(key); - } else skip(key); - } - ++idx; - } else skip(key); - } - } + auto tint = static_cast(effect); + + if (idx == 0) parsePropertyInternal(tint->black); + else if (idx == 1) parsePropertyInternal(tint->white); + else if (idx == 2) parsePropertyInternal(tint->intensity); + else skip(); } -void LottieParser::parseFill(LottieFxFill* effect) +void LottieParser::parseTritone(LottieEffect* effect, int idx) { - int idx = 0; - enterArray(); - while (nextArrayValue()) { - enterObject(); - while (auto key = nextObjectKey()) { - if (KEY_AS("v")) { - enterObject(); - while (auto key = nextObjectKey()) { - if (KEY_AS("k")) { - if (idx == 2) parsePropertyInternal(effect->color); - else if (idx == 6) parsePropertyInternal(effect->opacity); - else skip(key); - } else skip(key); - } - ++idx; - } else skip(key); - } - } + auto tritone = static_cast(effect); + + if (idx == 0) parsePropertyInternal(tritone->bright); + else if (idx == 1) parsePropertyInternal(tritone->midtone); + else if (idx == 2) parsePropertyInternal(tritone->dark); + else skip(); } -void LottieParser::parseGaussianBlur(LottieFxGaussianBlur* effect) +void LottieParser::parseFill(LottieEffect* effect, int idx) { - int idx = 0; - enterArray(); - while (nextArrayValue()) { - enterObject(); - while (auto key = nextObjectKey()) { - if (KEY_AS("v")) { - enterObject(); - while (auto key = nextObjectKey()) { - if (KEY_AS("k")) { - if (idx == 0) parsePropertyInternal(effect->blurness); - else if (idx == 1) parsePropertyInternal(effect->direction); - else if (idx == 2) parsePropertyInternal(effect->wrap); - else skip(key); - ++idx; - } else skip(key); - } - } else skip(key); - } - } + auto fill = static_cast(effect); + + if (idx == 2) parsePropertyInternal(fill->color); + else if (idx == 6) parsePropertyInternal(fill->opacity); + else skip(); } -void LottieParser::parseDropShadow(LottieFxDropShadow* effect) +void LottieParser::parseGaussianBlur(LottieEffect* effect, int idx) { - int idx = 0; - enterArray(); - while (nextArrayValue()) { - enterObject(); - while (auto key = nextObjectKey()) { - if (KEY_AS("v")) { - enterObject(); - while (auto key = nextObjectKey()) { - if (KEY_AS("k")) { - if (idx == 0) parsePropertyInternal(effect->color); - else if (idx == 1) parsePropertyInternal(effect->opacity); - else if (idx == 2) parsePropertyInternal(effect->angle); - else if (idx == 3) parsePropertyInternal(effect->distance); - else if (idx == 4) parsePropertyInternal(effect->blurness); - else skip(key); - ++idx; - } else skip(key); - } - } else skip(key); - } - } + auto blur = static_cast(effect); + + if (idx == 0) parsePropertyInternal(blur->blurness); + else if (idx == 1) parsePropertyInternal(blur->direction); + else if (idx == 2) parsePropertyInternal(blur->wrap); + else skip(); } -void LottieParser::parseStroke(LottieFxStroke* effect) +void LottieParser::parseDropShadow(LottieEffect* effect, int idx) { - int idx = 0; - enterArray(); - while (nextArrayValue()) { - enterObject(); - while (auto key = nextObjectKey()) { - if (KEY_AS("v")) { - enterObject(); - while (auto key = nextObjectKey()) { - if (KEY_AS("k")) { - if (idx == 0) parsePropertyInternal(effect->mask); - else if (idx == 1) parsePropertyInternal(effect->allMask); - else if (idx == 3) parsePropertyInternal(effect->color); - else if (idx == 4) parsePropertyInternal(effect->size); - else if (idx == 6) parsePropertyInternal(effect->opacity); - else if (idx == 7) parsePropertyInternal(effect->begin); - else if (idx == 8) parsePropertyInternal(effect->end); - else skip(key); - ++idx; - } else skip(key); - } - } else skip(key); - } - } + auto shadow = static_cast(effect); + + if (idx == 0) parsePropertyInternal(shadow->color); + else if (idx == 1) parsePropertyInternal(shadow->opacity); + else if (idx == 2) parsePropertyInternal(shadow->angle); + else if (idx == 3) parsePropertyInternal(shadow->distance); + else if (idx == 4) parsePropertyInternal(shadow->blurness); + else skip(); +} + + +void LottieParser::parseStroke(LottieEffect* effect, int idx) +{ + auto stroke = static_cast(effect); + + if (idx == 0) parsePropertyInternal(stroke->mask); + else if (idx == 1) parsePropertyInternal(stroke->allMask); + else if (idx == 3) parsePropertyInternal(stroke->color); + else if (idx == 4) parsePropertyInternal(stroke->size); + else if (idx == 6) parsePropertyInternal(stroke->opacity); + else if (idx == 7) parsePropertyInternal(stroke->begin); + else if (idx == 8) parsePropertyInternal(stroke->end); + else skip(); } @@ -1414,27 +1358,27 @@ void LottieParser::parseEffect(LottieEffect* effect) { switch (effect->type) { case LottieEffect::Tint: { - parseTint(static_cast(effect)); + parseEffect(effect, &LottieParser::parseTint); break; } case LottieEffect::Fill: { - parseFill(static_cast(effect)); + parseEffect(effect, &LottieParser::parseFill); break; } case LottieEffect::Stroke: { - parseStroke(static_cast(effect)); + parseEffect(effect, &LottieParser::parseStroke); break; } case LottieEffect::Tritone: { - parseTritone(static_cast(effect)); + parseEffect(effect, &LottieParser::parseTritone); break; } case LottieEffect::DropShadow: { - parseDropShadow(static_cast(effect)); + parseEffect(effect, &LottieParser::parseDropShadow); break; } case LottieEffect::GaussianBlur: { - parseGaussianBlur(static_cast(effect)); + parseEffect(effect, &LottieParser::parseGaussianBlur); break; } default: break; diff --git a/src/loaders/lottie/tvgLottieParser.h b/src/loaders/lottie/tvgLottieParser.h index af5a42ba..29bc6eae 100644 --- a/src/loaders/lottie/tvgLottieParser.h +++ b/src/loaders/lottie/tvgLottieParser.h @@ -98,12 +98,13 @@ private: LottieFont* parseFont(); LottieMarker* parseMarker(); - void parseStroke(LottieFxStroke* effect); - void parseTritone(LottieFxTritone* effect); - void parseTint(LottieFxTint* effect); - void parseFill(LottieFxFill* effect); - void parseGaussianBlur(LottieFxGaussianBlur* effect); - void parseDropShadow(LottieFxDropShadow* effect); + void parseEffect(LottieEffect* effect, void(LottieParser::*func)(LottieEffect*, int)); + void parseStroke(LottieEffect* effect, int idx); + void parseTritone(LottieEffect* effect, int idx); + void parseTint(LottieEffect* effect, int idx); + void parseFill(LottieEffect* effect, int idx); + void parseGaussianBlur(LottieEffect* effect, int idx); + void parseDropShadow(LottieEffect* effect, int idx); bool parseDirection(LottieShape* shape, const char* key); bool parseCommon(LottieObject* obj, const char* key); diff --git a/src/loaders/lottie/tvgLottieParserHandler.h b/src/loaders/lottie/tvgLottieParserHandler.h index 150912e9..199f1594 100644 --- a/src/loaders/lottie/tvgLottieParserHandler.h +++ b/src/loaders/lottie/tvgLottieParserHandler.h @@ -192,7 +192,7 @@ struct LookaheadParserHandler void getNull(); bool parseNext(); const char* nextObjectKey(); - void skip(const char* key); + void skip(const char* key = nullptr); void skipOut(int depth); int peekType(); char* getPos();