Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #ifndef INCLUDED_BASEGFX_POLYGON_B2DPOLYPOLYGONTOOLS_HXX
21 : #define INCLUDED_BASEGFX_POLYGON_B2DPOLYPOLYGONTOOLS_HXX
22 :
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>
29 : #include <vector>
30 : #include <set>
31 : #include <basegfx/basegfxdllapi.h>
32 :
33 :
34 :
35 :
36 : namespace basegfx
37 : {
38 : // predefinitions
39 : class B2DPolyPolygon;
40 : class B2DRange;
41 :
42 : namespace tools
43 : {
44 : // B2DPolyPolygon tools
45 :
46 : // Check and evtl. correct orientations of all contained Polygons so that
47 : // the orientations of contained polygons will variate to express areas and
48 : // holes
49 : BASEGFX_DLLPUBLIC B2DPolyPolygon correctOrientations(const B2DPolyPolygon& rCandidate);
50 :
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);
55 :
56 : // Subdivide all contained curves. Use distanceBound value if given.
57 : BASEGFX_DLLPUBLIC B2DPolyPolygon adaptiveSubdivideByDistance(const B2DPolyPolygon& rCandidate, double fDistanceBound = 0.0);
58 :
59 : // Subdivide all contained curves. Use distanceBound value if given. Else, a convenient one
60 : // is created.
61 : BASEGFX_DLLPUBLIC B2DPolyPolygon adaptiveSubdivideByAngle(const B2DPolyPolygon& rCandidate, double fAngleBound = 0.0);
62 :
63 : // Subdivide all contained curves. Use nCount divisions if given. Else, a convenient one
64 : // is created.
65 : BASEGFX_DLLPUBLIC B2DPolyPolygon adaptiveSubdivideByCount(const B2DPolyPolygon& rCandidate, sal_uInt32 nCount = 0L);
66 :
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);
70 :
71 : /** Get the range of a polyPolygon
72 :
73 : For detailed description look at getRange(const B2DPolygon&).
74 : This method just expands by the range of every sub-Polygon.
75 :
76 : @param rCandidate
77 : The B2DPolyPolygon eventually containing bezier segments
78 :
79 : @return
80 : The outer range of the polygon
81 : */
82 : BASEGFX_DLLPUBLIC B2DRange getRange(const B2DPolyPolygon& rCandidate);
83 :
84 : // get signed area of polygon
85 : BASEGFX_DLLPUBLIC double getSignedArea(const B2DPolyPolygon& rCandidate);
86 :
87 : // get area of polygon
88 : BASEGFX_DLLPUBLIC double getArea(const B2DPolyPolygon& rCandidate);
89 :
90 : /** Apply given LineDashing to given polyPolygon
91 :
92 : For a description see applyLineDashing in b2dpolygontoos.hxx
93 : */
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);
100 :
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);
105 :
106 : /** Helper class to transport PointIndices to a PolyPolygon,
107 : with an operator< for convenient sorting in a std::set usage
108 : */
109 : class BASEGFX_DLLPUBLIC SAL_WARN_UNUSED PointIndex
110 : {
111 : private:
112 : sal_uInt32 mnPolygonIndex;
113 : sal_uInt32 mnPointIndex;
114 :
115 : public:
116 0 : PointIndex(sal_uInt32 nPolygonIndex, sal_uInt32 nPointIndex)
117 : : mnPolygonIndex(nPolygonIndex),
118 0 : mnPointIndex(nPointIndex)
119 0 : {}
120 :
121 0 : sal_uInt32 getPolygonIndex() const { return mnPolygonIndex; }
122 0 : sal_uInt32 getPointIndex() const { return mnPointIndex; }
123 : bool operator<(const PointIndex& rComp) const;
124 : };
125 :
126 : /** the PointIndexSet itself; it allows to define a 'selection'of
127 : points in a PolyPolygon by giving the polygon and point index.
128 : Adding points double makes no sense, hence the std::set
129 : */
130 : typedef std::set< PointIndex > PointIndexSet;
131 :
132 : /** Read poly-polygon from SVG.
133 :
134 : This function imports a poly-polygon from an SVG-D
135 : attribute.
136 :
137 : @param o_rPolyPoly
138 : The output poly-polygon
139 :
140 : @param rSvgDAttribute
141 : A valid SVG-D attribute string
142 :
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.
148 :
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
158 :
159 : @return true, if the string was successfully parsed
160 : */
161 : BASEGFX_DLLPUBLIC bool importFromSvgD(
162 : B2DPolyPolygon& o_rPolyPoly,
163 : const OUString& rSvgDAttribute,
164 : bool bHandleRelativeNextPointCompatible,
165 : PointIndexSet* pHelpPointIndexSet);
166 :
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);
170 :
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);
176 :
177 : // force all sub-polygons to a point count of nSegments
178 : BASEGFX_DLLPUBLIC B2DPolyPolygon reSegmentPolyPolygon(const B2DPolyPolygon& rCandidate, sal_uInt32 nSegments);
179 :
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);
183 :
184 : // create 3d PolyPolygon from given 2d PolyPolygon. The given fZCoordinate is used to expand the
185 : // third coordinate.
186 : BASEGFX_DLLPUBLIC B3DPolyPolygon createB3DPolyPolygonFromB2DPolyPolygon(const B2DPolyPolygon& rCandidate, double fZCoordinate = 0.0);
187 :
188 : // create 2d 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);
191 :
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);
196 :
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);
200 :
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);
204 :
205 : /** Predicate whether a given poly-polygon is a rectangle.
206 :
207 : @param rPoly
208 : PolyPolygon to check
209 :
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
214 : points are ignored.
215 : */
216 : BASEGFX_DLLPUBLIC bool isRectangle( const B2DPolyPolygon& rPoly );
217 :
218 : /** Export poly-polygon to SVG.
219 :
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)
223 :
224 : @param rPolyPoly
225 : The poly-polygon to export
226 :
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.
231 :
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.
237 :
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.
243 :
244 : @return the generated SVG-D statement (the XML d attribute
245 : value alone, without any "<path ...>" or "d="...")
246 : */
247 : BASEGFX_DLLPUBLIC OUString exportToSvgD(
248 : const B2DPolyPolygon& rPolyPoly,
249 : bool bUseRelativeCoordinates,
250 : bool bDetectQuadraticBeziers,
251 : bool bHandleRelativeNextPointCompatible);
252 :
253 : // #i76891# Try to remove existing curve segments if they are simply edges
254 : BASEGFX_DLLPUBLIC B2DPolyPolygon simplifyCurveSegments(const B2DPolyPolygon& rCandidate);
255 :
256 : /** Creates polypolygon for seven-segment display number
257 :
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.
264 :
265 : @param cNumber
266 : Number from '0' to '9' as ASCII char, or '-', 'E' and '.'
267 : to convert to 7 segment code
268 :
269 : @param bLitSegments
270 : When true, return a polygon containing the segments that
271 : are 'lit' for the given number. Return un-lit segments
272 : otherwise.
273 : */
274 : B2DPolyPolygon createSevenSegmentPolyPolygon(sal_Char cNumber, bool bLitSegments=true);
275 :
276 : /** snap some polygon coordinates to discrete coordinates
277 :
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
281 :
282 : @param rCandidate
283 : The source polygon
284 :
285 : @return
286 : The modified version of the source polygon
287 : */
288 : BASEGFX_DLLPUBLIC B2DPolyPolygon snapPointsOfHorizontalOrVerticalEdges(const B2DPolyPolygon& rCandidate);
289 :
290 : /** returns true if the Polygon only contains horizontal or vertical edges
291 : so that it could be represented by RegionBands
292 : */
293 : BASEGFX_DLLPUBLIC bool containsOnlyHorizontalAndVerticalEdges(const B2DPolyPolygon& rCandidate);
294 :
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);
302 :
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);
310 :
311 : } // end of namespace tools
312 : } // end of namespace basegfx
313 :
314 : #endif // INCLUDED_BASEGFX_POLYGON_B2DPOLYPOLYGONTOOLS_HXX
315 :
316 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|