109dbbe93SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
309dbbe93SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
409dbbe93SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
509dbbe93SAndrew Rist  * distributed with this work for additional information
609dbbe93SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
709dbbe93SAndrew Rist  * to you under the Apache License, Version 2.0 (the
809dbbe93SAndrew Rist  * "License"); you may not use this file except in compliance
909dbbe93SAndrew Rist  * with the License.  You may obtain a copy of the License at
1009dbbe93SAndrew Rist  *
1109dbbe93SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
1209dbbe93SAndrew Rist  *
1309dbbe93SAndrew Rist  * Unless required by applicable law or agreed to in writing,
1409dbbe93SAndrew Rist  * software distributed under the License is distributed on an
1509dbbe93SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1609dbbe93SAndrew Rist  * KIND, either express or implied.  See the License for the
1709dbbe93SAndrew Rist  * specific language governing permissions and limitations
1809dbbe93SAndrew Rist  * under the License.
1909dbbe93SAndrew Rist  *
2009dbbe93SAndrew Rist  *************************************************************/
2109dbbe93SAndrew Rist 
22cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
23cdf0e10cSrcweir #include "precompiled_basegfx.hxx"
241f882ec4SArmin Le Grand 
25cdf0e10cSrcweir #include <basegfx/polygon/b2dpolypolygontools.hxx>
26cdf0e10cSrcweir #include <osl/diagnose.h>
27cdf0e10cSrcweir #include <basegfx/polygon/b2dpolypolygon.hxx>
28cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygon.hxx>
29cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygontools.hxx>
30cdf0e10cSrcweir #include <basegfx/numeric/ftools.hxx>
31cdf0e10cSrcweir #include <basegfx/polygon/b2dpolypolygoncutter.hxx>
32cdf0e10cSrcweir #include <numeric>
33cdf0e10cSrcweir 
34cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
35cdf0e10cSrcweir 
36cdf0e10cSrcweir namespace basegfx
37cdf0e10cSrcweir {
38cdf0e10cSrcweir 	namespace tools
39cdf0e10cSrcweir 	{
correctOrientations(const B2DPolyPolygon & rCandidate)40cdf0e10cSrcweir 		B2DPolyPolygon correctOrientations(const B2DPolyPolygon& rCandidate)
41cdf0e10cSrcweir 		{
42cdf0e10cSrcweir 			B2DPolyPolygon aRetval(rCandidate);
43cdf0e10cSrcweir 			const sal_uInt32 nCount(aRetval.count());
44cdf0e10cSrcweir 
45cdf0e10cSrcweir 			for(sal_uInt32 a(0L); a < nCount; a++)
46cdf0e10cSrcweir 			{
47cdf0e10cSrcweir 				const B2DPolygon aCandidate(rCandidate.getB2DPolygon(a));
48cdf0e10cSrcweir 				const B2VectorOrientation aOrientation(tools::getOrientation(aCandidate));
49cdf0e10cSrcweir 				sal_uInt32 nDepth(0L);
50cdf0e10cSrcweir 
51cdf0e10cSrcweir 				for(sal_uInt32 b(0L); b < nCount; b++)
52cdf0e10cSrcweir 				{
53cdf0e10cSrcweir 					if(b != a)
54cdf0e10cSrcweir 					{
55cdf0e10cSrcweir 						const B2DPolygon aCompare(rCandidate.getB2DPolygon(b));
56cdf0e10cSrcweir 
57cdf0e10cSrcweir 						if(tools::isInside(aCompare, aCandidate, true))
58cdf0e10cSrcweir 						{
59cdf0e10cSrcweir 							nDepth++;
60cdf0e10cSrcweir 						}
61cdf0e10cSrcweir 					}
62cdf0e10cSrcweir 				}
63cdf0e10cSrcweir 
64cdf0e10cSrcweir 				const bool bShallBeHole(1L == (nDepth & 0x00000001));
65cdf0e10cSrcweir 				const bool bIsHole(ORIENTATION_NEGATIVE == aOrientation);
66cdf0e10cSrcweir 
67cdf0e10cSrcweir 				if(bShallBeHole != bIsHole && ORIENTATION_NEUTRAL != aOrientation)
68cdf0e10cSrcweir 				{
69cdf0e10cSrcweir 					B2DPolygon aFlipped(aCandidate);
70cdf0e10cSrcweir 					aFlipped.flip();
71cdf0e10cSrcweir 					aRetval.setB2DPolygon(a, aFlipped);
72cdf0e10cSrcweir 				}
73cdf0e10cSrcweir 			}
74cdf0e10cSrcweir 
75cdf0e10cSrcweir 			return aRetval;
76cdf0e10cSrcweir 		}
77cdf0e10cSrcweir 
correctOutmostPolygon(const B2DPolyPolygon & rCandidate)78cdf0e10cSrcweir 		B2DPolyPolygon correctOutmostPolygon(const B2DPolyPolygon& rCandidate)
79cdf0e10cSrcweir 		{
80cdf0e10cSrcweir 			const sal_uInt32 nCount(rCandidate.count());
81cdf0e10cSrcweir 
82cdf0e10cSrcweir 			if(nCount > 1L)
83cdf0e10cSrcweir 			{
84cdf0e10cSrcweir 				for(sal_uInt32 a(0L); a < nCount; a++)
85cdf0e10cSrcweir 				{
86cdf0e10cSrcweir 					const B2DPolygon aCandidate(rCandidate.getB2DPolygon(a));
87cdf0e10cSrcweir 					sal_uInt32 nDepth(0L);
88cdf0e10cSrcweir 
89cdf0e10cSrcweir 					for(sal_uInt32 b(0L); b < nCount; b++)
90cdf0e10cSrcweir 					{
91cdf0e10cSrcweir 						if(b != a)
92cdf0e10cSrcweir 						{
93cdf0e10cSrcweir 							const B2DPolygon aCompare(rCandidate.getB2DPolygon(b));
94cdf0e10cSrcweir 
95cdf0e10cSrcweir 							if(tools::isInside(aCompare, aCandidate, true))
96cdf0e10cSrcweir 							{
97cdf0e10cSrcweir 								nDepth++;
98cdf0e10cSrcweir 							}
99cdf0e10cSrcweir 						}
100cdf0e10cSrcweir 					}
101cdf0e10cSrcweir 
102cdf0e10cSrcweir 					if(!nDepth)
103cdf0e10cSrcweir 					{
104cdf0e10cSrcweir 						B2DPolyPolygon aRetval(rCandidate);
105cdf0e10cSrcweir 
106cdf0e10cSrcweir 						if(a != 0L)
107cdf0e10cSrcweir 						{
108cdf0e10cSrcweir 							// exchange polygon a and polygon 0L
109cdf0e10cSrcweir 							aRetval.setB2DPolygon(0L, aCandidate);
110cdf0e10cSrcweir 							aRetval.setB2DPolygon(a, rCandidate.getB2DPolygon(0L));
111cdf0e10cSrcweir 						}
112cdf0e10cSrcweir 
113cdf0e10cSrcweir 						// exit
114cdf0e10cSrcweir 						return aRetval;
115cdf0e10cSrcweir 					}
116cdf0e10cSrcweir 				}
117cdf0e10cSrcweir 			}
118cdf0e10cSrcweir 
119cdf0e10cSrcweir 			return rCandidate;
120cdf0e10cSrcweir 		}
121cdf0e10cSrcweir 
adaptiveSubdivideByDistance(const B2DPolyPolygon & rCandidate,double fDistanceBound)122cdf0e10cSrcweir 		B2DPolyPolygon adaptiveSubdivideByDistance(const B2DPolyPolygon& rCandidate, double fDistanceBound)
123cdf0e10cSrcweir 		{
124cdf0e10cSrcweir 			if(rCandidate.areControlPointsUsed())
125cdf0e10cSrcweir 			{
126cdf0e10cSrcweir 				const sal_uInt32 nPolygonCount(rCandidate.count());
127cdf0e10cSrcweir 				B2DPolyPolygon aRetval;
128cdf0e10cSrcweir 
129cdf0e10cSrcweir 				for(sal_uInt32 a(0L); a < nPolygonCount; a++)
130cdf0e10cSrcweir 				{
131cdf0e10cSrcweir 					const B2DPolygon aCandidate(rCandidate.getB2DPolygon(a));
132cdf0e10cSrcweir 
133cdf0e10cSrcweir 					if(aCandidate.areControlPointsUsed())
134cdf0e10cSrcweir 					{
135cdf0e10cSrcweir 						aRetval.append(tools::adaptiveSubdivideByDistance(aCandidate, fDistanceBound));
136cdf0e10cSrcweir 					}
137cdf0e10cSrcweir 					else
138cdf0e10cSrcweir 					{
139cdf0e10cSrcweir 						aRetval.append(aCandidate);
140cdf0e10cSrcweir 					}
141cdf0e10cSrcweir 				}
142cdf0e10cSrcweir 
143cdf0e10cSrcweir 				return aRetval;
144cdf0e10cSrcweir 			}
145cdf0e10cSrcweir 			else
146cdf0e10cSrcweir 			{
147cdf0e10cSrcweir 				return rCandidate;
148cdf0e10cSrcweir 			}
149cdf0e10cSrcweir 		}
150cdf0e10cSrcweir 
adaptiveSubdivideByAngle(const B2DPolyPolygon & rCandidate,double fAngleBound)151cdf0e10cSrcweir 		B2DPolyPolygon adaptiveSubdivideByAngle(const B2DPolyPolygon& rCandidate, double fAngleBound)
152cdf0e10cSrcweir 		{
153cdf0e10cSrcweir 			if(rCandidate.areControlPointsUsed())
154cdf0e10cSrcweir 			{
155cdf0e10cSrcweir 				const sal_uInt32 nPolygonCount(rCandidate.count());
156cdf0e10cSrcweir 				B2DPolyPolygon aRetval;
157cdf0e10cSrcweir 
158cdf0e10cSrcweir 				for(sal_uInt32 a(0L); a < nPolygonCount; a++)
159cdf0e10cSrcweir 				{
160cdf0e10cSrcweir 					const B2DPolygon aCandidate(rCandidate.getB2DPolygon(a));
161cdf0e10cSrcweir 
162cdf0e10cSrcweir 					if(aCandidate.areControlPointsUsed())
163cdf0e10cSrcweir 					{
164cdf0e10cSrcweir 						aRetval.append(tools::adaptiveSubdivideByAngle(aCandidate, fAngleBound));
165cdf0e10cSrcweir 					}
166cdf0e10cSrcweir 					else
167cdf0e10cSrcweir 					{
168cdf0e10cSrcweir 						aRetval.append(aCandidate);
169cdf0e10cSrcweir 					}
170cdf0e10cSrcweir 				}
171cdf0e10cSrcweir 
172cdf0e10cSrcweir 				return aRetval;
173cdf0e10cSrcweir 			}
174cdf0e10cSrcweir 			else
175cdf0e10cSrcweir 			{
176cdf0e10cSrcweir 				return rCandidate;
177cdf0e10cSrcweir 			}
178cdf0e10cSrcweir 		}
179cdf0e10cSrcweir 
adaptiveSubdivideByCount(const B2DPolyPolygon & rCandidate,sal_uInt32 nCount)180cdf0e10cSrcweir 		B2DPolyPolygon adaptiveSubdivideByCount(const B2DPolyPolygon& rCandidate, sal_uInt32 nCount)
181cdf0e10cSrcweir 		{
182cdf0e10cSrcweir 			if(rCandidate.areControlPointsUsed())
183cdf0e10cSrcweir 			{
184cdf0e10cSrcweir 				const sal_uInt32 nPolygonCount(rCandidate.count());
185cdf0e10cSrcweir 				B2DPolyPolygon aRetval;
186cdf0e10cSrcweir 
187cdf0e10cSrcweir 				for(sal_uInt32 a(0L); a < nPolygonCount; a++)
188cdf0e10cSrcweir 				{
189cdf0e10cSrcweir 					const B2DPolygon aCandidate(rCandidate.getB2DPolygon(a));
190cdf0e10cSrcweir 
191cdf0e10cSrcweir 					if(aCandidate.areControlPointsUsed())
192cdf0e10cSrcweir 					{
193cdf0e10cSrcweir 						aRetval.append(tools::adaptiveSubdivideByCount(aCandidate, nCount));
194cdf0e10cSrcweir 					}
195cdf0e10cSrcweir 					else
196cdf0e10cSrcweir 					{
197cdf0e10cSrcweir 						aRetval.append(aCandidate);
198cdf0e10cSrcweir 					}
199cdf0e10cSrcweir 				}
200cdf0e10cSrcweir 
201cdf0e10cSrcweir 				return aRetval;
202cdf0e10cSrcweir 			}
203cdf0e10cSrcweir 			else
204cdf0e10cSrcweir 			{
205cdf0e10cSrcweir 				return rCandidate;
206cdf0e10cSrcweir 			}
207cdf0e10cSrcweir 		}
208cdf0e10cSrcweir 
isInside(const B2DPolyPolygon & rCandidate,const B2DPoint & rPoint,bool bWithBorder)209cdf0e10cSrcweir 		bool isInside(const B2DPolyPolygon& rCandidate, const B2DPoint& rPoint, bool bWithBorder)
210cdf0e10cSrcweir 		{
211cdf0e10cSrcweir 			const sal_uInt32 nPolygonCount(rCandidate.count());
212cdf0e10cSrcweir 
213cdf0e10cSrcweir 			if(1L == nPolygonCount)
214cdf0e10cSrcweir 			{
215cdf0e10cSrcweir 				return isInside(rCandidate.getB2DPolygon(0L), rPoint, bWithBorder);
216cdf0e10cSrcweir 			}
217cdf0e10cSrcweir 			else
218cdf0e10cSrcweir 			{
219cdf0e10cSrcweir 				sal_Int32 nInsideCount(0L);
220cdf0e10cSrcweir 
221cdf0e10cSrcweir 				for(sal_uInt32 a(0L); a < nPolygonCount; a++)
222cdf0e10cSrcweir 				{
223cdf0e10cSrcweir 					const B2DPolygon aPolygon(rCandidate.getB2DPolygon(a));
224cdf0e10cSrcweir 					const bool bInside(isInside(aPolygon, rPoint, bWithBorder));
225cdf0e10cSrcweir 
226cdf0e10cSrcweir 					if(bInside)
227cdf0e10cSrcweir 					{
228cdf0e10cSrcweir 						nInsideCount++;
229cdf0e10cSrcweir 					}
230cdf0e10cSrcweir 				}
231cdf0e10cSrcweir 
232cdf0e10cSrcweir 				return (nInsideCount % 2L);
233cdf0e10cSrcweir 			}
234cdf0e10cSrcweir 		}
235cdf0e10cSrcweir 
getRangeWithControlPoints(const B2DPolyPolygon & rCandidate)236cdf0e10cSrcweir 		B2DRange getRangeWithControlPoints(const B2DPolyPolygon& rCandidate)
237cdf0e10cSrcweir 		{
238cdf0e10cSrcweir 			B2DRange aRetval;
239cdf0e10cSrcweir 			const sal_uInt32 nPolygonCount(rCandidate.count());
240cdf0e10cSrcweir 
241cdf0e10cSrcweir 			for(sal_uInt32 a(0L); a < nPolygonCount; a++)
242cdf0e10cSrcweir 			{
243cdf0e10cSrcweir 				B2DPolygon aCandidate = rCandidate.getB2DPolygon(a);
244cdf0e10cSrcweir 				aRetval.expand(tools::getRangeWithControlPoints(aCandidate));
245cdf0e10cSrcweir 			}
246cdf0e10cSrcweir 
247cdf0e10cSrcweir 			return aRetval;
248cdf0e10cSrcweir 		}
249cdf0e10cSrcweir 
getRange(const B2DPolyPolygon & rCandidate)250cdf0e10cSrcweir 		B2DRange getRange(const B2DPolyPolygon& rCandidate)
251cdf0e10cSrcweir 		{
252cdf0e10cSrcweir 			B2DRange aRetval;
253cdf0e10cSrcweir 			const sal_uInt32 nPolygonCount(rCandidate.count());
254cdf0e10cSrcweir 
255cdf0e10cSrcweir 			for(sal_uInt32 a(0L); a < nPolygonCount; a++)
256cdf0e10cSrcweir 			{
257cdf0e10cSrcweir 				B2DPolygon aCandidate = rCandidate.getB2DPolygon(a);
258cdf0e10cSrcweir 				aRetval.expand(tools::getRange(aCandidate));
259cdf0e10cSrcweir 			}
260cdf0e10cSrcweir 
261cdf0e10cSrcweir 			return aRetval;
262cdf0e10cSrcweir 		}
263cdf0e10cSrcweir 
getSignedArea(const B2DPolyPolygon & rCandidate)2644665f8d3SArmin Le Grand 		double getSignedArea(const B2DPolyPolygon& rCandidate)
2654665f8d3SArmin Le Grand 		{
2664665f8d3SArmin Le Grand 			double fRetval(0.0);
2674665f8d3SArmin Le Grand 			const sal_uInt32 nPolygonCount(rCandidate.count());
2684665f8d3SArmin Le Grand 
2694665f8d3SArmin Le Grand 			for(sal_uInt32 a(0L); a < nPolygonCount; a++)
2704665f8d3SArmin Le Grand 			{
2714665f8d3SArmin Le Grand 				const B2DPolygon aCandidate(rCandidate.getB2DPolygon(a));
2724665f8d3SArmin Le Grand 
2734665f8d3SArmin Le Grand                 fRetval += tools::getSignedArea(aCandidate);
2744665f8d3SArmin Le Grand 			}
2754665f8d3SArmin Le Grand 
2764665f8d3SArmin Le Grand 			return fRetval;
2774665f8d3SArmin Le Grand 		}
2784665f8d3SArmin Le Grand 
getArea(const B2DPolyPolygon & rCandidate)2794665f8d3SArmin Le Grand 		double getArea(const B2DPolyPolygon& rCandidate)
2804665f8d3SArmin Le Grand 		{
2814665f8d3SArmin Le Grand 			return fabs(getSignedArea(rCandidate));
2824665f8d3SArmin Le Grand 		}
2834665f8d3SArmin Le Grand 
applyLineDashing(const B2DPolyPolygon & rCandidate,const::std::vector<double> & rDotDashArray,B2DPolyPolygon * pLineTarget,B2DPolyPolygon * pGapTarget,double fFullDashDotLen)2844665f8d3SArmin Le Grand         void applyLineDashing(const B2DPolyPolygon& rCandidate, const ::std::vector<double>& rDotDashArray, B2DPolyPolygon* pLineTarget, B2DPolyPolygon* pGapTarget, double fFullDashDotLen)
285cdf0e10cSrcweir 		{
286cdf0e10cSrcweir 			if(0.0 == fFullDashDotLen && rDotDashArray.size())
287cdf0e10cSrcweir 			{
288cdf0e10cSrcweir 				// calculate fFullDashDotLen from rDotDashArray
289cdf0e10cSrcweir 				fFullDashDotLen = ::std::accumulate(rDotDashArray.begin(), rDotDashArray.end(), 0.0);
290cdf0e10cSrcweir 			}
291cdf0e10cSrcweir 
292cdf0e10cSrcweir 			if(rCandidate.count() && fFullDashDotLen > 0.0)
293cdf0e10cSrcweir 			{
294cdf0e10cSrcweir 				B2DPolyPolygon aLineTarget, aGapTarget;
295cdf0e10cSrcweir 
296cdf0e10cSrcweir 				for(sal_uInt32 a(0L); a < rCandidate.count(); a++)
297cdf0e10cSrcweir 				{
298cdf0e10cSrcweir 					const B2DPolygon aCandidate(rCandidate.getB2DPolygon(a));
299cdf0e10cSrcweir 
300cdf0e10cSrcweir 					applyLineDashing(
301cdf0e10cSrcweir 						aCandidate,
302cdf0e10cSrcweir 						rDotDashArray,
303cdf0e10cSrcweir 						pLineTarget ? &aLineTarget : 0,
304cdf0e10cSrcweir 						pGapTarget ? &aGapTarget : 0,
305cdf0e10cSrcweir 						fFullDashDotLen);
306cdf0e10cSrcweir 
307cdf0e10cSrcweir 					if(pLineTarget)
308cdf0e10cSrcweir 					{
309cdf0e10cSrcweir 						pLineTarget->append(aLineTarget);
310cdf0e10cSrcweir 					}
311cdf0e10cSrcweir 
312cdf0e10cSrcweir 					if(pGapTarget)
313cdf0e10cSrcweir 					{
314cdf0e10cSrcweir 						pGapTarget->append(aGapTarget);
315cdf0e10cSrcweir 					}
316cdf0e10cSrcweir 				}
317cdf0e10cSrcweir 			}
318cdf0e10cSrcweir 		}
319cdf0e10cSrcweir 
isInEpsilonRange(const B2DPolyPolygon & rCandidate,const B2DPoint & rTestPosition,double fDistance)320cdf0e10cSrcweir 		bool isInEpsilonRange(const B2DPolyPolygon& rCandidate, const B2DPoint& rTestPosition, double fDistance)
321cdf0e10cSrcweir 		{
322cdf0e10cSrcweir 			const sal_uInt32 nPolygonCount(rCandidate.count());
323cdf0e10cSrcweir 
324cdf0e10cSrcweir 			for(sal_uInt32 a(0L); a < nPolygonCount; a++)
325cdf0e10cSrcweir 			{
326cdf0e10cSrcweir 				B2DPolygon aCandidate(rCandidate.getB2DPolygon(a));
327cdf0e10cSrcweir 
328cdf0e10cSrcweir 				if(isInEpsilonRange(aCandidate, rTestPosition, fDistance))
329cdf0e10cSrcweir 				{
330cdf0e10cSrcweir 					return true;
331cdf0e10cSrcweir 				}
332cdf0e10cSrcweir 			}
333cdf0e10cSrcweir 
334cdf0e10cSrcweir 			return false;
335cdf0e10cSrcweir 		}
336cdf0e10cSrcweir 
createB3DPolyPolygonFromB2DPolyPolygon(const B2DPolyPolygon & rCandidate,double fZCoordinate)337cdf0e10cSrcweir 		B3DPolyPolygon createB3DPolyPolygonFromB2DPolyPolygon(const B2DPolyPolygon& rCandidate, double fZCoordinate)
338cdf0e10cSrcweir 		{
339cdf0e10cSrcweir 			const sal_uInt32 nPolygonCount(rCandidate.count());
340cdf0e10cSrcweir 			B3DPolyPolygon aRetval;
341cdf0e10cSrcweir 
342cdf0e10cSrcweir 			for(sal_uInt32 a(0L); a < nPolygonCount; a++)
343cdf0e10cSrcweir 			{
344cdf0e10cSrcweir 				B2DPolygon aCandidate(rCandidate.getB2DPolygon(a));
345cdf0e10cSrcweir 
346cdf0e10cSrcweir 				aRetval.append(createB3DPolygonFromB2DPolygon(aCandidate, fZCoordinate));
347cdf0e10cSrcweir 			}
348cdf0e10cSrcweir 
349cdf0e10cSrcweir 			return aRetval;
350cdf0e10cSrcweir 		}
351cdf0e10cSrcweir 
createB2DPolyPolygonFromB3DPolyPolygon(const B3DPolyPolygon & rCandidate,const B3DHomMatrix & rMat)352cdf0e10cSrcweir 		B2DPolyPolygon createB2DPolyPolygonFromB3DPolyPolygon(const B3DPolyPolygon& rCandidate, const B3DHomMatrix& rMat)
353cdf0e10cSrcweir 		{
354cdf0e10cSrcweir 			const sal_uInt32 nPolygonCount(rCandidate.count());
355cdf0e10cSrcweir 			B2DPolyPolygon aRetval;
356cdf0e10cSrcweir 
357cdf0e10cSrcweir 			for(sal_uInt32 a(0L); a < nPolygonCount; a++)
358cdf0e10cSrcweir 			{
359cdf0e10cSrcweir 				B3DPolygon aCandidate(rCandidate.getB3DPolygon(a));
360cdf0e10cSrcweir 
361cdf0e10cSrcweir 				aRetval.append(createB2DPolygonFromB3DPolygon(aCandidate, rMat));
362cdf0e10cSrcweir 			}
363cdf0e10cSrcweir 
364cdf0e10cSrcweir 			return aRetval;
365cdf0e10cSrcweir 		}
366cdf0e10cSrcweir 
getSmallestDistancePointToPolyPolygon(const B2DPolyPolygon & rCandidate,const B2DPoint & rTestPoint,sal_uInt32 & rPolygonIndex,sal_uInt32 & rEdgeIndex,double & rCut)367cdf0e10cSrcweir 		double getSmallestDistancePointToPolyPolygon(const B2DPolyPolygon& rCandidate, const B2DPoint& rTestPoint, sal_uInt32& rPolygonIndex, sal_uInt32& rEdgeIndex, double& rCut)
368cdf0e10cSrcweir 		{
369cdf0e10cSrcweir 			double fRetval(DBL_MAX);
370cdf0e10cSrcweir 			const double fZero(0.0);
371cdf0e10cSrcweir 			const sal_uInt32 nPolygonCount(rCandidate.count());
372cdf0e10cSrcweir 
373cdf0e10cSrcweir 			for(sal_uInt32 a(0L); a < nPolygonCount; a++)
374cdf0e10cSrcweir 			{
375cdf0e10cSrcweir 				const B2DPolygon aCandidate(rCandidate.getB2DPolygon(a));
376cdf0e10cSrcweir 				sal_uInt32 nNewEdgeIndex;
377*e7fefffcSPedro Giffuni 				double fNewCut = 0.0;
378cdf0e10cSrcweir 				const double fNewDistance(getSmallestDistancePointToPolygon(aCandidate, rTestPoint, nNewEdgeIndex, fNewCut));
379cdf0e10cSrcweir 
380cdf0e10cSrcweir 				if(DBL_MAX == fRetval || fNewDistance < fRetval)
381cdf0e10cSrcweir 				{
382cdf0e10cSrcweir 					fRetval = fNewDistance;
383cdf0e10cSrcweir 					rPolygonIndex = a;
384cdf0e10cSrcweir 					rEdgeIndex = nNewEdgeIndex;
385cdf0e10cSrcweir 					rCut = fNewCut;
386cdf0e10cSrcweir 
387cdf0e10cSrcweir 					if(fTools::equal(fRetval, fZero))
388cdf0e10cSrcweir 					{
389cdf0e10cSrcweir 						// already found zero distance, cannot get better. Ensure numerical zero value and end loop.
390cdf0e10cSrcweir 						fRetval = 0.0;
391cdf0e10cSrcweir 						break;
392cdf0e10cSrcweir 					}
393cdf0e10cSrcweir 				}
394cdf0e10cSrcweir 			}
395cdf0e10cSrcweir 
396cdf0e10cSrcweir 			return fRetval;
397cdf0e10cSrcweir 		}
398cdf0e10cSrcweir 
distort(const B2DPolyPolygon & rCandidate,const B2DRange & rOriginal,const B2DPoint & rTopLeft,const B2DPoint & rTopRight,const B2DPoint & rBottomLeft,const B2DPoint & rBottomRight)399cdf0e10cSrcweir 		B2DPolyPolygon distort(const B2DPolyPolygon& rCandidate, const B2DRange& rOriginal, const B2DPoint& rTopLeft, const B2DPoint& rTopRight, const B2DPoint& rBottomLeft, const B2DPoint& rBottomRight)
400cdf0e10cSrcweir 		{
401cdf0e10cSrcweir 			const sal_uInt32 nPolygonCount(rCandidate.count());
402cdf0e10cSrcweir 			B2DPolyPolygon aRetval;
403cdf0e10cSrcweir 
404cdf0e10cSrcweir 			for(sal_uInt32 a(0L); a < nPolygonCount; a++)
405cdf0e10cSrcweir 			{
406cdf0e10cSrcweir 				const B2DPolygon aCandidate(rCandidate.getB2DPolygon(a));
407cdf0e10cSrcweir 
408cdf0e10cSrcweir 				aRetval.append(distort(aCandidate, rOriginal, rTopLeft, rTopRight, rBottomLeft, rBottomRight));
409cdf0e10cSrcweir 			}
410cdf0e10cSrcweir 
411cdf0e10cSrcweir 			return aRetval;
412cdf0e10cSrcweir 		}
413cdf0e10cSrcweir 
rotateAroundPoint(const B2DPolyPolygon & rCandidate,const B2DPoint & rCenter,double fAngle)414cdf0e10cSrcweir 		B2DPolyPolygon rotateAroundPoint(const B2DPolyPolygon& rCandidate, const B2DPoint& rCenter, double fAngle)
415cdf0e10cSrcweir 		{
416cdf0e10cSrcweir 			const sal_uInt32 nPolygonCount(rCandidate.count());
417cdf0e10cSrcweir 			B2DPolyPolygon aRetval;
418cdf0e10cSrcweir 
419cdf0e10cSrcweir 			for(sal_uInt32 a(0L); a < nPolygonCount; a++)
420cdf0e10cSrcweir 			{
421cdf0e10cSrcweir 				const B2DPolygon aCandidate(rCandidate.getB2DPolygon(a));
422cdf0e10cSrcweir 
423cdf0e10cSrcweir 				aRetval.append(rotateAroundPoint(aCandidate, rCenter, fAngle));
424cdf0e10cSrcweir 			}
425cdf0e10cSrcweir 
426cdf0e10cSrcweir 			return aRetval;
427cdf0e10cSrcweir 		}
428cdf0e10cSrcweir 
expandToCurve(const B2DPolyPolygon & rCandidate)429cdf0e10cSrcweir 		B2DPolyPolygon expandToCurve(const B2DPolyPolygon& rCandidate)
430cdf0e10cSrcweir 		{
431cdf0e10cSrcweir 			const sal_uInt32 nPolygonCount(rCandidate.count());
432cdf0e10cSrcweir 			B2DPolyPolygon aRetval;
433cdf0e10cSrcweir 
434cdf0e10cSrcweir 			for(sal_uInt32 a(0L); a < nPolygonCount; a++)
435cdf0e10cSrcweir 			{
436cdf0e10cSrcweir 				const B2DPolygon aCandidate(rCandidate.getB2DPolygon(a));
437cdf0e10cSrcweir 
438cdf0e10cSrcweir 				aRetval.append(expandToCurve(aCandidate));
439cdf0e10cSrcweir 			}
440cdf0e10cSrcweir 
441cdf0e10cSrcweir 			return aRetval;
442cdf0e10cSrcweir 		}
443cdf0e10cSrcweir 
setContinuity(const B2DPolyPolygon & rCandidate,B2VectorContinuity eContinuity)444cdf0e10cSrcweir 		B2DPolyPolygon setContinuity(const B2DPolyPolygon& rCandidate, B2VectorContinuity eContinuity)
445cdf0e10cSrcweir 		{
446cdf0e10cSrcweir 			if(rCandidate.areControlPointsUsed())
447cdf0e10cSrcweir 			{
448cdf0e10cSrcweir 				const sal_uInt32 nPolygonCount(rCandidate.count());
449cdf0e10cSrcweir 				B2DPolyPolygon aRetval;
450cdf0e10cSrcweir 
451cdf0e10cSrcweir 				for(sal_uInt32 a(0L); a < nPolygonCount; a++)
452cdf0e10cSrcweir 				{
453cdf0e10cSrcweir 					const B2DPolygon aCandidate(rCandidate.getB2DPolygon(a));
454cdf0e10cSrcweir 
455cdf0e10cSrcweir 					aRetval.append(setContinuity(aCandidate, eContinuity));
456cdf0e10cSrcweir 				}
457cdf0e10cSrcweir 
458cdf0e10cSrcweir 				return aRetval;
459cdf0e10cSrcweir 			}
460cdf0e10cSrcweir 			else
461cdf0e10cSrcweir 			{
462cdf0e10cSrcweir 				return rCandidate;
463cdf0e10cSrcweir 			}
464cdf0e10cSrcweir 		}
465cdf0e10cSrcweir 
growInNormalDirection(const B2DPolyPolygon & rCandidate,double fValue)466cdf0e10cSrcweir 		B2DPolyPolygon growInNormalDirection(const B2DPolyPolygon& rCandidate, double fValue)
467cdf0e10cSrcweir 		{
468cdf0e10cSrcweir 			if(0.0 != fValue)
469cdf0e10cSrcweir 			{
470cdf0e10cSrcweir 				B2DPolyPolygon aRetval;
471cdf0e10cSrcweir 
472cdf0e10cSrcweir 				for(sal_uInt32 a(0L); a < rCandidate.count(); a++)
473cdf0e10cSrcweir 				{
474cdf0e10cSrcweir 					aRetval.append(growInNormalDirection(rCandidate.getB2DPolygon(a), fValue));
475cdf0e10cSrcweir 				}
476cdf0e10cSrcweir 
477cdf0e10cSrcweir 				return aRetval;
478cdf0e10cSrcweir 			}
479cdf0e10cSrcweir 			else
480cdf0e10cSrcweir 			{
481cdf0e10cSrcweir 				return rCandidate;
482cdf0e10cSrcweir 			}
483cdf0e10cSrcweir 		}
484cdf0e10cSrcweir 
correctGrowShrinkPolygonPair(B2DPolyPolygon &,B2DPolyPolygon &)485cdf0e10cSrcweir 		void correctGrowShrinkPolygonPair(B2DPolyPolygon& /*rOriginal*/, B2DPolyPolygon& /*rGrown*/)
486cdf0e10cSrcweir 		{
487cdf0e10cSrcweir 		}
488cdf0e10cSrcweir 
reSegmentPolyPolygon(const B2DPolyPolygon & rCandidate,sal_uInt32 nSegments)489cdf0e10cSrcweir 		B2DPolyPolygon reSegmentPolyPolygon(const B2DPolyPolygon& rCandidate, sal_uInt32 nSegments)
490cdf0e10cSrcweir 		{
491cdf0e10cSrcweir 			B2DPolyPolygon aRetval;
492cdf0e10cSrcweir 
493cdf0e10cSrcweir 			for(sal_uInt32 a(0L); a < rCandidate.count(); a++)
494cdf0e10cSrcweir 			{
495cdf0e10cSrcweir 				aRetval.append(reSegmentPolygon(rCandidate.getB2DPolygon(a), nSegments));
496cdf0e10cSrcweir 			}
497cdf0e10cSrcweir 
498cdf0e10cSrcweir 			return aRetval;
499cdf0e10cSrcweir 		}
500cdf0e10cSrcweir 
interpolate(const B2DPolyPolygon & rOld1,const B2DPolyPolygon & rOld2,double t)501cdf0e10cSrcweir 		B2DPolyPolygon interpolate(const B2DPolyPolygon& rOld1, const B2DPolyPolygon& rOld2, double t)
502cdf0e10cSrcweir 		{
503cdf0e10cSrcweir 			OSL_ENSURE(rOld1.count() == rOld2.count(), "B2DPolyPolygon interpolate: Different geometry (!)");
504cdf0e10cSrcweir 			B2DPolyPolygon aRetval;
505cdf0e10cSrcweir 
506cdf0e10cSrcweir 			for(sal_uInt32 a(0L); a < rOld1.count(); a++)
507cdf0e10cSrcweir 			{
508cdf0e10cSrcweir 				aRetval.append(interpolate(rOld1.getB2DPolygon(a), rOld2.getB2DPolygon(a), t));
509cdf0e10cSrcweir 			}
510cdf0e10cSrcweir 
511cdf0e10cSrcweir 			return aRetval;
512cdf0e10cSrcweir 		}
513cdf0e10cSrcweir 
isRectangle(const B2DPolyPolygon & rPoly)514cdf0e10cSrcweir         bool isRectangle( const B2DPolyPolygon& rPoly )
515cdf0e10cSrcweir         {
516cdf0e10cSrcweir             // exclude some cheap cases first
517cdf0e10cSrcweir             if( rPoly.count() != 1 )
518cdf0e10cSrcweir                 return false;
519cdf0e10cSrcweir 
520cdf0e10cSrcweir             return isRectangle( rPoly.getB2DPolygon(0) );
521cdf0e10cSrcweir         }
522cdf0e10cSrcweir 
523cdf0e10cSrcweir 		// #i76891#
simplifyCurveSegments(const B2DPolyPolygon & rCandidate)524cdf0e10cSrcweir 		B2DPolyPolygon simplifyCurveSegments(const B2DPolyPolygon& rCandidate)
525cdf0e10cSrcweir 		{
526cdf0e10cSrcweir 			if(rCandidate.areControlPointsUsed())
527cdf0e10cSrcweir 			{
528cdf0e10cSrcweir 				B2DPolyPolygon aRetval;
529cdf0e10cSrcweir 
530cdf0e10cSrcweir 				for(sal_uInt32 a(0L); a < rCandidate.count(); a++)
531cdf0e10cSrcweir 				{
532cdf0e10cSrcweir 					aRetval.append(simplifyCurveSegments(rCandidate.getB2DPolygon(a)));
533cdf0e10cSrcweir 				}
534cdf0e10cSrcweir 
535cdf0e10cSrcweir 				return aRetval;
536cdf0e10cSrcweir 			}
537cdf0e10cSrcweir 			else
538cdf0e10cSrcweir 			{
539cdf0e10cSrcweir 				return rCandidate;
540cdf0e10cSrcweir 			}
541cdf0e10cSrcweir 		}
542cdf0e10cSrcweir 
reSegmentPolyPolygonEdges(const B2DPolyPolygon & rCandidate,sal_uInt32 nSubEdges,bool bHandleCurvedEdges,bool bHandleStraightEdges)543cdf0e10cSrcweir 		B2DPolyPolygon reSegmentPolyPolygonEdges(const B2DPolyPolygon& rCandidate, sal_uInt32 nSubEdges, bool bHandleCurvedEdges, bool bHandleStraightEdges)
544cdf0e10cSrcweir         {
545cdf0e10cSrcweir 			B2DPolyPolygon aRetval;
546cdf0e10cSrcweir 
547cdf0e10cSrcweir 			for(sal_uInt32 a(0L); a < rCandidate.count(); a++)
548cdf0e10cSrcweir 			{
549cdf0e10cSrcweir 				aRetval.append(reSegmentPolygonEdges(rCandidate.getB2DPolygon(a), nSubEdges, bHandleCurvedEdges, bHandleStraightEdges));
550cdf0e10cSrcweir 			}
551cdf0e10cSrcweir 
552cdf0e10cSrcweir 			return aRetval;
553cdf0e10cSrcweir         }
554cdf0e10cSrcweir 
555cdf0e10cSrcweir         //////////////////////////////////////////////////////////////////////
556cdf0e10cSrcweir 		// comparators with tolerance for 2D PolyPolygons
557cdf0e10cSrcweir 
equal(const B2DPolyPolygon & rCandidateA,const B2DPolyPolygon & rCandidateB,const double & rfSmallValue)558cdf0e10cSrcweir 		bool equal(const B2DPolyPolygon& rCandidateA, const B2DPolyPolygon& rCandidateB, const double& rfSmallValue)
559cdf0e10cSrcweir 		{
560cdf0e10cSrcweir 			const sal_uInt32 nPolygonCount(rCandidateA.count());
561cdf0e10cSrcweir 
562cdf0e10cSrcweir 			if(nPolygonCount != rCandidateB.count())
563cdf0e10cSrcweir 				return false;
564cdf0e10cSrcweir 
565cdf0e10cSrcweir 			for(sal_uInt32 a(0); a < nPolygonCount; a++)
566cdf0e10cSrcweir 			{
567cdf0e10cSrcweir 				const B2DPolygon aCandidate(rCandidateA.getB2DPolygon(a));
568cdf0e10cSrcweir 
569cdf0e10cSrcweir 				if(!equal(aCandidate, rCandidateB.getB2DPolygon(a), rfSmallValue))
570cdf0e10cSrcweir 					return false;
571cdf0e10cSrcweir 			}
572cdf0e10cSrcweir 
573cdf0e10cSrcweir 			return true;
574cdf0e10cSrcweir 		}
575cdf0e10cSrcweir 
equal(const B2DPolyPolygon & rCandidateA,const B2DPolyPolygon & rCandidateB)576cdf0e10cSrcweir 		bool equal(const B2DPolyPolygon& rCandidateA, const B2DPolyPolygon& rCandidateB)
577cdf0e10cSrcweir 		{
578cdf0e10cSrcweir 			const double fSmallValue(fTools::getSmallValue());
579cdf0e10cSrcweir 
580cdf0e10cSrcweir 			return equal(rCandidateA, rCandidateB, fSmallValue);
581cdf0e10cSrcweir 		}
582cdf0e10cSrcweir 
snapPointsOfHorizontalOrVerticalEdges(const B2DPolyPolygon & rCandidate)583cdf0e10cSrcweir 		B2DPolyPolygon snapPointsOfHorizontalOrVerticalEdges(const B2DPolyPolygon& rCandidate)
584cdf0e10cSrcweir 		{
585cdf0e10cSrcweir 			B2DPolyPolygon aRetval;
586cdf0e10cSrcweir 
587cdf0e10cSrcweir 			for(sal_uInt32 a(0L); a < rCandidate.count(); a++)
588cdf0e10cSrcweir 			{
589cdf0e10cSrcweir 				aRetval.append(snapPointsOfHorizontalOrVerticalEdges(rCandidate.getB2DPolygon(a)));
590cdf0e10cSrcweir 			}
591cdf0e10cSrcweir 
592cdf0e10cSrcweir 			return aRetval;
593cdf0e10cSrcweir 		}
594cdf0e10cSrcweir 
containsOnlyHorizontalAndVerticalEdges(const B2DPolyPolygon & rCandidate)595d8ed516eSArmin Le Grand         bool containsOnlyHorizontalAndVerticalEdges(const B2DPolyPolygon& rCandidate)
596d8ed516eSArmin Le Grand         {
597d8ed516eSArmin Le Grand             if(rCandidate.areControlPointsUsed())
598d8ed516eSArmin Le Grand             {
599d8ed516eSArmin Le Grand                 return false;
600d8ed516eSArmin Le Grand             }
601d8ed516eSArmin Le Grand 
602d8ed516eSArmin Le Grand             for(sal_uInt32 a(0); a < rCandidate.count(); a++)
603d8ed516eSArmin Le Grand             {
604d8ed516eSArmin Le Grand                 if(!containsOnlyHorizontalAndVerticalEdges(rCandidate.getB2DPolygon(a)))
605d8ed516eSArmin Le Grand                 {
606d8ed516eSArmin Le Grand                     return false;
607d8ed516eSArmin Le Grand                 }
608d8ed516eSArmin Le Grand             }
609d8ed516eSArmin Le Grand 
610d8ed516eSArmin Le Grand             return true;
611d8ed516eSArmin Le Grand         }
6121f882ec4SArmin Le Grand 
6131f882ec4SArmin Le Grand         //////////////////////////////////////////////////////////////////////////////
6141f882ec4SArmin Le Grand         // converters for com::sun::star::drawing::PointSequence
6151f882ec4SArmin Le Grand 
UnoPointSequenceSequenceToB2DPolyPolygon(const com::sun::star::drawing::PointSequenceSequence & rPointSequenceSequenceSource,bool bCheckClosed)6161f882ec4SArmin Le Grand         B2DPolyPolygon UnoPointSequenceSequenceToB2DPolyPolygon(
6171f882ec4SArmin Le Grand             const com::sun::star::drawing::PointSequenceSequence& rPointSequenceSequenceSource,
6181f882ec4SArmin Le Grand             bool bCheckClosed)
6191f882ec4SArmin Le Grand         {
6201f882ec4SArmin Le Grand             B2DPolyPolygon aRetval;
6211f882ec4SArmin Le Grand             const com::sun::star::drawing::PointSequence* pPointSequence = rPointSequenceSequenceSource.getConstArray();
6221f882ec4SArmin Le Grand             const com::sun::star::drawing::PointSequence* pPointSeqEnd = pPointSequence + rPointSequenceSequenceSource.getLength();
6231f882ec4SArmin Le Grand 
6241f882ec4SArmin Le Grand             for(;pPointSequence != pPointSeqEnd; pPointSequence++)
6251f882ec4SArmin Le Grand             {
6261f882ec4SArmin Le Grand                 const B2DPolygon aNewPolygon = UnoPointSequenceToB2DPolygon(*pPointSequence, bCheckClosed);
6271f882ec4SArmin Le Grand                 aRetval.append(aNewPolygon);
6281f882ec4SArmin Le Grand             }
6291f882ec4SArmin Le Grand 
6301f882ec4SArmin Le Grand             return aRetval;
6311f882ec4SArmin Le Grand         }
6321f882ec4SArmin Le Grand 
B2DPolyPolygonToUnoPointSequenceSequence(const B2DPolyPolygon & rPolyPolygon,com::sun::star::drawing::PointSequenceSequence & rPointSequenceSequenceRetval)6331f882ec4SArmin Le Grand         void B2DPolyPolygonToUnoPointSequenceSequence(
6341f882ec4SArmin Le Grand             const B2DPolyPolygon& rPolyPolygon,
6351f882ec4SArmin Le Grand             com::sun::star::drawing::PointSequenceSequence& rPointSequenceSequenceRetval)
6361f882ec4SArmin Le Grand         {
6371f882ec4SArmin Le Grand             const sal_uInt32 nCount(rPolyPolygon.count());
6381f882ec4SArmin Le Grand 
6391f882ec4SArmin Le Grand             if(nCount)
6401f882ec4SArmin Le Grand             {
6411f882ec4SArmin Le Grand                 rPointSequenceSequenceRetval.realloc(nCount);
6421f882ec4SArmin Le Grand                 com::sun::star::drawing::PointSequence* pPointSequence = rPointSequenceSequenceRetval.getArray();
6431f882ec4SArmin Le Grand 
6441f882ec4SArmin Le Grand                 for(sal_uInt32 a(0); a < nCount; a++)
6451f882ec4SArmin Le Grand                 {
6461f882ec4SArmin Le Grand                     const B2DPolygon aPolygon(rPolyPolygon.getB2DPolygon(a));
6471f882ec4SArmin Le Grand 
6481f882ec4SArmin Le Grand                     B2DPolygonToUnoPointSequence(aPolygon, *pPointSequence);
6491f882ec4SArmin Le Grand                     pPointSequence++;
6501f882ec4SArmin Le Grand                 }
6511f882ec4SArmin Le Grand             }
6521f882ec4SArmin Le Grand             else
6531f882ec4SArmin Le Grand             {
6541f882ec4SArmin Le Grand                 rPointSequenceSequenceRetval.realloc(0);
6551f882ec4SArmin Le Grand             }
6561f882ec4SArmin Le Grand         }
6571f882ec4SArmin Le Grand 
6581f882ec4SArmin Le Grand         //////////////////////////////////////////////////////////////////////////////
6591f882ec4SArmin Le Grand         // converters for com::sun::star::drawing::PolyPolygonBezierCoords (curved polygons)
6601f882ec4SArmin Le Grand 
UnoPolyPolygonBezierCoordsToB2DPolyPolygon(const com::sun::star::drawing::PolyPolygonBezierCoords & rPolyPolygonBezierCoordsSource,bool bCheckClosed)6611f882ec4SArmin Le Grand         B2DPolyPolygon UnoPolyPolygonBezierCoordsToB2DPolyPolygon(
6621f882ec4SArmin Le Grand             const com::sun::star::drawing::PolyPolygonBezierCoords& rPolyPolygonBezierCoordsSource,
6631f882ec4SArmin Le Grand             bool bCheckClosed)
6641f882ec4SArmin Le Grand         {
6651f882ec4SArmin Le Grand             B2DPolyPolygon aRetval;
6661f882ec4SArmin Le Grand             const sal_uInt32 nSequenceCount((sal_uInt32)rPolyPolygonBezierCoordsSource.Coordinates.getLength());
6671f882ec4SArmin Le Grand 
6681f882ec4SArmin Le Grand             if(nSequenceCount)
6691f882ec4SArmin Le Grand             {
6701f882ec4SArmin Le Grand                 OSL_ENSURE(nSequenceCount == (sal_uInt32)rPolyPolygonBezierCoordsSource.Flags.getLength(),
6711f882ec4SArmin Le Grand                     "UnoPolyPolygonBezierCoordsToB2DPolyPolygon: unequal number of Points and Flags (!)");
6721f882ec4SArmin Le Grand                 const com::sun::star::drawing::PointSequence* pPointSequence = rPolyPolygonBezierCoordsSource.Coordinates.getConstArray();
6731f882ec4SArmin Le Grand                 const com::sun::star::drawing::FlagSequence* pFlagSequence = rPolyPolygonBezierCoordsSource.Flags.getConstArray();
6741f882ec4SArmin Le Grand 
6751f882ec4SArmin Le Grand                 for(sal_uInt32 a(0); a < nSequenceCount; a++)
6761f882ec4SArmin Le Grand                 {
6771f882ec4SArmin Le Grand                     const B2DPolygon aNewPolygon(UnoPolygonBezierCoordsToB2DPolygon(
6781f882ec4SArmin Le Grand                         *pPointSequence,
6791f882ec4SArmin Le Grand                         *pFlagSequence,
6801f882ec4SArmin Le Grand                         bCheckClosed));
6811f882ec4SArmin Le Grand 
6821f882ec4SArmin Le Grand                     pPointSequence++;
6831f882ec4SArmin Le Grand                     pFlagSequence++;
6841f882ec4SArmin Le Grand                     aRetval.append(aNewPolygon);
6851f882ec4SArmin Le Grand                 }
6861f882ec4SArmin Le Grand             }
6871f882ec4SArmin Le Grand 
6881f882ec4SArmin Le Grand             return aRetval;
6891f882ec4SArmin Le Grand         }
6901f882ec4SArmin Le Grand 
B2DPolyPolygonToUnoPolyPolygonBezierCoords(const B2DPolyPolygon & rPolyPolygon,com::sun::star::drawing::PolyPolygonBezierCoords & rPolyPolygonBezierCoordsRetval)6911f882ec4SArmin Le Grand         void B2DPolyPolygonToUnoPolyPolygonBezierCoords(
6921f882ec4SArmin Le Grand             const B2DPolyPolygon& rPolyPolygon,
6931f882ec4SArmin Le Grand             com::sun::star::drawing::PolyPolygonBezierCoords& rPolyPolygonBezierCoordsRetval)
6941f882ec4SArmin Le Grand         {
6951f882ec4SArmin Le Grand             const sal_uInt32 nCount(rPolyPolygon.count());
6961f882ec4SArmin Le Grand 
6971f882ec4SArmin Le Grand             if(nCount)
6981f882ec4SArmin Le Grand             {
6991f882ec4SArmin Le Grand                 // prepare return value memory
7001f882ec4SArmin Le Grand                 rPolyPolygonBezierCoordsRetval.Coordinates.realloc((sal_Int32)nCount);
7011f882ec4SArmin Le Grand                 rPolyPolygonBezierCoordsRetval.Flags.realloc((sal_Int32)nCount);
7021f882ec4SArmin Le Grand 
7031f882ec4SArmin Le Grand                 // get pointers to arrays
7041f882ec4SArmin Le Grand                 com::sun::star::drawing::PointSequence* pPointSequence = rPolyPolygonBezierCoordsRetval.Coordinates.getArray();
7051f882ec4SArmin Le Grand                 com::sun::star::drawing::FlagSequence*  pFlagSequence = rPolyPolygonBezierCoordsRetval.Flags.getArray();
7061f882ec4SArmin Le Grand 
7071f882ec4SArmin Le Grand                 for(sal_uInt32 a(0); a < nCount; a++)
7081f882ec4SArmin Le Grand                 {
7091f882ec4SArmin Le Grand                     const B2DPolygon aSource(rPolyPolygon.getB2DPolygon(a));
7101f882ec4SArmin Le Grand 
7111f882ec4SArmin Le Grand                     B2DPolygonToUnoPolygonBezierCoords(
7121f882ec4SArmin Le Grand                         aSource,
7131f882ec4SArmin Le Grand                         *pPointSequence,
7141f882ec4SArmin Le Grand                         *pFlagSequence);
7151f882ec4SArmin Le Grand                     pPointSequence++;
7161f882ec4SArmin Le Grand                     pFlagSequence++;
7171f882ec4SArmin Le Grand                 }
7181f882ec4SArmin Le Grand             }
7191f882ec4SArmin Le Grand             else
7201f882ec4SArmin Le Grand             {
7211f882ec4SArmin Le Grand                 rPolyPolygonBezierCoordsRetval.Coordinates.realloc(0);
7221f882ec4SArmin Le Grand                 rPolyPolygonBezierCoordsRetval.Flags.realloc(0);
7231f882ec4SArmin Le Grand             }
7241f882ec4SArmin Le Grand         }
7251f882ec4SArmin Le Grand 
726d8ed516eSArmin Le Grand     } // end of namespace tools
727cdf0e10cSrcweir } // end of namespace basegfx
728cdf0e10cSrcweir 
729cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
730cdf0e10cSrcweir // eof
731