submodule: add rive-cpp to rive-tizen as submodule
[platform/core/uifw/rive-tizen.git] / submodule / src / shapes / paint / trim_path.cpp
1 #include "shapes/paint/trim_path.hpp"
2 #include "shapes/metrics_path.hpp"
3 #include "shapes/paint/stroke.hpp"
4
5 using namespace rive;
6
7 TrimPath::TrimPath() : m_TrimmedPath(makeRenderPath()) {}
8 TrimPath::~TrimPath() { delete m_TrimmedPath; }
9
10 StatusCode TrimPath::onAddedClean(CoreContext* context)
11 {
12         if (!parent()->is<Stroke>())
13         {
14                 return StatusCode::InvalidObject;
15         }
16
17         parent()->as<Stroke>()->addStrokeEffect(this);
18
19         return StatusCode::Ok;
20 }
21
22 RenderPath* TrimPath::effectPath(MetricsPath* source)
23 {
24         if (m_RenderPath != nullptr)
25         {
26                 return m_RenderPath;
27         }
28
29         
30
31         // Source is always a containing (shape) path.
32         const std::vector<MetricsPath*>& subPaths = source->paths();
33
34         m_TrimmedPath->reset();
35         auto renderOffset = std::fmod(std::fmod(offset(), 1.0f) + 1.0f, 1.0f);
36         switch (modeValue())
37         {
38                 case 1:
39                 {
40                         float totalLength = source->length();
41                         auto startLength = totalLength * (start() + renderOffset);
42                         auto endLength = totalLength * (end() + renderOffset);
43
44                         if (endLength < startLength)
45                         {
46                                 float swap = startLength;
47                                 startLength = endLength;
48                                 endLength = swap;
49                         }
50
51                         if (startLength > totalLength)
52                         {
53                                 startLength -= totalLength;
54                                 endLength -= totalLength;
55                         }
56
57                         int i = 0, subPathCount = (int) subPaths.size();
58                         while (endLength > 0)
59                         {
60                                 auto path = subPaths[i % subPathCount];
61                                 auto pathLength = path->length();
62
63                                 if (startLength < pathLength)
64                                 {
65                                         path->trim(startLength, endLength, true, m_TrimmedPath);
66                                         endLength -= pathLength;
67                                         startLength = 0;
68                                 }
69                                 else
70                                 {
71                                         startLength -= pathLength;
72                                         endLength -= pathLength;
73                                 }
74                                 i++;
75                         }
76                 }
77                 break;
78
79                 case 2:
80                 {
81                         for (auto path : subPaths)
82                         {
83                                 auto pathLength = path->length();
84                                 auto startLength = pathLength * (start() + renderOffset);
85                                 auto endLength = pathLength * (end() + renderOffset);
86                                 if (endLength < startLength)
87                                 {
88                                         auto length = startLength;
89                                         startLength = endLength;
90                                         endLength = length;
91                                 }
92
93                                 if (startLength > pathLength)
94                                 {
95                                         startLength -= pathLength;
96                                         endLength -= pathLength;
97                                 }
98                                 path->trim(startLength, endLength, true, m_TrimmedPath);
99                                 while (endLength > pathLength)
100                                 {
101                                         startLength = 0;
102                                         endLength -= pathLength;
103                                         path->trim(startLength, endLength, false, m_TrimmedPath);
104                                 }
105                         }
106                 }
107                 break;
108         }
109
110         m_RenderPath = m_TrimmedPath;
111         return m_RenderPath;
112 }
113
114 void TrimPath::invalidateEffect()
115 {
116         m_RenderPath = nullptr;
117         parent()->as<Stroke>()->parent()->addDirt(ComponentDirt::Paint);
118 }
119
120 void TrimPath::startChanged() { invalidateEffect(); }
121 void TrimPath::endChanged() { invalidateEffect(); }
122 void TrimPath::offsetChanged() { invalidateEffect(); }
123 void TrimPath::modeValueChanged() { invalidateEffect(); }