1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #ifndef INCLUDED_BASEGFX_POLYGON_B2DPOLYPOLYGONTOOLS_HXX
21 #define INCLUDED_BASEGFX_POLYGON_B2DPOLYPOLYGONTOOLS_HXX
23 #include <basegfx/point/b2dpoint.hxx>
24 #include <basegfx/vector/b2dvector.hxx>
25 #include <basegfx/polygon/b2dpolygon.hxx>
26 #include <basegfx/polygon/b3dpolypolygon.hxx>
27 #include <com/sun/star/drawing/PointSequenceSequence.hpp>
28 #include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
31 #include <basegfx/basegfxdllapi.h>
44 // B2DPolyPolygon tools
46 // Check and evtl. correct orientations of all contained Polygons so that
47 // the orientations of contained polygons will variate to express areas and
49 BASEGFX_DLLPUBLIC B2DPolyPolygon
correctOrientations(const B2DPolyPolygon
& rCandidate
);
51 // make sure polygon with index 0L is not a hole. This may evtl. change the
52 // sequence of polygons, but allows to use polygon with index 0L to
53 // get the correct normal for the whole polyPolygon
54 BASEGFX_DLLPUBLIC B2DPolyPolygon
correctOutmostPolygon(const B2DPolyPolygon
& rCandidate
);
56 // Subdivide all contained curves. Use distanceBound value if given.
57 BASEGFX_DLLPUBLIC B2DPolyPolygon
adaptiveSubdivideByDistance(const B2DPolyPolygon
& rCandidate
, double fDistanceBound
= 0.0);
59 // Subdivide all contained curves. Use distanceBound value if given. Else, a convenient one
61 BASEGFX_DLLPUBLIC B2DPolyPolygon
adaptiveSubdivideByAngle(const B2DPolyPolygon
& rCandidate
, double fAngleBound
= 0.0);
63 // Subdivide all contained curves. Use nCount divisions if given. Else, a convenient one
65 BASEGFX_DLLPUBLIC B2DPolyPolygon
adaptiveSubdivideByCount(const B2DPolyPolygon
& rCandidate
, sal_uInt32 nCount
= 0L);
67 // isInside test for B2dPoint. On border is not inside as long as not true is given
68 // in bWithBorder flag. It is assumed that the orientations of the given polygon are correct.
69 BASEGFX_DLLPUBLIC
bool isInside(const B2DPolyPolygon
& rCandidate
, const B2DPoint
& rPoint
, bool bWithBorder
= false);
71 /** Get the range of a polyPolygon
73 For detailed description look at getRange(const B2DPolygon&).
74 This method just expands by the range of every sub-Polygon.
77 The B2DPolyPolygon eventually containing bezier segments
80 The outer range of the polygon
82 BASEGFX_DLLPUBLIC B2DRange
getRange(const B2DPolyPolygon
& rCandidate
);
84 // get signed area of polygon
85 BASEGFX_DLLPUBLIC
double getSignedArea(const B2DPolyPolygon
& rCandidate
);
87 // get area of polygon
88 BASEGFX_DLLPUBLIC
double getArea(const B2DPolyPolygon
& rCandidate
);
90 /** Apply given LineDashing to given polyPolygon
92 For a description see applyLineDashing in b2dpolygontoos.hxx
94 BASEGFX_DLLPUBLIC
void applyLineDashing(
95 const B2DPolyPolygon
& rCandidate
,
96 const ::std::vector
<double>& rDotDashArray
,
97 B2DPolyPolygon
* pLineTarget
,
98 B2DPolyPolygon
* pGapTarget
= 0,
99 double fFullDashDotLen
= 0.0);
101 // test if point is inside epsilon-range around the given PolyPolygon. Can be used
102 // for HitTesting. The epsilon-range is defined to be the tube around the PolyPolygon
103 // with distance fDistance and rounded edges (start and end point).
104 BASEGFX_DLLPUBLIC
bool isInEpsilonRange(const B2DPolyPolygon
& rCandidate
, const B2DPoint
& rTestPosition
, double fDistance
);
106 /** Helper class to transport PointIndices to a PolyPolygon,
107 with an operator< for convenient sorting in a std::set usage
109 class BASEGFX_DLLPUBLIC SAL_WARN_UNUSED PointIndex
112 sal_uInt32 mnPolygonIndex
;
113 sal_uInt32 mnPointIndex
;
116 PointIndex(sal_uInt32 nPolygonIndex
, sal_uInt32 nPointIndex
)
117 : mnPolygonIndex(nPolygonIndex
),
118 mnPointIndex(nPointIndex
)
121 sal_uInt32
getPolygonIndex() const { return mnPolygonIndex
; }
122 sal_uInt32
getPointIndex() const { return mnPointIndex
; }
123 bool operator<(const PointIndex
& rComp
) const;
126 /** the PointIndexSet itself; it allows to define a 'selection'of
127 points in a tools::PolyPolygon by giving the polygon and point index.
128 Adding points double makes no sense, hence the std::set
130 typedef std::set
< PointIndex
> PointIndexSet
;
132 /** Read poly-polygon from SVG.
134 This function imports a poly-polygon from an SVG-D
138 The output poly-polygon
140 @param rSvgDAttribute
141 A valid SVG-D attribute string
143 @param bHandleRelativeNextPointCompatible
144 If set to true, the old error that after a relative 'z' command
145 the current point was not reset to the first point of the current
146 polygon is kept; this is needed to read odf files.
147 If false, pure svg is used; this is needed for svg import.
149 @param pHelpPointIndexSet
150 If given, all points created in the target PolyPolygon
151 which are only helper points are added here using their
152 point indices; this are currently points created from
153 import of the 'a' and 'A' svg:d statements which create
154 bezier curve info as representation and maybe points
155 which are no 'real' svg:d points, but helper points. It
156 is necessary to identify these e.g. when markers need to
157 be created in the svg import
159 @return true, if the string was successfully parsed
161 BASEGFX_DLLPUBLIC
bool importFromSvgD(
162 B2DPolyPolygon
& o_rPolyPoly
,
163 const OUString
& rSvgDAttribute
,
164 bool bHandleRelativeNextPointCompatible
,
165 PointIndexSet
* pHelpPointIndexSet
);
167 // grow for polyPolygon. Move all geometry in each point in the direction of the normal in that point
168 // with the given amount. Value may be negative.
169 BASEGFX_DLLPUBLIC B2DPolyPolygon
growInNormalDirection(const B2DPolyPolygon
& rCandidate
, double fValue
);
171 // This method will correct a pair of polyPolygons where the goal is to keep same point count
172 // to allow direct point association and also to remove self-intersections produced by shrinks.
173 // This method will eventually change both polyPolygons to reach that goal because there are cases
174 // where it is necessary to add new cut points to the original
175 BASEGFX_DLLPUBLIC
void correctGrowShrinkPolygonPair(B2DPolyPolygon
& rOriginal
, B2DPolyPolygon
& rGrown
);
177 // force all sub-polygons to a point count of nSegments
178 BASEGFX_DLLPUBLIC B2DPolyPolygon
reSegmentPolyPolygon(const B2DPolyPolygon
& rCandidate
, sal_uInt32 nSegments
);
180 // create polygon state at t from 0.0 to 1.0 between the two polygons. Both polygons must have the same
181 // organisation, e.g. same amount of polygons
182 BASEGFX_DLLPUBLIC B2DPolyPolygon
interpolate(const B2DPolyPolygon
& rOld1
, const B2DPolyPolygon
& rOld2
, double t
);
184 // create 3d tools::PolyPolygon from given 2d PolyPolygon. The given fZCoordinate is used to expand the
186 BASEGFX_DLLPUBLIC B3DPolyPolygon
createB3DPolyPolygonFromB2DPolyPolygon(const B2DPolyPolygon
& rCandidate
, double fZCoordinate
= 0.0);
188 // create 2d tools::PolyPolygon from given 3d PolyPolygon. All coordinates are transformed using the given
189 // matrix and the resulting x,y is used to form the new polygon.
190 BASEGFX_DLLPUBLIC B2DPolyPolygon
createB2DPolyPolygonFromB3DPolyPolygon(const B3DPolyPolygon
& rCandidate
, const B3DHomMatrix
& rMat
);
192 // for each contained edge in each contained polygon calculate the smallest distance. Return the index to the smallest
193 // edge in rEdgeIndex and the index to the polygon in rPolygonIndex. The relative position on the edge is returned in rCut.
194 // If nothing was found (e.g. empty input plygon), DBL_MAX is returned.
195 BASEGFX_DLLPUBLIC
double getSmallestDistancePointToPolyPolygon(const B2DPolyPolygon
& rCandidate
, const B2DPoint
& rTestPoint
, sal_uInt32
& rPolygonIndex
, sal_uInt32
& rEdgeIndex
, double& rCut
);
197 // distort PolyPolygon. rOriginal describes the original range, where the given points describe the distorted
198 // corresponding points.
199 BASEGFX_DLLPUBLIC B2DPolyPolygon
distort(const B2DPolyPolygon
& rCandidate
, const B2DRange
& rOriginal
, const B2DPoint
& rTopLeft
, const B2DPoint
& rTopRight
, const B2DPoint
& rBottomLeft
, const B2DPoint
& rBottomRight
);
201 // expand all segments (which are not yet) to curve segments. This is done with setting the control
202 // vectors on the 1/3 resp. 2/3 distances on each segment.
203 BASEGFX_DLLPUBLIC B2DPolyPolygon
expandToCurve(const B2DPolyPolygon
& rCandidate
);
205 /** Predicate whether a given poly-polygon is a rectangle.
208 tools::PolyPolygon to check
210 @return true, if the poly-polygon describes a rectangle
211 (contains exactly one polygon, polygon is closed, and the
212 points are either cw or ccw enumerations of a rectangle's
213 vertices). Note that intermediate points and duplicate
216 BASEGFX_DLLPUBLIC
bool isRectangle( const B2DPolyPolygon
& rPoly
);
218 /** Export poly-polygon to SVG.
220 This function exports a poly-polygon into an SVG-D
221 statement. Currently, output of relative point sequences
222 is not yet supported (might cause slightly larger output)
225 The poly-polygon to export
227 @param bUseRelativeCoordinates
228 When true, all coordinate values are exported as relative
229 to the current position. This tends to save some space,
230 since fewer digits needs to be written.
232 @param bDetectQuadraticBeziers
233 When true, the export tries to detect cubic bezier
234 segments in the input polygon, which can be represented by
235 quadratic bezier segments. Note that the generated string
236 causes versions prior to OOo2.0 to crash.
238 @param bHandleRelativeNextPointCompatible
239 If set to true, the old error that after a relative 'z' command
240 the current point was not reset to the first point of the current
241 polygon is kept; this is needed to read odf files.
242 If false, pure svg is used; this is needed for svg import.
244 @return the generated SVG-D statement (the XML d attribute
245 value alone, without any "<path ...>" or "d="...")
247 BASEGFX_DLLPUBLIC OUString
exportToSvgD(
248 const B2DPolyPolygon
& rPolyPoly
,
249 bool bUseRelativeCoordinates
,
250 bool bDetectQuadraticBeziers
,
251 bool bHandleRelativeNextPointCompatible
);
253 // #i76891# Try to remove existing curve segments if they are simply edges
254 BASEGFX_DLLPUBLIC B2DPolyPolygon
simplifyCurveSegments(const B2DPolyPolygon
& rCandidate
);
256 /** Creates polypolygon for seven-segment display number
258 This function takes an integer number between 0 and 9 and
259 convert it into the well-known seven-segment display
260 number (like most digital clocks show their numbers). The
261 digit will exactly fit the unit rectangle. The polypolygon
262 will be a line polygon, i.e. if you need the segment parts
263 to have width, use createAreaGeometry() on the result.
266 Number from '0' to '9' as ASCII char, or '-', 'E' and '.'
267 to convert to 7 segment code
270 When true, return a polygon containing the segments that
271 are 'lit' for the given number. Return un-lit segments
274 B2DPolyPolygon
createSevenSegmentPolyPolygon(sal_Char cNumber
, bool bLitSegments
=true);
276 /** snap some polygon coordinates to discrete coordinates
278 This method allows to snap some polygon points to discrete (integer) values
279 which equals e.g. a snap to discrete coordinates. It will snap points of
280 horizontal and vertical edges
286 The modified version of the source polygon
288 BASEGFX_DLLPUBLIC B2DPolyPolygon
snapPointsOfHorizontalOrVerticalEdges(const B2DPolyPolygon
& rCandidate
);
290 /** returns true if the Polygon only contains horizontal or vertical edges
291 so that it could be represented by RegionBands
293 BASEGFX_DLLPUBLIC
bool containsOnlyHorizontalAndVerticalEdges(const B2DPolyPolygon
& rCandidate
);
295 /// converters for com::sun::star::drawing::PointSequence
296 BASEGFX_DLLPUBLIC B2DPolyPolygon
UnoPointSequenceSequenceToB2DPolyPolygon(
297 const com::sun::star::drawing::PointSequenceSequence
& rPointSequenceSequenceSource
,
298 bool bCheckClosed
= true);
299 BASEGFX_DLLPUBLIC
void B2DPolyPolygonToUnoPointSequenceSequence(
300 const B2DPolyPolygon
& rPolyPolygon
,
301 com::sun::star::drawing::PointSequenceSequence
& rPointSequenceSequenceRetval
);
303 /// converters for com::sun::star::drawing::PolyPolygonBezierCoords (curved polygons)
304 BASEGFX_DLLPUBLIC B2DPolyPolygon
UnoPolyPolygonBezierCoordsToB2DPolyPolygon(
305 const com::sun::star::drawing::PolyPolygonBezierCoords
& rPolyPolygonBezierCoordsSource
,
306 bool bCheckClosed
= true);
307 BASEGFX_DLLPUBLIC
void B2DPolyPolygonToUnoPolyPolygonBezierCoords(
308 const B2DPolyPolygon
& rPolyPolygon
,
309 com::sun::star::drawing::PolyPolygonBezierCoords
& rPolyPolygonBezierCoordsRetval
);
311 } // end of namespace tools
312 } // end of namespace basegfx
314 #endif // INCLUDED_BASEGFX_POLYGON_B2DPOLYPOLYGONTOOLS_HXX
316 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */