6cd9be6766969570fdc6e5efa7e384ae0eecb4f5
[platform/core/graphics/tizenvg.git] / test / testTransform.cpp
1 #include "testCommon.h"
2
3 /************************************************************************/
4 /* Drawing Commands                                                     */
5 /************************************************************************/
6 tvg::Shape* pShape = nullptr;
7 tvg::Shape* pShape2 = nullptr;
8 tvg::Shape* pShape3 = nullptr;
9
10 void tvgDrawCmds(tvg::Canvas* canvas)
11 {
12     if (!canvas) return;
13
14     //Shape1
15     auto shape = tvg::Shape::gen();
16
17     /* Acquire shape pointer to access it again.
18        instead, you should consider not to interrupt this pointer life-cycle. */
19     pShape = shape.get();
20
21     shape->appendRect(-285, -300, 200, 200, 0, 0);
22     shape->appendRect(-185, -200, 300, 300, 100, 100);
23     shape->appendCircle(115, 100, 100, 100);
24     shape->appendCircle(115, 200, 170, 100);
25     shape->fill(255, 255, 255, 255);
26     shape->translate(385, 400);
27     if (canvas->push(move(shape)) != tvg::Result::Success) return;
28
29     //Shape2
30     auto shape2 = tvg::Shape::gen();
31     pShape2 = shape2.get();
32     shape2->appendRect(-50, -50, 100, 100, 0, 0);
33     shape2->fill(0, 255, 255, 255);
34     shape2->translate(400, 400);
35     if (canvas->push(move(shape2)) != tvg::Result::Success) return;
36
37     //Shape3
38     auto shape3 = tvg::Shape::gen();
39     pShape3 = shape3.get();
40
41     /* Look, how shape3's origin is different with shape2
42        The center of the shape is the anchor point for transformation. */
43     shape3->appendRect(100, 100, 150, 50, 20, 20);
44     shape3->fill(255, 0, 255, 255);
45     shape3->translate(400, 400);
46     if (canvas->push(move(shape3)) != tvg::Result::Success) return;
47 }
48
49 void tvgUpdateCmds(tvg::Canvas* canvas, float progress)
50 {
51     if (!canvas) return;
52
53     /* Update shape directly.
54        You can update only necessary properties of this shape,
55        while retaining other properties. */
56
57     //Update Shape1
58     pShape->scale(1 - 0.75 * progress);
59     pShape->rotate(360 * progress);
60
61     //Update shape for drawing (this may work asynchronously)
62     if (canvas->update(pShape) != tvg::Result::Success) return;
63
64     //Update Shape2
65     pShape2->rotate(360 * progress);
66     pShape2->translate(400 + progress * 300, 400);
67     if (canvas->update(pShape2) != tvg::Result::Success) return;
68
69     //Update Shape3
70     pShape3->rotate(-360 * progress);
71     pShape3->scale(0.5 + progress);
72     if (canvas->update(pShape3) != tvg::Result::Success) return;
73 }
74
75
76 /************************************************************************/
77 /* Sw Engine Test Code                                                  */
78 /************************************************************************/
79
80 static unique_ptr<tvg::SwCanvas> swCanvas;
81
82 void tvgSwTest(uint32_t* buffer)
83 {
84     //Create a Canvas
85     swCanvas = tvg::SwCanvas::gen();
86     swCanvas->target(buffer, WIDTH, WIDTH, HEIGHT, tvg::SwCanvas::ARGB8888);
87
88     /* Push the shape into the Canvas drawing list
89        When this shape is into the canvas list, the shape could update & prepare
90        internal data asynchronously for coming rendering.
91        Canvas keeps this shape node unless user call canvas->clear() */
92     tvgDrawCmds(swCanvas.get());
93 }
94
95 void transitSwCb(Elm_Transit_Effect *effect, Elm_Transit* transit, double progress)
96 {
97     tvgUpdateCmds(swCanvas.get(), progress);
98
99     //Update Efl Canvas
100     Eo* img = (Eo*) effect;
101     evas_object_image_data_update_add(img, 0, 0, WIDTH, HEIGHT);
102     evas_object_image_pixels_dirty_set(img, EINA_TRUE);
103 }
104
105 void drawSwView(void* data, Eo* obj)
106 {
107     if (swCanvas->draw() == tvg::Result::Success) {
108         swCanvas->sync();
109     }
110 }
111
112
113 /************************************************************************/
114 /* GL Engine Test Code                                                  */
115 /************************************************************************/
116
117 static unique_ptr<tvg::GlCanvas> glCanvas;
118
119 void initGLview(Evas_Object *obj)
120 {
121     static constexpr auto BPP = 4;
122
123     //Create a Canvas
124     glCanvas = tvg::GlCanvas::gen();
125     glCanvas->target(nullptr, WIDTH * BPP, WIDTH, HEIGHT);
126
127     /* Push the shape into the Canvas drawing list
128        When this shape is into the canvas list, the shape could update & prepare
129        internal data asynchronously for coming rendering.
130        Canvas keeps this shape node unless user call canvas->clear() */
131     tvgDrawCmds(glCanvas.get());
132 }
133
134 void drawGLview(Evas_Object *obj)
135 {
136     auto gl = elm_glview_gl_api_get(obj);
137     gl->glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
138     gl->glClear(GL_COLOR_BUFFER_BIT);
139
140     if (glCanvas->draw() == tvg::Result::Success) {
141         glCanvas->sync();
142     }
143 }
144
145 void transitGlCb(Elm_Transit_Effect *effect, Elm_Transit* transit, double progress)
146 {
147     tvgUpdateCmds(glCanvas.get(), progress);
148 }
149
150
151 /************************************************************************/
152 /* Main Code                                                            */
153 /************************************************************************/
154
155 int main(int argc, char **argv)
156 {
157     tvg::CanvasEngine tvgEngine = tvg::CanvasEngine::Sw;
158
159     if (argc > 1) {
160         if (!strcmp(argv[1], "gl")) tvgEngine = tvg::CanvasEngine::Gl;
161     }
162
163     //Initialize ThorVG Engine
164     if (tvgEngine == tvg::CanvasEngine::Sw) {
165         cout << "tvg engine: software" << endl;
166     } else {
167         cout << "tvg engine: opengl" << endl;
168     }
169
170     //Threads Count
171     auto threads = std::thread::hardware_concurrency();
172
173     //Initialize ThorVG Engine
174     if (tvg::Initializer::init(tvgEngine, threads) == tvg::Result::Success) {
175
176         elm_init(argc, argv);
177
178         Elm_Transit *transit = elm_transit_add();
179
180         if (tvgEngine == tvg::CanvasEngine::Sw) {
181             auto view = createSwView();
182             elm_transit_effect_add(transit, transitSwCb, view, nullptr);
183         } else {
184             auto view = createGlView();
185             elm_transit_effect_add(transit, transitGlCb, view, nullptr);
186         }
187
188         elm_transit_duration_set(transit, 2);
189         elm_transit_repeat_times_set(transit, -1);
190         elm_transit_auto_reverse_set(transit, EINA_TRUE);
191         elm_transit_go(transit);
192
193         elm_run();
194         elm_shutdown();
195
196         //Terminate ThorVG Engine
197         tvg::Initializer::term(tvgEngine);
198
199     } else {
200         cout << "engine is not supported" << endl;
201     }
202     return 0;
203 }