diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
commit | ed5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch) | |
tree | 7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /include/basegfx/polygon/b2dpolypolygoncutter.hxx | |
parent | Initial commit. (diff) | |
download | libreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.tar.xz libreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.zip |
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | include/basegfx/polygon/b2dpolypolygoncutter.hxx | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/include/basegfx/polygon/b2dpolypolygoncutter.hxx b/include/basegfx/polygon/b2dpolypolygoncutter.hxx new file mode 100644 index 000000000..55dd29cf8 --- /dev/null +++ b/include/basegfx/polygon/b2dpolypolygoncutter.hxx @@ -0,0 +1,144 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#pragma once + +#include <basegfx/polygon/b2dpolypolygon.hxx> +#include <basegfx/basegfxdllapi.h> + + +namespace basegfx::utils +{ + /** Solve all crossovers (aka self-intersections) in a polyPolygon. + + This re-layouts all contained polygons so that the result + will contain only non-cutting polygons. For that reason, + points will be added at crossover and touch points and the + single Polygons may be re-combined. The orientations of + the contained polygons in not changed but used as + topological information. Self crossovers of the contained + sub-polygons are implicitly handled, but to not lose the + topological information, it may be necessary to remove + self-intersections of the contained sub-polygons in a + preparing step and to explicitly correct their + orientations. + */ + BASEGFX_DLLPUBLIC B2DPolyPolygon solveCrossovers(const B2DPolyPolygon& rCandidate, + size_t* pPointLimit = nullptr); + + /** Solve all crossovers (aka self-intersections) in a Polygon + + Same as above, but for single polygons. Result will be + free of self-intersections. When result contains multiple + polygons, it may be necessary to rearrange their + orientations since holes may have been created (possibly use + correctOrientations). + */ + BASEGFX_DLLPUBLIC B2DPolyPolygon solveCrossovers(const B2DPolygon& rCandidate); + + /** Strip neutral polygons from PolyPolygon. + + Neutral polygons are ones who's orientation is neutral, so + normally they have no volume -> just closed paths. A + polygon with the same positive and negative oriented + volume is also neutral, so this may not be wanted. It is + safe to call with self-intersection-free polygons, though + (that's where it's mostly used). + */ + BASEGFX_DLLPUBLIC B2DPolyPolygon stripNeutralPolygons(const B2DPolyPolygon& rCandidate); + + /** Remove unnecessary/non-displayed polygons. + + Works only correct with self-intersection-free + polygons. For each polygon, the depth for the PolyPolygon + is calculated. The orientation is used to identify holes. + Start value for holes is -1, for polygons it's zero. Ech + time a polygon is contained in another one, it's depth is + increased when inside a polygon, decreased when inside a + hole. The result is a depth which e.g. is -1 for holes + outside everything, 1 for a polygon covered by another + polygon and zero for e.g. holes in a polygon or polygons + outside everything else. In the 2nd step, all polygons + with depth other than zero are removed. If bKeepAboveZero + is used, all polygons < 1 are removed. The bKeepAboveZero + mode is useful for clipping, e.g. just append one polygon + to another and use this mode -> only parts where two + polygons overlapped will be kept. In combination with + correct orientation of the input orientations and the + SolveCrossover calls this can be combined for logical + polygon operations or polygon clipping. + */ + BASEGFX_DLLPUBLIC B2DPolyPolygon stripDispensablePolygons(const B2DPolyPolygon& rCandidate, bool bKeepAboveZero = false); + + /** Emulate nonzero winding rule filling. + + Geometrically convert PolyPolygons which are proposed to + use nonzero fill rule to a representation where evenodd + paint will give the same result. To do this all + intersections and self-intersections get solved (the + polygons will be rearranged if needed). Then all polygons + which are inside another one with the same orientation get + deleted + */ + BASEGFX_DLLPUBLIC B2DPolyPolygon createNonzeroConform(const B2DPolyPolygon& rCandidate); + + // For convenience: the four basic operations OR, XOR, AND and DIFF for + // two PolyPolygons. These are combinations of the above methods. To not be forced + // to do evtl. already done preparations twice, You have to do the operations Yourself. + + // A source preparation consists of preparing it to be seen as XOR-Rule PolyPolygon, + // so it is freed of intersections, self-intersections and the orientations are corrected. + // Important is that it will define the same areas as before, but is intersection-free. + // As an example think about a single polygon looping in itself and having holes. To + // topologically correctly handle this, it is necessary to remove all intersections and + // to correct the orientations. The orientation of the isolated holes e.g. will be negative. + // Topologically it is necessary to prepare each polygon which is seen as entity. It is + // not sufficient just to concatenate them and prepare the result, this may be topologically + // different since the simple concatenation will be seen as XOR. To work correctly, You + // may need to OR those polygons. + + /// prep for ops - solve self-intersections and intersections, remove neutral parts and check orientations. + BASEGFX_DLLPUBLIC B2DPolyPolygon prepareForPolygonOperation(const B2DPolygon& rCandidate); + /// prep for ops - solve self-intersections and intersections, remove neutral parts and check orientations. + BASEGFX_DLLPUBLIC B2DPolyPolygon prepareForPolygonOperation(const B2DPolyPolygon& rCandidate); + + /// OR: Return all areas where CandidateA or CandidateB exist + BASEGFX_DLLPUBLIC B2DPolyPolygon solvePolygonOperationOr(const B2DPolyPolygon& rCandidateA, const B2DPolyPolygon& rCandidateB); + + /// XOR: Return all areas where CandidateA or CandidateB exist, but not both + BASEGFX_DLLPUBLIC B2DPolyPolygon solvePolygonOperationXor(const B2DPolyPolygon& rCandidateA, const B2DPolyPolygon& rCandidateB); + + /// AND: Return all areas where CandidateA and CandidateB exist + BASEGFX_DLLPUBLIC B2DPolyPolygon solvePolygonOperationAnd(const B2DPolyPolygon& rCandidateA, const B2DPolyPolygon& rCandidateB); + + /// DIFF: Return all areas where CandidateA is not covered by CandidateB (cut B out of A) + BASEGFX_DLLPUBLIC B2DPolyPolygon solvePolygonOperationDiff(const B2DPolyPolygon& rCandidateA, const B2DPolyPolygon& rCandidateB); + + /** merge all single PolyPolygons to a single, OR-ed PolyPolygon + + @param rInput + The source PolyPolygons + + @return A single tools::PolyPolygon containing the Or-merged result + */ + BASEGFX_DLLPUBLIC B2DPolyPolygon mergeToSinglePolyPolygon(const B2DPolyPolygonVector& rInput); + +} // end of namespace basegfx::utils + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |