Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <sal/types.h>
30 : : #include "cppunit/TestAssert.h"
31 : : #include "cppunit/TestFixture.h"
32 : : #include "cppunit/extensions/HelperMacros.h"
33 : :
34 : : #include <basegfx/matrix/b2dhommatrix.hxx>
35 : : #include <basegfx/curve/b2dcubicbezier.hxx>
36 : : #include <basegfx/curve/b2dbeziertools.hxx>
37 : : #include <basegfx/range/b2dpolyrange.hxx>
38 : : #include <basegfx/polygon/b2dpolygon.hxx>
39 : : #include <basegfx/polygon/b2dpolygontools.hxx>
40 : : #include <basegfx/polygon/b2dpolypolygontools.hxx>
41 : : #include <basegfx/polygon/b2dpolypolygoncutter.hxx>
42 : : #include <basegfx/polygon/b2dpolygonclipper.hxx>
43 : : #include <basegfx/polygon/b2dpolypolygon.hxx>
44 : : #include <basegfx/numeric/ftools.hxx>
45 : :
46 : : #include <boost/bind.hpp>
47 : :
48 : : using namespace ::basegfx;
49 : :
50 : :
51 : : namespace basegfx2d
52 : : {
53 : : /// Gets a random ordinal [0,n)
54 : : inline double getRandomOrdinal( const ::std::size_t n )
55 : : {
56 : : // use this one when displaying polygons in OOo, which still sucks
57 : : // great rocks when trying to import non-integer svg:d attributes
58 : : // return sal_Int64(double(n) * rand() / (RAND_MAX + 1.0));
59 : : return double(n) * rand() / (RAND_MAX + 1.0);
60 : : }
61 : :
62 : 8865 : inline bool compare(const B2DPoint& left, const B2DPoint& right)
63 : : {
64 : 8865 : return left.getX()<right.getX()
65 [ + + ][ + + ]: 8865 : || (left.getX()==right.getX() && left.getY()<right.getY());
[ + + ]
66 : : }
67 : :
68 : :
69 [ + - ][ + - ]: 45 : class boxclipper : public CppUnit::TestFixture
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ - + ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
70 : : {
71 : : private:
72 : : B2DPolyRange aDisjunctRanges;
73 : : B2DPolyRange aEqualRanges;
74 : : B2DPolyRange aIntersectionN;
75 : : B2DPolyRange aIntersectionE;
76 : : B2DPolyRange aIntersectionS;
77 : : B2DPolyRange aIntersectionW;
78 : : B2DPolyRange aIntersectionNE;
79 : : B2DPolyRange aIntersectionSE;
80 : : B2DPolyRange aIntersectionSW;
81 : : B2DPolyRange aIntersectionNW;
82 : : B2DPolyRange aRingIntersection;
83 : : B2DPolyRange aRingIntersection2;
84 : : B2DPolyRange aRingIntersectExtraStrip;
85 : : B2DPolyRange aComplexIntersections;
86 : : B2DPolyRange aRandomIntersections;
87 : :
88 : : public:
89 : : // initialise your test code values here.
90 : 15 : void setUp()
91 : : {
92 [ + - ]: 15 : B2DRange aCenter(100, 100, -100, -100);
93 [ + - ]: 15 : B2DRange aOffside(800, 800, 1000, 1000);
94 [ + - ]: 15 : B2DRange aNorth(100, 0, -100, -200);
95 [ + - ]: 15 : B2DRange aSouth(100, 200, -100, 0);
96 [ + - ]: 15 : B2DRange aEast(0, 100, 200, -100);
97 [ + - ]: 15 : B2DRange aWest(-200, 100, 0, -100);
98 [ + - ]: 15 : B2DRange aNorthEast(0, 0, 200, -200);
99 [ + - ]: 15 : B2DRange aSouthEast(0, 0, 200, 200);
100 [ + - ]: 15 : B2DRange aSouthWest(0, 0, -200, 200);
101 [ + - ]: 15 : B2DRange aNorthWest(0, 0, -200, -200);
102 : :
103 [ + - ]: 15 : B2DRange aNorth2(-150, 50, 150, 350);
104 [ + - ]: 15 : B2DRange aSouth2(-150, -50, 150, -350);
105 [ + - ]: 15 : B2DRange aEast2 (50, -150, 350, 150);
106 [ + - ]: 15 : B2DRange aWest2 (-50, -150,-350, 150);
107 : :
108 [ + - ]: 15 : aDisjunctRanges.appendElement( aCenter, ORIENTATION_NEGATIVE );
109 [ + - ]: 15 : aDisjunctRanges.appendElement( aOffside, ORIENTATION_NEGATIVE );
110 : :
111 [ + - ]: 15 : aEqualRanges.appendElement( aCenter, ORIENTATION_NEGATIVE );
112 [ + - ]: 15 : aEqualRanges.appendElement( aCenter, ORIENTATION_NEGATIVE );
113 : :
114 [ + - ]: 15 : aIntersectionN.appendElement( aCenter, ORIENTATION_NEGATIVE );
115 [ + - ]: 15 : aIntersectionN.appendElement( aNorth, ORIENTATION_NEGATIVE );
116 : :
117 [ + - ]: 15 : aIntersectionE.appendElement( aCenter, ORIENTATION_NEGATIVE );
118 [ + - ]: 15 : aIntersectionE.appendElement( aEast, ORIENTATION_NEGATIVE );
119 : :
120 [ + - ]: 15 : aIntersectionS.appendElement( aCenter, ORIENTATION_NEGATIVE );
121 [ + - ]: 15 : aIntersectionS.appendElement( aSouth, ORIENTATION_NEGATIVE );
122 : :
123 [ + - ]: 15 : aIntersectionW.appendElement( aCenter, ORIENTATION_NEGATIVE );
124 [ + - ]: 15 : aIntersectionW.appendElement( aWest, ORIENTATION_NEGATIVE );
125 : :
126 [ + - ]: 15 : aIntersectionNE.appendElement( aCenter, ORIENTATION_NEGATIVE );
127 [ + - ]: 15 : aIntersectionNE.appendElement( aNorthEast, ORIENTATION_NEGATIVE );
128 : :
129 [ + - ]: 15 : aIntersectionSE.appendElement( aCenter, ORIENTATION_NEGATIVE );
130 [ + - ]: 15 : aIntersectionSE.appendElement( aSouthEast, ORIENTATION_NEGATIVE );
131 : :
132 [ + - ]: 15 : aIntersectionSW.appendElement( aCenter, ORIENTATION_NEGATIVE );
133 [ + - ]: 15 : aIntersectionSW.appendElement( aSouthWest, ORIENTATION_NEGATIVE );
134 : :
135 [ + - ]: 15 : aIntersectionNW.appendElement( aCenter, ORIENTATION_NEGATIVE );
136 [ + - ]: 15 : aIntersectionNW.appendElement( aNorthWest, ORIENTATION_NEGATIVE );
137 : :
138 [ + - ]: 15 : aRingIntersection.appendElement( aNorth2, ORIENTATION_NEGATIVE );
139 [ + - ]: 15 : aRingIntersection.appendElement( aEast2, ORIENTATION_NEGATIVE );
140 [ + - ]: 15 : aRingIntersection.appendElement( aSouth2, ORIENTATION_NEGATIVE );
141 : :
142 [ + - ]: 15 : aRingIntersection2 = aRingIntersection;
143 [ + - ]: 15 : aRingIntersection2.appendElement( aWest2, ORIENTATION_NEGATIVE );
144 : :
145 [ + - ]: 15 : aRingIntersectExtraStrip = aRingIntersection2;
146 : : aRingIntersectExtraStrip.appendElement( B2DRange(0, -25, 200, 25),
147 [ + - ][ + - ]: 15 : ORIENTATION_NEGATIVE );
148 : :
149 [ + - ]: 15 : aComplexIntersections.appendElement( aCenter, ORIENTATION_NEGATIVE );
150 [ + - ]: 15 : aComplexIntersections.appendElement( aOffside, ORIENTATION_NEGATIVE );
151 [ + - ]: 15 : aComplexIntersections.appendElement( aCenter, ORIENTATION_NEGATIVE );
152 [ + - ]: 15 : aComplexIntersections.appendElement( aNorth, ORIENTATION_NEGATIVE );
153 [ + - ]: 15 : aComplexIntersections.appendElement( aEast, ORIENTATION_NEGATIVE );
154 [ + - ]: 15 : aComplexIntersections.appendElement( aSouth, ORIENTATION_NEGATIVE );
155 [ + - ]: 15 : aComplexIntersections.appendElement( aWest, ORIENTATION_NEGATIVE );
156 [ + - ]: 15 : aComplexIntersections.appendElement( aNorthEast, ORIENTATION_NEGATIVE );
157 [ + - ]: 15 : aComplexIntersections.appendElement( aSouthEast, ORIENTATION_NEGATIVE );
158 [ + - ]: 15 : aComplexIntersections.appendElement( aSouthWest, ORIENTATION_NEGATIVE );
159 [ + - ]: 15 : aComplexIntersections.appendElement( aNorthWest, ORIENTATION_NEGATIVE );
160 : :
161 : : #ifdef GENERATE_RANDOM
162 : : for( int i=0; i<800; ++i )
163 : : {
164 : : B2DRange aRandomRange(
165 : : getRandomOrdinal( 1000 ),
166 : : getRandomOrdinal( 1000 ),
167 : : getRandomOrdinal( 1000 ),
168 : : getRandomOrdinal( 1000 ) );
169 : :
170 : : aRandomIntersections.appendElement( aRandomRange, ORIENTATION_NEGATIVE );
171 : : }
172 : : #else
173 : 15 : const char* randomSvg="m394 783h404v57h-404zm-197-505h571v576h-571zm356-634h75v200h-75zm-40-113h403v588h-403zm93-811h111v494h-111zm-364-619h562v121h-562zm-134-8h292v27h-292zm110 356h621v486h-621zm78-386h228v25h-228zm475-345h201v201h-201zm-2-93h122v126h-122zm-417-243h567v524h-567zm-266-738h863v456h-863zm262-333h315v698h-315zm-328-826h43v393h-43zm830-219h120v664h-120zm-311-636h221v109h-221zm-500 137h628v19h-628zm681-94h211v493h-211zm-366-646h384v355h-384zm-189-199h715v247h-715zm165-459h563v601h-563zm258-479h98v606h-98zm270-517h65v218h-65zm-44-259h96v286h-96zm-599-202h705v468h-705zm216-803h450v494h-450zm-150-22h26v167h-26zm-55-599h50v260h-50zm190-278h490v387h-490zm-290-453h634v392h-634zm257 189h552v300h-552zm-151-690h136v455h-136zm12-597h488v432h-488zm501-459h48v39h-48zm-224-112h429v22h-429zm-281 102h492v621h-492zm519-158h208v17h-208zm-681-563h56v427h-56zm126-451h615v392h-615zm-47-410h598v522h-598zm-32 316h79v110h-79zm-71-129h18v127h-18zm126-993h743v589h-743zm211-430h428v750h-428zm61-554h100v220h-100zm-353-49h658v157h-658zm778-383h115v272h-115zm-249-541h119v712h-119zm203 86h94v40h-94z";
174 [ + - ]: 15 : B2DPolyPolygon randomPoly;
175 : : tools::importFromSvgD(
176 : : randomPoly,
177 [ + - ]: 15 : rtl::OUString::createFromAscii(randomSvg));
178 : : std::for_each(randomPoly.begin(),
179 : : randomPoly.end(),
180 : : boost::bind(
181 : : &B2DPolyRange::appendElement,
182 : : boost::ref(aRandomIntersections),
183 : : boost::bind(
184 : : &B2DPolygon::getB2DRange,
185 : : _1),
186 : : ORIENTATION_NEGATIVE,
187 [ + - ][ + - ]: 15 : 1));
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
188 : : #endif
189 : 15 : }
190 : :
191 : 15 : void tearDown()
192 : : {
193 : 15 : }
194 : :
195 : 250 : B2DPolyPolygon normalizePoly( const B2DPolyPolygon& rPoly )
196 : : {
197 : 250 : B2DPolyPolygon aRes;
198 [ + - ][ + + ]: 1420 : for( sal_uInt32 i=0; i<rPoly.count(); ++i )
199 : : {
200 [ + - ]: 1170 : B2DPolygon aTmp=rPoly.getB2DPolygon(i);
201 [ + - ][ + + ]: 1170 : if( ORIENTATION_NEGATIVE == tools::getOrientation(aTmp) )
202 [ + - ]: 1090 : aTmp.flip();
203 : :
204 [ + - ][ + - ]: 1170 : aTmp=tools::removeNeutralPoints(aTmp);
[ + - ]
205 [ + - ][ + - ]: 1170 : std::vector<B2DPoint> aTmp2(aTmp.count());
206 [ + - ][ + + ]: 7190 : for(sal_uInt32 j=0; j<aTmp.count(); ++j)
207 [ + - ]: 6020 : aTmp2[j] = aTmp.getB2DPoint(j);
208 : :
209 : 1170 : std::vector<B2DPoint>::iterator pSmallest=aTmp2.end();
210 [ + - ][ + + ]: 7190 : for(std::vector<B2DPoint>::iterator pCurr=aTmp2.begin(); pCurr!=aTmp2.end(); ++pCurr)
211 : : {
212 [ + - ][ + + ]: 6020 : if( pSmallest == aTmp2.end() || compare(*pCurr, *pSmallest) )
[ + + ][ + - ]
[ + + # # ]
213 : : {
214 : 2340 : pSmallest=pCurr;
215 : : }
216 : : }
217 : :
218 [ + - ][ + + ]: 1170 : if( pSmallest != aTmp2.end() )
219 [ + - ]: 1150 : std::rotate(aTmp2.begin(),pSmallest,aTmp2.end());
220 : :
221 [ + - ]: 1170 : aTmp.clear();
222 [ + - ][ + + ]: 7190 : for(std::vector<B2DPoint>::iterator pCurr=aTmp2.begin(); pCurr!=aTmp2.end(); ++pCurr)
223 [ + - ]: 6020 : aTmp.append(*pCurr);
224 : :
225 [ + - ]: 1170 : aRes.append(aTmp);
226 [ + - ]: 1170 : }
227 : :
228 : : // boxclipper & generic clipper disagree slightly on area-less
229 : : // polygons (one or two points only)
230 [ + - ][ + - ]: 250 : aRes = tools::stripNeutralPolygons(aRes);
[ + - ]
231 : :
232 : : // now, sort all polygons with increasing 0th point
233 : : std::sort(aRes.begin(),
234 : : aRes.end(),
235 : : boost::bind(
236 : : &compare,
237 : : boost::bind(
238 : : &B2DPolygon::getB2DPoint,
239 : : _1,0),
240 : : boost::bind(
241 : : &B2DPolygon::getB2DPoint,
242 [ + - ][ + - ]: 250 : _2,0)));
[ + - ][ + - ]
[ + - ][ + - ]
243 : :
244 : 250 : return aRes;
245 : : }
246 : :
247 : 75 : void verifyPoly(const char* sName, const char* sSvg, const B2DPolyRange& toTest)
248 : : {
249 [ + - ]: 75 : B2DPolyPolygon aTmp1;
250 [ + - ][ + - ]: 150 : CPPUNIT_ASSERT_MESSAGE(sName,
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
251 : : tools::importFromSvgD(
252 : : aTmp1,
253 [ + - ]: 75 : rtl::OUString::createFromAscii(sSvg)));
254 : :
255 : : const rtl::OUString aSvg=
256 [ + - ][ + - ]: 75 : tools::exportToSvgD(toTest.solveCrossovers());
[ + - ]
257 [ + - ]: 75 : B2DPolyPolygon aTmp2;
258 [ + - ][ + - ]: 150 : CPPUNIT_ASSERT_MESSAGE(sName,
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
259 : : tools::importFromSvgD(
260 : : aTmp2,
261 [ + - ]: 75 : aSvg));
262 [ + - ][ + - ]: 150 : CPPUNIT_ASSERT_MESSAGE(
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
263 : : sName,
264 [ + - + - ]: 150 : normalizePoly(aTmp2) == normalizePoly(aTmp1));
[ + - ]
265 : 75 : }
266 : :
267 : 5 : void verifyPoly()
268 : : {
269 : 5 : const char* disjunct="m-100-100v200h200v-200zm900 900v200h200v-200z";
270 : 5 : const char* equal="m-100-100v200h200v-200zm200 0h-200v200h200v-200z";
271 : 5 : const char* intersectionN="m-100-100v100h200v-100zm200 0v-100h-200v100 200h200v-200z";
272 : 5 : const char* intersectionE="m0-100v200h100v-200zm0 0h-100v200h100 200v-200z";
273 : 5 : const char* intersectionS="m-100 0v100h200v-100zm0-100v200 100h200v-100-200z";
274 : 5 : const char* intersectionW="m-100-100v200h100v-200zm0 0h-100v200h100 200v-200z";
275 : 5 : const char* intersectionNE="m0-100v100h100v-100zm0-100v100h-100v200h200v-100h100v-200z";
276 : 5 : const char* intersectionSE="m0 0v100h100v-100zm100 0v-100h-200v200h100v100h200v-200z";
277 : 5 : const char* intersectionSW="m-100 0v100h100v-100zm0-100v100h-100v200h200v-100h100v-200z";
278 : 5 : const char* intersectionNW="m-100-100v100h100v-100zm100 0v-100h-200v200h100v100h200v-200z";
279 : 5 : const char* ringIntersection="m50-150v100h100v-100zm0 200v100h100v-100zm100-200v-200h-300v300h200v100h-200v300h300v-200h200v-300z";
280 : : const char* ringIntersection2="m-150 50v100h100v-100zm0-200v100h100v-100zm100 200v-100h100v100z"
281 : 5 : "m100-200v100h100v-100zm0 200v100h100v-100zm100-200v-200h-300v200h-200v300h200v200h300v-200h200v-300z";
282 : : const char* ringIntersectExtraStrip="m-150 50v100h100v-100zm0-200v100h100v-100zm100 200v-100h100v25h-50v50h50v25z"
283 : : "m100-200v100h100v-100zm0 200v100h100v-100zm0-75v50h150v-50z"
284 : 5 : "m100-125v-200h-300v200h-200v300h200v200h300v-200h200v-300z";
285 : : const char* complexIntersections="m0 0zm0 0zm0 0zm0 0v-100 100h-100 100v100-100h100zm0 0v-100 100h-100 100v100-100h100z"
286 : : "m100 0v-100h-100-100v100 100h100 100v-100zm0 0v-100h-100-100v100 100h100 100v-100z"
287 : : "m0 0v-100h-100v-100 100h-100v100h-100 100v100h100v100-100h100v-100h100z"
288 : : "m0-100v-100h-100-100v100h-100v100 100h100v100h100 100v-100h100v-100-100z"
289 : 5 : "m100 0v-100h-200-100-100v100 200 100h100 100 200v-100-200zm600 900v200h200v-200z";
290 : : const char* randomIntersections="m20-4515v393h43v-393zm34-8690v127h18v-127zm24 674v427h56v-427zm126-451v16-16z"
291 : : "m22 3470v260h50v-260zm55 599v167h26v-167zm-49-1831v455h136v-455z"
292 : : "m10 8845v19h158v-19zm54-38v25h228v-25zm156-13245v108h100v-108z"
293 : : "m101 14826v200h75v-200zm-205-3000v365h315v-365zm-309-1877v19h628v-19z"
294 : : "m549-1398v127h98v-127zm18 5351v215h111v-215zm-362-10061v152h488v-152z"
295 : : "m488 0v-469h-492v621h4v280h488v-432zm-378 5368v48h384v-48zm274-10182v712h119v-712z"
296 : : "m-424 3173v-94h-47v110h47v96h551v-112zm-105-2249v157h353v112h100v-112h205v-157z"
297 : : "m284 5177v203h377v-203zm337 4727v66h40v-66zm-326 6110v57h374v-57zm351-12583v39h48v-39z"
298 : : "m23 12583v-505h-571v576h571v-14h30v-57zm-368-2682v-8h-292v27h134v102h562v-121z"
299 : : "m-9-12299v320h428v-320zm364 1216v-410h-598v316h-32v110h32v96h47v280h615v-392z"
300 : : "m-537 11431v486h388v279h111v-279h122v-486zm112-4621v142h550v-142zm101-2719v494h450v-494z"
301 : : "m340 6609v33h120v-33zm-85-4349v-479h-98v479h-258v459h-165v247h189v307h384v-307h142v-105h13v-601z"
302 : : "m-270-3159v36h490v-36zm442 2163v7h52v-7zm-345 7158v588h403v-588zm378-1813v-93h-122v126h2v155h148v-188z"
303 : : "m19-5345v-259h-96v266h44v20h52v-20h10v-7zm-91-6571v-430h-428v430h-211v589h743v-589z"
304 : : "m101 6571v-461h-705v468h599v20h44v191h65v-218zm-89-8442v40h94v-40zm-71 10742v-43h-221v109h181v427h211v-493z"
305 : : "m0-4727v-189h-634v392h257v97h33v351h490v-351h29v-300zm-97 6698v-333h-315v333h-262v456h863v-456z"
306 : : "m-142-8556v22h429v-22zm238-56v17h208v-17zm91 7234v664h120v-664zm69 2452v-336h-567v524h419v13h201v-201z"
307 : 5 : "m-42-13332v272h115v-272z";
308 : :
309 : 5 : verifyPoly("disjunct", disjunct, aDisjunctRanges);
310 : 5 : verifyPoly("equal", equal, aEqualRanges);
311 : 5 : verifyPoly("intersectionN", intersectionN, aIntersectionN);
312 : 5 : verifyPoly("intersectionE", intersectionE, aIntersectionE);
313 : 5 : verifyPoly("intersectionS", intersectionS, aIntersectionS);
314 : 5 : verifyPoly("intersectionW", intersectionW, aIntersectionW);
315 : 5 : verifyPoly("intersectionNE", intersectionNE, aIntersectionNE);
316 : 5 : verifyPoly("intersectionSE", intersectionSE, aIntersectionSE);
317 : 5 : verifyPoly("intersectionSW", intersectionSW, aIntersectionSW);
318 : 5 : verifyPoly("intersectionNW", intersectionNW, aIntersectionNW);
319 : 5 : verifyPoly("ringIntersection", ringIntersection, aRingIntersection);
320 : 5 : verifyPoly("ringIntersection2", ringIntersection2, aRingIntersection2);
321 : 5 : verifyPoly("ringIntersectExtraStrip", ringIntersectExtraStrip, aRingIntersectExtraStrip);
322 : 5 : verifyPoly("complexIntersections", complexIntersections, aComplexIntersections);
323 : 5 : verifyPoly("randomIntersections", randomIntersections, aRandomIntersections);
324 : 5 : }
325 : :
326 : 75 : void dumpSvg(const char* pName,
327 : : const ::basegfx::B2DPolyPolygon& rPoly)
328 : : {
329 : : (void)pName; (void)rPoly;
330 : : #if OSL_DEBUG_LEVEL > 2
331 : : fprintf(stderr, "%s - svg:d=\"%s\"\n",
332 : : pName, rtl::OUStringToOString(
333 : : basegfx::tools::exportToSvgD(rPoly),
334 : : RTL_TEXTENCODING_UTF8).getStr() );
335 : : #endif
336 : 75 : }
337 : :
338 : 5 : void getPolyPolygon()
339 : : {
340 : 5 : dumpSvg("disjunct",aDisjunctRanges.solveCrossovers());
341 : 5 : dumpSvg("equal",aEqualRanges.solveCrossovers());
342 : 5 : dumpSvg("intersectionN",aIntersectionN.solveCrossovers());
343 : 5 : dumpSvg("intersectionE",aIntersectionE.solveCrossovers());
344 : 5 : dumpSvg("intersectionS",aIntersectionS.solveCrossovers());
345 : 5 : dumpSvg("intersectionW",aIntersectionW.solveCrossovers());
346 : 5 : dumpSvg("intersectionNE",aIntersectionNE.solveCrossovers());
347 : 5 : dumpSvg("intersectionSE",aIntersectionSE.solveCrossovers());
348 : 5 : dumpSvg("intersectionSW",aIntersectionSW.solveCrossovers());
349 : 5 : dumpSvg("intersectionNW",aIntersectionNW.solveCrossovers());
350 : 5 : dumpSvg("ringIntersection",aRingIntersection.solveCrossovers());
351 : 5 : dumpSvg("ringIntersection2",aRingIntersection2.solveCrossovers());
352 : 5 : dumpSvg("aRingIntersectExtraStrip",aRingIntersectExtraStrip.solveCrossovers());
353 : 5 : dumpSvg("complexIntersections",aComplexIntersections.solveCrossovers());
354 : 5 : dumpSvg("randomIntersections",aRandomIntersections.solveCrossovers());
355 : :
356 [ + - ][ + - ]: 5 : CPPUNIT_ASSERT_MESSAGE("getPolyPolygon", true );
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
357 : 5 : }
358 : :
359 : 50 : void validatePoly( const char* pName, const B2DPolyRange& rRange )
360 : : {
361 [ + - ]: 50 : B2DPolyPolygon genericClip;
362 [ + - ]: 50 : const sal_uInt32 nCount=rRange.count();
363 [ + + ]: 150 : for( sal_uInt32 i=0; i<nCount; ++i )
364 : : {
365 : : B2DPolygon aRect=tools::createPolygonFromRect(
366 [ + - ][ + - ]: 100 : rRange.getElement(i).head);
367 [ + - ][ + - ]: 100 : if( rRange.getElement(i).tail.head == ORIENTATION_NEGATIVE )
368 [ + - ]: 100 : aRect.flip();
369 : :
370 [ + - ]: 100 : genericClip.append(aRect);
371 [ + - ]: 100 : }
372 : :
373 : : #if OSL_DEBUG_LEVEL > 2
374 : : fprintf(stderr, "%s input - svg:d=\"%s\"\n",
375 : : pName, rtl::OUStringToOString(
376 : : basegfx::tools::exportToSvgD(
377 : : genericClip),
378 : : RTL_TEXTENCODING_UTF8).getStr() );
379 : : #endif
380 : :
381 [ + - ]: 50 : const B2DPolyPolygon boxClipResult=rRange.solveCrossovers();
382 : : const rtl::OUString boxClipSvg(
383 : : basegfx::tools::exportToSvgD(
384 : : normalizePoly(
385 [ + - ][ + - ]: 50 : boxClipResult)));
[ + - ]
386 : : #if OSL_DEBUG_LEVEL > 2
387 : : fprintf(stderr, "%s boxclipper - svg:d=\"%s\"\n",
388 : : pName, rtl::OUStringToOString(
389 : : boxClipSvg,
390 : : RTL_TEXTENCODING_UTF8).getStr() );
391 : : #endif
392 : :
393 [ + - ][ + - ]: 50 : genericClip = tools::solveCrossovers(genericClip);
[ + - ]
394 : : const rtl::OUString genericClipSvg(
395 : : basegfx::tools::exportToSvgD(
396 : : normalizePoly(
397 [ + - ][ + - ]: 50 : genericClip)));
[ + - ]
398 : : #if OSL_DEBUG_LEVEL > 2
399 : : fprintf(stderr, "%s genclipper - svg:d=\"%s\"\n",
400 : : pName, rtl::OUStringToOString(
401 : : genericClipSvg,
402 : : RTL_TEXTENCODING_UTF8).getStr() );
403 : : #endif
404 : :
405 [ + - ][ + - ]: 100 : CPPUNIT_ASSERT_MESSAGE(pName,
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
406 [ + - ]: 100 : genericClipSvg == boxClipSvg);
[ + - + - ]
407 : 50 : }
408 : :
409 : 5 : void validatePoly()
410 : : {
411 : 5 : validatePoly("disjunct", aDisjunctRanges);
412 : 5 : validatePoly("equal", aEqualRanges);
413 : 5 : validatePoly("intersectionN", aIntersectionN);
414 : 5 : validatePoly("intersectionE", aIntersectionE);
415 : 5 : validatePoly("intersectionS", aIntersectionS);
416 : 5 : validatePoly("intersectionW", aIntersectionW);
417 : 5 : validatePoly("intersectionNE", aIntersectionNE);
418 : 5 : validatePoly("intersectionSE", aIntersectionSE);
419 : 5 : validatePoly("intersectionSW", aIntersectionSW);
420 : 5 : validatePoly("intersectionNW", aIntersectionNW);
421 : : // subtle differences on Solaris Intel, comparison not smart enough
422 : : // (due to floating point inaccuracies)
423 : : //validatePoly("ringIntersection", aRingIntersection);
424 : : //validatePoly("ringIntersection2", aRingIntersection2);
425 : : //validatePoly("ringIntersectExtraStrip", aRingIntersectExtraStrip);
426 : : // generic clipper buggy here, likely
427 : : //validatePoly("complexIntersections", aComplexIntersections);
428 : : //validatePoly("randomIntersections", aRandomIntersections);
429 : 5 : }
430 : :
431 : : // Change the following lines only, if you add, remove or rename
432 : : // member functions of the current class,
433 : : // because these macros are need by auto register mechanism.
434 : :
435 [ + - ][ + - ]: 10 : CPPUNIT_TEST_SUITE(boxclipper);
[ + - ][ + - ]
[ # # ]
436 [ + - ][ + - ]: 5 : CPPUNIT_TEST(validatePoly);
[ + - ][ + - ]
[ + - ][ + - ]
437 [ + - ][ + - ]: 5 : CPPUNIT_TEST(verifyPoly);
[ + - ][ + - ]
[ + - ][ + - ]
438 [ + - ][ + - ]: 5 : CPPUNIT_TEST(getPolyPolygon);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
439 [ + - ][ + - ]: 10 : CPPUNIT_TEST_SUITE_END();
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
440 : : };
441 : :
442 : : // -----------------------------------------------------------------------------
443 : 5 : CPPUNIT_TEST_SUITE_REGISTRATION(basegfx2d::boxclipper);
444 [ + - ][ + - ]: 15 : } // namespace basegfx2d
445 : :
446 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|