example boundary2: added image boundary check sample.
[platform/core/graphics/tizenvg.git] / src / examples / TvgSaver.cpp
1 /*
2  * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved.
3
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:
10
11  * The above copyright notice and this permission notice shall be included in all
12  * copies or substantial portions of the Software.
13
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
20  * SOFTWARE.
21  */
22
23 #include <iostream>
24 #include <fstream>
25 #include <thread>
26 #include <string.h>
27 #include <thorvg.h>
28
29 using namespace std;
30
31 /************************************************************************/
32 /* Drawing Commands                                                     */
33 /************************************************************************/
34
35 void tvgDrawStar(tvg::Shape* star)
36 {
37     star->moveTo(199, 34);
38     star->lineTo(253, 143);
39     star->lineTo(374, 160);
40     star->lineTo(287, 244);
41     star->lineTo(307, 365);
42     star->lineTo(199, 309);
43     star->lineTo(97, 365);
44     star->lineTo(112, 245);
45     star->lineTo(26, 161);
46     star->lineTo(146, 143);
47     star->close();
48 }
49
50 void exportTvg()
51 {
52     //prepare the main scene
53     auto scene = tvg::Scene::gen();
54
55     tvg::Fill::ColorStop colorStops1[3];
56     colorStops1[0] = {0, 255, 0, 0, 255};
57     colorStops1[1] = {0.5, 0, 0, 255, 127};
58     colorStops1[2] = {1, 127, 127, 127, 127};
59
60     tvg::Fill::ColorStop colorStops2[2];
61     colorStops2[0] = {0, 255, 0, 0, 255};
62     colorStops2[1] = {1, 50, 0, 255, 255};
63
64     tvg::Fill::ColorStop colorStops3[2];
65     colorStops3[0] = {0, 0, 0, 255, 155};
66     colorStops3[1] = {1, 0, 255, 0, 155};
67
68     float dashPattern[2] = {30, 40};
69
70     //gradient shape + dashed stroke
71     auto fillStroke1 = tvg::LinearGradient::gen();
72     fillStroke1->linear(20, 120, 380, 280);
73     fillStroke1->colorStops(colorStops1, 3);
74
75     auto fillShape1 = tvg::LinearGradient::gen();
76     fillShape1->linear(20, 120, 380, 280);
77     fillShape1->colorStops(colorStops1, 3);
78
79     auto shape1 = tvg::Shape::gen();
80     shape1->appendCircle(200, 200, 180, 80);
81     shape1->fill(move(fillShape1));
82     shape1->stroke(20);
83     shape1->stroke(dashPattern, 2);
84     shape1->stroke(move(fillStroke1));
85
86     if (scene->push(move(shape1)) != tvg::Result::Success) return;
87
88     //clipped image
89     ifstream file(EXAMPLE_DIR"/rawimage_200x300.raw");
90     if (!file.is_open()) return;
91     uint32_t *data = (uint32_t*) malloc(sizeof(uint32_t) * 200 * 300);
92     if (!data) return;
93     file.read(reinterpret_cast<char*>(data), sizeof(uint32_t) * 200 * 300);
94     file.close();
95
96     auto image = tvg::Picture::gen();
97     if (image->load(data, 200, 300, true) != tvg::Result::Success) return;
98     image->translate(400, 0);
99     image->scale(2);
100
101     auto imageClip = tvg::Shape::gen();
102     imageClip->appendCircle(400, 200, 80, 180);
103     imageClip->fill(0, 0, 0, 155);
104     imageClip->translate(200, 0);
105     image->composite(move(imageClip), tvg::CompositeMethod::ClipPath);
106
107     if (scene->push(move(image)) != tvg::Result::Success) return;
108     free(data);
109
110     //nested paints
111     auto scene2 = tvg::Scene::gen();
112     scene2->translate(100, 100);
113
114     auto scene3 = tvg::Scene::gen();
115     scene3->rotate(10);
116     scene3->scale(2);
117     scene3->translate(400,400);
118
119     auto shape2 = tvg::Shape::gen();
120     shape2->appendRect(50, 0, 50, 100, 10, 40);
121     shape2->fill(0, 0, 255, 125);
122     scene3->push(move(shape2));
123
124     scene2->push(move(scene3));
125
126     auto shape3 = tvg::Shape::gen();
127     shape3->appendRect(0, 0, 50, 100, 10, 40);
128     auto fillShape3 = tvg::RadialGradient::gen();
129     fillShape3->radial(25, 50, 25);
130     fillShape3->colorStops(colorStops2, 2);
131     shape3->fill(move(fillShape3));
132     shape3->scale(2);
133     shape3->opacity(200);
134     shape3->translate(400, 400);
135     scene2->push(move(shape3));
136
137     if (scene->push(move(scene2)) != tvg::Result::Success) return;
138
139     //masked svg file
140     auto svg = tvg::Picture::gen();
141     if (svg->load(EXAMPLE_DIR"/tiger.svg") != tvg::Result::Success) return;
142     svg->opacity(200);
143     svg->scale(0.3);
144     svg->translate(50, 450);
145
146     auto svgMask = tvg::Shape::gen();
147     tvgDrawStar(svgMask.get());
148     svgMask->fill(0, 0, 0, 255);
149     svgMask->translate(30, 440);
150     svgMask->opacity(200);
151     svgMask->scale(0.7);
152     svg->composite(move(svgMask), tvg::CompositeMethod::AlphaMask);
153
154     if (scene->push(move(svg)) != tvg::Result::Success) return;
155
156     //solid top circle and gradient bottom circle
157     auto circ1 = tvg::Shape::gen();
158     circ1->appendCircle(400, 375, 50, 50);
159     auto fill1 = tvg::RadialGradient::gen();
160     fill1->radial(400, 375, 50);
161     fill1->colorStops(colorStops3, 2);
162     circ1->fill(move(fill1));
163     circ1->fill(0, 255, 0, 155);
164
165     auto circ2 = tvg::Shape::gen();
166     circ2->appendCircle(400, 425, 50, 50);
167     circ2->fill(0, 255, 0, 155);
168     auto fill2 = tvg::RadialGradient::gen();
169     fill2->radial(400, 425, 50);
170     fill2->colorStops(colorStops3, 2);
171     circ2->fill(move(fill2));
172
173     if (scene->push(move(circ1)) != tvg::Result::Success) return;
174     if (scene->push(move(circ2)) != tvg::Result::Success) return;
175
176     //inv mask applied to the main scene
177     auto mask = tvg::Shape::gen();
178     mask->appendCircle(400, 400, 15, 15);
179     mask->fill(0, 0, 0, 255);
180     scene->composite(move(mask), tvg::CompositeMethod::InvAlphaMask);
181
182     //save the tvg file
183     auto saver = tvg::Saver::gen();
184     if (saver->save(move(scene), EXAMPLE_DIR"/test.tvg") == tvg::Result::Success) {
185         saver->sync();
186         cout << "Successfully exported to test.tvg, Please check the result using PictureTvg!" << endl;
187         return;
188     }
189     cout << "Problem with saving the test.tvg file. Did you enable TVG Saver?" << endl;
190 }
191
192
193 /************************************************************************/
194 /* Main Code                                                            */
195 /************************************************************************/
196
197 int main(int argc, char **argv)
198 {
199     tvg::CanvasEngine tvgEngine = tvg::CanvasEngine::Sw;
200
201     if (argc > 1) {
202         if (!strcmp(argv[1], "gl")) tvgEngine = tvg::CanvasEngine::Gl;
203     }
204
205     //Initialize ThorVG Engine
206     if (tvgEngine == tvg::CanvasEngine::Sw) {
207         cout << "tvg engine: software" << endl;
208     } else {
209         cout << "tvg engine: opengl" << endl;
210     }
211
212     //Threads Count
213     auto threads = std::thread::hardware_concurrency();
214
215     //Initialize ThorVG Engine
216     if (tvg::Initializer::init(tvgEngine, threads) == tvg::Result::Success) {
217
218         exportTvg();
219
220         //Terminate ThorVG Engine
221         tvg::Initializer::term(tvgEngine);
222
223     } else {
224         cout << "engine is not supported" << endl;
225     }
226     return 0;
227 }