rlottie: refactor lottie model and renderer code. accepted/tizen/unified/20200714.065703 submit/tizen/20200713.050659
authorSubhransu Mohanty <sub.mohanty@samsung.com>
Wed, 8 Jul 2020 08:17:30 +0000 (17:17 +0900)
committerJongmin Lee <jm105.lee@samsung.com>
Mon, 13 Jul 2020 03:33:20 +0000 (12:33 +0900)
- move all the internal code to rlottie::internal namespace
- move model related code to rlottie::internal::model namespace
- move rendering code to rlottie::internal::renderer namespace.
- run clang-format
- removed LOT class prefix.

12 files changed:
src/lottie/lottieanimation.cpp
src/lottie/lottieitem.cpp
src/lottie/lottieitem.h
src/lottie/lottieitem_capi.cpp
src/lottie/lottiekeypath.h
src/lottie/lottieloader.cpp
src/lottie/lottieloader.h [deleted file]
src/lottie/lottiemodel.cpp
src/lottie/lottiemodel.h
src/lottie/lottieparser.cpp
src/lottie/lottieparser.h [deleted file]
src/lottie/lottieproxymodel.h

index 165f8ea..b7b66d8 100644 (file)
  */
 #include "config.h"
 #include "lottieitem.h"
-#include "lottieloader.h"
 #include "lottiemodel.h"
 #include "rlottie.h"
 
 #include <fstream>
 
 using namespace rlottie;
+using namespace rlottie::internal;
 
 LOT_EXPORT void rlottie::configureModelCacheSize(size_t cacheSize)
 {
-    LottieLoader::configureModelCacheSize(cacheSize);
+    internal::model::configureModelCacheSize(cacheSize);
 }
 
 struct RenderTask {
@@ -43,15 +43,17 @@ using SharedRenderTask = std::shared_ptr<RenderTask>;
 
 class AnimationImpl {
 public:
-    void    init(const std::shared_ptr<LOTModel> &model);
+    void    init(std::shared_ptr<model::Composition> composition);
     bool    update(size_t frameNo, const VSize &size, bool keepAspectRatio);
     VSize   size() const { return mModel->size(); }
     double  duration() const { return mModel->duration(); }
     double  frameRate() const { return mModel->frameRate(); }
     size_t  totalFrame() const { return mModel->totalFrame(); }
     size_t  frameAtPos(double pos) const { return mModel->frameAtPos(pos); }
-    Surface render(size_t frameNo, const Surface &surface, bool keepAspectRatio);
-    std::future<Surface> renderAsync(size_t frameNo, Surface &&surface, bool keepAspectRatio);
+    Surface render(size_t frameNo, const Surface &surface,
+                   bool keepAspectRatio);
+    std::future<Surface> renderAsync(size_t frameNo, Surface &&surface,
+                                     bool keepAspectRatio);
     const LOTLayerNode * renderTree(size_t frameNo, const VSize &size);
 
     const LayerInfoList &layerInfoList() const
@@ -61,37 +63,34 @@ public:
         }
         return mLayerList;
     }
-    const MarkerList &markers() const
-    {
-        return mModel->markers();
-    }
-    void setValue(const std::string &keypath, LOTVariant &&value);
-    void removeFilter(const std::string &keypath, Property prop);
+    const MarkerList &markers() const { return mModel->markers(); }
+    void              setValue(const std::string &keypath, LOTVariant &&value);
+    void              removeFilter(const std::string &keypath, Property prop);
 
 private:
-    mutable LayerInfoList        mLayerList;
-    std::string                  mFilePath;
-    std::shared_ptr<LOTModel>    mModel;
-    std::unique_ptr<LOTCompItem> mCompItem;
-    SharedRenderTask             mTask;
-    std::atomic<bool>            mRenderInProgress;
+    mutable LayerInfoList                  mLayerList;
+    model::Composition *                   mModel;
+    SharedRenderTask                       mTask;
+    std::atomic<bool>                      mRenderInProgress;
+    std::unique_ptr<renderer::Composition> mRenderer{nullptr};
 };
 
 void AnimationImpl::setValue(const std::string &keypath, LOTVariant &&value)
 {
     if (keypath.empty()) return;
-    mCompItem->setValue(keypath, value);
+    mRenderer->setValue(keypath, value);
 }
 
 const LOTLayerNode *AnimationImpl::renderTree(size_t frameNo, const VSize &size)
 {
     if (update(frameNo, size, true)) {
-        mCompItem->buildRenderTree();
+        mRenderer->buildRenderTree();
     }
-    return mCompItem->renderTree();
+    return mRenderer->renderTree();
 }
 
-bool AnimationImpl::update(size_t frameNo, const VSize &size, bool keepAspectRatio)
+bool AnimationImpl::update(size_t frameNo, const VSize &size,
+                           bool keepAspectRatio)
 {
     frameNo += mModel->startFrame();
 
@@ -99,10 +98,11 @@ bool AnimationImpl::update(size_t frameNo, const VSize &size, bool keepAspectRat
 
     if (frameNo < mModel->startFrame()) frameNo = mModel->startFrame();
 
-    return mCompItem->update(int(frameNo), size, keepAspectRatio);
+    return mRenderer->update(int(frameNo), size, keepAspectRatio);
 }
 
-Surface AnimationImpl::render(size_t frameNo, const Surface &surface, bool keepAspectRatio)
+Surface AnimationImpl::render(size_t frameNo, const Surface &surface,
+                              bool keepAspectRatio)
 {
     bool renderInProgress = mRenderInProgress.load();
     if (renderInProgress) {
@@ -111,18 +111,20 @@ Surface AnimationImpl::render(size_t frameNo, const Surface &surface, bool keepA
     }
 
     mRenderInProgress.store(true);
-    update(frameNo,
-           VSize(int(surface.drawRegionWidth()), int(surface.drawRegionHeight())), keepAspectRatio);
-    mCompItem->render(surface);
+    update(
+        frameNo,
+        VSize(int(surface.drawRegionWidth()), int(surface.drawRegionHeight())),
+        keepAspectRatio);
+    mRenderer->render(surface);
     mRenderInProgress.store(false);
 
     return surface;
 }
 
-void AnimationImpl::init(const std::shared_ptr<LOTModel> &model)
+void AnimationImpl::init(std::shared_ptr<model::Composition> composition)
 {
-    mModel = model;
-    mCompItem = std::make_unique<LOTCompItem>(mModel.get());
+    mModel = composition.get();
+    mRenderer = std::make_unique<renderer::Composition>(composition);
     mRenderInProgress = false;
 }
 
@@ -161,8 +163,8 @@ class RenderTaskScheduler {
             }
             if (!success && !_q[i].pop(task)) break;
 
-            auto result =
-                task->playerImpl->render(task->frameNo, task->surface, task->keepAspectRatio);
+            auto result = task->playerImpl->render(task->frameNo, task->surface,
+                                                   task->keepAspectRatio);
             task->sender.set_value(result);
         }
     }
@@ -216,7 +218,8 @@ public:
 
     std::future<Surface> process(SharedRenderTask task)
     {
-        auto result = task->playerImpl->render(task->frameNo, task->surface, task->keepAspectRatio);
+        auto result = task->playerImpl->render(task->frameNo, task->surface,
+                                               task->keepAspectRatio);
         task->sender.set_value(result);
         return std::move(task->receiver);
     }
