Allow passing a color replacement map.

This commit is contained in:
John Preston 2019-08-07 15:18:26 +01:00
parent 14167128d1
commit d08a03b650
6 changed files with 59 additions and 15 deletions

View File

@ -291,7 +291,9 @@ public:
*/ */
static std::unique_ptr<Animation> static std::unique_ptr<Animation>
loadFromData(std::string jsonData, const std::string &key, loadFromData(std::string jsonData, const std::string &key,
const std::string &resourcePath="", bool cachePolicy=true); const std::string &resourcePath="", bool cachePolicy=true,
const std::vector<std::pair<std::uint32_t, std::uint32_t>>
&colorReplacements = {});
/** /**
* @brief Returns default framerate of the Lottie resource. * @brief Returns default framerate of the Lottie resource.

View File

@ -240,7 +240,9 @@ std::future<Surface> AnimationImpl::renderAsync(size_t frameNo,
*/ */
std::unique_ptr<Animation> Animation::loadFromData( std::unique_ptr<Animation> Animation::loadFromData(
std::string jsonData, const std::string &key, std::string jsonData, const std::string &key,
const std::string &resourcePath, bool cachePolicy) const std::string &resourcePath, bool cachePolicy,
const std::vector<std::pair<std::uint32_t, std::uint32_t>>
&colorReplacements)
{ {
if (jsonData.empty()) { if (jsonData.empty()) {
vWarning << "jason data is empty"; vWarning << "jason data is empty";
@ -249,7 +251,8 @@ std::unique_ptr<Animation> Animation::loadFromData(
LottieLoader loader; LottieLoader loader;
if (loader.loadFromData(std::move(jsonData), key, if (loader.loadFromData(std::move(jsonData), key,
(resourcePath.empty() ? " " : resourcePath), cachePolicy)) { (resourcePath.empty() ? " " : resourcePath),
cachePolicy, colorReplacements)) {
auto animation = std::unique_ptr<Animation>(new Animation); auto animation = std::unique_ptr<Animation>(new Animation);
animation->d->init(loader.model()); animation->d->init(loader.model());
return animation; return animation;

View File

@ -140,8 +140,11 @@ bool LottieLoader::load(const std::string &path, bool cachePolicy)
return true; return true;
} }
bool LottieLoader::loadFromData(std::string &&jsonData, const std::string &key, bool LottieLoader::loadFromData(
const std::string &resourcePath, bool cachePolicy) std::string &&jsonData, const std::string &key,
const std::string &resourcePath, bool cachePolicy,
const std::vector<std::pair<std::uint32_t, std::uint32_t>>
&colorReplacements)
{ {
if (cachePolicy) { if (cachePolicy) {
mModel = LottieModelCache::instance().find(key); mModel = LottieModelCache::instance().find(key);
@ -149,7 +152,7 @@ bool LottieLoader::loadFromData(std::string &&jsonData, const std::string &key,
} }
LottieParser parser(const_cast<char *>(jsonData.c_str()), LottieParser parser(const_cast<char *>(jsonData.c_str()),
resourcePath.c_str()); resourcePath.c_str(), colorReplacements);
mModel = parser.model(); mModel = parser.model();
if (!mModel) return false; if (!mModel) return false;

View File

@ -21,6 +21,7 @@
#include<sstream> #include<sstream>
#include<memory> #include<memory>
#include<vector>
class LOTModel; class LOTModel;
class LottieLoader class LottieLoader
@ -29,7 +30,9 @@ public:
static void configureModelCacheSize(size_t cacheSize); static void configureModelCacheSize(size_t cacheSize);
bool load(const std::string &filePath, bool cachePolicy); bool load(const std::string &filePath, bool cachePolicy);
bool loadFromData(std::string &&jsonData, const std::string &key, bool loadFromData(std::string &&jsonData, const std::string &key,
const std::string &resourcePath, bool cachePolicy); const std::string &resourcePath, bool cachePolicy,
const std::vector<std::pair<std::uint32_t, std::uint32_t>>
&colorReplacements);
std::shared_ptr<LOTModel> model(); std::shared_ptr<LOTModel> model();
private: private:
std::shared_ptr<LOTModel> mModel; std::shared_ptr<LOTModel> mModel;

View File

@ -169,8 +169,14 @@ protected:
class LottieParserImpl : public LookaheadParserHandler { class LottieParserImpl : public LookaheadParserHandler {
public: public:
LottieParserImpl(char *str, const char *dir_path) LottieParserImpl(char *str, const char *dir_path,
: LookaheadParserHandler(str), mDirPath(dir_path) {} const std::vector<std::pair<std::uint32_t, std::uint32_t>>
&colorReplacements)
: LookaheadParserHandler(str),
mColorReplacements(colorReplacements),
mDirPath(dir_path)
{
}
bool VerifyType(); bool VerifyType();
bool ParseNext(); bool ParseNext();
public: public:
@ -257,10 +263,13 @@ public:
std::shared_ptr<VInterpolator> interpolator(VPointF, VPointF, std::string); std::shared_ptr<VInterpolator> interpolator(VPointF, VPointF, std::string);
LottieColor toColor(const char *str); LottieColor toColor(const char *str);
LottieColor applyReplacements(const LottieColor &color);
void resolveLayerRefs(); void resolveLayerRefs();
protected: protected:
const std::vector<std::pair<std::uint32_t, std::uint32_t>>
&mColorReplacements;
std::unordered_map<std::string, std::shared_ptr<VInterpolator>> std::unordered_map<std::string, std::shared_ptr<VInterpolator>>
mInterpolatorCache; mInterpolatorCache;
std::shared_ptr<LOTCompositionData> mComposition; std::shared_ptr<LOTCompositionData> mComposition;
@ -789,6 +798,27 @@ LottieColor LottieParserImpl::toColor(const char *str)
tmp[1] = str[6]; tmp[1] = str[6];
color.b = std::strtol(tmp, nullptr, 16) / 255.0f; color.b = std::strtol(tmp, nullptr, 16) / 255.0f;
return applyReplacements(color);
}
LottieColor LottieParserImpl::applyReplacements(const LottieColor &color)
{
if (mColorReplacements.empty()) {
return color;
}
const auto convert = [](float value) {
return std::uint32_t(std::round(std::clamp(value, 0.f, 1.f) * 255.));
};
const auto part = [](std::uint32_t value, int shift) {
return float((value >> shift) & 0xFFU) / 255.f;
};
const auto converted =
convert(color.b) | (convert(color.g) << 8) | (convert(color.r) << 16);
for (const auto [key, value] : mColorReplacements) {
if (key == converted) {
return LottieColor(part(value, 16), part(value, 8), part(value, 0));
}
}
return color; return color;
} }
@ -1746,9 +1776,7 @@ void LottieParserImpl::getValue(LottieColor &color)
while (NextArrayValue()) { while (NextArrayValue()) {
val[i++] = GetDouble(); val[i++] = GetDouble();
} }
color.r = val[0]; color = applyReplacements(LottieColor(val[0], val[1], val[2]));
color.g = val[1];
color.b = val[2];
} }
void LottieParserImpl::getValue(LottieGradient &grad) void LottieParserImpl::getValue(LottieGradient &grad)
@ -2254,8 +2282,11 @@ public:
#endif #endif
LottieParser::~LottieParser() = default; LottieParser::~LottieParser() = default;
LottieParser::LottieParser(char *str, const char *dir_path) LottieParser::LottieParser(
: d(std::make_unique<LottieParserImpl>(str, dir_path)) char *str, const char *dir_path,
const std::vector<std::pair<std::uint32_t, std::uint32_t>>
&colorReplacements)
: d(std::make_unique<LottieParserImpl>(str, dir_path, colorReplacements))
{ {
if (d->VerifyType()) if (d->VerifyType())
d->parseComposition(); d->parseComposition();

View File

@ -26,7 +26,9 @@ class LottieParserImpl;
class LottieParser { class LottieParser {
public: public:
~LottieParser(); ~LottieParser();
LottieParser(char* str, const char *dir_path); LottieParser(char *str, const char *dir_path,
const std::vector<std::pair<std::uint32_t, std::uint32_t>>
&colorReplacements = {});
std::shared_ptr<LOTModel> model(); std::shared_ptr<LOTModel> model();
private: private:
std::unique_ptr<LottieParserImpl> d; std::unique_ptr<LottieParserImpl> d;