From 4a1fc2bff029c4ba231d4b57d1b962c4bcfb6f4f Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Tue, 17 Dec 2024 15:57:55 +0900 Subject: [PATCH] lottie: support Tritone LayerEffect issue: https://github.com/thorvg/thorvg/issues/2718 --- src/loaders/lottie/tvgLottieBuilder.cpp | 36 ++++++++++++--------- src/loaders/lottie/tvgLottieModel.h | 35 +++++++++++---------- src/loaders/lottie/tvgLottieParser.cpp | 42 +++++++++++++++++++++---- src/loaders/lottie/tvgLottieParser.h | 1 + 4 files changed, 78 insertions(+), 36 deletions(-) diff --git a/src/loaders/lottie/tvgLottieBuilder.cpp b/src/loaders/lottie/tvgLottieBuilder.cpp index 3e8e622e..0da9ea98 100644 --- a/src/loaders/lottie/tvgLottieBuilder.cpp +++ b/src/loaders/lottie/tvgLottieBuilder.cpp @@ -1314,17 +1314,9 @@ 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::Tint: { - auto effect = static_cast(*ef); - auto black = effect->black(frameNo); - auto white = effect->white(frameNo); - layer->scene->push(SceneEffect::Tint, black.rgb[0], black.rgb[1], black.rgb[2], white.rgb[0], white.rgb[1], white.rgb[2], effect->intensity(frameNo)); - break; - } - 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))); + case LottieEffect::GaussianBlur: { + 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; } case LottieEffect::DropShadow: { @@ -1333,9 +1325,25 @@ void LottieBuilder::updateEffect(LottieLayer* layer, float 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); - layer->scene->push(SceneEffect::GaussianBlur, effect->blurness(frameNo) * BLUR_TO_SIGMA, effect->direction(frameNo) - 1, effect->wrap(frameNo), QUALITY); + 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::Tint: { + auto effect = static_cast(*ef); + auto black = effect->black(frameNo); + auto white = effect->white(frameNo); + layer->scene->push(SceneEffect::Tint, black.rgb[0], black.rgb[1], black.rgb[2], white.rgb[0], white.rgb[1], white.rgb[2], effect->intensity(frameNo)); + break; + } + case LottieEffect::Tritone: { + auto effect = static_cast(*ef); + auto dark = effect->dark(frameNo); + auto midtone = effect->midtone(frameNo); + auto bright = effect->bright(frameNo); + layer->scene->push(SceneEffect::Tritone, dark.rgb[0], dark.rgb[1], dark.rgb[2], midtone.rgb[0], midtone.rgb[1], midtone.rgb[2], bright.rgb[0], bright.rgb[1], bright.rgb[2]); break; } default: break; diff --git a/src/loaders/lottie/tvgLottieModel.h b/src/loaders/lottie/tvgLottieModel.h index 8b3efdcb..e4170b1a 100644 --- a/src/loaders/lottie/tvgLottieModel.h +++ b/src/loaders/lottie/tvgLottieModel.h @@ -79,34 +79,26 @@ struct LottieStroke struct LottieEffect { - enum Type : uint8_t - { - DropShadow = 0, - GaussianBlur, - Fill, - Tint - }; + enum Type : uint8_t {Tint = 20, Fill, Tritone = 23, DropShadow = 25, GaussianBlur = 29}; virtual ~LottieEffect() {} - Type type; bool enable = false; }; - struct LottieFxFill : LottieEffect { - //LottieFloat fillMask? + //int16_t mask layer //LottieDropDown allMask? LottieColor color; //LottieDropDown inverted //LottieSlider horizontalFeather //LottieSlider verticalFeather - LottieSlider opacity = 0; + LottieSlider opacity; LottieFxFill() { - type = Fill; + type = LottieEffect::Fill; } }; @@ -118,7 +110,19 @@ struct LottieFxTint : LottieEffect LottieFxTint() { - type = Tint; + type = LottieEffect::Tint; + } +}; + +struct LottieFxTritone : LottieEffect +{ + LottieColor bright; + LottieColor midtone; + LottieColor dark; + + LottieFxTritone() + { + type = LottieEffect::Tritone; } }; @@ -132,11 +136,10 @@ struct LottieFxDropShadow : LottieEffect LottieFxDropShadow() { - type = DropShadow; + type = LottieEffect::DropShadow; } }; - struct LottieFxGaussianBlur : LottieEffect { LottieSlider blurness = 0.0f; @@ -145,7 +148,7 @@ struct LottieFxGaussianBlur : LottieEffect LottieFxGaussianBlur() { - type = GaussianBlur; + type = LottieEffect::GaussianBlur; } }; diff --git a/src/loaders/lottie/tvgLottieParser.cpp b/src/loaders/lottie/tvgLottieParser.cpp index 199bdbc4..7dcb2e2d 100644 --- a/src/loaders/lottie/tvgLottieParser.cpp +++ b/src/loaders/lottie/tvgLottieParser.cpp @@ -60,10 +60,11 @@ static unsigned long _int2str(int num) LottieEffect* LottieParser::getEffect(int type) { switch (type) { - case 20: return new LottieFxTint; - case 21: return new LottieFxFill; - case 25: return new LottieFxDropShadow; - case 29: return new LottieFxGaussianBlur; + case LottieEffect::Tint: return new LottieFxTint; + case LottieEffect::Fill: return new LottieFxFill; + case LottieEffect::Tritone: return new LottieFxTritone; + case LottieEffect::DropShadow: return new LottieFxDropShadow; + case LottieEffect::GaussianBlur: return new LottieFxGaussianBlur; default: return nullptr; } } @@ -1294,6 +1295,31 @@ void LottieParser::parseTint(LottieFxTint* effect) } +void LottieParser::parseTritone(LottieFxTritone* effect) +{ + int idx = 0; //bright, midtone, dark + 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(); + } else skip(); + } + ++idx; + } else skip(); + } + } +} + + + void LottieParser::parseFill(LottieFxFill* effect) { int idx = 0; //fill mask -> all mask -> color -> invert -> h feather -> v feather -> opacity @@ -1378,14 +1404,18 @@ void LottieParser::parseEffect(LottieEffect* effect) parseFill(static_cast(effect)); break; } - case LottieEffect::GaussianBlur: { - parseGaussianBlur(static_cast(effect)); + case LottieEffect::Tritone: { + parseTritone(static_cast(effect)); break; } case LottieEffect::DropShadow: { parseDropShadow(static_cast(effect)); break; } + case LottieEffect::GaussianBlur: { + parseGaussianBlur(static_cast(effect)); + break; + } default: break; } } diff --git a/src/loaders/lottie/tvgLottieParser.h b/src/loaders/lottie/tvgLottieParser.h index a765cd1d..7fb65231 100644 --- a/src/loaders/lottie/tvgLottieParser.h +++ b/src/loaders/lottie/tvgLottieParser.h @@ -98,6 +98,7 @@ private: LottieFont* parseFont(); LottieMarker* parseMarker(); + void parseTritone(LottieFxTritone* effect); void parseTint(LottieFxTint* effect); void parseFill(LottieFxFill* effect); void parseGaussianBlur(LottieFxGaussianBlur* effect);