2 * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
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:
11 * The above copyright notice and this permission notice shall be included in all
12 * copies or substantial portions of the Software.
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
23 #include <Elementary.h>
24 #include <thorvg_capi.h>
30 /************************************************************************/
32 /************************************************************************/
34 static uint32_t* buffer = NULL;
35 static Tvg_Canvas* canvas = NULL;
36 static Eo* view = NULL;
40 canvas = tvg_swcanvas_create();
41 tvg_swcanvas_set_target(canvas, buffer, WIDTH, WIDTH, HEIGHT, TVG_COLORSPACE_ARGB8888);
42 tvg_swcanvas_set_mempool(canvas, TVG_MEMPOOL_POLICY_DEFAULT);
44 tvg_canvas_reserve(canvas, 6);
46 //////1. Linear gradient shape with a linear gradient stroke
48 Tvg_Paint* shape1 = tvg_shape_new();
49 tvg_shape_move_to(shape1, 25.0f, 25.0f);
50 tvg_shape_line_to(shape1, 375.0f, 25.0f);
51 tvg_shape_cubic_to(shape1, 500.0f, 100.0f, -500.0f, 200.0f, 375.0f, 375.0f);
52 tvg_shape_close(shape1);
54 //Prepare a gradient for the fill
55 Tvg_Gradient* grad1 = tvg_linear_gradient_new();
56 tvg_linear_gradient_set(grad1, 25.0f, 25.0f, 200.0f, 200.0f);
57 Tvg_Color_Stop color_stops1[4] =
59 {0.00f, 255, 0, 0, 155},
60 {0.33f, 0, 255, 0, 100},
61 {0.66f, 255, 0, 255, 100},
62 {1.00f, 0, 0, 255, 155}
64 tvg_gradient_set_color_stops(grad1, color_stops1, 4);
65 tvg_gradient_set_spread(grad1, TVG_STROKE_FILL_REFLECT);
67 //Prepare a gradient for the stroke
68 Tvg_Gradient* grad1_stroke = tvg_gradient_duplicate(grad1);
71 tvg_shape_set_linear_gradient(shape1, grad1);
73 //Set a gradient stroke
74 tvg_shape_set_stroke_width(shape1, 20.0f);
75 tvg_shape_set_stroke_linear_gradient(shape1, grad1_stroke);
76 tvg_shape_set_stroke_join(shape1, TVG_STROKE_JOIN_ROUND);
79 //////2. Solid transformed shape
81 const Tvg_Path_Command* cmds;
86 Tvg_Paint* shape2 = tvg_shape_new();
87 tvg_shape_get_path_commands(shape1, &cmds, &cmdCnt);
88 tvg_shape_get_path_coords(shape1, &pts, &ptsCnt);
90 tvg_shape_append_path(shape2, cmds, cmdCnt, pts, ptsCnt);
91 tvg_shape_set_fill_color(shape2, 255, 255, 255, 128);
94 tvg_paint_scale(shape2, 0.3f);
95 tvg_paint_translate(shape2, 100.0f, 100.0f);
98 //Push shapes 1 and 2 into the canvas
99 tvg_canvas_push(canvas, shape1);
100 tvg_canvas_push(canvas, shape2);
103 //////3. Radial gradient shape with a radial dashed stroke
105 Tvg_Paint* shape3 = tvg_shape_new();
106 tvg_shape_append_rect(shape3, 550.0f, 20.0f, 100.0f, 50.0f, 0.0f, 0.0f);
107 tvg_shape_append_circle(shape3, 600.0f, 150.0f, 100.0f, 50.0f);
108 tvg_shape_append_rect(shape3, 550.0f, 230.0f, 100.0f, 100.0f, 20.0f, 40.0f);
110 //Prepare a radial gradient for the fill
111 Tvg_Gradient* grad2 = tvg_radial_gradient_new();
112 tvg_radial_gradient_set(grad2, 600.0f, 180.0f, 50.0f);
113 Tvg_Color_Stop color_stops2[3] =
115 {0.0f, 255, 0, 255, 255},
116 {0.5f, 0, 0, 255, 255},
117 {1.0f, 50, 55, 155, 255}
119 tvg_gradient_set_color_stops(grad2, color_stops2, 3);
120 tvg_gradient_set_spread(grad2, TVG_STROKE_FILL_PAD);
122 //Set a gradient fill
123 tvg_shape_set_radial_gradient(shape3, grad2);
125 //Prepaer a radial gradient for the stroke
127 const Tvg_Color_Stop* color_stops2_get;
128 tvg_gradient_get_color_stops(grad2, &color_stops2_get, &cnt);
130 float cx, cy, radius;
131 tvg_radial_gradient_get(grad2, &cx, &cy, &radius);
133 Tvg_Gradient* grad2_stroke = tvg_radial_gradient_new();
134 tvg_radial_gradient_set(grad2_stroke, cx, cy, radius);
135 tvg_gradient_set_color_stops(grad2_stroke, color_stops2_get, cnt);
136 tvg_gradient_set_spread(grad2_stroke, TVG_STROKE_FILL_REPEAT);
138 //Set a gradient stroke
139 tvg_shape_set_stroke_width(shape3, 30.0f);
140 tvg_shape_set_stroke_radial_gradient(shape3, grad2_stroke);
142 tvg_paint_set_opacity(shape3, 200);
144 //Push the shape into the canvas
145 tvg_canvas_push(canvas, shape3);
150 Tvg_Paint* scene = tvg_scene_new();
151 tvg_scene_reserve(scene, 2);
154 Tvg_Paint* scene_shape1 = tvg_shape_new();
155 tvg_shape_append_arc(scene_shape1, 175.0f, 600.0f, 150.0f, -45.0f, 90.0f, 1);
156 tvg_shape_append_arc(scene_shape1, 175.0f, 600.0f, 150.0f, 225.0f, -90.0f, 1);
157 tvg_shape_set_fill_color(scene_shape1, 0, 0, 255, 150);
159 //Set an arc with a dashed stroke
160 Tvg_Paint* scene_shape2 = tvg_paint_duplicate(scene_shape1);
161 tvg_shape_set_fill_color(scene_shape2, 75, 25, 155, 200);
163 //Prapare a dash for the stroke
164 float dashPattern[4] = {15.0f, 30.0f, 2.0f, 30.0f};
165 tvg_shape_set_stroke_dash(scene_shape2, dashPattern, 4);
166 tvg_shape_set_stroke_cap(scene_shape2, TVG_STROKE_CAP_ROUND);
167 tvg_shape_set_stroke_color(scene_shape2, 0, 0, 255, 255);
168 tvg_shape_set_stroke_width(scene_shape2, 15.0f);
171 tvg_paint_scale(scene_shape2, 0.7f);
172 tvg_paint_rotate(scene_shape2, -90.0f);
173 tvg_paint_translate(scene_shape2, -245.0f, 722.0f);
175 //Push the shapes into the scene
176 tvg_scene_push(scene, scene_shape1);
177 tvg_scene_push(scene, scene_shape2);
179 //Push the scene into the canvas
180 tvg_canvas_push(canvas, scene);
183 //////5. Masked picture
185 Tvg_Paint* pict = tvg_picture_new();
186 if (tvg_picture_load(pict, EXAMPLE_DIR"/tiger.svg") != TVG_RESULT_SUCCESS) {
187 printf("Problem with loading an svg file\n");
191 tvg_picture_get_size(pict, &w, &h);
192 tvg_picture_set_size(pict, w/2, h/2);
193 Tvg_Matrix m = {0.8f, 0.0f, 400.0f, 0.0f, 0.8f, 400.0f, 0.0f, 0.0f, 1.0f};
194 tvg_paint_transform(pict, &m);
196 // Set a composite shape
197 Tvg_Paint* comp = tvg_shape_new();
198 tvg_shape_append_circle(comp, 600.0f, 600.0f, 100.0f, 100.0f);
199 tvg_shape_set_fill_color(comp, 0, 0, 0, 200);
200 tvg_paint_set_composite_method(pict, comp, TVG_COMPOSITE_METHOD_INVERSE_ALPHA_MASK);
202 //Push the scene into the canvas
203 tvg_canvas_push(canvas, pict);
209 Tvg_Paint* shape = tvg_shape_new();
210 tvg_shape_append_circle(shape, 420.0f, 420.0f, 10.0f, 10.0f);
211 tvg_shape_set_fill_color(shape, 0, 255, 0, 200);
214 Tvg_Saver* saver = tvg_saver_new();
215 if (tvg_saver_save(saver, shape, EXAMPLE_DIR"/capi_test.tvg", true) != TVG_RESULT_SUCCESS) {
216 printf("Problem with saving a tvg file\n");
218 tvg_saver_sync(saver);
220 tvg_saver_del(saver);
222 //Load the saved paint
223 Tvg_Paint* pict_tvg = tvg_picture_new();
224 if (tvg_picture_load(pict_tvg, EXAMPLE_DIR"/capi_test.tvg") != TVG_RESULT_SUCCESS) {
225 printf("Problem with loading a tvg file\n");
226 tvg_paint_del(pict_tvg);
228 //Push the scene into the canvas
229 tvg_canvas_push(canvas, pict_tvg);
232 //////Draw the canvas
233 tvg_canvas_draw(canvas);
234 tvg_canvas_sync(canvas);
238 /************************************************************************/
240 /************************************************************************/
242 void win_del(void *data, Evas_Object *o, void *ev)
247 void resize_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
250 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
252 if ((w != WIDTH || h != HEIGHT) && (w != 0 && h != 0))
254 evas_object_image_data_set(view, NULL); //prevent evas scale on invalid buffer by rendering thread
255 buffer = (uint32_t*) realloc(buffer, sizeof(uint32_t) * w * h);
256 tvg_swcanvas_set_target(canvas, buffer, w, w, h, TVG_COLORSPACE_ARGB8888);
258 tvg_canvas_update(canvas);
259 tvg_canvas_draw(canvas);
260 tvg_canvas_sync(canvas);
262 evas_object_image_size_set(view, w, h);
263 evas_object_image_data_set(view, buffer);
264 evas_object_image_pixels_dirty_set(view, EINA_TRUE);
265 evas_object_image_data_update_add(view, 0, 0, w, h);
269 int main(int argc, char **argv)
271 elm_init(argc, argv);
272 tvg_engine_init(Tvg_Engine(TVG_ENGINE_SW | TVG_ENGINE_GL), 0);
274 buffer = (uint32_t*)malloc(sizeof(uint32_t) * WIDTH * HEIGHT);
276 Eo* win = elm_win_util_standard_add(NULL, "ThorVG Test");
278 evas_object_smart_callback_add(win, "delete,request", win_del, 0);
279 evas_object_event_callback_add(win, EVAS_CALLBACK_RESIZE, resize_cb, 0);
281 view = evas_object_image_filled_add(evas_object_evas_get(win));
282 evas_object_image_size_set(view, WIDTH, HEIGHT);
283 evas_object_image_data_set(view, buffer);
284 evas_object_image_pixels_dirty_set(view, EINA_TRUE);
285 evas_object_image_data_update_add(view, 0, 0, WIDTH, HEIGHT);
286 evas_object_size_hint_weight_set(view, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
287 evas_object_show(view);
289 elm_win_resize_object_add(win, view);
290 evas_object_geometry_set(win, 0, 0, WIDTH, HEIGHT);
291 evas_object_show(win);
297 tvg_canvas_destroy(canvas);
299 tvg_engine_term(Tvg_Engine(TVG_ENGINE_SW | TVG_ENGINE_GL));