From 67f103bc8b625f2a4a9e94f1d8c7bd84c5a08d1d Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Wed, 17 Nov 2021 13:49:48 +0400 Subject: [PATCH] Add Fitzpatrick skin type based color replacement --- inc/rlottie.h | 11 ++++- src/lottie/lottieanimation.cpp | 4 +- src/lottie/lottieloader.cpp | 4 +- src/lottie/lottieloader.h | 4 +- src/lottie/lottieparser.cpp | 83 +++++++++++++++++++++++++++++++--- src/lottie/lottieparser.h | 3 +- 6 files changed, 96 insertions(+), 13 deletions(-) diff --git a/inc/rlottie.h b/inc/rlottie.h index 1436539..db81448 100644 --- a/inc/rlottie.h +++ b/inc/rlottie.h @@ -43,6 +43,15 @@ struct LOTLayerNode; namespace rlottie { +enum class FitzModifier { + None, + Type12, + Type3, + Type4, + Type5, + Type6 +}; + /** * @brief Configures rlottie model cache policy. * @@ -293,7 +302,7 @@ class LOT_EXPORT Animation { loadFromData(std::string jsonData, const std::string &key, const std::string &resourcePath="", bool cachePolicy=true, const std::vector> - &colorReplacements = {}); + &colorReplacements = {}, FitzModifier fitzModifier = FitzModifier::None); /** * @brief Returns default framerate of the Lottie resource. diff --git a/src/lottie/lottieanimation.cpp b/src/lottie/lottieanimation.cpp index 58d1b13..197d259 100644 --- a/src/lottie/lottieanimation.cpp +++ b/src/lottie/lottieanimation.cpp @@ -242,7 +242,7 @@ std::unique_ptr Animation::loadFromData( std::string jsonData, const std::string &key, const std::string &resourcePath, bool cachePolicy, const std::vector> - &colorReplacements) + &colorReplacements, FitzModifier fitzModifier) { if (jsonData.empty()) { vWarning << "jason data is empty"; @@ -252,7 +252,7 @@ std::unique_ptr Animation::loadFromData( LottieLoader loader; if (loader.loadFromData(std::move(jsonData), key, (resourcePath.empty() ? " " : resourcePath), - cachePolicy, colorReplacements)) { + cachePolicy, colorReplacements, fitzModifier)) { auto animation = std::unique_ptr(new Animation); animation->d->init(loader.model()); return animation; diff --git a/src/lottie/lottieloader.cpp b/src/lottie/lottieloader.cpp index 8c06780..feacde0 100644 --- a/src/lottie/lottieloader.cpp +++ b/src/lottie/lottieloader.cpp @@ -144,7 +144,7 @@ bool LottieLoader::loadFromData( std::string &&jsonData, const std::string &key, const std::string &resourcePath, bool cachePolicy, const std::vector> - &colorReplacements) + &colorReplacements, rlottie::FitzModifier fitzModifier) { if (cachePolicy) { mModel = LottieModelCache::instance().find(key); @@ -152,7 +152,7 @@ bool LottieLoader::loadFromData( } LottieParser parser(const_cast(jsonData.c_str()), - resourcePath.c_str(), colorReplacements); + resourcePath.c_str(), colorReplacements, fitzModifier); mModel = parser.model(); if (!mModel) return false; diff --git a/src/lottie/lottieloader.h b/src/lottie/lottieloader.h index 711d0d6..48c1bc4 100644 --- a/src/lottie/lottieloader.h +++ b/src/lottie/lottieloader.h @@ -23,6 +23,8 @@ #include #include +#include "rlottie.h" + class LOTModel; class LottieLoader { @@ -32,7 +34,7 @@ class LottieLoader bool loadFromData(std::string &&jsonData, const std::string &key, const std::string &resourcePath, bool cachePolicy, const std::vector> - &colorReplacements); + &colorReplacements, rlottie::FitzModifier fitzModifier); std::shared_ptr model(); private: std::shared_ptr mModel; diff --git a/src/lottie/lottieparser.cpp b/src/lottie/lottieparser.cpp index e825958..5dccf17 100644 --- a/src/lottie/lottieparser.cpp +++ b/src/lottie/lottieparser.cpp @@ -171,9 +171,10 @@ class LottieParserImpl : public LookaheadParserHandler { public: LottieParserImpl(char *str, const char *dir_path, const std::vector> - &colorReplacements) + &colorReplacements, rlottie::FitzModifier fitzModifier) : LookaheadParserHandler(str), mColorReplacements(colorReplacements), + mFitzModifier(fitzModifier), mDirPath(dir_path) { } @@ -259,7 +260,10 @@ class LottieParserImpl : public LookaheadParserHandler { void parseShapeKeyFrame(LOTAnimInfo &obj); void parseShapeProperty(LOTAnimatable &obj); void parseDashProperty(LOTDashProperty &dash); - + + void parseFitzColorReplacements(); + void parseFitzColorReplacement(); + std::shared_ptr interpolator(VPointF, VPointF, std::string); LottieColor toColor(const char *str); @@ -268,8 +272,9 @@ class LottieParserImpl : public LookaheadParserHandler { void resolveLayerRefs(); protected: - const std::vector> - &mColorReplacements; + std::vector> + mColorReplacements; + const rlottie::FitzModifier mFitzModifier; std::unordered_map> mInterpolatorCache; std::shared_ptr mComposition; @@ -590,6 +595,8 @@ void LottieParserImpl::parseComposition() parseAssets(comp); } else if (0 == strcmp(key, "layers")) { parseLayers(comp); + } else if (0 == strcmp(key, "fitz")) { + parseFitzColorReplacements(); } else { #ifdef DEBUG_PARSER vWarning << "Composition Attribute Skipped : " << key; @@ -624,6 +631,70 @@ void LottieParserImpl::parseAssets(LOTCompositionData *composition) // update the precomp layers with the actual layer object } +void LottieParserImpl::parseFitzColorReplacements() +{ + RAPIDJSON_ASSERT(PeekType() == kArrayType); + EnterArray(); + while (NextArrayValue()) { + parseFitzColorReplacement(); + } +} + +void LottieParserImpl::parseFitzColorReplacement() +{ + uint32_t original = 0; + uint32_t type12 = 0; + uint32_t type3 = 0; + uint32_t type4 = 0; + uint32_t type5 = 0; + uint32_t type6 = 0; + + EnterObject(); + while (const char *key = NextObjectKey()) { + if (0 == strcmp(key, "o")) { + RAPIDJSON_ASSERT(PeekType() == kNumberType); + original = GetInt(); + } else if (0 == strcmp(key, "f12")) { + RAPIDJSON_ASSERT(PeekType() == kNumberType); + type12 = GetInt(); + } else if (0 == strcmp(key, "f3")) { + RAPIDJSON_ASSERT(PeekType() == kNumberType); + type3 = GetInt(); + } else if (0 == strcmp(key, "f4")) { + RAPIDJSON_ASSERT(PeekType() == kNumberType); + type4 = GetInt(); + } else if (0 == strcmp(key, "f5")) { + RAPIDJSON_ASSERT(PeekType() == kNumberType); + type5 = GetInt(); + } else if (0 == strcmp(key, "f6")) { + RAPIDJSON_ASSERT(PeekType() == kNumberType); + type6 = GetInt(); + } else { + Skip(key); + } + } + + switch (mFitzModifier) { + case rlottie::FitzModifier::None: + break; + case rlottie::FitzModifier::Type12: + mColorReplacements.push_back(std::pair(original, type12)); + break; + case rlottie::FitzModifier::Type3: + mColorReplacements.push_back(std::pair(original, type3)); + break; + case rlottie::FitzModifier::Type4: + mColorReplacements.push_back(std::pair(original, type4)); + break; + case rlottie::FitzModifier::Type5: + mColorReplacements.push_back(std::pair(original, type5)); + break; + case rlottie::FitzModifier::Type6: + mColorReplacements.push_back(std::pair(original, type6)); + break; + } +} + static constexpr const unsigned char B64index[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -2302,8 +2373,8 @@ LottieParser::~LottieParser() = default; LottieParser::LottieParser( char *str, const char *dir_path, const std::vector> - &colorReplacements) - : d(std::make_unique(str, dir_path, colorReplacements)) + &colorReplacements, rlottie::FitzModifier fitzModifier) + : d(std::make_unique(str, dir_path, colorReplacements, fitzModifier)) { if (d->VerifyType()) d->parseComposition(); diff --git a/src/lottie/lottieparser.h b/src/lottie/lottieparser.h index 06165f9..3a20e4f 100644 --- a/src/lottie/lottieparser.h +++ b/src/lottie/lottieparser.h @@ -19,6 +19,7 @@ #ifndef LOTTIEPARSER_H #define LOTTIEPARSER_H +#include "rlottie.h" #include "lottiemodel.h" #include @@ -28,7 +29,7 @@ class LottieParser { ~LottieParser(); LottieParser(char *str, const char *dir_path, const std::vector> - &colorReplacements = {}); + &colorReplacements = {}, rlottie::FitzModifier fitzModifier = rlottie::FitzModifier::None); std::shared_ptr model(); private: std::unique_ptr d;