From 4d4fa29212b5b8445507161b6c1655c4dfb78784 Mon Sep 17 00:00:00 2001 From: subhransu mohanty Date: Tue, 15 Jan 2019 09:52:31 +0900 Subject: [PATCH] lottie/parser: added support for image asset parsing. Change-Id: Ib7a4ec1b7d6d7f5c9357e451c3908d88c671bc37 --- src/lottie/lottieloader.cpp | 11 ++++++-- src/lottie/lottiemodel.h | 17 ++++++++++--- src/lottie/lottieparser.cpp | 50 +++++++++++++++++++++++++++++++------ src/lottie/lottieparser.h | 2 +- 4 files changed, 67 insertions(+), 13 deletions(-) diff --git a/src/lottie/lottieloader.cpp b/src/lottie/lottieloader.cpp index ac2da78..6b540f8 100644 --- a/src/lottie/lottieloader.cpp +++ b/src/lottie/lottieloader.cpp @@ -21,7 +21,7 @@ #include #include - +#include using namespace std; class LottieFileCache { @@ -56,6 +56,13 @@ void LottieFileCache::add(const std::string &key, std::shared_ptr valu mHash[key] = std::move(value); } +static std::string dirname(const std::string &path) +{ + const char *ptr = strrchr(path.c_str(), '/'); + int len = int(ptr + 1 - path.c_str()); // +1 to include '/' + return std::string(path, 0, len); +} + bool LottieLoader::load(const std::string &path) { LottieFileCache &fileCache = LottieFileCache::get(); @@ -73,7 +80,7 @@ bool LottieLoader::load(const std::string &path) std::stringstream buf; buf << f.rdbuf(); - LottieParser parser(const_cast(buf.str().data())); + LottieParser parser(const_cast(buf.str().data()), dirname(path).c_str()); mModel = parser.model(); fileCache.add(path, mModel); diff --git a/src/lottie/lottiemodel.h b/src/lottie/lottiemodel.h index 16a75d5..08f254e 100644 --- a/src/lottie/lottiemodel.h +++ b/src/lottie/lottiemodel.h @@ -339,9 +339,19 @@ public: class LOTLayerData; struct LOTAsset { - int mAssetType; //lottie asset type (precomp/char/image) - std::string mRefId; // ref id - std::vector> mLayers; + enum class Type { + Precomp, + Image, + Char + }; + + Type mAssetType{Type::Precomp}; + std::string mRefId; // ref id + std::vector> mLayers; + // image asset data + int mWidth{0}; + int mHeight{0}; + std::string mImagePath; }; class LOTLayerData : public LOTGroupData @@ -393,6 +403,7 @@ public: bool mAutoOrient{false}; std::vector> mMasks; LOTCompositionData *mCompRef{nullptr}; + std::shared_ptr mAsset; }; class LOTCompositionData : public LOTData diff --git a/src/lottie/lottieparser.cpp b/src/lottie/lottieparser.cpp index 16e9232..643c3cb 100644 --- a/src/lottie/lottieparser.cpp +++ b/src/lottie/lottieparser.cpp @@ -173,7 +173,9 @@ protected: class LottieParserImpl : protected LookaheadParserHandler { public: - LottieParserImpl(char *str) : LookaheadParserHandler(str) {} + LottieParserImpl(char *str, const char *dir_path) + :LookaheadParserHandler(str), + mDirPath(dir_path){} public: bool EnterObject(); @@ -270,6 +272,7 @@ protected: LOTCompositionData * compRef{nullptr}; LOTLayerData * curLayerRef{nullptr}; std::vector> mLayersToUpdate; + std::string mDirPath; void SkipOut(int depth); }; @@ -557,7 +560,11 @@ void LottieParserImpl::resolveLayerRefs() LOTLayerData *layer = i.get(); auto search = compRef->mAssets.find(layer->mPreCompRefId); if (search != compRef->mAssets.end()) { - layer->mChildren = search->second.get()->mLayers; + if (layer->mLayerType == LayerType::Image) { + layer->mAsset = search->second; + } else if (layer->mLayerType == LayerType::Precomp) { + layer->mChildren = search->second.get()->mLayers; + } } } } @@ -628,11 +635,23 @@ std::shared_ptr LottieParserImpl::parseAsset() RAPIDJSON_ASSERT(PeekType() == kObjectType); std::shared_ptr sharedAsset = std::make_shared(); LOTAsset * asset = sharedAsset.get(); + std::string filename; + std::string relativePath; EnterObject(); while (const char *key = NextObjectKey()) { - if (0 == strcmp(key, "ty")) { /* Type of layer: Shape. Value 4.*/ + if (0 == strcmp(key, "w")) { RAPIDJSON_ASSERT(PeekType() == kNumberType); - asset->mAssetType = GetInt(); + asset->mWidth = GetInt(); + } else if (0 == strcmp(key, "h")) { + RAPIDJSON_ASSERT(PeekType() == kNumberType); + asset->mHeight = GetInt(); + } else if (0 == strcmp(key, "p")) { /* image name */ + asset->mAssetType = LOTAsset::Type::Image; + RAPIDJSON_ASSERT(PeekType() == kStringType); + filename = std::string(GetString()); + } else if (0 == strcmp(key, "u")) { /* relative image path */ + RAPIDJSON_ASSERT(PeekType() == kStringType); + relativePath = std::string(GetString()); } else if (0 == strcmp(key, "id")) { /* reference id*/ if (PeekType() == kStringType) { asset->mRefId = std::string(GetString()); @@ -641,6 +660,7 @@ std::shared_ptr LottieParserImpl::parseAsset() asset->mRefId = std::to_string(GetInt()); } } else if (0 == strcmp(key, "layers")) { + asset->mAssetType = LOTAsset::Type::Precomp; RAPIDJSON_ASSERT(PeekType() == kArrayType); EnterArray(); while (NextArrayValue()) { @@ -654,6 +674,10 @@ std::shared_ptr LottieParserImpl::parseAsset() Skip(key); } } + // its an image asset + if (!filename.empty()) { + asset->mImagePath = mDirPath + relativePath + filename; + } return sharedAsset; } @@ -1978,8 +2002,20 @@ public: << ", ao:" << obj->autoOrient() << ", ddd:" << obj->mTransform->ddd() << ", W:" << obj->layerSize().width() - << ", H:" << obj->layerSize().height() - << "\n"; + << ", H:" << obj->layerSize().height(); + + if (obj->mLayerType == LayerType::Image) + vDebug << level + << "\t{ " + << "ImageInfo:" + << " W :" << obj->mAsset->mWidth + << ", H :" << obj->mAsset->mHeight + << ", Path :"<mAsset->mImagePath + <<" }" + << "\n"; + else { + vDebug<< level; + } visitChildren(static_cast(obj), level); vDebug << level << "} " @@ -2121,7 +2157,7 @@ LottieParser::~LottieParser() delete d; } -LottieParser::LottieParser(char *str) : d(new LottieParserImpl(str)) +LottieParser::LottieParser(char *str, const char *dir_path) : d(new LottieParserImpl(str, dir_path)) { d->parseComposition(); } diff --git a/src/lottie/lottieparser.h b/src/lottie/lottieparser.h index 3c63f65..d892c24 100644 --- a/src/lottie/lottieparser.h +++ b/src/lottie/lottieparser.h @@ -25,7 +25,7 @@ class LottieParserImpl; class LottieParser { public: ~LottieParser(); - LottieParser(char* str); + LottieParser(char* str, const char *dir_path=""); std::shared_ptr model(); private: LottieParserImpl *d; -- 2.34.1