bindings/capi: fix c compatibility warnings.
[platform/core/graphics/tizenvg.git] / src / examples / testMultiCanvas.cpp
1 #include <iostream>
2 #include <thread>
3 #include <vector>
4 #include <Elementary.h>
5 #include <thorvg.h>
6
7 using namespace std;
8
9 /************************************************************************/
10 /* Drawing Commands                                                     */
11 /************************************************************************/
12 #define WIDTH 800
13 #define HEIGHT 800
14 #define NUM_PER_LINE 4
15 #define SIZE 200
16
17 static size_t count = 0;
18 static std::vector<unique_ptr<tvg::Canvas>> canvases;
19
20
21 void win_del(void *data, Evas_Object *o, void* ev)
22 {
23    elm_exit();
24 }
25
26
27 void tvgDrawCmds(tvg::Canvas* canvas, const char* path, const char* name)
28 {
29     auto picture = tvg::Picture::gen();
30
31     char buf[PATH_MAX];
32     sprintf(buf,"%s/%s", path, name);
33
34     if (picture->load(buf) != tvg::Result::Success) return;
35
36     float x, y, w, h;
37     picture->viewbox(&x, &y, &w, &h);
38
39     float rate = (SIZE/(w > h ? w : h));
40     picture->scale(rate);
41
42     x *= rate;
43     y *= rate;
44     w *= rate;
45     h *= rate;
46
47     //Center Align ?
48     if (w > h) {
49         y -= (SIZE - h) * 0.5f;
50     } else {
51         x -= (SIZE - w) * 0.5f;
52     }
53     picture->translate(-x, -y);
54
55     if (canvas->push(move(picture)) != tvg::Result::Success) return;
56
57     cout << "SVG: " << buf << endl;
58
59     count++;
60 }
61
62
63 /************************************************************************/
64 /* Sw Engine Test Code                                                  */
65 /************************************************************************/
66
67 void sw_del(void* data, Evas* evas, Eo* obj, void* ev)
68 {
69     auto buffer = (uint32_t*) data;
70     free(buffer);
71 }
72
73
74 void drawSwView(void* data, Eo* obj)
75 {
76     auto i = reinterpret_cast<size_t>(data);
77     auto& canvas = canvases[i];
78
79     if (canvas->draw() == tvg::Result::Success) {
80         canvas->sync();
81     }
82 }
83
84
85 void tvgSwTest(const char* name, const char* path, void* data)
86 {
87     Eo* win = (Eo*) data;
88
89     uint32_t* buffer = (uint32_t*) calloc(sizeof(uint32_t), SIZE * SIZE);
90
91     Eo* view = evas_object_image_filled_add(evas_object_evas_get(win));
92     evas_object_image_size_set(view, SIZE, SIZE);
93     evas_object_image_data_set(view, buffer);
94     evas_object_image_pixels_dirty_set(view, EINA_TRUE);
95     evas_object_image_data_update_add(view, 0, 0, SIZE, SIZE);
96     evas_object_image_alpha_set(view, EINA_TRUE);
97     evas_object_image_pixels_get_callback_set(view, drawSwView, reinterpret_cast<void*>(count));
98     evas_object_event_callback_add(view, EVAS_CALLBACK_DEL, sw_del, buffer);
99     evas_object_resize(view, SIZE, SIZE);
100     evas_object_move(view, (count % NUM_PER_LINE) * SIZE, SIZE * (count / NUM_PER_LINE));
101     evas_object_show(view);
102
103     //Create a Canvas
104     auto canvas = tvg::SwCanvas::gen();
105     canvas->target(buffer, SIZE, SIZE, SIZE, tvg::SwCanvas::ARGB8888);
106
107     tvgDrawCmds(canvas.get(), path, name);
108
109     canvases.push_back(move(canvas));    
110 }
111
112
113 /************************************************************************/
114 /* GL Engine Test Code                                                  */
115 /************************************************************************/
116
117 struct ObjData
118 {
119     char* path;
120     char* name;
121     int idx;
122 };
123
124 void gl_del(void* data, Evas* evas, Eo* obj, void* ev)
125 {
126     auto objData = (ObjData*) data;
127     delete(objData);
128 }
129
130 void initGLview(Evas_Object *obj)
131 {
132     auto objData = reinterpret_cast<ObjData*>(evas_object_data_get(obj, "objdata"));
133     objData->idx = count;
134
135     static constexpr auto BPP = 4;
136
137     //Create a Canvas
138     auto canvas = tvg::GlCanvas::gen();
139     canvas->target(nullptr, SIZE * BPP, SIZE, SIZE);
140
141     /* Push the shape into the Canvas drawing list
142        When this shape is into the canvas list, the shape could update & prepare
143        internal data asynchronously for coming rendering.
144        Canvas keeps this shape node unless user call canvas->clear() */
145     tvgDrawCmds(canvas.get(), objData->path, objData->name);
146
147     canvases.push_back(move(canvas));
148 }
149
150
151 void drawGLview(Evas_Object *obj)
152 {
153     auto gl = elm_glview_gl_api_get(obj);
154     gl->glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
155     gl->glClear(GL_COLOR_BUFFER_BIT);
156
157     auto objData = reinterpret_cast<ObjData*>(evas_object_data_get(obj, "objdata"));
158     auto& canvas = canvases[objData->idx];
159
160     if (canvas->draw() == tvg::Result::Success) {
161         canvas->sync();
162     }
163 }
164
165
166 void tvgGlTest(const char* name, const char* path, void* data)
167 {
168     auto objData = new ObjData;
169     objData->name = strdup(name);
170     objData->path = strdup(path);
171
172     Eo* win = (Eo*) data;   
173
174     Eo* view = elm_glview_add(win);
175     elm_glview_mode_set(view, ELM_GLVIEW_ALPHA);
176     elm_glview_resize_policy_set(view, ELM_GLVIEW_RESIZE_POLICY_RECREATE);
177     elm_glview_render_policy_set(view, ELM_GLVIEW_RENDER_POLICY_ON_DEMAND);
178     elm_glview_init_func_set(view, initGLview);
179     elm_glview_render_func_set(view, drawGLview);
180     evas_object_data_set(view, "objdata", reinterpret_cast<void*>(objData));
181     evas_object_event_callback_add(view, EVAS_CALLBACK_DEL, gl_del, objData);
182     evas_object_resize(view, SIZE, SIZE);
183     evas_object_move(view, (count % NUM_PER_LINE) * SIZE, SIZE * (count / NUM_PER_LINE)); 
184     evas_object_show(view);
185 }
186
187
188 /************************************************************************/
189 /* Main Code                                                            */
190 /************************************************************************/
191
192 int main(int argc, char **argv)
193 {
194     tvg::CanvasEngine tvgEngine = tvg::CanvasEngine::Sw;
195
196     if (argc > 1) {
197         if (!strcmp(argv[1], "gl")) tvgEngine = tvg::CanvasEngine::Gl;
198     }
199
200     //Initialize ThorVG Engine
201     if (tvgEngine == tvg::CanvasEngine::Sw) {
202         cout << "tvg engine: software" << endl;
203     } else {
204         cout << "tvg engine: opengl" << endl;
205     }
206
207     //Threads Count
208     auto threads = std::thread::hardware_concurrency();
209
210     //Initialize ThorVG Engine
211     if (tvg::Initializer::init(tvgEngine, threads) == tvg::Result::Success) {
212
213         elm_init(argc, argv);
214
215         Eo* win = elm_win_util_standard_add(NULL, "ThorVG Test");
216         evas_object_smart_callback_add(win, "delete,request", win_del, 0);
217
218         if (tvgEngine == tvg::CanvasEngine::Sw) {
219             eina_file_dir_list(EXAMPLE_DIR, EINA_TRUE, tvgSwTest, win);
220         } else {
221             eina_file_dir_list(EXAMPLE_DIR, EINA_TRUE, tvgGlTest, win);
222         }
223
224         evas_object_geometry_set(win, 0, 0, WIDTH, HEIGHT);
225         evas_object_show(win);
226
227         elm_run();
228         elm_shutdown();
229
230         //Terminate ThorVG Engine
231         tvg::Initializer::term(tvg::CanvasEngine::Sw);
232
233     } else {
234         cout << "engine is not supported" << endl;
235     }
236     return 0;
237 }