@@ -225,7 +228,7 @@ public:
 
 std::future<Surface> AnimationImpl::renderAsync(size_t    frameNo,
                                                 Surface &&surface,
-                                                bool keepAspectRatio)
+                                                bool      keepAspectRatio)
 {
     if (!mTask) {
         mTask = std::make_shared<RenderTask>();
@@ -255,43 +258,48 @@ std::unique_ptr<Animation> Animation::loadFromData(
         return nullptr;
     }
 
-    LottieLoader loader;
-    if (loader.loadFromData(std::move(jsonData), key, resourcePath, cachePolicy)) {
+    auto composition = model::loadFromData(std::move(jsonData), key,
+                                           resourcePath, cachePolicy);
+    if (composition) {
         auto animation = std::unique_ptr<Animation>(new Animation);
-        animation->d->init(loader.model());
+        animation->d->init(std::move(composition));
         return animation;
     }
+
     return nullptr;
 }
 
-std::unique_ptr<Animation> Animation::loadFromData( std::string jsonData, std::string resourcePath, ColorFilter filter)
+std::unique_ptr<Animation> Animation::loadFromData(std::string jsonData,
+                                                   std::string resourcePath,
+                                                   ColorFilter filter)
 {
     if (jsonData.empty()) {
         vWarning << "jason data is empty";
         return nullptr;
     }
 
-    LottieLoader loader;
-    if (loader.loadFromData(std::move(jsonData), std::move(resourcePath), std::move(filter))) {
+    auto composition = model::loadFromData(
+        std::move(jsonData), std::move(resourcePath), std::move(filter));
+    if (composition) {
         auto animation = std::unique_ptr<Animation>(new Animation);
-        animation->d->init(loader.model());
+        animation->d->init(std::move(composition));
         return animation;
     }
     return nullptr;
 }
 
-std::unique_ptr<Animation>
-Animation::loadFromFile(const std::string &path, bool cachePolicy)
+std::unique_ptr<Animation> Animation::loadFromFile(const std::string &path,
+                                                   bool cachePolicy)
 {
     if (path.empty()) {
         vWarning << "File path is empty";
         return nullptr;
     }
 
-    LottieLoader loader;
-    if (loader.load(path, cachePolicy)) {
+    auto composition = model::loadFromFile(path, cachePolicy);
+    if (composition) {
         auto animation = std::unique_ptr<Animation>(new Animation);
-        animation->d->init(loader.model());
+        animation->d->init(std::move(composition));
         return animation;
     }
     return nullptr;
@@ -331,12 +339,14 @@ const LOTLayerNode *Animation::renderTree(size_t frameNo, size_t width,
     return d->renderTree(frameNo, VSize(int(width), int(height)));
 }
 
-std::future<Surface> Animation::render(size_t frameNo, Surface surface, bool keepAspectRatio)
+std::future<Surface> Animation::render(size_t frameNo, Surface surface,
+                                       bool keepAspectRatio)
 {
     return d->renderAsync(frameNo, std::move(surface), keepAspectRatio);
 }
 
-void Animation::renderSync(size_t frameNo, Surface surface, bool keepAspectRatio)
+void Animation::renderSync(size_t frameNo, Surface surface,
+                           bool keepAspectRatio)
 {
     d->render(frameNo, surface, keepAspectRatio);
 }
index a017e47..276fd71 100644 (file)
@@ -68,24 +68,24 @@ static bool strokeProp(rlottie::Property prop)
     }
 }
 
-static LOTLayerItem*
-createLayerItem(LOTLayerData *layerData, VArenaAlloc *allocator)
+static renderer::Layer *createLayerItem(model::Layer *layerData,
+                                        VArenaAlloc * allocator)
 {
     switch (layerData->mLayerType) {
-    case LayerType::Precomp: {
-        return allocator->make<LOTCompLayerItem>(layerData, allocator);
+    case model::Layer::Type::Precomp: {
+        return allocator->make<renderer::CompLayer>(layerData, allocator);
     }
-    case LayerType::Solid: {
-        return allocator->make<LOTSolidLayerItem>(layerData);
+    case model::Layer::Type::Solid: {
+        return allocator->make<renderer::SolidLayer>(layerData);
     }
-    case LayerType::Shape: {
-        return allocator->make<LOTShapeLayerItem>(layerData, allocator);
+    case model::Layer::Type::Shape: {
+        return allocator->make<renderer::ShapeLayer>(layerData, allocator);
     }
-    case LayerType::Null: {
-        return allocator->make<LOTNullLayerItem>(layerData);
+    case model::Layer::Type::Null: {
+        return allocator->make<renderer::NullLayer>(layerData);
     }
-    case LayerType::Image: {
-        return allocator->make<LOTImageLayerItem>(layerData);
+    case model::Layer::Type::Image: {
+        return allocator->make<renderer::ImageLayer>(layerData);
     }
     default:
         return nullptr;
@@ -93,27 +93,29 @@ createLayerItem(LOTLayerData *layerData, VArenaAlloc *allocator)
     }
 }
 
-LOTCompItem::LOTCompItem(LOTModel *model)
+renderer::Composition::Composition(std::shared_ptr<model::Composition> model)
     : mCurFrameNo(-1)
 {
-    mCompData = model->mRoot.get();
-    mRootLayer = createLayerItem(mCompData->mRootLayer, &mAllocator);
+    mModel = std::move(model);
+    mRootLayer = createLayerItem(mModel->mRootLayer, &mAllocator);
     mRootLayer->setComplexContent(false);
-    mViewSize = mCompData->size();
+    mViewSize = mModel->size();
 }
 
-void LOTCompItem::setValue(const std::string &keypath, LOTVariant &value)
+void renderer::Composition::setValue(const std::string &keypath,
+                                     LOTVariant &       value)
 {
     LOTKeyPath key(keypath);
     mRootLayer->resolveKeyPath(key, 0, value);
 }
 
-bool LOTCompItem::update(int frameNo, const VSize &size, bool keepAspectRatio)
+bool renderer::Composition::update(int frameNo, const VSize &size,
+                                   bool keepAspectRatio)
 {
     // check if cached frame is same as requested frame.
-    if ((mViewSize == size) &&
-        (mCurFrameNo == frameNo) &&
-        (mKeepAspectRatio == keepAspectRatio)) return false;
+    if ((mViewSize == size) && (mCurFrameNo == frameNo) &&
+        (mKeepAspectRatio == keepAspectRatio))
+        return false;
 
     mViewSize = size;
     mCurFrameNo = frameNo;
@@ -125,31 +127,33 @@ bool LOTCompItem::update(int frameNo, const VSize &size, bool keepAspectRatio)
      * viewbox to the viewport using AlignCenter rule.
      */
     VMatrix m;
-    VSize viewPort = mViewSize;
-    VSize viewBox = mCompData->size();
-    float sx = float(viewPort.width()) / viewBox.width();
-    float sy = float(viewPort.height()) / viewBox.height();
+    VSize   viewPort = mViewSize;
+    VSize   viewBox = mModel->size();
+    float   sx = float(viewPort.width()) / viewBox.width();
+    float   sy = float(viewPort.height()) / viewBox.height();
     if (mKeepAspectRatio) {
         float scale = std::min(sx, sy);
         float tx = (viewPort.width() - viewBox.width() * scale) * 0.5f;
         float ty = (viewPort.height() - viewBox.height() * scale) * 0.5f;
         m.translate(tx, ty).scale(scale, scale);
     } else {
-       m.scale(sx, sy);
+        m.scale(sx, sy);
     }
     mRootLayer->update(frameNo, m, 1.0);
     return true;
 }
 
-bool LOTCompItem::render(const rlottie::Surface &surface)
+bool renderer::Composition::render(const rlottie::Surface &surface)
 {
     mSurface.reset(reinterpret_cast<uchar *>(surface.buffer()),
-                   uint(surface.width()), uint(surface.height()), uint(surface.bytesPerLine()),
+                   uint(surface.width()), uint(surface.height()),
+                   uint(surface.bytesPerLine()),
                    VBitmap::Format::ARGB32_Premultiplied);
 
     /* schedule all preprocess task for this frame at once.
      */
-    VRect clip(0, 0, int(surface.drawRegionWidth()), int(surface.drawRegionHeight()));
+    VRect clip(0, 0, int(surface.drawRegionWidth()),
+               int(surface.drawRegionHeight()));
     mRootLayer->preprocess(clip);
 
     VPainter painter(&mSurface);
@@ -162,8 +166,8 @@ bool LOTCompItem::render(const rlottie::Surface &surface)
     return true;
 }
 
-void LOTMaskItem::update(int frameNo, const VMatrix &            parentMatrix,
-                         float /*parentAlpha*/, const DirtyFlag &flag)
+void renderer::Mask::update(int frameNo, const VMatrix &parentMatrix,
+                            float /*parentAlpha*/, const DirtyFlag &flag)
 {
     if (flag.testFlag(DirtyFlagBit::None) && mData->isStatic()) return;
 
@@ -183,7 +187,7 @@ void LOTMaskItem::update(int frameNo, const VMatrix &            parentMatrix,
     mRasterRequest = true;
 }
 
-VRle LOTMaskItem::rle()
+VRle renderer::Mask::rle()
 {
     if (mRasterRequest) {
         mRasterRequest = false;
@@ -194,13 +198,14 @@ VRle LOTMaskItem::rle()
     return mRasterizer.rle();
 }
 
-void LOTMaskItem::preprocess(const VRect &clip)
+void renderer::Mask::preprocess(const VRect &clip)
 {
-    if (mRasterRequest) mRasterizer.rasterize(mFinalPath, FillRule::Winding, clip);
+    if (mRasterRequest)
+        mRasterizer.rasterize(mFinalPath, FillRule::Winding, clip);
 }
 
-void LOTLayerItem::render(VPainter *painter, const VRle &inheritMask,
-                          const VRle &matteRle, SurfaceCache& cache)
+void renderer::Layer::render(VPainter *painter, const VRle &inheritMask,
+                             const VRle &matteRle, SurfaceCache &cache)
 {
     auto renderlist = renderList();
 
@@ -232,7 +237,7 @@ void LOTLayerItem::render(VPainter *painter, const VRle &inheritMask,
             if (!mask.empty()) rle = rle & mask;
 
             if (rle.empty()) continue;
-            if (matteType() == MatteType::AlphaInv) {
+            if (matteType() == model::MatteType::AlphaInv) {
                 rle = rle - matteRle;
                 painter->drawRle(VPoint(), rle);
             } else {
@@ -243,15 +248,14 @@ void LOTLayerItem::render(VPainter *painter, const VRle &inheritMask,
     }
 }
 
-void LOTLayerMaskItem::preprocess(const VRect &clip)
+void renderer::LayerMask::preprocess(const VRect &clip)
 {
     for (auto &i : mMasks) {
         i.preprocess(clip);
     }
 }
 
-
-LOTLayerMaskItem::LOTLayerMaskItem(LOTLayerData *layerData)
+renderer::LayerMask::LayerMask(model::Layer *layerData)
 {
     if (!layerData->mExtra) return;
 
@@ -263,8 +267,8 @@ LOTLayerMaskItem::LOTLayerMaskItem(LOTLayerData *layerData)
     }
 }
 
-void LOTLayerMaskItem::update(int frameNo, const VMatrix &parentMatrix,
-                              float parentAlpha, const DirtyFlag &flag)
+void renderer::LayerMask::update(int frameNo, const VMatrix &parentMatrix,
+                                 float parentAlpha, const DirtyFlag &flag)
 {
     if (flag.testFlag(DirtyFlagBit::None) && isStatic()) return;
 
@@ -274,28 +278,28 @@ void LOTLayerMaskItem::update(int frameNo, const VMatrix &parentMatrix,
     mDirty = true;
 }
 
-VRle LOTLayerMaskItem::maskRle(const VRect &clipRect)
+VRle renderer::LayerMask::maskRle(const VRect &clipRect)
 {
     if (!mDirty) return mRle;
 
     VRle rle;
     for (auto &i : mMasks) {
         switch (i.maskMode()) {
-        case LOTMaskData::Mode::Add: {
+        case model::Mask::Mode::Add: {
             rle = rle + i.rle();
             break;
         }
-        case LOTMaskData::Mode::Substarct: {
+        case model::Mask::Mode::Substarct: {
             if (rle.empty() && !clipRect.empty()) rle = VRle::toRle(clipRect);
             rle = rle - i.rle();
             break;
         }
-        case LOTMaskData::Mode::Intersect: {
+        case model::Mask::Mode::Intersect: {
             if (rle.empty() && !clipRect.empty()) rle = VRle::toRle(clipRect);
             rle = rle & i.rle();
             break;
         }
-        case LOTMaskData::Mode::Difference: {
+        case model::Mask::Mode::Difference: {
             rle = rle ^ i.rle();
             break;
         }
@@ -313,14 +317,14 @@ VRle LOTLayerMaskItem::maskRle(const VRect &clipRect)
     return mRle;
 }
 
-LOTLayerItem::LOTLayerItem(LOTLayerData *layerData) : mLayerData(layerData)
+renderer::Layer::Layer(model::Layer *layerData) : mLayerData(layerData)
 {
     if (mLayerData->mHasMask)
-        mLayerMask = std::make_unique<LOTLayerMaskItem>(mLayerData);
+        mLayerMask = std::make_unique<renderer::LayerMask>(mLayerData);
 }
 
-bool LOTLayerItem::resolveKeyPath(LOTKeyPath &keyPath, uint depth,
-                                  LOTVariant &value)
+bool renderer::Layer::resolveKeyPath(LOTKeyPath &keyPath, uint depth,
+                                     LOTVariant &value)
 {
     if (!keyPath.matches(name(), depth)) {
         return false;
@@ -335,10 +339,10 @@ bool LOTLayerItem::resolveKeyPath(LOTKeyPath &keyPath, uint depth,
     return true;
 }
 
-bool LOTShapeLayerItem::resolveKeyPath(LOTKeyPath &keyPath, uint depth,
-                                       LOTVariant &value)
+bool renderer::ShapeLayer::resolveKeyPath(LOTKeyPath &keyPath, uint depth,
+                                          LOTVariant &value)
 {
-    if (LOTLayerItem::resolveKeyPath(keyPath, depth, value)) {
+    if (renderer::Layer::resolveKeyPath(keyPath, depth, value)) {
         if (keyPath.propagate(name(), depth)) {
             uint newDepth = keyPath.nextDepth(name(), depth);
             mRoot->resolveKeyPath(keyPath, newDepth, value);
@@ -348,10 +352,10 @@ bool LOTShapeLayerItem::resolveKeyPath(LOTKeyPath &keyPath, uint depth,
     return false;
 }
 
-bool LOTCompLayerItem::resolveKeyPath(LOTKeyPath &keyPath, uint depth,
-                                      LOTVariant &value)
+bool renderer::CompLayer::resolveKeyPath(LOTKeyPath &keyPath, uint depth,
+                                         LOTVariant &value)
 {
-    if (LOTLayerItem::resolveKeyPath(keyPath, depth, value)) {
+    if (renderer::Layer::resolveKeyPath(keyPath, depth, value)) {
         if (keyPath.propagate(name(), depth)) {
             uint newDepth = keyPath.nextDepth(name(), depth);
             for (const auto &layer : mLayers) {
@@ -363,8 +367,8 @@ bool LOTCompLayerItem::resolveKeyPath(LOTKeyPath &keyPath, uint depth,
     return false;
 }
 
-void LOTLayerItem::update(int frameNumber, const VMatrix &parentMatrix,
-                          float parentAlpha)
+void renderer::Layer::update(int frameNumber, const VMatrix &parentMatrix,
+                             float parentAlpha)
 {
     mFrameNo = frameNumber;
     // 1. check if the layer is part of the current frame
@@ -409,20 +413,20 @@ void LOTLayerItem::update(int frameNumber, const VMatrix &parentMatrix,
     mDirtyFlag = DirtyFlagBit::None;
 }
 
-VMatrix LOTLayerItem::matrix(int frameNo) const
+VMatrix renderer::Layer::matrix(int frameNo) const
 {
     return mParentLayer
                ? (mLayerData->matrix(frameNo) * mParentLayer->matrix(frameNo))
                : mLayerData->matrix(frameNo);
 }
 
-bool LOTLayerItem::visible() const
+bool renderer::Layer::visible() const
 {
     return (frameNo() >= mLayerData->inFrame() &&
             frameNo() < mLayerData->outFrame());
 }
 
-void LOTLayerItem::preprocess(const VRect& clip)
+void renderer::Layer::preprocess(const VRect &clip)
 {
     // layer dosen't contribute to the frame
     if (skipRendering()) return;
@@ -433,8 +437,8 @@ void LOTLayerItem::preprocess(const VRect& clip)
     preprocessStage(clip);
 }
 
-LOTCompLayerItem::LOTCompLayerItem(LOTLayerData *layerModel, VArenaAlloc* allocator)
-    : LOTLayerItem(layerModel)
+renderer::CompLayer::CompLayer(model::Layer *layerModel, VArenaAlloc *allocator)
+    : renderer::Layer(layerModel)
 {
     if (!mLayerData->mChildren.empty())
         mLayers.reserve(mLayerData->mChildren.size());
@@ -442,8 +446,8 @@ LOTCompLayerItem::LOTCompLayerItem(LOTLayerData *layerModel, VArenaAlloc* alloca
     // 1. keep the layer in back-to-front order.
     // as lottie model keeps the data in front-toback-order.
     for (auto it = mLayerData->mChildren.crbegin();
-         it != mLayerData->mChildren.rend(); ++it ) {
-        auto model = static_cast<LOTLayerData *>(*it);
+         it != mLayerData->mChildren.rend(); ++it) {
+        auto model = static_cast<model::Layer *>(*it);
         auto item = createLayerItem(model, allocator);
         if (item) mLayers.push_back(item);
     }
@@ -461,14 +465,14 @@ LOTCompLayerItem::LOTCompLayerItem(LOTLayerData *layerModel, VArenaAlloc* alloca
 
     // 4. check if its a nested composition
     if (!layerModel->layerSize().empty()) {
-        mClipper = std::make_unique<LOTClipperItem>(layerModel->layerSize());
+        mClipper = std::make_unique<renderer::Clipper>(layerModel->layerSize());
     }
 
     if (mLayers.size() > 1) setComplexContent(true);
 }
 
-void LOTCompLayerItem::render(VPainter *painter, const VRle &inheritMask,
-                              const VRle &matteRle, SurfaceCache& cache)
+void renderer::CompLayer::render(VPainter *painter, const VRle &inheritMask,
+                                 const VRle &matteRle, SurfaceCache &cache)
 {
     if (vIsZero(combinedAlpha())) return;
 
@@ -478,11 +482,12 @@ void LOTCompLayerItem::render(VPainter *painter, const VRle &inheritMask,
         if (complexContent()) {
             VSize    size = painter->clipBoundingRect().size();
             VPainter srcPainter;
-            VBitmap  srcBitmap = cache.make_surface(size.width(), size.height());
+            VBitmap srcBitmap = cache.make_surface(size.width(), size.height());
             srcPainter.begin(&srcBitmap);
             renderHelper(&srcPainter, inheritMask, matteRle, cache);
             srcPainter.end();
-            painter->drawBitmap(VPoint(), srcBitmap, uchar(combinedAlpha() * 255.0f));
+            painter->drawBitmap(VPoint(), srcBitmap,
+                                uchar(combinedAlpha() * 255.0f));
             cache.release_surface(srcBitmap);
         } else {
             renderHelper(painter, inheritMask, matteRle, cache);
@@ -490,8 +495,10 @@ void LOTCompLayerItem::render(VPainter *painter, const VRle &inheritMask,
     }
 }
 
-void LOTCompLayerItem::renderHelper(VPainter *painter, const VRle &inheritMask,
-                                    const VRle &matteRle, SurfaceCache& cache)
+void renderer::CompLayer::renderHelper(VPainter *    painter,
+                                       const VRle &  inheritMask,
+                                       const VRle &  matteRle,
+                                       SurfaceCache &cache)
 {
     VRle mask;
     if (mLayerMask) {
@@ -508,7 +515,7 @@ void LOTCompLayerItem::renderHelper(VPainter *painter, const VRle &inheritMask,
         if (mask.empty()) return;
     }
 
-    LOTLayerItem *matte = nullptr;
+    renderer::Layer *matte = nullptr;
     for (const auto &layer : mLayers) {
         if (layer->hasMatte()) {
             matte = layer;
@@ -516,8 +523,8 @@ void LOTCompLayerItem::renderHelper(VPainter *painter, const VRle &inheritMask,
             if (layer->visible()) {
                 if (matte) {
                     if (matte->visible())
-                        renderMatteLayer(painter, mask, matteRle, matte,
-                                         layer, cache);
+                        renderMatteLayer(painter, mask, matteRle, matte, layer,
+                                         cache);
                 } else {
                     layer->render(painter, mask, matteRle, cache);
                 }
@@ -527,34 +534,36 @@ void LOTCompLayerItem::renderHelper(VPainter *painter, const VRle &inheritMask,
     }
 }
 
-void LOTCompLayerItem::renderMatteLayer(VPainter *painter, const VRle &mask,
-                                        const VRle &  matteRle,
-                                        LOTLayerItem *layer, LOTLayerItem *src, SurfaceCache& cache)
+void renderer::CompLayer::renderMatteLayer(VPainter *painter, const VRle &mask,
+                                           const VRle &     matteRle,
+                                           renderer::Layer *layer,
+                                           renderer::Layer *src,
+                                           SurfaceCache &   cache)
 {
     VSize size = painter->clipBoundingRect().size();
     // Decide if we can use fast matte.
     // 1. draw src layer to matte buffer
     VPainter srcPainter;
-    VBitmap srcBitmap = cache.make_surface(size.width(), size.height());
+    VBitmap  srcBitmap = cache.make_surface(size.width(), size.height());
     srcPainter.begin(&srcBitmap);
     src->render(&srcPainter, mask, matteRle, cache);
     srcPainter.end();
 
     // 2. draw layer to layer buffer
     VPainter layerPainter;
-    VBitmap layerBitmap = cache.make_surface(size.width(), size.height());
+    VBitmap  layerBitmap = cache.make_surface(size.width(), size.height());
     layerPainter.begin(&layerBitmap);
     layer->render(&layerPainter, mask, matteRle, cache);
 
     // 2.1update composition mode
     switch (layer->matteType()) {
-    case MatteType::Alpha:
-    case MatteType::Luma: {
+    case model::MatteType::Alpha:
+    case model::MatteType::Luma: {
         layerPainter.setBlendMode(BlendMode::DestIn);
         break;
     }
-    case MatteType::AlphaInv:
-    case MatteType::LumaInv: {
+    case model::MatteType::AlphaInv:
+    case model::MatteType::LumaInv: {
         layerPainter.setBlendMode(BlendMode::DestOut);
         break;
     }
@@ -563,8 +572,8 @@ void LOTCompLayerItem::renderMatteLayer(VPainter *painter, const VRle &mask,
     }
 
     // 2.2 update srcBuffer if the matte is luma type
-    if (layer->matteType() == MatteType::Luma ||
-        layer->matteType() == MatteType::LumaInv) {
+    if (layer->matteType() == model::MatteType::Luma ||
+        layer->matteType() == model::MatteType::LumaInv) {
         srcBitmap.updateLuma();
     }
 
@@ -578,7 +587,7 @@ void LOTCompLayerItem::renderMatteLayer(VPainter *painter, const VRle &mask,
     cache.release_surface(layerBitmap);
 }
 
-void LOTClipperItem::update(const VMatrix &matrix)
+void renderer::Clipper::update(const VMatrix &matrix)
 {
     mPath.reset();
     mPath.addRect(VRectF(0, 0, mSize.width(), mSize.height()));
@@ -586,25 +595,23 @@ void LOTClipperItem::update(const VMatrix &matrix)
     mRasterRequest = true;
 }
 
-void LOTClipperItem::preprocess(const VRect &clip)
+void renderer::Clipper::preprocess(const VRect &clip)
 {
-    if (mRasterRequest)
-        mRasterizer.rasterize(mPath, FillRule::Winding, clip);
+    if (mRasterRequest) mRasterizer.rasterize(mPath, FillRule::Winding, clip);
 
     mRasterRequest = false;
 }
 
-VRle LOTClipperItem::rle(const VRle& mask)
+VRle renderer::Clipper::rle(const VRle &mask)
 {
-    if (mask.empty())
-        return mRasterizer.rle();
+    if (mask.empty()) return mRasterizer.rle();
 
     mMaskedRle.clone(mask);
     mMaskedRle &= mRasterizer.rle();
     return mMaskedRle;
 }
 
-void LOTCompLayerItem::updateContent()
+void renderer::CompLayer::updateContent()
 {
     if (mClipper && flag().testFlag(DirtyFlagBit::Matrix)) {
         mClipper->update(combinedMatrix());
@@ -617,12 +624,12 @@ void LOTCompLayerItem::updateContent()
     }
 }
 
-void LOTCompLayerItem::preprocessStage(const VRect &clip)
+void renderer::CompLayer::preprocessStage(const VRect &clip)
 {
     // if layer has clipper
     if (mClipper) mClipper->preprocess(clip);
 
-    LOTLayerItem *matte = nullptr;
+    renderer::Layer *matte = nullptr;
     for (const auto &layer : mLayers) {
         if (layer->hasMatte()) {
             matte = layer;
@@ -642,46 +649,44 @@ void LOTCompLayerItem::preprocessStage(const VRect &clip)
     }
 }
 
-LOTSolidLayerItem::LOTSolidLayerItem(LOTLayerData *layerData)
-    : LOTLayerItem(layerData)
+renderer::SolidLayer::SolidLayer(model::Layer *layerData)
+    : renderer::Layer(layerData)
 {
     mDrawableList = &mRenderNode;
 }
 
-void LOTSolidLayerItem::updateContent()
+void renderer::SolidLayer::updateContent()
 {
     if (flag() & DirtyFlagBit::Matrix) {
         VPath path;
-        path.addRect(
-            VRectF(0, 0,
-                   mLayerData->layerSize().width(),
-                   mLayerData->layerSize().height()));
+        path.addRect(VRectF(0, 0, mLayerData->layerSize().width(),
+                            mLayerData->layerSize().height()));
         path.transform(combinedMatrix());
         mRenderNode.mFlag |= VDrawable::DirtyState::Path;
         mRenderNode.mPath = path;
     }
     if (flag() & DirtyFlagBit::Alpha) {
-        LottieColor color = mLayerData->solidColor();
-        VBrush      brush(color.toColor(combinedAlpha()));
+        model::Color color = mLayerData->solidColor();
+        VBrush       brush(color.toColor(combinedAlpha()));
         mRenderNode.setBrush(brush);
         mRenderNode.mFlag |= VDrawable::DirtyState::Brush;
     }
 }
 
-void LOTSolidLayerItem::preprocessStage(const VRect& clip)
+void renderer::SolidLayer::preprocessStage(const VRect &clip)
 {
     mRenderNode.preprocess(clip);
 }
 
-DrawableList LOTSolidLayerItem::renderList()
+renderer::DrawableList renderer::SolidLayer::renderList()
 {
     if (skipRendering()) return {};
 
-    return {&mDrawableList , 1};
+    return {&mDrawableList, 1};
 }
 
-LOTImageLayerItem::LOTImageLayerItem(LOTLayerData *layerData)
-    : LOTLayerItem(layerData)
+renderer::ImageLayer::ImageLayer(model::Layer *layerData)
+    : renderer::Layer(layerData)
 {
     mDrawableList = &mRenderNode;
 
@@ -692,7 +697,7 @@ LOTImageLayerItem::LOTImageLayerItem(LOTLayerData *layerData)
     mRenderNode.setBrush(brush);
 }
 
-void LOTImageLayerItem::updateContent()
+void renderer::ImageLayer::updateContent()
 {
     if (!mLayerData->asset()) return;
 
@@ -711,71 +716,71 @@ void LOTImageLayerItem::updateContent()
     }
 }
 
-void LOTImageLayerItem::preprocessStage(const VRect& clip)
+void renderer::ImageLayer::preprocessStage(const VRect &clip)
 {
     mRenderNode.preprocess(clip);
 }
 
-DrawableList LOTImageLayerItem::renderList()
+renderer::DrawableList renderer::ImageLayer::renderList()
 {
     if (skipRendering()) return {};
 
-    return {&mDrawableList , 1};
+    return {&mDrawableList, 1};
 }
 
-LOTNullLayerItem::LOTNullLayerItem(LOTLayerData *layerData)
-    : LOTLayerItem(layerData)
+renderer::NullLayer::NullLayer(model::Layer *layerData)
+    : renderer::Layer(layerData)
 {
 }
-void LOTNullLayerItem::updateContent() {}
+void renderer::NullLayer::updateContent() {}
 
-static LOTContentItem*
-createContentItem(LOTData *contentData, VArenaAlloc* allocator)
+static renderer::Object *createContentItem(model::Object *contentData,
+                                           VArenaAlloc *  allocator)
 {
     switch (contentData->type()) {
-    case LOTData::Type::ShapeGroup: {
-        return allocator->make<LOTContentGroupItem>(
-            static_cast<LOTGroupData *>(contentData), allocator);
+    case model::Object::Type::Group: {
+        return allocator->make<renderer::Group>(
+            static_cast<model::Group *>(contentData), allocator);
     }
-    case LOTData::Type::Rect: {
-        return allocator->make<LOTRectItem>(
-            static_cast<LOTRectData *>(contentData));
+    case model::Object::Type::Rect: {
+        return allocator->make<renderer::Rect>(
+            static_cast<model::Rect *>(contentData));
     }
-    case LOTData::Type::Ellipse: {
-        return allocator->make<LOTEllipseItem>(
-            static_cast<LOTEllipseData *>(contentData));
+    case model::Object::Type::Ellipse: {
+        return allocator->make<renderer::Ellipse>(
+            static_cast<model::Ellipse *>(contentData));
     }
-    case LOTData::Type::Shape: {
-        return allocator->make<LOTShapeItem>(
-            static_cast<LOTShapeData *>(contentData));
+    case model::Object::Type::Path: {
+        return allocator->make<renderer::Path>(
+            static_cast<model::Path *>(contentData));
     }
-    case LOTData::Type::Polystar: {
-        return allocator->make<LOTPolystarItem>(
-            static_cast<LOTPolystarData *>(contentData));
+    case model::Object::Type::Polystar: {
+        return allocator->make<renderer::Polystar>(
+            static_cast<model::Polystar *>(contentData));
     }
-    case LOTData::Type::Fill: {
-        return allocator->make<LOTFillItem>(
-            static_cast<LOTFillData *>(contentData));
+    case model::Object::Type::Fill: {
+        return allocator->make<renderer::Fill>(
+            static_cast<model::Fill *>(contentData));
     }
-    case LOTData::Type::GFill: {
-        return allocator->make<LOTGFillItem>(
-            static_cast<LOTGFillData *>(contentData));
+    case model::Object::Type::GFill: {
+        return allocator->make<renderer::GradientFill>(
+            static_cast<model::GradientFill *>(contentData));
     }
-    case LOTData::Type::Stroke: {
-        return allocator->make<LOTStrokeItem>(
-            static_cast<LOTStrokeData *>(contentData));
+    case model::Object::Type::Stroke: {
+        return allocator->make<renderer::Stroke>(
+            static_cast<model::Stroke *>(contentData));
     }
-    case LOTData::Type::GStroke: {
-        return allocator->make<LOTGStrokeItem>(
-            static_cast<LOTGStrokeData *>(contentData));
+    case model::Object::Type::GStroke: {
+        return allocator->make<renderer::GradientStroke>(
+            static_cast<model::GradientStroke *>(contentData));
     }
-    case LOTData::Type::Repeater: {
-        return allocator->make<LOTRepeaterItem>(
-            static_cast<LOTRepeaterData *>(contentData), allocator);
+    case model::Object::Type::Repeater: {
+        return allocator->make<renderer::Repeater>(
+            static_cast<model::Repeater *>(contentData), allocator);
     }
-    case LOTData::Type::Trim: {
-        return allocator->make<LOTTrimItem>(
-            static_cast<LOTTrimData *>(contentData));
+    case model::Object::Type::Trim: {
+        return allocator->make<renderer::Trim>(
+            static_cast<model::Trim *>(contentData));
     }
     default:
         return nullptr;
@@ -783,13 +788,14 @@ createContentItem(LOTData *contentData, VArenaAlloc* allocator)
     }
 }
 
-LOTShapeLayerItem::LOTShapeLayerItem(LOTLayerData *layerData, VArenaAlloc* allocator)
-    : LOTLayerItem(layerData),
-      mRoot(allocator->make<LOTContentGroupItem>(nullptr, allocator))
+renderer::ShapeLayer::ShapeLayer(model::Layer *layerData,
+                                 VArenaAlloc * allocator)
+    : renderer::Layer(layerData),
+      mRoot(allocator->make<renderer::Group>(nullptr, allocator))
 {
     mRoot->addChildren(layerData, allocator);
 
-    std::vector<LOTPathDataItem *> list;
+    std::vector<renderer::Shape *> list;
     mRoot->processPaintItems(list);
 
     if (layerData->hasPathOperator()) {
@@ -798,7 +804,7 @@ LOTShapeLayerItem::LOTShapeLayerItem(LOTLayerData *layerData, VArenaAlloc* alloc
     }
 }
 
-void LOTShapeLayerItem::updateContent()
+void renderer::ShapeLayer::updateContent()
 {
     mRoot->update(frameNo(), combinedMatrix(), combinedAlpha(), flag());
 
@@ -807,16 +813,15 @@ void LOTShapeLayerItem::updateContent()
     }
 }
 
-void LOTShapeLayerItem::preprocessStage(const VRect& clip)
+void renderer::ShapeLayer::preprocessStage(const VRect &clip)
 {
     mDrawableList.clear();
     mRoot->renderList(mDrawableList);
 
     for (auto &drawable : mDrawableList) drawable->preprocess(clip);
-
 }
 
-DrawableList LOTShapeLayerItem::renderList()
+renderer::DrawableList renderer::ShapeLayer::renderList()
 {
     if (skipRendering()) return {};
 
@@ -825,24 +830,24 @@ DrawableList LOTShapeLayerItem::renderList()
 
     if (mDrawableList.empty()) return {};
 
-    return {mDrawableList.data() , mDrawableList.size()};
+    return {mDrawableList.data(), mDrawableList.size()};
 }
 
-bool LOTContentGroupItem::resolveKeyPath(LOTKeyPath &keyPath, uint depth,
-                                         LOTVariant &value)
+bool renderer::Group::resolveKeyPath(LOTKeyPath &keyPath, uint depth,
+                                     LOTVariant &value)
 {
-   if (!keyPath.skip(name())) {
+    if (!keyPath.skip(name())) {
         if (!keyPath.matches(mModel.name(), depth)) {
-             return false;
+            return false;
         }
 
         if (!keyPath.skip(mModel.name())) {
-             if (keyPath.fullyResolvesTo(mModel.name(), depth) &&
-                 transformProp(value.property())) {
-                  mModel.filter().addValue(value);
-             }
+            if (keyPath.fullyResolvesTo(mModel.name(), depth) &&
+                transformProp(value.property())) {
+                mModel.filter().addValue(value);
+            }
         }
-   }
+    }
 
     if (keyPath.propagate(name(), depth)) {
         uint newDepth = keyPath.nextDepth(name(), depth);
@@ -853,8 +858,8 @@ bool LOTContentGroupItem::resolveKeyPath(LOTKeyPath &keyPath, uint depth,
     return true;
 }
 
-bool LOTFillItem::resolveKeyPath(LOTKeyPath &keyPath, uint depth,
-                                 LOTVariant &value)
+bool renderer::Fill::resolveKeyPath(LOTKeyPath &keyPath, uint depth,
+                                    LOTVariant &value)
 {
     if (!keyPath.matches(mModel.name(), depth)) {
         return false;
@@ -868,8 +873,8 @@ bool LOTFillItem::resolveKeyPath(LOTKeyPath &keyPath, uint depth,
     return false;
 }
 
-bool LOTStrokeItem::resolveKeyPath(LOTKeyPath &keyPath, uint depth,
-                                   LOTVariant &value)
+bool renderer::Stroke::resolveKeyPath(LOTKeyPath &keyPath, uint depth,
+                                      LOTVariant &value)
 {
     if (!keyPath.matches(mModel.name(), depth)) {
         return false;
@@ -883,13 +888,13 @@ bool LOTStrokeItem::resolveKeyPath(LOTKeyPath &keyPath, uint depth,
     return false;
 }
 
-LOTContentGroupItem::LOTContentGroupItem(LOTGroupData *data, VArenaAlloc* allocator)
+renderer::Group::Group(model::Group *data, VArenaAlloc *allocator)
     : mModel(data)
 {
     addChildren(data, allocator);
 }
 
-void LOTContentGroupItem::addChildren(LOTGroupData *data, VArenaAlloc* allocator)
+void renderer::Group::addChildren(model::Group *data, VArenaAlloc *allocator)
 {
     if (!data) return;
 
@@ -898,7 +903,7 @@ void LOTContentGroupItem::addChildren(LOTGroupData *data, VArenaAlloc* allocator
     // keep the content in back-to-front order.
     // as lottie model keeps it in front-to-back order.
     for (auto it = data->mChildren.crbegin(); it != data->mChildren.rend();
-         ++it ) {
+         ++it) {
         auto content = createContentItem(*it, allocator);
         if (content) {
             mContents.push_back(content);
@@ -906,11 +911,11 @@ void LOTContentGroupItem::addChildren(LOTGroupData *data, VArenaAlloc* allocator
     }
 }
 
-void LOTContentGroupItem::update(int frameNo, const VMatrix &parentMatrix,
-                                 float parentAlpha, const DirtyFlag &flag)
+void renderer::Group::update(int frameNo, const VMatrix &parentMatrix,
+                             float parentAlpha, const DirtyFlag &flag)
 {
     DirtyFlag newFlag = flag;
-    float alpha;
+    float     alpha;
 
     if (mModel.hasModel() && mModel.transform()) {
         VMatrix m = mModel.matrix(frameNo);
@@ -937,17 +942,17 @@ void LOTContentGroupItem::update(int frameNo, const VMatrix &parentMatrix,
     }
 }
 
-void LOTContentGroupItem::applyTrim()
+void renderer::Group::applyTrim()
 {
     for (auto i = mContents.rbegin(); i != mContents.rend(); ++i) {
         auto content = (*i);
         switch (content->type()) {
-        case ContentType::Trim: {
-            static_cast<LOTTrimItem *>(content)->update();
+        case renderer::Object::Type::Trim: {
+            static_cast<renderer::Trim *>(content)->update();
             break;
         }
-        case ContentType::Group: {
-            static_cast<LOTContentGroupItem *>(content)->applyTrim();
+        case renderer::Object::Type::Group: {
+            static_cast<renderer::Group *>(content)->applyTrim();
             break;
         }
         default:
@@ -956,34 +961,32 @@ void LOTContentGroupItem::applyTrim()
     }
 }
 
-void LOTContentGroupItem::renderList(std::vector<VDrawable *> &list)
+void renderer::Group::renderList(std::vector<VDrawable *> &list)
 {
     for (const auto &content : mContents) {
         content->renderList(list);
     }
 }
 
-void LOTContentGroupItem::processPaintItems(
-    std::vector<LOTPathDataItem *> &list)
+void renderer::Group::processPaintItems(std::vector<renderer::Shape *> &list)
 {
     size_t curOpCount = list.size();
     for (auto i = mContents.rbegin(); i != mContents.rend(); ++i) {
         auto content = (*i);
         switch (content->type()) {
-        case ContentType::Path: {
-            auto pathItem = static_cast<LOTPathDataItem *>(content);
+        case renderer::Object::Type::Shape: {
+            auto pathItem = static_cast<renderer::Shape *>(content);
             pathItem->setParent(this);
             list.push_back(pathItem);
             break;
         }
-        case ContentType::Paint: {
-            static_cast<LOTPaintDataItem *>(content)->addPathItems(list,
-                                                                   curOpCount);
+        case renderer::Object::Type::Paint: {
+            static_cast<renderer::Paint *>(content)->addPathItems(list,
+                                                                  curOpCount);
             break;
         }
-        case ContentType::Group: {
-            static_cast<LOTContentGroupItem *>(content)->processPaintItems(
-                list);
+        case renderer::Object::Type::Group: {
+            static_cast<renderer::Group *>(content)->processPaintItems(list);
             break;
         }
         default:
@@ -992,23 +995,24 @@ void LOTContentGroupItem::processPaintItems(
     }
 }
 
-void LOTContentGroupItem::processTrimItems(std::vector<LOTPathDataItem *> &list)
+void renderer::Group::processTrimItems(std::vector<renderer::Shape *> &list)
 {
     size_t curOpCount = list.size();
     for (auto i = mContents.rbegin(); i != mContents.rend(); ++i) {
         auto content = (*i);
 
         switch (content->type()) {
-        case ContentType::Path: {
-            list.push_back(static_cast<LOTPathDataItem *>(content));
+        case renderer::Object::Type::Shape: {
+            list.push_back(static_cast<renderer::Shape *>(content));
             break;
         }
-        case ContentType::Trim: {
-            static_cast<LOTTrimItem *>(content)->addPathItems(list, curOpCount);
+        case renderer::Object::Type::Trim: {
+            static_cast<renderer::Trim *>(content)->addPathItems(list,
+                                                                 curOpCount);
             break;
         }
-        case ContentType::Group: {
-            static_cast<LOTContentGroupItem *>(content)->processTrimItems(list);
+        case renderer::Object::Type::Group: {
+            static_cast<renderer::Group *>(content)->processTrimItems(list);
             break;
         }
         default:
@@ -1018,7 +1022,7 @@ void LOTContentGroupItem::processTrimItems(std::vector<LOTPathDataItem *> &list)
 }
 
 /*
- * LOTPathDataItem uses 2 path objects for path object reuse.
+ * renderer::Shape uses 2 path objects for path object reuse.
  * mLocalPath -  keeps track of the local path of the item before
  * applying path operation and transformation.
  * mTemp - keeps a referece to the mLocalPath and can be updated by the
@@ -1034,7 +1038,7 @@ void LOTContentGroupItem::processTrimItems(std::vector<LOTPathDataItem *> &list)
  * carefull about the refcount so that we don't generate deep copy while
  * modifying the path objects.
  */
-void LOTPathDataItem::update(int              frameNo, const VMatrix &, float,
+void renderer::Shape::update(int              frameNo, const VMatrix &, float,
                              const DirtyFlag &flag)
 {
     mDirtyPath = false;
@@ -1059,17 +1063,17 @@ void LOTPathDataItem::update(int              frameNo, const VMatrix &, float,
     }
 }
 
-void LOTPathDataItem::finalPath(VPath& result)
+void renderer::Shape::finalPath(VPath &result)
 {
-    result.addPath(mTemp, static_cast<LOTContentGroupItem *>(parent())->matrix());
+    result.addPath(mTemp, static_cast<renderer::Group *>(parent())->matrix());
 }
 
-LOTRectItem::LOTRectItem(LOTRectData *data)
-    : LOTPathDataItem(data->isStatic()), mData(data)
+renderer::Rect::Rect(model::Rect *data)
+    : renderer::Shape(data->isStatic()), mData(data)
 {
 }
 
-void LOTRectItem::updatePath(VPath &path, int frameNo)
+void renderer::Rect::updatePath(VPath &path, int frameNo)
 {
     VPointF pos = mData->mPos.value(frameNo);
     VPointF size = mData->mSize.value(frameNo);
@@ -1081,12 +1085,12 @@ void LOTRectItem::updatePath(VPath &path, int frameNo)
     path.addRoundRect(r, roundness, mData->direction());
 }
 
-LOTEllipseItem::LOTEllipseItem(LOTEllipseData *data)
-    : LOTPathDataItem(data->isStatic()), mData(data)
+renderer::Ellipse::Ellipse(model::Ellipse *data)
+    : renderer::Shape(data->isStatic()), mData(data)
 {
 }
 
-void LOTEllipseItem::updatePath(VPath &path, int frameNo)
+void renderer::Ellipse::updatePath(VPath &path, int frameNo)
 {
     VPointF pos = mData->mPos.value(frameNo);
     VPointF size = mData->mSize.value(frameNo);
@@ -1097,22 +1101,22 @@ void LOTEllipseItem::updatePath(VPath &path, int frameNo)
     path.addOval(r, mData->direction());
 }
 
-LOTShapeItem::LOTShapeItem(LOTShapeData *data)
-    : LOTPathDataItem(data->isStatic()), mData(data)
+renderer::Path::Path(model::Path *data)
+    : renderer::Shape(data->isStatic()), mData(data)
 {
 }
 
-void LOTShapeItem::updatePath(VPath &path, int frameNo)
+void renderer::Path::updatePath(VPath &path, int frameNo)
 {
     mData->mShape.value(frameNo, path);
 }
 
-LOTPolystarItem::LOTPolystarItem(LOTPolystarData *data)
-    : LOTPathDataItem(data->isStatic()), mData(data)
+renderer::Polystar::Polystar(model::Polystar *data)
+    : renderer::Shape(data->isStatic()), mData(data)
 {
 }
 
-void LOTPolystarItem::updatePath(VPath &path, int frameNo)
+void renderer::Polystar::updatePath(VPath &path, int frameNo)
 {
     VPointF pos = mData->mPos.value(frameNo);
     float   points = mData->mPointCount.value(frameNo);
@@ -1125,7 +1129,7 @@ void LOTPolystarItem::updatePath(VPath &path, int frameNo)
     path.reset();
     VMatrix m;
 
-    if (mData->mPolyType == LOTPolystarData::PolyType::Star) {
+    if (mData->mPolyType == model::Polystar::PolyType::Star) {
         path.addPolystar(points, innerRadius, outerRadius, innerRoundness,
                          outerRoundness, 0.0, 0.0, 0.0, mData->direction());
     } else {
@@ -1142,19 +1146,16 @@ void LOTPolystarItem::updatePath(VPath &path, int frameNo)
  * PaintData Node handling
  *
  */
-LOTPaintDataItem::LOTPaintDataItem(bool staticContent)
-    : mStaticContent(staticContent)
-{
-}
+renderer::Paint::Paint(bool staticContent) : mStaticContent(staticContent) {}
 
-void LOTPaintDataItem::update(int   frameNo, const VMatrix & parentMatrix,
-                              float parentAlpha, const DirtyFlag &/*flag*/)
+void renderer::Paint::update(int frameNo, const VMatrix &parentMatrix,
+                             float parentAlpha, const DirtyFlag & /*flag*/)
 {
     mRenderNodeUpdate = true;
     mContentToRender = updateContent(frameNo, parentMatrix, parentAlpha);
 }
 
-void LOTPaintDataItem::updateRenderNode()
+void renderer::Paint::updateRenderNode()
 {
     bool dirty = false;
     for (auto &i : mPathItems) {
@@ -1176,7 +1177,7 @@ void LOTPaintDataItem::updateRenderNode()
     }
 }
 
-void LOTPaintDataItem::renderList(std::vector<VDrawable *> &list)
+void renderer::Paint::renderList(std::vector<VDrawable *> &list)
 {
     if (mRenderNodeUpdate) {
         updateRenderNode();
@@ -1194,20 +1195,20 @@ void LOTPaintDataItem::renderList(std::vector<VDrawable *> &list)
     if (mContentToRender) list.push_back(&mDrawable);
 }
 
-void LOTPaintDataItem::addPathItems(std::vector<LOTPathDataItem *> &list,
-                                    size_t                          startOffset)
+void renderer::Paint::addPathItems(std::vector<renderer::Shape *> &list,
+                                   size_t                          startOffset)
 {
     std::copy(list.begin() + startOffset, list.end(),
               back_inserter(mPathItems));
 }
 
-LOTFillItem::LOTFillItem(LOTFillData *data)
-    : LOTPaintDataItem(data->isStatic()), mModel(data)
+renderer::Fill::Fill(model::Fill *data)
+    : renderer::Paint(data->isStatic()), mModel(data)
 {
     mDrawable.setName(mModel.name());
 }
 
-bool LOTFillItem::updateContent(int frameNo, const VMatrix &, float alpha)
+bool renderer::Fill::updateContent(int frameNo, const VMatrix &, float alpha)
 {
     auto combinedAlpha = alpha * mModel.opacity(frameNo);
     auto color = mModel.color(frameNo).toColor(combinedAlpha);
@@ -1219,13 +1220,14 @@ bool LOTFillItem::updateContent(int frameNo, const VMatrix &, float alpha)
     return !color.isTransparent();
 }
 
-LOTGFillItem::LOTGFillItem(LOTGFillData *data)
-    : LOTPaintDataItem(data->isStatic()), mData(data)
+renderer::GradientFill::GradientFill(model::GradientFill *data)
+    : renderer::Paint(data->isStatic()), mData(data)
 {
     mDrawable.setName(mData->name());
 }
 
-bool LOTGFillItem::updateContent(int frameNo, const VMatrix &matrix, float alpha)
+bool renderer::GradientFill::updateContent(int frameNo, const VMatrix &matrix,
+                                           float alpha)
 {
     float combinedAlpha = alpha * mData->opacity(frameNo);
 
@@ -1238,8 +1240,8 @@ bool LOTGFillItem::updateContent(int frameNo, const VMatrix &matrix, float alpha
     return !vIsZero(combinedAlpha);
 }
 
-LOTStrokeItem::LOTStrokeItem(LOTStrokeData *data)
-    : LOTPaintDataItem(data->isStatic()), mModel(data)
+renderer::Stroke::Stroke(model::Stroke *data)
+    : renderer::Paint(data->isStatic()), mModel(data)
 {
     mDrawable.setName(mModel.name());
     if (mModel.hasDashInfo()) {
@@ -1251,7 +1253,8 @@ LOTStrokeItem::LOTStrokeItem(LOTStrokeData *data)
 
 static thread_local std::vector<float> Dash_Vector;
 
-bool LOTStrokeItem::updateContent(int frameNo, const VMatrix &matrix, float alpha)
+bool renderer::Stroke::updateContent(int frameNo, const VMatrix &matrix,
+                                     float alpha)
 {
     auto combinedAlpha = alpha * mModel.opacity(frameNo);
     auto color = mModel.color(frameNo).toColor(combinedAlpha);
@@ -1260,7 +1263,8 @@ bool LOTStrokeItem::updateContent(int frameNo, const VMatrix &matrix, float alph
     mDrawable.setBrush(brush);
     float scale = matrix.scale();
     mDrawable.setStrokeInfo(mModel.capStyle(), mModel.joinStyle(),
-                            mModel.miterLimit(), mModel.strokeWidth(frameNo) * scale);
+                            mModel.miterLimit(),
+                            mModel.strokeWidth(frameNo) * scale);
 
     if (mModel.hasDashInfo()) {
         Dash_Vector.clear();
@@ -1274,8 +1278,8 @@ bool LOTStrokeItem::updateContent(int frameNo, const VMatrix &matrix, float alph
     return !color.isTransparent();
 }
 
-LOTGStrokeItem::LOTGStrokeItem(LOTGStrokeData *data)
-    : LOTPaintDataItem(data->isStatic()), mData(data)
+renderer::GradientStroke::GradientStroke(model::GradientStroke *data)
+    : renderer::Paint(data->isStatic()), mData(data)
 {
     mDrawable.setName(mData->name());
     if (mData->hasDashInfo()) {
@@ -1285,7 +1289,8 @@ LOTGStrokeItem::LOTGStrokeItem(LOTGStrokeData *data)
     }
 }
 
-bool LOTGStrokeItem::updateContent(int frameNo, const VMatrix &matrix, float alpha)
+bool renderer::GradientStroke::updateContent(int frameNo, const VMatrix &matrix,
+                                             float alpha)
 {
     float combinedAlpha = alpha * mData->opacity(frameNo);
 
@@ -1294,7 +1299,7 @@ bool LOTGStrokeItem::updateContent(int frameNo, const VMatrix &matrix, float alp
     mGradient->mMatrix = matrix;
     auto scale = mGradient->mMatrix.scale();
     mDrawable.setBrush(VBrush(mGradient.get()));
-    mDrawable.setStrokeInfo(mData->capStyle(),  mData->joinStyle(),
+    mDrawable.setStrokeInfo(mData->capStyle(), mData->joinStyle(),
                             mData->miterLimit(), mData->width(frameNo) * scale);
 
     if (mData->hasDashInfo()) {
@@ -1309,19 +1314,14 @@ bool LOTGStrokeItem::updateContent(int frameNo, const VMatrix &matrix, float alp
     return !vIsZero(combinedAlpha);
 }
 
-LOTTrimItem::LOTTrimItem(LOTTrimData *data)
-    : mData(data)
-{
-}
-
-void LOTTrimItem::update(int frameNo, const VMatrix & /*parentMatrix*/,
-                         float /*parentAlpha*/, const DirtyFlag & /*flag*/)
+void renderer::Trim::update(int frameNo, const VMatrix & /*parentMatrix*/,
+                            float /*parentAlpha*/, const DirtyFlag & /*flag*/)
 {
     mDirty = false;
 
     if (mCache.mFrameNo == frameNo) return;
 
-    LOTTrimData::Segment segment = mData->segment(frameNo);
+    model::Trim::Segment segment = mData->segment(frameNo);
 
     if (!(vCompare(mCache.mSegment.start, segment.start) &&
           vCompare(mCache.mSegment.end, segment.end))) {
@@ -1331,7 +1331,7 @@ void LOTTrimItem::update(int frameNo, const VMatrix & /*parentMatrix*/,
     mCache.mFrameNo = frameNo;
 }
 
-void LOTTrimItem::update()
+void renderer::Trim::update()
 {
     // when both path and trim are not dirty
     if (!(mDirty || pathDirty())) return;
@@ -1350,12 +1350,12 @@ void LOTTrimItem::update()
         return;
     }
 
-    if (mData->type() == LOTTrimData::TrimType::Simultaneously) {
+    if (mData->type() == model::Trim::TrimType::Simultaneously) {
         for (auto &i : mPathItems) {
             mPathMesure.setRange(mCache.mSegment.start, mCache.mSegment.end);
             i->updatePath(mPathMesure.trim(i->localPath()));
         }
-    } else {  // LOTTrimData::TrimType::Individually
+    } else {  // model::Trim::TrimType::Individually
         float totalLength = 0.0;
         for (auto &i : mPathItems) {
             totalLength += i->localPath().length();
@@ -1396,29 +1396,30 @@ void LOTTrimItem::update()
     }
 }
 
-void LOTTrimItem::addPathItems(std::vector<LOTPathDataItem *> &list,
-                               size_t                          startOffset)
+void renderer::Trim::addPathItems(std::vector<renderer::Shape *> &list,
+                                  size_t                          startOffset)
 {
     std::copy(list.begin() + startOffset, list.end(),
               back_inserter(mPathItems));
 }
 
-LOTRepeaterItem::LOTRepeaterItem(LOTRepeaterData *data, VArenaAlloc* allocator) : mRepeaterData(data)
+renderer::Repeater::Repeater(model::Repeater *data, VArenaAlloc *allocator)
+    : mRepeaterData(data)
 {
     assert(mRepeaterData->content());
 
     mCopies = mRepeaterData->maxCopies();
 
     for (int i = 0; i < mCopies; i++) {
-        auto content =
-            allocator->make<LOTContentGroupItem>(mRepeaterData->content(), allocator);
-        //content->setParent(this);
+        auto content = allocator->make<renderer::Group>(
+            mRepeaterData->content(), allocator);
+        // content->setParent(this);
         mContents.push_back(content);
     }
 }
 
-void LOTRepeaterItem::update(int frameNo, const VMatrix &parentMatrix,
-                             float parentAlpha, const DirtyFlag &flag)
+void renderer::Repeater::update(int frameNo, const VMatrix &parentMatrix,
+                                float parentAlpha, const DirtyFlag &flag)
 {
     DirtyFlag newFlag = flag;
 
@@ -1453,8 +1454,8 @@ void LOTRepeaterItem::update(int frameNo, const VMatrix &parentMatrix,
     }
 }
 
-void LOTRepeaterItem::renderList(std::vector<VDrawable *> &list)
+void renderer::Repeater::renderList(std::vector<VDrawable *> &list)
 {
     if (mHidden) return;
-    return LOTContentGroupItem::renderList(list);
+    return renderer::Group::renderList(list);
 }
index 09bc5d5..03ca77d 100644 (file)
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
  */
 
 #ifndef LOTTIEITEM_H
 #define LOTTIEITEM_H
 
-#include<sstream>
-#include<memory>
-
-#include"lottieproxymodel.h"
-#include"vmatrix.h"
-#include"vpath.h"
-#include"vpoint.h"
-#include"vpathmesure.h"
-#include"rlottiecommon.h"
-#include"rlottie.h"
-#include"vpainter.h"
-#include"vdrawable.h"
-#include"lottiekeypath.h"
-#include"varenaalloc.h"
+#include <memory>
+#include <sstream>
+
+#include "lottiekeypath.h"
+#include "lottieproxymodel.h"
+#include "rlottie.h"
+#include "rlottiecommon.h"
+#include "varenaalloc.h"
+#include "vdrawable.h"
+#include "vmatrix.h"
+#include "vpainter.h"
+#include "vpath.h"
+#include "vpathmesure.h"
+#include "vpoint.h"
 
 V_USE_NAMESPACE
 
-enum class DirtyFlagBit : uchar
-{
-   None   = 0x00,
-   Matrix = 0x01,
-   Alpha  = 0x02,
-   All    = (Matrix | Alpha)
-};
+namespace rlottie {
 
-class LOTLayerItem;
-class LOTMaskItem;
-class VDrawable;
+namespace internal {
 
-class LOTDrawable : public VDrawable
-{
-public:
-    void sync();
+template <class T>
+class VSpan {
 public:
-    std::unique_ptr<LOTNode>  mCNode{nullptr};
+    using reference = T &;
+    using pointer = T *;
+    using const_pointer = T const *;
+    using const_reference = T const &;
+    using index_type = size_t;
 
-    ~LOTDrawable() {
-        if (mCNode && mCNode->mGradient.stopPtr)
-          free(mCNode->mGradient.stopPtr);
+    using iterator = pointer;
+    using const_iterator = const_pointer;
+
+    VSpan() = default;
+    VSpan(pointer data, index_type size) : _data(data), _size(size) {}
+
+    constexpr pointer        data() const noexcept { return _data; }
+    constexpr index_type     size() const noexcept { return _size; }
+    constexpr bool           empty() const noexcept { return size() == 0; }
+    constexpr iterator       begin() const noexcept { return data(); }
+    constexpr iterator       end() const noexcept { return data() + size(); }
+    constexpr const_iterator cbegin() const noexcept { return data(); }
+    constexpr const_iterator cend() const noexcept { return data() + size(); }
+    constexpr reference      operator[](index_type idx) const
+    {
+        return *(data() + idx);
     }
+
+private:
+    pointer    _data{nullptr};
+    index_type _size{0};
+};
+
+namespace renderer {
+
+using DrawableList = VSpan<VDrawable *>;
+
+enum class DirtyFlagBit : uchar {
+    None = 0x00,
+    Matrix = 0x01,
+    Alpha = 0x02,
+    All = (Matrix | Alpha)
 };
+typedef vFlag<DirtyFlagBit> DirtyFlag;
 
-class SurfaceCache
-{
-public:  
-  SurfaceCache(){mCache.reserve(10);}
+class SurfaceCache {
+public:
+    SurfaceCache() { mCache.reserve(10); }
 
-  VBitmap make_surface(size_t width, size_t height, VBitmap::Format format=VBitmap::Format::ARGB32_Premultiplied)
-  {
-    if (mCache.empty()) return {width, height, format};
+    VBitmap make_surface(
+        size_t width, size_t height,
+        VBitmap::Format format = VBitmap::Format::ARGB32_Premultiplied)
+    {
+        if (mCache.empty()) return {width, height, format};
 
-    auto surface = mCache.back();
-    surface.reset(width, height, format);
+        auto surface = mCache.back();
+        surface.reset(width, height, format);
 
-    mCache.pop_back();
-    return surface;
-  }
+        mCache.pop_back();
+        return surface;
+    }
 
-  void release_surface(VBitmap& surface)
-  {
-     mCache.push_back(surface);
-  }
+    void release_surface(VBitmap &surface) { mCache.push_back(surface); }
 
 private:
-  std::vector<VBitmap> mCache;
+    std::vector<VBitmap> mCache;
 };
 
-class LOTCompItem
-{
+class Drawable : public VDrawable {
 public:
-   explicit LOTCompItem(LOTModel *model);
-   bool update(int frameNo, const VSize &size, bool keepAspectRatio);
-   VSize size() const { return mViewSize;}
-   void buildRenderTree();
-   const LOTLayerNode * renderTree()const;
-   bool render(const rlottie::Surface &surface);
-   void setValue(const std::string &keypath, LOTVariant &value);
-private:
-   SurfaceCache                                mSurfaceCache;
-   VBitmap                                     mSurface;
-   VMatrix                                     mScaleMatrix;
-   VSize                                       mViewSize;
-   LOTCompositionData                         *mCompData{nullptr};
-   LOTLayerItem                               *mRootLayer{nullptr};
-   VArenaAlloc                                 mAllocator{2048};
-   int                                         mCurFrameNo;
-   bool                                        mKeepAspectRatio{true};
+    void sync();
+
+public:
+    std::unique_ptr<LOTNode> mCNode{nullptr};
+
+    ~Drawable()
+    {
+        if (mCNode && mCNode->mGradient.stopPtr)
+            free(mCNode->mGradient.stopPtr);
+    }
 };
 
-class LOTLayerMaskItem;
+struct CApiData {
+    CApiData();
+    LOTLayerNode                mLayer;
+    std::vector<LOTMask>        mMasks;
+    std::vector<LOTLayerNode *> mLayers;
+    std::vector<LOTNode *>      mCNodeList;
+};
 
-class LOTClipperItem
-{
+class Clipper {
 public:
-    explicit LOTClipperItem(VSize size): mSize(size){}
+    explicit Clipper(VSize size) : mSize(size) {}
     void update(const VMatrix &matrix);
     void preprocess(const VRect &clip);
-    VRle rle(const VRle& mask);
+    VRle rle(const VRle &mask);
+
 public:
-    VSize                    mSize;
-    VPath                    mPath;
-    VRle                     mMaskedRle;
-    VRasterizer              mRasterizer;
-    bool                     mRasterRequest{false};
+    VSize       mSize;
+    VPath       mPath;
+    VRle        mMaskedRle;
+    VRasterizer mRasterizer;
+    bool        mRasterRequest{false};
 };
 
-typedef vFlag<DirtyFlagBit> DirtyFlag;
+class Mask {
+public:
+    explicit Mask(model::Mask *data) : mData(data) {}
+    void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha,
+                const DirtyFlag &flag);
+    model::Mask::Mode maskMode() const { return mData->mMode; }
+    VRle              rle();
+    void              preprocess(const VRect &clip);
 
-struct LOTCApiData
-{
-    LOTCApiData();
-    LOTLayerNode                  mLayer;
-    std::vector<LOTMask>          mMasks;
-    std::vector<LOTLayerNode *>   mLayers;
-    std::vector<LOTNode *>        mCNodeList;
+public:
+    model::Mask *mData{nullptr};
+    VPath        mLocalPath;
+    VPath        mFinalPath;
+    VRasterizer  mRasterizer;
+    float        mCombinedAlpha{0};
+    bool         mRasterRequest{false};
 };
 
-template< class T>
-class VSpan
-{
+/*
+ * Handels mask property of a layer item
+ */
+class LayerMask {
 public:
-    using reference         = T &;
-    using pointer           = T *;
-    using const_pointer     = T const *;
-    using const_reference   = T const &;
-    using index_type        = size_t;
+    explicit LayerMask(model::Layer *layerData);
+    void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha,
+                const DirtyFlag &flag);
+    bool isStatic() const { return mStatic; }
+    VRle maskRle(const VRect &clipRect);
+    void preprocess(const VRect &clip);
 
-    using iterator          = pointer;
-    using const_iterator    = const_pointer;
+public:
+    std::vector<Mask> mMasks;
+    VRle              mRle;
+    bool              mStatic{true};
+    bool              mDirty{true};
+};
 
-    VSpan() = default;
-    VSpan(pointer data, index_type size):_data(data), _size(size){}
+class Layer;
 
-    constexpr pointer data() const noexcept {return _data; }
-    constexpr index_type size() const noexcept {return _size; }
-    constexpr bool empty() const noexcept { return size() == 0 ;}
-    constexpr iterator begin() const noexcept { return data(); }
-    constexpr iterator end() const noexcept {return data() + size() ;}
-    constexpr const_iterator cbegin() const noexcept {return  data();}
-    constexpr const_iterator cend() const noexcept { return data() + size();}
-    constexpr reference operator[]( index_type idx ) const { return *( data() + idx );}
+class Composition {
+public:
+    explicit Composition(std::shared_ptr<model::Composition> composition);
+    bool  update(int frameNo, const VSize &size, bool keepAspectRatio);
+    VSize size() const { return mViewSize; }
+    void  buildRenderTree();
+    const LOTLayerNode *renderTree() const;
+    bool                render(const rlottie::Surface &surface);
+    void                setValue(const std::string &keypath, LOTVariant &value);
 
 private:
-    pointer      _data{nullptr};
-    index_type   _size{0};
+    SurfaceCache                        mSurfaceCache;
+    VBitmap                             mSurface;
+    VMatrix                             mScaleMatrix;
+    VSize                               mViewSize;
+    std::shared_ptr<model::Composition> mModel;
+    Layer *                             mRootLayer{nullptr};
+    VArenaAlloc                         mAllocator{2048};
+    int                                 mCurFrameNo;
+    bool                                mKeepAspectRatio{true};
 };
 
-using DrawableList = VSpan<VDrawable *>;
-
-class LOTLayerItem
-{
+class Layer {
 public:
-   virtual ~LOTLayerItem() = default;
-   LOTLayerItem& operator=(LOTLayerItem&&) noexcept = delete;
-   LOTLayerItem(LOTLayerData *layerData);
-   int id() const {return mLayerData->id();}
-   int parentId() const {return mLayerData->parentId();}
-   void setParentLayer(LOTLayerItem *parent){mParentLayer = parent;}
-   void setComplexContent(bool value) { mComplexContent = value;}
-   bool complexContent() const {return mComplexContent;}
-   virtual void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha);
-   VMatrix matrix(int frameNo) const;
-   void preprocess(const VRect& clip);
-   virtual DrawableList renderList(){ return {};}
-   virtual void render(VPainter *painter, const VRle &mask, const VRle &matteRle, SurfaceCache& cache);
-   bool hasMatte() { if (mLayerData->mMatteType == MatteType::None) return false; return true; }
-   MatteType matteType() const { return mLayerData->mMatteType;}
-   bool visible() const;
-   virtual void buildLayerNode();
-   LOTLayerNode& clayer() {return mCApiData->mLayer;}
-   std::vector<LOTLayerNode *>& clayers() {return mCApiData->mLayers;}
-   std::vector<LOTMask>& cmasks() {return mCApiData->mMasks;}
-   std::vector<LOTNode *>& cnodes() {return mCApiData->mCNodeList;}
-   const char* name() const {return mLayerData->name();}
-   virtual bool resolveKeyPath(LOTKeyPath &keyPath, uint depth, LOTVariant &value);
+    virtual ~Layer() = default;
+    Layer &operator=(Layer &&) noexcept = delete;
+    Layer(model::Layer *layerData);
+    int          id() const { return mLayerData->id(); }
+    int          parentId() const { return mLayerData->parentId(); }
+    void         setParentLayer(Layer *parent) { mParentLayer = parent; }
+    void         setComplexContent(bool value) { mComplexContent = value; }
+    bool         complexContent() const { return mComplexContent; }
+    virtual void update(int frameNo, const VMatrix &parentMatrix,
+                        float parentAlpha);
+    VMatrix      matrix(int frameNo) const;
+    void         preprocess(const VRect &clip);
+    virtual DrawableList renderList() { return {}; }
+    virtual void         render(VPainter *painter, const VRle &mask,
+                                const VRle &matteRle, SurfaceCache &cache);
+    bool                 hasMatte()
+    {
+        if (mLayerData->mMatteType == model::MatteType::None) return false;
+        return true;
+    }
+    model::MatteType matteType() const { return mLayerData->mMatteType; }
+    bool             visible() const;
+    virtual void     buildLayerNode();
+    LOTLayerNode &   clayer() { return mCApiData->mLayer; }
+    std::vector<LOTLayerNode *> &clayers() { return mCApiData->mLayers; }
+    std::vector<LOTMask> &       cmasks() { return mCApiData->mMasks; }
+    std::vector<LOTNode *> &     cnodes() { return mCApiData->mCNodeList; }
+    const char *                 name() const { return mLayerData->name(); }
+    virtual bool                 resolveKeyPath(LOTKeyPath &keyPath, uint depth,
+                                                LOTVariant &value);
+
 protected:
-   virtual void preprocessStage(const VRect& clip) = 0;
-   virtual void updateContent() = 0;
-   inline VMatrix combinedMatrix() const {return mCombinedMatrix;}
-   inline int frameNo() const {return mFrameNo;}
-   inline float combinedAlpha() const {return mCombinedAlpha;}
-   inline bool isStatic() const {return mLayerData->isStatic();}
-   float opacity(int frameNo) const {return mLayerData->opacity(frameNo);}
-   inline DirtyFlag flag() const {return mDirtyFlag;}
-   bool skipRendering() const {return (!visible() || vIsZero(combinedAlpha()));}
+    virtual void   preprocessStage(const VRect &clip) = 0;
+    virtual void   updateContent() = 0;
+    inline VMatrix combinedMatrix() const { return mCombinedMatrix; }
+    inline int     frameNo() const { return mFrameNo; }
+    inline float   combinedAlpha() const { return mCombinedAlpha; }
+    inline bool    isStatic() const { return mLayerData->isStatic(); }
+    float opacity(int frameNo) const { return mLayerData->opacity(frameNo); }
+    inline DirtyFlag flag() const { return mDirtyFlag; }
+    bool             skipRendering() const
+    {
+        return (!visible() || vIsZero(combinedAlpha()));
+    }
+
 protected:
-   std::unique_ptr<LOTLayerMaskItem>           mLayerMask;
-   LOTLayerData                               *mLayerData{nullptr};
-   LOTLayerItem                               *mParentLayer{nullptr};
-   VMatrix                                     mCombinedMatrix;
-   float                                       mCombinedAlpha{0.0};
-   int                                         mFrameNo{-1};
-   DirtyFlag                                   mDirtyFlag{DirtyFlagBit::All};
-   bool                                        mComplexContent{false};
-   std::unique_ptr<LOTCApiData>                mCApiData;
+    std::unique_ptr<LayerMask> mLayerMask;
+    model::Layer *             mLayerData{nullptr};
+    Layer *                    mParentLayer{nullptr};
+    VMatrix                    mCombinedMatrix;
+    float                      mCombinedAlpha{0.0};
+    int                        mFrameNo{-1};
+    DirtyFlag                  mDirtyFlag{DirtyFlagBit::All};
+    bool                       mComplexContent{false};
+    std::unique_ptr<CApiData>  mCApiData;
 };
 
-class LOTCompLayerItem: public LOTLayerItem
-{
+class CompLayer : public Layer {
 public:
-   explicit LOTCompLayerItem(LOTLayerData *layerData, VArenaAlloc* allocator);
+    explicit CompLayer(model::Layer *layerData, VArenaAlloc *allocator);
+
+    void render(VPainter *painter, const VRle &mask, const VRle &matteRle,
+                SurfaceCache &cache) final;
+    void buildLayerNode() final;
+    bool resolveKeyPath(LOTKeyPath &keyPath, uint depth,
+                        LOTVariant &value) override;
 
-   void render(VPainter *painter, const VRle &mask, const VRle &matteRle, SurfaceCache& cache) final;
-   void buildLayerNode() final;
-   bool resolveKeyPath(LOTKeyPath &keyPath, uint depth, LOTVariant &value) override;
 protected:
-   void preprocessStage(const VRect& clip) final;
-   void updateContent() final;
+    void preprocessStage(const VRect &clip) final;
+    void updateContent() final;
+
 private:
-    void renderHelper(VPainter *painter, const VRle &mask, const VRle &matteRle, SurfaceCache& cache);
-    void renderMatteLayer(VPainter *painter, const VRle &inheritMask, const VRle &matteRle,
-                          LOTLayerItem *layer, LOTLayerItem *src, SurfaceCache& cache);
+    void renderHelper(VPainter *painter, const VRle &mask, const VRle &matteRle,
+                      SurfaceCache &cache);
+    void renderMatteLayer(VPainter *painter, const VRle &inheritMask,
+                          const VRle &matteRle, Layer *layer, Layer *src,
+                          SurfaceCache &cache);
+
 private:
-   std::vector<LOTLayerItem*>            mLayers;
-   std::unique_ptr<LOTClipperItem>       mClipper;
+    std::vector<Layer *>     mLayers;
+    std::unique_ptr<Clipper> mClipper;
 };
 
-class LOTSolidLayerItem: public LOTLayerItem
-{
+class SolidLayer : public Layer {
 public:
-   explicit LOTSolidLayerItem(LOTLayerData *layerData);
-   void buildLayerNode() final;
-   DrawableList renderList() final;
+    explicit SolidLayer(model::Layer *layerData);
+    void         buildLayerNode() final;
+    DrawableList renderList() final;
+
 protected:
-   void preprocessStage(const VRect& clip) final;
-   void updateContent() final;
+    void preprocessStage(const VRect &clip) final;
+    void updateContent() final;
+
 private:
-   LOTDrawable                  mRenderNode;
-   VDrawable                   *mDrawableList{nullptr}; //to work with the Span api
+    Drawable   mRenderNode;
+    VDrawable *mDrawableList{nullptr};  // to work with the Span api
 };
 
-class LOTContentItem;
-class LOTContentGroupItem;
-class LOTShapeLayerItem: public LOTLayerItem
-{
-public:
-   explicit LOTShapeLayerItem(LOTLayerData *layerData, VArenaAlloc* allocator);
-   DrawableList renderList() final;
-   void buildLayerNode() final;
-   bool resolveKeyPath(LOTKeyPath &keyPath, uint depth, LOTVariant &value) override;
-protected:
-   void preprocessStage(const VRect& clip) final;
-   void updateContent() final;
-   std::vector<VDrawable *>             mDrawableList;
-   LOTContentGroupItem                 *mRoot{nullptr};
-};
+class Group;
 
-class LOTNullLayerItem: public LOTLayerItem
-{
+class ShapeLayer : public Layer {
 public:
-   explicit LOTNullLayerItem(LOTLayerData *layerData);
+    explicit ShapeLayer(model::Layer *layerData, VArenaAlloc *allocator);
+    DrawableList renderList() final;
+    void         buildLayerNode() final;
+    bool         resolveKeyPath(LOTKeyPath &keyPath, uint depth,
+                                LOTVariant &value) override;
+
 protected:
-   void preprocessStage(const VRect&) final {}
-   void updateContent() final;
+    void                     preprocessStage(const VRect &clip) final;
+    void                     updateContent() final;
+    std::vector<VDrawable *> mDrawableList;
+    Group *                  mRoot{nullptr};
 };
 
-class LOTImageLayerItem: public LOTLayerItem
-{
+class NullLayer : public Layer {
 public:
-   explicit LOTImageLayerItem(LOTLayerData *layerData);
-   void buildLayerNode() final;
-   DrawableList renderList() final;
+    explicit NullLayer(model::Layer *layerData);
+
 protected:
-   void preprocessStage(const VRect& clip) final;
-   void updateContent() final;
-private:
-   LOTDrawable                  mRenderNode;
-   VTexture                     mTexture;
-   VDrawable                   *mDrawableList{nullptr}; //to work with the Span api
+    void preprocessStage(const VRect &) final {}
+    void updateContent() final;
 };
 
-class LOTMaskItem
-{
+class ImageLayer : public Layer {
 public:
-    explicit LOTMaskItem(LOTMaskData *data): mData(data){}
-    void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha, const DirtyFlag &flag);
-    LOTMaskData::Mode maskMode() const { return mData->mMode;}
-    VRle rle();
-    void preprocess(const VRect &clip);
-public:
-    LOTMaskData             *mData{nullptr};
-    VPath                    mLocalPath;
-    VPath                    mFinalPath;
-    VRasterizer              mRasterizer;
-    float                    mCombinedAlpha{0};
-    bool                     mRasterRequest{false};
-};
+    explicit ImageLayer(model::Layer *layerData);
+    void         buildLayerNode() final;
+    DrawableList renderList() final;
 
-/*
- * Handels mask property of a layer item
- */
-class LOTLayerMaskItem
-{
-public:
-    explicit LOTLayerMaskItem(LOTLayerData *layerData);
-    void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha, const DirtyFlag &flag);
-    bool isStatic() const {return mStatic;}
-    VRle maskRle(const VRect &clipRect);
-    void preprocess(const VRect &clip);
-public:
-    std::vector<LOTMaskItem>   mMasks;
-    VRle                       mRle;
-    bool                       mStatic{true};
-    bool                       mDirty{true};
-};
+protected:
+    void preprocessStage(const VRect &clip) final;
+    void updateContent() final;
 
-class LOTPathDataItem;
-class LOTPaintDataItem;
-class LOTTrimItem;
-
-enum class ContentType : uchar
-{
-    Unknown,
-    Group,
-    Path,
-    Paint,
-    Trim
+private:
+    Drawable   mRenderNode;
+    VTexture   mTexture;
+    VDrawable *mDrawableList{nullptr};  // to work with the Span api
 };
 
-class LOTContentGroupItem;
-class LOTContentItem
-{
+class Object {
 public:
-   virtual ~LOTContentItem() = default;
-   LOTContentItem& operator=(LOTContentItem&&) noexcept = delete;
-   virtual void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha, const DirtyFlag &flag) = 0;   virtual void renderList(std::vector<VDrawable *> &){}
-   virtual bool resolveKeyPath(LOTKeyPath &, uint, LOTVariant &) {return false;}
-   virtual ContentType type() const {return ContentType::Unknown;}
+    enum class Type : uchar { Unknown, Group, Shape, Paint, Trim };
+    virtual ~Object() = default;
+    Object &     operator=(Object &&) noexcept = delete;
+    virtual void update(int frameNo, const VMatrix &parentMatrix,
+                        float parentAlpha, const DirtyFlag &flag) = 0;
+    virtual void renderList(std::vector<VDrawable *> &) {}
+    virtual bool resolveKeyPath(LOTKeyPath &, uint, LOTVariant &)
+    {
+        return false;
+    }
+    virtual Object::Type type() const { return Object::Type::Unknown; }
 };
 
-class LOTContentGroupItem: public LOTContentItem
-{
+class Shape;
+class Group : public Object {
 public:
-   LOTContentGroupItem() = default;
-   explicit LOTContentGroupItem(LOTGroupData *data, VArenaAlloc* allocator);
-   void addChildren(LOTGroupData *data, VArenaAlloc* allocator);
-   void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha, const DirtyFlag &flag) override;
-   void applyTrim();
-   void processTrimItems(std::vector<LOTPathDataItem *> &list);
-   void processPaintItems(std::vector<LOTPathDataItem *> &list);
-   void renderList(std::vector<VDrawable *> &list) override;
-   ContentType type() const final {return ContentType::Group;}
-   const VMatrix & matrix() const { return mMatrix;}
-   const char* name() const
-   {
-       static const char* TAG = "__";
-       return mModel.hasModel() ? mModel.name() : TAG;
-   }
-   bool resolveKeyPath(LOTKeyPath &keyPath, uint depth, LOTVariant &value) override;
+    Group() = default;
+    explicit Group(model::Group *data, VArenaAlloc *allocator);
+    void addChildren(model::Group *data, VArenaAlloc *allocator);
+    void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha,
+                const DirtyFlag &flag) override;
+    void applyTrim();
+    void processTrimItems(std::vector<Shape *> &list);
+    void processPaintItems(std::vector<Shape *> &list);
+    void renderList(std::vector<VDrawable *> &list) override;
+    Object::Type   type() const final { return Object::Type::Group; }
+    const VMatrix &matrix() const { return mMatrix; }
+    const char *   name() const
+    {
+        static const char *TAG = "__";
+        return mModel.hasModel() ? mModel.name() : TAG;
+    }
+    bool resolveKeyPath(LOTKeyPath &keyPath, uint depth,
+                        LOTVariant &value) override;
+
 protected:
-   std::vector<LOTContentItem*>   mContents;
-   VMatrix                                        mMatrix;
+    std::vector<Object *> mContents;
+    VMatrix               mMatrix;
+
 private:
-   LOTProxyModel<LOTGroupData> mModel;
+    LOTProxyModel<model::Group> mModel;
 };
 
-class LOTPathDataItem : public LOTContentItem
-{
+class Shape : public Object {
 public:
-   LOTPathDataItem(bool staticPath): mStaticPath(staticPath){}
-   void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha, const DirtyFlag &flag) final;
-   ContentType type() const final {return ContentType::Path;}
-   bool dirty() const {return mDirtyPath;}
-   const VPath &localPath() const {return mTemp;}
-   void finalPath(VPath& result);
-   void updatePath(const VPath &path) {mTemp = path; mDirtyPath = true;}
-   bool staticPath() const { return mStaticPath; }
-   void setParent(LOTContentGroupItem *parent) {mParent = parent;}
-   LOTContentGroupItem *parent() const {return mParent;}
+    Shape(bool staticPath) : mStaticPath(staticPath) {}
+    void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha,
+                const DirtyFlag &flag) final;
+    Object::Type type() const final { return Object::Type::Shape; }
+    bool         dirty() const { return mDirtyPath; }
+    const VPath &localPath() const { return mTemp; }
+    void         finalPath(VPath &result);
+    void         updatePath(const VPath &path)
+    {
+        mTemp = path;
+        mDirtyPath = true;
+    }
+    bool   staticPath() const { return mStaticPath; }
+    void   setParent(Group *parent) { mParent = parent; }
+    Group *parent() const { return mParent; }
+
 protected:
-   virtual void updatePath(VPath& path, int frameNo) = 0;
-   virtual bool hasChanged(int prevFrame, int curFrame) = 0;
+    virtual void updatePath(VPath &path, int frameNo) = 0;
+    virtual bool hasChanged(int prevFrame, int curFrame) = 0;
+
 private:
-   bool hasChanged(int frameNo) {
-       int prevFrame = mFrameNo;
-       mFrameNo = frameNo;
-       if (prevFrame == -1) return true;
-       if (mStaticPath ||
-           (prevFrame == frameNo)) return false;
-       return hasChanged(prevFrame, frameNo);
-   }
-   LOTContentGroupItem                    *mParent{nullptr};
-   VPath                                   mLocalPath;
-   VPath                                   mTemp;
-   int                                     mFrameNo{-1};
-   bool                                    mDirtyPath{true};
-   bool                                    mStaticPath;
+    bool hasChanged(int frameNo)
+    {
+        int prevFrame = mFrameNo;
+        mFrameNo = frameNo;
+        if (prevFrame == -1) return true;
+        if (mStaticPath || (prevFrame == frameNo)) return false;
+        return hasChanged(prevFrame, frameNo);
+    }
+    Group *mParent{nullptr};
+    VPath  mLocalPath;
+    VPath  mTemp;
+    int    mFrameNo{-1};
+    bool   mDirtyPath{true};
+    bool   mStaticPath;
 };
 
-class LOTRectItem: public LOTPathDataItem
-{
+class Rect : public Shape {
 public:
-   explicit LOTRectItem(LOTRectData *data);
+    explicit Rect(model::Rect *data);
+
 protected:
-   void updatePath(VPath& path, int frameNo) final;
-   LOTRectData           *mData{nullptr};
-
-   bool hasChanged(int prevFrame, int curFrame) final {
-       return (mData->mPos.changed(prevFrame, curFrame) ||
-               mData->mSize.changed(prevFrame, curFrame) ||
-               mData->mRound.changed(prevFrame, curFrame));
-   }
+    void         updatePath(VPath &path, int frameNo) final;
+    model::Rect *mData{nullptr};
+
+    bool hasChanged(int prevFrame, int curFrame) final
+    {
+        return (mData->mPos.changed(prevFrame, curFrame) ||
+                mData->mSize.changed(prevFrame, curFrame) ||
+                mData->mRound.changed(prevFrame, curFrame));
+    }
 };
 
-class LOTEllipseItem: public LOTPathDataItem
-{
+class Ellipse : public Shape {
 public:
-   explicit LOTEllipseItem(LOTEllipseData *data);
+    explicit Ellipse(model::Ellipse *data);
+
 private:
-   void updatePath(VPath& path, int frameNo) final;
-   LOTEllipseData           *mData{nullptr};
-   bool hasChanged(int prevFrame, int curFrame) final {
-       return (mData->mPos.changed(prevFrame, curFrame) ||
-               mData->mSize.changed(prevFrame, curFrame));
-   }
+    void            updatePath(VPath &path, int frameNo) final;
+    model::Ellipse *mData{nullptr};
+    bool            hasChanged(int prevFrame, int curFrame) final
+    {
+        return (mData->mPos.changed(prevFrame, curFrame) ||
+                mData->mSize.changed(prevFrame, curFrame));
+    }
 };
 
-class LOTShapeItem: public LOTPathDataItem
-{
+class Path : public Shape {
 public:
-   explicit LOTShapeItem(LOTShapeData *data);
+    explicit Path(model::Path *data);
+
 private:
-   void updatePath(VPath& path, int frameNo) final;
-   LOTShapeData             *mData{nullptr};
-   bool hasChanged(int prevFrame, int curFrame) final {
-       return mData->mShape.changed(prevFrame, curFrame);
-   }
+    void         updatePath(VPath &path, int frameNo) final;
+    model::Path *mData{nullptr};
+    bool         hasChanged(int prevFrame, int curFrame) final
+    {
+        return mData->mShape.changed(prevFrame, curFrame);
+    }
 };
 
-class LOTPolystarItem: public LOTPathDataItem
-{
+class Polystar : public Shape {
 public:
-   explicit LOTPolystarItem(LOTPolystarData *data);
+    explicit Polystar(model::Polystar *data);
+
 private:
-   void updatePath(VPath& path, int frameNo) final;
-   LOTPolystarData             *mData{nullptr};
-
-   bool hasChanged(int prevFrame, int curFrame) final {
-       return (mData->mPos.changed(prevFrame, curFrame) ||
-               mData->mPointCount.changed(prevFrame, curFrame) ||
-               mData->mInnerRadius.changed(prevFrame, curFrame) ||
-               mData->mOuterRadius.changed(prevFrame, curFrame) ||
-               mData->mInnerRoundness.changed(prevFrame, curFrame) ||
-               mData->mOuterRoundness.changed(prevFrame, curFrame) ||
-               mData->mRotation.changed(prevFrame, curFrame));
-   }
+    void             updatePath(VPath &path, int frameNo) final;
+    model::Polystar *mData{nullptr};
+
+    bool hasChanged(int prevFrame, int curFrame) final
+    {
+        return (mData->mPos.changed(prevFrame, curFrame) ||
+                mData->mPointCount.changed(prevFrame, curFrame) ||
+                mData->mInnerRadius.changed(prevFrame, curFrame) ||
+                mData->mOuterRadius.changed(prevFrame, curFrame) ||
+                mData->mInnerRoundness.changed(prevFrame, curFrame) ||
+                mData->mOuterRoundness.changed(prevFrame, curFrame) ||
+                mData->mRotation.changed(prevFrame, curFrame));
+    }
 };
 
-
-
-class LOTPaintDataItem : public LOTContentItem
-{
+class Paint : public Object {
 public:
-   LOTPaintDataItem(bool staticContent);
-   void addPathItems(std::vector<LOTPathDataItem *> &list, size_t startOffset);
-   void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha, const DirtyFlag &flag) override;
-   void renderList(std::vector<VDrawable *> &list) final;
-   ContentType type() const final {return ContentType::Paint;}
+    Paint(bool staticContent);
+    void addPathItems(std::vector<Shape *> &list, size_t startOffset);
+    void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha,
+                const DirtyFlag &flag) override;
+    void renderList(std::vector<VDrawable *> &list) final;
+    Object::Type type() const final { return Object::Type::Paint; }
+
 protected:
-   virtual bool updateContent(int frameNo, const VMatrix &matrix, float alpha) = 0;
+    virtual bool updateContent(int frameNo, const VMatrix &matrix,
+                               float alpha) = 0;
+
 private:
-   void updateRenderNode();
+    void updateRenderNode();
+
 protected:
-   std::vector<LOTPathDataItem *>   mPathItems;
-   LOTDrawable                      mDrawable;
-   VPath                            mPath;
-   DirtyFlag                        mFlag;
-   bool                             mStaticContent;
-   bool                             mRenderNodeUpdate{true};
-   bool                             mContentToRender{true};
+    std::vector<Shape *> mPathItems;
+    Drawable             mDrawable;
+    VPath                mPath;
+    DirtyFlag            mFlag;
+    bool                 mStaticContent;
+    bool                 mRenderNodeUpdate{true};
+    bool                 mContentToRender{true};
 };
 
-class LOTFillItem : public LOTPaintDataItem
-{
+class Fill : public Paint {
 public:
-   explicit LOTFillItem(LOTFillData *data);
+    explicit Fill(model::Fill *data);
+
 protected:
-   bool updateContent(int frameNo, const VMatrix &matrix, float alpha) final;
-   bool resolveKeyPath(LOTKeyPath &keyPath, uint depth, LOTVariant &value) final;
+    bool updateContent(int frameNo, const VMatrix &matrix, float alpha) final;
+    bool resolveKeyPath(LOTKeyPath &keyPath, uint depth,
+                        LOTVariant &value) final;
+
 private:
-   LOTProxyModel<LOTFillData> mModel;
+    LOTProxyModel<model::Fill> mModel;
 };
 
-class LOTGFillItem : public LOTPaintDataItem
-{
+class GradientFill : public Paint {
 public:
-   explicit LOTGFillItem(LOTGFillData *data);
+    explicit GradientFill(model::GradientFill *data);
+
 protected:
-   bool updateContent(int frameNo, const VMatrix &matrix, float alpha) final;
+    bool updateContent(int frameNo, const VMatrix &matrix, float alpha) final;
+
 private:
-   LOTGFillData                 *mData{nullptr};
-   std::unique_ptr<VGradient>    mGradient;
+    model::GradientFill *      mData{nullptr};
+    std::unique_ptr<VGradient> mGradient;
 };
 
-class LOTStrokeItem : public LOTPaintDataItem
-{
+class Stroke : public Paint {
 public:
-   explicit LOTStrokeItem(LOTStrokeData *data);
+    explicit Stroke(model::Stroke *data);
+
 protected:
-   bool updateContent(int frameNo, const VMatrix &matrix, float alpha) final;
-   bool resolveKeyPath(LOTKeyPath &keyPath, uint depth, LOTVariant &value) final;
+    bool updateContent(int frameNo, const VMatrix &matrix, float alpha) final;
+    bool resolveKeyPath(LOTKeyPath &keyPath, uint depth,
+                        LOTVariant &value) final;
+
 private:
-   LOTProxyModel<LOTStrokeData> mModel;
+    LOTProxyModel<model::Stroke> mModel;
 };
 
-class LOTGStrokeItem : public LOTPaintDataItem
-{
+class GradientStroke : public Paint {
 public:
-   explicit LOTGStrokeItem(LOTGStrokeData *data);
+    explicit GradientStroke(model::GradientStroke *data);
+
 protected:
-   bool updateContent(int frameNo, const VMatrix &matrix, float alpha) final;
+    bool updateContent(int frameNo, const VMatrix &matrix, float alpha) final;
+
 private:
-   LOTGStrokeData               *mData{nullptr};
-   std::unique_ptr<VGradient>    mGradient;
+    model::GradientStroke *    mData{nullptr};
+    std::unique_ptr<VGradient> mGradient;
 };
 
-
-// Trim Item
-
-class LOTTrimItem : public LOTContentItem
-{
+class Trim : public Object {
 public:
-   explicit LOTTrimItem(LOTTrimData *data);
-   void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha, const DirtyFlag &flag) final;
-   ContentType type() const final {return ContentType::Trim;}
-   void update();
-   void addPathItems(std::vector<LOTPathDataItem *> &list, size_t startOffset);
+    explicit Trim(model::Trim *data) : mData(data) {}
+    void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha,
+                const DirtyFlag &flag) final;
+    Object::Type type() const final { return Object::Type::Trim; }
+    void         update();
+    void         addPathItems(std::vector<Shape *> &list, size_t startOffset);
+
 private:
-   bool pathDirty() const {
-       for (auto &i : mPathItems) {
-           if (i->dirty())
-               return true;
-       }
-       return false;
-   }
-   struct Cache {
-        int                     mFrameNo{-1};
-        LOTTrimData::Segment    mSegment{};
-   };
-   Cache                            mCache;
-   std::vector<LOTPathDataItem *>   mPathItems;
-   LOTTrimData                     *mData{nullptr};
-   VPathMesure                      mPathMesure;
-   bool                             mDirty{true};
+    bool pathDirty() const
+    {
+        for (auto &i : mPathItems) {
+            if (i->dirty()) return true;
+        }
+        return false;
+    }
+    struct Cache {
+        int                  mFrameNo{-1};
+        model::Trim::Segment mSegment{};
+    };
+    Cache                mCache;
+    std::vector<Shape *> mPathItems;
+    model::Trim *        mData{nullptr};
+    VPathMesure          mPathMesure;
+    bool                 mDirty{true};
 };
 
-class LOTRepeaterItem : public LOTContentGroupItem
-{
+class Repeater : public Group {
 public:
-   explicit LOTRepeaterItem(LOTRepeaterData *data, VArenaAlloc* allocator);
-   void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha, const DirtyFlag &flag) final;
-   void renderList(std::vector<VDrawable *> &list) final;
+    explicit Repeater(model::Repeater *data, VArenaAlloc *allocator);
+    void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha,
+                const DirtyFlag &flag) final;
+    void renderList(std::vector<VDrawable *> &list) final;
+
 private:
-   LOTRepeaterData             *mRepeaterData{nullptr};
-   bool                         mHidden{false};
-   int                          mCopies{0};
+    model::Repeater *mRepeaterData{nullptr};
+    bool             mHidden{false};
+    int              mCopies{0};
 };
 
+}  // namespace renderer
 
-#endif // LOTTIEITEM_H
+}  // namespace internal
 
+}  // namespace rlottie
 
+#endif  // LOTTIEITEM_H
index 7d8ea9f..a4d8546 100644 (file)
@@ -9,7 +9,9 @@
 #include "lottieitem.h"
 #include "vdasher.h"
 
-LOTCApiData::LOTCApiData()
+using namespace rlottie::internal;
+
+renderer::CApiData::CApiData()
 {
     mLayer.mMaskList.ptr = nullptr;
     mLayer.mMaskList.size = 0;
@@ -27,24 +29,24 @@ LOTCApiData::LOTCApiData()
     mLayer.keypath = nullptr;
 }
 
-void LOTCompItem::buildRenderTree()
+void renderer::Composition::buildRenderTree()
 {
     mRootLayer->buildLayerNode();
 }
 
-const LOTLayerNode *LOTCompItem::renderTree() const
+const LOTLayerNode *renderer::Composition::renderTree() const
 {
     return &mRootLayer->clayer();
 }
 
-void LOTCompLayerItem::buildLayerNode()
+void renderer::CompLayer::buildLayerNode()
 {
-    LOTLayerItem::buildLayerNode();
+    renderer::Layer::buildLayerNode();
     if (mClipper) {
         const auto &elm = mClipper->mPath.elements();
         const auto &pts = mClipper->mPath.points();
-        auto ptPtr = reinterpret_cast<const float *>(pts.data());
-        auto elmPtr = reinterpret_cast<const char *>(elm.data());
+        auto        ptPtr = reinterpret_cast<const float *>(pts.data());
+        auto        elmPtr = reinterpret_cast<const char *>(elm.data());
         clayer().mClipPath.ptPtr = ptPtr;
         clayer().mClipPath.elmPtr = elmPtr;
         clayer().mClipPath.ptCount = 2 * pts.size();
@@ -64,16 +66,15 @@ void LOTCompLayerItem::buildLayerNode()
     }
 }
 
-
-void LOTShapeLayerItem::buildLayerNode()
+void renderer::ShapeLayer::buildLayerNode()
 {
-    LOTLayerItem::buildLayerNode();
+    renderer::Layer::buildLayerNode();
 
     auto renderlist = renderList();
 
     cnodes().clear();
     for (auto &i : renderlist) {
-        auto lotDrawable = static_cast<LOTDrawable *>(i);
+        auto lotDrawable = static_cast<renderer::Drawable *>(i);
         lotDrawable->sync();
         cnodes().push_back(lotDrawable->mCNode.get());
     }
@@ -81,10 +82,10 @@ void LOTShapeLayerItem::buildLayerNode()
     clayer().mNodeList.size = cnodes().size();
 }
 
-void LOTLayerItem::buildLayerNode()
+void renderer::Layer::buildLayerNode()
 {
     if (!mCApiData) {
-        mCApiData = std::make_unique<LOTCApiData>();
+        mCApiData = std::make_unique<renderer::CApiData>();
         clayer().keypath = name();
     }
     if (complexContent()) clayer().mAlpha = uchar(combinedAlpha() * 255.f);
@@ -92,16 +93,16 @@ void LOTLayerItem::buildLayerNode()
     // update matte
     if (hasMatte()) {
         switch (mLayerData->mMatteType) {
-        case MatteType::Alpha:
+        case model::MatteType::Alpha:
             clayer().mMatte = MatteAlpha;
             break;
-        case MatteType::AlphaInv:
+        case model::MatteType::AlphaInv:
             clayer().mMatte = MatteAlphaInv;
             break;
-        case MatteType::Luma:
+        case model::MatteType::Luma:
             clayer().mMatte = MatteLuma;
             break;
-        case MatteType::LumaInv:
+        case model::MatteType::LumaInv:
             clayer().mMatte = MatteLumaInv;
             break;
         default:
@@ -114,27 +115,27 @@ void LOTLayerItem::buildLayerNode()
         cmasks().resize(mLayerMask->mMasks.size());
         size_t i = 0;
         for (const auto &mask : mLayerMask->mMasks) {
-            auto       &cNode = cmasks()[i++];
+            auto &      cNode = cmasks()[i++];
             const auto &elm = mask.mFinalPath.elements();
             const auto &pts = mask.mFinalPath.points();
-            auto ptPtr = reinterpret_cast<const float *>(pts.data());
-            auto elmPtr = reinterpret_cast<const char *>(elm.data());
+            auto        ptPtr = reinterpret_cast<const float *>(pts.data());
+            auto        elmPtr = reinterpret_cast<const char *>(elm.data());
             cNode.mPath.ptPtr = ptPtr;
             cNode.mPath.ptCount = pts.size();
             cNode.mPath.elmPtr = elmPtr;
             cNode.mPath.elmCount = elm.size();
             cNode.mAlpha = uchar(mask.mCombinedAlpha * 255.0f);
             switch (mask.maskMode()) {
-            case LOTMaskData::Mode::Add:
+            case model::Mask::Mode::Add:
                 cNode.mMode = MaskAdd;
                 break;
-            case LOTMaskData::Mode::Substarct:
+            case model::Mask::Mode::Substarct:
                 cNode.mMode = MaskSubstract;
                 break;
-            case LOTMaskData::Mode::Intersect:
+            case model::Mask::Mode::Intersect:
                 cNode.mMode = MaskIntersect;
                 break;
-            case LOTMaskData::Mode::Difference:
+            case model::Mask::Mode::Difference:
                 cNode.mMode = MaskDifference;
                 break;
             default:
@@ -147,15 +148,15 @@ void LOTLayerItem::buildLayerNode()
     }
 }
 
-void LOTSolidLayerItem::buildLayerNode()
+void renderer::SolidLayer::buildLayerNode()
 {
-    LOTLayerItem::buildLayerNode();
+    renderer::Layer::buildLayerNode();
 
     auto renderlist = renderList();
 
     cnodes().clear();
     for (auto &i : renderlist) {
-        auto lotDrawable = static_cast<LOTDrawable *>(i);
+        auto lotDrawable = static_cast<renderer::Drawable *>(i);
         lotDrawable->sync();
         cnodes().push_back(lotDrawable->mCNode.get());
     }
@@ -163,15 +164,15 @@ void LOTSolidLayerItem::buildLayerNode()
     clayer().mNodeList.size = cnodes().size();
 }
 
-void LOTImageLayerItem::buildLayerNode()
+void renderer::ImageLayer::buildLayerNode()
 {
-    LOTLayerItem::buildLayerNode();
+    renderer::Layer::buildLayerNode();
 
     auto renderlist = renderList();
 
     cnodes().clear();
     for (auto &i : renderlist) {
-        auto lotDrawable = static_cast<LOTDrawable *>(i);
+        auto lotDrawable = static_cast<renderer::Drawable *>(i);
         lotDrawable->sync();
 
         lotDrawable->mCNode->mImageInfo.data =
@@ -194,7 +195,8 @@ void LOTImageLayerItem::buildLayerNode()
         lotDrawable->mCNode->mImageInfo.mMatrix.m33 = combinedMatrix().m_33();
 
         // Alpha calculation already combined.
-        lotDrawable->mCNode->mImageInfo.mAlpha = uchar(lotDrawable->mBrush.mTexture->mAlpha);
+        lotDrawable->mCNode->mImageInfo.mAlpha =
+            uchar(lotDrawable->mBrush.mTexture->mAlpha);
 
         cnodes().push_back(lotDrawable->mCNode.get());
     }
@@ -222,7 +224,7 @@ static void updateGStops(LOTNode *n, const VGradient *grad)
     }
 }
 
-void LOTDrawable::sync()
+void renderer::Drawable::sync()
 {
     if (!mCNode) {
         mCNode = std::make_unique<LOTNode>();
@@ -335,4 +337,3 @@ void LOTDrawable::sync()
         break;
     }
 }
-
index 921bcad..c6ab63d 100644 (file)
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
  */
 
 #ifndef LOTTIEKEYPATH_H
 #define LOTTIEKEYPATH_H
 
-#include "vglobal.h"
 #include <string>
 #include <vector>
+#include "vglobal.h"
 
-class LOTKeyPath{
+class LOTKeyPath {
 public:
     LOTKeyPath(const std::string &keyPath);
     bool matches(const std::string &key, uint depth);
     uint nextDepth(const std::string key, uint depth);
     bool fullyResolvesTo(const std::string key, uint depth);
 
-    bool propagate(const std::string key, uint depth) {
+    bool propagate(const std::string key, uint depth)
+    {
         return skip(key) ? true : (depth < size()) || (mKeys[depth] == "**");
     }
-    bool skip(const std::string &key) const { return key == "__";}
+    bool skip(const std::string &key) const { return key == "__"; }
+
 private:
-    bool isGlobstar(uint depth) const {return mKeys[depth] == "**";}
-    bool isGlob(uint depth) const {return mKeys[depth] == "*";}
-    bool endsWithGlobstar() const { return mKeys.back() == "**"; }
-    size_t size() const {return mKeys.size() - 1;}
+    bool   isGlobstar(uint depth) const { return mKeys[depth] == "**"; }
+    bool   isGlob(uint depth) const { return mKeys[depth] == "*"; }
+    bool   endsWithGlobstar() const { return mKeys.back() == "**"; }
+    size_t size() const { return mKeys.size() - 1; }
+
 private:
     std::vector<std::string> mKeys;
 };
 
-#endif //LOTTIEKEYPATH_H
+#endif  // LOTTIEKEYPATH_H
index 1783b0e..329c2eb 100644 (file)
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
  */
 
-#include "lottieloader.h"
-#include "lottieparser.h"
-
 #include <cstring>
 #include <fstream>
 #include <sstream>
 
+#include "lottiemodel.h"
+
 #ifdef LOTTIE_CACHE_SUPPORT
 
-#include <unordered_map>
 #include <mutex>
+#include <unordered_map>
+
+using namespace rlottie::internal;
 
-class LottieModelCache {
+class ModelCache {
 public:
-    static LottieModelCache &instance()
+    static ModelCache &instance()
     {
-        static LottieModelCache CACHE;
-        return CACHE;
+        static ModelCache singleton;
+        return singleton;
     }
-    std::shared_ptr<LOTModel> find(const std::string &key)
+    std::shared_ptr<model::Composition> find(const std::string &key)
     {
         std::lock_guard<std::mutex> guard(mMutex);
 
@@ -44,9 +45,8 @@ public:
         auto search = mHash.find(key);
 
         return (search != mHash.end()) ? search->second : nullptr;
-
     }
-    void add(const std::string &key, std::shared_ptr<LOTModel> value)
+    void add(const std::string &key, std::shared_ptr<model::Composition> value)
     {
         std::lock_guard<std::mutex> guard(mMutex);
 
@@ -68,49 +68,53 @@ public:
     }
 
 private:
-    LottieModelCache() = default;
+    ModelCache() = default;
 
-    std::unordered_map<std::string, std::shared_ptr<LOTModel>>  mHash;
-    std::mutex                                                  mMutex;
-    size_t                                                      mcacheSize{10};
+    std::unordered_map<std::string, std::shared_ptr<model::Composition>> mHash;
+    std::mutex                                                           mMutex;
+    size_t mcacheSize{10};
 };
 
 #else
 
-class LottieModelCache {
+class ModelCache {
 public:
-    static LottieModelCache &instance()
+    static ModelCache &instance()
+    {
+        static ModelCache singleton;
+        return singleton;
+    }
+    std::shared_ptr<model::Composition> find(const std::string &)
     {
-        static LottieModelCache CACHE;
-        return CACHE;
+        return nullptr;
     }
-    std::shared_ptr<LOTModel> find(const std::string &) { return nullptr; }
-    void add(const std::string &, std::shared_ptr<LOTModel>) {}
+    void add(const std::string &, std::shared_ptr<model::Composition>) {}
     void configureCacheSize(size_t) {}
 };
 
 #endif
 
-void LottieLoader::configureModelCacheSize(size_t cacheSize)
-{
-    LottieModelCache::instance().configureCacheSize(cacheSize);
-}
-
 static std::string dirname(const std::string &path)
 {
     const char *ptr = strrchr(path.c_str(), '/');
 #ifdef _WIN32
     if (ptr) ptr = strrchr(ptr + 1, '\\');
 #endif
-    int         len = int(ptr + 1 - path.c_str());  // +1 to include '/'
+    int len = int(ptr + 1 - path.c_str());  // +1 to include '/'
     return std::string(path, 0, len);
 }
 
-bool LottieLoader::load(const std::string &path, bool cachePolicy)
+void model::configureModelCacheSize(size_t cacheSize)
+{
+    ModelCache::instance().configureCacheSize(cacheSize);
+}
+
+std::shared_ptr<model::Composition> model::loadFromFile(const std::string &path,
+                                                        bool cachePolicy)
 {
     if (cachePolicy) {
-        mModel = LottieModelCache::instance().find(path);
-        if (mModel) return true;
+        auto obj = ModelCache::instance().find(path);
+        if (obj) return obj;
     }
 
     std::ifstream f;
@@ -118,56 +122,44 @@ bool LottieLoader::load(const std::string &path, bool cachePolicy)
 
     if (!f.is_open()) {
         vCritical << "failed to open file = " << path.c_str();
-        return false;
+        return {};
     } else {
         std::string content;
 
-        std::getline(f, content, '\0') ;
+        std::getline(f, content, '\0');
         f.close();
 
-        if (content.empty()) return false;
+        if (content.empty()) return {};
 
-        const char *str = content.c_str();
-        LottieParser parser(const_cast<char *>(str), dirname(path));
-        mModel = parser.model();
+        auto obj = internal::model::parse(const_cast<char *>(content.c_str()),
+                                          dirname(path));
 
-        if (!mModel) return false;
+        if (obj && cachePolicy) ModelCache::instance().add(path, obj);
 
-        if (cachePolicy)
-            LottieModelCache::instance().add(path, mModel);
+        return obj;
     }
-
-    return true;
 }
 
-bool LottieLoader::loadFromData(std::string jsonData, const std::string &key,
-                                std::string resourcePath, bool cachePolicy)
+std::shared_ptr<model::Composition> model::loadFromData(
+    std::string jsonData, const std::string &key, std::string resourcePath,
+    bool cachePolicy)
 {
     if (cachePolicy) {
-        mModel = LottieModelCache::instance().find(key);
-        if (mModel) return true;
+        auto obj = ModelCache::instance().find(key);
+        if (obj) return obj;
     }
 
-    LottieParser parser(const_cast<char *>(jsonData.c_str()), std::move(resourcePath));
-    mModel = parser.model();
+    auto obj = internal::model::parse(const_cast<char *>(jsonData.c_str()),
+                                      std::move(resourcePath));
 
-    if (!mModel) return false;
-
-    if (cachePolicy)
-        LottieModelCache::instance().add(key, mModel);
-
-    return true;
-}
-
-bool LottieLoader::loadFromData(std::string jsonData, std::string resourcePath, ColorFilter filter)
-{
-    LottieParser parser(const_cast<char *>(jsonData.c_str()), std::move(resourcePath), std::move(filter));
-    mModel = parser.model();
+    if (obj && cachePolicy) ModelCache::instance().add(key, obj);
 
-    return mModel ? true : false;
+    return obj;
 }
 
-std::shared_ptr<LOTModel> LottieLoader::model()
+std::shared_ptr<model::Composition> model::loadFromData(
+    std::string jsonData, std::string resourcePath, model::ColorFilter filter)
 {
-    return mModel;
+    return internal::model::parse(const_cast<char *>(jsonData.c_str()),
+                                  std::move(resourcePath), std::move(filter));
 }
diff --git a/src/lottie/lottieloader.h b/src/lottie/lottieloader.h
deleted file mode 100644 (file)
index 084bbea..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#ifndef LOTTIELOADER_H
-#define LOTTIELOADER_H
-
-#include<memory>
-#include <functional>
-
-class LOTModel;
-class LottieLoader
-{
-public:
-   using ColorFilter = std::function<void(float &, float &, float&)>;
-   static void configureModelCacheSize(size_t cacheSize);
-   bool load(const std::string &filePath, bool cachePolicy);
-   bool loadFromData(std::string jsonData, const std::string &key,
-                     std::string resourcePath, bool cachePolicy);
-   bool loadFromData(std::string jsonData, std::string resourcePath, ColorFilter filter);
-   std::shared_ptr<LOTModel> model();
-private:
-   std::shared_ptr<LOTModel>    mModel;
-};
-
-#endif // LOTTIELOADER_H
-
-
index f3e42e6..1851228 100644 (file)
@@ -23,6 +23,8 @@
 #include "vimageloader.h"
 #include "vline.h"
 
+using namespace rlottie::internal;
+
 /*
  * We process the iterator objects in the children list
  * by iterating from back to front. when we find a repeater object
  */
 class LottieRepeaterProcesser {
 public:
-    void visitChildren(LOTGroupData *obj)
+    void visitChildren(model::Group *obj)
     {
         for (auto i = obj->mChildren.rbegin(); i != obj->mChildren.rend();
              ++i) {
             auto child = (*i);
-            if (child->type() == LOTData::Type::Repeater) {
-                LOTRepeaterData *repeater =
-                    static_cast<LOTRepeaterData *>(child);
+            if (child->type() == model::Object::Type::Repeater) {
+                model::Repeater *repeater =
+                    static_cast<model::Repeater *>(child);
                 // check if this repeater is already processed
                 // can happen if the layer is an asset and referenced by
                 // multiple layer.
@@ -51,7 +53,7 @@ public:
 
                 repeater->markProcessed();
 
-                LOTShapeGroupData *content = repeater->content();
+                auto content = repeater->content();
                 // 1. increment the reverse iterator to point to the
                 //   object before the repeater
                 ++i;
@@ -71,12 +73,12 @@ public:
         }
     }
 
-    void visit(LOTData *obj)
+    void visit(model::Object *obj)
     {
         switch (obj->type()) {
-        case LOTData::Type::ShapeGroup:
-        case LOTData::Type::Layer: {
-            visitChildren(static_cast<LOTGroupData *>(obj));
+        case model::Object::Type::Group:
+        case model::Object::Type::Layer: {
+            visitChildren(static_cast<model::Group *>(obj));
             break;
         }
         default:
@@ -86,31 +88,32 @@ public:
 };
 
 class LottieUpdateStatVisitor {
-    LOTModelStat *stat;
+    model::Composition::Stats *stat;
+
 public:
-    explicit LottieUpdateStatVisitor(LOTModelStat *s):stat(s){}
-    void visitChildren(LOTGroupData *obj)
+    explicit LottieUpdateStatVisitor(model::Composition::Stats *s) : stat(s) {}
+    void visitChildren(model::Group *obj)
     {
         for (const auto &child : obj->mChildren) {
             if (child) visit(child);
         }
     }
-    void visitLayer(LOTLayerData *layer)
+    void visitLayer(model::Layer *layer)
     {
         switch (layer->mLayerType) {
-        case LayerType::Precomp:
+        case model::Layer::Type::Precomp:
             stat->precompLayerCount++;
             break;
-        case LayerType::Null:
+        case model::Layer::Type::Null:
             stat->nullLayerCount++;
             break;
-        case LayerType::Shape:
+        case model::Layer::Type::Shape:
             stat->shapeLayerCount++;
             break;
-        case LayerType::Solid:
+        case model::Layer::Type::Solid:
             stat->solidLayerCount++;
             break;
-        case LayerType::Image:
+        case model::Layer::Type::Image:
             stat->imageLayerCount++;
             break;
         default:
@@ -118,41 +121,40 @@ public:
         }
         visitChildren(layer);
     }
-    void visit(LOTData *obj)
+    void visit(model::Object *obj)
     {
         switch (obj->type()) {
-        case LOTData::Type::Layer: {
-            visitLayer(static_cast<LOTLayerData *>(obj));
+        case model::Object::Type::Layer: {
+            visitLayer(static_cast<model::Layer *>(obj));
             break;
         }
-        case LOTData::Type::Repeater: {
-            visitChildren(static_cast<LOTRepeaterData *>(obj)->content());
+        case model::Object::Type::Repeater: {
+            visitChildren(static_cast<model::Repeater *>(obj)->content());
             break;
         }
-        case LOTData::Type::ShapeGroup: {
-            visitChildren(static_cast<LOTGroupData *>(obj));
+        case model::Object::Type::Group: {
+            visitChildren(static_cast<model::Group *>(obj));
             break;
         }
         default:
             break;
         }
     }
-
 };
 
-void LOTCompositionData::processRepeaterObjects()
+void model::Composition::processRepeaterObjects()
 {
     LottieRepeaterProcesser visitor;
     visitor.visit(mRootLayer);
 }
 
-void LOTCompositionData::updateStats()
+void model::Composition::updateStats()
 {
     LottieUpdateStatVisitor visitor(&mStats);
     visitor.visit(mRootLayer);
 }
 
-VMatrix LOTRepeaterTransform::matrix(int frameNo, float multiplier) const
+VMatrix model::Repeater::Transform::matrix(int frameNo, float multiplier) const
 {
     VPointF scale = mScale.value(frameNo) / 100.f;
     scale.setX(std::pow(scale.x(), multiplier));
@@ -167,7 +169,7 @@ VMatrix LOTRepeaterTransform::matrix(int frameNo, float multiplier) const
     return m;
 }
 
-VMatrix TransformData::matrix(int frameNo, bool autoOrient) const
+VMatrix model::Transform::Data::matrix(int frameNo, bool autoOrient) const
 {
     VMatrix m;
     VPointF position;
@@ -195,7 +197,7 @@ VMatrix TransformData::matrix(int frameNo, bool autoOrient) const
     return m;
 }
 
-void LOTDashProperty::getDashInfo(int frameNo, std::vector<float>& result) const
+void model::Dash::getDashInfo(int frameNo, std::vector<float> &result) const
 {
     result.clear();
 
@@ -203,8 +205,7 @@ void LOTDashProperty::getDashInfo(int frameNo, std::vector<float>& result) const
 
     if (result.capacity() < mData.size()) result.reserve(mData.size() + 1);
 
-    for (const auto &elm : mData)
-        result.push_back(elm.value(frameNo));
+    for (const auto &elm : mData) result.push_back(elm.value(frameNo));
 
     // if the size is even then we are missing last
     // gap information which is same as the last dash value
@@ -212,10 +213,10 @@ void LOTDashProperty::getDashInfo(int frameNo, std::vector<float>& result) const
     // NOTE: last value is the offset and last-1 is the last dash value.
     auto size = result.size();
     if ((size % 2) == 0) {
-        //copy offset value to end.
+        // copy offset value to end.
         result.push_back(result.back());
         // copy dash value to gap.
-        result[size-1] = result[size-2];
+        result[size - 1] = result[size - 2];
     }
 }
 
@@ -239,22 +240,22 @@ void LOTDashProperty::getDashInfo(int frameNo, std::vector<float>& result) const
  *     ...
  * ]
  */
-void LOTGradient::populate(VGradientStops &stops, int frameNo)
+void model::Gradient::populate(VGradientStops &stops, int frameNo)
 {
-    LottieGradient gradData = mGradient.value(frameNo);
-    auto            size = gradData.mGradient.size();
-    float *        ptr = gradData.mGradient.data();
-    int            colorPoints = mColorPoints;
+    model::Gradient::Data gradData = mGradient.value(frameNo);
+    auto                  size = gradData.mGradient.size();
+    float *               ptr = gradData.mGradient.data();
+    int                   colorPoints = mColorPoints;
     if (colorPoints == -1) {  // for legacy bodymovin (ref: lottie-android)
         colorPoints = int(size / 4);
     }
-    auto    opacityArraySize = size - colorPoints * 4;
+    auto   opacityArraySize = size - colorPoints * 4;
     float *opacityPtr = ptr + (colorPoints * 4);
     stops.clear();
     size_t j = 0;
     for (int i = 0; i < colorPoints; i++) {
-        float       colorStop = ptr[0];
-        LottieColor color = LottieColor(ptr[1], ptr[2], ptr[3]);
+        float        colorStop = ptr[0];
+        model::Color color = model::Color(ptr[1], ptr[2], ptr[3]);
         if (opacityArraySize) {
             if (j == opacityArraySize) {
                 // already reached the end
@@ -304,7 +305,7 @@ void LOTGradient::populate(VGradientStops &stops, int frameNo)
     }
 }
 
-void LOTGradient::update(std::unique_ptr<VGradient> &grad, int frameNo)
+void model::Gradient::update(std::unique_ptr<VGradient> &grad, int frameNo)
 {
     bool init = false;
     if (!grad) {
@@ -344,8 +345,8 @@ void LOTGradient::update(std::unique_ptr<VGradient> &grad, int frameNo)
          */
         float progress = mHighlightLength.value(frameNo) / 100.0f;
         if (vCompare(progress, 1.0f)) progress = 0.99f;
-        float startAngle = VLine(start, end).angle();
-        float highlightAngle = mHighlightAngle.value(frameNo);
+        float                  startAngle = VLine(start, end).angle();
+        float                  highlightAngle = mHighlightAngle.value(frameNo);
         static constexpr float K_PI = 3.1415926f;
         float angle = (startAngle + highlightAngle) * (K_PI / 180.0f);
         grad->radial.fx =
@@ -357,18 +358,18 @@ void LOTGradient::update(std::unique_ptr<VGradient> &grad, int frameNo)
     }
 }
 
-void LOTAsset::loadImageData(std::string data)
+void model::Asset::loadImageData(std::string data)
 {
     if (!data.empty())
         mBitmap = VImageLoader::instance().load(data.c_str(), data.length());
 }
 
-void LOTAsset::loadImagePath(std::string path)
+void model::Asset::loadImagePath(std::string path)
 {
     if (!path.empty()) mBitmap = VImageLoader::instance().load(path.c_str());
 }
 
-std::vector<LayerInfo> LOTCompositionData::layerInfoList() const
+std::vector<LayerInfo> model::Composition::layerInfoList() const
 {
     if (!mRootLayer || mRootLayer->mChildren.empty()) return {};
 
@@ -377,7 +378,7 @@ std::vector<LayerInfo> LOTCompositionData::layerInfoList() const
     result.reserve(mRootLayer->mChildren.size());
 
     for (auto it : mRootLayer->mChildren) {
-        auto layer = static_cast<LOTLayerData *>(it);
+        auto layer = static_cast<model::Layer *>(it);
         result.emplace_back(layer->name(), layer->mInFrame, layer->mOutFrame);
     }
 
index 55d94a1..7342344 100644 (file)
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
  */
 
 #ifndef LOTModel_H
 #define LOTModel_H
 
-#include<vector>
-#include<memory>
-#include<unordered_map>
-#include<algorithm>
+#include <algorithm>
 #include <cmath>
 #include <cstring>
-#include"vpoint.h"
-#include"vrect.h"
-#include"vinterpolator.h"
-#include"vmatrix.h"
-#include"vbezier.h"
-#include"vbrush.h"
-#include"vpath.h"
-#include"varenaalloc.h"
+#include <functional>
+#include <memory>
+#include <unordered_map>
+#include <vector>
+#include "varenaalloc.h"
+#include "vbezier.h"
+#include "vbrush.h"
+#include "vinterpolator.h"
+#include "vmatrix.h"
+#include "vpath.h"
+#include "vpoint.h"
+#include "vrect.h"
 
 V_USE_NAMESPACE
 
-class LOTCompositionData;
-class LOTLayerData;
-class LOTTransformData;
-class LOTShapeGroupData;
-class LOTShapeData;
-class LOTRectData;
-class LOTEllipseData;
-class LOTTrimData;
-class LOTRepeaterData;
-class LOTFillData;
-class LOTStrokeData;
-class LOTGroupData;
-class LOTGFillData;
-class LOTGStrokeData;
-class LottieShapeData;
-class LOTPolystarData;
-class LOTMaskData;
-
-struct LOTModelStat
-{
-    uint16_t precompLayerCount{0};
-    uint16_t solidLayerCount{0};
-    uint16_t shapeLayerCount{0};
-    uint16_t imageLayerCount{0};
-    uint16_t nullLayerCount{0};
+namespace rlottie {
 
-};
+namespace internal {
 
-enum class MatteType: uchar
-{
-    None = 0,
-    Alpha = 1,
-    AlphaInv,
-    Luma,
-    LumaInv
-};
+using Marker = std::tuple<std::string, int, int>;
 
-enum class LayerType: uchar
+using LayerInfo = Marker;
+
+template <typename T>
+inline T lerp(const T &start, const T &end, float t)
 {
-    Precomp = 0,
-    Solid = 1,
-    Image = 2,
-    Null = 3,
-    Shape = 4,
-    Text = 5
+    return start + t * (end - start);
+}
+
+namespace model {
+
+enum class MatteType : uchar { None = 0, Alpha = 1, AlphaInv, Luma, LumaInv };
+
+enum class BlendMode : uchar {
+    Normal = 0,
+    Multiply = 1,
+    Screen = 2,
+    OverLay = 3
 };
 
-class LottieColor
-{
+class Color {
 public:
-    LottieColor() = default;
-    LottieColor(float red, float green , float blue):r(red), g(green),b(blue){}
-    VColor toColor(float a=1){ return VColor(uchar(255 * r),
-                                             uchar(255 * g),
-                                             uchar(255 * b),
-                                             uchar(255 * a));}
-    friend inline LottieColor operator+(const LottieColor &c1, const LottieColor &c2);
-    friend inline LottieColor operator-(const LottieColor &c1, const LottieColor &c2);
+    Color() = default;
+    Color(float red, float green, float blue) : r(red), g(green), b(blue) {}
+    VColor toColor(float a = 1)
+    {
+        return VColor(uchar(255 * r), uchar(255 * g), uchar(255 * b),
+                      uchar(255 * a));
+    }
+    friend inline Color operator+(const Color &c1, const Color &c2);
+    friend inline Color operator-(const Color &c1, const Color &c2);
+
 public:
     float r{1};
     float g{1};
     float b{1};
 };
 
-inline LottieColor operator-(const LottieColor &c1, const LottieColor &c2)
+inline Color operator-(const Color &c1, const Color &c2)
 {
-    return LottieColor(c1.r - c2.r, c1.g - c2.g, c1.b - c2.b);
+    return Color(c1.r - c2.r, c1.g - c2.g, c1.b - c2.b);
 }
-inline LottieColor operator+(const LottieColor &c1, const LottieColor &c2)
+inline Color operator+(const Color &c1, const Color &c2)
 {
-    return LottieColor(c1.r + c2.r, c1.g + c2.g, c1.b + c2.b);
+    return Color(c1.r + c2.r, c1.g + c2.g, c1.b + c2.b);
 }
 
-inline const LottieColor operator*(const LottieColor &c, float m)
-{ return LottieColor(c.r*m, c.g*m, c.b*m); }
-
-inline const LottieColor operator*(float m, const LottieColor &c)
-{ return LottieColor(c.r*m, c.g*m, c.b*m); }
+inline const Color operator*(const Color &c, float m)
+{
+    return Color(c.r * m, c.g * m, c.b * m);
+}
 
-class LottieShapeData
+inline const Color operator*(float m, const Color &c)
 {
-public:
-    void reserve(size_t size) {
-        mPoints.reserve(mPoints.size() + size);
-    }
-    static void lerp(const LottieShapeData& start, const LottieShapeData& end, float t, VPath& result)
+    return Color(c.r * m, c.g * m, c.b * m);
+}
+
+struct PathData {
+    std::vector<VPointF> mPoints;
+    bool                 mClosed = false; /* "c" */
+    void        reserve(size_t size) { mPoints.reserve(mPoints.size() + size); }
+    static void lerp(const PathData &start, const PathData &end, float t,
+                     VPath &result)
     {
         result.reset();
         auto size = std::min(start.mPoints.size(), end.mPoints.size());
@@ -129,16 +112,21 @@ public:
          * ptSize = size + 1(size + close)
          * elmSize = size/3 cubic + 1 move + 1 close
          */
-        result.reserve(size + 1 , size/3 + 2);
-        result.moveTo(start.mPoints[0] + t * (end.mPoints[0] - start.mPoints[0]));
-        for (size_t i = 1 ; i < size; i+=3) {
-           result.cubicTo(start.mPoints[i] + t * (end.mPoints[i] - start.mPoints[i]),
-                          start.mPoints[i+1] + t * (end.mPoints[i+1] - start.mPoints[i+1]),
-                          start.mPoints[i+2] + t * (end.mPoints[i+2] - start.mPoints[i+2]));
+        result.reserve(size + 1, size / 3 + 2);
+        result.moveTo(start.mPoints[0] +
+                      t * (end.mPoints[0] - start.mPoints[0]));
+        for (size_t i = 1; i < size; i += 3) {
+            result.cubicTo(
+                start.mPoints[i] + t * (end.mPoints[i] - start.mPoints[i]),
+                start.mPoints[i + 1] +
+                    t * (end.mPoints[i + 1] - start.mPoints[i + 1]),
+                start.mPoints[i + 2] +
+                    t * (end.mPoints[i + 2] - start.mPoints[i + 2]));
         }
         if (start.mClosed) result.close();
     }
-    void toPath(VPath& path) const {
+    void toPath(VPath &path) const
+    {
         path.reset();
 
         if (mPoints.empty()) return;
@@ -149,161 +137,150 @@ public:
          * ptSize = size + 1(size + close)
          * elmSize = size/3 cubic + 1 move + 1 close
          */
-        path.reserve(size + 1 , size/3 + 2);
+        path.reserve(size + 1, size / 3 + 2);
         path.moveTo(points[0]);
-        for (size_t i = 1 ; i < size; i+=3) {
-           path.cubicTo(points[i], points[i+1], points[i+2]);
+        for (size_t i = 1; i < size; i += 3) {
+            path.cubicTo(points[i], points[i + 1], points[i + 2]);
         }
-        if (mClosed)
-          path.close();
+        if (mClosed) path.close();
     }
-public:
-    std::vector<VPointF> mPoints;
-    bool                 mClosed = false;   /* "c" */
 };
 
-
-
-template<typename T>
-inline T lerp(const T& start, const T& end, float t)
-{
-    return start + t * (end - start);
-}
-
 template <typename T>
-struct LOTKeyFrameValue
-{
-    T mStartValue;
-    T mEndValue;
-    T value(float t) const {
-        return lerp(mStartValue, mEndValue, t);
-    }
-    float angle(float ) const { return 0;}
+struct Value {
+    T     mStartValue;
+    T     mEndValue;
+    T     at(float t) const { return lerp(mStartValue, mEndValue, t); }
+    float angle(float) const { return 0; }
 };
 
 template <>
-struct LOTKeyFrameValue<VPointF>
-{
+struct Value<VPointF> {
     VPointF mStartValue;
     VPointF mEndValue;
     VPointF mInTangent;
     VPointF mOutTangent;
     bool    mPathKeyFrame = false;
 
-    VPointF value(float t) const {
+    VPointF at(float t) const
+    {
         if (mPathKeyFrame) {
             /*
              * position along the path calcualated
              * using bezier at progress length (t * bezlen)
              */
-            VBezier b = VBezier::fromPoints(mStartValue, mStartValue + mOutTangent,
-                                       mEndValue + mInTangent, mEndValue);
+            VBezier b =
+                VBezier::fromPoints(mStartValue, mStartValue + mOutTangent,
+                                    mEndValue + mInTangent, mEndValue);
             return b.pointAt(b.tAtLength(t * b.length()));
-
         }
         return lerp(mStartValue, mEndValue, t);
     }
 
-    float angle(float t) const {
+    float angle(float t) const
+    {
         if (mPathKeyFrame) {
-            VBezier b = VBezier::fromPoints(mStartValue, mStartValue + mOutTangent,
-                                       mEndValue + mInTangent, mEndValue);
+            VBezier b =
+                VBezier::fromPoints(mStartValue, mStartValue + mOutTangent,
+                                    mEndValue + mInTangent, mEndValue);
             return b.angleAt(b.tAtLength(t * b.length()));
         }
         return 0;
     }
 };
 
-
-template<typename T>
-class LOTKeyFrame
-{
+template <typename T>
+class KeyFrame {
 public:
-    float progress(int frameNo) const {
-        return mInterpolator ? mInterpolator->value((frameNo - mStartFrame) / (mEndFrame - mStartFrame)) : 0;
-    }
-    T value(int frameNo) const {
-        return mValue.value(progress(frameNo));
-    }
-    float angle(int frameNo) const {
-        return mValue.angle(progress(frameNo));
+    float progress(int frameNo) const
+    {
+        return mInterpolator ? mInterpolator->value((frameNo - mStartFrame) /
+                                                    (mEndFrame - mStartFrame))
+                             : 0;
     }
+    T     value(int frameNo) const { return mValue.at(progress(frameNo)); }
+    float angle(int frameNo) const { return mValue.angle(progress(frameNo)); }
 
 public:
-    float                 mStartFrame{0};
-    float                 mEndFrame{0};
-    VInterpolator        *mInterpolator{nullptr};
-    LOTKeyFrameValue<T>   mValue;
+    float          mStartFrame{0};
+    float          mEndFrame{0};
+    VInterpolator *mInterpolator{nullptr};
+    Value<T>       mValue;
 };
 
-template<typename T>
-class LOTAnimInfo
-{
+template <typename T>
+class DynamicProperty {
 public:
-    T value(int frameNo) const {
+    T value(int frameNo) const
+    {
         if (mKeyFrames.front().mStartFrame >= frameNo)
             return mKeyFrames.front().mValue.mStartValue;
-        if(mKeyFrames.back().mEndFrame <= frameNo)
+        if (mKeyFrames.back().mEndFrame <= frameNo)
             return mKeyFrames.back().mValue.mEndValue;
 
-        for(const auto &keyFrame : mKeyFrames) {
+        for (const auto &keyFrame : mKeyFrames) {
             if (frameNo >= keyFrame.mStartFrame && frameNo < keyFrame.mEndFrame)
                 return keyFrame.value(frameNo);
         }
         return T();
     }
 
-    float angle(int frameNo) const {
+    float angle(int frameNo) const
+    {
         if ((mKeyFrames.front().mStartFrame >= frameNo) ||
-            (mKeyFrames.back().mEndFrame <= frameNo) )
+            (mKeyFrames.back().mEndFrame <= frameNo))
             return 0;
 
-        for(const auto &keyFrame : mKeyFrames) {
+        for (const auto &keyFrame : mKeyFrames) {
             if (frameNo >= keyFrame.mStartFrame && frameNo < keyFrame.mEndFrame)
                 return keyFrame.angle(frameNo);
         }
         return 0;
     }
 
-    bool changed(int prevFrame, int curFrame) const {
+    bool changed(int prevFrame, int curFrame) const
+    {
         auto first = mKeyFrames.front().mStartFrame;
         auto last = mKeyFrames.back().mEndFrame;
 
-        return !((first > prevFrame  && first > curFrame) ||
-                 (last < prevFrame  && last < curFrame));
+        return !((first > prevFrame && first > curFrame) ||
+                 (last < prevFrame && last < curFrame));
     }
 
 public:
-    std::vector<LOTKeyFrame<T>>    mKeyFrames;
+    std::vector<KeyFrame<T>> mKeyFrames;
 };
 
-template<typename T>
-class LOTAnimatable
-{
+template <typename T>
+class Property {
 public:
-    LOTAnimatable() { construct(impl.mValue, {}); }
-    explicit LOTAnimatable(T value) { construct(impl.mValue, std::move(value)); }
+    Property() { construct(impl.mValue, {}); }
+    explicit Property(T value) { construct(impl.mValue, std::move(value)); }
 
-    const LOTAnimInfo<T>& animation() const {return *(impl.mAnimInfo.get());}
-    const T& value() const {return impl.mValue;}
+    const DynamicProperty<T> &animation() const
+    {
+        return *(impl.mAnimInfo.get());
+    }
+    const T &value() const { return impl.mValue; }
 
-    LOTAnimInfo<T>& animation()
+    DynamicProperty<T> &animation()
     {
         if (mStatic) {
             destroy();
-            construct(impl.mAnimInfo, std::make_unique<LOTAnimInfo<T>>());
+            construct(impl.mAnimInfo, std::make_unique<DynamicProperty<T>>());
             mStatic = false;
         }
         return *(impl.mAnimInfo.get());
     }
 
-    Tvalue()
+    T &value()
     {
         assert(mStatic);
         return impl.mValue;
     }
 
-    LOTAnimatable(LOTAnimatable &&other) noexcept {
+    Property(Property &&other) noexcept
+    {
         if (!other.mStatic) {
             construct(impl.mAnimInfo, std::move(other.impl.mAnimInfo));
             mStatic = false;
@@ -313,21 +290,23 @@ public:
         }
     }
     // delete special member functions
-    LOTAnimatable(const LOTAnimatable &) = delete;
-    LOTAnimatable& operator=(const LOTAnimatable&) = delete;
-    LOTAnimatable& operator=(LOTAnimatable&&) = delete;
+    Property(const Property &) = delete;
+    Property &operator=(const Property &) = delete;
+    Property &operator=(Property &&) = delete;
 
-    ~LOTAnimatable() {destroy();}
+    ~Property() { destroy(); }
 
-    bool isStatic() const {return mStatic;}
+    bool isStatic() const { return mStatic; }
 
-    T value(int frameNo) const {
+    T value(int frameNo) const
+    {
         return isStatic() ? value() : animation().value(frameNo);
     }
 
-    // special function only for type T=LottieShapeData
-    template <typename SpecialT = LottieShapeData>
-    auto value(int frameNo, VPath& path) const-> typename std::enable_if_t<std::is_same<T, SpecialT>::value, void>
+    // special function only for type T=PathData
+    template <typename SpecialT = PathData>
+    auto value(int frameNo, VPath &path) const ->
+        typename std::enable_if_t<std::is_same<T, SpecialT>::value, void>
     {
         if (isStatic()) {
             value().toPath(path);
@@ -335,71 +314,97 @@ public:
             const auto &vec = animation().mKeyFrames;
             if (vec.front().mStartFrame >= frameNo)
                 return vec.front().mValue.mStartValue.toPath(path);
-            if(vec.back().mEndFrame <= frameNo)
+            if (vec.back().mEndFrame <= frameNo)
                 return vec.back().mValue.mEndValue.toPath(path);
 
-            for(const auto &keyFrame : vec) {
-                if (frameNo >= keyFrame.mStartFrame && frameNo < keyFrame.mEndFrame) {
-                    LottieShapeData::lerp(keyFrame.mValue.mStartValue,
-                                          keyFrame.mValue.mEndValue,
-                                          keyFrame.progress(frameNo),
-                                          path);
+            for (const auto &keyFrame : vec) {
+                if (frameNo >= keyFrame.mStartFrame &&
+                    frameNo < keyFrame.mEndFrame) {
+                    PathData::lerp(keyFrame.mValue.mStartValue,
+                                   keyFrame.mValue.mEndValue,
+                                   keyFrame.progress(frameNo), path);
                 }
             }
         }
     }
 
-    float angle(int frameNo) const {
+    float angle(int frameNo) const
+    {
         return isStatic() ? 0 : animation().angle(frameNo);
     }
 
-    bool changed(int prevFrame, int curFrame) const {
+    bool changed(int prevFrame, int curFrame) const
+    {
         return isStatic() ? false : animation().changed(prevFrame, curFrame);
     }
+
 private:
     template <typename Tp>
-    void construct(Tp& member, Tp&& val)
+    void construct(Tp &member, Tp &&val)
     {
         new (&member) Tp(std::move(val));
     }
 
-    void destroy() {
+    void destroy()
+    {
         if (mStatic) {
             impl.mValue.~T();
         } else {
             using std::unique_ptr;
-            impl.mAnimInfo.~unique_ptr<LOTAnimInfo<T>>();
+            impl.mAnimInfo.~unique_ptr<DynamicProperty<T>>();
         }
     }
     union details {
-        std::unique_ptr<LOTAnimInfo<T>>   mAnimInfo;
-        T                                 mValue;
+        std::unique_ptr<DynamicProperty<T>> mAnimInfo;
+        T                                   mValue;
         details(){};
-        details(const details&) = delete;
-        details(details&&) = delete;
-        details& operator=(details&&) = delete;
-        details& operator=(const details&) = delete;
+        details(const details &) = delete;
+        details(details &&) = delete;
+        details &operator=(details &&) = delete;
+        details &operator=(const details &) = delete;
         ~details(){};
-    }impl;
-    bool                                 mStatic{true};
+    } impl;
+    bool mStatic{true};
 };
 
-enum class LottieBlendMode: uchar
-{
-    Normal = 0,
-    Multiply = 1,
-    Screen = 2,
-    OverLay = 3
+class Path;
+struct PathData;
+struct Dash {
+    std::vector<Property<float>> mData;
+    bool                         empty() const { return mData.empty(); }
+    size_t                       size() const { return mData.size(); }
+    bool                         isStatic() const
+    {
+        for (const auto &elm : mData)
+            if (!elm.isStatic()) return false;
+        return true;
+    }
+    void getDashInfo(int frameNo, std::vector<float> &result) const;
 };
 
-class LOTDataVisitor;
-class LOTData
-{
+class Mask {
+public:
+    enum class Mode { None, Add, Substarct, Intersect, Difference };
+    float opacity(int frameNo) const
+    {
+        return mOpacity.value(frameNo) / 100.0f;
+    }
+    bool isStatic() const { return mIsStatic; }
+
+public:
+    Property<PathData> mShape;
+    Property<float>    mOpacity{100};
+    bool               mInv{false};
+    bool               mIsStatic{true};
+    Mask::Mode         mMode;
+};
+
+class Object {
 public:
-    enum class Type :unsigned char {
+    enum class Type : unsigned char {
         Composition = 1,
         Layer,
-        ShapeGroup,
+        Group,
         Transform,
         Fill,
         Stroke,
@@ -407,54 +412,57 @@ public:
         GStroke,
         Rect,
         Ellipse,
-        Shape,
+        Path,
         Polystar,
         Trim,
         Repeater
     };
 
-    explicit LOTData(LOTData::Type type):mPtr(nullptr)
+    explicit Object(Object::Type type) : mPtr(nullptr)
     {
-       mData._type = type;
-       mData._static = true;
-       mData._shortString = true;
-       mData._hidden = false;
+        mData._type = type;
+        mData._static = true;
+        mData._shortString = true;
+        mData._hidden = false;
     }
-    ~LOTData() { if (!shortString() && mPtr) free(mPtr); }
-    LOTData(const LOTData&) = delete;
-    LOTData& operator =(const LOTData&) = delete;
-
-    void setStatic(bool value) { mData._static = value;}
-    bool isStatic() const {return mData._static;}
-    bool hidden() const {return mData._hidden;}
-    void setHidden(bool value) {mData._hidden = value;}
-    void setType(LOTData::Type type) {mData._type = type;}
-    LOTData::Type type() const { return mData._type;}
-    void setName(const char *name)
+    ~Object()
+    {
+        if (!shortString() && mPtr) free(mPtr);
+    }
+    Object(const Object &) = delete;
+    Object &operator=(const Object &) = delete;
+
+    void         setStatic(bool value) { mData._static = value; }
+    bool         isStatic() const { return mData._static; }
+    bool         hidden() const { return mData._hidden; }
+    void         setHidden(bool value) { mData._hidden = value; }
+    void         setType(Object::Type type) { mData._type = type; }
+    Object::Type type() const { return mData._type; }
+    void         setName(const char *name)
     {
         if (name) {
             auto len = strlen(name);
             if (len < maxShortStringLength) {
                 setShortString(true);
-                strncpy ( mData._buffer, name, len+1);
+                strncpy(mData._buffer, name, len + 1);
             } else {
                 setShortString(false);
                 mPtr = strdup(name);
             }
-
         }
     }
-    const char* name() const {return shortString() ? mData._buffer : mPtr;}
+    const char *name() const { return shortString() ? mData._buffer : mPtr; }
+
 private:
     static constexpr unsigned char maxShortStringLength = 14;
-    void setShortString(bool value) {mData._shortString = value;}
-    bool shortString() const {return mData._shortString;}
-    struct Data{
-      char           _buffer[maxShortStringLength];
-      LOTData::Type  _type;
-      bool           _static      : 1;
-      bool           _hidden      : 1;
-      bool           _shortString : 1;
+    void setShortString(bool value) { mData._shortString = value; }
+    bool shortString() const { return mData._shortString; }
+    struct Data {
+        char         _buffer[maxShortStringLength];
+        Object::Type _type;
+        bool         _static : 1;
+        bool         _hidden : 1;
+        bool         _shortString : 1;
     };
     union {
         Data  mData;
@@ -462,80 +470,113 @@ private:
     };
 };
 
-class LOTGroupData: public LOTData
-{
-public:
-    explicit LOTGroupData(LOTData::Type  type):LOTData(type){}
-public:
-    std::vector<LOTData *>  mChildren;
-    LOTTransformData       *mTransform{nullptr};
-};
-
-class LOTShapeGroupData : public LOTGroupData
-{
-public:
-    LOTShapeGroupData():LOTGroupData(LOTData::Type::ShapeGroup){}
-};
-
-class LOTLayerData;
-struct LOTAsset
-{
-    enum class Type : unsigned char{
-        Precomp,
-        Image,
-        Char
-    };
-    bool isStatic() const {return mStatic;}
-    void setStatic(bool value) {mStatic = value;}
-    VBitmap  bitmap() const {return mBitmap;}
-    void loadImageData(std::string data);
-    void loadImagePath(std::string Path);
-    Type                                      mAssetType{Type::Precomp};
-    bool                                      mStatic{true};
-    std::string                               mRefId; // ref id
-    std::vector<LOTData *>                    mLayers;
+struct Asset {
+    enum class Type : unsigned char { Precomp, Image, Char };
+    bool                  isStatic() const { return mStatic; }
+    void                  setStatic(bool value) { mStatic = value; }
+    VBitmap               bitmap() const { return mBitmap; }
+    void                  loadImageData(std::string data);
+    void                  loadImagePath(std::string Path);
+    Type                  mAssetType{Type::Precomp};
+    bool                  mStatic{true};
+    std::string           mRefId;  // ref id
+    std::vector<Object *> mLayers;
     // image asset data
-    int                                       mWidth{0};
-    int                                       mHeight{0};
-    VBitmap                                   mBitmap;
+    int     mWidth{0};
+    int     mHeight{0};
+    VBitmap mBitmap;
 };
 
-struct TransformDataExtra
-{
-    LOTAnimatable<float>     m3DRx{0};
-    LOTAnimatable<float>     m3DRy{0};
-    LOTAnimatable<float>     m3DRz{0};
-    LOTAnimatable<float>     mSeparateX{0};
-    LOTAnimatable<float>     mSeparateY{0};
-    bool                     mSeparate{false};
-    bool                     m3DData{false};
-};
+class Layer;
 
-struct TransformData
-{
-    VMatrix matrix(int frameNo, bool autoOrient = false) const;
-    float opacity(int frameNo) const { return mOpacity.value(frameNo)/100.0f; }
-    void createExtraData()
+class Composition : public Object {
+public:
+    Composition() : Object(Object::Type::Composition) {}
+    std::vector<LayerInfo>     layerInfoList() const;
+    const std::vector<Marker> &markers() const { return mMarkers; }
+    double                     duration() const
+    {
+        return frameDuration() / frameRate();  // in second
+    }
+    size_t frameAtPos(double pos) const
     {
-        if (!mExtra) mExtra = std::make_unique<TransformDataExtra>();
+        if (pos < 0) pos = 0;
+        if (pos > 1) pos = 1;
+        return size_t(round(pos * frameDuration()));
     }
-    LOTAnimatable<float>                   mRotation{0};  /* "r" */
-    LOTAnimatable<VPointF>                 mScale{{100, 100}};     /* "s" */
-    LOTAnimatable<VPointF>                 mPosition;  /* "p" */
-    LOTAnimatable<VPointF>                 mAnchor;    /* "a" */
-    LOTAnimatable<float>                   mOpacity{100};   /* "o" */
-    std::unique_ptr<TransformDataExtra>    mExtra;
+    long frameAtTime(double timeInSec) const
+    {
+        return long(frameAtPos(timeInSec / duration()));
+    }
+    size_t totalFrame() const { return mEndFrame - mStartFrame; }
+    long   frameDuration() const { return mEndFrame - mStartFrame - 1; }
+    float  frameRate() const { return mFrameRate; }
+    size_t startFrame() const { return mStartFrame; }
+    size_t endFrame() const { return mEndFrame; }
+    VSize  size() const { return mSize; }
+    void   processRepeaterObjects();
+    void   updateStats();
+
+public:
+    struct Stats {
+        uint16_t precompLayerCount{0};
+        uint16_t solidLayerCount{0};
+        uint16_t shapeLayerCount{0};
+        uint16_t imageLayerCount{0};
+        uint16_t nullLayerCount{0};
+    };
+
+public:
+    std::string                              mVersion;
+    VSize                                    mSize;
+    long                                     mStartFrame{0};
+    long                                     mEndFrame{0};
+    float                                    mFrameRate{60};
+    BlendMode                                mBlendMode{BlendMode::Normal};
+    Layer *                                  mRootLayer{nullptr};
+    std::unordered_map<std::string, Asset *> mAssets;
+
+    std::vector<Marker> mMarkers;
+    VArenaAlloc         mArenaAlloc{2048};
+    Stats               mStats;
 };
 
-class LOTTransformData : public LOTData
-{
+class Transform : public Object {
 public:
-    LOTTransformData():LOTData(LOTData::Type::Transform){}
-    void set(TransformData* data, bool staticFlag)
+    struct Data {
+        struct Extra {
+            Property<float> m3DRx{0};
+            Property<float> m3DRy{0};
+            Property<float> m3DRz{0};
+            Property<float> mSeparateX{0};
+            Property<float> mSeparateY{0};
+            bool            mSeparate{false};
+            bool            m3DData{false};
+        };
+        VMatrix matrix(int frameNo, bool autoOrient = false) const;
+        float   opacity(int frameNo) const
+        {
+            return mOpacity.value(frameNo) / 100.0f;
+        }
+        void createExtraData()
+        {
+            if (!mExtra) mExtra = std::make_unique<Extra>();
+        }
+        Property<float>        mRotation{0};       /* "r" */
+        Property<VPointF>      mScale{{100, 100}}; /* "s" */
+        Property<VPointF>      mPosition;          /* "p" */
+        Property<VPointF>      mAnchor;            /* "a" */
+        Property<float>        mOpacity{100};      /* "o" */
+        std::unique_ptr<Extra> mExtra;
+    };
+
+    Transform() : Object(Object::Type::Transform) {}
+    void set(Transform::Data *data, bool staticFlag)
     {
         setStatic(staticFlag);
         if (isStatic()) {
-            new (&impl.mStaticData) static_data(data->matrix(0), data->opacity(0));
+            new (&impl.mStaticData)
+                StaticData(data->matrix(0), data->opacity(0));
         } else {
             impl.mData = data;
         }
@@ -550,153 +591,131 @@ public:
         if (isStatic()) return impl.mStaticData.mOpacity;
         return impl.mData->opacity(frameNo);
     }
-    LOTTransformData(const LOTTransformData&) = delete;
-    LOTTransformData(LOTTransformData&&) = delete;
-    LOTTransformData& operator=(LOTTransformData&) = delete;
-    LOTTransformData& operator=(LOTTransformData&&) = delete;
-    ~LOTTransformData() {destroy();}
+    Transform(const Transform &) = delete;
+    Transform(Transform &&) = delete;
+    Transform &operator=(Transform &) = delete;
+    Transform &operator=(Transform &&) = delete;
+    ~Transform() { destroy(); }
 
 private:
-    void destroy() {
+    void destroy()
+    {
         if (isStatic()) {
-            impl.mStaticData.~static_data();
+            impl.mStaticData.~StaticData();
         }
     }
-    struct static_data {
-       static_data(VMatrix &&m, float opacity):
-           mOpacity(opacity), mMatrix(std::move(m)){}
-       float    mOpacity;
-       VMatrix  mMatrix;
+    struct StaticData {
+        StaticData(VMatrix &&m, float opacity)
+            : mOpacity(opacity), mMatrix(std::move(m))
+        {
+        }
+        float   mOpacity;
+        VMatrix mMatrix;
     };
     union details {
-        TransformData     *mData{nullptr};
-        static_data        mStaticData;
+        Data *     mData{nullptr};
+        StaticData mStaticData;
         details(){};
-        details(const details&) = delete;
-        details(details&&) = delete;
-        details& operator=(details&&) = delete;
-        details& operator=(const details&) = delete;
+        details(const details &) = delete;
+        details(details &&) = delete;
+        details &operator=(details &&) = delete;
+        details &operator=(const details &) = delete;
         ~details(){};
-    }impl;
+    } impl;
 };
 
-struct ExtraLayerData
-{
-    LottieColor                mSolidColor;
-    std::string                mPreCompRefId;
-    LOTAnimatable<float>       mTimeRemap;  /* "tm" */
-    LOTCompositionData        *mCompRef{nullptr};
-    LOTAsset                  *mAsset{nullptr};
-    std::vector<LOTMaskData *>  mMasks;
+class Group : public Object {
+public:
+    Group() : Object(Object::Type::Group) {}
+    explicit Group(Object::Type type) : Object(type) {}
+
+public:
+    std::vector<Object *> mChildren;
+    Transform *           mTransform{nullptr};
 };
 
-class LOTLayerData : public LOTGroupData
-{
+class Layer : public Group {
 public:
-    LOTLayerData():LOTGroupData(LOTData::Type::Layer){}
-    bool hasPathOperator() const noexcept {return mHasPathOperator;}
-    bool hasGradient() const noexcept {return mHasGradient;}
-    bool hasMask() const noexcept {return mHasMask;}
-    bool hasRepeater() const noexcept {return mHasRepeater;}
-    int id() const noexcept{ return mId;}
-    int parentId() const noexcept{ return mParentId;}
-    bool hasParent() const noexcept {return mParentId != -1;}
-    int inFrame() const noexcept{return mInFrame;}
-    int outFrame() const noexcept{return mOutFrame;}
-    int startFrame() const noexcept{return mStartFrame;}
-    LottieColor solidColor() const noexcept{return mExtra->mSolidColor;}
-    bool autoOrient() const noexcept{return mAutoOrient;}
-    int timeRemap(int frameNo) const;
-    VSize layerSize() const {return mLayerSize;}
-    bool precompLayer() const {return mLayerType == LayerType::Precomp;}
+    enum class Type : uchar {
+        Precomp = 0,
+        Solid = 1,
+        Image = 2,
+        Null = 3,
+        Shape = 4,
+        Text = 5
+    };
+    Layer() : Group(Object::Type::Layer) {}
+    bool    hasPathOperator() const noexcept { return mHasPathOperator; }
+    bool    hasGradient() const noexcept { return mHasGradient; }
+    bool    hasMask() const noexcept { return mHasMask; }
+    bool    hasRepeater() const noexcept { return mHasRepeater; }
+    int     id() const noexcept { return mId; }
+    int     parentId() const noexcept { return mParentId; }
+    bool    hasParent() const noexcept { return mParentId != -1; }
+    int     inFrame() const noexcept { return mInFrame; }
+    int     outFrame() const noexcept { return mOutFrame; }
+    int     startFrame() const noexcept { return mStartFrame; }
+    Color   solidColor() const noexcept { return mExtra->mSolidColor; }
+    bool    autoOrient() const noexcept { return mAutoOrient; }
+    int     timeRemap(int frameNo) const;
+    VSize   layerSize() const { return mLayerSize; }
+    bool    precompLayer() const { return mLayerType == Type::Precomp; }
     VMatrix matrix(int frameNo) const
     {
-        return mTransform ? mTransform->matrix(frameNo, autoOrient()) : VMatrix{};
+        return mTransform ? mTransform->matrix(frameNo, autoOrient())
+                          : VMatrix{};
     }
     float opacity(int frameNo) const
     {
         return mTransform ? mTransform->opacity(frameNo) : 1.0f;
     }
-    LOTAsset* asset() const
+    Asset *asset() const
     {
         return (mExtra && mExtra->mAsset) ? mExtra->mAsset : nullptr;
     }
-public:
-    ExtraLayerData* extra()
+    struct Extra {
+        Color               mSolidColor;
+        std::string         mPreCompRefId;
+        Property<float>     mTimeRemap; /* "tm" */
+        Composition *       mCompRef{nullptr};
+        Asset *             mAsset{nullptr};
+        std::vector<Mask *> mMasks;
+    };
+
+    Layer::Extra *extra()
     {
-        if (!mExtra) mExtra = std::make_unique<ExtraLayerData>();
+        if (!mExtra) mExtra = std::make_unique<Layer::Extra>();
         return mExtra.get();
     }
-    MatteType            mMatteType{MatteType::None};
-    LayerType            mLayerType{LayerType::Null};
-    LottieBlendMode      mBlendMode{LottieBlendMode::Normal};
-    bool                 mHasPathOperator{false};
-    bool                 mHasMask{false};
-    bool                 mHasRepeater{false};
-    bool                 mHasGradient{false};
-    bool                 mAutoOrient{false};
-    VSize                mLayerSize;
-    int                  mParentId{-1}; // Lottie the id of the parent in the composition
-    int                  mId{-1};  // Lottie the group id  used for parenting.
-    float                mTimeStreatch{1.0f};
-    int                  mInFrame{0};
-    int                  mOutFrame{0};
-    int                  mStartFrame{0};
-    std::unique_ptr<ExtraLayerData> mExtra{nullptr};
-};
-
-using Marker = std::tuple<std::string, int , int>;
-using LayerInfo = Marker;
 
-class LOTCompositionData : public LOTData
-{
 public:
-    LOTCompositionData():LOTData(LOTData::Type::Composition){}
-    std::vector<LayerInfo> layerInfoList() const;
-    const std::vector<Marker> &markers() const { return  mMarkers;}
-    double duration() const {
-        return frameDuration() / frameRate(); // in second
-    }
-    size_t frameAtPos(double pos) const {
-        if (pos < 0) pos = 0;
-        if (pos > 1) pos = 1;
-        return size_t(round(pos * frameDuration()));
-    }
-    long frameAtTime(double timeInSec) const {
-        return long(frameAtPos(timeInSec / duration()));
-    }
-    size_t totalFrame() const {return mEndFrame - mStartFrame;}
-    long frameDuration() const {return mEndFrame - mStartFrame -1;}
-    float frameRate() const {return mFrameRate;}
-    long startFrame() const {return mStartFrame;}
-    long endFrame() const {return mEndFrame;}
-    VSize size() const {return mSize;}
-    void processRepeaterObjects();
-    void updateStats();
-public:
-    std::string          mVersion;
-    VSize                mSize;
-    long                 mStartFrame{0};
-    long                 mEndFrame{0};
-    float                mFrameRate{60};
-    LottieBlendMode      mBlendMode{LottieBlendMode::Normal};
-    LOTLayerData        *mRootLayer{nullptr};
-    std::unordered_map<std::string,
-                       LOTAsset*>    mAssets;
-
-    std::vector<Marker>     mMarkers;
-    VArenaAlloc             mArenaAlloc{2048};
-    LOTModelStat            mStats;
+    MatteType mMatteType{MatteType::None};
+    Type      mLayerType{Layer::Type::Null};
+    BlendMode mBlendMode{BlendMode::Normal};
+    bool      mHasPathOperator{false};
+    bool      mHasMask{false};
+    bool      mHasRepeater{false};
+    bool      mHasGradient{false};
+    bool      mAutoOrient{false};
+    VSize     mLayerSize;
+    int       mParentId{-1};  // Lottie the id of the parent in the composition
+    int       mId{-1};        // Lottie the group id  used for parenting.
+    float     mTimeStreatch{1.0f};
+    int       mInFrame{0};
+    int       mOutFrame{0};
+    int       mStartFrame{0};
+    std::unique_ptr<Extra> mExtra{nullptr};
 };
 
 /**
  * TimeRemap has the value in time domain(in sec)
- * To get the proper mapping first we get the mapped time at the current frame Number
- * then we need to convert mapped time to frame number using the composition time line
- * Ex: at frame 10 the mappend time is 0.5(500 ms) which will be convert to frame number
- * 30 if the frame rate is 60. or will result to frame number 15 if the frame rate is 30.
+ * To get the proper mapping first we get the mapped time at the current frame
+ * Number then we need to convert mapped time to frame number using the
+ * composition time line Ex: at frame 10 the mappend time is 0.5(500 ms) which
+ * will be convert to frame number 30 if the frame rate is 60. or will result to
+ * frame number 15 if the frame rate is 30.
  */
-inline int LOTLayerData::timeRemap(int frameNo) const
+inline int Layer::timeRemap(int frameNo) const
 {
     /*
      * only consider startFrame() when there is no timeRemap.
@@ -706,277 +725,247 @@ inline int LOTLayerData::timeRemap(int frameNo) const
     if (!mExtra || mExtra->mTimeRemap.isStatic())
         frameNo = frameNo - startFrame();
     else
-        frameNo = mExtra->mCompRef->frameAtTime(mExtra->mTimeRemap.value(frameNo));
+        frameNo =
+            mExtra->mCompRef->frameAtTime(mExtra->mTimeRemap.value(frameNo));
     /* Apply time streatch if it has any.
-     * Time streatch is just a factor by which the animation will speedup or slow
-     * down with respect to the overal animation.
-     * Time streach factor is already applied to the layers inFrame and outFrame.
-     * @TODO need to find out if timestreatch also affects the in and out frame of the
-     * child layers or not. */
+     * Time streatch is just a factor by which the animation will speedup or
+     * slow down with respect to the overal animation. Time streach factor is
+     * already applied to the layers inFrame and outFrame.
+     * @TODO need to find out if timestreatch also affects the in and out frame
+     * of the child layers or not. */
     return int(frameNo / mTimeStreatch);
 }
 
-class LOTFillData : public LOTData
-{
+class Stroke : public Object {
 public:
-    LOTFillData():LOTData(LOTData::Type::Fill){}
-    LottieColor color(int frameNo) const {return mColor.value(frameNo);}
-    float opacity(int frameNo) const {return mOpacity.value(frameNo)/100.0f;}
-    FillRule fillRule() const {return mFillRule;}
-public:
-    FillRule                       mFillRule{FillRule::Winding}; /* "r" */
-    bool                           mEnabled{true}; /* "fillEnabled" */
-    LOTAnimatable<LottieColor>     mColor;   /* "c" */
-    LOTAnimatable<float>           mOpacity{100};  /* "o" */
-};
-
-struct LOTDashProperty
-{
-    std::vector<LOTAnimatable<float>> mData;
-    bool empty() const {return mData.empty();}
-    size_t size() const {return mData.size();}
-    bool isStatic() const {
-        for(const auto &elm : mData)
-            if (!elm.isStatic()) return false;
-        return true;
+    Stroke() : Object(Object::Type::Stroke) {}
+    Color color(int frameNo) const { return mColor.value(frameNo); }
+    float opacity(int frameNo) const
+    {
+        return mOpacity.value(frameNo) / 100.0f;
     }
-    void getDashInfo(int frameNo, std::vector<float>& result) const;
-};
-
-class LOTStrokeData : public LOTData
-{
-public:
-    LOTStrokeData():LOTData(LOTData::Type::Stroke){}
-    LottieColor color(int frameNo) const {return mColor.value(frameNo);}
-    float opacity(int frameNo) const {return mOpacity.value(frameNo)/100.0f;}
-    float strokeWidth(int frameNo) const {return mWidth.value(frameNo);}
-    CapStyle capStyle() const {return mCapStyle;}
-    JoinStyle joinStyle() const {return mJoinStyle;}
-    float miterLimit() const{return mMiterLimit;}
-    bool  hasDashInfo() const {return !mDash.empty();}
-    void getDashInfo(int frameNo, std::vector<float>& result) const
+    float     strokeWidth(int frameNo) const { return mWidth.value(frameNo); }
+    CapStyle  capStyle() const { return mCapStyle; }
+    JoinStyle joinStyle() const { return mJoinStyle; }
+    float     miterLimit() const { return mMiterLimit; }
+    bool      hasDashInfo() const { return !mDash.empty(); }
+    void      getDashInfo(int frameNo, std::vector<float> &result) const
     {
         return mDash.getDashInfo(frameNo, result);
     }
-public:
-    LOTAnimatable<LottieColor>        mColor;      /* "c" */
-    LOTAnimatable<float>              mOpacity{100};    /* "o" */
-    LOTAnimatable<float>              mWidth{0};      /* "w" */
-    CapStyle                          mCapStyle{CapStyle::Flat};   /* "lc" */
-    JoinStyle                         mJoinStyle{JoinStyle::Miter};  /* "lj" */
-    float                             mMiterLimit{0}; /* "ml" */
-    LOTDashProperty                   mDash;
-    bool                              mEnabled{true}; /* "fillEnabled" */
-};
 
-class LottieGradient
-{
-public:
-    friend inline LottieGradient operator+(const LottieGradient &g1, const LottieGradient &g2);
-    friend inline LottieGradient operator-(const LottieGradient &g1, const LottieGradient &g2);
-    friend inline LottieGradient operator*(float m, const LottieGradient &g);
 public:
-    std::vector<float>    mGradient;
+    Property<Color> mColor;                       /* "c" */
+    Property<float> mOpacity{100};                /* "o" */
+    Property<float> mWidth{0};                    /* "w" */
+    CapStyle        mCapStyle{CapStyle::Flat};    /* "lc" */
+    JoinStyle       mJoinStyle{JoinStyle::Miter}; /* "lj" */
+    float           mMiterLimit{0};               /* "ml" */
+    Dash            mDash;
+    bool            mEnabled{true}; /* "fillEnabled" */
 };
 
-inline LottieGradient operator+(const LottieGradient &g1, const LottieGradient &g2)
-{
-    if (g1.mGradient.size() != g2.mGradient.size())
-        return g1;
-
-    LottieGradient newG;
-    newG.mGradient = g1.mGradient;
-
-    auto g2It = g2.mGradient.begin();
-    for(auto &i : newG.mGradient) {
-        i = i + *g2It;
-        g2It++;
-    }
-
-    return newG;
-}
-
-inline LottieGradient operator-(const LottieGradient &g1, const LottieGradient &g2)
-{
-    if (g1.mGradient.size() != g2.mGradient.size())
-        return g1;
-    LottieGradient newG;
-    newG.mGradient = g1.mGradient;
-
-    auto g2It = g2.mGradient.begin();
-    for(auto &i : newG.mGradient) {
-        i = i - *g2It;
-        g2It++;
-    }
-
-    return newG;
-}
-
-inline LottieGradient operator*(float m, const LottieGradient &g)
-{
-    LottieGradient newG;
-    newG.mGradient = g.mGradient;
-
-    for(auto &i : newG.mGradient) {
-        i = i * m;
+class Gradient : public Object {
+public:
+    class Data {
+    public:
+        friend inline Gradient::Data operator+(const Gradient::Data &g1,
+                                               const Gradient::Data &g2);
+        friend inline Gradient::Data operator-(const Gradient::Data &g1,
+                                               const Gradient::Data &g2);
+        friend inline Gradient::Data operator*(float                 m,
+                                               const Gradient::Data &g);
+
+    public:
+        std::vector<float> mGradient;
+    };
+    explicit Gradient(Object::Type type) : Object(type) {}
+    inline float opacity(int frameNo) const
+    {
+        return mOpacity.value(frameNo) / 100.0f;
     }
-    return newG;
-}
+    void update(std::unique_ptr<VGradient> &grad, int frameNo);
 
+private:
+    void populate(VGradientStops &stops, int frameNo);
 
+public:
+    int                      mGradientType{1};    /* "t" Linear=1 , Radial = 2*/
+    Property<VPointF>        mStartPoint;         /* "s" */
+    Property<VPointF>        mEndPoint;           /* "e" */
+    Property<float>          mHighlightLength{0}; /* "h" */
+    Property<float>          mHighlightAngle{0};  /* "a" */
+    Property<float>          mOpacity{100};       /* "o" */
+    Property<Gradient::Data> mGradient;           /* "g" */
+    int                      mColorPoints{-1};
+    bool                     mEnabled{true}; /* "fillEnabled" */
+};
 
-class LOTGradient : public LOTData
-{
+class GradientStroke : public Gradient {
 public:
-    explicit LOTGradient(LOTData::Type  type):LOTData(type){}
-    inline float opacity(int frameNo) const {return mOpacity.value(frameNo)/100.0f;}
-    void update(std::unique_ptr<VGradient> &grad, int frameNo);
+    GradientStroke() : Gradient(Object::Type::GStroke) {}
+    float     width(int frameNo) const { return mWidth.value(frameNo); }
+    CapStyle  capStyle() const { return mCapStyle; }
+    JoinStyle joinStyle() const { return mJoinStyle; }
+    float     miterLimit() const { return mMiterLimit; }
+    bool      hasDashInfo() const { return !mDash.empty(); }
+    void      getDashInfo(int frameNo, std::vector<float> &result) const
+    {
+        return mDash.getDashInfo(frameNo, result);
+    }
 
-private:
-    void populate(VGradientStops &stops, int frameNo);
 public:
-    int                                 mGradientType{1};        /* "t" Linear=1 , Radial = 2*/
-    LOTAnimatable<VPointF>              mStartPoint;          /* "s" */
-    LOTAnimatable<VPointF>              mEndPoint;            /* "e" */
-    LOTAnimatable<float>                mHighlightLength{0};     /* "h" */
-    LOTAnimatable<float>                mHighlightAngle{0};      /* "a" */
-    LOTAnimatable<float>                mOpacity{100};             /* "o" */
-    LOTAnimatable<LottieGradient>       mGradient;            /* "g" */
-    int                                 mColorPoints{-1};
-    bool                                mEnabled{true};      /* "fillEnabled" */
+    Property<float> mWidth;                       /* "w" */
+    CapStyle        mCapStyle{CapStyle::Flat};    /* "lc" */
+    JoinStyle       mJoinStyle{JoinStyle::Miter}; /* "lj" */
+    float           mMiterLimit{0};               /* "ml" */
+    Dash            mDash;
 };
 
-class LOTGFillData : public LOTGradient
-{
+class GradientFill : public Gradient {
 public:
-    LOTGFillData():LOTGradient(LOTData::Type::GFill){}
-    FillRule fillRule() const {return mFillRule;}
+    GradientFill() : Gradient(Object::Type::GFill) {}
+    FillRule fillRule() const { return mFillRule; }
+
 public:
-    FillRule                       mFillRule{FillRule::Winding}; /* "r" */
+    FillRule mFillRule{FillRule::Winding}; /* "r" */
 };
 
-class LOTGStrokeData : public LOTGradient
-{
+class Fill : public Object {
 public:
-    LOTGStrokeData():LOTGradient(LOTData::Type::GStroke){}
-    float width(int frameNo) const {return mWidth.value(frameNo);}
-    CapStyle capStyle() const {return mCapStyle;}
-    JoinStyle joinStyle() const {return mJoinStyle;}
-    float miterLimit() const{return mMiterLimit;}
-    bool  hasDashInfo() const {return !mDash.empty();}
-    void getDashInfo(int frameNo, std::vector<float>& result) const
+    Fill() : Object(Object::Type::Fill) {}
+    Color color(int frameNo) const { return mColor.value(frameNo); }
+    float opacity(int frameNo) const
     {
-        return mDash.getDashInfo(frameNo, result);
+        return mOpacity.value(frameNo) / 100.0f;
     }
+    FillRule fillRule() const { return mFillRule; }
+
 public:
-    LOTAnimatable<float>           mWidth;       /* "w" */
-    CapStyle                       mCapStyle{CapStyle::Flat};    /* "lc" */
-    JoinStyle                      mJoinStyle{JoinStyle::Miter};   /* "lj" */
-    float                          mMiterLimit{0};  /* "ml" */
-    LOTDashProperty                mDash;
+    FillRule        mFillRule{FillRule::Winding}; /* "r" */
+    bool            mEnabled{true};               /* "fillEnabled" */
+    Property<Color> mColor;                       /* "c" */
+    Property<float> mOpacity{100};                /* "o" */
 };
 
-class LOTPath : public LOTData
-{
+class Shape : public Object {
 public:
-    explicit LOTPath(LOTData::Type  type):LOTData(type){}
-    VPath::Direction direction() {
-        return (mDirection == 3) ?
-               VPath::Direction::CCW : VPath::Direction::CW;
+    explicit Shape(Object::Type type) : Object(type) {}
+    VPath::Direction direction()
+    {
+        return (mDirection == 3) ? VPath::Direction::CCW : VPath::Direction::CW;
     }
+
 public:
-    int                                    mDirection{1};
+    int mDirection{1};
 };
 
-class LOTShapeData : public LOTPath
-{
+class Path : public Shape {
 public:
-    LOTShapeData():LOTPath(LOTData::Type::Shape){}
+    Path() : Shape(Object::Type::Path) {}
+
 public:
-    LOTAnimatable<LottieShapeData>    mShape;
+    Property<PathData> mShape;
 };
 
-class LOTMaskData
-{
+class Rect : public Shape {
 public:
-    enum class Mode {
-      None,
-      Add,
-      Substarct,
-      Intersect,
-      Difference
-    };
-    float opacity(int frameNo) const {return mOpacity.value(frameNo)/100.0f;}
-    bool isStatic() const {return mIsStatic;}
+    Rect() : Shape(Object::Type::Rect) {}
+
 public:
-    LOTAnimatable<LottieShapeData>    mShape;
-    LOTAnimatable<float>              mOpacity{100};
-    bool                              mInv{false};
-    bool                              mIsStatic{true};
-    LOTMaskData::Mode                 mMode;
+    Property<VPointF> mPos;
+    Property<VPointF> mSize;
+    Property<float>   mRound{0};
 };
 
-class LOTRectData : public LOTPath
-{
+class Ellipse : public Shape {
 public:
-    LOTRectData():LOTPath(LOTData::Type::Rect){}
+    Ellipse() : Shape(Object::Type::Ellipse) {}
+
 public:
-    LOTAnimatable<VPointF>    mPos;
-    LOTAnimatable<VPointF>    mSize;
-    LOTAnimatable<float>      mRound{0};
+    Property<VPointF> mPos;
+    Property<VPointF> mSize;
 };
 
-class LOTEllipseData : public LOTPath
-{
+class Polystar : public Shape {
 public:
-    LOTEllipseData():LOTPath(LOTData::Type::Ellipse){}
+    enum class PolyType { Star = 1, Polygon = 2 };
+    Polystar() : Shape(Object::Type::Polystar) {}
+
 public:
-    LOTAnimatable<VPointF>   mPos;
-    LOTAnimatable<VPointF>   mSize;
+    Polystar::PolyType mPolyType{PolyType::Polygon};
+    Property<VPointF>  mPos;
+    Property<float>    mPointCount{0};
+    Property<float>    mInnerRadius{0};
+    Property<float>    mOuterRadius{0};
+    Property<float>    mInnerRoundness{0};
+    Property<float>    mOuterRoundness{0};
+    Property<float>    mRotation{0};
 };
 
-class LOTPolystarData : public LOTPath
-{
+class Repeater : public Object {
 public:
-    enum class PolyType {
-        Star = 1,
-        Polygon = 2
+    struct Transform {
+        VMatrix matrix(int frameNo, float multiplier) const;
+        float   startOpacity(int frameNo) const
+        {
+            return mStartOpacity.value(frameNo) / 100;
+        }
+        float endOpacity(int frameNo) const
+        {
+            return mEndOpacity.value(frameNo) / 100;
+        }
+        bool isStatic() const
+        {
+            return mRotation.isStatic() && mScale.isStatic() &&
+                   mPosition.isStatic() && mAnchor.isStatic() &&
+                   mStartOpacity.isStatic() && mEndOpacity.isStatic();
+        }
+        Property<float>   mRotation{0};       /* "r" */
+        Property<VPointF> mScale{{100, 100}}; /* "s" */
+        Property<VPointF> mPosition;          /* "p" */
+        Property<VPointF> mAnchor;            /* "a" */
+        Property<float>   mStartOpacity{100}; /* "so" */
+        Property<float>   mEndOpacity{100};   /* "eo" */
     };
-    LOTPolystarData():LOTPath(LOTData::Type::Polystar){}
+    Repeater() : Object(Object::Type::Repeater) {}
+    Group *content() const { return mContent ? mContent : nullptr; }
+    void   setContent(Group *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:
-    LOTPolystarData::PolyType     mPolyType{PolyType::Polygon};
-    LOTAnimatable<VPointF>        mPos;
-    LOTAnimatable<float>          mPointCount{0};
-    LOTAnimatable<float>          mInnerRadius{0};
-    LOTAnimatable<float>          mOuterRadius{0};
-    LOTAnimatable<float>          mInnerRoundness{0};
-    LOTAnimatable<float>          mOuterRoundness{0};
-    LOTAnimatable<float>          mRotation{0};
+    Group *         mContent{nullptr};
+    Transform       mTransform;
+    Property<float> mCopies{0};
+    Property<float> mOffset{0};
+    float           mMaxCopies{0.0};
+    bool            mProcessed{false};
 };
 
-class LOTTrimData : public LOTData
-{
+class Trim : public Object {
 public:
     struct Segment {
         float start{0};
         float end{0};
         Segment() = default;
-        explicit Segment(float s, float e):start(s), end(e) {}
-    };
-    enum class TrimType {
-        Simultaneously,
-        Individually
+        explicit Segment(float s, float e) : start(s), end(e) {}
     };
-    LOTTrimData():LOTData(LOTData::Type::Trim){}
+    enum class TrimType { Simultaneously, Individually };
+    Trim() : Object(Object::Type::Trim) {}
     /*
      * if start > end vector trims the path as a loop ( 2 segment)
      * if start < end vector trims the path without loop ( 1 segment).
      * if no offset then there is no loop.
      */
-    Segment segment(int frameNo) const {
-        float start = mStart.value(frameNo)/100.0f;
-        float end = mEnd.value(frameNo)/100.0f;
-        float offset = std::fmod(mOffset.value(frameNo), 360.0f)/ 360.0f;
+    Segment segment(int frameNo) const
+    {
+        float start = mStart.value(frameNo) / 100.0f;
+        float end = mEnd.value(frameNo) / 100.0f;
+        float offset = std::fmod(mOffset.value(frameNo), 360.0f) / 360.0f;
 
         float diff = std::abs(start - end);
         if (vCompare(diff, 0.0f)) return Segment(0, 0);
@@ -985,30 +974,32 @@ public:
         if (offset > 0) {
             start += offset;
             end += offset;
-            if (start <= 1 && end <=1) {
+            if (start <= 1 && end <= 1) {
                 return noloop(start, end);
             } else if (start > 1 && end > 1) {
                 return noloop(start - 1, end - 1);
             } else {
-                return (start > 1) ?
-                            loop(start - 1 , end) : loop(start , end - 1);
+                return (start > 1) ? loop(start - 1, end)
+                                   : loop(start, end - 1);
             }
         } else {
             start += offset;
-            end   += offset;
+            end += offset;
             if (start >= 0 && end >= 0) {
                 return noloop(start, end);
             } else if (start < 0 && end < 0) {
                 return noloop(1 + start, 1 + end);
             } else {
-                return (start < 0) ?
-                            loop(1 + start, end) : loop(start , 1 + end);
+                return (start < 0) ? loop(1 + start, end)
+                                   : loop(start, 1 + end);
             }
         }
     }
-    LOTTrimData::TrimType type() const {return mTrimType;}
+    Trim::TrimType type() const { return mTrimType; }
+
 private:
-    Segment noloop(float start, float end) const{
+    Segment noloop(float start, float end) const
+    {
         assert(start >= 0);
         assert(end >= 0);
         Segment s;
@@ -1016,7 +1007,8 @@ private:
         s.end = std::max(start, end);
         return s;
     }
-    Segment loop(float start, float end) const{
+    Segment loop(float start, float end) const
+    {
         assert(start >= 0);
         assert(end >= 0);
         Segment s;
@@ -1024,73 +1016,81 @@ private:
         s.end = std::min(start, end);
         return s;
     }
+
 public:
-    LOTAnimatable<float>             mStart{0};
-    LOTAnimatable<float>             mEnd{0};
-    LOTAnimatable<float>             mOffset{0};
-    LOTTrimData::TrimType            mTrimType{TrimType::Simultaneously};
+    Property<float> mStart{0};
+    Property<float> mEnd{0};
+    Property<float> mOffset{0};
+    Trim::TrimType  mTrimType{TrimType::Simultaneously};
 };
 
-class LOTRepeaterTransform
+inline Gradient::Data operator+(const Gradient::Data &g1,
+                                const Gradient::Data &g2)
 {
-public:
-    VMatrix matrix(int frameNo, float multiplier) const;
-    float startOpacity(int frameNo) const { return mStartOpacity.value(frameNo)/100;}
-    float endOpacity(int frameNo) const { return mEndOpacity.value(frameNo)/100;}
-    bool isStatic() const
-    {
-        return mRotation.isStatic() &&
-               mScale.isStatic() &&
-               mPosition.isStatic() &&
-               mAnchor.isStatic() &&
-               mStartOpacity.isStatic() &&
-               mEndOpacity.isStatic();
+    if (g1.mGradient.size() != g2.mGradient.size()) return g1;
+
+    Gradient::Data newG;
+    newG.mGradient = g1.mGradient;
+
+    auto g2It = g2.mGradient.begin();
+    for (auto &i : newG.mGradient) {
+        i = i + *g2It;
+        g2It++;
     }
-public:
-    LOTAnimatable<float>          mRotation{0};  /* "r" */
-    LOTAnimatable<VPointF>        mScale{{100, 100}};     /* "s" */
-    LOTAnimatable<VPointF>        mPosition;  /* "p" */
-    LOTAnimatable<VPointF>        mAnchor;    /* "a" */
-    LOTAnimatable<float>          mStartOpacity{100}; /* "so" */
-    LOTAnimatable<float>          mEndOpacity{100};   /* "eo" */
-};
 
-class LOTRepeaterData : public LOTData
+    return newG;
+}
+
+inline Gradient::Data operator-(const Gradient::Data &g1,
+                                const Gradient::Data &g2)
 {
-public:
-    LOTRepeaterData():LOTData(LOTData::Type::Repeater){}
-    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:
-    LOTShapeGroupData*                      mContent{nullptr};
-    LOTRepeaterTransform                    mTransform;
-    LOTAnimatable<float>                    mCopies{0};
-    LOTAnimatable<float>                    mOffset{0};
-    float                                   mMaxCopies{0.0};
-    bool                                    mProcessed{false};
-};
+    if (g1.mGradient.size() != g2.mGradient.size()) return g1;
+    Gradient::Data newG;
+    newG.mGradient = g1.mGradient;
 
-class LOTModel
+    auto g2It = g2.mGradient.begin();
+    for (auto &i : newG.mGradient) {
+        i = i - *g2It;
+        g2It++;
+    }
+
+    return newG;
+}
+
+inline Gradient::Data operator*(float m, const Gradient::Data &g)
 {
-public:
-   bool  isStatic() const {return mRoot->isStatic();}
-   VSize size() const {return mRoot->size();}
-   double duration() const {return mRoot->duration();}
-   size_t totalFrame() const {return mRoot->totalFrame();}
-   size_t frameDuration() const {return mRoot->frameDuration();}
-   double frameRate() const {return mRoot->frameRate();}
-   size_t startFrame() const {return mRoot->startFrame();}
-   size_t endFrame() const {return mRoot->endFrame();}
-   size_t frameAtPos(double pos) const {return mRoot->frameAtPos(pos);}
-   std::vector<LayerInfo> layerInfoList() const { return mRoot->layerInfoList();}
-   const std::vector<Marker> &markers() const { return mRoot->markers();}
-public:
-    std::shared_ptr<LOTCompositionData> mRoot;
-};
+    Gradient::Data newG;
+    newG.mGradient = g.mGradient;
+
+    for (auto &i : newG.mGradient) {
+        i = i * m;
+    }
+    return newG;
+}
+
+using ColorFilter = std::function<void(float &, float &, float &)>;
+
+void configureModelCacheSize(size_t cacheSize);
+
+std::shared_ptr<model::Composition> loadFromFile(const std::string &filePath,
+                                                 bool cachePolicy);
+
+std::shared_ptr<model::Composition> loadFromData(std::string        jsonData,
+                                                 const std::string &key,
+                                                 std::string resourcePath,
+                                                 bool        cachePolicy);
+
+std::shared_ptr<model::Composition> loadFromData(std::string jsonData,
+                                                 std::string resourcePath,
+                                                 ColorFilter filter);
+
+std::shared_ptr<model::Composition> parse(char *str, std::string dir_path,
+                                          ColorFilter filter = {});
+
+}  // namespace model
+
+}  // namespace internal
+
+}  // namespace rlottie
 
-#endif // LOTModel_H
+#endif  // LOTModel_H
index 2e2720f..b3d6394 100644 (file)
@@ -16,8 +16,6 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
  */
 
-#include "lottieparser.h"
-
 //#define DEBUG_PARSER
 
 // This parser implements JSON token-by-token parsing with an API that is
@@ -63,6 +61,8 @@ RAPIDJSON_DIAG_OFF(effc++)
 
 using namespace rapidjson;
 
+using namespace rlottie::internal;
+
 class LookaheadParserHandler {
 public:
     bool Null()
@@ -169,111 +169,116 @@ protected:
 
 class LottieParserImpl : public LookaheadParserHandler {
 public:
-    LottieParserImpl(char *str, std::string dir_path, ColorFilter filter)
+    LottieParserImpl(char *str, std::string dir_path, model::ColorFilter filter)
         : LookaheadParserHandler(str),
           mColorFilter(std::move(filter)),
-          mDirPath(std::move(dir_path)) {}
+          mDirPath(std::move(dir_path))
+    {
+    }
     bool VerifyType();
     bool ParseNext();
+
 public:
-    VArenaAlloc& allocator() {return compRef->mArenaAlloc;}
-    bool        EnterObject();
-    bool        EnterArray();
-    const char *NextObjectKey();
-    bool        NextArrayValue();
-    int         GetInt();
-    double      GetDouble();
-    const char *GetString();
-    bool        GetBool();
-    void        GetNull();
+    VArenaAlloc &allocator() { return compRef->mArenaAlloc; }
+    bool         EnterObject();
+    bool         EnterArray();
+    const char * NextObjectKey();
+    bool         NextArrayValue();
+    int          GetInt();
+    double       GetDouble();
+    const char * GetString();
+    bool         GetBool();
+    void         GetNull();
 
     void   SkipObject();
     void   SkipArray();
     void   SkipValue();
     Value *PeekValue();
-    int PeekType() const;
-    bool IsValid() { return st_ != kError; }
+    int    PeekType() const;
+    bool   IsValid() { return st_ != kError; }
 
     void                  Skip(const char *key);
-    LottieBlendMode       getBlendMode();
+    model::BlendMode      getBlendMode();
     CapStyle              getLineCap();
     JoinStyle             getLineJoin();
     FillRule              getFillRule();
-    LOTTrimData::TrimType getTrimType();
-    MatteType             getMatteType();
-    LayerType             getLayerType();
+    model::Trim::TrimType getTrimType();
+    model::MatteType      getMatteType();
+    model::Layer::Type    getLayerType();
 
-    std::shared_ptr<LOTCompositionData> composition() const
+    std::shared_ptr<model::Composition> composition() const
     {
         return mComposition;
     }
-    void                         parseComposition();
-    void                         parseMarkers();
-    void                         parseMarker();
-    void                         parseAssets(LOTCompositionData *comp);
-    LOTAsset*                    parseAsset();
-    void                         parseLayers(LOTCompositionData *comp);
-    LOTLayerData*                parseLayer();
-    void                         parseMaskProperty(LOTLayerData *layer);
-    void                         parseShapesAttr(LOTLayerData *layer);
-    void                         parseObject(LOTGroupData *parent);
-    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             parseComposition();
+    void             parseMarkers();
+    void             parseMarker();
+    void             parseAssets(model::Composition *comp);
+    model::Asset *   parseAsset();
+    void             parseLayers(model::Composition *comp);
+    model::Layer *   parseLayer();
+    void             parseMaskProperty(model::Layer *layer);
+    void             parseShapesAttr(model::Layer *layer);
+    void             parseObject(model::Group *parent);
+    model::Mask *    parseMaskObject();
+    model::Object *  parseObjectTypeAttr();
+    model::Object *  parseGroupObject();
+    model::Rect *    parseRectObject();
+    model::Ellipse * parseEllipseObject();
+    model::Path *    parseShapeObject();
+    model::Polystar *parsePolystarObject();
+
+    model::Transform *     parseTransformObject(bool ddd = false);
+    model::Fill *          parseFillObject();
+    model::GradientFill *  parseGFillObject();
+    model::Stroke *        parseStrokeObject();
+    model::GradientStroke *parseGStrokeObject();
+    model::Trim *          parseTrimObject();
+    model::Repeater *      parseReapeaterObject();
+
+    void parseGradientProperty(model::Gradient *gradient, const char *key);
 
     VPointF parseInperpolatorPoint();
 
     void getValue(VPointF &pt);
     void getValue(float &fval);
-    void getValue(LottieColor &color);
+    void getValue(model::Color &color);
     void getValue(int &ival);
-    void getValue(LottieShapeData &shape);
-    void getValue(LottieGradient &gradient);
+    void getValue(model::PathData &shape);
+    void getValue(model::Gradient::Data &gradient);
     void getValue(std::vector<VPointF> &v);
-    void getValue(LOTRepeaterTransform &);
+    void getValue(model::Repeater::Transform &);
 
     template <typename T>
-    bool parseKeyFrameValue(const char *key, LOTKeyFrameValue<T> &value);
+    bool parseKeyFrameValue(const char *key, model::Value<T> &value);
     template <typename T>
-    void parseKeyFrame(LOTAnimInfo<T> &obj);
+    void parseKeyFrame(model::DynamicProperty<T> &obj);
     template <typename T>
-    void parseProperty(LOTAnimatable<T> &obj);
+    void parseProperty(model::Property<T> &obj);
     template <typename T>
-    void parsePropertyHelper(LOTAnimatable<T> &obj);
+    void parsePropertyHelper(model::Property<T> &obj);
 
-    void parseShapeProperty(LOTAnimatable<LottieShapeData> &obj);
-    void parseDashProperty(LOTDashProperty &dash);
+    void parseShapeProperty(model::Property<model::PathData> &obj);
+    void parseDashProperty(model::Dash &dash);
 
-    VInterpolatorinterpolator(VPointF, VPointF, std::string);
+    VInterpolator *interpolator(VPointF, VPointF, std::string);
 
-    LottieColor toColor(const char *str);
+    model::Color toColor(const char *str);
 
     void resolveLayerRefs();
     void parsePathInfo();
+
 private:
-    ColorFilter mColorFilter;
+    model::ColorFilter mColorFilter;
     struct {
-        std::vector<VPointF>                       mInPoint;  /* "i" */
-        std::vector<VPointF>                       mOutPoint; /* "o" */
-        std::vector<VPointF>                       mVertices; /* "v" */
-        std::vector<VPointF>                       mResult;
-        bool                                       mClosed{false};
-
-        void convert() {
+        std::vector<VPointF> mInPoint;  /* "i" */
+        std::vector<VPointF> mOutPoint; /* "o" */
+        std::vector<VPointF> mVertices; /* "v" */
+        std::vector<VPointF> mResult;
+        bool                 mClosed{false};
+
+        void convert()
+        {
             // shape data could be empty.
             if (mInPoint.empty() || mOutPoint.empty() || mVertices.empty()) {
                 mResult.clear();
@@ -283,8 +288,8 @@ private:
             /*
              * Convert the AE shape format to
              * list of bazier curves
-             * The final structure will be Move +size*Cubic + Cubic (if the path is
-             * closed one)
+             * The final structure will be Move +size*Cubic + Cubic (if the path
+             * is closed one)
              */
             if (mInPoint.size() != mOutPoint.size() ||
                 mInPoint.size() != mVertices.size()) {
@@ -293,31 +298,34 @@ private:
                 auto size = mVertices.size();
                 mResult.push_back(mVertices[0]);
                 for (size_t i = 1; i < size; i++) {
-                    mResult.push_back(mVertices[i - 1] +
-                                     mOutPoint[i - 1]);  // CP1 = start + outTangent
+                    mResult.push_back(
+                        mVertices[i - 1] +
+                        mOutPoint[i - 1]);  // CP1 = start + outTangent
                     mResult.push_back(mVertices[i] +
-                                     mInPoint[i]);   // CP2 = end + inTangent
+                                      mInPoint[i]);   // CP2 = end + inTangent
                     mResult.push_back(mVertices[i]);  // end point
                 }
 
                 if (mClosed) {
-                    mResult.push_back(mVertices[size - 1] +
-                                     mOutPoint[size - 1]);  // CP1 = start + outTangent
+                    mResult.push_back(
+                        mVertices[size - 1] +
+                        mOutPoint[size - 1]);  // CP1 = start + outTangent
                     mResult.push_back(mVertices[0] +
-                                     mInPoint[0]);   // CP2 = end + inTangent
+                                      mInPoint[0]);   // CP2 = end + inTangent
                     mResult.push_back(mVertices[0]);  // end point
                 }
             }
         }
-        void reset() {
+        void reset()
+        {
             mInPoint.clear();
             mOutPoint.clear();
             mVertices.clear();
             mResult.clear();
             mClosed = false;
         }
-       void updatePath(VPath &out) {
-
+        void updatePath(VPath &out)
+        {
             if (mResult.empty()) return;
 
             auto size = mResult.size();
@@ -326,24 +334,23 @@ private:
              * ptSize = size + 1(size + close)
              * elmSize = size/3 cubic + 1 move + 1 close
              */
-            out.reserve(size + 1 , size/3 + 2);
+            out.reserve(size + 1, size / 3 + 2);
             out.moveTo(points[0]);
-            for (size_t i = 1 ; i < size; i+=3) {
-               out.cubicTo(points[i], points[i+1], points[i+2]);
+            for (size_t i = 1; i < size; i += 3) {
+                out.cubicTo(points[i], points[i + 1], points[i + 2]);
             }
-            if (mClosed)
-              out.close();
-       }
-    }mPathInfo;
+            if (mClosed) out.close();
+        }
+    } mPathInfo;
+
 protected:
-    std::unordered_map<std::string, VInterpolator*>
-                                               mInterpolatorCache;
-    std::shared_ptr<LOTCompositionData>        mComposition;
-    LOTCompositionData *                       compRef{nullptr};
-    LOTLayerData *                             curLayerRef{nullptr};
-    std::vector<LOTLayerData *>                mLayersToUpdate;
-    std::string                                mDirPath;
-    void                                       SkipOut(int depth);
+    std::unordered_map<std::string, VInterpolator *> mInterpolatorCache;
+    std::shared_ptr<model::Composition>              mComposition;
+    model::Composition *                             compRef{nullptr};
+    model::Layer *                                   curLayerRef{nullptr};
+    std::vector<model::Layer *>                      mLayersToUpdate;
+    std::string                                      mDirPath;
+    void                                             SkipOut(int depth);
 };
 
 LookaheadParserHandler::LookaheadParserHandler(char *str)
@@ -586,20 +593,20 @@ void LottieParserImpl::Skip(const char * /*key*/)
     }
 }
 
-LottieBlendMode LottieParserImpl::getBlendMode()
+model::BlendMode LottieParserImpl::getBlendMode()
 {
     RAPIDJSON_ASSERT(PeekType() == kNumberType);
-    LottieBlendMode mode = LottieBlendMode::Normal;
+    auto mode = model::BlendMode::Normal;
 
     switch (GetInt()) {
     case 1:
-        mode = LottieBlendMode::Multiply;
+        mode = model::BlendMode::Multiply;
         break;
     case 2:
-        mode = LottieBlendMode::Screen;
+        mode = model::BlendMode::Screen;
         break;
     case 3:
-        mode = LottieBlendMode::OverLay;
+        mode = model::BlendMode::OverLay;
         break;
     default:
         break;
@@ -610,11 +617,11 @@ LottieBlendMode LottieParserImpl::getBlendMode()
 void LottieParserImpl::resolveLayerRefs()
 {
     for (const auto &layer : mLayersToUpdate) {
-        auto          search = compRef->mAssets.find(layer->extra()->mPreCompRefId);
+        auto search = compRef->mAssets.find(layer->extra()->mPreCompRefId);
         if (search != compRef->mAssets.end()) {
-            if (layer->mLayerType == LayerType::Image) {
+            if (layer->mLayerType == model::Layer::Type::Image) {
                 layer->extra()->mAsset = search->second;
-            } else if (layer->mLayerType == LayerType::Precomp) {
+            } else if (layer->mLayerType == model::Layer::Type::Precomp) {
                 layer->mChildren = search->second->mLayers;
                 layer->setStatic(layer->isStatic() &&
                                  search->second->isStatic());
@@ -627,9 +634,9 @@ void LottieParserImpl::parseComposition()
 {
     RAPIDJSON_ASSERT(PeekType() == kObjectType);
     EnterObject();
-    std::shared_ptr<LOTCompositionData> sharedComposition =
-        std::make_shared<LOTCompositionData>();
-    LOTCompositionData *comp = sharedComposition.get();
+    std::shared_ptr<model::Composition> sharedComposition =
+        std::make_shared<model::Composition>();
+    model::Composition *comp = sharedComposition.get();
     compRef = comp;
     while (const char *key = NextObjectKey()) {
         if (0 == strcmp(key, "v")) {
@@ -686,7 +693,7 @@ void LottieParserImpl::parseMarker()
     EnterObject();
     std::string comment;
     int         timeframe{0};
-    int          duration{0};
+    int         duration{0};
     while (const char *key = NextObjectKey()) {
         if (0 == strcmp(key, "cm")) {
             RAPIDJSON_ASSERT(PeekType() == kStringType);
@@ -705,7 +712,8 @@ void LottieParserImpl::parseMarker()
             Skip(key);
         }
     }
-    compRef->mMarkers.emplace_back(std::move(comment), timeframe, timeframe + duration);
+    compRef->mMarkers.emplace_back(std::move(comment), timeframe,
+                                   timeframe + duration);
 }
 
 void LottieParserImpl::parseMarkers()
@@ -718,7 +726,7 @@ void LottieParserImpl::parseMarkers()
     // update the precomp layers with the actual layer object
 }
 
-void LottieParserImpl::parseAssets(LOTCompositionData *composition)
+void LottieParserImpl::parseAssets(model::Composition *composition)
 {
     RAPIDJSON_ASSERT(PeekType() == kArrayType);
     EnterArray();
@@ -740,10 +748,10 @@ static constexpr const unsigned char B64index[256] = {
 
 std::string b64decode(const char *data, const size_t len)
 {
-    auto p = reinterpret_cast<const unsigned char *>(data);
-    int            pad = len > 0 && (len % 4 || p[len - 1] == '=');
-    const size_t   L = ((len + 3) / 4 - pad) * 4;
-    std::string    str(L / 4 * 3 + pad, '\0');
+    auto         p = reinterpret_cast<const unsigned char *>(data);
+    int          pad = len > 0 && (len % 4 || p[len - 1] == '=');
+    const size_t L = ((len + 3) / 4 - pad) * 4;
+    std::string  str(L / 4 * 3 + pad, '\0');
 
     for (size_t i = 0, j = 0; i < L; i += 4) {
         int n = B64index[p[i]] << 18 | B64index[p[i + 1]] << 12 |
@@ -782,8 +790,9 @@ static std::string convertFromBase64(const std::string &str)
  *  so this is workaround for windows build
  */
 #include <sstream>
-template<class T>
-static std::string toString(const T &value) {
+template <class T>
+static std::string toString(const T &value)
+{
     std::ostringstream os;
     os << value;
     return os.str();
@@ -793,14 +802,14 @@ static std::string toString(const T &value) {
  * https://github.com/airbnb/lottie-web/blob/master/docs/json/layers/shape.json
  *
  */
-LOTAsset* LottieParserImpl::parseAsset()
+model::Asset *LottieParserImpl::parseAsset()
 {
     RAPIDJSON_ASSERT(PeekType() == kObjectType);
 
-    auto                      asset = allocator().make<LOTAsset>();
-    std::string               filename;
-    std::string               relativePath;
-    bool                      embededResource = false;
+    auto        asset = allocator().make<model::Asset>();
+    std::string filename;
+    std::string relativePath;
+    bool        embededResource = false;
     EnterObject();
     while (const char *key = NextObjectKey()) {
         if (0 == strcmp(key, "w")) {
@@ -810,7 +819,7 @@ LOTAsset* LottieParserImpl::parseAsset()
             RAPIDJSON_ASSERT(PeekType() == kNumberType);
             asset->mHeight = GetInt();
         } else if (0 == strcmp(key, "p")) { /* image name */
-            asset->mAssetType = LOTAsset::Type::Image;
+            asset->mAssetType = model::Asset::Type::Image;
             RAPIDJSON_ASSERT(PeekType() == kStringType);
             filename = std::string(GetString());
         } else if (0 == strcmp(key, "u")) { /* relative image path */
@@ -826,7 +835,7 @@ LOTAsset* LottieParserImpl::parseAsset()
                 asset->mRefId = toString(GetInt());
             }
         } else if (0 == strcmp(key, "layers")) {
-            asset->mAssetType = LOTAsset::Type::Precomp;
+            asset->mAssetType = model::Asset::Type::Precomp;
             RAPIDJSON_ASSERT(PeekType() == kArrayType);
             EnterArray();
             bool staticFlag = true;
@@ -846,7 +855,7 @@ LOTAsset* LottieParserImpl::parseAsset()
         }
     }
 
-    if (asset->mAssetType == LOTAsset::Type::Image) {
+    if (asset->mAssetType == model::Asset::Type::Image) {
         if (embededResource) {
             // embeder resource should start with "data:"
             if (filename.compare(0, 5, "data:") == 0) {
@@ -860,10 +869,10 @@ LOTAsset* LottieParserImpl::parseAsset()
     return asset;
 }
 
-void LottieParserImpl::parseLayers(LOTCompositionData *comp)
+void LottieParserImpl::parseLayers(model::Composition *comp)
 {
-    comp->mRootLayer = allocator().make<LOTLayerData>();
-    comp->mRootLayer->mLayerType = LayerType::Precomp;
+    comp->mRootLayer = allocator().make<model::Layer>();
+    comp->mRootLayer->mLayerType = model::Layer::Type::Precomp;
     comp->mRootLayer->setName("__");
     bool staticFlag = true;
     RAPIDJSON_ASSERT(PeekType() == kArrayType);
@@ -878,10 +887,10 @@ void LottieParserImpl::parseLayers(LOTCompositionData *comp)
     comp->mRootLayer->setStatic(staticFlag);
 }
 
-LottieColor LottieParserImpl::toColor(const char *str)
+model::Color LottieParserImpl::toColor(const char *str)
 {
-    LottieColor color;
-    auto len = strlen(str);
+    model::Color color;
+    auto         len = strlen(str);
 
     // some resource has empty color string
     // return a default color for those cases.
@@ -903,52 +912,52 @@ LottieColor LottieParserImpl::toColor(const char *str)
     return color;
 }
 
-MatteType LottieParserImpl::getMatteType()
+model::MatteType LottieParserImpl::getMatteType()
 {
     RAPIDJSON_ASSERT(PeekType() == kNumberType);
     switch (GetInt()) {
     case 1:
-        return MatteType::Alpha;
+        return model::MatteType::Alpha;
         break;
     case 2:
-        return MatteType::AlphaInv;
+        return model::MatteType::AlphaInv;
         break;
     case 3:
-        return MatteType::Luma;
+        return model::MatteType::Luma;
         break;
     case 4:
-        return MatteType::LumaInv;
+        return model::MatteType::LumaInv;
         break;
     default:
-        return MatteType::None;
+        return model::MatteType::None;
         break;
     }
 }
 
-LayerType LottieParserImpl::getLayerType()
+model::Layer::Type LottieParserImpl::getLayerType()
 {
     RAPIDJSON_ASSERT(PeekType() == kNumberType);
     switch (GetInt()) {
     case 0:
-        return LayerType::Precomp;
+        return model::Layer::Type::Precomp;
         break;
     case 1:
-        return LayerType::Solid;
+        return model::Layer::Type::Solid;
         break;
     case 2:
-        return LayerType::Image;
+        return model::Layer::Type::Image;
         break;
     case 3:
-        return LayerType::Null;
+        return model::Layer::Type::Null;
         break;
     case 4:
-        return LayerType::Shape;
+        return model::Layer::Type::Shape;
         break;
     case 5:
-        return LayerType::Text;
+        return model::Layer::Type::Text;
         break;
     default:
-        return LayerType::Null;
+        return model::Layer::Type::Null;
         break;
     }
 }
@@ -957,10 +966,10 @@ LayerType LottieParserImpl::getLayerType()
  * https://github.com/airbnb/lottie-web/blob/master/docs/json/layers/shape.json
  *
  */
-LOTLayerData* LottieParserImpl::parseLayer()
+model::Layer *LottieParserImpl::parseLayer()
 {
     RAPIDJSON_ASSERT(PeekType() == kObjectType);
-    LOTLayerData *layer = allocator().make<LOTLayerData>();
+    model::Layer *layer = allocator().make<model::Layer>();
     curLayerRef = layer;
     bool ddd = true;
     EnterObject();
@@ -1043,7 +1052,8 @@ LOTLayerData* LottieParserImpl::parseLayer()
     }
 
     // make sure layer data is not corrupted.
-    if (layer->hasParent() && (layer->id() == layer->parentId())) return nullptr;
+    if (layer->hasParent() && (layer->id() == layer->parentId()))
+        return nullptr;
 
     if (layer->mExtra) layer->mExtra->mCompRef = compRef;
 
@@ -1052,7 +1062,7 @@ LOTLayerData* LottieParserImpl::parseLayer()
         // transform matrix(when it is a parent of some other layer)
         // so force it to be a Null Layer and release all resource.
         layer->setStatic(layer->mTransform->isStatic());
-        layer->mLayerType = LayerType::Null;
+        layer->mLayerType = model::Layer::Type::Null;
         layer->mChildren = {};
         return layer;
     }
@@ -1074,7 +1084,7 @@ LOTLayerData* LottieParserImpl::parseLayer()
     return layer;
 }
 
-void LottieParserImpl::parseMaskProperty(LOTLayerData *layer)
+void LottieParserImpl::parseMaskProperty(model::Layer *layer)
 {
     RAPIDJSON_ASSERT(PeekType() == kArrayType);
     EnterArray();
@@ -1083,9 +1093,9 @@ void LottieParserImpl::parseMaskProperty(LOTLayerData *layer)
     }
 }
 
-LOTMaskData* LottieParserImpl::parseMaskObject()
+model::Mask *LottieParserImpl::parseMaskObject()
 {
-    auto obj = allocator().make<LOTMaskData>();
+    auto obj = allocator().make<model::Mask>();
 
     RAPIDJSON_ASSERT(PeekType() == kObjectType);
     EnterObject();
@@ -1095,27 +1105,27 @@ LOTMaskData* LottieParserImpl::parseMaskObject()
         } else if (0 == strcmp(key, "mode")) {
             const char *str = GetString();
             if (!str) {
-                obj->mMode = LOTMaskData::Mode::None;
+                obj->mMode = model::Mask::Mode::None;
                 continue;
             }
             switch (str[0]) {
             case 'n':
-                obj->mMode = LOTMaskData::Mode::None;
+                obj->mMode = model::Mask::Mode::None;
                 break;
             case 'a':
-                obj->mMode = LOTMaskData::Mode::Add;
+                obj->mMode = model::Mask::Mode::Add;
                 break;
             case 's':
-                obj->mMode = LOTMaskData::Mode::Substarct;
+                obj->mMode = model::Mask::Mode::Substarct;
                 break;
             case 'i':
-                obj->mMode = LOTMaskData::Mode::Intersect;
+                obj->mMode = model::Mask::Mode::Intersect;
                 break;
             case 'f':
-                obj->mMode = LOTMaskData::Mode::Difference;
+                obj->mMode = model::Mask::Mode::Difference;
                 break;
             default:
-                obj->mMode = LOTMaskData::Mode::None;
+                obj->mMode = model::Mask::Mode::None;
                 break;
             }
         } else if (0 == strcmp(key, "pt")) {
@@ -1130,7 +1140,7 @@ LOTMaskData* LottieParserImpl::parseMaskObject()
     return obj;
 }
 
-void LottieParserImpl::parseShapesAttr(LOTLayerData *layer)
+void LottieParserImpl::parseShapesAttr(model::Layer *layer)
 {
     RAPIDJSON_ASSERT(PeekType() == kArrayType);
     EnterArray();
@@ -1139,7 +1149,7 @@ void LottieParserImpl::parseShapesAttr(LOTLayerData *layer)
     }
 }
 
-LOTData* LottieParserImpl::parseObjectTypeAttr()
+model::Object *LottieParserImpl::parseObjectTypeAttr()
 {
     RAPIDJSON_ASSERT(PeekType() == kStringType);
     const char *type = GetString();
@@ -1182,7 +1192,7 @@ LOTData* LottieParserImpl::parseObjectTypeAttr()
     }
 }
 
-void LottieParserImpl::parseObject(LOTGroupData *parent)
+void LottieParserImpl::parseObject(model::Group *parent)
 {
     RAPIDJSON_ASSERT(PeekType() == kObjectType);
     EnterObject();
@@ -1196,9 +1206,9 @@ void LottieParserImpl::parseObject(LOTGroupData *parent)
     }
 }
 
-LOTData* LottieParserImpl::parseGroupObject()
+model::Object *LottieParserImpl::parseGroupObject()
 {
-    auto group = allocator().make<LOTShapeGroupData>();
+    auto group = allocator().make<model::Group>();
 
     while (const char *key = NextObjectKey()) {
         if (0 == strcmp(key, "nm")) {
@@ -1210,8 +1220,10 @@ LOTData* LottieParserImpl::parseGroupObject()
                 RAPIDJSON_ASSERT(PeekType() == kObjectType);
                 parseObject(group);
             }
-            if (group->mChildren.back()->type() == LOTData::Type::Transform) {
-                group->mTransform = static_cast<LOTTransformData *>(group->mChildren.back());
+            if (group->mChildren.back()->type() ==
+                model::Object::Type::Transform) {
+                group->mTransform =
+                    static_cast<model::Transform *>(group->mChildren.back());
                 group->mChildren.pop_back();
             }
         } else {
@@ -1233,9 +1245,9 @@ LOTData* LottieParserImpl::parseGroupObject()
 /*
  * https://github.com/airbnb/lottie-web/blob/master/docs/json/shapes/rect.json
  */
-LOTRectData* LottieParserImpl::parseRectObject()
+model::Rect *LottieParserImpl::parseRectObject()
 {
-    auto obj = allocator().make<LOTRectData>();
+    auto obj = allocator().make<model::Rect>();
 
     while (const char *key = NextObjectKey()) {
         if (0 == strcmp(key, "nm")) {
@@ -1262,9 +1274,9 @@ LOTRectData* LottieParserImpl::parseRectObject()
 /*
  * https://github.com/airbnb/lottie-web/blob/master/docs/json/shapes/ellipse.json
  */
-LOTEllipseData* LottieParserImpl::parseEllipseObject()
+model::Ellipse *LottieParserImpl::parseEllipseObject()
 {
-    auto obj = allocator().make<LOTEllipseData>();
+    auto obj = allocator().make<model::Ellipse>();
 
     while (const char *key = NextObjectKey()) {
         if (0 == strcmp(key, "nm")) {
@@ -1288,9 +1300,9 @@ LOTEllipseData* LottieParserImpl::parseEllipseObject()
 /*
  * https://github.com/airbnb/lottie-web/blob/master/docs/json/shapes/shape.json
  */
-LOTShapeData* LottieParserImpl::parseShapeObject()
+model::Path *LottieParserImpl::parseShapeObject()
 {
-    auto obj = allocator().make<LOTShapeData>();
+    auto obj = allocator().make<model::Path>();
 
     while (const char *key = NextObjectKey()) {
         if (0 == strcmp(key, "nm")) {
@@ -1316,9 +1328,9 @@ LOTShapeData* LottieParserImpl::parseShapeObject()
 /*
  * https://github.com/airbnb/lottie-web/blob/master/docs/json/shapes/star.json
  */
-LOTPolystarData* LottieParserImpl::parsePolystarObject()
+model::Polystar *LottieParserImpl::parsePolystarObject()
 {
-    auto obj = allocator().make<LOTPolystarData>();
+    auto obj = allocator().make<model::Polystar>();
 
     while (const char *key = NextObjectKey()) {
         if (0 == strcmp(key, "nm")) {
@@ -1339,8 +1351,9 @@ LOTPolystarData* LottieParserImpl::parsePolystarObject()
             parseProperty(obj->mRotation);
         } else if (0 == strcmp(key, "sy")) {
             int starType = GetInt();
-            if (starType == 1) obj->mPolyType = LOTPolystarData::PolyType::Star;
-            if (starType == 2) obj->mPolyType = LOTPolystarData::PolyType::Polygon;
+            if (starType == 1) obj->mPolyType = model::Polystar::PolyType::Star;
+            if (starType == 2)
+                obj->mPolyType = model::Polystar::PolyType::Polygon;
         } else if (0 == strcmp(key, "d")) {
             obj->mDirection = GetInt();
         } else if (0 == strcmp(key, "hd")) {
@@ -1361,19 +1374,19 @@ LOTPolystarData* LottieParserImpl::parsePolystarObject()
     return obj;
 }
 
-LOTTrimData::TrimType LottieParserImpl::getTrimType()
+model::Trim::TrimType LottieParserImpl::getTrimType()
 {
     RAPIDJSON_ASSERT(PeekType() == kNumberType);
     switch (GetInt()) {
     case 1:
-        return LOTTrimData::TrimType::Simultaneously;
+        return model::Trim::TrimType::Simultaneously;
         break;
     case 2:
-        return LOTTrimData::TrimType::Individually;
+        return model::Trim::TrimType::Individually;
         break;
     default:
         RAPIDJSON_ASSERT(0);
-        return LOTTrimData::TrimType::Simultaneously;
+        return model::Trim::TrimType::Simultaneously;
         break;
     }
 }
@@ -1381,9 +1394,9 @@ LOTTrimData::TrimType LottieParserImpl::getTrimType()
 /*
  * https://github.com/airbnb/lottie-web/blob/master/docs/json/shapes/trim.json
  */
-LOTTrimData* LottieParserImpl::parseTrimObject()
+model::Trim *LottieParserImpl::parseTrimObject()
 {
-    auto obj = allocator().make<LOTTrimData>();
+    auto obj = allocator().make<model::Trim>();
 
     while (const char *key = NextObjectKey()) {
         if (0 == strcmp(key, "nm")) {
@@ -1410,7 +1423,7 @@ LOTTrimData* LottieParserImpl::parseTrimObject()
     return obj;
 }
 
-void LottieParserImpl::getValue(LOTRepeaterTransform &obj)
+void LottieParserImpl::getValue(model::Repeater::Transform &obj)
 {
     EnterObject();
 
@@ -1433,11 +1446,11 @@ void LottieParserImpl::getValue(LOTRepeaterTransform &obj)
     }
 }
 
-LOTRepeaterData* LottieParserImpl::parseReapeaterObject()
+model::Repeater *LottieParserImpl::parseReapeaterObject()
 {
-    auto obj = allocator().make<LOTRepeaterData>();
+    auto obj = allocator().make<model::Repeater>();
 
-    obj->setContent(allocator().make<LOTShapeGroupData>());
+    obj->setContent(allocator().make<model::Group>());
 
     while (const char *key = NextObjectKey()) {
         if (0 == strcmp(key, "nm")) {
@@ -1478,15 +1491,14 @@ LOTRepeaterData* LottieParserImpl::parseReapeaterObject()
 /*
  * https://github.com/airbnb/lottie-web/blob/master/docs/json/shapes/transform.json
  */
-LOTTransformData* LottieParserImpl::parseTransformObject(
-    bool ddd)
+model::Transform *LottieParserImpl::parseTransformObject(bool ddd)
 {
-    auto objT = allocator().make<LOTTransformData>();
+    auto objT = allocator().make<model::Transform>();
 
-    std::shared_ptr<LOTTransformData> sharedTransform =
-        std::make_shared<LOTTransformData>();
+    std::shared_ptr<model::Transform> sharedTransform =
+        std::make_shared<model::Transform>();
 
-    auto obj = allocator().make<TransformData>();
+    auto obj = allocator().make<model::Transform::Data>();
     if (ddd) {
         obj->createExtraData();
         obj->mExtra->m3DData = true;
@@ -1537,8 +1549,7 @@ LOTTransformData* LottieParserImpl::parseTransformObject(
                     obj->mRotation.isStatic() && obj->mScale.isStatic() &&
                     obj->mOpacity.isStatic();
     if (obj->mExtra) {
-        isStatic = isStatic &&
-                   obj->mExtra->m3DRx.isStatic() &&
+        isStatic = isStatic && obj->mExtra->m3DRx.isStatic() &&
                    obj->mExtra->m3DRy.isStatic() &&
                    obj->mExtra->m3DRz.isStatic() &&
                    obj->mExtra->mSeparateX.isStatic() &&
@@ -1553,9 +1564,9 @@ LOTTransformData* LottieParserImpl::parseTransformObject(
 /*
  * https://github.com/airbnb/lottie-web/blob/master/docs/json/shapes/fill.json
  */
-LOTFillData* LottieParserImpl::parseFillObject()
+model::Fill *LottieParserImpl::parseFillObject()
 {
-    auto obj = allocator().make<LOTFillData>();
+    auto obj = allocator().make<model::Fill>();
 
     while (const char *key = NextObjectKey()) {
         if (0 == strcmp(key, "nm")) {
@@ -1639,9 +1650,9 @@ JoinStyle LottieParserImpl::getLineJoin()
 /*
  * https://github.com/airbnb/lottie-web/blob/master/docs/json/shapes/stroke.json
  */
-LOTStrokeData* LottieParserImpl::parseStrokeObject()
+model::Stroke *LottieParserImpl::parseStrokeObject()
 {
-    auto obj = allocator().make<LOTStrokeData>();
+    auto obj = allocator().make<model::Stroke>();
 
     while (const char *key = NextObjectKey()) {
         if (0 == strcmp(key, "nm")) {
@@ -1677,7 +1688,8 @@ LOTStrokeData* LottieParserImpl::parseStrokeObject()
     return obj;
 }
 
-void LottieParserImpl::parseGradientProperty(LOTGradient *obj, const char *key)
+void LottieParserImpl::parseGradientProperty(model::Gradient *obj,
+                                             const char *     key)
 {
     if (0 == strcmp(key, "t")) {
         RAPIDJSON_ASSERT(PeekType() == kNumberType);
@@ -1720,9 +1732,9 @@ void LottieParserImpl::parseGradientProperty(LOTGradient *obj, const char *key)
 /*
  * https://github.com/airbnb/lottie-web/blob/master/docs/json/shapes/gfill.json
  */
-LOTGFillData* LottieParserImpl::parseGFillObject()
+model::GradientFill *LottieParserImpl::parseGFillObject()
 {
-    auto obj = allocator().make<LOTGFillData>();
+    auto obj = allocator().make<model::GradientFill>();
 
     while (const char *key = NextObjectKey()) {
         if (0 == strcmp(key, "nm")) {
@@ -1736,7 +1748,7 @@ LOTGFillData* LottieParserImpl::parseGFillObject()
     return obj;
 }
 
-void LottieParserImpl::parseDashProperty(LOTDashProperty &dash)
+void LottieParserImpl::parseDashProperty(model::Dash &dash)
 {
     RAPIDJSON_ASSERT(PeekType() == kArrayType);
     EnterArray();
@@ -1757,9 +1769,9 @@ void LottieParserImpl::parseDashProperty(LOTDashProperty &dash)
 /*
  * https://github.com/airbnb/lottie-web/blob/master/docs/json/shapes/gstroke.json
  */
-LOTGStrokeData* LottieParserImpl::parseGStrokeObject()
+model::GradientStroke *LottieParserImpl::parseGStrokeObject()
 {
-    auto obj = allocator().make<LOTGStrokeData>();
+    auto obj = allocator().make<model::GradientStroke>();
 
     while (const char *key = NextObjectKey()) {
         if (0 == strcmp(key, "nm")) {
@@ -1831,7 +1843,7 @@ void LottieParserImpl::getValue(float &val)
     }
 }
 
-void LottieParserImpl::getValue(LottieColor &color)
+void LottieParserImpl::getValue(model::Color &color)
 {
     float val[4] = {0.f};
     int   i = 0;
@@ -1844,14 +1856,14 @@ void LottieParserImpl::getValue(LottieColor &color)
         }
     }
 
-    if (mColorFilter) mColorFilter( val[0] , val[1], val[2]) ;
+    if (mColorFilter) mColorFilter(val[0], val[1], val[2]);
 
     color.r = val[0];
     color.g = val[1];
     color.b = val[2];
 }
 
-void LottieParserImpl::getValue(LottieGradient &grad)
+void LottieParserImpl::getValue(model::Gradient::Data &grad)
 {
     if (PeekType() == kArrayType) EnterArray();
 
@@ -1907,7 +1919,7 @@ void LottieParserImpl::parsePathInfo()
     mPathInfo.convert();
 }
 
-void LottieParserImpl::getValue(LottieShapeData &obj)
+void LottieParserImpl::getValue(model::PathData &obj)
 {
     parsePathInfo();
     obj.mPoints = mPathInfo.mResult;
@@ -1931,14 +1943,14 @@ VPointF LottieParserImpl::parseInperpolatorPoint()
 }
 
 template <typename T>
-bool LottieParserImpl::parseKeyFrameValue(const char *, LOTKeyFrameValue<T> &)
+bool LottieParserImpl::parseKeyFrameValue(const char *, model::Value<T> &)
 {
     return false;
 }
 
 template <>
-bool LottieParserImpl::parseKeyFrameValue(const char *               key,
-                                          LOTKeyFrameValue<VPointF> &value)
+bool LottieParserImpl::parseKeyFrameValue(const char *           key,
+                                          model::Value<VPointF> &value)
 {
     if (0 == strcmp(key, "ti")) {
         value.mPathKeyFrame = true;
@@ -1952,8 +1964,9 @@ bool LottieParserImpl::parseKeyFrameValue(const char *               key,
     return true;
 }
 
-VInterpolator* LottieParserImpl::interpolator(
-    VPointF inTangent, VPointF outTangent, std::string key)
+VInterpolator *LottieParserImpl::interpolator(VPointF     inTangent,
+                                              VPointF     outTangent,
+                                              std::string key)
 {
     if (key.empty()) {
         std::array<char, 20> temp;
@@ -1977,7 +1990,7 @@ VInterpolator* LottieParserImpl::interpolator(
  * https://github.com/airbnb/lottie-web/blob/master/docs/json/properties/multiDimensionalKeyframed.json
  */
 template <typename T>
-void LottieParserImpl::parseKeyFrame(LOTAnimInfo<T> &obj)
+void LottieParserImpl::parseKeyFrame(model::DynamicProperty<T> &obj)
 {
     struct ParsedField {
         std::string interpolatorKey;
@@ -1988,10 +2001,10 @@ void LottieParserImpl::parseKeyFrame(LOTAnimInfo<T> &obj)
     };
 
     EnterObject();
-    ParsedField    parsed;
-    LOTKeyFrame<T> keyframe;
-    VPointF        inTangent;
-    VPointF        outTangent;
+    ParsedField        parsed;
+    model::KeyFrame<T> keyframe;
+    VPointF            inTangent;
+    VPointF            outTangent;
 
     while (const char *key = NextObjectKey()) {
         if (0 == strcmp(key, "i")) {
@@ -2069,7 +2082,7 @@ void LottieParserImpl::parseKeyFrame(LOTAnimInfo<T> &obj)
 /*
  * https://github.com/airbnb/lottie-web/blob/master/docs/json/properties/shape.json
  */
-void LottieParserImpl::parseShapeProperty(LOTAnimatable<LottieShapeData> &obj)
+void LottieParserImpl::parseShapeProperty(model::Property<model::PathData> &obj)
 {
     EnterObject();
     while (const char *key = NextObjectKey()) {
@@ -2098,7 +2111,7 @@ void LottieParserImpl::parseShapeProperty(LOTAnimatable<LottieShapeData> &obj)
 }
 
 template <typename T>
-void LottieParserImpl::parsePropertyHelper(LOTAnimatable<T> &obj)
+void LottieParserImpl::parsePropertyHelper(model::Property<T> &obj)
 {
     if (PeekType() == kNumberType) {
         if (!obj.isStatic()) {
@@ -2141,7 +2154,7 @@ void LottieParserImpl::parsePropertyHelper(LOTAnimatable<T> &obj)
  * https://github.com/airbnb/lottie-web/tree/master/docs/json/properties
  */
 template <typename T>
-void LottieParserImpl::parseProperty(LOTAnimatable<T> &obj)
+void LottieParserImpl::parseProperty(model::Property<T> &obj)
 {
     EnterObject();
     while (const char *key = NextObjectKey()) {
@@ -2155,9 +2168,9 @@ void LottieParserImpl::parseProperty(LOTAnimatable<T> &obj)
 
 #ifdef LOTTIE_DUMP_TREE_SUPPORT
 
-class LOTDataInspector {
+class model::ObjectInspector {
 public:
-    void visit(LOTCompositionData *obj, std::string level)
+    void visit(model::Composition *obj, std::string level)
     {
         vDebug << " { " << level << "Composition:: a: " << !obj->isStatic()
                << ", v: " << obj->mVersion << ", stFm: " << obj->startFrame()
@@ -2169,7 +2182,7 @@ public:
         level.erase(level.end() - 1, level.end());
         vDebug << " } " << level << "Composition End\n";
     }
-    void visit(LOTLayerData *obj, std::string level)
+    void visit(model::Layer *obj, std::string level)
     {
         vDebug << level << "{ " << layerType(obj->mLayerType)
                << ", name: " << obj->name() << ", id:" << obj->mId
@@ -2181,7 +2194,7 @@ public:
                << ", W:" << obj->layerSize().width()
                << ", H:" << obj->layerSize().height();
 
-        if (obj->mLayerType == LayerType::Image)
+        if (obj->mLayerType == model::Layer::Type::Image)
             vDebug << level << "\t{ "
                    << "ImageInfo:"
                    << " W :" << obj->extra()->mAsset->mWidth
@@ -2190,22 +2203,22 @@ public:
         else {
             vDebug << level;
         }
-        visitChildren(static_cast<LOTGroupData *>(obj), level);
+        visitChildren(static_cast<model::Group *>(obj), level);
         vDebug << level << "} " << layerType(obj->mLayerType).c_str()
                << ", id: " << obj->mId << "\n";
     }
-    void visitChildren(LOTGroupData *obj, std::string level)
+    void visitChildren(model::Group *obj, std::string level)
     {
         level.append("\t");
         for (const auto &child : obj->mChildren) visit(child, level);
         if (obj->mTransform) visit(obj->mTransform, level);
     }
 
-    void visit(LOTData *obj, std::string level)
+    void visit(model::Object *obj, std::string level)
     {
         switch (obj->type()) {
-        case LOTData::Type::Repeater: {
-            auto r = static_cast<LOTRepeaterData *>(obj);
+        case model::Object::Type::Repeater: {
+            auto r = static_cast<model::Repeater *>(obj);
             vDebug << level << "{ Repeater: name: " << obj->name()
                    << " , a:" << !obj->isStatic()
                    << ", copies:" << r->maxCopies()
@@ -2214,64 +2227,64 @@ public:
             vDebug << level << "} Repeater";
             break;
         }
-        case LOTData::Type::ShapeGroup: {
-            vDebug << level << "{ ShapeGroup: name: " << obj->name()
+        case model::Object::Type::Group: {
+            vDebug << level << "{ Group: name: " << obj->name()
                    << " , a:" << !obj->isStatic();
-            visitChildren(static_cast<LOTGroupData *>(obj), level);
-            vDebug << level << "} ShapeGroup";
+            visitChildren(static_cast<model::Group *>(obj), level);
+            vDebug << level << "} Group";
             break;
         }
-        case LOTData::Type::Layer: {
-            visit(static_cast<LOTLayerData *>(obj), level);
+        case model::Object::Type::Layer: {
+            visit(static_cast<model::Layer *>(obj), level);
             break;
         }
-        case LOTData::Type::Trim: {
+        case model::Object::Type::Trim: {
             vDebug << level << "{ Trim: name: " << obj->name()
                    << " , a:" << !obj->isStatic() << " }";
             break;
         }
-        case LOTData::Type::Rect: {
+        case model::Object::Type::Rect: {
             vDebug << level << "{ Rect: name: " << obj->name()
                    << " , a:" << !obj->isStatic() << " }";
             break;
         }
-        case LOTData::Type::Ellipse: {
+        case model::Object::Type::Ellipse: {
             vDebug << level << "{ Ellipse: name: " << obj->name()
                    << " , a:" << !obj->isStatic() << " }";
             break;
         }
-        case LOTData::Type::Shape: {
+        case model::Object::Type::Path: {
             vDebug << level << "{ Shape: name: " << obj->name()
                    << " , a:" << !obj->isStatic() << " }";
             break;
         }
-        case LOTData::Type::Polystar: {
+        case model::Object::Type::Polystar: {
             vDebug << level << "{ Polystar: name: " << obj->name()
                    << " , a:" << !obj->isStatic() << " }";
             break;
         }
-        case LOTData::Type::Transform: {
+        case model::Object::Type::Transform: {
             vDebug << level << "{ Transform: name: " << obj->name()
                    << " , a: " << !obj->isStatic() << " }";
             break;
         }
-        case LOTData::Type::Stroke: {
+        case model::Object::Type::Stroke: {
             vDebug << level << "{ Stroke: name: " << obj->name()
                    << " , a:" << !obj->isStatic() << " }";
             break;
         }
-        case LOTData::Type::GStroke: {
+        case model::Object::Type::GStroke: {
             vDebug << level << "{ GStroke: name: " << obj->name()
                    << " , a:" << !obj->isStatic() << " }";
             break;
         }
-        case LOTData::Type::Fill: {
+        case model::Object::Type::Fill: {
             vDebug << level << "{ Fill: name: " << obj->name()
                    << " , a:" << !obj->isStatic() << " }";
             break;
         }
-        case LOTData::Type::GFill: {
-            auto f = static_cast<LOTGFillData *>(obj);
+        case model::Object::Type::GFill: {
+            auto f = static_cast<model::GradientFill *>(obj);
             vDebug << level << "{ GFill: name: " << obj->name()
                    << " , a:" << !f->isStatic() << ", ty:" << f->mGradientType
                    << ", s:" << f->mStartPoint.value(0)
@@ -2286,19 +2299,19 @@ public:
     std::string matteType(MatteType type)
     {
         switch (type) {
-        case MatteType::None:
+        case model::MatteType::None:
             return "Matte::None";
             break;
-        case MatteType::Alpha:
+        case model::MatteType::Alpha:
             return "Matte::Alpha";
             break;
-        case MatteType::AlphaInv:
+        case model::MatteType::AlphaInv:
             return "Matte::AlphaInv";
             break;
-        case MatteType::Luma:
+        case model::MatteType::Luma:
             return "Matte::Luma";
             break;
-        case MatteType::LumaInv:
+        case model::MatteType::LumaInv:
             return "Matte::LumaInv";
             break;
         default:
@@ -2309,22 +2322,22 @@ public:
     std::string layerType(LayerType type)
     {
         switch (type) {
-        case LayerType::Precomp:
+        case model::Layer::Type::Precomp:
             return "Layer::Precomp";
             break;
-        case LayerType::Null:
+        case model::Layer::Type::Null:
             return "Layer::Null";
             break;
-        case LayerType::Shape:
+        case model::Layer::Type::Shape:
             return "Layer::Shape";
             break;
-        case LayerType::Solid:
+        case model::Layer::Type::Solid:
             return "Layer::Solid";
             break;
-        case LayerType::Image:
+        case model::Layer::Type::Image:
             return "Layer::Image";
             break;
-        case LayerType::Text:
+        case model::Layer::Type::Text:
             return "Layer::Text";
             break;
         default:
@@ -2336,32 +2349,30 @@ public:
 
 #endif
 
-LottieParser::~LottieParser() = default;
-LottieParser::LottieParser(char *str, std::string dir_path, ColorFilter filter)
-    : d(std::make_unique<LottieParserImpl>(str, std::move(dir_path), std::move(filter)))
-{
-    if (d->VerifyType())
-        d->parseComposition();
-    else
-        vWarning << "Input data is not Lottie format!";
-}
-
-std::shared_ptr<LOTModel> LottieParser::model()
+std::shared_ptr<model::Composition> model::parse(char *             str,
+                                                 std::string        dir_path,
+                                                 model::ColorFilter filter)
 {
-    if (!d->composition()) return nullptr;
-
-    std::shared_ptr<LOTModel> model = std::make_shared<LOTModel>();
-    model->mRoot = d->composition();
-    model->mRoot->processRepeaterObjects();
-    model->mRoot->updateStats();
+    LottieParserImpl obj(str, std::move(dir_path), std::move(filter));
 
+    if (obj.VerifyType()) {
+        obj.parseComposition();
+        auto composition = obj.composition();
+        if (composition) {
+            composition->processRepeaterObjects();
+            composition->updateStats();
 
 #ifdef LOTTIE_DUMP_TREE_SUPPORT
-    LOTDataInspector inspector;
-    inspector.visit(model->mRoot.get(), "");
+            model::ObjectInspector inspector;
+            inspector.visit(composition.get(), "");
 #endif
 
-    return model;
+            return composition;
+        }
+    }
+
+    vWarning << "Input data is not Lottie format!";
+    return {};
 }
 
 RAPIDJSON_DIAG_POP
diff --git a/src/lottie/lottieparser.h b/src/lottie/lottieparser.h
deleted file mode 100644 (file)
index 378719f..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#ifndef LOTTIEPARSER_H
-#define LOTTIEPARSER_H
-
-#include "lottiemodel.h"
-#include <memory>
-#include <functional>
-
-using ColorFilter = std::function<void(float &, float &, float &)>;
-class LottieParserImpl;
-class LottieParser {
-public:
-    ~LottieParser();
-    LottieParser(char* str, std::string dir_path, ColorFilter filter = {});
-    std::shared_ptr<LOTModel> model();
-private:
-   std::unique_ptr<LottieParserImpl>  d;
-};
-
-#endif // LOTTIEPARSER_H
index 9a6a3f9..6075169 100644 (file)
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
  */
 
 #ifndef LOTTIEPROXYMODEL_H
 #define LOTTIEPROXYMODEL_H
 
-#include<bitset>
-#include<algorithm>
-#include<cassert>
+#include <algorithm>
+#include <bitset>
+#include <cassert>
 #include "lottiemodel.h"
 #include "rlottie.h"
 
+using namespace rlottie::internal;
 // Naive way to implement std::variant
 // refactor it when we move to c++17
 // users should make sure proper combination
 // of id and value are passed while creating the object.
-class LOTVariant
-{
+class LOTVariant {
 public:
-    using ValueFunc = std::function<float(const rlottie::FrameInfo &)>;
-    using ColorFunc = std::function<rlottie::Color(const rlottie::FrameInfo &)>;
-    using PointFunc = std::function<rlottie::Point(const rlottie::FrameInfo &)>;
-    using SizeFunc = std::function<rlottie::Size(const rlottie::FrameInfo &)>;
+    using ValueFunc = std::function<float(const rlottie::FrameInfo&)>;
+    using ColorFunc = std::function<rlottie::Color(const rlottie::FrameInfo&)>;
+    using PointFunc = std::function<rlottie::Point(const rlottie::FrameInfo&)>;
+    using SizeFunc = std::function<rlottie::Size(const rlottie::FrameInfo&)>;
 
-    LOTVariant(rlottie::Property prop, const ValueFunc &v):mPropery(prop), mTag(Value)
+    LOTVariant(rlottie::Property prop, const ValueFunc& v)
+        : mPropery(prop), mTag(Value)
     {
         construct(impl.valueFunc, v);
     }
 
-    LOTVariant(rlottie::Property prop, ValueFunc &&v):mPropery(prop), mTag(Value)
+    LOTVariant(rlottie::Property prop, ValueFunc&& v)
+        : mPropery(prop), mTag(Value)
     {
         moveConstruct(impl.valueFunc, std::move(v));
     }
 
-    LOTVariant(rlottie::Property prop, const ColorFunc &v):mPropery(prop), mTag(Color)
+    LOTVariant(rlottie::Property prop, const ColorFunc& v)
+        : mPropery(prop), mTag(Color)
     {
         construct(impl.colorFunc, v);
     }
 
-    LOTVariant(rlottie::Property prop, ColorFunc &&v):mPropery(prop), mTag(Color)
+    LOTVariant(rlottie::Property prop, ColorFunc&& v)
+        : mPropery(prop), mTag(Color)
     {
         moveConstruct(impl.colorFunc, std::move(v));
     }
 
-    LOTVariant(rlottie::Property prop, const PointFunc &v):mPropery(prop), mTag(Point)
+    LOTVariant(rlottie::Property prop, const PointFunc& v)
+        : mPropery(prop), mTag(Point)
     {
         construct(impl.pointFunc, v);
     }
 
-    LOTVariant(rlottie::Property prop, PointFunc &&v):mPropery(prop), mTag(Point)
+    LOTVariant(rlottie::Property prop, PointFunc&& v)
+        : mPropery(prop), mTag(Point)
     {
         moveConstruct(impl.pointFunc, std::move(v));
     }
 
-    LOTVariant(rlottie::Property prop, const SizeFunc &v):mPropery(prop), mTag(Size)
+    LOTVariant(rlottie::Property prop, const SizeFunc& v)
+        : mPropery(prop), mTag(Size)
     {
         construct(impl.sizeFunc, v);
     }
 
-    LOTVariant(rlottie::Property prop, SizeFunc &&v):mPropery(prop), mTag(Size)
+    LOTVariant(rlottie::Property prop, SizeFunc&& v)
+        : mPropery(prop), mTag(Size)
     {
         moveConstruct(impl.sizeFunc, std::move(v));
     }
@@ -104,11 +112,22 @@ public:
     }
 
     LOTVariant() = default;
-    ~LOTVariant() noexcept {Destroy();}
-    LOTVariant(const LOTVariant& other) { Copy(other);}
-    LOTVariant(LOTVariant&& other) noexcept { Move(std::move(other));}
-    LOTVariant& operator=(LOTVariant&& other) { Destroy(); Move(std::move(other)); return *this;}
-    LOTVariant& operator=(const LOTVariant& other) { Destroy(); Copy(other); return *this;}
+    ~LOTVariant() noexcept { Destroy(); }
+    LOTVariant(const LOTVariant& other) { Copy(other); }
+    LOTVariant(LOTVariant&& other) noexcept { Move(std::move(other)); }
+    LOTVariant& operator=(LOTVariant&& other)
+    {
+        Destroy();
+        Move(std::move(other));
+        return *this;
+    }
+    LOTVariant& operator=(const LOTVariant& other)
+    {
+        Destroy();
+        Copy(other);
+        return *this;
+    }
+
 private:
     template <typename T>
     void construct(T& member, const T& val)
@@ -169,7 +188,7 @@ private:
 
     void Destroy()
     {
-        switch(mTag) {
+        switch (mTag) {
         case MonoState: {
             break;
         }
@@ -192,29 +211,29 @@ private:
         }
     }
 
-    enum Type {MonoState, Value, Color, Point , Size};
+    enum Type { MonoState, Value, Color, Point, Size };
     rlottie::Property mPropery;
     Type              mTag{MonoState};
-    union details{
-      ColorFunc   colorFunc;
-      ValueFunc   valueFunc;
-      PointFunc   pointFunc;
-      SizeFunc    sizeFunc;
-      details(){}
-      ~details(){}
-    }impl;
+    union details {
+        ColorFunc colorFunc;
+        ValueFunc valueFunc;
+        PointFunc pointFunc;
+        SizeFunc  sizeFunc;
+        details() {}
+        ~details() {}
+    } impl;
 };
 
-class LOTFilter
-{
+class LOTFilter {
 public:
-    void addValue(LOTVariant &value)
+    void addValue(LOTVariantvalue)
     {
         uint index = static_cast<uint>(value.property());
         if (mBitset.test(index)) {
-            std::replace_if(mFilters.begin(),
-                            mFilters.end(),
-                            [&value](const LOTVariant &e) {return e.property() == value.property();},
+            std::replace_if(mFilters.begin(), mFilters.end(),
+                            [&value](const LOTVariant& e) {
+                                return e.property() == value.property();
+                            },
                             value);
         } else {
             mBitset.set(index);
@@ -222,14 +241,16 @@ public:
         }
     }
 
-    void removeValue(LOTVariant &value)
+    void removeValue(LOTVariantvalue)
     {
         uint index = static_cast<uint>(value.property());
         if (mBitset.test(index)) {
             mBitset.reset(index);
-            mFilters.erase(std::remove_if(mFilters.begin(),
-                                          mFilters.end(),
-                                          [&value](const LOTVariant &e) {return e.property() == value.property();}),
+            mFilters.erase(std::remove_if(mFilters.begin(), mFilters.end(),
+                                          [&value](const LOTVariant& e) {
+                                              return e.property() ==
+                                                     value.property();
+                                          }),
                            mFilters.end());
         }
     }
@@ -237,55 +258,55 @@ public:
     {
         return mBitset.test(static_cast<uint>(prop));
     }
-    LottieColor color(rlottie::Property prop, int frame) const
+    model::Color color(rlottie::Property prop, int frame) const
     {
         rlottie::FrameInfo info(frame);
-        rlottie::Color col = data(prop).color()(info);
-        return LottieColor(col.r(), col.g(), col.b());
+        rlottie::Color     col = data(prop).color()(info);
+        return model::Color(col.r(), col.g(), col.b());
     }
     VPointF point(rlottie::Property prop, int frame) const
     {
         rlottie::FrameInfo info(frame);
-        rlottie::Point pt = data(prop).point()(info);
+        rlottie::Point     pt = data(prop).point()(info);
         return VPointF(pt.x(), pt.y());
     }
     VSize scale(rlottie::Property prop, int frame) const
     {
         rlottie::FrameInfo info(frame);
-        rlottie::Size sz = data(prop).size()(info);
+        rlottie::Size      sz = data(prop).size()(info);
         return VSize(sz.w(), sz.h());
     }
     float opacity(rlottie::Property prop, int frame) const
     {
         rlottie::FrameInfo info(frame);
-        float val = data(prop).value()(info);
-        return val/100;
+        float              val = data(prop).value()(info);
+        return val / 100;
     }
     float value(rlottie::Property prop, int frame) const
     {
         rlottie::FrameInfo info(frame);
         return data(prop).value()(info);
     }
+
 private:
     const LOTVariant& data(rlottie::Property prop) const
     {
-        auto result = std::find_if(mFilters.begin(),
-                                   mFilters.end(),
-                                   [prop](const LOTVariant &e){return e.property() == prop;});
+        auto result = std::find_if(
+            mFilters.begin(), mFilters.end(),
+            [prop](const LOTVariant& e) { return e.property() == prop; });
         return *result;
     }
-    std::bitset<32>            mBitset{0};
-    std::vector<LOTVariant>    mFilters;
+    std::bitset<32>         mBitset{0};
+    std::vector<LOTVariant> mFilters;
 };
 
 template <typename T>
-class LOTProxyModel
-{
+class LOTProxyModel {
 public:
-    LOTProxyModel(T *model): _modelData(model) {}
-    LOTFilter& filter() {return mFilter;}
-    const char* name() const {return _modelData->name();}
-    LottieColor color(int frame) const
+    LOTProxyModel(T* model) : _modelData(model) {}
+    LOTFilter&   filter() { return mFilter; }
+    const char*  name() const { return _modelData->name(); }
+    model::Color color(int frame) const
     {
         if (mFilter.hasFilter(rlottie::Property::StrokeColor)) {
             return mFilter.color(rlottie::Property::StrokeColor, frame);
@@ -306,27 +327,27 @@ public:
         }
         return _modelData->strokeWidth(frame);
     }
-    float miterLimit() const {return _modelData->miterLimit();}
-    CapStyle capStyle() const {return _modelData->capStyle();}
-    JoinStyle joinStyle() const {return _modelData->joinStyle();}
-    bool hasDashInfo() const { return _modelData->hasDashInfo();}
-    void getDashInfo(int frameNo, std::vector<float>& result) const {
+    float     miterLimit() const { return _modelData->miterLimit(); }
+    CapStyle  capStyle() const { return _modelData->capStyle(); }
+    JoinStyle joinStyle() const { return _modelData->joinStyle(); }
+    bool      hasDashInfo() const { return _modelData->hasDashInfo(); }
+    void      getDashInfo(int frameNo, std::vector<float>& result) const
+    {
         return _modelData->getDashInfo(frameNo, result);
     }
 
 private:
-    T                         *_modelData;
-    LOTFilter                  mFilter;
+    T*        _modelData;
+    LOTFilter mFilter;
 };
 
 template <>
-class LOTProxyModel<LOTFillData>
-{
+class LOTProxyModel<model::Fill> {
 public:
-    LOTProxyModel(LOTFillData *model): _modelData(model) {}
-    LOTFilter& filter() {return mFilter;}
-    const char* name() const {return _modelData->name();}
-    LottieColor color(int frame) const
+    LOTProxyModel(model::Fill* model) : _modelData(model) {}
+    LOTFilter&   filter() { return mFilter; }
+    const char*  name() const { return _modelData->name(); }
+    model::Color color(int frame) const
     {
         if (mFilter.hasFilter(rlottie::Property::FillColor)) {
             return mFilter.color(rlottie::Property::FillColor, frame);
@@ -340,22 +361,22 @@ public:
         }
         return _modelData->opacity(frame);
     }
-    FillRule fillRule() const {return _modelData->fillRule();}
+    FillRule fillRule() const { return _modelData->fillRule(); }
+
 private:
-    LOTFillData               *_modelData;
-    LOTFilter                  mFilter;
+    model::Fill* _modelData;
+    LOTFilter    mFilter;
 };
 
 template <>
-class LOTProxyModel<LOTGroupData>
-{
+class LOTProxyModel<model::Group> {
 public:
-    LOTProxyModel(LOTGroupData *model = nullptr): _modelData(model) {}
-    bool hasModel() const { return _modelData ? true : false; }
-    LOTFilter& filter() {return mFilter;}
-    const char* name() const {return _modelData->name();}
-    LOTTransformData* transform() const { return _modelData->mTransform; }
-    VMatrix matrix(int frame) const
+    LOTProxyModel(model::Group* model = nullptr) : _modelData(model) {}
+    bool              hasModel() const { return _modelData ? true : false; }
+    LOTFilter&        filter() { return mFilter; }
+    const char*       name() const { return _modelData->name(); }
+    model::Transform* transform() const { return _modelData->mTransform; }
+    VMatrix           matrix(int frame) const
     {
         VMatrix mS, mR, mT;
         if (mFilter.hasFilter(rlottie::Property::TrScale)) {
@@ -371,8 +392,9 @@ public:
 
         return _modelData->mTransform->matrix(frame) * mS * mR * mT;
     }
+
 private:
-    LOTGroupData               *_modelData;
-    LOTFilter                  mFilter;
+    model::Group* _modelData;
+    LOTFilter     mFilter;
 };
-#endif // LOTTIEITEM_H
+#endif  // LOTTIEITEM_H