summaryrefslogtreecommitdiff
path: root/basegfx/source
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
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')
-rw-r--r--basegfx/source/matrix/b2dhommatrixtools.cxx41
-rw-r--r--basegfx/source/polygon/b2dpolygon.cxx2
-rw-r--r--basegfx/source/polygon/b2dpolygontools.cxx33
-rw-r--r--basegfx/source/polygon/b2dpolypolygoncutter.cxx77
-rw-r--r--basegfx/source/polygon/b2dpolypolygontools.cxx17
5 files changed, 166 insertions, 4 deletions
diff --git a/basegfx/source/matrix/b2dhommatrixtools.cxx b/basegfx/source/matrix/b2dhommatrixtools.cxx
index 5666064d7933..3e39fd5e4df6 100644
--- a/basegfx/source/matrix/b2dhommatrixtools.cxx
+++ b/basegfx/source/matrix/b2dhommatrixtools.cxx
@@ -357,6 +357,47 @@ namespace basegfx
return aRetval;
}
+
+ /// special for the case to map from source range to target range
+ B2DHomMatrix createSourceRangeTargetRangeTransform(
+ const B2DRange& rSourceRange,
+ const B2DRange& rTargetRange)
+ {
+ B2DHomMatrix aRetval;
+
+ if(&rSourceRange == &rTargetRange)
+ {
+ return aRetval;
+ }
+
+ if(!fTools::equalZero(rSourceRange.getMinX()) || !fTools::equalZero(rSourceRange.getMinY()))
+ {
+ aRetval.set(0, 2, -rSourceRange.getMinX());
+ aRetval.set(1, 2, -rSourceRange.getMinY());
+ }
+
+ const double fSourceW(rSourceRange.getWidth());
+ const double fSourceH(rSourceRange.getHeight());
+ const bool bDivX(!fTools::equalZero(fSourceW) && !fTools::equal(fSourceW, 1.0));
+ const bool bDivY(!fTools::equalZero(fSourceH) && !fTools::equal(fSourceH, 1.0));
+ const double fScaleX(bDivX ? rTargetRange.getWidth() / fSourceW : rTargetRange.getWidth());
+ const double fScaleY(bDivY ? rTargetRange.getHeight() / fSourceH : rTargetRange.getHeight());
+
+ if(!fTools::equalZero(fScaleX) || !fTools::equalZero(fScaleY))
+ {
+ aRetval.scale(fScaleX, fScaleY);
+ }
+
+ if(!fTools::equalZero(rTargetRange.getMinX()) || !fTools::equalZero(rTargetRange.getMinY()))
+ {
+ aRetval.translate(
+ rTargetRange.getMinX(),
+ rTargetRange.getMinY());
+ }
+
+ return aRetval;
+ }
+
} // end of namespace tools
} // end of namespace basegfx
diff --git a/basegfx/source/polygon/b2dpolygon.cxx b/basegfx/source/polygon/b2dpolygon.cxx
index 6b661f9d42ad..a24cab41edcb 100644
--- a/basegfx/source/polygon/b2dpolygon.cxx
+++ b/basegfx/source/polygon/b2dpolygon.cxx
@@ -1252,7 +1252,7 @@ namespace basegfx
{
OSL_ENSURE(nIndex < mpPolygon->count(), "B2DPolygon access outside range (!)");
- if(getB2DPoint(nIndex) != rValue)
+ if(mpPolygon->getPoint(nIndex) != rValue)
{
mpPolygon->setPoint(nIndex, rValue);
}
diff --git a/basegfx/source/polygon/b2dpolygontools.cxx b/basegfx/source/polygon/b2dpolygontools.cxx
index 59b2813d3614..de75b15f9efe 100644
--- a/basegfx/source/polygon/b2dpolygontools.cxx
+++ b/basegfx/source/polygon/b2dpolygontools.cxx
@@ -3193,6 +3193,39 @@ namespace basegfx
}
}
+ bool containsOnlyHorizontalAndVerticalEdges(const B2DPolygon& rCandidate)
+ {
+ if(rCandidate.areControlPointsUsed())
+ {
+ return false;
+ }
+
+ const sal_uInt32 nPointCount(rCandidate.count());
+
+ if(nPointCount < 2)
+ {
+ return true;
+ }
+
+ const sal_uInt32 nEdgeCount(rCandidate.isClosed() ? nPointCount + 1 : nPointCount);
+ basegfx::B2DPoint aLast(rCandidate.getB2DPoint(0));
+
+ for(sal_uInt32 a(1); a < nEdgeCount; a++)
+ {
+ const sal_uInt32 nNextIndex(a % nPointCount);
+ const basegfx::B2DPoint aCurrent(rCandidate.getB2DPoint(nNextIndex));
+
+ if(!basegfx::fTools::equal(aLast.getX(), aCurrent.getX()) && !basegfx::fTools::equal(aLast.getY(), aCurrent.getY()))
+ {
+ return false;
+ }
+
+ aLast = aCurrent;
+ }
+
+ return true;
+ }
+
} // end of namespace tools
} // end of namespace basegfx
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;
}
}
};
diff --git a/basegfx/source/polygon/b2dpolypolygontools.cxx b/basegfx/source/polygon/b2dpolypolygontools.cxx
index c2b18eff4e44..b7db01c29e28 100644
--- a/basegfx/source/polygon/b2dpolypolygontools.cxx
+++ b/basegfx/source/polygon/b2dpolypolygontools.cxx
@@ -498,6 +498,23 @@ namespace basegfx
return aRetval;
}
+ bool containsOnlyHorizontalAndVerticalEdges(const B2DPolyPolygon& rCandidate)
+ {
+ if(rCandidate.areControlPointsUsed())
+ {
+ return false;
+ }
+
+ for(sal_uInt32 a(0); a < rCandidate.count(); a++)
+ {
+ if(!containsOnlyHorizontalAndVerticalEdges(rCandidate.getB2DPolygon(a)))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
} // end of namespace tools
} // end of namespace basegfx