CanvasRenderer::Shape: Add AddPath() Api
[platform/core/uifw/dali-adaptor.git] / dali / internal / canvas-renderer / tizen / shape-impl-tizen.cpp
1 /*
2  * Copyright (c) 2021 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali/internal/canvas-renderer/tizen/shape-impl-tizen.h>
20
21 // EXTERNAL INCLUDES
22 #include <dali/integration-api/debug.h>
23 #include <dali/public-api/object/type-registry.h>
24
25 namespace Dali
26 {
27 namespace Internal
28 {
29 namespace Adaptor
30 {
31 namespace // unnamed namespace
32 {
33 // Type Registration
34 Dali::BaseHandle Create()
35 {
36   return Dali::BaseHandle();
37 }
38
39 Dali::TypeRegistration type(typeid(Dali::CanvasRenderer::Shape), typeid(Dali::BaseHandle), Create);
40
41 } // unnamed namespace
42
43 ShapeTizen* ShapeTizen::New()
44 {
45   return new ShapeTizen();
46 }
47
48 ShapeTizen::ShapeTizen()
49 : mFillGradient(),
50   mStrokeGradient()
51 #ifdef THORVG_SUPPORT
52   ,
53   mTvgShape(nullptr)
54 #endif
55 {
56   Initialize();
57 }
58
59 ShapeTizen::~ShapeTizen()
60 {
61 }
62
63 void ShapeTizen::Initialize()
64 {
65 #ifdef THORVG_SUPPORT
66   mTvgShape = tvg::Shape::gen().release();
67   if(!mTvgShape)
68   {
69     DALI_LOG_ERROR("Shape is null [%p]\n", this);
70   }
71
72   Drawable::Create();
73   Drawable::SetObject(static_cast<void*>(mTvgShape));
74   Drawable::SetType(Drawable::Types::SHAPE);
75 #endif
76 }
77
78 bool ShapeTizen::AddRect(Rect<float> rect, Vector2 roundedCorner)
79 {
80 #ifdef THORVG_SUPPORT
81   if(!Drawable::GetObject() || !mTvgShape)
82   {
83     DALI_LOG_ERROR("Shape is null [%p]\n", this);
84     return false;
85   }
86   if(static_cast<tvg::Shape*>(mTvgShape)->appendRect(rect.x, rect.y, rect.width, rect.height, roundedCorner.x, roundedCorner.y) != tvg::Result::Success)
87   {
88     DALI_LOG_ERROR("Add Rect Fail [%p]\n", this);
89     return false;
90   }
91   Drawable::SetChanged(true);
92   return true;
93 #else
94   return false;
95 #endif
96 }
97
98 bool ShapeTizen::AddCircle(Vector2 center, Vector2 radius)
99 {
100 #ifdef THORVG_SUPPORT
101   if(!Drawable::GetObject() || !mTvgShape)
102   {
103     DALI_LOG_ERROR("Shape is null [%p]\n", this);
104     return false;
105   }
106   if(static_cast<tvg::Shape*>(mTvgShape)->appendCircle(center.x, center.y, radius.x, radius.y) != tvg::Result::Success)
107   {
108     DALI_LOG_ERROR("Add Circle Fail [%p]\n", this);
109     return false;
110   }
111   Drawable::SetChanged(true);
112   return true;
113 #else
114   return false;
115 #endif
116 }
117
118 bool ShapeTizen::AddArc(Vector2 center, float radius, float startAngle, float sweep, bool pie)
119 {
120 #ifdef THORVG_SUPPORT
121   if(!Drawable::GetObject() || !mTvgShape)
122   {
123     DALI_LOG_ERROR("Shape is null\n");
124     return false;
125   }
126
127   if(static_cast<tvg::Shape*>(mTvgShape)->appendArc(center.x, center.y, radius, startAngle, sweep, pie) != tvg::Result::Success)
128   {
129     DALI_LOG_ERROR("Add arc fail.\n");
130     return false;
131   }
132   Drawable::SetChanged(true);
133   return true;
134 #else
135   return false;
136 #endif
137 }
138
139 bool ShapeTizen::AddMoveTo(Vector2 point)
140 {
141 #ifdef THORVG_SUPPORT
142   if(!Drawable::GetObject() || !mTvgShape)
143   {
144     DALI_LOG_ERROR("Shape is null\n");
145     return false;
146   }
147
148   if(static_cast<tvg::Shape*>(mTvgShape)->moveTo(point.x, point.y) != tvg::Result::Success)
149   {
150     DALI_LOG_ERROR("AddMoveTo() fail.\n");
151     return false;
152   }
153   Drawable::SetChanged(true);
154   return true;
155 #else
156   return false;
157 #endif
158 }
159
160 bool ShapeTizen::AddLineTo(Vector2 line)
161 {
162 #ifdef THORVG_SUPPORT
163   if(!Drawable::GetObject() || !mTvgShape)
164   {
165     DALI_LOG_ERROR("Shape is null\n");
166     return false;
167   }
168
169   if(static_cast<tvg::Shape*>(mTvgShape)->lineTo(line.x, line.y) != tvg::Result::Success)
170   {
171     DALI_LOG_ERROR("AddLineTo() fail.\n");
172     return false;
173   }
174   Drawable::SetChanged(true);
175   return true;
176 #else
177   return false;
178 #endif
179 }
180
181 bool ShapeTizen::AddCubicTo(Vector2 controlPoint1, Vector2 controlPoint2, Vector2 endPoint)
182 {
183 #ifdef THORVG_SUPPORT
184   if(!Drawable::GetObject() || !mTvgShape)
185   {
186     DALI_LOG_ERROR("Shape is null\n");
187     return false;
188   }
189
190   if(static_cast<tvg::Shape*>(mTvgShape)->cubicTo(controlPoint1.x, controlPoint1.y, controlPoint2.x, controlPoint2.y, endPoint.x, endPoint.y) != tvg::Result::Success)
191   {
192     DALI_LOG_ERROR("cubicTo() fail.\n");
193     return false;
194   }
195   Drawable::SetChanged(true);
196   return true;
197 #else
198   return false;
199 #endif
200 }
201
202 bool ShapeTizen::AddPath(Dali::CanvasRenderer::Shape::PathCommands& pathCommand)
203 {
204 #ifdef THORVG_SUPPORT
205   if(!Drawable::GetObject() || !mTvgShape)
206   {
207     DALI_LOG_ERROR("Shape is null\n");
208     return false;
209   }
210
211   if(static_cast<tvg::Shape*>(mTvgShape)->appendPath(reinterpret_cast<const tvg::PathCommand*>(pathCommand.mCommands), pathCommand.mCommandCount, static_cast<const tvg::Point*>((void*)pathCommand.mPoints), pathCommand.mPointCount) != tvg::Result::Success)
212   {
213     DALI_LOG_ERROR("AddPath() fail.\n");
214     return false;
215   }
216   Drawable::SetChanged(true);
217   return true;
218 #else
219   return false;
220 #endif
221 }
222
223 bool ShapeTizen::Close()
224 {
225 #ifdef THORVG_SUPPORT
226   if(!Drawable::GetObject() || !mTvgShape)
227   {
228     DALI_LOG_ERROR("Shape is null\n");
229     return false;
230   }
231
232   if(static_cast<tvg::Shape*>(mTvgShape)->close() != tvg::Result::Success)
233   {
234     DALI_LOG_ERROR("close() fail.\n");
235     return false;
236   }
237   Drawable::SetChanged(true);
238   return true;
239 #else
240   return false;
241 #endif
242 }
243
244 bool ShapeTizen::ResetPath()
245 {
246 #ifdef THORVG_SUPPORT
247   if(!Drawable::GetObject() || !mTvgShape)
248   {
249     DALI_LOG_ERROR("Shape is null\n");
250     return false;
251   }
252
253   if(static_cast<tvg::Shape*>(mTvgShape)->reset() != tvg::Result::Success)
254   {
255     DALI_LOG_ERROR("reset() fail.\n");
256     return false;
257   }
258   Drawable::SetChanged(true);
259   return true;
260 #else
261   return false;
262 #endif
263 }
264
265 bool ShapeTizen::SetFillColor(Vector4 color)
266 {
267 #ifdef THORVG_SUPPORT
268   if(!Drawable::GetObject() || !mTvgShape)
269   {
270     DALI_LOG_ERROR("Shape is null [%p]\n", this);
271     return false;
272   }
273
274   if(static_cast<tvg::Shape*>(mTvgShape)->fill((uint8_t)(color.r * 255.f), (uint8_t)(color.g * 255.f), (uint8_t)(color.b * 255.f), (uint8_t)(color.a * 255.f)) != tvg::Result::Success)
275   {
276     DALI_LOG_ERROR("SetFillColor fail [%p]\n", this);
277     return false;
278   }
279   Drawable::SetChanged(true);
280   return true;
281 #else
282   return false;
283 #endif
284 }
285
286 Vector4 ShapeTizen::GetFillColor() const
287 {
288 #ifdef THORVG_SUPPORT
289   if(!Drawable::GetObject() || !mTvgShape)
290   {
291     DALI_LOG_ERROR("Shape is null [%p]\n", this);
292     return Vector4(0, 0, 0, 0);
293   }
294   uint8_t r, g, b, a;
295
296   if(static_cast<tvg::Shape*>(mTvgShape)->fillColor(&r, &g, &b, &a) != tvg::Result::Success)
297   {
298     DALI_LOG_ERROR("GetFillColor fail [%p]\n", this);
299     return Vector4(0, 0, 0, 0);
300   }
301   return Vector4(r / 255.f, g / 255.f, b / 255.f, a / 255.f);
302 #else
303   return Vector4::ZERO;
304 #endif
305 }
306
307 bool ShapeTizen::SetFillGradient(Dali::CanvasRenderer::Gradient& gradient)
308 {
309 #ifdef THORVG_SUPPORT
310   if(!Drawable::GetObject() || !mTvgShape)
311   {
312     DALI_LOG_ERROR("Shape is null [%p]\n", this);
313     return false;
314   }
315   mFillGradient = gradient;
316   Drawable::SetChanged(true);
317   return true;
318 #else
319   return false;
320 #endif
321 }
322
323 Dali::CanvasRenderer::Gradient ShapeTizen::GetFillGradient() const
324 {
325   return mFillGradient;
326 }
327
328 bool ShapeTizen::SetFillRule(Dali::CanvasRenderer::Shape::FillRule rule)
329 {
330 #ifdef THORVG_SUPPORT
331   if(!Drawable::GetObject() || !mTvgShape)
332   {
333     DALI_LOG_ERROR("Shape is null\n");
334     return false;
335   }
336   if(static_cast<tvg::Shape*>(mTvgShape)->fill(static_cast<tvg::FillRule>(rule)) != tvg::Result::Success)
337   {
338     DALI_LOG_ERROR("SetFillRule fail.\n");
339     return false;
340   }
341   Drawable::SetChanged(true);
342   return true;
343 #else
344   return false;
345 #endif
346 }
347
348 Dali::CanvasRenderer::Shape::FillRule ShapeTizen::GetFillRule() const
349 {
350 #ifdef THORVG_SUPPORT
351   if(!Drawable::GetObject() || !mTvgShape)
352   {
353     DALI_LOG_ERROR("Shape is null\n");
354     return Dali::CanvasRenderer::Shape::FillRule::WINDING;
355   }
356
357   tvg::FillRule rule = static_cast<tvg::Shape*>(mTvgShape)->fillRule();
358
359   return static_cast<Dali::CanvasRenderer::Shape::FillRule>(rule);
360 #endif
361   return Dali::CanvasRenderer::Shape::FillRule::WINDING;
362 }
363
364 bool ShapeTizen::SetStrokeWidth(float width)
365 {
366 #ifdef THORVG_SUPPORT
367   if(!Drawable::GetObject() || !mTvgShape)
368   {
369     DALI_LOG_ERROR("Shape is null\n");
370     return false;
371   }
372
373   if(static_cast<tvg::Shape*>(mTvgShape)->stroke(width) != tvg::Result::Success)
374   {
375     DALI_LOG_ERROR("SetStrokeWidth fail.\n");
376     return false;
377   }
378   Drawable::SetChanged(true);
379   return true;
380 #else
381   return false;
382 #endif
383 }
384
385 float ShapeTizen::GetStrokeWidth() const
386 {
387 #ifdef THORVG_SUPPORT
388   if(!Drawable::GetObject() || !mTvgShape)
389   {
390     DALI_LOG_ERROR("Shape is null\n");
391     return false;
392   }
393   return static_cast<tvg::Shape*>(mTvgShape)->strokeWidth();
394 #else
395   return false;
396 #endif
397 }
398
399 bool ShapeTizen::SetStrokeColor(Vector4 color)
400 {
401 #ifdef THORVG_SUPPORT
402   if(!Drawable::GetObject() || !mTvgShape)
403   {
404     DALI_LOG_ERROR("Shape is null\n");
405     return false;
406   }
407
408   if(static_cast<tvg::Shape*>(mTvgShape)->stroke(color.r * 255.f, color.g * 255.f, color.b * 255.f, color.a * 255.f) != tvg::Result::Success)
409   {
410     DALI_LOG_ERROR("SetStrokeColor fail.\n");
411     return false;
412   }
413   Drawable::SetChanged(true);
414   return true;
415 #else
416   return false;
417 #endif
418 }
419
420 Vector4 ShapeTizen::GetStrokeColor() const
421 {
422 #ifdef THORVG_SUPPORT
423   if(!Drawable::GetObject() || !mTvgShape)
424   {
425     DALI_LOG_ERROR("Shape is null\n");
426     return Vector4(0, 0, 0, 0);
427   }
428
429   uint8_t r, g, b, a;
430
431   if(static_cast<tvg::Shape*>(mTvgShape)->strokeColor(&r, &g, &b, &a) != tvg::Result::Success)
432   {
433     DALI_LOG_ERROR("GetStrokeColor fail.\n");
434     return Vector4(0, 0, 0, 0);
435   }
436   return Vector4(r / 255.f, g / 255.f, b / 255.f, a / 255.f);
437 #else
438   return Vector4(0, 0, 0, 0);
439 #endif
440 }
441
442 bool ShapeTizen::SetStrokeGradient(Dali::CanvasRenderer::Gradient& gradient)
443 {
444 #ifdef THORVG_SUPPORT
445   if(!Drawable::GetObject() || !mTvgShape)
446   {
447     DALI_LOG_ERROR("Shape is null [%p]\n", this);
448     return false;
449   }
450   mStrokeGradient = gradient;
451   Drawable::SetChanged(true);
452   return true;
453 #else
454   return false;
455 #endif
456 }
457
458 Dali::CanvasRenderer::Gradient ShapeTizen::GetStrokeGradient() const
459 {
460   return mStrokeGradient;
461 }
462
463 bool ShapeTizen::SetStrokeDash(const Dali::Vector<float> dashPattern)
464 {
465 #ifdef THORVG_SUPPORT
466   if(!Drawable::GetObject() || !mTvgShape)
467   {
468     DALI_LOG_ERROR("Shape is null\n");
469     return false;
470   }
471
472   float* tvgDashPattern = (float*)alloca(sizeof(float) * dashPattern.Count());
473
474   for(unsigned int i = 0u; i < dashPattern.Count(); ++i)
475   {
476     tvgDashPattern[i] = dashPattern[i];
477   }
478
479   if(static_cast<tvg::Shape*>(mTvgShape)->stroke(tvgDashPattern, dashPattern.Count()) != tvg::Result::Success)
480   {
481     DALI_LOG_ERROR("SetStrokeDash fail.\n");
482     return false;
483   }
484   Drawable::SetChanged(true);
485   return true;
486 #else
487   return false;
488 #endif
489 }
490
491 Dali::Vector<float> ShapeTizen::GetStrokeDash() const
492 {
493 #ifdef THORVG_SUPPORT
494   if(!Drawable::GetObject() || !mTvgShape)
495   {
496     DALI_LOG_ERROR("Shape is null\n");
497     return Vector<float>();
498   }
499   const float* tvgDashPattern = nullptr;
500   uint32_t     count          = 0;
501
502   count = static_cast<tvg::Shape*>(mTvgShape)->strokeDash(&tvgDashPattern);
503   if(!tvgDashPattern || count <= 0)
504   {
505     DALI_LOG_ERROR("GetStrokeDash() fail.\n");
506     return Vector<float>();
507   }
508
509   Dali::Vector<float> dashPattern;
510
511   dashPattern.Reserve(count);
512
513   for(unsigned int i = 0u; i < count; ++i)
514   {
515     dashPattern.PushBack(tvgDashPattern[i]);
516   }
517   return dashPattern;
518 #else
519   return Vector<float>();
520 #endif
521 }
522
523 bool ShapeTizen::SetStrokeCap(Dali::CanvasRenderer::Shape::StrokeCap cap)
524 {
525 #ifdef THORVG_SUPPORT
526   if(!Drawable::GetObject() || !mTvgShape)
527   {
528     DALI_LOG_ERROR("Shape is null\n");
529     return false;
530   }
531   if(static_cast<tvg::Shape*>(mTvgShape)->stroke(static_cast<tvg::StrokeCap>(cap)) != tvg::Result::Success)
532   {
533     DALI_LOG_ERROR("SetStrokeCap fail.\n");
534     return false;
535   }
536   Drawable::SetChanged(true);
537   return true;
538 #else
539   return false;
540 #endif
541 }
542
543 Dali::CanvasRenderer::Shape::StrokeCap ShapeTizen::GetStrokeCap() const
544 {
545 #ifdef THORVG_SUPPORT
546   if(!Drawable::GetObject() || !mTvgShape)
547   {
548     DALI_LOG_ERROR("Shape is null\n");
549     return Dali::CanvasRenderer::Shape::StrokeCap::SQUARE;
550   }
551
552   tvg::StrokeCap cap = static_cast<tvg::Shape*>(mTvgShape)->strokeCap();
553
554   return static_cast<Dali::CanvasRenderer::Shape::StrokeCap>(cap);
555 #endif
556   return Dali::CanvasRenderer::Shape::StrokeCap::SQUARE;
557 }
558
559 bool ShapeTizen::SetStrokeJoin(Dali::CanvasRenderer::Shape::StrokeJoin join)
560 {
561 #ifdef THORVG_SUPPORT
562   if(!Drawable::GetObject() || !mTvgShape)
563   {
564     DALI_LOG_ERROR("Shape is null\n");
565     return false;
566   }
567
568   if(static_cast<tvg::Shape*>(mTvgShape)->stroke(static_cast<tvg::StrokeJoin>(join)) != tvg::Result::Success)
569   {
570     DALI_LOG_ERROR("SetStrokejoin fail.\n");
571     return false;
572   }
573   Drawable::SetChanged(true);
574   return true;
575 #else
576   return false;
577 #endif
578 }
579
580 Dali::CanvasRenderer::Shape::StrokeJoin ShapeTizen::GetStrokeJoin() const
581 {
582 #ifdef THORVG_SUPPORT
583   if(!Drawable::GetObject() || !mTvgShape)
584   {
585     DALI_LOG_ERROR("Shape is null\n");
586     return Dali::CanvasRenderer::Shape::StrokeJoin::BEVEL;
587   }
588
589   tvg::StrokeJoin join = static_cast<tvg::Shape*>(mTvgShape)->strokeJoin();
590
591   return static_cast<Dali::CanvasRenderer::Shape::StrokeJoin>(join);
592 #endif
593   return Dali::CanvasRenderer::Shape::StrokeJoin::BEVEL;
594 }
595
596 } // namespace Adaptor
597
598 } // namespace Internal
599
600 } // namespace Dali