summaryrefslogtreecommitdiff
path: root/basegfx/source/polygon
diff options
context:
space:
mode:
authorArmin Weiss <aw@openoffice.org>2003-11-06 15:30:30 +0000
committerArmin Weiss <aw@openoffice.org>2003-11-06 15:30:30 +0000
commitfef23aeb65bed8951a90ed71beb1552b62cfce71 (patch)
treed2ee4fe2d735d77de4f1618ea6664042269a67fa /basegfx/source/polygon
parent8db4a5314c1b74eba07f4f4e383fafa24239e1f1 (diff)
Added tooling for PolyPolygon cutting and some more tooling at B2DPolygon and B2DPolyPolygon
Diffstat (limited to 'basegfx/source/polygon')
-rw-r--r--basegfx/source/polygon/b2dpolygon.cxx102
-rw-r--r--basegfx/source/polygon/b2dpolygontools.cxx345
-rw-r--r--basegfx/source/polygon/b2dpolypolygon.cxx20
-rw-r--r--basegfx/source/polygon/b2dpolypolygontools.cxx91
-rw-r--r--basegfx/source/polygon/makefile.mk13
5 files changed, 478 insertions, 93 deletions
diff --git a/basegfx/source/polygon/b2dpolygon.cxx b/basegfx/source/polygon/b2dpolygon.cxx
index 3d532cdf478d..e5bcd66a2e04 100644
--- a/basegfx/source/polygon/b2dpolygon.cxx
+++ b/basegfx/source/polygon/b2dpolygon.cxx
@@ -2,9 +2,9 @@
*
* $RCSfile: b2dpolygon.cxx,v $
*
- * $Revision: 1.3 $
+ * $Revision: 1.4 $
*
- * last change: $Author: aw $ $Date: 2003-11-05 12:25:54 $
+ * last change: $Author: aw $ $Date: 2003-11-06 16:30:29 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -82,15 +82,15 @@
class CoordinateData2D
{
- basegfx::point::B2DPoint maPoint;
+ ::basegfx::point::B2DPoint maPoint;
public:
CoordinateData2D() {}
- CoordinateData2D(const basegfx::point::B2DPoint& rData) : maPoint(rData) {}
+ CoordinateData2D(const ::basegfx::point::B2DPoint& rData) : maPoint(rData) {}
~CoordinateData2D() {}
- const basegfx::point::B2DPoint& getCoordinate() const { return maPoint; }
- void setCoordinate(const basegfx::point::B2DPoint& rValue) { if(rValue != maPoint) maPoint = rValue; }
+ const ::basegfx::point::B2DPoint& getCoordinate() const { return maPoint; }
+ void setCoordinate(const ::basegfx::point::B2DPoint& rValue) { if(rValue != maPoint) maPoint = rValue; }
sal_Bool operator==(const CoordinateData2D& rData ) const { return (maPoint == rData.getCoordinate()); }
};
@@ -128,12 +128,12 @@ public:
return (maVector == rCandidate.maVector);
}
- const basegfx::point::B2DPoint& getCoordinate(sal_uInt32 nIndex) const
+ const ::basegfx::point::B2DPoint& getCoordinate(sal_uInt32 nIndex) const
{
return maVector[nIndex].getCoordinate();
}
- void setCoordinate(sal_uInt32 nIndex, const basegfx::point::B2DPoint& rValue)
+ void setCoordinate(sal_uInt32 nIndex, const ::basegfx::point::B2DPoint& rValue)
{
maVector[nIndex].setCoordinate(rValue);
}
@@ -229,18 +229,18 @@ public:
class ControlVectorPair2D
{
- basegfx::vector::B2DVector maVectorA;
- basegfx::vector::B2DVector maVectorB;
+ ::basegfx::vector::B2DVector maVectorA;
+ ::basegfx::vector::B2DVector maVectorB;
public:
ControlVectorPair2D() {}
~ControlVectorPair2D() {}
- const basegfx::vector::B2DVector& getVectorA() const { return maVectorA; }
- void setVectorA(const basegfx::vector::B2DVector& rValue) { if(rValue != maVectorA) maVectorA = rValue; }
+ const ::basegfx::vector::B2DVector& getVectorA() const { return maVectorA; }
+ void setVectorA(const ::basegfx::vector::B2DVector& rValue) { if(rValue != maVectorA) maVectorA = rValue; }
- const basegfx::vector::B2DVector& getVectorB() const { return maVectorB; }
- void setVectorB(const basegfx::vector::B2DVector& rValue) { if(rValue != maVectorB) maVectorB = rValue; }
+ const ::basegfx::vector::B2DVector& getVectorB() const { return maVectorB; }
+ void setVectorB(const ::basegfx::vector::B2DVector& rValue) { if(rValue != maVectorB) maVectorB = rValue; }
sal_Bool operator==(const ControlVectorPair2D& rData ) const
{ return (maVectorA == rData.getVectorA() && maVectorB == rData.getVectorB()); }
@@ -305,12 +305,12 @@ public:
return (0L != mnUsedVectors);
}
- const basegfx::vector::B2DVector& getVectorA(sal_uInt32 nIndex) const
+ const ::basegfx::vector::B2DVector& getVectorA(sal_uInt32 nIndex) const
{
return maVector[nIndex].getVectorA();
}
- void setVectorA(sal_uInt32 nIndex, const basegfx::vector::B2DVector& rValue)
+ void setVectorA(sal_uInt32 nIndex, const ::basegfx::vector::B2DVector& rValue)
{
sal_Bool bWasUsed(mnUsedVectors && !maVector[nIndex].getVectorA().equalZero());
sal_Bool bIsUsed(!rValue.equalZero());
@@ -323,7 +323,7 @@ public:
}
else
{
- maVector[nIndex].setVectorA(basegfx::vector::B2DVector::getEmptyVector());
+ maVector[nIndex].setVectorA(::basegfx::vector::B2DVector::getEmptyVector());
mnUsedVectors--;
}
}
@@ -337,12 +337,12 @@ public:
}
}
- const basegfx::vector::B2DVector& getVectorB(sal_uInt32 nIndex) const
+ const ::basegfx::vector::B2DVector& getVectorB(sal_uInt32 nIndex) const
{
return maVector[nIndex].getVectorB();
}
- void setVectorB(sal_uInt32 nIndex, const basegfx::vector::B2DVector& rValue)
+ void setVectorB(sal_uInt32 nIndex, const ::basegfx::vector::B2DVector& rValue)
{
sal_Bool bWasUsed(mnUsedVectors && !maVector[nIndex].getVectorB().equalZero());
sal_Bool bIsUsed(!rValue.equalZero());
@@ -355,7 +355,7 @@ public:
}
else
{
- maVector[nIndex].setVectorB(basegfx::vector::B2DVector::getEmptyVector());
+ maVector[nIndex].setVectorB(::basegfx::vector::B2DVector::getEmptyVector());
mnUsedVectors--;
}
}
@@ -577,17 +577,17 @@ public:
return sal_False;
}
- const basegfx::point::B2DPoint& getPoint(sal_uInt32 nIndex) const
+ const ::basegfx::point::B2DPoint& getPoint(sal_uInt32 nIndex) const
{
return maPoints.getCoordinate(nIndex);
}
- void setPoint(sal_uInt32 nIndex, const basegfx::point::B2DPoint& rValue)
+ void setPoint(sal_uInt32 nIndex, const ::basegfx::point::B2DPoint& rValue)
{
maPoints.setCoordinate(nIndex, rValue);
}
- void insert(sal_uInt32 nIndex, const basegfx::point::B2DPoint& rPoint, sal_uInt32 nCount)
+ void insert(sal_uInt32 nIndex, const ::basegfx::point::B2DPoint& rPoint, sal_uInt32 nCount)
{
if(nCount)
{
@@ -602,7 +602,7 @@ public:
}
}
- const basegfx::point::B2DPoint& getControlPointA(sal_uInt32 nIndex) const
+ const ::basegfx::vector::B2DVector& getControlVectorA(sal_uInt32 nIndex) const
{
if(mpControlVector)
{
@@ -610,11 +610,11 @@ public:
}
else
{
- return basegfx::point::B2DPoint::getEmptyPoint();
+ return ::basegfx::vector::B2DVector::getEmptyVector();
}
}
- void setControlPointA(sal_uInt32 nIndex, const basegfx::point::B2DPoint& rValue)
+ void setControlVectorA(sal_uInt32 nIndex, const ::basegfx::vector::B2DVector& rValue)
{
if(!mpControlVector)
{
@@ -641,7 +641,7 @@ public:
return (mpControlVector && mpControlVector->isUsed());
}
- const basegfx::point::B2DPoint& getControlPointB(sal_uInt32 nIndex) const
+ const ::basegfx::vector::B2DVector& getControlVectorB(sal_uInt32 nIndex) const
{
if(mpControlVector)
{
@@ -649,11 +649,11 @@ public:
}
else
{
- return basegfx::point::B2DPoint::getEmptyPoint();
+ return ::basegfx::vector::B2DVector::getEmptyVector();
}
}
- void setControlPointB(sal_uInt32 nIndex, const basegfx::point::B2DPoint& rValue)
+ void setControlVectorB(sal_uInt32 nIndex, const ::basegfx::vector::B2DVector& rValue)
{
if(!mpControlVector)
{
@@ -751,10 +751,10 @@ public:
const sal_uInt32 nVectorSource(nCoorSource ? nCoorSource - 1L : nCount - 1L);
// get source data
- const basegfx::point::B2DPoint& rSourceCoor = pCoordinateCopy->getCoordinate(nCoorSource);
- const basegfx::point::B2DPoint& rVectorSourceCoor = pCoordinateCopy->getCoordinate(nVectorSource);
- const basegfx::vector::B2DVector& rVectorSourceA = pVectorCopy->getVectorA(nVectorSource);
- const basegfx::vector::B2DVector& rVectorSourceB = pVectorCopy->getVectorB(nVectorSource);
+ const ::basegfx::point::B2DPoint& rSourceCoor = pCoordinateCopy->getCoordinate(nCoorSource);
+ const ::basegfx::point::B2DPoint& rVectorSourceCoor = pCoordinateCopy->getCoordinate(nVectorSource);
+ const ::basegfx::vector::B2DVector& rVectorSourceA = pVectorCopy->getVectorA(nVectorSource);
+ const ::basegfx::vector::B2DVector& rVectorSourceB = pVectorCopy->getVectorB(nVectorSource);
// copy point data
maPoints.setCoordinate(a, rSourceCoor);
@@ -763,12 +763,12 @@ public:
if(rVectorSourceA.equalZero())
{
// unused, use zero vector
- mpControlVector->setVectorB(a, basegfx::vector::B2DVector::getEmptyVector());
+ mpControlVector->setVectorB(a, ::basegfx::vector::B2DVector::getEmptyVector());
}
else
{
// calculate new vector relative to new point
- basegfx::vector::B2DVector aNewVectorB((rVectorSourceA + rVectorSourceCoor) - rSourceCoor);
+ ::basegfx::vector::B2DVector aNewVectorB((rVectorSourceA + rVectorSourceCoor) - rSourceCoor);
mpControlVector->setVectorB(a, aNewVectorB);
}
@@ -776,12 +776,12 @@ public:
if(rVectorSourceB.equalZero())
{
// unused, use zero vector
- mpControlVector->setVectorA(a, basegfx::vector::B2DVector::getEmptyVector());
+ mpControlVector->setVectorA(a, ::basegfx::vector::B2DVector::getEmptyVector());
}
else
{
// calculate new vector relative to new point
- basegfx::vector::B2DVector aNewVectorA((rVectorSourceB + rVectorSourceCoor) - rSourceCoor);
+ ::basegfx::vector::B2DVector aNewVectorA((rVectorSourceB + rVectorSourceCoor) - rSourceCoor);
mpControlVector->setVectorA(a, aNewVectorA);
}
}
@@ -1006,14 +1006,14 @@ namespace basegfx
return mpPolygon->count();
}
- point::B2DPoint B2DPolygon::getB2DPoint(sal_uInt32 nIndex) const
+ ::basegfx::point::B2DPoint B2DPolygon::getB2DPoint(sal_uInt32 nIndex) const
{
DBG_ASSERT(nIndex < mpPolygon->count(), "B2DPolygon access outside range (!)");
return mpPolygon->getPoint(nIndex);
}
- void B2DPolygon::setB2DPoint(sal_uInt32 nIndex, const point::B2DPoint& rValue)
+ void B2DPolygon::setB2DPoint(sal_uInt32 nIndex, const ::basegfx::point::B2DPoint& rValue)
{
DBG_ASSERT(nIndex < mpPolygon->count(), "B2DPolygon access outside range (!)");
@@ -1024,7 +1024,7 @@ namespace basegfx
}
}
- void B2DPolygon::insert(sal_uInt32 nIndex, const point::B2DPoint& rPoint, sal_uInt32 nCount)
+ void B2DPolygon::insert(sal_uInt32 nIndex, const ::basegfx::point::B2DPoint& rPoint, sal_uInt32 nCount)
{
DBG_ASSERT(nIndex <= mpPolygon->count(), "B2DPolygon Insert outside range (!)");
@@ -1035,7 +1035,7 @@ namespace basegfx
}
}
- void B2DPolygon::append(const point::B2DPoint& rPoint, sal_uInt32 nCount)
+ void B2DPolygon::append(const ::basegfx::point::B2DPoint& rPoint, sal_uInt32 nCount)
{
if(nCount)
{
@@ -1044,39 +1044,39 @@ namespace basegfx
}
}
- point::B2DPoint B2DPolygon::getControlPointA(sal_uInt32 nIndex) const
+ ::basegfx::vector::B2DVector B2DPolygon::getControlVectorA(sal_uInt32 nIndex) const
{
DBG_ASSERT(nIndex < mpPolygon->count(), "B2DPolygon access outside range (!)");
- return mpPolygon->getControlPointA(nIndex);
+ return mpPolygon->getControlVectorA(nIndex);
}
- void B2DPolygon::setControlPointA(sal_uInt32 nIndex, const point::B2DPoint& rValue)
+ void B2DPolygon::setControlVectorA(sal_uInt32 nIndex, const ::basegfx::vector::B2DVector& rValue)
{
DBG_ASSERT(nIndex < mpPolygon->count(), "B2DPolygon access outside range (!)");
- if(mpPolygon->getControlPointA(nIndex) != rValue)
+ if(mpPolygon->getControlVectorA(nIndex) != rValue)
{
implForceUniqueCopy();
- mpPolygon->setControlPointA(nIndex, rValue);
+ mpPolygon->setControlVectorA(nIndex, rValue);
}
}
- point::B2DPoint B2DPolygon::getControlPointB(sal_uInt32 nIndex) const
+ ::basegfx::vector::B2DVector B2DPolygon::getControlVectorB(sal_uInt32 nIndex) const
{
DBG_ASSERT(nIndex < mpPolygon->count(), "B2DPolygon access outside range (!)");
- return mpPolygon->getControlPointB(nIndex);
+ return mpPolygon->getControlVectorB(nIndex);
}
- void B2DPolygon::setControlPointB(sal_uInt32 nIndex, const point::B2DPoint& rValue)
+ void B2DPolygon::setControlVectorB(sal_uInt32 nIndex, const ::basegfx::vector::B2DVector& rValue)
{
DBG_ASSERT(nIndex < mpPolygon->count(), "B2DPolygon access outside range (!)");
- if(mpPolygon->getControlPointB(nIndex) != rValue)
+ if(mpPolygon->getControlVectorB(nIndex) != rValue)
{
implForceUniqueCopy();
- mpPolygon->setControlPointB(nIndex, rValue);
+ mpPolygon->setControlVectorB(nIndex, rValue);
}
}
diff --git a/basegfx/source/polygon/b2dpolygontools.cxx b/basegfx/source/polygon/b2dpolygontools.cxx
index c5b56dd72e31..c7211c12bd07 100644
--- a/basegfx/source/polygon/b2dpolygontools.cxx
+++ b/basegfx/source/polygon/b2dpolygontools.cxx
@@ -2,9 +2,9 @@
*
* $RCSfile: b2dpolygontools.cxx,v $
*
- * $Revision: 1.3 $
+ * $Revision: 1.4 $
*
- * last change: $Author: aw $ $Date: 2003-11-05 12:25:54 $
+ * last change: $Author: aw $ $Date: 2003-11-06 16:30:29 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -99,7 +99,7 @@ namespace basegfx
}
// Get index of outmost point (e.g. biggest X and biggest Y)
- sal_uInt32 getIndexOfOutmostPoint(const polygon::B2DPolygon& rCandidate)
+ sal_uInt32 getIndexOfOutmostPoint(const ::basegfx::polygon::B2DPolygon& rCandidate)
{
sal_uInt32 nRetval(0L);
@@ -132,7 +132,7 @@ namespace basegfx
// Get successor and predecessor indices. Returning the same index means there
// is none. Same for successor.
- sal_uInt32 getIndexOfPredecessor(sal_uInt32 nIndex, const polygon::B2DPolygon& rCandidate)
+ sal_uInt32 getIndexOfPredecessor(sal_uInt32 nIndex, const ::basegfx::polygon::B2DPolygon& rCandidate)
{
if(nIndex)
{
@@ -148,7 +148,7 @@ namespace basegfx
}
}
- sal_uInt32 getIndexOfSuccessor(sal_uInt32 nIndex, const polygon::B2DPolygon& rCandidate)
+ sal_uInt32 getIndexOfSuccessor(sal_uInt32 nIndex, const ::basegfx::polygon::B2DPolygon& rCandidate)
{
if(nIndex + 1L < rCandidate.count())
{
@@ -160,7 +160,7 @@ namespace basegfx
}
}
- sal_uInt32 getIndexOfDifferentPredecessor(sal_uInt32 nIndex, const polygon::B2DPolygon& rCandidate)
+ sal_uInt32 getIndexOfDifferentPredecessor(sal_uInt32 nIndex, const ::basegfx::polygon::B2DPolygon& rCandidate)
{
if(rCandidate.count() > 1)
{
@@ -177,7 +177,7 @@ namespace basegfx
return nIndex;
}
- sal_uInt32 getIndexOfDifferentSuccessor(sal_uInt32 nIndex, const polygon::B2DPolygon& rCandidate)
+ sal_uInt32 getIndexOfDifferentSuccessor(sal_uInt32 nIndex, const ::basegfx::polygon::B2DPolygon& rCandidate)
{
if(rCandidate.count() > 1)
{
@@ -214,8 +214,8 @@ namespace basegfx
for(sal_uInt32 a(0L); a < nPointCount; a++)
{
- const basegfx::point::B2DPoint aCurrentPoint(rCandidate.getB2DPoint(a));
- const basegfx::point::B2DPoint aPreviousPoint(rCandidate.getB2DPoint((!a) ? nPointCount - 1L : a - 1L));
+ const ::basegfx::point::B2DPoint aCurrentPoint(rCandidate.getB2DPoint(a));
+ const ::basegfx::point::B2DPoint aPreviousPoint(rCandidate.getB2DPoint((!a) ? nPointCount - 1L : a - 1L));
// cross-over in Y?
const sal_Bool bCompYA(::basegfx::numeric::fTools::more(aPreviousPoint.getY(), rPoint.getY()));
@@ -291,8 +291,8 @@ namespace basegfx
{
for(sal_uInt32 a(0L); a < nPointCount; a++)
{
- const basegfx::point::B2DPoint aPreviousPoint(rCandidate.getB2DPoint((!a) ? nPointCount - 1L : a - 1L));
- const basegfx::point::B2DPoint aCurrentPoint(rCandidate.getB2DPoint(a));
+ const ::basegfx::point::B2DPoint aPreviousPoint(rCandidate.getB2DPoint((!a) ? nPointCount - 1L : a - 1L));
+ const ::basegfx::point::B2DPoint aCurrentPoint(rCandidate.getB2DPoint(a));
fRetval += aPreviousPoint.getX() * aCurrentPoint.getY();
fRetval -= aPreviousPoint.getY() * aCurrentPoint.getX();
@@ -321,9 +321,9 @@ namespace basegfx
if(rCandidate.isClosed() || nIndex + 1 != nPointCount)
{
const sal_uInt32 nNextIndex(nIndex + 1 == nPointCount ? 0L : nIndex + 1L);
- const basegfx::point::B2DPoint aCurrentPoint(rCandidate.getB2DPoint(nIndex));
- const basegfx::point::B2DPoint aNextPoint(rCandidate.getB2DPoint(nNextIndex));
- const basegfx::vector::B2DVector aVector(aNextPoint - aCurrentPoint);
+ const ::basegfx::point::B2DPoint aCurrentPoint(rCandidate.getB2DPoint(nIndex));
+ const ::basegfx::point::B2DPoint aNextPoint(rCandidate.getB2DPoint(nNextIndex));
+ const ::basegfx::vector::B2DVector aVector(aNextPoint - aCurrentPoint);
fRetval = aVector.getLength();
}
}
@@ -343,9 +343,9 @@ namespace basegfx
for(sal_uInt32 a(0L); a < nLoopCount; a++)
{
const sal_uInt32 nNextIndex(a + 1 == nPointCount ? 0L : a + 1L);
- const basegfx::point::B2DPoint aCurrentPoint(rCandidate.getB2DPoint(a));
- const basegfx::point::B2DPoint aNextPoint(rCandidate.getB2DPoint(nNextIndex));
- const basegfx::vector::B2DVector aVector(aNextPoint - aCurrentPoint);
+ const ::basegfx::point::B2DPoint aCurrentPoint(rCandidate.getB2DPoint(a));
+ const ::basegfx::point::B2DPoint aNextPoint(rCandidate.getB2DPoint(nNextIndex));
+ const ::basegfx::vector::B2DVector aVector(aNextPoint - aCurrentPoint);
fRetval += aVector.scalar(aVector);
}
@@ -498,6 +498,317 @@ namespace basegfx
return eRetval;
}
+
+ CutFlagValue findCut(
+ const ::basegfx::polygon::B2DPolygon& rCandidate,
+ sal_uInt32 nIndex1, sal_uInt32 nIndex2,
+ CutFlagValue aCutFlags,
+ double* pCut1, double* pCut2)
+ {
+ CutFlagValue aRetval(CUTFLAG_NONE);
+ const sal_uInt32 nPointCount(rCandidate.count());
+
+ if(nIndex1 < nPointCount && nIndex2 < nPointCount && nIndex1 != nIndex2)
+ {
+ sal_uInt32 nEnd1(getIndexOfSuccessor(nIndex1, rCandidate));
+ sal_uInt32 nEnd2(getIndexOfSuccessor(nIndex2, rCandidate));
+
+ const ::basegfx::point::B2DPoint aStart1(rCandidate.getB2DPoint(nIndex1));
+ const ::basegfx::point::B2DPoint aEnd1(rCandidate.getB2DPoint(nEnd1));
+ const ::basegfx::vector::B2DVector aVector1(aEnd1 - aStart1);
+
+ const ::basegfx::point::B2DPoint aStart2(rCandidate.getB2DPoint(nIndex2));
+ const ::basegfx::point::B2DPoint aEnd2(rCandidate.getB2DPoint(nEnd2));
+ const ::basegfx::vector::B2DVector aVector2(aEnd2 - aStart2);
+
+ aRetval = findCut(
+ aStart1, aVector1, aStart2, aVector2,
+ aCutFlags, pCut1, pCut2);
+ }
+
+ return aRetval;
+ }
+
+ CutFlagValue findCut(
+ const ::basegfx::polygon::B2DPolygon& rCandidate1, sal_uInt32 nIndex1,
+ const ::basegfx::polygon::B2DPolygon& rCandidate2, sal_uInt32 nIndex2,
+ CutFlagValue aCutFlags,
+ double* pCut1, double* pCut2)
+ {
+ CutFlagValue aRetval(CUTFLAG_NONE);
+ const sal_uInt32 nPointCount1(rCandidate1.count());
+ const sal_uInt32 nPointCount2(rCandidate2.count());
+
+ if(nIndex1 < nPointCount1 && nIndex2 < nPointCount2)
+ {
+ sal_uInt32 nEnd1(getIndexOfSuccessor(nIndex1, rCandidate1));
+ sal_uInt32 nEnd2(getIndexOfSuccessor(nIndex2, rCandidate2));
+
+ const ::basegfx::point::B2DPoint aStart1(rCandidate1.getB2DPoint(nIndex1));
+ const ::basegfx::point::B2DPoint aEnd1(rCandidate1.getB2DPoint(nEnd1));
+ const ::basegfx::vector::B2DVector aVector1(aEnd1 - aStart1);
+
+ const ::basegfx::point::B2DPoint aStart2(rCandidate2.getB2DPoint(nIndex2));
+ const ::basegfx::point::B2DPoint aEnd2(rCandidate2.getB2DPoint(nEnd2));
+ const ::basegfx::vector::B2DVector aVector2(aEnd2 - aStart2);
+
+ aRetval = findCut(
+ aStart1, aVector1, aStart2, aVector2,
+ aCutFlags, pCut1, pCut2);
+ }
+
+ return aRetval;
+ }
+
+ CutFlagValue findCut(
+ const ::basegfx::point::B2DPoint& rEdge1Start, const ::basegfx::vector::B2DVector& rEdge1Delta,
+ const ::basegfx::point::B2DPoint& rEdge2Start, const ::basegfx::vector::B2DVector& rEdge2Delta,
+ CutFlagValue aCutFlags,
+ double* pCut1, double* pCut2)
+ {
+ CutFlagValue aRetval(CUTFLAG_NONE);
+ double fCut1(0.0);
+ double fCut2(0.0);
+ sal_Bool bFinished(!((sal_Bool)(aCutFlags & CUTFLAG_ALL)));
+
+ // test for same points?
+ if(!bFinished
+ && (aCutFlags & (CUTFLAG_START1|CUTFLAG_END1))
+ && (aCutFlags & (CUTFLAG_START2|CUTFLAG_END2)))
+ {
+ // same startpoint?
+ if(!bFinished && (aCutFlags & (CUTFLAG_START1|CUTFLAG_START2)) == (CUTFLAG_START1|CUTFLAG_START2))
+ {
+ if(rEdge1Start.equal(rEdge2Start))
+ {
+ bFinished = sal_True;
+ aRetval = (CUTFLAG_START1|CUTFLAG_START2);
+ }
+ }
+
+ // same endpoint?
+ if(!bFinished && (aCutFlags & (CUTFLAG_END1|CUTFLAG_END2)) == (CUTFLAG_END1|CUTFLAG_END2))
+ {
+ const ::basegfx::point::B2DPoint aEnd1(rEdge1Start + rEdge1Delta);
+ const ::basegfx::point::B2DPoint aEnd2(rEdge2Start + rEdge2Delta);
+
+ if(aEnd1.equal(aEnd2))
+ {
+ bFinished = sal_True;
+ aRetval = (CUTFLAG_END1|CUTFLAG_END2);
+ fCut1 = fCut2 = 1.0;
+ }
+ }
+
+ // startpoint1 == endpoint2?
+ if(!bFinished && (aCutFlags & (CUTFLAG_START1|CUTFLAG_END2)) == (CUTFLAG_START1|CUTFLAG_END2))
+ {
+ const ::basegfx::point::B2DPoint aEnd2(rEdge2Start + rEdge2Delta);
+
+ if(rEdge1Start.equal(aEnd2))
+ {
+ bFinished = sal_True;
+ aRetval = (CUTFLAG_START1|CUTFLAG_END2);
+ fCut1 = 0.0;
+ fCut2 = 1.0;
+ }
+ }
+
+ // startpoint2 == endpoint1?
+ if(!bFinished&& (aCutFlags & (CUTFLAG_START2|CUTFLAG_END1)) == (CUTFLAG_START2|CUTFLAG_END1))
+ {
+ const ::basegfx::point::B2DPoint aEnd1(rEdge1Start + rEdge1Delta);
+
+ if(rEdge2Start.equal(aEnd1))
+ {
+ bFinished = sal_True;
+ aRetval = (CUTFLAG_START2|CUTFLAG_END1);
+ fCut1 = 1.0;
+ fCut2 = 0.0;
+ }
+ }
+ }
+
+ if(!bFinished && (aCutFlags & CUTFLAG_LINE))
+ {
+ if(!bFinished && (aCutFlags & CUTFLAG_START1))
+ {
+ // start1 on line 2 ?
+ if(isPointOnEdge(rEdge1Start, rEdge2Start, rEdge2Delta, &fCut2))
+ {
+ bFinished = sal_True;
+ aRetval = (CUTFLAG_LINE|CUTFLAG_START1);
+ }
+ }
+
+ if(!bFinished && (aCutFlags & CUTFLAG_START2))
+ {
+ // start2 on line 1 ?
+ if(isPointOnEdge(rEdge2Start, rEdge1Start, rEdge1Delta, &fCut1))
+ {
+ bFinished = sal_True;
+ aRetval = (CUTFLAG_LINE|CUTFLAG_START2);
+ }
+ }
+
+ if(!bFinished && (aCutFlags & CUTFLAG_END1))
+ {
+ // end1 on line 2 ?
+ const ::basegfx::point::B2DPoint aEnd1(rEdge1Start + rEdge1Delta);
+
+ if(isPointOnEdge(aEnd1, rEdge2Start, rEdge2Delta, &fCut2))
+ {
+ bFinished = sal_True;
+ aRetval = (CUTFLAG_LINE|CUTFLAG_END1);
+ }
+ }
+
+ if(!bFinished && (aCutFlags & CUTFLAG_END2))
+ {
+ // end2 on line 1 ?
+ const ::basegfx::point::B2DPoint aEnd2(rEdge2Start + rEdge2Delta);
+
+ if(isPointOnEdge(aEnd2, rEdge1Start, rEdge1Delta, &fCut1))
+ {
+ bFinished = sal_True;
+ aRetval = (CUTFLAG_LINE|CUTFLAG_END2);
+ }
+ }
+
+ if(!bFinished)
+ {
+ // cut in line1, line2 ?
+ fCut1 = (rEdge1Delta.getX() * rEdge2Delta.getY()) - (rEdge1Delta.getY() * rEdge2Delta.getX());
+
+ if(!::basegfx::numeric::fTools::equalZero(fCut1))
+ {
+ fCut1 = (rEdge2Delta.getY() * (rEdge2Start.getX() - rEdge1Start.getX())
+ + rEdge2Delta.getX() * (rEdge1Start.getY() - rEdge2Start.getY())) / fCut1;
+
+ const double fZero(0.0);
+ const double fOne(1.0);
+
+ // inside parameter range edge1 AND fCut2 is calcable
+ if(::basegfx::numeric::fTools::more(fCut1, fZero) && ::basegfx::numeric::fTools::less(fCut1, fOne)
+ && (!::basegfx::numeric::fTools::equalZero(rEdge2Delta.getX()) || !::basegfx::numeric::fTools::equalZero(rEdge2Delta.getY())))
+ {
+ // take the mopre precise calculation of the two possible
+ if(fabs(rEdge2Delta.getX()) > fabs(rEdge2Delta.getY()))
+ {
+ fCut2 = (rEdge1Start.getX() + fCut1
+ * rEdge1Delta.getX() - rEdge2Start.getX()) / rEdge2Delta.getX();
+ }
+ else
+ {
+ fCut2 = (rEdge1Start.getY() + fCut1
+ * rEdge1Delta.getY() - rEdge2Start.getY()) / rEdge2Delta.getY();
+ }
+
+ // inside parameter range edge2, too
+ if(::basegfx::numeric::fTools::more(fCut2, fZero) && ::basegfx::numeric::fTools::less(fCut2, fOne))
+ {
+ bFinished = sal_True;
+ aRetval = CUTFLAG_LINE;
+ }
+ }
+ }
+ }
+ }
+
+ // copy values if wanted
+ if(pCut1)
+ {
+ *pCut1 = fCut1;
+ }
+
+ if(pCut2)
+ {
+ *pCut2 = fCut2;
+ }
+
+ return aRetval;
+ }
+
+ sal_Bool isPointOnEdge(
+ const ::basegfx::point::B2DPoint& rPoint,
+ const ::basegfx::point::B2DPoint& rEdgeStart,
+ const ::basegfx::vector::B2DVector& rEdgeDelta,
+ double* pCut)
+ {
+ sal_Bool bDeltaXIsZero(::basegfx::numeric::fTools::equalZero(rEdgeDelta.getX()));
+ sal_Bool bDeltaYIsZero(::basegfx::numeric::fTools::equalZero(rEdgeDelta.getY()));
+ const double fZero(0.0);
+ const double fOne(1.0);
+
+ if(bDeltaXIsZero && bDeltaYIsZero)
+ {
+ // no line, just a point
+ return sal_False;
+ }
+ else if(bDeltaXIsZero)
+ {
+ // vertical line
+ if(::basegfx::numeric::fTools::equal(rPoint.getX(), rEdgeStart.getX()))
+ {
+ double fValue = (rPoint.getY() - rEdgeStart.getY()) / rEdgeDelta.getY();
+
+ if(::basegfx::numeric::fTools::more(fValue, fZero) && ::basegfx::numeric::fTools::less(fValue, fOne))
+ {
+ if(pCut)
+ {
+ *pCut = fValue;
+ }
+
+ return sal_True;
+ }
+ }
+ }
+ else if(bDeltaYIsZero)
+ {
+ // horizontal line
+ if(::basegfx::numeric::fTools::equal(rPoint.getY(), rEdgeStart.getY()))
+ {
+ double fValue = (rPoint.getX() - rEdgeStart.getX()) / rEdgeDelta.getX();
+
+ if(::basegfx::numeric::fTools::more(fValue, fZero)
+ && ::basegfx::numeric::fTools::less(fValue, fOne))
+ {
+ if(pCut)
+ {
+ *pCut = fValue;
+ }
+
+ return sal_True;
+ }
+ }
+ }
+ else
+ {
+ // any angle line
+ double fTOne = (rPoint.getX() - rEdgeStart.getX()) / rEdgeDelta.getX();
+ double fTTwo = (rPoint.getY() - rEdgeStart.getY()) / rEdgeDelta.getY();
+
+ if(::basegfx::numeric::fTools::equal(fTOne, fTTwo))
+ {
+ // same parameter representation, point is on line. Take
+ // middle value for better results
+ double fValue = (fTOne + fTTwo) / 2.0;
+
+ if(::basegfx::numeric::fTools::more(fValue, fZero) && ::basegfx::numeric::fTools::less(fValue, fOne))
+ {
+ // point is inside line bounds, too
+ if(pCut)
+ {
+ *pCut = fValue;
+ }
+
+ return sal_True;
+ }
+ }
+ }
+
+ return sal_False;
+ }
} // end of namespace tools
} // end of namespace polygon
} // end of namespace basegfx
diff --git a/basegfx/source/polygon/b2dpolypolygon.cxx b/basegfx/source/polygon/b2dpolypolygon.cxx
index b1183a6cf052..7b15b1282a71 100644
--- a/basegfx/source/polygon/b2dpolypolygon.cxx
+++ b/basegfx/source/polygon/b2dpolypolygon.cxx
@@ -2,9 +2,9 @@
*
* $RCSfile: b2dpolypolygon.cxx,v $
*
- * $Revision: 1.3 $
+ * $Revision: 1.4 $
*
- * last change: $Author: aw $ $Date: 2003-11-05 12:25:54 $
+ * last change: $Author: aw $ $Date: 2003-11-06 16:30:29 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -81,7 +81,7 @@
class ImplB2DPolyPolygon
{
- typedef ::std::vector< basegfx::polygon::B2DPolygon > PolygonVector;
+ typedef ::std::vector< ::basegfx::polygon::B2DPolygon > PolygonVector;
PolygonVector maPolygons;
sal_uInt32 mnRefCount;
@@ -127,17 +127,17 @@ public:
return sal_True;
}
- const basegfx::polygon::B2DPolygon& getPolygon(sal_uInt32 nIndex) const
+ const ::basegfx::polygon::B2DPolygon& getPolygon(sal_uInt32 nIndex) const
{
return maPolygons[nIndex];
}
- void setPolygon(sal_uInt32 nIndex, const basegfx::polygon::B2DPolygon& rPolygon)
+ void setPolygon(sal_uInt32 nIndex, const ::basegfx::polygon::B2DPolygon& rPolygon)
{
maPolygons[nIndex] = rPolygon;
}
- void insert(sal_uInt32 nIndex, const basegfx::polygon::B2DPolygon& rPolygon, sal_uInt32 nCount)
+ void insert(sal_uInt32 nIndex, const ::basegfx::polygon::B2DPolygon& rPolygon, sal_uInt32 nCount)
{
if(nCount)
{
@@ -148,7 +148,7 @@ public:
}
}
- void insert(sal_uInt32 nIndex, const basegfx::polygon::B2DPolyPolygon& rPolyPolygon)
+ void insert(sal_uInt32 nIndex, const ::basegfx::polygon::B2DPolyPolygon& rPolyPolygon)
{
const sal_uInt32 nCount = rPolyPolygon.count();
@@ -404,12 +404,6 @@ namespace basegfx
}
}
- ::basegfx::vector::B2DVectorOrientation B2DPolyPolygon::checkOrientations()
- {
- implForceUniqueCopy();
- return ::basegfx::polygon::tools::checkOrientations(*this);
- }
-
void B2DPolyPolygon::flip()
{
implForceUniqueCopy();
diff --git a/basegfx/source/polygon/b2dpolypolygontools.cxx b/basegfx/source/polygon/b2dpolypolygontools.cxx
index 016bad760cd4..07ada131585d 100644
--- a/basegfx/source/polygon/b2dpolypolygontools.cxx
+++ b/basegfx/source/polygon/b2dpolypolygontools.cxx
@@ -2,9 +2,9 @@
*
* $RCSfile: b2dpolypolygontools.cxx,v $
*
- * $Revision: 1.1 $
+ * $Revision: 1.2 $
*
- * last change: $Author: aw $ $Date: 2003-11-05 12:24:43 $
+ * last change: $Author: aw $ $Date: 2003-11-06 16:30:29 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -67,10 +67,22 @@
#include <basegfx/polygon/b2dpolypolygon.hxx>
#endif
+#ifndef _BGFX_POLYGON_B2DPOLYGON_HXX
+#include <basegfx/polygon/b2dpolygon.hxx>
+#endif
+
+#ifndef _BGFX_POLYGON_B2DPOLYGONTOOLS_HXX
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#endif
+
#ifndef _BGFX_NUMERIC_FTOOLS_HXX
#include <basegfx/numeric/ftools.hxx>
#endif
+#ifndef _BGFX_POLYGON_B2DPOLYPOLYGONCUTTER_HXX
+#include <basegfx/polygon/b2dpolypolygoncutter.hxx>
+#endif
+
//////////////////////////////////////////////////////////////////////////////
namespace basegfx
@@ -81,17 +93,84 @@ namespace basegfx
{
// B2DPolyPolygon tools
- // Check and evtl. correct orientations of contained Polygons
- ::basegfx::vector::B2DVectorOrientation checkOrientations(::basegfx::polygon::B2DPolyPolygon& rCandidate)
+ void correctOrientations(::basegfx::polygon::B2DPolyPolygon& rCandidate)
{
- ::basegfx::vector::B2DVectorOrientation eRetval(::basegfx::vector::ORIENTATION_NEUTRAL);
+ const sal_uInt32 nPolygonCount(rCandidate.count());
+ sal_uInt32 nIndexOfOutmostPolygon(0L);
+ sal_Bool bIndexOfOutmostPolygonSet(sal_False);
+
+ for(sal_uInt32 a(0L); a < nPolygonCount; a++)
+ {
+ ::basegfx::polygon::B2DPolygon aCandidate = rCandidate.getPolygon(a);
+ if(aCandidate.count() > 2L)
+ {
+ ::basegfx::vector::B2DVectorOrientation aOrientation =
+ ::basegfx::polygon::tools::getOrientation(aCandidate);
+ sal_Bool bDoFlip(::basegfx::vector::ORIENTATION_POSITIVE != aOrientation);
+ // init values for depth and compare point for
+ // inside test. Since the ordering makes only sense when assuming
+ // that there are no intersections, the inside test is done with
+ // any point of the candidate, so teke the first one.
+ sal_uInt32 nDepth(0L);
+ const ::basegfx::point::B2DPoint aTestPoint(aCandidate.getB2DPoint(0L));
+ // loop over other polygons and calculate depth
+ for(sal_uInt32 b(0L); b < nPolygonCount; b++)
+ {
+ if(b != a)
+ {
+ ::basegfx::polygon::B2DPolygon aComparePolygon = rCandidate.getPolygon(b);
+ if(::basegfx::polygon::tools::isInside(aComparePolygon, aTestPoint))
+ {
+ nDepth++;
+ }
+ }
+ }
+ // if nDepth is odd it is a hole
+ sal_Bool bIsHole(1L == (nDepth & 0x00000001));
+
+ // does polygon need to be flipped?
+ if((bDoFlip && !bIsHole) || (!bDoFlip && bIsHole))
+ {
+ aCandidate.flip();
+
+ // write back changed polygon
+ rCandidate.setPolygon(a, aCandidate);
+ }
+
+ // remember the index if it's the outmost polygon
+ if(!bIndexOfOutmostPolygonSet && 0L == nDepth)
+ {
+ bIndexOfOutmostPolygonSet = sal_True;
+ nIndexOfOutmostPolygon = a;
+ }
+ }
+ }
+
+ // if the outmost polygon is not the first, move it in front
+ if(bIndexOfOutmostPolygonSet && nIndexOfOutmostPolygon > 0L)
+ {
+ ::basegfx::polygon::B2DPolygon aOutmostPolygon = rCandidate.getPolygon(nIndexOfOutmostPolygon);
+ rCandidate.remove(nIndexOfOutmostPolygon);
+ rCandidate.insert(0L, aOutmostPolygon);
+ }
+ }
+
+ void removeIntersections(::basegfx::polygon::B2DPolyPolygon& rCandidate,
+ sal_Bool bForceOrientation, sal_Bool bInvertRemove)
+ {
+ ::basegfx::polygon::B2DPolyPolygonCutter aCutter;
- return eRetval;
+ aCutter.addPolyPolygon(rCandidate, bForceOrientation);
+ aCutter.removeSelfIntersections();
+ aCutter.removeDoubleIntersections();
+ aCutter.removeIncludedPolygons(!bInvertRemove);
+ rCandidate.clear();
+ aCutter.getPolyPolygon(rCandidate);
}
} // end of namespace tools
} // end of namespace polygon
diff --git a/basegfx/source/polygon/makefile.mk b/basegfx/source/polygon/makefile.mk
index 7e6e3384c48e..6cf70f361d67 100644
--- a/basegfx/source/polygon/makefile.mk
+++ b/basegfx/source/polygon/makefile.mk
@@ -2,9 +2,9 @@
#
# $RCSfile: makefile.mk,v $
#
-# $Revision: 1.2 $
+# $Revision: 1.3 $
#
-# last change: $Author: aw $ $Date: 2003-11-05 12:25:55 $
+# last change: $Author: aw $ $Date: 2003-11-06 16:30:29 $
#
# The Contents of this file are made available subject to the terms of
# either of the following licenses
@@ -75,10 +75,11 @@ TARGET=polygon
# --- Files -------------------------------------
SLOFILES= \
- $(SLO)$/b2dpolygon.obj \
- $(SLO)$/b2dpolygontools.obj \
- $(SLO)$/b2dpolypolygon.obj \
- $(SLO)$/b2dpolypolygontools.obj
+ $(SLO)$/b2dpolygon.obj \
+ $(SLO)$/b2dpolygontools.obj \
+ $(SLO)$/b2dpolypolygon.obj \
+ $(SLO)$/b2dpolypolygontools.obj \
+ $(SLO)$/b2dpolypolygoncutter.obj
# --- Targets ----------------------------------