1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24
25 // MARKER(update_precomp.py): autogen include statement, do not remove
26 #include "precompiled_basegfx.hxx"
27 // autogenerated file with codegen.pl
28
29 #include "preextstl.h"
30 #include "gtest/gtest.h"
31 #include "postextstl.h"
32
33 #include <basegfx/matrix/b2dhommatrix.hxx>
34 #include <basegfx/polygon/b2dpolygon.hxx>
35 #include <basegfx/polygon/b2dpolygontools.hxx>
36 #include <basegfx/curve/b2dcubicbezier.hxx>
37 #include <basegfx/curve/b2dbeziertools.hxx>
38 #include <basegfx/polygon/b2dpolypolygontools.hxx>
39 #include <basegfx/polygon/b2dpolygonclipper.hxx>
40 #include <basegfx/polygon/b2dpolypolygon.hxx>
41 #include <basegfx/range/b2dpolyrange.hxx>
42 #include <basegfx/numeric/ftools.hxx>
43 #include <basegfx/color/bcolor.hxx>
44 #include <basegfx/color/bcolortools.hxx>
45
46 #include <basegfx/tools/debugplotter.hxx>
47
48 #include <iostream>
49 #include <fstream>
50
51 using namespace ::basegfx;
52
53
54 namespace basegfx2d
55 {
56
57 class b2dsvgdimpex : public ::testing::Test
58 {
59 protected:
60 ::rtl::OUString aPath0;
61 ::rtl::OUString aPath1;
62 ::rtl::OUString aPath2;
63 ::rtl::OUString aPath3;
64
65 public:
66 // initialise your test code values here.
SetUp()67 virtual void SetUp()
68 {
69 // simple rectangle
70 aPath0 = ::rtl::OUString::createFromAscii(
71 "M 10 10-10 10-10-10 10-10Z" );
72
73 // simple bezier polygon
74 aPath1 = ::rtl::OUString::createFromAscii(
75 "m11430 0c-8890 3810 5715 6985 5715 6985 "
76 "0 0-17145-1905-17145-1905 0 0 22860-10160 "
77 "16510 6350-6350 16510-3810-11430-3810-11430z" );
78
79 // '@' as a bezier polygon
80 aPath2 = ::rtl::OUString::createFromAscii(
81 "m1917 1114c-89-189-233-284-430-284-167 "
82 "0-306 91-419 273-113 182-170 370-170 564 "
83 "0 145 33 259 98 342 65 84 150 126 257 126 "
84 "77 0 154-19 231-57 77-38 147-97 210-176 63"
85 "-79 99-143 109-190 38-199 76-398 114-598z"
86 "m840 1646c-133 73-312 139-537 197-225 57"
87 "-440 86-644 87-483-1-866-132-1150-392-284"
88 "-261-426-619-426-1076 0-292 67-560 200-803 "
89 "133-243 321-433 562-569 241-136 514-204 821"
90 "-204 405 0 739 125 1003 374 264 250 396 550 "
91 "396 899 0 313-88 576-265 787-177 212-386 318"
92 "-627 318-191 0-308-94-352-281-133 187-315 281"
93 "-546 281-172 0-315-67-428-200-113-133-170-301"
94 "-170-505 0-277 90-527 271-751 181-223 394"
95 "-335 640-335 196 0 353 83 470 250 13-68 26"
96 "-136 41-204 96 0 192 0 288 0-74 376-148 752"
97 "-224 1128-21 101-31 183-31 245 0 39 9 70 26 "
98 "93 17 24 39 36 67 36 145 0 279-80 400-240 121"
99 "-160 182-365 182-615 0-288-107-533-322-734"
100 "-215-201-487-301-816-301-395 0-715 124-960 "
101 "373-245 249-368 569-368 958 0 385 119 685 "
102 "357 900 237 216 557 324 958 325 189-1 389-27 "
103 "600-77 211-52 378-110 503-174 27 70 54 140 81 210z" );
104
105 // first part of 'Hello World' as a line polygon
106 aPath3 = ::rtl::OUString::createFromAscii(
107 "m1598 125h306v2334h-306v-1105h-1293v1105h-305v"
108 "-2334h305v973h1293zm2159 1015 78-44 85 235-91 "
109 "47-91 40-90 34-90 29-89 21-88 16-88 10-88 3-102"
110 "-4-97-12-91-19-85-26-40-16-39-18-38-20-36-22-34"
111 "-24-33-26-32-27-30-30-29-31-27-33-25-33-23-36-21"
112 "-36-19-38-18-40-16-40-26-86-18-91-11-97-4-103 3"
113 "-98 11-94 17-89 24-84 31-79 37-75 22-35 23-34 24"
114 "-33 27-32 28-30 29-28 31-27 31-24 33-22 34-21 35"
115 "-18 37-17 38-14 38-13 41-11 41-8 86-12 91-4 82 4 "
116 "78 10 37 9 37 9 36 12 35 14 33 15 33 17 32 19 31 "
117 "21 30 22 30 25 55 54 26 29 24 31 22 32 21 33 19 "
118 "34 18 36 30 74 23 80 17 84 10 89 3 94v78h-1277l6 "
119 "75 10 70 14 66 19 62 23 57 13 26 14 26 15 25 17 "
120 "23 17 22 19 21 19 20 21 18 21 18 23 16 23 14 24 "
121 "14 26 12 26 11 27 10 28 8 59 13 63 7 67 3 80-3 81"
122 "-9 79-14 80-21 78-26 79-32zm-1049-808-12 53h963l"
123 "-7-51-11-49-14-46-17-43-21-40-24-38-27-36-31-32"
124 "-33-29-35-25-37-22-38-17-40-14-41-9-42-6-44-2-48 "
125 "2-46 6-44 9-42 13-40 17-38 21-36 24-34 28-32 32"
126 "-29 34-26 38-23 41-20 44-17 47zm1648-1293h288v"
127 "2459h-288zm752-2459h288v2459h-288zm1286-1750 86-11 "
128 "91-4 91 4 85 12 42 8 39 11 39 13 38 14 36 17 35 18 "
129 "34 20 33 23 31 24 30 26 29 28 28 30 26 32 25 33 23 "
130 "34 21 35 37 75 31 80 24 84 16 90 11 94 3 100-3 100"
131 "-11 95-16 89-24 85-31 80-37 74-21 35-23 35-25 32-26 "
132 "32-28 30-29 28-30 26-31 24-33 22-34 21-35 18-36 17"
133 "-38 14-39 13-39 10-42 9-85 12-91 4-91-4-86-12-41-9"
134 "-40-10-39-13-37-14-36-17-35-18-34-21-33-22-31-24-30"
135 "-26-29-28-28-30-26-32-25-32-23-35-21-35-38-74-30-80"
136 "-24-85-17-89-11-95-3-100 3-101 11-95 17-90 24-85 30"
137 "-79 38-75 21-35 23-35 25-32 26-32 28-30 29-28 30-26 "
138 "31-24 33-22 34-20 35-18 36-16 37-15 39-12 40-11z" );
139 }
140
TearDown()141 virtual void TearDown()
142 {
143 }
144 }; // class b2dsvgdimpex
145
TEST_F(b2dsvgdimpex,impex)146 TEST_F(b2dsvgdimpex,impex)
147 {
148 B2DPolyPolygon aPoly;
149 ::rtl::OUString aExport;
150
151 ASSERT_TRUE(tools::importFromSvgD( aPoly, aPath0, false, 0 )) << "importing simple rectangle from SVG-D";
152 aExport = tools::exportToSvgD( aPoly, true, true, false );
153 const char* sExportString = "m10 10h-20v-20h20z";
154 ASSERT_TRUE(!aExport.compareToAscii(sExportString) ) << "exporting rectangle to SVG-D";
155 ASSERT_TRUE(tools::importFromSvgD( aPoly, aExport, false, 0 )) << "importing simple rectangle from SVG-D (round-trip";
156 aExport = tools::exportToSvgD( aPoly, true, true, false );
157 ASSERT_TRUE(!aExport.compareToAscii(sExportString)) << "exporting rectangle to SVG-D (round-trip)";
158
159 ASSERT_TRUE(tools::importFromSvgD( aPoly, aPath1, false, 0 )) << "importing simple bezier polygon from SVG-D";
160 aExport = tools::exportToSvgD( aPoly, true, true, false );
161
162 // Adaptions for B2DPolygon bezier change (see #i77162#):
163 //
164 // The import/export of aPath1 does not reproduce aExport again. This is
165 // correct since aPath1 contains a segment with non-used control points
166 // which gets exported now correctly as 'l' and also a point (#4, index 3)
167 // with C2 continuity which produces a 's' staement now.
168 //
169 // The old SVGexport identified nun-used ControlVectors erraneously as bezier segments
170 // because the 2nd vector at the start point was used, even when added
171 // with start point was identical to end point. Exactly for that reason
172 // i reworked the B2DPolygon to use prev, next control points.
173 //
174 // so for correct unit test i add the new exported string here as sExportStringSimpleBezier
175 // and compare to it.
176 const char* sExportStringSimpleBezier =
177 "m11430 0c-8890 3810 5715 6985 5715 6985"
178 "l-17145-1905c0 0 22860-10160 16510 6350"
179 "s-3810-11430-3810-11430z";
180 ASSERT_TRUE(!aExport.compareToAscii(sExportStringSimpleBezier)) << "exporting bezier polygon to SVG-D";
181
182 // Adaptions for B2DPolygon bezier change (see #i77162#):
183 //
184 // a 2nd good test is that re-importing of aExport has to create the same
185 // B2DPolPolygon again:
186 B2DPolyPolygon aReImport;
187 ASSERT_TRUE(tools::importFromSvgD( aReImport, aExport, false, 0)) << "importing simple bezier polygon from SVG-D";
188 ASSERT_TRUE(aReImport == aPoly) << "re-imported polygon needs to be identical";
189
190 ASSERT_TRUE(tools::importFromSvgD( aPoly, aPath2, false, 0)) << "importing '@' from SVG-D";
191 aExport = tools::exportToSvgD( aPoly, true, true, false );
192
193 // Adaptions for B2DPolygon bezier change (see #i77162#):
194 //
195 // same here, the corrected export with the corrected B2DPolygon is simply more efficient,
196 // so i needed to change the compare string. Also adding the re-import comparison below.
197 const char* sExportString1 =
198 "m1917 1114c-89-189-233-284-430-284-167 0-306 91-419 273s-170 370-17"
199 "0 564c0 145 33 259 98 342 65 84 150 126 257 126q115.5 0 231-57s147-97 210-176 99-143 109-190c38-199 76-398 114"
200 "-598zm840 1646c-133 73-312 139-537 197-225 57-440 86-644 87-483-1-866-132-1150-392-284-261-426-619-426-1076 0-"
201 "292 67-560 200-803s321-433 562-569 514-204 821-204c405 0 739 125 1003 374 264 250 396 550 396 899 0 313-88 576"
202 "-265 787q-265.5 318-627 318c-191 0-308-94-352-281-133 187-315 281-546 281-172 0-315-67-428-200s-170-301-170-50"
203 "5c0-277 90-527 271-751 181-223 394-335 640-335 196 0 353 83 470 250 13-68 26-136 41-204q144 0 288 0c-74 376-14"
204 "8 752-224 1128-21 101-31 183-31 245 0 39 9 70 26 93 17 24 39 36 67 36 145 0 279-80 400-240s182-365 182-615c0-2"
205 "88-107-533-322-734s-487-301-816-301c-395 0-715 124-960 373s-368 569-368 958q0 577.5 357 900c237 216 557 324 95"
206 "8 325 189-1 389-27 600-77 211-52 378-110 503-174q40.5 105 81 210z";
207 ASSERT_TRUE(tools::importFromSvgD( aReImport, aExport, false, 0)) << "re-importing '@' from SVG-D";
208 ASSERT_TRUE(aReImport == aPoly) << "re-imported '@' needs to be identical";
209
210 ASSERT_TRUE(!aExport.compareToAscii(sExportString1)) << "exporting '@' to SVG-D";
211 ASSERT_TRUE(tools::importFromSvgD( aPoly, aExport, false, 0 )) << "importing '@' from SVG-D (round-trip)";
212 aExport = tools::exportToSvgD( aPoly, true, true, false );
213 ASSERT_TRUE(!aExport.compareToAscii(sExportString1)) << "exporting '@' to SVG-D (round-trip)";
214
215
216 ASSERT_TRUE(tools::importFromSvgD( aPoly, aPath3, false, 0 )) << "importing complex polygon from SVG-D";
217 aExport = tools::exportToSvgD( aPoly, true, true, false );
218 const char* sExportString2 =
219 "m1598 125h306v2334h-306v-1105h-1293v1105h-305v-2334h305v973h1293"
220 "zm2159 1015 78-44 85 235-91 47-91 40-90 34-90 29-89 21-88 16-88 10-88 3-102-4-97"
221 "-12-91-19-85-26-40-16-39-18-38-20-36-22-34-24-33-26-32-27-30-30-29-31-27-33-25-3"
222 "3-23-36-21-36-19-38-18-40-16-40-26-86-18-91-11-97-4-103 3-98 11-94 17-89 24-84 3"
223 "1-79 37-75 22-35 23-34 24-33 27-32 28-30 29-28 31-27 31-24 33-22 34-21 35-18 37-"
224 "17 38-14 38-13 41-11 41-8 86-12 91-4 82 4 78 10 37 9 37 9 36 12 35 14 33 15 33 1"
225 "7 32 19 31 21 30 22 30 25 55 54 26 29 24 31 22 32 21 33 19 34 18 36 30 74 23 80 "
226 "17 84 10 89 3 94v78h-1277l6 75 10 70 14 66 19 62 23 57 13 26 14 26 15 25 17 23 1"
227 "7 22 19 21 19 20 21 18 21 18 23 16 23 14 24 14 26 12 26 11 27 10 28 8 59 13 63 7"
228 " 67 3 80-3 81-9 79-14 80-21 78-26 79-32zm-1049-808-12 53h963l-7-51-11-49-14-46-1"
229 "7-43-21-40-24-38-27-36-31-32-33-29-35-25-37-22-38-17-40-14-41-9-42-6-44-2-48 2-4"
230 "6 6-44 9-42 13-40 17-38 21-36 24-34 28-32 32-29 34-26 38-23 41-20 44-17 47zm1648"
231 "-1293h288v2459h-288zm752-2459h288v2459h-288zm1286-1750 86-11 91-4 91 4 85 12 42 "
232 "8 39 11 39 13 38 14 36 17 35 18 34 20 33 23 31 24 30 26 29 28 28 30 26 32 25 33 "
233 "23 34 21 35 37 75 31 80 24 84 16 90 11 94 3 100-3 100-11 95-16 89-24 85-31 80-37"
234 " 74-21 35-23 35-25 32-26 32-28 30-29 28-30 26-31 24-33 22-34 21-35 18-36 17-38 1"
235 "4-39 13-39 10-42 9-85 12-91 4-91-4-86-12-41-9-40-10-39-13-37-14-36-17-35-18-34-2"
236 "1-33-22-31-24-30-26-29-28-28-30-26-32-25-32-23-35-21-35-38-74-30-80-24-85-17-89-"
237 "11-95-3-100 3-101 11-95 17-90 24-85 30-79 38-75 21-35 23-35 25-32 26-32 28-30 29"
238 "-28 30-26 31-24 33-22 34-20 35-18 36-16 37-15 39-12 40-11z";
239 ASSERT_TRUE(!aExport.compareToAscii(sExportString2)) << "exporting complex polygon to SVG-D";
240 ASSERT_TRUE(tools::importFromSvgD( aPoly, aExport, false, 0 )) << "importing complex polygon from SVG-D (round-trip)";
241 aExport = tools::exportToSvgD( aPoly, true, true, false );
242 ASSERT_TRUE(!aExport.compareToAscii(sExportString2)) << "exporting complex polygon to SVG-D (round-trip)";
243
244 const B2DPolygon aRect(
245 tools::createPolygonFromRect( B2DRange(0.0,0.0,4000.0,4000.0) ));
246 aExport = tools::exportToSvgD( B2DPolyPolygon(aRect), false, false, false );
247
248 const char* sExportStringRect = "M0 0H4000V4000H0Z";
249 ASSERT_TRUE(!aExport.compareToAscii(sExportStringRect)) << "exporting to rectangle svg-d string";
250 }
251
252 class b2dpolyrange : public ::testing::Test
253 {
254 public:
SetUp()255 virtual void SetUp()
256 {}
257
TearDown()258 virtual void TearDown()
259 {}
260 };
261
TEST_F(b2dpolyrange,check)262 TEST_F(b2dpolyrange, check)
263 {
264 B2DPolyRange aRange;
265 aRange.appendElement(B2DRange(0,0,1,1),ORIENTATION_POSITIVE);
266 aRange.appendElement(B2DRange(2,2,3,3),ORIENTATION_POSITIVE);
267
268 ASSERT_TRUE(aRange.count() == 2) << "simple poly range - count";
269 ASSERT_TRUE(aRange.getElement(0).head == B2DRange(0,0,1,1)) << "simple poly range - first element";
270 ASSERT_TRUE(aRange.getElement(1).head == B2DRange(2,2,3,3)) << "simple poly range - second element";
271
272 // B2DPolyRange relies on correctly orientated rects
273 const B2DRange aRect(0,0,1,1);
274 ASSERT_TRUE(tools::getOrientation(tools::createPolygonFromRect(aRect)) == ORIENTATION_POSITIVE ) <<
275 "createPolygonFromRect - correct orientation";
276 }
277
278
279 class b2dbeziertools : public ::testing::Test
280 {
281 protected:
282 B2DCubicBezier aHalfCircle; // not exactly, but a look-alike
283 B2DCubicBezier aQuarterCircle; // not exactly, but a look-alike
284 B2DCubicBezier aLoop; // identical endpoints, curve goes back to where it started
285 B2DCubicBezier aStraightLineDistinctEndPoints; // truly a line
286 B2DCubicBezier aStraightLineDistinctEndPoints2; // truly a line, with slightly different control points
287 B2DCubicBezier aStraightLineIdenticalEndPoints; // degenerate case of aLoop
288 B2DCubicBezier aStraightLineIdenticalEndPoints2;// degenerate case of aLoop, with slightly different control points
289 B2DCubicBezier aCrossing; // curve self-intersects somewhere in the middle
290 B2DCubicBezier aCusp; // curve has a point of undefined tangency
291
292
293 public:
294 // initialise your test code values here.
SetUp()295 virtual void SetUp()
296 {
297 const B2DPoint a00(0.0, 0.0);
298 const B2DPoint a10(1.0, 0.0);
299 const B2DPoint a11(1.0, 1.0);
300 const B2DPoint a01(0.0, 1.0);
301 const B2DPoint middle( 0.5, 0.5 );
302 const B2DPoint quarterDown( 0.25, 0.25 );
303 const B2DPoint quarterUp( 0.75, 0.75 );
304
305 aHalfCircle = B2DCubicBezier(a00, a01, a11, a10);
306
307 // The spline control points become
308 //
309 // (R * cos(A), R * sin(A))
310 // (R * cos(A) - h * sin(A), R * sin(A) + h * cos (A))
311 // (R * cos(B) + h * sin(B), R * sin(B) - h * cos (B))
312 // (R * cos(B), R * sin(B))
313 //
314 // where h = 4/3 * R * tan ((B-A)/4)
315 //
316 // with R being the radius, A start angle and B end angle (A < B).
317 //
318 // (This calculation courtesy Carl Worth, himself based on
319 // Michael Goldapp and Dokken/Daehlen)
320
321 // Choosing R=1, A=0, B=pi/2
322 const double h( 4.0/3.0 * tan(M_PI/8.0) );
323 aQuarterCircle = B2DCubicBezier(a10 + B2DPoint(1.0,0.0),
324 B2DPoint(B2DPoint( 1.0, h ) + B2DPoint(1.0,0.0)),
325 B2DPoint(B2DPoint( h, 1.0) + B2DPoint(1.0,0.0)),
326 a01 + B2DPoint(1.0,0.0));
327
328 aCusp = B2DCubicBezier(a00 + B2DPoint(2.0,0.0),
329 B2DPoint(a11 + B2DPoint(2.0,0.0)),
330 B2DPoint(a01 + B2DPoint(2.0,0.0)),
331 a10 + B2DPoint(2.0,0.0));
332
333 aLoop = B2DCubicBezier(a00 + B2DPoint(3.0,0.0),
334 B2DPoint(a01 + B2DPoint(3.0,0.0)),
335 B2DPoint(a10 + B2DPoint(3.0,0.0)),
336 a00 + B2DPoint(3.0,0.0));
337
338 aStraightLineDistinctEndPoints = B2DCubicBezier(a00 + B2DPoint(4.0,0.0),
339 B2DPoint(middle + B2DPoint(4.0,0.0)),
340 B2DPoint(middle + B2DPoint(4.0,0.0)),
341 a11 + B2DPoint(4.0,0.0));
342
343 aStraightLineDistinctEndPoints2 = B2DCubicBezier(a00 + B2DPoint(5.0,0.0),
344 B2DPoint(quarterDown + B2DPoint(5.0,0.0)),
345 B2DPoint(quarterUp + B2DPoint(5.0,0.0)),
346 a11 + B2DPoint(5.0,0.0));
347
348 aStraightLineIdenticalEndPoints = B2DCubicBezier(a00 + B2DPoint(6.0,0.0),
349 B2DPoint(a11 + B2DPoint(6.0,0.0)),
350 B2DPoint(a11 + B2DPoint(6.0,0.0)),
351 a00 + B2DPoint(6.0,0.0));
352
353 aStraightLineIdenticalEndPoints2 = B2DCubicBezier(a00 + B2DPoint(7.0,0.0),
354 B2DPoint(quarterDown + B2DPoint(7.0,0.0)),
355 B2DPoint(quarterUp + B2DPoint(7.0,0.0)),
356 a00 + B2DPoint(7.0,0.0));
357
358 aCrossing = B2DCubicBezier(a00 + B2DPoint(8.0,0.0),
359 B2DPoint(B2DPoint(2.0,2.0) + B2DPoint(8.0,0.0)),
360 B2DPoint(B2DPoint(-1.0,2.0) + B2DPoint(8.0,0.0)),
361 a10 + B2DPoint(8.0,0.0));
362
363 ::std::ofstream output("bez_testcases.gnuplot");
364 DebugPlotter aPlotter( "Original curves",
365 output );
366
367 aPlotter.plot( aHalfCircle,
368 "half circle" );
369 aPlotter.plot( aQuarterCircle,
370 "quarter circle" );
371 aPlotter.plot( aCusp,
372 "cusp" );
373 aPlotter.plot( aLoop,
374 "loop" );
375 aPlotter.plot( aStraightLineDistinctEndPoints,
376 "straight line 0" );
377 aPlotter.plot( aStraightLineDistinctEndPoints2,
378 "straight line 1" );
379 aPlotter.plot( aStraightLineIdenticalEndPoints,
380 "straight line 2" );
381 aPlotter.plot( aStraightLineIdenticalEndPoints2,
382 "straight line 3" );
383 aPlotter.plot( aCrossing,
384 "crossing" );
385
386 // break up a complex bezier (loopy, spiky or self intersecting)
387 // into simple segments (left to right)
388 B2DCubicBezier aSegment = aCrossing;
389 double fExtremePos(0.0);
390
391 aPlotter.plot( aSegment, "segment" );
392 while(aSegment.getMinimumExtremumPosition(fExtremePos))
393 {
394 aSegment.split(fExtremePos, 0, &aSegment);
395 aPlotter.plot( aSegment, "segment" );
396 }
397 }
398
TearDown()399 virtual void TearDown()
400 {
401 }
402 }; // class b2dbeziertools
403
TEST_F(b2dbeziertools,adaptiveByDistance)404 TEST_F(b2dbeziertools, adaptiveByDistance)
405 {
406 ::std::ofstream output("bez_adaptiveByDistance.gnuplot");
407 DebugPlotter aPlotter( "distance-adaptive subdivision",
408 output );
409
410 const double fBound( 0.0001 );
411 B2DPolygon result;
412
413 aHalfCircle.adaptiveSubdivideByDistance(result, fBound);
414 aPlotter.plot(result,
415 "half circle"); result.clear();
416
417 aQuarterCircle.adaptiveSubdivideByDistance(result, fBound);
418 aPlotter.plot(result,
419 "quarter circle"); result.clear();
420
421 aLoop.adaptiveSubdivideByDistance(result, fBound);
422 aPlotter.plot(result,
423 "loop"); result.clear();
424
425 aStraightLineDistinctEndPoints.adaptiveSubdivideByDistance(result, fBound);
426 aPlotter.plot(result,
427 "straight line 0"); result.clear();
428
429 aStraightLineDistinctEndPoints2.adaptiveSubdivideByDistance(result, fBound);
430 aPlotter.plot(result,
431 "straight line 1"); result.clear();
432
433 aStraightLineIdenticalEndPoints.adaptiveSubdivideByDistance(result, fBound);
434 aPlotter.plot(result,
435 "straight line 2"); result.clear();
436
437 aStraightLineIdenticalEndPoints2.adaptiveSubdivideByDistance(result, fBound);
438 aPlotter.plot(result,
439 "straight line 3"); result.clear();
440
441 aCrossing.adaptiveSubdivideByDistance(result, fBound);
442 aPlotter.plot(result,
443 "straight line 4"); result.clear();
444
445 aCusp.adaptiveSubdivideByDistance(result, fBound);
446 aPlotter.plot(result,
447 "straight line 5"); result.clear();
448
449 ASSERT_TRUE( true ) << "adaptiveByDistance";
450 }
451
TEST_F(b2dbeziertools,adaptiveByAngle)452 TEST_F(b2dbeziertools, adaptiveByAngle)
453 {
454 const double fBound( 5.0 );
455 B2DPolygon result;
456
457 ::std::ofstream output("bez_adaptiveByAngle.gnuplot");
458 DebugPlotter aPlotter( "angle-adaptive subdivision",
459 output );
460
461 aHalfCircle.adaptiveSubdivideByAngle(result, fBound, true);
462 aPlotter.plot(result,
463 "half circle"); result.clear();
464
465 aQuarterCircle.adaptiveSubdivideByAngle(result, fBound, true);
466 aPlotter.plot(result,
467 "quarter cirle"); result.clear();
468
469 aLoop.adaptiveSubdivideByAngle(result, fBound, true);
470 aPlotter.plot(result,
471 "loop"); result.clear();
472
473 aStraightLineDistinctEndPoints.adaptiveSubdivideByAngle(result, fBound, true);
474 aPlotter.plot(result,
475 "straight line 0"); result.clear();
476
477 aStraightLineDistinctEndPoints2.adaptiveSubdivideByAngle(result, fBound, true);
478 aPlotter.plot(result,
479 "straight line 1"); result.clear();
480
481 aStraightLineIdenticalEndPoints.adaptiveSubdivideByAngle(result, fBound, true);
482 aPlotter.plot(result,
483 "straight line 2"); result.clear();
484
485 aStraightLineIdenticalEndPoints2.adaptiveSubdivideByAngle(result, fBound, true);
486 aPlotter.plot(result,
487 "straight line 3"); result.clear();
488
489 aCrossing.adaptiveSubdivideByAngle(result, fBound, true);
490 aPlotter.plot(result,
491 "straight line 4"); result.clear();
492
493 aCusp.adaptiveSubdivideByAngle(result, fBound, true);
494 aPlotter.plot(result,
495 "straight line 5"); result.clear();
496
497 ASSERT_TRUE( true ) << "adaptiveByAngle";
498 }
499
500
501 class b2dcubicbezier : public ::testing::Test
502 {
503 public:
504 // initialise your test code values here.
SetUp()505 virtual void SetUp()
506 {
507 }
508
TearDown()509 virtual void TearDown()
510 {
511 }
512 }; // class b2dcubicbezier
513
514
515 class b2dhommatrix : public ::testing::Test
516 {
517 protected:
518 B2DHomMatrix maIdentity;
519 B2DHomMatrix maScale;
520 B2DHomMatrix maTranslate;
521 B2DHomMatrix maShear;
522 B2DHomMatrix maAffine;
523 B2DHomMatrix maPerspective;
524
525 public:
526 // initialise your test code values here.
SetUp()527 virtual void SetUp()
528 {
529 // setup some test matrices
530 maIdentity.identity(); // force compact layout
531 maIdentity.set(0,0, 1.0);
532 maIdentity.set(0,1, 0.0);
533 maIdentity.set(0,2, 0.0);
534 maIdentity.set(1,0, 0.0);
535 maIdentity.set(1,1, 1.0);
536 maIdentity.set(1,2, 0.0);
537
538 maScale.identity(); // force compact layout
539 maScale.set(0,0, 2.0);
540 maScale.set(1,1, 20.0);
541
542 maTranslate.identity(); // force compact layout
543 maTranslate.set(0,2, 20.0);
544 maTranslate.set(1,2, 2.0);
545
546 maShear.identity(); // force compact layout
547 maShear.set(0,1, 3.0);
548 maShear.set(1,0, 7.0);
549 maShear.set(1,1, 22.0);
550
551 maAffine.identity(); // force compact layout
552 maAffine.set(0,0, 1.0);
553 maAffine.set(0,1, 2.0);
554 maAffine.set(0,2, 3.0);
555 maAffine.set(1,0, 4.0);
556 maAffine.set(1,1, 5.0);
557 maAffine.set(1,2, 6.0);
558
559 maPerspective.set(0,0, 1.0);
560 maPerspective.set(0,1, 2.0);
561 maPerspective.set(0,2, 3.0);
562 maPerspective.set(1,0, 4.0);
563 maPerspective.set(1,1, 5.0);
564 maPerspective.set(1,2, 6.0);
565 maPerspective.set(2,0, 7.0);
566 maPerspective.set(2,1, 8.0);
567 maPerspective.set(2,2, 9.0);
568 }
569
TearDown()570 virtual void TearDown()
571 {
572 }
573
impFillMatrix(B2DHomMatrix & rSource,double fScaleX,double fScaleY,double fShearX,double fRotate)574 void impFillMatrix(B2DHomMatrix& rSource, double fScaleX, double fScaleY, double fShearX, double fRotate)
575 {
576 // fill rSource with a linear combination of scale, shear and rotate
577 rSource.identity();
578 rSource.scale(fScaleX, fScaleY);
579 rSource.shearX(fShearX);
580 rSource.rotate(fRotate);
581 }
582
impDecomposeComposeTest(double fScaleX,double fScaleY,double fShearX,double fRotate)583 bool impDecomposeComposeTest(double fScaleX, double fScaleY, double fShearX, double fRotate)
584 {
585 // linear combine matrix with given values
586 B2DHomMatrix aSource;
587 impFillMatrix(aSource, fScaleX, fScaleY, fShearX, fRotate);
588
589 // decompose that matrix
590 B2DTuple aDScale;
591 B2DTuple aDTrans;
592 double fDRot;
593 double fDShX;
594 bool bWorked = aSource.decompose(aDScale, aDTrans, fDRot, fDShX);
595
596 // linear combine another matrix with decomposition results
597 B2DHomMatrix aRecombined;
598 impFillMatrix(aRecombined, aDScale.getX(), aDScale.getY(), fDShX, fDRot);
599
600 // if decomposition worked, matrices need to be the same
601 return bWorked && aSource == aRecombined;
602 }
603 }; // class b2dhommatrix
604
605
TEST_F(b2dhommatrix,equal)606 TEST_F(b2dhommatrix, equal)
607 {
608 B2DHomMatrix aIdentity;
609 B2DHomMatrix aScale;
610 B2DHomMatrix aTranslate;
611 B2DHomMatrix aShear;
612 B2DHomMatrix aAffine;
613 B2DHomMatrix aPerspective;
614
615 // setup some test matrices
616 aIdentity.identity(); // force compact layout
617 aIdentity.set(0,0, 1.0);
618 aIdentity.set(0,1, 0.0);
619 aIdentity.set(0,2, 0.0);
620 aIdentity.set(1,0, 0.0);
621 aIdentity.set(1,1, 1.0);
622 aIdentity.set(1,2, 0.0);
623
624 aScale.identity(); // force compact layout
625 aScale.set(0,0, 2.0);
626 aScale.set(1,1, 20.0);
627
628 aTranslate.identity(); // force compact layout
629 aTranslate.set(0,2, 20.0);
630 aTranslate.set(1,2, 2.0);
631
632 aShear.identity(); // force compact layout
633 aShear.set(0,1, 3.0);
634 aShear.set(1,0, 7.0);
635 aShear.set(1,1, 22.0);
636
637 aAffine.identity(); // force compact layout
638 aAffine.set(0,0, 1.0);
639 aAffine.set(0,1, 2.0);
640 aAffine.set(0,2, 3.0);
641 aAffine.set(1,0, 4.0);
642 aAffine.set(1,1, 5.0);
643 aAffine.set(1,2, 6.0);
644
645 aPerspective.set(0,0, 1.0);
646 aPerspective.set(0,1, 2.0);
647 aPerspective.set(0,2, 3.0);
648 aPerspective.set(1,0, 4.0);
649 aPerspective.set(1,1, 5.0);
650 aPerspective.set(1,2, 6.0);
651 aPerspective.set(2,0, 7.0);
652 aPerspective.set(2,1, 8.0);
653 aPerspective.set(2,2, 9.0);
654
655 ASSERT_TRUE(aIdentity == maIdentity) << "operator==: identity matrix";
656 ASSERT_TRUE(aScale == maScale) << "operator==: scale matrix";
657 ASSERT_TRUE(aTranslate == maTranslate) << "operator==: translate matrix";
658 ASSERT_TRUE(aShear == maShear) << "operator==: shear matrix";
659 ASSERT_TRUE(aAffine == maAffine) << "operator==: affine matrix";
660 ASSERT_TRUE(aPerspective == maPerspective) << "operator==: perspective matrix";
661 }
662
TEST_F(b2dhommatrix,identity)663 TEST_F(b2dhommatrix, identity)
664 {
665 B2DHomMatrix ident;
666
667 ASSERT_TRUE(maIdentity == ident) << "identity";
668 }
669
TEST_F(b2dhommatrix,scale)670 TEST_F(b2dhommatrix, scale)
671 {
672 B2DHomMatrix mat;
673 mat.scale(2.0,20.0);
674 ASSERT_TRUE(maScale == mat) << "scale";
675 }
676
TEST_F(b2dhommatrix,translate)677 TEST_F(b2dhommatrix, translate)
678 {
679 B2DHomMatrix mat;
680 mat.translate(20.0,2.0);
681 ASSERT_TRUE(maTranslate == mat) << "translate";
682 }
683
TEST_F(b2dhommatrix,shear)684 TEST_F(b2dhommatrix, shear)
685 {
686 B2DHomMatrix mat;
687 mat.shearX(3.0);
688 mat.shearY(7.0);
689 ASSERT_TRUE(maShear == mat) << "translate";
690 }
691
TEST_F(b2dhommatrix,multiply)692 TEST_F(b2dhommatrix, multiply)
693 {
694 B2DHomMatrix affineAffineProd;
695
696 affineAffineProd.set(0,0, 9);
697 affineAffineProd.set(0,1, 12);
698 affineAffineProd.set(0,2, 18);
699 affineAffineProd.set(1,0, 24);
700 affineAffineProd.set(1,1, 33);
701 affineAffineProd.set(1,2, 48);
702
703 B2DHomMatrix affinePerspectiveProd;
704
705 affinePerspectiveProd.set(0,0, 30);
706 affinePerspectiveProd.set(0,1, 36);
707 affinePerspectiveProd.set(0,2, 42);
708 affinePerspectiveProd.set(1,0, 66);
709 affinePerspectiveProd.set(1,1, 81);
710 affinePerspectiveProd.set(1,2, 96);
711 affinePerspectiveProd.set(2,0, 7);
712 affinePerspectiveProd.set(2,1, 8);
713 affinePerspectiveProd.set(2,2, 9);
714
715 B2DHomMatrix perspectiveAffineProd;
716
717 perspectiveAffineProd.set(0,0, 9);
718 perspectiveAffineProd.set(0,1, 12);
719 perspectiveAffineProd.set(0,2, 18);
720 perspectiveAffineProd.set(1,0, 24);
721 perspectiveAffineProd.set(1,1, 33);
722 perspectiveAffineProd.set(1,2, 48);
723 perspectiveAffineProd.set(2,0, 39);
724 perspectiveAffineProd.set(2,1, 54);
725 perspectiveAffineProd.set(2,2, 78);
726
727 B2DHomMatrix perspectivePerspectiveProd;
728
729 perspectivePerspectiveProd.set(0,0, 30);
730 perspectivePerspectiveProd.set(0,1, 36);
731 perspectivePerspectiveProd.set(0,2, 42);
732 perspectivePerspectiveProd.set(1,0, 66);
733 perspectivePerspectiveProd.set(1,1, 81);
734 perspectivePerspectiveProd.set(1,2, 96);
735 perspectivePerspectiveProd.set(2,0, 102);
736 perspectivePerspectiveProd.set(2,1, 126);
737 perspectivePerspectiveProd.set(2,2, 150);
738
739 B2DHomMatrix temp;
740
741 temp = maAffine;
742 temp*=maAffine;
743 ASSERT_TRUE(temp == affineAffineProd) << "multiply: both compact";
744
745 temp = maPerspective;
746 temp*=maAffine;
747 ASSERT_TRUE(temp == affinePerspectiveProd) << "multiply: first compact";
748
749 temp = maAffine;
750 temp*=maPerspective;
751 ASSERT_TRUE(temp == perspectiveAffineProd) << "multiply: second compact";
752
753 temp = maPerspective;
754 temp*=maPerspective;
755 ASSERT_TRUE(temp == perspectivePerspectiveProd) << "multiply: none compact";
756 }
757
758
TEST_F(b2dhommatrix,decompose)759 TEST_F(b2dhommatrix, decompose)
760 {
761 // test matrix decompositions. Each matrix decomposed and rebuilt
762 // using the decompose result should be the same as before. Test
763 // with all ranges of values. Translations are not tested since these
764 // are just the two rightmost values and uncritical
765 static double fSX(10.0);
766 static double fSY(12.0);
767 static double fR(45.0 * F_PI180);
768 static double fS(15.0 * F_PI180);
769
770 // check all possible scaling combinations
771 ASSERT_TRUE(impDecomposeComposeTest(fSX, fSY, 0.0, 0.0)) << "decompose: error test A1";
772 ASSERT_TRUE(impDecomposeComposeTest(-fSX, fSY, 0.0, 0.0)) << "decompose: error test A2";
773 ASSERT_TRUE(impDecomposeComposeTest(fSX, -fSY, 0.0, 0.0)) << "decompose: error test A3";
774 ASSERT_TRUE(impDecomposeComposeTest(-fSX, -fSY, 0.0, 0.0)) << "decompose: error test A4";
775
776 // check all possible scaling combinations with positive rotation
777 ASSERT_TRUE(impDecomposeComposeTest(fSX, fSY, 0.0, fR)) << "decompose: error test B1";
778 ASSERT_TRUE(impDecomposeComposeTest(-fSX, fSY, 0.0, fR)) << "decompose: error test B2";
779 ASSERT_TRUE(impDecomposeComposeTest(fSX, -fSY, 0.0, fR)) << "decompose: error test B3";
780 ASSERT_TRUE(impDecomposeComposeTest(-fSX, -fSY, 0.0, fR)) << "decompose: error test B4";
781
782 // check all possible scaling combinations with negative rotation
783 ASSERT_TRUE(impDecomposeComposeTest(fSX, fSY, 0.0, -fR)) << "decompose: error test C1";
784 ASSERT_TRUE(impDecomposeComposeTest(-fSX, fSY, 0.0, -fR)) << "decompose: error test C2";
785 ASSERT_TRUE(impDecomposeComposeTest(fSX, -fSY, 0.0, -fR)) << "decompose: error test C3";
786 ASSERT_TRUE(impDecomposeComposeTest(-fSX, -fSY, 0.0, -fR)) << "decompose: error test C4";
787
788 // check all possible scaling combinations with positive shear
789 ASSERT_TRUE(impDecomposeComposeTest(fSX, fSY, tan(fS), 0.0)) << "decompose: error test D1";
790 ASSERT_TRUE(impDecomposeComposeTest(-fSX, fSY, tan(fS), 0.0)) << "decompose: error test D2";
791 ASSERT_TRUE(impDecomposeComposeTest(fSX, -fSY, tan(fS), 0.0)) << "decompose: error test D3";
792 ASSERT_TRUE(impDecomposeComposeTest(-fSX, -fSY, tan(fS), 0.0)) << "decompose: error test D4";
793
794 // check all possible scaling combinations with negative shear
795 ASSERT_TRUE(impDecomposeComposeTest(fSX, fSY, tan(-fS), 0.0)) << "decompose: error test E1";
796 ASSERT_TRUE(impDecomposeComposeTest(-fSX, fSY, tan(-fS), 0.0)) << "decompose: error test E2";
797 ASSERT_TRUE(impDecomposeComposeTest(fSX, -fSY, tan(-fS), 0.0)) << "decompose: error test E3";
798 ASSERT_TRUE(impDecomposeComposeTest(-fSX, -fSY, tan(-fS), 0.0)) << "decompose: error test E4";
799
800 // check all possible scaling combinations with positive rotate and positive shear
801 ASSERT_TRUE(impDecomposeComposeTest(fSX, fSY, tan(fS), fR)) << "decompose: error test F1";
802 ASSERT_TRUE(impDecomposeComposeTest(-fSX, fSY, tan(fS), fR)) << "decompose: error test F2";
803 ASSERT_TRUE(impDecomposeComposeTest(fSX, -fSY, tan(fS), fR)) << "decompose: error test F3";
804 ASSERT_TRUE(impDecomposeComposeTest(-fSX, -fSY, tan(fS), fR)) << "decompose: error test F4";
805
806 // check all possible scaling combinations with negative rotate and positive shear
807 ASSERT_TRUE(impDecomposeComposeTest(fSX, fSY, tan(fS), -fR)) << "decompose: error test G1";
808 ASSERT_TRUE(impDecomposeComposeTest(-fSX, fSY, tan(fS), -fR)) << "decompose: error test G2";
809 ASSERT_TRUE(impDecomposeComposeTest(fSX, -fSY, tan(fS), -fR)) << "decompose: error test G3";
810 ASSERT_TRUE(impDecomposeComposeTest(-fSX, -fSY, tan(fS), -fR)) << "decompose: error test G4";
811
812 // check all possible scaling combinations with positive rotate and negative shear
813 ASSERT_TRUE(impDecomposeComposeTest(fSX, fSY, tan(-fS), fR)) << "decompose: error test H1";
814 ASSERT_TRUE(impDecomposeComposeTest(-fSX, fSY, tan(-fS), fR)) << "decompose: error test H2";
815 ASSERT_TRUE(impDecomposeComposeTest(fSX, -fSY, tan(-fS), fR)) << "decompose: error test H3";
816 ASSERT_TRUE(impDecomposeComposeTest(-fSX, -fSY, tan(-fS), fR)) << "decompose: error test H4";
817
818 // check all possible scaling combinations with negative rotate and negative shear
819 ASSERT_TRUE(impDecomposeComposeTest(fSX, fSY, tan(-fS), -fR)) << "decompose: error test I1";
820 ASSERT_TRUE(impDecomposeComposeTest(-fSX, fSY, tan(-fS), -fR)) << "decompose: error test I2";
821 ASSERT_TRUE(impDecomposeComposeTest(fSX, -fSY, tan(-fS), -fR)) << "decompose: error test I3";
822 ASSERT_TRUE(impDecomposeComposeTest(-fSX, -fSY, tan(-fS), -fR)) << "decompose: error test I4";
823 }
824
825
826 class b2dhompoint : public ::testing::Test
827 {
828 public:
829 // initialise your test code values here.
SetUp()830 virtual void SetUp()
831 {
832 }
833
TearDown()834 virtual void TearDown()
835 {
836 }
837 }; // class b2dhompoint
838
839
840 class b2dpoint : public ::testing::Test
841 {
842 public:
843 // initialise your test code values here.
SetUp()844 virtual void SetUp()
845 {
846 }
847
TearDown()848 virtual void TearDown()
849 {
850 }
851 }; // class b2dpoint
852
853
854 class b2dpolygon : public ::testing::Test
855 {
856 public:
857 // initialise your test code values here.
SetUp()858 virtual void SetUp()
859 {
860 }
861
TearDown()862 virtual void TearDown()
863 {
864 }
865 }; // class b2dpolygon
866
TEST_F(b2dpolygon,testBasics)867 TEST_F(b2dpolygon, testBasics)
868 {
869 B2DPolygon aPoly;
870
871 aPoly.appendBezierSegment(B2DPoint(1,1),B2DPoint(2,2),B2DPoint(3,3));
872
873 ASSERT_TRUE(aPoly.getB2DPoint(0) == B2DPoint(3,3)) << "#1 first polygon point wrong";
874 ASSERT_TRUE(aPoly.getPrevControlPoint(0) == B2DPoint(2,2)) << "#1 first control point wrong";
875 ASSERT_TRUE(aPoly.getNextControlPoint(0) == B2DPoint(3,3)) << "#1 second control point wrong";
876 ASSERT_TRUE(aPoly.isNextControlPointUsed(0) == false) << "next control point not used";
877
878 aPoly.setNextControlPoint(0,B2DPoint(4,4));
879 ASSERT_TRUE(aPoly.getNextControlPoint(0) == B2DPoint(4,4)) << "#1.1 second control point wrong";
880 ASSERT_TRUE(aPoly.isNextControlPointUsed(0) == true) << "next control point used";
881 ASSERT_TRUE(aPoly.areControlPointsUsed() == true) << "areControlPointsUsed() wrong";
882 ASSERT_TRUE(aPoly.getContinuityInPoint(0) == CONTINUITY_C2) << "getContinuityInPoint() wrong";
883
884 aPoly.resetControlPoints();
885 ASSERT_TRUE(aPoly.getB2DPoint(0) == B2DPoint(3,3)) << "resetControlPoints() did not clear";
886 ASSERT_TRUE(aPoly.getPrevControlPoint(0) == B2DPoint(3,3)) << "resetControlPoints() did not clear";
887 ASSERT_TRUE(aPoly.getNextControlPoint(0) == B2DPoint(3,3)) << "resetControlPoints() did not clear";
888 ASSERT_TRUE(aPoly.areControlPointsUsed() == false) << "areControlPointsUsed() wrong #2";
889
890 aPoly.clear();
891 aPoly.append(B2DPoint(0,0));
892 aPoly.appendBezierSegment(B2DPoint(1,1),B2DPoint(2,2),B2DPoint(3,3));
893
894 ASSERT_TRUE(aPoly.getB2DPoint(0) == B2DPoint(0,0)) << "#2 first polygon point wrong";
895 ASSERT_TRUE(aPoly.getPrevControlPoint(0) == B2DPoint(0,0)) << "#2 first control point wrong";
896 ASSERT_TRUE(aPoly.getNextControlPoint(0) == B2DPoint(1,1)) << "#2 second control point wrong";
897 ASSERT_TRUE(aPoly.getPrevControlPoint(1) == B2DPoint(2,2)) << "#2 third control point wrong";
898 ASSERT_TRUE(aPoly.getNextControlPoint(1) == B2DPoint(3,3)) << "#2 fourth control point wrong";
899 ASSERT_TRUE(aPoly.getB2DPoint(1) == B2DPoint(3,3)) << "#2 second polygon point wrong";
900 }
901
902 class b2dpolygontools : public ::testing::Test
903 {
904 public:
905 // initialise your test code values here.
SetUp()906 virtual void SetUp()
907 {
908 }
909
TearDown()910 virtual void TearDown()
911 {
912 }
913 }; // class b2dpolygontools
914
TEST_F(b2dpolygontools,testIsRectangle)915 TEST_F(b2dpolygontools, testIsRectangle)
916 {
917 B2DPolygon aRect1(
918 tools::createPolygonFromRect(
919 B2DRange(0,0,1,1) ) );
920
921 B2DPolygon aRect2;
922 aRect2.append( B2DPoint(0,0) );
923 aRect2.append( B2DPoint(1,0) );
924 aRect2.append( B2DPoint(1,.5));
925 aRect2.append( B2DPoint(1,1) );
926 aRect2.append( B2DPoint(0,1) );
927 aRect2.setClosed(true);
928
929 B2DPolygon aNonRect1;
930 aNonRect1.append( B2DPoint(0,0) );
931 aNonRect1.append( B2DPoint(1,0) );
932 aNonRect1.append( B2DPoint(1,1) );
933 aNonRect1.append( B2DPoint(0.5,1) );
934 aNonRect1.append( B2DPoint(0.5,0) );
935 aNonRect1.setClosed(true);
936
937 B2DPolygon aNonRect2;
938 aNonRect2.append( B2DPoint(0,0) );
939 aNonRect2.append( B2DPoint(1,1) );
940 aNonRect2.append( B2DPoint(1,0) );
941 aNonRect2.append( B2DPoint(0,1) );
942 aNonRect2.setClosed(true);
943
944 B2DPolygon aNonRect3;
945 aNonRect3.append( B2DPoint(0,0) );
946 aNonRect3.append( B2DPoint(1,0) );
947 aNonRect3.append( B2DPoint(1,1) );
948 aNonRect3.setClosed(true);
949
950 B2DPolygon aNonRect4;
951 aNonRect4.append( B2DPoint(0,0) );
952 aNonRect4.append( B2DPoint(1,0) );
953 aNonRect4.append( B2DPoint(1,1) );
954 aNonRect4.append( B2DPoint(0,1) );
955
956 B2DPolygon aNonRect5;
957 aNonRect5.append( B2DPoint(0,0) );
958 aNonRect5.append( B2DPoint(1,0) );
959 aNonRect5.append( B2DPoint(1,1) );
960 aNonRect5.append( B2DPoint(0,1) );
961 aNonRect5.setControlPoints(1,B2DPoint(1,0),B2DPoint(-11,0));
962 aNonRect5.setClosed(true);
963
964 ASSERT_TRUE(tools::isRectangle( aRect1 )) << "checking rectangle-ness of rectangle 1";
965 ASSERT_TRUE(tools::isRectangle( aRect2 )) << "checking rectangle-ness of rectangle 2";
966 ASSERT_TRUE(!tools::isRectangle( aNonRect1 )) << "checking non-rectangle-ness of polygon 1";
967 ASSERT_TRUE(!tools::isRectangle( aNonRect2 )) << "checking non-rectangle-ness of polygon 2";
968 ASSERT_TRUE(!tools::isRectangle( aNonRect3 )) << "checking non-rectangle-ness of polygon 3";
969 ASSERT_TRUE(!tools::isRectangle( aNonRect4 )) << "checking non-rectangle-ness of polygon 4";
970 ASSERT_TRUE(!tools::isRectangle( aNonRect5 )) << "checking non-rectangle-ness of polygon 5";
971 }
972
973 class b2dpolypolygon : public ::testing::Test
974 {
975 public:
976 // initialise your test code values here.
SetUp()977 virtual void SetUp()
978 {
979 }
980
TearDown()981 virtual void TearDown()
982 {
983 }
984 }; // class b2dpolypolygon
985
986
987 class b2dquadraticbezier : public ::testing::Test
988 {
989 public:
990 // initialise your test code values here.
SetUp()991 virtual void SetUp()
992 {
993 }
994
TearDown()995 virtual void TearDown()
996 {
997 }
998 }; // class b2dquadraticbezier
999
1000
1001 class b2drange : public ::testing::Test
1002 {
1003 public:
1004 // initialise your test code values here.
SetUp()1005 virtual void SetUp()
1006 {
1007 }
1008
TearDown()1009 virtual void TearDown()
1010 {
1011 }
1012 }; // class b2drange
1013
1014
1015 class b2dtuple : public ::testing::Test
1016 {
1017 public:
1018 // initialise your test code values here.
SetUp()1019 virtual void SetUp()
1020 {
1021 }
1022
TearDown()1023 virtual void TearDown()
1024 {
1025 }
1026 }; // class b2dtuple
1027
1028
1029 class b2dvector : public ::testing::Test
1030 {
1031 public:
1032 // initialise your test code values here.
SetUp()1033 virtual void SetUp()
1034 {
1035 }
1036
TearDown()1037 virtual void TearDown()
1038 {
1039 }
1040 }; // class b2dvector
1041
1042 class bcolor : public ::testing::Test
1043 {
1044 protected:
1045 BColor maWhite;
1046 BColor maBlack;
1047 BColor maRed;
1048 BColor maGreen;
1049 BColor maBlue;
1050 BColor maYellow;
1051 BColor maMagenta;
1052 BColor maCyan;
1053
1054 public:
bcolor()1055 bcolor() :
1056 maWhite(1,1,1),
1057 maBlack(0,0,0),
1058 maRed(1,0,0),
1059 maGreen(0,1,0),
1060 maBlue(0,0,1),
1061 maYellow(1,1,0),
1062 maMagenta(1,0,1),
1063 maCyan(0,1,1)
1064 {}
1065
1066
1067 // initialise your test code values here.
SetUp()1068 virtual void SetUp()
1069 {
1070 }
1071
TearDown()1072 virtual void TearDown()
1073 {
1074 }
1075 }; // class bcolor
1076
TEST_F(bcolor,hslTest)1077 TEST_F(bcolor, hslTest)
1078 {
1079 ASSERT_TRUE(tools::rgb2hsl(maWhite) == BColor(0,0,1)) << "white";
1080 ASSERT_TRUE(tools::rgb2hsl(maBlack) == BColor(0,0,0)) << "black";
1081 ASSERT_TRUE(tools::rgb2hsl(maRed) == BColor(0,1,0.5)) << "red";
1082 ASSERT_TRUE(tools::rgb2hsl(maGreen) == BColor(120,1,0.5)) << "green";
1083 ASSERT_TRUE(tools::rgb2hsl(maBlue) == BColor(240,1,0.5)) << "blue";
1084 ASSERT_TRUE(tools::rgb2hsl(maYellow) == BColor(60,1,0.5)) << "yellow";
1085 ASSERT_TRUE(tools::rgb2hsl(maMagenta) == BColor(300,1,0.5)) << "magenta";
1086 ASSERT_TRUE(tools::rgb2hsl(maCyan) == BColor(180,1,0.5)) << "cyan";
1087 ASSERT_TRUE(tools::rgb2hsl(BColor(0,0.5,1)) == BColor(210,1,0.5)) << "third hue case";
1088
1089 ASSERT_TRUE(tools::hsl2rgb(tools::rgb2hsl(maWhite)) == maWhite) << "roundtrip white";
1090 ASSERT_TRUE(tools::hsl2rgb(tools::rgb2hsl(maBlack)) == maBlack) << "roundtrip black";
1091 ASSERT_TRUE(tools::hsl2rgb(tools::rgb2hsl(maRed)) == maRed) << "roundtrip red";
1092 ASSERT_TRUE(tools::hsl2rgb(tools::rgb2hsl(maGreen)) == maGreen) << "roundtrip green";
1093 ASSERT_TRUE(tools::hsl2rgb(tools::rgb2hsl(maBlue)) == maBlue) << "roundtrip blue";
1094 ASSERT_TRUE(tools::hsl2rgb(tools::rgb2hsl(maYellow)) == maYellow) << "roundtrip yellow";
1095 ASSERT_TRUE(tools::hsl2rgb(tools::rgb2hsl(maMagenta)) == maMagenta) << "roundtrip magenta";
1096 ASSERT_TRUE(tools::hsl2rgb(tools::rgb2hsl(maCyan)) == maCyan) << "roundtrip cyan";
1097
1098 ASSERT_TRUE(tools::rgb2hsl(maWhite*.1) == BColor(0,0,.1)) << "grey10";
1099 ASSERT_TRUE(tools::rgb2hsl(maWhite*.9) == BColor(0,0,.9)) << "grey90";
1100 ASSERT_TRUE(tools::rgb2hsl(maRed*.5) == BColor(0,1,0.25)) << "red/2";
1101 ASSERT_TRUE(tools::rgb2hsl(maGreen*.5) == BColor(120,1,0.25)) << "green/2";
1102 ASSERT_TRUE(tools::rgb2hsl(maBlue*.5) == BColor(240,1,0.25)) << "blue/2";
1103 ASSERT_TRUE(tools::rgb2hsl(maYellow*.5) == BColor(60,1,0.25)) << "yellow/2";
1104 ASSERT_TRUE(tools::rgb2hsl(maMagenta*.5) == BColor(300,1,0.25)) << "magenta/2";
1105 ASSERT_TRUE(tools::rgb2hsl(maCyan*.5) == BColor(180,1,0.25)) << "cyan/2";
1106
1107 ASSERT_TRUE(tools::rgb2hsl(BColor(.75,.25,.25)) == BColor(0,.5,.5)) << "pastel";
1108 }
1109
TEST_F(bcolor,hsvTest)1110 TEST_F(bcolor, hsvTest)
1111 {
1112 ASSERT_TRUE(tools::rgb2hsv(maWhite) == BColor(0,0,1)) << "white";
1113 ASSERT_TRUE(tools::rgb2hsv(maBlack) == BColor(0,0,0)) << "black";
1114 ASSERT_TRUE(tools::rgb2hsv(maRed) == BColor(0,1,1)) << "red";
1115 ASSERT_TRUE(tools::rgb2hsv(maGreen) == BColor(120,1,1)) << "green";
1116 ASSERT_TRUE(tools::rgb2hsv(maBlue) == BColor(240,1,1)) << "blue";
1117 ASSERT_TRUE(tools::rgb2hsv(maYellow) == BColor(60,1,1)) << "yellow";
1118 ASSERT_TRUE(tools::rgb2hsv(maMagenta) == BColor(300,1,1)) << "magenta";
1119 ASSERT_TRUE(tools::rgb2hsv(maCyan) == BColor(180,1,1)) << "cyan";
1120
1121 ASSERT_TRUE(tools::hsv2rgb(tools::rgb2hsv(maWhite)) == maWhite) << "roundtrip white";
1122 ASSERT_TRUE(tools::hsv2rgb(tools::rgb2hsv(maBlack)) == maBlack) << "roundtrip black";
1123 ASSERT_TRUE(tools::hsv2rgb(tools::rgb2hsv(maRed)) == maRed) << "roundtrip red";
1124 ASSERT_TRUE(tools::hsv2rgb(tools::rgb2hsv(maGreen)) == maGreen) << "roundtrip green";
1125 ASSERT_TRUE(tools::hsv2rgb(tools::rgb2hsv(maBlue)) == maBlue) << "roundtrip blue";
1126 ASSERT_TRUE(tools::hsv2rgb(tools::rgb2hsv(maYellow)) == maYellow) << "roundtrip yellow";
1127 ASSERT_TRUE(tools::hsv2rgb(tools::rgb2hsv(maMagenta)) == maMagenta) << "roundtrip magenta";
1128 ASSERT_TRUE(tools::hsv2rgb(tools::rgb2hsv(maCyan)) == maCyan) << "roundtrip cyan";
1129
1130 ASSERT_TRUE(tools::rgb2hsv(maWhite*.1) == BColor(0,0,.1)) << "grey10";
1131 ASSERT_TRUE(tools::rgb2hsv(maWhite*.9) == BColor(0,0,.9)) << "grey90";
1132 ASSERT_TRUE(tools::rgb2hsv(maRed*.5) == BColor(0,1,0.5)) << "red/2";
1133 ASSERT_TRUE(tools::rgb2hsv(maGreen*.5) == BColor(120,1,0.5)) << "green/2";
1134 ASSERT_TRUE(tools::rgb2hsv(maBlue*.5) == BColor(240,1,0.5)) << "blue/2";
1135 ASSERT_TRUE(tools::rgb2hsv(maYellow*.5) == BColor(60,1,0.5)) << "yellow/2";
1136 ASSERT_TRUE(tools::rgb2hsv(maMagenta*.5) == BColor(300,1,0.5)) << "magenta/2";
1137 ASSERT_TRUE(tools::rgb2hsv(maCyan*.5) == BColor(180,1,0.5)) << "cyan/2";
1138
1139 ASSERT_TRUE(tools::rgb2hsv(BColor(.5,.25,.25)) == BColor(0,.5,.5)) << "pastel";
1140 }
1141
TEST_F(bcolor,ciexyzTest)1142 TEST_F(bcolor, ciexyzTest)
1143 {
1144 tools::rgb2ciexyz(maWhite);
1145 tools::rgb2ciexyz(maBlack);
1146 tools::rgb2ciexyz(maRed);
1147 tools::rgb2ciexyz(maGreen);
1148 tools::rgb2ciexyz(maBlue);
1149 tools::rgb2ciexyz(maYellow);
1150 tools::rgb2ciexyz(maMagenta);
1151 tools::rgb2ciexyz(maCyan);
1152 }
1153
1154 // -----------------------------------------------------------------------------
1155
1156 } // namespace basegfx2d
1157
1158