#include <fstream>
#include <unordered_map>
-
+#include <cstring>
using namespace std;
class LottieFileCache {
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();
std::stringstream buf;
buf << f.rdbuf();
- LottieParser parser(const_cast<char *>(buf.str().data()));
+ LottieParser parser(const_cast<char *>(buf.str().data()), dirname(path).c_str());
mModel = parser.model();
fileCache.add(path, mModel);
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();
LOTCompositionData * compRef{nullptr};
LOTLayerData * curLayerRef{nullptr};
std::vector<std::shared_ptr<LOTLayerData>> mLayersToUpdate;
+ std::string mDirPath;
void SkipOut(int depth);
};
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;
+ }
}
}
}
RAPIDJSON_ASSERT(PeekType() == kObjectType);
std::shared_ptr<LOTAsset> sharedAsset = std::make_shared<LOTAsset>();
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());
asset->mRefId = std::to_string(GetInt());
}
} else if (0 == strcmp(key, "layers")) {
+ asset->mAssetType = LOTAsset::Type::Precomp;
RAPIDJSON_ASSERT(PeekType() == kArrayType);
EnterArray();
while (NextArrayValue()) {
Skip(key);
}
}
+ // its an image asset
+ if (!filename.empty()) {
+ asset->mImagePath = mDirPath + relativePath + filename;
+ }
return sharedAsset;
}
<< ", 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 :"<<obj->mAsset->mImagePath
+ <<" }"
+ << "\n";
+ else {
+ vDebug<< level;
+ }
visitChildren(static_cast<LOTGroupData *>(obj), level);
vDebug << level
<< "} "
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();
}