From a0a7ec25a2b0e8dac54e9d760cbeeea02a0c6eb6 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Wed, 11 Dec 2024 19:40:26 +0900 Subject: [PATCH] lottie: support Layer Effect Fill type During the fill properties, only color/opacity is available. Not support other properties since they are unclear spec now. issue: https://github.com/thorvg/thorvg/issues/2718 --- src/loaders/lottie/tvgLottieBuilder.cpp | 10 ++++-- src/loaders/lottie/tvgLottieModel.h | 28 +++++++++++++--- src/loaders/lottie/tvgLottieParser.cpp | 43 ++++++++++++++++++++----- src/loaders/lottie/tvgLottieParser.h | 5 +-- 4 files changed, 69 insertions(+), 17 deletions(-) diff --git a/src/loaders/lottie/tvgLottieBuilder.cpp b/src/loaders/lottie/tvgLottieBuilder.cpp index 348a152a..a4ee8337 100644 --- a/src/loaders/lottie/tvgLottieBuilder.cpp +++ b/src/loaders/lottie/tvgLottieBuilder.cpp @@ -1314,14 +1314,20 @@ void LottieBuilder::updateEffect(LottieLayer* layer, float frameNo) for (auto ef = layer->effects.begin(); ef < layer->effects.end(); ++ef) { if (!(*ef)->enable) continue; switch ((*ef)->type) { + case LottieEffect::Fill: { + auto effect = static_cast(*ef); + auto color = effect->color(frameNo); + layer->scene->push(SceneEffect::Fill, color.rgb[0], color.rgb[1], color.rgb[2], (int)(255.0f *effect->opacity(frameNo))); + break; + } case LottieEffect::DropShadow: { - auto effect = static_cast(*ef); + auto effect = static_cast(*ef); auto color = effect->color(frameNo); layer->scene->push(SceneEffect::DropShadow, color.rgb[0], color.rgb[1], color.rgb[2], (int)effect->opacity(frameNo), effect->angle(frameNo), effect->distance(frameNo), effect->blurness(frameNo) * BLUR_TO_SIGMA, QUALITY); break; } case LottieEffect::GaussianBlur: { - auto effect = static_cast(*ef); + auto effect = static_cast(*ef); layer->scene->push(SceneEffect::GaussianBlur, effect->blurness(frameNo) * BLUR_TO_SIGMA, effect->direction(frameNo) - 1, effect->wrap(frameNo), QUALITY); break; } diff --git a/src/loaders/lottie/tvgLottieModel.h b/src/loaders/lottie/tvgLottieModel.h index 93081d34..ceab9ff9 100644 --- a/src/loaders/lottie/tvgLottieModel.h +++ b/src/loaders/lottie/tvgLottieModel.h @@ -83,6 +83,7 @@ struct LottieEffect { DropShadow = 0, GaussianBlur = 1, + Fill = 2, }; virtual ~LottieEffect() {} @@ -92,28 +93,45 @@ struct LottieEffect }; -struct LottieDropShadow : LottieEffect +struct LottieFxFill : LottieEffect +{ + //LottieFloat fillMask? + //LottieDropDown allMask? + LottieColor color; + //LottieDropDown inverted + //LottieSlider horizontalFeather + //LottieSlider verticalFeather + LottieSlider opacity = 0; + + LottieFxFill() + { + type = Fill; + } +}; + + +struct LottieFxDropShadow : LottieEffect { LottieColor color; - LottieFloat opacity = 0; + LottieSlider opacity = 0; LottieAngle angle = 0.0f; LottieSlider distance = 0.0f; LottieSlider blurness = 0.0f; - LottieDropShadow() + LottieFxDropShadow() { type = DropShadow; } }; -struct LottieGaussianBlur : LottieEffect +struct LottieFxGaussianBlur : LottieEffect { LottieSlider blurness = 0.0f; LottieCheckbox direction = 0; LottieCheckbox wrap = 0; - LottieGaussianBlur() + LottieFxGaussianBlur() { type = GaussianBlur; } diff --git a/src/loaders/lottie/tvgLottieParser.cpp b/src/loaders/lottie/tvgLottieParser.cpp index de196783..3687fe56 100644 --- a/src/loaders/lottie/tvgLottieParser.cpp +++ b/src/loaders/lottie/tvgLottieParser.cpp @@ -60,8 +60,9 @@ static unsigned long _int2str(int num) LottieEffect* LottieParser::getEffect(int type) { switch (type) { - case 25: return new LottieDropShadow; - case 29: return new LottieGaussianBlur; + case 21: return new LottieFxFill; + case 25: return new LottieFxDropShadow; + case 29: return new LottieFxGaussianBlur; default: return nullptr; } } @@ -1268,7 +1269,30 @@ void LottieParser::parseMasks(LottieLayer* layer) } -void LottieParser::parseGaussianBlur(LottieGaussianBlur* effect) +void LottieParser::parseFill(LottieFxFill* effect) +{ + int idx = 0; //fill mask -> all mask -> color -> invert -> h feather -> v feather -> opacity + 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(); + } else skip(); + } + ++idx; + } else skip(); + } + } +} + + +void LottieParser::parseGaussianBlur(LottieFxGaussianBlur* effect) { int idx = 0; //blurness -> direction -> wrap enterArray(); @@ -1292,7 +1316,7 @@ void LottieParser::parseGaussianBlur(LottieGaussianBlur* effect) } -void LottieParser::parseDropShadow(LottieDropShadow* effect) +void LottieParser::parseDropShadow(LottieFxDropShadow* effect) { int idx = 0; //color -> opacity -> angle -> distance -> blur enterArray(); @@ -1321,12 +1345,16 @@ void LottieParser::parseDropShadow(LottieDropShadow* effect) void LottieParser::parseEffect(LottieEffect* effect) { switch (effect->type) { + case LottieEffect::Fill: { + parseFill(static_cast(effect)); + break; + } case LottieEffect::GaussianBlur: { - parseGaussianBlur(static_cast(effect)); + parseGaussianBlur(static_cast(effect)); break; } case LottieEffect::DropShadow: { - parseDropShadow(static_cast(effect)); + parseDropShadow(static_cast(effect)); break; } default: break; @@ -1336,11 +1364,10 @@ void LottieParser::parseEffect(LottieEffect* effect) void LottieParser::parseEffects(LottieLayer* layer) { - auto invalid = true; - enterArray(); while (nextArrayValue()) { LottieEffect* effect = nullptr; + auto invalid = true; enterObject(); while (auto key = nextObjectKey()) { //type must be priortized. diff --git a/src/loaders/lottie/tvgLottieParser.h b/src/loaders/lottie/tvgLottieParser.h index 1922826d..d6550afb 100644 --- a/src/loaders/lottie/tvgLottieParser.h +++ b/src/loaders/lottie/tvgLottieParser.h @@ -98,8 +98,9 @@ private: LottieFont* parseFont(); LottieMarker* parseMarker(); - void parseGaussianBlur(LottieGaussianBlur* effect); - void parseDropShadow(LottieDropShadow* effect); + void parseFill(LottieFxFill* effect); + void parseGaussianBlur(LottieFxGaussianBlur* effect); + void parseDropShadow(LottieFxDropShadow* effect); bool parseDirection(LottieShape* shape, const char* key); bool parseCommon(LottieObject* obj, const char* key);