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>
42 // B2DPolyPolygon tools
44 // Check and evtl. correct orientations of all contained Polygons so that
45 // the orientations of contained polygons will variate to express areas and
47 BASEGFX_DLLPUBLIC B2DPolyPolygon
correctOrientations(const B2DPolyPolygon
& rCandidate
);
49 // make sure polygon with index 0L is not a hole. This may evtl. change the
50 // sequence of polygons, but allows to use polygon with index 0L to
51 // get the correct normal for the whole polyPolygon
52 BASEGFX_DLLPUBLIC B2DPolyPolygon
correctOutmostPolygon(const B2DPolyPolygon
& rCandidate
);
54 // Subdivide all contained curves. Use distanceBound value if given.
55 BASEGFX_DLLPUBLIC B2DPolyPolygon
adaptiveSubdivideByDistance(const B2DPolyPolygon
& rCandidate
, double fDistanceBound
);
57 // Subdivide all contained curves. Use distanceBound value if given. Else, a convenient one
59 BASEGFX_DLLPUBLIC B2DPolyPolygon
adaptiveSubdivideByAngle(const B2DPolyPolygon
& rCandidate
, double fAngleBound
= 0.0);
61 // isInside test for B2dPoint. On border is not inside as long as not true is given
62 // in bWithBorder flag. It is assumed that the orientations of the given polygon are correct.
63 BASEGFX_DLLPUBLIC
bool isInside(const B2DPolyPolygon
& rCandidate
, const B2DPoint
& rPoint
, bool bWithBorder
= false);
65 /** Get the range of a polyPolygon
67 For detailed description look at getRange(const B2DPolygon&).
68 This method just expands by the range of every sub-Polygon.
71 The B2DPolyPolygon possibly containing bezier segments
74 The outer range of the polygon
76 BASEGFX_DLLPUBLIC B2DRange
getRange(const B2DPolyPolygon
& rCandidate
);
78 // get signed area of polygon
79 BASEGFX_DLLPUBLIC
double getSignedArea(const B2DPolyPolygon
& rCandidate
);
81 // get area of polygon
82 BASEGFX_DLLPUBLIC
double getArea(const B2DPolyPolygon
& rCandidate
);
84 /** Apply given LineDashing to given polyPolygon
86 For a description see applyLineDashing in b2dpolygontoos.hxx
88 BASEGFX_DLLPUBLIC
void applyLineDashing(
89 const B2DPolyPolygon
& rCandidate
,
90 const ::std::vector
<double>& rDotDashArray
,
91 B2DPolyPolygon
* pLineTarget
,
92 B2DPolyPolygon
* pGapTarget
= nullptr,
93 double fFullDashDotLen
= 0.0);
95 // test if point is inside epsilon-range around the given PolyPolygon. Can be used
96 // for HitTesting. The epsilon-range is defined to be the tube around the PolyPolygon
97 // with distance fDistance and rounded edges (start and end point).
98 BASEGFX_DLLPUBLIC
bool isInEpsilonRange(const B2DPolyPolygon
& rCandidate
, const B2DPoint
& rTestPosition
, double fDistance
);
100 /** Helper class to transport PointIndices to a PolyPolygon,
101 with an operator< for convenient sorting in a std::set usage
103 class SAL_WARN_UNUSED BASEGFX_DLLPUBLIC PointIndex
106 sal_uInt32 mnPolygonIndex
;
107 sal_uInt32 mnPointIndex
;
110 PointIndex(sal_uInt32 nPolygonIndex
, sal_uInt32 nPointIndex
)
111 : mnPolygonIndex(nPolygonIndex
),
112 mnPointIndex(nPointIndex
)
115 sal_uInt32
getPolygonIndex() const { return mnPolygonIndex
; }
116 sal_uInt32
getPointIndex() const { return mnPointIndex
; }
117 bool operator<(const PointIndex
& rComp
) const;
120 /** the PointIndexSet itself; it allows to define a 'selection'of
121 points in a tools::PolyPolygon by giving the polygon and point index.
122 Adding points double makes no sense, hence the std::set
124 typedef std::set
< PointIndex
> PointIndexSet
;
126 /** Read poly-polygon from SVG.
128 This function imports a poly-polygon from an SVG-D
132 The output poly-polygon
134 @param rSvgDAttribute
135 A valid SVG-D attribute string
137 @param bHandleRelativeNextPointCompatible
138 If set to true, the old error that after a relative 'z' command
139 the current point was not reset to the first point of the current
140 polygon is kept; this is needed to read odf files.
141 If false, pure svg is used; this is needed for svg import.
143 @param pHelpPointIndexSet
144 If given, all points created in the target PolyPolygon
145 which are only helper points are added here using their
146 point indices; this are currently points created from
147 import of the 'a' and 'A' svg:d statements which create
148 bezier curve info as representation and maybe points
149 which are no 'real' svg:d points, but helper points. It
150 is necessary to identify these e.g. when markers need to
151 be created in the svg import
153 @return true, if the string was successfully parsed
155 BASEGFX_DLLPUBLIC
bool importFromSvgD(
156 B2DPolyPolygon
& o_rPolyPoly
,
157 const OUString
& rSvgDAttribute
,
158 bool bHandleRelativeNextPointCompatible
,
159 PointIndexSet
* pHelpPointIndexSet
);
161 // grow for polyPolygon. Move all geometry in each point in the direction of the normal in that point
162 // with the given amount. Value may be negative.
163 BASEGFX_DLLPUBLIC B2DPolyPolygon
growInNormalDirection(const B2DPolyPolygon
& rCandidate
, double fValue
);
165 // force all sub-polygons to a point count of nSegments
166 BASEGFX_DLLPUBLIC B2DPolyPolygon
reSegmentPolyPolygon(const B2DPolyPolygon
& rCandidate
, sal_uInt32 nSegments
);
168 // create polygon state at t from 0.0 to 1.0 between the two polygons. Both polygons must have the same
169 // organisation, e.g. same amount of polygons
170 BASEGFX_DLLPUBLIC B2DPolyPolygon
interpolate(const B2DPolyPolygon
& rOld1
, const B2DPolyPolygon
& rOld2
, double t
);
172 // create 3d tools::PolyPolygon from given 2d PolyPolygon. The given fZCoordinate is used to expand the
174 BASEGFX_DLLPUBLIC B3DPolyPolygon
createB3DPolyPolygonFromB2DPolyPolygon(const B2DPolyPolygon
& rCandidate
, double fZCoordinate
= 0.0);
176 // create 2d tools::PolyPolygon from given 3d PolyPolygon. All coordinates are transformed using the given
177 // matrix and the resulting x,y is used to form the new polygon.
178 BASEGFX_DLLPUBLIC B2DPolyPolygon
createB2DPolyPolygonFromB3DPolyPolygon(const B3DPolyPolygon
& rCandidate
, const B3DHomMatrix
& rMat
);
180 // for each contained edge in each contained polygon calculate the smallest distance. Return the index to the smallest
181 // edge in rEdgeIndex and the index to the polygon in rPolygonIndex. The relative position on the edge is returned in rCut.
182 // If nothing was found (e.g. empty input plygon), DBL_MAX is returned.
183 BASEGFX_DLLPUBLIC
double getSmallestDistancePointToPolyPolygon(const B2DPolyPolygon
& rCandidate
, const B2DPoint
& rTestPoint
, sal_uInt32
& rPolygonIndex
, sal_uInt32
& rEdgeIndex
, double& rCut
);
185 // distort PolyPolygon. rOriginal describes the original range, where the given points describe the distorted
186 // corresponding points.
187 BASEGFX_DLLPUBLIC B2DPolyPolygon
distort(const B2DPolyPolygon
& rCandidate
, const B2DRange
& rOriginal
, const B2DPoint
& rTopLeft
, const B2DPoint
& rTopRight
, const B2DPoint
& rBottomLeft
, const B2DPoint
& rBottomRight
);
189 // expand all segments (which are not yet) to curve segments. This is done with setting the control
190 // vectors on the 1/3 resp. 2/3 distances on each segment.
191 BASEGFX_DLLPUBLIC B2DPolyPolygon
expandToCurve(const B2DPolyPolygon
& rCandidate
);
193 /** Predicate whether a given poly-polygon is a rectangle.
196 tools::PolyPolygon to check
198 @return true, if the poly-polygon describes a rectangle
199 (contains exactly one polygon, polygon is closed, and the
200 points are either cw or ccw enumerations of a rectangle's
201 vertices). Note that intermediate points and duplicate
204 BASEGFX_DLLPUBLIC
bool isRectangle( const B2DPolyPolygon
& rPoly
);
206 /** Export poly-polygon to SVG.
208 This function exports a poly-polygon into an SVG-D
209 statement. Currently, output of relative point sequences
210 is not yet supported (might cause slightly larger output)
213 The poly-polygon to export
215 @param bUseRelativeCoordinates
216 When true, all coordinate values are exported as relative
217 to the current position. This tends to save some space,
218 since fewer digits needs to be written.
220 @param bDetectQuadraticBeziers
221 When true, the export tries to detect cubic bezier
222 segments in the input polygon, which can be represented by
223 quadratic bezier segments. Note that the generated string
224 causes versions prior to OOo2.0 to crash.
226 @param bHandleRelativeNextPointCompatible
227 If set to true, the old error that after a relative 'z' command
228 the current point was not reset to the first point of the current
229 polygon is kept; this is needed to read odf files.
230 If false, pure svg is used; this is needed for svg import.
232 @return the generated SVG-D statement (the XML d attribute
233 value alone, without any "<path ...>" or "d="...")
235 BASEGFX_DLLPUBLIC OUString
exportToSvgD(
236 const B2DPolyPolygon
& rPolyPoly
,
237 bool bUseRelativeCoordinates
,
238 bool bDetectQuadraticBeziers
,
239 bool bHandleRelativeNextPointCompatible
);
241 // #i76891# Try to remove existing curve segments if they are simply edges
242 BASEGFX_DLLPUBLIC B2DPolyPolygon
simplifyCurveSegments(const B2DPolyPolygon
& rCandidate
);
244 /** Creates polypolygon for seven-segment display number
246 This function takes an integer number between 0 and 9 and
247 convert it into the well-known seven-segment display
248 number (like most digital clocks show their numbers). The
249 digit will exactly fit the unit rectangle. The polypolygon
250 will be a line polygon, i.e. if you need the segment parts
251 to have width, use createAreaGeometry() on the result.
254 Number from '0' to '9' as ASCII char, or '-', 'E' and '.'
255 to convert to 7 segment code
258 When true, return a polygon containing the segments that
259 are 'lit' for the given number. Return un-lit segments
262 B2DPolyPolygon
createSevenSegmentPolyPolygon(sal_Char cNumber
, bool bLitSegments
);
264 /** snap some polygon coordinates to discrete coordinates
266 This method allows to snap some polygon points to discrete (integer) values
267 which equals e.g. a snap to discrete coordinates. It will snap points of
268 horizontal and vertical edges
274 The modified version of the source polygon
276 BASEGFX_DLLPUBLIC B2DPolyPolygon
snapPointsOfHorizontalOrVerticalEdges(const B2DPolyPolygon
& rCandidate
);
278 /// converters for css::drawing::PointSequence
279 BASEGFX_DLLPUBLIC B2DPolyPolygon
UnoPointSequenceSequenceToB2DPolyPolygon(
280 const css::drawing::PointSequenceSequence
& rPointSequenceSequenceSource
,
281 bool bCheckClosed
= true);
282 BASEGFX_DLLPUBLIC
void B2DPolyPolygonToUnoPointSequenceSequence(
283 const B2DPolyPolygon
& rPolyPolygon
,
284 css::drawing::PointSequenceSequence
& rPointSequenceSequenceRetval
);
286 /// converters for css::drawing::PolyPolygonBezierCoords (curved polygons)
287 BASEGFX_DLLPUBLIC B2DPolyPolygon
UnoPolyPolygonBezierCoordsToB2DPolyPolygon(
288 const css::drawing::PolyPolygonBezierCoords
& rPolyPolygonBezierCoordsSource
,
289 bool bCheckClosed
= true);
290 BASEGFX_DLLPUBLIC
void B2DPolyPolygonToUnoPolyPolygonBezierCoords(
291 const B2DPolyPolygon
& rPolyPolygon
,
292 css::drawing::PolyPolygonBezierCoords
& rPolyPolygonBezierCoordsRetval
);
294 } // end of namespace tools
295 } // end of namespace basegfx
297 #endif // INCLUDED_BASEGFX_POLYGON_B2DPOLYPOLYGONTOOLS_HXX
299 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */