lottie/render: handle AlphaInverse matte for composition layer.
[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    void buildRenderTree();
42    const LOTLayerNode * renderTree()const;
43    bool render(const lottie::Surface &surface);
44 private:
45    VMatrix                                    mScaleMatrix;
46    VSize                                      mViewSize;
47    LOTModel                                   *mRootModel;
48    LOTCompositionData                         *mCompData;
49    std::unique_ptr<LOTLayerItem>               mRootLayer;
50    bool                                        mUpdateViewBox;
51    int                                         mCurFrameNo;
52    std::vector<LOTNode *>                      mRenderList;
53    std::vector<VDrawable *>                    mDrawableList;
54 };
55
56 typedef vFlag<DirtyFlagBit> DirtyFlag;
57 class LOTLayerItem
58 {
59 public:
60    LOTLayerItem(LOTLayerData *layerData);
61    virtual ~LOTLayerItem()= default;
62    int id() const {return mLayerData->id();}
63    int parentId() const {return mLayerData->parentId();}
64    void setParentLayer(LOTLayerItem *parent){mParentLayer = parent;}
65    void setPrecompLayer(LOTLayerItem *precomp){mPrecompLayer = precomp;}
66    virtual void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha);
67    VMatrix matrix(int frameNo) const;
68    virtual void renderList(std::vector<VDrawable *> &){}
69    virtual void updateStaticProperty();
70    virtual void render(VPainter *painter, const VRle &mask, const VRle &inheritMatte, LOTLayerItem *matteSource);
71    bool hasMatte() { if (mLayerData->mMatteType == MatteType::None) return false; return true; }
72    MatteType matteType() const { return mLayerData->mMatteType;}
73    bool visible() const;
74    virtual void buildLayerNode();
75    LOTLayerNode * layerNode() const {return mLayerCNode.get();}
76 protected:
77    virtual void updateContent() = 0;
78    inline VMatrix combinedMatrix() const {return mCombinedMatrix;}
79    inline int frameNo() const {return mFrameNo;}
80    inline float combinedAlpha() const {return mCombinedAlpha;}
81    inline bool isStatic() const {return mStatic;}
82    float opacity(int frameNo) const;
83    inline DirtyFlag flag() const {return mDirtyFlag;}
84    VRle maskRle(const VRect &clipRect);
85    bool hasMask() const {return !mMasks.empty();}
86 protected:
87    std::unique_ptr<LOTLayerNode>               mLayerCNode;
88    std::vector<VDrawable *>                    mDrawableList;
89    std::vector<std::unique_ptr<LOTMaskItem>>   mMasks;
90    LOTLayerData                               *mLayerData{nullptr};
91    LOTLayerItem                               *mParentLayer{nullptr};
92    LOTLayerItem                               *mPrecompLayer{nullptr};
93    VMatrix                                     mCombinedMatrix;
94    float                                       mCombinedAlpha{0.0};
95    int                                         mFrameNo{-1};
96    DirtyFlag                                   mDirtyFlag{DirtyFlagBit::All};
97    bool                                        mStatic;
98 };
99
100 class LOTCompLayerItem: public LOTLayerItem
101 {
102 public:
103    LOTCompLayerItem(LOTLayerData *layerData);
104    void renderList(std::vector<VDrawable *> &list)final;
105    void updateStaticProperty() final;
106    void render(VPainter *painter, const VRle &mask, const VRle &inheritMatte, LOTLayerItem *matteSource) final;
107    void buildLayerNode() final;
108 protected:
109    void updateContent() final;
110 private:
111    std::vector<LOTLayerNode *>                  mLayersCNode;
112    std::vector<std::unique_ptr<LOTLayerItem>>   mLayers;
113    int                                          mLastFrame;
114 };
115
116 class LOTSolidLayerItem: public LOTLayerItem
117 {
118 public:
119    LOTSolidLayerItem(LOTLayerData *layerData);
120    void buildLayerNode() final;
121 protected:
122    void updateContent() final;
123    void renderList(std::vector<VDrawable *> &list) final;
124 private:
125    std::vector<LOTNode *>       mCNodeList;
126    std::unique_ptr<VDrawable>   mRenderNode;
127 };
128
129 class LOTContentItem;
130 class LOTContentGroupItem;
131 class LOTShapeLayerItem: public LOTLayerItem
132 {
133 public:
134    LOTShapeLayerItem(LOTLayerData *layerData);
135    static std::unique_ptr<LOTContentItem> createContentItem(LOTData *contentData);
136    void renderList(std::vector<VDrawable *> &list)final;
137    void buildLayerNode() final;
138 protected:
139    void updateContent() final;
140    std::vector<LOTNode *>               mCNodeList;
141    std::unique_ptr<LOTContentGroupItem> mRoot;
142 };
143
144 class LOTNullLayerItem: public LOTLayerItem
145 {
146 public:
147    LOTNullLayerItem(LOTLayerData *layerData);
148 protected:
149    void updateContent() final;
150 };
151
152 class LOTMaskItem
153 {
154 public:
155     LOTMaskItem(LOTMaskData *data): mData(data), mCombinedAlpha(0){}
156     void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha, const DirtyFlag &flag);
157     LOTMaskData::Mode maskMode() const { return mData->mMode;}
158     VRle rle();
159 public:
160     LOTMaskData             *mData;
161     float                    mCombinedAlpha;
162     VMatrix                  mCombinedMatrix;
163     VPath                    mLocalPath;
164     std::future<VRle>        mRleTask;
165     VRle                     mRle;
166 };
167
168 class LOTDrawable : public VDrawable
169 {
170 public:
171     void sync();
172 public:
173     std::unique_ptr<LOTNode>  mCNode;
174
175     ~LOTDrawable() {
176         if (mCNode && mCNode->mGradient.stopPtr)
177           free(mCNode->mGradient.stopPtr);
178     }
179 };
180
181 class LOTPathDataItem;
182 class LOTPaintDataItem;
183 class LOTTrimItem;
184
185 class LOTContentItem
186 {
187 public:
188    virtual ~LOTContentItem()= default;
189    virtual void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha, const DirtyFlag &flag) = 0;
190    virtual void renderList(std::vector<VDrawable *> &){}
191    void setParent(LOTContentItem *parent) {mParent = parent;}
192    LOTContentItem *parent() const {return mParent;}
193 private:
194    LOTContentItem *mParent{nullptr};
195 };
196
197 class LOTContentGroupItem: public LOTContentItem
198 {
199 public:
200    LOTContentGroupItem(LOTShapeGroupData *data);
201    void addChildren(LOTGroupData *data);
202    void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha, const DirtyFlag &flag) final;
203    void applyTrim();
204    void processTrimItems(std::vector<LOTPathDataItem *> &list);
205    void processPaintItems(std::vector<LOTPathDataItem *> &list);
206    void renderList(std::vector<VDrawable *> &list) final;
207    const VMatrix & matrix() const { return mMatrix;}
208 private:
209    LOTShapeGroupData                             *mData;
210    std::vector<std::unique_ptr<LOTContentItem>>   mContents;
211    VMatrix                                        mMatrix;
212 };
213
214 class LOTPathDataItem : public LOTContentItem
215 {
216 public:
217    LOTPathDataItem(bool staticPath): mStaticPath(staticPath){}
218    void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha, const DirtyFlag &flag) final;
219    bool dirty() const {return mPathChanged;}
220    const VPath &localPath() const {return mTemp;}
221    const VPath &finalPath();
222    void updatePath(const VPath &path) {mTemp.clone(path); mPathChanged = true; mNeedUpdate = true;}
223    bool staticPath() const { return mStaticPath; }
224 protected:
225    virtual void updatePath(VPath& path, int frameNo) = 0;
226    virtual bool hasChanged(int prevFrame, int curFrame) = 0;
227 private:
228    bool hasChanged(int frameNo) {
229        int prevFrame = mFrameNo;
230        mFrameNo = frameNo;
231        if (prevFrame == -1) return true;
232        if (mStaticPath ||
233            (prevFrame == frameNo)) return false;
234        return hasChanged(prevFrame, frameNo);
235    }
236    VPath                                   mLocalPath;
237    VPath                                   mTemp;
238    VPath                                   mFinalPath;
239    int                                     mFrameNo{-1};
240    bool                                    mPathChanged{true};
241    bool                                    mNeedUpdate{true};
242    bool                                    mStaticPath;
243 };
244
245 class LOTRectItem: public LOTPathDataItem
246 {
247 public:
248    LOTRectItem(LOTRectData *data);
249 protected:
250    void updatePath(VPath& path, int frameNo) final;
251    LOTRectData           *mData;
252
253    bool hasChanged(int prevFrame, int curFrame) final {
254        return (mData->mPos.changed(prevFrame, curFrame) ||
255                mData->mSize.changed(prevFrame, curFrame) ||
256                mData->mRound.changed(prevFrame, curFrame)) ? true : false;
257    }
258 };
259
260 class LOTEllipseItem: public LOTPathDataItem
261 {
262 public:
263    LOTEllipseItem(LOTEllipseData *data);
264 private:
265    void updatePath(VPath& path, int frameNo) final;
266    LOTEllipseData           *mData;
267    bool hasChanged(int prevFrame, int curFrame) final {
268        return (mData->mPos.changed(prevFrame, curFrame) ||
269                mData->mSize.changed(prevFrame, curFrame)) ? true : false;
270    }
271 };
272
273 class LOTShapeItem: public LOTPathDataItem
274 {
275 public:
276    LOTShapeItem(LOTShapeData *data);
277 private:
278    void updatePath(VPath& path, int frameNo) final;
279    LOTShapeData             *mData;
280    bool hasChanged(int prevFrame, int curFrame) final {
281        return mData->mShape.changed(prevFrame, curFrame);
282    }
283 };
284
285 class LOTPolystarItem: public LOTPathDataItem
286 {
287 public:
288    LOTPolystarItem(LOTPolystarData *data);
289 private:
290    void updatePath(VPath& path, int frameNo) final;
291    LOTPolystarData             *mData;
292
293    bool hasChanged(int prevFrame, int curFrame) final {
294        return (mData->mPos.changed(prevFrame, curFrame) ||
295                mData->mPointCount.changed(prevFrame, curFrame) ||
296                mData->mInnerRadius.changed(prevFrame, curFrame) ||
297                mData->mOuterRadius.changed(prevFrame, curFrame) ||
298                mData->mInnerRoundness.changed(prevFrame, curFrame) ||
299                mData->mOuterRoundness.changed(prevFrame, curFrame) ||
300                mData->mRotation.changed(prevFrame, curFrame)) ? true : false;
301    }
302 };
303
304
305
306 class LOTPaintDataItem : public LOTContentItem
307 {
308 public:
309    LOTPaintDataItem(bool staticContent);
310    void addPathItems(std::vector<LOTPathDataItem *> &list, int startOffset);
311    void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha, const DirtyFlag &flag) override;
312    void renderList(std::vector<VDrawable *> &list) final;
313 protected:
314    virtual void updateContent(int frameNo) = 0;
315    virtual void updateRenderNode();
316    inline float parentAlpha() const {return mParentAlpha;}
317 public:
318    float                            mParentAlpha;
319    VPath                            mPath;
320    DirtyFlag                        mFlag;
321    int                              mFrameNo;
322    std::vector<LOTPathDataItem *>   mPathItems;
323    std::unique_ptr<VDrawable>       mDrawable;
324    bool                             mStaticContent;
325    bool                             mRenderNodeUpdate{true};
326 };
327
328 class LOTFillItem : public LOTPaintDataItem
329 {
330 public:
331    LOTFillItem(LOTFillData *data);
332 protected:
333    void updateContent(int frameNo) final;
334    void updateRenderNode() final;
335 private:
336    LOTFillData             *mData;
337    VColor                  mColor;
338    FillRule                mFillRule;
339 };
340
341 class LOTGFillItem : public LOTPaintDataItem
342 {
343 public:
344    LOTGFillItem(LOTGFillData *data);
345 protected:
346    void updateContent(int frameNo) final;
347    void updateRenderNode() final;
348 private:
349    LOTGFillData                 *mData;
350    std::unique_ptr<VGradient>    mGradient;
351    FillRule                      mFillRule;
352 };
353
354 class LOTStrokeItem : public LOTPaintDataItem
355 {
356 public:
357    LOTStrokeItem(LOTStrokeData *data);
358 protected:
359    void updateContent(int frameNo) final;
360    void updateRenderNode() final;
361 private:
362    LOTStrokeData             *mData;
363    CapStyle                  mCap;
364    JoinStyle                 mJoin;
365    float                     mMiterLimit;
366    VColor                    mColor;
367    float                     mWidth;
368    float                     mDashArray[6];
369    int                       mDashArraySize;
370 };
371
372 class LOTGStrokeItem : public LOTPaintDataItem
373 {
374 public:
375    LOTGStrokeItem(LOTGStrokeData *data);
376 protected:
377    void updateContent(int frameNo) final;
378    void updateRenderNode() final;
379 private:
380    LOTGStrokeData               *mData;
381    std::unique_ptr<VGradient>    mGradient;
382    CapStyle                      mCap;
383    JoinStyle                     mJoin;
384    float                         mMiterLimit;
385    VColor                        mColor;
386    float                         mWidth;
387    float                         mDashArray[6];
388    int                           mDashArraySize;
389 };
390
391
392 // Trim Item
393
394 class LOTTrimItem : public LOTContentItem
395 {
396 public:
397    LOTTrimItem(LOTTrimData *data);
398    void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha, const DirtyFlag &flag) final;
399    void update();
400    void addPathItems(std::vector<LOTPathDataItem *> &list, int startOffset);
401 private:
402    bool pathDirty() const {
403        for (auto &i : mPathItems) {
404            if (i->dirty())
405                return true;
406        }
407        return false;
408    }
409    struct Cache {
410         int                     mFrameNo{-1};
411         LOTTrimData::Segment    mSegment{};
412    };
413    Cache                            mCache;
414    std::vector<LOTPathDataItem *>   mPathItems;
415    LOTTrimData                     *mData;
416    bool                             mDirty{true};
417 };
418
419 class LOTRepeaterItem : public LOTContentItem
420 {
421 public:
422    LOTRepeaterItem(LOTRepeaterData *data);
423    void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha, const DirtyFlag &flag) final;
424    void renderList(std::vector<VDrawable *> &list) final;
425 private:
426    LOTRepeaterData             *mData;
427 };
428
429
430 #endif // LOTTIEITEM_H
431
432