1 /*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2018-2019 KiCad Developers, see AUTHORS.TXT for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 * or you may search the http://www.gnu.org website for the version 2 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
24 #include <boost/test/unit_test.hpp>
25
26 #include "color4d_test_utils.h"
27
28 #include <qa_utils/wx_utils/unit_test_utils.h>
29
30 #include <gal/color4d.h>
31
32 #ifdef WX_COMPATIBILITY
33 #include <wx/colour.h>
34 #endif
35
36 // All these tests are of a class in KIGFX
37 using namespace KIGFX;
38
39
40 /**
41 * Declares a struct as the Boost test fixture.
42 */
43 BOOST_AUTO_TEST_SUITE( Color4D )
44
45
46 /**
47 * Check basic setting and getting of values
48 */
BOOST_AUTO_TEST_CASE(BasicOps)49 BOOST_AUTO_TEST_CASE( BasicOps )
50 {
51 const auto c = COLOR4D{ 0.4, 0.5, 0.6, 0.7 };
52
53 BOOST_CHECK_EQUAL( c.r, 0.4 );
54 BOOST_CHECK_EQUAL( c.g, 0.5 );
55 BOOST_CHECK_EQUAL( c.b, 0.6 );
56 BOOST_CHECK_EQUAL( c.a, 0.7 );
57
58 const auto copied = c;
59
60 // Test equality
61 BOOST_CHECK_EQUAL( c, copied );
62
63 const auto c2 = COLOR4D{ 0.1, 0.2, 0.3, 0.4 };
64
65 // Test inequality
66 BOOST_CHECK_NE( c, c2 );
67 }
68
69
70 /**
71 * Test case data for a test that takes a colour and a scalar factor
72 * and returns a result.
73 */
74 struct COLOR_SCALAR_CASE
75 {
76 COLOR4D start;
77 double factor;
78 COLOR4D expected;
79 };
80
81
82 /**
83 * Check inversion
84 */
BOOST_AUTO_TEST_CASE(Invert)85 BOOST_AUTO_TEST_CASE( Invert )
86 {
87 // Inverts RGB, A is the same
88 static const std::vector<COLOR_SCALAR_CASE> cases = {
89 { { 0.0, 0.25, 1.0, 1.0 }, 0.0, { 1.0, 0.75, 0.0, 1.0 } },
90 };
91
92 for( const auto& c : cases )
93 {
94 auto col = c.start;
95
96 const auto inverted = col.Inverted();
97 BOOST_CHECK_EQUAL( inverted, c.expected );
98
99 // Test in-place function
100 col.Invert();
101 BOOST_CHECK_EQUAL( col, c.expected );
102 }
103 }
104
105
106 /**
107 * Check inversion
108 */
BOOST_AUTO_TEST_CASE(Brighten)109 BOOST_AUTO_TEST_CASE( Brighten )
110 {
111 static const std::vector<COLOR_SCALAR_CASE> cases = {
112 { { 0.0, 0.0, 0.0, 1.0 }, 0.5, { 0.5, 0.5, 0.5, 1.0 } },
113 { { 0.0, 0.5, 1.0, 1.0 }, 0.5, { 0.5, 0.75, 1.0, 1.0 } },
114 };
115
116 for( const auto& c : cases )
117 {
118 auto col = c.start;
119
120 const auto brightened = col.Brightened( c.factor );
121 BOOST_CHECK_EQUAL( brightened, c.expected );
122
123 // Test in-place function
124 col.Brighten( c.factor );
125 BOOST_CHECK_EQUAL( col, c.expected );
126 }
127 }
128
129
130 /**
131 * Check darken
132 */
BOOST_AUTO_TEST_CASE(Darken)133 BOOST_AUTO_TEST_CASE( Darken )
134 {
135 static const std::vector<COLOR_SCALAR_CASE> cases = {
136 { { 0.0, 0.0, 0.0, 1.0 }, 0.5, { 0.0, 0.0, 0.0, 1.0 } },
137 { { 1.0, 1.0, 1.0, 1.0 }, 0.5, { 0.5, 0.5, 0.5, 1.0 } },
138 };
139
140 for( const auto& c : cases )
141 {
142 auto col = c.start;
143
144 const auto brightened = col.Darkened( c.factor );
145 BOOST_CHECK_EQUAL( brightened, c.expected );
146
147 // Test in-place function
148 col.Darken( c.factor );
149 BOOST_CHECK_EQUAL( col, c.expected );
150 }
151 }
152
153
154 /**
155 * Check alpha setting
156 */
BOOST_AUTO_TEST_CASE(WithAlpha)157 BOOST_AUTO_TEST_CASE( WithAlpha )
158 {
159 static const std::vector<COLOR_SCALAR_CASE> cases = {
160 { { 0.0, 0.0, 0.0, 1.0 }, 0.5, { 0.0, 0.0, 0.0, 0.5 } },
161 { { 0.0, 0.5, 1.0, 1.0 }, 0.5, { 0.0, 0.5, 1.0, 0.5 } },
162 };
163
164 for( const auto& c : cases )
165 {
166 auto col = c.start;
167
168 const auto with_alpha = col.WithAlpha( c.factor );
169 BOOST_CHECK_EQUAL( with_alpha, c.expected );
170 }
171
172 // Note: If COLOR4D::WithAlpha raised an exception, we could check
173 // the bounds-checking with BOOST_REQUIRE_THROW,
174 // but it assert()s, so we can't.
175 }
176
177 struct FROM_HSV_TO_HEX_CASE
178 {
179 double h;
180 double s;
181 double v;
182 unsigned char r;
183 unsigned char g;
184 unsigned char b;
185 };
186
187
188 /**
189 * Check FromHSV
190 */
BOOST_AUTO_TEST_CASE(FromHsv)191 BOOST_AUTO_TEST_CASE( FromHsv )
192 {
193 static const std::vector<FROM_HSV_TO_HEX_CASE> cases = {
194 { 10, 0.71, 0.66, 168, 69, 49 },
195 { 15, 0.96, 0.34, 87, 24, 3 },
196 { 120, 0.50, 0.50, 64, 128, 64 },
197 { 190, 0.32, 0.97, 168, 234, 247 },
198 { 240, 0.15, 0.75, 163, 163, 191 },
199 { 240, 0.90, 0.75, 19, 19, 191 },
200 { 310, 0.71, 0.66, 168, 49, 148 },
201 { 331, 0.15, 0.85, 217, 184, 200 },
202 };
203
204 for( const auto& c : cases )
205 {
206 auto col = COLOR4D{};
207 col.FromHSV( c.h, c.s, c.v );
208 double new_h, new_s, new_v;
209 col.ToHSV( new_h, new_s, new_v );
210 const unsigned char alpha = 0xFF;
211
212 BOOST_CHECK_PREDICATE( KI_TEST::IsColorNearHex, ( col )( c.r )( c.g )( c.b )( alpha ) );
213 BOOST_CHECK_CLOSE( c.h, new_h, 0.0001 );
214 BOOST_CHECK_CLOSE( c.s, new_s, 0.0001 );
215 BOOST_CHECK_CLOSE( c.v, new_v, 0.0001 );
216 }
217 }
218
219 struct FROM_HSL_TO_HEX_CASE
220 {
221 double h;
222 double s;
223 double l;
224 unsigned char r;
225 unsigned char g;
226 unsigned char b;
227 };
228
229
230 /**
231 * Check FromHSL
232 */
BOOST_AUTO_TEST_CASE(FromHsl)233 BOOST_AUTO_TEST_CASE( FromHsl )
234 {
235 static const std::vector<FROM_HSL_TO_HEX_CASE> cases = {
236 { 10, 0.71, 0.66, 230, 127, 107 },
237 { 15, 0.96, 0.34, 170, 45, 3 },
238 { 120, 0.5, 0.5, 64, 191, 64 },
239 { 190, 0.32, 0.97, 245, 249, 250 },
240 { 240, 0.15, 0.75, 182, 182, 201 },
241 { 240, 0.90, 0.75, 134, 134, 249 },
242 { 310, 0.71, 0.66, 230, 107, 209 },
243 { 331, 0.15, 0.85, 222, 211, 217 },
244 };
245
246 for( const auto& c : cases )
247 {
248 auto col = COLOR4D{};
249 col.FromHSL( c.h, c.s, c.l );
250 double new_h, new_s, new_l;
251 col.ToHSL( new_h, new_s, new_l );
252 const unsigned char alpha = 0xFF;
253
254 BOOST_CHECK_PREDICATE( KI_TEST::IsColorNearHex, ( col )( c.r )( c.g )( c.b )( alpha ) );
255 BOOST_CHECK_CLOSE( c.h, new_h, 0.0001 );
256 BOOST_CHECK_CLOSE( c.s, new_s, 0.0001 );
257 BOOST_CHECK_CLOSE( c.l, new_l, 0.0001 );
258 }
259 }
260
261
262 #ifdef WX_COMPATIBILITY
263
264 struct WX_CONV_CASE
265 {
266 wxColour wx;
267 COLOR4D c4d;
268 };
269
270
271 static std::vector<WX_CONV_CASE> wx_conv_cases = {
272 { { 0x00, 0x00, 0x00, 0x00 }, { 0.0, 0.0, 0.0, 0.0 } },
273 { { 0x66, 0x80, 0x99, 0xB3 }, { 0.4, 0.5, 0.6, 0.7 } },
274 { { 0xFF, 0xFF, 0xFF, 0xFF }, { 1.0, 1.0, 1.0, 1.0 } },
275 { { 0xFF, 0x00, 0x00, 0xFF }, { 0.999, 0.001, 0.0, 1.0 } },
276 };
277
278
279 /**
280 * Check conversion to WxColour
281 */
BOOST_AUTO_TEST_CASE(ToWx)282 BOOST_AUTO_TEST_CASE( ToWx )
283 {
284 for( const auto& c : wx_conv_cases )
285 {
286 wxColour wx_col = c.c4d.ToColour();
287
288 // A hack, but avoids having to define a custom operator<<
289 BOOST_CHECK_EQUAL( wx_col.Red(), c.wx.Red() );
290 BOOST_CHECK_EQUAL( wx_col.Green(), c.wx.Green() );
291 BOOST_CHECK_EQUAL( wx_col.Blue(), c.wx.Blue() );
292 BOOST_CHECK_EQUAL( wx_col.Alpha(), c.wx.Alpha() );
293 }
294 }
295
296
297 /**
298 * Check conversion from WxColour
299 */
BOOST_AUTO_TEST_CASE(FromWx)300 BOOST_AUTO_TEST_CASE( FromWx )
301 {
302 const double tol = 0.5 / 255.0; // One bit of quantised error
303
304 for( const auto& c : wx_conv_cases )
305 {
306 const auto col = COLOR4D{ c.wx };
307
308 BOOST_CHECK_PREDICATE( KI_TEST::IsColorNear, ( col )( c.c4d )( tol ) );
309 }
310 }
311
312 #endif // WX_COMPATIBILITY
313
314 BOOST_AUTO_TEST_SUITE_END()
315