summaryrefslogtreecommitdiff
path: root/basegfx/source/polygon/b2dpolypolygoncutter.cxx
diff options
context:
space:
mode:
authorArmin Le Grand <alg@apache.org>2013-08-13 15:10:34 +0000
committerCaolán McNamara <caolanm@redhat.com>2013-08-14 11:32:19 +0100
commitb5c9668d34acdbce500609725760d6578debb95a (patch)
tree0e61d3bb269c40fb010b86684637a9be9cb13c1b /basegfx/source/polygon/b2dpolypolygoncutter.cxx
parentb74a2e6ee80e30ed42ef99e24f85eb1d2df346ca (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.cxx77
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;
}
}
};