summaryrefslogtreecommitdiff
path: root/basegfx/source/polygon
diff options
context:
space:
mode:
authorArmin Weiss <aw@openoffice.org>2003-11-05 11:25:58 +0000
committerArmin Weiss <aw@openoffice.org>2003-11-05 11:25:58 +0000
commitc3663a687ccc9365b2b4eb4a3950b8d94c2d6ea7 (patch)
treec47ce5e59d718d5f772121000a356ef523662b17 /basegfx/source/polygon
parent571971699571e0baf9710ddf076ebf27aebb548d (diff)
Added PolyPolygonTools, Added PolygonTool functionality, changed bool to sal_Bool
Diffstat (limited to 'basegfx/source/polygon')
-rw-r--r--basegfx/source/polygon/b2dpolygon.cxx176
-rw-r--r--basegfx/source/polygon/b2dpolygontools.cxx422
-rw-r--r--basegfx/source/polygon/b2dpolypolygon.cxx112
-rw-r--r--basegfx/source/polygon/makefile.mk11
4 files changed, 671 insertions, 50 deletions
diff --git a/basegfx/source/polygon/b2dpolygon.cxx b/basegfx/source/polygon/b2dpolygon.cxx
index a9ddb6e90534..3d532cdf478d 100644
--- a/basegfx/source/polygon/b2dpolygon.cxx
+++ b/basegfx/source/polygon/b2dpolygon.cxx
@@ -2,9 +2,9 @@
*
* $RCSfile: b2dpolygon.cxx,v $
*
- * $Revision: 1.2 $
+ * $Revision: 1.3 $
*
- * last change: $Author: aw $ $Date: 2003-10-31 10:13:58 $
+ * last change: $Author: aw $ $Date: 2003-11-05 12:25:54 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -128,12 +128,12 @@ public:
return (maVector == rCandidate.maVector);
}
- const basegfx::vector::B2DVector& 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::vector::B2DVector& rValue)
+ void setCoordinate(sal_uInt32 nIndex, const basegfx::point::B2DPoint& rValue)
{
maVector[nIndex].setCoordinate(rValue);
}
@@ -192,6 +192,37 @@ public:
}
}
}
+
+ void removeDoublePointsAtBeginEnd()
+ {
+ // remove from end as long as there are at least two points
+ // and begin/end are equal
+ while((maVector.size() > 1L) && (maVector[0] == maVector[maVector.size() - 1L]))
+ {
+ maVector.pop_back();
+ }
+ }
+
+ void removeDoublePointsWholeTrack()
+ {
+ sal_uInt32 nIndex(0L);
+
+ // test as long as there are at least two points and as long as the index
+ // is smaller or equal second last point
+ while((maVector.size() > 1L) && (nIndex <= maVector.size() - 2L))
+ {
+ if(maVector[nIndex] == maVector[nIndex + 1L])
+ {
+ // if next is same as index, delete next
+ maVector.erase(maVector.begin() + (nIndex + 1L));
+ }
+ else
+ {
+ // if different, step forward
+ nIndex++;
+ }
+ }
+ }
};
//////////////////////////////////////////////////////////////////////////////
@@ -765,6 +796,124 @@ public:
}
}
}
+
+ sal_Bool hasDoublePoints() const
+ {
+ if(mbIsClosed)
+ {
+ // check for same start and end point
+ const sal_uInt32 nIndex(maPoints.count() - 1L);
+
+ if(maPoints.getCoordinate(0L) == maPoints.getCoordinate(nIndex))
+ {
+ if(mpControlVector)
+ {
+ if(mpControlVector->getVectorA(nIndex).equalZero()
+ && mpControlVector->getVectorB(nIndex).equalZero())
+ {
+ return sal_True;
+ }
+ }
+ else
+ {
+ return sal_True;
+ }
+ }
+ }
+
+ // test for range
+ for(sal_uInt32 a(0L); a < maPoints.count() - 1L; a++)
+ {
+ if(maPoints.getCoordinate(a) == maPoints.getCoordinate(a + 1L))
+ {
+ if(mpControlVector)
+ {
+ if(mpControlVector->getVectorA(a).equalZero()
+ && mpControlVector->getVectorB(a).equalZero())
+ {
+ return sal_True;
+ }
+ }
+ else
+ {
+ return sal_True;
+ }
+ }
+ }
+
+ return sal_False;
+ }
+
+ void removeDoublePointsAtBeginEnd()
+ {
+ // Only remove DoublePoints at Begin and End when poly is closed
+ if(mbIsClosed)
+ {
+ if(mpControlVector)
+ {
+ sal_Bool bRemove;
+
+ do
+ {
+ bRemove = sal_False;
+
+ if(maPoints.count() > 1L)
+ {
+ const sal_uInt32 nIndex(maPoints.count() - 1L);
+
+ if(maPoints.getCoordinate(0L) == maPoints.getCoordinate(nIndex))
+ {
+ if(mpControlVector->getVectorA(nIndex).equalZero()
+ && mpControlVector->getVectorB(nIndex).equalZero())
+ {
+ bRemove = sal_True;
+ }
+ }
+ }
+
+ if(bRemove)
+ {
+ const sal_uInt32 nIndex(maPoints.count() - 1L);
+ remove(nIndex, 1L);
+ }
+ } while(bRemove);
+ }
+ else
+ {
+ maPoints.removeDoublePointsAtBeginEnd();
+ }
+ }
+ }
+
+ void removeDoublePointsWholeTrack()
+ {
+ if(mpControlVector)
+ {
+ sal_uInt32 nIndex(0L);
+
+ // test as long as there are at least two points and as long as the index
+ // is smaller or equal second last point
+ while((maPoints.count() > 1L) && (nIndex <= maPoints.count() - 2L))
+ {
+ if(maPoints.getCoordinate(nIndex) == maPoints.getCoordinate(nIndex + 1L)
+ && mpControlVector->getVectorA(nIndex).equalZero()
+ && mpControlVector->getVectorB(nIndex).equalZero())
+ {
+ // if next is same as index and the control vectors are unused, delete index
+ remove(nIndex, 1L);
+ }
+ else
+ {
+ // if different, step forward
+ nIndex++;
+ }
+ }
+ }
+ else
+ {
+ maPoints.removeDoublePointsWholeTrack();
+ }
+ }
};
//////////////////////////////////////////////////////////////////////////////
@@ -836,7 +985,7 @@ namespace basegfx
{
if(mpPolygon == rPolygon.mpPolygon)
{
- return true;
+ return sal_True;
}
return mpPolygon->isEqual(*(rPolygon.mpPolygon));
@@ -846,7 +995,7 @@ namespace basegfx
{
if(mpPolygon == rPolygon.mpPolygon)
{
- return false;
+ return sal_False;
}
return !mpPolygon->isEqual(*(rPolygon.mpPolygon));
@@ -1034,6 +1183,21 @@ namespace basegfx
mpPolygon->flip();
}
}
+
+ sal_Bool B2DPolygon::hasDoublePoints() const
+ {
+ return mpPolygon->hasDoublePoints();
+ }
+
+ void B2DPolygon::removeDoublePoints()
+ {
+ if(mpPolygon->count() > 1)
+ {
+ implForceUniqueCopy();
+ mpPolygon->removeDoublePointsAtBeginEnd();
+ mpPolygon->removeDoublePointsWholeTrack();
+ }
+ }
} // end of namespace polygon
} // end of namespace basegfx
diff --git a/basegfx/source/polygon/b2dpolygontools.cxx b/basegfx/source/polygon/b2dpolygontools.cxx
index 0c1136ca5553..c5b56dd72e31 100644
--- a/basegfx/source/polygon/b2dpolygontools.cxx
+++ b/basegfx/source/polygon/b2dpolygontools.cxx
@@ -2,9 +2,9 @@
*
* $RCSfile: b2dpolygontools.cxx,v $
*
- * $Revision: 1.2 $
+ * $Revision: 1.3 $
*
- * last change: $Author: aw $ $Date: 2003-10-31 10:13:58 $
+ * last change: $Author: aw $ $Date: 2003-11-05 12:25:54 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -67,8 +67,12 @@
#include <basegfx/polygon/b2dpolygon.hxx>
#endif
-#ifndef _BGFX_CURVE_B2DCUBICBEZIER_HXX
-#include <basegfx/curve/b2dcubicbezier.hxx>
+#ifndef _BGFX_NUMERIC_FTOOLS_HXX
+#include <basegfx/numeric/ftools.hxx>
+#endif
+
+#ifndef _BGFX_RANGE_B2DRANGE_HXX
+#include <basegfx/range/b2drange.hxx>
#endif
//////////////////////////////////////////////////////////////////////////////
@@ -84,53 +88,415 @@ namespace basegfx
{
while(rCandidate.count() > 1L)
{
- bool bFirstLastPointEqual(
- rCandidate.getB2DPoint(0L) == rCandidate.getB2DPoint(rCandidate.count() - 1L));
+ sal_Bool bFirstLastPointEqual(rCandidate.getB2DPoint(0L).equal(rCandidate.getB2DPoint(rCandidate.count() - 1L)));
if(bFirstLastPointEqual)
{
- rCandidate.setClosed(true);
+ rCandidate.setClosed(sal_True);
rCandidate.remove(rCandidate.count() - 1L);
}
}
}
- // Checks if one of the control vectors is used
- bool isEdgeBezier(const polygon::B2DPolygon& rPolygon, sal_uInt32 nEdgeIndex)
+ // Get index of outmost point (e.g. biggest X and biggest Y)
+ sal_uInt32 getIndexOfOutmostPoint(const polygon::B2DPolygon& rCandidate)
+ {
+ sal_uInt32 nRetval(0L);
+
+ if(rCandidate.count())
+ {
+ ::basegfx::point::B2DPoint aOutmostPoint(rCandidate.getB2DPoint(0L));
+
+ for(sal_uInt32 a(1L); a < rCandidate.count(); a++)
+ {
+ ::basegfx::point::B2DPoint rPoint(rCandidate.getB2DPoint(a));
+
+ if(::basegfx::numeric::fTools::more(rPoint.getX(), aOutmostPoint.getX()))
+ {
+ nRetval = a;
+ aOutmostPoint = rPoint;
+ }
+ else
+ {
+ if(::basegfx::numeric::fTools::more(rPoint.getY(), aOutmostPoint.getY()))
+ {
+ nRetval = a;
+ aOutmostPoint = rPoint;
+ }
+ }
+ }
+ }
+
+ return nRetval;
+ }
+
+ // 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)
+ {
+ if(nIndex)
+ {
+ return nIndex - 1L;
+ }
+ else if(rCandidate.count())
+ {
+ return rCandidate.count() - 1L;
+ }
+ else
+ {
+ return nIndex;
+ }
+ }
+
+ sal_uInt32 getIndexOfSuccessor(sal_uInt32 nIndex, const polygon::B2DPolygon& rCandidate)
+ {
+ if(nIndex + 1L < rCandidate.count())
+ {
+ return nIndex + 1L;
+ }
+ else
+ {
+ return 0L;
+ }
+ }
+
+ sal_uInt32 getIndexOfDifferentPredecessor(sal_uInt32 nIndex, const polygon::B2DPolygon& rCandidate)
+ {
+ if(rCandidate.count() > 1)
+ {
+ sal_uInt32 nNewIndex = getIndexOfPredecessor(nIndex, rCandidate);
+ ::basegfx::point::B2DPoint aPoint(rCandidate.getB2DPoint(nIndex));
+
+ while(nNewIndex != nIndex
+ && aPoint.equal(rCandidate.getB2DPoint(nNewIndex)))
+ {
+ nNewIndex = getIndexOfPredecessor(nNewIndex, rCandidate);
+ }
+ }
+
+ return nIndex;
+ }
+
+ sal_uInt32 getIndexOfDifferentSuccessor(sal_uInt32 nIndex, const polygon::B2DPolygon& rCandidate)
{
- if(rPolygon.areControlPointsUsed())
+ if(rCandidate.count() > 1)
{
- DBG_ASSERT(nEdgeIndex < rPolygon.count(), "EdgeIndex out of range (!)");
+ sal_uInt32 nNewIndex = getIndexOfSuccessor(nIndex, rCandidate);
+ ::basegfx::point::B2DPoint aPoint(rCandidate.getB2DPoint(nIndex));
+
+ while(nNewIndex != nIndex
+ && aPoint.equal(rCandidate.getB2DPoint(nNewIndex)))
+ {
+ nNewIndex = getIndexOfSuccessor(nNewIndex, rCandidate);
+ }
+ }
- if(!rPolygon.getControlPointA(nEdgeIndex).equalZero())
- return true;
+ return nIndex;
+ }
+
+ ::basegfx::vector::B2DVectorOrientation getOrientation(const ::basegfx::polygon::B2DPolygon& rCandidate)
+ {
+ ::basegfx::vector::B2DVectorOrientation eRetval(::basegfx::vector::ORIENTATION_NEUTRAL);
- if(!rPolygon.getControlPointB(nEdgeIndex).equalZero())
- return true;
+ if(rCandidate.count() > 2)
+ {
+ sal_uInt32 nIndex = getIndexOfOutmostPoint(rCandidate);
+ eRetval = getPointOrientation(rCandidate, nIndex);
}
- return false;
+ return eRetval;
}
- bool isEdgeTrivialBezier(const polygon::B2DPolygon& rPolygon, sal_uInt32 nEdgeIndex)
+ sal_Bool isInside(const ::basegfx::polygon::B2DPolygon& rCandidate, const ::basegfx::point::B2DPoint& rPoint)
{
- if(rPolygon.areControlPointsUsed())
+ sal_Bool bRetval(sal_False);
+ const sal_uInt32 nPointCount(rCandidate.count());
+
+ for(sal_uInt32 a(0L); a < nPointCount; a++)
{
- DBG_ASSERT(nEdgeIndex < rPolygon.count(), "EdgeIndex out of range (!)");
- const sal_uInt32 nEndIndex((nEdgeIndex + 1L) % rPolygon.count());
+ const basegfx::point::B2DPoint aCurrentPoint(rCandidate.getB2DPoint(a));
+ const basegfx::point::B2DPoint aPreviousPoint(rCandidate.getB2DPoint((!a) ? nPointCount - 1L : a - 1L));
- curve::B2DCubicBezier aCubicBezier(
- rPolygon.getB2DPoint(nEdgeIndex),
- rPolygon.getControlPointA(nEdgeIndex),
- rPolygon.getControlPointB(nEdgeIndex),
- rPolygon.getB2DPoint(nEndIndex));
+ // cross-over in Y?
+ const sal_Bool bCompYA(::basegfx::numeric::fTools::more(aPreviousPoint.getY(), rPoint.getY()));
+ const sal_Bool bCompYB(::basegfx::numeric::fTools::more(aCurrentPoint.getY(), rPoint.getY()));
- aCubicBezier.testAndSolveTrivialBezier();
+ if(bCompYA != bCompYB)
+ {
+ const sal_Bool bCompXA(::basegfx::numeric::fTools::more(aPreviousPoint.getX(), rPoint.getX()));
+ const sal_Bool bCompXB(::basegfx::numeric::fTools::more(aCurrentPoint.getX(), rPoint.getX()));
+
+ if(bCompXA == bCompXB)
+ {
+ if(bCompXA)
+ {
+ bRetval = !bRetval;
+ }
+ }
+ else
+ {
+ const double fCompare =
+ aCurrentPoint.getX() - (aCurrentPoint.getY() - rPoint.getY()) *
+ (aPreviousPoint.getX() - aCurrentPoint.getX()) /
+ (aPreviousPoint.getY() - aCurrentPoint.getY());
+
+ if(::basegfx::numeric::fTools::more(fCompare, rPoint.getX()))
+ {
+ bRetval = !bRetval;
+ }
+ }
+ }
+ }
+
+ return bRetval;
+ }
+
+ sal_Bool isInside(const ::basegfx::polygon::B2DPolygon& rCandidate, const ::basegfx::polygon::B2DPolygon& rPolygon)
+ {
+ const sal_uInt32 nPointCount(rPolygon.count());
- return !aCubicBezier.isBezier();
+ for(sal_uInt32 a(0L); a < nPointCount; a++)
+ {
+ const ::basegfx::point::B2DPoint aTestPoint(rPolygon.getB2DPoint(a));
+
+ if(!isInside(rCandidate, aTestPoint))
+ {
+ return sal_False;
+ }
+ }
+
+ return sal_True;
+ }
+
+ ::basegfx::range::B2DRange getRange(const ::basegfx::polygon::B2DPolygon& rCandidate)
+ {
+ ::basegfx::range::B2DRange aRetval;
+ const sal_uInt32 nPointCount(rCandidate.count());
+
+ for(sal_uInt32 a(0L); a < nPointCount; a++)
+ {
+ const ::basegfx::point::B2DPoint aTestPoint(rCandidate.getB2DPoint(a));
+ aRetval.expand(aTestPoint);
+ }
+
+ return aRetval;
+ }
+
+ double getArea(const ::basegfx::polygon::B2DPolygon& rCandidate)
+ {
+ double fRetval(0.0);
+ const sal_uInt32 nPointCount(rCandidate.count());
+
+ if(nPointCount > 2)
+ {
+ 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));
+
+ fRetval += aPreviousPoint.getX() * aCurrentPoint.getY();
+ fRetval -= aPreviousPoint.getY() * aCurrentPoint.getX();
+ }
+
+ fRetval /= 2.0;
+
+ const double fZero(0.0);
+
+ if(::basegfx::numeric::fTools::less(fRetval, fZero))
+ {
+ fRetval = -fRetval;
+ }
+ }
+
+ return fRetval;
+ }
+
+ double getEdgeLength(const ::basegfx::polygon::B2DPolygon& rCandidate, sal_uInt32 nIndex)
+ {
+ double fRetval(0.0);
+ const sal_uInt32 nPointCount(rCandidate.count());
+
+ if(nIndex < nPointCount)
+ {
+ 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);
+ fRetval = aVector.getLength();
+ }
+ }
+
+ return fRetval;
+ }
+
+ double getLength(const ::basegfx::polygon::B2DPolygon& rCandidate)
+ {
+ // This method may also be implemented using a loop over getEdgeLength, but
+ // since this would cause a lot of sqare roots to be solved it is much better
+ // to sum up the quadrats first and then use a singe suare root (if necessary)
+ double fRetval(0.0);
+ const sal_uInt32 nPointCount(rCandidate.count());
+ const sal_uInt32 nLoopCount(rCandidate.isClosed() ? nPointCount : nPointCount - 1L);
+
+ 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);
+ fRetval += aVector.scalar(aVector);
+ }
+
+ if(!::basegfx::numeric::fTools::equalZero(fRetval))
+ {
+ const double fOne(1.0);
+
+ if(!::basegfx::numeric::fTools::equal(fOne, fRetval))
+ {
+ fRetval = sqrt(fRetval);
+ }
+ }
+
+ return fRetval;
+ }
+
+ ::basegfx::point::B2DPoint getPositionAbsolute(const ::basegfx::polygon::B2DPolygon& rCandidate, double fDistance, double fLength)
+ {
+ ::basegfx::point::B2DPoint aRetval;
+ const sal_uInt32 nPointCount(rCandidate.count());
+
+ if(nPointCount > 1L)
+ {
+ sal_uInt32 nIndex(0L);
+ sal_Bool bIndexDone(sal_False);
+ const double fZero(0.0);
+ double fEdgeLength(fZero);
+
+ // get length if not given
+ if(::basegfx::numeric::fTools::equalZero(fLength))
+ {
+ fLength = getLength(rCandidate);
+ }
+
+ // handle fDistance < 0.0
+ if(::basegfx::numeric::fTools::less(fDistance, fZero))
+ {
+ if(rCandidate.isClosed())
+ {
+ // if fDistance < 0.0 increment with multiple of fLength
+ sal_uInt32 nCount(sal_uInt32(-fDistance / fLength));
+ fDistance += double(nCount + 1L) * fLength;
+ }
+ else
+ {
+ // crop to polygon start
+ fDistance = fZero;
+ bIndexDone = sal_True;
+ }
+ }
+
+ // handle fDistance >= fLength
+ if(::basegfx::numeric::fTools::moreOrEqual(fDistance, fLength))
+ {
+ if(rCandidate.isClosed())
+ {
+ // if fDistance >= fLength decrement with multiple of fLength
+ sal_uInt32 nCount(sal_uInt32(fDistance / fLength));
+ fDistance -= (double)(nCount) * fLength;
+ }
+ else
+ {
+ // crop to polygon end
+ fDistance = fZero;
+ nIndex = nPointCount - 1L;
+ bIndexDone = sal_True;
+ }
+ }
+
+ // look for correct index. fDistance is now [0.0 .. fLength[
+ if(!bIndexDone)
+ {
+ do
+ {
+ // get length of next edge
+ fEdgeLength = getEdgeLength(rCandidate, nIndex);
+
+ if(::basegfx::numeric::fTools::moreOrEqual(fDistance, fEdgeLength))
+ {
+ // go to next edge
+ fDistance -= fEdgeLength;
+ nIndex++;
+ }
+ else
+ {
+ // it's on this edge, stop
+ bIndexDone = sal_True;
+ }
+ } while (!bIndexDone);
+ }
+
+ // get the point using nIndex
+ aRetval = rCandidate.getB2DPoint(nIndex);
+
+ // if fDistance != 0.0, move that length on the edge. The edge
+ // length is in fEdgeLength.
+ if(!::basegfx::numeric::fTools::equalZero(fDistance))
+ {
+ sal_uInt32 nNextIndex(getIndexOfSuccessor(nIndex, rCandidate));
+ const ::basegfx::point::B2DPoint aNextPoint(rCandidate.getB2DPoint(nNextIndex));
+ double fRelative(fZero);
+
+ if(!::basegfx::numeric::fTools::equalZero(fEdgeLength))
+ {
+ fRelative = fDistance / fEdgeLength;
+ }
+
+ // add calculated average value to the return value
+ aRetval += ::basegfx::tuple::average(aRetval, aNextPoint, fRelative);
+ }
+ }
+
+ return aRetval;
+ }
+
+ ::basegfx::point::B2DPoint getPositionRelative(const ::basegfx::polygon::B2DPolygon& rCandidate, double fDistance, double fLength)
+ {
+ // get length if not given
+ if(::basegfx::numeric::fTools::equalZero(fLength))
+ {
+ fLength = getLength(rCandidate);
+ }
+
+ // multiply fDistance with real length to get absolute position and
+ // use getPositionAbsolute
+ return getPositionAbsolute(rCandidate, fDistance * fLength, fLength);
+ }
+
+ ::basegfx::vector::B2DVectorOrientation getPointOrientation(const ::basegfx::polygon::B2DPolygon& rCandidate, sal_uInt32 nIndex)
+ {
+ ::basegfx::vector::B2DVectorOrientation eRetval(::basegfx::vector::ORIENTATION_NEUTRAL);
+
+ if(rCandidate.count() > 2)
+ {
+ sal_uInt32 nIndPrev = getIndexOfDifferentPredecessor(nIndex, rCandidate);
+
+ if(nIndPrev != nIndex)
+ {
+ sal_uInt32 nIndNext = getIndexOfDifferentSuccessor(nIndex, rCandidate);
+
+ if(nIndNext != nIndex && nIndNext != nIndPrev)
+ {
+ ::basegfx::point::B2DPoint aPoint(rCandidate.getB2DPoint(nIndex));
+ ::basegfx::vector::B2DVector aVecPrev(rCandidate.getB2DPoint(nIndPrev) - aPoint);
+ ::basegfx::vector::B2DVector aVecNext(rCandidate.getB2DPoint(nIndNext) - aPoint);
+ eRetval = ::basegfx::vector::getOrientation(aVecPrev, aVecNext);
+ }
+ }
}
- return true;
+ return eRetval;
}
} // end of namespace tools
} // end of namespace polygon
diff --git a/basegfx/source/polygon/b2dpolypolygon.cxx b/basegfx/source/polygon/b2dpolypolygon.cxx
index 642f25b469e6..b1183a6cf052 100644
--- a/basegfx/source/polygon/b2dpolypolygon.cxx
+++ b/basegfx/source/polygon/b2dpolypolygon.cxx
@@ -2,9 +2,9 @@
*
* $RCSfile: b2dpolypolygon.cxx,v $
*
- * $Revision: 1.2 $
+ * $Revision: 1.3 $
*
- * last change: $Author: aw $ $Date: 2003-10-31 10:13:58 $
+ * last change: $Author: aw $ $Date: 2003-11-05 12:25:54 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -71,6 +71,10 @@
#include <tools/debug.hxx>
#endif
+#ifndef _BGFX_POLYPOLYGON_B2DPOLYGONTOOLS_HXX
+#include <basegfx/polygon/b2dpolypolygontools.hxx>
+#endif
+
#include <vector>
//////////////////////////////////////////////////////////////////////////////
@@ -106,21 +110,21 @@ public:
void incRefCount() { mnRefCount++; }
void decRefCount() { mnRefCount--; }
- bool isEqual(const ImplB2DPolyPolygon& rPolygonList) const
+ sal_Bool isEqual(const ImplB2DPolyPolygon& rPolygonList) const
{
// same polygon count?
if(maPolygons.size() != rPolygonList.maPolygons.size())
- return false;
+ return sal_False;
// if zero polygons the polys are equal
if(!maPolygons.size())
- return true;
+ return sal_True;
// compare polygon content
if(maPolygons != rPolygonList.maPolygons)
- return false;
+ return sal_False;
- return true;
+ return sal_True;
}
const basegfx::polygon::B2DPolygon& getPolygon(sal_uInt32 nIndex) const
@@ -180,6 +184,30 @@ public:
{
return maPolygons.size();
}
+
+ void setClosed(sal_Bool bNew)
+ {
+ for(sal_uInt32 a(0L); a < maPolygons.size(); a++)
+ {
+ maPolygons[a].setClosed(bNew);
+ }
+ }
+
+ void flip()
+ {
+ for(sal_uInt32 a(0L); a < maPolygons.size(); a++)
+ {
+ maPolygons[a].flip();
+ }
+ }
+
+ void removeDoublePoints()
+ {
+ for(sal_uInt32 a(0L); a < maPolygons.size(); a++)
+ {
+ maPolygons[a].removeDoublePoints();
+ }
+ }
};
//////////////////////////////////////////////////////////////////////////////
@@ -241,21 +269,21 @@ namespace basegfx
return *this;
}
- bool B2DPolyPolygon::operator==(const B2DPolyPolygon& rPolyPolygon) const
+ sal_Bool B2DPolyPolygon::operator==(const B2DPolyPolygon& rPolyPolygon) const
{
if(mpPolyPolygon == rPolyPolygon.mpPolyPolygon)
{
- return true;
+ return sal_True;
}
return mpPolyPolygon->isEqual(*(rPolyPolygon.mpPolyPolygon));
}
- bool B2DPolyPolygon::operator!=(const B2DPolyPolygon& rPolyPolygon) const
+ sal_Bool B2DPolyPolygon::operator!=(const B2DPolyPolygon& rPolyPolygon) const
{
if(mpPolyPolygon == rPolyPolygon.mpPolyPolygon)
{
- return false;
+ return sal_False;
}
return !mpPolyPolygon->isEqual(*(rPolyPolygon.mpPolyPolygon));
@@ -349,6 +377,68 @@ namespace basegfx
mpPolyPolygon = &maStaticDefaultPolyPolygon;
mpPolyPolygon->incRefCount();
}
+
+ sal_Bool B2DPolyPolygon::isClosed() const
+ {
+ sal_Bool bRetval(sal_True);
+
+ // PolyPOlygon is closed when all contained Polygons are closed or
+ // no Polygon exists.
+ for(sal_uInt32 a(0L); bRetval && a < mpPolyPolygon->count(); a++)
+ {
+ if(!(mpPolyPolygon->getPolygon(a)).isClosed())
+ {
+ bRetval = sal_False;
+ }
+ }
+
+ return bRetval;
+ }
+
+ void B2DPolyPolygon::setClosed(sal_Bool bNew)
+ {
+ if(bNew != isClosed())
+ {
+ implForceUniqueCopy();
+ mpPolyPolygon->setClosed(bNew);
+ }
+ }
+
+ ::basegfx::vector::B2DVectorOrientation B2DPolyPolygon::checkOrientations()
+ {
+ implForceUniqueCopy();
+ return ::basegfx::polygon::tools::checkOrientations(*this);
+ }
+
+ void B2DPolyPolygon::flip()
+ {
+ implForceUniqueCopy();
+ mpPolyPolygon->flip();
+ }
+
+ sal_Bool B2DPolyPolygon::hasDoublePoints() const
+ {
+ sal_Bool bRetval(sal_False);
+
+ for(sal_uInt32 a(0L); !bRetval && a < mpPolyPolygon->count(); a++)
+ {
+ if((mpPolyPolygon->getPolygon(a)).hasDoublePoints())
+ {
+ bRetval = sal_True;
+ }
+ }
+
+ return bRetval;
+ }
+
+ void B2DPolyPolygon::removeDoublePoints()
+ {
+ if(hasDoublePoints())
+ {
+ implForceUniqueCopy();
+ mpPolyPolygon->removeDoublePoints();
+ }
+ }
} // end of namespace polygon
} // end of namespace basegfx
diff --git a/basegfx/source/polygon/makefile.mk b/basegfx/source/polygon/makefile.mk
index 6d2921a7155f..7e6e3384c48e 100644
--- a/basegfx/source/polygon/makefile.mk
+++ b/basegfx/source/polygon/makefile.mk
@@ -2,9 +2,9 @@
#
# $RCSfile: makefile.mk,v $
#
-# $Revision: 1.1 $
+# $Revision: 1.2 $
#
-# last change: $Author: aw $ $Date: 2003-10-28 11:23:55 $
+# last change: $Author: aw $ $Date: 2003-11-05 12:25:55 $
#
# The Contents of this file are made available subject to the terms of
# either of the following licenses
@@ -75,9 +75,10 @@ TARGET=polygon
# --- Files -------------------------------------
SLOFILES= \
- $(SLO)$/b2dpolygon.obj \
- $(SLO)$/b2dpolygontools.obj \
- $(SLO)$/b2dpolypolygon.obj
+ $(SLO)$/b2dpolygon.obj \
+ $(SLO)$/b2dpolygontools.obj \
+ $(SLO)$/b2dpolypolygon.obj \
+ $(SLO)$/b2dpolypolygontools.obj
# --- Targets ----------------------------------