diff options
author | Armin Le Grand <alg@apache.org> | 2013-08-13 15:10:34 +0000 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2013-08-14 11:32:19 +0100 |
commit | b5c9668d34acdbce500609725760d6578debb95a (patch) | |
tree | 0e61d3bb269c40fb010b86684637a9be9cb13c1b /basegfx/source/polygon/b2dpolypolygoncutter.cxx | |
parent | b74a2e6ee80e30ed42ef99e24f85eb1d2df346ca (diff) |
Resolves: #i122149# Corrected stuff around polygon-based clip regions
do not use them where not needed
(cherry picked from commit 4ccb1eb7d58005ab3b501b7c6ff128fadbcd5066)
Conflicts:
basegfx/inc/basegfx/matrix/b2dhommatrixtools.hxx
basegfx/inc/basegfx/polygon/b2dpolygontools.hxx
basegfx/inc/basegfx/polygon/b2dpolypolygontools.hxx
basegfx/inc/basegfx/tuple/b2dtuple.hxx
basegfx/inc/basegfx/tuple/b3dtuple.hxx
sc/source/ui/inc/output.hxx
sc/source/ui/view/gridwin.cxx
sc/source/ui/view/output.cxx
vcl/win/source/gdi/salgdi.cxx
Change-Id: Ie265814a51180bffe3c821a3f2148cb3bb54ecad
Diffstat (limited to 'basegfx/source/polygon/b2dpolypolygoncutter.cxx')
-rw-r--r-- | basegfx/source/polygon/b2dpolypolygoncutter.cxx | 77 |
1 files changed, 74 insertions, 3 deletions
diff --git a/basegfx/source/polygon/b2dpolypolygoncutter.cxx b/basegfx/source/polygon/b2dpolypolygoncutter.cxx index f30d9228c226..22b9d4fffad4 100644 --- a/basegfx/source/polygon/b2dpolypolygoncutter.cxx +++ b/basegfx/source/polygon/b2dpolypolygoncutter.cxx @@ -104,6 +104,8 @@ namespace basegfx typedef ::std::vector< PN > PNV; typedef ::std::vector< VN > VNV; typedef ::std::vector< SN > SNV; + typedef ::std::pair< basegfx::B2DPoint /*orig*/, basegfx::B2DPoint /*repl*/ > CorrectionPair; + typedef ::std::vector< CorrectionPair > CorrectionTable; ////////////////////////////////////////////////////////////////////////////// @@ -114,6 +116,7 @@ namespace basegfx PNV maPNV; VNV maVNV; SNV maSNV; + CorrectionTable maCorrectionTable; unsigned mbIsCurve : 1; unsigned mbChanged : 1; @@ -438,13 +441,44 @@ namespace basegfx void impSolve() { - // sort by point to identify common nodes + // sort by point to identify common nodes easier ::std::sort(maSNV.begin(), maSNV.end()); // handle common nodes const sal_uInt32 nNodeCount(maSNV.size()); + sal_uInt32 a(0); - for(sal_uInt32 a(0); a < nNodeCount - 1; a++) + // snap unsharp-equal points + if(nNodeCount) + { + basegfx::B2DPoint* pLast(&maSNV[0].mpPN->maPoint); + + for(a = 1; a < nNodeCount; a++) + { + basegfx::B2DPoint* pCurrent(&maSNV[a].mpPN->maPoint); + + if(pLast->equal(*pCurrent) && (pLast->getX() != pCurrent->getX() || pLast->getY() != pCurrent->getY())) + { + const basegfx::B2DPoint aMiddle((*pLast + *pCurrent) * 0.5); + + if(pLast->getX() != aMiddle.getX() || pLast->getY() != aMiddle.getY()) + { + maCorrectionTable.push_back(CorrectionPair(*pLast, aMiddle)); + *pLast = aMiddle; + } + + if(pCurrent->getX() != aMiddle.getX() || pCurrent->getY() != aMiddle.getY()) + { + maCorrectionTable.push_back(CorrectionPair(*pCurrent, aMiddle)); + *pCurrent = aMiddle; + } + } + + pLast = pCurrent; + } + } + + for(a = 0; a < nNodeCount - 1; a++) { // test a before using it, not after. Also use nPointCount instead of aSortNodes.size() PN& rPNb = *(maSNV[a].mpPN); @@ -614,8 +648,45 @@ namespace basegfx } else { + const sal_uInt32 nCorrectionSize(maCorrectionTable.size()); + // no change, return original - return maOriginal; + if(!nCorrectionSize) + { + return maOriginal; + } + + // apply coordinate corrections to ensure inside/outside correctness after solving + const sal_uInt32 nPolygonCount(maOriginal.count()); + basegfx::B2DPolyPolygon aRetval(maOriginal); + + for(sal_uInt32 a(0); a < nPolygonCount; a++) + { + basegfx::B2DPolygon aTemp(aRetval.getB2DPolygon(a)); + const sal_uInt32 nPointCount(aTemp.count()); + bool bChanged; + + for(sal_uInt32 b(0); b < nPointCount; b++) + { + const basegfx::B2DPoint aCandidate(aTemp.getB2DPoint(b)); + + for(sal_uInt32 c(0); c < nCorrectionSize; c++) + { + if(maCorrectionTable[c].first.getX() == aCandidate.getX() && maCorrectionTable[c].first.getY() == aCandidate.getY()) + { + aTemp.setB2DPoint(b, maCorrectionTable[c].second); + bChanged = true; + } + } + } + + if(bChanged) + { + aRetval.setB2DPolygon(a, aTemp); + } + } + + return aRetval; } } }; |