lottie: refactor trim object handling
[platform/core/uifw/lottie-player.git] / src / lottie / lottieitem.h
1 #ifndef LOTTIEITEM_H
2 #define LOTTIEITEM_H
3
4 #include<lottiemodel.h>
5 #include<sstream>
6 #include<memory>
7
8 #include"vmatrix.h"
9 #include"vpath.h"
10 #include"vpoint.h"
11 #include"vpathmesure.h"
12 #include"lottiecommon.h"
13 #include"lottieanimation.h"
14 #include"vpainter.h"
15 #include"vdrawable.h"
16
17 V_USE_NAMESPACE
18
19 enum class DirtyFlagBit : uchar
20 {
21    None   = 0x00,
22    Matrix = 0x01,
23    Alpha  = 0x02,
24    All    = (Matrix | Alpha)
25 };
26
27 class LOTLayerItem;
28 class LOTMaskItem;
29 class VDrawable;
30
31 class LOTCompItem
32 {
33 public:
34    LOTCompItem(LOTModel *model);
35    static std::unique_ptr<LOTLayerItem> createLayerItem(LOTLayerData *layerData);
36    bool update(int frameNo);
37    void resize(const VSize &size);
38    VSize size() const;
39    const std::vector<LOTNode *>& renderList()const;
40    void buildRenderList();
41    bool render(const lottie::Surface &surface);
42 private:
43    VMatrix                                    mScaleMatrix;
44    VSize                                      mViewSize;
45    LOTModel                                   *mRootModel;
46    LOTCompositionData                         *mCompData;
47    std::unique_ptr<LOTLayerItem>               mRootLayer;
48    bool                                        mUpdateViewBox;
49    int                                         mCurFrameNo;
50    std::vector<LOTNode *>                      mRenderList;
51    std::vector<VDrawable *>                    mDrawableList;
52 };
53
54 typedef vFlag<DirtyFlagBit> DirtyFlag;
55 class LOTLayerItem
56 {
57 public:
58    LOTLayerItem(LOTLayerData *layerData);
59    virtual ~LOTLayerItem()= default;
60    int id() const {return mLayerData->id();}
61    int parentId() const {return mLayerData->parentId();}
62    void setParentLayer(LOTLayerItem *parent){mParentLayer = parent;}
63    void setPrecompLayer(LOTLayerItem *precomp){mPrecompLayer = precomp;}
64    virtual void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha);
65    VMatrix matrix(int frameNo) const;
66    virtual void renderList(std::vector<VDrawable *> &){}
67    virtual void updateStaticProperty();
68    virtual void render(VPainter *painter, const VRle &mask, const VRle &inheritMatte, LOTLayerItem *matteSource);
69    bool hasMatte() { if (mLayerData->mMatteType == MatteType::None) return false; return true; }
70    bool visible() const;
71
72 protected:
73    virtual void updateContent() = 0;
74    inline VMatrix combinedMatrix() const {return mCombinedMatrix;}
75    inline int frameNo() const {return mFrameNo;}
76    inline float combinedAlpha() const {return mCombinedAlpha;}
77    inline bool isStatic() const {return mStatic;}
78    float opacity(int frameNo) const;
79    inline DirtyFlag flag() const {return mDirtyFlag;}
80    VRle maskRle(const VRect &clipRect);
81    bool hasMask() const {return !mMasks.empty();}
82 protected:
83    std::vector<VDrawable *>                    mDrawableList;
84    std::vector<std::unique_ptr<LOTMaskItem>>   mMasks;
85    LOTLayerData                               *mLayerData{nullptr};
86    LOTLayerItem                               *mParentLayer{nullptr};
87    LOTLayerItem                               *mPrecompLayer{nullptr};
88    VMatrix                                     mCombinedMatrix;
89    float                                       mCombinedAlpha{0.0};
90    int                                         mFrameNo{-1};
91    DirtyFlag                                   mDirtyFlag{DirtyFlagBit::All};
92    bool                                        mStatic;
93 };
94
95 class LOTCompLayerItem: public LOTLayerItem
96 {
97 public:
98    LOTCompLayerItem(LOTLayerData *layerData);
99    void renderList(std::vector<VDrawable *> &list)final;
100    void updateStaticProperty() final;
101    void render(VPainter *painter, const VRle &mask, const VRle &inheritMatte, LOTLayerItem *matteSource) final;
102 protected:
103    void updateContent() final;
104 private:
105    std::vector<std::unique_ptr<LOTLayerItem>>   mLayers;
106    int                                          mLastFrame;
107 };
108
109 class LOTSolidLayerItem: public LOTLayerItem
110 {
111 public:
112    LOTSolidLayerItem(LOTLayerData *layerData);
113 protected:
114    void updateContent() final;
115    void renderList(std::vector<VDrawable *> &list) final;
116 private:
117    std::unique_ptr<VDrawable>   mRenderNode;
118 };
119
120 class LOTContentItem;
121 class LOTContentGroupItem;
122 class LOTShapeLayerItem: public LOTLayerItem
123 {
124 public:
125    LOTShapeLayerItem(LOTLayerData *layerData);
126    static std::unique_ptr<LOTContentItem> createContentItem(LOTData *contentData);
127    void renderList(std::vector<VDrawable *> &list)final;
128 protected:
129    void updateContent() final;
130    std::unique_ptr<LOTContentGroupItem> mRoot;
131 };
132
133 class LOTNullLayerItem: public LOTLayerItem
134 {
135 public:
136    LOTNullLayerItem(LOTLayerData *layerData);
137 protected:
138    void updateContent() final;
139 };
140
141 class LOTMaskItem
142 {
143 public:
144     LOTMaskItem(LOTMaskData *data): mData(data), mCombinedAlpha(0){}
145     void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha, const DirtyFlag &flag);
146     LOTMaskData::Mode maskMode() const { return mData->mMode;}
147     VRle rle();
148 public:
149     LOTMaskData             *mData;
150     float                    mCombinedAlpha;
151     VMatrix                  mCombinedMatrix;
152     VPath                    mLocalPath;
153     std::future<VRle>        mRleTask;
154     VRle                     mRle;
155 };
156
157 class LOTDrawable : public VDrawable
158 {
159 public:
160     void sync();
161 public:
162     std::unique_ptr<LOTNode>  mCNode;
163
164     ~LOTDrawable() {
165         if (mCNode && mCNode->mGradient.stopPtr)
166           free(mCNode->mGradient.stopPtr);
167     }
168 };
169
170 class LOTPathDataItem;
171 class LOTPaintDataItem;
172 class LOTTrimItem;
173
174 class LOTContentItem
175 {
176 public:
177    virtual ~LOTContentItem()= default;
178    virtual void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha, const DirtyFlag &flag) = 0;
179    virtual void renderList(std::vector<VDrawable *> &){}
180    void setParent(LOTContentItem *parent) {mParent = parent;}
181    LOTContentItem *parent() const {return mParent;}
182 private:
183    LOTContentItem *mParent{nullptr};
184 };
185
186 class LOTContentGroupItem: public LOTContentItem
187 {
188 public:
189    LOTContentGroupItem(LOTShapeGroupData *data);
190    void addChildren(LOTGroupData *data);
191    void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha, const DirtyFlag &flag) final;
192    void applyTrim();
193    void processTrimItems(std::vector<LOTPathDataItem *> &list);
194    void processPaintItems(std::vector<LOTPathDataItem *> &list);
195    void renderList(std::vector<VDrawable *> &list) final;
196    const VMatrix & matrix() const { return mMatrix;}
197 private:
198    LOTShapeGroupData                             *mData;
199    std::vector<std::unique_ptr<LOTContentItem>>   mContents;
200    VMatrix                                        mMatrix;
201 };
202
203 class LOTPathDataItem : public LOTContentItem
204 {
205 public:
206    LOTPathDataItem(bool staticPath): mStaticPath(staticPath){}
207    void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha, const DirtyFlag &flag) final;
208    bool dirty() const {return mPathChanged;}
209    const VPath &localPath() const {return mTemp;}
210    const VPath &finalPath();
211    void updatePath(const VPath &path) {mTemp.clone(path); mPathChanged = true; mNeedUpdate = true;}
212    bool staticPath() const { return mStaticPath; }
213 protected:
214    virtual void updatePath(VPath& path, int frameNo) = 0;
215    virtual bool hasChanged(int frameNo) = 0;
216 private:
217    VPath                                   mLocalPath;
218    VPath                                   mTemp;
219    VPath                                   mFinalPath;
220    bool                                    mPathChanged{true};
221    bool                                    mNeedUpdate{true};
222    bool                                    mStaticPath;
223 };
224
225 class LOTRectItem: public LOTPathDataItem
226 {
227 public:
228    LOTRectItem(LOTRectData *data);
229 protected:
230    void updatePath(VPath& path, int frameNo) final;
231    LOTRectData           *mData;
232
233    struct Cache {
234         int                  mFrameNo{-1};
235         float                mRoundness;
236         VPointF              mPos;
237         VPointF              mSize;
238    };
239    Cache                     mCache;
240
241    void updateCache(int frameNo, VPointF pos, VPointF size, float roundness) {
242         mCache.mFrameNo = frameNo;
243         mCache.mPos = pos;
244         mCache.mSize = size;
245         mCache.mRoundness = roundness;
246    }
247    bool hasChanged(int frameNo) final {
248         if (mCache.mFrameNo != -1 && staticPath()) return false;
249         if (mCache.mFrameNo == frameNo) return false;
250
251         VPointF pos = mData->mPos.value(frameNo);
252         VPointF size = mData->mSize.value(frameNo);
253         float   roundness = mData->mRound.value(frameNo);
254
255         if (vCompare(mCache.mPos.x(), pos.x()) && vCompare(mCache.mPos.y(), pos.y()) &&
256             vCompare(mCache.mSize.x(), size.x()) && vCompare(mCache.mSize.y(), size.y()) &&
257             vCompare(mCache.mRoundness, roundness))
258           return false;
259
260         return true;
261    }
262 };
263
264 class LOTEllipseItem: public LOTPathDataItem
265 {
266 public:
267    LOTEllipseItem(LOTEllipseData *data);
268 private:
269    void updatePath(VPath& path, int frameNo) final;
270    LOTEllipseData           *mData;
271
272    struct Cache {
273         int                  mFrameNo{-1};
274         VPointF              mPos;
275         VPointF              mSize;
276    };
277    Cache                     mCache;
278
279    void updateCache(int frameNo, VPointF pos, VPointF size) {
280         mCache.mFrameNo = frameNo;
281         mCache.mPos = pos;
282         mCache.mSize = size;
283    }
284    bool hasChanged(int frameNo) final {
285         if (mCache.mFrameNo != -1 && staticPath()) return false;
286         if (mCache.mFrameNo == frameNo) return false;
287
288         VPointF pos = mData->mPos.value(frameNo);
289         VPointF size = mData->mSize.value(frameNo);
290
291         if (vCompare(mCache.mPos.x(), pos.x()) && vCompare(mCache.mPos.y(), pos.y()) &&
292             vCompare(mCache.mSize.x(), size.x()) && vCompare(mCache.mSize.y(), size.y()))
293           return false;
294
295         return true;
296    }
297 };
298
299 class LOTShapeItem: public LOTPathDataItem
300 {
301 public:
302    LOTShapeItem(LOTShapeData *data);
303 private:
304    void updatePath(VPath& path, int frameNo) final;
305    LOTShapeData             *mData;
306    bool hasChanged(int) final { return true; }
307 };
308
309 class LOTPolystarItem: public LOTPathDataItem
310 {
311 public:
312    LOTPolystarItem(LOTPolystarData *data);
313 private:
314    void updatePath(VPath& path, int frameNo) final;
315    LOTPolystarData             *mData;
316
317    struct Cache {
318         int                     mFrameNo{-1};
319         VPointF                 mPos;
320         float                   mPoints{0};
321         float                   mInnerRadius{0};
322         float                   mOuterRadius{0};
323         float                   mInnerRoundness{0};
324         float                   mOuterRoundness{0};
325         float                   mRotation{0};
326    };
327    Cache                        mCache;
328
329    void updateCache(int frameNo, VPointF pos, float points, float innerRadius, float outerRadius,
330                     float innerRoundness, float outerRoundness, float rotation) {
331         mCache.mFrameNo = frameNo;
332         mCache.mPos = pos;
333         mCache.mPoints = points;
334         mCache.mInnerRadius = innerRadius;
335         mCache.mOuterRadius = outerRadius;
336         mCache.mInnerRoundness = innerRoundness;
337         mCache.mOuterRoundness = outerRoundness;
338         mCache.mRotation = rotation;
339    }
340    bool hasChanged(int frameNo) final {
341         if (mCache.mFrameNo != -1 && staticPath()) return false;
342         if (mCache.mFrameNo == frameNo) return false;
343
344         VPointF pos = mData->mPos.value(frameNo);
345         float   points = mData->mPointCount.value(frameNo);
346         float   innerRadius = mData->mInnerRadius.value(frameNo);
347         float   outerRadius = mData->mOuterRadius.value(frameNo);
348         float   innerRoundness = mData->mInnerRoundness.value(frameNo);
349         float   outerRoundness = mData->mOuterRoundness.value(frameNo);
350         float   rotation = mData->mRotation.value(frameNo);
351
352         if (vCompare(mCache.mPos.x(), pos.x()) && vCompare(mCache.mPos.y(), pos.y()) &&
353             vCompare(mCache.mPoints, points) && vCompare(mCache.mRotation, rotation) &&
354             vCompare(mCache.mInnerRadius, innerRadius) && vCompare(mCache.mOuterRadius, outerRadius) &&
355             vCompare(mCache.mInnerRoundness, innerRoundness) && vCompare(mCache.mOuterRoundness, outerRoundness))
356           return false;
357
358         return true;
359    }
360 };
361
362
363
364 class LOTPaintDataItem : public LOTContentItem
365 {
366 public:
367    LOTPaintDataItem(bool staticContent);
368    void addPathItems(std::vector<LOTPathDataItem *> &list, int startOffset);
369    void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha, const DirtyFlag &flag) override;
370    void renderList(std::vector<VDrawable *> &list) final;
371 protected:
372    virtual void updateContent(int frameNo) = 0;
373    virtual void updateRenderNode();
374    inline float parentAlpha() const {return mParentAlpha;}
375 public:
376    float                            mParentAlpha;
377    VPath                            mPath;
378    DirtyFlag                        mFlag;
379    int                              mFrameNo;
380    std::vector<LOTPathDataItem *>   mPathItems;
381    std::unique_ptr<VDrawable>       mDrawable;
382    bool                             mStaticContent;
383    bool                             mRenderNodeUpdate{true};
384 };
385
386 class LOTFillItem : public LOTPaintDataItem
387 {
388 public:
389    LOTFillItem(LOTFillData *data);
390 protected:
391    void updateContent(int frameNo) final;
392    void updateRenderNode() final;
393 private:
394    LOTFillData             *mData;
395    VColor                  mColor;
396    FillRule                mFillRule;
397 };
398
399 class LOTGFillItem : public LOTPaintDataItem
400 {
401 public:
402    LOTGFillItem(LOTGFillData *data);
403 protected:
404    void updateContent(int frameNo) final;
405    void updateRenderNode() final;
406 private:
407    LOTGFillData                 *mData;
408    std::unique_ptr<VGradient>    mGradient;
409    FillRule                      mFillRule;
410 };
411
412 class LOTStrokeItem : public LOTPaintDataItem
413 {
414 public:
415    LOTStrokeItem(LOTStrokeData *data);
416 protected:
417    void updateContent(int frameNo) final;
418    void updateRenderNode() final;
419 private:
420    LOTStrokeData             *mData;
421    CapStyle                  mCap;
422    JoinStyle                 mJoin;
423    float                     mMiterLimit;
424    VColor                    mColor;
425    float                     mWidth;
426    float                     mDashArray[6];
427    int                       mDashArraySize;
428 };
429
430 class LOTGStrokeItem : public LOTPaintDataItem
431 {
432 public:
433    LOTGStrokeItem(LOTGStrokeData *data);
434 protected:
435    void updateContent(int frameNo) final;
436    void updateRenderNode() final;
437 private:
438    LOTGStrokeData               *mData;
439    std::unique_ptr<VGradient>    mGradient;
440    CapStyle                      mCap;
441    JoinStyle                     mJoin;
442    float                         mMiterLimit;
443    VColor                        mColor;
444    float                         mWidth;
445    float                         mDashArray[6];
446    int                           mDashArraySize;
447 };
448
449
450 // Trim Item
451
452 class LOTTrimItem : public LOTContentItem
453 {
454 public:
455    LOTTrimItem(LOTTrimData *data);
456    void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha, const DirtyFlag &flag) final;
457    void update();
458    void addPathItems(std::vector<LOTPathDataItem *> &list, int startOffset);
459 private:
460    bool pathDirty() const {
461        for (auto &i : mPathItems) {
462            if (i->dirty())
463                return true;
464        }
465        return false;
466    }
467    struct Cache {
468         int                     mFrameNo{-1};
469         LOTTrimData::Segment    mSegment{};
470    };
471    Cache                            mCache;
472    std::vector<LOTPathDataItem *>   mPathItems;
473    LOTTrimData                     *mData;
474    bool                             mDirty{true};
475 };
476
477 class LOTRepeaterItem : public LOTContentItem
478 {
479 public:
480    LOTRepeaterItem(LOTRepeaterData *data);
481    void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha, const DirtyFlag &flag) final;
482    void renderList(std::vector<VDrawable *> &list) final;
483 private:
484    LOTRepeaterData             *mData;
485 };
486
487
488 #endif // LOTTIEITEM_H
489
490