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 .
22 #include <basegfx/polygon/b2dpolypolygon.hxx>
23 #include <basegfx/basegfxdllapi.h>
26 namespace basegfx::utils
28 /** Solve all crossovers (aka self-intersections) in a polyPolygon.
30 This re-layouts all contained polygons so that the result
31 will contain only non-cutting polygons. For that reason,
32 points will be added at crossover and touch points and the
33 single Polygons may be re-combined. The orientations of
34 the contained polygons in not changed but used as
35 topological information. Self crossovers of the contained
36 sub-polygons are implicitly handled, but to not lose the
37 topological information, it may be necessary to remove
38 self-intersections of the contained sub-polygons in a
39 preparing step and to explicitly correct their
42 BASEGFX_DLLPUBLIC B2DPolyPolygon
solveCrossovers(const B2DPolyPolygon
& rCandidate
,
43 size_t* pPointLimit
= nullptr);
45 /** Solve all crossovers (aka self-intersections) in a Polygon
47 Same as above, but for single polygons. Result will be
48 free of self-intersections. When result contains multiple
49 polygons, it may be necessary to rearrange their
50 orientations since holes may have been created (possibly use
53 BASEGFX_DLLPUBLIC B2DPolyPolygon
solveCrossovers(const B2DPolygon
& rCandidate
);
55 /** Strip neutral polygons from PolyPolygon.
57 Neutral polygons are ones who's orientation is neutral, so
58 normally they have no volume -> just closed paths. A
59 polygon with the same positive and negative oriented
60 volume is also neutral, so this may not be wanted. It is
61 safe to call with self-intersection-free polygons, though
62 (that's where it's mostly used).
64 BASEGFX_DLLPUBLIC B2DPolyPolygon
stripNeutralPolygons(const B2DPolyPolygon
& rCandidate
);
66 /** Remove unnecessary/non-displayed polygons.
68 Works only correct with self-intersection-free
69 polygons. For each polygon, the depth for the PolyPolygon
70 is calculated. The orientation is used to identify holes.
71 Start value for holes is -1, for polygons it's zero. Ech
72 time a polygon is contained in another one, it's depth is
73 increased when inside a polygon, decreased when inside a
74 hole. The result is a depth which e.g. is -1 for holes
75 outside everything, 1 for a polygon covered by another
76 polygon and zero for e.g. holes in a polygon or polygons
77 outside everything else. In the 2nd step, all polygons
78 with depth other than zero are removed. If bKeepAboveZero
79 is used, all polygons < 1 are removed. The bKeepAboveZero
80 mode is useful for clipping, e.g. just append one polygon
81 to another and use this mode -> only parts where two
82 polygons overlapped will be kept. In combination with
83 correct orientation of the input orientations and the
84 SolveCrossover calls this can be combined for logical
85 polygon operations or polygon clipping.
87 BASEGFX_DLLPUBLIC B2DPolyPolygon
stripDispensablePolygons(const B2DPolyPolygon
& rCandidate
, bool bKeepAboveZero
= false);
89 /** Emulate nonzero winding rule filling.
91 Geometrically convert PolyPolygons which are proposed to
92 use nonzero fill rule to a representation where evenodd
93 paint will give the same result. To do this all
94 intersections and self-intersections get solved (the
95 polygons will be rearranged if needed). Then all polygons
96 which are inside another one with the same orientation get
99 BASEGFX_DLLPUBLIC B2DPolyPolygon
createNonzeroConform(const B2DPolyPolygon
& rCandidate
);
101 // For convenience: the four basic operations OR, XOR, AND and DIFF for
102 // two PolyPolygons. These are combinations of the above methods. To not be forced
103 // to do evtl. already done preparations twice, You have to do the operations Yourself.
105 // A source preparation consists of preparing it to be seen as XOR-Rule PolyPolygon,
106 // so it is freed of intersections, self-intersections and the orientations are corrected.
107 // Important is that it will define the same areas as before, but is intersection-free.
108 // As an example think about a single polygon looping in itself and having holes. To
109 // topologically correctly handle this, it is necessary to remove all intersections and
110 // to correct the orientations. The orientation of the isolated holes e.g. will be negative.
111 // Topologically it is necessary to prepare each polygon which is seen as entity. It is
112 // not sufficient just to concatenate them and prepare the result, this may be topologically
113 // different since the simple concatenation will be seen as XOR. To work correctly, You
114 // may need to OR those polygons.
116 /// prep for ops - solve self-intersections and intersections, remove neutral parts and check orientations.
117 BASEGFX_DLLPUBLIC B2DPolyPolygon
prepareForPolygonOperation(const B2DPolygon
& rCandidate
);
118 /// prep for ops - solve self-intersections and intersections, remove neutral parts and check orientations.
119 BASEGFX_DLLPUBLIC B2DPolyPolygon
prepareForPolygonOperation(const B2DPolyPolygon
& rCandidate
);
121 /// OR: Return all areas where CandidateA or CandidateB exist
122 BASEGFX_DLLPUBLIC B2DPolyPolygon
solvePolygonOperationOr(const B2DPolyPolygon
& rCandidateA
, const B2DPolyPolygon
& rCandidateB
);
124 /// XOR: Return all areas where CandidateA or CandidateB exist, but not both
125 BASEGFX_DLLPUBLIC B2DPolyPolygon
solvePolygonOperationXor(const B2DPolyPolygon
& rCandidateA
, const B2DPolyPolygon
& rCandidateB
);
127 /// AND: Return all areas where CandidateA and CandidateB exist
128 BASEGFX_DLLPUBLIC B2DPolyPolygon
solvePolygonOperationAnd(const B2DPolyPolygon
& rCandidateA
, const B2DPolyPolygon
& rCandidateB
);
130 /// DIFF: Return all areas where CandidateA is not covered by CandidateB (cut B out of A)
131 BASEGFX_DLLPUBLIC B2DPolyPolygon
solvePolygonOperationDiff(const B2DPolyPolygon
& rCandidateA
, const B2DPolyPolygon
& rCandidateB
);
133 /** merge all single PolyPolygons to a single, OR-ed PolyPolygon
136 The source PolyPolygons
138 @return A single tools::PolyPolygon containing the Or-merged result
140 BASEGFX_DLLPUBLIC B2DPolyPolygon
mergeToSinglePolyPolygon(const B2DPolyPolygonVector
& rInput
);
142 } // end of namespace basegfx::utils
144 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */