/* -*- 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 #include 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: */