prepare tvg v0.8 release
[platform/core/graphics/tizenvg.git] / test / testFill.cpp
1 /*
2  * Copyright (c) 2021 - 2022 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 <thorvg.h>
24 #include <memory>
25 #include "catch.hpp"
26
27 using namespace tvg;
28 using namespace std;
29
30
31 TEST_CASE("Filling Creation", "[tvgFill]")
32 {
33     auto linear = LinearGradient::gen();
34     REQUIRE(linear);
35
36     REQUIRE(linear->identifier() == LinearGradient::identifier());
37     REQUIRE(linear->identifier() != RadialGradient::identifier());
38
39     auto radial = RadialGradient::gen();
40     REQUIRE(radial);
41
42     REQUIRE(radial->identifier() == RadialGradient::identifier());
43     REQUIRE(radial->identifier() != LinearGradient::identifier());
44 }
45
46 TEST_CASE("Common Filling", "[tvgFill]")
47 {
48     auto fill = LinearGradient::gen();
49     REQUIRE(fill);
50
51     //Options
52     REQUIRE(fill->spread() == FillSpread::Pad);
53     REQUIRE(fill->spread(FillSpread::Pad) == Result::Success);
54     REQUIRE(fill->spread(FillSpread::Reflect) == Result::Success);
55     REQUIRE(fill->spread(FillSpread::Repeat) == Result::Success);
56     REQUIRE(fill->spread() == FillSpread::Repeat);
57
58     //ColorStops
59     const Fill::ColorStop* cs = nullptr;
60     REQUIRE(fill->colorStops(nullptr) == 0);
61     REQUIRE(fill->colorStops(&cs) == 0);
62     REQUIRE(cs == nullptr);
63
64     Fill::ColorStop cs2[4] = {
65         {0.0f, 0, 0, 0, 0},
66         {0.2f, 50, 25, 50, 25},
67         {0.5f, 100, 100, 100, 125},
68         {1.0f, 255, 255, 255, 255}
69     };
70
71     REQUIRE(fill->colorStops(nullptr, 4) == Result::InvalidArguments);
72     REQUIRE(fill->colorStops(cs2, 0) == Result::InvalidArguments);
73     REQUIRE(fill->colorStops(cs2, 4) == Result::Success);
74     REQUIRE(fill->colorStops(&cs) == 4);
75
76     for (int i = 0; i < 4; ++i) {
77         REQUIRE(cs[i].offset == cs2[i].offset);
78         REQUIRE(cs[i].r == cs2[i].r);
79         REQUIRE(cs[i].g == cs2[i].g);
80         REQUIRE(cs[i].b == cs2[i].b);
81     };
82
83     //Reset ColorStop
84     REQUIRE(fill->colorStops(nullptr, 0) == Result::Success);
85     REQUIRE(fill->colorStops(&cs) == 0);
86
87     //Set to Shape
88     auto shape = Shape::gen();
89     REQUIRE(shape);
90
91     auto pFill = fill.get();
92     REQUIRE(shape->fill(move(fill)) == Result::Success);
93     REQUIRE(shape->fill() == pFill);
94 }
95
96 TEST_CASE("Fill Transformation", "[tvgFill]")
97 {
98     auto fill = LinearGradient::gen();
99     REQUIRE(fill);
100
101     //no transformation
102     auto mGet = fill->transform();
103     REQUIRE(mGet.e11 == Approx(1.0f).margin(0.000001));
104     REQUIRE(mGet.e12 == Approx(0.0f).margin(0.000001));
105     REQUIRE(mGet.e13 == Approx(0.0f).margin(0.000001));
106     REQUIRE(mGet.e21 == Approx(0.0f).margin(0.000001));
107     REQUIRE(mGet.e22 == Approx(1.0f).margin(0.000001));
108     REQUIRE(mGet.e23 == Approx(0.0f).margin(0.000001));
109     REQUIRE(mGet.e31 == Approx(0.0f).margin(0.000001));
110     REQUIRE(mGet.e32 == Approx(0.0f).margin(0.000001));
111     REQUIRE(mGet.e33 == Approx(1.0f).margin(0.000001));
112
113     auto mSet = Matrix{1.1f, 2.2f, 3.3f, 4.4f, 5.5f, 6.6f, -7.7f, -8.8f, -9.9f};
114     REQUIRE(fill->transform(mSet) == Result::Success);
115
116     //transformation was set
117     mGet = fill->transform();
118     REQUIRE(mGet.e11 == Approx(mSet.e11).margin(0.000001));
119     REQUIRE(mGet.e12 == Approx(mSet.e12).margin(0.000001));
120     REQUIRE(mGet.e13 == Approx(mSet.e13).margin(0.000001));
121     REQUIRE(mGet.e21 == Approx(mSet.e21).margin(0.000001));
122     REQUIRE(mGet.e22 == Approx(mSet.e22).margin(0.000001));
123     REQUIRE(mGet.e23 == Approx(mSet.e23).margin(0.000001));
124     REQUIRE(mGet.e31 == Approx(mSet.e31).margin(0.000001));
125     REQUIRE(mGet.e32 == Approx(mSet.e32).margin(0.000001));
126     REQUIRE(mGet.e33 == Approx(mSet.e33).margin(0.000001));
127 }
128
129 TEST_CASE("Linear Filling", "[tvgFill]")
130 {
131     auto fill = LinearGradient::gen();
132     REQUIRE(fill);
133
134     float x1, y1, x2, y2;
135
136     REQUIRE(fill->linear(nullptr, nullptr, nullptr, nullptr) == Result::Success);
137     REQUIRE(fill->linear(0, 0, 0, 0) == Result::Success);
138
139     REQUIRE(fill->linear(&x1, nullptr, &x2, nullptr) == Result::Success);
140     REQUIRE(x1 == 0.0f);
141     REQUIRE(x2 == 0.0f);
142
143     REQUIRE(fill->linear(-1.0f, -1.0f, 100.0f, 100.0f) == Result::Success);
144     REQUIRE(fill->linear(&x1, &y1, &x2, &y2) == Result::Success);
145     REQUIRE(x1 == -1.0f);
146     REQUIRE(y1 == -1.0f);
147     REQUIRE(x2 == 100.0f);
148     REQUIRE(y2 == 100.0f);
149 }
150
151 TEST_CASE("Radial Filling", "[tvgFill]")
152 {
153     auto fill = RadialGradient::gen();
154     REQUIRE(fill);
155
156     float cx, cy, radius;
157
158     REQUIRE(fill->radial(0, 0, -1) == Result::InvalidArguments);
159     REQUIRE(fill->radial(nullptr, nullptr, nullptr) == Result::Success);
160     REQUIRE(fill->radial(100, 120, 50) == Result::Success);
161
162     REQUIRE(fill->radial(&cx, nullptr, &radius) == Result::Success);
163     REQUIRE(cx == 100.0f);
164     REQUIRE(radius == 50.0f);
165
166     REQUIRE(fill->radial(nullptr, &cy, nullptr) == Result::Success);
167     REQUIRE(cy == 120);
168
169     REQUIRE(fill->radial(0, 0, 0) == Result::Success);
170     REQUIRE(fill->radial(&cx, &cy, &radius) == Result::Success);
171     REQUIRE(cx == 0.0f);
172     REQUIRE(cy == 0.0f);
173     REQUIRE(radius == 0.0f);
174 }
175
176 TEST_CASE("Linear Filling Dupliction", "[tvgFill]")
177 {
178     auto fill = LinearGradient::gen();
179     REQUIRE(fill);
180
181     //Setup
182     Fill::ColorStop cs[4] = {
183         {0.0f, 0, 0, 0, 0},
184         {0.2f, 50, 25, 50, 25},
185         {0.5f, 100, 100, 100, 125},
186         {1.0f, 255, 255, 255, 255}
187     };
188
189     REQUIRE(fill->colorStops(cs, 4) == Result::Success);
190     REQUIRE(fill->spread(FillSpread::Reflect) == Result::Success);
191     REQUIRE(fill->linear(-10.0f, 10.0f, 100.0f, 120.0f) == Result::Success);
192
193     auto m = Matrix{1.1f, 2.2f, 3.3f, 4.4f, 5.5f, 6.6f, -7.7f, -8.8f, -9.9f};
194     REQUIRE(fill->transform(m) == Result::Success);
195
196     //Duplication
197     auto dup = unique_ptr<LinearGradient>(static_cast<LinearGradient*>(fill->duplicate()));
198     REQUIRE(dup);
199
200     REQUIRE(dup->spread() == FillSpread::Reflect);
201
202     float x1, y1, x2, y2;
203     REQUIRE(fill->linear(&x1, &y1, &x2, &y2) == Result::Success);
204     REQUIRE(x1 == -10.0f);
205     REQUIRE(y1 == 10.0f);
206     REQUIRE(x2 == 100.0f);
207     REQUIRE(y2 == 120.0f);
208
209     const Fill::ColorStop* cs2 = nullptr;
210     REQUIRE(fill->colorStops(&cs2) == 4);
211
212     for (int i = 0; i < 4; ++i) {
213         REQUIRE(cs[i].offset == cs2[i].offset);
214         REQUIRE(cs[i].r == cs2[i].r);
215         REQUIRE(cs[i].g == cs2[i].g);
216         REQUIRE(cs[i].b == cs2[i].b);
217     }
218
219     auto mDup = dup->transform();
220     REQUIRE(mDup.e11 == Approx(m.e11).margin(0.000001));
221     REQUIRE(mDup.e12 == Approx(m.e12).margin(0.000001));
222     REQUIRE(mDup.e13 == Approx(m.e13).margin(0.000001));
223     REQUIRE(mDup.e21 == Approx(m.e21).margin(0.000001));
224     REQUIRE(mDup.e22 == Approx(m.e22).margin(0.000001));
225     REQUIRE(mDup.e23 == Approx(m.e23).margin(0.000001));
226     REQUIRE(mDup.e31 == Approx(m.e31).margin(0.000001));
227     REQUIRE(mDup.e32 == Approx(m.e32).margin(0.000001));
228     REQUIRE(mDup.e33 == Approx(m.e33).margin(0.000001));
229 }
230
231 TEST_CASE("Radial Filling Dupliction", "[tvgFill]")
232 {
233     auto fill = RadialGradient::gen();
234     REQUIRE(fill);
235
236     //Setup
237     Fill::ColorStop cs[4] = {
238         {0.0f, 0, 0, 0, 0},
239         {0.2f, 50, 25, 50, 25},
240         {0.5f, 100, 100, 100, 125},
241         {1.0f, 255, 255, 255, 255}
242     };
243
244     REQUIRE(fill->colorStops(cs, 4) == Result::Success);
245     REQUIRE(fill->spread(FillSpread::Reflect) == Result::Success);
246     REQUIRE(fill->radial(100.0f, 120.0f, 50.0f) == Result::Success);
247
248     auto m = Matrix{1.1f, 2.2f, 3.3f, 4.4f, 5.5f, 6.6f, -7.7f, -8.8f, -9.9f};
249     REQUIRE(fill->transform(m) == Result::Success);
250
251     //Duplication
252     auto dup = unique_ptr<RadialGradient>(static_cast<RadialGradient*>(fill->duplicate()));
253     REQUIRE(dup);
254
255     REQUIRE(dup->spread() == FillSpread::Reflect);
256
257     float cx, cy, radius;
258     REQUIRE(dup->radial(&cx, &cy, &radius) == Result::Success);
259     REQUIRE(cx == 100.0f);
260     REQUIRE(cy == 120.0f);
261     REQUIRE(radius == 50.0f);
262
263     const Fill::ColorStop* cs2 = nullptr;
264     REQUIRE(fill->colorStops(&cs2) == 4);
265
266     for (int i = 0; i < 4; ++i) {
267         REQUIRE(cs[i].offset == cs2[i].offset);
268         REQUIRE(cs[i].r == cs2[i].r);
269         REQUIRE(cs[i].g == cs2[i].g);
270         REQUIRE(cs[i].b == cs2[i].b);
271     }
272
273     auto mDup = dup->transform();
274     REQUIRE(mDup.e11 == Approx(m.e11).margin(0.000001));
275     REQUIRE(mDup.e12 == Approx(m.e12).margin(0.000001));
276     REQUIRE(mDup.e13 == Approx(m.e13).margin(0.000001));
277     REQUIRE(mDup.e21 == Approx(m.e21).margin(0.000001));
278     REQUIRE(mDup.e22 == Approx(m.e22).margin(0.000001));
279     REQUIRE(mDup.e23 == Approx(m.e23).margin(0.000001));
280     REQUIRE(mDup.e31 == Approx(m.e31).margin(0.000001));
281     REQUIRE(mDup.e32 == Approx(m.e32).margin(0.000001));
282     REQUIRE(mDup.e33 == Approx(m.e33).margin(0.000001));
283 }