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 #ifndef _BGFX_POLYGON_B2DPOLYGONTOOLS_HXX
25 #define _BGFX_POLYGON_B2DPOLYGONTOOLS_HXX
26 
27 #include <basegfx/point/b2dpoint.hxx>
28 #include <basegfx/vector/b2dvector.hxx>
29 #include <basegfx/range/b2drectangle.hxx>
30 #include <basegfx/polygon/b2dpolypolygon.hxx>
31 #include <basegfx/polygon/b3dpolygon.hxx>
32 #include <com/sun/star/drawing/PointSequence.hpp>
33 #include <com/sun/star/drawing/FlagSequence.hpp>
34 #include <vector>
35 
36 //////////////////////////////////////////////////////////////////////////////
37 
38 namespace basegfx
39 {
40 	// predefinitions
41 	class B2DPolygon;
42 	class B2DRange;
43 
44 	namespace tools
45 	{
46 		// B2DPolygon tools
47 
48 		// open/close with point add/remove and control point corrections
49 		void openWithGeometryChange(B2DPolygon& rCandidate);
50 		void closeWithGeometryChange(B2DPolygon& rCandidate);
51 
52 		/**	Check if given polygon is closed.
53 
54         	This is kind of a 'classic' method to support old polygon
55         	definitions.  Those old polygon definitions define the
56         	closed state of the polygon using identical start and
57         	endpoints. This method corrects this (removes double
58         	start/end points) and sets the Closed()-state of the
59         	polygon correctly.
60 		*/
61 		void checkClosed(B2DPolygon& rCandidate);
62 
63 		// Get successor and predecessor indices. Returning the same index means there
64 		// is none. Same for successor.
65 		sal_uInt32 getIndexOfPredecessor(sal_uInt32 nIndex, const B2DPolygon& rCandidate);
66 		sal_uInt32 getIndexOfSuccessor(sal_uInt32 nIndex, const B2DPolygon& rCandidate);
67 
68 		// Get orientation of Polygon
69 		B2VectorOrientation getOrientation(const B2DPolygon& rCandidate);
70 
71 		// isInside tests for B2dPoint and other B2dPolygon. On border is not inside as long as
72 		// not true is given in bWithBorder flag.
73 		bool isInside(const B2DPolygon& rCandidate, const B2DPoint& rPoint, bool bWithBorder = false);
74 		bool isInside(const B2DPolygon& rCandidate, const B2DPolygon& rPolygon, bool bWithBorder = false);
75 
76 		/** Get the range of a polygon including bezier control points
77 
78 			For detailed discussion, see B2DPolygon::getB2DRange()
79 
80 			@param rCandidate
81 			The B2DPolygon eventually containing bezier segments
82 
83 			@return
84 			The outer range of the bezier curve containing bezier control points
85 		*/
86 		B2DRange getRangeWithControlPoints(const B2DPolygon& rCandidate);
87 
88 		/** Get the range of a polygon
89 
90 			This method creates the outer range of the subdivided bezier curve.
91             For detailed discussion see B2DPolygon::getB2DRange()
92 
93             @param rCandidate
94 			The B2DPolygon eventually containing bezier segments
95 
96 			@return
97 			The outer range of the bezier curve
98 		*/
99 		B2DRange getRange(const B2DPolygon& rCandidate);
100 
101 		// get signed area of polygon
102 		double getSignedArea(const B2DPolygon& rCandidate);
103 
104 		// get area of polygon
105 		double getArea(const B2DPolygon& rCandidate);
106 
107 		/** get length of polygon edge from point nIndex to nIndex + 1 */
108 		double getEdgeLength(const B2DPolygon& rCandidate, sal_uInt32 nIndex);
109 
110 		/** get length of polygon */
111 		double getLength(const B2DPolygon& rCandidate);
112 
113 		// get position on polygon for absolute given distance. If
114 		// length is given, it is assumed the correct polygon length, if 0.0 it is calculated
115 		// using getLength(...)
116 		B2DPoint getPositionAbsolute(const B2DPolygon& rCandidate, double fDistance, double fLength = 0.0);
117 
118 		// get position on polygon for relative given distance in range [0.0 .. 1.0]. If
119 		// length is given, it is assumed the correct polygon length, if 0.0 it is calculated
120 		// using getLength(...)
121 		B2DPoint getPositionRelative(const B2DPolygon& rCandidate, double fDistance, double fLength = 0.0);
122 
123 		// get a snippet from given polygon for absolute distances. The polygon is assumed
124 		// to be opened (not closed). fFrom and fTo need to be in range [0.0 .. fLength], where
125 		// fTo >= fFrom. If length is given, it is assumed the correct polygon length,
126 		// if 0.0 it is calculated using getLength(...)
127 		B2DPolygon getSnippetAbsolute(const B2DPolygon& rCandidate, double fFrom, double fTo, double fLength = 0.0);
128 
129 		// get a snippet from given polygon for relative distances. The polygon is assumed
130 		// to be opened (not closed). fFrom and fTo need to be in range [0.0 .. 1.0], where
131 		// fTo >= fFrom. If length is given, it is assumed the correct polygon length,
132 		// if 0.0 it is calculated using getLength(...)
133 		B2DPolygon getSnippetRelative(const B2DPolygon& rCandidate, double fFrom = 0.0, double fTo = 1.0, double fLength = 0.0);
134 
135 		// Continuity check for point with given index
136 		B2VectorContinuity getContinuityInPoint(const B2DPolygon& rCandidate, sal_uInt32 nIndex);
137 
138 		// Subdivide all contained curves. Use distanceBound value if given.
139 		B2DPolygon adaptiveSubdivideByDistance(const B2DPolygon& rCandidate, double fDistanceBound = 0.0);
140 
141 		// Subdivide all contained curves. Use angleBound value if given.
142 		B2DPolygon adaptiveSubdivideByAngle(const B2DPolygon& rCandidate, double fAngleBound = 0.0);
143 
144 		// #i37443# Subdivide all contained curves.
145 		B2DPolygon adaptiveSubdivideByCount(const B2DPolygon& rCandidate, sal_uInt32 nCount = 0L);
146 
147         // Definitions for the cut flags used from the findCut methods
148 		typedef sal_uInt16 CutFlagValue;
149 
150 		#define	CUTFLAG_NONE			(0x0000)
151 		#define	CUTFLAG_LINE			(0x0001)
152 		#define	CUTFLAG_START1			(0x0002)
153 		#define	CUTFLAG_START2			(0x0004)
154 		#define	CUTFLAG_END1			(0x0008)
155 		#define	CUTFLAG_END2			(0x0010)
156 		#define	CUTFLAG_ALL			(CUTFLAG_LINE|CUTFLAG_START1|CUTFLAG_START2|CUTFLAG_END1|CUTFLAG_END2)
157 		#define	CUTFLAG_DEFAULT		(CUTFLAG_LINE|CUTFLAG_START2|CUTFLAG_END2)
158 
159 		// Calculate cut between the points given by the two indices. pCut1
160 		// and pCut2 will contain the cut coordinate on each edge in ]0.0, 1.0]
161 		// (if given) and the return value will contain a cut description.
162 		CutFlagValue findCut(
163 			const B2DPolygon& rCandidate,
164 			sal_uInt32 nIndex1, sal_uInt32 nIndex2,
165 			CutFlagValue aCutFlags = CUTFLAG_DEFAULT,
166 			double* pCut1 = 0L, double* pCut2 = 0L);
167 
168 		// This version is working with two indexed edges from different
169 		// polygons.
170 		CutFlagValue findCut(
171 			const B2DPolygon& rCandidate1, sal_uInt32 nIndex1,
172 			const B2DPolygon& rCandidate2, sal_uInt32 nIndex2,
173 			CutFlagValue aCutFlags = CUTFLAG_DEFAULT,
174 			double* pCut1 = 0L, double* pCut2 = 0L);
175 
176 		// This version works with two points and vectors to define the
177 		// edges for the cut test.
178 		CutFlagValue findCut(
179 			const B2DPoint& rEdge1Start, const B2DVector& rEdge1Delta,
180 			const B2DPoint& rEdge2Start, const B2DVector& rEdge2Delta,
181 			CutFlagValue aCutFlags = CUTFLAG_DEFAULT,
182 			double* pCut1 = 0L, double* pCut2 = 0L);
183 
184 		// test if point is on the given edge in range ]0.0..1.0[ without
185 		// the start/end points. If so, return true and put the parameter
186 		// value in pCut (if provided)
187 		bool isPointOnEdge(
188 			const B2DPoint& rPoint,
189 			const B2DPoint& rEdgeStart,
190 			const B2DVector& rEdgeDelta,
191 			double* pCut = 0L);
192 
193 		/** Apply given LineDashing to given polygon
194 
195 			This method is used to cut down line polygons to the needed
196 			pieces when a dashing needs to be applied.
197 			It is now capable of keeping contained bezier segments.
198 			It is also capable of delivering line and non-line portions
199 			depending on what target polygons You provide. This is useful
200 			e.g. for dashed lines with two colors.
201 			If the last and the first snippet in one of the results have
202 			a common start/end ppoint, they will be merged to achieve as
203 			view as needed result line snippets. This is also relevant for
204 			further processing the results.
205 
206 			@param rCandidate
207 			The polygon based on which the snippets will be created.
208 
209 			@param rDotDashArray
210 			The line pattern given as array of length values
211 
212 			@param pLineTarget
213 			The target for line snippets, e.g. the first entry will be
214 			a line segment with length rDotDashArray[0]. The given
215 			polygon will be emptied as preparation.
216 
217 			@param pGapTarget
218 			The target for gap snippets, e.g. the first entry will be
219 			a line segment with length rDotDashArray[1]. The given
220 			polygon will be emptied as preparation.
221 
222 			@param fFullDashDotLen
223 			The sumed-up length of the rDotDashArray. If zero, it will
224 			be calculated internally.
225 		*/
226 		void applyLineDashing(
227 			const B2DPolygon& rCandidate,
228 			const ::std::vector<double>& rDotDashArray,
229 			B2DPolyPolygon* pLineTarget,
230             B2DPolyPolygon* pGapTarget = 0,
231 			double fFullDashDotLen = 0.0);
232 
233 		// test if point is inside epsilon-range around an edge defined
234 		// by the two given points. Can be used for HitTesting. The epsilon-range
235 		// is defined to be the rectangle centered to the given edge, using height
236 		// 2 x fDistance, and the circle around both points with radius fDistance.
237 		bool isInEpsilonRange(const B2DPoint& rEdgeStart, const B2DPoint& rEdgeEnd, const B2DPoint& rTestPosition, double fDistance);
238 
239 		// test if point is inside epsilon-range around the given Polygon. Can be used
240 		// for HitTesting. The epsilon-range is defined to be the rectangle centered
241         // to the given edge, using height 2 x fDistance, and the circle around both points
242         // with radius fDistance.
243 		bool isInEpsilonRange(const B2DPolygon& rCandidate, const B2DPoint& rTestPosition, double fDistance);
244 
245         /** Create a polygon from a rectangle.
246 
247 			@param rRect
248             The rectangle which describes the polygon size
249 
250 			@param fRadius
251             Radius of the edge rounding, relative to the rectangle size. 0.0 means no
252 			rounding, 1.0 will lead to an ellipse
253          */
254         B2DPolygon createPolygonFromRect( const B2DRectangle& rRect, double fRadius );
255 
256         /** Create a polygon from a rectangle.
257 
258 			@param rRect
259             The rectangle which describes the polygon size
260 
261 			@param fRadiusX
262 			@param fRadiusY
263             Radius of the edge rounding, relative to the rectangle size. 0.0 means no
264 			rounding, 1.0 will lead to an ellipse
265          */
266 		B2DPolygon createPolygonFromRect( const B2DRectangle& rRect, double fRadiusX, double fRadiusY );
267 
268         /** Create a polygon from a rectangle.
269          */
270 		B2DPolygon createPolygonFromRect( const B2DRectangle& rRect );
271 
272         /** Create the unit polygon
273          */
274 		B2DPolygon createUnitPolygon();
275 
276         /** Create a circle polygon with given radius.
277 
278         	This method creates a circle approximation consisting of
279         	four cubic bezier segments, which approximate the given
280         	circle with an error of less than 0.5 percent.
281 
282         	@param rCenter
283             Center point of the circle
284 
285             @param fRadius
286             Radius of the circle
287          */
288         B2DPolygon createPolygonFromCircle( const B2DPoint& rCenter, double fRadius );
289 
290         /// create half circle centered on (0,0) from [0 .. F_PI]
291         B2DPolygon createHalfUnitCircle();
292 
293 		/** create a polygon which describes the unit circle and close it
294 
295 			@param nStartQuadrant
296 			To be able to rebuild the old behaviour where the circles started at bottom,
297 			this parameter is used. Default is 0 which is the first quadrant and the
298 			polygon's start point will be the rightmost one. When using e.g. 1, the
299 			first created quadrant will start at the YMax-position (with Y down on screens,
300 			this is the lowest one). This is needed since when lines are dashed, toe old
301 			geometry started at bottom point, else it would look different.
302 		 */
303         B2DPolygon createPolygonFromUnitCircle(sal_uInt32 nStartQuadrant = 0);
304 
305 		/** Create an ellipse polygon with given radii.
306 
307         	This method creates an ellipse approximation consisting of
308         	four cubic bezier segments, which approximate the given
309         	ellipse with an error of less than 0.5 percent.
310 
311         	@param rCenter
312             Center point of the circle
313 
314             @param fRadiusX
315             Radius of the ellipse in X direction
316 
317             @param fRadiusY
318             Radius of the ellipse in Y direction
319          */
320         B2DPolygon createPolygonFromEllipse( const B2DPoint& rCenter, double fRadiusX, double fRadiusY );
321 
322 		/** Create an unit ellipse polygon with the given angles, from start to end
323          */
324         B2DPolygon createPolygonFromEllipseSegment( const B2DPoint& rCenter, double fRadiusX, double fRadiusY, double	fStart, double fEnd );
325 
326         B2DPolygon createPolygonFromUnitEllipseSegment( double fStart, double fEnd );
327 
328         /** Predicate whether a given polygon is a rectangle.
329 
330         	@param rPoly
331             Polygon to check
332 
333             @return true, if the polygon describes a rectangle
334             (polygon is closed, and the points are either cw or ccw
335             enumerations of a rectangle's vertices). Note that
336             intermediate points and duplicate points are ignored.
337          */
338         bool isRectangle( const B2DPolygon& rPoly );
339 
340 		// create 3d polygon from given 2d polygon. The given fZCoordinate is used to expand the
341 		// third coordinate.
342 		B3DPolygon createB3DPolygonFromB2DPolygon(const B2DPolygon& rCandidate, double fZCoordinate = 0.0);
343 
344 		// create 2d PolyPolygon from given 3d PolyPolygon. All coordinates are transformed using the given
345 		// matrix and the resulting x,y is used to form the new polygon.
346 		B2DPolygon createB2DPolygonFromB3DPolygon(const B3DPolygon& rCandidate, const B3DHomMatrix& rMat);
347 
348 		// create simplified version of the original polygon by
349 		// replacing segments with spikes/loops and self intersections
350 		// by several trivial sub-segments
351 		B2DPolygon createSimplifiedPolygon(const B2DPolygon&);
352 
353 		// calculate the distance to the given endless ray and return. The relative position on the edge is returned in Cut.
354         // That position may be less than 0.0 or more than 1.0
355 		double getDistancePointToEndlessRay(const B2DPoint& rPointA, const B2DPoint& rPointB, const B2DPoint& rTestPoint, double& rCut);
356 
357 		// calculate the smallest distance to given edge and return. The relative position on the edge is returned in Cut.
358         // That position is in the range [0.0 .. 1.0] and the returned distance is adapted accordingly to the start or end
359         // point of the edge
360 		double getSmallestDistancePointToEdge(const B2DPoint& rPointA, const B2DPoint& rPointB, const B2DPoint& rTestPoint, double& rCut);
361 
362 		// for each contained edge calculate the smallest distance. Return the index to the smallest
363 		// edge in rEdgeIndex. The relative position on the edge is returned in rCut.
364 		// If nothing was found (e.g. empty input plygon), DBL_MAX is returned.
365 		double getSmallestDistancePointToPolygon(const B2DPolygon& rCandidate, const B2DPoint& rTestPoint, sal_uInt32& rEdgeIndex, double& rCut);
366 
367 		// distort single point. rOriginal describes the original range, where the given points describe the distorted corresponding points.
368 		B2DPoint distort(const B2DPoint& rCandidate, const B2DRange& rOriginal, const B2DPoint& rTopLeft, const B2DPoint& rTopRight, const B2DPoint& rBottomLeft, const B2DPoint& rBottomRight);
369 
370 		// distort polygon. rOriginal describes the original range, where the given points describe the distorted corresponding points.
371 		B2DPolygon distort(const B2DPolygon& rCandidate, const B2DRange& rOriginal, const B2DPoint& rTopLeft, const B2DPoint& rTopRight, const B2DPoint& rBottomLeft, const B2DPoint& rBottomRight);
372 
373 		// rotate polygon around given point with given angle.
374 		B2DPolygon rotateAroundPoint(const B2DPolygon& rCandidate, const B2DPoint& rCenter, double fAngle);
375 
376 		// expand all segments (which are not yet) to curve segments. This is done with setting the control
377 		// vectors on the 1/3 resp. 2/3 distances on each segment.
378 		B2DPolygon expandToCurve(const B2DPolygon& rCandidate);
379 
380 		// expand given segment to curve segment. This is done with setting the control
381 		// vectors on the 1/3 resp. 2/3 distances. The return value describes if a change took place.
382 		bool expandToCurveInPoint(B2DPolygon& rCandidate, sal_uInt32 nIndex);
383 
384 		// set continuity for the whole curve. If not a curve, nothing will change. Non-curve points are not changed, too.
385 		B2DPolygon setContinuity(const B2DPolygon& rCandidate, B2VectorContinuity eContinuity);
386 
387 		// set continuity for given index. If not a curve, nothing will change. Non-curve points are not changed, too.
388 		// The return value describes if a change took place.
389 		bool setContinuityInPoint(B2DPolygon& rCandidate, sal_uInt32 nIndex, B2VectorContinuity eContinuity);
390 
391 		// test if polygon contains neutral points. A neutral point is one whos orientation is neutral
392 		// e.g. positioned on the edge of it's predecessor and successor
393 		bool hasNeutralPoints(const B2DPolygon& rCandidate);
394 
395 		// remove neutral points. A neutral point is one whos orientation is neutral
396 		// e.g. positioned on the edge of it's predecessor and successor
397 		B2DPolygon removeNeutralPoints(const B2DPolygon& rCandidate);
398 
399 		// tests if polygon is convex
400 		bool isConvex(const B2DPolygon& rCandidate);
401 
402 		// calculates the orientation at edge nIndex
403 		B2VectorOrientation getOrientationForIndex(const B2DPolygon& rCandidate, sal_uInt32 nIndex);
404 
405 		// calculates if given point is on given line, taking care of the numerical epsilon
406 		bool isPointOnLine(const B2DPoint& rStart, const B2DPoint& rEnd, const B2DPoint& rCandidate, bool bWithPoints = false);
407 
408 		// calculates if given point is on given polygon, taking care of the numerical epsilon. Uses
409 		// isPointOnLine internally
410 		bool isPointOnPolygon(const B2DPolygon& rCandidate, const B2DPoint& rPoint, bool bWithPoints = true);
411 
412 		// test if candidate is inside triangle
413 		bool isPointInTriangle(const B2DPoint& rA, const B2DPoint& rB, const B2DPoint& rC, const B2DPoint& rCandidate, bool bWithBorder = false);
414 
415 		// test if candidateA and candidateB are on the same side of the given line
416 		bool arePointsOnSameSideOfLine(const B2DPoint& rStart, const B2DPoint& rEnd, const B2DPoint& rCandidateA, const B2DPoint& rCandidateB, bool bWithLine = false);
417 
418 		// add triangles for given rCandidate to rTarget. For each triangle, 3 points will be added to rCandidate.
419 		// All triangles will go from the start point of rCandidate to two consecutive points, building (rCandidate.count() - 2)
420 		// triangles.
421 		void addTriangleFan(const B2DPolygon& rCandidate, B2DPolygon& rTarget);
422 
423 		// grow for polygon. Move all geometry in each point in the direction of the normal in that point
424 		// with the given amount. Value may be negative.
425 		B2DPolygon growInNormalDirection(const B2DPolygon& rCandidate, double fValue);
426 
427 		// force all sub-polygons to a point count of nSegments
428 		B2DPolygon reSegmentPolygon(const B2DPolygon& rCandidate, sal_uInt32 nSegments);
429 
430 		// create polygon state at t from 0.0 to 1.0 between the two polygons. Both polygons must have the same
431 		// organisation, e.g. same amount of points
432 		B2DPolygon interpolate(const B2DPolygon& rOld1, const B2DPolygon& rOld2, double t);
433 
434 		bool isPolyPolygonEqualRectangle( const B2DPolyPolygon& rPolyPoly, const B2DRange& rRect );
435 
436 		// #i76891# Try to remove existing curve segments if they are simply edges
437 		B2DPolygon simplifyCurveSegments(const B2DPolygon& rCandidate);
438 
439 		// makes the given indexed point the new polygon start point. To do that, the points in the
440 		// polygon will be rotated. This is only valid for closed polygons, for non-closed ones
441 		// an assertion will be triggered
442 		B2DPolygon makeStartPoint(const B2DPolygon& rCandidate, sal_uInt32 nIndexOfNewStatPoint);
443 
444         /** create edges of given length along given B2DPolygon
445 
446         	@param rCandidate
447             The polygon to move along. Points at the given polygon are created, starting
448 			at position fStart and stopping at less or equal to fEnd. The closed state is
449 			preserved.
450 			The polygon is subdivided if curve segments are included. That subdivision is the base
451 			for the newly created points.
452 			If the source is closed, the indirectly existing last edge may NOT have the
453 			given length.
454 			If the source is open, all edges will have the given length. You may use the last
455 			point of the original when You want to add the last edge Yourself.
456 
457             @param fLength
458             The length of the created edges. If less or equal zero, an empty polygon is returned.
459 
460             @param fStart
461             The start distance for the first to be generated point. Use 0.0 to get the
462 			original start point. Negative values are truncated to 0.0.
463 
464             @param fEnd
465             The maximum distance for the last point. No more points behind this distance will be created.
466 			Use 0.0 to proccess the whole polygon. Negative values are truncated to 0.0. It also
467 			needs to be more or equal to fStart, else it is truncated to fStart.
468 
469 			@return
470 			The newly created polygon
471          */
472 		B2DPolygon createEdgesOfGivenLength(const B2DPolygon& rCandidate, double fLength, double fStart = 0.0, double fEnd = 0.0);
473 
474 		/** Create Waveline along given polygon
475             The implementation is based on createEdgesOfGivenLength and creates a curve
476             segment with the given dimensions for each created line segment. The polygon
477             is treated as if opened (closed state will be ignored) and only for whole
478             edges a curve segment will be created (no rest handling)
479 
480             @param rCandidate
481             The polygon along which the waveline will be created
482 
483             @param fWaveWidth
484             The length of a single waveline curve segment
485 
486             @param fgWaveHeight
487             The height of the waveline (amplitude)
488         */
489 		B2DPolygon createWaveline(const B2DPolygon& rCandidate, double fWaveWidth, double fWaveHeight);
490 
491         /** split each edge of a polygon in exactly nSubEdges equidistant edges
492 
493             @param rCandidate
494             The source polygon. If too small (no edges), nSubEdges too small (<2)
495             or neither bHandleCurvedEdgesnor bHandleStraightEdges it will just be returned.
496             Else for each edge nSubEdges will be created. Closed state is preserved.
497 
498             @param nSubEdges
499             How many edges shall be created as replacement for each single edge
500 
501             @param bHandleCurvedEdges
502             Process curved edges or not. If to handle the curved edges will be splitted
503             into nSubEdges part curved edges of equidistant bezier distances. If not,
504             curved edges will just be copied.
505 
506             @param bHandleStraightEdges
507             Process straight edges or not. If to handle the straight edges will be splitted
508             into nSubEdges part curved edges of equidistant length. If not,
509             straight edges will just be copied.
510         */
511 		B2DPolygon reSegmentPolygonEdges(const B2DPolygon& rCandidate, sal_uInt32 nSubEdges, bool bHandleCurvedEdges, bool bHandleStraightEdges);
512 
513 		//////////////////////////////////////////////////////////////////////
514 		// comparators with tolerance for 2D Polygons
515 		bool equal(const B2DPolygon& rCandidateA, const B2DPolygon& rCandidateB, const double& rfSmallValue);
516 		bool equal(const B2DPolygon& rCandidateA, const B2DPolygon& rCandidateB);
517 
518 		/** snap some polygon coordinates to discrete coordinates
519 
520 			This method allows to snap some polygon points to discrete (integer) values
521 			which equals e.g. a snap to discrete coordinates. It will snap points of
522 			horizontal and vertical edges
523 
524 			@param rCandidate
525 			The source polygon
526 
527 			@return
528 			The modified version of the source polygon
529 		*/
530 		B2DPolygon snapPointsOfHorizontalOrVerticalEdges(const B2DPolygon& rCandidate);
531 
532         /** returns true if the Polygon only contains horizontal or vertical edges
533             so that it could be represented by RegionBands
534         */
535         bool containsOnlyHorizontalAndVerticalEdges(const B2DPolygon& rCandidate);
536 
537         /// get the tangent with which the given point is entered seen from the previous
538         /// polygon path data. Take into account all stuff like closed state, zero-length edges and others.
539         B2DVector getTangentEnteringPoint(const B2DPolygon& rCandidate, sal_uInt32 nIndex);
540 
541         /// get the tangent with which the given point is left seen from the following
542         /// polygon path data. Take into account all stuff like closed state, zero-length edges and others.
543         B2DVector getTangentLeavingPoint(const B2DPolygon& rCandidate, sal_uInt32 nIndex);
544 
545         /// converters for com::sun::star::drawing::PointSequence
546         B2DPolygon UnoPointSequenceToB2DPolygon(
547             const com::sun::star::drawing::PointSequence& rPointSequenceSource,
548             bool bCheckClosed = true);
549         void B2DPolygonToUnoPointSequence(
550             const B2DPolygon& rPolygon,
551             com::sun::star::drawing::PointSequence& rPointSequenceRetval);
552 
553         /* converters for com::sun::star::drawing::PointSequence and
554            com::sun::star::drawing::FlagSequence to B2DPolygon (curved polygons)
555          */
556         B2DPolygon UnoPolygonBezierCoordsToB2DPolygon(
557             const com::sun::star::drawing::PointSequence& rPointSequenceSource,
558             const com::sun::star::drawing::FlagSequence& rFlagSequenceSource,
559             bool bCheckClosed = true);
560         void B2DPolygonToUnoPolygonBezierCoords(
561             const B2DPolygon& rPolyPolygon,
562             com::sun::star::drawing::PointSequence& rPointSequenceRetval,
563             com::sun::star::drawing::FlagSequence& rFlagSequenceRetval);
564 
565         /** Read poly-polygon from SVG.
566 
567             This function imports a poly-polygon from an SVG points
568             attribute (a plain list of coordinate pairs).
569 
570             @param o_rPoly
571             The output polygon. Note that svg:points can only define a
572             single polygon
573 
574             @param rSvgPointsAttribute
575             A valid SVG points attribute string
576 
577             @return true, if the string was successfully parsed
578          */
579         bool importFromSvgPoints( B2DPolygon&            o_rPoly,
580                                   const ::rtl::OUString& rSvgPointsAttribute );
581 
582         /** Write poly-polygon to SVG.
583 
584             This function imports a non-bezier polygon to SVG points
585             (a plain list of coordinate pairs).
586 
587             @param rPoly
588             The polygon to export
589 
590             @param rSvgPointsAttribute
591             A valid SVG points attribute string
592 
593             @return true, if the string was successfully parsed
594          */
595         ::rtl::OUString exportToSvgPoints( const B2DPolygon& rPoly );
596 
597     } // end of namespace tools
598 } // end of namespace basegfx
599 
600 #endif /* _BGFX_POLYGON_B2DPOLYGONTOOLS_HXX */
601