evas_object_vg_root_node_set(mVg, root);
}
+void LottieView::updateTree(const LOTLayerNode * node)
+{
+ Efl_VG *root = evas_vg_container_add(mVg);
+ update(node, root);
+ evas_object_vg_root_node_set(mVg, root);
+}
+
+void LottieView::update(const LOTLayerNode * node, Efl_VG *parent)
+{
+ // if the layer is invisible return
+ if (!node->mVisible) return;
+
+ // check if this layer is a container layer
+ bool hasMatte = false;
+ if (node->mLayerList.size) {
+ for (unsigned int i = 0; i < node->mLayerList.size; i++) {
+ if (hasMatte) {
+ hasMatte = false;
+ continue;
+ }
+ // if the layer has matte then
+ // the next layer has to be rendered using this layer
+ // as matte source
+ if (node->mLayerList.ptr[i]->mMatte != MatteNone) {
+ hasMatte = true;
+ printf("Matte is not supported Yet\n");
+ continue;
+ }
+ update(node->mLayerList.ptr[i], parent);
+ }
+ }
+
+ // check if this layer has drawable
+ if (node->mNodeList.size) {
+ for (unsigned int i = 0; i < node->mNodeList.size; i++) {
+ createVgNode(node->mNodeList.ptr[i], parent);
+ }
+ }
+}
+
static void mImageDelCb(void *data, Evas *evas, Evas_Object *obj, void *)
{
LottieView *lottie = (LottieView *)data;
evas_object_image_data_update_add(mImage, 0 , 0, surface.width(), surface.height());
}
} else {
- const std::vector<LOTNode *> &renderList = mPlayer->renderList(mCurFrame, mw, mh);
- update(renderList);
+ const LOTLayerNode *root = mPlayer->renderTree(mCurFrame, mw, mh);
+ updateTree(root);
}
}
private:
void createVgNode(LOTNode *node, Efl_VG *root);
void update(const std::vector<LOTNode *> &);
+ void updateTree(const LOTLayerNode *);
+ void update(const LOTLayerNode *, Efl_VG *parent);
void restart();
public:
int mw;
class AnimationImpl;
struct LOTNode;
+struct LOTLayerNode;
namespace lottie {
const std::vector<LOTNode *> &renderList(size_t frameNo, size_t width, size_t height) const;
/**
+ * @brief Returns root layer of the composition updated with
+ * content of the lottie resource at frame number {frameNo}.
+ *
+ * @param[in] frameNo Content corresponds to the frameno needs to be extracted.
+ * @param[in] width content viewbox width
+ * @param[in] height content viewbox height
+ *
+ * @return Root layer node.
+ */
+ const LOTLayerNode * renderTree(size_t frameNo, size_t width, size_t height) const;
+
+ /**
* @brief default destructor
*/
~Animation();
unsigned char r, g, b, a;
} LOTGradientStop;
+struct LOTNode;
+
+typedef enum
+{
+ MaskModeAdd = 0,
+ MaskModeSubstract,
+ MaskModeIntersect,
+ MaskModeDifference
+} LOTMaskMode;
+
+typedef struct _LOTMask {
+ struct {
+ const float *ptPtr;
+ int ptCount;
+ const char* elmPtr;
+ int elmCount;
+ } mPath;
+ LOTMaskMode mMode;
+}LOTMask;
+
+typedef enum
+{
+ MatteNone = 0,
+ MatteAlpha,
+ MatteAlphaInv,
+ MatteLuma,
+ MatteLumaInv
+} LOTMatteType;
+
+typedef struct LOTLayerNode {
+
+ struct {
+ LOTMask *ptr;
+ unsigned int size;
+ }mMaskList;
+
+ struct {
+ LOTLayerNode **ptr;
+ unsigned int size;
+ }mLayerList;
+
+ struct {
+ LOTNode **ptr;
+ unsigned int size;
+ }mNodeList;
+
+ LOTMatteType mMatte;
+ int mVisible;
+
+}LOTLayerNode;
+
typedef struct LOTNode {
#define ChangeFlagNone 0x0000
const std::vector<LOTNode *> &
renderList(size_t frameNo, const VSize &size);
+ const LOTLayerNode *
+ renderTree(size_t frameNo, const VSize &size);
private:
std::string mFilePath;
std::shared_ptr<LOTModel> mModel;
return mCompItem->renderList();
}
+const LOTLayerNode *AnimationImpl::renderTree(size_t frameNo, const VSize &size)
+{
+ if (update(frameNo, size)) {
+ mCompItem->buildRenderTree();
+ }
+ return mCompItem->renderTree();
+}
+
bool AnimationImpl::update(size_t frameNo, const VSize &size)
{
frameNo += mModel->startFrame();
return d->renderList(frameNo, VSize(width, height));
}
+const LOTLayerNode *
+Animation::renderTree(size_t frameNo, size_t width, size_t height) const
+{
+ return d->renderTree(frameNo, VSize(width, height));
+}
+
std::future<Surface> Animation::render(size_t frameNo, Surface surface)
{
return render_scheduler.render(d.get(), frameNo, std::move(surface));
return mRenderList;
}
+void LOTCompItem::buildRenderTree()
+{
+ mRootLayer->buildLayerNode();
+}
+
+const LOTLayerNode * LOTCompItem::renderTree() const
+{
+ return mRootLayer->layerNode();
+}
+
bool LOTCompItem::render(const lottie::Surface &surface)
{
VBitmap bitmap((uchar *)surface.buffer(), surface.width(), surface.height(),
return mRle;
}
+void LOTLayerItem::buildLayerNode()
+{
+ if (!mLayerCNode) {
+ mLayerCNode = std::make_unique<LOTLayerNode>();
+ mLayerCNode->mMaskList.ptr = nullptr;
+ mLayerCNode->mMaskList.size = 0;
+ mLayerCNode->mLayerList.ptr = nullptr;
+ mLayerCNode->mLayerList.size = 0;
+ mLayerCNode->mNodeList.ptr = nullptr;
+ mLayerCNode->mNodeList.size = 0;
+ mLayerCNode->mMatte = MatteNone;
+ mLayerCNode->mVisible = 0;
+ }
+ mLayerCNode->mVisible = visible();
+ // update matte
+ if (hasMatte()) {
+ switch (mLayerData->mMatteType) {
+ case MatteType::Alpha:
+ mLayerCNode->mMatte = MatteAlpha;
+ break;
+ case MatteType::AlphaInv:
+ mLayerCNode->mMatte = MatteAlphaInv;
+ break;
+ case MatteType::Luma:
+ mLayerCNode->mMatte = MatteLuma;
+ break;
+ case MatteType::LumaInv:
+ mLayerCNode->mMatte = MatteLumaInv;
+ break;
+ default:
+ mLayerCNode->mMatte = MatteNone;
+ break;
+ }
+ }
+ if (hasMask()) {
+ //TODO populate mask property
+ }
+}
+
void LOTLayerItem::render(VPainter *painter, const VRle &inheritMask, const VRle &inheritMatte, LOTLayerItem *matteSource)
{
VRle matteRle;
}
}
+void LOTCompLayerItem::buildLayerNode()
+{
+ LOTLayerItem::buildLayerNode();
+ if (mLayers.size() != mLayersCNode.size()) {
+ for (const auto &layer : mLayers) {
+ layer->buildLayerNode();
+ mLayersCNode.push_back(layer->layerNode());
+ }
+ layerNode()->mLayerList.ptr = mLayersCNode.data();
+ layerNode()->mLayerList.size = mLayersCNode.size();
+ } else {
+ for (const auto &layer : mLayers) {
+ layer->buildLayerNode();
+ }
+ }
+}
+
void LOTCompLayerItem::render(VPainter *painter, const VRle &inheritMask, const VRle &inheritMatte, LOTLayerItem *matteSource)
{
VRle matteRle;
}
}
+void LOTSolidLayerItem::buildLayerNode()
+{
+ LOTLayerItem::buildLayerNode();
+
+ mDrawableList.clear();
+ renderList(mDrawableList);
+
+ mCNodeList.clear();
+ for (auto &i : mDrawableList) {
+ LOTDrawable *lotDrawable = static_cast<LOTDrawable *>(i);
+ lotDrawable->sync();
+ mCNodeList.push_back(lotDrawable->mCNode.get());
+ }
+ layerNode()->mNodeList.ptr = mCNodeList.data();
+ layerNode()->mNodeList.size = mCNodeList.size();
+}
+
void LOTSolidLayerItem::renderList(std::vector<VDrawable *> &list)
{
if (!visible()) return;
}
}
+void LOTShapeLayerItem::buildLayerNode()
+{
+ LOTLayerItem::buildLayerNode();
+
+ mDrawableList.clear();
+ renderList(mDrawableList);
+
+ mCNodeList.clear();
+ for (auto &i : mDrawableList) {
+ LOTDrawable *lotDrawable = static_cast<LOTDrawable *>(i);
+ lotDrawable->sync();
+ mCNodeList.push_back(lotDrawable->mCNode.get());
+ }
+ layerNode()->mNodeList.ptr = mCNodeList.data();
+ layerNode()->mNodeList.size = mCNodeList.size();
+}
+
void LOTShapeLayerItem::renderList(std::vector<VDrawable *> &list)
{
if (!visible()) return;
VSize size() const;
const std::vector<LOTNode *>& renderList()const;
void buildRenderList();
+ void buildRenderTree();
+ const LOTLayerNode * renderTree()const;
bool render(const lottie::Surface &surface);
private:
VMatrix mScaleMatrix;
virtual void render(VPainter *painter, const VRle &mask, const VRle &inheritMatte, LOTLayerItem *matteSource);
bool hasMatte() { if (mLayerData->mMatteType == MatteType::None) return false; return true; }
bool visible() const;
-
+ virtual void buildLayerNode();
+ LOTLayerNode * layerNode() const {return mLayerCNode.get();}
protected:
virtual void updateContent() = 0;
inline VMatrix combinedMatrix() const {return mCombinedMatrix;}
VRle maskRle(const VRect &clipRect);
bool hasMask() const {return !mMasks.empty();}
protected:
+ std::unique_ptr<LOTLayerNode> mLayerCNode;
std::vector<VDrawable *> mDrawableList;
std::vector<std::unique_ptr<LOTMaskItem>> mMasks;
LOTLayerData *mLayerData{nullptr};
void renderList(std::vector<VDrawable *> &list)final;
void updateStaticProperty() final;
void render(VPainter *painter, const VRle &mask, const VRle &inheritMatte, LOTLayerItem *matteSource) final;
+ void buildLayerNode() final;
protected:
void updateContent() final;
private:
+ std::vector<LOTLayerNode *> mLayersCNode;
std::vector<std::unique_ptr<LOTLayerItem>> mLayers;
int mLastFrame;
};
{
public:
LOTSolidLayerItem(LOTLayerData *layerData);
+ void buildLayerNode() final;
protected:
void updateContent() final;
void renderList(std::vector<VDrawable *> &list) final;
private:
+ std::vector<LOTNode *> mCNodeList;
std::unique_ptr<VDrawable> mRenderNode;
};
LOTShapeLayerItem(LOTLayerData *layerData);
static std::unique_ptr<LOTContentItem> createContentItem(LOTData *contentData);
void renderList(std::vector<VDrawable *> &list)final;
+ void buildLayerNode() final;
protected:
void updateContent() final;
+ std::vector<LOTNode *> mCNodeList;
std::unique_ptr<LOTContentGroupItem> mRoot;
};