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. 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 141 virtual void TearDown() 142 { 143 } 144 }; // class b2dsvgdimpex 145 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' statement now. 168 // 169 // The old SVGexport identified nun-used ControlVectors erroneously 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: 255 virtual void SetUp() 256 {} 257 258 virtual void TearDown() 259 {} 260 }; 261 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. 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 399 virtual void TearDown() 400 { 401 } 402 }; // class b2dbeziertools 403 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 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. 505 virtual void SetUp() 506 { 507 } 508 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. 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 570 virtual void TearDown() 571 { 572 } 573 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 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 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 663 TEST_F(b2dhommatrix, identity) 664 { 665 B2DHomMatrix ident; 666 667 ASSERT_TRUE(maIdentity == ident) << "identity"; 668 } 669 670 TEST_F(b2dhommatrix, scale) 671 { 672 B2DHomMatrix mat; 673 mat.scale(2.0,20.0); 674 ASSERT_TRUE(maScale == mat) << "scale"; 675 } 676 677 TEST_F(b2dhommatrix, translate) 678 { 679 B2DHomMatrix mat; 680 mat.translate(20.0,2.0); 681 ASSERT_TRUE(maTranslate == mat) << "translate"; 682 } 683 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 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 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. 830 virtual void SetUp() 831 { 832 } 833 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. 844 virtual void SetUp() 845 { 846 } 847 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. 858 virtual void SetUp() 859 { 860 } 861 862 virtual void TearDown() 863 { 864 } 865 }; // class b2dpolygon 866 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. 906 virtual void SetUp() 907 { 908 } 909 910 virtual void TearDown() 911 { 912 } 913 }; // class b2dpolygontools 914 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. 977 virtual void SetUp() 978 { 979 } 980 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. 991 virtual void SetUp() 992 { 993 } 994 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. 1005 virtual void SetUp() 1006 { 1007 } 1008 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. 1019 virtual void SetUp() 1020 { 1021 } 1022 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. 1033 virtual void SetUp() 1034 { 1035 } 1036 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: 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. 1068 virtual void SetUp() 1069 { 1070 } 1071 1072 virtual void TearDown() 1073 { 1074 } 1075 }; // class bcolor 1076 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 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 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