#include"vbezier.h"
#include"vbrush.h"
#include"vpath.h"
+#include"varenaalloc.h"
V_USE_NAMESPACE
public:
float mStartFrame{0};
float mEndFrame{0};
- std::shared_ptr<VInterpolator> mInterpolator;
- LOTKeyFrameValue<T> mValue;
+ VInterpolator *mInterpolator{nullptr};
+ LOTKeyFrameValue<T> mValue;
};
template<typename T>
public:
explicit LOTGroupData(LOTData::Type type):LOTData(type){}
public:
- std::vector<std::shared_ptr<LOTData>> mChildren;
- std::shared_ptr<LOTTransformData> mTransform;
+ std::vector<LOTData *> mChildren;
+ LOTTransformData *mTransform{nullptr};
};
class LOTShapeGroupData : public LOTGroupData
Type mAssetType{Type::Precomp};
bool mStatic{true};
std::string mRefId; // ref id
- std::vector<std::shared_ptr<LOTData>> mLayers;
+ std::vector<LOTData *> mLayers;
// image asset data
int mWidth{0};
int mHeight{0};
{
public:
LOTTransformData():LOTData(LOTData::Type::Transform){}
- void set(std::unique_ptr<TransformData> data, bool staticFlag)
+ void set(TransformData* data, bool staticFlag)
{
setStatic(staticFlag);
if (isStatic()) {
new (&impl.mStaticData) static_data(data->matrix(0), data->opacity(0));
} else {
- new (&impl.mData) std::unique_ptr<TransformData>(std::move(data));
+ impl.mData = data;
}
}
VMatrix matrix(int frameNo, bool autoOrient = false) const
void destroy() {
if (isStatic()) {
impl.mStaticData.~static_data();
- } else {
- using std::unique_ptr;
- impl.mData.~unique_ptr<TransformData>();
}
}
struct static_data {
VMatrix mMatrix;
};
union details {
- std::unique_ptr<TransformData> mData;
- static_data mStaticData;
+ TransformData *mData;
+ static_data mStaticData;
details(){};
details(const details&) = delete;
details(details&&) = delete;
std::string mPreCompRefId;
LOTAnimatable<float> mTimeRemap; /* "tm" */
LOTCompositionData *mCompRef{nullptr};
- std::shared_ptr<LOTAsset> mAsset;
- std::vector<std::shared_ptr<LOTMaskData>> mMasks;
+ LOTAsset *mAsset;
+ std::vector<LOTMaskData *> mMasks;
};
class LOTLayerData : public LOTGroupData
}
LOTAsset* asset() const
{
- return (mExtra && mExtra->mAsset) ? mExtra->mAsset.get() : nullptr;
+ return (mExtra && mExtra->mAsset) ? mExtra->mAsset : nullptr;
}
public:
ExtraLayerData* extra()
long mEndFrame{0};
float mFrameRate{60};
LottieBlendMode mBlendMode{LottieBlendMode::Normal};
- std::shared_ptr<LOTLayerData> mRootLayer;
+ LOTLayerData *mRootLayer;
std::unordered_map<std::string,
- std::shared_ptr<LOTAsset>> mAssets;
+ LOTAsset*> mAssets;
std::vector<LayerInfo> mLayerInfoList;
std::vector<Marker> mMarkers;
+ VArenaAlloc mArenaAlloc{2048};
LOTModelStat mStats;
};
{
public:
LOTRepeaterData():LOTData(LOTData::Type::Repeater){}
- LOTShapeGroupData *content() const { return mContent ? mContent.get() : nullptr; }
- void setContent(std::shared_ptr<LOTShapeGroupData> content) {mContent = std::move(content);}
+ LOTShapeGroupData *content() const { return mContent ? mContent : nullptr; }
+ void setContent(LOTShapeGroupData *content) {mContent = content;}
int maxCopies() const { return int(mMaxCopies);}
float copies(int frameNo) const {return mCopies.value(frameNo);}
float offset(int frameNo) const {return mOffset.value(frameNo);}
+ bool processed() const {return mProcessed;}
+ void markProcessed() {mProcessed = true;}
public:
- std::shared_ptr<LOTShapeGroupData> mContent{nullptr};
+ LOTShapeGroupData* mContent{nullptr};
LOTRepeaterTransform mTransform;
LOTAnimatable<float> mCopies{0};
LOTAnimatable<float> mOffset{0};
float mMaxCopies{0.0};
+ bool mProcessed{false};
};
class LOTModel
bool VerifyType();
bool ParseNext();
public:
+ VArenaAlloc& allocator() {return compRef->mArenaAlloc;}
bool EnterObject();
bool EnterArray();
const char *NextObjectKey();
void parseMarkers();
void parseMarker();
void parseAssets(LOTCompositionData *comp);
- std::shared_ptr<LOTAsset> parseAsset();
+ LOTAsset* parseAsset();
void parseLayers(LOTCompositionData *comp);
- std::shared_ptr<LOTData> parseLayer(bool record = false);
+ LOTLayerData* parseLayer(bool record = false);
void parseMaskProperty(LOTLayerData *layer);
void parseShapesAttr(LOTLayerData *layer);
void parseObject(LOTGroupData *parent);
- std::shared_ptr<LOTMaskData> parseMaskObject();
- std::shared_ptr<LOTData> parseObjectTypeAttr();
- std::shared_ptr<LOTData> parseGroupObject();
- std::shared_ptr<LOTData> parseRectObject();
- std::shared_ptr<LOTData> parseEllipseObject();
- std::shared_ptr<LOTData> parseShapeObject();
- std::shared_ptr<LOTData> parsePolystarObject();
-
- std::shared_ptr<LOTTransformData> parseTransformObject(bool ddd = false);
- std::shared_ptr<LOTData> parseFillObject();
- std::shared_ptr<LOTData> parseGFillObject();
- std::shared_ptr<LOTData> parseStrokeObject();
- std::shared_ptr<LOTData> parseGStrokeObject();
- std::shared_ptr<LOTData> parseTrimObject();
- std::shared_ptr<LOTData> parseReapeaterObject();
+ LOTMaskData* parseMaskObject();
+ LOTData* parseObjectTypeAttr();
+ LOTData* parseGroupObject();
+ LOTRectData* parseRectObject();
+ LOTEllipseData* parseEllipseObject();
+ LOTShapeData* parseShapeObject();
+ LOTPolystarData* parsePolystarObject();
+
+ LOTTransformData* parseTransformObject(bool ddd = false);
+ LOTFillData* parseFillObject();
+ LOTGFillData* parseGFillObject();
+ LOTStrokeData* parseStrokeObject();
+ LOTGStrokeData* parseGStrokeObject();
+ LOTTrimData* parseTrimObject();
+ LOTRepeaterData* parseReapeaterObject();
void parseGradientProperty(LOTGradient *gradient, const char *key);
void parseShapeProperty(LOTAnimatable<LottieShapeData> &obj);
void parseDashProperty(LOTDashProperty &dash);
- std::shared_ptr<VInterpolator> interpolator(VPointF, VPointF, std::string);
+ VInterpolator* interpolator(VPointF, VPointF, std::string);
LottieColor toColor(const char *str);
void resolveLayerRefs();
protected:
- std::unordered_map<std::string, std::shared_ptr<VInterpolator>>
+ std::unordered_map<std::string, VInterpolator*>
mInterpolatorCache;
std::shared_ptr<LOTCompositionData> mComposition;
LOTCompositionData * compRef{nullptr};
LOTLayerData * curLayerRef{nullptr};
- std::vector<std::shared_ptr<LOTLayerData>> mLayersToUpdate;
+ std::vector<LOTLayerData *> mLayersToUpdate;
std::string mDirPath;
std::vector<LayerInfo> mLayerInfoList;
std::vector<VPointF> mInPoint; /* "i" */
void LottieParserImpl::resolveLayerRefs()
{
- for (const auto &i : mLayersToUpdate) {
- LOTLayerData *layer = i.get();
+ for (const auto &layer : mLayersToUpdate) {
auto search = compRef->mAssets.find(layer->extra()->mPreCompRefId);
if (search != compRef->mAssets.end()) {
if (layer->mLayerType == LayerType::Image) {
RAPIDJSON_ASSERT(PeekType() == kArrayType);
EnterArray();
while (NextArrayValue()) {
- std::shared_ptr<LOTAsset> asset = parseAsset();
+ auto asset = parseAsset();
composition->mAssets[asset->mRefId] = asset;
}
// update the precomp layers with the actual layer object
* https://github.com/airbnb/lottie-web/blob/master/docs/json/layers/shape.json
*
*/
-std::shared_ptr<LOTAsset> LottieParserImpl::parseAsset()
+LOTAsset* LottieParserImpl::parseAsset()
{
RAPIDJSON_ASSERT(PeekType() == kObjectType);
- std::shared_ptr<LOTAsset> sharedAsset = std::make_shared<LOTAsset>();
- LOTAsset * asset = sharedAsset.get();
+
+ auto asset = allocator().make<LOTAsset>();
std::string filename;
std::string relativePath;
bool embededResource = false;
EnterArray();
bool staticFlag = true;
while (NextArrayValue()) {
- std::shared_ptr<LOTData> layer = parseLayer();
+ auto layer = parseLayer();
if (layer) {
staticFlag = staticFlag && layer->isStatic();
asset->mLayers.push_back(layer);
}
}
- return sharedAsset;
+ return asset;
}
void LottieParserImpl::parseLayers(LOTCompositionData *comp)
{
- comp->mRootLayer = std::make_shared<LOTLayerData>();
+ comp->mRootLayer = allocator().make<LOTLayerData>();
comp->mRootLayer->mLayerType = LayerType::Precomp;
comp->mRootLayer->setName("__");
bool staticFlag = true;
RAPIDJSON_ASSERT(PeekType() == kArrayType);
EnterArray();
while (NextArrayValue()) {
- std::shared_ptr<LOTData> layer = parseLayer(true);
+ auto layer = parseLayer(true);
if (layer) {
staticFlag = staticFlag && layer->isStatic();
comp->mRootLayer->mChildren.push_back(layer);
* https://github.com/airbnb/lottie-web/blob/master/docs/json/layers/shape.json
*
*/
-std::shared_ptr<LOTData> LottieParserImpl::parseLayer(bool record)
+LOTLayerData* LottieParserImpl::parseLayer(bool record)
{
RAPIDJSON_ASSERT(PeekType() == kObjectType);
- std::shared_ptr<LOTLayerData> sharedLayer =
- std::make_shared<LOTLayerData>();
- LOTLayerData *layer = sharedLayer.get();
+ LOTLayerData *layer = allocator().make<LOTLayerData>();
curLayerRef = layer;
bool ddd = true;
EnterObject();
RAPIDJSON_ASSERT(PeekType() == kStringType);
layer->extra()->mPreCompRefId = std::string(GetString());
layer->mHasGradient = true;
- mLayersToUpdate.push_back(sharedLayer);
+ mLayersToUpdate.push_back(layer);
} else if (0 == strcmp(key, "sr")) { // "Layer Time Stretching"
RAPIDJSON_ASSERT(PeekType() == kNumberType);
layer->mTimeStreatch = GetDouble();
layer->setStatic(layer->mTransform->isStatic());
layer->mLayerType = LayerType::Null;
layer->mChildren = {};
- return sharedLayer;
+ return layer;
}
// update the static property of layer
bool staticFlag = true;
for (const auto &child : layer->mChildren) {
- staticFlag &= child.get()->isStatic();
+ staticFlag &= child->isStatic();
}
if (layer->hasMask()) {
mLayerInfoList.push_back(
LayerInfo(layer->name(), layer->mInFrame, layer->mOutFrame));
}
- return sharedLayer;
+ return layer;
}
void LottieParserImpl::parseMaskProperty(LOTLayerData *layer)
}
}
-std::shared_ptr<LOTMaskData> LottieParserImpl::parseMaskObject()
+LOTMaskData* LottieParserImpl::parseMaskObject()
{
- std::shared_ptr<LOTMaskData> sharedMask = std::make_shared<LOTMaskData>();
- LOTMaskData * obj = sharedMask.get();
+ auto obj = allocator().make<LOTMaskData>();
RAPIDJSON_ASSERT(PeekType() == kObjectType);
EnterObject();
}
}
obj->mIsStatic = obj->mShape.isStatic() && obj->mOpacity.isStatic();
- return sharedMask;
+ return obj;
}
void LottieParserImpl::parseShapesAttr(LOTLayerData *layer)
}
}
-std::shared_ptr<LOTData> LottieParserImpl::parseObjectTypeAttr()
+LOTData* LottieParserImpl::parseObjectTypeAttr()
{
RAPIDJSON_ASSERT(PeekType() == kStringType);
const char *type = GetString();
}
}
-std::shared_ptr<LOTData> LottieParserImpl::parseGroupObject()
+LOTData* LottieParserImpl::parseGroupObject()
{
- std::shared_ptr<LOTShapeGroupData> sharedGroup =
- std::make_shared<LOTShapeGroupData>();
+ auto group = allocator().make<LOTShapeGroupData>();
- LOTShapeGroupData *group = sharedGroup.get();
while (const char *key = NextObjectKey()) {
if (0 == strcmp(key, "nm")) {
group->setName(GetString());
parseObject(group);
}
if (group->mChildren.back()->type() == LOTData::Type::Transform) {
- group->mTransform = std::static_pointer_cast<LOTTransformData>(
- group->mChildren.back());
+ group->mTransform = static_cast<LOTTransformData *>(group->mChildren.back());
group->mChildren.pop_back();
}
} else {
}
bool staticFlag = true;
for (const auto &child : group->mChildren) {
- staticFlag &= child.get()->isStatic();
+ staticFlag &= child->isStatic();
}
if (group->mTransform) {
group->setStatic(staticFlag && group->mTransform->isStatic());
}
- return sharedGroup;
+ return group;
}
/*
* https://github.com/airbnb/lottie-web/blob/master/docs/json/shapes/rect.json
*/
-std::shared_ptr<LOTData> LottieParserImpl::parseRectObject()
+LOTRectData* LottieParserImpl::parseRectObject()
{
- std::shared_ptr<LOTRectData> sharedRect = std::make_shared<LOTRectData>();
- LOTRectData * obj = sharedRect.get();
+ auto obj = allocator().make<LOTRectData>();
while (const char *key = NextObjectKey()) {
if (0 == strcmp(key, "nm")) {
}
obj->setStatic(obj->mPos.isStatic() && obj->mSize.isStatic() &&
obj->mRound.isStatic());
- return sharedRect;
+ return obj;
}
/*
* https://github.com/airbnb/lottie-web/blob/master/docs/json/shapes/ellipse.json
*/
-std::shared_ptr<LOTData> LottieParserImpl::parseEllipseObject()
+LOTEllipseData* LottieParserImpl::parseEllipseObject()
{
- std::shared_ptr<LOTEllipseData> sharedEllipse =
- std::make_shared<LOTEllipseData>();
- LOTEllipseData *obj = sharedEllipse.get();
+ auto obj = allocator().make<LOTEllipseData>();
while (const char *key = NextObjectKey()) {
if (0 == strcmp(key, "nm")) {
}
}
obj->setStatic(obj->mPos.isStatic() && obj->mSize.isStatic());
- return sharedEllipse;
+ return obj;
}
/*
* https://github.com/airbnb/lottie-web/blob/master/docs/json/shapes/shape.json
*/
-std::shared_ptr<LOTData> LottieParserImpl::parseShapeObject()
+LOTShapeData* LottieParserImpl::parseShapeObject()
{
- std::shared_ptr<LOTShapeData> sharedShape =
- std::make_shared<LOTShapeData>();
- LOTShapeData *obj = sharedShape.get();
+ auto obj = allocator().make<LOTShapeData>();
while (const char *key = NextObjectKey()) {
if (0 == strcmp(key, "nm")) {
}
obj->setStatic(obj->mShape.isStatic());
- return sharedShape;
+ return obj;
}
/*
* https://github.com/airbnb/lottie-web/blob/master/docs/json/shapes/star.json
*/
-std::shared_ptr<LOTData> LottieParserImpl::parsePolystarObject()
+LOTPolystarData* LottieParserImpl::parsePolystarObject()
{
- std::shared_ptr<LOTPolystarData> sharedPolystar =
- std::make_shared<LOTPolystarData>();
- LOTPolystarData *obj = sharedPolystar.get();
+ auto obj = allocator().make<LOTPolystarData>();
while (const char *key = NextObjectKey()) {
if (0 == strcmp(key, "nm")) {
obj->mOuterRadius.isStatic() && obj->mOuterRoundness.isStatic() &&
obj->mRotation.isStatic());
- return sharedPolystar;
+ return obj;
}
LOTTrimData::TrimType LottieParserImpl::getTrimType()
/*
* https://github.com/airbnb/lottie-web/blob/master/docs/json/shapes/trim.json
*/
-std::shared_ptr<LOTData> LottieParserImpl::parseTrimObject()
+LOTTrimData* LottieParserImpl::parseTrimObject()
{
- std::shared_ptr<LOTTrimData> sharedTrim = std::make_shared<LOTTrimData>();
- LOTTrimData * obj = sharedTrim.get();
+ auto obj = allocator().make<LOTTrimData>();
while (const char *key = NextObjectKey()) {
if (0 == strcmp(key, "nm")) {
}
obj->setStatic(obj->mStart.isStatic() && obj->mEnd.isStatic() &&
obj->mOffset.isStatic());
- return sharedTrim;
+ return obj;
}
void LottieParserImpl::getValue(LOTRepeaterTransform &obj)
}
}
-std::shared_ptr<LOTData> LottieParserImpl::parseReapeaterObject()
+LOTRepeaterData* LottieParserImpl::parseReapeaterObject()
{
- std::shared_ptr<LOTRepeaterData> sharedRepeater =
- std::make_shared<LOTRepeaterData>();
- LOTRepeaterData *obj = sharedRepeater.get();
+ auto obj = allocator().make<LOTRepeaterData>();
+
+ obj->setContent(allocator().make<LOTShapeGroupData>());
while (const char *key = NextObjectKey()) {
if (0 == strcmp(key, "nm")) {
obj->setStatic(obj->mCopies.isStatic() && obj->mOffset.isStatic() &&
obj->mTransform.isStatic());
- return sharedRepeater;
+ return obj;
}
/*
* https://github.com/airbnb/lottie-web/blob/master/docs/json/shapes/transform.json
*/
-std::shared_ptr<LOTTransformData> LottieParserImpl::parseTransformObject(
+LOTTransformData* LottieParserImpl::parseTransformObject(
bool ddd)
{
+ auto objT = allocator().make<LOTTransformData>();
+
std::shared_ptr<LOTTransformData> sharedTransform =
std::make_shared<LOTTransformData>();
- auto obj = std::make_unique<TransformData>();
+ auto obj = allocator().make<TransformData>();
if (ddd) {
obj->createExtraData();
obj->mExtra->m3DData = true;
obj->mExtra->mSeparateY.isStatic();
}
- sharedTransform->set(std::move(obj), isStatic);
+ objT->set(obj, isStatic);
- return sharedTransform;
+ return objT;
}
/*
* https://github.com/airbnb/lottie-web/blob/master/docs/json/shapes/fill.json
*/
-std::shared_ptr<LOTData> LottieParserImpl::parseFillObject()
+LOTFillData* LottieParserImpl::parseFillObject()
{
- std::shared_ptr<LOTFillData> sharedFill = std::make_shared<LOTFillData>();
- LOTFillData * obj = sharedFill.get();
+ auto obj = allocator().make<LOTFillData>();
while (const char *key = NextObjectKey()) {
if (0 == strcmp(key, "nm")) {
}
obj->setStatic(obj->mColor.isStatic() && obj->mOpacity.isStatic());
- return sharedFill;
+ return obj;
}
/*
/*
* https://github.com/airbnb/lottie-web/blob/master/docs/json/shapes/stroke.json
*/
-std::shared_ptr<LOTData> LottieParserImpl::parseStrokeObject()
+LOTStrokeData* LottieParserImpl::parseStrokeObject()
{
- std::shared_ptr<LOTStrokeData> sharedStroke =
- std::make_shared<LOTStrokeData>();
- LOTStrokeData *obj = sharedStroke.get();
+ auto obj = allocator().make<LOTStrokeData>();
while (const char *key = NextObjectKey()) {
if (0 == strcmp(key, "nm")) {
}
obj->setStatic(obj->mColor.isStatic() && obj->mOpacity.isStatic() &&
obj->mWidth.isStatic() && obj->mDash.isStatic());
- return sharedStroke;
+ return obj;
}
void LottieParserImpl::parseGradientProperty(LOTGradient *obj, const char *key)
/*
* https://github.com/airbnb/lottie-web/blob/master/docs/json/shapes/gfill.json
*/
-std::shared_ptr<LOTData> LottieParserImpl::parseGFillObject()
+LOTGFillData* LottieParserImpl::parseGFillObject()
{
- std::shared_ptr<LOTGFillData> sharedGFill =
- std::make_shared<LOTGFillData>();
- LOTGFillData *obj = sharedGFill.get();
+ auto obj = allocator().make<LOTGFillData>();
while (const char *key = NextObjectKey()) {
if (0 == strcmp(key, "nm")) {
parseGradientProperty(obj, key);
}
}
- return sharedGFill;
+ return obj;
}
void LottieParserImpl::parseDashProperty(LOTDashProperty &dash)
/*
* https://github.com/airbnb/lottie-web/blob/master/docs/json/shapes/gstroke.json
*/
-std::shared_ptr<LOTData> LottieParserImpl::parseGStrokeObject()
+LOTGStrokeData* LottieParserImpl::parseGStrokeObject()
{
- std::shared_ptr<LOTGStrokeData> sharedGStroke =
- std::make_shared<LOTGStrokeData>();
- LOTGStrokeData *obj = sharedGStroke.get();
+ auto obj = allocator().make<LOTGStrokeData>();
while (const char *key = NextObjectKey()) {
if (0 == strcmp(key, "nm")) {
obj->setStatic(obj->isStatic() && obj->mWidth.isStatic() &&
obj->mDash.isStatic());
- return sharedGStroke;
+ return obj;
}
void LottieParserImpl::getValue(std::vector<VPointF> &v)
return true;
}
-std::shared_ptr<VInterpolator> LottieParserImpl::interpolator(
+VInterpolator* LottieParserImpl::interpolator(
VPointF inTangent, VPointF outTangent, std::string key)
{
if (key.empty()) {
return search->second;
}
- auto obj = std::make_shared<VInterpolator>(
- VInterpolator(outTangent, inTangent));
+ auto obj = allocator().make<VInterpolator>(outTangent, inTangent);
mInterpolatorCache[std::move(key)] = obj;
return obj;
}