lottie/vector: Fixed vpath::clone() implementation.
[platform/core/uifw/lottie-player.git] / src / vector / vpath.h
1 #ifndef VPATH_H
2 #define VPATH_H
3 #include <vector>
4 #include "vcowptr.h"
5 #include "vmatrix.h"
6 #include "vpoint.h"
7 #include "vrect.h"
8
9 V_BEGIN_NAMESPACE
10
11 struct VPathData;
12 class VPath {
13 public:
14     enum class Direction { CCW, CW };
15
16     enum class Element : uchar { MoveTo, LineTo, CubicTo, Close };
17     bool  empty() const;
18     bool  null() const;
19     void  moveTo(const VPointF &p);
20     void  moveTo(float x, float y);
21     void  lineTo(const VPointF &p);
22     void  lineTo(float x, float y);
23     void  cubicTo(const VPointF &c1, const VPointF &c2, const VPointF &e);
24     void  cubicTo(float c1x, float c1y, float c2x, float c2y, float ex,
25                   float ey);
26     void  arcTo(const VRectF &rect, float startAngle, float sweepLength,
27                 bool forceMoveTo);
28     void  close();
29     void  reset();
30     void  reserve(int pts, int elms);
31     int   segments() const;
32     void  addCircle(float cx, float cy, float radius,
33                     VPath::Direction dir = Direction::CW);
34     void  addOval(const VRectF &rect, VPath::Direction dir = Direction::CW);
35     void  addRoundRect(const VRectF &rect, float rx, float ry,
36                        VPath::Direction dir = Direction::CW);
37     void  addRoundRect(const VRectF &rect, float roundness,
38                        VPath::Direction dir = Direction::CW);
39     void  addRect(const VRectF &rect, VPath::Direction dir = Direction::CW);
40     void  addPolystar(float points, float innerRadius, float outerRadius,
41                       float innerRoundness, float outerRoundness,
42                       float startAngle, float cx, float cy,
43                       VPath::Direction dir = Direction::CW);
44     void  addPolygon(float points, float radius, float roundness,
45                      float startAngle, float cx, float cy,
46                      VPath::Direction dir = Direction::CW);
47     void addPath(const VPath &path);
48     void  transform(const VMatrix &m);
49     float length() const;
50     const std::vector<VPath::Element> &elements() const;
51     const std::vector<VPointF> &       points() const;
52     void  clone(const VPath &srcPath);
53     bool unique() const { return d.unique();}
54     int refCount() const { return d.refCount();}
55
56 private:
57     struct VPathData {
58         bool  empty() const { return m_elements.empty(); }
59         bool  null() const { return empty() && !m_elements.capacity();}
60         void  moveTo(float x, float y);
61         void  lineTo(float x, float y);
62         void  cubicTo(float cx1, float cy1, float cx2, float cy2, float ex, float ey);
63         void  close();
64         void  reset();
65         void  reserve(int, int);
66         void  checkNewSegment();
67         int   segments() const;
68         void  transform(const VMatrix &m);
69         float length() const;
70         void  addRoundRect(const VRectF &, float, float, VPath::Direction);
71         void  addRoundRect(const VRectF &, float, VPath::Direction);
72         void  addRect(const VRectF &, VPath::Direction);
73         void  arcTo(const VRectF &, float, float, bool);
74         void  addCircle(float, float, float, VPath::Direction);
75         void  addOval(const VRectF &, VPath::Direction);
76         void  addPolystar(float points, float innerRadius, float outerRadius,
77                           float innerRoundness, float outerRoundness,
78                           float startAngle, float cx, float cy,
79                           VPath::Direction dir = Direction::CW);
80         void  addPolygon(float points, float radius, float roundness,
81                          float startAngle, float cx, float cy,
82                          VPath::Direction dir = Direction::CW);
83         void  addPath(const VPathData &path);
84         const std::vector<VPath::Element> &elements() const
85         {
86             return m_elements;
87         }
88         const std::vector<VPointF> &points() const { return m_points; }
89         std::vector<VPointF>        m_points;
90         std::vector<VPath::Element> m_elements;
91         int                         m_segments;
92         VPointF                     mStartPoint;
93         mutable float               mLength{0};
94         mutable bool                mLengthDirty{true};
95         bool                        mNewSegment;
96     };
97
98     vcow_ptr<VPathData> d;
99 };
100
101 inline bool VPath::empty() const
102 {
103     return d->empty();
104 }
105
106 /*
107  * path is empty as well as null(no memory for data allocated yet).
108  */
109 inline bool VPath::null() const
110 {
111     return d->null();
112 }
113
114 inline void VPath::moveTo(const VPointF &p)
115 {
116     d.write().moveTo(p.x(), p.y());
117 }
118
119 inline void VPath::lineTo(const VPointF &p)
120 {
121     d.write().lineTo(p.x(), p.y());
122 }
123
124 inline void VPath::close()
125 {
126     d.write().close();
127 }
128
129 inline void VPath::reset()
130 {
131     d.write().reset();
132 }
133
134 inline void VPath::reserve(int pts, int elms)
135 {
136     d.write().reserve(pts, elms);
137 }
138
139 inline int VPath::segments() const
140 {
141     return d->segments();
142 }
143
144 inline float VPath::length() const
145 {
146     return d->length();
147 }
148
149 inline void VPath::cubicTo(const VPointF &c1, const VPointF &c2,
150                            const VPointF &e)
151 {
152     d.write().cubicTo(c1.x(), c1.y(), c2.x(), c2.y(), e.x(), e.y());
153 }
154
155 inline void VPath::lineTo(float x, float y)
156 {
157     d.write().lineTo(x, y);
158 }
159
160 inline void VPath::moveTo(float x, float y)
161 {
162     d.write().moveTo(x, y);
163 }
164
165 inline void VPath::cubicTo(float c1x, float c1y, float c2x, float c2y, float ex,
166                            float ey)
167 {
168     d.write().cubicTo(c1x, c1y, c2x, c2y, ex, ey);
169 }
170
171 inline void VPath::transform(const VMatrix &m)
172 {
173     d.write().transform(m);
174 }
175
176 inline void VPath::arcTo(const VRectF &rect, float startAngle,
177                          float sweepLength, bool forceMoveTo)
178 {
179     d.write().arcTo(rect, startAngle, sweepLength, forceMoveTo);
180 }
181
182 inline void VPath::addRect(const VRectF &rect, VPath::Direction dir)
183 {
184     d.write().addRect(rect, dir);
185 }
186
187 inline void VPath::addRoundRect(const VRectF &rect, float rx, float ry,
188                                 VPath::Direction dir)
189 {
190     d.write().addRoundRect(rect, rx, ry, dir);
191 }
192
193 inline void VPath::addRoundRect(const VRectF &rect, float roundness,
194                                 VPath::Direction dir)
195 {
196     d.write().addRoundRect(rect, roundness, dir);
197 }
198
199 inline void VPath::addCircle(float cx, float cy, float radius,
200                              VPath::Direction dir)
201 {
202     d.write().addCircle(cx, cy, radius, dir);
203 }
204
205 inline void VPath::addOval(const VRectF &rect, VPath::Direction dir)
206 {
207     d.write().addOval(rect, dir);
208 }
209
210 inline void VPath::addPolystar(float points, float innerRadius,
211                                float outerRadius, float innerRoundness,
212                                float outerRoundness, float startAngle, float cx,
213                                float cy, VPath::Direction dir)
214 {
215     d.write().addPolystar(points, innerRadius, outerRadius, innerRoundness,
216                           outerRoundness, startAngle, cx, cy, dir);
217 }
218
219 inline void VPath::addPolygon(float points, float radius, float roundness,
220                               float startAngle, float cx, float cy,
221                               VPath::Direction dir)
222 {
223     d.write().addPolygon(points, radius, roundness, startAngle, cx, cy, dir);
224 }
225
226 inline void VPath::addPath(const VPath &path)
227 {
228     if (path.empty()) return;
229
230     if (null()) {
231         *this = path;
232     } else {
233         d.write().addPath(path.d.read());
234     }
235 }
236
237 inline const std::vector<VPath::Element> &VPath::elements() const
238 {
239     return d->elements();
240 }
241
242 inline const std::vector<VPointF> &VPath::points() const
243 {
244     return d->points();
245 }
246
247 inline void VPath::clone(const VPath &srcPath)
248 {
249    reset();
250    addPath(srcPath);
251 }
252
253 V_END_NAMESPACE
254
255 #endif  // VPATH_H