1 /*
2  * Copyright (c) 2023 - 2024 the ThorVG project. All rights reserved.
3 
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10 
11  * The above copyright notice and this permission notice shall be included in all
12  * copies or substantial portions of the Software.
13 
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20  * SOFTWARE.
21  */
22 
23 #include "../../lv_conf_internal.h"
24 #if LV_USE_THORVG_INTERNAL
25 
26 #ifndef _TVG_LOTTIE_BUILDER_H_
27 #define _TVG_LOTTIE_BUILDER_H_
28 
29 #include "tvgCommon.h"
30 #include "tvgInlist.h"
31 #include "tvgPaint.h"
32 #include "tvgShape.h"
33 #include "tvgLottieExpressions.h"
34 #include "tvgLottieModifier.h"
35 
36 struct LottieComposition;
37 
38 struct RenderRepeater
39 {
40     int cnt;
41     Matrix transform;
42     float offset;
43     Point position;
44     Point anchor;
45     Point scale;
46     float rotation;
47     uint8_t startOpacity;
48     uint8_t endOpacity;
49     bool interpOpacity;
50     bool inorder;
51 };
52 
53 struct RenderContext
54 {
55     INLIST_ITEM(RenderContext);
56 
57     Shape* propagator = nullptr;  //for propagating the shape properties excluding paths
58     Shape* merging = nullptr;  //merging shapes if possible (if shapes have same properties)
59     LottieObject** begin = nullptr; //iteration entry point
60     Array<RenderRepeater> repeaters;
61     Matrix* transform = nullptr;
62     LottieRoundnessModifier* roundness = nullptr;
63     LottieOffsetModifier* offsetPath = nullptr;
64     bool fragmenting = false;  //render context has been fragmented by filling
65     bool reqFragment = false;  //requirement to fragment the render context
66 
RenderContextRenderContext67     RenderContext(Shape* propagator)
68     {
69         P(propagator)->reset();
70         PP(propagator)->ref();
71         this->propagator = propagator;
72     }
73 
~RenderContextRenderContext74     ~RenderContext()
75     {
76         PP(propagator)->unref();
77         free(transform);
78         delete(roundness);
79         delete(offsetPath);
80     }
81 
82     RenderContext(const RenderContext& rhs, Shape* propagator, bool mergeable = false)
83     {
84         if (mergeable) merging = rhs.merging;
85         PP(propagator)->ref();
86         this->propagator = propagator;
87         this->repeaters = rhs.repeaters;
88         if (rhs.roundness) this->roundness = new LottieRoundnessModifier(rhs.roundness->r);
89         if (rhs.offsetPath) this->offsetPath = new LottieOffsetModifier(rhs.offsetPath->offset, rhs.offsetPath->miterLimit, rhs.offsetPath->join);
90     }
91 };
92 
93 struct LottieBuilder
94 {
LottieBuilderLottieBuilder95     LottieBuilder()
96     {
97         exps = LottieExpressions::instance();
98     }
99 
~LottieBuilderLottieBuilder100     ~LottieBuilder()
101     {
102         LottieExpressions::retrieve(exps);
103     }
104 
105     bool update(LottieComposition* comp, float progress);
106     void build(LottieComposition* comp);
107 
108 private:
109     void updateEffect(LottieLayer* layer, float frameNo);
110     void updateLayer(LottieComposition* comp, Scene* scene, LottieLayer* layer, float frameNo);
111     bool updateMatte(LottieComposition* comp, float frameNo, Scene* scene, LottieLayer* layer);
112     void updatePrecomp(LottieComposition* comp, LottieLayer* precomp, float frameNo);
113     void updateSolid(LottieLayer* layer);
114     void updateImage(LottieGroup* layer);
115     void updateText(LottieLayer* layer, float frameNo);
116     void updateMaskings(LottieLayer* layer, float frameNo);
117     void updateTransform(LottieLayer* layer, float frameNo);
118     void updateChildren(LottieGroup* parent, float frameNo, Inlist<RenderContext>& contexts);
119     void updateGroup(LottieGroup* parent, LottieObject** child, float frameNo, Inlist<RenderContext>& pcontexts, RenderContext* ctx);
120     void updateTransform(LottieGroup* parent, LottieObject** child, float frameNo, Inlist<RenderContext>& contexts, RenderContext* ctx);
121     void updateSolidFill(LottieGroup* parent, LottieObject** child, float frameNo, Inlist<RenderContext>& contexts, RenderContext* ctx);
122     void updateSolidStroke(LottieGroup* parent, LottieObject** child, float frameNo, Inlist<RenderContext>& contexts, RenderContext* ctx);
123     void updateGradientFill(LottieGroup* parent, LottieObject** child, float frameNo, Inlist<RenderContext>& contexts, RenderContext* ctx);
124     void updateGradientStroke(LottieGroup* parent, LottieObject** child, float frameNo, Inlist<RenderContext>& contexts, RenderContext* ctx);
125     void updateRect(LottieGroup* parent, LottieObject** child, float frameNo, Inlist<RenderContext>& contexts, RenderContext* ctx);
126     void updateEllipse(LottieGroup* parent, LottieObject** child, float frameNo, Inlist<RenderContext>& contexts, RenderContext* ctx);
127     void updatePath(LottieGroup* parent, LottieObject** child, float frameNo, Inlist<RenderContext>& contexts, RenderContext* ctx);
128     void updatePolystar(LottieGroup* parent, LottieObject** child, float frameNo, Inlist<RenderContext>& contexts, RenderContext* ctx);
129     void updateTrimpath(LottieGroup* parent, LottieObject** child, float frameNo, Inlist<RenderContext>& contexts, RenderContext* ctx);
130     void updateRepeater(LottieGroup* parent, LottieObject** child, float frameNo, Inlist<RenderContext>& contexts, RenderContext* ctx);
131     void updateRoundedCorner(LottieGroup* parent, LottieObject** child, float frameNo, Inlist<RenderContext>& contexts, RenderContext* ctx);
132     void updateOffsetPath(LottieGroup* parent, LottieObject** child, float frameNo, Inlist<RenderContext>& contexts, RenderContext* ctx);
133 
134     LottieExpressions* exps;
135 };
136 
137 #endif //_TVG_LOTTIE_BUILDER_H
138 
139 #endif /* LV_USE_THORVG_INTERNAL */
140 
141