renderer, example: implments shape animation
[platform/core/uifw/rive-tizen.git] / src / renderer / src / thorvg_renderer.cpp
1 #include "thorvg_renderer.hpp"
2 #include "math/vec2d.hpp"
3 #include "shapes/paint/color.hpp"
4
5 using namespace rive;
6
7 TvgRenderPath::TvgRenderPath()
8 {
9         this->m_Shape = tvg::Shape::gen().release();
10 }
11
12 void TvgRenderPath::fillRule(FillRule value)
13 {
14         switch (value)
15         {
16                 case FillRule::evenOdd:
17                         m_Shape->fill(tvg::FillRule::EvenOdd);
18                         break;
19                 case FillRule::nonZero:
20                         break;
21         }
22 }
23
24 Vec2D applyTransform(const Vec2D &vec, const Mat2D &mat)
25 {
26         tvg::Matrix m = {1, 0, 0, 0, 1, 0, 0, 0, 1};
27         m.e11 = mat[0];
28         m.e12 = mat[2];
29         m.e13 = mat[4];
30         m.e21 = mat[1];
31         m.e22 = mat[3];
32         m.e23 = mat[5];
33
34         Vec2D ret;
35         ret[0] = round(vec[0] * m.e11 + vec[1] * m.e12 + m.e13);
36         ret[1] = round(vec[0] * m.e21 + vec[1] * m.e22 + m.e23);
37
38         return ret;
39 }
40
41 void TvgRenderPath::addRenderPath(RenderPath* path, const Mat2D& transform)
42 {
43    auto m_PathType = reinterpret_cast<TvgRenderPath*>(path)->m_PathType;
44    auto m_PathPoints = reinterpret_cast<TvgRenderPath*>(path)->m_PathPoints;
45    Vec2D vec1, vec2, vec3, vecOut1, vecOut2, vecOut3;
46
47    int index = 0;
48    for (size_t i = 0; i < m_PathType.size(); i++)
49    {
50       PathCommand type = m_PathType[i];
51       switch(type)
52       {
53          case PathCommand::MoveTo:
54             vecOut1 = applyTransform(m_PathPoints[index], transform);
55             m_Shape->moveTo(vecOut1[0], vecOut1[1]);
56             index += 1;
57             break;
58          case PathCommand::LineTo:
59             vecOut1 = applyTransform(m_PathPoints[index], transform);
60             m_Shape->lineTo(vecOut1[0], vecOut1[1]);
61             index += 1;
62             break;
63          case PathCommand::CubicTo:
64             vecOut1 = applyTransform(m_PathPoints[index], transform);
65             vecOut2 = applyTransform(m_PathPoints[index + 1], transform);
66             vecOut3 = applyTransform(m_PathPoints[index + 2], transform);
67             m_Shape->cubicTo(vecOut1[0], vecOut1[1],
68                              vecOut2[0], vecOut2[1],
69                              vecOut3[0], vecOut3[1]);
70             index += 3;
71             break;
72          case PathCommand::Close:
73             m_Shape->close();
74             break;
75       }
76    }
77 }
78
79 void TvgRenderPath::reset()
80 {
81    m_Shape->reset();
82    m_PathType.clear();
83    m_PathPoints.clear();
84 }
85
86 void TvgRenderPath::moveTo(float x, float y)
87 {
88    m_PathType.push_back(PathCommand::MoveTo);
89    m_PathPoints.push_back({x, y});
90 }
91
92 void TvgRenderPath::lineTo(float x, float y)
93 {
94    m_PathType.push_back(PathCommand::LineTo);
95    m_PathPoints.push_back({x, y});
96 }
97
98 void TvgRenderPath::cubicTo(float ox, float oy, float ix, float iy, float x, float y)
99 {
100    m_PathType.push_back(PathCommand::CubicTo);
101    m_PathPoints.push_back({ox, oy});
102    m_PathPoints.push_back({ix, iy});
103    m_PathPoints.push_back({x, y});
104 }
105
106 void TvgRenderPath::close()
107 {
108    m_PathType.push_back(PathCommand::Close);
109 }
110
111 void TvgRenderer::save()
112 {
113 }
114
115 void TvgRenderer::restore()
116 {
117 }
118
119 void TvgRenderer::transform(const Mat2D& transform)
120 {
121    m_Transform = transform;
122 }
123
124 void TvgRenderer::drawPath(RenderPath* path, RenderPaint* paint)
125 {
126         Matrix m = {m_Transform[0], 0, m_Transform[4], 0, m_Transform[3], m_Transform[5], 0, 0, 1};
127
128    auto renderPath = reinterpret_cast<TvgRenderPath*>(path);
129    auto shape = reinterpret_cast<TvgRenderPath*>(path)->shape();
130    shape->transform(m);
131
132    auto tvgPaint = reinterpret_cast<TvgRenderPaint*>(paint)->paint();
133
134    if (tvgPaint->isFill)
135    {
136       shape->fill(tvgPaint->fillColor[0], tvgPaint->fillColor[1], tvgPaint->fillColor[2], tvgPaint->fillColor[3]);
137    }
138
139    if (tvgPaint->isStroke)
140    {
141       shape->stroke(tvgPaint->strokeColor[0], tvgPaint->strokeColor[1], tvgPaint->strokeColor[2], tvgPaint->strokeColor[3]);
142       shape->stroke(tvgPaint->cap);
143       shape->stroke(tvgPaint->join);
144       if (tvgPaint->thickness != 0)
145       {
146          shape->stroke(tvgPaint->thickness);
147       }
148    }
149
150    if (!renderPath->getPushed())
151    {
152       m_Canvas->push(unique_ptr<Shape>(shape));
153       renderPath->setPushed(true);
154    }
155    else
156    {
157       m_Canvas->update(shape);
158    }
159 }
160
161 void TvgRenderer::clipPath(RenderPath* path)
162 {
163
164 }
165
166 TvgRenderPaint::TvgRenderPaint()
167 {
168
169 }
170
171 void TvgRenderPaint::style(RenderPaintStyle style)
172 {
173         switch (style)
174         {
175                 case RenderPaintStyle::fill:
176          m_Paint.style = RenderPaintStyle::fill;
177          m_Paint.isFill = true;
178                         break;
179                 case RenderPaintStyle::stroke:
180          m_Paint.style = RenderPaintStyle::stroke;
181          m_Paint.isStroke = true;
182                         break;
183         }
184 }
185 void TvgRenderPaint::color(unsigned int value)
186 {
187    int b = value >> 0 & 255;
188    int g = value >> 8 & 255;
189    int r = value >> 16 & 255;
190    int a = value >> 24 & 255;
191
192    if (m_Paint.style == RenderPaintStyle::fill)
193    {
194       m_Paint.fillColor[0] = r;
195       m_Paint.fillColor[1] = g;
196       m_Paint.fillColor[2] = b;
197       m_Paint.fillColor[3] = a;
198    }
199    else if (m_Paint.style == RenderPaintStyle::stroke)
200    {
201       m_Paint.strokeColor[0] = r;
202       m_Paint.strokeColor[1] = g;
203       m_Paint.strokeColor[2] = b;
204       m_Paint.strokeColor[3] = a;
205    }
206 }
207
208 void TvgRenderPaint::thickness(float value)
209 {
210    m_Paint.thickness = value;
211 }
212
213 void TvgRenderPaint::join(StrokeJoin value)
214 {
215    switch (value)
216    {
217       case rive::StrokeJoin::round:
218          m_Paint.join = tvg::StrokeJoin::Round;
219          break;
220       case rive::StrokeJoin::bevel:
221          m_Paint.join = tvg::StrokeJoin::Bevel;
222          break;
223       case rive::StrokeJoin::miter:
224          m_Paint.join = tvg::StrokeJoin::Miter;
225          break;
226    }
227 }
228
229 void TvgRenderPaint::cap(StrokeCap value)
230 {
231    switch (value)
232    {
233       case rive::StrokeCap::butt:
234          m_Paint.cap = tvg::StrokeCap::Butt;
235          break;
236       case rive::StrokeCap::round:
237          m_Paint.cap = tvg::StrokeCap::Round;
238          break;
239       case rive::StrokeCap::square:
240          m_Paint.cap = tvg::StrokeCap::Square;
241          break;
242    }
243 }
244
245 void TvgRenderPaint::linearGradient(float sx, float sy, float ex, float ey)
246 {
247
248 }
249
250 void TvgRenderPaint::radialGradient(float sx, float sy, float ex, float ey)
251 {
252 }
253
254 void TvgRenderPaint::addStop(unsigned int color, float stop)
255 {
256 }
257
258 void TvgRenderPaint::completeGradient()
259 {
260
261 }
262
263 void TvgRenderPaint::blendMode(BlendMode value)
264 {
265
266 }
267
268 namespace rive
269 {
270    RenderPath* makeRenderPath() { return new TvgRenderPath();}
271    RenderPaint* makeRenderPaint() { return new TvgRenderPaint();}
272 }