7e3d7753b503b04c733f4a10755373fe8c7c712f
[platform/core/graphics/tizenvg.git] / test / testSvg.cpp
1 #include <vector>
2 #include "testCommon.h"
3
4 /************************************************************************/
5 /* Drawing Commands                                                     */
6 /************************************************************************/
7
8 #define NUM_PER_LINE 4
9 #define SIZE 200
10
11 static int count = 0;
12
13 static std::vector<unique_ptr<tvg::Picture>> pictures;
14
15 void svgDirCallback(const char* name, const char* path, void* data)
16 {
17     tvg::Canvas* canvas = static_cast<tvg::Canvas*>(data);
18
19     auto picture = tvg::Picture::gen();
20
21     char buf[PATH_MAX];
22     sprintf(buf,"%s/%s", path, name);
23
24     if (picture->load(buf) != tvg::Result::Success) return;
25
26     float x, y, w, h;
27     picture->viewbox(&x, &y, &w, &h);
28
29     float rate = (SIZE/(w > h ? w : h));
30     picture->scale(rate);
31
32     x *= rate;
33     y *= rate;
34     w *= rate;
35     h *= rate;
36
37     //Center Align ?
38     if (w > h) {
39          y -= (SIZE - h) * 0.5f;
40     } else {
41          x -= (SIZE - w) * 0.5f;
42     }
43
44     picture->translate((count % NUM_PER_LINE) * SIZE - x, SIZE * (count / NUM_PER_LINE) - y);
45
46     pictures.push_back(move(picture));
47
48     cout << "SVG: " << buf << endl;
49
50     count++;
51 }
52
53 void tvgDrawCmds(tvg::Canvas* canvas)
54 {
55     if (!canvas) return;
56
57     //Background
58     auto shape = tvg::Shape::gen();
59     shape->appendRect(0, 0, WIDTH, HEIGHT, 0, 0);    //x, y, w, h, rx, ry
60     shape->fill(255, 255, 255, 255);                 //r, g, b, a
61
62     if (canvas->push(move(shape)) != tvg::Result::Success) return;
63
64     eina_file_dir_list("./svgs", EINA_TRUE, svgDirCallback, canvas);
65
66     /* This showcase shows you asynchrounous loading of svg.
67        For this, pushing pictures at a certian sync time.
68        This means it earns the time to finish loading svg resources,
69        otherwise you can push pictures immediately. */
70     for (auto& paint : pictures) {
71         canvas->push(move(paint));
72     }
73
74     pictures.clear();
75 }
76
77
78 /************************************************************************/
79 /* Sw Engine Test Code                                                  */
80 /************************************************************************/
81
82 static unique_ptr<tvg::SwCanvas> swCanvas;
83
84 void tvgSwTest(uint32_t* buffer)
85 {
86     //Create a Canvas
87     swCanvas = tvg::SwCanvas::gen();
88     swCanvas->target(buffer, WIDTH, WIDTH, HEIGHT, tvg::SwCanvas::ARGB8888);
89
90     /* Push the shape into the Canvas drawing list
91        When this shape is into the canvas list, the shape could update & prepare
92        internal data asynchronously for coming rendering.
93        Canvas keeps this shape node unless user call canvas->clear() */
94     tvgDrawCmds(swCanvas.get());
95 }
96
97 void drawSwView(void* data, Eo* obj)
98 {
99     if (swCanvas->draw() == tvg::Result::Success) {
100         swCanvas->sync();
101     }
102 }
103
104
105 /************************************************************************/
106 /* GL Engine Test Code                                                  */
107 /************************************************************************/
108
109 static unique_ptr<tvg::GlCanvas> glCanvas;
110
111 void initGLview(Evas_Object *obj)
112 {
113     static constexpr auto BPP = 4;
114
115     //Create a Canvas
116     glCanvas = tvg::GlCanvas::gen();
117     glCanvas->target(nullptr, WIDTH * BPP, WIDTH, HEIGHT);
118
119     /* Push the shape into the Canvas drawing list
120        When this shape is into the canvas list, the shape could update & prepare
121        internal data asynchronously for coming rendering.
122        Canvas keeps this shape node unless user call canvas->clear() */
123     tvgDrawCmds(glCanvas.get());
124 }
125
126 void drawGLview(Evas_Object *obj)
127 {
128     auto gl = elm_glview_gl_api_get(obj);
129     gl->glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
130     gl->glClear(GL_COLOR_BUFFER_BIT);
131
132     if (glCanvas->draw() == tvg::Result::Success) {
133         glCanvas->sync();
134     }
135 }
136
137
138 /************************************************************************/
139 /* Main Code                                                            */
140 /************************************************************************/
141
142 int main(int argc, char **argv)
143 {
144     tvg::CanvasEngine tvgEngine = tvg::CanvasEngine::Sw;
145
146     if (argc > 1) {
147         if (!strcmp(argv[1], "gl")) tvgEngine = tvg::CanvasEngine::Gl;
148     }
149
150     //Initialize ThorVG Engine
151     if (tvgEngine == tvg::CanvasEngine::Sw) {
152         cout << "tvg engine: software" << endl;
153     } else {
154         cout << "tvg engine: opengl" << endl;
155     }
156
157     //Threads Count
158     auto threads = std::thread::hardware_concurrency();
159
160     //Initialize ThorVG Engine
161     if (tvg::Initializer::init(tvgEngine, threads) == tvg::Result::Success) {
162
163         elm_init(argc, argv);
164
165         if (tvgEngine == tvg::CanvasEngine::Sw) {
166             createSwView();
167         } else {
168             createGlView();
169         }
170
171         elm_run();
172         elm_shutdown();
173
174         //Terminate ThorVG Engine
175         tvg::Initializer::term(tvg::CanvasEngine::Sw);
176
177     } else {
178         cout << "engine is not supported" << endl;
179     }
180     return 0;
181 }