example boundary2: added image boundary check sample.
[platform/core/graphics/tizenvg.git] / src / examples / Capi.cpp
1 /*
2  * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. 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 <Elementary.h>
24 #include <thorvg_capi.h>
25
26 #define WIDTH 800
27 #define HEIGHT 800
28
29
30 /************************************************************************/
31 /* Capi Test Code                                                       */
32 /************************************************************************/
33
34 static uint32_t* buffer = NULL;
35 static Tvg_Canvas* canvas = NULL;
36 static Eo* view = NULL;
37
38 void testCapi()
39 {
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);
43
44     tvg_canvas_reserve(canvas, 6);
45
46 //////1. Linear gradient shape with a linear gradient stroke
47     //Set a shape
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);
53
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] =
58     {
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}
63     };
64     tvg_gradient_set_color_stops(grad1, color_stops1, 4);
65     tvg_gradient_set_spread(grad1, TVG_STROKE_FILL_REFLECT);
66
67     //Prepare a gradient for the stroke
68     Tvg_Gradient* grad1_stroke = tvg_gradient_duplicate(grad1);
69
70     //Set a gradient fill
71     tvg_shape_set_linear_gradient(shape1, grad1);
72
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);
77
78
79 //////2. Solid transformed shape
80     //Set a shape
81     const Tvg_Path_Command* cmds;
82     uint32_t cmdCnt;
83     const Tvg_Point* pts;
84     uint32_t ptsCnt;
85
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);
89
90     tvg_shape_append_path(shape2, cmds, cmdCnt, pts, ptsCnt);
91     tvg_shape_set_fill_color(shape2, 255, 255, 255, 128);
92
93     //Transform a shape
94     tvg_paint_scale(shape2, 0.3f);
95     tvg_paint_translate(shape2, 100.0f, 100.0f);
96
97
98     //Push shapes 1 and 2 into the canvas
99     tvg_canvas_push(canvas, shape1);
100     tvg_canvas_push(canvas, shape2);
101
102
103 //////3. Radial gradient shape with a radial dashed stroke
104     //Set a shape
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);
109
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] =
114     {
115         {0.0f, 255,   0, 255, 255},
116         {0.5f,   0,   0, 255, 255},
117         {1.0f,  50,  55, 155, 255}
118     };
119     tvg_gradient_set_color_stops(grad2, color_stops2, 3);
120     tvg_gradient_set_spread(grad2, TVG_STROKE_FILL_PAD);
121
122     //Set a gradient fill
123     tvg_shape_set_radial_gradient(shape3, grad2);
124
125     //Prepaer a radial gradient for the stroke
126     uint32_t cnt;
127     const Tvg_Color_Stop* color_stops2_get;
128     tvg_gradient_get_color_stops(grad2, &color_stops2_get, &cnt);
129
130     float cx, cy, radius;
131     tvg_radial_gradient_get(grad2, &cx, &cy, &radius);
132
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);
137
138     //Set a gradient stroke
139     tvg_shape_set_stroke_width(shape3, 30.0f);
140     tvg_shape_set_stroke_radial_gradient(shape3, grad2_stroke);
141
142     tvg_paint_set_opacity(shape3, 200);
143
144     //Push the shape into the canvas
145     tvg_canvas_push(canvas, shape3);
146
147
148 //////4. Scene
149     //Set a scene
150     Tvg_Paint* scene = tvg_scene_new();
151     tvg_scene_reserve(scene, 2);
152
153     //Set an arc
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);
158
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);
162
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);
169
170     //Transform a shape
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);
174
175     //Push the shapes into the scene
176     tvg_scene_push(scene, scene_shape1);
177     tvg_scene_push(scene, scene_shape2);
178
179     //Push the scene into the canvas
180     tvg_canvas_push(canvas, scene);
181
182
183 //////5. Masked picture
184     //Set a scene
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");
188         tvg_paint_del(pict);
189     } else {
190         float w, h;
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_set_transform(pict, &m);
195
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);
201
202         //Push the scene into the canvas
203         tvg_canvas_push(canvas, pict);
204     }
205
206
207 //////Save a paint
208     //Create a shape
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);
212
213     //Save the shape
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");
217     } else {
218       tvg_saver_sync(saver);
219     }
220     tvg_saver_del(saver);
221
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);
227     } else {
228         //Push the scene into the canvas
229         tvg_canvas_push(canvas, pict_tvg);
230     }
231
232 //////Draw the canvas
233     tvg_canvas_draw(canvas);
234     tvg_canvas_sync(canvas);
235 }
236
237
238 /************************************************************************/
239 /* Main Code                                                            */
240 /************************************************************************/
241
242 void win_del(void *data, Evas_Object *o, void *ev)
243 {
244    elm_exit();
245 }
246
247 void resize_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
248 {
249     int w = 0, h = 0;
250     evas_object_geometry_get(obj, NULL, NULL, &w, &h);
251
252     if ((w != WIDTH || h != HEIGHT) && (w != 0 && h != 0))
253     {
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);
257
258         tvg_canvas_update(canvas);
259         tvg_canvas_draw(canvas);
260         tvg_canvas_sync(canvas);
261
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);
266     }
267 }
268
269 int main(int argc, char **argv)
270 {
271     elm_init(argc, argv);
272     tvg_engine_init(Tvg_Engine(TVG_ENGINE_SW | TVG_ENGINE_GL), 0);
273
274     buffer = (uint32_t*)malloc(sizeof(uint32_t) * WIDTH * HEIGHT);
275
276     Eo* win = elm_win_util_standard_add(NULL, "ThorVG Test");
277
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);
280
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);
288
289     elm_win_resize_object_add(win, view);
290     evas_object_geometry_set(win, 0, 0, WIDTH, HEIGHT);
291     evas_object_show(win);
292
293     testCapi();
294
295     elm_run();
296
297     tvg_canvas_destroy(canvas);
298     free(buffer);
299     tvg_engine_term(Tvg_Engine(TVG_ENGINE_SW | TVG_ENGINE_GL));
300     elm_shutdown();
301
302     return 0;
303 }