2 * Copyright (c) 2020 - 2023 the ThorVG project. 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
25 /************************************************************************/
26 /* Drawing Commands */
27 /************************************************************************/
29 void tvgDrawCmds(tvg::Canvas* canvas)
33 canvas->reserve(3); //reserve 3 shape nodes (optional)
35 //Prepare Round Rectangle
36 auto shape1 = tvg::Shape::gen();
37 shape1->appendRect(0, 0, 400, 400, 0, 0); //x, y, w, h, rx, ry
40 auto fill = tvg::LinearGradient::gen();
41 fill->linear(0, 0, 400, 400);
43 //Gradient Color Stops
44 tvg::Fill::ColorStop colorStops[2];
45 colorStops[0] = {0, 0, 0, 0, 255};
46 colorStops[1] = {1, 255, 255, 255, 255};
48 fill->colorStops(colorStops, 2);
50 shape1->fill(move(fill));
51 if (canvas->push(move(shape1)) != tvg::Result::Success) return;
54 auto shape2 = tvg::Shape::gen();
55 shape2->appendCircle(400, 400, 200, 200); //cx, cy, radiusW, radiusH
58 auto fill2 = tvg::LinearGradient::gen();
59 fill2->linear(400, 200, 400, 600);
61 //Gradient Color Stops
62 tvg::Fill::ColorStop colorStops2[3];
63 colorStops2[0] = {0, 255, 0, 0, 255};
64 colorStops2[1] = {0.5, 255, 255, 0, 255};
65 colorStops2[2] = {1, 255, 255, 255, 255};
67 fill2->colorStops(colorStops2, 3);
69 shape2->fill(move(fill2));
70 if (canvas->push(move(shape2)) != tvg::Result::Success) return;
74 auto shape3 = tvg::Shape::gen();
75 shape3->appendCircle(600, 600, 150, 100); //cx, cy, radiusW, radiusH
78 auto fill3 = tvg::LinearGradient::gen();
79 fill3->linear(450, 600, 750, 600);
81 //Gradient Color Stops
82 tvg::Fill::ColorStop colorStops3[4];
83 colorStops3[0] = {0, 0, 127, 0, 127};
84 colorStops3[1] = {0.25, 0, 170, 170, 170};
85 colorStops3[2] = {0.5, 200, 0, 200, 200};
86 colorStops3[3] = {1, 255, 255, 255, 255};
88 fill3->colorStops(colorStops3, 4);
90 shape3->fill(move(fill3));
91 if (canvas->push(move(shape3)) != tvg::Result::Success) return;
95 /************************************************************************/
96 /* Sw Engine Test Code */
97 /************************************************************************/
99 static unique_ptr<tvg::SwCanvas> swCanvas;
101 void tvgSwTest(uint32_t* buffer)
104 swCanvas = tvg::SwCanvas::gen();
105 swCanvas->target(buffer, WIDTH, WIDTH, HEIGHT, tvg::SwCanvas::ARGB8888);
107 /* Push the shape into the Canvas drawing list
108 When this shape is into the canvas list, the shape could update & prepare
109 internal data asynchronously for coming rendering.
110 Canvas keeps this shape node unless user call canvas->clear() */
111 tvgDrawCmds(swCanvas.get());
114 void drawSwView(void* data, Eo* obj)
116 if (swCanvas->draw() == tvg::Result::Success) {
122 /************************************************************************/
123 /* GL Engine Test Code */
124 /************************************************************************/
126 static unique_ptr<tvg::GlCanvas> glCanvas;
128 void initGLview(Evas_Object *obj)
130 static constexpr auto BPP = 4;
133 glCanvas = tvg::GlCanvas::gen();
134 glCanvas->target(nullptr, WIDTH * BPP, WIDTH, HEIGHT);
136 /* Push the shape into the Canvas drawing list
137 When this shape is into the canvas list, the shape could update & prepare
138 internal data asynchronously for coming rendering.
139 Canvas keeps this shape node unless user call canvas->clear() */
140 tvgDrawCmds(glCanvas.get());
143 void drawGLview(Evas_Object *obj)
145 auto gl = elm_glview_gl_api_get(obj);
146 gl->glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
147 gl->glClear(GL_COLOR_BUFFER_BIT);
149 if (glCanvas->draw() == tvg::Result::Success) {
155 /************************************************************************/
157 /************************************************************************/
159 int main(int argc, char **argv)
161 tvg::CanvasEngine tvgEngine = tvg::CanvasEngine::Sw;
164 if (!strcmp(argv[1], "gl")) tvgEngine = tvg::CanvasEngine::Gl;
167 //Initialize ThorVG Engine
168 if (tvgEngine == tvg::CanvasEngine::Sw) {
169 cout << "tvg engine: software" << endl;
171 cout << "tvg engine: opengl" << endl;
175 auto threads = std::thread::hardware_concurrency();
176 if (threads > 0) --threads; //Allow the designated main thread capacity
178 //Initialize ThorVG Engine
179 if (tvg::Initializer::init(tvgEngine, threads) == tvg::Result::Success) {
181 elm_init(argc, argv);
183 if (tvgEngine == tvg::CanvasEngine::Sw) {
192 //Terminate ThorVG Engine
193 tvg::Initializer::term(tvgEngine);
196 cout << "engine is not supported" << endl;