1 /*
2 * Copyright (c) 2020 - 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 #include "config.h"
27 #include <string>
28 #include "thorvg.h"
29 #include "thorvg_capi.h"
30 #ifdef THORVG_LOTTIE_LOADER_SUPPORT
31 #include "thorvg_lottie.h"
32 #endif
33
34 using namespace std;
35 using namespace tvg;
36
37 #ifdef __cplusplus
38 extern "C" {
39 #endif
40
41
42 /************************************************************************/
43 /* Engine API */
44 /************************************************************************/
45
tvg_engine_init(Tvg_Engine engine_method,unsigned threads)46 TVG_API Tvg_Result tvg_engine_init(Tvg_Engine engine_method, unsigned threads)
47 {
48 return (Tvg_Result) Initializer::init(CanvasEngine(engine_method), threads);
49 }
50
51
tvg_engine_term(Tvg_Engine engine_method)52 TVG_API Tvg_Result tvg_engine_term(Tvg_Engine engine_method)
53 {
54 return (Tvg_Result) Initializer::term(CanvasEngine(engine_method));
55 }
56
57
tvg_engine_version(uint32_t * major,uint32_t * minor,uint32_t * micro,const char ** version)58 TVG_API Tvg_Result tvg_engine_version(uint32_t* major, uint32_t* minor, uint32_t* micro, const char** version)
59 {
60 if (version) *version = Initializer::version(major, minor, micro);
61 return TVG_RESULT_SUCCESS;
62 }
63
64 /************************************************************************/
65 /* Canvas API */
66 /************************************************************************/
67
tvg_swcanvas_create()68 TVG_API Tvg_Canvas* tvg_swcanvas_create()
69 {
70 return (Tvg_Canvas*) SwCanvas::gen().release();
71 }
72
73
tvg_canvas_destroy(Tvg_Canvas * canvas)74 TVG_API Tvg_Result tvg_canvas_destroy(Tvg_Canvas* canvas)
75 {
76 if (!canvas) return TVG_RESULT_INVALID_ARGUMENT;
77 delete(reinterpret_cast<Canvas*>(canvas));
78 return TVG_RESULT_SUCCESS;
79 }
80
81
tvg_swcanvas_set_mempool(Tvg_Canvas * canvas,Tvg_Mempool_Policy policy)82 TVG_API Tvg_Result tvg_swcanvas_set_mempool(Tvg_Canvas* canvas, Tvg_Mempool_Policy policy)
83 {
84 if (!canvas) return TVG_RESULT_INVALID_ARGUMENT;
85 return (Tvg_Result) reinterpret_cast<SwCanvas*>(canvas)->mempool(static_cast<SwCanvas::MempoolPolicy>(policy));
86 }
87
88
tvg_swcanvas_set_target(Tvg_Canvas * canvas,uint32_t * buffer,uint32_t stride,uint32_t w,uint32_t h,Tvg_Colorspace cs)89 TVG_API Tvg_Result tvg_swcanvas_set_target(Tvg_Canvas* canvas, uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t h, Tvg_Colorspace cs)
90 {
91 if (!canvas) return TVG_RESULT_INVALID_ARGUMENT;
92 return (Tvg_Result) reinterpret_cast<SwCanvas*>(canvas)->target(buffer, stride, w, h, static_cast<SwCanvas::Colorspace>(cs));
93 }
94
95
tvg_canvas_push(Tvg_Canvas * canvas,Tvg_Paint * paint)96 TVG_API Tvg_Result tvg_canvas_push(Tvg_Canvas* canvas, Tvg_Paint* paint)
97 {
98 if (!canvas || !paint) return TVG_RESULT_INVALID_ARGUMENT;
99 return (Tvg_Result) reinterpret_cast<Canvas*>(canvas)->push(unique_ptr<Paint>((Paint*)paint));
100 }
101
102
tvg_canvas_reserve(Tvg_Canvas * canvas,uint32_t n)103 TVG_API Tvg_Result tvg_canvas_reserve(Tvg_Canvas* canvas, uint32_t n)
104 {
105 return TVG_RESULT_NOT_SUPPORTED;
106 }
107
108
tvg_canvas_clear(Tvg_Canvas * canvas,bool free)109 TVG_API Tvg_Result tvg_canvas_clear(Tvg_Canvas* canvas, bool free)
110 {
111 if (!canvas) return TVG_RESULT_INVALID_ARGUMENT;
112 return (Tvg_Result) reinterpret_cast<Canvas*>(canvas)->clear(free);
113 }
114
115
tvg_canvas_update(Tvg_Canvas * canvas)116 TVG_API Tvg_Result tvg_canvas_update(Tvg_Canvas* canvas)
117 {
118 if (!canvas) return TVG_RESULT_INVALID_ARGUMENT;
119 return (Tvg_Result) reinterpret_cast<Canvas*>(canvas)->update(nullptr);
120 }
121
122
tvg_canvas_update_paint(Tvg_Canvas * canvas,Tvg_Paint * paint)123 TVG_API Tvg_Result tvg_canvas_update_paint(Tvg_Canvas* canvas, Tvg_Paint* paint)
124 {
125 if (!canvas || !paint) return TVG_RESULT_INVALID_ARGUMENT;
126 return (Tvg_Result) reinterpret_cast<Canvas*>(canvas)->update((Paint*) paint);
127 }
128
129
tvg_canvas_draw(Tvg_Canvas * canvas)130 TVG_API Tvg_Result tvg_canvas_draw(Tvg_Canvas* canvas)
131 {
132 if (!canvas) return TVG_RESULT_INVALID_ARGUMENT;
133 return (Tvg_Result) reinterpret_cast<Canvas*>(canvas)->draw();
134 }
135
136
tvg_canvas_sync(Tvg_Canvas * canvas)137 TVG_API Tvg_Result tvg_canvas_sync(Tvg_Canvas* canvas)
138 {
139 if (!canvas) return TVG_RESULT_INVALID_ARGUMENT;
140 return (Tvg_Result) reinterpret_cast<Canvas*>(canvas)->sync();
141 }
142
143
tvg_canvas_set_viewport(Tvg_Canvas * canvas,int32_t x,int32_t y,int32_t w,int32_t h)144 TVG_API Tvg_Result tvg_canvas_set_viewport(Tvg_Canvas* canvas, int32_t x, int32_t y, int32_t w, int32_t h)
145 {
146 if (!canvas) return TVG_RESULT_INVALID_ARGUMENT;
147 return (Tvg_Result) reinterpret_cast<Canvas*>(canvas)->viewport(x, y, w, h);
148 }
149
150
151 /************************************************************************/
152 /* Paint API */
153 /************************************************************************/
154
tvg_paint_del(Tvg_Paint * paint)155 TVG_API Tvg_Result tvg_paint_del(Tvg_Paint* paint)
156 {
157 if (!paint) return TVG_RESULT_INVALID_ARGUMENT;
158 delete(reinterpret_cast<Paint*>(paint));
159 return TVG_RESULT_SUCCESS;
160 }
161
162
tvg_paint_scale(Tvg_Paint * paint,float factor)163 TVG_API Tvg_Result tvg_paint_scale(Tvg_Paint* paint, float factor)
164 {
165 if (!paint) return TVG_RESULT_INVALID_ARGUMENT;
166 return (Tvg_Result) reinterpret_cast<Paint*>(paint)->scale(factor);
167 }
168
169
tvg_paint_rotate(Tvg_Paint * paint,float degree)170 TVG_API Tvg_Result tvg_paint_rotate(Tvg_Paint* paint, float degree)
171 {
172 if (!paint) return TVG_RESULT_INVALID_ARGUMENT;
173 return (Tvg_Result) reinterpret_cast<Paint*>(paint)->rotate(degree);
174 }
175
176
tvg_paint_translate(Tvg_Paint * paint,float x,float y)177 TVG_API Tvg_Result tvg_paint_translate(Tvg_Paint* paint, float x, float y)
178 {
179 if (!paint) return TVG_RESULT_INVALID_ARGUMENT;
180 return (Tvg_Result) reinterpret_cast<Paint*>(paint)->translate(x, y);
181 }
182
183
tvg_paint_set_transform(Tvg_Paint * paint,const Tvg_Matrix * m)184 TVG_API Tvg_Result tvg_paint_set_transform(Tvg_Paint* paint, const Tvg_Matrix* m)
185 {
186 if (!paint || !m) return TVG_RESULT_INVALID_ARGUMENT;
187 return (Tvg_Result) reinterpret_cast<Paint*>(paint)->transform(*(reinterpret_cast<const Matrix*>(m)));
188 }
189
190
tvg_paint_get_transform(Tvg_Paint * paint,Tvg_Matrix * m)191 TVG_API Tvg_Result tvg_paint_get_transform(Tvg_Paint* paint, Tvg_Matrix* m)
192 {
193 if (!paint || !m) return TVG_RESULT_INVALID_ARGUMENT;
194 *reinterpret_cast<Matrix*>(m) = reinterpret_cast<Paint*>(paint)->transform();
195 return TVG_RESULT_SUCCESS;
196 }
197
198
tvg_paint_duplicate(Tvg_Paint * paint)199 TVG_API Tvg_Paint* tvg_paint_duplicate(Tvg_Paint* paint)
200 {
201 if (!paint) return nullptr;
202 return (Tvg_Paint*) reinterpret_cast<Paint*>(paint)->duplicate();
203 }
204
205
tvg_paint_set_opacity(Tvg_Paint * paint,uint8_t opacity)206 TVG_API Tvg_Result tvg_paint_set_opacity(Tvg_Paint* paint, uint8_t opacity)
207 {
208 if (!paint) return TVG_RESULT_INVALID_ARGUMENT;
209 return (Tvg_Result) reinterpret_cast<Paint*>(paint)->opacity(opacity);
210 }
211
212
tvg_paint_get_opacity(const Tvg_Paint * paint,uint8_t * opacity)213 TVG_API Tvg_Result tvg_paint_get_opacity(const Tvg_Paint* paint, uint8_t* opacity)
214 {
215 if (!paint || !opacity) return TVG_RESULT_INVALID_ARGUMENT;
216 *opacity = reinterpret_cast<const Paint*>(paint)->opacity();
217 return TVG_RESULT_SUCCESS;
218 }
219
220
tvg_paint_get_bounds(const Tvg_Paint * paint,float * x,float * y,float * w,float * h,bool transformed)221 TVG_API Tvg_Result tvg_paint_get_bounds(const Tvg_Paint* paint, float* x, float* y, float* w, float* h, bool transformed)
222 {
223 if (!paint) return TVG_RESULT_INVALID_ARGUMENT;
224 return (Tvg_Result) reinterpret_cast<const Paint*>(paint)->bounds(x, y, w, h, transformed);
225 }
226
227
tvg_paint_set_composite_method(Tvg_Paint * paint,Tvg_Paint * target,Tvg_Composite_Method method)228 TVG_API Tvg_Result tvg_paint_set_composite_method(Tvg_Paint* paint, Tvg_Paint* target, Tvg_Composite_Method method)
229 {
230 if (!paint) return TVG_RESULT_INVALID_ARGUMENT;
231 return (Tvg_Result) reinterpret_cast<Paint*>(paint)->composite(unique_ptr<Paint>((Paint*)(target)), (CompositeMethod)method);
232 }
233
234
tvg_paint_get_composite_method(const Tvg_Paint * paint,const Tvg_Paint ** target,Tvg_Composite_Method * method)235 TVG_API Tvg_Result tvg_paint_get_composite_method(const Tvg_Paint* paint, const Tvg_Paint** target, Tvg_Composite_Method* method)
236 {
237 if (!paint || !target || !method) return TVG_RESULT_INVALID_ARGUMENT;
238 *reinterpret_cast<CompositeMethod*>(method) = reinterpret_cast<const Paint*>(paint)->composite(reinterpret_cast<const Paint**>(target));
239 return TVG_RESULT_SUCCESS;
240 }
241
242
tvg_paint_set_blend_method(Tvg_Paint * paint,Tvg_Blend_Method method)243 TVG_API Tvg_Result tvg_paint_set_blend_method(Tvg_Paint* paint, Tvg_Blend_Method method)
244 {
245 if (!paint) return TVG_RESULT_INVALID_ARGUMENT;
246 return (Tvg_Result) reinterpret_cast<Paint*>(paint)->blend((BlendMethod)method);
247 }
248
249
tvg_paint_get_type(const Tvg_Paint * paint,Tvg_Type * type)250 TVG_API Tvg_Result tvg_paint_get_type(const Tvg_Paint* paint, Tvg_Type* type)
251 {
252 if (!paint || !type) return TVG_RESULT_INVALID_ARGUMENT;
253 *type = static_cast<Tvg_Type>(reinterpret_cast<const Paint*>(paint)->type());
254 return TVG_RESULT_SUCCESS;
255 }
256
257
tvg_paint_set_clip(Tvg_Paint * paint,Tvg_Paint * clipper)258 TVG_API Tvg_Result tvg_paint_set_clip(Tvg_Paint* paint, Tvg_Paint* clipper)
259 {
260 if (!paint) return TVG_RESULT_INVALID_ARGUMENT;
261 return (Tvg_Result) reinterpret_cast<Paint*>(paint)->clip(unique_ptr<Paint>((Paint*)(clipper)));
262 }
263
264
tvg_paint_get_identifier(const Tvg_Paint * paint,Tvg_Identifier * identifier)265 TVG_DEPRECATED TVG_API Tvg_Result tvg_paint_get_identifier(const Tvg_Paint* paint, Tvg_Identifier* identifier)
266 {
267 return tvg_paint_get_type(paint, (Tvg_Type*) identifier);
268 }
269
270 /************************************************************************/
271 /* Shape API */
272 /************************************************************************/
273
tvg_shape_new()274 TVG_API Tvg_Paint* tvg_shape_new()
275 {
276 return (Tvg_Paint*) Shape::gen().release();
277 }
278
279
tvg_shape_reset(Tvg_Paint * paint)280 TVG_API Tvg_Result tvg_shape_reset(Tvg_Paint* paint)
281 {
282 if (!paint) return TVG_RESULT_INVALID_ARGUMENT;
283 return (Tvg_Result) reinterpret_cast<Shape*>(paint)->reset();
284 }
285
286
tvg_shape_move_to(Tvg_Paint * paint,float x,float y)287 TVG_API Tvg_Result tvg_shape_move_to(Tvg_Paint* paint, float x, float y)
288 {
289 if (!paint) return TVG_RESULT_INVALID_ARGUMENT;
290 return (Tvg_Result) reinterpret_cast<Shape*>(paint)->moveTo(x, y);
291 }
292
293
tvg_shape_line_to(Tvg_Paint * paint,float x,float y)294 TVG_API Tvg_Result tvg_shape_line_to(Tvg_Paint* paint, float x, float y)
295 {
296 if (!paint) return TVG_RESULT_INVALID_ARGUMENT;
297 return (Tvg_Result) reinterpret_cast<Shape*>(paint)->lineTo(x, y);
298 }
299
300
tvg_shape_cubic_to(Tvg_Paint * paint,float cx1,float cy1,float cx2,float cy2,float x,float y)301 TVG_API Tvg_Result tvg_shape_cubic_to(Tvg_Paint* paint, float cx1, float cy1, float cx2, float cy2, float x, float y)
302 {
303 if (!paint) return TVG_RESULT_INVALID_ARGUMENT;
304 return (Tvg_Result) reinterpret_cast<Shape*>(paint)->cubicTo(cx1, cy1, cx2, cy2, x, y);
305 }
306
307
tvg_shape_close(Tvg_Paint * paint)308 TVG_API Tvg_Result tvg_shape_close(Tvg_Paint* paint)
309 {
310 if (!paint) return TVG_RESULT_INVALID_ARGUMENT;
311 return (Tvg_Result) reinterpret_cast<Shape*>(paint)->close();
312 }
313
314
tvg_shape_append_rect(Tvg_Paint * paint,float x,float y,float w,float h,float rx,float ry)315 TVG_API Tvg_Result tvg_shape_append_rect(Tvg_Paint* paint, float x, float y, float w, float h, float rx, float ry)
316 {
317 if (!paint) return TVG_RESULT_INVALID_ARGUMENT;
318 return (Tvg_Result) reinterpret_cast<Shape*>(paint)->appendRect(x, y, w, h, rx, ry);
319 }
320
321
tvg_shape_append_arc(Tvg_Paint * paint,float cx,float cy,float radius,float startAngle,float sweep,uint8_t pie)322 TVG_API Tvg_Result tvg_shape_append_arc(Tvg_Paint* paint, float cx, float cy, float radius, float startAngle, float sweep, uint8_t pie)
323 {
324 if (!paint) return TVG_RESULT_INVALID_ARGUMENT;
325 return (Tvg_Result) reinterpret_cast<Shape*>(paint)->appendArc(cx, cy, radius, startAngle, sweep, pie);
326 }
327
328
tvg_shape_append_circle(Tvg_Paint * paint,float cx,float cy,float rx,float ry)329 TVG_API Tvg_Result tvg_shape_append_circle(Tvg_Paint* paint, float cx, float cy, float rx, float ry)
330 {
331 if (!paint) return TVG_RESULT_INVALID_ARGUMENT;
332 return (Tvg_Result) reinterpret_cast<Shape*>(paint)->appendCircle(cx, cy, rx, ry);
333 }
334
335
tvg_shape_append_path(Tvg_Paint * paint,const Tvg_Path_Command * cmds,uint32_t cmdCnt,const Tvg_Point * pts,uint32_t ptsCnt)336 TVG_API Tvg_Result tvg_shape_append_path(Tvg_Paint* paint, const Tvg_Path_Command* cmds, uint32_t cmdCnt, const Tvg_Point* pts, uint32_t ptsCnt)
337 {
338 if (!paint) return TVG_RESULT_INVALID_ARGUMENT;
339 return (Tvg_Result) reinterpret_cast<Shape*>(paint)->appendPath((const PathCommand*)cmds, cmdCnt, (const Point*)pts, ptsCnt);
340 }
341
342
tvg_shape_get_path_coords(const Tvg_Paint * paint,const Tvg_Point ** pts,uint32_t * cnt)343 TVG_API Tvg_Result tvg_shape_get_path_coords(const Tvg_Paint* paint, const Tvg_Point** pts, uint32_t* cnt)
344 {
345 if (!paint || !pts || !cnt) return TVG_RESULT_INVALID_ARGUMENT;
346 *cnt = reinterpret_cast<const Shape*>(paint)->pathCoords((const Point**)pts);
347 return TVG_RESULT_SUCCESS;
348 }
349
350
tvg_shape_get_path_commands(const Tvg_Paint * paint,const Tvg_Path_Command ** cmds,uint32_t * cnt)351 TVG_API Tvg_Result tvg_shape_get_path_commands(const Tvg_Paint* paint, const Tvg_Path_Command** cmds, uint32_t* cnt)
352 {
353 if (!paint || !cmds || !cnt) return TVG_RESULT_INVALID_ARGUMENT;
354 *cnt = reinterpret_cast<const Shape*>(paint)->pathCommands((const PathCommand**)cmds);
355 return TVG_RESULT_SUCCESS;
356 }
357
358
tvg_shape_set_stroke_width(Tvg_Paint * paint,float width)359 TVG_API Tvg_Result tvg_shape_set_stroke_width(Tvg_Paint* paint, float width)
360 {
361 if (!paint) return TVG_RESULT_INVALID_ARGUMENT;
362 return (Tvg_Result) reinterpret_cast<Shape*>(paint)->stroke(width);
363 }
364
365
tvg_shape_get_stroke_width(const Tvg_Paint * paint,float * width)366 TVG_API Tvg_Result tvg_shape_get_stroke_width(const Tvg_Paint* paint, float* width)
367 {
368 if (!paint || !width) return TVG_RESULT_INVALID_ARGUMENT;
369 *width = reinterpret_cast<const Shape*>(paint)->strokeWidth();
370 return TVG_RESULT_SUCCESS;
371 }
372
373
tvg_shape_set_stroke_color(Tvg_Paint * paint,uint8_t r,uint8_t g,uint8_t b,uint8_t a)374 TVG_API Tvg_Result tvg_shape_set_stroke_color(Tvg_Paint* paint, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
375 {
376 if (!paint) return TVG_RESULT_INVALID_ARGUMENT;
377 return (Tvg_Result) reinterpret_cast<Shape*>(paint)->stroke(r, g, b, a);
378 }
379
380
tvg_shape_get_stroke_color(const Tvg_Paint * paint,uint8_t * r,uint8_t * g,uint8_t * b,uint8_t * a)381 TVG_API Tvg_Result tvg_shape_get_stroke_color(const Tvg_Paint* paint, uint8_t* r, uint8_t* g, uint8_t* b, uint8_t* a)
382 {
383 if (!paint) return TVG_RESULT_INVALID_ARGUMENT;
384 return (Tvg_Result) reinterpret_cast<const Shape*>(paint)->strokeColor(r, g, b, a);
385 }
386
387
tvg_shape_set_stroke_linear_gradient(Tvg_Paint * paint,Tvg_Gradient * gradient)388 TVG_API Tvg_Result tvg_shape_set_stroke_linear_gradient(Tvg_Paint* paint, Tvg_Gradient* gradient)
389 {
390 if (!paint) return TVG_RESULT_INVALID_ARGUMENT;
391 return (Tvg_Result) reinterpret_cast<Shape*>(paint)->stroke(unique_ptr<LinearGradient>((LinearGradient*)(gradient)));
392 }
393
394
tvg_shape_set_stroke_radial_gradient(Tvg_Paint * paint,Tvg_Gradient * gradient)395 TVG_API Tvg_Result tvg_shape_set_stroke_radial_gradient(Tvg_Paint* paint, Tvg_Gradient* gradient)
396 {
397 if (!paint) return TVG_RESULT_INVALID_ARGUMENT;
398 return (Tvg_Result) reinterpret_cast<Shape*>(paint)->stroke(unique_ptr<RadialGradient>((RadialGradient*)(gradient)));
399 }
400
401
tvg_shape_get_stroke_gradient(const Tvg_Paint * paint,Tvg_Gradient ** gradient)402 TVG_API Tvg_Result tvg_shape_get_stroke_gradient(const Tvg_Paint* paint, Tvg_Gradient** gradient)
403 {
404 if (!paint || !gradient) return TVG_RESULT_INVALID_ARGUMENT;
405 *gradient = (Tvg_Gradient*)(reinterpret_cast<const Shape*>(paint)->strokeFill());
406 return TVG_RESULT_SUCCESS;
407 }
408
409
tvg_shape_set_stroke_dash(Tvg_Paint * paint,const float * dashPattern,uint32_t cnt)410 TVG_API Tvg_Result tvg_shape_set_stroke_dash(Tvg_Paint* paint, const float* dashPattern, uint32_t cnt)
411 {
412 if (!paint) return TVG_RESULT_INVALID_ARGUMENT;
413 return (Tvg_Result) reinterpret_cast<Shape*>(paint)->stroke(dashPattern, cnt);
414 }
415
416
tvg_shape_get_stroke_dash(const Tvg_Paint * paint,const float ** dashPattern,uint32_t * cnt)417 TVG_API Tvg_Result tvg_shape_get_stroke_dash(const Tvg_Paint* paint, const float** dashPattern, uint32_t* cnt)
418 {
419 if (!paint || !cnt || !dashPattern) return TVG_RESULT_INVALID_ARGUMENT;
420 *cnt = reinterpret_cast<const Shape*>(paint)->strokeDash(dashPattern);
421 return TVG_RESULT_SUCCESS;
422 }
423
424
tvg_shape_set_stroke_cap(Tvg_Paint * paint,Tvg_Stroke_Cap cap)425 TVG_API Tvg_Result tvg_shape_set_stroke_cap(Tvg_Paint* paint, Tvg_Stroke_Cap cap)
426 {
427 if (!paint) return TVG_RESULT_INVALID_ARGUMENT;
428 return (Tvg_Result) reinterpret_cast<Shape*>(paint)->stroke((StrokeCap)cap);
429 }
430
431
tvg_shape_get_stroke_cap(const Tvg_Paint * paint,Tvg_Stroke_Cap * cap)432 TVG_API Tvg_Result tvg_shape_get_stroke_cap(const Tvg_Paint* paint, Tvg_Stroke_Cap* cap)
433 {
434 if (!paint || !cap) return TVG_RESULT_INVALID_ARGUMENT;
435 *cap = (Tvg_Stroke_Cap) reinterpret_cast<const Shape*>(paint)->strokeCap();
436 return TVG_RESULT_SUCCESS;
437 }
438
439
tvg_shape_set_stroke_join(Tvg_Paint * paint,Tvg_Stroke_Join join)440 TVG_API Tvg_Result tvg_shape_set_stroke_join(Tvg_Paint* paint, Tvg_Stroke_Join join)
441 {
442 if (!paint) return TVG_RESULT_INVALID_ARGUMENT;
443 return (Tvg_Result) reinterpret_cast<Shape*>(paint)->stroke((StrokeJoin)join);
444 }
445
446
tvg_shape_get_stroke_join(const Tvg_Paint * paint,Tvg_Stroke_Join * join)447 TVG_API Tvg_Result tvg_shape_get_stroke_join(const Tvg_Paint* paint, Tvg_Stroke_Join* join)
448 {
449 if (!paint || !join) return TVG_RESULT_INVALID_ARGUMENT;
450 *join = (Tvg_Stroke_Join) reinterpret_cast<const Shape*>(paint)->strokeJoin();
451 return TVG_RESULT_SUCCESS;
452 }
453
454
tvg_shape_set_stroke_miterlimit(Tvg_Paint * paint,float ml)455 TVG_API Tvg_Result tvg_shape_set_stroke_miterlimit(Tvg_Paint* paint, float ml)
456 {
457 if (!paint) return TVG_RESULT_INVALID_ARGUMENT;
458 return (Tvg_Result) reinterpret_cast<Shape*>(paint)->strokeMiterlimit(ml);
459 }
460
461
tvg_shape_get_stroke_miterlimit(const Tvg_Paint * paint,float * ml)462 TVG_API Tvg_Result tvg_shape_get_stroke_miterlimit(const Tvg_Paint* paint, float* ml)
463 {
464 if (!paint || !ml) return TVG_RESULT_INVALID_ARGUMENT;
465 *ml = reinterpret_cast<const Shape*>(paint)->strokeMiterlimit();
466 return TVG_RESULT_SUCCESS;
467 }
468
469
tvg_shape_set_stroke_trim(Tvg_Paint * paint,float begin,float end,bool simultaneous)470 TVG_API Tvg_Result tvg_shape_set_stroke_trim(Tvg_Paint* paint, float begin, float end, bool simultaneous)
471 {
472 if (!paint) return TVG_RESULT_INVALID_ARGUMENT;
473 return (Tvg_Result) reinterpret_cast<Shape*>(paint)->strokeTrim(begin, end, simultaneous);
474 }
475
476
tvg_shape_set_fill_color(Tvg_Paint * paint,uint8_t r,uint8_t g,uint8_t b,uint8_t a)477 TVG_API Tvg_Result tvg_shape_set_fill_color(Tvg_Paint* paint, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
478 {
479 if (!paint) return TVG_RESULT_INVALID_ARGUMENT;
480 return (Tvg_Result) reinterpret_cast<Shape*>(paint)->fill(r, g, b, a);
481 }
482
483
tvg_shape_get_fill_color(const Tvg_Paint * paint,uint8_t * r,uint8_t * g,uint8_t * b,uint8_t * a)484 TVG_API Tvg_Result tvg_shape_get_fill_color(const Tvg_Paint* paint, uint8_t* r, uint8_t* g, uint8_t* b, uint8_t* a)
485 {
486 if (!paint) return TVG_RESULT_INVALID_ARGUMENT;
487 return (Tvg_Result) reinterpret_cast<const Shape*>(paint)->fillColor(r, g, b, a);
488 }
489
490
tvg_shape_set_fill_rule(Tvg_Paint * paint,Tvg_Fill_Rule rule)491 TVG_API Tvg_Result tvg_shape_set_fill_rule(Tvg_Paint* paint, Tvg_Fill_Rule rule)
492 {
493 if (!paint) return TVG_RESULT_INVALID_ARGUMENT;
494 return (Tvg_Result) reinterpret_cast<Shape*>(paint)->fill((FillRule)rule);
495 }
496
497
tvg_shape_get_fill_rule(const Tvg_Paint * paint,Tvg_Fill_Rule * rule)498 TVG_API Tvg_Result tvg_shape_get_fill_rule(const Tvg_Paint* paint, Tvg_Fill_Rule* rule)
499 {
500 if (!paint || !rule) return TVG_RESULT_INVALID_ARGUMENT;
501 *rule = (Tvg_Fill_Rule) reinterpret_cast<const Shape*>(paint)->fillRule();
502 return TVG_RESULT_SUCCESS;
503 }
504
505
tvg_shape_set_paint_order(Tvg_Paint * paint,bool strokeFirst)506 TVG_API Tvg_Result tvg_shape_set_paint_order(Tvg_Paint* paint, bool strokeFirst)
507 {
508 if (!paint) return TVG_RESULT_INVALID_ARGUMENT;
509 return (Tvg_Result) reinterpret_cast<Shape*>(paint)->order(strokeFirst);
510 }
511
512
tvg_shape_set_linear_gradient(Tvg_Paint * paint,Tvg_Gradient * gradient)513 TVG_API Tvg_Result tvg_shape_set_linear_gradient(Tvg_Paint* paint, Tvg_Gradient* gradient)
514 {
515 if (!paint) return TVG_RESULT_INVALID_ARGUMENT;
516 return (Tvg_Result) reinterpret_cast<Shape*>(paint)->fill(unique_ptr<LinearGradient>((LinearGradient*)(gradient)));
517 }
518
519
tvg_shape_set_radial_gradient(Tvg_Paint * paint,Tvg_Gradient * gradient)520 TVG_API Tvg_Result tvg_shape_set_radial_gradient(Tvg_Paint* paint, Tvg_Gradient* gradient)
521 {
522 if (!paint) return TVG_RESULT_INVALID_ARGUMENT;
523 return (Tvg_Result) reinterpret_cast<Shape*>(paint)->fill(unique_ptr<RadialGradient>((RadialGradient*)(gradient)));
524 }
525
526
tvg_shape_get_gradient(const Tvg_Paint * paint,Tvg_Gradient ** gradient)527 TVG_API Tvg_Result tvg_shape_get_gradient(const Tvg_Paint* paint, Tvg_Gradient** gradient)
528 {
529 if (!paint || !gradient) return TVG_RESULT_INVALID_ARGUMENT;
530 *gradient = (Tvg_Gradient*)(reinterpret_cast<const Shape*>(paint)->fill());
531 return TVG_RESULT_SUCCESS;
532 }
533
534 /************************************************************************/
535 /* Picture API */
536 /************************************************************************/
537
tvg_picture_new()538 TVG_API Tvg_Paint* tvg_picture_new()
539 {
540 return (Tvg_Paint*) Picture::gen().release();
541 }
542
543
tvg_picture_load(Tvg_Paint * paint,const char * path)544 TVG_API Tvg_Result tvg_picture_load(Tvg_Paint* paint, const char* path)
545 {
546 if (!paint) return TVG_RESULT_INVALID_ARGUMENT;
547 return (Tvg_Result) reinterpret_cast<Picture*>(paint)->load(path);
548 }
549
550
tvg_picture_load_raw(Tvg_Paint * paint,uint32_t * data,uint32_t w,uint32_t h,bool copy)551 TVG_API Tvg_Result tvg_picture_load_raw(Tvg_Paint* paint, uint32_t *data, uint32_t w, uint32_t h, bool copy)
552 {
553 if (!paint) return TVG_RESULT_INVALID_ARGUMENT;
554 return (Tvg_Result) reinterpret_cast<Picture*>(paint)->load(data, w, h, copy);
555 }
556
557
tvg_picture_load_data(Tvg_Paint * paint,const char * data,uint32_t size,const char * mimetype,bool copy)558 TVG_API Tvg_Result tvg_picture_load_data(Tvg_Paint* paint, const char *data, uint32_t size, const char *mimetype, bool copy)
559 {
560 if (!paint) return TVG_RESULT_INVALID_ARGUMENT;
561 return (Tvg_Result) reinterpret_cast<Picture*>(paint)->load(data, size, mimetype ? mimetype : "", copy);
562 }
563
564
tvg_picture_set_size(Tvg_Paint * paint,float w,float h)565 TVG_API Tvg_Result tvg_picture_set_size(Tvg_Paint* paint, float w, float h)
566 {
567 if (!paint) return TVG_RESULT_INVALID_ARGUMENT;
568 return (Tvg_Result) reinterpret_cast<Picture*>(paint)->size(w, h);
569 }
570
571
tvg_picture_get_size(const Tvg_Paint * paint,float * w,float * h)572 TVG_API Tvg_Result tvg_picture_get_size(const Tvg_Paint* paint, float* w, float* h)
573 {
574 if (!paint) return TVG_RESULT_INVALID_ARGUMENT;
575 return (Tvg_Result) reinterpret_cast<const Picture*>(paint)->size(w, h);
576 }
577
578
tvg_picture_get_paint(Tvg_Paint * paint,uint32_t id)579 TVG_API const Tvg_Paint* tvg_picture_get_paint(Tvg_Paint* paint, uint32_t id)
580 {
581 if (!paint) return nullptr;
582 return (Tvg_Paint*) reinterpret_cast<Picture*>(paint)->paint(id);
583 }
584
585
586 /************************************************************************/
587 /* Gradient API */
588 /************************************************************************/
589
tvg_linear_gradient_new()590 TVG_API Tvg_Gradient* tvg_linear_gradient_new()
591 {
592 return (Tvg_Gradient*)LinearGradient::gen().release();
593 }
594
595
tvg_radial_gradient_new()596 TVG_API Tvg_Gradient* tvg_radial_gradient_new()
597 {
598 return (Tvg_Gradient*)RadialGradient::gen().release();
599 }
600
601
tvg_gradient_duplicate(Tvg_Gradient * grad)602 TVG_API Tvg_Gradient* tvg_gradient_duplicate(Tvg_Gradient* grad)
603 {
604 if (!grad) return nullptr;
605 return (Tvg_Gradient*) reinterpret_cast<Fill*>(grad)->duplicate();
606 }
607
608
tvg_gradient_del(Tvg_Gradient * grad)609 TVG_API Tvg_Result tvg_gradient_del(Tvg_Gradient* grad)
610 {
611 if (!grad) return TVG_RESULT_INVALID_ARGUMENT;
612 delete(reinterpret_cast<Fill*>(grad));
613 return TVG_RESULT_SUCCESS;
614 }
615
616
tvg_linear_gradient_set(Tvg_Gradient * grad,float x1,float y1,float x2,float y2)617 TVG_API Tvg_Result tvg_linear_gradient_set(Tvg_Gradient* grad, float x1, float y1, float x2, float y2)
618 {
619 if (!grad) return TVG_RESULT_INVALID_ARGUMENT;
620 return (Tvg_Result) reinterpret_cast<LinearGradient*>(grad)->linear(x1, y1, x2, y2);
621 }
622
623
tvg_linear_gradient_get(Tvg_Gradient * grad,float * x1,float * y1,float * x2,float * y2)624 TVG_API Tvg_Result tvg_linear_gradient_get(Tvg_Gradient* grad, float* x1, float* y1, float* x2, float* y2)
625 {
626 if (!grad) return TVG_RESULT_INVALID_ARGUMENT;
627 return (Tvg_Result) reinterpret_cast<LinearGradient*>(grad)->linear(x1, y1, x2, y2);
628 }
629
630
tvg_radial_gradient_set(Tvg_Gradient * grad,float cx,float cy,float radius)631 TVG_API Tvg_Result tvg_radial_gradient_set(Tvg_Gradient* grad, float cx, float cy, float radius)
632 {
633 if (!grad) return TVG_RESULT_INVALID_ARGUMENT;
634 return (Tvg_Result) reinterpret_cast<RadialGradient*>(grad)->radial(cx, cy, radius);
635 }
636
637
tvg_radial_gradient_get(Tvg_Gradient * grad,float * cx,float * cy,float * radius)638 TVG_API Tvg_Result tvg_radial_gradient_get(Tvg_Gradient* grad, float* cx, float* cy, float* radius)
639 {
640 if (!grad) return TVG_RESULT_INVALID_ARGUMENT;
641 return (Tvg_Result) reinterpret_cast<RadialGradient*>(grad)->radial(cx, cy, radius);
642 }
643
644
tvg_gradient_set_color_stops(Tvg_Gradient * grad,const Tvg_Color_Stop * color_stop,uint32_t cnt)645 TVG_API Tvg_Result tvg_gradient_set_color_stops(Tvg_Gradient* grad, const Tvg_Color_Stop* color_stop, uint32_t cnt)
646 {
647 if (!grad) return TVG_RESULT_INVALID_ARGUMENT;
648 return (Tvg_Result) reinterpret_cast<Fill*>(grad)->colorStops(reinterpret_cast<const Fill::ColorStop*>(color_stop), cnt);
649 }
650
651
tvg_gradient_get_color_stops(const Tvg_Gradient * grad,const Tvg_Color_Stop ** color_stop,uint32_t * cnt)652 TVG_API Tvg_Result tvg_gradient_get_color_stops(const Tvg_Gradient* grad, const Tvg_Color_Stop** color_stop, uint32_t* cnt)
653 {
654 if (!grad || !color_stop || !cnt) return TVG_RESULT_INVALID_ARGUMENT;
655 *cnt = reinterpret_cast<const Fill*>(grad)->colorStops(reinterpret_cast<const Fill::ColorStop**>(color_stop));
656 return TVG_RESULT_SUCCESS;
657 }
658
659
tvg_gradient_set_spread(Tvg_Gradient * grad,const Tvg_Stroke_Fill spread)660 TVG_API Tvg_Result tvg_gradient_set_spread(Tvg_Gradient* grad, const Tvg_Stroke_Fill spread)
661 {
662 if (!grad) return TVG_RESULT_INVALID_ARGUMENT;
663 return (Tvg_Result) reinterpret_cast<Fill*>(grad)->spread((FillSpread)spread);
664 }
665
666
tvg_gradient_get_spread(const Tvg_Gradient * grad,Tvg_Stroke_Fill * spread)667 TVG_API Tvg_Result tvg_gradient_get_spread(const Tvg_Gradient* grad, Tvg_Stroke_Fill* spread)
668 {
669 if (!grad || !spread) return TVG_RESULT_INVALID_ARGUMENT;
670 *spread = (Tvg_Stroke_Fill) reinterpret_cast<const Fill*>(grad)->spread();
671 return TVG_RESULT_SUCCESS;
672 }
673
674
tvg_gradient_set_transform(Tvg_Gradient * grad,const Tvg_Matrix * m)675 TVG_API Tvg_Result tvg_gradient_set_transform(Tvg_Gradient* grad, const Tvg_Matrix* m)
676 {
677 if (!grad || !m) return TVG_RESULT_INVALID_ARGUMENT;
678 return (Tvg_Result) reinterpret_cast<Fill*>(grad)->transform(*(reinterpret_cast<const Matrix*>(m)));
679 }
680
681
tvg_gradient_get_transform(const Tvg_Gradient * grad,Tvg_Matrix * m)682 TVG_API Tvg_Result tvg_gradient_get_transform(const Tvg_Gradient* grad, Tvg_Matrix* m)
683 {
684 if (!grad || !m) return TVG_RESULT_INVALID_ARGUMENT;
685 *reinterpret_cast<Matrix*>(m) = reinterpret_cast<Fill*>(const_cast<Tvg_Gradient*>(grad))->transform();
686 return TVG_RESULT_SUCCESS;
687 }
688
689
tvg_gradient_get_type(const Tvg_Gradient * grad,Tvg_Type * type)690 TVG_API Tvg_Result tvg_gradient_get_type(const Tvg_Gradient* grad, Tvg_Type* type)
691 {
692 if (!grad || !type) return TVG_RESULT_INVALID_ARGUMENT;
693 *type = static_cast<Tvg_Type>(reinterpret_cast<const Fill*>(grad)->type());
694 return TVG_RESULT_SUCCESS;
695 }
696
697
tvg_gradient_get_identifier(const Tvg_Gradient * grad,Tvg_Identifier * identifier)698 TVG_DEPRECATED TVG_API Tvg_Result tvg_gradient_get_identifier(const Tvg_Gradient* grad, Tvg_Identifier* identifier)
699 {
700 return tvg_gradient_get_type(grad, (Tvg_Type*) identifier);
701 }
702
703 /************************************************************************/
704 /* Scene API */
705 /************************************************************************/
706
tvg_scene_new()707 TVG_API Tvg_Paint* tvg_scene_new()
708 {
709 return (Tvg_Paint*) Scene::gen().release();
710 }
711
712
tvg_scene_reserve(Tvg_Paint * scene,uint32_t size)713 TVG_API Tvg_Result tvg_scene_reserve(Tvg_Paint* scene, uint32_t size)
714 {
715 return TVG_RESULT_NOT_SUPPORTED;
716 }
717
718
tvg_scene_push(Tvg_Paint * scene,Tvg_Paint * paint)719 TVG_API Tvg_Result tvg_scene_push(Tvg_Paint* scene, Tvg_Paint* paint)
720 {
721 if (!scene || !paint) return TVG_RESULT_INVALID_ARGUMENT;
722 return (Tvg_Result) reinterpret_cast<Scene*>(scene)->push(unique_ptr<Paint>((Paint*)paint));
723 }
724
725
tvg_scene_clear(Tvg_Paint * scene,bool free)726 TVG_API Tvg_Result tvg_scene_clear(Tvg_Paint* scene, bool free)
727 {
728 if (!scene) return TVG_RESULT_INVALID_ARGUMENT;
729 return (Tvg_Result) reinterpret_cast<Scene*>(scene)->clear(free);
730 }
731
732
733 /************************************************************************/
734 /* Text API */
735 /************************************************************************/
736
tvg_text_new()737 TVG_API Tvg_Paint* tvg_text_new()
738 {
739 return (Tvg_Paint*)Text::gen().release();
740 }
741
742
tvg_text_set_font(Tvg_Paint * paint,const char * name,float size,const char * style)743 TVG_API Tvg_Result tvg_text_set_font(Tvg_Paint* paint, const char* name, float size, const char* style)
744 {
745 if (!paint) return TVG_RESULT_INVALID_ARGUMENT;
746 return (Tvg_Result) reinterpret_cast<Text*>(paint)->font(name, size, style);
747 }
748
749
tvg_text_set_text(Tvg_Paint * paint,const char * text)750 TVG_API Tvg_Result tvg_text_set_text(Tvg_Paint* paint, const char* text)
751 {
752 if (!paint) return TVG_RESULT_INVALID_ARGUMENT;
753 return (Tvg_Result) reinterpret_cast<Text*>(paint)->text(text);
754 }
755
756
tvg_text_set_fill_color(Tvg_Paint * paint,uint8_t r,uint8_t g,uint8_t b)757 TVG_API Tvg_Result tvg_text_set_fill_color(Tvg_Paint* paint, uint8_t r, uint8_t g, uint8_t b)
758 {
759 if (!paint) return TVG_RESULT_INVALID_ARGUMENT;
760 return (Tvg_Result) reinterpret_cast<Text*>(paint)->fill(r, g, b);
761 }
762
763
tvg_text_set_gradient(Tvg_Paint * paint,Tvg_Gradient * gradient)764 TVG_API Tvg_Result tvg_text_set_gradient(Tvg_Paint* paint, Tvg_Gradient* gradient)
765 {
766 if (!paint) return TVG_RESULT_INVALID_ARGUMENT;
767 return (Tvg_Result) reinterpret_cast<Text*>(paint)->fill(unique_ptr<Fill>((Fill*)(gradient)));
768 }
769
770
tvg_font_load(const char * path)771 TVG_API Tvg_Result tvg_font_load(const char* path)
772 {
773 return (Tvg_Result) Text::load(path);
774 }
775
776
tvg_font_load_data(const char * name,const char * data,uint32_t size,const char * mimetype,bool copy)777 TVG_API Tvg_Result tvg_font_load_data(const char* name, const char* data, uint32_t size, const char *mimetype, bool copy)
778 {
779 return (Tvg_Result) Text::load(name, data, size, mimetype ? mimetype : "", copy);
780 }
781
782
tvg_font_unload(const char * path)783 TVG_API Tvg_Result tvg_font_unload(const char* path)
784 {
785 return (Tvg_Result) Text::unload(path);
786 }
787
788
789 /************************************************************************/
790 /* Saver API */
791 /************************************************************************/
792
tvg_saver_new()793 TVG_API Tvg_Saver* tvg_saver_new()
794 {
795 return (Tvg_Saver*) Saver::gen().release();
796 }
797
798
tvg_saver_save(Tvg_Saver * saver,Tvg_Paint * paint,const char * path,bool compress)799 TVG_API Tvg_Result tvg_saver_save(Tvg_Saver* saver, Tvg_Paint* paint, const char* path, bool compress)
800 {
801 if (!saver || !paint || !path) return TVG_RESULT_INVALID_ARGUMENT;
802 return (Tvg_Result) reinterpret_cast<Saver*>(saver)->save(unique_ptr<Paint>((Paint*)paint), path, compress);
803 }
804
805
tvg_saver_sync(Tvg_Saver * saver)806 TVG_API Tvg_Result tvg_saver_sync(Tvg_Saver* saver)
807 {
808 if (!saver) return TVG_RESULT_INVALID_ARGUMENT;
809 return (Tvg_Result) reinterpret_cast<Saver*>(saver)->sync();
810 }
811
812
tvg_saver_del(Tvg_Saver * saver)813 TVG_API Tvg_Result tvg_saver_del(Tvg_Saver* saver)
814 {
815 if (!saver) return TVG_RESULT_INVALID_ARGUMENT;
816 delete(reinterpret_cast<Saver*>(saver));
817 return TVG_RESULT_SUCCESS;
818 }
819
820
821 /************************************************************************/
822 /* Animation API */
823 /************************************************************************/
824
tvg_animation_new()825 TVG_API Tvg_Animation* tvg_animation_new()
826 {
827 return (Tvg_Animation*) Animation::gen().release();
828 }
829
830
tvg_animation_set_frame(Tvg_Animation * animation,float no)831 TVG_API Tvg_Result tvg_animation_set_frame(Tvg_Animation* animation, float no)
832 {
833 if (!animation) return TVG_RESULT_INVALID_ARGUMENT;
834 return (Tvg_Result) reinterpret_cast<Animation*>(animation)->frame(no);
835 }
836
837
tvg_animation_get_frame(Tvg_Animation * animation,float * no)838 TVG_API Tvg_Result tvg_animation_get_frame(Tvg_Animation* animation, float* no)
839 {
840 if (!animation || !no) return TVG_RESULT_INVALID_ARGUMENT;
841 *no = reinterpret_cast<Animation*>(animation)->curFrame();
842 return TVG_RESULT_SUCCESS;
843 }
844
845
tvg_animation_get_total_frame(Tvg_Animation * animation,float * cnt)846 TVG_API Tvg_Result tvg_animation_get_total_frame(Tvg_Animation* animation, float* cnt)
847 {
848 if (!animation || !cnt) return TVG_RESULT_INVALID_ARGUMENT;
849 *cnt = reinterpret_cast<Animation*>(animation)->totalFrame();
850 return TVG_RESULT_SUCCESS;
851 }
852
853
tvg_animation_get_picture(Tvg_Animation * animation)854 TVG_API Tvg_Paint* tvg_animation_get_picture(Tvg_Animation* animation)
855 {
856 if (!animation) return nullptr;
857 return (Tvg_Paint*) reinterpret_cast<Animation*>(animation)->picture();
858 }
859
860
tvg_animation_get_duration(Tvg_Animation * animation,float * duration)861 TVG_API Tvg_Result tvg_animation_get_duration(Tvg_Animation* animation, float* duration)
862 {
863 if (!animation || !duration) return TVG_RESULT_INVALID_ARGUMENT;
864 *duration = reinterpret_cast<Animation*>(animation)->duration();
865 return TVG_RESULT_SUCCESS;
866 }
867
868
tvg_animation_set_segment(Tvg_Animation * animation,float start,float end)869 TVG_API Tvg_Result tvg_animation_set_segment(Tvg_Animation* animation, float start, float end)
870 {
871 if (!animation) return TVG_RESULT_INVALID_ARGUMENT;
872 return (Tvg_Result) reinterpret_cast<Animation*>(animation)->segment(start, end);
873 }
874
875
tvg_animation_get_segment(Tvg_Animation * animation,float * start,float * end)876 TVG_API Tvg_Result tvg_animation_get_segment(Tvg_Animation* animation, float* start, float* end)
877 {
878 if (!animation) return TVG_RESULT_INVALID_ARGUMENT;
879 return (Tvg_Result) reinterpret_cast<Animation*>(animation)->segment(start, end);
880 }
881
882
tvg_animation_del(Tvg_Animation * animation)883 TVG_API Tvg_Result tvg_animation_del(Tvg_Animation* animation)
884 {
885 if (!animation) return TVG_RESULT_INVALID_ARGUMENT;
886 delete(reinterpret_cast<Animation*>(animation));
887 return TVG_RESULT_SUCCESS;
888 }
889
890
891 /************************************************************************/
892 /* Accessor API */
893 /************************************************************************/
894
tvg_accessor_generate_id(const char * name)895 TVG_API uint32_t tvg_accessor_generate_id(const char* name)
896 {
897 return Accessor::id(name);
898 }
899
900
901 /************************************************************************/
902 /* Lottie Animation API */
903 /************************************************************************/
904
tvg_lottie_animation_new()905 TVG_API Tvg_Animation* tvg_lottie_animation_new()
906 {
907 #ifdef THORVG_LOTTIE_LOADER_SUPPORT
908 return (Tvg_Animation*) LottieAnimation::gen().release();
909 #endif
910 return nullptr;
911 }
912
913
tvg_lottie_animation_override(Tvg_Animation * animation,const char * slot)914 TVG_API Tvg_Result tvg_lottie_animation_override(Tvg_Animation* animation, const char* slot)
915 {
916 #ifdef THORVG_LOTTIE_LOADER_SUPPORT
917 if (!animation) return TVG_RESULT_INVALID_ARGUMENT;
918 return (Tvg_Result) reinterpret_cast<LottieAnimation*>(animation)->override(slot);
919 #endif
920 return TVG_RESULT_NOT_SUPPORTED;
921 }
922
923
tvg_lottie_animation_set_marker(Tvg_Animation * animation,const char * marker)924 TVG_API Tvg_Result tvg_lottie_animation_set_marker(Tvg_Animation* animation, const char* marker)
925 {
926 #ifdef THORVG_LOTTIE_LOADER_SUPPORT
927 if (!animation) return TVG_RESULT_INVALID_ARGUMENT;
928 return (Tvg_Result) reinterpret_cast<LottieAnimation*>(animation)->segment(marker);
929 #endif
930 return TVG_RESULT_NOT_SUPPORTED;
931 }
932
933
tvg_lottie_animation_get_markers_cnt(Tvg_Animation * animation,uint32_t * cnt)934 TVG_API Tvg_Result tvg_lottie_animation_get_markers_cnt(Tvg_Animation* animation, uint32_t* cnt)
935 {
936 #ifdef THORVG_LOTTIE_LOADER_SUPPORT
937 if (!animation || !cnt) return TVG_RESULT_INVALID_ARGUMENT;
938 *cnt = reinterpret_cast<LottieAnimation*>(animation)->markersCnt();
939 return TVG_RESULT_SUCCESS;
940 #endif
941 return TVG_RESULT_NOT_SUPPORTED;
942 }
943
944
tvg_lottie_animation_get_marker(Tvg_Animation * animation,uint32_t idx,const char ** name)945 TVG_API Tvg_Result tvg_lottie_animation_get_marker(Tvg_Animation* animation, uint32_t idx, const char** name)
946 {
947 #ifdef THORVG_LOTTIE_LOADER_SUPPORT
948 if (!animation || !name) return TVG_RESULT_INVALID_ARGUMENT;
949 *name = reinterpret_cast<LottieAnimation*>(animation)->marker(idx);
950 if (!(*name)) return TVG_RESULT_INVALID_ARGUMENT;
951 return TVG_RESULT_SUCCESS;
952 #endif
953 return TVG_RESULT_NOT_SUPPORTED;
954 }
955
956 #ifdef __cplusplus
957 }
958 #endif
959
960 #endif /* LV_USE_THORVG_INTERNAL */
961
962