2 * Copyright (c) 2021 - 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
23 #include <thorvg_capi.h>
24 #include "../catch.hpp"
26 TEST_CASE("Multiple shapes", "[capiShapes]")
28 Tvg_Paint* paint = tvg_shape_new();
31 REQUIRE(tvg_shape_append_rect(paint, 0, 0, 100, 100, 0, 0) == TVG_RESULT_SUCCESS);
32 REQUIRE(tvg_shape_append_rect(paint, 0, 0, 100, 100, 50, 50) == TVG_RESULT_SUCCESS);
33 REQUIRE(tvg_shape_append_rect(paint, 0, 0, 100, 100, 100, 100) == TVG_RESULT_SUCCESS);
34 REQUIRE(tvg_shape_append_circle(paint, 100, 100, 50, 50) == TVG_RESULT_SUCCESS);
35 REQUIRE(tvg_shape_append_circle(paint, 100, 100, 0, 0) == TVG_RESULT_SUCCESS);
36 REQUIRE(tvg_shape_append_arc(paint, 100, 100, 50, 90, 90, 0) == TVG_RESULT_SUCCESS);
39 REQUIRE(tvg_shape_append_rect(NULL, 0, 0, 0, 0, 0, 0) == TVG_RESULT_INVALID_ARGUMENT);
40 REQUIRE(tvg_shape_append_circle(NULL, 0, 0, 0, 0) == TVG_RESULT_INVALID_ARGUMENT);
41 REQUIRE(tvg_shape_append_arc(NULL, 0, 0, 0, 0, 0, 0) == TVG_RESULT_INVALID_ARGUMENT);
43 REQUIRE(tvg_paint_del(paint) == TVG_RESULT_SUCCESS);
46 TEST_CASE("Shape reset", "[capiShapes]")
48 Tvg_Paint* paint = tvg_shape_new();
51 REQUIRE(tvg_shape_reset(NULL) == TVG_RESULT_INVALID_ARGUMENT);
52 REQUIRE(tvg_shape_reset(paint) == TVG_RESULT_SUCCESS);
54 REQUIRE(tvg_paint_del(paint) == TVG_RESULT_SUCCESS);
57 TEST_CASE("Shape path", "[capiShapePath]")
59 Tvg_Paint* paint = tvg_shape_new();
62 Tvg_Path_Command* cmds_get;
67 Tvg_Path_Command cmds[11];
68 cmds[0] = TVG_PATH_COMMAND_MOVE_TO;
69 cmds[1] = TVG_PATH_COMMAND_LINE_TO;
70 cmds[2] = TVG_PATH_COMMAND_LINE_TO;
71 cmds[3] = TVG_PATH_COMMAND_LINE_TO;
72 cmds[4] = TVG_PATH_COMMAND_LINE_TO;
73 cmds[5] = TVG_PATH_COMMAND_LINE_TO;
74 cmds[6] = TVG_PATH_COMMAND_LINE_TO;
75 cmds[7] = TVG_PATH_COMMAND_LINE_TO;
76 cmds[8] = TVG_PATH_COMMAND_LINE_TO;
77 cmds[9] = TVG_PATH_COMMAND_LINE_TO;
78 cmds[10] = TVG_PATH_COMMAND_CLOSE;
81 pts[0] = {199, 34}; //MoveTo
82 pts[1] = {253, 143}; //LineTo
83 pts[2] = {374, 160}; //LineTo
84 pts[3] = {287, 244}; //LineTo
85 pts[4] = {307, 365}; //LineTo
86 pts[5] = {199, 309}; //LineTo
87 pts[6] = {97, 365}; //LineTo
88 pts[7] = {112, 245}; //LineTo
89 pts[8] = {26, 161}; //LineTo
90 pts[9] = {146, 143}; //LineTo
92 REQUIRE(tvg_shape_append_path(paint, cmds, 11, pts, 10) == TVG_RESULT_SUCCESS);
94 REQUIRE(tvg_shape_get_path_commands(paint, (const Tvg_Path_Command**) &cmds_get, &cnt) == TVG_RESULT_SUCCESS);
96 for (i = 0; i < cnt; i++) {
97 REQUIRE(cmds_get[i] == cmds[i]);
100 REQUIRE(tvg_shape_get_path_coords(paint, (const Tvg_Point**) &pts_get, &cnt) == TVG_RESULT_SUCCESS);
102 for (i = 0; i < cnt; i++) {
103 REQUIRE(pts_get[i].x == pts[i].x);
104 REQUIRE(pts_get[i].y == pts[i].y);
108 REQUIRE(tvg_shape_append_path(NULL, NULL, 0, NULL, 0) == TVG_RESULT_INVALID_ARGUMENT);
109 REQUIRE(tvg_shape_get_path_coords(NULL, NULL, NULL) == TVG_RESULT_INVALID_ARGUMENT);
111 REQUIRE(tvg_shape_reset(paint) == TVG_RESULT_SUCCESS);
113 REQUIRE(tvg_shape_move_to(paint, 0, 10) == TVG_RESULT_SUCCESS);
114 REQUIRE(tvg_shape_line_to(paint, 100, 110) == TVG_RESULT_SUCCESS);
115 REQUIRE(tvg_shape_line_to(paint, 100, 10) == TVG_RESULT_SUCCESS);
116 REQUIRE(tvg_shape_close(paint) == TVG_RESULT_SUCCESS);
118 REQUIRE(tvg_shape_move_to(paint, 100, 0) == TVG_RESULT_SUCCESS);
119 REQUIRE(tvg_shape_cubic_to(paint, 150, 0, 200, 50, 200, 100) == TVG_RESULT_SUCCESS);
120 REQUIRE(tvg_shape_close(paint) == TVG_RESULT_SUCCESS);
123 REQUIRE(tvg_shape_move_to(NULL, 0, 0) == TVG_RESULT_INVALID_ARGUMENT);
124 REQUIRE(tvg_shape_line_to(NULL, 0, 0) == TVG_RESULT_INVALID_ARGUMENT);
125 REQUIRE(tvg_shape_cubic_to(NULL, 0, 0, 0, 0, 0, 0) == TVG_RESULT_INVALID_ARGUMENT);
126 REQUIRE(tvg_shape_close(NULL) == TVG_RESULT_INVALID_ARGUMENT);
128 REQUIRE(tvg_paint_del(paint) == TVG_RESULT_SUCCESS);
131 TEST_CASE("Stroke width", "[capiStrokeWidth]")
133 Tvg_Paint* paint = tvg_shape_new();
138 REQUIRE(tvg_shape_set_stroke_width(paint, 0.0f) == TVG_RESULT_SUCCESS);
139 REQUIRE(tvg_shape_get_stroke_width(paint, &stroke) == TVG_RESULT_SUCCESS);
140 REQUIRE(stroke == 0.0f);
142 REQUIRE(tvg_shape_set_stroke_width(paint, 5.0f) == TVG_RESULT_SUCCESS);
143 REQUIRE(tvg_shape_get_stroke_width(paint, &stroke) == TVG_RESULT_SUCCESS);
144 REQUIRE(stroke == 5.0f);
146 //Invalid paint or width pointer
147 REQUIRE(tvg_shape_set_stroke_width(NULL, 0) == TVG_RESULT_INVALID_ARGUMENT);
148 REQUIRE(tvg_shape_get_stroke_width(NULL, &stroke) == TVG_RESULT_INVALID_ARGUMENT);
149 REQUIRE(tvg_shape_get_stroke_width(paint, NULL) == TVG_RESULT_INVALID_ARGUMENT);
151 REQUIRE(tvg_paint_del(paint) == TVG_RESULT_SUCCESS);
154 TEST_CASE("Stroke color", "[capiStrokeColor]")
156 Tvg_Paint* paint = tvg_shape_new();
161 REQUIRE(tvg_shape_set_stroke_color(paint, 100, 200, 50, 1) == TVG_RESULT_SUCCESS);
162 REQUIRE(tvg_shape_get_stroke_color(paint, &r, &g, &b, &a) == TVG_RESULT_SUCCESS);
168 //Invalid paint or no color pointers
169 REQUIRE(tvg_shape_set_stroke_color(NULL, 0, 0, 0, 0) == TVG_RESULT_INVALID_ARGUMENT);
170 REQUIRE(tvg_shape_get_stroke_color(NULL, &r, &g, &b, &a) == TVG_RESULT_INVALID_ARGUMENT);
171 REQUIRE(tvg_shape_get_stroke_color(paint, &r, &g, &b, NULL) == TVG_RESULT_SUCCESS);
172 REQUIRE(tvg_shape_get_stroke_color(paint, NULL, NULL, NULL, &a) == TVG_RESULT_SUCCESS);
174 REQUIRE(tvg_paint_del(paint) == TVG_RESULT_SUCCESS);
177 TEST_CASE("Stroke dash", "[capiStrokeDash]")
179 Tvg_Paint* paint = tvg_shape_new();
182 float dash[2] = {20, 10};
186 REQUIRE(tvg_shape_set_stroke_dash(paint, dash, 2) == TVG_RESULT_SUCCESS);
187 REQUIRE(tvg_shape_get_stroke_dash(paint, (const float**) &dash_get, &cnt) == TVG_RESULT_SUCCESS);
189 for (uint32_t i = 0; i < cnt; i++) {
190 REQUIRE(dash_get[i] == dash[i]);
193 REQUIRE(tvg_paint_del(paint) == TVG_RESULT_SUCCESS);
196 TEST_CASE("Stroke cap", "[capiStrokeCap]")
198 Tvg_Paint* paint = tvg_shape_new();
203 REQUIRE(tvg_shape_set_stroke_cap(paint, TVG_STROKE_CAP_ROUND) == TVG_RESULT_SUCCESS);
204 REQUIRE(tvg_shape_get_stroke_cap(paint, &cap) == TVG_RESULT_SUCCESS);
205 REQUIRE(cap == TVG_STROKE_CAP_ROUND);
207 REQUIRE(tvg_shape_set_stroke_cap(paint, TVG_STROKE_CAP_BUTT) == TVG_RESULT_SUCCESS);
208 REQUIRE(tvg_shape_get_stroke_cap(paint, &cap) == TVG_RESULT_SUCCESS);
209 REQUIRE(cap == TVG_STROKE_CAP_BUTT);
211 REQUIRE(tvg_paint_del(paint) == TVG_RESULT_SUCCESS);
214 TEST_CASE("Stroke join", "[capiStrokeJoin]")
216 Tvg_Paint* paint = tvg_shape_new();
219 Tvg_Stroke_Join join;
221 REQUIRE(tvg_shape_set_stroke_join(paint, TVG_STROKE_JOIN_BEVEL) == TVG_RESULT_SUCCESS);
222 REQUIRE(tvg_shape_get_stroke_join(paint, &join) == TVG_RESULT_SUCCESS);
223 REQUIRE(join == TVG_STROKE_JOIN_BEVEL);
225 REQUIRE(tvg_shape_set_stroke_join(paint, TVG_STROKE_JOIN_MITER) == TVG_RESULT_SUCCESS);
226 REQUIRE(tvg_shape_get_stroke_join(paint, &join) == TVG_RESULT_SUCCESS);
227 REQUIRE(join == TVG_STROKE_JOIN_MITER);
229 REQUIRE(tvg_paint_del(paint) == TVG_RESULT_SUCCESS);
232 TEST_CASE("Fill color", "[capiFillColor]")
234 Tvg_Paint* paint = tvg_shape_new();
239 REQUIRE(tvg_shape_set_fill_color(paint, 129, 190, 57, 20) == TVG_RESULT_SUCCESS);
240 REQUIRE(tvg_shape_get_fill_color(paint, &r, &g, &b, &a) == TVG_RESULT_SUCCESS);
246 REQUIRE(tvg_paint_del(paint) == TVG_RESULT_SUCCESS);
249 TEST_CASE("Fill rule", "[capiFillRule]")
251 Tvg_Paint* paint = tvg_shape_new();
254 Tvg_Fill_Rule rule, rule_get;
256 rule = TVG_FILL_RULE_EVEN_ODD;
257 REQUIRE(tvg_shape_set_fill_rule(paint, rule) == TVG_RESULT_SUCCESS);
258 REQUIRE(tvg_shape_get_fill_rule(paint, &rule_get) == TVG_RESULT_SUCCESS);
259 REQUIRE(rule == rule_get);
261 rule = TVG_FILL_RULE_WINDING;
262 REQUIRE(tvg_shape_set_fill_rule(paint, rule) == TVG_RESULT_SUCCESS);
263 REQUIRE(tvg_shape_get_fill_rule(paint, &rule_get) == TVG_RESULT_SUCCESS);
264 REQUIRE(rule == rule_get);
266 REQUIRE(tvg_paint_del(paint) == TVG_RESULT_SUCCESS);