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>
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.

View File

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

View File

@ -140,8 +140,11 @@ bool LottieLoader::load(const std::string &path, bool cachePolicy)
return true;
}
bool LottieLoader::loadFromData(std::string &&jsonData, const std::string &key,
const std::string &resourcePath, bool cachePolicy)
bool LottieLoader::loadFromData(
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) {
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()),
resourcePath.c_str());
resourcePath.c_str(), colorReplacements);
mModel = parser.model();
if (!mModel) return false;

View File

@ -21,6 +21,7 @@
#include<sstream>
#include<memory>
#include<vector>
class LOTModel;
class LottieLoader
@ -29,7 +30,9 @@ public:
static void configureModelCacheSize(size_t cacheSize);
bool load(const std::string &filePath, bool cachePolicy);
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();
private:
std::shared_ptr<LOTModel> mModel;

View File

@ -169,8 +169,14 @@ protected:
class LottieParserImpl : public LookaheadParserHandler {
public:
LottieParserImpl(char *str, const char *dir_path)
: LookaheadParserHandler(str), mDirPath(dir_path) {}
LottieParserImpl(char *str, const char *dir_path,
const std::vector<std::pair<std::uint32_t, std::uint32_t>>
&colorReplacements)
: LookaheadParserHandler(str),
mColorReplacements(colorReplacements),
mDirPath(dir_path)
{
}
bool VerifyType();
bool ParseNext();
public:
@ -257,10 +263,13 @@ public:
std::shared_ptr<VInterpolator> interpolator(VPointF, VPointF, std::string);
LottieColor toColor(const char *str);
LottieColor applyReplacements(const LottieColor &color);
void resolveLayerRefs();
protected:
const std::vector<std::pair<std::uint32_t, std::uint32_t>>
&mColorReplacements;
std::unordered_map<std::string, std::shared_ptr<VInterpolator>>
mInterpolatorCache;
std::shared_ptr<LOTCompositionData> mComposition;
@ -789,6 +798,27 @@ LottieColor LottieParserImpl::toColor(const char *str)
tmp[1] = str[6];
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;
}
@ -1746,9 +1776,7 @@ void LottieParserImpl::getValue(LottieColor &color)
while (NextArrayValue()) {
val[i++] = GetDouble();
}
color.r = val[0];
color.g = val[1];
color.b = val[2];
color = applyReplacements(LottieColor(val[0], val[1], val[2]));
}
void LottieParserImpl::getValue(LottieGradient &grad)
@ -2254,8 +2282,11 @@ public:
#endif
LottieParser::~LottieParser() = default;
LottieParser::LottieParser(char *str, const char *dir_path)
: d(std::make_unique<LottieParserImpl>(str, dir_path))
LottieParser::LottieParser(
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())
d->parseComposition();

View File

@ -26,7 +26,9 @@ class LottieParserImpl;
class LottieParser {
public:
~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();
private:
std::unique_ptr<LottieParserImpl> d;