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 tvgDrawStar(tvg::Shape* star)
31 star->moveTo(199, 34);
32 star->lineTo(253, 143);
33 star->lineTo(374, 160);
34 star->lineTo(287, 244);
35 star->lineTo(307, 365);
36 star->lineTo(199, 309);
37 star->lineTo(97, 365);
38 star->lineTo(112, 245);
39 star->lineTo(26, 161);
40 star->lineTo(146, 143);
44 void tvgDrawCmds(tvg::Canvas* canvas)
48 auto shape = tvg::Shape::gen();
49 shape->appendRect(0, 0, WIDTH, HEIGHT, 0, 0);
50 shape->fill(255, 255, 255, 255);
51 if (canvas->push(move(shape)) != tvg::Result::Success) return;
53 //////////////////////////////////////////////
54 auto scene = tvg::Scene::gen();
57 auto star1 = tvg::Shape::gen();
58 tvgDrawStar(star1.get());
59 star1->fill(255, 255, 0, 255);
60 star1->stroke(255 ,0, 0, 255);
64 star1->translate(-10, -10);
66 auto clipStar = tvg::Shape::gen();
67 clipStar->appendCircle(200, 230, 110, 110);
68 clipStar->fill(255, 255, 255, 255); // clip object must have alpha.
69 clipStar->translate(10, 10);
71 star1->composite(move(clipStar), tvg::CompositeMethod::ClipPath);
73 auto star2 = tvg::Shape::gen();
74 tvgDrawStar(star2.get());
75 star2->fill(0, 255, 255, 255);
76 star2->stroke(0 ,255, 0, 255);
81 star2->translate(10, 40);
83 auto clip = tvg::Shape::gen();
84 clip->appendCircle(200, 230, 130, 130);
85 clip->fill(255, 255, 255, 255); // clip object must have alpha.
86 clip->translate(10, 10);
88 scene->push(move(star1));
89 scene->push(move(star2));
91 //Clipping scene to shape
92 scene->composite(move(clip), tvg::CompositeMethod::ClipPath);
94 canvas->push(move(scene));
96 //////////////////////////////////////////////
97 auto star3 = tvg::Shape::gen();
98 tvgDrawStar(star3.get());
101 auto fill = tvg::LinearGradient::gen();
102 fill->linear(100, 100, 300, 300);
103 tvg::Fill::ColorStop colorStops[2];
104 colorStops[0] = {0, 0, 0, 0, 255};
105 colorStops[1] = {1, 255, 255, 255, 255};
106 fill->colorStops(colorStops, 2);
107 star3->fill(move(fill));
109 star3->stroke(255 ,0, 0, 255);
111 star3->translate(400, 0);
113 auto clipRect = tvg::Shape::gen();
114 clipRect->appendRect(500, 120, 200, 200, 0, 0); //x, y, w, h, rx, ry
115 clipRect->fill(255, 255, 255, 255); // clip object must have alpha.
116 clipRect->translate(20, 20);
118 //Clipping scene to rect(shape)
119 star3->composite(move(clipRect), tvg::CompositeMethod::ClipPath);
121 canvas->push(move(star3));
123 //////////////////////////////////////////////
124 auto picture = tvg::Picture::gen();
125 if (picture->load(EXAMPLE_DIR"/cartman.svg") != tvg::Result::Success) return;
128 picture->translate(50, 400);
130 auto clipPath = tvg::Shape::gen();
131 clipPath->appendCircle(200, 510, 50, 50); //x, y, w, h, rx, ry
132 clipPath->appendCircle(200, 650, 50, 50); //x, y, w, h, rx, ry
133 clipPath->fill(255, 255, 255, 255); // clip object must have alpha.
134 clipPath->translate(20, 20);
136 //Clipping picture to path
137 picture->composite(move(clipPath), tvg::CompositeMethod::ClipPath);
139 canvas->push(move(picture));
141 //////////////////////////////////////////////
142 auto shape1 = tvg::Shape::gen();
143 shape1->appendRect(500, 420, 100, 100, 20, 20);
144 shape1->fill(255, 0, 255, 160);
146 auto clipShape = tvg::Shape::gen();
147 clipShape->appendRect(600, 420, 100, 100, 0, 0);
148 clipShape->fill(255, 0, 255, 150);
150 //Clipping shape1 to clipShape
151 shape1->composite(move(clipShape), tvg::CompositeMethod::ClipPath);
153 canvas->push(move(shape1));
157 /************************************************************************/
158 /* Sw Engine Test Code */
159 /************************************************************************/
161 unique_ptr<tvg::SwCanvas> swCanvas;
163 void tvgSwTest(uint32_t* buffer)
166 swCanvas = tvg::SwCanvas::gen();
167 swCanvas->target(buffer, WIDTH, WIDTH, HEIGHT, tvg::SwCanvas::ARGB8888);
169 /* Push the shape into the Canvas drawing list
170 When this shape is into the canvas list, the shape could update & prepare
171 internal data asynchronously for coming rendering.
172 Canvas keeps this shape node unless user call canvas->clear() */
173 tvgDrawCmds(swCanvas.get());
176 void drawSwView(void* data, Eo* obj)
178 if (swCanvas->draw() == tvg::Result::Success) {
184 /************************************************************************/
185 /* GL Engine Test Code */
186 /************************************************************************/
188 static unique_ptr<tvg::GlCanvas> glCanvas;
190 void initGLview(Evas_Object *obj)
192 static constexpr auto BPP = 4;
195 glCanvas = tvg::GlCanvas::gen();
196 glCanvas->target(nullptr, WIDTH * BPP, WIDTH, HEIGHT);
198 /* Push the shape into the Canvas drawing list
199 When this shape is into the canvas list, the shape could update & prepare
200 internal data asynchronously for coming rendering.
201 Canvas keeps this shape node unless user call canvas->clear() */
202 tvgDrawCmds(glCanvas.get());
205 void drawGLview(Evas_Object *obj)
207 auto gl = elm_glview_gl_api_get(obj);
208 gl->glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
209 gl->glClear(GL_COLOR_BUFFER_BIT);
211 if (glCanvas->draw() == tvg::Result::Success) {
217 /************************************************************************/
219 /************************************************************************/
221 int main(int argc, char **argv)
223 tvg::CanvasEngine tvgEngine = tvg::CanvasEngine::Sw;
226 if (!strcmp(argv[1], "gl")) tvgEngine = tvg::CanvasEngine::Gl;
229 //Initialize ThorVG Engine
230 if (tvgEngine == tvg::CanvasEngine::Sw) {
231 cout << "tvg engine: software" << endl;
233 cout << "tvg engine: opengl" << endl;
237 auto threads = std::thread::hardware_concurrency();
238 if (threads > 0) --threads; //Allow the designated main thread capacity
240 //Initialize ThorVG Engine
241 if (tvg::Initializer::init(tvgEngine, threads) == tvg::Result::Success) {
243 elm_init(argc, argv);
245 if (tvgEngine == tvg::CanvasEngine::Sw) {
254 //Terminate ThorVG Engine
255 tvg::Initializer::term(tvgEngine);
258 cout << "engine is not supported" << endl;